#===============================================
# Rietan
#===============================================
package Rietan;
use Exporter;
@ISA = qw(Exporter);
#公開したいサブルーチン
@EXPORT = qw();
use strict;
use File::Basename;
use Cwd;
use Math::Complex;
use JFile;
use Deps;
use ProgVars;
use GraphData;
use Sci qw($pi $a0);
use Sci::DiffractionPeakArray;
use Crystal::SpaceGroup;
my $DirectorySeparator = "\\";
my $SystemCharCode = "sjis";
#===============================================
# パス(読み込みDB)
# Web関係変数
# CGI の仮想パス
# プログラム名
#===============================================
my $HOME = $ENV{'HOME'};
my $WebRootDir = "d:\\MyWebs";
my $CGIPath = Deps::MakePath($WebRootDir, "cgi-bin", 1);
#my $ProgramDir = "d:\\Programs";
my $RietanDir = ProgVars::RietanDir(); #Deps::MakePath($ProgramDir, "X線回折", 0);
#$RietanDir = Deps::MakePath($RietanDir, "Rietan2000", 0);
my $RietanProgramPath = Deps::MakePath($RietanDir, "Programs", 0);
Jcode::convert(\$RietanProgramPath, $SystemCharCode) if($SystemCharCode);
#my $RietanPath = Deps::MakePath($RietanProgramPath, "rietan.exe", 0);
#my $RietanPath = Deps::MakePath($RietanProgramPath, "rietan20040701.exe", 0);
my $RietanPath = Deps::MakePath($RietanProgramPath, "RIETAN_VENUS/rietan64.exe", 0);
my $TeePath = Deps::MakePath($RietanProgramPath, "tee.exe", 0);
my $DBDir = ProgVars::DBDir();
#my $DBDir = Deps::MakePath($WebRootDir, "Research", 0);
# $DBDir = Deps::MakePath($DBDir, "Databases", 0);
#Utils::InitHTML();
#print "
DBDir: $DBDir
\n";
my $CrystalDBDir = Deps::MakePath($WebRootDir, "Research", 0);
$CrystalDBDir = Deps::MakePath($CrystalDBDir, "CrystalStructure", 0);
my $CrystalRietanFileDir = Deps::MakePath($CrystalDBDir, "Rietan", 0);
my $SpaceGroupDBPath = Deps::MakePath($DBDir, "SPGRA", 0);
#my $SpaceGroupDBPath = Deps::MakePath($RietanProgramPath, "SPGRA", 0);
# = Deps::MakePath($ProgramDir, "X線回折\\Rietan2000\\programs\\SPGRA", 0);
my $ASFDCPath = Deps::MakePath($DBDir, "asfdc", 0);
#print "ASFDCPath $ASFDCPath
\n";
if($^O eq 'linux') {
#unless(-d $RietanDir) {
$RietanDir = "$HOME/rietan" ;
$RietanProgramPath = "$HOME/rietan/bin";
$RietanPath = Deps::MakePath($RietanProgramPath, "rietan", 0);
$TeePath = "tee";
$DBDir = $RietanProgramPath;
$SpaceGroupDBPath = Deps::MakePath($RietanProgramPath, "spgra", 0);
}
#============================================================
# 変数等取得関数
#============================================================
sub ClearAll { my $this=shift;
undef $this->{'FileType'}; undef $this->{'DataArray'};
undef $this->{'DiffractionPeakArray'}; }
sub GetpDiffractionPeakArray { return shift->{'DiffractionPeakArray'}; }
sub GetnDiffractionPeakArray {
my $array = shift->GetpDiffractionPeakArray(); return scalar @$array; }
sub FileType { return shift->{'FileType'}; }
sub FileName { return shift->{'FileName'}; }
sub SetFileName { my ($this,$f)=@_; return $this->{'FileName'} = $f; }
sub DataArray { return shift->{'DataArray'}; }
sub SetDataArray
{
my ($this, $DataArray) = @_;
return $this->{'DataArray'} = $DataArray;
}
sub iLaueG { return shift->{'iLaueG'}; }
sub iCenter { return shift->{'iCenter'}; }
#============================================================
# コンストラクタ、デストラクタ
#============================================================
sub new
{
my ($module) = @_;
my $this = {};
bless $this;
return $this;
}
sub DESTROY
{
my $this = shift;
}
#============================================================
# 継承クラスで定義しなおす関数
#============================================================
sub CheckFileType
{
my ($path) = @_;
my ($drive, $dir, $filename, $ext, $lastdir, $filebody)
= Deps::SplitFilePath($path);
#print "Path: $path\n";
if($ext =~ /^\.int$/i) {
return "Rietan Intensity File";
}
elsif($ext =~ /^\.ins$/i) {
return "Rietan Input File";
}
elsif($ext =~ /^\.lst$/i) {
return "Rietan Output File";
}
elsif($ext =~ /^\.asc$/i) {
return "RINT2000 ASCIIFile";
}
elsif($ext =~ /^\.txt$/i) {
my $infile = new JFile;
my $ret = $infile->Open($path, "r");
return undef unless($ret);
my $line1 = $infile->ReadLine();
my $line2 = $infile->ReadLine();
my $line3 = $infile->ReadLine();
$infile->Close();
return "TOPAS Text File" if($line3 =~ /DIFFRAC/);
return undef;
}
elsif($ext =~ /^\.pat$/i or $ext =~ /^\.itx$/i) {
my $infile = new JFile;
my $ret = $infile->Open($path, "r");
return undef unless($ret);
my $line1 = $infile->ReadLine();
my $line2 = $infile->ReadLine();
my $line3 = $infile->ReadLine();
$infile->Close();
Utils::DelSpace($line1);
Utils::DelSpace($line2);
Utils::DelSpace($line3);
#print "1: $line1\n";
#print "2: $line2\n";
#print "3: $line3\n";
if($line1 =~ /^IGOR/) {
return "Rietan Pattern File (IGOR)" unless($line2 =~ /yobs/);
return "Rietan Fitting Pattern File (IGOR)";
}
else {
if($line3 =~ /^\s*\d+\s+[\d\.]+\s*$/) {
return "RietanFP Pattern File (RietPlot)";
}
if($line2 =~ /^\s*\d+\s+[\d\.]+\s+[\d\.]+\s+\d+/) {
return "Rietan Pattern File (RietPlot)";
}
my @array = split(/\s+/, $line1);
if(@array == 8) {
return "Rietan Pattern File (gnuplot)";
}
if(@array >= 10) {
return "Rietan Fitting Pattern File";
}
}
return undef;
}
return undef;
}
sub ReadIGORPatternFile
{
my ($this, $filename) = @_;
my $infile = new JFile;
my $ret = $infile->Open($filename, "r");
return undef unless($ret);
$this->SetDataArray(new GraphDataArray);
my $title = $infile->ReadLine();
Utils::DelSpace($title);
$infile->SkipTo("BEGIN");
my $IntData = new GraphData;
my @Q;
my @Int;
my $line;
my $c = 0;
while($line = $infile->ReadLine()) {
last if($line =~ /^END/);
my @array = split(/\s+/, $line);
my ($x, $y) = Utils::RemoveSpaceElement(@array);
#print "line: $line x=$x y=$y\n";
$Q[$c] = $x + 0.0;
$Int[$c] = $y + 0.0;
$c++;
}
$IntData->SetTitle($title);
$IntData->{'x0'} = $IntData->{'2Q'} = \@Q;
$IntData->{'y0'} = $IntData->{'Intensity'} = \@Int;
$IntData->CalMinMax();
$this->{'DataArray'}->AddGraphData($IntData);
$infile->SkipTo("BEGIN");
# my $PeakData = new GraphData;
my @Diffraction;
$Diffraction[0] = new DiffractionPeakArray;;
my @Q2;
my @Q20;
my @d;
while($line = $infile->ReadLine()) {
last if($line =~ /^END/);
# my ($x1, $x0, $y, $d) = split(/\s+/, $line);
# push(@Q2, $x1);
# push(@Q20, $x0);
# push(@d, $d);
my @a = Utils::Split("\\s+", $line);
# my $n = @a;
#print "Q=$a[0]\n";
$Diffraction[0]->Add("", $a[0]+0.0, '', 0.0);
}
$infile->SkipTo("BEGIN");
for(my $i = 0 ; $i < $Diffraction[0]->nPeaks() ; $i++) {
$line = $infile->ReadLine();
last if($line =~ /^END/);
my ($h, $k, $l) = Utils::Split("\\s+", $line);
my $s = "$h $k $l";
$Diffraction[0]->Sethkl($i, $s);
}
$infile->Close();
$this->{DiffractionPeakArray} = \@Diffraction;
#print "DP: $this,$this->{DiffractionPeakArray}\n";
# $PeakData->SetTitle($title);
# $PeakData->{'2Q'} = \@Q2;
# $PeakData->{'x0'} = $PeakData->{'2Q0'} = \@Q20;
# $PeakData->{'y0'} = $PeakData->{'d'} = \@d;
# $PeakData->CalMinMax();
# $this->{'DataArray'}->AddGraphData($PeakData);
return $filename;
}
sub ReadRietPlotFile
{
my ($this, $filename) = @_;
my $infile = new JFile;
my $ret = $infile->Open($filename, "r");
return undef unless($ret);
$this->SetDataArray(new GraphDataArray);
my $title = $infile->ReadLine();
Utils::DelSpace($title);
Utils::DelQuote($title);
my $line = $infile->ReadLine();
my ($nData, $Start, $Step, $nPeak) = ($line =~ /^\s*(\d+)\s+([\d\.]+)\s+([\d\.]+)\s+(\d+)/);
#print "nData=$nData 2Q=$Start, $Step\n";
my $IntData = new GraphData;
my @Q;
my @Int;
my $c = 0;
while($line = $infile->ReadLine()) {
last if($line =~ /^END/);
my @array = split(/\s+/, $line);
@array = Utils::RemoveSpaceElement(@array);
for(my $i = 0 ; $i < @array ; $i++) {
my $Q = $Start + $c*$Step;
$Q[$c] = $Q;
$Int[$c] = $array[$i] + 0.0;
$c++;
}
last if($c >= $nData);
}
$IntData->SetTitle($title);
$IntData->{'x0'} = $IntData->{'2Q'} = \@Q;
$IntData->{'y0'} = $IntData->{'Intensity'} = \@Int;
$IntData->CalMinMax();
$this->{'DataArray'}->AddGraphData($IntData);
# my $PeakData = new GraphData;
my @Diffraction;
$Diffraction[0] = new DiffractionPeakArray;
my @Q2;
# $c = 0;
while($line = $infile->ReadLine()) {
last if($line =~ /^END/);
# my @array = split(/\s+/, $line);
# @array = Utils::RemoveSpaceElement(@array);
my @a = Utils::Split("\\s+", $line);
for(my $i = 0 ; $i < @a ; $i++) {
# $Q2[$c] = $array[$i] + 0.0;
# $c++;
$Diffraction[0]->Add("", $a[$i]+0.0, '', 0.0);
#print "Q=$a[$i]\n";
}
}
$infile->Close();
$this->{'DiffractionPeakArray'} = \@Diffraction;
# $PeakData->SetTitle($title);
# $PeakData->{'x0'} = $PeakData->{'2Q'} = \@Q2;
# $PeakData->CalMinMax();
# $this->{'DataArray'}->AddGraphData($PeakData);
return $filename;
}
sub ReadRietanFPRietPlotFile
{
my ($this, $filename) = @_;
my $infile = new JFile;
my $ret = $infile->Open($filename, "r");
return undef unless($ret);
$this->SetDataArray(new GraphDataArray);
my $title = $infile->ReadLine();
Utils::DelSpace($title);
Utils::DelQuote($title);
my $line = $infile->ReadLine();
#print "l1: $line";
my ($idx1, $Step, $nPeak, $idx2) = Utils::Split("\\s+", $line);
$line = $infile->ReadLine();
#print "l2: $line";
my ($nData, $Start) = Utils::Split("\\s+", $line);
print "nData=$nData 2Q=$Start, $Step nPeak=$nPeak\n";
my $IntData = new GraphData;
my @Q;
my @Obs;
my @Cal;
my @BG;
my @Diff;
my $c = 0;
while(1) {
$line = $infile->ReadLine();
my @array = Utils::Split("\\s+", $line);
for(my $i = 0 ; $i < @array ; $i += 3) {
my $Q = $Start + $c*$Step;
$Q[$c] = $Q;
$Obs[$c] = $array[$i ] + 0.0;
$Cal[$c] = $array[$i+1] + 0.0;
$BG[$c] = $array[$i+2] + 0.0;
$Diff[$c] = $Obs[$c] - $Cal[$c];
$c++;
}
last if($c >= $nData);
}
$IntData->SetTitle($title);
$IntData->{'x0'} = $IntData->{'2Q'} = \@Q;
$IntData->{'y0'} = $IntData->{'ObsIntensity'} = \@Obs;
$IntData->{'y1'} = $IntData->{'CalIntensity'} = \@Cal;
$IntData->{'y2'} = $IntData->{'BGIntensity'} = \@BG;
$IntData->{'y3'} = $IntData->{'DiffIntensity'} = \@Diff;
$IntData->CalMinMax();
$this->{DataArray}->AddGraphData($IntData);
delete $this->{DiffractionPeakArray};
my @Diffraction;
$Diffraction[0] = new DiffractionPeakArray;
while($line = $infile->ReadLine()) {
last if($line =~ /^END/);
my @a = Utils::Split("\\s+", $line);
for(my $i = 0 ; $i < @a ; $i++) {
$Diffraction[0]->Add("$a[$i]", $a[$i]+0.0, '', 0.0);
}
}
$infile->Close();
$this->{DiffractionPeakArray} = \@Diffraction;
# $PeakData->SetTitle($title);
# $PeakData->{'x0'} = $PeakData->{'2Q'} = \@Q2;
# $PeakData->CalMinMax();
# $this->{'DataArray'}->AddGraphData($PeakData);
return $filename;
}
sub ReadgnuplotFile
{
my ($this, $filename) = @_;
my $infile = new JFile;
my $ret = $infile->Open($filename, "r");
return undef unless($ret);
$this->SetDataArray(new GraphDataArray);
my $line;
my $IntData = new GraphData;
my @Q;
my @Int;
# my @hkl;
# my @Q2a;
# my @Q2b;
# my @F;
my @Diffraction;
$Diffraction[0] = new DiffractionPeakArray;
my $c = 0;
while($line = $infile->ReadLine()) {
last if($line =~ /^END/);
my @array = split(/\s+/, $line);
my ($Q, $Int, $h, $k, $l, $Q2a, $Q2b, $F)
= Utils::RemoveSpaceElement(@array);
$Q[$c] = $Q + 0.0;
$Int[$c] = $Int + 0.0;
if($F) {
# $hkl[$c] = "$h $k $l";
# $Q2a[$c] = $Q2a;
# $Q2b[$c] = $Q2b;
# $F[$c] = $F;
$Diffraction[0]->Add("$h $k $l", $Q2a+0.0, '', $F+0.0);
}
$c++;
}
$infile->Close();
$IntData->SetTitle('');
$IntData->{'x0'} = $IntData->{'2Q'} = \@Q;
$IntData->{'y0'} = $IntData->{'Intensity'} = \@Int;
$IntData->CalMinMax();
$this->{'DataArray'}->AddGraphData($IntData);
$this->{'DiffractionPeakArray'} = \@Diffraction;
# my $PeakData = new GraphData;
# $PeakData->SetTitle('');
# $PeakData->{'x0'} = $PeakData->{'2Qa'} = \@Q2a;
# $PeakData->{'2Qb'} = \@Q2a;
# $PeakData->{'hkl'} = \@hkl;
# $PeakData->{'F'} = \@F;
# $PeakData->CalMinMax();
# $this->{'DataArray'}->AddGraphData($PeakData);
return $filename;
}
sub ReadIntFile
{
my ($this, $filename) = @_;
my $infile = new JFile;
my $ret = $infile->Open($filename, "r");
return undef unless($ret);
$this->SetDataArray(new GraphDataArray);
my $title = $infile->ReadLine();
Utils::DelSpace($title);
my $nData = $infile->ReadLine();
my $line;
my $IntData = new GraphData;
my @Q;
my @Int;
my $c = 0;
while($line = $infile->ReadLine()) {
last if($line =~ /^END/);
my @array = split(/\s+/, $line);
@array = Utils::RemoveSpaceElement(@array);
$Q[$c] = $array[0]+0.0;
$Int[$c] = $array[1]+0.0;
$c++;
}
$IntData->SetTitle($title);
$IntData->{'x0'} = $IntData->{'2Q'} = \@Q;
$IntData->{'y0'} = $IntData->{'Intensity'} = \@Int;
$IntData->CalMinMax();
$this->{'DataArray'}->AddGraphData($IntData);
$infile->Close();
return $filename;
}
sub ReadIGORFittingPatternFile
{
my ($this, $filename) = @_;
my $infile = new JFile;
my $ret = $infile->Open($filename, "r");
return undef unless($ret);
$this->SetDataArray(new GraphDataArray);
my $line;
my $IntData = new GraphData;
my @Q;
my @Obs;
my @Cal;
my @BG;
my @Diff;
my $c = 0;
$infile->SkipTo("BEGIN");
while($line = $infile->ReadLine()) {
last if($line =~ /^END/);
my ($Q, $obs, $cal, $diff, $bg) = Utils::Split("\\s+", $line);
$Q[$c] = $Q+0.0;
$Obs[$c] = $obs+0.0;
$Cal[$c] = $cal+0.0;
$Diff[$c] = $diff+0.0;
$BG[$c] = $bg+0.0;
$c++;
}
$IntData->SetTitle('');
$IntData->{'x0'} = $IntData->{'2Q'} = \@Q;
$IntData->{'y0'} = $IntData->{'ObsIntensity'} = \@Obs;
$IntData->{'y1'} = $IntData->{'CalIntensity'} = \@Cal;
$IntData->{'y2'} = $IntData->{'BGIntensity'} = \@BG;
$IntData->{'y3'} = $IntData->{'DiffIntensity'} = \@Diff;
$IntData->CalMinMax();
$this->{'DataArray'}->AddGraphData($IntData);
$infile->SkipTo("BEGIN");
my @Diffraction;
$Diffraction[0] = new DiffractionPeakArray;;
my @Q2;
my @Q20;
my @d;
while($line = $infile->ReadLine()) {
last if($line =~ /^END/);
my @a = Utils::Split("\\s+", $line);
$Diffraction[0]->Add("", $a[0]+0.0, $a[1]+0.0, 0.0);
}
$infile->SkipTo("BEGIN");
for(my $i = 0 ; $i < $Diffraction[0]->nPeaks() ; $i++) {
$line = $infile->ReadLine();
last if($line =~ /^END/);
my ($h, $k, $l) = Utils::Split("\\s+", $line);
my $s = "$h $k $l";
$Diffraction[0]->Sethkl($i, $s);
}
$infile->Close();
$this->{DiffractionPeakArray} = \@Diffraction;
#print "*** pPeakArray=$this->{DiffractionPeakArray}\n";
return $filename;
}
sub ReadFittingPatternFile
{
my ($this, $filename) = @_;
my $infile = new JFile;
my $ret = $infile->Open($filename, "r");
return undef unless($ret);
$this->SetDataArray(new GraphDataArray);
my $line;
my $IntData = new GraphData;
my @Q;
my @Obs;
my @Cal;
my @BG;
my @Diff;
my @Diffraction;
my $c = 0;
while($line = $infile->ReadLine()) {
last if($line =~ /^END/);
chomp($line);
my ($l1, $l2) = ($line =~ /^(.{46})(.*)$/);
my ($Q, $obs, $cal, $bg) = Utils::Split("\\s+", $l1);
$Q[$c] = $Q+0.0;
$BG[$c] = $bg+0.0;
$Obs[$c] = $obs+0.0;
$Cal[$c] = $cal+0.0;
$Diff[$c] = $obs - $cal;
#if($c < 20) {
# print "$c: l1: $l1\n";
# print " l2: $l2\n";
#}
my $ip = 0;
while(1) {
last if(length($l2) < 30);
$line = $l2;
($l1, $l2) = ($line =~ /^(.{36})(.*)$/);
#if($c < 20) {
# print " l3: $l2\n";
#}
my ($h, $k, $l, $Q2a, $Q2b, $F)
= Utils::Split("\\s+", $l1);
if(defined $F) {
$Diffraction[$ip] = new DiffractionPeakArray
unless(defined $Diffraction[$ip]);
$Diffraction[$ip]->Add("$h $k $l", $Q2a+0.0, $Q2b+0.0, $F+0.0);
}
$ip++;
}
$c++;
}
$infile->Close();
$IntData->SetTitle('');
$IntData->{'x0'} = $IntData->{'2Q'} = \@Q;
$IntData->{'y0'} = $IntData->{'ObsIntensity'} = \@Obs;
$IntData->{'y1'} = $IntData->{'CalIntensity'} = \@Cal;
$IntData->{'y2'} = $IntData->{'BGIntensity'} = \@BG;
$IntData->{'y3'} = $IntData->{'DiffIntensity'} = \@Diff;
$IntData->CalMinMax();
$this->{'DataArray'}->AddGraphData($IntData);
$this->{'DiffractionPeakArray'} = \@Diffraction;
return $filename;
}
sub ReadTOPASTextFile
{
my ($this, $filename) = @_;
my $infile = new JFile;
my $ret = $infile->Open($filename, "r");
return undef unless($ret);
$this->SetDataArray(new GraphDataArray);
my $line = $infile->ReadLine();
$line = $infile->ReadLine();
my $title = ($line =~ /Title:(.*)$/);
Utils::DelSpace($title);
my $pos;
while(1) {
$line = $infile->ReadLine();
#print "l:$line";
if(!defined $line or $line !~ /^!/) {
$infile->seek($pos, 0) if(defined $pos);
last;
}
$pos = $infile->tell();
}
my $nData = $infile->ReadLine();
my $IntData = new GraphData;
my @Q;
my @Int;
my $c = 0;
while($line = $infile->ReadLine()) {
Utils::DelSpace($line);
last if($line eq '');
my @array = Utils::Split("\\s+", $line);
$Q[$c] = $array[0]+0.0;
$Int[$c] = $array[1]+0.0;
$c++;
}
$IntData->SetTitle($title);
$IntData->{x0} = $IntData->{'2Q'} = \@Q;
$IntData->{y0} = $IntData->{Intensity} = \@Int;
$IntData->CalMinMax();
$this->{DataArray}->AddGraphData($IntData);
$infile->Close();
return $filename;
}
sub ReadRINT2000ASCIIFile
{
my ($this, $filename) = @_;
my ($drive, $dir, $fname, $ext, $lastdir, $filebody)
= Deps::SplitFilePath($filename);
my $in = new JFile($filename, "r");
return undef unless($in);
my $line = $in->SkipTo("\\*SAMPLE ");
my ($Sample) = ($line =~ /=\s*(\S+)/);
$Sample = $filebody unless($Sample);
Utils::DelSpace($Sample);
#print "Sample: $Sample\n";
$in->rewind();
$line = $in->SkipTo("\\*START ");
my ($start) = ($line =~ /=\s*(\S+)/);
#print "Start: $start\n";
$in->rewind();
$line = $in->SkipTo("\\*STEP ");
my ($step) = ($line =~ /=\s*(\S+)/);
#print "Step: $step\n";
$in->rewind();
$line = $in->SkipTo("\\*COUNT ");
my ($nData) = ($line =~ /=\s*(\S+)/);
#print "nData: $nData\n";
my @Q2;
my @Int;
my $c = 0;
while(!$in->eof()) {
$line = $in->ReadLine();
last if($line =~ /\\*END/);
last if($line =~ /\\*EOF/);
my @a = Utils::Split("\\,\\s*", $line);
for(my $i = 0 ; $i < @a ; $i++) {
$Q2[$c] = $start + $c * $step;
$Int[$c] = $a[$i];
$c++;
last if($c >= $nData);
}
last if($c >= $nData);
}
$nData = $c;
#print "nData: $nData\n";
$in->Close();
$this->SetDataArray(new GraphDataArray);
my $IntData = new GraphData;
$IntData->SetTitle($Sample);
$IntData->{'x0'} = $IntData->{"2Q"} = \@Q2;
$IntData->{'y0'} = $IntData->{Intensity} = \@Int;
$IntData->{'x0_Name'} = "2Theta";
$IntData->SetXCaption("2Theta");
$IntData->{'y0_Name'} = $Sample;
$IntData->SetYCaption("Intensity");
$IntData->CalMinMax();
$this->{'DataArray'}->AddGraphData($IntData);
return $filename;
}
sub Read
{
my ($this, $filename) = @_;
$this->ClearAll();
my $FileType = $this->{'FileType'} = Rietan::CheckFileType($filename);
$this->SetFileName($filename);
#print "Read: this=$this\n";
#print "aFileType: $FileType\n";
if($FileType eq "Rietan Intensity File") {
return $this->ReadIntFile($filename);
}
elsif($FileType eq "Rietan Pattern File (IGOR)") {
return $this->ReadIGORPatternFile($filename);
}
elsif($FileType eq "RietanFP Pattern File (RietPlot)") {
return $this->ReadRietanFPRietPlotFile($filename);
}
elsif($FileType eq "Rietan Pattern File (RietPlot)") {
return $this->ReadRietPlotFile($filename);
}
elsif($FileType eq "Rietan Pattern File (gnuplot)") {
return $this->ReadgnuplotFile($filename);
}
elsif($FileType eq "Rietan Fitting Pattern File (IGOR)") {
return $this->ReadIGORFittingPatternFile($filename);
}
elsif($FileType eq "Rietan Fitting Pattern File") {
return $this->ReadFittingPatternFile($filename);
}
elsif($FileType eq "Rietan Input File") {
return 1;
}
elsif($FileType eq "Rietan Output File") {
return 1;
}
elsif($FileType eq 'TOPAS Text File') {
return $this->ReadTOPASTextFile($filename);
}
elsif($FileType eq "RINT2000 ASCIIFile") {
return $this->ReadRINT2000ASCIIFile($filename);
}
return undef
}
sub SetSampleName
{
my ($this, $name) = @_;
return $this->{'SampleName'} = $name;
}
sub SampleName
{
my ($this) = @_;
return $this->{'SampleName'};
}
sub SPGDBPath
{
my ($this) = @_;
return $SpaceGroupDBPath;
}
sub GetASFDCAtoms
{
my ($this, $asfdcfile) = @_;
$asfdcfile = $ASFDCPath if(!defined $asfdcfile);
my @Atoms;
my $in = new JFile($asfdcfile, "r");
if(!$in) {
print "Can not read [$asfdcfile].\n";
return undef;
}
while(!$in->eof()) {
my $line1 = $in->ReadLine();
$in->ReadLine();
$in->ReadLine();
last if($in->eof());
my ($n) = Utils::Split("\\s+", $line1);
push(@Atoms, $n);
}
$in->Close();
return @Atoms;
}
sub ReadASFParameters
{
my ($this, $AtomName, $asfdcfile, $XraySource) = @_;
$asfdcfile = $ASFDCPath if(!defined $asfdcfile or $asfdcfile eq '');
#print "AtomName=[$AtomName] Path=[$ASFDCPath]\n";
my $in = new JFile($asfdcfile, "r");
if(!$in) {
print "Can not read [$asfdcfile].\n";
exit;
return undef;
}
my $ReadAtomName;
while(!$in->eof()) {
my $line = $in->ReadLine();
last if($in->eof());
my ($n) = Utils::Split("\\s+", $line);
if(uc $n eq uc $AtomName) { #$line =~ /^\s*$AtomName\s/i) {
$ReadAtomName = $line;
last;
}
}
#print "Atom: [$AtomName] $ReadAtomName";
my $line1 = $in->ReadLine();
my $line2 = $in->ReadLine();
my @a1 = Utils::Split("\\s+", $line1);
if(@a1 <= 9) {
# $a1[9] = 0.0;
}
my @a2 = Utils::Split("\\s+", $line2);
if(@a2 == 11) {
@a1 = ($a2[0], $a2[6], $a2[1], $a2[7], $a2[2], $a2[8], $a2[3], $a2[9], $a2[4], $a2[10], $a2[5]);
$line2 = $in->ReadLine();
}
else {
@a1 = ($a1[0], $a1[1], $a1[2], $a1[3], $a1[4], $a1[5], $a1[6], $a1[7], 0.0, 1.0, $a1[8]);
}
# my @all = @a1;
my @a3;
if($line2 !~ /0\//) {
@a3 = Utils::Split("[,\\s]+", $line2);
# @all = (@a1, @a3);
#print "a1=", join(', ', @a1), "\n";
#print "a3=", join(', ', @a3), "\n";
}
$in->Close();
# return undef if(!defined $line2);
if(!defined $line2) {
print "Error in Rietan::ReadASFParameters: Can not find ASF for [$AtomName].\n";
exit;
}
my ($atomname) = ($ReadAtomName =~ /^(.[a-z]?)/);
my ($AtomicNumber, $aname, $charge) = AtomType::GetAtomInformation($atomname);
$this->{AtomicNumber} = $AtomicNumber;
#print "[$ReadAtomName - $atomname] ($AtomicNumber, $aname, $charge)\n";
#print "ASF: $atomname: [$a1[0],$a1[1]] [$a1[2],$a1[3]] [$a1[4],$a1[5]] [$a1[6],$a1[7]] [$a1[8],$a1[9]] [$a1[10]]\n";
#print "S=$XraySource\n";
if(defined $XraySource) {
my ($A1, $B1, $A2, $B2, $A3, $B3, $A4, $B4, $A5, $B5, $C, $b) = @a1;
my ($Crdf1, $Crdf2, $Fedf1, $Fedf2, $Codf1, $Codf2, $Cudf1,$Cudf2,
$Modf1, $Modf2, $Agdf1, $Agdf2, $Kbdf1, $Kbdf2) = @a3;
# my ($A1, $B1, $A2, $B2, $A3, $B3, $A4, $B4, $A5, $B5, $C, $b,
# $Crdf1, $Crdf2, $Fedf1, $Fedf2, $Codf1, $Codf2, $Cudf1,$Cudf2,
# $Modf1, $Modf2, $Agdf1, $Agdf2, $Kbdf1, $Kbdf2) = @all;
#print "S=$XraySource: atm=$atomname: Cu=$Cudf1, $Cudf2\n";
if($XraySource eq 'Cr' and defined $Crdf2) {
@a1 = ($A1, $B1, $A2, $B2, $A3, $B3, $A4, $B4, $A5, $B5, $C, $b,$Crdf1,$Crdf2);
}
elsif($XraySource eq 'Fe' and defined $Fedf2) {
@a1 = ($A1, $B1, $A2, $B2, $A3, $B3, $A4, $B4, $A5, $B5, $C, $b,$Fedf1,$Fedf2);
}
elsif($XraySource eq 'Co' and defined $Codf2) {
@a1 = ($A1, $B1, $A2, $B2, $A3, $B3, $A4, $B4, $A5, $B5, $C, $b,$Codf1,$Codf2);
}
elsif($XraySource eq 'Cu' and defined $Cudf2) {
@a1 = ($A1, $B1, $A2, $B2, $A3, $B3, $A4, $B4, $A5, $B5, $C, $b,$Cudf1,$Cudf2);
}
elsif($XraySource eq 'Mo' and defined $Modf2) {
@a1 = ($A1, $B1, $A2, $B2, $A3, $B3, $A4, $B4, $A5, $B5, $C, $b,$Modf1,$Modf2);
}
elsif($XraySource eq 'Ag' and defined $Agdf2) {
@a1 = ($A1, $B1, $A2, $B2, $A3, $B3, $A4, $B4, $A5, $B5, $C, $b,$Agdf1,$Agdf2);
}
elsif($XraySource eq 'Kb' and defined $Kbdf2) {
@a1 = ($A1, $B1, $A2, $B2, $A3, $B3, $A4, $B4, $A5, $B5, $C, $b,$Kbdf1,$Kbdf2);
}
else {
@a1 = ($A1, $B1, $A2, $B2, $A3, $B3, $A4, $B4, $A5, $B5, $C, $b);
}
}
else {
}
$this->{pASFDCParameters} = \@a1;
$this->{ASFDCAtomName} = $AtomName;
if(@a1 < 11) {
print "Error in Rietan::ReadASFParameters: Can not find ASF for [$AtomName].\n";
exit;
}
return @a1;
}
# $s = sin Q / lambda (in nm)
sub AtomicScatteringFactor
{
my ($this, $s) = @_;
return $this->asf($s);
}
# $s = sin Q / lambda (in nm)
sub asfElectron
{
my ($this, $s) = @_;
$s = 1.0e-5 if($s <= 0.0);
my $s2 = $s * $s;
my $k = 1.0e-2 * 8.0 * $pi * $pi / ($a0 * 1.0e9);
my $Z = $this->{AtomicNumber};
my $asfXray = $this->asf($s);
return $k * ($Z - $asfXray) / $s2;
}
# $s = sin Q / lambda (in nm)
sub asf
{
my ($this, $s) = @_;
my $s2 = 0.01 * $s * $s;
my $pP = $this->{pASFDCParameters};
my $n = 11; #@$pP;
my $asf = $pP->[$n-1];
for(my $i = 0 ; $i < $n-1 ; $i += 2) {
# last if(!defined $pP->[$i+1]);
$asf += $pP->[$i] * exp(-$pP->[$i+1] * $s2);
}
if(defined $pP->[13]) {
return cplx($asf + $pP->[12], $pP->[13]);
}
return $asf;
}
# $s = sin Q / lambda (in nm)
sub HydrogenAtomicScatteringFactor
{
my ($this, $s) = @_;
my $k = 4.0 * $pi * $pi * $a0 * $a0 * 1.0e18;
my $a = 1.0 + $k * $s * $s;
return 1.0 / $a / $a;
}
sub ReadSpaceGroup
{
my ($this, $ispg, $iset) = @_;
return 0 unless(open(IN,"<$SpaceGroupDBPath"));
while() {
my $line = $_;
my ($iSPG, $iSet, $LaueG, $nCentr, $nSym, $SPGName)
= ($line =~ /^\s*?(\d+?)\s+?(\d+?)\s+?(\d+?)\s+?(\d+?)\s+?(\d+?)\s+?(\S.*)$/);
#print "line: $line
";
#print "i: $iSPG ($iSet) - $ispg ($iset)
\n";
last if(!defined $iSPG or $iSPG < 1);
unless($iSPG == $ispg and $iSet == $iset) {
my $ICONDLine = ;
for(my $i = 0 ; $i < $nSym ; $i++) {
my $SymOp = ;
}
next;
}
#print "iSPG: $iSPG\n";
#print "iCenter: $nCentr\n";
$this->{iLaueG} = $LaueG;
$this->{iCenter} = $nCentr;
my $SPG = new SpaceGroup();
$SPG->SetSPGName($SPGName);
$SPG->SetiSPG($iSPG);
$SPG->SetiSet($iSet);
$SPG->SetiLaueGroup($LaueG);
$SPG->AnalyzeTranslation();
my $ICONDLine = ;
my @ICOND = unpack("a2a2a2a2a2a2a2a2a2a2a2a2a2a2", $ICONDLine);
$SPG->SetRietanDiffractinCondition(@ICOND);
# for(my $i = 0 ; $i < 14 ; $i++) {
# my $type = SpaceGroup::ICONDTypeStrByRietanIndex($i);
# my $str = SpaceGroup::ICONDCondStrByRietanIndex($i);
# printf " %3s: %s${LF}", $type, $str
# if($ICOND[$i] > 0);
# }
for(my $i = 0 ; $i < $nSym ; $i++) {
my $SymOp = ;
Utils::DelSpace($SymOp);
$SPG->AddSymmetryOperation($SymOp);
#print "symop: $SymOp
\n";
# my @SymOpXYZ = split(/,\s*/, $SymOp);
# my @XMatrix = SpaceGroup::SymOpToMatrix($SymOpXYZ[0]);
# my @YMatrix = SpaceGroup::SymOpToMatrix($SymOpXYZ[1]);
# my @ZMatrix = SpaceGroup::SymOpToMatrix($SymOpXYZ[2]);
}
$SPG->ExpandSymmetryOperation($nCentr);
close(IN);
return $SPG;
}
close(IN);
return 0;
}
sub ReadSpaceGroupFromSPGName
{
my ($this, $SPGName) = @_;
$SPGName =~ s/\s//g;
#print "b [$SPGName]
\n";
my ($count, $iSPG, $iSet) = $this->GetiSPGFromSPGName($SPGName);
#print "b
";
return $this->ReadSpaceGroup($iSPG, $iSet);
}
sub GetiSPGFromSPGName
{
my ($this, $SPGName) = @_;
#print "DB: [$SpaceGroupDBPath]\n";
return 0 unless(open(IN,"<$SpaceGroupDBPath"));
my @list;
my $count = 0;
while() {
my $line = $_;
my ($iSPG,$iSet,$LaueG,$nCentr,$nSym,$SPG)
= ($line =~ /^\s*?(\d+?)\s+?(\d+?)\s+?(\d+?)\s+?(\d+?)\s+?(\d+?)\s+?(\S.*)$/);
last if(!defined $iSPG or $iSPG < 1);
$count++;
$SPG =~ s/\s//g;
$SPGName =~ s/\s//g;
#print "$count: $SPG : $SPGName
\n";
if(uc $SPG eq uc $SPGName) {
close(IN);
return ($count, $iSPG, $iSet);
}
my $ICONDLine = ;
for(my $i = 0 ; $i < $nSym ; $i++) {
my $SymOp = ;
}
}
close(IN);
return (-1, -1, -1);
}
sub GetSpaceGroupList
{
my ($this) = @_;
return 0 unless(open(IN,"<$SpaceGroupDBPath"));
my @list;
my $count = 0;
while() {
my $line = $_;
my ($iSPG,$iSet,$LaueG,$nCentr,$nSym,$SPG)
= ($line =~ /^\s*?(\d+?)\s+?(\d+?)\s+?(\d+?)\s+?(\d+?)\s+?(\d+?)\s+?(\S.*)$/);
last if($iSPG < 1);
$count++;
my $str = sprintf "%3d-%d (%s) [%d]",
$iSPG, $iSet, $SPG, $count;
push(@list, $str);
my $ICONDLine = ;
for(my $i = 0 ; $i < $nSym ; $i++) {
my $SymOp = ;
}
}
close(IN);
return \@list;
}
sub FindNearestAtom
{
my ($this, $name, $charge) = @_;
my @list;
my $NearestName = '';
my $NearestCharge = 100;
#print "name: $name, charge: $charge
";
# my $ASFDCPath = Deps::MakePath($DBDir, "asfdc", 0);
unless(open(IN,$ASFDCPath)) {
print "Can not read ($ASFDCPath).
\n";
return -1;
}
while() {
my $line1 = $_;
my $line2 = ;
my $line3 = ;
my ($aname) = ($line1 =~ /^(\S+)\s/);
#print "aname: $aname ";
if($aname =~ /^($name(\.v|[\d\+-]*))$/i) {
#print "aname: $aname ";
my ($c, $sign) = ($aname =~ /(\d*)([\+-])/);
$c = 1 if($c eq '');
#print "aname: $aname c:$c s:$sign
";
if($sign eq '-') {
$c = -$c;
}
if(abs($charge-$NearestCharge) >= abs($charge-$c)) {
$NearestCharge = $c;
$NearestName = $aname;
#print "nearestname: $NearestName, charge: $NearestCharge
";
}
push(@list, $aname);
}
}
close(IN);
return ($NearestName, @list);
}
sub FindIdenticalSpaceGroup
{
my ($this,$SPG) = @_;
my $iSPG = $SPG->iSPG();
my $Crystal = new Crystal();
$Crystal->SetLatticeParameters(3, 4, 5, 80, 85, 75);
$Crystal->SetCSpaceGroup($SPG);
$Crystal->AddAtomSite("H1", "H", 0.1, 0.15, 0.2, 1.0);
$Crystal->ExpandCoordinates();
my @AtomList = $Crystal->GetCExpandedAtomSiteList();
my $neq = @AtomList;
print "+++*** neq=$neq
\n";
for(my $i = 1 ; $i < 100 ; $i++) {
my $RSPG = $this->ReadSpaceGroup($iSPG, $i);
last if($RSPG == 0);
#my $ns = $RSPG->nSymmetryOperation();
#for(my $k = 0 ; $k < $ns ; $k++) {
# my $symop = $RSPG->SymmetryOperation($k+1);
# print "sym$k: $symop
\n";
#}
my $RCrystal = new Crystal();
$RCrystal->SetLatticeParameters(3, 4, 5, 80, 85, 75);
$RCrystal->SetCSpaceGroup($RSPG);
$RCrystal->AddAtomSite("H1", "H", 0.1, 0.15, 0.2, 1.0);
$RCrystal->ExpandCoordinates();
my @RAtomList = $RCrystal->GetCExpandedAtomSiteList();
my $Rneq = @RAtomList;
#print "+++*** $i: Rneq=$Rneq
\n";
next if($Rneq != $neq);
my $IsPassed = 1;
for(my $j = 0 ; $j < $neq ; $j++) {
my $atom0 = $AtomList[$j];
my ($x0, $y0, $z0) = $atom0->Position(1);
my $IsPassed0 = 0;
for(my $l = 0 ; $l < $neq ; $l++) {
my $atom1 = $RAtomList[$l];
my ($x1, $y1, $z1) = $atom1->Position(1);
my $dis = $Crystal->GetNearestInterAtomicDistance(
$x0, $y0, $z0, $x1, $y1, $z1);
#print "j=$j, l=$l: $dis: ($x0, $y0, $z0) - ($x1, $y1, $z1)
\n";
if($dis < 0.01) {
$IsPassed0 = 1;
last;
}
}
if($IsPassed0 == 0) {
$IsPassed = 0;
last;
}
}
next if($IsPassed == 0);
return $RSPG;
}
return -1;
}
sub Execute
{
my ($this, $filepath, $Actgion, $Program) = @_;
$Program = 'Rietan2000' if(!defined $Program);
my $LF = "
\n";
if($Program eq 'RietanFP') {
$RietanDir = ProgVars::RietanFPDir();
$RietanProgramPath = Deps::MakePath($RietanDir, ["RIETAN_VENUS"], 0);
$RietanPath = Deps::MakePath($RietanProgramPath, "rietan.exe", 0);
if($^O eq 'linux') {
$RietanDir = "$HOME/rietan" ;
$RietanProgramPath = "$HOME/rietan/bin";
$RietanPath = Deps::MakePath($RietanProgramPath, "rietan", 0);
}
}
#ファイル名を(ベース名, ディレクトリ名, 拡張子)に分解
my @filenames = fileparse($filepath, "\.[^\.]+");
my $WorkingDir = $filenames[1];
my $inspath = "$filenames[0].ins";
my $intpath = "$filenames[0].int";
my $bkgpath = "$filenames[0].bkg";
my $patpath = "$filenames[0].pat";
my $lstpath = "$filenames[0].lst";
my $csvpath = "$filenames[0].csv";
print "[$patpath] was deleted.$LF" if(unlink("$WorkingDir$patpath"));
print "[$lstpath] was deleted.$LF" if(unlink("$WorkingDir$lstpath"));
print "[$csvpath] was deleted.$LF" if(unlink("$WorkingDir$csvpath"));
$WorkingDir =~ s/[\\\/]$//;
if($WorkingDir ne '' and $WorkingDir ne '.') {
print "Change working directory to ($WorkingDir)$LF";
unless(-d $WorkingDir) {
print " ($WorkingDir) does not exist.$LF$LF";
return 0;
}
chdir($WorkingDir);
my $CurrentDirectory = cwd();
my $cd = $CurrentDirectory;
$cd =~ s/\\/\//g;
my $wd = $WorkingDir;
$wd =~ s/\\/\//g;
if(uc $cd ne uc $wd) {
print " Can not change to ($wd).$LF";
print " Current directory is ($cd)$LF$LF";
return 0;
}
}
print "Set Rietan=$RietanProgramPath$LF";
$ENV{"Rietan"} = $RietanProgramPath;
my $command = "$RietanPath $inspath $intpath $bkgpath $patpath";
#"%RIETAN%\rietan.exe" "%SAMPLE%.ins" "%SAMPLE%.int" "%SAMPLE%.bkg" "%SAMPLE%.pat"
#"%SAMPLE%.hkl" "%SAMPLE%.xyz" "%SAMPLE%.mem" "%SAMPLE%.ffe" "%SAMPLE%.fba"
#"%SAMPLE%.ffi" "%SAMPLE%.ffo" "%SAMPLE%.vcs" | "%RIETAN%\tee.exe" "%SAMPLE%.lst"
print "Execute: [$command]...$LF";
print "\n";
unless(open(OUT, ">$lstpath")) {
print "Error in Rietan.pm:Execute: Can not write to [$lstpath].$LF";
return;
}
unless(open(IN, "$command|")) {
close(OUT);
print "Error in Rietan.pm:Execute: Can not execute $RietanPath.$LF";
return;
}
while() {
print OUT $_;
print $_;
}
close(IN);
close(OUT);
print "
\n";
print "Convert $patpath file to CSV file ($csvpath).$LF";
unless(open(IN,"<$patpath")) {
print "Error in Rietan.pm:Execute: Can not read [$patpath].$LF";
return;
}
unless(open(OUT,">$csvpath")) {
print "Error in Rietan.pm:Execute: Can not write to [$csvpath].$LF";
return;
}
my $line = ; #Title;
Utils::DelSpace($line);
print "Title: $line\n";
$line = ;
my ($ndata, $start, $step, $npeak) = Utils::Split("\\s+", $line);
print "nData: $ndata, Start angle: $start, Step: $step, nPeaks: $npeak$LF";
print OUT "2Theta,Intensity\n";
my $count = 0;
while() {
my @data = split(/\s+/, $_);
for(my $i = 0 ; $i < @data ; $i++) {
next if($data[$i] eq '');
my $angle = $start + $step * $count;
$count++;
print OUT "$angle,$data[$i]\n";
last if($count >= $ndata);
}
last if($count >= $ndata);
}
close(OUT);
close(IN);
print "$LF";
$inspath = Deps::MakePath($WorkingDir, $inspath, 0);
$intpath = Deps::MakePath($WorkingDir, $intpath, 0);
$patpath = Deps::MakePath($WorkingDir, $patpath, 0);
$lstpath = Deps::MakePath($WorkingDir, $lstpath, 0);
$csvpath = Deps::MakePath($WorkingDir, $csvpath, 0);
return ($inspath, $intpath, $patpath, $lstpath, $csvpath);
}
sub SaveInsFile
{
my ($this, $Crystal, $filename, $IsExpandCoordinate, $IsChooseRandomly,
$IsSimulation, $StartAngle, $EndAngle, $StepAngle, $Program) = @_;
$Program = 'Rietan2000' if(!defined $Program);
if(!defined $IsSimulation or lc $IsSimulation eq 'simulation' or $IsSimulation eq '1') {
$IsSimulation = 1;
}
else {
$IsSimulation = 0;
}
my $LF = "
\n";
print "IsSimulation: $IsSimulation\n";
print "Program $Program\n";
print "Angle: ($StartAngle - $EndAngle), $StepAngle\n";
$StartAngle = 5.0 if($StartAngle eq '');
$EndAngle = 120.0 if($EndAngle eq '');
$StepAngle = 0.02 if($StepAngle eq '');
my $RefineTemplateDir = ($Program eq 'Rietan2000')? ProgVars::RietanTemplateDir() : ProgVars::RietanFPTemplateDir();
#print "Temp: $RefineTemplateDir\n";
my $TemplatePath = Deps::MakePath($RefineTemplateDir, "Refinement-Template.ins", 0);
if($IsSimulation) {
$TemplatePath = Deps::MakePath($RefineTemplateDir, "Simulation-Template.ins", 0);
}
print "Template: $TemplatePath\n";
print "Save to [$filename]\n";
my $Content;
unless(open(IN,"<$TemplatePath")) {
print "Can not open template $TemplatePath.$LF$LF";
return;
}
while() {
$Content .= $_;
}
close(IN);
#Rietanに使える原子名をasfdcから取得
my @AtomTypeList = $Crystal->GetCAtomTypeList();
my $nAtomType = @AtomTypeList;
my %RietanAtomName;
print "Search atom/ion names available for Rietan.
\n";
for(my $i = 0 ; $i < $nAtomType ; $i++) {
my $atom = $AtomTypeList[$i];
my $name = $atom->AtomNameOnly();
my $charge = $atom->Charge() + 0;
my $namecharge = $name;
if($charge > 0) {
$namecharge = "$name$charge+";
}
elsif($charge < 0) {
my $c = -$charge;
$namecharge = "$name$c-";
}
$namecharge =~ s/1//g;
my ($NearestName, @list) = $this->FindNearestAtom($name, $charge);
$RietanAtomName{$name} = $NearestName;
print "++ $NearestName is chosen for $namecharge from (@list)
\n";
}
#一致する空間群を取得
print "Search space group number/origin set.
\n";
my $SPG = $Crystal->GetCSpaceGroup();
my $RSPG = $this->FindIdenticalSpaceGroup($SPG);
if($RSPG <= 0) {
print "Error in Rietan.pm::SaveInsFile: Identical space group was not found.$LF";
return -1;
}
my $SPGName = $RSPG->SPGName();
my $iSPG = $RSPG->iSPG();
my $iSet = $RSPG->iSet();
print "+++ Name: ($SPGName) [#$iSPG - $iSet]$LF";
#置換開始
my $SampleName = $this->SampleName();
$Content =~ s/{Title}/$SampleName/sig;
$Content =~ s/{PHNAME1}/$SampleName/sig;
print "T: $TemplatePath ($StartAngle, $EndAngle, $StepAngle)\n";
$Content =~ s/{StartAngle}/$StartAngle/sig;
$Content =~ s/{EndAngle}/$EndAngle/sig;
$Content =~ s/{StepAngle}/$StepAngle/sig;
my $Atoms = '';
for(my $i = 0 ; $i < $nAtomType ; $i++) {
my $atom = $AtomTypeList[$i];
my $atomname = $atom->AtomNameOnly();
my $name = $RietanAtomName{$atomname};
$Atoms .= " '$name'"
if($Atoms !~ /$name/);
}
$Content =~ s/{Atoms}/$Atoms/sig;
# my $iSPG = $Crystal->iSPGByOutputMode();
# my $iSet = $Crystal->iSetByOutputMode();
my $RietanSPG = "A-$iSPG";
$RietanSPG = "$RietanSPG-$iSet" if($iSet ne '');
$Content =~ s/{SPG}/$RietanSPG/sig;
$Content =~ s/{SPGName}/$SPGName/sig;
my ($a,$b,$c,$alpha,$beta,$gamma) = $Crystal->LatticeParametersByOutputMode(0);
my $CELLQ;
$CELLQ = "$a $b $c $alpha $beta $gamma";
$Content =~ s/{CELLQ}/$CELLQ/sig;
my @ExpandedAtomSiteList = $Crystal->GetCExpandedAtomSiteListByOutputMode();
my $nExpandedAtomSite = @ExpandedAtomSiteList;
my $ATOMCOORDS;
my %AtomCount;
for(my $i = 0 ; $i < $nExpandedAtomSite ; $i++) {
my $atom = $ExpandedAtomSiteList[$i];
my $atomname = $atom->AtomName();
my $atomnameonly = $atom->AtomNameOnly();
my $name = $RietanAtomName{$atomnameonly};
my ($x,$y,$z) = $atom->Position(1);
my $occupancy = $atom->Occupancy();
my $i1 = $i+1;
$AtomCount{$atomname}++;
my $c = $AtomCount{$atomname};
my $label = "$atomnameonly$c";
$ATOMCOORDS .= " $label/$name $occupancy $x $y $z 0.5000 01101\n";
}
$Content =~ s/{ATOMCOORDS}/$ATOMCOORDS/sig;
unless(open(OUT,">$filename")) {
print "Can not write to $filename.$LF$LF";
return;
}
print OUT $Content;
print OUT "\n";
close(OUT);
return 1;
}
1;