FOX/ObjCryst++  2022
RefinableObj.cpp
1 /* ObjCryst++ Object-Oriented Crystallographic Library
2  (c) 2000-2002 Vincent Favre-Nicolin vincefn@users.sourceforge.net
3  2000-2001 University of Geneva (Switzerland)
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19 /*
20 * source file for the RefinablePar and RefinableObj classes
21 *
22 */
23 #include <ctime>
24 #include <boost/format.hpp>
25 #include "ObjCryst/RefinableObj/RefinableObj.h"
26 #include "ObjCryst/Quirks/VFNStreamFormat.h"
27 #include "ObjCryst/Quirks/VFNDebug.h"
28 #ifdef __WX__CRYST__
29  #include "ObjCryst/wxCryst/wxRefinableObj.h"
30  #undef GetClassName // Conflict from wxMSW headers ? (cygwin)
31 #endif
32 #include <algorithm>
33 
34 #define POSSIBLY_UNUSED(expr) (void)(expr)
35 
36 namespace ObjCryst
37 {
38 //######################################################################
39 //
40 // RefParType
41 //
42 //######################################################################
43 RefParType::RefParType(const string &name):
44 mpParent(0),mName(name),mId(0)
45 {
46  this->InitId();
47 }
48 
49 RefParType::RefParType(const RefParType *parent,const string &name):
50 mpParent(parent),mName(name),mId(0)
51 {
52  this->InitId();
53 }
54 
56 
58 {
59  VFN_DEBUG_MESSAGE("RefParType::IsDescendantFromOrSameAs(RefParType*): "<<this<<" : "<<mpParent,1)
60  if(type->mId==mId) return true;
61  if(0==mpParent) return false;
62  return mpParent->IsDescendantFromOrSameAs(type);
63 }
64 
65 bool RefParType::operator==(const RefParType *type) const
66 {
67  if(this==type) return true;
68  return false;
69 }
70 const string& RefParType::GetName() const{ return mName;}
71 
73 {
74  static unsigned long nbRefParType=0;
75  mId=nbRefParType++;
76 }
77 
79 long NiftyStaticGlobalObjectsInitializer_RefinableObj::mCount=0;
80 //######################################################################
81 //
82 //
83 //
84 //######################################################################
85 
86 unsigned long RefinableObjClock::msTick0=0;
87 unsigned long RefinableObjClock::msTick1=0;
88 RefinableObjClock::RefinableObjClock()
89 {
90  //this->Click();
91  mTick0=0;
92  mTick1=0;
93 }
94 RefinableObjClock::~RefinableObjClock()
95 {
96  // first copy & clear sets to avoid possible loops in RemoveChild()
97  set<const RefinableObjClock*> vChild=mvChild;
98  set<RefinableObjClock*> vParent=mvParent;
99  mvChild.clear();
100  mvParent.clear();
101  for(std::set<const RefinableObjClock*>::iterator pos=vChild.begin();
102  pos!=vChild.end();++pos) (*pos)->RemoveParent(*this);
103  for(std::set<RefinableObjClock*>::iterator pos=vParent.begin();
104  pos!=vParent.end();++pos) (*pos)->RemoveChild(*this);
105 }
106 
107 bool RefinableObjClock::operator< (const RefinableObjClock &rhs)const
108 {
109  if(mTick1<rhs.mTick1) return true;
110  if(mTick1==rhs.mTick1) {if(mTick0<rhs.mTick0) return true;}
111  return false;
112 }
113 bool RefinableObjClock::operator<=(const RefinableObjClock &rhs)const
114 {
115  if(mTick1<rhs.mTick1) return true;
116  if(mTick1==rhs.mTick1) if(mTick0<=rhs.mTick0) return true;
117  return false;
118 }
119 bool RefinableObjClock::operator> (const RefinableObjClock &rhs)const
120 {
121  if(mTick1>rhs.mTick1) return true;
122  if(mTick1==rhs.mTick1) if(mTick0>rhs.mTick0) return true;
123  return false;
124 }
125 bool RefinableObjClock::operator>=(const RefinableObjClock &rhs)const
126 {
127  if(mTick1>rhs.mTick1) return true;
128  if(mTick1==rhs.mTick1) if(mTick0>=rhs.mTick0) return true;
129  return false;
130 }
132 {
133  //return;
134  if(++msTick0==0) ++msTick1;//Update ObjCryst++ static event counter
135  mTick0=msTick0;
136  mTick1=msTick1;
137  for(std::set<RefinableObjClock*>::iterator pos=mvParent.begin();
138  pos!=mvParent.end();++pos) (*pos)->Click();
139  VFN_DEBUG_MESSAGE("RefinableObjClock::Click():"<<mTick1<<":"<<mTick0<<"(at "<<this<<")",0)
140  //this->Print();
141 }
143 {
144  mTick0=0;
145  mTick1=0;
146 }
148 {
149  cout <<"Clock():"<<mTick1<<":"<<mTick0;
150  VFN_DEBUG_MESSAGE_SHORT(" (at "<<this<<")",4)
151  cout <<endl;
152 }
154 {
155  cout <<"RefinableObj class Clock():"<<msTick1<<":"<<msTick0<<endl;
156 }
158 {mvChild.insert(&clock);clock.AddParent(*this);this->Click();}
160 {
161  const unsigned int i = mvChild.erase(&clock); POSSIBLY_UNUSED(i);
162  VFN_DEBUG_MESSAGE("RefinableObjClock::RemoveChild():"<<i,5)
163  clock.RemoveParent(*this);
164  this->Click();
165 }
167 {
168  // First check for loop
169  if(&clock==this)
170  throw ObjCrystException("RefinableObjClock::AddParent(..) child == Parent !!");
171  if(clock.HasParent(*this)==true)
172  throw ObjCrystException("RefinableObjClock::AddParent(..) Loop in clock tree !!");
173  mvParent.insert(&clock);
174 }
176 {
177  // avoid warnings about unused i when not debugging.
178  const unsigned int i = mvParent.erase(&clock); POSSIBLY_UNUSED(i);
179  VFN_DEBUG_MESSAGE("RefinableObjClock::RemoveParent():"<<i,5)
180 }
181 
183 {
184  mTick0=rhs.mTick0;
185  mTick1=rhs.mTick1;
186  for(std::set<RefinableObjClock*>::iterator pos=mvParent.begin();
187  pos!=mvParent.end();++pos) if( (*this) > (**pos) ) **pos = *this;
188 }
189 
190 bool RefinableObjClock::HasParent(const RefinableObjClock &clock) const
191 {
192  for(std::set<RefinableObjClock*>::iterator pos=mvParent.begin();
193  pos!=mvParent.end();++pos)
194  {
195  if((*pos)==&clock) return true;
196  if((*pos)->HasParent(clock)) return true;
197  }
198  return false;
199 }
200 //######################################################################
201 // Restraint
202 //######################################################################
204 mpRefParType(gpRefParTypeObjCryst)
205 {}
206 
208 mpRefParType(type)
209 {}
210 
211 Restraint::~Restraint()
212 {}
213 
214 const RefParType* Restraint::GetType()const{return mpRefParType;}
215 
216 void Restraint::SetType(const RefParType *type){mpRefParType=type;}
217 
218 REAL Restraint::GetLogLikelihood()const{return 0.;}
219 
220 //######################################################################
221 // RefinablePar
222 //######################################################################
223 
225 Restraint(),
226 mName(""),mpValue(0),mMin(0),mMax(0),
227 mHasLimits(false),mIsFixed(true),mIsUsed(true),mIsPeriodic(false),
228 mPeriod(0.),mGlobalOptimStep(1.),mDerivStep(1e-5),mRefParDerivStepModel(REFPAR_DERIV_STEP_ABSOLUTE),
229 mSigma(0.),mHumanScale(1.),mHasAssignedClock(false),mpClock(0)
230 #ifdef __WX__CRYST__
231 ,mpWXFieldRefPar(0)
232 #endif
233 {}
234 
235 RefinablePar::RefinablePar( const string &name,
236  REAL *refPar,
237  const REAL min,
238  const REAL max,
239  const RefParType *type,
240  RefParDerivStepModel derivMode,
241  const bool hasLimits,
242  const bool isFixed,
243  const bool isUsed,
244  const bool isPeriodic,
245  const REAL humanScale,
246  REAL period):
247 Restraint(type),
248 mName(name),mpValue(refPar),mMin(min),mMax(max),
249 mHasLimits(hasLimits),mIsFixed(isFixed),mIsUsed(isUsed),mIsPeriodic(isPeriodic),mPeriod(period),
250 mGlobalOptimStep((max-min)/100.),mDerivStep(1e-5),mRefParDerivStepModel(derivMode),
251 mSigma(0.),mHumanScale(humanScale),
252 #if 0
253 mUseEquation(false),mEquationNbRefPar(0),mEquationCoeff(0),
254 #endif
255 mHasAssignedClock(false),mpClock(0)
256 #ifdef __WX__CRYST__
257 ,mpWXFieldRefPar(0)
258 #endif
259 {}
260 
261 RefinablePar::~RefinablePar()
262 {
263  #ifdef __WX__CRYST__
264  this->WXDelete();
265  #endif
266 }
267 
268 void RefinablePar::Init(const string &name,
269  REAL *refPar,
270  const REAL min,
271  const REAL max,
272  const RefParType *type,
273  RefParDerivStepModel derivMode,
274  const bool hasLimits,
275  const bool isFixed,
276  const bool isUsed,
277  const bool isPeriodic,
278  const REAL humanScale,
279  REAL period)
280 {
281  mName=name;
282  mpValue=refPar;
283  mMin=min;
284  mMax=max;
285  Restraint::SetType(type);
286  mHasLimits=hasLimits;
287  mIsFixed=isFixed;
288  mIsUsed=isUsed;
289  mIsPeriodic=isPeriodic;
290  mPeriod=period;
291  mGlobalOptimStep=(max-min)/100.;
292  mDerivStep=1e-5;
293  mRefParDerivStepModel=derivMode;
294  mSigma=0.;
295  mHumanScale=humanScale;
296  #if 0
297  mUseEquation=false;
298  mEquationNbRefPar=0;
299  mEquationCoeff=0;
300  #endif
301  mHasAssignedClock=false;
302  mpClock=0;
303 }
305 Restraint(old)
306 {
307  mpValue=old.mpValue;
308  #ifdef __WX__CRYST__
309  mpWXFieldRefPar=0;
310  #endif
311  this->CopyAttributes(old);
313  mpClock=old.mpClock;
314 }
315 
317 {
318  mName=old.mName;
319  mMin=old.GetMin();
320  mMax=old.GetMax();
322  mIsFixed=old.mIsFixed;
323  mIsUsed=old.mIsUsed;
325  mPeriod=old.mPeriod;
329  mSigma=old.mSigma;
331  #if 0
332  mUseEquation=old.mUseEquation;
333  mEquationNbRefPar=old.mEquationNbRefPar;
334  mEquationCoeff=old.mEquationCoeff;
335  #endif
336 }
337 
339 {
340  #if 0
341  if(true==mUseEquation)
342  {
343  VFN_DEBUG_MESSAGE("RefinablePar::Value():Evaluating Equation",0)
344  REAL tmp=mEquationCoeff(0);
345  for(int i=0;i<mEquationNbRefPar;i++)
346  tmp += mEquationCoeff(i+1) * mEquationRefPar[i]->GetValue();
347  *mpValue = tmp;
348  }
349  #endif
350  return *mpValue;
351 }
352 
353 const REAL* RefinablePar::GetPointer()const
354 {
355  return mpValue;
356 }
357 
358 void RefinablePar::SetValue(const REAL value)
359 {
360  if(*mpValue == value) return;
361  this->Click();
362  VFN_DEBUG_MESSAGE("RefinablePar::SetValue()",2)
363  #if 0
364  if(true==mUseEquation)
365  {
366  cout << "RefinablePar::SetValue(): this parameter is defined by an equation !!" <<endl;
367  throw 0;
368  }
369  #endif
370  *mpValue = value;
371  /*
372  if(this->IsLimited() ==true)
373  {
374  if(true==this->IsPeriodic())
375  {
376  if(*mpValue > this->GetMax()) *mpValue -= this->GetMax()-this->GetMin();
377  if(*mpValue < this->GetMin()) *mpValue += this->GetMax()-this->GetMin();
378  }
379  else
380  {
381  if(*mpValue > this->GetMax()) *mpValue=this->GetMax();
382  if(*mpValue < this->GetMin()) *mpValue=this->GetMin();
383  }
384  }
385  */
386  if(this->IsLimited() ==true)
387  {
388  if(*mpValue > this->GetMax()) *mpValue=this->GetMax();
389  if(*mpValue < this->GetMin()) *mpValue=this->GetMin();
390  }
391  else if(true==this->IsPeriodic())
392  {
393  if(*mpValue > mPeriod) *mpValue -= mPeriod;
394  if(*mpValue < 0) *mpValue += mPeriod;
395  }
396 }
397 
398 const REAL& RefinablePar::GetHumanValue() const
399 {
400  static REAL val;
401  val = *mpValue * mHumanScale;
402  return val;
403 }
404 
405 void RefinablePar::SetHumanValue(const REAL &value)
406 {
407  if(*mpValue == (value/mHumanScale)) return;
408  this->Click();
409  VFN_DEBUG_MESSAGE("RefinablePar::SetHumanValue()",2)
410  #if 0
411  if(true==mUseEquation)
412  {
413  cout << "RefinablePar::SetValue(): this parameter is defined by an equation !!" <<endl;
414  throw 0;
415  }
416  #endif
417  *mpValue = value/mHumanScale;
418  /*
419  if(this->IsLimited() ==true)
420  {
421  if(true==this->IsPeriodic())
422  {
423  if(*mpValue > this->GetMax()) *mpValue -= this->GetMax()-this->GetMin();
424  if(*mpValue < this->GetMin()) *mpValue += this->GetMax()-this->GetMin();
425  }
426  else
427  {
428  if(*mpValue > this->GetMax()) *mpValue=this->GetMax();
429  if(*mpValue < this->GetMin()) *mpValue=this->GetMin();
430  }
431  }
432  */
433  if(this->IsLimited() ==true)
434  {
435  if(*mpValue > this->GetMax()) *mpValue=this->GetMax();
436  if(*mpValue < this->GetMin()) *mpValue=this->GetMin();
437  }
438  else if(true==this->IsPeriodic())
439  {
440  if(*mpValue > mPeriod) *mpValue -= mPeriod;
441  if(*mpValue < 0) *mpValue += mPeriod;
442  }
443 }
444 
445 void RefinablePar::Mutate(const REAL mutateValue)
446 {
447  if(0==mutateValue) return;
448  VFN_DEBUG_MESSAGE("RefinablePar::Mutate():"<<this->GetName(),1)
449  if(true==mIsFixed) return;
450  this->Click();
451  #if 0
452  if(true==mUseEquation)
453  {
454  cout << "RefinablePar::Mutate(): this parameter is defined by an equation !!" <<endl;
455  throw 0;
456  }
457  #endif
458  *mpValue += mutateValue;
459  /*
460  if(this->IsLimited() ==true)
461  {
462  if(true==this->IsPeriodic())
463  {
464  if(*mpValue > this->GetMax()) *mpValue -= this->GetMax()-this->GetMin();
465  if(*mpValue < this->GetMin()) *mpValue += this->GetMax()-this->GetMin();
466  }
467  else
468  {
469  if(*mpValue > this->GetMax()) *mpValue=this->GetMax();
470  if(*mpValue < this->GetMin()) *mpValue=this->GetMin();
471  }
472  }
473  */
474  if(this->IsLimited() ==true)
475  {
476  if(*mpValue > this->GetMax()) *mpValue=this->GetMax();
477  if(*mpValue < this->GetMin()) *mpValue=this->GetMin();
478  }
479  else if(true==this->IsPeriodic())
480  {
481  //if(*mpValue > mPeriod) *mpValue -= mPeriod;
482  *mpValue=fmod((REAL)*mpValue,(REAL)mPeriod);
483  if(*mpValue < 0) *mpValue += mPeriod;
484  }
485  VFN_DEBUG_MESSAGE("RefinablePar::Mutate():End",0)
486 }
487 
488 void RefinablePar::MutateTo(const REAL mutateValue)
489 {
490  VFN_DEBUG_MESSAGE("RefinablePar::MutateTo()",2)
491  if(true==mIsFixed) return;
492  if(*mpValue == mutateValue)return;
493  this->Click();
494  #if 0
495  if(true==mUseEquation)
496  {
497  cout << "RefinablePar::Mutate(): this parameter is defined by an equation !!" <<endl;
498  throw 0;
499  }
500  #endif
501  *mpValue = mutateValue;
502  /*
503  if(this->IsLimited() ==true)
504  {
505  if(true==this->IsPeriodic())
506  {
507  if(*mpValue > this->GetMax()) *mpValue -= this->GetMax()-this->GetMin();
508  if(*mpValue < this->GetMin()) *mpValue += this->GetMax()-this->GetMin();
509  }
510  else
511  {
512  if(*mpValue > this->GetMax()) *mpValue=this->GetMax();
513  if(*mpValue < this->GetMin()) *mpValue=this->GetMin();
514  }
515  }
516  */
517  if(this->IsLimited() ==true)
518  {
519  if(*mpValue > this->GetMax()) *mpValue=this->GetMax();
520  if(*mpValue < this->GetMin()) *mpValue=this->GetMin();
521  }
522  else if(true==this->IsPeriodic())
523  {
524  if(*mpValue > mPeriod) *mpValue -= mPeriod;
525  if(*mpValue < 0) *mpValue += mPeriod;
526  }
527 }
528 
529 REAL RefinablePar::GetSigma()const {return mSigma;}
530 REAL RefinablePar::GetHumanSigma()const {return mSigma*mHumanScale;}
531 void RefinablePar::SetSigma(const REAL sigma) {mSigma=sigma; this->Click();}
532 
533 void RefinablePar::Print() const
534 {
535  cout << this->GetName() << " : " << this->GetHumanValue()
536  << " Fixed:"<< mIsFixed <<" Periodic:"<<mIsPeriodic<<" Limited:"<<mHasLimits
537  << " Min:" << this->GetHumanMin() << " Max:" << this->GetHumanMax()
538  << " Step:" <<GetGlobalOptimStep()
539  #ifdef __DEBUG__
540  << ",HasClock=" << mHasAssignedClock << " at " << mpClock
541  #endif
542  <<endl;
543 }
544 
545 string RefinablePar::GetName()const {return mName;}
546 void RefinablePar::SetName(const string &name) {mName=name;}
547 
548 bool RefinablePar::IsFixed()const {return mIsFixed;}
549 void RefinablePar::SetIsFixed(const bool b)
550 {
551  VFN_DEBUG_MESSAGE("RefinablePar::SetIsFixed():"<<this->GetName(),1)
552  mIsFixed=b;
553 }
554 
555 bool RefinablePar::IsLimited()const {return mHasLimits;}
556 void RefinablePar::SetIsLimited(const bool b) {mHasLimits=b;this->Click();}
557 
558 bool RefinablePar::IsUsed()const {return mIsUsed;}
559 void RefinablePar::SetIsUsed(const bool b) {mIsUsed=b;this->Click();}
560 
561 bool RefinablePar::IsPeriodic()const {return mIsPeriodic;}
562 void RefinablePar::SetIsPeriodic(const bool b,REAL period)
563 {mIsPeriodic=b;mPeriod=period;this->Click();}
564 
565 
566 REAL RefinablePar::GetMin()const {return mMin;}
567 void RefinablePar::SetMin(const REAL min) { mMin=min;this->Click();}
569 void RefinablePar::SetHumanMin(const REAL min) { mMin=min/mHumanScale;this->Click();}
570 
571 REAL RefinablePar::GetMax()const {return mMax;}
572 void RefinablePar::SetMax(const REAL max) { mMax=max;this->Click();}
573 REAL RefinablePar::GetHumanMax()const {return mMax * mHumanScale;}
574 void RefinablePar::SetHumanMax(const REAL max) { mMax=max/mHumanScale;this->Click();}
575 
576 REAL RefinablePar::GetPeriod()const {return mPeriod;}
577 void RefinablePar::SetPeriod(const REAL period)
578 { mPeriod=period;this->Click();}
579 
581 {
582  if(REFPAR_DERIV_STEP_ABSOLUTE==mRefParDerivStepModel) return mDerivStep;
583  REAL d=mDerivStep* (*mpValue);
584 
585  //:KLUDGE: Parameter will probably has a singular value, so it should not matter..
586  if(d == 0.) return 1e-8;
587  return d;
588 }
589 
590 void RefinablePar::SetDerivStep(const REAL step)
591 {
592  this->Click();
593  mDerivStep = step;
594 }
595 
598 
600 void RefinablePar::SetHumanScale(const REAL scale) {mHumanScale=scale;}
601 #if 0
602 void RefinablePar::SetUseEquation(const bool useItOrNot,const REAL c0)
603 {
604  this->Click();
605  mUseEquation=useItOrNot;
606  if(true==mUseEquation)
607  {
608  mEquationCoeff.resize(mEquationMaxRefPar);
609  mEquationCoeff(0)=c0;
610  }
611 }
612 
613 void RefinablePar::SetUseEquation(const bool useItOrNot,const REAL c0,
614  const REAL c1, const RefinablePar &refpar1)
615 {
616  this->Click();
617  mUseEquation=useItOrNot;
618  if(true==mUseEquation)
619  {
620  mEquationCoeff.resize(mEquationMaxRefPar);
621  mEquationCoeff(0)=c0;
622  mEquationCoeff(1)=c1;
623  mEquationRefPar[0]=&refpar1;
624  }
625 }
626 
627 void RefinablePar::SetUseEquation(const bool useItOrNot,const REAL c0,
628  const REAL c1, const RefinablePar &refpar1,
629  const REAL c2, const RefinablePar &refpar2)
630 {
631  this->Click();
632  mUseEquation=useItOrNot;
633  if(true==mUseEquation)
634  {
635  mEquationCoeff.resize(mEquationMaxRefPar);
636  mEquationCoeff(0)=c0;
637  mEquationCoeff(1)=c1;
638  mEquationCoeff(2)=c2;
639  mEquationRefPar[0]=&refpar1;
640  mEquationRefPar[1]=&refpar2;
641  }
642 }
643 
644 void RefinablePar::SetUseEquation(const bool useItOrNot,const REAL c0,
645  const REAL c1, const RefinablePar &refpar1,
646  const REAL c2, const RefinablePar &refpar2,
647  const REAL c3, const RefinablePar &refpar3)
648 {
649  this->Click();
650  mUseEquation=useItOrNot;
651  if(true==mUseEquation)
652  {
653  mEquationCoeff.resize(mEquationMaxRefPar);
654  mEquationCoeff(0)=c0;
655  mEquationCoeff(1)=c1;
656  mEquationCoeff(2)=c2;
657  mEquationCoeff(3)=c2;
658  mEquationRefPar[0]=&refpar1;
659  mEquationRefPar[1]=&refpar2;
660  mEquationRefPar[2]=&refpar2;
661  }
662 }
663 #endif
665 {
666  VFN_DEBUG_MESSAGE("RefinablePar::AssignClock() for "<<this->GetName()<< "at "<<&clock,4)
667  mpClock=&clock;
668  mHasAssignedClock=true;
669 }
671 {
672  if(false==mHasAssignedClock) return;
673  VFN_DEBUG_MESSAGE("RefinablePar::Click():"<<this->GetName(),1)
674  mpClock->Click();
675  //mpClock->Print();
676  //VFN_DEBUG_MESSAGE("RefinablePar::Click():End",2)
677 }
678 
679 void RefinablePar::SetLimitsAbsolute(const REAL min, const REAL max)
680 {
681  //:TODO: check limits
682  mMin=min;
683  mMax=max;
684  mHasLimits=true;
685 }
686 void RefinablePar::SetLimitsRelative(const REAL min, const REAL max)
687 {
688  VFN_DEBUG_MESSAGE("RefinablePar::SetLimitsRelative():"<<this->GetName(),1)
689  //:TODO: check limits
690  mMin=this->GetValue()+min;
691  mMax=this->GetValue()+max;
692  this->SetIsLimited(true);
693 }
694 void RefinablePar::SetLimitsProportional(const REAL min, const REAL max)
695 {
696  //:TODO: check limits
697  mMin=this->GetValue()*min;
698  mMax=this->GetValue()*max;
699  this->SetIsLimited(true);
700 }
701 #ifdef __WX__CRYST__
702 WXCrystObjBasic* RefinablePar::WXCreate(wxWindow *parent)
703 {
704  VFN_DEBUG_MESSAGE("RefinablePar::WXCreate()",8)
705  if(mpWXFieldRefPar!=0)
706  {
707  throw ObjCrystException((string)"RefinablePar::WXCreate():"+this->GetName()+(string)" WXFieldRefPar already exists !");
708  }
709  mpWXFieldRefPar=new WXFieldRefPar (parent,this->GetName(),this);
710  return (WXCrystObjBasic*) mpWXFieldRefPar;
711 }
712 WXCrystObjBasic* RefinablePar::WXGet()
713 {
714  return (WXCrystObjBasic*) mpWXFieldRefPar;
715 }
716 void RefinablePar::WXDelete()
717 {
718  if(0!=mpWXFieldRefPar)
719  {
720  VFN_DEBUG_MESSAGE("RefinablePar::WXDelete():"<<mName,5)
721  delete mpWXFieldRefPar;
722  }
723  mpWXFieldRefPar=0;
724 }
725 void RefinablePar::WXNotifyDelete()
726 {
727  VFN_DEBUG_MESSAGE("RefinablePar::WXNotifyDelete():"<<mName,5)
728  mpWXFieldRefPar=0;
729 }
730 #endif
731 
732 //######################################################################
733 // RefObjOpt
734 //######################################################################
736 {
737  #ifdef __WX__CRYST__
738  mpWXFieldOption=0;
739  #endif
740 }
741 
742 RefObjOpt::~RefObjOpt()
743 {}
744 
745 void RefObjOpt::Init(const int nbChoice,
746  const string *name,
747  const string *choiceNames)
748 {
749  VFN_DEBUG_MESSAGE("RefObjOpt::Init()"<<*name,5)
750  mNbChoice=nbChoice;
751  mChoice=0;
752  mpName=name;
753  mpChoiceName=choiceNames;
754 }
755 
756 int RefObjOpt::GetNbChoice()const
757 { return mNbChoice;}
758 
759 int RefObjOpt::GetChoice()const
760 { return mChoice;}
761 
762 void RefObjOpt::SetChoice(const int choice)
763 {
764  if(mChoice==choice)return;
765  VFN_DEBUG_MESSAGE("RefObjOpt::SetChoice()"<<this->GetName()<< \
766  " to "<<this->GetChoiceName(choice),5)
767  mChoice=choice;
768  mClock.Click();
769 }
770 void RefObjOpt::SetChoice(const string &choiceName)
771 {
772  int choice;
773  for(choice=0;choice<mNbChoice;choice++) if(choiceName==*(mpChoiceName+choice)) break;
774  if(choice==mNbChoice) choice=0;
775  this->SetChoice(choice);
776 }
777 
778 const string& RefObjOpt::GetName()const
779 {
780  return *mpName;
781 }
782 
783 const string& RefObjOpt::GetClassName()const
784 {
785  static string className="Option";
786  return className;
787 }
788 
789 const string& RefObjOpt::GetChoiceName(const int i)const
790 {
791  return *(mpChoiceName+i);
792 }
793 
794 const RefinableObjClock& RefObjOpt::GetClock()const{return mClock;}
795 
796 #ifdef __WX__CRYST__
797 WXCrystObjBasic* RefObjOpt::WXCreate(wxWindow *parent)
798 {
799  VFN_DEBUG_MESSAGE("RefObjOpt::WXCreate()",8)
800  mpWXFieldOption=new WXFieldOption (parent,-1,this);
801  return mpWXFieldOption;
802 }
803 WXCrystObjBasic* RefObjOpt::WXGet()
804 {
805  return mpWXFieldOption;
806 }
807 void RefObjOpt::WXDelete()
808 {
809  if(0!=mpWXFieldOption)
810  {
811  VFN_DEBUG_MESSAGE("RefObjOpt::WXDelete()",5)
812  delete mpWXFieldOption;
813  }
814  mpWXFieldOption=0;
815 }
816 void RefObjOpt::WXNotifyDelete()
817 {
818  VFN_DEBUG_MESSAGE("RefObjOpt::WXNotifyDelete()",5)
819  mpWXFieldOption=0;
820 }
821 #endif
822 
823 //######################################################################
824 // RefObjOption
825 //######################################################################
826 template<class T> RefObjOption<T>::RefObjOption(T* obj):
827 mpObj(obj)
828 {}
829 
830 template<class T> RefObjOption<T>::~RefObjOption()
831 {}
832 
833 template<class T> void RefObjOption<T>::SetChoice(const int choice)
834 {
835  if(mChoice==choice)return;
836  VFN_DEBUG_MESSAGE("RefObjOption<T>::SetChoice()"<<this->GetName()<< \
837  " to "<<this->GetChoiceName(choice),5)
838  mChoice=choice;
839  mClock.Click();
840  if(mfpSetNewValue !=0) (mpObj->*mfpSetNewValue)(choice);
841 }
842 
843 template<class T> void RefObjOption<T>::Init(const int nbChoice,
844  const string *name,
845  const string *choiceNames,
846  void (T::*fp)(const int))
847 {
848  this->RefObjOpt::Init(nbChoice,name,choiceNames);
849  mfpSetNewValue=fp;
850 }
851 
852 //######################################################################
853 // ObjRegistry
854 //######################################################################
855 #ifdef __WX__CRYST__
856 bool operator==(const wxString&wx,const string&str)
857 {
858  return wx==str.c_str();
859 }
860 bool operator==(const string&str,const wxString&wx)
861 {
862  return wx==str.c_str();
863 }
864 #endif
865 
866 template<class T> ObjRegistry<T>::ObjRegistry():
867 mName(""),mAutoUpdateUI(true)
868 #ifdef __WX__CRYST__
869 ,mpWXRegistry(0)
870 #endif
871 {
872  VFN_DEBUG_MESSAGE("ObjRegistry::ObjRegistry()",5)
873 }
874 
875 template<class T> ObjRegistry<T>::ObjRegistry(const string &name):
876 mName(name),mAutoUpdateUI(true)
877 #ifdef __WX__CRYST__
878 ,mpWXRegistry(0)
879 #endif
880 {
881  VFN_DEBUG_MESSAGE("ObjRegistry::ObjRegistry(name):"<<mName,5)
882 }
883 
884 //:TODO: a copy constructor
885 template<class T> ObjRegistry<T>::~ObjRegistry()
886 {
887  VFN_DEBUG_MESSAGE("ObjRegistry::~ObjRegistry():"<<mName,5)
888  #ifdef __WX__CRYST__
889  this->WXDelete();
890  #endif
891 }
892 
893 template<class T> void ObjRegistry<T>::Register(T &obj)
894 {
895  VFN_DEBUG_ENTRY("ObjRegistry("<<mName<<")::Register():"<<obj.GetName(),2)
896  typename vector<T*>::iterator pos=find(mvpRegistry.begin(),mvpRegistry.end(),&obj);
897  if(pos!=mvpRegistry.end())
898  {
899  VFN_DEBUG_EXIT("ObjRegistry("<<mName<<")::Register():"<<obj.GetName()<<"Already registered!",2)
900  return;
901  }
902  mvpRegistry.push_back(&obj);
903  mvpRegistryList.push_back(&obj);
904  mListClock.Click();
905  #ifdef __WX__CRYST__
906  if((0!=mpWXRegistry) && mAutoUpdateUI)
907  mpWXRegistry->Add(obj.WXCreate(mpWXRegistry));
908  #endif
909  //this->Print();
910  VFN_DEBUG_EXIT("ObjRegistry("<<mName<<")::Register():"<<obj.GetName(),2)
911 }
912 
913 template<class T> void ObjRegistry<T>::DeRegister(T &obj)
914 {
915  VFN_DEBUG_ENTRY("ObjRegistry("<<mName<<")::Deregister(&obj)"<<mvpRegistry.size(),2)
916  if (mvpRegistry.size() == 0)
917  {// This may happen if an object is deleted several times due to inherited destructors
918  // :TODO: make sure it does not happen, while making sure WXGet() below
919  //is not pure virtual because the child destructor has already done its job...
920  VFN_DEBUG_EXIT("ObjRegistry(" << mName << ")::Deregister(&obj): EMPTY registry", 2)
921  return;
922  }
923  //this->Print();
924  typename vector<T*>::iterator pos=find(mvpRegistry.begin(),mvpRegistry.end(),&obj);
925  if(pos==mvpRegistry.end())
926  {
927  VFN_DEBUG_EXIT("ObjRegistry("<<mName<<")::Deregister(&obj):NOT FOUND !!!",2)
928  return; //:TODO: throw something ?
929  }
930  #ifdef __WX__CRYST__
931  if(0!=mpWXRegistry) mpWXRegistry->Remove(obj.WXGet());
932  #endif
933  mvpRegistry.erase(pos);
934 
935  typename list<T*>::iterator pos2=find(mvpRegistryList.begin(),mvpRegistryList.end(),&obj);
936  mvpRegistryList.erase(pos2);
937 
938  mListClock.Click();
939  VFN_DEBUG_EXIT("ObjRegistry("<<mName<<")::Deregister(&obj)",2)
940 }
941 
942 template<class T> void ObjRegistry<T>::DeRegister(const string &objName)
943 {
944  VFN_DEBUG_ENTRY("ObjRegistry("<<mName<<")::Deregister(name):"<<objName,2)
945 
946  const long i=this->Find(objName);
947  if(-1==i)
948  {
949  VFN_DEBUG_EXIT("ObjRegistry("<<mName<<")::Deregister(name): NOT FOUND !!!",2)
950  return; //:TODO: throw something ?
951  }
952  //:KLUDGE: should directly do an iterator search on the name...
953  typename vector<T*>::iterator pos=find(mvpRegistry.begin(),mvpRegistry.end(),mvpRegistry[i]);
954 
955  #ifdef __WX__CRYST__
956  if(0!=mpWXRegistry) mpWXRegistry->Remove((*pos)->WXGet());
957  #endif
958  mvpRegistry.erase(pos);
959 
960  typename list<T*>::iterator pos2=find(mvpRegistryList.begin(),mvpRegistryList.end(),mvpRegistry[i]);
961  mvpRegistryList.erase(pos2);
962 
963  mListClock.Click();
964  VFN_DEBUG_EXIT("ObjRegistry("<<mName<<")::Deregister(name):",2)
965 }
966 
967 template<class T> void ObjRegistry<T>::DeRegisterAll()
968 {
969  VFN_DEBUG_ENTRY("ObjRegistry("<<mName<<")::DeRegisterAll():",5)
970  #ifdef __WX__CRYST__
971  if(0!=mpWXRegistry)
972  {
973  typename vector<T*>::iterator pos;
974  for(pos=mvpRegistry.begin();pos!=mvpRegistry.end();++pos)
975  mpWXRegistry->Remove((*pos)->WXGet());
976  }
977  #endif
978  mvpRegistry.clear();
979  mvpRegistryList.clear();
980  mListClock.Click();
981  VFN_DEBUG_EXIT("ObjRegistry("<<mName<<")::DeRegisterAll():",5)
982 }
983 
984 template<class T> void ObjRegistry<T>::DeleteAll()
985 {
986  VFN_DEBUG_ENTRY("ObjRegistry("<<mName<<")::DeleteAll():",5)
987  vector<T*> reg=mvpRegistry;//mvpRegistry will be modified as objects are deleted, so use a copy
988  typename vector<T*>::iterator pos;
989  for(pos=reg.begin();pos!=reg.end();++pos) delete *pos;
990  mvpRegistry.clear();
991  mvpRegistryList.clear();
992  mListClock.Click();
993  VFN_DEBUG_EXIT("ObjRegistry("<<mName<<")::DeleteAll():",5)
994 }
995 
996 template<class T> T& ObjRegistry<T>::GetObj(const unsigned int i)
997 {
998  if(i>=this->GetNb()) throw ObjCrystException("ObjRegistry<T>::GetObj(i): i >= nb!");
999  return *(mvpRegistry[i]);
1000 }
1001 
1002 template<class T> const T& ObjRegistry<T>::GetObj(const unsigned int i) const
1003 {
1004  if(i>=this->GetNb()) throw ObjCrystException("ObjRegistry<T>::GetObj(i): i >= nb!");
1005  return *(mvpRegistry[i]);
1006 }
1007 
1008 template<class T> T& ObjRegistry<T>::GetObj(const string &objName)
1009 {
1010  const long i=this->Find(objName);
1011  return *(mvpRegistry[i]);
1012 }
1013 
1014 template<class T> const T& ObjRegistry<T>::GetObj(const string &objName) const
1015 {
1016  const long i=this->Find(objName);
1017  return *(mvpRegistry[i]);
1018 }
1019 
1020 template<class T> T& ObjRegistry<T>::GetObj(const string &objName,
1021  const string& className)
1022 {
1023  const long i=this->Find(objName,className);
1024  return *(mvpRegistry[i]);
1025 }
1026 
1027 template<class T> const T& ObjRegistry<T>::GetObj(const string &objName,
1028  const string& className) const
1029 {
1030  const long i=this->Find(objName,className);
1031  return *(mvpRegistry[i]);
1032 }
1033 
1034 template<class T> long ObjRegistry<T>::GetNb()const{return (long)mvpRegistry.size();}
1035 
1036 template<class T> void ObjRegistry<T>::Print()const
1037 {
1038  VFN_DEBUG_MESSAGE("ObjRegistry::Print():",2)
1039  cout <<mName<<" :"<<this->GetNb()<<" object registered:" <<endl;
1040 
1041  for(long i=0;i<this->GetNb();++i)
1042  cout << boost::format("#%3d:%s(%s)") %i %this->GetObj(i).GetClassName() %this->GetObj(i).GetName()<<endl;
1043 }
1044 
1045 template<class T> void ObjRegistry<T>::SetName(const string &name){ mName=name;}
1046 
1047 template<class T> const string& ObjRegistry<T>::GetName()const { return mName;}
1048 
1049 template<class T> long ObjRegistry<T>::Find(const string &objName) const
1050 {
1051  VFN_DEBUG_MESSAGE("ObjRegistry::Find(objName)",2)
1052  long index=-1;
1053  //bool error=false;
1054  for(long i=this->GetNb()-1;i>=0;i--)
1055  if( mvpRegistry[i]->GetName() == objName) return i;
1056  // if(-1 != index) error=true ;else index=i;
1057  //if(true == error)
1058  //{
1059  // cout << "ObjRegistry::Find(name) : ";
1060  // cout << "found duplicate name ! This *cannot* be !!" ;
1061  // cout << objName <<endl;
1062  // this->Print();
1063  // throw 0;
1064  //}
1065  cout << "ObjRegistry<T>::Find("<<objName<<"): Not found !!"<<endl;
1066  this->Print();
1067  throw ObjCrystException("ObjRegistry<T>::Find("+objName+"): Not found !!");
1068  return index;
1069 }
1070 
1071 template<class T> long ObjRegistry<T>::Find(const string &objName,
1072  const string &className,
1073  const bool nothrow) const
1074 {
1075  VFN_DEBUG_MESSAGE("ObjRegistry::Find(objName,className)",2)
1076  long index=-1;
1077  //bool error=false;
1078  for(long i=this->GetNb()-1;i>=0;i--)
1079  if( mvpRegistry[i]->GetName() == objName)
1080  if(className==mvpRegistry[i]->GetClassName()) return i;
1081  // if(-1 != index) error=true ;else index=i;
1082  //if(true == error)
1083  //{
1084  // cout << "ObjRegistry::Find(name) : ";
1085  // cout << "found duplicate name ! This *cannot* be !!" ;
1086  // cout << objName <<endl;
1087  // this->Print();
1088  // throw 0;
1089  //}
1090  cout << "ObjRegistry<T>::Find("<<objName<<","<<className<<"): Not found !!"<<endl;
1091  this->Print();
1092  if(nothrow==false)
1093  throw ObjCrystException("ObjRegistry<T>::Find("+objName+","+className+"): Not found !!");
1094  return index;
1095 }
1096 
1097 template<class T> long ObjRegistry<T>::Find(const T &obj) const
1098 {
1099  VFN_DEBUG_MESSAGE("ObjRegistry::Find(&obj)",2)
1100  for(long i=this->GetNb()-1;i>=0;i--)
1101  if( mvpRegistry[i]== &obj) return i;
1102  //:TODO: throw something
1103  return -1;
1104 }
1105 
1106 template<class T> long ObjRegistry<T>::Find(const T *pobj) const
1107 {
1108  VFN_DEBUG_MESSAGE("ObjRegistry::Find(&obj)",2)
1109  for(long i=this->GetNb()-1;i>=0;i--)
1110  if( mvpRegistry[i]== pobj) return i;
1111  //:TODO: throw something
1112  return -1;
1113 }
1114 
1115 template<class T> const RefinableObjClock& ObjRegistry<T>::GetRegistryClock()const{return mListClock;}
1116 
1117 template<class T> void ObjRegistry<T>::AutoUpdateUI(const bool autoup)
1118 {
1119  mAutoUpdateUI=autoup;
1120 }
1121 
1122 template<class T> void ObjRegistry<T>::UpdateUI()
1123 {
1124  #ifdef __WX__CRYST__
1125  for(unsigned int i=0;i<this->GetNb();i++)
1126  {
1127  if((this->GetObj(i).WXGet()==NULL) && (0!=mpWXRegistry))
1128  mpWXRegistry->Add(this->GetObj(i).WXCreate(mpWXRegistry));
1129  }
1130  #endif
1131 }
1132 
1133 template<class T> std::size_t ObjRegistry<T>::size() const
1134 {
1135  return (std::size_t) mvpRegistry.size();
1136 }
1137 
1138 template<class T> typename vector<T*>::const_iterator ObjRegistry<T>::begin() const
1139 {
1140  return mvpRegistry.begin();
1141 }
1142 
1143 template<class T> typename vector<T*>::const_iterator ObjRegistry<T>::end() const
1144 {
1145  return mvpRegistry.end();
1146 }
1147 
1148 template<class T> typename list<T*>::const_iterator ObjRegistry<T>::list_begin() const
1149 {
1150  return mvpRegistryList.begin();
1151 }
1152 
1153 template<class T> typename list<T*>::const_iterator ObjRegistry<T>::list_end() const
1154 {
1155  return mvpRegistryList.end();
1156 }
1157 
1158 #ifdef __WX__CRYST__
1159 template<class T> WXRegistry<T>* ObjRegistry<T>::WXCreate(wxWindow *parent)
1160 {
1161  VFN_DEBUG_MESSAGE("ObjRegistry<T>::WXCreate()",2)
1162  mpWXRegistry=new WXRegistry<T> (parent,this);
1163  for(int i=0;i<this->GetNb();i++)
1164  mpWXRegistry->Add(this->GetObj(i).WXCreate(mpWXRegistry));
1165  return mpWXRegistry;
1166 }
1167 template<class T> void ObjRegistry<T>::WXDelete()
1168 {
1169  if(0!=mpWXRegistry)
1170  {
1171  VFN_DEBUG_MESSAGE("ObjRegistry<T>::WXDelete()",2)
1172  delete mpWXRegistry;
1173  }
1174  mpWXRegistry=0;
1175 }
1176 template<class T> void ObjRegistry<T>::WXNotifyDelete()
1177 {
1178  VFN_DEBUG_MESSAGE("ObjRegistry<T>::WXNotifyDelete()",2)
1179  mpWXRegistry=0;
1180 }
1181 #endif
1182 
1183 //######################################################################
1184 // function RefObjRegisterRecursive
1185 //######################################################################
1186 template<class T> void RefObjRegisterRecursive(T &obj,ObjRegistry<T> &reg)
1187 {
1188  VFN_DEBUG_MESSAGE("RefObjRegisterRecursive()",3)
1189  reg.Register(obj);
1190  ObjRegistry<T> *pObjReg=&(obj.GetSubObjRegistry());
1191  for(int i=0;i<pObjReg->GetNb();i++)
1192  RefObjRegisterRecursive(pObjReg->GetObj(i),reg);
1193  return;
1194 }
1195 //######################################################################
1196 // function RefObjRegisterRecursive
1197 //######################################################################
1198 
1199 void GetSubRefObjListClockRecursive(ObjRegistry<RefinableObj> &reg,RefinableObjClock &clock)
1200 {
1201  if(reg.GetRegistryClock()>clock) clock=reg.GetRegistryClock();
1202  for(int i=0;i<reg.GetNb();i++)
1203  GetSubRefObjListClockRecursive(reg.GetObj(i).GetSubObjRegistry(),clock);
1204 }
1205 
1206 //######################################################################
1207 // RefinableObj
1208 //######################################################################
1209 
1210 ObjRegistry<RefinableObj> gRefinableObjRegistry("Global RefinableObj registry");
1211 ObjRegistry<RefinableObj> gTopRefinableObjRegistry("Global Top RefinableObj registry");
1212 
1213 RefinableObj::RefinableObj():
1214 mName(""),
1215 mNbRefParNotFixed(-1),mOptimizationDepth(0),mDeleteRefParInDestructor(true)
1216 #ifdef __WX__CRYST__
1217 ,mpWXCrystObj(0)
1218 #endif
1219 {
1220  VFN_DEBUG_MESSAGE("RefinableObj::RefinableObj()",3)
1221  gRefinableObjRegistry.Register(*this);
1222  mSubObjRegistry.SetName("Registry for sub-objects");
1223  mClientObjRegistry.SetName("Registry for Clients");
1224 
1225  VFN_DEBUG_MESSAGE("RefinableObj::RefinableObj():End",2)
1226 }
1227 RefinableObj::RefinableObj(const bool internalUseOnly):
1228 mName(""),
1229 mNbRefParNotFixed(-1),mOptimizationDepth(0),mDeleteRefParInDestructor(true)
1230 #ifdef __WX__CRYST__
1231 ,mpWXCrystObj(0)
1232 #endif
1233 {
1234  VFN_DEBUG_MESSAGE("RefinableObj::RefinableObj(bool)",3)
1235  if(false==internalUseOnly) gRefinableObjRegistry.Register(*this);
1236  mSubObjRegistry.SetName("Registry for sub-objects");
1237  mClientObjRegistry.SetName("Registry for Clients");
1238 
1239  VFN_DEBUG_MESSAGE("RefinableObj::RefinableObj(bool):End",2)
1240 }
1241 
1242 RefinableObj::RefinableObj(const RefinableObj &old) {}
1243 /*
1244 RefinableObj::RefinableObj(const RefinableObj &old):
1245 mName(old.mName),mMaxNbRefPar(old.mMaxNbRefPar),mSavedValuesSetIsUsed(mMaxNbSavedSets),
1246 mOptimizationDepth(0),mDeleteRefParInDestructor(true)
1247 #ifdef __WX__CRYST__
1248 ,mpWXCrystObj(0)
1249 #endif
1250 {
1251  VFN_DEBUG_MESSAGE("RefinableObj::RefinableObj(RefinableObj&)",3)
1252  mpRefPar = new RefinablePar*[mMaxNbRefPar];
1253  mpSavedValuesSet = new CrystVector_REAL* [mMaxNbSavedSets];
1254  mpSavedValuesSetName = new string* [mMaxNbSavedSets];
1255  mSavedValuesSetIsUsed=false;
1256  *this=old;
1257  mSubObjRegistry.SetName("Registry for sub-objects of "+mName);
1258  mClientObjRegistry.SetName("Registry for Clients of "+mName);
1259  gRefinableObjRegistry.Register(*this);
1260 }
1261 */
1262 RefinableObj::~RefinableObj()
1263 {
1264  VFN_DEBUG_MESSAGE("RefinableObj::~RefinableObj():"<<this->GetName(),5)
1265  if(mvpRefPar.size()>0)
1266  {
1267  if(true==mDeleteRefParInDestructor)
1268  {
1269  vector<RefinablePar*>::iterator pos;
1270  for(pos=mvpRefPar.begin();pos!=mvpRefPar.end();pos++) delete *pos;
1271  }
1272  }
1273  gRefinableObjRegistry.DeRegister(*this);
1274  for(int i=0;i<mSubObjRegistry.GetNb();i++)
1275  mSubObjRegistry.GetObj(i).DeRegisterClient(*this);
1276  VFN_DEBUG_MESSAGE("RefinableObj::~RefinableObj():End",4)
1277  #ifdef __WX__CRYST__
1278  this->WXDelete();
1279  #endif
1280 }
1281 
1282 const string& RefinableObj::GetClassName() const
1283 {
1284  const static string className="RefinableObj";
1285  return className;
1286 }
1287 
1288 const string& RefinableObj::GetName() const {return mName;}
1289 void RefinableObj::SetName(const string &name)
1290 {
1291  VFN_DEBUG_MESSAGE("RefinableObj::SetName()to :"<<name,6)
1292  mName=name;
1293  mSubObjRegistry.SetName("Registry for sub-objects of "+mName);
1294 }
1295 /*
1296 void RefinableObj::operator=(const RefinableObj &old)
1297 {
1298  VFN_DEBUG_MESSAGE("RefinableObj::operator=(RefinableObj&)",3)
1299  this->ResetParList();
1300  //this->AddPar(old);
1301  // Do not copy old saved sets
1302  //... but erase any that may be stored
1303  for(long i=0;i<mMaxNbSavedSets;i++)
1304  if(true==mSavedValuesSetIsUsed(i))
1305  {
1306  delete *(mpSavedValuesSetName+i);
1307  delete *(mpSavedValuesSet+i);
1308  }
1309  mSavedValuesSetIsUsed=false;
1310 }
1311 */
1312 void RefinableObj::PrepareForRefinement() const
1313 {
1314  VFN_DEBUG_MESSAGE("RefinableObj::PrepareForRefinement()",5)
1315  mNbRefParNotFixed=0;
1316  mRefparNotFixedIndex.resize(this->GetNbPar());
1317  for(long i=0;i<this->GetNbPar();i++)
1318  if ( (this->GetPar(i).IsFixed() == false) && (this->GetPar(i).IsUsed() == true))
1319  {
1320  mRefparNotFixedIndex(mNbRefParNotFixed) = i;
1321  mNbRefParNotFixed++;
1322  }
1323  //this->Print();
1324  VFN_DEBUG_MESSAGE("RefinableObj::PrepareForRefinement():End",5)
1325 }
1326 
1327 void RefinableObj::FixAllPar()
1328 {
1329  VFN_DEBUG_ENTRY("RefinableObj("<<this->GetClassName()<<":"
1330  <<this->GetName()<<")::FixAllPar()",4)
1331  for(long i=0;i<this->GetNbPar();i++) this->GetPar(i).SetIsFixed(true);
1332  for(int i=0;i<this->GetSubObjRegistry().GetNb();i++)
1333  this->GetSubObjRegistry().GetObj(i).FixAllPar();
1334  VFN_DEBUG_EXIT("RefinableObj("<<this->GetName()<<")::FixAllPar()",4)
1335 }
1336 
1337 void RefinableObj::UnFixAllPar()
1338 {
1339  for(long i=0;i<this->GetNbPar();i++) this->GetPar(i).SetIsFixed(false);
1340  for(int i=0;i<this->GetSubObjRegistry().GetNb();i++)
1341  this->GetSubObjRegistry().GetObj(i).UnFixAllPar();
1342 }
1343 
1344 void RefinableObj::SetParIsFixed(const long parIndex,const bool fix)
1345 {
1346  this->GetPar(parIndex).SetIsFixed(fix);
1347 }
1348 
1349 void RefinableObj::SetParIsFixed(const string& name,const bool fix)
1350 {
1351  for(long i=this->GetNbPar()-1;i>=0;i--)
1352  if( this->GetPar(i).GetName() == name)
1353  this->GetPar(i).SetIsFixed(fix);
1354 }
1355 
1356 void RefinableObj::SetParIsFixed(const RefParType *type,const bool fix)
1357 {
1358  for(long i=0;i<this->GetNbPar();i++)
1359  if( this->GetPar(i).GetType()->IsDescendantFromOrSameAs(type))
1360  {
1361  //cout << " Fixing ..." << this->GetPar(i).Name()<<endl;
1362  this->GetPar(i).SetIsFixed(fix);
1363  }
1364  for(int i=0;i<this->GetSubObjRegistry().GetNb();i++)
1365  this->GetSubObjRegistry().GetObj(i).SetParIsFixed(type,fix);
1366 }
1367 
1368 void RefinableObj::SetParIsUsed(const string& name,const bool use)
1369 {
1370  for(long i=this->GetNbPar()-1;i>=0;i--)
1371  if( this->GetPar(i).GetName() == name)
1372  this->GetPar(i).SetIsUsed(use);
1373 }
1374 
1375 void RefinableObj::SetParIsUsed(const RefParType *type,const bool use)
1376 {
1377  for(long i=0;i<this->GetNbPar();i++)
1378  if( this->GetPar(i).GetType()->IsDescendantFromOrSameAs(type))
1379  {
1380  //cout << " Now used (Waow!) : ..." << this->GetPar(i).Name()<<endl;
1381  this->GetPar(i).SetIsUsed(use);
1382  }
1383  for(int i=0;i<this->GetSubObjRegistry().GetNb();i++)
1384  this->GetSubObjRegistry().GetObj(i).SetParIsUsed(type,use);
1385 }
1386 
1387 long RefinableObj::GetNbPar()const { return mvpRefPar.size();}
1388 
1389 long RefinableObj::GetNbParNotFixed()const {return mNbRefParNotFixed;}
1390 
1391 RefinablePar& RefinableObj::GetPar(const long i)
1392 {
1393  return *(mvpRefPar[i]);
1394 }
1395 
1396 const RefinablePar& RefinableObj::GetPar(const long i) const
1397 {
1398  return *(mvpRefPar[i]);
1399 }
1400 
1401 RefinablePar& RefinableObj::GetPar(const string & name)
1402 {
1403  const long i=this->FindPar(name);
1404  if(-1==i)
1405  {
1406  this->Print();
1407  throw ObjCrystException("RefinableObj::GetPar(): cannot find parameter: "+name+" in object:"+this->GetName());
1408  }
1409  return *(mvpRefPar[i]);
1410 }
1411 
1412 const RefinablePar& RefinableObj::GetPar(const string & name) const
1413 {
1414  const long i=this->FindPar(name);
1415  if(-1==i)
1416  {
1417  this->Print();
1418  throw ObjCrystException("RefinableObj::GetPar(): cannot find parameter: "+name+" in object:"+this->GetName());
1419  }
1420  return *(mvpRefPar[i]);
1421 }
1422 
1423 RefinablePar& RefinableObj::GetPar(const REAL *p)
1424 {
1425  const long i=this->FindPar(p);
1426  if(-1==i)
1427  {
1428  this->Print();
1429  throw ObjCrystException("RefinableObj::GetPar(*p): cannot find parameter in object:"+this->GetName());
1430  }
1431  return *(mvpRefPar[i]);
1432 }
1433 
1434 const RefinablePar& RefinableObj::GetPar(const REAL *p) const
1435 {
1436  const long i=this->FindPar(p);
1437  if(-1==i)
1438  {
1439  this->Print();
1440  throw ObjCrystException("RefinableObj::GetPar(*p): cannot find parameter in object:"+this->GetName());
1441  }
1442  return *(mvpRefPar[i]);
1443 }
1444 
1445 RefinablePar& RefinableObj::GetParNotFixed(const long i)
1446 {
1447  return *(mvpRefPar[mRefparNotFixedIndex(i)]);
1448 }
1449 
1450 const RefinablePar& RefinableObj::GetParNotFixed(const long i) const
1451 {
1452  return *(mvpRefPar[mRefparNotFixedIndex(i)]);
1453 }
1454 
1455 void RefinableObj::AddPar(const RefinablePar &newRefPar)
1456 {
1457  VFN_DEBUG_MESSAGE("RefinableObj::AddPar(RefPar&)",2)
1458  string name=newRefPar.GetName();
1459  long ct=0;
1460  if(this->FindPar(name)>=0)
1461  while(this->FindPar(name)!=-1)
1462  {// KLUDGE ? Extend name if another parameter already exists with the same name
1463  VFN_DEBUG_MESSAGE("RefinableObj::AddPar(): need to change name ?! -> "<<name<<","<<this->FindPar(name),10)
1464  name += "~";
1465  if(++ct==100) break;// KLUDGE, let go and hope for the best...
1466  }
1467 
1468  mvpRefPar.push_back(new RefinablePar(newRefPar));
1469  mvpRefPar.back()->SetName(name);
1470  mRefParListClock.Click();
1471 }
1472 
1473 void RefinableObj::AddPar(RefinablePar *newRefPar)
1474 {
1475  VFN_DEBUG_MESSAGE("RefinableObj::AddPar(RefPar&)",2)
1476  string name=newRefPar->GetName();
1477  long ct=0;
1478  if(this->FindPar(name)>=0)
1479  while(this->FindPar(name)!=-1)
1480  {// KLUDGE ? Extend name if another parameter already exists with the same name
1481  VFN_DEBUG_MESSAGE("RefinableObj::AddPar(): need to change name ?! -> "<<name<<","<<this->FindPar(name),10)
1482  name += "~";
1483  if(++ct==100) break;// KLUDGE, let go and hope for the best...
1484  }
1485  mvpRefPar.push_back(newRefPar);
1486  mvpRefPar.back()->SetName(name);
1487  mRefParListClock.Click();
1488 }
1489 
1490 void RefinableObj::AddPar(RefinableObj &newRefParList,const bool copyParam)
1491 {
1492  VFN_DEBUG_MESSAGE("RefinableObj::AddPar(RefParList&)" <<newRefParList.GetNbPar() ,2)
1493  RefinablePar *p;
1494  for(long i=0;i<newRefParList.GetNbPar();i++)
1495  {
1496  if(copyParam) p=new RefinablePar(newRefParList.GetPar(i));
1497  else p=&(newRefParList.GetPar(i));
1498  this->AddPar(p);
1499  }
1500 }
1501 
1502 vector<RefinablePar *>::iterator RefinableObj::RemovePar(RefinablePar *refPar)
1503 {
1504  VFN_DEBUG_MESSAGE("RefinableObj::RemovePar(RefPar&)",2)
1505  vector<RefinablePar *>::iterator pos=find(mvpRefPar.begin(),mvpRefPar.end(),refPar);
1506  if(pos==mvpRefPar.end())
1507  {
1508  throw ObjCrystException("RefinableObj::RemovePar():"+refPar->GetName()
1509  +"is not in this object:"+this->GetName());
1510  }
1511  return mvpRefPar.erase(pos);
1512 }
1513 
1514 void RefinableObj::Print() const
1515 {
1516  VFN_DEBUG_ENTRY("RefinableObj::Print()",2)
1517  cout << "Refinable Object:"<<this->GetName()
1518  <<", with " << this->GetNbPar() << " parameters" <<endl;
1519  for(int i=0;i<this->GetNbPar();i++)
1520  {
1521  if(this->GetPar(i).IsUsed() == false) continue;
1522  cout << "#"<<i<<"#" << this->GetPar(i).GetName() << ": " ;
1523  cout << FormatFloat(this->GetPar(i).GetHumanValue(),18,12) << " ";
1524  if(true == this->GetPar(i).IsFixed()) cout << "Fixed";
1525  else
1526  if(true == this->GetPar(i).IsLimited())
1527  {
1528  cout << "Limited (" << this->GetPar(i).GetHumanMin()<<","
1529  <<this->GetPar(i).GetHumanMax()<<")";
1530  if(true == this->GetPar(i).IsPeriodic()) cout << ",Periodic" ;
1531  }
1532  VFN_DEBUG_MESSAGE_SHORT(" (at "<<this->GetPar(i).mpValue<<")",5)
1533  if(true == this->GetPar(i).mHasAssignedClock)
1534  {
1535  VFN_DEBUG_MESSAGE_SHORT(" (Clock at "<<this->GetPar(i).mpClock<<")",5)
1536  }
1537  cout << endl;
1538  }
1539  VFN_DEBUG_EXIT("RefinableObj::Print()",2)
1540 }
1541 
1542 unsigned long RefinableObj::CreateParamSet(const string name) const
1543 {
1544  VFN_DEBUG_ENTRY("RefinableObj::CreateParamSet()",3)
1545  unsigned long id;
1546  for(id=0;id<=mvpSavedValuesSet.size();id++)
1547  if(mvpSavedValuesSet.end()==mvpSavedValuesSet.find(id)) break;
1548 
1549  pair< CrystVector_REAL ,string> p;
1550  p.second=name;
1551  mvpSavedValuesSet.insert(make_pair(id,p));
1552 
1553  this->SaveParamSet(id);
1554  VFN_DEBUG_MESSAGE("RefinableObj::CreateParamSet(): new parameter set with id="<<id<<" and name:"<<name,2)
1555  VFN_DEBUG_EXIT("RefinableObj::CreateParamSet()",3)
1556  return id;
1557 }
1558 
1559 void RefinableObj::ClearParamSet(const unsigned long id)const
1560 {
1561  VFN_DEBUG_ENTRY("RefinableObj::ClearParamSet()",2)
1562  mvpSavedValuesSet.erase(this->FindParamSet(id));
1563  VFN_DEBUG_EXIT("RefinableObj::ClearParamSet()",2)
1564 }
1565 
1566 void RefinableObj::SaveParamSet(const unsigned long id)const
1567 {
1568  VFN_DEBUG_MESSAGE("RefinableObj::SaveRefParSet()",2)
1569  map<unsigned long,pair<CrystVector_REAL,string> >::iterator pos=this->FindParamSet(id);
1570  pos->second.first.resize(mvpRefPar.size());
1571  REAL *p=pos->second.first.data();
1572  for(long i=0;i<this->GetNbPar();i++) *p++ = this->GetPar(i).GetValue();
1573 }
1574 
1575 void RefinableObj::RestoreParamSet(const unsigned long id)
1576 {
1577  VFN_DEBUG_MESSAGE("RefinableObj::RestoreRefParSet()",2)
1578  map<unsigned long,pair<CrystVector_REAL,string> >::iterator pos=this->FindParamSet(id);
1579  REAL *p=pos->second.first.data();
1580  for(long i=0;i<this->GetNbPar();i++)
1581  {
1582  //if( !this->GetPar(i).IsFixed() && this->GetPar(i).IsUsed())
1583  if(this->GetPar(i).IsUsed())
1584  this->GetPar(i).SetValue(*p);
1585  p++;
1586  }
1587 }
1588 
1589 const CrystVector_REAL & RefinableObj::GetParamSet(const unsigned long id)const
1590 {
1591  VFN_DEBUG_MESSAGE("RefinableObj::GetParamSet() const",2)
1592  map<unsigned long,pair<CrystVector_REAL,string> >::const_iterator pos=this->FindParamSet(id);
1593  return pos->second.first;
1594 }
1595 
1596 CrystVector_REAL & RefinableObj::GetParamSet(const unsigned long id)
1597 {
1598  VFN_DEBUG_MESSAGE("RefinableObj::GetParamSet()",2)
1599  map<unsigned long,pair<CrystVector_REAL,string> >::iterator pos=this->FindParamSet(id);
1600  return pos->second.first;
1601 }
1602 
1603 REAL RefinableObj::GetParamSet_ParNotFixedHumanValue(const unsigned long id,
1604  const long par)const
1605 {
1606  VFN_DEBUG_MESSAGE("RefinableObj::RefParSetNotFixedHumanValue()",0)
1607  map<unsigned long,pair<CrystVector_REAL,string> >::iterator pos=this->FindParamSet(id);
1608  return pos->second.first(mRefparNotFixedIndex(par));
1609 }
1610 
1611 const void RefinableObj::EraseAllParamSet()
1612 {
1613  mvpSavedValuesSet.clear();
1614 }
1615 
1616 const string& RefinableObj::GetParamSetName(const unsigned long id)const
1617 {
1618  VFN_DEBUG_MESSAGE("RefinableObj::GetParamSetName()",2)
1619  map<unsigned long,pair<CrystVector_REAL,string> >::const_iterator pos=this->FindParamSet(id);
1620  return pos->second.second;
1621 }
1622 
1623 void RefinableObj::SetLimitsAbsolute(const string &name,const REAL min,const REAL max)
1624 {
1625  for(long i=this->GetNbPar()-1;i>=0;i--)
1626  if( this->GetPar(i).GetName() == name)
1627  this->GetPar(i).SetLimitsAbsolute(min,max);
1628 }
1629 void RefinableObj::SetLimitsAbsolute(const RefParType *type,
1630  const REAL min,const REAL max)
1631 {
1632  for(long i=0;i<this->GetNbPar();i++)
1633  if(this->GetPar(i).GetType()->IsDescendantFromOrSameAs(type))
1634  this->GetPar(i).SetLimitsAbsolute(min,max);
1635  for(int i=0;i<this->GetSubObjRegistry().GetNb();i++)
1636  this->GetSubObjRegistry().GetObj(i).SetLimitsAbsolute(type,min,max);
1637 }
1638 void RefinableObj::SetLimitsRelative(const string &name, const REAL min, const REAL max)
1639 {
1640  for(long i=this->GetNbPar()-1;i>=0;i--)
1641  if( this->GetPar(i).GetName() == name)
1642  this->GetPar(i).SetLimitsRelative(min,max);
1643 }
1644 void RefinableObj::SetLimitsRelative(const RefParType *type,
1645  const REAL min, const REAL max)
1646 {
1647  VFN_DEBUG_MESSAGE("RefinableObj::SetLimitsRelative(RefParType*):"<<this->GetName(),2)
1648  for(long i=0;i<this->GetNbPar();i++)
1649  {
1650  VFN_DEBUG_MESSAGE("RefinableObj::SetLimitsRelative(RefParType*):par #"<<i,2)
1651  if(this->GetPar(i).GetType()->IsDescendantFromOrSameAs(type))
1652  this->GetPar(i).SetLimitsRelative(min,max);
1653  }
1654  for(int i=0;i<this->GetSubObjRegistry().GetNb();i++)
1655  this->GetSubObjRegistry().GetObj(i).SetLimitsRelative(type,min,max);
1656 }
1657 void RefinableObj::SetLimitsProportional(const string &name,const REAL min,const REAL max)
1658 {
1659  for(long i=this->GetNbPar()-1;i>=0;i--)
1660  if( this->GetPar(i).GetName() == name)
1661  this->GetPar(i).SetLimitsProportional(min,max);
1662 }
1663 void RefinableObj::SetLimitsProportional(const RefParType *type,
1664  const REAL min, const REAL max)
1665 {
1666  for(long i=0;i<this->GetNbPar();i++)
1667  if(this->GetPar(i).GetType()->IsDescendantFromOrSameAs(type))
1668  this->GetPar(i).SetLimitsProportional(min,max);
1669  for(int i=0;i<this->GetSubObjRegistry().GetNb();i++)
1670  this->GetSubObjRegistry().GetObj(i).SetLimitsProportional(type,min,max);
1671 }
1672 void RefinableObj::SetGlobalOptimStep(const RefParType *type, const REAL step)
1673 {
1674  for(long i=0;i<this->GetNbPar();i++)
1675  if(this->GetPar(i).GetType()->IsDescendantFromOrSameAs(type))
1676  this->GetPar(i).SetGlobalOptimStep(step);
1677  for(int i=0;i<this->GetSubObjRegistry().GetNb();i++)
1678  this->GetSubObjRegistry().GetObj(i).SetGlobalOptimStep(type,step);
1679 }
1680 
1681 ObjRegistry<RefinableObj>& RefinableObj::GetSubObjRegistry()
1682 {return mSubObjRegistry;}
1683 
1684 const ObjRegistry<RefinableObj>& RefinableObj::GetSubObjRegistry()const
1685 {return mSubObjRegistry;}
1686 
1687 void RefinableObj::RegisterClient(RefinableObj &obj)const
1688 {mClientObjRegistry.Register(obj);}
1689 
1690 void RefinableObj::DeRegisterClient(RefinableObj &obj)const
1691 {mClientObjRegistry.DeRegister(obj);}
1692 
1693 const ObjRegistry<RefinableObj>& RefinableObj::GetClientRegistry()const{return mClientObjRegistry;}
1694  ObjRegistry<RefinableObj>& RefinableObj::GetClientRegistry() {return mClientObjRegistry;}
1695 
1696 bool RefinableObj::IsBeingRefined()const {return mOptimizationDepth>0;}
1697 
1698 extern const long ID_WXOBJ_ENABLE; //These are defined in wxCryst/wxCryst.cpp
1699 extern const long ID_WXOBJ_DISABLE;
1700 void RefinableObj::BeginOptimization(const bool allowApproximations,
1701  const bool enableRestraints)
1702 {
1703  mOptimizationDepth++;
1704  if(mOptimizationDepth>1) return;
1705  this->Prepare();
1706  for(int i=0;i<mSubObjRegistry.GetNb();i++)
1707  mSubObjRegistry.GetObj(i).BeginOptimization(allowApproximations);
1708  #ifdef __WX__CRYST__
1709  if(0!=mpWXCrystObj)
1710  {
1711  if(true==wxThread::IsMain()) mpWXCrystObj->Enable(false);
1712  else
1713  {
1714  wxUpdateUIEvent event(ID_WXOBJ_DISABLE);
1715  wxPostEvent(mpWXCrystObj,event);
1716  }
1717  }
1718  #endif
1719 }
1720 
1721 void RefinableObj::EndOptimization()
1722 {
1723  mOptimizationDepth--;
1724  if(mOptimizationDepth<0) throw ObjCrystException("RefinableObj::EndOptimization(): mOptimizationDepth<0 !!");
1725 
1726  if(mOptimizationDepth>0) return;
1727  for(int i=0;i<mSubObjRegistry.GetNb();i++)
1728  mSubObjRegistry.GetObj(i).EndOptimization();
1729  #ifdef __WX__CRYST__
1730  if(0!=mpWXCrystObj)
1731  {
1732  if(true==wxThread::IsMain()) mpWXCrystObj->Enable(true);
1733  else
1734  {
1735  wxUpdateUIEvent event(ID_WXOBJ_ENABLE);
1736  wxPostEvent(mpWXCrystObj,event);
1737  }
1738  }
1739  #endif
1740 }
1741 
1742 void RefinableObj::SetApproximationFlag(const bool allow)
1743 {
1744 for(int i=0;i<mSubObjRegistry.GetNb();i++)
1745  mSubObjRegistry.GetObj(i).SetApproximationFlag(allow);
1746 }
1747 
1748 void RefinableObj::RandomizeConfiguration()
1749 {
1750  VFN_DEBUG_ENTRY("RefinableObj::RandomizeConfiguration():"<<mName,5)
1751  this->PrepareForRefinement();
1752  for(int j=0;j<this->GetNbParNotFixed();j++)
1753  {
1754  if(true==this->GetParNotFixed(j).IsLimited())
1755  {
1756  const REAL min=this->GetParNotFixed(j).GetMin();
1757  const REAL max=this->GetParNotFixed(j).GetMax();
1758  this->GetParNotFixed(j).MutateTo(min+(max-min)*(rand()/(REAL)RAND_MAX) );
1759  }
1760  else
1761  if(true==this->GetParNotFixed(j).IsPeriodic())
1762  {
1763 
1764  this->GetParNotFixed(j).MutateTo((rand()/(REAL)RAND_MAX)
1765  * this->GetParNotFixed(j).GetPeriod());
1766  }
1767  }
1768  for(int i=0;i<this->GetSubObjRegistry().GetNb();i++)
1769  this->GetSubObjRegistry().GetObj(i).RandomizeConfiguration();
1770  VFN_DEBUG_EXIT("RefinableObj::RandomizeConfiguration():Finished",5)
1771 }
1772 
1773 void RefinableObj::GlobalOptRandomMove(const REAL mutationAmplitude,
1774  const RefParType *type)
1775 {
1776  if(mRandomMoveIsDone) return;
1777  VFN_DEBUG_ENTRY("RefinableObj::GlobalOptRandomMove()",2)
1778  for(int j=0;j<this->GetNbParNotFixed();j++)
1779  {
1780  if(this->GetParNotFixed(j).GetType()->IsDescendantFromOrSameAs(type))
1781  this->GetParNotFixed(j).Mutate( this->GetParNotFixed(j).GetGlobalOptimStep()
1782  *2*(rand()/(REAL)RAND_MAX-0.5)*mutationAmplitude);
1783  }
1784  for(int i=0;i<mSubObjRegistry.GetNb();i++)
1785  mSubObjRegistry.GetObj(i).GlobalOptRandomMove(mutationAmplitude,type);
1786  mRandomMoveIsDone=true;
1787  VFN_DEBUG_EXIT("RefinableObj::GlobalOptRandomMove()",2)
1788 }
1789 void RefinableObj::BeginGlobalOptRandomMove()
1790 {
1791  mRandomMoveIsDone=false;
1792  for(int i=0;i<mSubObjRegistry.GetNb();i++)
1793  mSubObjRegistry.GetObj(i).BeginGlobalOptRandomMove();
1794 }
1795 
1796 unsigned int RefinableObj::GetNbLSQFunction()const{return 0;}
1797 
1798 REAL RefinableObj::GetLogLikelihood()const
1799 {
1800  VFN_DEBUG_ENTRY("RefinableObj::GetLogLikelihood()",3)
1801  if(0==mvpRestraint.size())
1802  {
1803  VFN_DEBUG_EXIT("RefinableObj::GetLogLikelihood()=0",3)
1804  return 0;
1805  }
1806  VFN_DEBUG_MESSAGE("RefinableObj::GetLogLikelihood()there are restraints...",2)
1807  REAL loglike=0;
1808  vector< Restraint * >::const_iterator pos;
1809  for(pos=mvpRestraint.begin();pos!=mvpRestraint.end();pos++)
1810  {
1811  VFN_DEBUG_MESSAGE("RefinableObj::GetLogLikelihood()Restraint: "<<*pos,2)
1812  loglike+= (*pos)->GetLogLikelihood();
1813  }
1814  VFN_DEBUG_EXIT("RefinableObj::GetLogLikelihood()="<<loglike,3)
1815  return loglike;
1816 }
1817 
1818 // std::map<RefinablePar*, REAL>& RefinableObj::GetLogLikelihood_FullDeriv(std::set<RefinablePar *> &vPar)
1819 // {
1820 // //TODO
1821 // return mLogLikelihood_FullDeriv;
1822 // }
1823 
1824 const CrystVector_REAL& RefinableObj::GetLSQCalc(const unsigned int) const
1825 {
1826  throw ObjCrystException("Error: called RefinableObj::GetLSQCalc()");
1827  CrystVector_REAL *noWarning=new CrystVector_REAL;
1828  return *noWarning;
1829 }
1830 
1831 const CrystVector_REAL& RefinableObj::GetLSQObs(const unsigned int) const
1832 {
1833  throw ObjCrystException("Error: called RefinableObj::GetLSQObs()");
1834  CrystVector_REAL *noWarning=new CrystVector_REAL;
1835  return *noWarning;
1836 }
1837 
1838 const CrystVector_REAL& RefinableObj::GetLSQWeight(const unsigned int) const
1839 {
1840  throw ObjCrystException("Error: called RefinableObj::GetLSQWeight()");
1841  CrystVector_REAL *noWarning=new CrystVector_REAL;
1842  return *noWarning;
1843 }
1844 
1845 const CrystVector_REAL& RefinableObj::GetLSQDeriv(const unsigned int n, RefinablePar&par)
1846 {
1847  // By default, use numerical derivatives
1848  const REAL step=par.GetDerivStep();
1849  par.Mutate(step);
1850  mLSQDeriv =this->GetLSQCalc(n);
1851  par.Mutate(-2*step);
1852  mLSQDeriv -=this->GetLSQCalc(n);
1853  par.Mutate(step);
1854  mLSQDeriv /= step*2;
1855  return mLSQDeriv;
1856 }
1857 
1858 std::map<RefinablePar*, CrystVector_REAL> & RefinableObj::GetLSQ_FullDeriv(const unsigned int n,std::set<RefinablePar *> &vPar)
1859 {
1860  mLSQ_FullDeriv[n].clear();
1861  mLSQ_FullDeriv[n][(RefinablePar*)0]=this->GetLSQCalc(n);
1862  for(std::set<RefinablePar *>::const_iterator pos=vPar.begin();pos!=vPar.end();pos++)
1863  mLSQ_FullDeriv[n][*pos]=this->GetLSQDeriv(n,**pos);
1864 
1865  return mLSQ_FullDeriv[n];
1866 }
1867 
1868 void RefinableObj::ResetParList()
1869 {
1870  VFN_DEBUG_MESSAGE("RefinableObj::ResetParList()",3)
1871  if(mvpRefPar.size()>0)
1872  {
1873  if(true==mDeleteRefParInDestructor)
1874  {
1875  vector<RefinablePar*>::iterator pos;
1876  for(pos=mvpRefPar.begin();pos!=mvpRefPar.end();pos++) delete *pos;
1877  }
1878  mvpRefPar.clear();
1879  }
1880  mNbRefParNotFixed=-1;
1881 
1882  VFN_DEBUG_MESSAGE("RefinableObj::ResetParList():Deleting Saved Sets....",2)
1883  this->EraseAllParamSet();
1884  mRefParListClock.Click();
1885  VFN_DEBUG_MESSAGE("RefinableObj::ResetParList():End.",3)
1886 }
1887 
1888 ObjRegistry<RefObjOpt>& RefinableObj::GetOptionList()
1889 {
1890  return mOptionRegistry;
1891 }
1892 
1893 unsigned int RefinableObj::GetNbOption()const
1894 {
1895  return mOptionRegistry.GetNb();
1896 }
1897 
1898 RefObjOpt& RefinableObj::GetOption(const unsigned int i)
1899 {
1900  VFN_DEBUG_MESSAGE("RefinableObj::GetOption()"<<i,3)
1901  //:TODO: Check
1902  return mOptionRegistry.GetObj(i);
1903 }
1904 
1905 RefObjOpt& RefinableObj::GetOption(const string & name)
1906 {
1907  VFN_DEBUG_MESSAGE("RefinableObj::GetOption()"<<name,3)
1908  const long i=mOptionRegistry.Find(name);
1909  if(i<0)
1910  {
1911  this->Print();
1912  throw ObjCrystException("RefinableObj::GetOption(): cannot find option: "+name+" in object:"+this->GetName());
1913  }
1914  return mOptionRegistry.GetObj(i);
1915 }
1916 
1917 const RefObjOpt& RefinableObj::GetOption(const unsigned int i)const
1918 {
1919  //:TODO: Check
1920  return mOptionRegistry.GetObj(i);
1921 }
1922 
1923 const RefObjOpt& RefinableObj::GetOption(const string & name)const
1924 {
1925  VFN_DEBUG_MESSAGE("RefinableObj::GetOption()"<<name,3)
1926  const long i=mOptionRegistry.Find(name);
1927  if(i<0)
1928  {
1929  this->Print();
1930  throw ObjCrystException("RefinableObj::GetOption(): cannot find option: "+name+" in object:"+this->GetName());
1931  }
1932  return mOptionRegistry.GetObj(i);
1933 }
1934 
1935 void RefinableObj::GetGeneGroup(const RefinableObj &obj,
1936  CrystVector_uint & groupIndex,
1937  unsigned int &first) const
1938 {
1939  VFN_DEBUG_MESSAGE("RefinableObj::GetGeneGroup()",4)
1940  for(long i=0;i<obj.GetNbPar();i++)
1941  for(long j=0;j<this->GetNbPar();j++)
1942  if(&(obj.GetPar(i)) == &(this->GetPar(j))) groupIndex(i)= first++;
1943 }
1944 void RefinableObj::SetDeleteRefParInDestructor(const bool b) {mDeleteRefParInDestructor=b;}
1945 
1946 const RefinableObjClock& RefinableObj::GetRefParListClock()const{return mRefParListClock;}
1947 
1948 REAL RefinableObj::GetRestraintCost()const
1949 {
1950  vector<Restraint*>::const_iterator pos;
1951  REAL cost(0);
1952  for(pos=mvpRestraint.begin();pos != mvpRestraint.end();++pos)
1953  cost += (*pos)->GetLogLikelihood();
1954  return 0;
1955 }
1956 
1957 void RefinableObj::AddRestraint(Restraint *pNewRestraint)
1958 {
1959  VFN_DEBUG_MESSAGE("RefinableObj::AddRestraint(Restraint*)",2)
1960  mvpRestraint.push_back(pNewRestraint);
1961 }
1962 
1963 vector<Restraint*>::iterator RefinableObj::RemoveRestraint(Restraint *pRestraint)
1964 {
1965  VFN_DEBUG_MESSAGE("RefinableObj::RemoveRestraint(Restraint*)",2)
1966  vector<Restraint*>::iterator pos=find(mvpRestraint.begin(),mvpRestraint.end(),pRestraint);
1967  if(mvpRestraint.end() != pos)
1968  {
1969  return mvpRestraint.erase(pos);
1970  }
1971  else
1972  {
1973  cout <<"RefinableObj::RemoveRestraint(..)"
1974  <<" Whoops... tried to remove a Restraint which does not exist..."<<endl;
1975  }
1976  return pos;
1977 }
1978 
1979 void RefinableObj::TagNewBestConfig()const
1980 {
1981 }
1982 const RefinableObjClock& RefinableObj::GetClockMaster()const{return mClockMaster;}
1983 
1984 size_t RefinableObj::int_ptr() const {return (size_t)this;}
1985 
1986 void RefinableObj::UpdateDisplay()const
1987 {
1988  #ifdef __WX__CRYST__
1989  VFN_DEBUG_ENTRY("RefinableObj::UpdateDisplay()",3)
1990  if(0!=mpWXCrystObj) mpWXCrystObj->CrystUpdate(true,true);
1991  VFN_DEBUG_EXIT("RefinableObj::UpdateDisplay()",3)
1992  #endif
1993 }
1994 
1995 long RefinableObj::FindPar(const string &name) const
1996 {
1997  long index=-1;
1998  bool warning=false;
1999  for(long i=this->GetNbPar()-1;i>=0;i--)
2000  if( this->GetPar(i).GetName() == name)
2001  {
2002  if(-1 != index) warning=true ;else index=i;
2003  }
2004  if(true == warning)
2005  {
2006  throw ObjCrystException("RefinableObj::FindPar("+name+"): found duplicate refinable variable name in object:"+this->GetName());
2007  }
2008  return index;
2009 }
2010 
2011 long RefinableObj::FindPar(const REAL *p) const
2012 {
2013  long index=-1;
2014  bool warning=false;
2015  for(long i=this->GetNbPar()-1;i>=0;i--)
2016  if( p == mvpRefPar[i]->mpValue ) //&(this->GetPar(i).GetValue())
2017  {
2018  if(-1 != index) warning=true ;else index=i;
2019  }
2020  if(true == warning)
2021  {
2022  throw ObjCrystException("RefinableObj::FindPar(*p): Found duplicate parameter in object:"+this->GetName());
2023  }
2024 
2025  return index;
2026 }
2027 
2028 void RefinableObj::AddSubRefObj(RefinableObj &obj)
2029 {
2030  VFN_DEBUG_MESSAGE("RefinableObj::AddSubRefObj()",3)
2031  mSubObjRegistry.Register(obj);
2032  mClockMaster.AddChild(obj.GetClockMaster());
2033 }
2034 
2035 void RefinableObj::RemoveSubRefObj(RefinableObj &obj)
2036 {
2037  VFN_DEBUG_MESSAGE("RefinableObj::RemoveSubRefObj()",3)
2038  mSubObjRegistry.DeRegister(obj);
2039  mClockMaster.RemoveChild(obj.GetClockMaster());
2040 }
2041 
2042 void RefinableObj::AddOption(RefObjOpt *opt)
2043 {
2044  VFN_DEBUG_MESSAGE("RefinableObj::AddOption()",5)
2045  //:TODO: automagically resize the option array if necessary
2046  mOptionRegistry.Register(*opt);
2047  mClockMaster.AddChild(opt->GetClock());
2048  VFN_DEBUG_MESSAGE("RefinableObj::AddOption():End",5)
2049 }
2050 
2051 void RefinableObj::Prepare()
2052 {
2053  VFN_DEBUG_MESSAGE("RefinableObj::Prepare()",5)
2054  for(int i=0;i<this->GetSubObjRegistry().GetNb();i++)
2055  this->GetSubObjRegistry().GetObj(i).Prepare();
2056 }
2057 
2058 map<unsigned long,pair<CrystVector_REAL,string> >::iterator
2059  RefinableObj:: FindParamSet(const unsigned long id)const
2060 {
2061  VFN_DEBUG_ENTRY("RefinableObj::FindParamSet()",2)
2062  map<unsigned long,pair<CrystVector_REAL,string> >::iterator pos;
2063  pos=mvpSavedValuesSet.find(id);
2064  if(mvpSavedValuesSet.end() == pos)
2065  {//throw up
2066  throw ObjCrystException("RefinableObj::FindParamSet(long): Unknown saved set ! In object:"+this->GetName());
2067  }
2068  VFN_DEBUG_EXIT("RefinableObj::FindParamSet()",2)
2069  return pos;
2070 }
2071 
2072 #ifdef __WX__CRYST__
2073 WXCrystObjBasic* RefinableObj::WXCreate(wxWindow *parent)
2074 {
2075  VFN_DEBUG_MESSAGE("RefinableObj::WXCreate()",8)
2076  mpWXCrystObj=new WXRefinableObj (parent,this);
2077  return mpWXCrystObj;
2078 }
2079 WXCrystObjBasic* RefinableObj::WXGet()
2080 {
2081  return mpWXCrystObj;
2082 }
2083 void RefinableObj::WXDelete()
2084 {
2085  if(0!=mpWXCrystObj)
2086  {
2087  VFN_DEBUG_MESSAGE("RefinableObj::WXDelete()",5)
2088  delete mpWXCrystObj;
2089  }
2090  mpWXCrystObj=0;
2091 }
2092 void RefinableObj::WXNotifyDelete()
2093 {
2094  VFN_DEBUG_MESSAGE("RefinableObj::WXNotifyDelete():"<<mName,5)
2095  mpWXCrystObj=0;
2096 }
2097 #endif
2098 //######################################################################
2099 // function GetRefParListClockRecursive
2100 //######################################################################
2101 
2102 void GetRefParListClockRecursive(ObjRegistry<RefinableObj> &reg,RefinableObjClock &clock)
2103 {
2104  for(int i=0;i<reg.GetNb();i++)
2105  {
2106  if(reg.GetObj(i).GetRefParListClock()>clock)
2107  clock=reg.GetObj(i).GetRefParListClock();
2108  GetRefParListClockRecursive(reg.GetObj(i).GetSubObjRegistry(),clock);
2109  }
2110 }
2111 
2112 //***********EXPLICIT INSTANTIATION*******************//
2113 template void RefObjRegisterRecursive(RefinableObj &obj,ObjRegistry<RefinableObj> &reg);
2114 }//namespace
2115 #include "ObjCryst/ObjCryst/Crystal.h"
2116 #include "ObjCryst/ObjCryst/Scatterer.h"
2117 #include "ObjCryst/ObjCryst/ScatteringPower.h"
2118 #include "ObjCryst/ObjCryst/ZScatterer.h"
2119 #include "ObjCryst/ObjCryst/PowderPattern.h"
2120 #include "ObjCryst/ObjCryst/DiffractionDataSingleCrystal.h"
2121 #include "ObjCryst/ObjCryst/ScatteringCorr.h"
2122 #include "ObjCryst/RefinableObj/GlobalOptimObj.h"
2123 #include "ObjCryst/RefinableObj/IO.h"
2124 #include "ObjCryst/ObjCryst/ReflectionProfile.h"
2125 
2126 namespace ObjCryst {
2127 
2128 template class ObjRegistry<RefObjOpt>;
2129 template class ObjRegistry<RefinableObj>;
2130 template class ObjRegistry<Crystal>;
2131 template class ObjRegistry<Scatterer>;
2132 template class ObjRegistry<ScatteringPower>;
2133 template class ObjRegistry<ScatteringPowerAtom>;
2134 template class ObjRegistry<PowderPattern>;
2135 template class ObjRegistry<PowderPatternComponent>;
2136 template class ObjRegistry<DiffractionDataSingleCrystal>;
2137 template class ObjRegistry<OptimizationObj>;
2138 //template class ObjRegistry<IOCrystTag>;//to be removed
2139 template class ObjRegistry<XMLCrystTag>;
2140 template class ObjRegistry<ZAtom>;
2141 template class ObjRegistry<TexturePhaseMarchDollase>;
2142 template class ObjRegistry<TextureEllipsoid>;
2143 template class ObjRegistry<ReflectionProfile>;
2144 
2145 template class RefObjOption<RefinableObj>;
2146 template class RefObjOption<Crystal>;
2147 template class RefObjOption<Radiation>;
2148 template class RefObjOption<Scatterer>;
2149 template class RefObjOption<ScatteringPower>;
2150 template class RefObjOption<ScatteringPowerAtom>;
2151 template class RefObjOption<PowderPattern>;
2152 template class RefObjOption<PowderPatternComponent>;
2153 template class RefObjOption<PowderPatternBackground>;
2154 template class RefObjOption<DiffractionDataSingleCrystal>;
2155 template class RefObjOption<PowderPatternDiffraction>;
2156 //template class RefObjOption<GlobalOptimObj>;
2157 //template class RefObjOption<IOCrystTag>;
2158 
2159 } // namespace ObjCryst
The namespace which includes all objects (crystallographic and algorithmic) in ObjCryst++.
Definition: doc-main.h:25
const RefParType * gpRefParTypeObjCryst
Top RefParType for the ObjCryst++ library.
RefParDerivStepModel
How do we compute steps h for numerical derivative calculation : d=f(x+h)-f(x-h)/h/2 either h is fixe...
Definition: RefinableObj.h:56
Exception class for ObjCryst++ library.
Definition: General.h:122
class of refinable parameter types.
Definition: RefinableObj.h:80
RefParType(const string &name)
Create a top parameter type.
~RefParType()
Destructor.
void InitId()
Get a Unique id (RefParType::mId)
bool operator==(const RefParType *parent) const
returns true if the two types are the same.
const string & GetName() const
Get the name for this parameter.
unsigned long mId
The unique number identifying this type.
Definition: RefinableObj.h:103
const RefParType * mpParent
the parent for this RefParType (we could easily allow several...)
Definition: RefinableObj.h:99
bool IsDescendantFromOrSameAs(const RefParType *type) const
Returns true if the parameter is a descendant of 'type'.
const string mName
The name/description for this parameter type.
Definition: RefinableObj.h:101
We need to record exactly when refinable objects have been modified for the last time (to avoid re-co...
Definition: RefinableObj.h:140
std::set< RefinableObjClock * > mvParent
List of parent clocks, which will be clicked whenever this one is.
Definition: RefinableObj.h:180
void Reset()
Reset a Clock to 0, to force an update.
void Print() const
Print clock value. Only for debugging purposes.
std::set< const RefinableObjClock * > mvChild
List of 'child' clocks, which will click this clock whenever they are clicked.
Definition: RefinableObj.h:176
void AddChild(const RefinableObjClock &)
Add a 'child' clock.
void AddParent(RefinableObjClock &) const
Add a 'parent' clock.
void RemoveChild(const RefinableObjClock &)
remove a child clock. This also tells the child clock to remove the parent.
void RemoveParent(RefinableObjClock &) const
remove a parent clock
void operator=(const RefinableObjClock &rhs)
This will (i) set the clock to the same values as the rhs clock, but will not change the list of chil...
void Click()
Record an event for this clock (generally, the 'time' an object has been modified,...
void PrintStatic() const
Print current general clock value. Only for debugging purposes.
Restraint: generic class for a restraint of a given model.
Definition: RefinableObj.h:201
virtual REAL GetLogLikelihood() const
Get -ln(likelihood) for this restraint.
Restraint()
Default constructor, sets RefParType to gpRefParTypeObjCryst.
Generic class for parameters of refinable objects.
Definition: RefinableObj.h:225
void SetHumanScale(const REAL)
Human scale for this parameter : for angles, this is equal to 180/pi.
REAL GetDerivStep() const
Fixed step to use to compute numerical derivative.
REAL mDerivStep
Step to use for numerical derivative calculation.
Definition: RefinableObj.h:509
REAL GetHumanMin() const
Get the minimum value allowed (if limited)
bool mIsPeriodic
Is the parameter periodic ? If this is the case, then when using the RefinablePar::Mutate() function,...
Definition: RefinableObj.h:503
REAL mHumanScale
Scale to be used to display 'human' value.
Definition: RefinableObj.h:517
string GetName() const
Get the parameter's name.
REAL mMin
Hard lower and upper limits.
Definition: RefinableObj.h:493
void SetDerivStep(const REAL)
Fixed step to use to compute numerical derivative.
bool mHasAssignedClock
Is there a clock associated with this parameter ? If yes, then it must Click() it each time it is mod...
Definition: RefinableObj.h:533
void SetMax(const REAL)
Get the maximum value allowed (if limited)
REAL GetMin() const
Minimum value allowed (if limited or periodic)
REAL mGlobalOptimStep
Step to use for global method search (simulated annealing,...)
Definition: RefinableObj.h:507
void Click()
Click the Clock ! to telle the RefinableObj it has been modified.
REAL GetHumanScale() const
Human scale for this parameter : for angles, this is equal to 180/pi.
REAL GetValue() const
of the parameter.
void SetValue(const REAL value)
of the parameter.
void CopyAttributes(const RefinablePar &)
Copy all attributes (limits, flags, etc...) from another RefinablePar object.
void Init(const string &name, REAL *refPar, const REAL min, const REAL max, const RefParType *type, RefParDerivStepModel derivMode=REFPAR_DERIV_STEP_RELATIVE, const bool hasLimits=true, const bool isFixed=false, const bool isUsed=true, const bool isPeriodic=false, const REAL humanScale=1., REAL period=1.)
Constructor.
const REAL * GetPointer() const
Access to a const pointer to the refined value.
void MutateTo(const REAL newValue)
Change the current value to the given one.
void SetHumanValue(const REAL &)
Current value of parameter, scaled if necessary (for angles) to a human-understandable value.
void SetMin(const REAL)
Set the Minimum value allowed (if limited)
bool mHasLimits
Does the refinable parameter need limits (min and max) ?
Definition: RefinableObj.h:495
REAL * mpValue
Pointer to the refinable value.
Definition: RefinableObj.h:491
REAL mSigma
Calculated sigma on value.
Definition: RefinableObj.h:513
void SetPeriod(const REAL)
Set the period value (if periodic)
bool mIsUsed
Is the parameter currently used ?
Definition: RefinableObj.h:499
REAL GetHumanMax() const
Get the maximum value allowed (if limited)
void SetGlobalOptimStep(const REAL)
Maximum step to use during Global Optimization algorithms.
void SetLimitsAbsolute(const REAL min, const REAL max)
Change the limits for this object, giving absolute new limits.
bool IsUsed() const
Is the parameter used (if not, it is simply irrelevant in the model) ?
void AssignClock(RefinableObjClock &clock)
REAL GetMax() const
Get the maximum value allowed (if limited)
const REAL & GetHumanValue() const
Current value of parameter, scaled if necessary (for angles) to a human-understandable value.
void Mutate(const REAL mutateValue)
Add the given amount to the parameter current value.
void SetName(const string &)
Set the name of the parameter. It should be unique in the RefinableObj.
bool mIsFixed
is the parameter currently fixed ?
Definition: RefinableObj.h:497
void SetLimitsRelative(const REAL min, const REAL max)
Change the limits for this object, giving relative new limits (eg giving -.1 and +....
void SetHumanMin(const REAL)
Set the minimum value allowed (if limited)
RefParDerivStepModel mRefParDerivStepModel
Model followed for derivation.
Definition: RefinableObj.h:511
void SetHumanMax(const REAL)
Get the maximum value allowed (if limited)
REAL mPeriod
Period value (if relevant)
Definition: RefinableObj.h:505
RefinablePar()
Default Constructor.
REAL GetGlobalOptimStep() const
Maximum step to use during Global Optimization algorithms.
void SetIsUsed(const bool)
Is the parameter used (if not, it is simply irrelevant in the model) ?
REAL GetPeriod() const
Get the period (if periodic)
void SetLimitsProportional(const REAL min, const REAL max)
Change the limits for this object, proportionnaly to the current value.
string mName
name of the refinable parameter
Definition: RefinableObj.h:489
RefObjOpt()
Constructor for the option.
Class for options of RefinableObj, templated so that we can warn the object that something has been c...
Definition: RefinableObj.h:608
RefObjOption(T *obj)
Constructor for the option.
Object Registry.
Definition: RefinableObj.h:645
void DeRegisterAll()
De-register all objects from the list.
void DeRegister(T &obj)
De-register an object.
T & GetObj(const unsigned int i)
Get object #i in the registry.
long GetNb() const
Get the index of an object in the registry, from its name Warning: it can change if an object is remo...
void Register(T &obj)
Register a new object. Already registered objects are skipped.
void DeleteAll()
Delete all objects in the registry.. Use with caution !!
Abstract base class for all objects in wxCryst.
Definition: wxCryst.h:128
A field for a RefinablePar.