FOX/ObjCryst++  1.10.X (development)
wxGlobalOptimObj.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 //#include <sstream> //for stringstream
20 #include <fstream>
21 
22 // wx headers, with or without precompilation
23 #include "wx/wxprec.h"
24 #ifdef __BORLANDC__
25  #pragma hdrstop
26 #endif
27 #ifndef WX_PRECOMP
28  #include "wx/wx.h"
29 #endif
30 
31 #include "wx/progdlg.h"
32 
33 #include "ObjCryst/wxCryst/wxGlobalOptimObj.h"
34 
35 #include "ObjCryst/ObjCryst/IO.h"
36 // Next two just to fix some parameters during global optimization
37 #include "ObjCryst/ObjCryst/Crystal.h"
38 #include "ObjCryst/ObjCryst/ScatteringData.h"
39 
40 //Fixes for Cygwin; where do those stupid macros come from ? Somewhere in wxMSW headers
41 #ifdef max
42 #undef max
43 #endif
44 #ifdef min
45 #undef min
46 #endif
47 #ifdef DrawText
48 #undef DrawText
49 #endif
50 
51 namespace ObjCryst
52 {
53 
55 //
56 // WXOptimizationObj
57 //
59 static long ID_GLOBALOPT_MENU_OBJECTS= WXCRYST_ID();
60 static long ID_GLOBALOPT_MENU_OBJECTS_ADDOBJ= WXCRYST_ID();
61 static long ID_GLOBALOPT_MENU_OBJECTS_REMOVEOBJ= WXCRYST_ID();
62 static long ID_GLOBALOPT_MENU_OBJECTS_ADDCOSTFUNC= WXCRYST_ID();
63 static long ID_GLOBALOPT_MENU_OBJECTS_REMOVECOSTFUNC=WXCRYST_ID();
64 static long ID_GLOBALOPT_MENU_OPT= WXCRYST_ID();
65 static long ID_GLOBALOPT_MENU_OPT_RUN= WXCRYST_ID();
66 static long ID_GLOBALOPT_MENU_OPT_RUN_MULTIPLE= WXCRYST_ID();
67 static long ID_GLOBALOPT_MENU_OPT_STOP= WXCRYST_ID();
68 static long ID_GLOBALOPT_MENU_OPT_LSQ= WXCRYST_ID();
69 static long ID_GLOBALOPT_MENU_SOLUTIONS= WXCRYST_ID();
70 static long ID_GLOBALOPT_MENU_SOLUTIONS_BROWSE= WXCRYST_ID();
71 static long ID_BROWSE_WIN= WXCRYST_ID();
72 
73 WXOptimizationObj::WXOptimizationObj(wxWindow* parent, OptimizationObj *obj):
74 WXCrystObj(parent),mpGlobalOptimRunThread(0)
75 {
76  VFN_DEBUG_ENTRY("WXOptimizationObj::WXOptimizationObj(wxWindow*,GlobalOptimObj*,)",7)
77  #ifdef VFN_CRYST_MUTEX
78  cout <<"new CrystMutex("<<&mMutex<<")for WXOptimizationObj:"<<obj->GetName()<<endl;
79  #endif
80  mpWXTitle->SetForegroundColour(wxColour(255,0,0));
81  mpWXTitle->SetLabel("Global Optimization:");
82  mpWXTitle->SetSize(400,-1);
83  // Menu
84  mpMenuBar=new WXCrystMenuBar(this,this);
85  mpSizer->Add(mpMenuBar);
86  mList.Add(mpMenuBar);
87 
88  //mpMenuBar->AddMenu("Object",ID_REFOBJ_MENU_OBJ);
89  //mpMenuBar->AddMenuItem(ID_REFOBJ_MENU_OBJ,ID_REFOBJ_MENU_OBJ_SAVE,"Save");
90  //mpMenuBar->AddMenuItem(ID_REFOBJ_MENU_OBJ,ID_REFOBJ_MENU_OBJ_LOAD,"Load");
91  mpMenuBar->AddMenu("Optimized Objects",ID_GLOBALOPT_MENU_OBJECTS);
92  mpMenuBar->AddMenuItem(ID_GLOBALOPT_MENU_OBJECTS,ID_GLOBALOPT_MENU_OBJECTS_ADDOBJ,
93  "Add object to optimize");
94  mpMenuBar->AddMenu("Run/Stop",ID_GLOBALOPT_MENU_OPT);
95  mpMenuBar->AddMenuItem(ID_GLOBALOPT_MENU_OPT,
96  ID_GLOBALOPT_MENU_OPT_RUN_MULTIPLE,"Multiple Runs");
97  mpMenuBar->AddMenuItem(ID_GLOBALOPT_MENU_OPT,
98  ID_GLOBALOPT_MENU_OPT_RUN,"Single Run");
99  mpMenuBar->AddMenuItem(ID_GLOBALOPT_MENU_OPT,
100  ID_GLOBALOPT_MENU_OPT_STOP,"Stop Optimization");
101  mpMenuBar->GetMenu(ID_GLOBALOPT_MENU_OPT).AppendSeparator();
102  mpMenuBar->AddMenuItem(ID_GLOBALOPT_MENU_OPT,
103  ID_GLOBALOPT_MENU_OPT_LSQ,"Least Squares Fit");
104  mpMenuBar->AddMenu("Solutions",ID_GLOBALOPT_MENU_SOLUTIONS);
105  mpMenuBar->AddMenuItem(ID_GLOBALOPT_MENU_SOLUTIONS,
106  ID_GLOBALOPT_MENU_SOLUTIONS_BROWSE,"Browse Solutions");
107  mpMenuBar->Layout();
108  //mpSizer->SetItemMinSize(mpMenuBar,
109  // mpMenuBar->GetSize().GetWidth(),
110  // mpMenuBar->GetSize().GetHeight());
111  //Refined Objects
112  for(int i=0;i<obj->mRefinedObjList.GetNb();i++)
113  {
114  WXFieldName *refobj=new WXFieldName(this,"Optimized object:",this,-1,300,false);
115  refobj->SetValue(obj->mRefinedObjList.GetObj(i).GetClassName()
116  +":"+obj->mRefinedObjList.GetObj(i).GetName());
117  mpSizer->Add(refobj);
118  mList.Add(refobj);
119  }
120 
121  // This will be done later
122  //this->CrystUpdate();
123  VFN_DEBUG_EXIT("WXOptimizationObj::WXOptimizationObj(wxWindow*,GlobalOptimObj*,)",7)
124 }
125 
126 void WXOptimizationObj::CrystUpdate(const bool uui,const bool lock)
127 {
128  VFN_DEBUG_ENTRY("WXOptimizationObj::CrystUpdate("<<uui<<lock<<")",7)
129  this->WXCrystObj::CrystUpdate(uui,lock);
130  if(uui)
131  {
132  if(true==wxThread::IsMain()) this->UpdateUI(lock);
133  else
134  {
135  wxUpdateUIEvent event(ID_CRYST_UPDATEUI);
136  wxPostEvent(this,event);
137  }
138  }
139  VFN_DEBUG_EXIT("WXOptimizationObj::CrystUpdate("<<uui<<lock<<")",7)
140 }
141 
143 {
144  VFN_DEBUG_MESSAGE("WXOptimizationObj::OnChangeName()",6)
145  if(id==ID_WXOBJ_NAME)
146  {
147  VFN_DEBUG_MESSAGE("WXOptimizationObj::OnChangeName():Changing GlobalOptimObj Name",6)
148  this->GetOptimizationObj().SetName(mpWXTitle->GetValue());
149  return true;
150  }
151  return false;
152 }
153 void WXOptimizationObj::OnSave(){}
154 
155 void WXOptimizationObj::OnLoad(){}
156 
157 void WXOptimizationObj::OnAddRefinedObject(wxCommandEvent & WXUNUSED(event))
158 {
160  int choice;
161  RefinableObj *obj=
163  "Choose object to optimize:",choice);
164  if(0==obj) return;
165  this->GetOptimizationObj().AddRefinableObj(*obj);
166 }
167 
169 {
171  WXFieldName *refobj=new WXFieldName(this,"Optimized object:",this,-1,300,false);
172  refobj->SetValue(obj.GetClassName()+":"+obj.GetName());
173  mpSizer->Add(refobj);
174  mList.Add(refobj);
175  wxTheApp->GetTopWindow()->Layout();
176  wxTheApp->GetTopWindow()->SendSizeEvent();
177  refobj->UpdateUI(true);
178 }
179 
180 void WXOptimizationObj::OnRemoveRefinedObject(wxCommandEvent & WXUNUSED(event))
181 {
182 }
183 
184 void WXOptimizationObj::OnStopOptimization(wxCommandEvent & WXUNUSED(event))
185 {
186  this->GetOptimizationObj().StopAfterCycle();
187 }
188 void WXOptimizationObj::OnUpdateUI(wxUpdateUIEvent& event)
189 {
190  VFN_DEBUG_ENTRY("WXOptimizationObj::OnUpdateUI()",5)
191  this->UpdateUI(true);
192  event.Skip();
193  VFN_DEBUG_EXIT("WXOptimizationObj::OnUpdateUI()",5)
194 }
195 
196 void WXOptimizationObj::UpdateUI(const bool lock)
197 {
198  VFN_DEBUG_ENTRY("WXOptimizationObj::UpdateUI()",5)
199  if(lock) mMutex.Lock();
200  mpWXTitle->SetValue(this->GetOptimizationObj().GetName());
201  mpWXTitle->UpdateUI(false);
202  this->WXCrystObj::UpdateUI(false);
203  if(lock) mMutex.Unlock();
204  VFN_DEBUG_EXIT("WXOptimizationObj::UpdateUI()",5)
205 }
206 
207 void WXOptimizationObj::OnBrowseParamSet(wxCommandEvent & WXUNUSED(event))
208 {
209  if(this->GetOptimizationObj().IsOptimizing())
210  {
211  wxMessageDialog dumbUser(this,_T("Cannot browse during Optimisation !"),
212  _T("Cannot browse during Optimisation!"),wxOK|wxICON_EXCLAMATION);
213  dumbUser.ShowModal();
214  return;
215  }
216  wxFrame *frame= new wxFrame(this,-1,_T("Stored Configurations"),
217  wxDefaultPosition,wxSize(250,200));
218  const long nb=this->GetOptimizationObj().mvSavedParamSet.size();
219  wxArrayString choices;
220  mpwxParamSetList=new wxListBox(frame, ID_BROWSE_WIN, wxDefaultPosition,
221  wxDefaultSize, choices,
222  wxLB_SINGLE|wxLB_NEEDED_SB, wxDefaultValidator,
223  _T("listBox"));
224  for(int i=0;i<nb;i++)
225  {
226  wxString tmpname=wxString::FromAscii(this->GetOptimizationObj().mRefParList.GetParamSetName
227  (this->GetOptimizationObj().mvSavedParamSet[i].first).c_str());
228  mpwxParamSetList->Append(wxString::Format(_T("%d, cost= %f, %s"),i,
229  this->GetOptimizationObj().mvSavedParamSet[i].second,tmpname.c_str()));
230  }
231  //mpwxParamSetList->SetEventHandler(this);
233  frame->Show(true);
234 }
235 
236 void WXOptimizationObj::OnSelectParamSet(wxCommandEvent &event)
237 {
238 
239  if(this->GetOptimizationObj().IsOptimizing())
240  {
241  wxMessageDialog dumbUser(this,_T("Cannot browse during Optimisation !"),
242  _T("Cannot browse during Optimisation!"),wxOK|wxICON_EXCLAMATION);
243  dumbUser.ShowModal();
244  return;
245  }
246  const long n=event.GetSelection();
247  if(n>=0)
248  {// n=-1 when window is closed ?
249  // Window is alive, check the number of browsable parameters is unchanged
250  if(mpwxParamSetList->GetCount()!=this->GetOptimizationObj().mvSavedParamSet.size())
251  {
252  const long nb=this->GetOptimizationObj().mvSavedParamSet.size();
253  wxArrayString choices;
254  for(int i=0;i<nb;i++)
255  {
256  wxString tmpname=wxString::FromAscii(this->GetOptimizationObj().mRefParList.GetParamSetName
257  (this->GetOptimizationObj().mvSavedParamSet[i].first).c_str());
258  choices.Add(wxString::Format(_T("%d, cost= %f, %s"),i,
259  this->GetOptimizationObj().mvSavedParamSet[i].second,tmpname.c_str()));
260  }
261  mpwxParamSetList->Set(choices);
263  //wxMessageDialog bad(mpwxParamSetList,_T("The list has changed. Updating"),
264  // _T("The list has changed. Updating"),wxOK|wxSTAY_ON_TOP);
265  //bad.ShowModal();
266  return;
267  }
268  if(mClockParamSetWindow>this->GetOptimizationObj().mRefParList.GetRefParListClock())
269  {
270  try
271  {
272  this->GetOptimizationObj().mRefParList
273  .RestoreParamSet(this->GetOptimizationObj().mvSavedParamSet[n].first);
274  }
275  catch(const ObjCrystException &except)
276  {
277  wxMessageDialog bad(this,_T("Impossible ! Model has been altered !"),
278  _T("Impossible ! Model has been altered !"),wxOK|wxICON_EXCLAMATION);
279  mpwxParamSetList->GetParent()->Close();
281  }
282  this->GetOptimizationObj().UpdateDisplay();
283  cout <<"Param set #"<<this->GetOptimizationObj().mvSavedParamSet[n].first<<", cost="
284  <<this->GetOptimizationObj().mvSavedParamSet[n].second
285  <<", now cost="<<this->GetOptimizationObj().GetLogLikelihood()<<endl;
286  }
287  else
288  {
289  wxMessageDialog bad(this,_T("Impossible ! The list of parameters has been changed !"),
290  _T("Impossible ! The list of parameters has been changed !"),wxOK|wxICON_EXCLAMATION);
291  bad.ShowModal();
292  }
293  }
294 }
295 
296 #if 0
297 void WXOptimizationObj::OnClose(wxCloseEvent& event)
298 {
299  if(event.GetId()==ID_BROWSE_WIN)
300  {
301  cout<<"Closing browse window..."<<endl;
303  }
304  else cout<<event.GetId()<<"?"<<endl;
305  event.Skip();
306 }
307 #endif
308 
310 //
311 // WXGlobalOptimRunThread
312 //
314 WXGlobalOptimRunThread::WXGlobalOptimRunThread(OptimizationObj &globalOptObj,long &nbTrial,
315  const REAL finalCost,long &nbRun,const bool multiple):
316 wxThread(wxTHREAD_DETACHED),mpGlobalOptObj(&globalOptObj),mpNbTrial(&nbTrial),mpNbRun(&nbRun),
317 mFinalCost(finalCost),mDoMultiple(multiple)
318 {
319 }
320 
321 void *WXGlobalOptimRunThread::Entry()
322 {
323  cout <<endl<<"Entering refinement thread "<<endl<<endl;
324  try{
325  if(mDoMultiple) mpGlobalOptObj->MultiRunOptimize(*mpNbRun,*mpNbTrial,false,mFinalCost);
326  else mpGlobalOptObj->Optimize(*mpNbTrial,false,mFinalCost);
327  }
328  catch(...){cout<<"Unhandled exception in WXGlobalOptimRunThread::Entry() ?"<<endl;}
329  return NULL;
330 }
331 
332 void WXGlobalOptimRunThread::OnExit()
333 {
334  cout <<endl<<"Exiting refinement thread "<<endl<<endl;
335  XMLCrystFileSaveGlobal("Fox-LastOptimizationStop.xml");
336 }
338 //
339 // WXMonteCarloObj
340 //
342 BEGIN_EVENT_TABLE(WXMonteCarloObj, wxWindow)
343  EVT_BUTTON(ID_WXOBJ_COLLAPSE, WXCrystObj::OnToggleCollapse)
344  //EVT_MENU(ID_REFOBJ_MENU_OBJ_SAVE, WXOptimizationObj::OnSave)
345  //EVT_MENU(ID_REFOBJ_MENU_OBJ_LOAD, WXOptimizationObj::OnLoad)
346  EVT_MENU(ID_GLOBALOPT_MENU_OBJECTS_ADDOBJ, WXOptimizationObj::OnAddRefinedObject)
347  EVT_MENU(ID_GLOBALOPT_MENU_OPT_RUN, WXOptimizationObj::OnRunOptimization)
348  EVT_MENU(ID_GLOBALOPT_MENU_OPT_RUN_MULTIPLE, WXOptimizationObj::OnRunOptimization)
349  EVT_MENU(ID_GLOBALOPT_MENU_OPT_STOP, WXOptimizationObj::OnStopOptimization)
350  EVT_MENU(ID_GLOBALOPT_MENU_OPT_LSQ, WXMonteCarloObj::OnLSQRefine)
351  EVT_MENU(ID_GLOBALOPT_MENU_SOLUTIONS_BROWSE, WXOptimizationObj::OnBrowseParamSet)
352  EVT_UPDATE_UI(ID_CRYST_UPDATEUI, WXOptimizationObj::OnUpdateUI)
353  EVT_LISTBOX(ID_BROWSE_WIN, WXOptimizationObj::OnSelectParamSet)
354  EVT_LISTBOX_DCLICK(ID_BROWSE_WIN, WXOptimizationObj::OnSelectParamSet)
355  //EVT_CLOSE( WXOptimizationObj::OnClose)
356 END_EVENT_TABLE()
357 
358 WXMonteCarloObj::WXMonteCarloObj(wxWindow *parent, MonteCarloObj* obj):
359 WXOptimizationObj(parent,obj),mpMonteCarloObj(obj),mNbRun(-1)
360 {
361  VFN_DEBUG_ENTRY("WXMonteCarloObj::WXMonteCarloObj()",7)
362  //options
363  WXFieldOption *opt;
364 
365  opt=new WXFieldOption(this,-1,&(mpMonteCarloObj->mGlobalOptimType));
366  mpSizer->Add(opt,0,wxALIGN_LEFT);
367  mList.Add(opt);
368 
369  opt=new WXFieldOption(this,-1,&(mpMonteCarloObj->mAnnealingScheduleTemp));
370  mpSizer->Add(opt,0,wxALIGN_LEFT);
371  mList.Add(opt);
372 
373  wxBoxSizer *sizerTemp=new wxBoxSizer(wxHORIZONTAL);
374  WXFieldPar<REAL> *tempMax=
375  new WXFieldPar<REAL>(this,"Temperature Max:",-1,&(mpMonteCarloObj->mTemperatureMax));
376  WXFieldPar<REAL> *tempMin=
377  new WXFieldPar<REAL>(this,"Temperature Min:",-1,&(mpMonteCarloObj->mTemperatureMin));
378  WXFieldPar<REAL> *tempGamma=
379  new WXFieldPar<REAL>(this,"Gamma:",-1,&(mpMonteCarloObj->mTemperatureGamma));
380  sizerTemp->Add(tempMax);
381  sizerTemp->Add(tempMin);
382  sizerTemp->Add(tempGamma);
383  mpSizer->Add(sizerTemp);
384  mList.Add(tempMax);
385  mList.Add(tempMin);
386  mList.Add(tempGamma);
387  tempMax->SetFormat(_T("%8f"));
388  tempMin->SetFormat(_T("%8f"));
389  tempGamma->SetFormat(_T("%8f"));
390 
391  opt=new WXFieldOption(this,-1,&(mpMonteCarloObj->mAnnealingScheduleMutation));
392  mpSizer->Add(opt,0,wxALIGN_LEFT);
393  mList.Add(opt);
394 
395  wxBoxSizer *sizerAmp=new wxBoxSizer(wxHORIZONTAL);
396  WXFieldPar<REAL> *ampMax=
397  new WXFieldPar<REAL>(this,"Amplitude Max:",-1,&(mpMonteCarloObj->mMutationAmplitudeMax));
398  WXFieldPar<REAL> *ampMin=
399  new WXFieldPar<REAL>(this,"Amplitude Min:",-1,&(mpMonteCarloObj->mMutationAmplitudeMin));
400  WXFieldPar<REAL> *ampGamma=
401  new WXFieldPar<REAL>(this,"Gamma:",-1,&(mpMonteCarloObj->mMutationAmplitudeGamma));
402  sizerAmp->Add(ampMax);
403  sizerAmp->Add(ampMin);
404  sizerAmp->Add(ampGamma);
405  mpSizer->Add(sizerAmp);
406  mList.Add(ampMax);
407  mList.Add(ampMin);
408  mList.Add(ampGamma);
409  ampMax->SetFormat(_T("%8f"));
410  ampMin->SetFormat(_T("%8f"));
411  ampGamma->SetFormat(_T("%8f"));
412 
413  opt=new WXFieldOption(this,-1,&(mpMonteCarloObj->mSaveTrackedData));
414  mpSizer->Add(opt,0,wxALIGN_LEFT);
415  mList.Add(opt);
416  opt->SetToolTip(_T("Saved Tracked values (costs, Chi^2, parameters...)\n\n")
417  _T("This is only useful for Test purposes.\n")
418  _T("Data is saved in the file (Name)-Tracker(-Run#).dat"));
419 
420  opt=new WXFieldOption(this,-1,&(mpMonteCarloObj->mXMLAutoSave));
421  mpSizer->Add(opt,0,wxALIGN_LEFT);
422  mList.Add(opt);
423  opt->SetToolTip(_T("Periodically save the best configuration\n\n")
424  _T("Recommended choice is : After Each Run\n")
425  _T("File name is: (name)-(date)-(Run#)-cost.xml\n\n")
426  _T("For Multiple Runs, Note that all choices\n")
427  _T("save the *best* configuration overall, except for\n")
428  _T("'After Each Run', for which the configuration\n")
429  _T("saved are the best for each run."));
430 
431  opt=new WXFieldOption(this,-1,&(mpMonteCarloObj->mAutoLSQ));
432  mpSizer->Add(opt,0,wxALIGN_LEFT);
433  mList.Add(opt);
434  opt->SetToolTip(_T("Least squares refinement can be run:\n\n")
435  _T(" - at the end of each run\n")
436  _T(" - perdiodically during the optimization\n\n")
437  _T(" This allows to find the global minimum\n")
438  _T("much faster\n")
439  _T(" Note that if a LSQ refinement is run but does\n")
440  _T("not reach the real global minimum, the returned\n")
441  _T("structure can be very distorted, but this is\n")
442  _T("harmless (restraints will bring back a correct \n")
443  _T("conformation after a few thousand tests)"));
444 
445  // Number of trials to go
446  mpWXFieldNbTrial=new WXFieldPar<long>(this,"Number of trials per run:",-1,&(mpMonteCarloObj->NbTrialPerRun()),70);
447  mpSizer->Add(mpWXFieldNbTrial);
448  mList.Add(mpWXFieldNbTrial);
449  mpWXFieldNbTrial->SetFormat(_T("%ld"));
450  mpWXFieldNbTrial->SetToolTip(_T("Number of triels per run.\n")
451  _T("This number will be updated during the optimization.\n\n")
452  _T("Using Multiple Runs:\n")
453  _T(" For simple problems (e.g. PbSO4), use 200 000\n")
454  _T(" For larger problems (e.g. Cimetidine), use 2 000 000\n")
455  _T(" For much larger problems, use 10 000 000\n\n")
456  _T("For a single run using Parallel Tempering, use a large number (100 000 000:\n"));
457  // Number of cycles (-1=run indefinitely)
458  WXFieldPar<long> *pWXFieldNbRun=new WXFieldPar<long>(this,"Number of Runs to perform:",-1,&mNbRun,40);
459  mpSizer->Add(pWXFieldNbRun);
460  mList.Add(pWXFieldNbRun);
461  pWXFieldNbRun->SetFormat(_T("%ld"));
462  pWXFieldNbRun->SetToolTip(_T("Number of runs to perform (for Multiple Runs).\n")
463  _T("Use -1 (the default) to run an infinite number of Runs.\n\n")
464  _T("The model will be randomized at the beginning of each run.\n"));
465  // Best cost so far
466  WXFieldPar<REAL> *pWXFieldBestCost=new WXFieldPar<REAL>(this,"Overall Best Cost:",-1,&(mpMonteCarloObj->GetBestCost()),130);
467  mpSizer->Add(pWXFieldBestCost);
468  mList.Add(pWXFieldBestCost);
469  pWXFieldBestCost->SetFormat(_T("%12.2f"));
470  pWXFieldBestCost->SetToolTip(_T("Overall (all runs) Best Cost"));
471  this->CrystUpdate(true);
472  VFN_DEBUG_EXIT("WXMonteCarloObj::WXMonteCarloObj()",7)
473 }
474 
475 void WXMonteCarloObj::OnRunOptimization(wxCommandEvent & event)
476 {
477  VFN_DEBUG_ENTRY("WXMonteCarloObj::OnRunOptimization()",6)
479  if(true==this->GetOptimizationObj().IsOptimizing())
480  {
481  wxMessageDialog dumbUser(this,_T("The optimization is already running !"),_T("Huh ?"),
482  wxOK|wxICON_EXCLAMATION);
483  dumbUser.ShowModal();
484  VFN_DEBUG_EXIT("WXMonteCarloObj::OnRunOptimization()",6)
485  return;
486  }
487 
488  //Fix parameters than really should not be global-optimized
489  mpMonteCarloObj->SetParIsFixed(gpRefParTypeUnitCell,true);
490  mpMonteCarloObj->SetParIsFixed(gpRefParTypeScattDataScale,true);
491  mpMonteCarloObj->SetParIsFixed(gpRefParTypeScattDataProfile,true);
495  mpMonteCarloObj->SetParIsFixed(gpRefParTypeScattDataCorrPos,true);
497  mpMonteCarloObj->SetParIsFixed(gpRefParTypeRadiation,true);
498  mpMonteCarloObj->UpdateDisplay();
499 
500  double finalCost=0;
501  if(mpMonteCarloObj->NbTrialPerRun()<0)
502  {
504  wxTextEntryDialog costDialog(this,_T("Enter desired cost for the optimization to stop"),
505  _T("Goal Cost"),_T(".20"),wxOK | wxCANCEL);
506  if(wxID_OK==costDialog.ShowModal()) costDialog.GetValue().ToDouble(&finalCost);
507  }
508  if(event.GetId()==ID_GLOBALOPT_MENU_OPT_RUN_MULTIPLE)
509  mpGlobalOptimRunThread = new WXGlobalOptimRunThread(this->GetOptimizationObj(),
510  mpMonteCarloObj->NbTrialPerRun(),finalCost,mNbRun,true);
511  else
512  mpGlobalOptimRunThread = new WXGlobalOptimRunThread(this->GetOptimizationObj(),
513  mpMonteCarloObj->NbTrialPerRun(),finalCost,mNbRun,false);
514  // Tracker window
515  if(this->GetOptimizationObj().GetMainTracker().WXGet()==0)
516  {
517  wxFrame *frame= new wxFrame(this,-1,_T("Tracked data"),
518  wxDefaultPosition,wxSize(300,200));
519  wxWindow* pwxTrackerGraph = this->GetOptimizationObj().GetMainTracker().WXCreate(frame);
520 
521  wxSizer *ps=new wxBoxSizer(wxHORIZONTAL);
522  ps->Add(pwxTrackerGraph,1,wxEXPAND);
523  frame->CreateStatusBar(2);
524  frame->SetSizer(ps);
525  frame->SetAutoLayout(true);
526  frame->Show(true);
527  }
528  if(mpGlobalOptimRunThread->Create() != wxTHREAD_NO_ERROR)
529  wxLogError(_T("Can't create optimization thread"));
530  else mpGlobalOptimRunThread->Run();
531 
532  VFN_DEBUG_EXIT("WXMonteCarloObj::OnRunOptimization()",6)
533 }
534 
535 void WXMonteCarloObj::OnLSQRefine(wxCommandEvent &event)
536 {
538  if(true==this->GetOptimizationObj().IsOptimizing())
539  {
540  wxMessageDialog dumbUser(this,_T("An optimization is already running !"),_T("Huh ?"),
541  wxOK|wxICON_EXCLAMATION);
542  dumbUser.ShowModal();
543  return;
544  }
545  char buf[200];
548  mpMonteCarloObj->InitLSQ(true);
549 
550  sprintf(buf,"LSQ: start");
551  REAL cost=mpMonteCarloObj->GetLogLikelihood();
553  wxProgressDialog dlgProgress(_T("Least Squares refinement"),wxString::Format(_T("Least Squares refinement, cycle #%02d/20, Chi^2=%012.2f"),0,cost),
554  19,this,wxPD_AUTO_HIDE|wxPD_ELAPSED_TIME|wxPD_CAN_ABORT);
555  for(unsigned i=0;i<20;++i)
556  {
557  try {mpMonteCarloObj->GetLSQObj().Refine(1,true,false,false);}
558  catch(const ObjCrystException &except){};
560  sprintf(buf,"LSQ: cycle #%02d",i);
563  if(dlgProgress.Update(i,wxString::Format(_T("Least Squares refinement, cycle #%02d/20, Chi^2=%012.2f"),i,cost))==false) break;
564  }
566 }
567 
569 {
570  VFN_DEBUG_MESSAGE("WXMonteCarloObj::UpdateDisplayNbTrial()",5)
571  mMutex.Lock();
572  mList.CrystUpdate(false);
573  mMutex.Unlock();
574  wxUpdateUIEvent event(ID_CRYST_UPDATEUI);
575  wxPostEvent(this,event);
576 }
577 
578 OptimizationObj & WXMonteCarloObj::GetOptimizationObj()
579 {
580  VFN_DEBUG_MESSAGE("WXMonteCarloObj::GetOptimizationObj()",2)
581  return *mpMonteCarloObj;
582 }
583 const OptimizationObj & WXMonteCarloObj::GetOptimizationObj()const
584 {
585  VFN_DEBUG_MESSAGE("WXMonteCarloObj::GetOptimizationObj() const",2)
586  return *mpMonteCarloObj;
587 }
588 
589 
590 }// namespace
591 
void SetName(const string &)
Set the name for this object.
RefinableObjClock mClockParamSetWindow
Record when the window giving the list of recorded parameter set was created.
T * WXDialogChooseFromRegistry(ObjRegistry< T > &reg, wxWindow *parent, const string &message, int &choice)
This function allows to pick up one object in a registry.
void SetValue(const string &)
This actually posts an UpdateUI event, so that it is safe to call it from a non-graphic thread...
Definition: wxCryst.cpp:467
virtual void InitLSQ(const bool useFullPowderPatternProfile=true)
Prepare mLSQ for least-squares refinement during the global optimization.
virtual void MultiRunOptimize(long &nbCycle, long &nbSteps, const bool silent=false, const REAL finalcost=0, const REAL maxTime=-1)=0
Launch optimization for multiple runs of N steps.
void WXCrystValidateAllUserInput()
This function validates all user input (in a WXField) not yet taken into account, if needs be...
Definition: wxCryst.cpp:257
const RefParType * gpRefParTypeScattDataCorrPos
Parameter type for correction to peak positions.
CrystMutex mMutex
Mutex used to lock data when preparing to update the UI in non-main thread.
Definition: wxCryst.h:189
virtual void AddRefinedObject(RefinableObj &obj)
Added by the library.
void AddRefinableObj(RefinableObj &)
Add a refined object. All sub-objects are also added.
void Add(WXCrystObjBasic *)
Add an object to the list.
Definition: wxCryst.cpp:199
virtual void UpdateUI(const bool mutexlock=false)
Update the User Interface, if necessary.
virtual void OnRemoveRefinedObject(wxCommandEvent &WXUNUSED(event))
From the menu.
LSQNumObj & GetLSQObj()
Access to the builtin LSQ optimization object.
long mNbRun
The number of cycles.
void Click()
Record an event for this clock (generally, the 'time' an object has been modified, or some computation has been made)
void SetLabel(const string &)
Change the field's label.
Definition: wxCryst.cpp:285
virtual void Optimize(long &nbSteps, const bool silent=false, const REAL finalcost=0, const REAL maxTime=-1)=0
Launch optimization (a single run) for N steps.
virtual void UpdateUI(const bool mutexlock=false)
Update the User Interface, if necessary.
Definition: wxCryst.cpp:491
wxMenu & GetMenu(const int menuId)
Get access to a menu.
Definition: wxCryst.cpp:922
WXFieldName * mpWXTitle
The title.
Definition: wxCryst.h:273
void UpdateDisplayNbTrial()
Called during optimization, to show the user something's still going on...
A field with the name of a WXCrystObj.
Definition: wxCryst.h:371
const RefParType * gpRefParTypeScattDataProfile
Type for reflection profile.
long * mpNbTrial
This points to OptimizationObj::mNbTrialPerRun.
void CrystUpdate(const bool updateUI=false, const bool mutexlock=false)
Forces all objects in the list to update.
Definition: wxCryst.cpp:223
ObjRegistry< RefinableObj > gTopRefinableObjRegistry("Global Top RefinableObj registry")
This is a special registry for 'top' object for an optimization.
Generic Refinable Object.
Definition: RefinableObj.h:752
WXCrystObjBasicList mList
All windows but the title and collapse button are in this list.
Definition: wxCryst.h:277
const RefParType * gpRefParTypeScattDataScale
Type for scattering data scale factors.
const RefParType * gpRefParTypeScattDataBackground
Parameter type for background intensity.
virtual void OnBrowseParamSet(wxCommandEvent &WXUNUSED(event))
Opens a window where the stored parameter set can be selected.
void AddMenuItem(const int menuId, int id, const string &item, const string &help="", const bool checkable=false)
Add an entry to a menu.
Definition: wxCryst.cpp:928
const REAL mFinalCost
The value of the cost below which the optimization should stop (0 by default) even if the desired num...
MonteCarloObj * mpMonteCarloObj
The algorithm object.
const string GetValue() const
Get the current name.
Definition: wxCryst.cpp:481
void XMLCrystFileSaveGlobal(const string &filename)
Save all Objcryst++ objects.
virtual bool SetForegroundColour(const wxColour &colour)
Change the colour of the field's title.
Definition: wxCryst.cpp:291
wxListBox * mpwxParamSetList
Window giving the list of recorded parameter sets.
void RestoreParamSet(const unsigned long id)
Restore a saved set of values.
RefinableObj mRefParList
The refinable par list used during refinement.
virtual const string & GetClassName() const
Name for this class ("RefinableObj", "Crystal",...).
virtual void OnAddRefinedObject(wxCommandEvent &WXUNUSED(event))
From the menu.
virtual void SetSize(int width, int height)
Change the size of the field (excluding the title)
Definition: wxCryst.cpp:531
long * mpNbRun
This points to the mNbRun member in WXOptimizationObj.
const RefParType * gpRefParTypeScattDataCorrIntAbsorp
Parameter type for absorption correction.
void AddMenu(const string &name, const int menuId, const string &help="")
Add a menu.
Definition: wxCryst.cpp:909
MainTracker & GetMainTracker()
Get the MainTracker.
const RefParType * gpRefParTypeScattDataCorrIntPolar
Parameter type for polarization correction.
virtual bool OnChangeName(const int id)
When a WXFieldName has been changed by the user, it is handled here.
wxBoxSizer * mpSizer
Sizer including all sub-objects.
Definition: wxCryst.h:271
Class for Graphical interface to Monte-Carlo objects (Simulated Annealing, Parallel Tempering) ...
Base object for Optimization methods.
Exception class for ObjCryst++ library.
Definition: General.h:119
void StopAfterCycle()
Stop after the current cycle. USed for interactive refinement.
The namespace which includes all objects (crystallographic and algorithmic) in ObjCryst++.
Definition: Atom.cpp:47
WX Class for a Global Optimization objects.
virtual void EndOptimization()
End optimization for all objects.
virtual const string & GetName() const
Name of the object.
virtual void UpdateUI(const bool mutexlock=false)
Update the User Interface, if necessary.
Definition: wxCryst.cpp:834
const RefParType * gpRefParTypeScattDataCorrIntExtinc
Parameter type for extinction correction.
virtual void CrystUpdate(const bool updateUI=false, const bool mutexlock=false)
Get new values to be displayed from the underlying object, and raise flag if an UI update is necessar...
virtual void BeginOptimization(const bool allowApproximations=false, const bool enableRestraints=false)
Begin optimization for all objects.
virtual void UpdateDisplay()
Update Display (if any display is available), when a new 'relevant' configuration is reached...
const bool mDoMultiple
Use multiple Runs ?
virtual long & NbTrialPerRun()
Number of trial per run.
unsigned long CreateParamSet(const string name="") const
Save the current set of refined values in a new set.
std::vector< pair< long, REAL > > mvSavedParamSet
List of saved parameter sets.
virtual void OnSelectParamSet(wxCommandEvent &WXUNUSED(event))
Restore one parameter set.
virtual void CrystUpdate(const bool updateUI=false, const bool mutexlock=false)
Get new values to be displayed from the underlying object, and raise flag if an UI update is necessar...
Definition: wxCryst.cpp:826
virtual REAL GetLogLikelihood() const
The optimized (minimized, actually) function.
void Refine(int nbCycle=1, bool useLevenbergMarquardt=false, const bool silent=false, const bool callBeginEndOptimization=true, const float minChi2var=0.01)
Do the refinement.
Definition: LSQNumObj.cpp:104