28 #include <boost/format.hpp>
30 #include "cctbx/sgtbx/space_group.h"
32 #include "ObjCryst/ObjCryst/Crystal.h"
33 #include "ObjCryst/ObjCryst/Molecule.h"
34 #include "ObjCryst/ObjCryst/Atom.h"
36 #include "ObjCryst/Quirks/VFNStreamFormat.h"
37 #include "ObjCryst/Quirks/VFNDebug.h"
40 #include "ObjCryst/wxCryst/wxCrystal.h"
48 const RefParType *gpRefParTypeCrystal=0;
49 long NiftyStaticGlobalObjectsInitializer_Crystal::mCount=0;
58 mScattererRegistry(
"List of Crystal Scatterers"),
59 mBumpMergeCost(0.0),mBumpMergeScale(1.0),
60 mDistTableMaxDistance(1.0),
61 mDistTableForInterMolMaxDistance(1.0),
62 mDistMaxMultiplier(2),
63 mScatteringPowerRegistry(
"List of Crystal ScatteringPowers"),
64 mBondValenceCost(0.0),mBondValenceCostScale(1.0),mDeleteSubObjInDestructor(1),
65 mInterMolDistCostScale(1.0),mInterMolDistCost(0.0),mCostCalcMethod(0),mInterMolDistListNeedsInit(true)
67 VFN_DEBUG_MESSAGE(
"Crystal::Crystal()",10)
69 this->
Init(10,11,12,M_PI/2+.1,M_PI/2+.2,M_PI/2+.3,
"P 1",
"");
77 Crystal::Crystal(
const REAL a,
const REAL b,
const REAL c,
const string &SpaceGroupId):
78 mScattererRegistry(
"List of Crystal Scatterers"),
79 mBumpMergeCost(0.0),mBumpMergeScale(1.0),
80 mDistTableMaxDistance(1.0),
81 mDistTableForInterMolMaxDistance(1.0),
82 mDistMaxMultiplier(2),
83 mScatteringPowerRegistry(
"List of Crystal ScatteringPowers"),
84 mBondValenceCost(0.0),mBondValenceCostScale(1.0),mDeleteSubObjInDestructor(1),
85 mInterMolDistCostScale(1.0),mInterMolDistCost(0.0),mCostCalcMethod(0),mInterMolDistListNeedsInit(true)
87 VFN_DEBUG_MESSAGE(
"Crystal::Crystal(a,b,c,Sg)",10)
88 this->
Init(a,b,c,M_PI/2,M_PI/2,M_PI/2,SpaceGroupId,
"");
98 const REAL beta,
const REAL gamma,
const string &SpaceGroupId):
99 mScattererRegistry(
"List of Crystal Scatterers"),
100 mBumpMergeCost(0.0),mBumpMergeScale(1.0),
101 mDistTableMaxDistance(1.0),
102 mDistTableForInterMolMaxDistance(1.0),
103 mDistMaxMultiplier(2),
104 mScatteringPowerRegistry(
"List of Crystal ScatteringPowers"),
105 mBondValenceCost(0.0),mBondValenceCostScale(1.0),mDeleteSubObjInDestructor(1),
106 mInterMolDistCostScale(1.0),mInterMolDistCost(0.0),mCostCalcMethod(0),mInterMolDistListNeedsInit(true)
108 VFN_DEBUG_MESSAGE(
"Crystal::Crystal(a,b,c,alpha,beta,gamma,Sg)",10)
109 this->
Init(a,b,c,alpha,beta,gamma,SpaceGroupId,
"");
119 mScattererRegistry(
"List of Crystal Scatterers"),
120 mBumpMergeCost(0.0),mBumpMergeScale(1.0),
121 mDistTableMaxDistance(1.0),
122 mDistTableForInterMolMaxDistance(1.0),
123 mDistMaxMultiplier(2),
124 mScatteringPowerRegistry(
"List of Crystal ScatteringPowers"),
125 mBondValenceCost(0.0),mBondValenceCostScale(1.0),mDeleteSubObjInDestructor(1),
126 mInterMolDistCostScale(1.0),mInterMolDistCost(0.0),mCostCalcMethod(0),mInterMolDistListNeedsInit(true)
128 VFN_DEBUG_MESSAGE(
"Crystal::Crystal()",10)
131 this->
Init(10,11,12,M_PI/2+.1,M_PI/2+.2,M_PI/2+.3,
"P 1",
"");
147 VFN_DEBUG_ENTRY(
"Crystal::~Crystal()",5)
150 VFN_DEBUG_MESSAGE(
"Crystal::~Crystal(&scatt):1:"<<i,5)
154 if( mDeleteSubObjInDestructor )
164 VFN_DEBUG_MESSAGE(
"Crystal::~Crystal(&scatt):2:"<<i,5)
169 if( mDeleteSubObjInDestructor )
179 VFN_DEBUG_EXIT(
"Crystal::~Crystal()",5)
184 const static string className=
"Crystal";
190 VFN_DEBUG_ENTRY(
"Crystal::AddScatterer(&scatt)",5)
196 VFN_DEBUG_EXIT(
"Crystal::AddScatterer(&scatt):Finished",5)
201 VFN_DEBUG_MESSAGE(
"Crystal::RemoveScatterer(&scatt)",5)
205 if(del)
delete scatt;
207 VFN_DEBUG_MESSAGE(
"Crystal::RemoveScatterer(&scatt):Finished",5)
253 VFN_DEBUG_ENTRY(
"Crystal::RemoveScatteringPower()",2)
259 if(del)
delete scattPow;
263 if((pos->first.first==scattPow)||(pos->first.second==scattPow))
271 for(map<pair<const ScatteringPower*,const ScatteringPower*>, REAL>::iterator
274 if((pos->first.first==scattPow)||(pos->first.second==scattPow))
281 VFN_DEBUG_EXIT(
"Crystal::RemoveScatteringPower()",2)
309 if(mClockScattCompList<this->
GetScatt(i).GetClockScatterer()) {update=
true;
break;}
313 VFN_DEBUG_MESSAGE(
"Crystal::GetScatteringComponentList()",2)
314 TAU_PROFILE(
"Crystal::GetScatteringComponentList()",
"ScattCompList& ()",TAU_DEFAULT);
327 VFN_DEBUG_MESSAGE(
"Crystal::GetScatteringComponentList():End",2)
340 void Crystal::Print(ostream &os)
const
342 VFN_DEBUG_MESSAGE(
"Crystal::Print()",5)
343 this->UnitCell::Print(os);
351 std::map<long, REAL>::const_iterator posBV;
362 <<
", Occup=" <<
FormatFloat(list(j).mOccupancy,6,4)
365 if( NULL != list(j).mpScattPow )
367 os <<
", ScattPow:" <<
FormatString(list(j).mpScattPow->GetName(),16)
368 <<
", Biso=" <<
FormatFloat(list(j).mpScattPow->GetBiso());
372 os <<
", ScattPow: dummy";
379 os <<
": Valence="<<posBV->second<<
" (expected="
387 <<
"Occupancy = occ * dyn, where:"<<endl
388 <<
" - occ is the 'real' occupancy"<< endl
389 <<
" - dyn is the dynamical occupancy correction, indicating either"<< endl
390 <<
" an atom on a special position, or several identical atoms "<< endl
391 <<
" overlapping (dyn=0.5 -> atom on a symetry plane / 2fold axis.."<< endl
392 <<
" -> OR 2 atoms strictly overlapping)"<< endl
398 os <<
" Total number of components (atoms) in one unit cell : " << nbAtoms<<endl
399 <<
" Chemical formula: "<< this->
GetFormula() << endl
400 <<
" Weight: "<< this->
GetWeight()<<
" g/mol" << endl;
402 VFN_DEBUG_MESSAGE(
"Crystal::Print():End",5)
409 std::map<std::string,float> velts;
417 if(velts.count(p)==0)
419 else velts[p] += psi->mOccupancy * psi->
mDynPopCorr;
422 s<<std::setprecision(2);
423 for(std::map<std::string,float>::const_iterator pos=velts.begin();pos!=velts.end();++pos)
425 if(pos!=velts.begin()) s<<
" ";
426 float nb=pos->second;
427 if(abs(round(nb)-nb)<0.005)
429 if(
int(round(nb))==1) s<<pos->first;
430 else s<<pos->first<<int(round(nb));
432 else s<<pos->first<<nb;
457 VFN_DEBUG_MESSAGE(
"Crystal::MinDistanceTable()",5)
461 CrystMatrix_REAL minDistTable(nbComponent,nbComponent);
464 REAL min=minDistance*minDistance;
465 if(minDistance<0) min = -1.;
467 for(
int i=0;i<nbComponent;i++)
470 std::vector<Crystal::Neighbour>::const_iterator pos;
471 for(pos=mvDistTableSq[i].mvNeighbour.begin();
472 pos<mvDistTableSq[i].mvNeighbour.end();pos++)
475 dist=minDistTable(i,pos->mNeighbourIndex);
477 && ((tmp>min) || ( (mvDistTableSq[i].mIndex !=pos->mNeighbourIndex)
478 &&(mvDistTableSq[i].mUniquePosSymmetryIndex
479 !=pos->mNeighbourSymmetryIndex))))
480 minDistTable(i,pos->mNeighbourIndex)=tmp;
483 for(
int i=0;i<nbComponent;i++)
485 for(
int j=0;j<=i;j++)
487 if(9999.>minDistTable(i,j)) minDistTable(i,j)=sqrt(minDistTable(i,j));
488 else minDistTable(i,j)=-1;
489 minDistTable(j,i)=minDistTable(i,j);
492 VFN_DEBUG_MESSAGE(
"Crystal::MinDistanceTable():End",3)
498 VFN_DEBUG_MESSAGE(
"Crystal::PrintMinDistanceTable()",5)
499 CrystMatrix_REAL minDistTable;
501 VFN_DEBUG_MESSAGE(
"Crystal::PrintMinDistanceTable():0",5)
502 os <<
"Table of minimal distances between all components (atoms)"<<endl;
506 VFN_DEBUG_MESSAGE(
"Crystal::PrintMinDistanceTable()1:Scatt:"<<i,3)
516 VFN_DEBUG_MESSAGE(
"Crystal::PrintMinDistanceTable()2:Scatt,comp:"<<i<<
","<<j,3)
518 for(
long k=0;k<nbComponent;k++)
520 if(minDistTable(l,k)>0) os <<
FormatFloat(minDistTable(l,k),6,3) ;
526 VFN_DEBUG_MESSAGE(
"Crystal::PrintMinDistanceTable():End",3)
531 VFN_DEBUG_MESSAGE(
"Crystal::POVRayDescription(os,bool)",5)
532 os <<
"/////////////////////// MACROS////////////////////"<<endl;
534 os <<
"#macro ObjCrystAtom(atomx,atomy,atomz,atomr,atomc,occ,atten)"
536 <<
" { <atomx,atomy,atomz>,atomr"<<endl
537 <<
" finish {ambient 0.5*occ*atten diffuse 0.4*occ*atten phong occ*atten specular 0.2*occ*atten "
538 <<
"roughness 0.02 metallic reflection 0.0}"<<endl
539 <<
" pigment { colour atomc transmit (1-occ*atten)}"<<endl
540 <<
" no_shadow"<<endl
542 <<
"#end"<<endl<<endl;
544 os <<
"#macro ObjCrystBond(x1,y1,z1,x2,y2,z2,bondradius,bondColour,occ,atten)"<<endl
546 <<
" { <x1,y1,z1>,"<<endl
547 <<
" <x2,y2,z2>,"<<endl
548 <<
" bondradius"<<endl
549 <<
" finish {ambient 0.5*occ*atten diffuse 0.4*occ*atten phong occ*atten specular 0.2*occ*atten "
550 <<
"roughness 0.02 metallic reflection 0.0}"<<endl
551 <<
" pigment { colour bondColour transmit (1-occ*atten)}"<<endl
552 <<
" no_shadow"<<endl
554 <<
"#end"<<endl<<endl;
556 os <<
"//////////// Crystal Unit Cell /////////////////" <<endl;
559 os <<
" //box{ <0,0,0>, <"<< x <<
"," << y <<
"," << z <<
">" <<endl;
560 os <<
" // pigment {colour rgbf<1,1,1,0.9>}" << endl;
561 os <<
" // hollow" << endl;
562 os <<
" //}" <<endl<<endl;
564 #define UNITCELL_EDGE(X0,Y0,Z0,X1,Y1,Z1)\
566 REAL x0=X0,y0=Y0,z0=Z0,x1=X1,y1=Y1,z1=Z1;\
567 this->FractionalToOrthonormalCoords(x0,y0,z0);\
568 this->FractionalToOrthonormalCoords(x1,y1,z1);\
569 os << " ObjCrystBond("\
570 <<x0<<","<<y0<<","<<z0<< ","\
571 <<x1<<","<<y1<<","<<z1<< ","\
572 << "0.02,rgb<1.0,1.0,1.0>,1.0,1.0)"<<endl;\
575 UNITCELL_EDGE(0,0,0,1,0,0)
576 UNITCELL_EDGE(0,0,0,0,1,0)
577 UNITCELL_EDGE(0,0,0,0,0,1)
579 UNITCELL_EDGE(1,1,1,0,1,1)
580 UNITCELL_EDGE(1,1,1,1,0,1)
581 UNITCELL_EDGE(1,1,1,1,1,0)
583 UNITCELL_EDGE(1,0,0,1,1,0)
584 UNITCELL_EDGE(1,0,0,1,0,1)
586 UNITCELL_EDGE(0,1,0,1,1,0)
587 UNITCELL_EDGE(0,1,0,0,1,1)
589 UNITCELL_EDGE(0,0,1,1,0,1)
590 UNITCELL_EDGE(0,0,1,0,1,1)
592 os <<endl<<
"/////////////// GLOBAL DECLARATIONS FOR ATOMS & BONDS ///////"<<endl;
593 os <<
"// Atom colours"<<endl;
600 <<
"= rgb <"<< r<<
","<<g<<
","<<b<<
">;"<< endl;
602 os <<
"// Bond colours"<<endl
603 <<
" #declare colour_freebond = rgb <0.7,0.7,0.7>;"<< endl
604 <<
" #declare colour_nonfreebond= rgb <0.3,0.3,0.3>;"<< endl;
607 os <<
"/////////////// SCATTERERS ///////"<<endl;
614 void Crystal::GLInitDisplayList(
const bool onlyIndependentAtoms,
615 const REAL xMin,
const REAL xMax,
616 const REAL yMin,
const REAL yMax,
617 const REAL zMin,
const REAL zMax,
618 const bool displayNames,
619 const bool hideHydrogens,
620 const REAL fadeDistance,
621 const bool fullMoleculeInLimits)
const
623 VFN_DEBUG_ENTRY(
"Crystal::GLInitDisplayList()",5)
628 REAL xc=(xMin+xMax)/2.;
629 REAL yc=(yMin+yMax)/2.;
630 REAL zc=(zMin+zMax)/2.;
631 if(false==displayNames)
673 const GLfloat colour0 [] = {0.00, 0.00, 0.00, 0.00};
674 const GLfloat colour1 [] = {0.50, 0.50, 0.50, 1.00};
675 const GLfloat colour2 [] = {1.00, 1.00, 1.00, 1.00};
676 glMaterialfv(GL_FRONT, GL_AMBIENT, colour1);
677 glMaterialfv(GL_FRONT, GL_DIFFUSE, colour0);
678 glMaterialfv(GL_FRONT, GL_SPECULAR, colour0);
679 glMaterialfv(GL_FRONT, GL_EMISSION, colour1);
680 glMaterialfv(GL_FRONT, GL_SHININESS, colour0);
682 x=1.2-xc;y=-yc;z=-zc;
684 glRasterPos3f(en*x,y,z);
687 x=-xc;y=1.2-yc;z=-zc;
689 glRasterPos3f(en*x,y,z);
692 x=-xc;y=-yc;z=1.2-zc;
694 glRasterPos3f(en*x,y,z);
697 glMaterialfv(GL_FRONT, GL_AMBIENT, colour1);
698 glMaterialfv(GL_FRONT, GL_DIFFUSE, colour1);
699 glMaterialfv(GL_FRONT, GL_SPECULAR, colour1);
700 glMaterialfv(GL_FRONT, GL_EMISSION, colour0);
701 glMaterialfv(GL_FRONT, GL_SHININESS, colour0);
703 glTranslatef(-xc*en, -yc, -zc);
706 glNormal3f((x110+x010-xM)*en,y110+y010-yM,z110+z010-zM);
707 glVertex3f( x110*en, y110, z110);
708 glVertex3f( x010*en, y010, z010);
710 glNormal3f((x011+x010-xM)*en,y011+y010-yM,z011+z010-zM);
711 glVertex3f( x010*en, y010, z010);
712 glVertex3f( x011*en, y011, z011);
714 glNormal3f((x011+x111-xM)*en,y011+y111-yM,z011+z111-zM);
715 glVertex3f( x011*en, y011, z011);
716 glVertex3f( x111*en, y111, z111);
718 glNormal3f((x110+x111-xM)*en,y110+y111-yM,z110+z111-zM);
719 glVertex3f( x111*en, y111, z111);
720 glVertex3f( x110*en, y110, z110);
722 glNormal3f((x101+x001-xM)*en,y101+y001-yM,z101+z001-zM);
723 glVertex3f( x101*en, y101, z101);
724 glVertex3f( x001*en, y001, z001);
726 glNormal3f((x000+x001-xM)*en,y000+y001-yM,z000+z001-zM);
727 glVertex3f( x001*en, y001, z001);
728 glVertex3f( x000*en, y000, z000);
730 glNormal3f((x000+x100-xM)*en,y000+y100-yM,z000+z100-zM);
731 glVertex3f( x000*en, y000, z000);
732 glVertex3f( x100*en, y100, z100);
734 glNormal3f((x101+x100-xM)*en,y101+y100-yM,z101+z100-zM);
735 glVertex3f( x100*en, y100, z100);
736 glVertex3f( x101*en, y101, z101);
738 glNormal3f((x101+x111-xM)*en,y101+y111-yM,z101+z111-zM);
739 glVertex3f( x101*en, y101, z101);
740 glVertex3f( x111*en, y111, z111);
742 glNormal3f((x001+x011-xM)*en,y001+y011-yM,z001+z011-zM);
743 glVertex3f( x001*en, y001, z001);
744 glVertex3f( x011*en, y011, z011);
746 glNormal3f((x000+x010-xM)*en,y000+y010-yM,z000+z010-zM);
747 glVertex3f( x000*en, y000, z000);
748 glVertex3f( x010*en, y010, z010);
750 glNormal3f((x100+x110-xM)*en,y100+y110-yM,z100+z110-zM);
751 glVertex3f( x100*en, y100, z100);
752 glVertex3f( x110*en, y110, z110);
758 VFN_DEBUG_MESSAGE(
"Crystal::GLView(bool):Scatterers...",5)
761 glTranslatef(-xc*en, -yc, -zc);
762 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
764 bool displayEnantiomer=
false;
767 this->
GetScatt(i).GLInitDisplayList(onlyIndependentAtoms,
768 xMin,xMax,yMin,yMax,zMin,zMax,
769 displayEnantiomer,displayNames,hideHydrogens,fadeDistance,fullMoleculeInLimits);
772 VFN_DEBUG_EXIT(
"Crystal::GLInitDisplayList(bool)",5)
778 VFN_DEBUG_ENTRY(
"Crystal::CalcDynPopCorr(REAL)",4)
779 TAU_PROFILE(
"Crystal::CalcDynPopCorr()",
"void (REAL)",TAU_DEFAULT);
786 CrystVector_REAL neighborsDist(nbComponent*nbSymmetrics);
791 const REAL overlapDistSq=overlapDist*overlapDist;
793 for(
long i=0;i<nbComponent;i++)
795 VFN_DEBUG_MESSAGE(
"Crystal::CalcDynPopCorr(): Component:"<<i,0)
803 std::vector<Crystal::Neighbour>::const_iterator pos;
804 for(pos=mvDistTableSq[i].mvNeighbour.begin();
805 pos<mvDistTableSq[i].mvNeighbour.end();pos++)
807 VFN_DEBUG_MESSAGE(
"Crystal::CalcDynPopCorr(): Component:"<<i<<
"Neighbour:"<<pos->mNeighbourIndex,0)
809 if(atomicNumber==
mScattCompList(pos->mNeighbourIndex).mpScattPow->GetDynPopCorrIndex())
811 if(overlapDistSq > pos->mDist2)
815 if(nbNeighbors==neighborsDist.numElements()) neighborsDist.resizeAndPreserve(nbNeighbors+20);
816 neighborsDist(nbNeighbors++)=sqrt(pos->mDist2);
821 for(
long j=0;j<nbNeighbors;j++)
823 dist=neighborsDist(j)-mergeDist;
825 corr += fabs((overlapDist-dist-mergeDist)/(overlapDist-mergeDist));
830 VFN_DEBUG_EXIT(
"Crystal::CalcDynPopCorr(REAL):End.",4)
855 throw ObjCrystException(
"Crystal::GetDynPopCorr(): did not find this scatterer !");
861 VFN_DEBUG_MESSAGE(
"Crystal::SetUseDynPopCorr()",1)
873 VFN_DEBUG_MESSAGE(
"Crystal::FindScatterer(name)",0)
879 Cannot find this scatterer:"+scattName);
881 vector<int> Crystal::FindScatterersInComponentList(
const string &scattName)
const
884 for(
int i=0;i<mNamedScattCompList.size();i++) {
885 if(mNamedScattCompList[i].
mName.compare(scattName)==0) {
891 bool Crystal::isScattererInInterMolDistList(
string &scattName)
const
893 for(
long i=0;i<mInterMolDistList.size();i++) {
894 for(
long j=0;j<mInterMolDistList[i].mAt1.size();j++) {
895 if(mInterMolDistList[i].mAt1[j].compare(scattName)==0) {
899 for(
long j=0;j<mInterMolDistList[i].mAt2.size();j++) {
900 if(mInterMolDistList[i].mAt2[j].compare(scattName)==0) {
907 bool Crystal::isScattererInInterMolDistListAt1(
string &scattName)
const
909 for(
long i=0;i<mInterMolDistList.size();i++) {
910 for(
long j=0;j<mInterMolDistList[i].mAt1.size();j++) {
911 if(mInterMolDistList[i].mAt1[j].compare(scattName)==0) {
918 bool Crystal::isScattererInInterMolDistListAt2(
string &scattName)
const
920 for(
long i=0;i<mInterMolDistList.size();i++) {
921 for(
long j=0;j<mInterMolDistList[i].mAt2.size();j++) {
922 if(mInterMolDistList[i].mAt2[j].compare(scattName)==0) {
930 Crystal::BumpMergePar::BumpMergePar():
931 mDist2(1.),mCanOverlap(false){}
933 Crystal::BumpMergePar::BumpMergePar(
const REAL dist,
const bool canOverlap):
934 mDist2(dist*dist),mCanOverlap(canOverlap){}
943 VFN_DEBUG_ENTRY(
"Crystal::GetBumpMergeCost()",4)
946 TAU_PROFILE(
"Crystal::GetBumpMergeCost()",
"REAL (REAL)",TAU_DEFAULT);
950 std::vector<NeighbourHood>::const_iterator pos;
951 std::vector<Crystal::Neighbour>::const_iterator neigh;
954 VBumpMergePar::const_iterator par;
955 for(pos=mvDistTableSq.begin();pos<mvDistTableSq.end();pos++)
958 for(neigh=pos->mvNeighbour.begin();neigh<pos->mvNeighbour.end();neigh++)
964 if(neigh->mDist2 > par->second.mDist2)
continue;
965 if(
true==par->second.mCanOverlap)
966 tmp = 0.5*sin(M_PI*(1.-sqrt(neigh->mDist2/par->second.mDist2)))/0.1;
968 tmp = tan(M_PI*0.49999*(1.-sqrt(neigh->mDist2/par->second.mDist2)))/0.1;
981 VFN_DEBUG_MESSAGE(
"Crystal::SetBumpMergeDistance()",5)
988 const bool allowMerge)
990 VFN_DEBUG_MESSAGE(
"Crystal::SetBumpMergeDistance("<<scatt1.
GetName()<<
","<<scatt2.
GetName()<<
")="<<dist<<
","<<allowMerge,3)
991 if(&scatt1 < &scatt2)
1000 Crystal::VBumpMergePar::iterator pos;
1001 if(&scatt1 < &scatt2) pos=
mvBumpMergePar.find(make_pair(&scatt1 , &scatt2));
1010 Crystal::InterMolDistPar::InterMolDistPar():
1011 mActDist(-1),mDist2(-1),mSig(0.01),mDelta(0.01)
1013 Crystal::InterMolDistPar::InterMolDistPar(
const vector<string> At1,
const vector<string> At2,
const REAL actualDist,
const REAL dist,
const REAL sigma,
const REAL delta):
1014 mAt1(At1),mAt2(At2),mActDist(actualDist),mDist2(dist*dist),mSig(sigma),mDelta(delta)
1016 string Crystal::InterMolDistPar::get_list_At1()
1019 for(
int j=0;j<mAt1.size();j++) {
1021 if(j<(mAt1.size()-1)) {
1027 string Crystal::InterMolDistPar::get_list_At2()
1030 for(
int j=0;j<mAt2.size();j++) {
1032 if(j<(mAt2.size()-1)) {
1038 void Crystal::InterMolDistPar::set_At2(
string atom_names)
1040 stringstream ss(atom_names);
1042 while (ss >> word) {
1043 mAt2.push_back(word);
1046 void Crystal::SetNewInterMolDist(
const vector<string> At1,
const vector<string> At2,
const REAL dist,
const REAL sigma,
const REAL delta)
const
1048 mInterMolDistList.push_back(InterMolDistPar(At1, At2, 0, dist, sigma, delta));
1049 mInterMolDistListNeedsInit=
true;
1051 int Crystal::GetIntermolDistNb()
const
1053 return mInterMolDistList.size();
1055 void Crystal::RemoveIntermolDistPar(
int Index)
const
1057 if((Index>=mInterMolDistList.size()) || (Index<0))
return;
1059 mInterMolDistList.erase(mInterMolDistList.begin() + Index);
1060 mInterMolDistListNeedsInit=
true;
1064 Crystal::InterMolDistPar Crystal::GetIntermolDistPar(
int Index)
const
1066 if((Index>=mInterMolDistList.size()) || (Index<0)) {
1067 return InterMolDistPar();
1069 return mInterMolDistList[Index];
1071 Crystal::InterMolDistPar *Crystal::GetIntermolDistPar_ptr(
int Index)
const
1073 if((Index>=mInterMolDistList.size()) || (Index<0)) {
1076 return &mInterMolDistList[Index];
1078 REAL Crystal::GetInterMolDistCost()
const
1080 if(mInterMolDistList.size()==0)
return 0;
1081 if(mInterMolDistCostScale==0.0)
return 0;
1083 this->CalcDistTableForInterMolDistCost();
1085 VFN_DEBUG_ENTRY(
"Crystal::GetInterMolDistCost()",4)
1087 TAU_PROFILE("
Crystal::GetInterMolDistCost()","REAL (REAL)",TAU_DEFAULT);
1089 mInterMolDistCost=0;
1091 std::vector<NeighbourHood>::const_iterator pos;
1092 std::vector<
Crystal::Neighbour>::const_iterator neigh;
1094 std::vector<InterMolDistPar>::const_iterator imd;
1095 std::vector<
string>::const_iterator itAt2;
1099 float mindiff=10000000;
1104 for(imd = mInterMolDistList.begin();imd<mInterMolDistList.end();imd++) {
1107 bestDist = mDistTableForInterMolMaxDistance;
1109 for(pos=imd->mNbh.begin();pos<imd->mNbh.end();pos++)
1111 for(neigh=pos->mvNeighbour.begin();neigh<pos->mvNeighbour.end();neigh++)
1113 if(imd->mDist2 > neigh->mDist2) actdiff = imd->mDist2 - neigh->mDist2;
1114 else actdiff = neigh->mDist2 - imd->mDist2;
1117 if(actdiff<mindiff) {
1119 bestDist = neigh->mDist2;
1129 if(bestDist<=0) bestDist = 0.00001;
1130 else bestDist = sqrt(bestDist);
1134 float d = imd->mDist2;
1135 if(d<=0) d = 0.0000001;
1140 if(mCostCalcMethod==0) {
1142 if((bestDist < (d + imd->mDelta)) && (bestDist > (d - imd->mDelta))) {
1143 mInterMolDistCost += 0;
1145 }
else if(bestDist<=(d-imd->mDelta)) {
1146 mInterMolDistCost += pow((bestDist-(d-imd->mDelta))/imd->mSig, 2);
1149 mInterMolDistCost += pow((bestDist-(d+imd->mDelta))/imd->mSig, 2);
1152 }
else if(mCostCalcMethod==1) {
1154 if((bestDist < (d + imd->mDelta)) && (bestDist > (d - imd->mDelta))) {
1155 mInterMolDistCost += 0;
1156 }
else if(bestDist<=(d-imd->mDelta)) {
1157 mInterMolDistCost += 1 - ( 1 / ( 1 + pow( ((bestDist-(d-imd->mDelta)) / imd->mSig), 2)));
1159 mInterMolDistCost += 1 - ( 1 / ( 1 + pow( ((bestDist-(d+imd->mDelta)) / imd->mSig), 2)));
1161 }
else if(mCostCalcMethod==2) {
1167 float sig = d/1.122462;
1168 if((bestDist < (d + imd->mDelta)) && (bestDist > (d - imd->mDelta))) {
1169 mInterMolDistCost += 0;
1170 }
else if(bestDist<=(d-imd->mDelta)) {
1171 float ri = bestDist+imd->mDelta;
1173 mInterMolDistCost += 1;
1175 mInterMolDistCost += 4*1*((pow(sig/ri, 12)-pow(sig/ri, 6)))+1;
1178 float ri = bestDist-imd->mDelta;
1179 mInterMolDistCost += 4*1*((pow(sig/ri, 12)-pow(sig/ri, 6)))+1;
1190 mInterMolDistCostClock.
Click();
1192 return mInterMolDistCost*mInterMolDistCostScale;
1202 VFN_DEBUG_ENTRY(
"Crystal::GlobalOptRandomMove()",2)
1205 if( ((rand()/(REAL)RAND_MAX)<.02) && (nb>1))
1209 const unsigned long n1=rand()%nb;
1210 const unsigned long n2=( (rand()%(nb-1)) +n1+1) %nb;
1226 VFN_DEBUG_EXIT(
"Crystal::GlobalOptRandomMove()",2)
1236 VFN_DEBUG_ENTRY(
"Crystal::OutputCIF()",5)
1239 string tempname =
mName;
1241 size = tempname.size();
1244 tempname = tempname.substr(0,32);
1245 size = tempname.size();
1252 where = tempname.find(
" ",0);
1253 while (where != (
int)string::npos)
1255 tempname.replace(where,1,
"_");
1256 where = tempname.find(
" ",0);
1259 os <<
"data_" << tempname <<endl<<endl;
1262 os <<
"_computing_structure_solution 'FOX http://objcryst.sourceforge.net'"<<endl<<endl;
1280 os <<
"_symmetry_space_group_name_H-M '"
1286 os <<
"_symmetry_space_group_name_Hall '"
1308 os <<
"loop_" << endl
1309 <<
" _atom_site_label" <<endl
1310 <<
" _atom_site_type_symbol" <<endl
1311 <<
" _atom_site_fract_x"<<endl
1312 <<
" _atom_site_fract_y" <<endl
1313 <<
" _atom_site_fract_z" <<endl
1314 <<
" _atom_site_U_iso_or_equiv" <<endl
1315 <<
" _atom_site_occupancy" <<endl
1316 <<
" _atom_site_adp_type" <<endl;
1318 const double BtoU = 1.0 / (8 * M_PI * M_PI);
1319 std::vector<const ScatteringPower*> anisovec;
1320 std::vector<std::string> namevec;
1321 CrystMatrix_REAL minDistTable;
1330 if(0==list(j).mpScattPow)
continue;
1331 bool redundant=
false;
1332 for(
unsigned long l=0;l<k;++l)
if(abs(minDistTable(l,k))<mindist) redundant=
true;
1337 size_t posc=s.find(
' ');
1338 while(posc!=string::npos){s[posc]=
'~';posc=s.find(
' ');}
1340 bool isiso = list(j).mpScattPow->IsIsotropic();
1343 anisovec.push_back(list(j).mpScattPow);
1344 namevec.push_back(s);
1349 <<
FormatString(list(j).mpScattPow->GetSymbol(),8) <<
" "
1353 <<
FormatFloat(list(j).mpScattPow->GetBiso()*BtoU,9,6) <<
" "
1355 << (isiso ?
" Uiso" :
" Uani")
1364 if( anisovec.size() > 0 )
1369 <<
" _atom_site_aniso_label" << endl
1370 <<
" _atom_site_aniso_U_11" << endl
1371 <<
" _atom_site_aniso_U_22" << endl
1372 <<
" _atom_site_aniso_U_33" << endl
1373 <<
" _atom_site_aniso_U_12" << endl
1374 <<
" _atom_site_aniso_U_13" << endl
1375 <<
" _atom_site_aniso_U_23" << endl;
1378 for(
size_t i = 0; i < anisovec.size(); ++i)
1381 for(
int j=0; j<6; ++j)
1382 os <<
FormatFloat(anisovec[i]->GetBij(j)*BtoU,9,6) <<
" ";
1395 if(0==list(j).mpScattPow)
continue;
1396 bool redundant=
false;
1397 for(
unsigned long l=0;l<k;++l)
if(abs(minDistTable(l,k))<mindist) redundant=
true;
1404 <<
"# The following atoms have been excluded by Fox because they are"<<endl
1405 <<
"# almost fully overlapping with another atom (d<" << mindist <<
"A)"<< endl;
1408 <<
FormatString(list(j).mpScattPow->GetName(),8) <<
" "
1413 <<
FormatFloat(list(j).mpScattPow->GetBiso()*BtoU,9,6) <<
" "
1426 os <<
"# Dynamical occupancy corrections found by ObjCryst++:"<<endl
1427 <<
"# values below 1. (100%) indicate a correction,"<<endl
1428 <<
"# which means either that the atom is on a special position,"<<endl
1429 <<
"# or that it is overlapping with another identical atom."<<endl;
1446 VFN_DEBUG_EXIT(
"Crystal::OutputCIF()",5)
1450 CrystVector_uint & groupIndex,
1451 unsigned int &first)
const
1454 unsigned int latticeIndex=0;
1455 VFN_DEBUG_MESSAGE(
"Crystal::GetGeneGroup()",4)
1457 for(
long j=0;j<this->
GetNbPar();j++)
1462 if(latticeIndex==0) latticeIndex=first++;
1463 groupIndex(i)=latticeIndex;
1495 mDistTableForInterMolMaxDistance = 1.0;
1496 for(
int i=0;i<mInterMolDistList.size();i++) {
1497 if(mInterMolDistList[i].mDist2>0) {
1498 float d = sqrt(mInterMolDistList[i].mDist2);
1499 if(d>mDistTableForInterMolMaxDistance) {
1500 mDistTableForInterMolMaxDistance = d;
1505 mInterMolDistListNeedsInit =
true;
1507 if(mInterMolDistList.size()!=0) {
1508 mDistTableForInterMolMaxDistance*=mDistMaxMultiplier;
1522 void Crystal::RemoveBondValenceRo(
const ScatteringPower &pow1,
const ScatteringPower &pow2)
1524 map<pair<const ScatteringPower*,const ScatteringPower*>, REAL>::iterator pos;
1533 VFN_DEBUG_MESSAGE(
"Crystal::GetBondValenceCost()?",4)
1543 VFN_DEBUG_MESSAGE(
"Crystal::GetBondValenceCost():"<<
mvBondValenceCalc.size()<<
" valences",4)
1544 TAU_PROFILE(
"Crystal::GetBondValenceCost()",
"REAL ()",TAU_DEFAULT);
1546 std::map<long, REAL>::const_iterator pos;
1549 const REAL a=pos->second-
mScattCompList(pos->first).mpScattPow->GetFormalCharge();
1551 VFN_DEBUG_MESSAGE(
"Crystal::GetBondValenceCost():"
1553 <<
"="<<pos->second,4)
1559 std::map<pair<const ScatteringPower*,const ScatteringPower*>, REAL>& Crystal::GetBondValenceRoList()
1562 const std::map<pair<const ScatteringPower*,const ScatteringPower*>, REAL>& Crystal::GetBondValenceRoList()
const
1569 VFN_DEBUG_MESSAGE(
"Crystal::CalcBondValenceSum()?",4)
1572 VFN_DEBUG_MESSAGE(
"Crystal::CalcBondValenceSum()",4)
1573 TAU_PROFILE(
"Crystal::CalcBondValenceSum()",
"void ()",TAU_DEFAULT);
1580 std::vector<Crystal::Neighbour>::const_iterator pos;
1581 for(pos=mvDistTableSq[i].mvNeighbour.begin();
1582 pos<mvDistTableSq[i].mvNeighbour.end();pos++)
1584 const REAL dist=sqrt(pos->mDist2);
1585 const REAL occup=
mScattCompList(pos->mNeighbourIndex).mOccupancy
1588 map<pair<const ScatteringPower*,const ScatteringPower*>,REAL>::const_iterator pos;
1593 const REAL v=exp((pos->second-dist)/0.37);
1604 const REAL beta,
const REAL gamma,
const string &SpaceGroupId,
1607 VFN_DEBUG_MESSAGE(
"Crystal::Init(a,b,c,alpha,beta,gamma,Sg,name)",10)
1613 VFN_DEBUG_MESSAGE(
"Crystal::Init(a,b,c,alpha,beta,gamma,Sg,name):End",10)
1618 return b1->GetLength()<b2->GetLength();
1621 bool ComparePairSecond(
const std::pair<int,float> &b1,
const std::pair<int,float> &b2)
1623 return b1.second < b2.second;
1628 VFN_DEBUG_ENTRY(
"Crystal::ConnectAtoms(...)",10)
1634 if(warnuser_fail) (*fpObjCrystInformUser)(
"Crystal::ConnectAtoms(): cannot connect atoms unless there are only Atoms in a Crystal");
1644 std::set<int> vAssignedAtoms;
1645 std::set<int> vTriedAtom0;
1646 VFN_DEBUG_MESSAGE(
"Crystal::ConnectAtoms(...)",10)
1649 VFN_DEBUG_MESSAGE(
"Crystal::ConnectAtoms(...): new Molecule ?",7)
1652 int maxAtomicNumber = 0;
1655 if((vAssignedAtoms.count(i)>0) || (vTriedAtom0.find(i)!=vTriedAtom0.end()) )
continue;
1656 if(
mScattCompList(i).mpScattPow->GetClassName()==
"ScatteringPowerAtom")
1664 else if((p->
GetAtomicNumber()>maxAtomicNumber) && (maxAtomicNumber!=6))
1673 (*fpObjCrystInformUser)(
"Crystal::ConnectAtoms(): cannot connect atoms unless there are only Atoms in a Crystal");
1674 VFN_DEBUG_EXIT(
"Crystal::ConnectAtoms(...):cannot connect atoms unless there are only Atoms in the structure:"<<i<<
":"<<
mScattCompList(i).mpScattPow->GetClassName(),10)
1680 if((pmol==NULL) && warnuser_fail)
1682 (*fpObjCrystInformUser)(
"Crystal::ConnectAtoms(): cannot connect atoms unless there is at least one carbon atom");
1683 VFN_DEBUG_EXIT(
"Crystal::ConnectAtoms(...):cannot connect atoms unless there is at least one carbon atom",10)
1688 vTriedAtom0.insert(atom0);
1691 std::map<int,int>newAtoms;
1693 std::map<MolAtom*,int> molAtoms;
1699 vAssignedAtoms.insert(atom0);
1708 pmol->GetAtomList().back()->SetOccupancy(occ);
1710 molAtoms[pmol->GetAtomList().back()]=atom0;
1712 vector<unsigned int> vElementCount(140);
1713 for(vector<unsigned int>::iterator pos=vElementCount.begin();pos!=vElementCount.end();++pos) *pos=0;
1715 while(newAtoms.size()>0)
1717 atom0=newAtoms.begin()->first;
1719 VFN_DEBUG_ENTRY(
"Crystal::ConnectAtoms(...):atom0="<<atom0<<
","<<
mScattererRegistry.GetObj(atom0).GetName()<<
"["<<p0->
GetSymbol()<<
"],"<<newAtoms.size()<<
" new atoms",7)
1720 std::vector<std::pair<int,float> > vatomsneighbours;
1722 for(std::vector<Crystal::Neighbour>::const_iterator pos=mvDistTableSq[atom0].mvNeighbour.begin();
1723 pos!=mvDistTableSq[atom0].mvNeighbour.end();pos++)
1730 if( ((min_relat_dist*dcov)<sqrt(pos->mDist2))
1731 &&((max_relat_dist*dcov)>sqrt(pos->mDist2)))
1733 VFN_DEBUG_MESSAGE(
"Crystal::ConnectAtoms(...):atom0="<<
mScattererRegistry.GetObj(atom0).GetName()<<
"-"<<p1->
GetName()<<
"("<<p1->
GetMaxCovBonds()<<
"):dcov="<<dcov<<
",d="<<sqrt(pos->mDist2),7)
1734 vatomsneighbours.push_back(std::make_pair(pos->mNeighbourIndex,sqrt(pos->mDist2)));
1738 VFN_DEBUG_MESSAGE(
"Crystal::ConnectAtoms(...):atom0="<<
mScattererRegistry.GetObj(atom0).GetName()<<
"-"<<p1->
GetName()<<
"("<<p1->
GetMaxCovBonds()<<
"):dcov="<<dcov<<
",d="<<sqrt(pos->mDist2),5)
1744 float extra=vatomsneighbours.size()-maxbonds;
1749 for(std::vector<std::pair<int,float> >::const_iterator pos=vatomsneighbours.begin();pos!=vatomsneighbours.end();++pos)
1753 extra = nbbond-maxbonds;
1756 std::sort(vatomsneighbours.begin(), vatomsneighbours.end(),ComparePairSecond);
1757 VFN_DEBUG_ENTRY(
"Crystal::ConnectAtoms(...): too many bonds for"<<
mScattererRegistry.GetObj(atom0).GetName()
1758 <<
" ?(allowed="<<maxbonds<<
",nb="<<vatomsneighbours.size()<<
",nb_occ="<<nbbond<<
",longest="<<vatomsneighbours.back().second<<
"["
1760 const REAL maxdist=vatomsneighbours[vatomsneighbours.size()-extra].second*1.05;
1761 while(vatomsneighbours.back().second>maxdist)
1763 VFN_DEBUG_MESSAGE(
"Crystal::ConnectAtoms(...): Remove bond="<<
mScattererRegistry.GetObj(atom0).GetName()
1764 <<
"-"<<
mScattererRegistry.GetObj(vatomsneighbours.back().first).GetName()<<
", d="<<vatomsneighbours.back().second,10)
1765 vatomsneighbours.pop_back();
1767 VFN_DEBUG_EXIT(
"Crystal::ConnectAtoms(...): too many bonds for"<<
mScattererRegistry.GetObj(atom0).GetName()
1768 <<
" ?(allowed="<<maxbonds<<
",nb="<<vatomsneighbours.size()<<
",longest="<<vatomsneighbours.back().second<<
"["
1775 for(std::vector<std::pair<int,float> >::const_iterator pos=vatomsneighbours.begin();pos!=vatomsneighbours.end();++pos)
1777 if(vAssignedAtoms.count(pos->first)!=0)
1784 vAssignedAtoms.insert(pos->first);
1791 pmol->GetAtomList().back()->SetOccupancy(occ);
1793 molAtoms[pmol->GetAtomList().back()]=pos->first;
1797 newAtoms.erase(atom0);
1798 VFN_DEBUG_EXIT(
"Crystal::ConnectAtoms(...):atom0="<<atom0<<
","<<
mScattererRegistry.GetObj(atom0).GetName()<<
"["<<p0->
GetSymbol()<<
"],"<<newAtoms.size()<<
" new atoms. Temp Molecule:"<<pmol->
GetFormula(),7)
1802 if((vElementCount[6]>0) && (pmol->
GetNbComponent()>=3)) keep=
true;
1806 std::vector<unsigned int> vnb;
1808 cout<<
" Crystal::ConnectAtoms(..): Molecule ?";
1810 for(
unsigned int i=0;i<vElementCount.size();++i)
1811 if(vElementCount[i]!=0)
1813 vnb.push_back(vElementCount[i]);
1815 cout<<
"Z="<<i<<
"("<< vElementCount[i]<<
") ";
1824 if((vElementCount[8]==1) && (vElementCount[1]==2)) keep=
true;
1825 if((vElementCount[8]==1) && (vElementCount[1]==3)) keep=
true;
1826 if((vElementCount[7]==1) && (vElementCount[1]==3)) keep=
true;
1827 if((vElementCount[7]==1) && (vElementCount[1]==4)) keep=
true;
1828 if((vElementCount[7]==1) && (vElementCount[8]==2)) keep=
true;
1829 if((vElementCount[7]==1) && (vElementCount[8]==3)) keep=
true;
1830 if((vElementCount[5]==1) && (vElementCount[1]==3)) keep=
true;
1831 if((vElementCount[5]==1) && (vElementCount[1]==4)) keep=
true;
1832 if((vElementCount[14]==1) && (vElementCount[8]==4)) keep=
true;
1833 if((vElementCount[15]==1) && (vElementCount[8]==4)) keep=
true;
1837 if( ((vnb[0]==1)||(vnb[1]==1)) && ((vnb[0]+vnb[1])>2)) keep=
true;
1845 VFN_DEBUG_MESSAGE(
"Crystal::ConnectAtoms(...):Rejected molecule: "<<pmol->
GetFormula(),10)
1847 for(std::map<MolAtom*,int>::const_iterator pos=molAtoms.begin();pos!=molAtoms.end();++pos) vAssignedAtoms.erase(pos->second);
1852 for(
unsigned int i=0;i<pmol->GetAtomList().size();i++)
1854 for(
unsigned int j=i+1;j<pmol->GetAtomList().size();j++)
1856 const REAL d=
GetBondLength(pmol->GetAtom(i), pmol->GetAtom(j));
1859 if( ((min_relat_dist*dcov)<d) && ((max_relat_dist*dcov)>d))
1861 VFN_DEBUG_MESSAGE(
"Crystal::ConnectAtoms(...):Add bond="<<pmol->GetAtom(i).GetName()<<
"-"<<pmol->GetAtom(j).GetName()<<
", d="<<d<<
"(dcov="<<dcov<<
")",6)
1862 pmol->
AddBond(pmol->GetAtom(i),pmol->GetAtom(j),d,.01,.02,
false);
1870 for(vector<MolAtom*>::iterator pos=pmol->GetAtomList().begin();pos!=pmol->GetAtomList().end();)
1876 VFN_DEBUG_MESSAGE(
"Crystal::ConnectAtoms(...):no bond remaining for:"<<(*pos)->GetName()<<
"! Removing atom from Molecule",10)
1878 vAssignedAtoms.erase(molAtoms[*pos]);
1879 molAtoms.erase(*pos);
1884 int extra=p->second.size()-maxbonds;
1888 std::vector<MolBond*> vbonds;
1890 for(std::set<MolAtom*>::iterator p1=p->second.begin();p1!=p->second.end();++p1)
1892 vbonds.push_back(*(pmol->
FindBond(**pos,**p1)));
1893 nbbond+=(*p1)->GetOccupancy();
1895 VFN_DEBUG_MESSAGE(
"Crystal::ConnectAtoms(...): too many bonds for"<<(*pos)->GetName()<<
" ?(allowed="<<maxbonds<<
",nb="<<p->second.size()<<
",nb_occ="<<nbbond<<
")", 10)
1896 const int extra= (int)(nbbond-maxbonds);
1899 std::sort(vbonds.begin(), vbonds.end(),CompareBondDist);
1900 if(
size_t(extra) < vbonds.size())
1902 const REAL maxdist=vbonds[vbonds.size()-extra]->GetLength()*1.05;
1903 while(vbonds.back()->GetLength()>maxdist)
1905 VFN_DEBUG_MESSAGE(
"Crystal::ConnectAtoms(...): Remove bond="<<vbonds.back()->GetAtom1().GetName()<<
"-"<<vbonds.back()->GetAtom2().GetName()<<
", d="<<vbonds.back()->GetLength(),10)
1908 VFN_DEBUG_MESSAGE(
"Crystal::ConnectAtoms(...): Next bond ="<<vbonds.back()->GetAtom1().GetName()<<
"-"<<vbonds.back()->GetAtom2().GetName()<<
", d="<<vbonds.back()->GetLength(),10)
1920 for(set<MolAtom*>::const_iterator pos1=pos->second.begin();
1921 pos1!=pos->second.end();++pos1)
1923 for(set<MolAtom*>::const_iterator pos2=pos1;
1924 pos2!=pos->second.end();++pos2)
1926 if(pos2==pos1)
continue;
1927 if(pmol->
FindBondAngle(**pos1,*(pos->first),**pos2)== pmol->GetBondAngleList().end())
1929 GetBondAngle(**pos1,*(pos->first),**pos2),0.01,0.02,
false);
1934 REAL xc=0,yc=0,zc=0;
1935 for(std::map<MolAtom*,int>::const_iterator pos=molAtoms.begin();pos!=molAtoms.end();++pos)
1949 VFN_DEBUG_MESSAGE(
"Crystal::ConnectAtoms(...): center?"<<pmol->
GetNbComponent()<<
","<<molAtoms.size()<<
":"<<xc<<
","<<yc<<
","<<zc,10)
1954 (*fpObjCrystInformUser)(
"ConnectAtoms: found Molecule: "+pmol->
GetFormula());
1956 std::set<Scatterer*> vpAtom;
1957 for(std::set<int>::const_iterator pos=vAssignedAtoms.begin();pos!=vAssignedAtoms.end();++pos)
1962 while(vpAtom.size()>0)
1964 VFN_DEBUG_MESSAGE(
"Crystal::ConnectAtoms(...): remove atom:"<<(*vpAtom.begin())->GetName()<<
","<<vpAtom.size()<<
" remaining...",6)
1966 vpAtom.erase(vpAtom.begin());
1968 VFN_DEBUG_EXIT(
"Crystal::ConnectAtoms(...)",10)
1973 VFN_DEBUG_ENTRY(
"Crystal::MergeEqualScatteringPowers("<<oneScatteringPowerPerElement<<
")", 10)
1975 std::set<ScatteringPower*> vremovedpow;
1976 std::map<ScatteringPower*,std::set<ScatteringPower*> > vequivpow;
1980 if(vremovedpow.find(p1)!=vremovedpow.end())
continue;
1981 vequivpow[p1] = std::set<ScatteringPower*>();
1985 if(oneScatteringPowerPerElement)
1992 if(*p1 != *p2)
continue;
1994 vequivpow[p1].insert(p2);
1995 vremovedpow.insert(p2);
1998 if(oneScatteringPowerPerElement)
2001 for(std::map<
ScatteringPower*,std::set<ScatteringPower*> >::iterator pos=vequivpow.begin();pos!=vequivpow.end();++pos)
2003 if(pos->second.size()==0)
continue;
2004 REAL b = pos->first->GetBiso();
2005 CrystVector_REAL bij(6);
2006 for(
unsigned int i=0;i<6;i++) bij(i) = pos->first->GetBij(i);
2007 for(std::set<ScatteringPower*>::const_iterator pos2=pos->second.begin(); pos2!=pos->second.end();++pos2)
2009 b += (*pos2)->GetBiso();
2010 for(
unsigned int i=0;i<6;i++) bij(i) += (*pos2)->GetBij(i);
2012 b /= pos->second.size() + 1;
2013 bij /= pos->second.size() + 1;
2014 pos->first->SetBiso(b);
2015 for(
unsigned int i=0;i<6;i++)
if(abs(bij(i)) > 1e-6) pos->first->SetBij(i,bij(i));
2019 for(std::map<
ScatteringPower*,std::set<ScatteringPower*> >::iterator pos=vequivpow.begin();pos!=vequivpow.end();++pos)
2021 const unsigned int nb = pos->second.size();
2022 if(oneScatteringPowerPerElement) pos->first->SetName(pos->first->GetSymbol());
2024 (*fpObjCrystInformUser)((boost::format(
"Merging ScatteringPower: %s[%s] (%d identical scattering powers)") % pos->first->GetName().c_str() % pos->first->GetSymbol().c_str() % pos->second.size()).str());
2025 for(std::set<ScatteringPower*>::const_iterator pos2=pos->second.begin(); pos2!=pos->second.end();++pos2)
2035 VFN_DEBUG_MESSAGE(
"Crystal:MergeEqualScatteringPowers() Atom "<<pat->
GetName()<<
": "<<pat->
GetScatteringPower().
GetName()<<
"->"<<pos->first->GetName(), 10)
2042 for(std::vector<MolAtom*>::iterator pat=pmol->GetAtomList().begin();pat!=pmol->GetAtomList().end();++pat)
2044 if(&((*pat)->GetScatteringPower()) == (*pos2))
2045 (*pat)->SetScatteringPower(*(pos->first));
2051 cout<<__FILE__<<
":"<<__LINE__<<
":Crystal::MergeEqualScatteringPowers(): unidentified scatterer, cannot merge scattering power..."
2052 <<(*pos2)->
GetName()<<
"["<<(*pos2)->GetClassName()<<
"]"<<endl;
2058 for(std::set<ScatteringPower*>::iterator pos=vremovedpow.begin();pos!=vremovedpow.end();++pos)
2061 const unsigned int nb=(*pos)->GetClientRegistry().GetNb();
2064 VFN_DEBUG_MESSAGE(
"Crystal::MergeEqualScatteringPowers(): "<<nb<<
" clients remaining for scattering power: "<<(*pos)->GetName()<<
"["<<(*pos)->GetClassName()<<
"]", 5)
2065 for(
unsigned int i=0; i<nb;i++)
2067 VFN_DEBUG_MESSAGE(
" "<<&((*pos)->GetClientRegistry().GetObj(i))<<
":"<<(*pos)->GetClientRegistry().GetObj(i).GetName()<<
"["<<(*pos)->GetClientRegistry().GetObj(i).GetClassName()<<
"]", 5)
2074 VFN_DEBUG_EXIT(
"Crystal::MergeEqualScatteringPowers()", 10)
2079 VFN_DEBUG_ENTRY(
"Crystal::InitOptions",10)
2080 static string UseDynPopCorrname;
2081 static string UseDynPopCorrchoices[2];
2083 static string DisplayEnantiomername;
2084 static string DisplayEnantiomerchoices[2];
2086 static bool needInitNames=
true;
2087 if(
true==needInitNames)
2089 UseDynPopCorrname=
"Use Dynamical Occupancy Correction";
2090 UseDynPopCorrchoices[0]=
"No";
2091 UseDynPopCorrchoices[1]=
"Yes";
2093 DisplayEnantiomername=
"Display Enantiomer";
2094 DisplayEnantiomerchoices[0]=
"No";
2095 DisplayEnantiomerchoices[1]=
"Yes";
2097 needInitNames=
false;
2099 VFN_DEBUG_MESSAGE(
"Crystal::Init(a,b,c,alpha,beta,gamma,Sg,name):Init options",5)
2107 VFN_DEBUG_EXIT(
"Crystal::InitOptions",10)
2110 Crystal::Neighbour::Neighbour(
const unsigned long neighbourIndex,
const int sym,
2112 mNeighbourIndex(neighbourIndex),mNeighbourSymmetryIndex(sym),mDist2(dist2)
2115 Crystal::DistTableInternalPosition::DistTableInternalPosition(
const long atomIndex,
const int sym,
2116 const REAL x,
const REAL y,
const REAL z):
2117 mAtomIndex(atomIndex),mSymmetryIndex(sym),mX(x),mY(y),mZ(z)
2120 void Crystal::InitializeInterMolDistList()
const
2124 GetNamedScatteringComponentList();
2126 for(
long i=0;i<mInterMolDistList.size();i++) {
2127 mInterMolDistList[i].mAt1Indexes.clear();
2128 for(
int j=0;j<mInterMolDistList[i].mAt1.size();j++) {
2129 p = FindScatterersInComponentList(mInterMolDistList[i].mAt1[j]);
2130 mInterMolDistList[i].mAt1Indexes.insert(mInterMolDistList[i].mAt1Indexes.end(), p.begin(), p.end());
2132 mInterMolDistList[i].mAt2Indexes.clear();
2133 for(
int j=0;j<mInterMolDistList[i].mAt2.size();j++) {
2134 p = FindScatterersInComponentList(mInterMolDistList[i].mAt2[j]);
2135 mInterMolDistList[i].mAt2Indexes.insert(mInterMolDistList[i].mAt2Indexes.end(), p.begin(), p.end());
2138 mInterMolDistListNeedsInit =
false;
2140 const vector<Crystal::NamedScatteringComponent>& Crystal::GetNamedScatteringComponentList()
const
2153 for(
int j=0;j<list.GetNbComponent();j++) {
2155 mNamedScattCompList[counts].mDynPopCorr = list(j).mDynPopCorr;
2156 mNamedScattCompList[counts].mOccupancy = list(j).mOccupancy;
2157 mNamedScattCompList[counts].mpScattPow = list(j).mpScattPow;
2158 mNamedScattCompList[counts].mX = list(j).mX;
2159 mNamedScattCompList[counts].mY = list(j).mY;
2160 mNamedScattCompList[counts].mZ = list(j).mZ;
2168 return mNamedScattCompList;
2170 void Crystal::printInterMolDistList()
const
2172 cout<<
"Printing mInterMolDistList:"<<endl;
2173 cout<<
"size: "<<mInterMolDistList.size()<<endl;
2174 for(
int i=0;i<mInterMolDistList.size();i++) {
2175 cout<<
"["<<i<<
"]:"<<endl;
2177 for(
int j=0;j<mInterMolDistList[i].mAt1.size();j++) {
2178 cout<<mInterMolDistList[i].mAt1[j]<<
" ";
2182 cout<<
"mAt1Indexes: ";
2183 for(
int j=0;j<mInterMolDistList[i].mAt1Indexes.size();j++) {
2184 cout<<mInterMolDistList[i].mAt1Indexes[j]<<
" ";
2188 cout<<
"vUniqueIndexAt1: ";
2189 for(
int j=0;j<mInterMolDistList[i].vUniqueIndexAt1.size();j++) {
2190 cout<<mInterMolDistList[i].vUniqueIndexAt1[j].mAtomIndex<<
" ";
2195 for(
int j=0;j<mInterMolDistList[i].mAt2.size();j++) {
2196 cout<<mInterMolDistList[i].mAt2[j]<<
" ";
2200 cout<<
"mAt2Indexes: ";
2201 for(
int j=0;j<mInterMolDistList[i].mAt2Indexes.size();j++) {
2202 cout<<mInterMolDistList[i].mAt2Indexes[j]<<
" ";
2207 for(
int j=0;j<mInterMolDistList[i].vPosAt2.size();j++) {
2208 cout<<mInterMolDistList[i].vPosAt2[j].mAtomIndex<<
" ";
2213 for(
int j=0;j<mInterMolDistList[i].mNbh.size();j++) {
2214 cout<<
"["<<j<<
"]: mIndex: "<<mInterMolDistList[i].mNbh[j].mIndex<<endl;
2215 for(
int k=0;k<mInterMolDistList[i].mNbh[j].mvNeighbour.size();k++) {
2216 cout<<
" mDist2: "<<mInterMolDistList[i].mNbh[j].mvNeighbour[k].mDist2<<endl;
2217 cout<<
" mNeighbourIndex: "<<mInterMolDistList[i].mNbh[j].mvNeighbour[k].mNeighbourIndex<<endl;
2218 cout<<
" mNeighbourSymmetryIndex: "<<mInterMolDistList[i].mNbh[j].mvNeighbour[k].mNeighbourSymmetryIndex<<endl;
2226 void Crystal::CalcDistTableForInterMolDistCost()
const
2228 if(mInterMolDistList.size()==0)
return;
2234 if(mDistTableForInterMolMaxDistance<1.1) {
2236 mDistTableForInterMolMaxDistance = 1.0;
2237 for(
int i=0;i<mInterMolDistList.size();i++) {
2238 if(mInterMolDistList[i].mDist2>0) {
2239 float d = sqrt(mInterMolDistList[i].mDist2);
2240 if(d>mDistTableForInterMolMaxDistance) {
2241 mDistTableForInterMolMaxDistance = d;
2245 mDistTableForInterMolMaxDistance*=mDistMaxMultiplier;
2259 const REAL halfasuxrange=(asux1-asux0)*0.5+1e-5;
2260 const REAL halfasuyrange=(asuy1-asuy0)*0.5+1e-5;
2261 const REAL halfasuzrange=(asuz1-asuz0)*0.5+1e-5;
2263 const REAL asuxc=0.5*(asux0+asux1);
2264 const REAL asuyc=0.5*(asuy0+asuy1);
2265 const REAL asuzc=0.5*(asuz0+asuz1);
2267 const REAL maxdx=halfasuxrange+mDistTableForInterMolMaxDistance/
GetLatticePar(0);
2268 const REAL maxdy=halfasuyrange+mDistTableForInterMolMaxDistance/
GetLatticePar(1);
2269 const REAL maxdz=halfasuzrange+mDistTableForInterMolMaxDistance/
GetLatticePar(2);
2271 const REAL asymUnitMargin2 = mDistTableForInterMolMaxDistance*mDistTableForInterMolMaxDistance;
2275 bool loopOnLattice=
true;
2276 if( ((this->
GetLatticePar(0)*.5)>mDistTableForInterMolMaxDistance)
2277 &&((this->
GetLatticePar(1)*.5)>mDistTableForInterMolMaxDistance)
2278 &&((this->
GetLatticePar(2)*.5)>mDistTableForInterMolMaxDistance)) loopOnLattice=
false;
2280 CrystMatrix_REAL symmetricsCoords;
2284 if(mInterMolDistListNeedsInit) {
2286 InitializeInterMolDistList();
2289 GetNamedScatteringComponentList();
2293 for(
long i=0;i<mInterMolDistList.size();i++) {
2294 mInterMolDistList[i].vUniqueIndexAt1.clear();
2297 for(
int k=0;k<mInterMolDistList[i].mAt1Indexes.size();k++) {
2300 mNamedScattCompList[mInterMolDistList[i].mAt1Indexes[k]].mY,
2301 mNamedScattCompList[mInterMolDistList[i].mAt1Indexes[k]].mZ,
2304 bool hasUnique=
false;
2305 for(
int j=0;j<nbSymmetrics;j++)
2308 REAL x=fmod(symmetricsCoords(j,0)-asuxc,(REAL)1.0);
if(x<-.5)x+=1;
else if(x>.5)x-=1;
2309 REAL y=fmod(symmetricsCoords(j,1)-asuyc,(REAL)1.0);
if(y<-.5)y+=1;
else if(y>.5)y-=1;
2310 REAL z=fmod(symmetricsCoords(j,2)-asuzc,(REAL)1.0);
if(z<-.5)z+=1;
else if(z>.5)z-=1;
2313 if( (abs(x)<maxdx) && (abs(y)<maxdy) && (abs(z)<maxdz) ) {
2316 if( (abs(x)<halfasuxrange) && (abs(y)<halfasuyrange) && (abs(z)<halfasuzrange) )
2319 mInterMolDistList[i].vUniqueIndexAt1.push_back(DistTableInternalPosition(mInterMolDistList[i].mAt1Indexes[k], j, x+asuxc, y+asuyc, z+asuzc));
2326 throw ObjCrystException(
"One atom did not have any symmetric in the ASU !");
2329 mInterMolDistList[i].vPosAt2.clear();
2332 for(
int k=0;k<mInterMolDistList[i].mAt2Indexes.size();k++) {
2335 mNamedScattCompList[mInterMolDistList[i].mAt2Indexes[k]].mY,
2336 mNamedScattCompList[mInterMolDistList[i].mAt2Indexes[k]].mZ,
2338 for(
int j=0;j<nbSymmetrics;j++)
2341 REAL x=fmod(symmetricsCoords(j,0)-asuxc,(REAL)1.0);
if(x<-.5)x+=1;
else if(x>.5)x-=1;
2342 REAL y=fmod(symmetricsCoords(j,1)-asuyc,(REAL)1.0);
if(y<-.5)y+=1;
else if(y>.5)y-=1;
2343 REAL z=fmod(symmetricsCoords(j,2)-asuzc,(REAL)1.0);
if(z<-.5)z+=1;
else if(z>.5)z-=1;
2346 if( (abs(x)<maxdx) && (abs(y)<maxdy) && (abs(z)<maxdz) ) {
2347 mInterMolDistList[i].vPosAt2.push_back(DistTableInternalPosition(mInterMolDistList[i].mAt2Indexes[k], j, x+asuxc, y+asuyc, z+asuzc));
2354 const CrystMatrix_REAL* pOrthMatrix=&(this->
GetOrthMatrix());
2356 const REAL m00=(*pOrthMatrix)(0,0);
2357 const REAL m01=(*pOrthMatrix)(0,1);
2358 const REAL m02=(*pOrthMatrix)(0,2);
2359 const REAL m11=(*pOrthMatrix)(1,1);
2360 const REAL m12=(*pOrthMatrix)(1,2);
2361 const REAL m22=(*pOrthMatrix)(2,2);
2364 for(
long i=0;i<mInterMolDistList.size();i++)
2366 mInterMolDistList[i].mNbh.clear();
2368 for(
long q=0;q<mInterMolDistList[i].vUniqueIndexAt1.size();q++) {
2370 nbh.mIndex = mInterMolDistList[i].vUniqueIndexAt1[q].mAtomIndex;
2371 nbh.mUniquePosSymmetryIndex = mInterMolDistList[i].vUniqueIndexAt1[q].mSymmetryIndex;
2373 mInterMolDistList[i].mNbh.push_back(nbh);
2376 vector<Crystal::Neighbour> *
const vnb=&(mInterMolDistList[i].mNbh[mInterMolDistList[i].mNbh.size()-1].mvNeighbour);
2377 const REAL x0i=mInterMolDistList[i].vUniqueIndexAt1[q].mX;
2378 const REAL y0i=mInterMolDistList[i].vUniqueIndexAt1[q].mY;
2379 const REAL z0i=mInterMolDistList[i].vUniqueIndexAt1[q].mZ;
2380 for(
unsigned long j=0;j<mInterMolDistList[i].vPosAt2.size();j++)
2384 REAL x=fmod(mInterMolDistList[i].vPosAt2[j].mX - x0i,(REAL)1.0);
if(x<-.5)x+=1;
if(x>.5)x-=1;
2385 REAL y=fmod(mInterMolDistList[i].vPosAt2[j].mY - y0i,(REAL)1.0);
if(y<-.5)y+=1;
if(y>.5)y-=1;
2386 REAL z=fmod(mInterMolDistList[i].vPosAt2[j].mZ - z0i,(REAL)1.0);
if(z<-.5)z+=1;
if(z>.5)z-=1;
2388 const REAL x0=m00 * x + m01 * y + m02 * z;
2389 const REAL y0= m11 * y + m12 * z;
2390 const REAL z0= m22 * z;
2394 for(
int sz=-1;sz<=1;sz+=2)
2396 for(
int nz=(sz+1)/2;;++nz)
2398 const REAL z=z0+sz*nz*m22;
2399 if(abs(z)>mDistTableForInterMolMaxDistance)
break;
2400 for(
int sy=-1;sy<=1;sy+=2)
2402 for(
int ny=(sy+1)/2;;++ny)
2404 const REAL y=y0 + sy*ny*m11 + sz*nz*m12;
2405 if(abs(y)>mDistTableForInterMolMaxDistance)
break;
2406 for(
int sx=-1;sx<=1;sx+=2)
2408 for(
int nx=(sx+1)/2;;++nx)
2411 const REAL x=x0 + sx*nx*m00 + sy*ny*m01 + sz*nz*m02;
2412 if(abs(x)>mDistTableForInterMolMaxDistance)
break;
2413 const REAL d2=x*x+y*y+z*z;
2414 if(d2<0.001)
continue;
2415 if(d2<=asymUnitMargin2)
2417 Neighbour neigh(mInterMolDistList[i].vPosAt2[j].mAtomIndex,mInterMolDistList[i].vPosAt2[j].mSymmetryIndex,d2);
2418 vnb->push_back(neigh);
2422 <<vPos[j].mSymmetryIndex<<
":"
2429 <<
"("<<sx*nx<<
","<<sy*ny<<
","<<sz*nz<<
")"<<endl;
2441 const REAL d2=x0*x0+y0*y0+z0*z0;
2442 if(d2<=asymUnitMargin2)
2444 Neighbour neigh(mInterMolDistList[i].vPosAt2[j].mAtomIndex,mInterMolDistList[i].vPosAt2[j].mSymmetryIndex,d2);
2445 vnb->push_back(neigh);
2449 <<vPos[j].mSymmetryIndex<<
":"
2452 <<vPos[j].mZ<<
" vector="
2453 <<x0<<
","<<y0<<
","<<z0<<
":"<<sqrt(d2)<<
","<<asymUnitMargin2<<endl;
2480 mvDistTableSq.resize(nbComponent);
2482 std::vector<NeighbourHood>::iterator pos;
2483 for(pos=mvDistTableSq.begin();pos<mvDistTableSq.end();pos++)
2484 pos->mvNeighbour.clear();
2486 VFN_DEBUG_MESSAGE(
"Crystal::CalcDistTable():1",3)
2497 const REAL halfasuxrange=(asux1-asux0)*0.5+1e-5;
2498 const REAL halfasuyrange=(asuy1-asuy0)*0.5+1e-5;
2499 const REAL halfasuzrange=(asuz1-asuz0)*0.5+1e-5;
2501 const REAL asuxc=0.5*(asux0+asux1);
2502 const REAL asuyc=0.5*(asuy0+asuy1);
2503 const REAL asuzc=0.5*(asuz0+asuz1);
2510 std::vector<DistTableInternalPosition> vPos;
2512 std::vector<unsigned long> vUniqueIndex(nbComponent);
2518 VFN_DEBUG_MESSAGE(
"Crystal::CalcDistTable(fast):2",3)
2519 TAU_PROFILE(
"Crystal::CalcDistTable(fast=true)",
"Matrix (string&)",TAU_DEFAULT);
2520 TAU_PROFILE_TIMER(timer1,
"DiffractionData::CalcDistTable1",
"", TAU_FIELD);
2521 TAU_PROFILE_TIMER(timer2,
"DiffractionData::CalcDistTable2",
"", TAU_FIELD);
2523 TAU_PROFILE_START(timer1);
2526 bool loopOnLattice=
true;
2529 &&((this->
GetLatticePar(2)*.5)>mDistTableMaxDistance)) loopOnLattice=
false;
2531 CrystMatrix_REAL symmetricsCoords;
2536 for(
long i=0;i<nbComponent;i++)
2538 VFN_DEBUG_MESSAGE(
"Crystal::CalcDistTable(fast):3:component "<<i,0)
2544 mvDistTableSq[i].mIndex=i;
2545 bool hasUnique=
false;
2546 for(
int j=0;j<nbSymmetrics;j++)
2549 REAL x=fmod(symmetricsCoords(j,0)-asuxc,(REAL)1.0);
if(x<-.5)x+=1;
else if(x>.5)x-=1;
2550 REAL y=fmod(symmetricsCoords(j,1)-asuyc,(REAL)1.0);
if(y<-.5)y+=1;
else if(y>.5)y-=1;
2551 REAL z=fmod(symmetricsCoords(j,2)-asuzc,(REAL)1.0);
if(z<-.5)z+=1;
else if(z>.5)z-=1;
2554 if( (abs(x)<maxdx) && (abs(y)<maxdy) && (abs(z)<maxdz) )
2558 if( (abs(x)<halfasuxrange) && (abs(y)<halfasuyrange) && (abs(z)<halfasuzrange) )
2561 vUniqueIndex[i]=vPos.size()-1;
2562 mvDistTableSq[i].mUniquePosSymmetryIndex=j;
2570 TAU_PROFILE_STOP(timer1);
2571 TAU_PROFILE_START(timer2);
2575 const CrystMatrix_REAL* pOrthMatrix=&(this->
GetOrthMatrix());
2577 const REAL m00=(*pOrthMatrix)(0,0);
2578 const REAL m01=(*pOrthMatrix)(0,1);
2579 const REAL m02=(*pOrthMatrix)(0,2);
2580 const REAL m11=(*pOrthMatrix)(1,1);
2581 const REAL m12=(*pOrthMatrix)(1,2);
2582 const REAL m22=(*pOrthMatrix)(2,2);
2584 for(
long i=0;i<nbComponent;i++)
2586 VFN_DEBUG_MESSAGE(
"Crystal::CalcDistTable(fast):4:component "<<i,0)
2588 if(!this->
IsBeingRefined()) cout<<endl<<
"Unique pos:"<<vUniqueIndex[i]<<
":"
2589 <<vPos[vUniqueIndex[i]].mAtomIndex<<
":"
2590 <<
mScattCompList(vPos[vUniqueIndex[i]].mAtomIndex).mpScattPow->GetName()<<
":"
2591 <<vPos[vUniqueIndex[i]].mSymmetryIndex<<
":"
2594 <<
FormatFloat(vPos[vUniqueIndex[i]].mZ,8,5)<<endl;
2596 std::vector<Crystal::Neighbour> *
const vnb=&(mvDistTableSq[i].mvNeighbour);
2597 const REAL x0i=vPos[vUniqueIndex[i] ].mX;
2598 const REAL y0i=vPos[vUniqueIndex[i] ].mY;
2599 const REAL z0i=vPos[vUniqueIndex[i] ].mZ;
2600 for(
unsigned long j=0;j<vPos.size();j++)
2602 if((vUniqueIndex[i]==j) && (!loopOnLattice))
continue;
2604 REAL x=fmod(vPos[j].mX - x0i,(REAL)1.0);
if(x<-.5)x+=1;
if(x>.5)x-=1;
2605 REAL y=fmod(vPos[j].mY - y0i,(REAL)1.0);
if(y<-.5)y+=1;
if(y>.5)y-=1;
2606 REAL z=fmod(vPos[j].mZ - z0i,(REAL)1.0);
if(z<-.5)z+=1;
if(z>.5)z-=1;
2608 const REAL x0=m00 * x + m01 * y + m02 * z;
2609 const REAL y0= m11 * y + m12 * z;
2610 const REAL z0= m22 * z;
2614 for(
int sz=-1;sz<=1;sz+=2)
2616 for(
int nz=(sz+1)/2;;++nz)
2618 const REAL z=z0+sz*nz*m22;
2620 for(
int sy=-1;sy<=1;sy+=2)
2622 for(
int ny=(sy+1)/2;;++ny)
2624 const REAL y=y0 + sy*ny*m11 + sz*nz*m12;
2626 for(
int sx=-1;sx<=1;sx+=2)
2628 for(
int nx=(sx+1)/2;;++nx)
2630 if((vUniqueIndex[i]==j) && (nx==0) && (ny==0) && (nz==0))
continue;
2631 const REAL x=x0 + sx*nx*m00 + sy*ny*m01 + sz*nz*m02;
2633 const REAL d2=x*x+y*y+z*z;
2634 if(d2<=asymUnitMargin2)
2636 Neighbour neigh(vPos[j].mAtomIndex,vPos[j].mSymmetryIndex,d2);
2637 vnb->push_back(neigh);
2641 <<vPos[j].mSymmetryIndex<<
":"
2648 <<
"("<<sx*nx<<
","<<sy*ny<<
","<<sz*nz<<
")"<<endl;
2660 const REAL d2=x0*x0+y0*y0+z0*z0;
2661 if(d2<=asymUnitMargin2)
2663 Neighbour neigh(vPos[j].mAtomIndex,vPos[j].mSymmetryIndex,d2);
2664 vnb->push_back(neigh);
2668 <<vPos[j].mSymmetryIndex<<
":"
2671 <<vPos[j].mZ<<
" vector="
2672 <<x0<<
","<<y0<<
","<<z0<<
":"<<sqrt(d2)<<
","<<asymUnitMargin2<<endl;
2679 TAU_PROFILE_STOP(timer2);
2682 VFN_DEBUG_EXIT(
"Crystal::CalcDistTable()",4)
2686 mDeleteSubObjInDestructor=b;
2689 #ifdef __WX__CRYST__
2692 VFN_DEBUG_ENTRY(
"Crystal::WXCreate(wxWindow*)",6)
2694 mpWXCrystObj=new
WXCrystal(parent,this);
2695 VFN_DEBUG_EXIT("
Crystal::WXCreate(wxWindow*)",6)
2696 return mpWXCrystObj;
The namespace which includes all objects (crystallographic and algorithmic) in ObjCryst++.
REAL GetBondLength(const MolAtom &at1, const MolAtom &at2)
Get The Bond Length between two atoms.
REAL GetBondAngle(const MolAtom &at1, const MolAtom &at2, const MolAtom &at3)
Get The Bond Angle of 3 atoms.
ObjRegistry< Crystal > gCrystalRegistry("List of all Crystals")
Global registry for all Crystal objects.
ObjRegistry< RefinableObj > gTopRefinableObjRegistry("Global Top RefinableObj registry")
This is a special registry for 'top' object for an optimization.
The basic atom scatterer, in a crystal.
void SetScatteringPower(const ScatteringPower &pow)
Change the ScatteringPower for this atom.
const ScatteringPower & GetScatteringPower() const
Get the ScatteringPowerAtom corresponding to this atom.
Crystal class: Unit cell, spacegroup, scatterers.
void ResetDynPopCorr() const
Reset Dynamical Population Correction factors (ie set it to 1)
RefinableObjClock mMasterClockScatteringPower
master clock recording every change in Scattering Powers
virtual void CIFOutput(ostream &os, double mindist=0.5) const
output Crystal structure as a cif file
~Crystal()
Crystal destructor.
virtual void XMLOutput(ostream &os, int indent=0) const
Output to stream in well-formed XML.
REAL GetBondValenceCost() const
Get the Bond-Valence cost function, which compares the expected valence to the one computed from Bond...
ostream & POVRayDescription(ostream &os, const CrystalPOVRayOptions &options) const
XMLOutput POV-Ray Description for this Crystal.
RefinableObjClock mClockDynPopCorr
CrystMatrix_REAL GetMinDistanceTable(const REAL minDistance=0.1) const
Minimum interatomic distance between all scattering components (atoms) in the crystal.
ScatteringComponentList mScattCompList
The list of all scattering components in the crystal.
RefinableObjClock mBondValenceParClock
Last Time Bond Valence parameters were changed.
REAL mBondValenceCostScale
Bond Valence cost scale factor.
RefinableObjClock mBondValenceCalcClock
Last time Bond Valences were calculated.
void CalcDistTable(const bool fast) const
Compute the distance Table (mDistTable) for all scattering components.
ScatteringPower & GetScatteringPower(const string &name)
Find a ScatteringPower from its name. Names must be unique in a given Crystal.
void PrintMinDistanceTable(const REAL minDistance=0.1, ostream &os=cout) const
Print the minimum distance table between all scattering centers (atoms) in the crystal.
std::map< long, REAL > mvBondValenceCalc
List of calculated bond valences, as a map, the key being the index of the atom in Crystal::mScattCom...
Crystal()
Default Constructor.
ObjRegistry< Scatterer > & GetScattererRegistry()
Get the registry of scatterers.
void SetUseDynPopCorr(const int use)
Set the use of dynamical population correction (Crystal::mUseDynPopCorr).
RefinableObjClock mBumpMergeCostClock
Last Time Anti-bump parameters were changed.
virtual const ScatteringComponentList & GetScatteringComponentList() const
Get the list of all scattering components.
virtual void GlobalOptRandomMove(const REAL mutationAmplitude, const RefParType *type=gpRefParTypeObjCryst)
Make a random move of the current configuration.
void ConnectAtoms(const REAL min_relat_dist=0.4, const REAL max_relat_dist=1.3, const bool warnuser_fail=false)
Convert as much as possible the crystal's atoms to molecule(s).
void InitOptions()
Init options.
RefinableObjClock mDistTableForInterMolDistClock
The time when the distance table was last calculated.
int GetUseDynPopCorr() const
Get dynamical population correction setting.
void AddScatteringPower(ScatteringPower *scattPow)
Add a ScatteringPower for this Crystal.
int FindScatterer(const string &scattName) const
Find a scatterer (its index # in mpScatterrer[]) with a given name.
const RefinableObjClock & GetClockScattererList() const
When was the list of scatterers last changed ?
RefinableObjClock mClockScattererList
Last time the list of Scatterers was changed.
ObjRegistry< ScatteringPower > mScatteringPowerRegistry
The registry of ScatteringPower for this Crystal.
map< pair< const ScatteringPower *, const ScatteringPower * >, REAL > mvBondValenceRo
Map of Bond Valence "Ro" parameters for each couple of ScatteringPower.
void CalcBondValenceSum() const
Calculate all Bond Valences.
virtual void BeginOptimization(const bool allowApproximations=false, const bool enableRestraints=false)
This should be called by any optimization class at the begining of an optimization.
RefinableObjClock mClockNeighborTable
void MergeEqualScatteringPowers(const bool oneScatteringPowerPerElement)
Merge all equal scattering powers.
REAL GetWeight() const
Weight for the crystal formula, in atomic units (g/mol).
REAL mDistTableMaxDistance
The distance up to which the distance table & neighbours needs to be calculated.
REAL GetDynPopCorr(const Scatterer *pscatt, unsigned int component) const
Access the Dynamical Occupancy Correction for a given component (atom) in a given Scatterer.
ObjRegistry< Scatterer > mScattererRegistry
The registry of scatterers for this UnitCell.
VBumpMergePar mvBumpMergePar
Anti-bump parameters map.
ObjRegistry< ScatteringPower > & GetScatteringPowerRegistry()
Get the registry of ScatteringPower included in this Crystal.
const RefinableObjClock & GetClockScattCompList() const
Get the list of all scattering components.
REAL GetBumpMergeCost() const
Get the Anti-bumping/pro-Merging cost function.
RefinableObjClock mBumpMergeParClock
Last Time Anti-bump parameters were changed.
RefObjOpt mUseDynPopCorr
Use Dynamical population correction (ScatteringComponent::mDynPopCorr) during Structure factor calcul...
RefObjOpt mDisplayEnantiomer
Display the enantiomeric (mirror along x) structure in 3D? This can be helpful for non-centrosymmetri...
virtual const string & GetClassName() const
Name for this class ("RefinableObj", "Crystal",...).
Scatterer & GetScatt(const string &scattName)
Provides an access to the scatterers.
void RemoveScatteringPower(ScatteringPower *scattPow, const bool del=true)
Remove a ScatteringPower for this Crystal.
void RemoveBumpMergeDistance(const ScatteringPower &scatt1, const ScatteringPower &scatt2)
Remove an Anti-bumping distance between two scattering types.
void RemoveScatterer(Scatterer *scatt, const bool del=true)
Remove a Scatterer. This also deletes the scatterer unless del=false.
RefinableObjClock mClockScattCompList
std::string GetFormula() const
Formula with atoms in alphabetic order.
virtual void XMLInput(istream &is, const XMLCrystTag &tag)
Input the crystal structure from a stream.
long GetNbScatterer() const
Number of scatterers in the crystal.
void AddScatterer(Scatterer *scatt)
Add a scatterer to the crystal.
REAL mBumpMergeCost
Current bump-merge cost.
RefinableObjClock mDistTableClock
The time when the distance table was last calculated.
void SetBumpMergeDistance(const ScatteringPower &scatt1, const ScatteringPower &scatt2, const REAL dist=1.5)
Set the Anti-bumping distance between two scattering types.
virtual REAL GetLogLikelihood() const
Get -log(likelihood) of the current configuration for the object.
RefinableObjClock mLatticeClock
Clock for lattice paramaters.
void CalcDynPopCorr(const REAL overlapDist=1., const REAL mergeDist=.0) const
Compute the 'Dynamical population correction for all atoms. Atoms which are considered "equivalent" (...
RefinableObjClock mBondValenceCostClock
Last time the Bond Valence cost was calculated.
void SetDeleteSubObjInDestructor(const bool b)
Set whether to delete the Scatterers and ScatteringPowers in the destructor.
REAL mBumpMergeScale
Bump-merge scale factor.
virtual void GetGeneGroup(const RefinableObj &obj, CrystVector_uint &groupIndex, unsigned int &firstGroup) const
Get the gene group assigned to each parameter.
void Init(const REAL a, const REAL b, const REAL c, const REAL alpha, const REAL beta, const REAL gamma, const string &SpaceGroupId, const string &name)
Init all Crystal parameters.
std::map< pair< const ScatteringPower *, const ScatteringPower * >, Crystal::BumpMergePar > VBumpMergePar
Anti-bump parameters.
REAL mBondValenceCost
Current Bond Valence cost.
const RefinableObjClock & GetMasterClockScatteringPower() const
Get the clock which reports all changes in ScatteringPowers.
Storage for anti-bump/merge parameters.
Exception class for ObjCryst++ library.
Class to store POV-Ray output options.
MolAtom : atom inside a Molecule.
Bond between two atoms, also a restraint on the associated bond length.
Molecule : class for complex scatterer descriptions using cartesian coordinates with bond length/angl...
void AddBondAngle(MolAtom &atom1, MolAtom &atom2, MolAtom &atom3, const REAL angle, const REAL sigma, const REAL delta, const bool updateDisplay=true)
Add a bond angle restraint.
void BuildConnectivityTable() const
Build the Connectivity table.
vector< MolBondAngle * >::const_iterator FindBondAngle(const MolAtom &at1, const MolAtom &at0, const MolAtom &at2) const
Searches whether a bond between three atoms already exists, searching for either (at1,...
vector< MolAtom * >::iterator RemoveAtom(MolAtom &, const bool del=true)
Remove an atom.
vector< MolBond * >::const_iterator FindBond(const MolAtom &, const MolAtom &) const
Searches whether a bond between two atoms already exists.
void AddAtom(const REAL x, const REAL y, const REAL z, const ScatteringPower *pPow, const string &name, const bool updateDisplay=true)
Add an atom.
virtual int GetNbComponent() const
Number of components in the scatterer (eg number of point scatterers)
std::string GetFormula() const
Formula with atoms in alphabetic order.
vector< MolBond * >::iterator RemoveBond(const MolBond &, const bool del=true)
Remove a bond.
void AddBond(MolAtom &atom1, MolAtom &atom2, const REAL length, const REAL sigma, const REAL delta, const REAL bondOrder=1., const bool updateDisplay=true)
Add a bond.
const map< MolAtom *, set< MolAtom * > > & GetConnectivityTable()
Get the connectivity table.
Generic type of scatterer: can be an atom, or a more complex assembly of atoms.
virtual const string & GetClassName() const
Name for this class ("RefinableObj", "Crystal",...).
virtual int GetNbComponent() const =0
Number of components in the scatterer (eg number of point scatterers)
virtual string GetComponentName(const int i) const =0
Name for the i-th component of this scatterer.
virtual void SetZ(const REAL z)
Z coordinate (fractionnal) of the scatterer (for complex scatterers, this corresponds to the position...
virtual void SetY(const REAL y)
Y coordinate (fractionnal) of the scatterer (for complex scatterers, this corresponds to the position...
virtual ostream & POVRayDescription(ostream &os, const CrystalPOVRayOptions &options) const =0
REAL GetX() const
X coordinate (fractionnal) of the scatterer (for complex scatterers, this corresponds to the position...
REAL GetZ() const
Z coordinate (fractionnal) of the scatterer (for complex scatterers, this corresponds to the position...
virtual const ScatteringComponentList & GetScatteringComponentList() const =0
Get the list of all scattering components for this scatterer.
void SetCrystal(Crystal &)
Set the crystal in which is included this Scatterer.
REAL GetY() const
Y coordinate (fractionnal) of the scatterer (for complex scatterers, this corresponds to the position...
virtual void SetX(const REAL x)
X coordinate (fractionnal) of the scatterer (for complex scatterers, this corresponds to the position...
Abstract Base Class to describe the scattering power of any Scatterer component in a crystal.
virtual const string & GetClassName() const
Name for this class ("RefinableObj", "Crystal",...).
const RefinableObjClock & GetMaximumLikelihoodParClock() const
Get the clock value for the last change on the maximum likelihood parameters (positionnal error,...
virtual const string & GetSymbol() const
Symbol for this Scattering power (the atom name for atoms)
The Scattering Power for an Atom.
virtual const string & GetSymbol() const
Returns the symbol ('Ta', 'O2-',...) of the atom.
REAL GetCovalentRadius() const
Covalent Radius for this atom, in Angstroems (from cctbx)
REAL GetAtomicWeight() const
Atomic weight (g/mol) for this atom.
unsigned int GetMaxCovBonds() const
Maximum number of covalent bonds (from openbabel element.txt)
int GetAtomicNumber() const
Atomic number for this atom.
A scattering position in a crystal, associated with the corresponding occupancy and a pointer to the ...
const ScatteringPower * mpScattPow
The ScatteringPower associated with this position.
REAL mDynPopCorr
Dynamical Population Correction.
list of scattering positions in a crystal, associated with the corresponding occupancy and a pointer ...
void Reset()
Reset the list.
long GetNbComponent() const
Number of components.
void Print() const
Print the list of Scattering components. For debugging.
char GetExtension() const
Extension to space group symbol ('1','2':origin choice ; 'R','H'=rhomboedral/hexagonal)
int GetNbSymmetrics(const bool noCenter=false, const bool noTransl=false) const
Return the number of equivalent positions in the spacegroup, ie the multilicity of the general positi...
CrystMatrix_REAL GetAllSymmetrics(const REAL x, const REAL y, const REAL z, const bool noCenter=false, const bool noTransl=false, const bool noIdentical=false) const
Get all equivalent positions of a (xyz) position.
const AsymmetricUnit & GetAsymUnit() const
Get the AsymmetricUnit for this spacegroup.
const cctbx::sgtbx::space_group & GetCCTbxSpg() const
Get the underlying cctbx Spacegroup object.
CrystVector_REAL GetLatticePar() const
Lattice parameters (a,b,c,alpha,beta,gamma) as a 6-element vector in Angstroems and radians.
const RefinableObjClock & GetClockMetricMatrix() const
last time the metric matrices were changed
REAL GetVolume() const
Volume of Unit Cell (in Angstroems)
virtual void Init(const REAL a, const REAL b, const REAL c, const REAL alpha, const REAL beta, const REAL gamma, const string &SpaceGroupId, const string &name)
Init all UnitCell parameters.
void OrthonormalToFractionalCoords(REAL &x, REAL &y, REAL &z) const
Get fractional cartesian coordinates for a set of (x,y,z) orthonormal coordinates.
const SpaceGroup & GetSpaceGroup() const
Access to the SpaceGroup object.
const CrystMatrix_REAL & GetOrthMatrix() const
Get the orthogonalization matrix (UnitCell::mOrthMatrix)for the UnitCell in real space.
const RefinableObjClock & GetClockLatticePar() const
last time the Lattice parameters were changed
void FractionalToOrthonormalCoords(REAL &x, REAL &y, REAL &z) const
Get orthonormal cartesian coordinates for a set of (x,y,z) fractional coordinates.
class to input or output a well-formatted xml beginning or ending tag.
class of refinable parameter types.
We need to record exactly when refinable objects have been modified for the last time (to avoid re-co...
void Reset()
Reset a Clock to 0, to force an update.
void AddChild(const RefinableObjClock &)
Add a 'child' clock.
void RemoveChild(const RefinableObjClock &)
remove a child clock. This also tells the child clock to remove the parent.
void Click()
Record an event for this clock (generally, the 'time' an object has been modified,...
Generic Refinable Object.
bool IsBeingRefined() const
Is the object being refined ? (Can be refined by one algorithm at a time only.)
virtual void RegisterClient(RefinableObj &) const
Register a new object using this object.
RefinablePar & GetPar(const long i)
Access all parameters in the order they were inputted.
virtual const string & GetName() const
Name of the object.
long GetNbPar() const
Total number of refinable parameter in the object.
virtual void BeginOptimization(const bool allowApproximations=false, const bool enableRestraints=false)
This should be called by any optimization class at the begining of an optimization.
const RefinableObjClock & GetClockMaster() const
This clocks records any change in the object. See refinableObj::mClockMaster.
void AddOption(RefObjOpt *opt)
virtual void DeRegisterClient(RefinableObj &) const
Deregister an object (which not any more) using this object.
virtual void UpdateDisplay() const
If there is an interface, this should be automatically be called each time there is a 'new,...
RefinableObjClock mClockMaster
Master clock, which is changed whenever the object has been altered.
string mName
Name for this RefinableObject. Should be unique, at least in the same scope.+.
void AddSubRefObj(RefinableObj &)
void SetGlobalOptimStep(const RefParType *type, const REAL step)
Change the maximum step to use during Global Optimization algorithms.
void RemoveSubRefObj(RefinableObj &)
virtual void GlobalOptRandomMove(const REAL mutationAmplitude, const RefParType *type=gpRefParTypeObjCryst)
Make a random move of the current configuration.
output a number as a formatted float:
output a string with a fixed length (adding necessary space or removing excess characters) :
Abstract base class for all objects in wxCryst.
wxCryst class for Crystals