#===============================================
# 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 "<H1>DBDir: $DBDir</H1>\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 "<H1>ASFDCPath $ASFDCPath</H1>\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 '');

	my $in = new JFile($asfdcfile, "r");
	if(!$in) {
		print "Can not read [$asfdcfile].\n";
		return undef;
	}
	my $ReadAtomName;
	while(!$in->eof()) {
		my $line = $in->ReadLine();
		last if($in->eof());
		my ($n) = Utils::Split("\\s+", $line);
#print "n: $n/$AtomName\n";
		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();
	$in->Close();
	return undef if(!defined $line2);

	my ($atomname) = ($ReadAtomName =~ /^(.[a-z]?)/);
	my ($AtomicNumber, $aname, $charge) = AtomType::GetAtomInformation($atomname);
	$this->{AtomicNumber} = $AtomicNumber;
#print "[$ReadAtomName - $atomname] ($AtomicNumber, $aname, $charge)\n";

	my @a1 = Utils::Split("\\s+", $line1);
	if(@a1 <= 9) {
		$a1[9] = 0.0;
	}

	my @all = @a1;
	if($line2 !~ /0\//) {
		my @a2 = Utils::Split("[,\\s]+", $line2);
		@all = (@a1, @a2);
	}

#print "S=$XraySource\n";
	if(defined $XraySource) {
		my ($A1,$B1,$A2,$B2,$A3,$B3,$A4,$B4,$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,$C, $b,$Crdf1,$Crdf2);
		}
		elsif($XraySource eq 'Fe' and defined $Fedf2) {
			@a1 = ($A1,$B1,$A2,$B2,$A3,$B3,$A4,$B4,$C, $b,$Fedf1,$Fedf2);
		}
		elsif($XraySource eq 'Co' and defined $Codf2) {
			@a1 = ($A1,$B1,$A2,$B2,$A3,$B3,$A4,$B4,$C, $b,$Codf1,$Codf2);
		}
		elsif($XraySource eq 'Cu' and defined $Cudf2) {
			@a1 = ($A1,$B1,$A2,$B2,$A3,$B3,$A4,$B4,$C, $b,$Cudf1,$Cudf2);
		}
		elsif($XraySource eq 'Mo' and defined $Modf2) {
			@a1 = ($A1,$B1,$A2,$B2,$A3,$B3,$A4,$B4,$C, $b,$Modf1,$Modf2);
		}
		elsif($XraySource eq 'Ag' and defined $Agdf2) {
			@a1 = ($A1,$B1,$A2,$B2,$A3,$B3,$A4,$B4,$C, $b,$Agdf1,$Agdf2);
		}
		elsif($XraySource eq 'Kb' and defined $Kbdf2) {
			@a1 = ($A1,$B1,$A2,$B2,$A3,$B3,$A4,$B4,$C, $b,$Kbdf1,$Kbdf2);
		}
		else {
			@a1 = ($A1,$B1,$A2,$B2,$A3,$B3,$A4,$B4,$C, $b);
		}
	}
	else {
	}
	$this->{pASFDCParameters} = \@a1;
	$this->{ASFDCAtomName}    = $AtomName;
	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   = 9; #@$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->[11]) {
		return cplx($asf + $pP->[10], $pP->[11]);
	}
	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(<IN>) {
		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<br>";
#print "i: $iSPG ($iSet) - $ispg ($iset)<br>\n";
		last if(!defined $iSPG or $iSPG < 1);
		unless($iSPG == $ispg and $iSet == $iset) {
			my $ICONDLine = <IN>;
			for(my $i = 0 ; $i < $nSym ; $i++) {
				my $SymOp = <IN>;
			}
			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 = <IN>;
		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 = <IN>;
			Utils::DelSpace($SymOp);
			$SPG->AddSymmetryOperation($SymOp);
#print "symop: $SymOp<br>\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]<br>\n";
	my ($count, $iSPG, $iSet) = $this->GetiSPGFromSPGName($SPGName);
#print "b<br>";
	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(<IN>) {
		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<br>\n";
		if(uc $SPG eq uc $SPGName) {
			close(IN);
			return ($count, $iSPG, $iSet);
		}
		my $ICONDLine = <IN>;
		for(my $i = 0 ; $i < $nSym ; $i++) {
			my $SymOp = <IN>;
		}
	}
	close(IN);
	return (-1, -1, -1);
}

sub GetSpaceGroupList
{
	my ($this) = @_;
	
	return 0 unless(open(IN,"<$SpaceGroupDBPath"));

	my @list;
	my $count = 0;
	while(<IN>) {
		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 = <IN>;

		for(my $i = 0 ; $i < $nSym ; $i++) {
			my $SymOp = <IN>;
		}
	}
	
	close(IN);
	return \@list;
}

sub FindNearestAtom
{
	my ($this, $name, $charge) = @_;
	my @list;
	my $NearestName = '';
	my $NearestCharge = 100;

print "name: $name, charge: $charge<br>";
#	my $ASFDCPath = Deps::MakePath($DBDir, "asfdc", 0);
	unless(open(IN,$ASFDCPath)) {
		print "Can not read ($ASFDCPath).<br>\n";
		return -1;
	}
	while(<IN>) {
		my $line1 = $_;
		my $line2 = <IN>;
		my $line3 = <IN>;
		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<br>";
			if($sign eq '-') {
				$c = -$c;
			}
			if(abs($charge-$NearestCharge) >= abs($charge-$c)) {
				$NearestCharge = $c;
				$NearestName = $aname;
#print "nearestname: $NearestName, charge: $NearestCharge<br>";
			}
			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<br>\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<br>\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<br>\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)<br>\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 = "<br>\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 "<b>Change working directory to ($WorkingDir)</b>$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 "<b>Set Rietan=$RietanProgramPath</b>$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 "<b>Execute: [$command]...</b>$LF";
	print "<pre>\n";
	unless(open(OUT, ">$lstpath")) {
		print "<b>Error in Rietan.pm:Execute: Can not write to [$lstpath].</b>$LF";
		return;
	}
	unless(open(IN, "$command|")) {
		close(OUT);
		print "<b>Error in Rietan.pm:Execute: Can not execute $RietanPath.</b>$LF";
		return;
	}
	while(<IN>) {
		print OUT $_;
		print $_;
	}
	close(IN);
	close(OUT);
	print "</pre>\n";

	print "<b>Convert $patpath file to CSV file ($csvpath).</b>$LF";
	unless(open(IN,"<$patpath")) {
		print "<b>Error in Rietan.pm:Execute: Can not read [$patpath].</b>$LF";
		return;
	}
	unless(open(OUT,">$csvpath")) {
		print "<b>Error in Rietan.pm:Execute: Can not write to [$csvpath].</b>$LF";
		return;
	}
	my $line = <IN>; #Title;
	Utils::DelSpace($line);
	print "Title: $line\n";
	$line = <IN>;
	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(<IN>) {
		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 = "<br>\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(<IN>) {
		$Content .= $_;
	}
	close(IN);

#Rietanに使える原子名をasfdcから取得
	my @AtomTypeList    = $Crystal->GetCAtomTypeList();
	my $nAtomType = @AtomTypeList;
	my %RietanAtomName;

	print "<b>Search atom/ion names available for Rietan.</b><br>\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)<br>\n";
	}

#一致する空間群を取得
	print "<b>Search space group number/origin set.</b><br>\n";
	my $SPG = $Crystal->GetCSpaceGroup();
	my $RSPG = $this->FindIdenticalSpaceGroup($SPG);
	if($RSPG <= 0) {
		print "<b>Error in Rietan.pm::SaveInsFile: Identical space group was not found.</b>$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;
