void AsymmetricUnit::SetSpaceGroup(const SpaceGroup &spg) { VFN_DEBUG_MESSAGE("AsymmetricUnit::SetSpaceGroup(SpGroup)",5) tmp_C_Numeric_locale tmploc; # if 0 TAU_PROFILE("(AsymmetricUnit::SetSpaceGroup)","void (SpaceGroup)",TAU_DEFAULT); mXmin=0.; mYmin=0.; mZmin=0.; mXmax=1.; mYmax=1.; mZmax=1.; if(1==spg.GetSpaceGroupNumber()) return;//no need to search an asymmetric unit // Test points=reular grid of points inside the unit cell // All points must be or have at least a symmetric in the asymmetric unit const long nbPoints=13; CrystMatrix_REAL testPoints(nbPoints*nbPoints*nbPoints,3); { long l=0; for(long i=0;i<nbPoints;i++) for(long j=0;j<nbPoints;j++) for(long k=0;k<nbPoints;k++) { testPoints(l ,0)=i/(REAL)nbPoints; testPoints(l ,1)=j/(REAL)nbPoints; testPoints(l++,2)=k/(REAL)nbPoints; } } testPoints += 0.01; CrystVector_REAL vert(8);//vertices limits vert(0)=1/8.; vert(1)=1/6.; vert(2)=1/4.; vert(3)=1/3.; vert(4)=1/2.; vert(5)=2/3.; vert(6)=3/4.; vert(7)=1.; const int NbStep=vert.numElements(); CrystMatrix_REAL coords; double junk; REAL minVolume=1.; bool allPtsInAsym,tmp; for(long nx=0;nx<NbStep;nx++) for(long ny=0;ny<NbStep;ny++) for(long nz=0;nz<NbStep;nz++) { if(minVolume<(vert(nx)*vert(ny)*vert(nz)-.0001)) break; allPtsInAsym=true; for(int i=0;i<testPoints.rows();i++) { coords=spg.GetAllSymmetrics(testPoints(i,0),testPoints(i,1),testPoints(i,2)); for(long j=0;j<coords.numElements();j++) coords(j)=modf(coords(j)+10.,&junk) ; tmp=false; for(long j=0;j<coords.rows();j++) {//Test if at least one of the symmetrics is in the parallelepiped if( (coords(j,0) < vert(nx)) &&(coords(j,1) < vert(ny)) &&(coords(j,2) < vert(nz))) { //cout << modf(coords(j,0)+10.,junk) << " " // << modf(coords(j,1)+10.,junk) << " " // << modf(coords(j,2)+10.,junk) << endl; tmp=true; break; } } if(false==tmp) { //cout << " Rejected:"<<vert(nx)<<" "<<vert(ny)<<" "<<vert(nz)<<" "<<i<<endl; //cout << coords <<endl; allPtsInAsym=false; break; } } if( (true==allPtsInAsym)) { mXmax=vert(nx); mYmax=vert(ny); mZmax=vert(nz); VFN_DEBUG_MESSAGE("->ACCEPTED:" << mXmax <<" "<< mYmax <<" "<< mZmax <<endl,2) //cout << "->ACCEPTED:" << mXmax <<" "<< mYmax <<" "<< mZmax <<endl; minVolume=vert(nx)*vert(ny)*vert(nz); break;//no need to grow any more along z } } cout<<"->Finished Generating (pseudo) Asymmetric Unit, with:"<<endl <<" 0 <= x <= "<< mXmax<<endl <<" 0 <= y <= "<< mYmax<<endl <<" 0 <= z <= "<< mZmax<<endl<<endl; #else const cctbx::sgtbx::brick b(spg.GetCCTbxSpg().type()); #ifdef __DEBUG__ cout<<"->>Parallelepipedic Asymmetric Unit, from cctbx::sgtbx::brick:"<<endl <<b.as_string()<<endl; #endif mXmin=boost::rational_cast<REAL,int>(b(0,0).value()); mYmin=boost::rational_cast<REAL,int>(b(1,0).value()); mZmin=boost::rational_cast<REAL,int>(b(2,0).value()); mXmax=boost::rational_cast<REAL,int>(b(0,1).value()); mYmax=boost::rational_cast<REAL,int>(b(1,1).value()); mZmax=boost::rational_cast<REAL,int>(b(2,1).value()); #endif }
void CIFData::ExtractSpacegroup(const bool verbose) { map<ci_string,string>::const_iterator positem; bool found = false; positem=mvItem.find("_space_group_IT_number"); if(positem!=mvItem.end()) { mSpacegroupNumberIT=CIFNumeric2Int(positem->second); found = true; if(verbose) cout<<"Found spacegroup IT number:"<<mSpacegroupNumberIT<<endl; } else { positem=mvItem.find("_symmetry_Int_Tables_number"); if(positem!=mvItem.end()) { mSpacegroupNumberIT=CIFNumeric2Int(positem->second); found = true; if(verbose) cout<<"Found spacegroup IT number (with OBSOLETE CIF #1.0 TAG):"<<mSpacegroupNumberIT<<endl; } else mSpacegroupNumberIT=0; } positem=mvItem.find("_space_group_name_Hall"); if(positem!=mvItem.end()) { mSpacegroupSymbolHall=positem->second; found = true; if(verbose) cout<<"Found spacegroup Hall symbol:"<<mSpacegroupSymbolHall<<endl; } else { positem=mvItem.find("_symmetry_space_group_name_Hall"); if(positem!=mvItem.end()) { mSpacegroupSymbolHall=positem->second; found = true; if(verbose) cout<<"Found spacegroup Hall symbol (with OBSOLETE CIF #1.0 TAG):"<<mSpacegroupSymbolHall<<endl; } } positem=mvItem.find("_space_group_name_H-M_alt"); if(positem!=mvItem.end()) { mSpacegroupHermannMauguin=positem->second; found = true; if(verbose) cout<<"Found spacegroup Hermann-Mauguin symbol:"<<mSpacegroupHermannMauguin<<endl; } else { positem=mvItem.find("_symmetry_space_group_name_H-M"); if(positem!=mvItem.end()) { mSpacegroupHermannMauguin=positem->second; found = true; if(verbose) cout<<"Found spacegroup Hermann-Mauguin symbol (with OBSOLETE CIF #1.0 TAG):"<<mSpacegroupHermannMauguin<<endl; } } if (mSpacegroupSymbolHall.length() > 0) mSpaceGroup = SpaceGroup::GetSpaceGroup(mSpacegroupSymbolHall); else mSpaceGroup=NULL; if (!mSpaceGroup && mSpacegroupHermannMauguin.length() > 0) mSpaceGroup = SpaceGroup::GetSpaceGroup(mSpacegroupHermannMauguin); if (!mSpaceGroup) mSpaceGroup = SpaceGroup::GetSpaceGroup(mSpacegroupNumberIT); SpaceGroup *sg = new SpaceGroup(); if (mSpacegroupSymbolHall.length() > 0) sg->SetHallName(mSpacegroupSymbolHall); if (mSpacegroupHermannMauguin.length() > 0) sg->SetHMName(mSpacegroupHermannMauguin); if (mSpacegroupNumberIT > 0) sg->SetId(mSpacegroupNumberIT); positem=mvItem.find("_symmetry_equiv_pos_as_xyz"); if(positem!=mvItem.end()) { sg->AddTransform (positem->second); found = true; } else for(map<set<ci_string>,map<ci_string,vector<string> > >::const_iterator loop=mvLoop.begin(); loop!=mvLoop.end();++loop) { map<ci_string,vector<string> >::const_iterator pos; unsigned i, nb; pos=loop->second.find("_symmetry_equiv_pos_as_xyz"); if (pos!=loop->second.end()) { nb=pos->second.size(); found = true; for (i = 0; i < nb; i++) sg->AddTransform(pos->second[i]); break; // found the transforms, so we have done with them } } if (found) mSpaceGroup = SpaceGroup::Find(sg); delete sg; if (mSpaceGroup != NULL) // set the space group name to Hall symbol mSpacegroupSymbolHall = mSpaceGroup->GetHallName(); }
void testSpaceGroupTransformations() { // See https://github.com/openbabel/openbabel/pull/254 SpaceGroup group; vector<string> trans; vector<string> trans_exp; vector<string> trans_got; // Same transformation trans_exp.push_back("x,y,z"); trans.push_back("x,y,z"); trans.push_back(" x , y , z "); trans.push_back("x,y+1,z"); trans.push_back("x,y-1,z-1"); trans.push_back("x,y-1,z"); // Same transformation trans_exp.push_back("x,-y,z"); trans.push_back("x,-y,z"); trans.push_back("x,1-y,z"); trans.push_back("x,-y+1,z"); // Same transformation trans_exp.push_back("x,-y,-z"); trans.push_back("x,-y,-z"); trans.push_back("x,1-y,1-z"); trans.push_back("x,-y+1,-z+1"); // Same transformation trans_exp.push_back("x,-y,-y-z"); trans.push_back("x,-y,-z-y"); trans.push_back("x,1-y,-y+1-z"); trans.push_back("x,-y+1,-y-z+1"); // Same transformation trans_exp.push_back("x,-y,1/6-y-z"); trans.push_back("x,-y,-z-y+1/6"); trans.push_back("x,-y,-z-y+7/6"); trans.push_back("x,1-y,7/6-y+1-z"); trans.push_back("x,-y+1,-y-z+1+1/6"); trans.push_back("x,-y+1,-y+1/6-z+1"); // Same transformation trans_exp.push_back("x,3/4-y+z,5/6-y-z"); trans.push_back("x,3/4-y+z,-1/6-z-y"); trans.push_back("x,-y+3/4+z,-z-y-1/6"); trans.push_back("x,z-y+3/4,-z-y-7/6"); trans.push_back("x,1+z+3/4-y,-7/6-y-z"); trans.push_back("X , 3 / 4 - Y + 1 + z , - Y - Z - 1 / 6 "); trans.push_back("x,z-y+1+3/4,-y-1/6-z+1"); vector<string>::const_iterator i, iend; iend = trans.end(); for (i = trans.begin(); i != iend; ++i) group.AddTransform(i->c_str()); // Loop over symmetry operators transform3dIterator ti; const transform3d *t = group.BeginTransform(ti); while(t){ trans_got.push_back(t->DescribeAsString()); //cout << t->DescribeAsString() << "\n"; t = group.NextTransform(ti); } OB_ASSERT( trans_exp.size() == trans_got.size() ); OB_ASSERT( equal(trans_exp.begin(), trans_exp.end(), trans_got.begin()) ); }