#!/usr/bin/perl

use lib 'd:/Programs/Perl/lib';

use Crystal::CIF;
use Crystal::Crystal;

use strict;

#==========================================
# CIFクラスを作成
#==========================================
my $cif = new CIF($ARGV[0]);
print "CIF: ", $cif->FileName(), "\n";

#==========================================
#CIFファイル名を引数に与えて読み込む
#==========================================
$cif->Read($ARGV[0]);

#==========================================
# CIFクラスの内容から、Crystalクラスを作成
# 作成した時点で、Metricsの計算、イオン情報(原子量など)の読み込み、
# 格子体積の計算は終わっている
#==========================================
my $Crystal = $cif->GetCCrystal();

print "\n";
my $CrystalName = $Crystal->CrystalName();
print "CrystalName: $CrystalName\n";
my ($a,$b,$c,$alpha,$beta,$gamma) = $Crystal->LatticeParameters();
print "cell: $a $b $c  $alpha $beta $gamma\n";
my ($g11,$g12,$g13,$g21,$g22,$g23,$g31,$g32,$g33) = $Crystal->Metrics();
print "Metrics: $g11 $g22 $g33  $g12 $g23 $g31\n";
my $vol = $Crystal->Volume();
print "Volume: $vol\n";

print "\n";
#==========================================
# Crystalクラスから、SpaceGroupクラスを取り出す
# この時点で、並進対称要素の抽出、LatticeSystemの抽出は完了している
#==========================================
my $SPG = $Crystal->GetCSpaceGroup();
my $SPGName = $SPG->SPGName();
my $iSPG    = $SPG->iSPG();
my $LatticeSystem = $SPG->LatticeSystem();
print "Space Group: $SPGName ($iSPG)\n";
print "Lattice System: $LatticeSystem\n";

print "\n";
my $nTranslation = $SPG->nTranslation();
print "nTranslation: $nTranslation\n";
for(my $i = 0 ; $i < $nTranslation ; $i++) {
	my ($x,$y,$z) = $SPG->TranslationVector($i+1);
	print "   ($x, $y, $z)\n";
}

print "\n";
my $nSymmetryOperation = $SPG->nSymmetryOperation();
print "nSymmetryOperation: $nSymmetryOperation\n";
for(my $i = 0 ; $i < $nSymmetryOperation ; $i++) {
	my $symop = $SPG->SymmetryOperation($i+1);
	print "   $symop\n";
	
	my ($x1,$y1,$z1,$t1,
		$x2,$y2,$z2,$t2,
		$x3,$y3,$z3,$t3)
		= $SPG->SymmetryOperationByMatrix($i+1);
	print "      $x1 $y1 $z1  $t1\n";
	print "      $x2 $y2 $z2  $t2\n";
	print "      $x3 $y3 $z3  $t3\n";
}

print "\n";
#==========================================
# Crystalクラス中の、原子の種類 AtomTypeクラスのリストをとる
#==========================================
my @AtomTypeList = $Crystal->GetCAtomTypeList();
my $nAtomType = @AtomTypeList;
print "nAtomType: $nAtomType\n";
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)\n";
}

print "\n";
#==========================================
# Crystalクラス中の、非対称単位中の原子 AsymmetricAtomSiteクラスのリストをとる
#==========================================
my @AtomSiteList        = $Crystal->GetCAsymmetricAtomSiteList();
my $nAsymmetricAtomSite = @AtomSiteList;
print "nAsymmetricAtomSite: $nAsymmetricAtomSite\n";
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]\n";
}

#==========================================
# 対称要素を使い、非対称単位中の原子を展開する
# この際、Densityも計算される
#==========================================
$Crystal->ExpandCoordinates();

print "\n";
my @ExpandedAtomSiteList   = $Crystal->GetCExpandedAtomSiteList();
my $nTotalExpandedAtomSite = $Crystal->nTotalExpandedAtomSite();
my @nMultiplicityExpandedAtomSiteList 
	= $Crystal->GetCnMultiplicityExpandedAtomSiteList();
print "nTotalExpandedAtomSite: $nTotalExpandedAtomSite\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 $id = $ExpandedAtomSiteList[$i]->IdAsymmetricAtomSite();
	my $mult = $nMultiplicityExpandedAtomSiteList[$id-1];
	my $i1 = $i+1;
	print "   $i1: [$id]$label ($type): ($x, $y, $z) [$occupancy][$mult]\n";
}

print "\n";
my $Density = $Crystal->Density();
print "Density: $Density g/cm^3\n";

#==========================================
# $Crystalをもとに、超格子の結晶格子$SuperLatticeを作る
#==========================================
my ($nx,$ny,$nz) = (2,2,2);
$Crystal->CreateSuperLattice($nx,$ny,$nz);
my $SuperLattice = $Crystal->GetCSuperLattice();

print "\n";
print "SuplaerLattice $nx x $ny x $nz\n";
my ($a,$b,$c,$alpha,$beta,$gamma) = $SuperLattice->LatticeParameters();
print "Cell: $a $b $c  $alpha $beta $gamma\n";

my @ExpandedAtomSiteList = $SuperLattice->GetCExpandedAtomSiteList();
my $nTotalExpandedAtomSite = $SuperLattice->nTotalExpandedAtomSite();
my @nMultiplicityExpandedAtomSiteList 
	= $SuperLattice->GetCnMultiplicityExpandedAtomSiteList();
print "nTotalExpandedAtomSite: $nTotalExpandedAtomSite\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 $id = $ExpandedAtomSiteList[$i]->IdAsymmetricAtomSite();
	my $mult = $nMultiplicityExpandedAtomSiteList[$id-1];
	my $i1 = $i+1;
	print "   $i1: [$id]$label ($type): ($x, $y, $z) [$occupancy][$mult]\n";
}



exit;
