#!d:/Perl/bin/perl

use lib 'd:/Programs/Perl/lib';

use strict;
#use warnings;
use File::Path;
use File::Basename;
use File::Find;
use Jcode;
use CGI;
use Cwd;

use Math::Matrix;
use Math::MatrixReal;

use ProgVars;
use Deps;
use Utils;

use Sci::GeneralFileFormat;

use Crystal::CIF;
use Crystal::DiffractionPeak;
use Crystal::Crystal;
use Crystal::SpaceGroup;
use Crystal::AtomType;

use Crystal::RietanFP;
use Crystal::GULP;
use Crystal::XCrySDen;
use Crystal::MXD;
use Crystal::LD;
use Crystal::VASP;
use Crystal::PWSCF;
use Crystal::TranSIESTA;
use Crystal::CRYSTAL06;
use Crystal::CASTEP;
use Crystal::WIEN2k;
use Crystal::TB;
use Crystal::VRML;
use Crystal::X3D;
use Crystal::POVRay;
use Crystal::SCIGRESS;

#===============================================
# デバッグ関係変数
#===============================================
my $Debug = 0;
#$PrintLevelが大きいほど、情報が詳しくなる
my $PrintLevel = 0;

#===============================================
# スクリプト大域変数
#===============================================
my $form = new CGI;

my $LF = "<br>\n";
my $DirectorySeparator = Deps::DirectorySeparator(); #"\\";

my $SGROUPPath = ProgVars::SGROUPPath();
my $TEEPath = ProgVars::TEEPath();

my $CIF = new CIF();
my $Crystal = new Crystal();


#===============================================
# 文字コード関係変数
#===============================================
# sjis, euc, jis, noconv
my $SystemCharCode     = "sjis";
my $FileSystemCharCode = "sjis";
my $MySQLCharCode      = "sjis";
my $WebCharSet         = "x-sjis";
my $WebCharCode        = "sjis";
my $ProgramCharCode    = 'sjis';

#===============================================
# パス（読み込みDB）
# Web関係変数
# CGI の仮想パス
# プログラム名
#===============================================
my $Program          = basename($0);
my $WebRootDir       = "d:\\MyWebs";
my $CGIPath          = Deps::MakePath($WebRootDir, "cgi-bin", 1);
my $ProgramDir       = "d:\\Programs";
my $ResearchRootURL  = "/Research";

my $ResearchDir      = Deps::MakePath($WebRootDir, "Research", 0);
#my $DBDir            = Deps::MakePath($ResearchDir, "Databases", 0);
my $DBDir            = ProgVars::DBDir();
#Utils::InitHTML();
#print "<H1>"DBDir2: $DBDir</H2>\n";

my $WorkingDir       = Deps::MakePath($ResearchDir, "Working", 0);
my $XPRDir           = Deps::MakePath($ProgramDir, "X線回折", 0);
   $XPRDir           = Deps::MakePath($XPRDir, "XPR", 0);
#my $KDir             = Deps::MakePath($XPRDir, "bin${DirectorySeparator}Release", 0);
my $KDir             = Deps::MakePath($XPRDir, "bin", 0);

my $KPath            = Deps::MakePath($KDir, "K.exe", 0);

my $PeriodicTable3DB = Deps::MakePath($DBDir, "PERIODIC.CSV", 0);
my $SpaceGroupDBPath = Deps::MakePath($DBDir, "SPGRA", 0);

my $CrystalDBDir             = Deps::MakePath($WebRootDir, "Research", 0);
$CrystalDBDir                = Deps::MakePath($CrystalDBDir, "CrystalStructure", 0);
my $DeleteCrystalDBDir       = Deps::MakePath($CrystalDBDir, "Deleted", 0);
my $CrystalDBURL             = Deps::MakePath($ResearchRootURL, "CrystalStructure", 0);
my $CrystalCommonFileDir     = Deps::MakePath($CrystalDBDir, "Common", 0);
my $CrystalRietanFileDir     = Deps::MakePath($CrystalDBDir, "Rietan", 0);
my $CrystalDVXaFileDir       = Deps::MakePath($CrystalDBDir, "DVXa", 0);
my $CrystalLDFileDir         = Deps::MakePath($CrystalDBDir, "LD", 0);
my $CrystalGULPFileDir       = Deps::MakePath($CrystalDBDir, "GULP", 0);
my $CrystalMXDOrtoFileDir    = Deps::MakePath($CrystalDBDir, "MXDOrto", 0);
#my $CrystalVASPFileDir       = "d:\\Temp";
my $CrystalVASPFileDir       = Deps::MakePath($CrystalDBDir, "VASP", 0);
my $CrystalPWSCFFileDir      = Deps::MakePath($CrystalDBDir, "PWSCF", 0);
my $CrystalTranSIESTAFileDir = Deps::MakePath($CrystalDBDir, "TranSIESTA", 0);
my $CrystalWIEN2kFileDir     = Deps::MakePath($CrystalDBDir, "WIEN2k", 0);

my $WebElementsBaseURL = "http://www.webelements.com/";
my $WebElementsURL     = "http://www.webelements.com/webelements/elements/text/{AtomName}/key.html";
my $WebElementsIEURL   = "http://www.webelements.com/webelements/elements/text/{AtomName}/ionz.html";
my $SPGDBBaseURL       = "http://www.cryst.ehu.es/";


#CIFファイルの内容
#my %CIFContent;

#==========================================
# メイン関数スタート
#==========================================
my $Action = &GetArg('Action');

Utils::InitHTML("Research", $WebCharSet, "_self");

my $InitialDirectory = cwd(); 
$InitialDirectory =~ s/\//$DirectorySeparator/g;
if($Debug) {
	print "Initial Directory: $InitialDirectory${LF}";
	print "${LF}";
}

#==========================================
# 引数を取得する
# parseInput関数はutil.plにある
#==========================================

#print "<H1>Action: $Action</H1>\n";

if(&GetArg('RenameButton')) {
	&RenameCIFFile($Action);
	my $PrevAction = &GetArg("PreviousAction");
	if($PrevAction eq 'ShowConvertStructureFile') {
		&ShowConvertStructureFile($Action);
	}
	elsif($PrevAction eq 'ShowCalculateDistanceAngle') {
		&ShowCalculateDistanceAngle($Action);
	}
	else {
		&ShowCrystalDB($Action);
	}
}
elsif(&GetArg('DeleteButton')) {
	&DeleteCIFFile($Action);
	my $PrevAction = &GetArg("PreviousAction");
	if($PrevAction eq 'ShowConvertStructureFile') {
		&ShowConvertStructureFile($Action);
	}
	elsif($PrevAction eq 'ShowCalculateDistanceAngle') {
		&ShowCalculateDistanceAngle($Action);
	}
	else {
		&ShowCrystalDB($Action);
	}
}
elsif($Action =~ /^SimulateByRietan$/i) {
	&SimulateByRietan($Action);
}
elsif($Action =~ /^ShowSimulateByRietan$/i) {
	&ShowSimulateByRietan($Action);
}
elsif($Action =~ /^CalculateDiffractionAngles$/i) {
	&CalculateDiffractionAngles($Action);
}
elsif($Action =~ /^ShowLatticeConversion$/i) {
	&ShowLatticeConversion($Action);
}
elsif($Action =~ /^LatticeConversion$/i) {
	&LatticeConversion($Action);
}
elsif($Action =~ /^ShowCalculateDiffractionAngles$/i) {
	&ShowCalculateDiffractionAngles($Action);
}
elsif($Action =~ /^CalculateLatticeParameters$/i) {
	&CalculateLatticeParameters($Action);
}
elsif($Action =~ /^ShowCalculateLatticeParameters$/i) {
	&ShowCalculateLatticeParameters($Action);
}
elsif($Action =~ /^MakeCIFFile$/i) {
	&MakeCIFFile($Action);
}
elsif($Action =~ /^ShowMakeCIFFile$/i) {
	&ShowMakeCIFFile($Action);
}
elsif($Action =~ /^ShowExpandCoordinate$/i) {
	&ShowExpandCoordinate($Action);
}
elsif($Action =~ /^ExpandCoordinate$/i) {
	&DoExpandCoordinate($Action);
}
elsif($Action =~ /^ShowAtomInf$/i) {
	print "<H1>関係リンク</H1>\n";
	print "<a href=\"$WebElementsBaseURL\" _target=\"_blank\">Web Elements</a> (原子の各情報に詳しい)$LF";
	print "$LF";
	&ShowAtomInformation($Action);
}
elsif($Action =~ /^ShowSpaceGroup$/i) {
	print "<H1>関係リンク</H1>\n";
	print "<a href=\"$SPGDBBaseURL\" _target=\"_blank\">空間群、逆格子データベース</a>$LF";
	&ShowSpaceGroup($Action);
}
elsif($Action =~ /^ShowFile$/i) {
	&ShowFile($Action);
}
elsif($Action =~ /^ShowCrystalDB$/i) {
	&ShowCrystalDB($Action);
}
elsif($Action =~ /^ShowCIFInf$/i) {
	my $ShowCIFInf = &GetArg('ShowCIFInf');
	&ShowCIFInf($Action, $ShowCIFInf);
	print "<hr>\n";
	if(&GetArg('ShowCrystalStructure') eq 'ON' and &GetArg("FILE") ne '') {
		&ShowCrystalStructure($Action);
		print "<hr>\n";
	}

	my $filepath = &GetArg("FILE");
	if($filepath ne '') {
		print "<H1>Files</H1>\n";
		&MakeCIFFileLink($Action);
		&MakeSimpleCIFFile($Action) if(&GetArg('MakeSimpleCIFFile') eq 'ON');
		&MakeRietanINSFile($Action) if(&GetArg('MakeRietanINSFiles') eq 'ON');
		&MakeLDFile($Action) if(&GetArg('MakeLDFiles') eq 'ON');
		&MakeKHLabFile($Action) if(&GetArg('MakeKHLabFiles') eq 'ON');
		&MakeCASTEPCIFFile($Action) if(&GetArg('MakeCIFFile') eq 'ON');
		&MakeBDLFile($Action) if(&GetArg('MakeBDLFile') eq 'ON');
		&MakeCARFile($Action) if(&GetArg('MakeCARFile') eq 'ON');
		&MakeTranSIESTAFiles($Action) if(&GetArg('MakeTranSIESTAFiles') eq 'ON');
		&MakeWIEN2kXYZFile($Action) if(&GetArg('MakeWIEN2kXYZFile') eq 'ON');
		&MakeWIEN2kStructFile($Action) if(&GetArg('MakeWIEN2kStructFile') eq 'ON');
		&MakeTBFile($Action) if(&GetArg('MakeTBFile') eq 'ON');
		&MakeGULPFiles($Action) if(&GetArg('MakeGULPFiles') eq 'ON');
		&MakeMXDORTOFiles($Action) if(&GetArg('MakeMXDORTOFiles') eq 'ON');
		&MakePWSCFFile($Action) if(&GetArg('MakePWSCFFile') eq 'ON');
		&MakeVASPFiles($Action) if(&GetArg('MakeVASPFiles') eq 'ON');
		&MakeCRYSTAL06Files($Action) if(&GetArg('MakeCRYSTAL06Files') eq 'ON');
		&MakeDVXaFiles($Action) if(&GetArg('MakeDVXaFiles') eq 'ON');
		&MakeVRMLFile($Action) if(&GetArg('MakeVRMLFile') eq 'ON');
		&MakePOVRayFile($Action) if(&GetArg('MakePOVRayFile') eq 'ON');
	}
}
elsif($Action =~ /^UploadCIFFile$/i) {
	&UploadCIFFile($Action);
}
elsif($Action =~ /^ShowConvertStructureFile$/i) {
	&ShowConvertStructureFile($Action);
}
elsif($Action =~ /^ConvertStructureFile$/i) {
	&ConvertStructureFile($Action);
}
elsif($Action =~ /^ShowCalculateRDF$/i or
	($Action =~ /^CalculateRDF$/i and &GetArg('FILE') eq '') ) {
	&ShowCalculateRDF($Action);
}
elsif($Action =~ /^CalculateRDF$/i) {
	&CalculateRDF($Action);
}
elsif($Action =~ /^ShowCalculateDistanceAngle$/i or
	($Action =~ /^CalculateDistanceAngle$/i and &GetArg('FILE') eq '') ) {
	&ShowCalculateDistanceAngle($Action);
}
elsif($Action =~ /^CalculateDistanceAngle$/i) {
	&CalculateDistanceAngle($Action);
}
else {
	print "${LF}";
	print "Invalid Action: $Action${LF}";
	exit;
}

Utils::EndHTML();

exit;

#===============================================
# スクリプト終了
#===============================================

#==========================================
# &Subroutines
#==========================================

sub GetArg
{
	my ($key, $defvalue) = @_;

	my $str;
	for(my $i = 0 ; $i < @ARGV ; $i++) {
		if($ARGV[$i] =~ /^--$key=(.*)$/i) {
			$str = $1;
		}
	}

	if($str eq '') {
		$str = $form->param($key);
	}

	$str = $defvalue if($str eq '');

	return $str;
}

sub ConvertToValidFileName
{
	my ($fname) = @_;
	$fname =~ s/[\s:\\\/\*\?\|]/_/g;
	return $fname;
}

sub UploadFile
{
	my ($SourcePathKey, $UploadDir) = @_;

	my $filename   = $form->param($SourcePathKey);
	my $parsename = $filename;
#	print "Source File: $parsename$LF";

	return -1 if($parsename eq '');
#ファイルが転送されていなかったら、$filename は 未定義値となっている
#フォーム上でファイルを選択しない場合は、$filename は空文字列
	return -2 unless (defined($filename));
# ファイルが転送されていない場合$filenameは偽
	return -3 unless($filename);

#ファイル名を（ベース名, ディレクトリ名, 拡張子）に分解
	my @filenames = fileparse($parsename, "\.[^\.]+");
#print "filenames: $filenames[0] : $filenames[1] : $filenames[2]<br>\n";
	my $fname = $filenames[0];
	$fname = $fname . $filenames[2] if($filenames[2] ne '');
	my $UploadFile = Deps::MakePath($UploadDir, $fname, 0);
#print "Upload path: $UploadFile$LF";

#ファイルの保存
	return -4 unless (open (OUTFILE,">$UploadFile"));
	binmode($filename);
	binmode(OUTFILE);

#保存用ファイルを無事 open できた場合
# $filename から内容を読み出して保存用ファイルに書き出す
#この場合、変数 $filename はファイルハンドルとして機能する
	my $buffer;
	my $count = 0;
	while (1) {
		my $ret = read($filename, $buffer, 1024);
		last if($ret == 0);
		$count += $ret;
		print OUTFILE $buffer;
	}
#	print "Bytes uploaded: $count bytes.$LF";

#ファイルを close して終了メッセージを表示
#この場合、$filename は、送信元クライアント
#マシン内でのファイルパスを返す
	unless(close (OUTFILE)) {
		return -5;
	}
	return $UploadFile;
}

sub ShowFileLink
{
	my ($URLrootpath, $path, $message) = @_;

	my $Reg = Utils::RegExpQuote($URLrootpath);
	my $url = $path;
	$url =~ s/$Reg//ig;
	my $RegDS = Utils::RegExpQuote($DirectorySeparator);
	$url =~ s/$RegDS/\//g;
#print "URL: $url<br>\n";
	print "<a href=\"$url\">$message</a> ";
	print "(<a href=\"/cgi-bin/Research.pl?Action=ShowFile&File=$path\">View on web</a>)$LF";
}

sub SimulateByRietan
{
	my ($Action) = @_;

	my $PrevAction = &GetArg("PreviousAction");
	my $CIFFile = &GetArg("FILE");
	Utils::DelSpace($CIFFile);
	return &ShowSimulateByRietan($Action) if($CIFFile eq '');

	my $StartAngle = &GetArg('StartAngle');
	my $EndAngle = &GetArg('EndAngle');

	print "<H1>Simulate XRD profile by Rietan</H1>\n";

#CIFファイル名を引数に与えて読み込む
	unless($CIF->Read($CIFFile)) {
		print "Error: Can not read $CIFFile.$LF$LF";
		return 0;
	}
#CIFクラスの内容から、Crystalクラスを作成
	$Crystal = $CIF->GetCCrystal();
	$Crystal->ExpandCoordinates();

#ファイル名を（ベース名, ディレクトリ名, 拡張子）に分解
	my @filenames  = fileparse($CIFFile, "\.[^\.]+");
	my $ins        = $filenames[0] . "-sim.ins";
	my $InsFile    = Deps::MakePath($CrystalRietanFileDir, $ins, 0);
	my $SampleName = "'$filenames[0]'";

	print "$InsFile was deleted.$LF" if(unlink($InsFile));
	my $Rietan = new RietanFP();
	$Rietan->SetSampleName($SampleName);
	if($Rietan->SaveInsFile($Crystal, $InsFile, 0, 0, 1, $StartAngle, $EndAngle) <= 0) {
		print "<b>Error in Research.pl::SimulateByRietan: Can not make ($InsFile).</b>$LF";
		return -1;
	}

	print "<b>Links:</b>$LF";
	&ShowFileLink($WebRootDir, $InsFile, "Rietan .ins File (simulation)") if(-e $InsFile);

	my (@Files) = $Rietan->Execute($InsFile);
	for(my $i = 0 ; $i < @Files ; $i++) {
		my @fs = fileparse($Files[$i], "\.[^\.]+");
		&ShowFileLink($WebRootDir, $Files[$i], "$fs[0]$fs[2]")
			if(-e $Files[$i]);
	}
}

sub ShowSimulateByRietan
{
	my ($Action) = @_;

	my $PrevAction = &GetArg("PreviousAction");
	$PrevAction = 'ShowSimulateByRietan' if($PrevAction eq '');
	my $FileSelect = &GetArg('FileSelect');
	$FileSelect = '*' if($FileSelect eq '');

	print <<EOT1;
<hr>
<h1>Simulate XRD profile by Rietan</h1>
<H2>CIFファイルアップロード</H2>
<form action="/cgi-bin/Research.pl" onSubmit="" ENCTYPE="multipart/form-data" method="POST">
  <input type="hidden" name="Action" value="UploadCIFFile">
  <input type="hidden" name="PreviousAction" value="ShowSimulateByRietan">
  <input type="file" name="UploadCIFFilePath" size="60"> 
  <input type="submit" value="Upload" name="B1">  
</form>
<hr>

<H2>CIFファイルの選択</H2>
<form action="/cgi-bin/Research.pl" onSubmit="" ENCTYPE="multipart/form-data" method="POST">
  <input type="hidden" name="Action" value="SimulateByRietan">
  <input type="hidden" name="PreviousAction" value="$PrevAction"><p>

  <input type="submit" value="submit" name="B1"><br>

  <b>Angle range (2Theta):</b> 
  &nbsp;&nbsp;&nbsp;
  <input type="text" name="StartAngle" value="5.0" size="10"> -
  <input type="text" name="EndAngle" value="120.0" size="10"> 
  <b>File select:</b> <input type="text" name="FileSelect" value="$FileSelect" size="20">
   (use wildcard * and ?, ^/\$ for the first/last characters)<p>

  <table border="1" width="100%">
    <tr>
EOT1

	&ShowFileList($FileSelect);

	print <<EOT2;
    </tr>
  </table>
</form>
EOT2

}

sub LatticeConversion
{
	my ($Action) = @_;

	print "<H1>Lattice conversion</H1>\n";

	my @ParametersSelect = &GetArg('Parameters');
	my $ParametersSelect = $ParametersSelect[0];
	my @DirectionSelect  = &GetArg('Direction');
	my $DirectionSelect  = $DirectionSelect[0];
	my $CheckConsistency = &GetArg('CheckConsistency');

	my $a = &GetArg('a'); $a = eval($a);
	my $b = &GetArg('b'); $b = eval($b);
	my $c = &GetArg('c'); $c = eval($c);
	my $alpha = &GetArg('alpha'); $alpha = eval($alpha);
	my $beta  = &GetArg('beta');  $beta  = eval($beta);
	my $gamma = &GetArg('gamma'); $gamma = eval($gamma);

	my $sxyz = new Math::MatrixReal(3, 1);
	my $v = &GetArg('sx'); $v = eval($v);
	$sxyz->assign(1, 1, $v);
	$v = &GetArg('sy'); $v = eval($v);
	$sxyz->assign(2, 1, $v);
	$v = &GetArg('sz'); $v = eval($v);
	$sxyz->assign(3, 1, $v);

	my $shkl = new Math::MatrixReal(3, 1);
	$v = &GetArg('sh'); $v = eval($v);
	$shkl->assign(1, 1, $v);
	$v = &GetArg('sk'); $v = eval($v);
	$shkl->assign(2, 1, $v);
	$v = &GetArg('sl'); $v = eval($v);
	$shkl->assign(3, 1, $v);

	my $sT = new Math::MatrixReal(3, 3);
	my @PresetRule = &GetArg('PresetRule');
	my $PresetRule = $PresetRule[0];
	print "<b>PresetRule:</b> $PresetRule$LF";
	if($PresetRule eq 'RhombHex') {
		$sT = Math::MatrixReal->new_from_cols( 
				[ [ 1, -1,  0], 
				  [ 0,  1, -1],
				  [ 1,  1,  1] ] );
		$sT->transpose($sT);
	}
	elsif($PresetRule eq 'HexRhomb') {
		$sT = Math::MatrixReal->new_from_cols( 
				[ [ 2/3, 1/3, 1/3],
				  [-1/3, 1/3, 1/3],
				  [-1/3,-2/3, 1/3] ]);
		$sT->transpose($sT);
	}
	elsif($PresetRule eq 'HexOrtho') {
		$sT = Math::MatrixReal->new_from_cols( 
				[ [ 1, 0, 0], 
				  [ 1, 2, 0],
				  [ 0, 0, 1] ] );
		$sT->transpose($sT);
	}
	elsif($PresetRule eq 'FCCPrim') {
		$sT = Math::MatrixReal->new_from_cols( 
				[ [ 0.5, 0.5,   0], 
				  [ 0,   0.5, 0.5],
				  [ 0.5,   0, 0.5] ] );
		$sT->transpose($sT);
	}
	elsif($PresetRule eq 'BCCPrim') {
		$sT = Math::MatrixReal->new_from_cols( 
				[ [-0.5, 0.5, 0.5], 
				  [ 0.5,-0.5, 0.5],
				  [ 0.5, 0.5,-0.5] ] );
		$sT->transpose($sT);
	}
	elsif($PresetRule eq 'ACenterPrim') {
		$sT = Math::MatrixReal->new_from_cols( 
				[ [ 1.0, 0.0, 0.0], 
				  [ 0.0, 0.5, 0.5],
				  [ 0.0,-0.5, 0.5] ] );
		$sT->transpose($sT);
	}
	elsif($PresetRule eq 'BCenterPrim') {
		$sT = Math::MatrixReal->new_from_cols( 
				[ [ 0.5, 0.0, 0.5], 
				  [ 0.0, 1.0, 0.0],
				  [-0.5, 0.0, 0.5] ] );
		$sT->transpose($sT);
	}
	elsif($PresetRule eq 'CCenterPrim') {
		$sT = Math::MatrixReal->new_from_cols( 
				[ [ 0.5, 0.5, 0.0], 
				  [-0.5, 0.5, 0.0],
				  [ 0.0, 0.0, 1.0] ] );
		$sT->transpose($sT);
	}
	else {
		print "  Rule is specified by Matrix:$LF";
		$sT->assign(1, 1, eval(&GetArg('t11')));
		$sT->assign(1, 2, eval(&GetArg('t12')));
		$sT->assign(1, 3, eval(&GetArg('t13')));
		$sT->assign(2, 1, eval(&GetArg('t21')));
		$sT->assign(2, 2, eval(&GetArg('t22')));
		$sT->assign(2, 3, eval(&GetArg('t23')));
		$sT->assign(3, 1, eval(&GetArg('t31')));
		$sT->assign(3, 2, eval(&GetArg('t32')));
		$sT->assign(3, 3, eval(&GetArg('t33')));
	}
	print "<b>Direction:</b> $DirectionSelect$LF";
	print "<b>Check consistency:</b>$CheckConsistency$LF";

#基本ベクトルの変換行列
	my $T = new Math::MatrixReal(3, 3);

	print "<h2>Conversion rule:</h2>\n";
	my $IsChosen = 0;
	if($ParametersSelect eq 'ai') {
		if($DirectionSelect eq 'OriginalToConverted') {
			print "<b>Real space vectors:</b> (<b>a'<sub>i</sub></b>) = "
				."(t<sub>ij</sub>)(<b>a<sub>i</sub></b>)$LF";
			$T = $sT;
			$IsChosen = 1;
		}
		elsif($DirectionSelect eq 'ConvertedlToOriginal') {
			print "<b>Real space vectors:</b> (<b>a<sub>i</sub></b>) = "
				."(t<sub>ij</sub>)(<b>a'<sub>i</sub></b>)$LF";
			$T = $sT->inverse();
			$IsChosen = 1;
		}
	}
	elsif($ParametersSelect eq 'xyz') {
		if($DirectionSelect eq 'OriginalToConverted') {
			print "<b>Real space coordinates:</b> (x'<sub>i</sub>) = "
				."(t<sub>ij</sub>)(x<sub>i</sub>)$LF";
			$T->transpose($sT);
			$T = $T->inverse();
			$IsChosen = 1;
		}
		elsif($DirectionSelect eq 'ConvertedlToOriginal') {
			print "<b>Real space vectors:</b> (x<sub>i</sub>) = "
				."(t<sub>ij</sub>)(x'<sub>i</sub>)$LF";
			$T->transpose($sT);
			$IsChosen = 1;
		}
	}
	elsif($ParametersSelect eq 'a*i') {
		if($DirectionSelect eq 'OriginalToConverted') {
			print "<b>Reciprocal space vectors:</b> (<b>a'*<sub>i</sub></b>) = "
				."(t<sub>ij</sub>)(<b>a*<sub>i</sub></b>)$LF";
			$T->transpose($sT);
			$T = $T->inverse();
			$IsChosen = 1;
		}
		elsif($DirectionSelect eq 'ConvertedlToOriginal') {
			print "<b>Reciprocal space vectors:</b> (<b>a*<sub>i</sub></b>) = "
				."(t<sub>ij</sub>)(<b>a'*<sub>i</sub></b>)$LF";
			$T->transpose($sT);
			$IsChosen = 1;
		}
	}
	elsif($ParametersSelect eq 'hkl') {
		if($DirectionSelect eq 'OriginalToConverted') {
			print "<b>Reciprocal space coordinates:</b> (h'<sub>i</sub>) = "
				."(t<sub>ij</sub>)(h<sub>i</sub>)$LF";
			$T = $sT;
			$IsChosen = 1;
		}
		elsif($DirectionSelect eq 'ConvertedlToOriginal') {
			print "<b>Reciprocal space coordinates:</b> (h<sub>i</sub>) = "
				."(t<sub>ij</sub>)(h'i</sub>)$LF";
			$T = $sT->inverse();
			$IsChosen = 1;
		}
	}
	unless($IsChosen) {
		print "Selected option {Parameters: $ParametersSelect} in {$DirectionSelect}"
			." direction is not supported.$LF";
		return 1;
	}

#	print "<b>\$T$LF";
#	print "<pre>\n";
#	printf "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|%10.4f %10.4f %10.4f|\n", 
#		$T->element(1,1), $T->element(1,2), $T->element(1,3);
#	printf "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|%10.4f %10.4f %10.4f|\n", 
#		$T->element(2,1), $T->element(2,2), $T->element(2,3);
#	printf "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|%10.4f %10.4f %10.4f|\n", 
#		$T->element(3,1), $T->element(3,2), $T->element(3,3);
#	print "</pre>\n";
#	print "$LF";
#	print "<hr>\n";


	print "<b>Input matrix:</b> (t<sub>ij</sub>)$LF";
	print "<pre>\n";
	printf "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|%10.4f %10.4f %10.4f|\n", 
		$sT->element(1,1), $sT->element(1,2), $sT->element(1,3);
	printf "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|%10.4f %10.4f %10.4f|\n", 
		$sT->element(2,1), $sT->element(2,2), $sT->element(2,3);
	printf "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|%10.4f %10.4f %10.4f|\n", 
		$sT->element(3,1), $sT->element(3,2), $sT->element(3,3);
	print "</pre>\n";
	print "<hr>\n";

#実空間べクトル(ai)の変換行列
	print "<b>Real space vector:</b> (<b>a'<sub>i</sub></b>) = "
		."(T<sub>ij</sub>)(<b>a<sub>i</sub></b>)$LF";
	print "<pre>\n";
	printf "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|%10.4f %10.4f %10.4f|\n", 
		$T->element(1,1), $T->element(1,2), $T->element(1,3);
	printf "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|%10.4f %10.4f %10.4f|\n", 
		$T->element(2,1), $T->element(2,2), $T->element(2,3);
	printf "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|%10.4f %10.4f %10.4f|\n", 
		$T->element(3,1), $T->element(3,2), $T->element(3,3);
	print "</pre>\n";

#実空間座標(x,y,z)の変換行列
	my $tRT = new Math::MatrixReal(3, 3);
	$tRT->transpose($T);
	$tRT = $tRT->inverse();
	print "<b>Real space coordinate conversion matrix</b> (x') = "
		."((T<sub>ij</sub>)<sup>t</sup>)<sup>-1</sup>(x)$LF";
	print "<pre>\n";
	printf "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|%10.4f %10.4f %10.4f|\n", 
		$tRT->element(1,1), $tRT->element(1,2), $tRT->element(1,3);
	printf "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|%10.4f %10.4f %10.4f|\n", 
		$tRT->element(2,1), $tRT->element(2,2), $tRT->element(2,3);
	printf "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|%10.4f %10.4f %10.4f|\n", 
		$tRT->element(3,1), $tRT->element(3,2), $tRT->element(3,3);
	print "</pre>\n";

#逆空間ベクトル(a*i)の変換行列: $tRT
	my $RT = new Math::MatrixReal(3, 3);
	$RT->transpose($T);
	$RT = $RT->inverse();
	print "<b>Reciprocal space vector conversion matrix</b> (<b>a<sup>*</sup>'</b>) = "
		."((T<sub>ij</sub>)<sup>t</sup>)<sup>-1</sup>(<b>a<sup>*</sup></b>)$LF";
	print "<pre>\n";
	printf "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|%10.4f %10.4f %10.4f|\n", 
		$RT->element(1,1), $RT->element(1,2), $RT->element(1,3);
	printf "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|%10.4f %10.4f %10.4f|\n", 
		$RT->element(2,1), $RT->element(2,2), $RT->element(2,3);
	printf "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|%10.4f %10.4f %10.4f|\n", 
		$RT->element(3,1), $RT->element(3,2), $RT->element(3,3);
	print "</pre>\n";
	print "$LF";

#逆空間座標(h k l)の変換行列: $T
	my $tR = new Math::MatrixReal(3, 3);
	$tR = $T;
	print "<b>Reciprocal space coordinate conversion matrix</b> (h') = (T<sub>ij</sub>)(h)$LF";
	print "<pre>\n";
	printf "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|%10.4f %10.4f %10.4f|\n", 
		$tR->element(1,1), $tR->element(1,2), $tR->element(1,3);
	printf "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|%10.4f %10.4f %10.4f|\n", 
		$tR->element(2,1), $tR->element(2,2), $tR->element(2,3);
	printf "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|%10.4f %10.4f %10.4f|\n", 
		$tR->element(3,1), $tR->element(3,2), $tR->element(3,3);
	print "</pre>\n";
	print "$LF";
	print "<hr>\n";

#座標(sxyz)の変換: tRT
	if($sxyz->element(1,1) ne '') {
		my $a1 = 
		my $txyz = $tRT * $sxyz;
		print "<b>Real space coordinate conversion:</b>$LF";
		printf "(%10.4f, %10.4f, %10.4f) => (%10.4f, %10.4f, %10.4f)$LF",
			$sxyz->element(1,1), $sxyz->element(2,1), $sxyz->element(3,1),
			$txyz->element(1,1), $txyz->element(2,1), $txyz->element(3,1);
		print "$LF";
	}

#逆空間座標(shkl)の変換: tR
	if($shkl->element(1,1) ne '') {
		my $thkl = $tR * $shkl;
		print "<b>Reciprocal space coordinate conversion:</b>$LF";
		printf "(%10.4f, %10.4f, %10.4f) => (%10.4f, %10.4f, %10.4f)$LF",
			$shkl->element(1,1), $shkl->element(2,1), $shkl->element(3,1),
			$thkl->element(1,1), $thkl->element(2,1), $thkl->element(3,1);
		print "$LF";
	}

#格子定数の変換
	if($a ne '') {
		print "<b>Original lattice parameters:</b>$LF";
		printf "a=%12.6f b=%12.6f c=%12.6f  alpha=%8.4f beta=%8.4f gamma=%8.4f$LF",
					$a, $b, $c, $alpha, $beta, $gamma;
		my $Crystal = new Crystal;
		$Crystal->SetLatticeParameters($a,$b,$c,$alpha,$beta,$gamma);

		my $NewCrystal = $Crystal->ConvertLattice($T, 1);

		my ($a2,$b2,$c2,$alpha2,$beta2,$gamma2) = $NewCrystal->LatticeParameters();
		print "<b>Converted lattice parameters:</b>$LF";
		printf "a'=%12.6f b'=%12.6f c'=%12.6f  alpha'=%8.4f beta'=%8.4f gamma'=%8.4f$LF",
			$a2, $b2, $c2, $alpha2, $beta2, $gamma2;
		print "$LF";

		my ($g11, $g12, $g13, $g21, $g22, $g23, $g31, $g32, $g33)
			= $Crystal->Metrics();

		print "<b>Real space metrics conversion:</b>$LF";
		print "<pre>\n";
		printf "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|%10.4f %10.4f %10.4f|\n", $g11, $g12, $g13;
		printf "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|%10.4f %10.4f %10.4f|\n", $g21, $g22, $g23;
		printf "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|%10.4f %10.4f %10.4f|\n", $g31, $g32, $g33;
		print "</pre>\n";
		print "=>$LF";

		($g11, $g12, $g13, $g21, $g22, $g23, $g31, $g32, $g33)
			= $NewCrystal->Metrics();
		print "<pre>\n";
		printf "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|%10.4f %10.4f %10.4f|\n", $g11, $g12, $g13;
		printf "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|%10.4f %10.4f %10.4f|\n", $g21, $g22, $g23;
		printf "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|%10.4f %10.4f %10.4f|\n", $g31, $g32, $g33;
		print "</pre>\n";
	}

	my $ret = &UploadFile('UploadCIFFilePath', $WorkingDir);
	if($ret < 0) {
		print "<H2>Error in UploadFile: Upload failed due to Code $ret.</H2>\n";
		return;
	}
	else {
		my $InputFile = $ret;
		print "<hr>\n";
		print "Convert CIF File ($InputFile).$LF";
		print "<b>Links:</b>$LF";
		&ShowFileLink($WebRootDir, $InputFile, "Input CIF File");

		if($InputFile !~ /\.cif$/i) {
			print "<H2>Error: ($InputFile) is not a CIF file.</H2>\n";
			return;
		}

		my $CIF = new CIF();
		unless($CIF->Read($InputFile)) {
			print "<H2>Error: Can not read $InputFile.</H2>\n";
			return -2;
		}

		my $SimplifiedCIFFile = $InputFile;
		$SimplifiedCIFFile =~ s/\.cif/-simple\.cif/i;
		if($CIF->WriteSimpleCIFFile($SimplifiedCIFFile)) {
			&ShowFileLink($WebRootDir, $SimplifiedCIFFile, "Simplified CIF File");
		}

		my $Crystal = $CIF->GetCCrystal();
		$Crystal->ExpandCoordinates();
		my ($a,$b,$c,$alpha,$beta,$gamma) = $Crystal->LatticeParameters();
		print "<b>Lattice parameters:</b>$LF";
		print "a=$a b=$b c=$c  alpha=$alpha beta=$beta gamma=$gamma$LF";
		print "<b>Volume of original lattice:</b> ", $Crystal->Volume(), " A<sup>3</sup>$LF";
		print "<b>Density of original lattice:</b> ", $Crystal->Density(), 
					" g/cm<sup>3</sup>$LF";
		print "$LF";

		my $NewCrystal = $Crystal->ConvertLattice($T, 0, $CheckConsistency);
		my ($a2,$b2,$c2,$alpha2,$beta2,$gamma2) = $NewCrystal->LatticeParameters();

		my ($g11, $g12, $g13, $g21, $g22, $g23, $g31, $g32, $g33) = $Crystal->Metrics();
		print "<b>Real space metrics conversion:</b>$LF";
		print "<pre>\n";
		printf "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|%10.4f %10.4f %10.4f|\n", $g11, $g12, $g13;
		printf "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|%10.4f %10.4f %10.4f|\n", $g21, $g22, $g23;
		printf "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|%10.4f %10.4f %10.4f|\n", $g31, $g32, $g33;
		print "</pre>\n";
		print "=>$LF";

		($g11, $g12, $g13, $g21, $g22, $g23, $g31, $g32, $g33) = $NewCrystal->Metrics();
		print "<pre>\n";
		printf "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|%10.4f %10.4f %10.4f|\n", $g11, $g12, $g13;
		printf "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|%10.4f %10.4f %10.4f|\n", $g21, $g22, $g23;
		printf "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|%10.4f %10.4f %10.4f|\n", $g31, $g32, $g33;
		print "</pre>\n";

		my $OutputFile = $InputFile;
		$OutputFile =~ s/\.cif/-converted\.cif/i;

		print "<b>Converted Lattice parameters:</b>$LF";
		print "a'=$a2 b'=$b2 c'=$c2  alpha'=$alpha2 beta'=$beta2 gamma'=$gamma2$LF";
		print "<b>Volume of converted lattice:</b> ", $NewCrystal->Volume(), " A<sup>3</sup>$LF";
		print "<b>Density of converted lattice:</b> ", $NewCrystal->Density(), 
					" g/cm<sup>3</sup>$LF";

		my $NewCIF = new CIF();
		$NewCIF->SetFileName($OutputFile);
		$NewCIF->SetCrystalName($Crystal->CrystalName());
		$NewCIF->SetLatticeParameters($a2, $b2, $c2, $alpha2, $beta2, $gamma2);
		$NewCIF->SetSpaceGroup("P 1", 1);
		$NewCIF->SetVolume($NewCrystal->Volume());
		$NewCIF->AddSymmetryOperation("x,y,z");
		my @ExpandedAtomSiteList = $NewCrystal->GetCExpandedAtomSiteList();
		my $nTotalExpandedAtomSite = $NewCrystal->nTotalExpandedAtomSite();
		for(my $i = 0 ; $i < $nTotalExpandedAtomSite ; $i++) {
			my $atom      = $ExpandedAtomSiteList[$i];
			my $label     = $atom->Label();
			my $atomname  = $atom->AtomNameOnly();
			my $charge    = $atom->Charge();
			my ($x,$y,$z) = $atom->Position();
			my $occ       = $atom->Occupancy();

			$NewCIF->AddAsymmetricAtomSite($label, $atomname, $x, $y, $z,$occ);
		}
		$NewCIF->FillCIFData();

		unless($NewCIF->WriteSimpleCIFFile($OutputFile)) {
			print "<H2>Error: Could not write to ($OutputFile).</H2>\n";
			return -1;
		}
		&ShowFileLink($WebRootDir, $OutputFile,   "Converted CIF File");

		if(abs($Crystal->Density() - $NewCrystal->Density()) / $Crystal->Density()
				> 0.05) {
			print "<H1>Causion!!.</H1>\n";
			print "<H2>Densities of the original and converted cells are "
				."different.</H2>\n";
			print "<H2>The conversion rule employed would not be compatible with "
				."the original cell.</H2>\n";
		}

		if($PresetRule eq 'HexOrtho' or 
		   $PresetRule eq 'FCCPrim' or
		   $PresetRule eq 'BCCPrim') {

			print "<H2>Find symmetry for the converted lattice</H2>";

			my ($drive, $dir, $filename, $ext, $lastdir, $filebody)
				= Deps::SplitFilePath($InputFile);
			my $SampleName = $filebody;
#my $OutputFile = $InputFile;
#   $OutputFile =~ s/\.cif/-converted\.cif/i;
			my $StructPath = $InputFile;
			   $StructPath =~ s/\.cif/\.struct/i;
			my $SymStructPath = $InputFile;
			   $SymStructPath =~ s/\.cif/\-Symmetrized.struct/i;
			my $SymCIFPath = $InputFile;
			   $SymCIFPath =~ s/\.cif/\-Symmetrized.cif/i;

			my ($a0,$b0,$c0,$alpha0,$beta0,$gamma0) = $NewCrystal->LatticeParameters();
			if($PresetRule eq 'HexOrtho') {
				$NewCrystal->SetLatticeParameters($a0, $a0*1.3, $c0,$alpha0,$beta0,$gamma0);
			}
			elsif($PresetRule eq 'FCCPrim' or $PresetRule eq 'BCCPrim') {
				$NewCrystal->SetLatticeParameters($a0,$b0, $c0, 65,65,65);
			}

			print "<H3>MakeStruct: Save to $StructPath</H3>";
			my $WIEN = new WIEN2k;
			$WIEN->SetSampleName($SampleName);
			$WIEN->SaveStructFile($NewCrystal, $StructPath, 0, 0, 0, 0);
			&ShowFileLink($WebRootDir, $StructPath,   "Struct File");

			print "<H3>Execute sgroup: Save to $SymStructPath</H3>";
			print("$SGROUPPath -wi $StructPath$LF");
			open(PIPEIN, "$SGROUPPath -wi $StructPath |");
			open(OUT, ">$StructPath.out");
			while(<PIPEIN>) {
				print OUT $_;
			}
			close(OUT);
			close(PIPEIN);

			print("$SGROUPPath -wi -wo $StructPath $SymStructPath$LF");
			system("$SGROUPPath -wi -wo $StructPath $SymStructPath");
			&ShowFileLink($WebRootDir, "$StructPath.out",   "sgroup output");
			&ShowFileLink($WebRootDir, $SymStructPath,   "Symmetrized Struct File");

			my $WIEN2k2 = new WIEN2k;
			my $SymCrystal = $WIEN2k2->ReadStructFile($SymStructPath, 0);
			unless($SymCrystal) {
				print("Error: Can not read [$SymStructPath].$LF");
				return 0;
			}

			my $SPG = $SymCrystal->GetCSpaceGroup();
			my $SPGName = $SPG->SPGName();
			if($SPGName =~ /^R/i or $SPGName =~ /^P\s*\-?3/i) {
				$SPG->SetSPGName("$SPGName R");
				my ($a,$b,$c,$alpha,$beta,$gamma) = $SymCrystal->LatticeParameters();
				print("  Hexagonal axis: a=$a   c=$c$LF");
				my $ar = sqrt(3.0*$a*$a + $c*$c) / 3.0;
				my $alphah = 1.5 / sqrt(3.0 + ($c/$a)*($c/$a));
				$alphah = 2.0 * Sci::asin($alphah) * Sci::todeg();
				$alphah = $alpha0 if(abs($alphah -65.0) < 1.0e-3);
				print("  Rhombohedral axis: a=$ar   alpha=$alphah$LF");
				$SymCrystal->SetLatticeParameters($ar,$ar,$ar,$alphah,$alphah,$alphah);
			}
			my $CIF2 = new CIF;
			if(!$CIF2->CreateCIFFileFromCCrystal($SymCrystal, $SymCIFPath, 0, 'unix')) {
				print("Error: Can not create [$SymCIFPath].$LF");
				return 0;
			}
			&ShowFileLink($WebRootDir, $SymCIFPath,   "Symmetrized CIF File");

#ここでは使わないが、念のため、後始末でもとにもどす
			$NewCrystal->SetLatticeParameters($a0,$b0,$c0,$alpha0,$beta0,$gamma0);
		}
	}

	return 1;
}

sub ShowLatticeConversion
{
	my ($Action) = @_;

	my $PrevAction = &GetArg("PreviousAction");

	print <<EOT1;
<hr>
<h1>結晶格子の変換</h1>
<form action="/cgi-bin/Research.pl" onSubmit="" ENCTYPE="multipart/form-data" method="POST">
  <input type="hidden" name="Action" value="LatticeConversion">
  <input type="hidden" name="PreviousAction" value="$PrevAction">

  <input type="submit" value="submit" name="B1">

  <p><input type="checkbox" name="CheckConsistency" value="ON" checked>Check consistency</p>
  <H2>Conversion rule:</H2>
  Preset rule: 
  <select size="1" name="PresetRule">
    <option value="HexRhomb" selected>Hexagonal to Rhombohedral</option>
    <option value="RhombHex"         >Rhombohedral to Hexagonal</option>
    <option value="HexOrtho"         >Hexagonal to Orthorhombic</option>
    <option value="FCCPrim"          >FCC to Primitive cell</option>
    <option value="BCCPrim"          >BCC to Primitive cell</option>
    <option value="ACenterPrim"      >A center to Primitive cell</option>
    <option value="BCenterPrim"      >B center to Primitive cell</option>
    <option value="CCenterPrim"      >C center to Primitive cell</option>
    <option value="Specified"        >Specified</option>
    </select>
  <p>

  Parameters: 
  <select size="1" name="Parameters">
    <option value="ai" selected>Lattice vectors <b>a<sub>i</sub></b></option>
    <option value="xyz"        >hkl</option>
    <option value="a*i"        >Reciprocal lattice vectors <b>a<sup>*</sup><sub>i</sub></b></option>
    <option value="hkl"        >hkl</option>
    </select>
  <p>
  Direction: 
  <select size="1" name="Direction">
    <option value="OriginalToConverted" selected>(Converted) = (t<sub>ij</sub>)(Original)</option>
    <option value="ConvertedlToOriginal"        >(Original) = (t<sub>ij</sub>)(Converted)</option>
    </select>
  <p>

  <p>
  (t<sub>ij</sub>) = <br>
  &nbsp;<input type="text" name="t11" size="7" value="1"> 
  &nbsp;<input type="text" name="t12" size="7" value="0"> 
  &nbsp;<input type="text" name="t13" size="7" value="0"><br>
  &nbsp;<input type="text" name="t21" size="7" value="0"> 
  &nbsp;<input type="text" name="t22" size="7" value="1""> 
  &nbsp;<input type="text" name="t23" size="7" value="0"><br>
  &nbsp;<input type="text" name="t31" size="7" value="0"> 
  &nbsp;<input type="text" name="t32" size="7" value="0"> 
  &nbsp;<input type="text" name="t33" size="7" value="1""></p>
  <p>
  <hr>
  <H2>Parameters of the original lattice</H2>
  (x,y,z) = (<input type="text" name="sx" size="7" value="">, 
             <input type="text" name="sy" size="7" value="0">, 
             <input type="text" name="sz" size="7" value="0">)</p>
  <p>
  (h k l) = (<input type="text" name="sh" size="7" value=""> 
             <input type="text" name="sk" size="7" value="0"> 
             <input type="text" name="sl" size="7" value="0">)</p>
  <p>
  a = <input type="text" name="a" size="7" value="">, 
  b = <input type="text" name="b" size="7" value="4.0">, 
  c = <input type="text" name="c" size="7" value="4.0">
  <br>
  alpha = <input type="text" name="alpha" size="7" value="90.0">, 
  beta  = <input type="text" name="beta"  size="7" value="90.0">, 
  gamma = <input type="text" name="gamma" size="7" value="90.0"> <p>

  CIF file: <input type="file" name="UploadCIFFilePath" size="60"> <br>

</form>
EOT1
}

sub ConvertStructureFile
{
	print "<H1>ConvertStructureFile</H1>\n";

	my @InputFileFormat = &GetArg("InputFileFormat");
	my $InputFileFormat = $InputFileFormat[0];
#    <option value="Auto" selected>Auto select</option>
#    <option value="CIF">CIF File</option>
#    <option value="GULP_OPTI_OUTPUT">GULP opti Output</option>

	my @TargetFileFormat = &GetArg("TargetFileFormat");
	my $TargetFileFormat = $TargetFileFormat[0];
#    <option value="SimpleCIF" selected>Simple CIF File</option>

	my $ExpandCoordinate = &GetArg("ExpandCoordinate");
	my $ExppandLatticeA  = &GetArg("ExpandLatticeA");
	my $ExppandLatticeB  = &GetArg("ExpandLatticeB");
	my $ExppandLatticeC  = &GetArg("ExpandLatticeC");
	my $ChooseRandomly   = &GetArg("ChooseRandomly");

	print "ExpandCoordinate: $ExpandCoordinate$LF";
	print "Expand lattice to ($ExppandLatticeA, $ExppandLatticeB, $ExppandLatticeC)$LF";
	print "ChooseRandomly: $ChooseRandomly$LF";

	my $ret = &UploadFile('UploadCIFFilePath', $WorkingDir);
	if($ret < 0) {
		print "<H2>Error in UploadFile: Upload failed due to Code $ret.</H2>\n";
		return;
	}
	my $InputFile = $ret;
	print "File was saved to ($InputFile) in the server.$LF";
	print "<b>Link:</b> ";
	&ShowFileLink($WebRootDir, $InputFile, "Input File");

	print "<b>InputFileFormat:</b> $InputFileFormat$LF";
	my $InputFileFormat = GeneralFileFormat::GuessFileFormat($InputFile)
		if($InputFileFormat =~ /Auto/i);
	print "<b>Input File Format:</b> $InputFileFormat$LF";
	print "<b>TargetFileFormat:</b> $TargetFileFormat$LF";

#ファイル名を（ベース名, ディレクトリ名, 拡張子）に分解
	my @filenames = fileparse($InputFile, "\.[^\.]+");
	my $fname = $filenames[0] . "-simple.cif";
	if($TargetFileFormat eq 'XSF') {
		$fname = $filenames[0] . ".xsf";
		$fname = $filenames[0] . ".axsf"
			if($InputFileFormat =~ /GULP MD History/i);
	}
	elsif($TargetFileFormat eq 'CSV') {
		$fname = $filenames[0] . ".csv";
	}
	my $OutputFile = Deps::MakePath($CrystalCommonFileDir, $fname, 0);
	$fname = $filenames[0] . "-initial.cif";
	if($TargetFileFormat eq 'XSF') {
		$fname = $filenames[0] . "-initial.xsf";
	}
	my $InitialFile = Deps::MakePath($CrystalCommonFileDir, $fname, 0);
	$fname = $filenames[0] . "-optimized.cif";
	if($TargetFileFormat eq 'XSF') {
		$fname = $filenames[0] . "-optimized.xsf";
	}
	my $OptimizedFile = Deps::MakePath($CrystalCommonFileDir, $fname, 0);
	$fname = $filenames[0] . "-MD-\%04d.cif";
	if($TargetFileFormat eq 'XSF') {
		$fname = $filenames[0] . "-MD-\%04d.xsf";
	}
	my $MDFileTemplate = Deps::MakePath($CrystalCommonFileDir, $fname, 0);

	if(unlink($OutputFile)) {
		print "($OutputFile) was deleted.$LF";
	}
	if(unlink($InitialFile)) {
		print "($InitialFile) was deleted.$LF";
	}
	if(unlink($OptimizedFile)) {
		print "($OptimizedFile) was deleted.$LF";
	}
	my $i;
	for($i = 0 ; $i < 10000 ; $i++) {
		my $fname = sprintf($MDFileTemplate, $i+1);
		last unless(unlink($fname));
	}
	my $fname1 = sprintf($MDFileTemplate, 1);
	my $fname2 = sprintf($MDFileTemplate, $i);
	print "($fname1)-($fname2) were deleted.$LF" if($i > 0);

	print "<hr>\n";
	print "<b>Link to results:</b>$LF";
	if($InputFileFormat =~ /CIF/i) {
		my $CIF = new CIF();
		unless($CIF->Read($InputFile)) {
			print "<H2>Error: Can not read $InputFile.</H2>\n";
			return -2;
		}
		if($TargetFileFormat eq 'SimpleCIF') {
			unless($CIF->WriteSimpleCIFFile($OutputFile)) {
				print "<H2>Error: Could not write to ($OutputFile).</H2>\n";
				return -1;
			}
			&ShowFileLink($WebRootDir, $OutputFile,   "Simple CIF File");
			return 1;
		}
		elsif($TargetFileFormat eq 'XSF') {
			my $XCrySDen = new XCrySDen();
			unless($XCrySDen->WriteXSFFileFromCIF($OutputFile, $CIF)) {
				print "<H2>Error: Could not write to ($OutputFile).</H2>\n";
				return -1;
			}
			&ShowFileLink($WebRootDir, $OutputFile,   "XCrySDen XSF File");
			return 1;
		}
	}
	elsif($InputFileFormat =~ /GULP Output opti/i) {
		my $GULP = new GULP;
		my $InitialCrystalCIF
			= $GULP->ExtractCrystalStructuresFromOptimiseOutput($InputFile, 1);
		if($InitialCrystalCIF <= 0) {
			print "<h2>Error in GULP.pm::"
				."ExtractCrystalStructuresFromOptimiseOutput1</h2>\n";
			return -1;
		}
		my $OptimizedCrystalCIF
			= $GULP->ExtractCrystalStructuresFromOptimiseOutput($InputFile, 2);
		if($OptimizedCrystalCIF <= 0) {
			print "<h2>Error in GULP.pm::"
				."ExtractCrystalStructuresFromOptimiseOutput2</h2>\n";
			return -2;
		}
		if($TargetFileFormat eq 'SimpleCIF') {
			unless($InitialCrystalCIF->WriteSimpleCIFFile($InitialFile)) {
				print "<H2>Error: Could not write to ($InitialFile).</H2>\n";
				return -1;
			}
			unless($OptimizedCrystalCIF->WriteSimpleCIFFile($OptimizedFile)) {
				print "<H2>Error: Could not write to ($OptimizedFile).</H2>\n";
				return -1;
			}
			&ShowFileLink($WebRootDir, $InitialFile,   "Initial Structure CIF");
			&ShowFileLink($WebRootDir, $OptimizedFile, "Optimized Structure CIF");
		}
		elsif($TargetFileFormat eq 'XSF') {
			my $XCrySDen = new XCrySDen();
			unless($XCrySDen->WriteXSFFileFromCIF($InitialFile,
					$InitialCrystalCIF, $OptimizedCrystalCIF)) {
				print "<H2>Error: Could not write to ($InitialFile).</H2>\n";
				return -1;
			}
			unless($XCrySDen->WriteXSFFileFromCIF($OptimizedFile, 
					$OptimizedCrystalCIF, $InitialCrystalCIF)) {
				print "<H2>Error: Could not write to ($OptimizedFile).</H2>\n";
				return -1;
			}
			&ShowFileLink($WebRootDir, $InitialFile,   "Initial Structure XSF");
			&ShowFileLink($WebRootDir, $OptimizedFile, "Optimized Structure XSF");
			return 1;
		}

		return 1;
	}
	elsif($InputFileFormat =~ /GULP Output md/i) {
		my $GULP = new GULP;
		if($TargetFileFormat eq 'CSV') {
			$GULP->SaveMDPropertyHistoryToCSV($InputFile, $OutputFile);
			&ShowFileLink($WebRootDir, $OutputFile, "MD Property History CSV");
			return 1;
		}
	}
	elsif($InputFileFormat =~ /GULP MD History/i) {
		my $GULP = new GULP;
		my $nStep = $GULP->GetMDStepFromMDHistory($InputFile);
		my $nAtom = $GULP->GetnAtomFromMDHistory($InputFile);
#print "nStep: $nStep, $nAtom<br>\n";
		if($TargetFileFormat eq 'SimpleCIF') {
			my $IN;
			unless(open($IN, "<$InputFile")) {
				print "<H2>Error: Could not read ($InputFile).</H2>\n";
				return -1;
			}
			for(my $i = 1 ; $i <= $nStep ; $i++) {
				my $OutputPath = sprintf($MDFileTemplate, $i);

				my ($CrystalCIF, $TotalTime)
					= $GULP->GetNextCrystalStructureFromMDHistory($IN, $nAtom);
#				my ($CrystalCIF, $TotalTime)
#					= $GULP->ExtractCrystalStructureFromMDHistory($InputFile, $i);
				if($CrystalCIF <= 0) {
					print "<h2>Error in GULP.pm::"
						."ExtractCrystalStructureFromMDHistory</h2>\n";
					return -1;
				}
				last if($CrystalCIF == 1);

				unless($CrystalCIF->WriteSimpleCIFFile($OutputPath)) {
					print "<H2>Error: Could not write to ($OutputPath).</H2>\n";
					return -1;
				}
				&ShowFileLink($WebRootDir, $OutputPath, "MD step #$i (t=$TotalTime ps) CIF");
			}
			close($IN);
			return 1;
		}
		elsif($TargetFileFormat eq 'XSF') {
			my $XCrySDen = new XCrySDen();
			my ($CrystalCIF, $TotalTime)
				= $GULP->ExtractCrystalStructureFromMDHistory($InputFile, 1);
			unless($XCrySDen->WriteXSFAnimationFileHeaderFromCIF($OutputFile, $nStep, $CrystalCIF) <= 0) {
				print "<H2>Error: Could not write to ($OutputFile).</H2>\n";
				return -1;
			}

			my $IN;
			unless(open($IN, "<$InputFile")) {
				print "<H2>Error: Could not read ($InputFile).</H2>\n";
				return -1;
			}
#print "a<br>\n";
			for(my $i = 1 ; $i <= $nStep ; $i++) {
#last if($i > 3);
#print "a1<br>\n";
				my ($CrystalCIF, $TotalTime)
					= $GULP->GetNextCrystalStructureFromMDHistory($IN, $nAtom);
#print "a2<br>\n";
#				my ($CrystalCIF, $TotalTime)
#					= $GULP->ExtractCrystalStructureFromMDHistory($InputFile, $i);
				if($CrystalCIF <= 0) {
					print "<h2>Error in GULP.pm::"
						."ExtractCrystalStructureFromMDHistory</h2>\n";
					return -1;
				}
				last if($CrystalCIF == 1);
				unless($XCrySDen->AddXSFAnimationFileStepFromCIF($OutputFile, $i, $CrystalCIF)) {
					print "<H2>Error: Could not write to ($InitialFile).</H2>\n";
					return -1;
				}
				print "Step $i ";
				print $LF if($i % 5 == 0);
			}
			close($IN);
			print "$LF";
			&ShowFileLink($WebRootDir, $OutputFile, "MD XSF Animation");
			return 1;
		}
		elsif($TargetFileFormat eq 'CSV') {
			$GULP->SaveMDLatticeHistoryToCSV($InputFile, $OutputFile);
			&ShowFileLink($WebRootDir, $OutputFile, "MD Lattice History CSV");
			return 1;
		}
	}

	print "<H2>Error: Input or Output File Format is not supported.</H2>\n";
	return -3;
}

sub ShowConvertStructureFile
{
	my ($Action) = @_;

	my $PrevAction = &GetArg("PreviousAction");

	print <<EOT1;
<hr>
<h1>結晶構\造ファイルの相互変換</h1>
<form action="/cgi-bin/Research.pl" onSubmit="" ENCTYPE="multipart/form-data" method="POST">
  <input type="hidden" name="Action" value="ConvertStructureFile">
  <input type="hidden" name="PreviousAction" value="$PrevAction">

  <input type="submit" value="送信" name="submit"><br>
  Input file to be uploaded: <input type="file" name="UploadCIFFilePath" size="60"> <br>

  Input File Format: 
  <select size="1" name="InputFileFormat">
    <option value="Auto" selected>Auto select</option>
    <option value="CIF">CIF File</option>
    <option value="GULP Output opti">GULP opti Output</option>
    <option value="GULP MD History" >GULP md History</option>

    </select>
  <br>

  Target File Format: 
  <select size="1" name="TargetFileFormat">
    <option value="SimpleCIF" selected>Simple CIF File</option>
    <option value="XSF">XCrySDen XSF File</option>
    <option value="CSV">Data File (CSV)</option>
    </select>
  <br>
  &nbsp;&nbsp;&nbsp; <input type="checkbox" name="ExpandCoordinate" value="ON">
  Expand all atoms to P1<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Expand Lattice: &nbsp; 
  a:<input type="text" name="ExpandLatticeA" value="1" size="5"> 
  b:<input type="text" name="ExpandLatticeB" value="1" size="5"> 
  c:<input type="text" name="ExpandLatticeC" value="1" size="5"><br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  <input type="checkbox" name="ChooseRandomly" value="ON">
  Randomly choose partial occupancy atoms<br>
</form>
EOT1
}

sub CalculateDiffractionAngles
{
	my ($Action) = @_;

	my $Rietan = new Rietan();
	my $SPGList = $Rietan->GetSpaceGroupList();
	if($SPGList == 0) {
		my $s = $Rietan->SPGDBPath();
		print "Error: Can not read [$s]$LF$LF";
		return 0;
	}

	my $a = &GetArg('a');
	my $b = &GetArg('b');
	my $c = &GetArg('c');
	my $alpha = &GetArg('alpha');
	my $beta  = &GetArg('beta');
	my $gamma = &GetArg('gamma');

	my @SpaceGroup = $form->param('SpaceGroup');
	my $SpaceGroup = $SpaceGroup[0];
	my ($iSPG,$iSet,$SPGName,$snSPGDB)
		= ($SpaceGroup =~ /\s*(\d+)-(\d+)\s*\((.*?)\)_(.*?)/);

	my $Rietan = new Rietan();
	my $SPG = $Rietan->ReadSpaceGroup($iSPG,$iSet);
	if($SPG == 0) {
		print "Can not get Space Group: $iSPG ($iSet) $SPGName$LF$LF";
		return 0;
	}
	my $Crystal = new Crystal();
	$Crystal->SetLatticeParameters($a, $b, $c, $alpha, $beta, $gamma);
	$Crystal->SetCSpaceGroup($SPG);
	my $LatticeSystem = $Crystal->LatticeSystem();

	my $Start2Q = &GetArg('Start2Q');
	my $End2Q   = &GetArg('End2Q');
	my $Wavelength = &GetArg('Wavelength');

	print "<h1>Calculate Lattice Parameters from Diffraction Angles</h1>\n";
	print "<b>Lattice Parameters:</b> $a $b $c  $alpha $beta $gamma$LF";
	print "<b>Space Group:</b> $SPGName($iSPG-$iSet)$LF";
	print "<b>Lattice System:</b> $LatticeSystem$LF";
	print "<b>Wavelength:</b> $Wavelength A$LF";
	print "<b>2Q Range:</b> $Start2Q - $End2Q <sup>o</sup>$LF";
	
	my $dmin = $Wavelength * 0.5 / Sci::dsin($End2Q*0.5);
	my $dmax = $Wavelength * 0.5 / Sci::dsin($Start2Q*0.5);
	printf "<b>d range:</b> %9.5f - %9.5f A$LF", $dmin, $dmax;
	my $hmax = int($a / $dmin + 2);
	my $kmax = int($b / $dmin + 2);
	my $lmax = int($c / $dmin + 2);
	print "<b>(h,k,l) range to be examined:</b> ($hmax,$kmax,$lmax)$LF";
	print "$LF";
	
	my $Volume = $Crystal->Volume();
	printf "<b>Volume:</b> %12.4f A<sup>3</sup>$LF", $Volume;
	print "$LF";

	print "<b>Metrics:</b>$LF";
	my ($g11, $g12, $g13, $g21, $g22, $g23,
		$g31, $g32, $g33) = $Crystal->Metrics();
	my ($Rg11, $Rg12, $Rg13, $Rg21, $Rg22, $Rg23,
		$Rg31, $Rg32, $Rg33) = $Crystal->RMetrics();
	printf "<pre>\n";
	printf "   (g) = |%12.4f %12.4f %12.4f|\n", $g11,  $g12,  $g13;
	printf "         |%12.4f %12.4f %12.4f|\n", $g21,  $g22,  $g23;
	printf "         |%12.4f %12.4f %12.4f|\n", $g31,  $g32,  $g33;
	printf "  (Rg) = |%12.4G %12.4g %12.4g|\n", $Rg11, $Rg12, $Rg13;
	printf "         |%12.4g %12.4g %12.4g|\n", $Rg21, $Rg22, $Rg23;
	printf "         |%12.4g %12.4g %12.4g|\n", $Rg31, $Rg32, $Rg33;
	printf "</pre>\n";
	print "$LF";

	print "<b>Diffraction condition:</b>$LF";
	for(my $i = 0 ; $i < 14 ; $i++) {
		my $type = SpaceGroup::ICONDTypeStrByRietanIndex($i);
		my $str  = SpaceGroup::ICONDCondStrByRietanIndex($i);
		my $cond = $SPG->RietanDiffractinCondition($i);
		printf "      $type: $str$LF" if($cond != 0);
	}

	my $lmin = 0;
	my $kmin = -$kmax;
	my $hmin = -$hmax;
	if($LatticeSystem eq 'cubic' or $LatticeSystem eq 'trigonal' or 
	   $LatticeSystem eq 'tetragonal' or $LatticeSystem eq 'orthorhombic') {
		$hmin = 0;
		$kmin = 0;
	}
	elsif($LatticeSystem eq 'hexagonal') {
		$kmin = 0;
	}
	elsif($LatticeSystem eq 'monoclinic' and $alpha != 90.0) {
		$hmin = 0;
	}
	elsif($LatticeSystem eq 'monoclinic' and $beta != 90.0) {
		$kmin = 0;
	}
	my @PeakList;
	print "<pre>\n";
	if($LatticeSystem eq 'hexagonal') {
		print "         (i=-h-k)\n";
		print "  h   k   i   l      dhkl       2Theta\n";
	}
	else {
		print "  h   k   l      dhkl       2Theta\n";
	}
	for(my $h = $hmin ; $h <= $hmax ; $h++) {
#print "h=$h<br>";
		if($LatticeSystem eq 'cubic' or $LatticeSystem eq 'trigonal') {
			$kmin = $h;
		}
		elsif($LatticeSystem eq 'tetragonal' or $LatticeSystem eq 'hexagonal') {
			$kmin = $h;
			$kmin = 0 if($kmin < 0);
		}
#print "min:($hmin,$kmin,$lmin)<br>";
		for(my $k = $kmin ; $k <= $kmax ; $k++) {
			if($LatticeSystem eq 'cubic' or $LatticeSystem eq 'trigonal') {
				$lmin = $k;
			}
			for(my $l = $lmin ; $l <= $lmax ; $l++) {
#print "d:($h,$k,$l)<br>";
				my $d = $Crystal->CalculateHKLInterplanarSpacing($h, $k, $l);
#print "d:$d ($h,$k,$l)<br>";
				next if($d < $dmin or $d > $dmax);
				my $Q = $Crystal->CalculateDiffractionAngleFromInterplanarSpacing($Wavelength, $d);
#print "Q:$Q<br>";
				my $peak = new DiffractionPeak;
#print "a<br>";
				$peak->SetPeak($h, $k, $l, $d, $Q);
#print "b<br>";
				push(@PeakList, $peak);
#print "c<br>";
#				printf "%3d %3d %3d   %10.6f  %9.5f\n", $h, $k, $l, $d, $Q;
	
			}
		}
	}
#print "nPeakList: ", scalar @PeakList, "$LF";
	@PeakList = sort SortPeakListFunc @PeakList;
	for(my $i = 0 ; $i < @PeakList ; $i++) {
		my $peak = $PeakList[$i];
		my ($h, $k, $l, $d, $Q) = $peak->Peak();;
		if($LatticeSystem eq 'hexagonal') {
			printf "%3d %3d %3d %3d   %10.6f  %9.5f\n", $h, $k, -$h-$k, $l, $d, 2.0*$Q;
		}
		else {
			printf "%3d %3d %3d   %10.6f  %9.5f\n", $h, $k, $l, $d, 2.0*$Q;
		}
	}
	print "</pre>\n";
}

sub SortPeakListFunc
{
#print "a<br>";
#	my ($a, $b) = @_;
#print "a: $a $b<br>";
	return $a->{'Q'} <=> $b->{'Q'};
}

sub ShowCalculateDiffractionAngles
{
	my ($Action) = @_;

	my $PrevAction = &GetArg('PreviousAction');
	$PrevAction = 'ShowCalculateDiffractionAngles' if($PrevAction eq '');
	my $Rietan = new Rietan();
	my $SPGList = $Rietan->GetSpaceGroupList();
	if($SPGList == 0) {
		my $s = $Rietan->SPGDBPath();
		print "Error: Can not read [$s]$LF$LF";
		return 0;
	}

	print <<EOT1;
<hr>
<h1>Calculate Diffraction Angles from Lattice Parameters</h1>
<form action="/cgi-bin/Research.pl" onSubmit="" ENCTYPE="multipart/form-data" method="POST">
  <input type="hidden" name="Action" value="CalculateDiffractionAngles">

  <input type="submit" value="submit" name="B1"><br>

  <b>Lattice parameters:</b><br>
  &nbsp;&nbsp;&nbsp;
  a=<input type="text" name="a" value="5.0" size="10"> 
  b=<input type="text" name="b" value="5.0" size="10"> 
  c=<input type="text" name="c" value="5.0" size="10"> A<br> 
  alpha=<input type="text" name="alpha" value="90.0" size="10"> 
  beta =<input type="text" name="beta"  value="90.0" size="10"> 
  gamma=<input type="text" name="gamma" value="90.0" size="10"><br>

  <p>
  <b>Space Group: (used just for extinction rule)</b> 
  <select size="1" name="SpaceGroup">
EOT1

	for(my $i = 0 ; $i < @$SPGList ; $i++) {
		my $line = $SPGList->[$i];
		$line =~ s/\s*\[(.*?)\]//;
		my $sn = $1;
		print "  <option value=\"${line}_$sn\">$line</option>\n";
	}

	print <<EOT2;
  </select><p>

  <b>Calculation range in 2Theta:</b><br>
  <input type="text" name="Start2Q" value="5.0" size="10"> - 
  <input type="text" name="End2Q" value="120.0" size="10"> <sup>o</sup><br>
  <b>X-ray wavelength:</b> 
  <input type="text" name="Wavelength" value="1.540562" cols="50"> A<br>
      Cu Ka : 1.541838 A<br>
      Cu Ka1: 1.540562 A<br>
      Cu Ka2: 1.544390 A<br>
      Mo Ka : 0.710730 A<br>
      Mo Ka1: 0.709300 A<br>
      Mo Ka2: 0.713590 A<br>
      Fe Ka : 1.937355 A<br>
      Fe Ka1: 1.936042 A<br>
      Fe Ka2: 1.93998 A<br>
      <p>

</form>
EOT2

}

sub CalculateLatticeParameters
{
	my ($Action) = @_;

	my $FileName = &GetArg("FileName");
	$FileName = &ConvertToValidFileName($FileName);
	my $InputFile  = "$FileName.Kin.txt";
	my $InputPath  = Deps::MakePath($WorkingDir, $InputFile, 0);
	my $OutputFile = "$FileName.Kout.txt";
	my $OutputPath = Deps::MakePath($WorkingDir, $OutputFile, 0);

	my $LatticeSystem = &GetArg("LatticeSystem");
	my $ErrorCorrection2 = 0;
	my $ErrorCorrection3 = 0;
	my $ErrorCorrection4 = 0;
	$ErrorCorrection2 = 1 if(&GetArg("ErrorCorrection2") ne '');
	$ErrorCorrection3 = 1 if(&GetArg("ErrorCorrection3") ne '');
	$ErrorCorrection4 = 1 if(&GetArg("ErrorCorrection4") ne '');
	my $WeightFunction = &GetArg("WeightFunction");
	$WeightFunction = 2;
	my $Wevelength = &GetArg("Wavelength");
	my $DiffractionLiens = &GetArg("Diffractions");

	my $Rietan = new Rietan();
	my $SPGList = $Rietan->GetSpaceGroupList();
	if($SPGList == 0) {
		my $s = $Rietan->SPGDBPath();
		print "Error: Can not read [$s]$LF$LF";
		return 0;
	}

	print "<h1>Calculate Lattice Parameters from Diffraction Angles</h1>\n";
	print "<b>Lattice system:</b> $LatticeSystem$LF";
	print "<b>Wevelength:</b> $Wevelength$LF";
	print "<b>Use Error Correction Function 2:</b> $ErrorCorrection2$LF";
	print "<b>Use Error Correction Function 3:</b> $ErrorCorrection3$LF";
	print "<b>Use Error Correction Function 4:</b> $ErrorCorrection4$LF";
	print "<b>Weight Function:</b> $WeightFunction$LF";

	print "Change to working directory ($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;
	}
	if(unlink($InputFile)) {
		print "($InputFile) was deleted.$LF";
	}
	if(unlink($OutputFile)) {
		print "($OutputFile) was deleted.$LF";
	}
	print "K.exe path: $KPath$LF";
	
	print "Input File ($InputFile) is being created...$LF";
	unless(open(IN,">$InputPath")) {
		print "<H2>Error: Can not write to ($InputPath).</H2>\n";
		return 0;
	}
	print IN "$FileName\n";
	printf IN "%d %d %d %d 0 0 %d 4 1\n",
		$LatticeSystem+0,  $ErrorCorrection2,
		$ErrorCorrection3, $ErrorCorrection4,
		$WeightFunction;
	print IN "$Wevelength 0.0\n";
	my @lines = split(/[\r\n]+/, $DiffractionLiens);
	print "<b>Diffractions:</b>$LF";
	for(my $i = 0 ; $i < @lines ; $i++) {
		$lines[$i] =~ s/^\s+//;
		$lines[$i] =~ s/\s+$//;
		next if($lines[$i] eq '');
		my ($h,$k,$l,$ang,$dummy,$w) = ($lines[$i] =~ /(\d+)\s+(\d+)\s+(\d+)\s+(\S+)(s+(\S+))?/);
		next if($h eq '');
		$w = 1.0 if($w eq '');
		if($WeightFunction == 2) {
			printf "%2d %2d %2d  %9.5f$LF", $h, $k, $l, $ang;
			printf IN "%2d %2d %2d  %9.5f\n", $h, $k, $l, $ang;
		}
		else {
			printf "%2d %2d %2d  %9.5f  %9.5f$LF", $h, $k, $l, $ang, $w;
			printf IN "%2d %2d %2d  %9.5f  %9.5f\n", $h, $k, $l, $ang, $w;
		}
	}
	print IN "1000 0 0 0\n";
	print IN "0\n";
	close(IN);

	my $command = "$KPath $InputFile $OutputFile --silent";
print "cwd: ", cwd(), ": <br>\n";
	print "<b>Execute command:</b> $command$LF";
	my $status = system($command);
	print " Error in system() Status: $status: $!$LF" if($status);


	print "<b>Link to results: </b>$LF";
	&ShowFileLink($WebRootDir, $InputPath, "InputFile");
	&ShowFileLink($WebRootDir, $OutputPath, "OutputFile")
			if(-f $OutputPath);
}

sub ShowCalculateLatticeParameters
{
	my ($Action) = @_;

	my $Rietan = new Rietan();
	my $SPGList = $Rietan->GetSpaceGroupList();
	if($SPGList == 0) {
		my $s = $Rietan->SPGDBPath();
		print "Error: Can not read [$s]$LF$LF";
		return 0;
	}
	print <<EOT1;
<hr>
<h1>Calculate Lattice Parameters from Diffraction Angles</h1>
<form action="/cgi-bin/Research.pl" onSubmit="" ENCTYPE="multipart/form-data" method="POST">
  <input type="hidden" name="Action" value="CalculateLatticeParameters">

  <input type="submit" value="submit" name="B1"><br>

  <b>File Name:</b> 
  <input type="text" name="FileName" value="undefined" size="50"><p>

  <p>
  <b>LatticeSystem:</b> 
  <select size="1" name="LatticeSystem">
    <option value=\"1 triclinic\">triclinic</option>\n";
    <option value=\"2 b, monoclinic\">b, monoclinic</option>\n";
    <option value=\"3 c, monoclinic\">c, monoclinic</option>\n";
    <option value=\"4 orthorhombic\">orthorhombic</option>\n";
    <option value=\"5 tetragonal\">tetragonal</option>\n";
    <option value=\"6 cubic\" selected>cubic</option>\n";
    <option value=\"7 trigonal\">trigonal</option>\n";
    <option value=\"8 hexagonal\">hexagonal</option>\n";
  </select><p>

  <b>Error correction function:</b><br> 
  &nbsp;&nbsp;&nbsp; <input type="checkbox" name="ErrorCorrection2" value="ON">(pi/2-Q)tan(pi/2-Q)<br>
  &nbsp;&nbsp;&nbsp; <input type="checkbox" name="ErrorCorrection3" value="ON">{sin(2Q)}<sup>2</sup><br>
  &nbsp;&nbsp;&nbsp; <input type="checkbox" name="ErrorCorrection4" value="ON">{sin(2Q)}<sup>2</sup>(1/sinQ+1/Q)<p>

  <b>Weight function:</b> 
  <select size="1" name="WeightFunction">
    <option value=\"0\">w/{sin(2Q)}<sup>2</sup></option>\n";
    <option value=\"2\" selected>1</option>\n";
  </select><p>

  <b>X-ray wavelength:</b> 
  <input type="text" name="Wavelength" value="1.540562" cols="50"> A<br>
      Cu Ka : 1.541838 A<br>
      Cu Ka1: 1.540562 A<br>
      Cu Ka2: 1.544390 A<br>
      Mo Ka : 0.710730 A<br>
      Mo Ka1: 0.709300 A<br>
      Mo Ka2: 0.713590 A<br>
      Fe Ka : 1.937355 A<br>
      Fe Ka1: 1.936042 A<br>
      Fe Ka2: 1.93998 A<br>
      <p>

  <p><b>Miller Indices and Diffraction angles:</b><br>
  &nbsp; (one diffraction in one line.<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  h k l  2Theta(degree)<br>
  &nbsp;&nbsp;&nbsp; )<br>
  <textarea rows="15" name="Diffractions" cols="70">
1 0 0 21.224
1 1 0 30.179
1 1 1 37.155
2 0 0 43.151
  </textarea></p>

</form>
EOT1
}

sub MakeCIFFile
{
	my ($Action) = @_;

	print "<H1>Make CIF File</H1>\n";

	my $FileName = &GetArg('FileName');
	my $CrystalName = &GetArg('CrystalName');
	my $Source = &GetArg('Source');
	$FileName = $CrystalName if($FileName eq '');
	$CrystalName = $FileName if($CrystalName eq '');
	if($CrystalName eq '') {
		$FileName = $CrystalName = 'Undefined';
	}
	$Source = 'Not specified' if($Source eq '');
	print "File Name   : $FileName$LF";
	print "Crystal Name: $CrystalName$LF";
	print "Source      : $Source$LF";

	my $a = &GetArg('a');
	my $b = &GetArg('b');
	my $c = &GetArg('c');
	my $alpha = &GetArg('alpha');
	my $beta  = &GetArg('beta');
	my $gamma = &GetArg('gamma');
	print "Lattice parameters: $a $b $c  $alpha $beta $gamma$LF";

	my @SpaceGroup = $form->param('SpaceGroup');
	my $SpaceGroup = $SpaceGroup[0];
	my ($iSPG,$iSet,$SPGName,$snSPGDB)
		= ($SpaceGroup =~ /\s*(\d+)-(\d+)\s*\((.*?)\)_(.*?)/);
	print "Space Group: $SPGName ($iSPG-$iSet)$LF";

	my $Rietan = new Rietan();
	my $SPG = $Rietan->ReadSpaceGroup($iSPG,$iSet);
	if($SPG == 0) {
		print "Can not get Space Group: $iSPG ($iSet) $SPGName$LF$LF";
		return 0;
	}

	my $AsymmetricSitesStr = &GetArg('AsymmetricSites');

	my $CIF = new CIF();
	$CIF->SetFileName($FileName);
	$CIF->SetCrystalName($CrystalName);
	$CIF->SetLatticeParameters($a, $b, $c, $alpha, $beta, $gamma);
	$CIF->SetSpaceGroup($SPGName, $iSPG);
	$CIF->SetContent("_journal_name_full", "$Source");

	my $nSymmetryOperation = $SPG->nSymmetryOperation();
	for(my $i = 0 ; $i < $nSymmetryOperation ; $i++) {
		my $symop = $SPG->SymmetryOperation($i+1);
#print "symop: $symop$LF";
		$CIF->AddSymmetryOperation($symop);
	}

	my @lines = split(/[\r\n]/, $AsymmetricSitesStr);
	my $count = 0;
	my %AtomTypeCount;
	for(my $i = 0 ; $i < @lines ; $i++) {
		my $line = $lines[$i];
		$line =~ s/^\s+//;
		$line =~ s/\s+$//;
		next if($line eq '');
		$line =~ s/([\d\.])\s+(\()/$1$2/g;
#print "$i: $line$LF";
		my @strs = split(/[\s,]+/, $line);
		my $atomtype = $strs[0];
		my ($atomname,$charge) = ($atomtype =~ /^(.+)(\d+[\+-])/);
		$AtomTypeCount{$atomname}++;
		my $label = $atomname . $AtomTypeCount{$atomname};
		my $x = $strs[1];
		my $y = $strs[2];
		my $z = $strs[3];
		my $occ = $strs[4];
		$occ = 1.0 if($occ eq '');
#print "Add:  $label: $atomname: ($x,$y,$z) [$occ]$LF";
		$CIF->AddAsymmetricAtomSite($label, $atomtype, $x, $y, $z, $occ);
		$count++;
	}

	my @SiteList = $CIF->GetCAsymmetricAtomSiteList();
	for(my $i = 0 ; $i < @SiteList ; $i++) {
		my $site = $SiteList[$i];
		my $label = $site->Label();
		my $name = $site->AtomName();
		my ($x1,$y1,$z1) = $site->Position();
		my $i1 = $i+1;
#print "Check: $i1: $label: $name: ($x1,$y1,$z1)$LF";
	}
#print "a<br>";

	$CIF->FillCIFData();

#ファイル名を（ベース名, ディレクトリ名, 拡張子）に分解
	my @filenames = fileparse($FileName, "\.[^\.]+");
	my $fname = $filenames[0] . ".cif";
	$fname = "$FileName.cif" if($filenames[0] eq '');
	my $NewFile = Deps::MakePath($CrystalCommonFileDir, $fname, 0);

	unless($CIF->WriteSimpleCIFFile($NewFile, 1)) {
		print "Error: Can not write to $NewFile";
		return 0;
	}

	my $URL = $NewFile;
	my $Reg = Utils::RegExpQuote($WebRootDir);
	$URL =~ s/$Reg//ig;
	print "<b>Simple CIF File: </b>";
	print "<a href=\"$URL\">$fname</a> ";
	print "(<a href=\"/cgi-bin/Research.pl?Action=ShowFile&File=$NewFile\">View on web</a>)$LF";


}

sub ShowMakeCIFFile
{
	my ($Action) = @_;

	my $Rietan = new Rietan();
	my $SPGList = $Rietan->GetSpaceGroupList();
	if($SPGList == 0) {
		my $s = $Rietan->SPGDBPath();
		print "Error: Can not read [$s]$LF$LF";
		return 0;
	}
	print <<EOT1;
<hr>
<h1>CIFファイルを作る</h1>
<form action="/cgi-bin/Research.pl" onSubmit="" ENCTYPE="multipart/form-data" method="POST">
  <input type="hidden" name="Action" value="MakeCIFFile">

  <input type="submit" value="submit" name="B1"><br>

  <table border="1">
    <tr>
      <td><b>File Name</b></td>
      <td><input type="text" name="FileName" value="undefined" size="50"></td>
    </tr>
    <tr>
      <td><b>Crystal name</b></td>
      <td><input type="text" name="CrystalName" value="undefined" size="50"></td>
    </tr>
    <tr>
      <td><b>Source (Paper, ICSD #, Journal etc.)</b></td>
      <td><input type="text" name="Source" value="undefined" size="100"></td>
    </tr>
    <tr>
      <td><b>Lattice parameters</b></td>
      <td>a=<input type="text" name="a" value="5.0" size="20">, 
          b=<input type="text" name="b" value="5.0" size="20">, 
          c=<input type="text" name="c" value="5.0" size="20"> A<br>
          alpha=<input type="text" name="alpha" value="90.0" size="20">, 
          beta =<input type="text" name="beta"  value="90.0" size="20">, 
          gamma=<input type="text" name="gamma" value="90.0" size="20">
      </td>
    </tr>
  </table>

  <p>
  <b>Space Group:</\b> 
  <select size="1" name="SpaceGroup">
EOT1

	for(my $i = 0 ; $i < @$SPGList ; $i++) {
		my $line = $SPGList->[$i];
		$line =~ s/\s*\[(.*?)\]//;
		my $sn = $1;
		print "  <option value=\"${line}_$sn\">$line</option>\n";
	}

	print <<EOT2;
  </select><p>

  <p><b>Asymmetric sites:</b><br>
  &nbsp; (one atomic site in one line.<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  IonName&nbsp; X(error)&nbsp; Y(error)&nbsp; Z(error)&nbsp; Occupancy(error)<br>
  &nbsp;&nbsp;&nbsp; )<br>
  <textarea rows="15" name="AsymmetricSites" cols="70">
Ca2+ 0.0      0.0 0.0      1.0
O2-  0.375(1) 0.5 0.532(2) 0.366(3)
</textarea></p>

</form>
EOT2
}

sub DoExpandCoordinate
{
	my ($Action) = @_;
	
	my @SpaceGroup = $form->param('SpaceGroup');
	my $SpaceGroup = $SpaceGroup[0];
	my ($iSPG,$iSet,$SPGName,$snSPGDB)
		= ($SpaceGroup =~ /\s*(\d+)-(\d+)\s*\((.*?)\)_(.*?)/);
	my $X = eval(&GetArg('X'));
	my $Y = eval(&GetArg('Y'));
	my $Z = eval(&GetArg('Z'));

	my $Rietan = new Rietan();
	my $SPG = $Rietan->ReadSpaceGroup($iSPG,$iSet);
	if($SPG == 0) {
		print "Can not get Space Group: $iSPG ($iSet) $SPGName$LF$LF";
		return 0;
	}

	print "<H1>内部座標の展開</H1>\n";
	print "  iSPG: $iSPG ($iSet)$LF";
	print "  Space Group: $SPGName$LF";
	print "  Coordinate: ($X, $Y, $Z)$LF";

	my $Crystal = new Crystal();
	$Crystal->SetLatticeParameters(10.0, 10.0, 10.0, 90.0, 90.0, 90.0);
	$Crystal->SetCSpaceGroup($SPG);
	my $n = $Crystal->AddAtomType('H');
#	my $atomtype = $Crystal->GetCAtomType(0);
#	print "name: ", $atomtype->AtomName(), "$LF";
	$Crystal->AddAtomSite('H1', 'H', $X, $Y, $Z, 1.0);
#	my $atomsite = $Crystal->GetCAtomSite(0);
#	print "name: ", $atomsite->Label(), "$LF";

	$Crystal->ExpandCoordinates();

	print "<hr>\n";
	print "<H2>Expanded coordinate</H2>\n";
	my @SiteList = $Crystal->GetCExpandedAtomSiteList();
	for(my $i = 0 ; $i < @SiteList ; $i++) {
		my $site = $SiteList[$i];
#		my $label = $site->Label();
		my $name = $site->AtomName();
		my ($x1,$y1,$z1) = $site->Position();
		my $i1 = $i+1;
		print "$i1: ($x1,$y1,$z1)$LF";
	}

	print "<hr>\n";
	print "<H2>Symmetry operation</H2>\n";
	my $nSymmetryOperation = $SPG->nSymmetryOperation();
	print "nSymmetryOperation: $nSymmetryOperation$LF";
	for(my $i = 0 ; $i < $nSymmetryOperation ; $i++) {
		my $symop = $SPG->SymmetryOperation($i);
		print "  $symop$LF";
	}

}

sub ShowExpandCoordinate
{
	my ($Action) = @_;

	my $Rietan = new Rietan();
	my $SPGList = $Rietan->GetSpaceGroupList();
	if($SPGList == 0) {
		my $s = $Rietan->SPGDBPath();
		print "Error: Can not read [$s]$LF$LF";
		return 0;
	}
	print <<EOT1;
<hr>
<h1>空間群を選んで内部座標を展開</h1>
<form action="/cgi-bin/Research.pl" onSubmit="" ENCTYPE="multipart/form-data" method="POST">
  <input type="hidden" name="Action" value="ExpandCoordinate">

  <input type="submit" value="submit" name="B1"><br>
  
  <select size="1" name="SpaceGroup">
EOT1

	for(my $i = 0 ; $i < @$SPGList ; $i++) {
		my $line = $SPGList->[$i];
		$line =~ s/\s*\[(.*?)\]//;
		my $sn = $1;
		print "  <option value=\"${line}_$sn\">$line</option>\n";
	}

	print <<EOT2;
  </select><br>
  Fractional coordinate: (
  <input type="text" name="X" size="13" value="0">, 
  <input type="text" name="Y" size="13" value="0">, 
  <input type="text" name="Z" size="13" value="0">
  )<br>
  &nbsp;&nbsp;&nbsp;&nbsp; (ex. (0.25, 0.17, 0.55)&nbsp;&nbsp;&nbsp; (1/4, 3/8, 0.55)<br>

</form>
EOT2
}

sub CalculateRDF
{
	my ($Action, $ShowCIFInf) = @_;

	my $PrevAction = &GetArg("PreviousAction");
	my $CIFFile = &GetArg("FILE");
	Utils::DelSpace($CIFFile);

	my $MaximumDistance = &GetArg('MaximumDistance');
	$MaximumDistance = 3.5 if($MaximumDistance <= 0.0);
	my $nMesh = &GetArg('nMesh');
	$nMesh = 201 if($nMesh <= 2);

	print "<H1>Calculate RDF</H1>\n";
	print "<H3>CIF File: $CIFFile</H3>\n";
	return &ShowCalculateRDF($Action) if($CIFFile eq '');

	print "<b>Link to CIF: </b> ";
	&ShowFileLink($WebRootDir, $CIFFile, "CIF File");

	print "Maximum distance: $MaximumDistance A$LF";
	print "Number of mesh in distance: $nMesh$LF";
	my $rstep = $MaximumDistance / ($nMesh - 1);
	print "Step in R: $rstep A$LF";

#CIFファイル名を引数に与えて読み込む
	unless($CIF->Read($CIFFile)) {
		print "Error: Can not read $CIFFile.$LF$LF";
		return 0;
	}
#CIFクラスの内容から、Crystalクラスを作成
	$Crystal = $CIF->GetCCrystal();
	$Crystal->ExpandCoordinates();
	my @AtomTypeList = $Crystal->GetCAtomTypeList();
	my $nAtomType = @AtomTypeList;
	my @AtomSiteList = $Crystal->GetCAsymmetricAtomSiteList();
	my $nAsymmetricAtomSite = @AtomSiteList;
	my @ExpandedAtomSiteList = $Crystal->GetCExpandedAtomSiteList();
	my $nTotalExpandedAtomSite = $Crystal->nTotalExpandedAtomSite();
	my @nMultiplicityExpandedAtomSiteList 
		= $Crystal->GetCnMultiplicityExpandedAtomSiteList();

	my ($a,$b,$c,$alpha,$beta,$gamma) = $Crystal->LatticeParameters();
	print "<b>Lattice parameters:</b> $a $b $c  $alpha $beta $gamma$LF";
	my ($g11, $g12, $g13, $g21, $g22, $g23, $g31, $g32, $g33) = $Crystal->Metrics(); 
	print "<pre>\n";
	printf "Metric:  gij = |%12.4f %12.4f %12.4f|\n", $g11, $g12,$g13;
	printf "               |%12.4f %12.4f %12.4f|\n", $g21, $g22,$g23;
	printf "               |%12.4f %12.4f %12.4f|\n", $g31, $g32,$g33;
	print "</pre>\n";
	print "<b>nAtom:</b> $nTotalExpandedAtomSite<br>\n";
	for(my $i = 0 ; $i < $nTotalExpandedAtomSite ; $i++) {
		my $label     = $ExpandedAtomSiteList[$i]->Label();
		my $type      = $ExpandedAtomSiteList[$i]->AtomName();
		my ($x,$y,$z) = $ExpandedAtomSiteList[$i]->Position(1);
		my $occupancy = $ExpandedAtomSiteList[$i]->Occupancy();
		my $i1 = $i+1;
		printf " %3d: %4s: %4s (%8.4f, %8.4f, %8.4f) [%7.4f]$LF",
			$i1, $label, $type, $x, $y, $z, $occupancy;
	}

	my $nLatticeX = int($MaximumDistance / $a) + 1;
	my $nLatticeY = int($MaximumDistance / $a) + 1;
	my $nLatticeZ = int($MaximumDistance / $a) + 1;
	print "<b>Unit cell numbers to be examined:</b> ($nLatticeX, $nLatticeY, $nLatticeZ)$LF";

	print "$LF";
	print "<H2>Calculating RDFs...</H2>\n";
	my @RDF;
	for(my $i = 0 ; $i < $nAtomType ; $i++) {
		my @array1;
		for(my $j = 0 ; $j < $nAtomType ; $j++) {
			$array1[$j] = ();
		}
		$RDF[$i] = \@array1;
	}
	my @nCountedAtoms;

	my $count = 0;
	my @iAtomListArray;
	my @CDistanceArray;
	for(my $ia = 0 ; $ia < $nAsymmetricAtomSite ; $ia++) {
		my $label0       = $AtomSiteList[$ia]->Label();
		my $name0        = $AtomSiteList[$ia]->AtomNameOnly();
		my ($x0,$y0,$z0) = $AtomSiteList[$ia]->Position(1);
		my $occupancy0   = $AtomSiteList[$ia]->Occupancy();
		my $iAtomType0   = $Crystal->FindiAtomType($name0);
		my $ia1 = $ia+1;
print "ia=$ia $name0$LF";
		$nCountedAtoms[$iAtomType0-1]++;

		for(my $iz = -$nLatticeZ ; $iz <= $nLatticeZ ; $iz++) {
		for(my $iy = -$nLatticeY ; $iy <= $nLatticeY ; $iy++) {
		for(my $ix = -$nLatticeX ; $ix <= $nLatticeX ; $ix++) {
			for(my $i = 0 ; $i < $nTotalExpandedAtomSite ; $i++) {
				my $label1       = $ExpandedAtomSiteList[$i]->Label();
				my $name1        = $ExpandedAtomSiteList[$i]->AtomNameOnly();
				my ($x1,$y1,$z1) = $ExpandedAtomSiteList[$i]->Position(1);
				my $Occupancy1   = $ExpandedAtomSiteList[$i]->Occupancy();
				my $iAtomType1   = $Crystal->FindiAtomType($name1);

				my $dis = $Crystal->GetInterAtomicDistance(
					$x0, $y0, $z0, $x1+$ix, $y1+$iy, $z1+$iz );
				next if($dis > $MaximumDistance);
				
				my $idx = int($dis / $rstep);
				
				$RDF[$iAtomType0-1][$iAtomType1-1][$idx] += $Occupancy1;
#print "$name0 [$iAtomType0] - $name1 [$iAtomType1]: $dis [$idx] ($Occupancy1)$LF";
				$count++;
			}
		}
		}
		}
	}

	print "<hr>\n";
	my @filenames = fileparse($CIFFile, "\.[^\.]+");
	print "<b>Links to CSV files</b>$LF";

	for(my $i = 0 ; $i < $nAtomType ; $i++) {
		my $atom0 = $AtomTypeList[$i];
		my $name0 = $atom0->AtomNameOnly();
		my $count = $nCountedAtoms[$i];
		next if($count <= 0);
		for(my $j = 0 ; $j < $nAtomType ; $j++) {
			my $atom1 = $AtomTypeList[$j];
			my $name1 = $atom1->AtomNameOnly();
			
			my $fname = "$filenames[0]-$name0-$name1-RDF.csv";
			my $path = Deps::MakePath($WorkingDir, $fname, 0);
			
			unless(open(OUT, ">$path")) {
				print "Error: Can not write to [$path].$LF";
				next;
			}
			print OUT "r(A),RDF($name0-$name1),RCN($name0-$name1)\n";
			my $integ = 0.0;
			for(my $k = 0 ; $k < $nMesh ; $k++) {
				my $r = $rstep * $k;
				my $v = $RDF[$i][$j][$k] / $count;
				$v = 0.0 if($v eq '');
				$integ += $v if($k > 0);
				print OUT "$r,$v,$integ\n";
			}
			close(OUT);
			&ShowFileLink($WebRootDir, $path, "RDF for $name0-$name1");
		}
	}

	print "$LF";
	print "<hr>\n";
	print "<b>Radial distribution (RDF) and running coordination number (RCN)</b>$LF";

	for(my $i = 0 ; $i < $nAtomType ; $i++) {
		my $atom0 = $AtomTypeList[$i];
		my $name0 = $atom0->AtomNameOnly();
		my $count = $nCountedAtoms[$i];
		next if($count <= 0);

		for(my $j = 0 ; $j < $nAtomType ; $j++) {
			my $atom1 = $AtomTypeList[$j];
			my $name1 = $atom1->AtomNameOnly();

			print "<pre>\n";
			print "RDF for $name0 - $name1:\n";
			print "+++ Count for $name0 in asymmetric unit: $count\n";
			print "     r(A)       RDF        RCN\n";
			my $integ = 0.0;
			my $DoShow = 0;
			for(my $k = 0 ; $k < $nMesh ; $k++) {
				my $r = $rstep * $k;
				my $v = $RDF[$i][$j][$k] / $count;
				$v = 0.0 if($v eq '');
				$integ += $v if($k > 0);
				$DoShow = 1 if($k > 0 and $v > 0);
				next unless($DoShow);
				printf "  %10.4f %12.4f %12.4f\n", $r, $v, $integ;
			}
			print "</pre>\n";
		}
	}
}

sub ShowCalculateRDF
{
	my ($Action, $ShowCIFInf) = @_;

	my $PrevAction = &GetArg("PreviousAction");
	$PrevAction = "ShowCalculateRDF" if($PrevAction eq '');
	my $FileSelect = &GetArg('FileSelect');
	$FileSelect = '*' if($FileSelect eq '');
	my $MaximumDistance = &GetArg('MaximumDistance');
	$MaximumDistance = 5.0 if($MaximumDistance <= 0.0);
	my $nMesh = &GetArg('nMesh');
	$nMesh = 201 if($nMesh <= 0.0);
	print <<EOT1;
<hr>
<h1>CIFファイルから動径分布を計算</h1>
<H2>CIFファイルアップロード</H2>
<form action="/cgi-bin/Research.pl" onSubmit="" ENCTYPE="multipart/form-data" method="POST">
  <input type="hidden" name="Action" value="UploadCIFFile">
  <input type="hidden" name="PreviousAction" value="ShowCalculateRDF">
  <input type="file" name="UploadCIFFilePath" size="60"> 
  <input type="submit" value="Upload" name="B1">  
</form>
<hr>

<H2>CIFファイルの選択</H2>
<form method="POST" action="/cgi-bin/Research.pl">
  <input type="hidden" name="Action" value="CalculateRDF">
  <input type="hidden" name="PreviousAction" value="$PrevAction">
  <input type="submit" value="送信" name="submit"><br>
  <b>File select:</b> <input type="text" name="FileSelect" value="$FileSelect" size="20">
   (use wildcard * and ?, ^/\$ for the first/last characters)<p>

  <b>Maximum distance:</b> <input type="text" name="MaximumDistance" value="$MaximumDistance" size="5"> A<br>
  <b>Number of mesh in distance:</b> 
  <input type="text" name="nMesh" value="$nMesh" size="5"><br>

  <table border="1" width="100%">
    <tr>
EOT1

	&ShowFileList($FileSelect);

	print <<EOT2;
    </tr>
  </table>
  <input type="submit" value="送信" name="submit"></p>
  <input type="submit" value="Rename" name="RenameButton">
   New File Name: <input type="text" name="NewFileName" size="20"></p>
  <input type="submit" value="Delete" name="DeleteButton">

</form>
EOT2
}

sub CalculateDistanceAngle
{
	my ($Action, $ShowCIFInf) = @_;

	my $PrevAction = &GetArg("PreviousAction");
	my $CIFFile    = &GetArg("FILE");
	Utils::DelSpace($CIFFile);
	
	return &ShowCalculateDistanceAngle($Action) if($CIFFile eq '');

	my $MaximumDistance = &GetArg('MaximumDistance');
	$MaximumDistance    = 3.5 if($MaximumDistance <= 0.0);
	my $MaximumNumber   = &GetArg('MaximumNumber');
	$MaximumNumber      = 100 if($MaximumNumber <= 0);
	my $DoSort          = &GetArg('DoSORT');
	$DoSort             = 0 if($DoSort eq '');

	print "<H1>Calculate inter-atomic distances and angles</H1>\n";
	print "<H3>CIF File: $CIFFile</H3>$LF";
	print "Maximum distance: $MaximumDistance A$LF";
	print "Maximum number to be shown: $MaximumNumber$LF";
	print "Sort by distance and ion names: $DoSort$LF";

#CIFファイル名を引数に与えて読み込む
	unless($CIF->Read($CIFFile)) {
		print "Error: Can not read $CIFFile.$LF$LF";
		return 0;
	}
#CIFクラスの内容から、Crystalクラスを作成
	$Crystal = $CIF->GetCCrystal();
	$Crystal->ExpandCoordinates();
	my @AtomTypeList = $Crystal->GetCAtomTypeList();
	my $nAtomType = @AtomTypeList;
	my @AtomSiteList = $Crystal->GetCAsymmetricAtomSiteList();
	my $nAsymmetricAtomSite = @AtomSiteList;
	my @ExpandedAtomSiteList = $Crystal->GetCExpandedAtomSiteList();
	my $nTotalExpandedAtomSite = $Crystal->nTotalExpandedAtomSite();
	my @nMultiplicityExpandedAtomSiteList 
		= $Crystal->GetCnMultiplicityExpandedAtomSiteList();
	
	my ($a,$b,$c,$alpha,$beta,$gamma) = $Crystal->LatticeParameters();
	print "<b>Lattice parameters:</b> $a $b $c  $alpha $beta $gamma$LF";
	my ($g11, $g12, $g13, $g21, $g22, $g23, $g31, $g32, $g33) = $Crystal->Metrics(); 
	print "g=($g11 $g12 $g13)<br>\n";
	print "g=($g21 $g22 $g23)<br>\n";
	print "g=($g31 $g32 $g33)<br>\n";
	print "<b>nAtom:</b> $nTotalExpandedAtomSite<br>\n";
	for(my $i = 0 ; $i < $nTotalExpandedAtomSite ; $i++) {
		my $label     = $ExpandedAtomSiteList[$i]->Label();
		my $type      = $ExpandedAtomSiteList[$i]->AtomName();
		my ($x,$y,$z) = $ExpandedAtomSiteList[$i]->Position(1);
		my $occupancy = $ExpandedAtomSiteList[$i]->Occupancy();
		my $i1 = $i+1;
		printf " %3d: %4s: %4s (%8.4f, %8.4f, %8.4f) [%7.4f]$LF",
			$i1, $label, $type, $x, $y, $z, $occupancy;
	}

	my $nLatticeX = int($MaximumDistance / $a) + 1;
	my $nLatticeY = int($MaximumDistance / $a) + 1;
	my $nLatticeZ = int($MaximumDistance / $a) + 1;
	print "<b>Unit cell numbers to be examined:</b> ($nLatticeX, $nLatticeY, $nLatticeZ)$LF";

	print "$LF";
	print "<H2>Inter-atomic distances</H2>\n";
	my $count = 0;
	my @iAtomListArray;
	my @CDistanceArray;
	for(my $ia = 0 ; $ia < $nAsymmetricAtomSite ; $ia++) {
		my $label0       = $AtomSiteList[$ia]->Label();
		my $type0        = $AtomSiteList[$ia]->AtomName();
		my ($x0,$y0,$z0) = $AtomSiteList[$ia]->Position(1);
		my $occupancy0   = $AtomSiteList[$ia]->Occupancy();
#		my $iAtomType0   = $Crystal->FindiAtomType($type);
		my $ia1 = $ia+1;
		my $k1;
		for(my $k = 0 ; $k < $nTotalExpandedAtomSite ; $k++) {
			my $id = $ExpandedAtomSiteList[$k]->IdAsymmetricAtomSite();
			if($id == $ia1) {
				$k1 = $k+1;
				last;
			}
		}
		$k1 = -1 if($k1 eq '');
		my @iAtomList;
		$iAtomListArray[$ia] = \@iAtomList;;

		for(my $iz = -$nLatticeZ ; $iz <= $nLatticeZ ; $iz++) {
		for(my $iy = -$nLatticeY ; $iy <= $nLatticeY ; $iy++) {
		for(my $ix = -$nLatticeX ; $ix <= $nLatticeX ; $ix++) {
			last if($count >= $MaximumNumber);
			for(my $i = 0 ; $i < $nTotalExpandedAtomSite ; $i++) {
				my $label     = $ExpandedAtomSiteList[$i]->Label();
				my $type      = $ExpandedAtomSiteList[$i]->AtomName();
				my ($x,$y,$z) = $ExpandedAtomSiteList[$i]->Position(1);
				my $occupancy = $ExpandedAtomSiteList[$i]->Occupancy();
				my $id = $ExpandedAtomSiteList[$i]->IdAsymmetricAtomSite();
#				my $mult = $nMultiplicityExpandedAtomSiteList[$id-1];
				my $i1 = $i+1;
#				print "   $i1: [$id]$label ($type): ($x, $y, $z) [$occupancy][$mult]$LF";

				my $dis = $Crystal->GetInterAtomicDistance(
					$x0, $y0, $z0, $x+$ix, $y+$iy, $z+$iz );
				next if($dis > $MaximumDistance);
				
				my %Peak;
				$Peak{'sn'}     = $count+1;
				$Peak{'label0'} = $label0;
				$Peak{'ia1'}    = $ia1;
				$Peak{'k1'}     = $k1;
				$Peak{'label'}  = $label;
				$Peak{'i1'}     = $i1;
				$Peak{'ix'}     = $ix;
				$Peak{'iy'}     = $iy;
				$Peak{'iz'}     = $iz;
				$Peak{'dis'}    = $dis;
				$Peak{'x0'}     = $x0;
				$Peak{'y0'}     = $y0;
				$Peak{'z0'}     = $z0;
				$Peak{'x1'}     = $x+$ix;
				$Peak{'y1'}     = $y+$iy;
				$Peak{'z1'}     = $z+$iz;
				push(@CDistanceArray, \%Peak);
#				printf "   %04d: %4s(#%3d,\@%3d) - %4s(\@%3d)[%d,%d,%d]: %7.4f A  ---  "
#					."(%7.4f,%7.4f,%7.4f)-(%7.4f,%7.4f,%7.4f)$LF",
#					$count+1, $label0, $ia1, $k1, $label, $i1, $ix, $iy, $iz, $dis,
#					$x0, $y0, $z0, $x+$ix, $y+$iy, $z+$iz;

				my $xx = $x+$ix;
				my $yy = $y+$iy;
				my $zz = $z+$iz;
				my $s = "$i $label $xx $yy $zz";
				push(@iAtomList, $s);

				$count++;
				if($count >= $MaximumNumber) {
					print "Maximum number ($MaximumNumber) reached.$LF";
					print "Skip further calculation.$LF";
					last;
				}
			}
		}
		}
		}
	}
	
	if($DoSort) {
#print "<H1>SORT</H1>";
		@CDistanceArray = sort SortDistanceArrayFunc @CDistanceArray;
	}
	print "<pre>\n";
	for(my $i = 0 ; $i < @CDistanceArray ; $i++) {
		my $peak = $CDistanceArray[$i];
		printf "   %04d(%04d): %4s(#%3d,\@%3d) - %4s(\@%3d)[%2d,%2d,%2d]: %7.4f A  ---  "
			."(%7.4f,%7.4f,%7.4f)-(%7.4f,%7.4f,%7.4f)\n",
			$i+1, $peak->{'sn'}, $peak->{'label0'}, $peak->{'ia1'}, $peak->{'k1'},
			$peak->{'label'}, $peak->{'i1'}, $peak->{'ix'}, $peak->{'iy'}, $peak->{'iz'}, 
			$peak->{'dis'}, $peak->{'x0'}, $peak->{'y0'}, $peak->{'z0'}, 
			$peak->{'x1'}, $peak->{'y1'}, $peak->{'z1'};
	}
	print "</pre>\n";

	print "$LF";
	print "<H2>Inter-atomic Angles</H2>\n";
	my $count = 0;
	for(my $ia = 0 ; $ia < $nAsymmetricAtomSite ; $ia++) {
		next if($count >= $MaximumNumber);
		my $label0       = $AtomSiteList[$ia]->Label();
		my $type0        = $AtomSiteList[$ia]->AtomName();
		my ($x0,$y0,$z0) = $AtomSiteList[$ia]->Position(1);
		my $ia1 = $ia+1;
		my $iAtomList = $iAtomListArray[$ia];
		my $k1;
		for(my $k = 0 ; $k < $nTotalExpandedAtomSite ; $k++) {
			my $id = $ExpandedAtomSiteList[$k]->IdAsymmetricAtomSite();
			if($id == $ia1) {
				$k1 = $k+1;
				last;
			}
		}
		$k1 = -1 if($k1 eq '');

		for(my $i1 = 0 ; $i1 < @$iAtomList ; $i1++) {
			next if($count >= $MaximumNumber);
			my $s1 = $iAtomList->[$i1];
			my ($i1a, $label1, $x1, $y1, $z1) = (split(/\s/, $s1));
			my $i11 = $i1+1;
			my $dis01 = $Crystal->GetInterAtomicDistance(
				$x0, $y0, $z0, $x1, $y1, $z1);
#print "dis01($x0,$y0,$z0)-($x1,$y1,$z1): $dis01$LF";
			next if($dis01 <= 0.0);
			for(my $i2 = 0 ; $i2 < @$iAtomList ; $i2++) {
				my $s2 = $iAtomList->[$i2];
				my ($i2a, $label2, $x2, $y2, $z2) = (split(/\s/, $s2));
				my $i21 = $i2+1;
				my $dis02 = $Crystal->GetInterAtomicDistance(
					$x0, $y0, $z0, $x2, $y2, $z2);
				next if($dis02 <= 0.0);

				my $dis12 = $Crystal->GetInterAtomicDistance(
					$x1, $y1, $z1, $x2, $y2, $z2);
				next if($dis12 <= 0.0);


				my $angle = $Crystal->GetInterAtomicAngle(
							$x0, $y0, $z0, 
							$x1, $y1, $z1,
							$x2, $y2, $z2 );
				printf "   %04d: %4s(#%3d,\@%3d) - %4s(\@%3d) - %4s(\@%3d): "
					."%7.3f <sup>o</sup>  ---  "
					."(%6.3f,%6.3f,%6.3f)-(%6.3f,%6.3f,%6.3f)-(%6.3f,%6.3f,%6.3f)$LF",
					$count+1, 
					$label0, $ia1, $k1, $label1, $i11, $label2, $i21, 
					$angle,
					$x0, $y0, $z0, $x1, $y1, $z1, $x2, $y2, $z2;

				$count++;
				if($count >= $MaximumNumber) {
					print "Maximum number ($MaximumNumber) reached.$LF";
					print "Skip further calculation.$LF";
					last;
				}
			}
		}
	}

	print "$LF";
	print "<hr>\n";
#Crystalクラス中の、原子の種類 AtomTypeクラスのリストをとる
	print "nAtomType: $nAtomType$LF";
	for(my $i = 0 ; $i < $nAtomType ; $i++) {
		my $label    = $AtomTypeList[$i]->Label();
		my $atomname = $AtomTypeList[$i]->AtomName();
		my $charge   = $AtomTypeList[$i]->Charge();
		my $AtomicNumber = $AtomTypeList[$i]->AtomicNumber();
		my $AtomicMass   = $AtomTypeList[$i]->AtomicMass();
		my $i1 = $i+1;
		print "   \$$i1: $label : $atomname [$AtomicNumber] ($charge) "
			."($AtomicMass)$LF";
	}

	print "$LF";
#Crystalクラス中の、非対称単位中の原子 AsymmetricAtomSiteクラスのリストをとる
	print "nAsymmetricAtomSite: $nAsymmetricAtomSite$LF";
	for(my $i = 0 ; $i < $nAsymmetricAtomSite ; $i++) {
		my $label     = $AtomSiteList[$i]->Label();
		my $type      = $AtomSiteList[$i]->AtomName();
		my ($x,$y,$z) = $AtomSiteList[$i]->Position(1);
		my $occupancy = $AtomSiteList[$i]->Occupancy();
		my $iAtomType = $Crystal->FindiAtomType($type);

		my $i1 = $i+1;
		printf "   #%03d: %4s (%4s)[%2d]: (%7.4f, %7.4f, %7.4f) [%7.4f]$LF",
			$i1, $label, $type, $iAtomType, $x, $y, $z, $occupancy;
	}

	print "$LF";
	print "nTotalExpandedAtomSite: $nTotalExpandedAtomSite$LF";
	for(my $i = 0 ; $i < $nTotalExpandedAtomSite ; $i++) {
		my $label     = $ExpandedAtomSiteList[$i]->Label();
		my $type      = $ExpandedAtomSiteList[$i]->AtomName();
		my ($x,$y,$z) = $ExpandedAtomSiteList[$i]->Position(1);
		my $occupancy = $ExpandedAtomSiteList[$i]->Occupancy();
		my $id = $ExpandedAtomSiteList[$i]->IdAsymmetricAtomSite();
		my $mult = $nMultiplicityExpandedAtomSiteList[$id-1];

		my $i1 = $i+1;
		printf "   \@%04d: [%2d]%4s (%4s): (%7.4f, %7.4f, %7.4f) [%7.4f][%d]$LF",
			$i1, $id, $label, $type, $x, $y, $z, $occupancy, $mult;
	}

	print "$LF";
	my $Density = $Crystal->Density();
	print "Density: $Density g/cm^3$LF";

}

sub SortDistanceArrayFunc
{
	return $a->{'dis'} <=> $b->{'dis'} or 
		$a->{'label0'} <=> $b->{'label0'} or
		$a->{'label'}  <=> $b->{'label'};
}

sub ShowCalculateDistanceAngle
{
	my ($Action, $ShowCIFInf) = @_;

	my $PrevAction = &GetArg("PreviousAction");
	$PrevAction = 'ShowCalculateDistanceAngle' if($PrevAction eq '');
	my $FileSelect = &GetArg('FileSelect');
	$FileSelect = '*' if($FileSelect eq '');
	my $MaximumDistance = &GetArg('MaximumDistance');
	$MaximumDistance = 3.0 if($MaximumDistance <= 0.0);
	my $MaximumNumber = &GetArg('MaximumNumber');
	$MaximumNumber = 300 if($MaximumNumber <= 0);
	print <<EOT1;
<hr>
<h1>CIFファイルから原子間距離、角度を計算</h1>
<H2>CIFファイルアップロード</H2>
<form action="/cgi-bin/Research.pl" onSubmit="" ENCTYPE="multipart/form-data" method="POST">
  <input type="hidden" name="Action" value="UploadCIFFile">
  <input type="hidden" name="PreviousAction" value="ShowCalculateDistanceAngle">
  <input type="file" name="UploadCIFFilePath" size="60"> 
  <input type="submit" value="Upload" name="B1">  
</form>
<hr>

<H2>CIFファイルの選択</H2>
<form method="POST" action="/cgi-bin/Research.pl">
  <input type="hidden" name="Action" value="CalculateDistanceAngle">
  <input type="hidden" name="PreviousAction" value="$PrevAction">
  <input type="submit" value="送信" name="submit"><br>
  <b>File select:</b> <input type="text" name="FileSelect" value="$FileSelect" size="20">
   (use wildcard * and ?, ^/\$ for the first/last characters)<p>

  <b>Maximum distance:</b> <input type="text" name="MaximumDistance" value="$MaximumDistance" size="5"> A<br>
  <b>Maximum number to be shown:</b> <input type="text" name="MaximumNumber" value="$MaximumNumber" size="5"><br>
  <input type="checkbox" name="DoSORT" value="ON" checked>Sort by distance and ion names</p>

  <table border="1" width="100%">
    <tr>
EOT1

	&ShowFileList($FileSelect);

	print <<EOT2;
    </tr>
  </table>
  <input type="submit" value="送信" name="submit"></p>
  <input type="submit" value="Rename" name="RenameButton">
   New File Name: <input type="text" name="NewFileName" size="20"></p>
  <input type="submit" value="Delete" name="DeleteButton">

</form>
<hr>
<ul>
  <li><a href="$ResearchRootURL/CASTEP-CommonFileFormats.mht">結晶構\造共通フォーマット： 
    CASTEP.mht</a></li>
  <li>　   
  <li><a href="http://cst-www.nrl.navy.mil/lattice/">Crystal Lattice Structures</a> 
</ul>
EOT2
}

sub ShowCrystalDB 
{
	my ($Action) = @_;

	my $PrevAction = &GetArg("PreviousAction");
	my $FileSelect = &GetArg('FileSelect');
	$FileSelect = '*' if($FileSelect eq '');
	print <<EOT1;
<hr>
<H2>CIFファイルアップロード</H2>
<form action="/cgi-bin/Research.pl" onSubmit="" ENCTYPE="multipart/form-data" method="POST">
  <input type="hidden" name="PreviousAction" value="ShowCrystalDB">
  <input type="hidden" name="Action" value="UploadCIFFile">

  <input type="file" name="UploadCIFFilePath" size="60"> 
  <input type="submit" value="Upload" name="B1">  
</form>

<hr>

<H1>CIFファイルを選択して結晶構\造ファイルを作成する</H1>
<form method="POST" action="/cgi-bin/Research.pl">
  <input type="hidden" name="Action" value="ShowCIFInf">
  <input type="hidden" name="PreviousAction" value="$PrevAction">

  <input type="submit" value="送信" name="submit"><br>
  <b>File select:</b> <input type="text" name="FileSelect" value="$FileSelect" size="20">
   (use wildcard * and ?, ^/\$ for the first/last characters)<p>

  <input type="checkbox" name="ShowCIFInf" value="ON">Show detail CIF Information<br>
  <input type="checkbox" name="ShowCrystalStructure" value="ON" checked>Show summarized Crystal Structure<br>

  <H3>Do not choose more than one from the following choices.</H3>

  <input type="checkbox" name="MakeSimpleCIFFile" value="ON">Make <b>Simple CIF File</b><br>
  &nbsp;&nbsp;&nbsp; <input type="checkbox" name="CIFExpandCoordinate" value="ON">
  Expand all atoms to P1<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Expand Lattice: &nbsp; 
  a:<input type="text" name="CIFExpandLatticeA" value="1" size="5"> 
  b:<input type="text" name="CIFExpandLatticeB" value="1" size="5"> 
  c:<input type="text" name="CIFExpandLatticeC" value="1" size="5"><br>

  <input type="checkbox" name="MakeVRMLFile"  value="ON">Make <b>VRML Files</b><br>
  &nbsp;&nbsp;&nbsp;
  <select size="1" name="VRMLVersion">
    <option value="V1.0"         >VRML V1.0 ascii</option>
    <option value="V2.0"         >VRML V2.0 utf8</option>
    <option value="V2.5"         >X3D VRML Encoding utf8</option>
    <option value="V3.0" selected>X3D utf8</option>
    </select>
  <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Expand Lattice: &nbsp; 
  a:<input type="text" name="VRMLExpandLatticeA" value="1.2" size="5"> 
  b:<input type="text" name="VRMLExpandLatticeB" value="1.2" size="5"> 
  c:<input type="text" name="VRMLExpandLatticeC" value="1.2" size="5"><br>
  &nbsp;&nbsp;&nbsp;Max bond length:
  <input type="text" name="VRMLMaxBondLength" value="2.8" size="5"> 
  Max number of bonds:
  <input type="text" name="VRMLnMaxBonds" value="1000" size="5"><br>
  &nbsp;&nbsp;&nbsp;Ion radius scale factor
  <input type="text" name="VRMLIonRadiusScaleFactor" value="0.5" size="5"><br>

  <input type="checkbox" name="MakePOVRayFile"  value="ON">Make <b>POV-Ray Files</b><br>
  &nbsp;&nbsp;&nbsp;
  <select size="1" name="POVRayMaterial">
    <option value="Normal" selected>Normal</option>
    <option value="Glass"          >Glass</option>
  </select>
  <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Expand Lattice: &nbsp; 
  a:<input type="text" name="POVRayExpandLatticeA" value="1.2" size="5"> 
  b:<input type="text" name="POVRayExpandLatticeB" value="1.2" size="5"> 
  c:<input type="text" name="POVRayExpandLatticeC" value="1.2" size="5"><br>
  &nbsp;&nbsp;&nbsp;Max bond length:
  <input type="text" name="POVRayMaxBondLength" value="2.5" size="5"> 
  Max number of bonds:
  <input type="text" name="POVRaynMaxBonds" value="1000" size="5"><br>
  &nbsp;&nbsp;&nbsp;Ion radius scale factor
  <input type="text" name="POVRayIonRadiusScaleFactor" value="0.7" size="5"><br>

  <input type="checkbox" name="MakeRietanINSFiles" value="ON">Make <b>Rietan INS Files</b><br>
  &nbsp;&nbsp;&nbsp; <input type="checkbox" name="RietanExpandCoordinate" value="ON">
  Expand all atoms to P1
  <input type="checkbox" name="RietanChooseRandomly" value="ON">
  Randomly choose partial occupancy atoms<br>

  <input type="checkbox" name="MakeCIFFile" value="ON">Make <b>CIF File (CASTEP etc.)</b><br>
  &nbsp;&nbsp;&nbsp; <input type="checkbox" name="CIFExpandCoordinate" value="ON" checked>
  Expand all atoms to P1<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Expand Lattice: &nbsp; 
  a:<input type="text" name="CIFExpandLatticeA" value="1" size="5"> 
  b:<input type="text" name="CIFExpandLatticeB" value="1" size="5"> 
  c:<input type="text" name="CIFExpandLatticeC" value="1" size="5"><br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <input type="checkbox" name="CIFChooseRandomly" value="ON">
  Randomly choose partial occupancy atoms<br>

  <input type="checkbox" name="MakeBDLFile" value="ON">Make <b>SCIGRESS/ME-MD .bdl File</b><br>
  &nbsp;&nbsp;&nbsp; <input type="checkbox" name="BDLExpandCoordinate" value="ON" checked>
  Expand all atoms to P1<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Expand Lattice: &nbsp; 
  a:<input type="text" name="BDLExpandLatticeA" value="1" size="5"> 
  b:<input type="text" name="BDLExpandLatticeB" value="1" size="5"> 
  c:<input type="text" name="BDLExpandLatticeC" value="1" size="5"><br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <input type="checkbox" name="BDLChooseRandomly" value="ON">
  Randomly choose partial occupancy atoms<br>

  <input type="checkbox" name="MakeCARFile" value="ON">Make <b>CAR File (Use with care: CASTEP)</b><br>
  &nbsp;&nbsp;&nbsp; <input type="checkbox" name="CARExpandCoordinate" value="ON" checked>
  Expand all atoms to P1<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Expand Lattice: &nbsp; 
  a:<input type="text" name="CARExpandLatticeA" value="1" size="5"> 
  b:<input type="text" name="CARExpandLatticeB" value="1" size="5"> 
  c:<input type="text" name="CARExpandLatticeC" value="1" size="5"><br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <input type="checkbox" name="CARChooseRandomly" value="ON">
  Randomly choose partial occupancy atoms<br>

  <input type="checkbox" name="MakePWSCFFile" value="ON">Make <b>PWSCF File</b><br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <input type="checkbox" name="PWSCFUseBravaisLattice" value="ON">
  Use Bravais Lattice<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <input type="checkbox" name="PWSCFUseCELLDM" value="ON" checked>
  Use celldm<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Function: &nbsp; 
  <select size="1" name="PWSCFFunction">
    <option value="scf" selected>SCF</option>
    <option value="nscf"        >Band(nscf)</option>
    <option value="relax"       >Relaxation</option>
    <option value="vc-relax"    >Variable cell relaxation</option>
    <option value="md"          >MD</option>
    <option value="vc-md"       >Variable cell MD</option>
    <option value="phonon"      >Phonon</option>
  </select>
  <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Pseudo Potential: &nbsp; 
  <select size="1" name="PWSCFPseudoPotential">
    <option value="pbe" selected>PBE</option>
    <option value="pw91"        >PW91</option>
    <option value="pz"          >PZ</option>
    <option value="blyp"        >BLYP</option>
  </select>
  <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Expand Lattice: &nbsp; 
  a:<input type="text" name="PWSCFExpandLatticeA" value="1" size="5"> 
  b:<input type="text" name="PWSCFExpandLatticeB" value="1" size="5"> 
  c:<input type="text" name="PWSCFExpandLatticeC" value="1" size="5"><br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <input type="checkbox" name="PWSCFChooseRandomly" value="ON">
  Randomly choose partial occupancy atoms<br>

  <input type="checkbox" name="MakeVASPFiles" value="ON">Make <b>VASP Files</b><br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <input type="checkbox" name="UseConventionalCell" value="ON" checked>
  Use conventional cell<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Function: &nbsp; 
  <select size="1" name="VASPFunction">
    <option value="scf" selected>SCF</option>
    <option value="nscf"        >Band(nscf)</option>
    <option value="relax"       >Relaxation</option>
    <option value="vc-relax"    >Variable cell relaxation</option>
    <option value="md"          >MD</option>
    </select>
  <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Density Functional: &nbsp; 
  <select size="1" name="VASPFunctional">
    <option value="US_LDA"          >US LDA</option>
    <option value="GGA"             >GGA</option>
    <option value="PAW"             >PAW</option>
    <option value="PAW_GGA"         >PAW GGA</option>
    <option value="PAW_PBE" selected>PAW PBE</option>
    </select>
  <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <input type="checkbox" name="VASPUseDPP" value="ON">
  Use _d Pseudo Potential<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" name="VASPSpinPolarized" value="ON">
  Spin Polarized<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Expand Lattice: &nbsp; 
  a:<input type="text" name="VASPExpandLatticeA" value="1" size="5"> 
  b:<input type="text" name="VASPExpandLatticeB" value="1" size="5"> 
  c:<input type="text" name="VASPExpandLatticeC" value="1" size="5"><br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <input type="checkbox" name="VASPChooseRandomly" value="ON">
  Randomly choose partial occupancy atoms<br>

  <input type="checkbox" name="MakeCRYSTAL06Files" value="ON">Make <b>CRYSTAL06 Files</b><br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Function: &nbsp; 
  <select size="1" name="CRYSTAL06Function">
    <option value="scf" selected>SCF</option>
    </select>
  <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" name="CRYSTAL06SpinPolarized" value="ON">
  Spin Polarized<br>
  &nbsp;&nbsp;&nbsp; <input type="checkbox" name="CRYSTAL06ExpandCoordinate" value="ON">
  Expand all atoms to P1<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Expand Lattice: &nbsp; 
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Expand Lattice: &nbsp; 
  a:<input type="text" name="CRYSTAL06ExpandLatticeA" value="1" size="5"> 
  b:<input type="text" name="CRYSTAL06ExpandLatticeB" value="1" size="5"> 
  c:<input type="text" name="CRYSTAL06ExpandLatticeC" value="1" size="5"><br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <input type="checkbox" name="CRYSTAL06ChooseRandomly" value="ON">
  Randomly choose partial occupancy atoms<br>

  <input type="checkbox" name="MakeTranSIESTAFiles" value="ON">Make <b>Virtual Nanolab File</b><br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Version: 
  <select size="1" name="TranSIESTAVersion">
    <option value="Ver11"         >1.1</option>
    <option value="Ver20" selected>2.0</option>
    </select>
  <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Function: 
  <select size="1" name="TranSIESTAFunction">
    <option value="scf" selected>SCF</option>
    <option value="relax"       >Relaxation</option>
    </select>
  <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Basis set: 
  <select size="1" name="TranSIESTABasisSet">
    <option value="SZ"          >SZ</option>
    <option value="DZ"          >DZ</option>
    <option value="SZP"         >SZP</option>
    <option value="DZP" selected>DZP</option>
    <option value="DZDP"        >DZDP</option>
    </select>
  <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XC Functional: 
  <select size="1" name="TranSIESTAXCFunctional">
    <option value="LDA-PZ"          >LDA-PZ</option>
    <option value="LSDA-PZ"         >LSDA-PZ (Spin polarized)</option>
    <option value="GGA-PBE" selected>GGA-PBE</option>
    <option value="SGGA-PBE"        >SGGA-PBE (Spin polarized)</option>
    </select>
  <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Initial spin for Spin Polarized calc.: 
  <select size="1" name="TranSIESTAInitialSpin">
    <option value="0"           >0</option>
    <option value="0.5" selected>0.5 hbar</option>
    <option value="1.0"         >1 hbar</option>
    <option value="1.5"         >1.5 hbar</option>
    <option value="2.0"         >2 hbar</option>
    <option value="2.5"         >2.5 hbar</option>
    <option value="3.0"         >3 hbar</option>
    <option value="3.5"         >3.5 hbar</option>
    </select>
  <br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Expand Lattice: &nbsp; 
  a:<input type="text" name="TranSIESTAExpandLatticeA" value="1" size="5"> 
  b:<input type="text" name="TranSIESTAExpandLatticeB" value="1" size="5"> 
  c:<input type="text" name="TranSIESTAExpandLatticeC" value="1" size="5"><br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <input type="checkbox" name="TranSIESTAChooseRandomly" value="ON">
  Randomly choose partial occupancy atoms<br>

  <input type="checkbox" name="MakeWIEN2kStructFile" value="ON">Make <b>WIEN2k Struct File</b><br>
  &nbsp;&nbsp;&nbsp; <input type="checkbox" name="WEIN2kStructExpandCoordinate" value="ON" checked>
  Expand all atoms to P1<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Expand Lattice: &nbsp; 
  a:<input type="text" name="WIEN2kExpandLatticeA" value="1" size="5"> 
  b:<input type="text" name="WIEN2kExpandLatticeB" value="1" size="5"> 
  c:<input type="text" name="WIEN2kExpandLatticeC" value="1" size="5"><br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <input type="checkbox" name="WEIN2kStructChooseRandomly" value="ON">
  Randomly choose partial occupancy atoms<br>

  <input type="checkbox" name="MakeTBFile" value="ON">Make <b>Tight-binding Input File</b><br>
  &nbsp;&nbsp;&nbsp; <input type="checkbox" name="TBExpandCoordinate" value="ON" checked>
  Expand all atoms to P1<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Expand Lattice: &nbsp; 
  a:<input type="text" name="TBExpandLatticeA" value="1" size="5"> 
  b:<input type="text" name="TBExpandLatticeB" value="1" size="5"> 
  c:<input type="text" name="TBExpandLatticeC" value="1" size="5"><br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <input type="checkbox" name="TBChooseRandomly" value="ON">
  Randomly choose partial occupancy atoms<br>

  <input type="checkbox" name="MakeMXDORTOFiles" value="ON">Make <b>MXDORTO Files</b><br>
  &nbsp;&nbsp;&nbsp;Expand all atoms to P1<br>
  &nbsp;&nbsp;&nbsp;&nbsp; Expand Lattice: &nbsp; 
  a:<input type="text" name="MXDExpandLatticeA" value="1" size="5"> 
  b:<input type="text" name="MXDExpandLatticeB" value="1" size="5"> 
  c:<input type="text" name="MXDExpandLatticeC" value="1" size="5"><br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <input type="checkbox" name="MXDChooseRandomly" value="ON">
  Randomly choose partial occupancy atoms<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  <input type="radio" value="MDNPT" checked name="MXDFunction"> NPT MD<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  <input type="radio" value="XDNPT"         name="MXDFunction"> NPT XD(not work well)<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Version: <select size="1" name="MXDVersion">
    <option value="1" selected>1.0</option>\n";
    <option value="2"         >2.0</option>\n";
  </select><br>

  <input type="checkbox" name="MakeLDFiles" value="ON">Make <b>Lattice Dynamics Files</b><br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Function: 
  <select size="1" name="LDFunction">
    <option value=\"Energy\" selected>Energy</option>\n";
    <option value=\"Permit\"         >Permit</option>\n";
    <option value=\"WMin\"           >WMin</option>\n";
    <option value=\"xLSQ\"           >xLSQ</option>\n";
    <option value=\"Phonon\"         >Phonon</option>\n";
  </select><br>

  <input type="checkbox" name="MakeGULPFiles" value="ON">Make <b>GULP File</b><br>
  &nbsp;&nbsp;&nbsp; <input type="checkbox" name="GULPExpandCoordinate" value="ON" checked>
  Expand all atoms to P1<br>
  &nbsp;&nbsp;&nbsp;&nbsp; Expand Lattice: &nbsp; 
  a:<input type="text" name="GULPExpandLatticeA" value="1" size="5"> 
  b:<input type="text" name="GULPExpandLatticeB" value="1" size="5"> 
  c:<input type="text" name="GULPExpandLatticeC" value="1" size="5"><br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <input type="checkbox" name="GULPChooseRandomly" value="ON">
  Randomly choose partial occupancy atoms<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  <input type="checkbox" name="GULPUseShellModelForCation" value="ON" checked>Use Shell Model for Cation
  <input type="checkbox" name="GULPUseShellModelForAnion"  value="ON" checked>Use Shell Model for Anion<br>
  &nbsp;&nbsp;&nbsp;&nbsp;Potential model: 
  <select size="1" name="LibraryFile">
    <option value=\"Kamiya.lib\"                 >Kamiya Core-Shell model</option>\n";
    <option value=\"Kamiya-NoShell.lib\" selected>Kamiya Core model</option>\n";
    <option value=\"bush.lib\"                   >Buch Core-Shell model</option>\n";
    <option value=\"catlow.lib\"                 >Catlow Core-Shell model</option>\n";
    <option value=\"lewis.lib\"                  >Lewis Core-Shell model</option>\n";
    <option value=\"suttonchen.lib\"             >Suttonchen Core model</option>\n";
    <option value=\"glass.lib\"                  >Glass Core model</option>\n";
  </select><br>
  &nbsp;&nbsp;&nbsp;&nbsp;
  Choose function:<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  <input type="radio" value="Optimize" checked name="GULPFunction">
      Optimize Structure, Material Properties, at Constant Pressure<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  <input type="radio" value="Fit"    name="GULPFunction">
      Fit Potential Parameters, Material Properties, at Constant Pressure<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  <input type="radio" value="MD-NVT" name="GULPFunction">
      MD at NVT<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  <input type="radio" value="MD-NPT" name="GULPFunction">
      MD at NPT<br>

  <input type="checkbox" name="MakeWIEN2kXYZFile" value="ON">Make <b>WIEN2k XYZ File</b><br>
  <input type="checkbox" name="MakeDVXaFiles" value="ON">Make DVXa Files (not implimented)<br>

  <input type="checkbox" name="MakeKHLabFiles" value="ON">
  Make <b>KHLab Common Crystal Structure Format Files</b><br>
  &nbsp;&nbsp;&nbsp; <input type="checkbox" name="KHLabExpandCoordinate" value="ON" checked>
  Expand all atoms to P1<br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Expand Lattice: &nbsp; 
  a:<input type="text" name="KHLabExpandLatticeA" value="1" size="5"> 
  b:<input type="text" name="KHLabExpandLatticeB" value="1" size="5"> 
  c:<input type="text" name="KHLabExpandLatticeC" value="1" size="5"><br>
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <input type="checkbox" name="KHLabChooseRandomly" value="ON">
  Randomly choose partial occupancy atoms<br>

  <table border="1" width="100%">
    <tr>
EOT1

	&ShowFileList($FileSelect);

	print <<EOT2;
    </tr>
  </table>
  <input type="submit" value="送信" name="submit"></p>
  <input type="submit" value="Rename" name="RenameButton">
   New File Name: <input type="text" name="NewFileName" size="20"></p>
  <input type="submit" value="Delete" name="DeleteButton">

</form>
<hr>
<ul>
  <li><a href="$ResearchRootURL/CASTEP-CommonFileFormats.mht">結晶構\造共通フォーマット： 
    CASTEP.mht</a></li>
  <li>　   
  <li><a href="http://cst-www.nrl.navy.mil/lattice/">Crystal Lattice Structures</a> 
</ul>
EOT2
}

sub ShowFileList
{
	my ($FileSelect) = @_;

	$FileSelect = '*' if($FileSelect eq '');
	$FileSelect = "$FileSelect*" if($FileSelect !~ /[\$\*\?]$/);
	$FileSelect = "*$FileSelect" if($FileSelect !~ /^[\$\*\?]/);
	my $path    = Deps::MakePath($CrystalDBDir, $FileSelect, 0);
#print "path: $path$LF";
	my @files = glob($path);
	my $count = 0;
	for my $f (sort @files) {
#print "$f$LF";
#next;
		next unless(-f $f);
		next unless($f =~ /^(.*)\\(.*?)\.(cif|xyz)$/i);
		my $dirname = $1;
		my $fname   = $2;
		my $ext     = $3;
		
		print "<td>\n";
		print "<input type=\"radio\" name=\"FILE\" value=\"$f\">$fname\n";
#		print "<input type=\"radio\" name=\"FILE\" value=\"$f\">$fname.$ext\n";
		print "</td>\n";
		$count++;
		if($count % 5 == 0) {
			print "</tr>\n";
			print "<tr>\n";
		}
	}
	print "$LF";
}

sub RenameCIFFile
{
	my $CIFFile = &GetArg("FILE");
	Utils::DelSpace($CIFFile);

	my $NewCIFFile = &GetArg("NewFileName");
	Utils::DelSpace($NewCIFFile);

	if($NewCIFFile eq '') {
		print "<H1>Error: Specify New File Name.</H1>\n";
		return 0;
	}

#ファイル名を（ベース名, ディレクトリ名, 拡張子）に分解
#print "filenames: $filenames[0] : $filenames[1] : $filenames[2]<br>\n";

	my @SourceFileNames = fileparse($CIFFile, "\.[^\.]+");
	my @NewFileNames    = fileparse($NewCIFFile, "\.[^\.]+");

	$NewCIFFile = $NewFileNames[0] . $SourceFileNames[2];
	my $NewFilePath = Deps::MakePath($CrystalDBDir, $NewCIFFile, 0);
	
	if(-e $NewFilePath) {
		print "<H1>Error: File [$NewFilePath] exists.</H1>\n";
		print "<H2>     Specify another name.</H2>\n";
		return 0;
	}

	print "<H1>Rename [$CIFFile] to [$NewCIFFile]</H1>\n";
	rename($CIFFile, $NewFilePath);

	return 1;
}

sub DeleteCIFFile
{
	my $CIFFile = &GetArg("FILE");
	Utils::DelSpace($CIFFile);

#ファイル名を（ベース名, ディレクトリ名, 拡張子）に分解
	my @filenames = fileparse($CIFFile, "\.[^\.]+");
#print "filenames: $filenames[0] : $filenames[1] : $filenames[2]<br>\n";
	my $SourceFileName = $filenames[0];

	my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) 
		= localtime(time());
	my $NewFileName = sprintf "%s_%04d%02d%02d%02d%02d%02d", 
		$SourceFileName, $year+1900, $mon+1, $mday, $hour, $min, $sec;

	$NewFileName = $NewFileName . $filenames[2] if($filenames[2] ne '');

	$NewFileName = Deps::MakePath($DeleteCrystalDBDir, $NewFileName, 0);

	print "<H1>Delete [$SourceFileName$filenames[2]]</H1>\n";

	Utils::CreateDirecotry($DeleteCrystalDBDir, $DirectorySeparator);

	rename($CIFFile, $NewFileName);

	return 1;
}

sub ShowFile
{
	my $CIFFile = &GetArg("File");

	unless(open(IN,"<$CIFFile")) {
		print "Can not read $CIFFile.$LF$LF";
		return -1;
	}
	my $content;
	while(<IN>) {
		my $a = $_;
		Utils::InvalidateHTMLTags($a);
		$content .= $a;
	}
	close(IN);
	print "<PRE>\n";
	print $content;
	print "</PRE>\n";
	return;
}

sub MakeCIFFileLink
{
	my $CIFFile = &GetArg("FILE");
#ファイル名を（ベース名, ディレクトリ名, 拡張子）に分解
	my @filenames = fileparse($CIFFile, "\.[^\.]+");
	my $fname = $filenames[0];
	$fname = "$fname$filenames[2]" if($filenames[2] ne '');

	print "<b>Link to CIF File:</b> ";
	&ShowFileLink($WebRootDir, $CIFFile, $fname);

	return;
}

sub UploadCIFFile
{
	print "<H1>Upload CIF File</H1>\n";
	my $filename   = $form->param('UploadCIFFilePath');

	my $parsename = $filename;

	print "Source File: $parsename$LF";

	if($parsename eq '') {
		print "<H2>Error: Specify filename</H2>$LF$LF";
		exit;
	}

#ファイルが転送されていなかったら、$filename は 未定義値となっている
#フォーム上でファイルを選択しない場合は、$filename は空文字列
	unless (defined($filename)){
		my $error = $form->cgi_error;
		print "Can't upload $filename: $error$LF$LF";
		exit;
	}
# ファイルが転送されていない場合$filenameは偽
	unless($filename) {
		print "$filename could not be uploead.$LF$LF";
		exit;
	}

#ファイルパス内の「\」を「/」に変換
#	$parsename =~ s/\\/\//g;
#print "Client File: $parsename<br>\n";

#サーバー側パス名の決定
	my $RegSep = Utils::RegExpQuote($DirectorySeparator);
#ファイル名を（ベース名, ディレクトリ名, 拡張子）に分解
	my @filenames = fileparse($parsename, "\.[^\.]+");
#print "filenames: $filenames[0] : $filenames[1] : $filenames[2]<br>\n";
	my $fname = $filenames[0];
	$fname = $fname . $filenames[2] if($filenames[2] ne '');
	my $UploadFile = Deps::MakePath($CrystalDBDir, $fname, 0);
#print "Upload path: $UploadFile$LF";
	my $ext   = $filenames[2];
	unless($ext =~ /\.(cif|xyz)$/i) {
		print "$fname is not allowed for upload.$LF$LF";
		exit;
	}

#既に同名のファイルが存在した場合
#（複数の同名ファイルを同時にアップロードした場合など）は、
#ベース名にアンダースコアと番号を付けて別名にする
	my $i = 0;
	while (-f $UploadFile) {
		$i++;
		my $fn = $filenames[0] . "_" . $i . $ext;
#print "fn: $fn$LF";
		$UploadFile = Deps::MakePath($CrystalDBDir, $fn, 0);
	}
#	Utils::ConvertDirectorySeparator($UploadFile, '/', '\\', 0);

	print "Upload path: $UploadFile$LF";

#ファイルの保存
	unless (open (OUTFILE,">$UploadFile")) {
		print "Can not open $UploadFile: $!$LF$LF";
		exit;
	}
	binmode($filename);
	binmode(OUTFILE);

#保存用ファイルを無事 open できた場合
# $filename から内容を読み出して保存用ファイルに書き出す
#この場合、変数 $filename はファイルハンドルとして機能する
	my $buffer;
	my $count = 0;
	while (1) {
		my $ret = read($filename, $buffer, 1024);
		last if($ret == 0);
		$count += $ret;
		print OUTFILE $buffer;
	}
	print "Bytes uploaded: $count bytes.$LF";

#ファイルを close して終了メッセージを表示
#この場合、$filename は、送信元クライアント
#マシン内でのファイルパスを返す
	close (OUTFILE)
		and print "<H3>$filename is saved as $UploadFile.</H3>\n"
		or print "Could not close the file $UploadFile.<br>\n";

	print "<hr>\n";

	my $PrevAction = &GetArg('PreviousAction');
print "PrevAction: $PrevAction$LF";
	if($PrevAction =~ /^ShowCalculateRDF$/i) {
		&ShowCalculateRDF($Action);
	}
	elsif($PrevAction =~ /^ShowSimulateByRietan/i) {
		&ShowSimulateByRietan($Action);
	}
	elsif($PrevAction =~ /^ShowCalculateDistanceAngle$/i) {
		&ShowCalculateDistanceAngle($Action);
	}
	elsif($PrevAction =~ /^CalculateDiffractionAngles$/i) {
		&CalculateDiffractionAngles($Action);
	}
	else {
		&ShowCrystalDB($Action);
	}

	return;
}

sub ShowCrystalStructure
{
	print "<H1>Crystal Structure</H1>\n";

	my $SPG = $Crystal->GetCSpaceGroup();
	my $SPGName = $SPG->SPGName();
	my $iSPG    = $SPG->iSPG();
	my ($a,$b,$c,$alpha,$beta,$gamma) = $Crystal->LatticeParameters();
	my $vol = $Crystal->Volume();
	my $Density = $Crystal->Density();

	print "<b>Chemical formula:</b> ", 
		$CIF->GetContent("_chemical_formula_structural"), "$LF";
	print "<b>Space group:</b> $SPGName ($iSPG)$LF";
	print "<b>Lattice system:</b> ", $SPG->LatticeSystem(), "$LF";
	print "<b>Lattice parameters:</b>$LF";
	print "  a=$a A$LF";
	print "  b=$b A$LF";
	print "  c=$c A$LF";
	print "  alpha=$alpha$LF";
	print "  beta =$beta$LF";
	print "  gamma=$gamma$LF";
	my ($g11,$g12,$g13,$g21,$g22,$g23,$g31,$g32,$g33)
		= $Crystal->Metrics();
	print "<b>Metrics:</b>$LF";
	printf "  |%7.4f %7.4f %7.4f|$LF", $g11, $g12, $g13;
	printf "  |%7.4f %7.4f %7.4f|$LF", $g21, $g22, $g23;
	printf "  |%7.4f %7.4f %7.4f|$LF", $g31, $g32, $g33;
	my ($a11,$a12,$a13,$a21,$a22,$a23,$a31,$a32,$a33)
		= $Crystal->LatticeVectors();
	print "<b>Lattice Vectors:</b>$LF";
	printf "  |%7.4f %7.4f %7.4f|$LF", $a11, $a12, $a13;
	printf "  |%7.4f %7.4f %7.4f|$LF", $a21, $a22, $a23;
	printf "  |%7.4f %7.4f %7.4f|$LF", $a31, $a32, $a33;
	print "  Volume=$vol A<sup>3</sup>$LF";
	print "  Density=$Density g/cm<sup>3</sup>$LF";

	print "<b>Atom types:</b>$LF";
	my @AtomTypeList = $Crystal->GetCAtomTypeList();
	my $nAtomType = @AtomTypeList;
	print "nAtomType: $nAtomType$LF";
	for(my $i = 0 ; $i < $nAtomType ; $i++) {
		my $label    = $AtomTypeList[$i]->Label();
		my $atomname = $AtomTypeList[$i]->AtomName();
		my $charge   = $AtomTypeList[$i]->Charge();
		my $AtomicNumber = $AtomTypeList[$i]->AtomicNumber();
		my $AtomicMass   = $AtomTypeList[$i]->AtomicMass();
		my $i1 = $i+1;
		$AtomicMass = 'Mass not specified' if($AtomicMass eq '');
		print "   #$i1: $label : $atomname [$AtomicNumber] ($charge) "
			."($AtomicMass)$LF";
	}

	print "<b>Atoms in asymmetric unit:</b>$LF";
	my @AtomSiteList = $Crystal->GetCAsymmetricAtomSiteList();
	my $nAsymmetricAtomSite = @AtomSiteList;
	print "nAsymmetricAtomSite: $nAsymmetricAtomSite$LF";
	for(my $i = 0 ; $i < $nAsymmetricAtomSite ; $i++) {
		my $label     = $AtomSiteList[$i]->Label();
		my $type      = $AtomSiteList[$i]->AtomName();
		my ($x,$y,$z) = $AtomSiteList[$i]->Position(1);
		my $occupancy = $AtomSiteList[$i]->Occupancy();
		my $iAtomType = $Crystal->FindiAtomType($type);

		print "  $label($type) [#$iAtomType]: ($x, $y, $z) [$occupancy]$LF";
	}

	print "$LF";
	print "<b>Equivalent positions:</b>$LF";
	my $nTranslation = $SPG->nTranslation();
	print "nTranslation: $nTranslation$LF";
	for(my $i = 0 ; $i < $nTranslation ; $i++) {
		my ($x,$y,$z) = $SPG->TranslationVector($i+1);
		print "   ($x, $y, $z)$LF";
	}
	my $nSymmetryOperation = $SPG->nSymmetryOperation();
	print "nSymmetryOperation: $nSymmetryOperation$LF";
	for(my $i = 0 ; $i < $nSymmetryOperation ; $i++) {
		my $symop = $SPG->SymmetryOperation($i+1);
		my $i1 = $i+1;
		print "  $i1: $symop$LF";
	}

	print "$LF";
	print "<b>Expanded coordinates:</b>$LF";
	my @ExpandedAtomSiteList = $Crystal->GetCExpandedAtomSiteList();
	my $nTotalExpandedAtomSite = $Crystal->nTotalExpandedAtomSite();
	my @nMultiplicityExpandedAtomSiteList 
		= $Crystal->GetCnMultiplicityExpandedAtomSiteList();
	print "<b>Total atom number:</b> $nTotalExpandedAtomSite$LF";
	for(my $i = 0 ; $i < $nTotalExpandedAtomSite ; $i++) {
		my $label     = $ExpandedAtomSiteList[$i]->Label();
		my $type      = $ExpandedAtomSiteList[$i]->AtomName();
		my ($x,$y,$z) = $ExpandedAtomSiteList[$i]->Position(1);
		my $occupancy = $ExpandedAtomSiteList[$i]->Occupancy();
		my $id = $ExpandedAtomSiteList[$i]->IdAsymmetricAtomSite();
		my $mult = $nMultiplicityExpandedAtomSiteList[$id-1];
		my $i1 = $i+1;
		print "   $i1: [$id]$label ($type): ($x, $y, $z) "
			."[$occupancy][$mult]$LF";
	}
}

sub ExpandSuperLatticeCoordinate
{
	my ($UseAtomicUnit, $IsExpandCoordinate,
		$nExpandLatticeA, $nExpandLatticeB, $nExpandLatticeC,
		$IsChooseRandomly) = @_;

	$nExpandLatticeA = 1 if($nExpandLatticeA < 1);
	$nExpandLatticeB = 1 if($nExpandLatticeB < 1);
	$nExpandLatticeC = 1 if($nExpandLatticeC < 1);
	unless($IsExpandCoordinate) {
		$nExpandLatticeA = 1;
		$nExpandLatticeB = 1;
		$nExpandLatticeC = 1;
		$IsChooseRandomly = 0 
	}

	print "+<b>In sub ExpandSuperLatticeCoordinate:</b>$LF";
	print "++<b>IsExpandCoordinate=</b>$IsExpandCoordinate$LF";
	print "++<b>nExpandLattice=</b>($nExpandLatticeA, $nExpandLatticeB, $nExpandLatticeC)$LF";
	print "++<b>IsChooseRandomly=</b>$IsChooseRandomly$LF";

print "<H2>Create Super Lattice: Crystal.pm</H2>\n";
	$Crystal->CreateSuperLattice($nExpandLatticeA,$nExpandLatticeB, $nExpandLatticeC);
	my $SPG = $Crystal->GetCSpaceGroup();
	my $SuperLattice = $Crystal->GetCSuperLattice();

#基本的な結晶構造データを変数に代入
	if($IsExpandCoordinate) {
		if($IsChooseRandomly) {
			$Crystal->SetOutputMode('choose');
		}
		else {
			$Crystal->SetOutputMode('expanded');
		}
	}
	else {
		$Crystal->SetOutputMode('asymmetric');
	}

	my $SampleName = $Crystal->CrystalName();
	my $SPGName = $Crystal->SPGNameByOutputMode();
	my $iSPG    = $Crystal->iSPGByOutputMode();
	my $WIEN2kSPGName = SpaceGroup::GetWIEN2kSPG($iSPG);
	my ($a,$b,$c,$alpha,$beta,$gamma) 
		= $Crystal->LatticeParametersByOutputMode($UseAtomicUnit);

	my @AsymmetricAtomSiteList  = $Crystal->GetCAsymmetricAtomSiteList();
	my $nAsymmetricAtomSite     = @AsymmetricAtomSiteList;

	my @ExpandedAtomSiteList    = $Crystal->GetCExpandedAtomSiteListByOutputMode();
	my $nExpandedAtomSiteList  = @ExpandedAtomSiteList;

#ファイルに書き込む結晶構造をWeb上に表示
	print "<H2>Crystal structure to be written.</H2>\n";
	print "<b>++Sample:</b> $SampleName$LF";
	if($IsExpandCoordinate) {
		print "++<b>Unit cell is expanded by</b> "
			."($nExpandLatticeA, $nExpandLatticeB, $nExpandLatticeC)$LF";
	}
	printf "<b>++Lattice parameters:</b> %10.6f %10.6f %10.6f  %12.6f %12.6f %12.6f$LF",
		$a, $b, $c, $alpha, $beta,$gamma;
	print "<b>++Space group:</b> $SPGName$LF";
	print "<b>++nAtomSites:</b> $nExpandedAtomSiteList$LF";

	for(my $i = 0 ; $i < $nExpandedAtomSiteList ; $i++) {
		my $atom      = $ExpandedAtomSiteList[$i];
		my $label     = $atom->Label();
		my $name      = $atom->AtomName();
		my ($x,$y,$z) = $atom->Position(1);
		my $occupancy = $atom->Occupancy();
		my $id        = $atom->Id();
		my $mult      = $atom->Multiplicity();

		my $i1 = $i+1;
print "+++$i1: $label: $name (id=$id): ($x, $y, $z) [occ=$occupancy][mult=$mult]$LF";
	}

	return 1;
}

sub ListPartialOccupancyAtoms
{
	my @ExpandedAtomSiteList    = $Crystal->GetCExpandedAtomSiteListByOutputMode();
	my $nPartialAtom = 0;
	for(my $i = 0 ; $i < @ExpandedAtomSiteList ; $i++) {
		my $atom      = $ExpandedAtomSiteList[$i];
		my $occupancy = $atom->Occupancy();
		$nPartialAtom++ if($occupancy < 0.9999);
	}
	return 0 if($nPartialAtom == 0);

	print OUT "\n\n\n";

	print OUT "Partial Occupancy atoms:\n";
	print OUT "ATOM  i [Name]: X=xxx Y=yyy Z=zzz  Occupancy  Id\n";

	for(my $i = 0 ; $i < @ExpandedAtomSiteList ; $i++) {
		my $atom      = $ExpandedAtomSiteList[$i];
		my $atomname  = $atom->AtomNameOnly();
		my $charge    = $atom->Charge();
		my ($x,$y,$z) = $atom->Position(1);
		my $occupancy = $atom->Occupancy();
		my $id        = $atom->Id();
		next if($occupancy > 0.9999);

		printf OUT "ATOM i=%3d[%2s(ID=%3d)]: X=%10.8f Y=%10.8f Z=%10.8f  Occ=%9.4f\n",
			$i, $atomname, $id, $x, $y, $z, $occupancy;
	}

	return 1;
}

sub MakeVASPFiles
{
	print "<b>Make VASP Files:</b>$LF";

	my $UseConventionalCell = &GetArg('UseConventionalCell');
	my @Function   = &GetArg('VASPFunction');
	my $Function   = $Function[0];
	my @Functional = &GetArg('VASPFunctional');
	my $Functional = $Functional[0];
	my $UseDPP     = &GetArg('VASPUseDPP');
	my $SpinPolarized = &GetArg('VASPSpinPolarized');
	if($SpinPolarized eq '') {
		$SpinPolarized = 'No';
	}
	else {
		$SpinPolarized = 'Yes';
	}

	my $IsExpandCoordinate = 1;
	my $nExpandLatticeA    = &GetArg("VASPExpandLatticeA");
	$nExpandLatticeA = 1 if($nExpandLatticeA < 1);
	my $nExpandLatticeB    = &GetArg("VASPExpandLatticeB");
	$nExpandLatticeB = 1 if($nExpandLatticeB < 1);
	my $nExpandLatticeC    = &GetArg("VASPExpandLatticeC");
	$nExpandLatticeC = 1 if($nExpandLatticeC < 1);
	my $IsChooseRandomly   = &GetArg("VASPChooseRandomly");

	if($UseConventionalCell ne 'ON' and
	    ($nExpandLatticeA != 1 or
	     $nExpandLatticeB != 1 or
	     $nExpandLatticeC != 1 or
	     $IsChooseRandomly eq 'ON')) {
		print "<H2>Warning: UseConventionalCell=FALSE is not compatible with "
			. "ExpandLattice and RandomlyChoose flags</H2>\n";
		print "<H2>         UseConventionalCell flag is set TRUE.</H2>\n";
		$UseConventionalCell = 'ON';
	}
#	if($UseConventionalCell ne 'ON') {
#		$IsExpandCoordinate = '';
#	}
	
	print "<b>Use conventional Cell:</b> $UseConventionalCell$LF";
	print "<b>Function:</b>   $Function$LF";
	print "<b>Functional:</b> $Functional$LF";
	print "<b>Use _d PP:</b> $UseDPP$LF";
	print "<b>Spin Polarized:</b> $SpinPolarized$LF";

	&ExpandSuperLatticeCoordinate(0, $IsExpandCoordinate, 
		$nExpandLatticeA, $nExpandLatticeB, $nExpandLatticeC,
		$IsChooseRandomly);

	my $CIFFile = &GetArg("FILE");
#ファイル名を（ベース名, ディレクトリ名, 拡張子）に分解
	my @filenames = fileparse($CIFFile, "\.[^\.]+");
#	my $fname = "INCAR";
#	my $NewFile = Deps::MakePath($CrystalVASPFileDir, $fname, 0);

#Primitive Cellをつくる
	my $SPG = $Crystal->GetCSpaceGroup();
	my $SPGName = $SPG->SPGName();
	my ($CellType) = ($SPGName =~ /^\s*(.)/);
	if($UseConventionalCell ne 'ON' and $SPGName =~ /^\s*[FIABC]/i) {
		my $PrimCIFFile = Deps::MakePath($CrystalVASPFileDir, "${filenames[0]}-Primitive.cif");
		print "<H2>Make Primitive Cell.</H2>\n";
		print "  CIF File: $PrimCIFFile$LF";

		print "  SpaceGroup: $SPGName$LF";
		
		my $T = new Math::MatrixReal(3, 3);
		if($SPGName =~ /^\s*F/i) {
			$T = Math::MatrixReal->new_from_cols( 
				[ [ 0.5, 0.5,   0], 
				  [ 0,   0.5, 0.5],
				  [ 0.5,   0, 0.5] ] );
			$T->transpose($T);
		}
		elsif($SPGName =~ /^\s*I/i) {
			$T = Math::MatrixReal->new_from_cols( 
				[ [-0.5, 0.5, 0.5], 
				  [ 0.5,-0.5, 0.5],
				  [ 0.5, 0.5,-0.5] ] );
			$T->transpose($T);
		}
		elsif($SPGName =~ /^\s*A/i) {
			$T = Math::MatrixReal->new_from_cols( 
				[ [ 1.0, 0.0, 0.0], 
				  [ 0.0, 0.5, 0.5],
				  [ 0.0,-0.5, 0.5] ] );
			$T->transpose($T);
		}
		elsif($SPGName =~ /^\s*B/i) {
			$T = Math::MatrixReal->new_from_cols( 
				[ [ 0.5, 0.0, 0.5], 
				  [ 0.0, 1.0, 0.0],
				  [-0.5, 0.0, 0.5] ] );
			$T->transpose($T);
		}
		elsif($SPGName =~ /^\s*C/i) {
			$T = Math::MatrixReal->new_from_cols( 
				[ [ 0.5, 0.5, 0.0], 
				  [-0.5, 0.5, 0.0],
				  [ 0.0, 0.0, 1.0] ] );
			$T->transpose($T);
		}

#実空間べクトル(ai)の変換行列
		print "Conversion matrix for real space vector: (<b>a'<sub>i</sub></b>) = "
			."(T<sub>ij</sub>)(<b>a<sub>i</sub></b>)$LF";
		print "<pre>\n";
		printf "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|%10.4f %10.4f %10.4f|\n", 
			$T->element(1,1), $T->element(1,2), $T->element(1,3);
		printf "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|%10.4f %10.4f %10.4f|\n", 
			$T->element(2,1), $T->element(2,2), $T->element(2,3);
		printf "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|%10.4f %10.4f %10.4f|\n", 
			$T->element(3,1), $T->element(3,2), $T->element(3,3);
		print "</pre>\n";

		my $PrimCrystal = $Crystal->ConvertLattice($T, 0, 1);
		my $PrimCIF = new CIF;
		$PrimCIF->CreateCIFFileFromCCrystal($PrimCrystal, $PrimCIFFile, 0, "unix");
		&ShowFileLink($WebRootDir, $PrimCIFFile, "Primitive cell CIF");
		
		$Crystal = $PrimCrystal;
		$CellType = "$CellType-Primitive";

		print "$LF";
	}

	print "<H2>Make VASP files.</H2>\n";
	print "  Cell type: $CellType$LF";
	my $VASP = new VASP();
	my $SampleName = $filenames[0];
	$VASP->SetSampleName($SampleName);
	my $KListDBDir = Deps::MakePath($WebRootDir, "Research", 1);
	$KListDBDir = Deps::MakePath($KListDBDir, "klist", 1);
	$VASP->SetKListDBDir($KListDBDir);
	print "klist DB dir: $KListDBDir$LF";
	my @Files = $VASP->SaveVASPFiles($Crystal, $CellType, $UseConventionalCell, $Function, $Functional, 
				$UseDPP, $SpinPolarized, 
				$CrystalVASPFileDir, $IsChooseRandomly);

	print "<b>VASP Files:</b> $LF";
	for(my $i = 0 ; $i < @Files ; $i++) {
		my @filenames = fileparse($Files[$i], "\.[^\.]+");
		&ShowFileLink($WebRootDir, $Files[$i], $filenames[0] . $filenames[2])
			if(-e $Files[$i]);
	}
	return;
}

sub MakeCRYSTAL06Files
{
	print "<b>Make CRYSTAL06 Files:</b>$LF";

	my $IsExpandCoordinate = &GetArg('CRYSTAL06ExpandCoordinate');
	my $UseConventionalCell = &GetArg('UseConventionalCell');
	my @Function   = &GetArg('CRYSTAL06Function');
	my $Function   = $Function[0];
	my $SpinPolarized = &GetArg('CRYSTAL06SpinPolarized');
	if($SpinPolarized eq '') {
		$SpinPolarized = 'No';
	}
	else {
		$SpinPolarized = 'Yes';
	}

	print "<b>IsExpandCoordinate:</b>   $IsExpandCoordinate";
	print "<b>Function:</b>   $Function$LF";
	print "<b>Spin Polarized:</b> $SpinPolarized$LF";
	my $nExpandLatticeA    = &GetArg("CRYSTAL06ExpandLatticeA");
	$nExpandLatticeA = 1 if($nExpandLatticeA < 1);
	my $nExpandLatticeB    = &GetArg("CRYSTAL06ExpandLatticeB");
	$nExpandLatticeB = 1 if($nExpandLatticeB < 1);
	my $nExpandLatticeC    = &GetArg("CRYSTAL06ExpandLatticeC");
	$nExpandLatticeC = 1 if($nExpandLatticeC < 1);
	my $IsChooseRandomly   = &GetArg("CRYSTAL06ChooseRandomly");

	&ExpandSuperLatticeCoordinate(0, $IsExpandCoordinate, 
		$nExpandLatticeA, $nExpandLatticeB, $nExpandLatticeC,
		$IsChooseRandomly);

	my $CIFFile = &GetArg("FILE");
#ファイル名を（ベース名, ディレクトリ名, 拡張子）に分解
	my @filenames = fileparse($CIFFile, "\.[^\.]+");

	print "<H2>Make CRYSTAL06 files.</H2>\n";
	my $CRYSTAL06 = new CRYSTAL06;
	my $SampleName = $filenames[0];
	$CRYSTAL06->SetSampleName($SampleName);
	my @Files = $CRYSTAL06->SaveInputFiles($Crystal, $Function, $SpinPolarized, 
				$CrystalVASPFileDir, $IsChooseRandomly);

	print "<b>CRYSTAL06 Files:</b> $LF";
	for(my $i = 0 ; $i < @Files ; $i++) {
		my @filenames = fileparse($Files[$i], "\.[^\.]+");
		&ShowFileLink($WebRootDir, $Files[$i], $filenames[0] . $filenames[2])
			if(-e $Files[$i]);
	}
	return;
}

sub MakePWSCFFile
{
	print "<b>Make PWSCF File:</b>$LF";

	my @Function = &GetArg('PWSCFFunction');
	my $Function = $Function[0];
# scf nscf relax vc-relax md phonon
	my $UseBravaisLattice = &GetArg('PWSCFUseBravaisLattice');
	my $PWSCFUseCELLDM    = &GetArg('PWSCFUseCELLDM');
#print "<H1>UseBravaisLattice: $UseBravaisLattice</H1>\n";
	my @PP = &GetArg('PWSCFPseudoPotential');
	my $PP = $PP[0];
#pz pbe

	print("<b>DBDir:</b> $CrystalPWSCFFileDir<br>\n");
	print "<b>Function:</b> $Function<br>\n";
	print "<b>Pseudo Potential:</b> $PP<br>\n";
	print "<br>\n";

	my $IsExpandCoordinate = 1;
	my $nExpandLatticeA    = &GetArg("PWSCFExpandLatticeA");
	$nExpandLatticeA = 1 if($nExpandLatticeA < 1);
	my $nExpandLatticeB    = &GetArg("PWSCFExpandLatticeB");
	$nExpandLatticeB = 1 if($nExpandLatticeB < 1);
	my $nExpandLatticeC    = &GetArg("PWSCFExpandLatticeC");
	$nExpandLatticeC = 1 if($nExpandLatticeC < 1);
	my $IsChooseRandomly   = &GetArg("PWSCFChooseRandomly");

	&ExpandSuperLatticeCoordinate(0, $IsExpandCoordinate, 
		$nExpandLatticeA, $nExpandLatticeB, $nExpandLatticeC,
		$IsChooseRandomly);

	my $CIFFile = &GetArg("FILE");
#ファイル名を（ベース名, ディレクトリ名, 拡張子）に分解
	my @filenames = fileparse($CIFFile, "\.[^\.]+");
	my $fname = $filenames[0] . ".inp";
	my $NewFile = Deps::MakePath($CrystalPWSCFFileDir, $fname, 0);

	my $PWSCF = new PWSCF();
	my $SampleName = $fname;
	$SampleName =~ s/\..*$//;
	$PWSCF->SetSampleName($SampleName);
	
	if($UseBravaisLattice eq 'ON') {
		$UseBravaisLattice = 1;
	}
	else {
		$UseBravaisLattice = 0;
	}
	my @Files = $PWSCF->SavePWSCFInpFile($Function, $PP, $Crystal, $NewFile, 
						$IsChooseRandomly, $UseBravaisLattice, $PWSCFUseCELLDM);

	print "<b>PWScf Files:</b> $LF";
#	&ShowFileLink($WebRootDir, $NewFile, $fname);
	for(my $i = 0 ; $i < @Files ; $i++) {
		my @filenames = fileparse($Files[$i], "\.[^\.]+");
		if($Files[$i] =~ /^http/i) {
			print "--<a href=\"$Files[$i]\">$Files[$i]</a><br>\n";
		}
		elsif(-e $Files[$i]) {
			print "----";
			&ShowFileLink($WebRootDir, $Files[$i], $filenames[0] . $filenames[2])
		}
		;
	}

	return;
}

sub MakeTranSIESTAFiles
{
	print "<b>Make TranSIESTA-C File:</b>$LF";

	my @Function = &GetArg('TranSIESTAFunction');
	my $Function = $Function[0];
	my @BasisSet = &GetArg('TranSIESTABasisSet');
	my $BasisSet = $BasisSet[0];
	my @Version  = &GetArg('TranSIESTAVersion');
	my $Version  = $Version[0];
	my @XCFunctional = &GetArg('TranSIESTAXCFunctional');
	my $XCFunctional = $XCFunctional[0];
	my @InitialSpin  = &GetArg('TranSIESTAInitialSpin');
	my $InitialSpin  = $InitialSpin[0];

	my $IsExpandCoordinate = 1;
	my $nExpandLatticeA    = &GetArg("TranSIESTAExpandLatticeA");
	$nExpandLatticeA = 1 if($nExpandLatticeA < 1);
	my $nExpandLatticeB    = &GetArg("TranSIESTAExpandLatticeB");
	$nExpandLatticeB = 1 if($nExpandLatticeB < 1);
	my $nExpandLatticeC    = &GetArg("TranSIESTAExpandLatticeC");
	$nExpandLatticeC = 1 if($nExpandLatticeC < 1);
	my $IsChooseRandomly   = &GetArg("TranSIESTAChooseRandomly");

	&ExpandSuperLatticeCoordinate(0, $IsExpandCoordinate, 
		$nExpandLatticeA, $nExpandLatticeB, $nExpandLatticeC,
		$IsChooseRandomly);

	my $CIFFile = &GetArg("FILE");
#ファイル名を（ベース名, ディレクトリ名, 拡張子）に分解
	my @filenames = fileparse($CIFFile, "\.[^\.]+");
	my $fname = $filenames[0] . ".atk";
	my $NewFile = Deps::MakePath($CrystalTranSIESTAFileDir, $fname, 0);

	my $SIESTA = new TranSIESTA();
	my $SampleName = $fname;
	$SampleName =~ s/\..*$//;
	$SIESTA->SetSampleName($SampleName);
	my $KListDBDir = Deps::MakePath($WebRootDir, "Research", 1);
	$KListDBDir = Deps::MakePath($KListDBDir, "klist", 1);
	$SIESTA->SetKListDBDir($KListDBDir);
	print "klist DB dir: $KListDBDir$LF";
	my @Files = $SIESTA->SaveTranSIESTAATKFile(
			$Crystal, $NewFile, $Function, $BasisSet, $Version,
			$XCFunctional, $InitialSpin, $IsChooseRandomly);

	print "<b>.atk (TranSIESTA-C) File:</b> $LF";
	for(my $i = 0 ; $i < @Files ; $i++) {
		my @filenames = fileparse($Files[$i], "\.[^\.]+");
		&ShowFileLink($WebRootDir, $Files[$i], $filenames[0] . $filenames[2])
			if(-e $Files[$i]);
	}
#	&ShowFileLink($WebRootDir, $NewFile, $fname);
	
	return;
}

sub MakeCASTEPCIFFile
{
	print "<b>Make CIF File:</b>$LF";

	my $IsExpandCoordinate = &GetArg("CIFExpandCoordinate");
	my $nExpandLatticeA    = &GetArg("CIFExpandLatticeA");
	$nExpandLatticeA = 1 if($nExpandLatticeA < 1);
	my $nExpandLatticeB    = &GetArg("CIFExpandLatticeB");
	$nExpandLatticeB = 1 if($nExpandLatticeB < 1);
	my $nExpandLatticeC    = &GetArg("CIFExpandLatticeC");
	$nExpandLatticeC = 1 if($nExpandLatticeC < 1);
	my $IsChooseRandomly   = &GetArg("CIFChooseRandomly");

	&ExpandSuperLatticeCoordinate(0, $IsExpandCoordinate, 
		$nExpandLatticeA, $nExpandLatticeB, $nExpandLatticeC,
		$IsChooseRandomly);

#ファイル名を（ベース名, ディレクトリ名, 拡張子）に分解
	my $CIFFile = &GetArg("FILE");
	my @filenames = fileparse($CIFFile, "\.[^\.]+");
	my $fname = $filenames[0] . ".cif";
	my $NewFile = Deps::MakePath($CrystalCommonFileDir, $fname, 0);
	my $fnameUnix = $filenames[0] . "-unix.cif";
	my $NewFileUnix = Deps::MakePath($CrystalCommonFileDir, $fnameUnix, 0);

	my $SampleName = $filenames[0];
	
	my $CIF = new CIF();
	$CIF->SetCrystalName($SampleName);
	$CIF->CreateCIFFileFromCCrystal($Crystal, $NewFile, $IsChooseRandomly, "win");
	$CIF->CreateCIFFileFromCCrystal($Crystal, $NewFileUnix, $IsChooseRandomly, "unix");

	print "<b>.CIF File (CASTEP etc.):</b>$LF";
	&ShowFileLink($WebRootDir, $NewFile, $fname);
	&ShowFileLink($WebRootDir, $NewFileUnix, "$fnameUnix(unix)");
	print "$LF";

	return;
}

sub MakeBDLFile
{
	print "<b>Make SCIGRESS/MD-ME .bdl File:</b>$LF";

	my $IsExpandCoordinate = &GetArg("BDLExpandCoordinate");
	my $nExpandLatticeA    = &GetArg("BDLExpandLatticeA");
	$nExpandLatticeA = 1 if($nExpandLatticeA < 1);
	my $nExpandLatticeB    = &GetArg("BDLExpandLatticeB");
	$nExpandLatticeB = 1 if($nExpandLatticeB < 1);
	my $nExpandLatticeC    = &GetArg("BDLExpandLatticeC");
	$nExpandLatticeC = 1 if($nExpandLatticeC < 1);
	my $IsChooseRandomly   = &GetArg("BDLChooseRandomly");

	&ExpandSuperLatticeCoordinate(0, $IsExpandCoordinate, 
		$nExpandLatticeA, $nExpandLatticeB, $nExpandLatticeC,
		$IsChooseRandomly);

#ファイル名を（ベース名, ディレクトリ名, 拡張子）に分解
	my $CIFFile = &GetArg("FILE");
	my @filenames = fileparse($CIFFile, "\.[^\.]+");
	my $fname = $filenames[0] . ".bdl";
	my $NewFile = Deps::MakePath($CrystalCommonFileDir, $fname, 0);
	my $SampleName = $fname;
	$SampleName =~ s/\..*$//;
	
	my $SCIGRESS = new SCIGRESS;
	$SCIGRESS->SetSampleName($SampleName);
	$SCIGRESS->SaveBDLFile($Crystal, $NewFile, $IsChooseRandomly, 1);

	print "<b>.bdl File (SCIGRESS/MD-ME):</b> ";
	&ShowFileLink($WebRootDir, $NewFile, $fname);
	print "$LF";

	return;
}

sub MakeCARFile
{
	print "<b>Make CAR File:</b>$LF";

	my $IsExpandCoordinate = &GetArg("CARExpandCoordinate");
	my $nExpandLatticeA    = &GetArg("CARExpandLatticeA");
	$nExpandLatticeA = 1 if($nExpandLatticeA < 1);
	my $nExpandLatticeB    = &GetArg("CARExpandLatticeB");
	$nExpandLatticeB = 1 if($nExpandLatticeB < 1);
	my $nExpandLatticeC    = &GetArg("CARExpandLatticeC");
	$nExpandLatticeC = 1 if($nExpandLatticeC < 1);
	my $IsChooseRandomly   = &GetArg("CARChooseRandomly");

	&ExpandSuperLatticeCoordinate(0, $IsExpandCoordinate, 
		$nExpandLatticeA, $nExpandLatticeB, $nExpandLatticeC,
		$IsChooseRandomly);

#ファイル名を（ベース名, ディレクトリ名, 拡張子）に分解
	my $CIFFile = &GetArg("FILE");
	my @filenames = fileparse($CIFFile, "\.[^\.]+");
	my $fname = $filenames[0] . ".car";
	my $NewFile = Deps::MakePath($CrystalCommonFileDir, $fname, 0);
	my $SampleName = $fname;
	$SampleName =~ s/\..*$//;
	
	my $CASTEP = new CASTEP();
	$CASTEP->SetSampleName($SampleName);
	$CASTEP->SaveCARFile($Crystal, $NewFile, $IsChooseRandomly);

	print "<b>.CAR (Cartesian) File (CASTEP):</b> ";
	&ShowFileLink($WebRootDir, $NewFile, $fname);
	print "$LF";

	return;
}

sub MakeKHLabFile
{
	print "<b>Make KHLab Common Crystal Structure Format File:</b>$LF";

	my $IsExpandCoordinate = &GetArg("KHLabExpandCoordinate");
	my $nExpandLatticeA    = &GetArg("KHLabExpandLatticeA");
	$nExpandLatticeA = 1 if($nExpandLatticeA < 1);
	my $nExpandLatticeB    = &GetArg("KHLabExpandLatticeB");
	$nExpandLatticeB = 1 if($nExpandLatticeB < 1);
	my $nExpandLatticeC    = &GetArg("KHLabExpandLatticeC");
	$nExpandLatticeC = 1 if($nExpandLatticeC < 1);
	my $IsChooseRandomly = &GetArg("KHLabChooseRandomly");

	&ExpandSuperLatticeCoordinate(0, $IsExpandCoordinate, 
		$nExpandLatticeA, $nExpandLatticeB, $nExpandLatticeC,
		$IsChooseRandomly);

#ファイル名を（ベース名, ディレクトリ名, 拡張子）に分解
	my $CIFFile = &GetArg("FILE");
	my @filenames = fileparse($CIFFile, "\.[^\.]+");
	my $fname = $filenames[0] . ".khc";
	my $NewFile = Deps::MakePath($CrystalCommonFileDir, $fname, 0);
	my $SampleName = $fname;
	$SampleName =~ s/\..*$//;

#ファイル作製開始
	unless(open(OUT,">$NewFile")) {
		print "Can not write to $NewFile.$LF$LF";
		return;
	}

	print OUT "[Title]\n";
	print OUT "$SampleName\n";

	my $SPG = $Crystal->GetCSpaceGroup();
	my $SPGName = $Crystal->SPGName();
	my $iSPG = $Crystal->iSPG();

	print OUT "[SpaceGroupName]\n";
	print OUT "$SPGName\n";
	print OUT "$iSPG\n";

	my ($a,$b,$c,$alpha,$beta,$gamma) 
		= $Crystal->LatticeParametersByOutputMode(0);
	print OUT "[LatticeParameters]\n";
	printf OUT "%10.6f%10.6f%10.6f%10.6f%10.6f%10.6f\n",
		$a, $b, $c, $alpha, $beta, $gamma;

	print OUT "\n";

	print OUT "[nTotalAsymmetricSites]\n";
	print OUT "{nTotalExpandedAtomSite}\n";
	print OUT "[AtomsInAsymmetricUnit]\n";

	my @ExpandedAtomSiteList    = $Crystal->GetCExpandedAtomSiteListByOutputMode();
	my $nExpandedAtomSite = @ExpandedAtomSiteList;

#Occupancyが1のサイト
	my $count = 0;
	for(my $i = 0 ; $i < $nExpandedAtomSite ; $i++) {
		my $atom      = $ExpandedAtomSiteList[$i];
		my $atomname  = $atom->AtomNameOnly();
		my $charge    = $atom->Charge();
		my ($x,$y,$z) = $atom->Position(1);
		my $occupancy = $atom->Occupancy();
		my $mult      = $atom->Multiplicity();
		$mult = 1 if($IsExpandCoordinate or $IsChooseRandomly);
		next if($occupancy < 0.9999);

		$count++;
		printf OUT "%03d\n", $count;
		print OUT "$atomname\n";
		print OUT "$charge\n";
		printf OUT "%10.8f %10.8f %10.8f  %10.8f\n", $x, $y, $z, $occupancy;
	}
#Occupancyが1未満のサイト
	for(my $i = 0 ; $i < $nExpandedAtomSite ; $i++) {
		my $atom      = $ExpandedAtomSiteList[$i];
		my $atomname  = $atom->AtomNameOnly();
		my $charge    = $atom->Charge();
		my ($x,$y,$z) = $atom->Position(1);
		my $occupancy = $atom->Occupancy();
		my $mult      = $atom->Multiplicity();
		$mult = 1 if($IsExpandCoordinate or $IsChooseRandomly);
		next if($occupancy >= 0.9999);

		$count++;
		printf OUT "%03d\n", $count;
		print OUT "$atomname\n";
		print OUT "$charge\n";
		printf OUT "%10.8f %10.8f %10.8f  %10.8f\n", $x, $y, $z, $occupancy;
	}

	print OUT "\n";
	print OUT "[SpaceGroup]\n";
#対称操作
	my @SymmetryOperation = $SPG->ExpandSymmetryOperation();
	my $nSymmetryOperation = @SymmetryOperation;

	print OUT "$SPGName\n";
	print OUT "$iSPG\n";
	print OUT "[nSymmetryOperation]\n";
	print OUT "$nSymmetryOperation\n";
	print OUT "[SymmetryOperation]\n";
	for(my $i = 0 ; $i < $nSymmetryOperation ; $i++) {
		my $SymOp = $SymmetryOperation[$i];
		Utils::DelSpace($SymOp);
		
		printf OUT "%03d\n", $i+1;
		print  OUT "$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]);
		printf OUT "%10.7f %10.7f %10.7f %10.7f \n",
			$XMatrix[0], $XMatrix[1], $XMatrix[2], $XMatrix[3];
		printf OUT "%10.7f %10.7f %10.7f %10.7f \n",
			$YMatrix[0], $YMatrix[1], $YMatrix[2], $YMatrix[3];
		printf OUT "%10.7f %10.7f %10.7f %10.7f \n",
			$ZMatrix[0], $ZMatrix[1], $ZMatrix[2], $ZMatrix[3];
		printf OUT "     %3d\n", $i+1;
	}

	close(OUT);

	unless(open(IN,"<$NewFile")) {
		print "Can not read $NewFile.$LF$LF";
		return;
	}
	my $buff;
	my $s = sprintf("%3d", $count-1); 
	while(<IN>) {
		my $line = $_;
		$line =~ s/{nTotalExpandedAtomSite}/$s/sg;
		$buff .= $line;
	}
	close(IN);
	unless(open(OUT,">$NewFile")) {
		print "Can not re-write to $NewFile.$LF$LF";
		return;
	}
	print OUT $buff;
	close(OUT);
	
	print "<b>KHLab Common Crystal Structure Format File:</b> ";
	&ShowFileLink($WebRootDir, $NewFile, $fname);
	print "$LF";

	return;
}

sub MakeTBFile
{
	print "<b>Make Tight-binding Input File:</b>$LF";

	my $IsExpandCoordinate = &GetArg("TBExpandCoordinate");
	my $nExpandLatticeA    = &GetArg("TBExpandLatticeA");
	$nExpandLatticeA = 1 if($nExpandLatticeA < 1);
	my $nExpandLatticeB    = &GetArg("TBExpandLatticeB");
	$nExpandLatticeB = 1 if($nExpandLatticeB < 1);
	my $nExpandLatticeC    = &GetArg("TBExpandLatticeC");
	$nExpandLatticeC = 1 if($nExpandLatticeC < 1);
	my $IsChooseRandomly = &GetArg("TBChooseRandomly");

	&ExpandSuperLatticeCoordinate(1, $IsExpandCoordinate, 
		$nExpandLatticeA, $nExpandLatticeB, $nExpandLatticeC,
		$IsChooseRandomly);

#ファイル名を（ベース名, ディレクトリ名, 拡張子）に分解
	my $CIFFile = &GetArg("FILE");
	my @filenames = fileparse($CIFFile, "\.[^\.]+");
	my $fname = $filenames[0] . ".inp";
	my $NewFile = Deps::MakePath($CrystalWIEN2kFileDir, $fname, 0);
	my $SampleName = $fname;
	$SampleName =~ s/\..*$//;

	my $TB = new TB;
	$TB->SetSampleName($SampleName);
	my $DVXaDir = Deps::MakePath($ProgramDir, "DVXa97", 1);
	$DVXaDir = Deps::MakePath($DVXaDir, "exec", 1);
	my $NonRelDir = $TB->SetNonRelDir($DVXaDir);
	my $NonRelPath = $TB->NonRelPath();
	print "Nonrel path: $NonRelPath$LF";
	my $KListDBDir = Deps::MakePath($WebRootDir, "Research", 1);
	$KListDBDir = Deps::MakePath($KListDBDir, "klist", 1);
	$TB->SetKListDBDir($KListDBDir);
	print "klist DB dir: $KListDBDir$LF";

	my @Files = $TB->SaveTBInputFile($Crystal, $NewFile);

	print "<b>Tight-binding Input File:</b>$LF";
	for(my $i = 0 ; $i < @Files ; $i++) {
		my @filenames = fileparse($Files[$i], "\.[^\.]+");
		&ShowFileLink($WebRootDir, $Files[$i], $filenames[0] . $filenames[2])
			if(-e $Files[$i]);
	}
	print "$LF";

	return;
}

sub MakeWIEN2kStructFile
{
	print "<b>Make WIEN2k Struct File:</b>$LF";

	my $IsExpandCoordinate = &GetArg("WEIN2kStructExpandCoordinate");
	my $nExpandLatticeA    = &GetArg("WIEN2kExpandLatticeA");
	$nExpandLatticeA = 1 if($nExpandLatticeA < 1);
	my $nExpandLatticeB    = &GetArg("WIEN2kExpandLatticeB");
	$nExpandLatticeB = 1 if($nExpandLatticeB < 1);
	my $nExpandLatticeC    = &GetArg("WIEN2kExpandLatticeC");
	$nExpandLatticeC = 1 if($nExpandLatticeC < 1);
	my $IsChooseRandomly = &GetArg("WEIN2kStructChooseRandomly");

	&ExpandSuperLatticeCoordinate(1, $IsExpandCoordinate, 
		$nExpandLatticeA, $nExpandLatticeB, $nExpandLatticeC,
		$IsChooseRandomly);

#ファイル名を（ベース名, ディレクトリ名, 拡張子）に分解
	my $CIFFile = &GetArg("FILE");
	my @filenames = fileparse($CIFFile, "\.[^\.]+");
	my $fname = $filenames[0] . ".struct";
	my $NewFile = Deps::MakePath($CrystalWIEN2kFileDir, $fname, 0);
	my $SampleName = $fname;
	$SampleName =~ s/\..*$//;

	my $WIEN = new WIEN2k;
	$WIEN->SetSampleName($SampleName);
	$WIEN->SaveStructFile($Crystal, $NewFile, 
			$IsExpandCoordinate, $IsChooseRandomly);

	my $KListDBDir = Deps::MakePath($WebRootDir, "Research", 1);
	$KListDBDir = Deps::MakePath($KListDBDir, "klist", 1);
	my $XC = new XCrySDen;
	my $KListDBDir = $XC->SetKListDBDir($KListDBDir);
	print "klist DB dir: $KListDBDir$LF";
	my $SPGName = $Crystal->SPGName();
	my $iSPG    = $Crystal->iSPG();
	my ($KListFilePath, @KList) = $XC->ReadKList($iSPG, $SPGName);

	my @Files = ($KListFilePath, $NewFile);
	print "<b>WIEN2k Struct File:</b>$LF";
	for(my $i = 0 ; $i < @Files ; $i++) {
		my @filenames = fileparse($Files[$i], "\.[^\.]+");
		&ShowFileLink($WebRootDir, $Files[$i], $filenames[0] . $filenames[2])
			if(-e $Files[$i]);
	}

	print "$LF";

	return;
}

sub MakeWIEN2kXYZFile
{
	print "<b>Make WIEN2k XYZ File:</b>$LF";

	my $IsExpandCoordinate = &GetArg("WEIN2kStructExpandCoordinate");
	my $nExpandLatticeA    = &GetArg("WIEN2kExpandLatticeA");
	$nExpandLatticeA = 1 if($nExpandLatticeA < 1);
	my $nExpandLatticeB    = &GetArg("WIEN2kExpandLatticeB");
	$nExpandLatticeB = 1 if($nExpandLatticeB < 1);
	my $nExpandLatticeC    = &GetArg("WIEN2kExpandLatticeC");
	$nExpandLatticeC = 1 if($nExpandLatticeC < 1);
	my $IsChooseRandomly = &GetArg("WEIN2kStructChooseRandomly");

	&ExpandSuperLatticeCoordinate(1, $IsExpandCoordinate, 
		$nExpandLatticeA, $nExpandLatticeB, $nExpandLatticeC,
		$IsChooseRandomly);

#ファイル名を（ベース名, ディレクトリ名, 拡張子）に分解
	my $CIFFile = &GetArg("FILE");
	my @filenames = fileparse($CIFFile, "\.[^\.]+");
	my $fname = $filenames[0] . ".struct";
	my $NewFile = Deps::MakePath($CrystalWIEN2kFileDir, $fname, 0);
	my $SampleName = $fname;
	$SampleName =~ s/\..*$//;

	my $WIEN = new WIEN2k;
	$WIEN->SetSampleName($SampleName);
	$WIEN->SaveXYZFile($Crystal, $NewFile, 
			$IsExpandCoordinate, $IsChooseRandomly);

	print "<b>xyz2struct (in WIEN2k package) File:</b> ";
	&ShowFileLink($WebRootDir, $NewFile, $fname);
	print "$LF";

	return;
}

sub MakeGULPFiles
{
	print "<b>Make GULP File:</b>$LF";

	my $IsExpandCoordinate = &GetArg("GULPExpandCoordinate");
	my $nExpandLatticeA    = &GetArg("GULPExpandLatticeA");
	$nExpandLatticeA       = 1 if($nExpandLatticeA < 1);
	my $nExpandLatticeB    = &GetArg("GULPExpandLatticeB");
	$nExpandLatticeB       = 1 if($nExpandLatticeB < 1);
	my $nExpandLatticeC    = &GetArg("GULPExpandLatticeC");
	$nExpandLatticeC       = 1 if($nExpandLatticeC < 1);
	my $IsChooseRandomly   = &GetArg("GULPChooseRandomly");

	&ExpandSuperLatticeCoordinate(0, $IsExpandCoordinate, 
		$nExpandLatticeA, $nExpandLatticeB, $nExpandLatticeC,
		$IsChooseRandomly);
	if($IsExpandCoordinate) {
		if($IsChooseRandomly) {
			$Crystal->SetOutputMode('choose');
		}
		else {
			$Crystal->SetOutputMode('expanded');
		}
	}
	else {
		$Crystal->SetOutputMode('asymmetric');
	}

#ファイル名を（ベース名, ディレクトリ名, 拡張子）に分解
	my $CIFFile = &GetArg("FILE");
	my @filenames = fileparse($CIFFile, "\.[^\.]+");
	my $fname1 = "$filenames[0].glp";
	my $NewFile1 = Deps::MakePath($CrystalGULPFileDir, $fname1, 0);

#	print "<H3>Write to $NewFile1.</H3>\n";

	my $SampleName = $filenames[0];

	my $Function               = &GetArg("GULPFunction");
	my $UseShellModelForCation = &GetArg("GULPUseShellModelForCation");
	my $UseShellModelForAnion  = &GetArg("GULPUseShellModelForAnion");
	my $LibraryFile            = &GetArg("LibraryFile");

	my $GULP = new GULP();
	$GULP->SetSampleName($SampleName);
	$GULP->SetUseShellModelForCation($UseShellModelForCation);
	$GULP->SetUseShellModelForAnion($UseShellModelForAnion);
	$GULP->SetLibraryFile($LibraryFile);

	$GULP->SaveGULPInputFile($Crystal, $Function, $NewFile1, $IsChooseRandomly);

	print "$LF";
	print "<b>Function:</b> $Function$LF";
	my $LibPath = $GULP->LibraryPath();
	my $IsExist = (-e $LibPath)? '' : ': File not found';
	print "<b>Library File:</b> $LibraryFile ($LibPath$IsExist)$LF";
	print "$LF";

	print "<b>GULP File:</b> ";
	&ShowFileLink($WebRootDir, $NewFile1, $fname1);
	print "$LF";

	return;
}

sub MakeMXDORTOFiles
{
	print "<H2>Make MXDOrto files.</H2>\n";

# MDNPT, XDNPT
	my $MXDFunction = &GetArg('MXDFunction');

	my $IsExpandCoordinate = 1;
	my $nExpandLatticeA    = &GetArg("MXDExpandLatticeA");
	$nExpandLatticeA = 1 if($nExpandLatticeA < 1);
	my $nExpandLatticeB    = &GetArg("MXDExpandLatticeB");
	$nExpandLatticeB = 1 if($nExpandLatticeB < 1);
	my $nExpandLatticeC    = &GetArg("MXDExpandLatticeC");
	$nExpandLatticeC = 1 if($nExpandLatticeC < 1);
	my $IsChooseRandomly = &GetArg("MXDChooseRandomly");

	if($MXDFunction =~ /XD/i) {
		&ExpandSuperLatticeCoordinate(0, $IsExpandCoordinate, 
			1, 1, 1, $IsChooseRandomly);
	}
	else {
		&ExpandSuperLatticeCoordinate(0, $IsExpandCoordinate, 
			$nExpandLatticeA, $nExpandLatticeB, $nExpandLatticeC,
			$IsChooseRandomly);
	}
	if($IsExpandCoordinate) {
		if($IsChooseRandomly) {
			$Crystal->SetOutputMode('choose');
		}
		else {
			$Crystal->SetOutputMode('expanded');
		}
	}
	else {
		$Crystal->SetOutputMode('asymmetric');
	}

	$Crystal->FillAtomTypeData();
	$Crystal->SortAtomTypeOrder("ChargeAscend");

	my $CIFFile = &GetArg("FILE");
#ファイル名を（ベース名, ディレクトリ名, 拡張子）に分解
	my @filenames = fileparse($CIFFile, "\.[^\.]+");
	my $FilePrefix       = $filenames[0];
	my $fname05 = "$FilePrefix.f05";
	my $File05 = Deps::MakePath($CrystalMXDOrtoFileDir, $fname05, 0);
	my $fname07 = "$FilePrefix.f07";
	my $File07 = Deps::MakePath($CrystalMXDOrtoFileDir, $fname07, 0);
	my $fname10 = "$FilePrefix.f10";
	my $File10 = Deps::MakePath($CrystalMXDOrtoFileDir, $fname10, 0);

	print "$LF";
	print "File05: $File05$LF";
	print "File07: $File07$LF";
	print "File10: $File10$LF";

	print "[$File05] was deleted.$LF" if(unlink($File05));
	print "[$File07] was deleted.$LF" if(unlink($File07));
	print "[$File10] was deleted.$LF" if(unlink($File10));

	my $MXD = new MXD();
	if($MXDFunction =~ /XD/i) {
		$MXD->SetSampleName("$filenames[0]");
		$MXD->SetnExpandCells($nExpandLatticeA, $nExpandLatticeB, 
				$nExpandLatticeC);
	}
	else {
		$MXD->SetSampleName("$filenames[0] ($nExpandLatticeA x "
			   ."$nExpandLatticeB x $nExpandLatticeC)");
#		$MXD->SetnExpandCells(1, 1, 1);
		$MXD->SetnExpandCells($nExpandLatticeA, $nExpandLatticeB, 
				$nExpandLatticeC);
	}

	if($MXD->MakeMXDFiles($Crystal, $MXDFunction,
		$File05, $File07, $File10, $IsChooseRandomly) <= 0) {
		print "<b>Error in Research.pl::MakeMXDORTOFiles: "
			."Can not create *.f0? files.</b>$LF";
		return -1;
	}

	print "$LF";
	print "<b>MXDOrto Files made by MXD.pm (not recommended):</b>$LF";
	&ShowFileLink($WebRootDir, $File05, $fname05) if(-e $File05);
	&ShowFileLink($WebRootDir, $File07, $fname07) if(-e $File07);
	&ShowFileLink($WebRootDir, $File10, "$fname10 (not work well)") 
			if(-e $File10);

	print "$LF";
	print "<b>Make MXD files by MXDInput.exe</b>$LF";

	my ($FileXTALDATA, $MXDInputFile, $MXDInputOutFile,
		$MXDFile05File, $MXDFile06File, $MXDFile07File, $MXDFile10File)
		= $MXD->MakeXTALDATA($Crystal, $MXDFunction, $WorkingDir, $FilePrefix);
	if($FileXTALDATA == -1) {
		print "<b>Error in Research.pl::MakeMXDORTOFiles: "
			."Can not create file [$FileXTALDATA].</b>$LF";
		return -1;
	}

	print "<b>MXDOrto Files made by MXDInput.exe (recommended):</b>$LF";
	&ShowFileLink($WebRootDir, $MXDFile05File, $fname05) 
		if(-e $MXDFile05File);
	&ShowFileLink($WebRootDir, $MXDFile07File, $fname07) 
		if(-e $MXDInputFile);
	&ShowFileLink($WebRootDir, $MXDFile10File, $fname10) 
		if(-e $MXDFile10File);
	print "+++Related files$LF";
	&ShowFileLink($WebRootDir, $FileXTALDATA, "XTALDATA.DAT") 
		if(-e $FileXTALDATA);
	&ShowFileLink($WebRootDir, $MXDInputFile, "MXDInput.in") 
		if(-e $MXDInputFile);
	&ShowFileLink($WebRootDir, $MXDInputOutFile, "MXDInput.out") 
		if(-e $MXDInputOutFile);
	&ShowFileLink($WebRootDir, $MXDFile06File, "FILE06.dat") 
		if(-e $MXDFile06File);

	print "$LF";

	return;
}

sub MakeDVXaFiles
{
}

sub MakeVRMLFile
{
	print "<b>Make VRML File</b>$LF";

	my @VRMLVersion = &GetArg("VRMLVersion");
	my $VRMLVersion = @VRMLVersion[0];
	my $IonRadiusScaleFactor = &GetArg('VRMLIonRadiusScaleFactor');
	my $MaxBondLength = &GetArg('VRMLMaxBondLength');
	my $nMaxBonds = &GetArg('VRMLnMaxBonds');

	my $nExpandLatticeA    = &GetArg("VRMLExpandLatticeA");
	$nExpandLatticeA = 1 if($nExpandLatticeA < 1);
	my $nExpandLatticeB    = &GetArg("VRMLExpandLatticeB");
	$nExpandLatticeB = 1 if($nExpandLatticeB < 1);
	my $nExpandLatticeC    = &GetArg("VRMLExpandLatticeC");
	$nExpandLatticeC = 1 if($nExpandLatticeC < 1);

	&ExpandSuperLatticeCoordinate(0, 1, 1, 1, 1, 0);
#	&ExpandSuperLatticeCoordinate(0, 1, $nExpandLatticeA, $nExpandLatticeB, $nExpandLatticeC, 0);

#ファイル名を（ベース名, ディレクトリ名, 拡張子）に分解
	my $CIFFile = &GetArg("FILE");
	my @filenames = fileparse($CIFFile, "\.[^\.]+");
	my $fname;
	my $VRML;
	if($VRMLVersion eq 'V3.0') {
		$fname = $filenames[0] . ".x3d";
		$VRML = new X3D;
	}
	elsif($VRMLVersion eq 'V2.5') {
		$fname = $filenames[0] . ".x3dv";
		$VRML = new VRML;
	}
	else {
		$fname = $filenames[0] . ".wrl";
		$VRML = new VRML;
	}
	my $NewFile = Deps::MakePath($CrystalCommonFileDir, $fname, 0);
	my $SampleName = $fname;
	$SampleName =~ s/\..*$//;

	$VRML->SetSampleName($SampleName);
	my (@Files) = $VRML->SaveFile($Crystal, $NewFile, 
				$nExpandLatticeA, $nExpandLatticeB, $nExpandLatticeC, 
				$MaxBondLength, $nMaxBonds,
				1.0, $IonRadiusScaleFactor, $VRMLVersion);

	print "<b>VRML Files:</b> ";
	for(my $i = 0 ; $i < @Files ; $i++) {
		my @filenames = fileparse($Files[$i], "\.[^\.]+");
		&ShowFileLink($WebRootDir, $Files[$i], $filenames[0] . $filenames[2])
			if(-e $Files[$i]);
	}
	print "$LF";

	for(my $i = 0 ; $i < @Files ; $i++) {
		my $width = 300;
		my $height = 300;
		$width = 250 if($i >= 1);
		print "<EMBED SRC=\"$Files[$i]\" ALIGN=\"baseline\" BORDER=\"0\" "
			."WIDTH=\"$width\" HEIGHT=\"$height\"> "
					if(-e $Files[$i]);
	}

	return;
}

sub MakePOVRayFile
{
	print "<b>Make POV-Ray File</b>$LF";

	my @POVRayMaterial = &GetArg("POVRayMaterial");
	my $POVRayMaterial = @POVRayMaterial[0];
	my $IonRadiusScaleFactor = &GetArg('POVRayIonRadiusScaleFactor');
	my $MaxBondLength = &GetArg('POVRayMaxBondLength');
	my $nMaxBonds = &GetArg('POVRaynMaxBonds');

	my $nExpandLatticeA    = &GetArg("POVRayExpandLatticeA");
	$nExpandLatticeA = 1 if($nExpandLatticeA < 1);
	my $nExpandLatticeB    = &GetArg("POVRayExpandLatticeB");
	$nExpandLatticeB = 1 if($nExpandLatticeB < 1);
	my $nExpandLatticeC    = &GetArg("POVRayExpandLatticeC");
	$nExpandLatticeC = 1 if($nExpandLatticeC < 1);

	&ExpandSuperLatticeCoordinate(0, 1, 1, 1, 1, 0);

#ファイル名を（ベース名, ディレクトリ名, 拡張子）に分解
	my $CIFFile = &GetArg("FILE");
	my @filenames = fileparse($CIFFile, "\.[^\.]+");
	my $fname = $filenames[0] . ".pov";
	my $NewFile = Deps::MakePath($CrystalCommonFileDir, $fname, 0);
	my $SampleName = $fname;
	$SampleName =~ s/\..*$//;

	my $POVRay = new POVRay;
	$POVRay->SetSampleName($SampleName);
	my (@Files) = $POVRay->SaveFile($Crystal, $NewFile, 
				$nExpandLatticeA, $nExpandLatticeB, $nExpandLatticeC, 
				$MaxBondLength, $nMaxBonds,
				1.0, $IonRadiusScaleFactor, $POVRayMaterial);

	print "<b>POVRay File:</b> ";
	for(my $i = 0 ; $i < @Files ; $i++) {
		my @filenames = fileparse($Files[$i], "\.[^\.]+");
		&ShowFileLink($WebRootDir, $Files[$i], $filenames[0] . $filenames[2])
			if(-e $Files[$i]);
	}
	print "$LF";

	return;
}

sub MakeSimpleCIFFile
{
print "<H1>Research.pl::MakeSimpleCIFFile</H1>\n";
	my $IsExpandCoordinate = &GetArg("CIFExpandCoordinate");
	my $nExpandLatticeA    = &GetArg("CIFExpandLatticeA");
	$nExpandLatticeA = 1 if($nExpandLatticeA < 1);
	my $nExpandLatticeB    = &GetArg("CIFExpandLatticeB");
	$nExpandLatticeB = 1 if($nExpandLatticeB < 1);
	my $nExpandLatticeC    = &GetArg("CIFExpandLatticeC");
	$nExpandLatticeC = 1 if($nExpandLatticeC < 1);

	&ExpandSuperLatticeCoordinate(0, $IsExpandCoordinate, 
		$nExpandLatticeA, $nExpandLatticeB, $nExpandLatticeC, 0);

	my $CIFFile = &GetArg("FILE");
#ファイル名を（ベース名, ディレクトリ名, 拡張子）に分解
	my @filenames = fileparse($CIFFile, "\.[^\.]+");
	my $fname = $filenames[0];
	$fname = $fname . $filenames[2] if($filenames[2] ne '');
	my $NewFile = Deps::MakePath($CrystalCommonFileDir, $fname, 0);
	my $NewFileUnix = Deps::MakePath($CrystalCommonFileDir, "$filenames[0]-unix.cif", 0);

#	unless($CIF->WriteSimpleCIFFile($NewFile)) {
	unless($CIF->CreateCIFFileFromCCrystal($Crystal, $NewFile, 0, "win")) {
		print "Can not write to $NewFile.$LF$LF";
		return 0;
	}
#	unless($CIF->WriteSimpleCIFFile($NewFileUnix, 1, "unix")) {
	unless($CIF->CreateCIFFileFromCCrystal($Crystal, $NewFileUnix, 0, "unix")) {
		print "Can not write to $NewFileUnix.$LF$LF";
		return 0;
	}

	print "<b>Simple CIF File:</b><br>";
	&ShowFileLink($WebRootDir, $NewFile, $fname);
	&ShowFileLink($WebRootDir, $NewFileUnix, "$fname (UNIX)");


	return 1;
}

sub MakeLDFile
{
	print "<H2>Make LD files.</H2>\n";

	my @Function = &GetArg('LDFunction');
#Energy, Permit, WMin, xLSQ, Phonon
	my $Function = $Function[0];
	
	print "<b>Function:</b> $Function$LF";

	my $IsExpandCoordinate = 1;
	my $nExpandLatticeA    = &GetArg("MXDExpandLatticeA");
	$nExpandLatticeA = 1 if($nExpandLatticeA < 1);
	my $nExpandLatticeB    = &GetArg("MXDExpandLatticeB");
	$nExpandLatticeB = 1 if($nExpandLatticeB < 1);
	my $nExpandLatticeC    = &GetArg("MXDExpandLatticeC");
	$nExpandLatticeC = 1 if($nExpandLatticeC < 1);
	my $IsChooseRandomly = &GetArg("MXDChooseRandomly");

	&ExpandSuperLatticeCoordinate(0, $IsExpandCoordinate, 
		$nExpandLatticeA, $nExpandLatticeB, $nExpandLatticeC,
		$IsChooseRandomly);
	if($IsExpandCoordinate) {
		if($IsChooseRandomly) {
			$Crystal->SetOutputMode('choose');
		}
		else {
			$Crystal->SetOutputMode('expanded');
		}
	}
	else {
		$Crystal->SetOutputMode('asymmetric');
	}

	my $CIFFile = &GetArg("FILE");
#ファイル名を（ベース名, ディレクトリ名, 拡張子）に分解
	my @filenames = fileparse($CIFFile, "\.[^\.]+");
	my $fname = $filenames[0];

	my $LDDATPath = Deps::MakePath($CrystalLDFileDir, "$fname.DAT",   0);
	my $LD01Path  = Deps::MakePath($CrystalLDFileDir, "${fname}.f01", 0);
	my $LD02Path  = Deps::MakePath($CrystalLDFileDir, "${fname}.f02", 0);
	my $LD07Path  = Deps::MakePath($CrystalLDFileDir, "${fname}.f07", 0);

	print "($LDDATPath) was deleted.$LF" if(unlink($LDDATPath));
	print "($LD01Path) was deleted.$LF"  if(unlink($LD01Path));
	print "($LD02Path) was deleted.$LF"  if(unlink($LD02Path));
	print "($LD07Path) was deleted.$LF"  if(unlink($LD07Path));

	my $LD = new LD();
	$LD->SetSampleName($fname);

	if($LD->MakeLD01File($Crystal, $Function, $LD01Path) <= 0) {
		print "Error in Research.pl::MakeLDFile: Can not write to [$LD01Path].$LF";
		return -1;
	}
	if($LD->MakeLD02File($Crystal, $Function, $LD02Path) <= 0) {
		print "Error in Research.pl::MakeLDFile: Can not write to [$LD02Path].$LF";
		return -1;
	}
	if($LD->MakeLD07File($Crystal, $Function, $LD07Path) <= 0) {
		print "Error in Research.pl::MakeLDFile: Can not write to [$LD07Path].$LF";
		return -1;
	}

#ファイル名リストのファイル .DAT をつくる
	unless(open(OUT,">$LDDATPath")) {
		print "Can't write to $LDDATPath.$LF$LF";
		return;
	}
	print OUT "[Files]\n";
	print OUT "${fname}.f01\n";
	print OUT "${fname}.f02\n";
	print OUT "${fname}.f04\n";
	print OUT "${fname}.f07\n";
	print OUT "${fname}.f08\n";
	print OUT "${fname}.f09\n";
	if($Function =~ /Phonon/i) {
		print OUT "\n";
		print OUT "[General]\n";
		print OUT "0.4    EwaldAlpha\n";
		print OUT "0.8    MinIonicRadius\n";
		print OUT "1.0e-6 ConvergenceEPS\n";
		print OUT "\n";
		print OUT "[CalRange for Phonon]\n";
		print OUT "Execute\n";
		print OUT "\n";
		print OUT "[CalDistance]\n";
		print OUT "6.0    MaxDistance\n";
		print OUT "Execute\n";
		print OUT "\n";
		print OUT "[SaveCrystal]\n";
		print OUT "Execute\n";
		print OUT "\n";
		print OUT "[EnergyTest]\n";
		print OUT "NotExecute\n";
		print OUT "\n";
		print OUT "[CalEnergies]\n";
		print OUT "NotExecute\n";
		print OUT "\n";
		print OUT "[Phonon]\n";
		print OUT "0       fPhononDebug\n";
		print OUT "1       fUsedu/dx\n";
		print OUT "0       iPrintMatrixLevel=0: none 1: Wij 2: Wij/Gij "
			 ."3: Wij/Gij/Normalized Wij\n";
		print OUT "0       iEigenSolver=0: ZHEGV(Hermitian) "
			 ."1: ZGGEV(Asymmetric) 2: EigAB(Real)\n";
		print OUT "2       iPrintEigenVectorLevel=0: none 1: Complex "
			 ."2: Norm 3: Complex/Norm\n";
		print OUT "10      nPrintEigenVectors\n";
		print OUT "3.0e-5  500 500 500      CalPhononPrecision  "
			 ."nULimitNRange(3)\n";
		print OUT "1.0e-14 EigCHEPS (for iEigenSolver=2)\n";
		print OUT "3.0 3.0 wWindowFunc, nSigmaUsed\n";
		print OUT "2\n";
		print OUT "0.0 1.0 0.0 0.0 0.0 0.0  21\n";
		print OUT "0.0 0.0 0.0 0.0 0.0 1.0  21\n";
		print OUT "Execute\n";
		print OUT "0.0 1.0 0.0 1.0 0.0 0.0  21\n";
		print OUT "0.0 1.0 0.0 1.0 0.0 1.0  21\n";
	}
	close(OUT);

	print "<b>LD Files (for $Function.exe):</b>$LF";
	&ShowFileLink($WebRootDir, $LDDATPath, "${fname}.DAT") if(-e $LDDATPath);
	&ShowFileLink($WebRootDir, $LD01Path,  "${fname}.f01") if(-e $LD01Path);
	&ShowFileLink($WebRootDir, $LD02Path,  "${fname}.f02") if(-e $LD02Path);
	&ShowFileLink($WebRootDir, $LD07Path,  "${fname}.f07") if(-e $LD07Path);
	print "$LF";

	return;
}

sub MakeRietanINSFile
{
	print "<H2>Make Rietan ins files.</H2>\n";

	my $IsExpandCoordinate = &GetArg("RietanExpandCoordinate");
	my $nExpandLatticeA    = 1;
	my $nExpandLatticeB    = 1;
	my $nExpandLatticeC    = 1;
	my $IsChooseRandomly   = &GetArg("RietanChooseRandomly");

	&ExpandSuperLatticeCoordinate(0, $IsExpandCoordinate, 
		$nExpandLatticeA, $nExpandLatticeB, $nExpandLatticeC,
		$IsChooseRandomly);
	if($IsExpandCoordinate) {
		if($IsChooseRandomly) {
			$Crystal->SetOutputMode('choose');
		}
		else {
			$Crystal->SetOutputMode('expanded');
		}
	}
	else {
		$Crystal->SetOutputMode('asymmetric');
	}

	my $CIFFile = &GetArg("FILE");
#ファイル名を（ベース名, ディレクトリ名, 拡張子）に分解
	my @filenames = fileparse($CIFFile, "\.[^\.]+");
	my $fname1 = $filenames[0] . ".ins";
	my $NewFile1 = Deps::MakePath($CrystalRietanFileDir, $fname1, 0);

	my $fname2 = $filenames[0] . "-sim.ins";
	my $NewFile2 = Deps::MakePath($CrystalRietanFileDir, $fname2, 0);
	my $SampleName = "'$filenames[0]'";

	my $Rietan = new Rietan();
	$Rietan->SetSampleName($SampleName);
	$Rietan->SaveInsFile($Crystal, $NewFile1, $IsExpandCoordinate, $IsChooseRandomly, 0);
	$Rietan->SaveInsFile($Crystal, $NewFile2, $IsExpandCoordinate, $IsChooseRandomly, 1);

	print "<b>Links:</b>$LF";
	&ShowFileLink($WebRootDir, $NewFile1, "Rietan .ins File (refinement)");
	&ShowFileLink($WebRootDir, $NewFile2, "Rietan .ins File (simulation)");

	return;
}

sub ShowCIFInf
{
	my ($Action, $ShowCIFInf) = @_;

	my $CIFFile = &GetArg("FILE");
	Utils::DelSpace($CIFFile);

	return &ShowCrystalDB($Action) if($CIFFile eq '');

	print "<H1>Read CIF File</H1>";
	print "+++ <b>File:</b> $CIFFile$LF";

#CIFファイル名を引数に与えて読み込む
	unless($CIF->Read($CIFFile)) {
		print "aError: Can not read $CIFFile.$LF$LF";
		return 0;
	}

#CIFクラスの内容から、Crystalクラスを作成
	$Crystal = $CIF->GetCCrystal();
	$Crystal->ExpandCoordinates();

	if($ShowCIFInf) {
		print "<H1>Show CIF Information</H1>\n";
		print "<H3>CIF File: $CIFFile</H3>$LF";

		foreach my $key (keys %$CIF) {
			my $s = $CIF->{$key};
			print "  <b>$key:</b> $s$LF";
		}
	}

	return;
}
