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.

cif.py

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";
}

"""