Skip to content

Commit 983738a

Browse files
committed
Merge remote-tracking branch 'objcryst/master' into upstream-objcryst
* objcryst/master: Crystal::XMLInput(): add a hook to re-use atomic scattering power when mDeleteSubObjInDestructor is False. This is useful when re-loading Crystal configurations using their xml descriptions repeatedly, notably in python.
2 parents 9a0b195 + f1cfa84 commit 983738a

File tree

2 files changed

+63
-5
lines changed

2 files changed

+63
-5
lines changed

ObjCryst/ObjCryst/Crystal.h

+10-3
Original file line numberDiff line numberDiff line change
@@ -341,19 +341,26 @@ class Crystal:public UnitCell
341341
const RefinableObjClock& GetClockScattererList()const;
342342

343343
virtual void XMLOutput(ostream &os,int indent=0)const;
344+
/** \brief Input the crystal structure from a stream.
345+
*
346+
* This will destroy any Scatterer of ScatteringPower if
347+
* mDeleteSubObjInDestructor is true. Otherwise they will just
348+
* be de-registered and should be deleted somewhere else,
349+
* but there is a special hook implemented where any
350+
* previously existing ScatteringPowerAtom will be re-used if
351+
* equivalent to the one in the input.
352+
*/
344353
virtual void XMLInput(istream &is,const XMLCrystTag &tag);
345354
//virtual void XMLInputOld(istream &is,const IOCrystTag &tag);
346355

347356
virtual void GlobalOptRandomMove(const REAL mutationAmplitude,
348357
const RefParType *type=gpRefParTypeObjCryst);
349358
virtual REAL GetLogLikelihood()const;
350-
/** \brief output Crystal structure as a cif file (EXPERIMENTAL !)
359+
/** \brief output Crystal structure as a cif file
351360
* \param mindist : minimum distance between atoms to consider them
352361
* overlapping. Overlapping atoms are only included as comments in the
353362
* CIF file.
354363
*
355-
* \warning This is very crude and EXPERIMENTAL so far: there is not much
356-
* information beside atom positions...
357364
*/
358365
virtual void CIFOutput(ostream &os, double mindist = 0.5)const;
359366

ObjCryst/ObjCryst/IO.cpp

+53-2
Original file line numberDiff line numberDiff line change
@@ -896,13 +896,37 @@ void Crystal::XMLInput(istream &is,const XMLCrystTag &tagg)
896896
this->RemoveSubRefObj(mScatteringPowerRegistry.GetObj(i));
897897
mScatteringPowerRegistry.GetObj(i).DeRegisterClient(*this);
898898
}
899-
mScatteringPowerRegistry.DeleteAll();
899+
900+
std::list<ScatteringPowerAtom*> vold_scattpow;
901+
if(mDeleteSubObjInDestructor)
902+
{
903+
mScatteringPowerRegistry.DeleteAll();
904+
}
905+
else
906+
{
907+
// Keep track of the old atomic scattering powers to see if they can be re-used
908+
for(std::vector<ScatteringPower*>::const_iterator pos=mScatteringPowerRegistry.begin() ;
909+
pos!=mScatteringPowerRegistry.end(); ++pos)
910+
{
911+
if((*pos)->GetClassName().compare("ScatteringPowerAtom")!=0) continue;
912+
vold_scattpow.push_back(dynamic_cast<ScatteringPowerAtom*>(*pos));
913+
}
914+
mScatteringPowerRegistry.DeRegisterAll();
915+
}
916+
900917
for(long i=0;i<mScattererRegistry.GetNb();i++)
901918
{
902919
this->RemoveSubRefObj(mScattererRegistry.GetObj(i));
903920
mScattererRegistry.GetObj(i).DeRegisterClient(*this);
904921
}
905-
mScattererRegistry.DeleteAll();
922+
if(mDeleteSubObjInDestructor)
923+
{
924+
mScattererRegistry.DeleteAll();
925+
}
926+
else
927+
{
928+
mScattererRegistry.DeRegisterAll();
929+
}
906930

907931
for(unsigned int i=0;i<tagg.GetNbAttribute();i++)
908932
{
@@ -1011,6 +1035,33 @@ void Crystal::XMLInput(istream &is,const XMLCrystTag &tagg)
10111035
VFN_DEBUG_MESSAGE("Crystal::XMLInput():reading a ScatteringPowerAtom",5)
10121036
ScatteringPowerAtom *sc=new ScatteringPowerAtom;
10131037
sc->XMLInput(is,tag);
1038+
if(!mDeleteSubObjInDestructor)
1039+
{
1040+
// Can we re-use a previous scattering power since we did not delete them ?
1041+
for(std::list<ScatteringPowerAtom*>::iterator pos= vold_scattpow.begin();
1042+
pos!=vold_scattpow.end();++pos)
1043+
{
1044+
if((*pos)->GetSymbol() != sc->GetSymbol()) continue;
1045+
if((*pos)->GetName() != sc->GetName()) continue;
1046+
if((*pos)->GetFormalCharge() != sc->GetFormalCharge()) continue;
1047+
if((*pos)->GetMaximumLikelihoodNbGhostAtom() != sc->GetMaximumLikelihoodNbGhostAtom()) continue;
1048+
if((*pos)->GetMaximumLikelihoodPositionError() != sc->GetMaximumLikelihoodPositionError()) continue;
1049+
if((*pos)->IsIsotropic() != sc->IsIsotropic()) continue;
1050+
if(fabs((*pos)->GetBiso() - sc->GetBiso()) > 1e-4f) continue;
1051+
if(!(*pos)->IsIsotropic())
1052+
{
1053+
if(fabs((*pos)->GetBij(0) - sc->GetBij(0)) > 1e-4f) continue;
1054+
if(fabs((*pos)->GetBij(1) - sc->GetBij(1)) > 1e-4f) continue;
1055+
if(fabs((*pos)->GetBij(2) - sc->GetBij(2)) > 1e-4f) continue;
1056+
if(fabs((*pos)->GetBij(3) - sc->GetBij(3)) > 1e-4f) continue;
1057+
if(fabs((*pos)->GetBij(4) - sc->GetBij(4)) > 1e-4f) continue;
1058+
if(fabs((*pos)->GetBij(5) - sc->GetBij(5)) > 1e-4f) continue;
1059+
}
1060+
VFN_DEBUG_MESSAGE("Crystal::XMLInput(): reusing scattering power: "<<sc->GetName(),5);
1061+
delete sc;
1062+
sc = *pos;
1063+
}
1064+
}
10141065
this->AddScatteringPower(sc);
10151066
VFN_DEBUG_EXIT("Crystal::XMLInput():reading a ScatteringPowerAtom",5)
10161067
continue;

0 commit comments

Comments
 (0)