#===============================================
# CIFObject
#===============================================
package CIFObject;
use Exporter;
@ISA = qw(Exporter);
#公開したいサブルーチン
@EXPORT = qw();
use strict;
#use File::Path;
use File::Basename;
use Utils;
use Crystal::Crystal;
use Crystal::SpaceGroup;
use Crystal::AtomType;
use Crystal::AtomSite;
my $LF = "
\n";
my $Debug = 0;
#============================================================
# 静的メンバー関数
#============================================================
sub BuildCreationDateStr {
my ($sec, $min, $hour, $mday, $mon, $year,
$wday, $yday, $isdst) = localtime(time());
$mon++;
$year += 1900;
my $s = sprintf "%04d/%02d/%02d", $year, $mon, $mday;
return $s;
}
#============================================================
# コンストラクタ、デストラクタ
#============================================================
sub new
{
my ($module, $filename) = @_;
my $this = {};
bless $this;
$this->SetFileName($filename);
return $this;
}
sub DESTROY
{
my $this = shift;
}
#============================================================
# 一般関数
#============================================================
sub ReadCrystal
{
my ($this, $cifpath) = @_;
unless($this->Read($cifpath, 0)) {
return undef;
}
return $this->GetCCrystal();
}
sub SetCrystalName
{
my ($this,$name) = @_;
Utils::DelSpace($name);
$this->{'CrystalName'} = $name;
return $name;
}
sub CrystalName
{
my ($this) = @_;
return $this->{'CrystalName'};
}
sub SetFormula
{
my ($this,$s) = @_;
$this->{'_chemical_formula_sum'} = $s;
$this->{'_chemical_formula_structural'} = $s
if($this->{'_chemical_formula_structural'} eq '');
return $s;
}
sub Formula
{
my ($this) = @_;
return $this->{'_chemical_formula_structural'} if(defined $this->{'_chemical_formula_sum'});
return $this->{'_chemical_formula_sum'} if(defined $this->{'_chemical_formula_sum'});
return undef;
}
sub SetFileName
{
my $this = shift;
my $s = shift;
Utils::DelSpace($s);
#no strict;
$this->{'FileName'} = $s;
#use strict;
}
sub FileName
{
my $this = shift;
return $this->{'FileName'};
}
sub Read
{
my ($this, $f) = @_;
# $this->SetFileName($f) if($f ne '');
my $in = new JFile;
unless($in->Open($f, "r")) {
# print "$!: $f\n";
return 0;
}
my $ret = $this->ReadByJFile($in);
$in->Close();
return $ret;
}
sub ReadByJFile
{
my ($this, $in) = @_;
$this->SetFileName($in->{FileName});
my $FileEnd = 0;
#最初の一行
my $header;
while(!$FileEnd) {
$header = $in->ReadLine();
if(!defined $header) {
return 0;
}
Utils::DelSpace($header);
if($header =~ /^_/) {
$in->rewind();
last;
}
if($header ne '') {
$this->{header} = $header;
last;
}
}
my $ExitLoop = 0;
while(!$FileEnd) {
last if($ExitLoop);
my $line = $in->ReadLine();
last if(!defined $line);
Utils::DelSpace($line);
if($Debug) {
print "line: $line$LF";
}
# 空行はスキップ
next if($line =~ /^$/);
# next if($line =~ /^#/);
# #Endを見つけたら終わる
if($line =~ /^#End/i) {
$FileEnd = 1;
last;
}
next if($line =~ /^#/);
#print "l0: $line\n";
#loop_の無いデータを読み込み
if($line =~ /^_/) {
my ($key, $content) = ($line =~ /^(\S+?)\s+(.*)$/);
# if(defined $key and $key ne '') {
if($content ne '') {
$this->{$key} = $content;
next;
}
else {
$line = $in->ReadLine();
#print "ll0: $line";
Utils::DelSpace($line);
next if($line ne ';');
$content = '';
while(1) {
$line = $in->ReadLine();
#print "ll1: $line";
Utils::DelSpace($line);
last if($line eq ';' or $line =~ /^#End/i);
$content .= "$line\n";
}
$content =~ s/[\r\n]+$//;
#print "cont: [$content]\n";
$this->{$key} = $content;
next;
}
}
#loop_のデータを読み込み
elsif($line =~ /^loop_$/i) {
#print "l: $line\n";
my @Params;
my $Count = 0;
my $line2 = '';
#loop_内のパラメータ名を取得
# my $pos = 0;
my $pos = $in->tell();
#print "loop_
\n";
while(!$FileEnd) {
$line2 = $in->ReadLine();
#print "l2: $line2";
last if(!defined $line2);
if($line2 =~ /^#End/i) {
$FileEnd = 1;
last;
}
next if($line2 =~ /^#/);
Utils::DelSpace($line2);
#print "line2: $line2
\n";
unless($line2 =~ /^(_|loop_)/) {
#2006/5/4 Na.cifのためにコメントをはずす
$in->seek($pos, 0) if($pos > 0);
last;
}
$Params[$Count] = $line2;
$Count++;
#2006/5/4 Na.cifのためにコメントをはずす
$pos = $in->tell();
}
#$Debug=1;
if($Debug) {
foreach my $s (@Params) {
print "Key: $s$LF";
}
}
#loop_内のパラメータを取得
#2006/5/4 Na.cifのために''で初期化するように変更
# my $LoopContent = $line2;
my $LoopContent = '';
$pos = 0;
while(!$FileEnd) {
$line2 = $in->ReadLine();
last if(!defined $line2);
if($line2 =~ /^#End/i) {
$FileEnd = 1;
last;
}
next if($line2 =~ /^#/);
#print "l3: $line2";
Utils::DelSpace($line2);
next if($line2 eq '');
# last if($line2 eq '');
#次のloop_を見つけたら、LoopContentを解析
if($line2 =~ /^(_|loop_)/) {
$in->seek($pos, 0) if($pos > 0);
last;
}
$LoopContent = "$LoopContent $line2";
$pos = $in->tell();
}
last if($ExitLoop);
#print "LoopC: [$LoopContent]\n";
my $pt = 0;
my $c = 0;
while($LoopContent =~ /(\'.*?\'|\S+)/g) {
my $s = $1;
my $i = int($c / $Count) + 1;
$c++;
# if($ShowCIFInf ne '') {
# print " $Params[$pt]" . "[$i] " . ": $s\n";
# print " $i: $Params[$pt]: $s\n";
# }
# $Params[$pt] =~ s/[\r\n\s]//g;
my $key = "${Params[$pt]}[$i]";
#print "k: $key: $s\n";
$this->{$key} = $s;
if($Debug) {
print "akey: {$key} : $s$LF";
}
$pt++;
$pt = 0 if($pt >= $Count);
}
}
last if($ExitLoop);
}
$this->SetOtherParameters();
#exit;
return 1;
}
sub SetOtherParameters
{
my ($this) = @_;
my $nAtomType = 0;
for(my $i = 1 ; ; $i++) {
my $val = &GetValue($this, "_atom_type_symbol", $i);
# if(!defined $val or $val eq '') {
# $val = &GetValue($this, "_atom_site_label", $i);
# $val =~ s/[\d+-]+//g;
# }
last if(!defined $val or $val eq '');
$this->{"iAtomType_$val"} = $i;
$nAtomType++;
}
$this->{"nAtomType"} = $nAtomType;
my $nAsymmetricAtomSite = 0;
for(my $i = 1 ; ; $i++) {
my $val = &GetValue($this, "_atom_site_fract_x", $i);
last if(!defined $val or $val eq '');
$nAsymmetricAtomSite++;
}
$this->{"nAsymmetricAtomSite"} = $nAsymmetricAtomSite;
# if($nAtomType == 0) {
for(my $i = 1 ; $i <= $nAsymmetricAtomSite ; $i++) {
my $val = &GetValue($this, "_atom_site_type_symbol", $i);
if(!defined $val or $val eq '') {
$val = &GetValue($this, "_atom_site_label", $i);
$val =~ s/[\d+-]+//g;
}
#print "v: $val$LF";
if($val =~ /^(\w+)([\+-])([\d\.]+)$/i) {
if($3 == 1) {
$val = "$1$2";
}
else {
$val = "$1$3$2";
}
#print " => v: $val$LF";
}
#print "v: $val$LF";
$this->AddAtomType($val);
&SetContent($this, "_atom_site_type_symbol", $i, $val);
}
# }
my $a = &GetValue($this, "_cell_length_a");
my $b = &GetValue($this, "_cell_length_b");
my $c = &GetValue($this, "_cell_length_c");
my $alpha = &GetValue($this, "_cell_angle_alpha");
my $beta = &GetValue($this, "_cell_angle_beta");
my $gamma = &GetValue($this, "_cell_angle_gamma");
my $lattice = $this->{"_symmetry_cell_setting"};
#print "lat: $a $b $c$LF";
my $SPG = new SpaceGroup();
my ($SPGName, $iSPG) = $this->GetSpaceGroup();
$SPG->SetSPGName($SPGName);
$SPG->SetiSPG($iSPG);
#print "SPGName1 in CIFObject: $SPGName\n";
$SPG->SetLatticeParameters($a,$b,$c,$alpha,$beta,$gamma);
$SPG->SetLatticeSystem($lattice);
$this->{"_symmetry_cell_setting"} = $SPG->LatticeSystem();
$this->{"nTranslation"} = $SPG->AnalyzeTranslation();
# my $nSymmetryOperation = 0;
for(my $i = 1 ; ; $i++) {
my $val = &GetValue($this, "_symmetry_equiv_pos_as_xyz", $i);
$val = &GetValue($this, "_space_group_symop_operation_xyz", $i) if($val eq '');
last if(!defined $val or $val eq '');
$SPG->AddSymmetryOperation($val);
# $nSymmetryOperation++;
}
$this->{"nSymmetryOperation"} = $SPG->nSymmetryOperation();
#print "a$LF";
return;
}
sub AddSymmetryOperation
{
my ($this,$symop) = @_;
my $nSymmetryOperation = $this->{"nSymmetryOperation"};
$nSymmetryOperation++;
#print "Add: i=$nSymmetryOperation: $symop
";
$this->SetContent("_symmetry_equiv_pos_as_xyz", $nSymmetryOperation, $symop);
return $this->{"nSymmetryOperation"} = $nSymmetryOperation;
}
sub GetCSpaceGroup
{
my ($this) = @_;
my $a = &GetValue($this, "_cell_length_a");
my $b = &GetValue($this, "_cell_length_b");
my $c = &GetValue($this, "_cell_length_c");
my $alpha = &GetValue($this, "_cell_angle_alpha");
my $beta = &GetValue($this, "_cell_angle_beta");
my $gamma = &GetValue($this, "_cell_angle_gamma");
my $lattice = $this->{"_symmetry_cell_setting"};
my $SPG = new SpaceGroup();
my ($SPGName, $iSPG) = &GetSpaceGroup($this);
$SPG->SetSPGName($SPGName);
$SPG->SetiSPG($iSPG);
$SPG->SetLatticeParameters($a,$b,$c,$alpha,$beta,$gamma);
$SPG->SetLatticeSystem($lattice);
$SPG->AnalyzeTranslation();
for(my $i = 1 ; ; $i++) {
my $val = &GetValue($this, "_symmetry_equiv_pos_as_xyz", $i);
$val = &GetValue($this, "_space_group_symop_operation_xyz", $i) if($val eq '');
last if(!defined $val or $val eq '');
$SPG->AddSymmetryOperation($val);
}
return $SPG;
}
sub SetContent
{
my ($this, $key, $idx, $content) = @_;
if(@_ == 3) {
$content = $idx;
$idx = '';
}
$key = ${key} . "[$idx]" if($idx ne '' and $idx > 0);
$this->{$key} = $content;
return $content;
}
sub GetContent
{
my ($this, $key, $idx, $defvalue) = @_;
$key = ${key} . "[$idx]" if(defined $idx and $idx ne '' and $idx > 0);
my $val = $this->{$key};
#print "key: $key\n";
#print "val: $val\n";
#print "keys: ", keys %$this, "\n";
#print "v1: $val => ";
$val =~ s/^(\')(.*)(\1)$/$2/ if(defined $val);
#print "$val => ";
$val = $defvalue if(defined $val and $val eq '');
#print "$val
\n";
return $val;
}
sub GetValue
{
my ($this, $key, $idx) = @_;
my $val = &GetContent($this, $key, $idx);
#数値の最後の(誤差)を削除
$val =~ s/^([+-\.\deE]+)\s*(\(.*?\))$/$1/ if(defined $val);
#両端の引用符を削除
$val =~ s/^\s*(['"])(.*)\1\s*$/$2/ if(defined $val);
return $val;
}
sub SetVolume
{
my ($this,$v) = @_;
return $this->SetContent("_cell_volume", $v);
}
sub Volume
{
my ($this) = @_;
return $this->GetValue("_cell_volume");
}
sub SetLatticeParameters
{
my ($this,$a,$b,$c,$alpha,$beta,$gamma) = @_;
$a = Utils::Round($a, 6);
$b = Utils::Round($b, 6);
$c = Utils::Round($c, 6);
$alpha = Utils::Round($alpha, 6);
$beta = Utils::Round($beta , 6);
$gamma = Utils::Round($gamma, 6);
$this->SetContent("_cell_length_a", $a);
$this->SetContent("_cell_length_b", $b);
$this->SetContent("_cell_length_c", $c);
$this->SetContent("_cell_angle_alpha", $alpha);
$this->SetContent("_cell_angle_beta", $beta);
$this->SetContent("_cell_angle_gamma", $gamma);
return ($a,$b,$c,$alpha,$beta,$gamma);
}
sub LatticeParameters
{
my ($this) = @_;
my $a = &GetValue($this, "_cell_length_a");
my $b = &GetValue($this, "_cell_length_b");
my $c = &GetValue($this, "_cell_length_c");
my $alpha = &GetValue($this, "_cell_angle_alpha");
my $beta = &GetValue($this, "_cell_angle_beta");
my $gamma = &GetValue($this, "_cell_angle_gamma");
return ($a,$b,$c,$alpha,$beta,$gamma);
}
sub GetSpaceGroup
{
my ($this) = @_;
my $SPGName = &GetValue($this, "_symmetry_space_group_name_H-M");
$SPGName = &GetValue($this, "_space_group_name_H-M_alt") if($SPGName eq '');
my $iSPG = &GetValue($this, "_symmetry_Int_Tables_number");
$iSPG = &GetValue($this, "_space_group_IT_number") if($iSPG eq '');
if($iSPG eq '') {
$iSPG = 1;
$SPGName = 'P 1';
}
return ($SPGName, $iSPG);
}
sub SetSpaceGroup
{
my ($this, $SPGName, $iSPG) = @_;
$this->SetContent("_symmetry_space_group_name_H-M", $SPGName);
$this->SetContent("_symmetry_Int_Tables_number", $iSPG);
# $this->{"nTranslation"} = $this->AnalyzeTranslation();
return ($SPGName, $iSPG);
}
sub SetSpaceGroupInformation
{
my ($this, $SPG) = @_;
$this->SetSpaceGroup($SPG->SPGName(), $SPG->iSPG());
my $nSymmetryOperation = $SPG->nSymmetryOperation();
for(my $i = 0 ; $i < $nSymmetryOperation ; $i++) {
my $symop = $SPG->SymmetryOperation($i);
$this->AddSymmetryOperation($symop);
}
}
sub LatticeSystem
{
my ($this) = @_;
return &GetValue($this, "_symmetry_cell_setting");
}
sub nTranslation
{
my ($this) = @_;
return &GetValue($this, "nTranslation");
}
sub nSymmetryOperation
{
my ($this) = @_;
return &GetValue($this, "nSymmetryOperation");
}
sub SymmetryOperation
{
my ($this, $i) = @_;
my $val = &GetValue($this, "_symmetry_equiv_pos_as_xyz", $i);
#print "Get: i=$i: $val
";
return $val;
}
sub nAtomType
{
my ($this, $i) = @_;
return &GetValue($this, "nAtomType");
}
sub SetnAtomType
{
my ($this, $n) = @_;
return $this->SetContent("nAtomType", $n);
}
sub GetCAtomType
{
my ($this, $i) = @_;
my ($atomname, $charge) = $this->AtomType($i);
my $atom = new AtomType();
$atom->SetAtomName($atomname);
$atom->SetCharge($charge);
return $atom;
}
sub GetCAtomTypeList
{
my ($this) = @_;
my $natom = $this->nAtomType();
my @atomlist;
for(my $i = 0 ; $i < $natom ; $i++)
{
my $atom = $this->GetCAtomType($i+1);
push(@atomlist, $atom);
}
return @atomlist;
}
sub AtomType
{
my ($this, $i) = @_;
my $name = &GetValue($this, "_atom_type_symbol", $i);
my $charge = &GetValue($this, "_atom_type_oxidation_number", $i);
if(!defined $name or $name eq '') {
$name = &GetValue($this, "_atom_site_label", $i);
$name =~ s/[\d+-]+//g;
$charge = 0.0;
}
#print "name: $name, $charge
\n";
return ($name, $charge);
}
sub AddAtomType
{
my ($this, $atomtype) = @_;
$atomtype = ucfirst $atomtype;
#print "AtomType: $atomtype\n";
my $nAtomType = $this->nAtomType();
#print "na=$nAtomType\n";
for(my $i = 0 ; ; $i++) {
my $val = $this->GetContent("_atom_type_symbol", $i+1);
# if(!defined $val or $val eq '') {
# $val = &GetValue($this, "_atom_site_label", $i);
# $val =~ s/[\d+-]+//g;
# }
#print "i=$i: $val:$atomtype\n";
last if($val eq '');
return $nAtomType if($val eq $atomtype);
}
my ($name,$charge,$sign) = ($atomtype =~ /^(\D+)(\d+)?([\+-])?/);
$charge = -$charge if($sign =~ /-/);
#print "name: $name - $charge - $sign
";
$nAtomType++;
$this->SetContent("_atom_type_symbol", $nAtomType, $atomtype);
$this->SetContent("_atom_type_oxidation_number", $nAtomType, $charge);
$this->SetnAtomType($nAtomType);
return $nAtomType;
}
#配列の引数は1からはじまる
sub SetAsymmetricAtomSiteVelocity
{
my ($this, $i, $vx, $vy, $vz) = @_;
$this->SetContent("Atom_site_velocity_x", $i, $vx);
$this->SetContent("Atom_site_velocity_y", $i, $vy);
$this->SetContent("Atom_site_velocity_z", $i, $vz);
my $nSites = $this->nAsymmetricAtomSite();
return $nSites;
}
sub AsymmetricAtomSiteVelocity
{
my ($this, $i) = @_;
my $vx = $this->GetContent("Atom_site_velocity_x", $i);
my $vy = $this->GetContent("Atom_site_velocity_y", $i);
my $vz = $this->GetContent("Atom_site_velocity_z", $i);
#print "CIF:AsymmetricAtomSiteVelocity: $i: ($vx, $vy, $vz)
\n";
return ($vx, $vy, $vz);
}
sub AddAsymmetricAtomSiteWithVelocity
{
my ($this, $label, $atomtype, $x, $y, $z, $occ,
$vx, $vy, $vz) = @_;
$vx = 0.0 if($vx eq '');
$vy = 0.0 if($vy eq '');
$vz = 0.0 if($vz eq '');
my $i = $this->AddAsymmetricAtomSite($label,$atomtype,$x,$y,$z,$occ);
$this->SetAsymmetricAtomSiteVelocity($i, $vx, $vy, $vz);
#print "CIF: $i: ($x,$y,$z) ($vx,$vy,$vz)
\n";
}
#配列の引数は1からはじまる
sub AddAsymmetricAtomSite
{
my ($this, $label, $atomtype, $x, $y, $z, $occ) = @_;
my $nSites = $this->nAsymmetricAtomSite();
$nSites++;
$this->SetContent("_atom_site_label", $nSites, $label);
$this->SetContent("_atom_site_type_symbol", $nSites, $atomtype);
#print "t: $atomtype\n";
$this->AddAtomType($atomtype);
$this->SetContent("_atom_site_fract_x", $nSites, $x);
$this->SetContent("_atom_site_fract_y", $nSites, $y);
$this->SetContent("_atom_site_fract_z", $nSites, $z);
$this->SetContent("_atom_site_occupancy", $nSites, $occ);
$this->SetnAsymmetricAtomSite($nSites);
#print "n: $nSites ($label)
";
return $nSites;
}
sub SetnAsymmetricAtomSite
{
my ($this,$n) = @_;
return $this->SetContent("nAsymmetricAtomSite", $n);
}
sub nAsymmetricAtomSite
{
my ($this) = @_;
return &GetValue($this, "nAsymmetricAtomSite");
}
sub GetCAsymmetricAtomSite
{
my ($this, $i) = @_;
my ($label,$type,$x,$y,$z,$occupancy)
= $this->AsymmetricAtomSite($i);
my ($vx,$vy,$vz)
= $this->AsymmetricAtomSiteVelocity($i);
my $atom = new AtomSite();
$atom->SetLabel($label);
$atom->SetAtomName($type);
$atom->SetPosition($x, $y, $z);
$atom->SetOccupancy($occupancy);
#print "v2: $i: ($vx,$vy,$vz)
\n";
$atom->SetVelocity($vx, $vy, $vz);
# my ($vx,$vy,$vz) = $atom->Velocity();
#print "v3: $i: ($vx,$vy,$vz)
\n";
return $atom;
}
sub GetCAsymmetricAtomSiteList
{
my ($this) = @_;
my $natom = $this->nAsymmetricAtomSite();
my @atomlist;
for(my $i = 0 ; $i < $natom ; $i++)
{
my $atom = $this->GetCAsymmetricAtomSite($i+1);
push(@atomlist, $atom);
}
return @atomlist;
}
sub AsymmetricAtomSite
{
my ($this, $i) = @_;
my $label = &GetValue($this, "_atom_site_label", $i);
my $type = &GetValue($this, "_atom_site_type_symbol", $i);
if(!defined $type or $type eq '') {
$type = &GetValue($this, "_atom_site_label", $i);
$type =~ s/[\d+-]+//g;
}
my $x = &GetValue($this, "_atom_site_fract_x", $i);
my $y = &GetValue($this, "_atom_site_fract_y", $i);
my $z = &GetValue($this, "_atom_site_fract_z", $i);
my $occupancy = &GetValue($this, "_atom_site_occupancy", $i);
return ($label,$type,$x,$y,$z,$occupancy);
}
sub FillCIFData
{
my ($this) = @_;
my $crystal = new Crystal();
$crystal->SetCrystalName($this->CrystalName());
$crystal->SetLatticeParameters($this->LatticeParameters());
$this->SetContent("_cell_volume", $crystal->Volume());
my $SPG = $this->GetCSpaceGroup();
$crystal->SetCSpaceGroup($SPG);
$crystal->SetCAtomTypeList($this->GetCAtomTypeList() );
$crystal->SetCAsymmetricAtomSiteList($this->GetCAsymmetricAtomSiteList() );
$crystal->ExpandCoordinates();
my @MultList = $crystal->GetCnMultiplicityExpandedAtomSiteList();
for(my $i = 0 ; $i < @MultList ; $i++) {
$this->SetContent("_atom_site_symmetry_multiplicity",
$i+1, $MultList[$i]);
}
if($this->GetContent("_symmetry_cell_setting") eq '') {
$this->SetContent("_symmetry_cell_setting",
$SPG->LatticeSystem());
}
if($SPG->SPGName() =~ /^P\s*1$/i) {
$this->SetContent("_symmetry_cell_setting", 'triclinic');
}
my %AtomCount;
my $nAsymmetricAtomSite = $crystal->nAsymmetricAtomSite();
for(my $i = 0 ; $i < $nAsymmetricAtomSite ; $i++) {
my $site = $crystal->GetCAtomSite($i);
my $mult = $MultList[$i];
my $name = $site->AtomNameOnly();
$AtomCount{$name} += $mult * $site->Occupancy();
#print "occ: ", $site->Occupancy(), "
";
}
my $s = '';
my @keys = keys %AtomCount;
for(my $i = 0 ; $i < @keys ; $i++) {
my $name = $keys[$i];
my $n = $AtomCount{$name};
my $s1 = substr("$n", 0, 5);
#print "$n:$s1
";
$s = "$s $name$s1";
}
$s =~ s/^\s+//;
$this->SetContent("_chemical_formula_structural", $s);
$this->SetContent("_chemical_formula_sum", $s);
$s =~ s/\s//g;
$this->SetContent("_chemical_name_systematic", $s);
$this->SetContent("_cell_formula_units_Z", 1);
my $date = $this->GetContent("_audit_creation_date");
if($date eq '') {
my ($sec, $min, $hour, $mday, $mon, $year,
$wday, $yday, $isdst) = localtime(time());
$mon++;
$year += 1900;
my $s = sprintf "%04d/%02d/%02d", $year, $mon, $mday;
$this->SetContent("_audit_creation_date", $s);
}
$this->SetContent("_audit_creation_method", "generated by Perl:CIF.pm 0.1");
return $crystal;
}
sub GetCCrystal
{
my ($this) = @_;
my $crystal = new Crystal();
$crystal->{'CIFFileName'} = $this->{'FileName'};
my $Sample = $this->{'FileName'};
$Sample =~ s/^(.*[\\\/])?(.*?)(\..*?)?$/$2/;
$crystal->SetCrystalName($Sample);
my $SPG = $this->GetCSpaceGroup();
$crystal->SetCSpaceGroup($SPG);
$crystal->SetLatticeParameters($this->LatticeParameters() );
my @AtomTypeList = $this->GetCAtomTypeList();
$crystal->SetCAtomTypeList(@AtomTypeList);
$crystal->SetCAsymmetricAtomSiteList($this->GetCAsymmetricAtomSiteList() );
$crystal->ExpandCoordinates();
return $crystal;
}
sub InsertSpaceToSPGName
{
my ($this, $SPGName) = @_;
if($SPGName =~ /[RH]$/) {
return $SPGName if($SPGName =~ /\s.+\S\s+[RHS]$/);
}
else {
return $SPGName if($SPGName =~ /\s/);
}
$SPGName =~ s/(.)/$1 /g;
$SPGName =~ s/\s\s+/ /g;
$SPGName =~ s/- /-/g;
$SPGName =~ s/ \/ /\//g;
$SPGName =~ s/([^\-])2 1/${1}21/g;
$SPGName =~ s/([^\-])3 1/${1}31/g;
$SPGName =~ s/([^\-])3 2/${1}32/g;
$SPGName =~ s/([^\-])4 1/${1}41/g;
$SPGName =~ s/([^\-])4 2/${1}42/g;
$SPGName =~ s/([^\-])4 3/${1}43/g;
$SPGName =~ s/([^\-])6 1/${1}61/g;
$SPGName =~ s/([^\-])6 2/${1}62/g;
$SPGName =~ s/([^\-])6 3/${1}63/g;
$SPGName =~ s/([^\-])6 4/${1}64/g;
$SPGName =~ s/([^\-])6 5/${1}65/g;
print "SPGN: $SPGName\n";
return $SPGName;
my ($Lattice, $res) = ($SPGName =~ /^(.)(.*)$/);
my ($Sym0, $res2);
if($res =~ /^(.+\/.)(.*)$/) {
($Sym0, $res2) = ($1, $2);
}
else {
($Sym0, $res2) = ($res =~ /^(-?.)(.*)$/);
}
$res2 =~ s/([^\-\/])/$1 /g;
$res2 =~ s/^\s*//;
$res2 =~ s/\s*$//;
$res2 =~ s/\s+/ /g;
$SPGName = "$Lattice $Sym0 $res2";
#print "SPGN: $SPGName\n";
return $SPGName;
}
sub WriteSimpleCIFFile
{
my ($this, $NewFile, $WritePublication, $strCRLF) = @_;
#print "