import os
import sys
import shutil
import glob
import numpy as np
from numpy import sin, cos, tan, pi
import csv
from pprint import pprint
sys.path.append("c:/Programs/python/lib")
sys.path.append("d:/Programs/python/lib")
from tkfile import tkFile
from tkcrystal.tkcif import tkCIF
from tkcrystal.tkcrystal import tkCrystal
from tkcrystal.tkatomtype import tkAtomType
"""
tklibを使って CIFファイルを読み込み、Crystalオブジェクトを返す。
Crystalオブジェクトから結晶構造情報を抜き出して表示
Read a CIF file using tklib and return a Crystal object.
Crystal structure inf will be shown using the Crystal object attributes.
"""
debug = 0
# default cif files to be red
infile = 'cif/*.cif'
#infile = 'test1.cif'
#infile = 'test.cif'
narg = len(sys.argv)
if narg >= 2:
infile = sys.argv[1]
if narg >= 3:
debug = int(sys.argv[2])
# If single == 1 one crystal structure will be red from one cif file
# If single != 1 all crystal structures will be red from one cif file
single = 1
# A CIF may include multiple sections, and the first section is not necessary a crystal structure inf.
# This flag try to find a valid structure section.
findvalidstructure = 1
# These are for test purpose. Read results will be stored in checklist
checklist = 'cifcheck.txt'
# If okdir points an existing directory,
# the cif file with success reading will be moved to okdir
#okdir = 'cif/ok'
okdir = ''
print("infile: {}".format(infile))
print("single: {}".format(single))
print("findvalidstructure: {}".format(findvalidstructure))
print("checklist: {}".format(checklist))
print("debug: {}".format(debug))
def main():
# open the output checklist file using tklib.tkFile
cout = tkFile(checklist, 'w')
# find files using wildcard indicated by infile
files = glob.glob(infile)
for f in files:
print("\nRead from [{}]".format(f))
cout.Write("{}\n".format(f))
cif = tkCIF()
cif.debug = debug
# atom = tkAtomType()
# inf = atom.GetAtomInformation('Au')
# for key in inf:
# print("{}: {}".format(key, inf[key]))
# print("")
# exit()
# If single == 1 one crystal structure will be red from one cif file
if single:
cifdata = cif.ReadCIF(f, find_valid_structure = findvalidstructure)
cifdata.Print()
cry = cifdata.GetCrystal()
print("")
print("==============================================")
cry.PrintInf()
print("")
print("==============================================")
d = cry.Density()
ad = cry.AtomDensity()
if not (0.8 < d < 20.0):
print("Error in [{}]: Too low or large density {} g/cm3".format(f, d))
exit()
if not (1.0e22 < ad < 10.0e23):
print("Error in [{}]: Too low or large atom density {} /cm3".format(f, ad))
exit()
if okdir != '':
# print("fp=", cif.fp)
# cif.fp.close()
print("move {} to {}".format(f, okdir))
shutil.move(f, okdir)
# shutil.copy2(f, okdir)
# os.unlink(f)
outfile = 'a.cif'
cifdata.WriteSimpleCIFFile(outfile)
outfile = 'b.cif'
cifdata.CreateCIFFileFromCCrystal(cry, outfile)
# pos0 = [0.3, 0.2, 0.1]
# isym = 1
# pos1 = cry.DoSymmetryOperation(pos0, isym)
# print("pos0 ", pos0, " => sym %d" % (isym), pos1)
else:
# If single != 1 all crystal structures will be red from one cif file
cifdatas = cif.ReadCIFs(f)
for cifdata in cifdatas:
cifdata.Print()
cif.Close()
cout.Close()
if __name__ == "__main__":
main()
"""
# Ignore lines below
# These from Perl tklib and saved for future translation to python
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";
}
"""