23 #include "cctbx/sgtbx/space_group.h"
26 #include "wx/wxprec.h"
33 #include "wx/dcbuffer.h"
34 #include "wx/config.h"
35 #include "wx/notebook.h"
36 #include "wx/progdlg.h"
37 #include "wx/filename.h"
39 #include "ObjCryst/wxCryst/wxPowderPattern.h"
40 #include "ObjCryst/wxCryst/wxRadiation.h"
41 #include "ObjCryst/RefinableObj/Simplex.h"
42 #include "ObjCryst/RefinableObj/LSQNumObj.h"
43 #include "ObjCryst/ObjCryst/PowderPatternBackgroundBayesianMinimiser.h"
44 #include "ObjCryst/Quirks/VFNStreamFormat.h"
45 #include "ObjCryst/Quirks/Chronometer.h"
67 BEGIN_EVENT_TABLE(WXRadiation, wxWindow)
68 EVT_UPDATE_UI(ID_CRYST_UPDATEUI, WXRadiation::OnUpdateUI)
71 WXRadiation::WXRadiation(wxWindow *parent, Radiation* rad):
72 WXCrystObjBasic(parent),mpRadiation(rad)
74 VFN_DEBUG_ENTRY(
"WXRadiation::WXRadiation()",6)
77 mpSizer=new wxBoxSizer(wxHORIZONTAL);
79 mpFieldRadType= new WXFieldOption(this,-1,&(mpRadiation->mRadiationType));
80 mpSizer->Add(mpFieldRadType,0);
81 mList.Add(mpFieldRadType);
83 mpFieldWavelengthType= new WXFieldOption(this,-1,&(mpRadiation->mWavelengthType));
84 mpSizer->Add(mpFieldWavelengthType,0);
85 mList.Add(mpFieldWavelengthType);
87 WXCrystObjBasic* pFieldWavelength
88 =mpRadiation->GetPar(mpRadiation->mWavelength.data()).WXCreate(this);
89 mpSizer->Add(pFieldWavelength,0);
90 mList.Add(pFieldWavelength);
92 WXFieldPar<REAL> *polarRate=new WXFieldPar<REAL>(this,"Linear Polar Rate:",-1,
93 &(mpRadiation->mLinearPolarRate));
94 mpSizer->Add(polarRate,0,wxALIGN_LEFT);
97 WXFieldPar<REAL> *xRayTubeDlambda=new WXFieldPar<REAL>(this,"Tube-DeltaLambda:",-1,
98 &(mpRadiation->mXRayTubeDeltaLambda));
99 mpSizer->Add(xRayTubeDlambda,0,wxALIGN_LEFT);
100 mList.Add(xRayTubeDlambda);
102 WXFieldPar<REAL> *xRayTubeAlpha2Alpha1=new WXFieldPar<REAL>(this,"Tube-Alpha2/Alpha1:",-1,
103 &(mpRadiation->mXRayTubeAlpha2Alpha1Ratio));
104 mpSizer->Add(xRayTubeAlpha2Alpha1,0,wxALIGN_LEFT);
105 mList.Add(xRayTubeAlpha2Alpha1);
107 this->CrystUpdate(true);
108 this->SetSizer(mpSizer);
109 mpSizer->SetSizeHints(this);
111 VFN_DEBUG_EXIT("WXRadiation::WXRadiation()",6)
113 WXRadiation::~WXRadiation()
115 mpRadiation->WXNotifyDelete();
125 if(
true==wxThread::IsMain()) this->
UpdateUI(lock);
128 wxUpdateUIEvent event(ID_CRYST_UPDATEUI);
129 wxPostEvent(
this,event);
137 void WXRadiation::OnUpdateUI(wxUpdateUIEvent& event)
145 class WXProfileFitting:
public wxWindow
148 WXProfileFitting(wxWindow *parent,PowderPattern *pPattern,PowderPatternDiffraction *pDiff=0);
151 void OnFit(wxCommandEvent &event);
152 void OnExploreSpacegroups(wxCommandEvent &event);
154 PowderPattern *mpPattern;
155 PowderPatternDiffraction *mpDiff;
156 wxCheckListBox *mpFitCheckList;
160 DECLARE_EVENT_TABLE()
168 static const long ID_POWDER_MENU_COMP_ADDBACKGD_BAYESIAN=WXCRYST_ID();
169 static const long ID_POWDER_MENU_COMP_ADDBACKGD= WXCRYST_ID();
170 static const long ID_POWDER_MENU_COMP_ADDCRYST= WXCRYST_ID();
171 static const long ID_POWDER_MENU_GRAPH= WXCRYST_ID();
172 static const long ID_POWDER_MENU_SAVETEXT= WXCRYST_ID();
173 static const long ID_POWDER_MENU_SIMULATE= WXCRYST_ID();
174 static const long ID_POWDER_MENU_EXPORT= WXCRYST_ID();
175 static const long ID_POWDER_MENU_EXPORT_FULLPROF= WXCRYST_ID();
176 static const long ID_POWDER_MENU_IMPORT_FULLPROF= WXCRYST_ID();
177 static const long ID_POWDER_MENU_IMPORT_PSI_DMC= WXCRYST_ID();
178 static const long ID_POWDER_MENU_IMPORT_ILL_D1A5= WXCRYST_ID();
179 static const long ID_POWDER_MENU_IMPORT_XDD= WXCRYST_ID();
180 static const long ID_POWDER_MENU_IMPORT_CPI= WXCRYST_ID();
181 static const long ID_POWDER_MENU_IMPORT_FULLPROF4= WXCRYST_ID();
182 static const long ID_POWDER_MENU_IMPORT_MULTIDETECTORLLBG42=WXCRYST_ID();
183 static const long ID_POWDER_MENU_IMPORT_2THETAOBSSIGMA= WXCRYST_ID();
184 static const long ID_POWDER_MENU_IMPORT_2THETAOBS= WXCRYST_ID();
185 static const long ID_POWDER_MENU_IMPORT_TOFISISXYSIGMA= WXCRYST_ID();
186 static const long ID_POWDER_MENU_IMPORT_GSAS= WXCRYST_ID();
187 static const long ID_POWDER_MENU_IMPORT_CIF= WXCRYST_ID();
188 static const long ID_POWDER_MENU_FITSCALE_R= WXCRYST_ID();
189 static const long ID_POWDER_MENU_FITSCALE_RW= WXCRYST_ID();
190 static const long ID_POWDER_MENU_WAVELENGTH= WXCRYST_ID();
191 static const long ID_POWDER_MENU_WAVELENGTH_XRAY= WXCRYST_ID();
192 static const long ID_POWDER_MENU_WAVELENGTH_NEUTRON= WXCRYST_ID();
193 static const long ID_POWDER_MENU_WAVELENGTH_NEUTRON_TOF= WXCRYST_ID();
194 static const long ID_POWDER_MENU_WAVELENGTH_SET= WXCRYST_ID();
195 static const long ID_POWDER_MENU_WAVELENGTH_SET_AG= WXCRYST_ID();
196 static const long ID_POWDER_MENU_WAVELENGTH_SET_MO= WXCRYST_ID();
197 static const long ID_POWDER_MENU_WAVELENGTH_SET_CU= WXCRYST_ID();
198 static const long ID_POWDER_MENU_WAVELENGTH_SET_FE= WXCRYST_ID();
199 static const long ID_POWDER_MENU_WAVELENGTH_SET_CO= WXCRYST_ID();
200 static const long ID_POWDER_MENU_WAVELENGTH_SET_CR= WXCRYST_ID();
201 static const long ID_POWDER_MENU_WAVELENGTH_SET_AGA1= WXCRYST_ID();
202 static const long ID_POWDER_MENU_WAVELENGTH_SET_MOA1= WXCRYST_ID();
203 static const long ID_POWDER_MENU_WAVELENGTH_SET_CUA1= WXCRYST_ID();
204 static const long ID_POWDER_MENU_WAVELENGTH_SET_FEA1= WXCRYST_ID();
205 static const long ID_POWDER_MENU_WAVELENGTH_SET_COA1= WXCRYST_ID();
206 static const long ID_POWDER_MENU_WAVELENGTH_SET_CRA1= WXCRYST_ID();
207 static const long ID_POWDER_MENU_ADD_2THETA_EXCLUDE= WXCRYST_ID();
208 static const long ID_POWDER_MENU_LEBAIL= WXCRYST_ID();
209 static const long ID_POWDERBACKGROUND_IMPORT= WXCRYST_ID();
210 static const long ID_POWDERBACKGROUND_OPTIMIZEBAYESIAN= WXCRYST_ID();
211 static const long ID_POWDERDIFF_CRYSTAL= WXCRYST_ID();
212 static const long ID_POWDERDIFF_SAVEHKLFCALC= WXCRYST_ID();
213 static const long ID_POWDER_GRAPH_NEW_PATTERN= WXCRYST_ID();
214 static const long ID_POWDERTEXTURE_MENU_ADDPHASE= WXCRYST_ID();
215 static const long ID_POWDERTEXTURE_MENU_DELETEPHASE= WXCRYST_ID();
216 static const long ID_POWDERPATTERN_MENU_COMPONENTS= WXCRYST_ID();
217 static const long ID_POWDERPATTERN_MENU_PATTERN= WXCRYST_ID();
218 static const long ID_POWDERDIFF_PROFILE_DEPV= WXCRYST_ID();
219 static const long ID_POWDER_GRAPH_WIN= WXCRYST_ID();
222 BEGIN_EVENT_TABLE(WXPowderPattern, wxWindow)
223 EVT_BUTTON(ID_WXOBJ_COLLAPSE, WXCrystObj::OnToggleCollapse)
224 EVT_MENU(ID_POWDER_MENU_EXPORT_FULLPROF, WXPowderPattern::OnMenuExport)
225 EVT_MENU(ID_REFOBJ_MENU_OBJ_SAVE, WXRefinableObj::OnMenuSave)
226 EVT_MENU(ID_REFOBJ_MENU_OBJ_LOAD, WXRefinableObj::OnMenuLoad)
227 EVT_MENU(ID_REFOBJ_MENU_PAR_FIXALL, WXRefinableObj::OnMenuFixAllPar)
228 EVT_MENU(ID_REFOBJ_MENU_PAR_UNFIXALL, WXRefinableObj::OnMenuUnFixAllPar)
229 EVT_MENU(ID_POWDER_MENU_COMP_ADDBACKGD, WXPowderPattern::OnMenuAddCompBackgd)
230 EVT_MENU(ID_POWDER_MENU_COMP_ADDBACKGD_BAYESIAN, WXPowderPattern::OnMenuAddCompBackgdBayesian)
231 EVT_MENU(ID_POWDER_MENU_COMP_ADDCRYST, WXPowderPattern::OnMenuAddCompCryst)
232 EVT_MENU(ID_POWDER_MENU_SAVETEXT, WXPowderPattern::OnMenuSaveText)
233 EVT_MENU(ID_POWDER_MENU_SIMULATE, WXPowderPattern::OnMenuSimulate)
234 EVT_MENU(ID_POWDER_MENU_IMPORT_FULLPROF, WXPowderPattern::OnMenuImportPattern)
235 EVT_MENU(ID_POWDER_MENU_IMPORT_PSI_DMC, WXPowderPattern::OnMenuImportPattern)
236 EVT_MENU(ID_POWDER_MENU_IMPORT_ILL_D1A5, WXPowderPattern::OnMenuImportPattern)
237 EVT_MENU(ID_POWDER_MENU_IMPORT_XDD, WXPowderPattern::OnMenuImportPattern)
238 EVT_MENU(ID_POWDER_MENU_IMPORT_CPI, WXPowderPattern::OnMenuImportPattern)
239 EVT_MENU(ID_POWDER_MENU_IMPORT_FULLPROF4, WXPowderPattern::OnMenuImportPattern)
240 EVT_MENU(ID_POWDER_MENU_IMPORT_MULTIDETECTORLLBG42,WXPowderPattern::OnMenuImportPattern)
241 EVT_MENU(ID_POWDER_MENU_IMPORT_2THETAOBSSIGMA, WXPowderPattern::OnMenuImportPattern)
242 EVT_MENU(ID_POWDER_MENU_IMPORT_2THETAOBS, WXPowderPattern::OnMenuImportPattern)
243 EVT_MENU(ID_POWDER_MENU_IMPORT_TOFISISXYSIGMA, WXPowderPattern::OnMenuImportPattern)
244 EVT_MENU(ID_POWDER_MENU_IMPORT_GSAS, WXPowderPattern::OnMenuImportPattern)
245 EVT_MENU(ID_POWDER_MENU_IMPORT_CIF, WXPowderPattern::OnMenuImportPattern)
246 EVT_MENU(ID_POWDER_MENU_WAVELENGTH_SET, WXPowderPattern::OnMenuSetWavelength)
247 EVT_MENU(ID_POWDER_MENU_WAVELENGTH_XRAY, WXPowderPattern::OnMenuSetWavelength)
248 EVT_MENU(ID_POWDER_MENU_WAVELENGTH_NEUTRON, WXPowderPattern::OnMenuSetWavelength)
249 EVT_MENU(ID_POWDER_MENU_WAVELENGTH_NEUTRON_TOF, WXPowderPattern::OnMenuSetWavelength)
250 EVT_MENU(ID_POWDER_MENU_WAVELENGTH_SET_AG, WXPowderPattern::OnMenuSetWavelength)
251 EVT_MENU(ID_POWDER_MENU_WAVELENGTH_SET_MO, WXPowderPattern::OnMenuSetWavelength)
252 EVT_MENU(ID_POWDER_MENU_WAVELENGTH_SET_CU, WXPowderPattern::OnMenuSetWavelength)
253 EVT_MENU(ID_POWDER_MENU_WAVELENGTH_SET_FE, WXPowderPattern::OnMenuSetWavelength)
254 EVT_MENU(ID_POWDER_MENU_WAVELENGTH_SET_CO, WXPowderPattern::OnMenuSetWavelength)
255 EVT_MENU(ID_POWDER_MENU_WAVELENGTH_SET_CR, WXPowderPattern::OnMenuSetWavelength)
256 EVT_MENU(ID_POWDER_MENU_WAVELENGTH_SET_AGA1, WXPowderPattern::OnMenuSetWavelength)
257 EVT_MENU(ID_POWDER_MENU_WAVELENGTH_SET_MOA1, WXPowderPattern::OnMenuSetWavelength)
258 EVT_MENU(ID_POWDER_MENU_WAVELENGTH_SET_CUA1, WXPowderPattern::OnMenuSetWavelength)
259 EVT_MENU(ID_POWDER_MENU_WAVELENGTH_SET_FEA1, WXPowderPattern::OnMenuSetWavelength)
260 EVT_MENU(ID_POWDER_MENU_WAVELENGTH_SET_COA1, WXPowderPattern::OnMenuSetWavelength)
261 EVT_MENU(ID_POWDER_MENU_WAVELENGTH_SET_CRA1, WXPowderPattern::OnMenuSetWavelength)
262 EVT_MENU(ID_POWDER_MENU_GRAPH, WXPowderPattern::OnMenuShowGraph)
263 EVT_MENU(ID_POWDER_MENU_FITSCALE_R, WXPowderPattern::OnMenuFitScaleForR)
264 EVT_MENU(ID_POWDER_MENU_FITSCALE_RW, WXPowderPattern::OnMenuFitScaleForRw)
265 EVT_MENU(ID_POWDER_MENU_ADD_2THETA_EXCLUDE, WXPowderPattern::OnMenuAddExclude)
266 EVT_MENU(ID_POWDER_MENU_LEBAIL, WXPowderPattern::OnMenuLeBail)
267 EVT_UPDATE_UI(ID_CRYST_UPDATEUI, WXRefinableObj::OnUpdateUI)
270 WXPowderPattern::WXPowderPattern(wxWindow *parent, PowderPattern* pow):
271 WXRefinableObj(parent,pow),mpPowderPattern(pow),mpGraph(0),
272 mChi2(0.0),mGoF(0.0),mRwp(0.0),mRp(0.0)
274 VFN_DEBUG_MESSAGE(
"WXPowderPattern::WXPowderPattern()",6)
275 mpWXTitle->SetForegroundColour(wxColour(255,0,0));
276 mpWXTitle->SetSize(400,-1);
278 mpMenuBar->AddMenu("Data",ID_REFOBJ_MENU_OBJ);
282 mpMenuBar->AddMenuItem(ID_REFOBJ_MENU_OBJ,ID_POWDER_MENU_SAVETEXT,
283 "Save pattern (text)");
284 mpMenuBar->AddMenuItem(ID_REFOBJ_MENU_OBJ,ID_POWDER_MENU_SIMULATE,
285 "Simulation mode (no obs. pattern)");
286 mpMenuBar->GetMenu(ID_REFOBJ_MENU_OBJ).AppendSeparator();
287 mpMenuBar->AddMenuItem(ID_REFOBJ_MENU_OBJ,ID_POWDER_MENU_IMPORT_CIF,
288 "Import CIF Powder Data");
289 mpMenuBar->AddMenuItem(ID_REFOBJ_MENU_OBJ,ID_POWDER_MENU_IMPORT_GSAS,
290 "Import GSAS Data(CONS-ESD,CONS6STD,RALF-ALT)");
291 mpMenuBar->GetMenu(ID_REFOBJ_MENU_OBJ).AppendSeparator();
292 mpMenuBar->AddMenuItem(ID_REFOBJ_MENU_OBJ,ID_POWDER_MENU_IMPORT_2THETAOBSSIGMA,
293 "Import 2Theta-Obs-Sigma Pattern");
294 mpMenuBar->AddMenuItem(ID_REFOBJ_MENU_OBJ,ID_POWDER_MENU_IMPORT_2THETAOBS,
295 "Import 2Theta-Obs Pattern");
296 mpMenuBar->AddMenuItem(ID_REFOBJ_MENU_OBJ,ID_POWDER_MENU_IMPORT_FULLPROF,
297 "Import Fullprof Pattern");
298 mpMenuBar->AddMenuItem(ID_REFOBJ_MENU_OBJ,ID_POWDER_MENU_IMPORT_FULLPROF4,
299 "Import FullProf format
#4");
300 mpMenuBar->AddMenuItem(ID_REFOBJ_MENU_OBJ,ID_POWDER_MENU_IMPORT_XDD,
301 "Import Xdd Pattern");
302 mpMenuBar->AddMenuItem(ID_REFOBJ_MENU_OBJ,ID_POWDER_MENU_IMPORT_CPI,
303 "Import Sietronics CPI Pattern");
304 mpMenuBar->GetMenu(ID_REFOBJ_MENU_OBJ).AppendSeparator();
305 mpMenuBar->AddMenuItem(ID_REFOBJ_MENU_OBJ,ID_POWDER_MENU_IMPORT_ILL_D1A5,
306 "Import Neutron ILL(D1A-D1B) Pattern (D1A5)");
307 mpMenuBar->AddMenuItem(ID_REFOBJ_MENU_OBJ,ID_POWDER_MENU_IMPORT_PSI_DMC,
308 "Import PSI(DMC) Pattern");
309 mpMenuBar->AddMenuItem(ID_REFOBJ_MENU_OBJ,ID_POWDER_MENU_IMPORT_MULTIDETECTORLLBG42,
310 "Import Neutron Multi-Detector Format (LLB G42)");
311 mpMenuBar->GetMenu(ID_REFOBJ_MENU_OBJ).AppendSeparator();
312 mpMenuBar->AddMenuItem(ID_REFOBJ_MENU_OBJ,ID_POWDER_MENU_IMPORT_TOFISISXYSIGMA,
313 "Import Neutron TOF ISIS X Y Sigma");
314 mpMenuBar->AddMenu(
"Export",ID_POWDER_MENU_EXPORT);
315 mpMenuBar->AddMenuItem(ID_POWDER_MENU_EXPORT,ID_POWDER_MENU_EXPORT_FULLPROF,
316 "Export to Fullprof");
317 mpMenuBar->AddMenu(
"Parameters",ID_REFOBJ_MENU_PAR);
318 mpMenuBar->AddMenuItem(ID_REFOBJ_MENU_PAR,ID_REFOBJ_MENU_PAR_FIXALL,
"Fix all");
320 mpMenuBar->AddMenu(
"Phases",ID_POWDERPATTERN_MENU_COMPONENTS);
321 mpMenuBar->AddMenuItem(ID_POWDERPATTERN_MENU_COMPONENTS,
322 ID_POWDER_MENU_COMP_ADDBACKGD_BAYESIAN,
323 "Add Background (Bayesian, automatic)");
324 mpMenuBar->AddMenuItem(ID_POWDERPATTERN_MENU_COMPONENTS,
325 ID_POWDER_MENU_COMP_ADDBACKGD,
326 "Add user-supplied Background ");
327 mpMenuBar->AddMenuItem(ID_POWDERPATTERN_MENU_COMPONENTS,ID_POWDER_MENU_COMP_ADDCRYST,
328 "Add Crystalline Phase");
329 mpMenuBar->AddMenu(
"Radiation",ID_POWDER_MENU_WAVELENGTH);
330 mpMenuBar->AddMenuItem(ID_POWDER_MENU_WAVELENGTH,
331 ID_POWDER_MENU_WAVELENGTH_NEUTRON,
333 mpMenuBar->AddMenuItem(ID_POWDER_MENU_WAVELENGTH,
334 ID_POWDER_MENU_WAVELENGTH_NEUTRON_TOF,
335 "Neutron Time Of Flight");
336 mpMenuBar->AddMenuItem(ID_POWDER_MENU_WAVELENGTH,
337 ID_POWDER_MENU_WAVELENGTH_XRAY,
339 mpMenuBar->AddMenuItem(ID_POWDER_MENU_WAVELENGTH,
340 ID_POWDER_MENU_WAVELENGTH_SET,
341 "Monochromatic Wavelength");
342 mpMenuBar->AddMenuItem(ID_POWDER_MENU_WAVELENGTH,
343 ID_POWDER_MENU_WAVELENGTH_SET_AG,
344 "X-Ray Tube Ag Ka12");
345 mpMenuBar->AddMenuItem(ID_POWDER_MENU_WAVELENGTH,
346 ID_POWDER_MENU_WAVELENGTH_SET_AGA1,
347 "X-Ray Tube Ag Ka1");
348 mpMenuBar->AddMenuItem(ID_POWDER_MENU_WAVELENGTH,
349 ID_POWDER_MENU_WAVELENGTH_SET_MO,
350 "X-Ray Tube Mo Ka12");
351 mpMenuBar->AddMenuItem(ID_POWDER_MENU_WAVELENGTH,
352 ID_POWDER_MENU_WAVELENGTH_SET_MOA1,
353 "X-Ray Tube Mo Ka1");
354 mpMenuBar->AddMenuItem(ID_POWDER_MENU_WAVELENGTH,
355 ID_POWDER_MENU_WAVELENGTH_SET_CU,
356 "X-Ray Tube Cu Ka12");
357 mpMenuBar->AddMenuItem(ID_POWDER_MENU_WAVELENGTH,
358 ID_POWDER_MENU_WAVELENGTH_SET_CUA1,
359 "X-Ray Tube Cu Ka1");
360 mpMenuBar->AddMenuItem(ID_POWDER_MENU_WAVELENGTH,
361 ID_POWDER_MENU_WAVELENGTH_SET_FE,
362 "X-Ray Tube Fe Ka12");
363 mpMenuBar->AddMenuItem(ID_POWDER_MENU_WAVELENGTH,
364 ID_POWDER_MENU_WAVELENGTH_SET_FEA1,
365 "X-Ray Tube Fe Ka1");
366 mpMenuBar->AddMenuItem(ID_POWDER_MENU_WAVELENGTH,
367 ID_POWDER_MENU_WAVELENGTH_SET_CO,
368 "X-Ray Tube Co Ka12");
369 mpMenuBar->AddMenuItem(ID_POWDER_MENU_WAVELENGTH,
370 ID_POWDER_MENU_WAVELENGTH_SET_COA1,
371 "X-Ray Tube Co Ka1");
372 mpMenuBar->AddMenuItem(ID_POWDER_MENU_WAVELENGTH,
373 ID_POWDER_MENU_WAVELENGTH_SET_CR,
374 "X-Ray Tube Cr Ka12");
375 mpMenuBar->AddMenuItem(ID_POWDER_MENU_WAVELENGTH,
376 ID_POWDER_MENU_WAVELENGTH_SET_CRA1,
377 "X-Ray Tube Cr Ka1");
378 mpMenuBar->AddMenu(
"Pattern",ID_POWDERPATTERN_MENU_PATTERN);
379 mpMenuBar->AddMenuItem(ID_POWDERPATTERN_MENU_PATTERN,ID_POWDER_MENU_GRAPH,
381 mpMenuBar->AddMenuItem(ID_POWDERPATTERN_MENU_PATTERN,ID_POWDER_MENU_FITSCALE_R,
383 mpMenuBar->AddMenuItem(ID_POWDERPATTERN_MENU_PATTERN,ID_POWDER_MENU_FITSCALE_RW,
385 mpMenuBar->AddMenuItem(ID_POWDERPATTERN_MENU_PATTERN,
386 ID_POWDER_MENU_ADD_2THETA_EXCLUDE,
387 "Add excluded region");
388 mpMenuBar->GetMenu(ID_POWDERPATTERN_MENU_PATTERN).AppendSeparator();
389 mpMenuBar->AddMenuItem(ID_POWDERPATTERN_MENU_PATTERN,
390 ID_POWDER_MENU_LEBAIL,
391 "Fit profile + Le Bail extract");
396 mpSizer->Add(mpPowderPattern->mRadiation.WXCreate(
this),0);
397 mList.Add(mpPowderPattern->mRadiation.WXGet());
399 wxBoxSizer* thetaCorrSizer=
new wxBoxSizer(wxHORIZONTAL);
401 WXCrystObjBasic* fieldZero
402 =mpPowderPattern->GetPar(&(mpPowderPattern->mXZero)).WXCreate(
this);
403 fieldZero->SetToolTip(_T(
"Zero shift of peaks\n")
404 _T(
"2Theta = 2Theta_Bragg + Zero\n"));
405 WXCrystObjBasic* fieldThetaDispl
406 =mpPowderPattern->GetPar(&(mpPowderPattern->m2ThetaDisplacement)).WXCreate(
this);
407 fieldThetaDispl->SetToolTip(_T(
"Peak shift due to sample displacement:\n")
408 _T(
"2Theta = 2Theta_Bragg + Displacement/cos(Theta)"));
409 WXCrystObjBasic* fieldThetaTransp
410 =mpPowderPattern->GetPar(&(mpPowderPattern->m2ThetaTransparency)).WXCreate(
this);
411 fieldThetaTransp->SetToolTip(_T(
"Zero shift of the peak 2theta positions\n")
412 _T(
"2Theta = 2Theta_Bragg + Transparency*sin(Theta)"));
414 thetaCorrSizer->Add(fieldZero,0);
415 thetaCorrSizer->Add(fieldThetaDispl,0);
416 thetaCorrSizer->Add(fieldThetaTransp,0);
417 mList.Add(fieldZero);
418 mList.Add(fieldThetaDispl);
419 mList.Add(fieldThetaTransp);
420 mpSizer->Add(thetaCorrSizer);
422 wxBoxSizer* tofSizer=
new wxBoxSizer(wxHORIZONTAL);
423 WXCrystObjBasic* fieldDIFC=mpPowderPattern->GetPar(&(mpPowderPattern->mDIFC)).WXCreate(
this);
424 WXCrystObjBasic* fieldDIFA=mpPowderPattern->GetPar(&(mpPowderPattern->mDIFA)).WXCreate(
this);
425 fieldDIFA->SetToolTip(_T(
"Peak position (time, in microseconds):\n")
426 _T(
"t = DIFA * d_hkl + DIFC * d_hkl^2 + ZERO"));
427 fieldDIFC->SetToolTip(_T(
"Peak position (time, in microseconds):\n")
428 _T(
"t = DIFA * d_hkl + DIFC * d_hkl^2 + ZERO"));
429 tofSizer->Add(fieldDIFC,0);
430 tofSizer->Add(fieldDIFA,0);
431 mList.Add(fieldDIFC);
432 mList.Add(fieldDIFA);
433 mpSizer->Add(tofSizer);
435 WXFieldPar<REAL> *maxSiThOvLa=
436 new WXFieldPar<REAL>(
this,
"Max Sin(theta)/lambda:",-1,
437 &(mpPowderPattern->mMaxSinThetaOvLambda));
438 mpSizer->Add(maxSiThOvLa,0,wxALIGN_LEFT);
439 mList.Add(maxSiThOvLa);
440 maxSiThOvLa->SetToolTip(_T(
"Maximum sin(theta)/lambda=1/2d\n")
441 _T(
"For global optimization, the default value of ")
442 _T(
"0.25 (2A resolution) should be sufficient.\n")
443 _T(
"Use larger values if necessary (0.4(1.25A), 0.5(1A))")
444 _T(
"but keep in mind that the number of reflections (and")
445 _T(
"therefore the computing time) varies as [sin(theta/lambda)]^3..."));
447 wxBoxSizer* pStats=
new wxBoxSizer(wxHORIZONTAL);
449 WXFieldPar<REAL> *pWXFieldChi2=
new WXFieldPar<REAL>(
this,
"Chi^2",-1,&mChi2,140);
450 pStats->Add(pWXFieldChi2 ,0,wxALIGN_CENTER);
451 mList.Add(pWXFieldChi2);
452 pWXFieldChi2->SetToolTip(_T(
"Chi^2=SUM[(Obs_i-Calc_i)^2/Sigma_i^2]"));
453 dynamic_cast<WXFieldParBase *
>(pWXFieldChi2)->SetFormat(_T(
"%10.2f"));
455 WXFieldPar<REAL> *pWXFieldGof=
new WXFieldPar<REAL>(
this,
"GoF",-1,&mGoF,90);
456 pStats->Add(pWXFieldGof ,0,wxALIGN_CENTER);
457 mList.Add(pWXFieldGof);
458 pWXFieldGof->SetToolTip(_T(
"GoF=Chi^2/NbPoints"));
459 dynamic_cast<WXFieldParBase *
>(pWXFieldGof)->SetFormat(_T(
"%8.3f"));
461 WXFieldPar<REAL> *pWXFieldRwp=
new WXFieldPar<REAL>(
this,
"Rwp",-1,&mRwp,70);
462 pStats->Add(pWXFieldRwp ,0,wxALIGN_CENTER);
463 mList.Add(pWXFieldRwp);
464 pWXFieldRwp->SetToolTip(_T(
"Full profile R-factor (weighted)\n")
465 _T(
"Will use integrated profiles if option is set."));
466 dynamic_cast<WXFieldParBase *
>(pWXFieldRwp)->SetFormat(_T(
"%8.4f"));
468 WXFieldPar<REAL> *pWXFieldRp=
new WXFieldPar<REAL>(
this,
"Rp",-1,&mRp,70);
469 pStats->Add(pWXFieldRp ,0,wxALIGN_CENTER);
470 mList.Add(pWXFieldRp);
471 pWXFieldRp->SetToolTip(_T(
"Full profile R-factor (unweighted)\n")
472 _T(
"Will use integrated profiles if option is set."));
473 dynamic_cast<WXFieldParBase *
>(pWXFieldRp)->SetFormat(_T(
"%8.4f"));
477 mpSizer->Add(pStats);
479 mpWXComponent=mpPowderPattern
480 ->mPowderPatternComponentRegistry.WXCreate(
this);
481 mpSizer->Add(mpWXComponent,0,wxALIGN_LEFT);
482 mList.Add(mpWXComponent);
484 VFN_DEBUG_MESSAGE(
"WXPowderPattern::WXPowderPattern():1",6)
485 this->CrystUpdate(true);
487 if(!wxConfigBase::Get()->HasEntry(_T(
"PowderPattern/BOOL/Automatically open powder pattern graph")))
488 wxConfigBase::Get()->Write(_T(
"PowderPattern/BOOL/Automatically open powder pattern graph"),
false);
492 wxConfigBase::Get()->Read(_T(
"PowderPattern/BOOL/Automatically open powder pattern graph"), &val);
495 wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED,ID_POWDER_MENU_GRAPH);
496 wxPostEvent(
this,event);
500 VFN_DEBUG_MESSAGE(
"WXPowderPattern::WXPowderPattern():End",6)
505 VFN_DEBUG_ENTRY(
"WXPowderPattern::CrystUpdate()",7)
519 VFN_DEBUG_MESSAGE(
"WXPowderPattern::CrystUpdate()",7)
521 VFN_DEBUG_MESSAGE(
"WXPowderPattern::CrystUpdate()",7)
524 if(mpPowderPattern->mNbPointUsed>0)
525 mGoF=mpPowderPattern->
GetChi2()/mpPowderPattern->mNbPointUsed;
528 mRwp=mpPowderPattern->
GetRw();
529 mRp=mpPowderPattern->
GetR();
533 CrystVector_REAL tmp;
536 for(
long i=0;i<tmp.numElements();i++)
538 if(tmp(i)<0) tmp(i)=0;
539 else tmp(i)=sqrt(tmp(i));
549 VFN_DEBUG_EXIT(
"WXPowderPattern::CrystUpdate()",7)
552 void WXPowderPattern::OnMenuAddCompBackgd(wxCommandEvent & WXUNUSED(event))
554 VFN_DEBUG_MESSAGE(
"WXPowderPattern::OnMenuAddCompBackgd()",6)
556 const
unsigned int nb=mpPowderPattern->GetNbPowderPatternComponent();
558 for(
unsigned int i=0;i<nb;i++)
566 wxMessageDialog dialog(
this,_T(
"You already have one background !\n")
567 _T(
" Are you sure you want to add one ?"),
568 _T(
"Warning : Duplicate Background !"),
569 wxYES_NO|wxICON_HAND|wxNO_DEFAULT);
570 if(wxID_YES!=dialog.ShowModal())
573 PowderPatternBackground *backgdData=
new PowderPatternBackground;
575 if(mpGraph!=0) mpPowderPattern->
Prepare();
576 wxTheApp->GetTopWindow()->Layout();
577 wxTheApp->GetTopWindow()->SendSizeEvent();
580 void WXPowderPattern::OnMenuAddCompBackgdBayesian(wxCommandEvent & WXUNUSED(event))
582 VFN_DEBUG_ENTRY(
"WXPowderPattern::OnMenuAddCompBackgdBayesian()",6)
584 const
unsigned int nb=mpPowderPattern->GetNbPowderPatternComponent();
586 for(
unsigned int i=0;i<nb;i++)
587 if(mpPowderPattern->GetPowderPatternComponent(i).GetClassName()=="PowderPatternBackground")
594 wxMessageDialog dialog(
this,_T(
"You already have one background !\n")
595 _T(
" Are you sure you want to add one ?"),
596 _T(
"Warning : Duplicate Background !"),
597 wxYES_NO|wxICON_HAND|wxNO_DEFAULT);
598 if(wxID_YES!=dialog.ShowModal())
602 long nbPointSpline=20;
603 wxString mes=_T(
"Number of Interpolation Points");
605 s.Printf(_T(
"%ld"),nbPointSpline);
606 wxTextEntryDialog dialog(
this,mes,_T(
"Automatic Bayesian (David-Sivia) Background"),
608 if(wxID_OK!=dialog.ShowModal())
610 VFN_DEBUG_EXIT(
"WXPowderPattern::OnMenuAddCompBackgdBayesian():Canceled",6)
613 dialog.GetValue().ToLong(&nbPointSpline);
614 if(nbPointSpline<=1)nbPointSpline=2;
616 wxProgressDialog dlgProgress(_T("Automatic Bayesian Background"),_T("Automatic Background: Initializing..."),
617 4,this,wxPD_AUTO_HIDE|wxPD_ELAPSED_TIME|wxPD_CAN_ABORT);
619 PowderPatternBackground *pBckgd= new PowderPatternBackground;
620 VFN_DEBUG_MESSAGE("WXPowderPattern::OnMenuAddCompBackgdBayesian()",6)
621 mpPowderPattern->AddPowderPatternComponent(*pBckgd);
622 VFN_DEBUG_MESSAGE("WXPowderPattern::OnMenuAddCompBackgdBayesian()",6)
624 CrystVector_REAL x(nbPointSpline),backgd(nbPointSpline);
625 const CrystVector_REAL *pObs=&(pBckgd->GetParentPowderPattern().GetPowderPatternObs());
626 const unsigned long nbPoint=pBckgd->GetParentPowderPattern().GetNbPoint();
627 const float xmin=pBckgd->GetParentPowderPattern().GetPowderPatternX()(0),
628 xmax=pBckgd->GetParentPowderPattern().GetPowderPatternX()(nbPoint-1);
629 for(
int i=0;i<nbPointSpline;i++)
631 x(i)=xmin+(xmax-xmin)/(REAL)(nbPointSpline-1)*REAL(i);
632 REAL x1=xmin+(xmax-xmin)/(REAL)(nbPointSpline-1)*REAL(i-.2);
633 REAL x2=xmin+(xmax-xmin)/(REAL)(nbPointSpline-1)*REAL(i+.2);
634 long n1=(long)(pBckgd->GetParentPowderPattern().X2Pixel(x1));
635 long n2=(long)(pBckgd->GetParentPowderPattern().X2Pixel(x2));
637 if(n2>(
long)nbPoint)n2=nbPoint;
638 backgd(i)=(*pObs)(n1);
639 for(
long j=n1;j<n2;j++)
640 if((*pObs)(j)<backgd(i))backgd(i)=(*pObs)(j);
642 pBckgd->SetInterpPoints(x,backgd);
644 if(mpGraph!=0) mpPowderPattern->
Prepare();
646 pBckgd->UnFixAllPar();
647 pBckgd->GetOption(0).SetChoice(0);
648 if(dlgProgress.Update(1,_T(
"Automatic Background: Optimizing Linear Model..."))==
false)
return;
649 pBckgd->OptimizeBayesianBackground();
650 pBckgd->GetOption(0).SetChoice(1);
651 if(dlgProgress.Update(2,_T(
"Automatic Background: Optimizing Spline Model..."))==
false)
return;
652 pBckgd->OptimizeBayesianBackground();
655 wxTheApp->GetTopWindow()->Layout();
656 wxTheApp->GetTopWindow()->SendSizeEvent();
657 VFN_DEBUG_EXIT(
"WXPowderPattern::OnMenuAddCompBackgdBayesian()",6)
660 void WXPowderPattern::OnMenuAddCompCryst(wxCommandEvent & WXUNUSED(event))
662 VFN_DEBUG_ENTRY(
"WXPowderPattern::OnMenuAddCompCryst()",10)
664 PowderPatternDiffraction * diffData=new PowderPatternDiffraction;
666 Crystal *cryst=dynamic_cast<Crystal*>
668 "Choose a Crystal Structure:",choice));
669 if(0==cryst) {
delete diffData;
return;}
670 VFN_DEBUG_MESSAGE(
"WXPowderPattern::OnMenuAddCompCryst()",10)
671 diffData->SetCrystal(*cryst);
672 VFN_DEBUG_MESSAGE("WXPowderPattern::OnMenuAddCompCryst()",10)
673 mpPowderPattern->AddPowderPatternComponent(*diffData);
674 VFN_DEBUG_MESSAGE("WXPowderPattern::OnMenuAddCompCryst()",10)
675 if(diffData->GetRadiation().GetWavelengthType()==WAVELENGTH_TOF)
677 VFN_DEBUG_MESSAGE(
"WXPowderPattern::OnMenuAddCompCryst()",10)
680 ReflectionProfileDoubleExponentialPseudoVoigt *p=
681 new ReflectionProfileDoubleExponentialPseudoVoigt
682 (diffData->GetCrystal());
683 diffData->SetProfile(p);
685 VFN_DEBUG_MESSAGE("WXPowderPattern::OnMenuAddCompCryst()",10)
686 if(mpGraph!=0) mpPowderPattern->Prepare();
687 wxTheApp->GetTopWindow()->Layout();
688 wxTheApp->GetTopWindow()->SendSizeEvent();
690 VFN_DEBUG_EXIT("WXPowderPattern::OnMenuAddCompCryst()",10)
693 class WXPowderPatternGraphFrame :public wxFrame
696 WXPowderPatternGraphFrame(wxWindow *parent, wxWindowID
id,
const wxString& title,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = wxDEFAULT_FRAME_STYLE,
const wxString& name = wxFrameNameStr) :
697 wxFrame(parent, id, title, pos, size, style, name)
699 ~WXPowderPatternGraphFrame()
701 gvWindowPosition[ID_POWDER_GRAPH_WIN] = make_pair(this->GetScreenPosition(), this->GetSize());
705 void WXPowderPattern::OnMenuShowGraph(wxCommandEvent & WXUNUSED(event))
707 VFN_DEBUG_MESSAGE(
"WXPowderPattern::OnMenuShowGraph()"<<mpGraph,6)
708 if(mpGraph!=0) return;
709 if(mpPowderPattern->GetNbPoint()<=0) return;
711 mpPowderPattern->Prepare();
714 frame = new WXPowderPatternGraphFrame(this, ID_POWDER_GRAPH_WIN, wxString::FromAscii(mpPowderPattern->GetName().c_str()),
716 gvWindowPosition[ID_POWDER_GRAPH_WIN].second,wxCLOSE_BOX|wxRESIZE_BORDER|wxCAPTION);
718 frame = new WXPowderPatternGraphFrame(this, ID_POWDER_GRAPH_WIN, wxString::FromAscii(mpPowderPattern->GetName().c_str()),
719 wxDefaultPosition,wxSize(500,300),wxCLOSE_BOX|wxRESIZE_BORDER|wxCAPTION);
720 mpGraph = new WXPowderPatternGraph(frame,this);
722 wxSizer *ps=new wxBoxSizer(wxHORIZONTAL);
723 ps->Add(mpGraph,1,wxEXPAND);
725 frame->SetAutoLayout(true);
727 frame->CreateStatusBar(2);
730 this->CrystUpdate(true);
734 void WXPowderPattern::OnMenuSaveText(wxCommandEvent & WXUNUSED(event))
736 VFN_DEBUG_MESSAGE(
"WXPowderPattern::OnMenuSaveText()",6)
738 wxFileDialog save(this,_T("Choose a file"),_T(""),_T(""),_T("*.txt"),wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
739 if(save.ShowModal() != wxID_OK) return;
741 ofstream out(save.GetPath().ToAscii());
743 mpPowderPattern->PrintObsCalcData(out);
747 void WXPowderPattern::OnMenuSimulate(wxCommandEvent & WXUNUSED(event))
749 VFN_DEBUG_ENTRY(
"WXPowderPattern::OnMenuSimulate()",6)
751 double min=0.,max=120.;
754 wxTextEntryDialog dialog(
this,_T(
"2Theta Min"),
755 _T(
"Enter minimum 2Theta (degrees)"),_T(
"5"),wxOK | wxCANCEL);
756 if(wxID_OK!=dialog.ShowModal())
758 VFN_DEBUG_EXIT(
"WXPowderPattern::OnMenuSimulate():Cancelled",6)
761 dialog.GetValue().ToDouble(&min);
765 wxTextEntryDialog dialog(
this,_T(
"2Theta Max"),
766 _T(
"Enter maximum 2Theta (degrees)"),_T(
"100"),wxOK | wxCANCEL);
767 if(wxID_OK!=dialog.ShowModal())
769 VFN_DEBUG_EXIT(
"WXPowderPattern::OnMenuSimulate():Cancelled",6)
772 dialog.GetValue().ToDouble(&max);
775 wxTextEntryDialog dialog(
this,_T(
"Number of points"),
776 _T(
"Enter the number of points"),_T(
"1000"),wxOK | wxCANCEL);
777 if(wxID_OK!=dialog.ShowModal())
779 VFN_DEBUG_EXIT(
"WXPowderPattern::OnMenuSimulate():Cancelled",6)
782 dialog.GetValue().ToLong(&nbPoints);
784 CrystVector_REAL newObs(nbPoints);
785 mpPowderPattern->SetPowderPatternPar(min*DEG2RAD,(max-min)/(nbPoints-1)*DEG2RAD,nbPoints);
788 if(mpPowderPattern->GetNbPowderPatternComponent()>0)
793 for(
long i=0;i<newObs.numElements();++i)
794 newObs(i) += sqrt(newObs(i))*(2*rand()/(REAL)RAND_MAX-1);
797 VFN_DEBUG_EXIT(
"WXPowderPattern::OnMenuSimulate()",6)
800 void WXPowderPattern::OnMenuImportPattern(wxCommandEvent &event)
802 VFN_DEBUG_MESSAGE(
"WXPowderPattern::OnMenuImportPattern()",6)
803 wxFileDialog open(this,_T("Choose a file"),_T(""),_T(""),_T("*.*"),wxFD_OPEN | wxFD_FILE_MUST_EXIST);
804 if(open.ShowModal() != wxID_OK) return;
805 if(event.GetId()==(
long)ID_POWDER_MENU_IMPORT_FULLPROF)
806 mpPowderPattern->ImportPowderPatternFullprof(
string(open.GetPath().ToAscii()));
807 if(event.GetId()==(
long)ID_POWDER_MENU_IMPORT_PSI_DMC)
808 mpPowderPattern->ImportPowderPatternPSI_DMC(
string(open.GetPath().ToAscii()));
809 if(event.GetId()==(
long)ID_POWDER_MENU_IMPORT_ILL_D1A5)
810 mpPowderPattern->ImportPowderPatternILL_D1A5(
string(open.GetPath().ToAscii()));
811 if(event.GetId()==(
long)ID_POWDER_MENU_IMPORT_XDD)
812 mpPowderPattern->ImportPowderPatternXdd(
string(open.GetPath().ToAscii()));
813 if(event.GetId()==(
long)ID_POWDER_MENU_IMPORT_CPI)
814 mpPowderPattern->ImportPowderPatternSietronicsCPI(
string(open.GetPath().ToAscii()));
815 if(event.GetId()==(
long)ID_POWDER_MENU_IMPORT_FULLPROF4)
816 mpPowderPattern->ImportPowderPatternFullprof4(
string(open.GetPath().ToAscii()));
817 if(event.GetId()==(
long)ID_POWDER_MENU_IMPORT_MULTIDETECTORLLBG42)
818 mpPowderPattern->ImportPowderPatternMultiDetectorLLBG42(
string(open.GetPath().ToAscii()));
819 if(event.GetId()==(
long)ID_POWDER_MENU_IMPORT_2THETAOBSSIGMA)
820 mpPowderPattern->ImportPowderPattern2ThetaObsSigma(
string(open.GetPath().ToAscii()));
821 if(event.GetId()==(
long)ID_POWDER_MENU_IMPORT_2THETAOBS)
822 mpPowderPattern->ImportPowderPattern2ThetaObs(
string(open.GetPath().ToAscii()));
823 if(event.GetId()==(
long)ID_POWDER_MENU_IMPORT_TOFISISXYSIGMA)
824 mpPowderPattern->ImportPowderPatternTOF_ISIS_XYSigma(
string(open.GetPath().ToAscii()));
825 if(event.GetId()==(
long)ID_POWDER_MENU_IMPORT_GSAS)
826 mpPowderPattern->ImportPowderPatternGSAS(
string(open.GetPath().ToAscii()));
827 if(event.GetId()==(
long)ID_POWDER_MENU_IMPORT_CIF)
829 ifstream fin (open.GetPath().ToAscii());
832 throw ObjCrystException(
"WXPowderPattern::OnMenuImportPattern(): Error opening file for input:"+
string(open.GetPath().ToAscii()));
838 wxConfigBase::Get()->Read(_T(
"PowderPattern/BOOL/Automatically open powder pattern graph"), &val);
841 wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED,ID_POWDER_MENU_GRAPH);
842 wxPostEvent(
this,event);
846 void WXPowderPattern::OnMenuFitScaleForR(wxCommandEvent & WXUNUSED(event))
848 if(0==mpGraph)
return;
854 void WXPowderPattern::OnMenuFitScaleForRw(wxCommandEvent & WXUNUSED(event))
856 if(0==mpGraph)
return;
863 void WXPowderPattern::OnMenuSetWavelength(wxCommandEvent & event)
869 if(event.GetId()== ID_POWDER_MENU_WAVELENGTH_XRAY)
871 if(event.GetId()== ID_POWDER_MENU_WAVELENGTH_NEUTRON)
873 if(event.GetId()== ID_POWDER_MENU_WAVELENGTH_NEUTRON_TOF)
878 if(event.GetId()== ID_POWDER_MENU_WAVELENGTH_SET)
881 wxTextEntryDialog dialog(
this,_T(
"new Wavelength)"),
882 _T(
"Enter new Wavelength (Angstroems)"),_T(
"1"),wxOK | wxCANCEL);
883 if(wxID_OK!=dialog.ShowModal())
885 VFN_DEBUG_EXIT(
"WXPowderPattern))OnMenuSetWavelength())Monochromatic)Cancelled",6)
888 dialog.GetValue().ToDouble(&lambda);
889 mpPowderPattern->SetWavelength(lambda);
891 if(event.GetId()== ID_POWDER_MENU_WAVELENGTH_SET_AG)
892 mpPowderPattern->SetWavelength("Ag");
893 if(event.GetId()== ID_POWDER_MENU_WAVELENGTH_SET_MO)
894 mpPowderPattern->SetWavelength("Mo");
895 if(event.GetId()== ID_POWDER_MENU_WAVELENGTH_SET_CU)
896 mpPowderPattern->SetWavelength("Cu");
897 if(event.GetId()== ID_POWDER_MENU_WAVELENGTH_SET_FE)
898 mpPowderPattern->SetWavelength("Fe");
899 if(event.GetId()== ID_POWDER_MENU_WAVELENGTH_SET_CO)
900 mpPowderPattern->SetWavelength("Co");
901 if(event.GetId()== ID_POWDER_MENU_WAVELENGTH_SET_CR)
902 mpPowderPattern->SetWavelength("Cr");
903 if(event.GetId()== ID_POWDER_MENU_WAVELENGTH_SET_AGA1)
904 mpPowderPattern->SetWavelength("AgA1");
905 if(event.GetId()== ID_POWDER_MENU_WAVELENGTH_SET_MOA1)
906 mpPowderPattern->SetWavelength("MoA1");
907 if(event.GetId()== ID_POWDER_MENU_WAVELENGTH_SET_CUA1)
908 mpPowderPattern->SetWavelength("CuA1");
909 if(event.GetId()== ID_POWDER_MENU_WAVELENGTH_SET_FEA1)
910 mpPowderPattern->SetWavelength("FeA1");
911 if(event.GetId()== ID_POWDER_MENU_WAVELENGTH_SET_COA1)
912 mpPowderPattern->SetWavelength("CoA1");
913 if(event.GetId()== ID_POWDER_MENU_WAVELENGTH_SET_CRA1)
914 mpPowderPattern->SetWavelength("CrA1");
915 this->CrystUpdate(true);
918 void WXPowderPattern::OnMenuAddExclude(wxCommandEvent & WXUNUSED(event))
924 wxString txt=_T(
"Enter Min 2theta to exclude (degrees):");
926 txt=_T(
"Enter Min 2theta to exclude (microseconds):");
927 wxTextEntryDialog dialog(
this,_T(
"Min"),txt,_T(
"0"),wxOK | wxCANCEL);
928 if(wxID_OK!=dialog.ShowModal())
930 VFN_DEBUG_EXIT(
"WXPowderPattern::OnMenuAddExclude():Cancelled",6)
933 dialog.GetValue().ToDouble(&min);
937 wxString txt=_T(
"Enter Max 2theta to exclude (degrees):");
939 txt=_T(
"Enter Max 2theta to exclude (microseconds):");
940 wxTextEntryDialog dialog(
this,_T(
"Max"),txt,_T(
"5"),wxOK | wxCANCEL);
941 if(wxID_OK!=dialog.ShowModal())
943 VFN_DEBUG_EXIT(
"WXPowderPattern::OnMenuAddExclude():Cancelled",6)
946 dialog.GetValue().ToDouble(&max);
950 VFN_DEBUG_EXIT(
"WXPowderPattern::OnMenuAddExclude():Stupid user.",6)
953 if(mpPowderPattern->GetRadiation().GetWavelengthType()==WAVELENGTH_TOF)
954 mpPowderPattern->AddExcludedRegion(min,max);
955 else mpPowderPattern->AddExcludedRegion(min*DEG2RAD,max*DEG2RAD);
961 wxFrame *pFrame=
new wxFrame(
this,-1,_T(
"Profile Fitting"));
962 WXProfileFitting *pFit;
963 pFit=
new WXProfileFitting(pFrame,&(this->GetPowderPattern()));
966 cout<<
"Beginning refinement"<<endl;
977 try {lsq.
Refine(10,
true,
false);}
979 cout<<
"Finishing refinement"<<endl;
984 void WXPowderPattern::OnMenuExport(wxCommandEvent &event)
987 wxFileDialog save(
this,_T(
"Choose a .pcr file"),_T(
""),_T(
""),_T(
"*.pcr"),wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
988 if(save.ShowModal() != wxID_OK)
return;
990 wxString path,name,ext;
991 wxFileName::SplitPath(save.GetPath(), &path, &name, &ext, wxPATH_NATIVE);
993 wxString pcr=path+wxFileName::GetPathSeparator()+name+_T(
".pcr");
994 wxString dat=path+wxFileName::GetPathSeparator()+name+_T(
".dat");
995 mes.Printf(_T(
"This will create the files:\n %s\n %s"),pcr.c_str(),dat.c_str());
996 wxMessageDialog mesd(
this,mes,_T(
"Files"),wxOK|wxCANCEL|wxICON_INFORMATION);
997 if(mesd.ShowModal()==wxID_OK)
998 mpPowderPattern->
ExportFullprof(
string((path+wxFileName::GetPathSeparator()+name).ToAscii()));
1001 void WXPowderPattern::NotifyDeleteGraph() {mpGraph=0;}
1002 const PowderPattern& WXPowderPattern::GetPowderPattern()
const
1003 {
return *mpPowderPattern;}
1005 PowderPattern& WXPowderPattern::GetPowderPattern()
1006 {
return *mpPowderPattern;}
1013 mpGraph->GetParent()->SetLabel(wxString::FromAscii(mpPowderPattern->
GetName().c_str()));
1023 static const long ID_POWDERGRAPH_MENU_UPDATE=
WXCRYST_ID();
1024 static const long ID_POWDERGRAPH_MENU_TOGGLELABEL=
WXCRYST_ID();
1025 static const long ID_POWDERGRAPH_MENU_TOGGPEAK=
WXCRYST_ID();
1026 static const long ID_POWDERGRAPH_MENU_FINDPEAKS=
WXCRYST_ID();
1027 static const long ID_POWDERGRAPH_MENU_LOADPEAKS=
WXCRYST_ID();
1028 static const long ID_POWDERGRAPH_MENU_SAVEPEAKS=
WXCRYST_ID();
1029 static const long ID_POWDERGRAPH_MENU_ADDPEAK=
WXCRYST_ID();
1030 static const long ID_POWDERGRAPH_MENU_REMOVEPEAK=
WXCRYST_ID();
1031 static const long ID_POWDERGRAPH_MENU_INDEX=
WXCRYST_ID();
1032 static const long ID_POWDERGRAPH_MENU_XSCALE_DATA=
WXCRYST_ID();
1033 static const long ID_POWDERGRAPH_MENU_XSCALE_D=
WXCRYST_ID();
1034 static const long ID_POWDERGRAPH_MENU_XSCALE_2PID=
WXCRYST_ID();
1035 static const long ID_POWDERGRAPH_MENU_YSCALE_LINEAR=
WXCRYST_ID();
1036 static const long ID_POWDERGRAPH_MENU_YSCALE_SQRT=
WXCRYST_ID();
1037 static const long ID_POWDERGRAPH_MENU_YSCALE_LOG10=
WXCRYST_ID();
1038 static const long ID_POWDERGRAPH_MENU_LEBAIL=
WXCRYST_ID();
1066 wxWindow(frame,-1,wxPoint(-1,-1),wxSize(-1,-1)),
1067 mpPattern(parent),mMargin(20),mDiffPercentShift(.20),
1068 mMaxIntensity(-1),mMinIntensity(-1),mMinX(-1),mMaxX(-1),
1069 mDefaultIntensityScale(true),
1070 mpParentFrame(frame),
1071 mIsDragging(false),mDisplayLabel(true),mDisplayPeak(true)
1073 mpPopUpMenu=
new wxMenu(_T(
"Powder Pattern"));
1074 mpPopUpMenu->Append(ID_POWDERGRAPH_MENU_UPDATE, _T(
"&Update"));
1075 mpPopUpMenu->Append(ID_POWDERGRAPH_MENU_TOGGLELABEL, _T(
"&Hide labels"));
1077 mpPopUpMenu->AppendSeparator();
1078 mpPopUpMenu->Append(ID_POWDERGRAPH_MENU_FINDPEAKS, _T(
"&Find peaks"));
1079 mpPopUpMenu->Append(ID_POWDERGRAPH_MENU_LOADPEAKS, _T(
"&Load peaks"));
1080 mpPopUpMenu->Append(ID_POWDERGRAPH_MENU_SAVEPEAKS, _T(
"&Save peaks"));
1081 mpPopUpMenu->Append(ID_POWDERGRAPH_MENU_INDEX, _T(
"&Index !"));
1082 mpPopUpMenu->Append(ID_POWDERGRAPH_MENU_TOGGPEAK, _T(
"&Hide peaks"));
1083 mpPopUpMenu->Append(ID_POWDERGRAPH_MENU_ADDPEAK, _T(
"&Add peak"));
1084 mpPopUpMenu->Append(ID_POWDERGRAPH_MENU_REMOVEPEAK, _T(
"&Remove peak"));
1085 mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_SAVEPEAKS, FALSE);
1086 mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_TOGGPEAK, FALSE);
1087 mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_ADDPEAK, TRUE);
1088 mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_REMOVEPEAK, FALSE);
1089 mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_INDEX, FALSE);
1091 mpPopUpMenu->AppendSeparator();
1092 mpPopUpMenu->Append(ID_POWDERGRAPH_MENU_LEBAIL, _T(
"Fit &Profile + Le Bail extraction"));
1093 mpPopUpMenu->AppendSeparator();
1094 mpPopUpMenu->Append(ID_POWDERGRAPH_MENU_XSCALE_DATA, _T(
"&X scale: 2theta/TOF"));
1095 mpPopUpMenu->Append(ID_POWDERGRAPH_MENU_XSCALE_D, _T(
"&X scale: Q=1/d"));
1096 mpPopUpMenu->Append(ID_POWDERGRAPH_MENU_XSCALE_2PID, _T(
"&X scale: Q=2pi/d"));
1097 mpPopUpMenu->Append(ID_POWDERGRAPH_MENU_YSCALE_LINEAR, _T(
"&Y scale: I"));
1098 mpPopUpMenu->Append(ID_POWDERGRAPH_MENU_YSCALE_SQRT, _T(
"&Y scale: sqrt(I)"));
1099 mpPopUpMenu->Append(ID_POWDERGRAPH_MENU_YSCALE_LOG10, _T(
"&Y scale: log10(I)"));
1100 if(!wxConfigBase::Get()->HasEntry(_T(
"PowderPattern/BOOL/Default-display reflection indices")))
1101 wxConfigBase::Get()->Write(_T(
"PowderPattern/BOOL/Default-display reflection indices"), mDisplayLabel);
1104 wxConfigBase::Get()->Read(_T(
"PowderPattern/BOOL/Default-display reflection indices"), &mDisplayLabel);
1105 if(mDisplayLabel) mpPopUpMenu->SetLabel(ID_POWDERGRAPH_MENU_TOGGLELABEL, _T(
"Hide labels"));
1106 else mpPopUpMenu->SetLabel(ID_POWDERGRAPH_MENU_TOGGLELABEL, _T(
"Show labels"));
1110 if(!wxConfigBase::Get()->HasEntry(_T(
"PowderPattern/LONG/graph x scale")))
1111 wxConfigBase::Get()->Write(_T(
"PowderPattern/LONG/graph x scale"), 0);
1114 if(!wxConfigBase::Get()->HasEntry(_T(
"PowderPattern/LONG/graph y scale")))
1115 wxConfigBase::Get()->Write(_T(
"PowderPattern/LONG/graph y scale"), 0);
1117 wxConfigBase::Get()->Read(_T(
"PowderPattern/LONG/graph x scale"), &mXScale);
1118 wxConfigBase::Get()->Read(_T(
"PowderPattern/LONG/graph y scale"), &mYScale);
1120 mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_XSCALE_DATA, TRUE);
1121 mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_XSCALE_D, TRUE);
1122 mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_XSCALE_2PID, TRUE);
1123 mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_YSCALE_LINEAR, TRUE);
1124 mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_YSCALE_SQRT, TRUE);
1125 mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_YSCALE_LOG10, TRUE);
1127 if(mXScale==0) mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_XSCALE_DATA, FALSE);
1128 if(mXScale==1) mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_XSCALE_D, FALSE);
1129 if(mXScale==2) mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_XSCALE_2PID, FALSE);
1130 if(mYScale==0)mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_YSCALE_LINEAR, FALSE);
1131 if(mYScale==1) mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_YSCALE_SQRT, FALSE);
1132 if(mYScale==2) mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_YSCALE_LOG10, FALSE);
1134 mpPattern->CrystUpdate(
true);
1137 WXPowderPatternGraph::~WXPowderPatternGraph()
1139 mpPattern->NotifyDeleteGraph();
1144 if((mObs.numElements()<=0)||(mCalc.numElements()<=0))
return;
1145 VFN_DEBUG_MESSAGE(
"WXPowderPatternGraph:OnPaint()",5)
1147 while(wxMUTEX_NO_ERROR!=
mMutex.TryLock())
1153 wxBufferedPaintDC dc(
this);
1155 mpParentFrame->PrepareDC(dc);
1157 dc.DestroyClippingRegion();
1158 dc.SetBackground(wxBrush(_T(
"white"), wxSOLID));
1161 wxColour blue=wxColour(0,0,255);
1162 wxPen bluePen=wxPen(blue);
1165 dc.SetFont(*wxNORMAL_FONT);
1167 dc.SetFont(*wxSMALL_FONT);
1170 long nbPoint=mX.numElements();
1173 wxCoord width,height;
1174 this->GetSize(&width, &height);
1178 VFN_DEBUG_MESSAGE(
"WXPowderPatternGraph:OnPaint():1",5)
1181 VFN_DEBUG_MESSAGE(
"WXPowderPatternGraph:OnPaint():2:"<<mObs.numElements(),5)
1183 VFN_DEBUG_MESSAGE(
"WXPowderPatternGraph:OnPaint():3:min="
1184 <<mMinX<<
", max="<<mMaxX<<
", width="
1185 <<width<<
",margin="<<mMargin,5)
1188 dc.SetPen(* wxLIGHT_GREY_PEN);
1190 for(
long i=0;i<nbPoint;i++)
1192 if((mX(i)>mMinX)&&(mX(i)<mMaxX))
1194 x=this->Point2ScreenX(i);
1195 y1=this->Data2ScreenY(mObs(i)-mSigma(i)/2.);
1196 y2=this->Data2ScreenY(mObs(i)+mSigma(i)/2.);
1198 dc.DrawLine(x,y1,x,y2);
1205 dc.SetPen(* wxBLACK_PEN);
1206 dc.DrawLine(mMargin*3,height-mMargin,mMargin*3,mMargin);
1207 dc.DrawLine(mMargin*3,height-mMargin,width,height-mMargin);
1208 const int nbTick=10;
1212 xc=(wxCoord)mMargin*3;
1213 REAL miny=mMinIntensity,maxy=mMaxIntensity;
1214 if(mYScale==1) {miny=sqrt(miny) ;maxy=sqrt(maxy);}
1215 if(mYScale==2) {miny=log10(miny);maxy=log10(maxy);}
1216 REAL yStep=pow((
float)10,(
float)floor(log10((maxy-miny)/nbTick)));
1217 yStep *= floor((maxy-miny)/yStep/nbTick);
1218 for(REAL ys=yStep*ceil(miny/yStep);ys<maxy;ys+=yStep)
1221 if(mYScale==1) {y=ys*ys;}
1222 if(mYScale==2) {y=pow((
float)10,(
float)ys);}
1223 yc=this->Data2ScreenY(y);
1224 dc.DrawLine(xc-3,yc,xc+3,yc);
1225 fontInfo.Printf(_T(
"%g"),y);
1226 dc.GetTextExtent(fontInfo, &tmpW, &tmpH);
1227 dc.DrawText(fontInfo,xc-tmpW-3,yc-tmpH/2);
1232 yc=(wxCoord)(height-mMargin);
1234 REAL minx=mMinX,maxx=mMaxX;
1236 if(mpPattern->GetPowderPattern().GetRadiation().GetWavelengthType()!=WAVELENGTH_TOF)
1238 mind=2*mpPattern->GetPowderPattern().X2STOL(minx*DEG2RAD);
1239 maxd=2*mpPattern->GetPowderPattern().X2STOL(maxx*DEG2RAD);
1243 mind=2*mpPattern->GetPowderPattern().X2STOL(minx);
1244 maxd=2*mpPattern->GetPowderPattern().X2STOL(maxx);
1246 if(mXScale==1) {minx=mind; maxx=maxd;}
1247 if(mXScale==2) {minx=2*M_PI*mind;maxx=2*M_PI*maxd;}
1249 REAL xStep=pow((
float)10,(
float)floor(log10((maxx-minx)/nbTick)));
1250 xStep *= floor((maxx-minx)/xStep/nbTick);
1251 for(REAL xs=xStep*ceil(minx/xStep);xs<maxx;xs+=xStep)
1254 if(mXScale==1) {x=mpPattern->GetPowderPattern().STOL2X(xs/2);}
1255 if(mXScale==2) {x=mpPattern->GetPowderPattern().STOL2X(xs/(4*M_PI));}
1256 if(mXScale==0) xc=this->Data2ScreenX(x);
1259 if(mpPattern->GetPowderPattern().GetRadiation().GetWavelengthType()!=WAVELENGTH_TOF)
1260 xc=this->Data2ScreenX(RAD2DEG*x);
1261 else xc=this->Data2ScreenX(x);
1263 dc.DrawLine(xc,yc-3,xc,yc+3);
1264 fontInfo.Printf(_T(
"%g"),xs);
1265 dc.GetTextExtent(fontInfo, &tmpW, &tmpH);
1266 dc.DrawText(fontInfo,xc-tmpW/2,yc+6);
1272 dc.SetPen(* wxGREY_PEN);
1273 wxCoord x1,y1,x2,y2;
1274 x2=this->Point2ScreenX(0);
1275 const REAL s=(mMaxIntensity-mMinIntensity)/mChi2Cumul(mpPattern->GetPowderPattern().GetNbPointUsed()-1);
1276 y2=this->Data2ScreenY(mMinIntensity+mChi2Cumul(0)*s);
1277 for(
unsigned long i=0;i<mpPattern->GetPowderPattern().GetNbPointUsed();i++)
1279 if((mX(i)>mMinX)&&(mX(i)<mMaxX))
1283 x2=this->Point2ScreenX(i);
1284 y2=this->Data2ScreenY(mMinIntensity+mChi2Cumul(i)*s);
1285 dc.DrawLine(x1,y1,x2,y2);
1290 VFN_DEBUG_MESSAGE(
"WXPowderPatternGraph:OnPaint():4:",5)
1293 wxCoord x1,y1,x2,y2;
1294 x2=this->Point2ScreenX(0);
1295 y2=this->Data2ScreenY(mObs(0));
1296 for(
long i=0;i<nbPoint;i++)
1298 if((mX(i)>mMinX)&&(mX(i)<mMaxX))
1302 x2=this->Point2ScreenX(i);
1303 y2=this->Data2ScreenY(mObs(i));
1304 dc.DrawLine(x1,y1,x2,y2);
1310 VFN_DEBUG_MESSAGE(
"WXPowderPatternGraph:OnPaint():5:",5)
1312 dc.SetPen(* wxRED_PEN);
1313 wxCoord x1,y1,x2,y2;
1314 x2=this->Point2ScreenX(0);
1315 y2=this->Data2ScreenY(mCalc(0));
1316 for(
long i=0;i<nbPoint;i++)
1318 if((mX(i)>mMinX)&&(mX(i)<mMaxX))
1322 x2=this->Point2ScreenX(i);
1323 y2=this->Data2ScreenY(mCalc(i));
1324 dc.DrawLine(x1,y1,x2,y2);
1330 list<list<pair<const REAL ,const string > > > vLabel;
1331 if(
true==mDisplayLabel)
1332 for(list<list<pair<const REAL ,const string > > >::const_iterator
1333 comp=mvLabelList.begin();comp!=mvLabelList.end();++comp) vLabel.push_back(*comp);
1335 if((
true==mDisplayPeak)&&(mPeakList.GetPeakList().size()>0))
1337 list<pair<const REAL ,const string > > peakLabels;
1340 for(vector<PeakList::hkl>::const_iterator pos=mPeakList.GetPeakList().begin();pos!=mPeakList.GetPeakList().end();++pos)
1342 const float x=mpPattern->GetPowderPattern().STOL2X(pos->dobs/2);
1345 if(mpPattern->GetPowderPattern().GetRadiation().GetWavelengthType()!=WAVELENGTH_TOF)
1346 sprintf(buf,
"#%2u,x=%6.3f d=%6.3fA SPURIOUS?",ix,x*RAD2DEG,1/pos->dobs);
1348 sprintf(buf,
"#%2u,x=%6.3f d=%6.3fA SPURIOUS?",ix,x ,1/pos->dobs);
1352 if(mpPattern->GetPowderPattern().GetRadiation().GetWavelengthType()!=WAVELENGTH_TOF)
1353 sprintf(buf,
"#%2u,x=%6.2f d=%6.3fA",ix,x*RAD2DEG,1/pos->dobs);
1355 sprintf(buf,
"#%2u,x=%6.2f d=%6.3fA",ix,x ,1/pos->dobs);
1358 peakLabels.push_back(make_pair(x,buf));
1360 vLabel.push_back(peakLabels);
1362 if(mPeakList.mvPredictedHKL.size()>0)
1365 for(list<PeakList::hkl>::const_iterator pos=mPeakList.mvPredictedHKL.begin();pos!=mPeakList.mvPredictedHKL.end();++pos)
1367 const float dobs=sqrt(pos->d2calc);
1368 const float x=mpPattern->GetPowderPattern().STOL2X(dobs/2);
1369 sprintf(buf,
"?(%2d %2d %2d)?",pos->h,pos->k,pos->l);
1370 peakLabels.push_back(make_pair(x,buf));
1372 vLabel.push_back(peakLabels);
1376 VFN_DEBUG_MESSAGE(
"WXPowderPatternGraph:OnPaint():5:",5)
1384 unsigned int icomp=0;
1386 for(list<list<pair<const REAL ,const string > > >::const_iterator comp=vLabel.begin();comp!=vLabel.end();comp++)
1395 case 0 : dc.SetPen(wxPen(wxColour( 0, 0, 0),2));dc.SetTextForeground(wxColour( 0, 0, 0));
break;
1396 case 1 : dc.SetPen(wxPen(wxColour( 0, 0,255),2));dc.SetTextForeground(wxColour( 0, 0,255));
break;
1397 case 2 : dc.SetPen(wxPen(wxColour( 0,255, 0),2));dc.SetTextForeground(wxColour( 0,255, 0));
break;
1398 case 3 : dc.SetPen(wxPen(wxColour(255, 0, 0),2));dc.SetTextForeground(wxColour(255, 0, 0));
break;
1399 case 4 : dc.SetPen(wxPen(wxColour( 0,255,255),2));dc.SetTextForeground(wxColour( 0,255,255));
break;
1400 case 5 : dc.SetPen(wxPen(wxColour(255, 0,255),2));dc.SetTextForeground(wxColour(255, 0,255));
break;
1401 case 6 : dc.SetPen(wxPen(wxColour(255,160, 0),2));dc.SetTextForeground(wxColour(255,160, 0));
break;
1402 case 7 : dc.SetPen(wxPen(wxColour(128,128,255),2));dc.SetTextForeground(wxColour(128,128,255));
break;
1403 case 8 : dc.SetPen(wxPen(wxColour(128,255,128),2));dc.SetTextForeground(wxColour(128,255,128));
break;
1404 case 9 : dc.SetPen(wxPen(wxColour(255,128,128),2));dc.SetTextForeground(wxColour(255,128,128));
break;
1405 case 10: dc.SetPen(wxPen(wxColour( 0, 0,128),2));dc.SetTextForeground(wxColour( 0, 0,128));
break;
1406 case 11: dc.SetPen(wxPen(wxColour( 0, 80, 0),2));dc.SetTextForeground(wxColour( 0, 80, 0));
break;
1407 case 12: dc.SetPen(wxPen(wxColour(128, 0, 0),2));dc.SetTextForeground(wxColour(128, 0, 0));
break;
1408 default: dc.SetPen(wxPen(wxColour(128,128,128),2));dc.SetTextForeground(wxColour(128,128,128));
break;
1411 for(list<pair<const REAL ,const string > >::const_iterator pos=comp->begin();pos!=comp->end();++pos)
1413 REAL point=pos->first;
1414 if(mpPattern->GetPowderPattern().GetRadiation().GetWavelengthType()!=WAVELENGTH_TOF)
1416 if((point>=mMinX)&&(point<=mMaxX))
1420 cout <<
"Too many labels (>100): displaying only first 100 and ticking 100 more..."<<endl;
1423 x=this->Data2ScreenX(point);
1424 const REAL pixel=mpPattern->GetPowderPattern().X2Pixel(pos->first);
1425 if(mCalc((
long)pixel)>mObs((
long)pixel)) yr=mCalc((
long)pixel);
1426 else yr=mObs((
long)pixel);
1427 y=this->Data2ScreenY(yr);
1429 dc.DrawLine(x,y-5,x,y-10);
1432 fontInfo.Printf(wxString::FromAscii(pos->second.c_str()));
1433 dc.GetTextExtent(fontInfo, &tmpW, &tmpH);
1434 dc.DrawText(fontInfo,x-tmpW/2,y-tmpH*(loop++)-10);
1441 if(icomp<mpPattern->GetPowderPattern().GetNbPowderPatternComponent())
1444 if(mpPattern->GetPowderPattern().GetPowderPatternComponent(icomp).GetClassName()==
"PowderPatternDiffraction")
1453 if((icomp-mpPattern->GetPowderPattern().GetNbPowderPatternComponent())==0)
1454 legend=
"Found Peaks";
1455 else legend=
"Indexed HKL";
1457 fontInfo.Printf(legend);
1459 dc.GetTextExtent(fontInfo, &tmpW, &tmpH);
1460 dc.DrawText(fontInfo,(wxCoord)mMargin*3+5,(wxCoord)(mMargin+tmpH*(pen)));
1466 VFN_DEBUG_MESSAGE(
"WXPowderPatternGraph:OnPaint():End",5)
1471 if(event.Leaving())
return;
1472 if(wxMUTEX_NO_ERROR!=
mMutex.TryLock())
1477 VFN_DEBUG_MESSAGE(
"WXPowderPatternGraph:OnMouse()"
1478 <<endl<<
"IsButton():"<<event.IsButton()
1479 <<endl<<
"ButtonDown():"<<
event.ButtonDown()
1480 <<endl<<
"Dragging():"<<
event.Dragging()
1481 <<endl<<
"Entering():"<<
event.Entering()
1482 <<endl<<
"Leaving():"<<
event.Leaving()
1483 <<endl<<
"GetButton()"<<
event.GetButton()
1484 <<endl<<
"GetWheelAxis():"<<
event.GetWheelAxis()
1485 <<endl<<
"GetWheelDelta():"<<
event.GetWheelDelta()
1486 <<endl<<
"GetWheelRotation():"<<
event.GetWheelRotation()
1487 <<endl<<
"Moving():"<<
event.Moving()
1490 wxClientDC dc(
this);
1492 mpParentFrame->PrepareDC(dc);
1494 wxPoint pos=
event.GetPosition();
1495 const long x= dc.DeviceToLogicalX(pos.x);
1496 const long y= dc.DeviceToLogicalY(pos.y);
1498 wxCoord width,height;
1499 this->GetSize(&width, &height);
1501 if((x>width)||(y>height))
1507 const REAL x0=this->Screen2DataX(x);
1508 const REAL intensity=this->Screen2DataY(y);
1509 if(mpPattern->GetPowderPattern().GetRadiation().GetWavelengthType()==WAVELENGTH_TOF)
1513 (long)(mpPattern->GetPowderPattern().X2PixelCorr(x0));
1514 str.Printf(_T(
"tof=%6.2f ,I=%12.2f. pixel=#%ld"),x0,intensity,pixel);
1516 mpParentFrame->SetStatusText(str);
1518 str.Printf(_T(
"d=%6.3fA"),0.5/mpPattern->GetPowderPattern().X2STOL(x0));
1520 mpParentFrame->SetStatusText(str,1);
1525 const REAL intensity=this->Screen2DataY(y);
1529 (long)(mpPattern->GetPowderPattern().X2PixelCorr(x0*DEG2RAD));
1530 str.Printf(_T(
"2theta=%6.2f ,I=%12.2f. pixel=#%ld"),x0,intensity,pixel);
1533 mpParentFrame->SetStatusText(str);
1535 str.Printf(_T(
"d=%6.3fA"),0.5/mpPattern->GetPowderPattern().X2STOL(x0*DEG2RAD));
1537 mpParentFrame->SetStatusText(str,1);
1540 if (event.Dragging() &&
event.LeftIsDown() && (!mIsDragging))
1544 mDraggingIntensity0=intensity;
1548 if(event.LeftUp() && mIsDragging)
1550 VFN_DEBUG_MESSAGE(
"WXPowderPatternGraph::OnMouse():Finished zooming...",5)
1553 if( (fabs(x0-mDraggingX0)<.1) || (fabs(mDraggingIntensity0-intensity)< fabs(mMaxIntensity*.02)) )
1558 if(mDraggingIntensity0>intensity)
1560 if(mDraggingIntensity0<0.)
1565 mMinIntensity=intensity;
1566 mMaxIntensity=mDraggingIntensity0;
1575 mMinIntensity=mDraggingIntensity0;
1576 mMaxIntensity=intensity;
1588 mDefaultIntensityScale=
false;
1589 mClockAxisLimits.Click();
1591 wxUpdateUIEvent event(ID_POWDER_GRAPH_NEW_PATTERN);
1592 wxPostEvent(
this,event);
1596 if(
false==event.Dragging()) mIsDragging=
false;
1598 if(event.LeftDClick())
1601 this->ResetAxisLimits();
1602 wxUpdateUIEvent event(ID_POWDER_GRAPH_NEW_PATTERN);
1603 wxPostEvent(
this,event);
1608 if(event.RightIsDown())
1611 if(mpPattern->GetPowderPattern().IsBeingRefined())
1612 mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_UPDATE,
false);
1614 mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_UPDATE,
true);
1617 this->PopupMenu(mpPopUpMenu, event.GetX(),
event.GetY() );
1620 if (event.GetWheelDelta()>0)
1622 if(event.ControlDown())
1624 VFN_DEBUG_MESSAGE(
"WXPowderPatternGraph::OnMouse(): Mouse Wheel / double touch + control (OSX: command)",2)
1628 VFN_DEBUG_MESSAGE(
"WXPowderPatternGraph::OnMouse(): Mouse Wheel / double touch",2)
1629 const int delta=
event.GetWheelDelta();
1631 if(event.GetWheelAxis()==1) dx=event.GetWheelRotation();
1632 else dy=
event.GetWheelRotation();
1638 const long nbPoint=mX.numElements();
1641 const REAL range=mMaxX-mMinX;
1642 mMaxX += range/128.*abs(dx);
1643 if(mX(nbPoint-1)>mX(0))
1645 if(mMaxX>=mX(nbPoint-1)) mMaxX=mX(nbPoint-1);
1649 if(mMaxX>=mX(0)) mMaxX=mX(0);
1655 const REAL range=mMaxX-mMinX;
1656 mMinX -= range/128.*abs(dx);
1657 if(mX(nbPoint-1)>mX(0))
1659 if(mMinX<mX(0)) mMinX=mX(0);
1663 if(mMinX<mX(nbPoint-1)) mMinX=mX(nbPoint-1);
1670 if(abs(mMaxX-mMinX)>1)
1672 const REAL halfrange=(mMaxX-mMinX)/2;
1673 const REAL middle=(mMaxX+mMinX)/2;
1675 const REAL d1=(x0-mMinX)/halfrange;
1676 const REAL d2=(mMaxX-x0)/halfrange;
1677 mMinX= middle-halfrange*(64-abs(dy)*d1)/64.;
1678 mMaxX= middle+halfrange*(64-abs(dy)*d2)/64.;
1683 const REAL halfrange=(mMaxX-mMinX)/2;
1684 const REAL middle=(mMaxX+mMinX)/2;
1685 const REAL d1=(x0-mMinX)/halfrange;
1686 const REAL d2=(mMaxX-x0)/halfrange;
1687 mMinX= middle-halfrange*(64+abs(dy)*d1)/64.;
1688 mMaxX= middle+halfrange*(64+abs(dy)*d2)/64.;
1690 if(mX(nbPoint-1)>mX(0))
1692 if(mMinX<mX(0)) mMinX=mX(0);
1693 if(mMaxX>mX(nbPoint-1)) mMaxX=mX(nbPoint-1);
1697 if(mMinX<mX(nbPoint-1)) mMinX=mX(nbPoint-1);
1698 if(mMaxX>mX(0)) mMaxX=mX(0);
1700 if(mDefaultIntensityScale)
1702 float x0=mMinX,x1=mMaxX;
1703 if(mpPattern->GetPowderPattern().GetRadiation().GetWavelengthType()!=WAVELENGTH_TOF)
1708 long ix0=long(this->mpPattern->GetPowderPattern().X2Pixel(x0));
1709 long ix1=long(this->mpPattern->GetPowderPattern().X2Pixel(x1));
1712 if(ix0>=mX.numElements()) ix0=mX.numElements()-1;
1714 if(ix1>=mX.numElements()) ix1=mX.numElements()-1;
1717 const long ixtmp=ix0;
1721 const long imin=mObs.imin(ix0,ix1);
1722 const long imax=mObs.imax(ix0,ix1);
1723 const long iminc=mCalc.imin(ix0,ix1);
1724 const long imaxc=mCalc.imax(ix0,ix1);
1726 if(mObs(imin)<mCalc(iminc)) mMinIntensity=mObs(imin);
else mMinIntensity=mCalc(iminc);
1727 if(mObs(imax)>mCalc(imaxc)) mMaxIntensity=mObs(imax);
else mMaxIntensity=mCalc(imaxc);
1728 mMaxIntensity=mMaxIntensity+(mMaxIntensity-mMinIntensity)*0.1;
1732 mClockAxisLimits.Click();
1733 wxUpdateUIEvent event(ID_POWDER_GRAPH_NEW_PATTERN);
1734 wxPostEvent(
this,event);
1744 VFN_DEBUG_ENTRY(
"WXPowderPatternGraph::OnMouseWheel()",6)
1745 wxMutexLocker mlock(
mMutex);
1746 const long nbPoint=mX.numElements();
1747 if(event.GetWheelRotation()>=
event.GetWheelDelta())
1749 const REAL range=mMaxX-mMinX;
1751 if(mX(nbPoint-1)>mX(0))
1753 if(mMaxX>=mX(nbPoint-1)) mMaxX=mX(nbPoint-1);
1757 if(mMaxX>=mX(0)) mMaxX=mX(0);
1761 if(event.GetWheelRotation()<=(-
event.GetWheelDelta()))
1763 const REAL range=mMaxX-mMinX;
1765 if(mX(nbPoint-1)>mX(0))
1767 if(mMinX<mX(0)) mMinX=mX(0);
1771 if(mMinX<mX(nbPoint-1)) mMinX=mX(nbPoint-1);
1775 mClockAxisLimits.Click();
1776 wxUpdateUIEvent ev(ID_POWDER_GRAPH_NEW_PATTERN);
1777 wxPostEvent(
this,ev);
1778 VFN_DEBUG_EXIT(
"WXPowderPatternGraph::OnMouseWheel()",6)
1783 VFN_DEBUG_MESSAGE(
"WXPowderPatternGraph::OnUpdate()",6)
1784 mpPattern->CrystUpdate(
true,
true);
1787 void WXPowderPatternGraph::OnToggleLabel(wxCommandEvent &event)
1789 VFN_DEBUG_MESSAGE(
"WXPowderPatternGraph::OnToggleLabel()",6)
1790 if(event.GetId()==ID_POWDERGRAPH_MENU_TOGGPEAK)
1792 mDisplayPeak = !mDisplayPeak;
1793 if(mDisplayPeak) mpPopUpMenu->SetLabel(ID_POWDERGRAPH_MENU_TOGGPEAK, _T(
"Hide peaks"));
1794 else mpPopUpMenu->SetLabel(ID_POWDERGRAPH_MENU_TOGGPEAK, _T(
"Show peaks"));
1796 if(event.GetId()==ID_POWDERGRAPH_MENU_TOGGLELABEL)
1798 mDisplayLabel = !mDisplayLabel;
1799 if(mDisplayLabel) mpPopUpMenu->SetLabel(ID_POWDERGRAPH_MENU_TOGGLELABEL, _T(
"Hide labels"));
1800 else mpPopUpMenu->SetLabel(ID_POWDERGRAPH_MENU_TOGGLELABEL, _T(
"Show labels"));
1802 this->Refresh(
false);
1805 void WXPowderPatternGraph::OnFindPeaks(wxCommandEvent& WXUNUSED(event))
1810 mPeakList=mpPattern->GetPowderPattern().FindPeaks(dmin,-1,1000);
1812 if((mPeakList.GetPeakList().size()>30)||(dmin<0.3))
break;
1815 const unsigned int nb=mPeakList.GetPeakList().size();
1818 mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_SAVEPEAKS, TRUE);
1819 mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_TOGGPEAK, TRUE);
1820 mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_INDEX, TRUE);
1821 mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_ADDPEAK, TRUE);
1822 mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_REMOVEPEAK, TRUE);
1825 if(mPeakList.GetPeakList().size()>40) mPeakList.GetPeakList().resize(40);
1829 CrystVector_REAL obsd2;
1830 obsd2=SavitzkyGolay(mObs,4,2);
1831 const float norm=-obsd2.min();
1838 this->Refresh(
false);
1841 void WXPowderPatternGraph::OnLoadPeaks(wxCommandEvent& WXUNUSED(event))
1843 wxFileDialog fn(
this,_T(
"Choose a file"),_T(
""),_T(
""),_T(
"*"),wxFD_OPEN);
1844 if(fn.ShowModal() != wxID_OK)
return;
1845 ifstream f(fn.GetPath().ToAscii());
1847 mPeakList.GetPeakList().clear();
1848 mPeakList.ImportDhklDSigmaIntensity(f);
1851 mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_SAVEPEAKS, TRUE);
1852 mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_TOGGPEAK, TRUE);
1853 mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_INDEX, TRUE);
1854 mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_ADDPEAK, TRUE);
1855 mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_REMOVEPEAK, TRUE);
1856 this->Refresh(
false);
1859 void WXPowderPatternGraph::OnSavePeaks(wxCommandEvent& WXUNUSED(event))
1861 wxFileDialog save(
this,_T(
"Choose a file"),_T(
""),_T(
""),_T(
"*.txt"),wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
1862 if(save.ShowModal() != wxID_OK)
return;
1864 ofstream out(save.GetPath().ToAscii());
1866 mPeakList.ExportDhklDSigmaIntensity(out);
1873 if(event.GetId()==ID_POWDERGRAPH_MENU_REMOVEPEAK)
1876 const float d=2*mpPattern->GetPowderPattern().X2STOL(this->Screen2DataX((
long)mDraggingX0)*DEG2RAD);
1878 for(
unsigned int i=0;i<mPeakList.GetPeakList().size();++i)
1880 float x=mpPattern->GetPowderPattern().STOL2X(mPeakList.GetPeakList()[i].dobs/2);
1881 if(mpPattern->GetPowderPattern().GetRadiation().GetWavelengthType()!=WAVELENGTH_TOF)
1883 x=this->Data2ScreenX(x);
1884 if(abs(x-mDraggingX0)<dist)
1886 dist=abs(x-mDraggingX0);
1889 cout<<__FILE__<<
":"<<__LINE__<<
": 1/d0="<<d<<
" peak #"<<i<<
",d="<<1/mPeakList.GetPeakList()[i].dobs
1890 <<
"("<<mDraggingX0<<
","<<x<<
"), mindist="<<dist<<endl;
1892 if(dist>5) mpParentFrame->SetStatusText(_T(
"Could not find peak close enough"),1);
1895 if(mPeakList.GetPeakList().size()<5) mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_INDEX, FALSE);
1896 if(mPeakList.GetPeakList().size()==0)
1898 mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_TOGGPEAK, FALSE);
1899 mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_SAVEPEAKS, FALSE);
1900 mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_REMOVEPEAK, FALSE);
1903 buf.Printf(_T(
"Removing peak at d=%6.3f"),1/mPeakList.GetPeakList()[idx].dobs);
1904 mpParentFrame->SetStatusText(buf,1);
1905 mPeakList.RemovePeak(idx);
1906 this->Refresh(
false);
1909 if(event.GetId()==ID_POWDERGRAPH_MENU_ADDPEAK)
1912 if(mpPattern->GetPowderPattern().GetRadiation().GetWavelengthType()!=WAVELENGTH_TOF)
1914 d = 2*mpPattern->GetPowderPattern().X2STOL(this->Screen2DataX((
long)mDraggingX0 )*DEG2RAD);
1916 long x1=(long)(mpPattern->GetPowderPattern().STOL2Pixel(d/2));
1918 sig=2*abs( mpPattern->GetPowderPattern().X2STOL(mpPattern->GetPowderPattern().GetPowderPatternX()(x1 ))
1919 -mpPattern->GetPowderPattern().X2STOL(mpPattern->GetPowderPattern().GetPowderPatternX()(x1-1)));
1923 d = 2*mpPattern->GetPowderPattern().X2STOL(this->Screen2DataX((
long)mDraggingX0 ));
1924 long x1=(long)(mpPattern->GetPowderPattern().STOL2Pixel(d/2));
1925 cout<<__FILE__<<
":"<<__LINE__<<
":"<<x1<<endl;
1927 sig=2*abs( mpPattern->GetPowderPattern().X2STOL(mpPattern->GetPowderPattern().GetPowderPatternX()(x1 ))
1928 -mpPattern->GetPowderPattern().X2STOL(mpPattern->GetPowderPattern().GetPowderPatternX()(x1-1)));
1929 cout<<__FILE__<<
":"<<__LINE__<<
":"<<sig<<endl;
1932 mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_SAVEPEAKS, TRUE);
1933 mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_TOGGPEAK, TRUE);
1934 if(mPeakList.GetPeakList().size()>=5) mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_INDEX, TRUE);
1935 mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_REMOVEPEAK, TRUE);
1938 buf.Printf(_T(
"Added peak at d=%6.3f"),1/d);
1939 mPeakList.AddPeak(d,1.0,sig);
1940 mpParentFrame->SetStatusText(buf,1);
1941 this->Refresh(
false);
1942 mPeakList.Print(cout);
1947 class WXCellExplorer:
public wxWindow
1953 void OnIndex(wxCommandEvent &event);
1955 void OnSelectCell(wxCommandEvent &event);
1957 void OnApplyCell(wxCommandEvent &event);
1959 void OnChooseCrystal(wxCommandEvent &event);
1962 void OnAutoLeBail(wxCommandEvent &event);
1967 wxRadioBox *mpAlgorithm;
1968 wxRadioBox *mpBravais;
1971 wxTextCtrl *mpLengthMin,*mpLengthMax;
1972 wxTextCtrl *mpAngleMin,*mpAngleMax;
1973 wxTextCtrl *mpVolumeMin,*mpVolumeMax;
1974 wxTextCtrl *mpNbSpurious;
1975 wxTextCtrl *mpNbPeak;
1976 wxTextCtrl *mpErrorD;
1978 wxTextCtrl *mpStopOnScore,*mpStopOnDepth;
1979 wxTextCtrl *mpReportOnScore,*mpReportOnDepth;
1982 wxCheckBox *mpWeakDiffraction;
1983 wxCheckBox *mpContinueOnSolution;
1984 wxCheckBox *mpTryCenteredLattice;
1985 wxCheckBox *mpAutomaticLeBail;
1986 DECLARE_EVENT_TABLE()
1988 static const long ID_CELLEXPLORER_INDEX= WXCRYST_ID();
1989 static const long ID_CELLEXPLORER_INDEX_QUICK= WXCRYST_ID();
1990 static const long ID_CELLEXPLORER_WEAK= WXCRYST_ID();
1991 static const long ID_CELLEXPLORER_SELECTCELL= WXCRYST_ID();
1992 static const long ID_CELLEXPLORER_APPLYCELL= WXCRYST_ID();
1993 static const long ID_CELLEXPLORER_CHOOSECRYSTAL= WXCRYST_ID();
1994 static const long ID_CELLEXPLORER_LEBAIL= WXCRYST_ID();
1995 static const long ID_CELLEXPLORER_CENTERED= WXCRYST_ID();
1997 BEGIN_EVENT_TABLE(WXCellExplorer, wxWindow)
1998 EVT_BUTTON(ID_CELLEXPLORER_INDEX, WXCellExplorer::OnIndex)
1999 EVT_BUTTON(ID_CELLEXPLORER_INDEX_QUICK, WXCellExplorer::OnIndex)
2000 EVT_LISTBOX(ID_CELLEXPLORER_SELECTCELL, WXCellExplorer::OnSelectCell)
2001 EVT_LISTBOX_DCLICK(ID_CELLEXPLORER_SELECTCELL,WXCellExplorer::OnApplyCell)
2002 EVT_BUTTON(ID_CELLEXPLORER_APPLYCELL, WXCellExplorer::OnApplyCell)
2003 EVT_BUTTON(ID_CELLEXPLORER_CHOOSECRYSTAL, WXCellExplorer::OnChooseCrystal)
2004 EVT_CHECKBOX(ID_CELLEXPLORER_LEBAIL, WXCellExplorer::OnAutoLeBail)
2007 WXCellExplorer::WXCellExplorer(wxWindow *parent, PeakList &peaklist, WXPowderPatternGraph *graph):
2008 wxWindow(parent,-1),mpGraph(graph),mpPeakList(&peaklist),mpCellExplorer(0),mpCrystal(0),mpDiff(0)
2010 wxBoxSizer *pSizer1=
new wxBoxSizer(wxHORIZONTAL);
2011 this->SetSizer(pSizer1);
2013 wxNotebook *pNotebook =
new wxNotebook(
this, -1);
2015 pSizer1->Add(pNotebook,0,wxALIGN_TOP);
2018 wxWindow *pQuick=
new wxWindow(pNotebook,-1);
2019 pNotebook->AddPage(pQuick,_T(
"Quick"));
2021 wxStaticBoxSizer *pSizerQuick=
new wxStaticBoxSizer(wxVERTICAL,pQuick);
2023 wxButton *pQuickButtonIndex=
new wxButton(pQuick,ID_CELLEXPLORER_INDEX_QUICK,_T(
"Find cell!"));
2024 pSizerQuick->Add(pQuickButtonIndex,0,wxALIGN_CENTER);
2026 mpWeakDiffraction=
new wxCheckBox(pQuick,ID_CELLEXPLORER_WEAK,_T(
"Weak Diffraction (scan larger volume)"));
2027 pSizerQuick->Add(mpWeakDiffraction,0,wxALIGN_CENTER);
2029 mpContinueOnSolution=
new wxCheckBox(pQuick,ID_CELLEXPLORER_WEAK,_T(
"Continue exploring after solution"));
2030 pSizerQuick->Add(mpContinueOnSolution,0,wxALIGN_CENTER);
2032 mpTryCenteredLattice=
new wxCheckBox(pQuick,ID_CELLEXPLORER_CENTERED,_T(
"Try Centered Lattices"));
2033 pSizerQuick->Add(mpTryCenteredLattice,0,wxALIGN_CENTER);
2035 pQuick->SetSizer(pSizerQuick);
2036 pSizerQuick->Fit(pQuick);
2037 pSizerQuick->RecalcSizes();
2040 wxWindow *pAdvanced=
new wxWindow(pNotebook,-1);
2042 wxStaticBoxSizer *pSizerAdvanced=
new wxStaticBoxSizer(wxVERTICAL,pAdvanced);
2044 wxButton *pButton1=
new wxButton(pAdvanced,ID_CELLEXPLORER_INDEX,_T(
"Find cell!"));
2045 pSizerAdvanced->Add(pButton1,0,wxALIGN_CENTER);
2047 wxBoxSizer *pLengthSizer=
new wxBoxSizer(wxHORIZONTAL);
2048 wxStaticText *pLengthText=
new wxStaticText(pAdvanced,-1,_T(
"Length min, max (A):"));
2049 pLengthSizer->Add(pLengthText,0,wxALIGN_CENTER);
2050 mpLengthMin=
new wxTextCtrl(pAdvanced,-1,_T(
"3"),wxDefaultPosition,wxSize(30,-1),0,
2051 wxTextValidator(wxFILTER_NUMERIC));
2052 pLengthSizer->Add(mpLengthMin,0,wxALIGN_CENTER);
2053 mpLengthMax=
new wxTextCtrl(pAdvanced,-1,_T(
"25"),wxDefaultPosition,wxSize(30,-1),0,
2054 wxTextValidator(wxFILTER_NUMERIC));
2055 pLengthSizer->Add(mpLengthMax,0,wxALIGN_CENTER);
2056 pSizerAdvanced->Add(pLengthSizer,0,wxALIGN_CENTER);
2058 wxBoxSizer *pAngleSizer=
new wxBoxSizer(wxHORIZONTAL);
2059 wxStaticText *pAngleText=
new wxStaticText(pAdvanced,-1,_T(
"Angle max(90< <179):"));
2060 pAngleSizer->Add(pAngleText,0,wxALIGN_CENTER);
2064 mpAngleMax=
new wxTextCtrl(pAdvanced,-1,_T(
"130"),wxDefaultPosition,wxSize(40,-1),0,
2065 wxTextValidator(wxFILTER_NUMERIC));
2066 pAngleSizer->Add(mpAngleMax,0,wxALIGN_CENTER);
2067 pSizerAdvanced->Add(pAngleSizer,0,wxALIGN_CENTER);
2069 wxBoxSizer *pVolumeSizer=
new wxBoxSizer(wxHORIZONTAL);
2070 wxStaticText *pVolumeText=
new wxStaticText(pAdvanced,-1,_T(
"Volume min, max (A3):"));
2071 pVolumeSizer->Add(pVolumeText,0,wxALIGN_CENTER);
2072 mpVolumeMin=
new wxTextCtrl(pAdvanced,-1,_T(
"10"),wxDefaultPosition,wxSize(50,-1),0,
2073 wxTextValidator(wxFILTER_NUMERIC));
2074 pVolumeSizer->Add(mpVolumeMin,0,wxALIGN_CENTER);
2075 mpVolumeMax=
new wxTextCtrl(pAdvanced,-1,_T(
"2500"),wxDefaultPosition,wxSize(50,-1),0,
2076 wxTextValidator(wxFILTER_NUMERIC));
2077 pVolumeSizer->Add(mpVolumeMax,0,wxALIGN_CENTER);
2078 pSizerAdvanced->Add(pVolumeSizer,0,wxALIGN_CENTER);
2080 wxBoxSizer *pSpuriousSizer=
new wxBoxSizer(wxHORIZONTAL);
2081 wxStaticText *pSpuriousText=
new wxStaticText(pAdvanced,-1,_T(
"Nb spurious lines:"));
2082 pSpuriousSizer->Add(pSpuriousText,0,wxALIGN_CENTER);
2083 mpNbSpurious=
new wxTextCtrl(pAdvanced,-1,_T(
"0"),wxDefaultPosition,wxSize(40,-1),0,
2084 wxTextValidator(wxFILTER_NUMERIC));
2085 pSpuriousSizer->Add(mpNbSpurious,0,wxALIGN_CENTER);
2086 pSizerAdvanced->Add(pSpuriousSizer,0,wxALIGN_CENTER);
2088 wxBoxSizer *pNbPeakSizer=
new wxBoxSizer(wxHORIZONTAL);
2089 wxStaticText *pNbPeakText=
new wxStaticText(pAdvanced,-1,_T(
"Use Nb Peaks:"));
2090 pNbPeakSizer->Add(pNbPeakText,0,wxALIGN_CENTER);
2091 mpNbPeak=
new wxTextCtrl(pAdvanced,-1,_T(
"20"),wxDefaultPosition,wxSize(40,-1),0,
2092 wxTextValidator(wxFILTER_NUMERIC));
2093 pNbPeakSizer->Add(mpNbPeak,0,wxALIGN_CENTER);
2094 pSizerAdvanced->Add(pNbPeakSizer,0,wxALIGN_CENTER);
2096 wxBoxSizer *pStopSizer=
new wxBoxSizer(wxHORIZONTAL);
2097 wxStaticText* pStopOnScoreText=
new wxStaticText(pAdvanced,-1,_T(
"Stop on Score>"));
2098 pStopSizer->Add(pStopOnScoreText,0,wxALIGN_CENTER);
2099 mpStopOnScore=
new wxTextCtrl(pAdvanced,-1,_T(
"50"),wxDefaultPosition,wxSize(50,-1),0,
2100 wxTextValidator(wxFILTER_NUMERIC));
2101 pStopSizer->Add(mpStopOnScore,0,wxALIGN_CENTER);
2103 wxStaticText* pStopOnDepthText=
new wxStaticText(pAdvanced,-1,_T(
"and depth>="));
2104 pStopSizer->Add(pStopOnDepthText,0,wxALIGN_CENTER);
2105 mpStopOnDepth=
new wxTextCtrl(pAdvanced,-1,_T(
"6"),wxDefaultPosition,wxSize(30,-1),0,
2106 wxTextValidator(wxFILTER_NUMERIC));
2107 pStopSizer->Add(mpStopOnDepth,0,wxALIGN_CENTER);
2108 pSizerAdvanced->Add(pStopSizer,0,wxALIGN_CENTER);
2111 wxBoxSizer *pReportSizer=
new wxBoxSizer(wxHORIZONTAL);
2112 wxStaticText* pReportOnScoreText=
new wxStaticText(pAdvanced,-1,_T(
"Report score>"));
2113 pReportSizer->Add(pReportOnScoreText,0,wxALIGN_CENTER);
2114 mpReportOnScore=
new wxTextCtrl(pAdvanced,-1,_T(
"10"),wxDefaultPosition,wxSize(50,-1),0,
2115 wxTextValidator(wxFILTER_NUMERIC));
2116 pReportSizer->Add(mpReportOnScore,0,wxALIGN_CENTER);
2118 wxStaticText* pReportOnDepthText=
new wxStaticText(pAdvanced,-1,_T(
"or depth>="));
2119 pReportSizer->Add(pReportOnDepthText,0,wxALIGN_CENTER);
2120 mpReportOnDepth=
new wxTextCtrl(pAdvanced,-1,_T(
"4"),wxDefaultPosition,wxSize(50,-1),0,
2121 wxTextValidator(wxFILTER_NUMERIC));
2122 pReportSizer->Add(mpReportOnDepth,0,wxALIGN_CENTER);
2123 pSizerAdvanced->Add(pReportSizer,0,wxALIGN_CENTER);
2125 wxBoxSizer *pErrorSizer=
new wxBoxSizer(wxHORIZONTAL);
2126 wxStaticText* pErrorText=
new wxStaticText(pAdvanced,-1,_T(
"delta(d)/d^2 error:"));
2127 pErrorSizer->Add(pErrorText,0,wxALIGN_CENTER);
2128 mpErrorD=
new wxTextCtrl(pAdvanced,-1,_T(
"0"),wxDefaultPosition,wxSize(50,-1),0,
2129 wxTextValidator(wxFILTER_NUMERIC));
2130 pErrorSizer->Add(mpErrorD,0,wxALIGN_CENTER);
2131 pSizerAdvanced->Add(pErrorSizer,0,wxALIGN_CENTER);
2133 wxArrayString bravaisChoices;
2134 bravaisChoices.Add(_T(
"Triclinic"));
2135 bravaisChoices.Add(_T(
"Monoclinic"));
2136 bravaisChoices.Add(_T(
"Orthorombic"));
2137 bravaisChoices.Add(_T(
"Hexagonal"));
2138 bravaisChoices.Add(_T(
"Rhomboedral"));
2139 bravaisChoices.Add(_T(
"Tetragonal"));
2140 bravaisChoices.Add(_T(
"Cubic"));
2141 mpBravais=
new wxRadioBox((wxWindow*)pAdvanced,-1,_T(
"Crystal System"),wxDefaultPosition,wxDefaultSize,bravaisChoices,0,wxRA_SPECIFY_ROWS);
2142 mpBravais->SetSelection(2);
2144 pSizerAdvanced->Add(mpBravais,0,wxALIGN_CENTER);
2146 wxArrayString algoChoices;
2147 algoChoices.Add(_T(
"DICVOL"));
2150 mpAlgorithm=
new wxRadioBox(pAdvanced,-1,_T(
"Algorithm"),wxDefaultPosition,wxDefaultSize,algoChoices,0,wxRA_SPECIFY_ROWS);
2151 mpAlgorithm->Enable(1,
false);
2152 pSizerAdvanced->Add(mpAlgorithm,0,wxALIGN_CENTER);
2154 pAdvanced->SetSizer(pSizerAdvanced);
2155 pSizerAdvanced->Fit(pAdvanced);
2156 pSizerAdvanced->RecalcSizes();
2157 pAdvanced->Layout();
2159 pNotebook->AddPage(pAdvanced,_T(
"Advanced"));
2161 pNotebook->Layout();
2163 wxBoxSizer *pSizer2=
new wxBoxSizer(wxVERTICAL);
2168 mpFieldCrystal=
new WXFieldChoice(
this,ID_CELLEXPLORER_CHOOSECRYSTAL,
"Choose crystal to apply selected cell to:",200);
2169 pSizer2->Add(mpFieldCrystal,0,wxALIGN_CENTER);
2171 mpAutomaticLeBail=
new wxCheckBox(
this,ID_CELLEXPLORER_LEBAIL,_T(
"Automatic Profile Fitting (Le Bail)"));
2172 pSizer2->Add(mpAutomaticLeBail,0,wxALIGN_CENTER);
2174 wxArrayString cells;
2175 mpCell=
new wxListBox(
this,ID_CELLEXPLORER_SELECTCELL,wxDefaultPosition,wxSize(750,400),cells,wxLB_SINGLE);
2176 mpCell->SetFont(wxFont(9,wxTELETYPE,wxFONTSTYLE_NORMAL,wxFONTWEIGHT_NORMAL));
2177 pSizer2->Add(mpCell,0,wxALIGN_CENTER);
2179 mpLog =
new wxTextCtrl(
this,-1,_T(
""),wxDefaultPosition,wxSize(750,250),wxTE_MULTILINE|wxTE_READONLY|wxTE_DONTWRAP);
2180 mpLog->SetFont(wxFont(9,wxTELETYPE,wxFONTSTYLE_NORMAL,wxFONTWEIGHT_NORMAL));
2181 pSizer2->Add(mpLog,0,wxALIGN_CENTER);
2183 pSizer1->Add(pSizer2,0,wxALIGN_TOP);
2186 pSizer1->Fit(this->GetParent());
2187 pSizer1->SetSizeHints(
this);
2191 unsigned int nb=mpPeakList->GetPeakList().size();
2193 const float dmin=mpPeakList->GetPeakList()[nb-1].dobs;
2194 const float dmax=mpPeakList->GetPeakList()[0].dobs/10;
2195 mpLog->AppendText(wxString::Format(_T(
"Predicted unit vell volume from %2u observed peaks between: dmax=%6.3f A-> dmin=%6.3fA\n"),nb,1/dmax,1/dmin));
2196 mpLog->AppendText(wxString::Format(_T(
"(Assuming observed lines represent 120%% down to 30%% of existing reflections)\n")));
2197 mpLog->AppendText(wxString::Format(_T(
" Cubic P v=%6.0f -> %6.0f A\n"),
EstimateCellVolume(dmin,dmax,nb,CUBIC ,LATTICE_P,1.2),
EstimateCellVolume(dmin,dmax,nb,CUBIC ,LATTICE_P,0.3)));
2198 mpLog->AppendText(wxString::Format(_T(
" Cubic I v=%6.0f -> %6.0f A\n"),
EstimateCellVolume(dmin,dmax,nb,CUBIC ,LATTICE_I,1.2),
EstimateCellVolume(dmin,dmax,nb,CUBIC ,LATTICE_I,0.3)));
2199 mpLog->AppendText(wxString::Format(_T(
" Cubic F v=%6.0f -> %6.0f A\n"),
EstimateCellVolume(dmin,dmax,nb,CUBIC ,LATTICE_F,1.2),
EstimateCellVolume(dmin,dmax,nb,CUBIC ,LATTICE_F,0.3)));
2200 mpLog->AppendText(wxString::Format(_T(
" Tetragonal P v=%6.0f -> %6.0f A\n"),
EstimateCellVolume(dmin,dmax,nb,TETRAGONAL ,LATTICE_P,1.2),
EstimateCellVolume(dmin,dmax,nb,TETRAGONAL ,LATTICE_P,0.3)));
2201 mpLog->AppendText(wxString::Format(_T(
" Tetragonal I v=%6.0f -> %6.0f A\n"),
EstimateCellVolume(dmin,dmax,nb,TETRAGONAL ,LATTICE_I,1.2),
EstimateCellVolume(dmin,dmax,nb,TETRAGONAL ,LATTICE_I,0.3)));
2202 mpLog->AppendText(wxString::Format(_T(
" Orthorombic P v=%6.0f -> %6.0f A\n"),
EstimateCellVolume(dmin,dmax,nb,ORTHOROMBIC,LATTICE_P,1.2),
EstimateCellVolume(dmin,dmax,nb,ORTHOROMBIC,LATTICE_P,0.3)));
2203 mpLog->AppendText(wxString::Format(_T(
" Orthorombic I,C v=%6.0f -> %6.0f A\n"),
EstimateCellVolume(dmin,dmax,nb,ORTHOROMBIC,LATTICE_I,1.2),
EstimateCellVolume(dmin,dmax,nb,ORTHOROMBIC,LATTICE_I,0.3)));
2204 mpLog->AppendText(wxString::Format(_T(
" Orthorombic F v=%6.0f -> %6.0f A\n"),
EstimateCellVolume(dmin,dmax,nb,ORTHOROMBIC,LATTICE_F,1.2),
EstimateCellVolume(dmin,dmax,nb,ORTHOROMBIC,LATTICE_I,0.3)));
2205 mpLog->AppendText(wxString::Format(_T(
" Hexagonal v=%6.0f -> %6.0f A\n"),
EstimateCellVolume(dmin,dmax,nb,HEXAGONAL ,LATTICE_P,1.2),
EstimateCellVolume(dmin,dmax,nb,HEXAGONAL ,LATTICE_P,0.3)));
2206 mpLog->AppendText(wxString::Format(_T(
" Monoclinic P v=%6.0f -> %6.0f A\n"),
EstimateCellVolume(dmin,dmax,nb,MONOCLINIC ,LATTICE_P,1.2),
EstimateCellVolume(dmin,dmax,nb,MONOCLINIC ,LATTICE_P,0.3)));
2207 mpLog->AppendText(wxString::Format(_T(
" Monoclinic C v=%6.0f -> %6.0f A\n"),
EstimateCellVolume(dmin,dmax,nb,MONOCLINIC ,LATTICE_C,1.2),
EstimateCellVolume(dmin,dmax,nb,MONOCLINIC ,LATTICE_C,0.3)));
2208 mpLog->AppendText(wxString::Format(_T(
" Triclinic v=%6.0f -> %6.0f A\n"),
EstimateCellVolume(dmin,dmax,nb,TRICLINIC ,LATTICE_P,1.2),
EstimateCellVolume(dmin,dmax,nb,TRICLINIC ,LATTICE_P,0.3)));
2211 WXCellExplorer::~WXCellExplorer()
2215 mpDiff->SetExtractionMode(
false,
false);
2216 mpDiff->UpdateDisplay();
2220 void WXCellExplorer::OnIndex(wxCommandEvent &event)
2224 if(event.GetId()==ID_CELLEXPLORER_INDEX_QUICK)
2227 for(vector<PeakList::hkl>::iterator pos=mpPeakList->mvHKL.begin();pos!=mpPeakList->mvHKL.end();++pos)
2228 pos->isSpurious=
false;
2231 PeakList peaklist=*mpPeakList;
2232 if(peaklist.GetPeakList().size()>20) peaklist.GetPeakList().resize(20);
2236 unsigned int nb=mpPeakList->GetPeakList().size();
2238 float dmin=mpPeakList->GetPeakList()[nb-1].dobs;
2239 const float dmax=mpPeakList->GetPeakList()[0].dobs/10;
2240 mpLog->AppendText(wxString::Format(_T(
"Predicting volumes from %2u peaks between d=%6.3f and d=%6.3f\n"),nb,1/dmax,1/dmin));
2241 mpLog->AppendText(wxString::Format(_T(
"Starting indexing using %2u peaks\n"),nb));
2243 mpCellExplorer =
new CellExplorer(peaklist,CUBIC,0);
2244 mpCellExplorer->SetLengthMinMax(3,25);
2245 mpCellExplorer->SetAngleMinMax(90*DEG2RAD,140*DEG2RAD);
2246 mpCellExplorer->SetD2Error(0);
2249 if(mpWeakDiffraction->GetValue()) weak_f=0.5;
2250 const bool continueOnSolution=mpContinueOnSolution->GetValue();
2252 const bool noCentered=!(mpTryCenteredLattice->GetValue());
2254 const float stopOnScore=50, reportOnScore=10;
2255 const unsigned int stopOnDepth=6+int(continueOnSolution), reportOnDepth=4;
2257 unsigned int nbSpurious=0;
2258 wxProgressDialog dlgProgress(_T(
"Indexing..."),_T(
"Starting Indexing in Quick Mode"),
2259 7,
this,wxPD_AUTO_HIDE|wxPD_ELAPSED_TIME|wxPD_CAN_ABORT);
2260 while(nbSpurious<=3)
2262 float t0,minv,maxv,lengthmax;
2263 mpCellExplorer->SetNbSpurious(nbSpurious);
2264 CrystalCentering cent;
2266 for(
int lat=0;lat<=2;++lat)
2270 case 0:cent=LATTICE_P;centc=
'P';
break;
2271 case 1:cent=LATTICE_I;centc=
'I';
break;
2272 case 2:cent=LATTICE_F;centc=
'F';
break;
2276 mpCellExplorer->SetVolumeMinMax(minv,maxv);
2277 lengthmax=pow(maxv,(
float)(1/3.0))*3;
2278 if(lengthmax<25)lengthmax=25;
2279 mpCellExplorer->SetLengthMinMax(3,lengthmax);
2280 mpCellExplorer->SetCrystalSystem(CUBIC);
2281 mpCellExplorer->SetCrystalCentering(cent);
2282 mpLog->AppendText(wxString::Format(_T(
"CUBIC %c : V= %6.0f -> %6.0f A^3, max length=%6.2fA"),centc,minv,maxv,lengthmax));
2283 t0=chrono.seconds();
2284 if(dlgProgress.Update(0,wxString::Format(_T(
"CUBIC %c (%u spurious), V=%6.0f-%6.0f, l<%6.2fA\n")
2285 _T(
"Best Score=%6.1f"),centc,
2286 nbSpurious,minv,maxv,lengthmax,mpCellExplorer->GetBestScore()))==
false)
break;
2287 mpCellExplorer->DicVol(reportOnScore,reportOnDepth,stopOnScore,stopOnDepth);
2288 mpLog->AppendText(wxString::Format(_T(
" -> %3u sols in %6.2fs, best score=%6.1f\n"),
2289 (
unsigned int)(mpCellExplorer->GetSolutions().size()),chrono.seconds()-t0,mpCellExplorer->GetBestScore()));
2291 if(noCentered)
break;
2293 for(
int lat=0;lat<=1;++lat)
2294 if((mpCellExplorer->GetBestScore()<=stopOnScore)||continueOnSolution)
2298 case 0:cent=LATTICE_P;centc=
'P';
break;
2299 case 1:cent=LATTICE_I;centc=
'I';
break;
2303 mpCellExplorer->SetVolumeMinMax(minv,maxv);
2304 float lengthmax=pow(maxv,(
float)(1/3.0))*3;
2305 if(lengthmax<25)lengthmax=25;
2306 mpCellExplorer->SetLengthMinMax(3,lengthmax);
2307 mpCellExplorer->SetCrystalSystem(TETRAGONAL);
2308 mpCellExplorer->SetCrystalCentering(cent);
2309 mpLog->AppendText(wxString::Format(_T(
"TETRAGONAL %c : V= %6.0f -> %6.0f A^3, max length=%6.2fA"),centc,minv,maxv,lengthmax));
2310 t0=chrono.seconds();
2311 if(dlgProgress.Update(1,wxString::Format(_T(
"TETRAGONAL %c (%u spurious), V=%6.0f-%6.0f, l<%6.2fA\n")
2312 _T(
"Best Score=%6.1f"),centc,
2313 nbSpurious,minv,maxv,lengthmax,mpCellExplorer->GetBestScore()))==
false)
break;
2314 mpCellExplorer->DicVol(reportOnScore,reportOnDepth,stopOnScore,stopOnDepth);
2315 mpLog->AppendText(wxString::Format(_T(
" -> %3u sols in %6.2fs, best score=%6.1f\n"),
2316 (
unsigned int)(mpCellExplorer->GetSolutions().size()),chrono.seconds()-t0,mpCellExplorer->GetBestScore()));
2318 if(noCentered)
break;
2320 if((mpCellExplorer->GetBestScore()<=stopOnScore)||continueOnSolution)
2324 mpCellExplorer->SetVolumeMinMax(minv,maxv);
2325 lengthmax=pow(maxv,(
float)(1/3.0))*3;
2326 if(lengthmax<25)lengthmax=25;
2327 mpCellExplorer->SetLengthMinMax(3,lengthmax);
2328 mpCellExplorer->SetCrystalSystem(RHOMBOEDRAL);
2329 mpCellExplorer->SetCrystalCentering(LATTICE_P);
2330 mpLog->AppendText(wxString::Format(_T(
"RHOMBOEDRAL : V= %6.0f -> %6.0f A^3, max length=%6.2fA"),minv,maxv,lengthmax));
2331 t0=chrono.seconds();
2332 if(dlgProgress.Update(2,wxString::Format(_T(
"RHOMBOEDRAL (%u spurious), V=%6.0f-%6.0f, l<%6.2fA\n")
2333 _T(
"Best Score=%6.1f"),
2334 nbSpurious,minv,maxv,lengthmax,mpCellExplorer->GetBestScore()))==
false)
break;
2335 mpCellExplorer->DicVol(reportOnScore,reportOnDepth,stopOnScore,stopOnDepth);
2336 mpLog->AppendText(wxString::Format(_T(
" -> %3u sols in %6.2fs, best score=%6.1f\n"),
2337 (
unsigned int)(mpCellExplorer->GetSolutions().size()),chrono.seconds()-t0,mpCellExplorer->GetBestScore()));
2340 if((mpCellExplorer->GetBestScore()<=stopOnScore)||continueOnSolution)
2344 mpCellExplorer->SetVolumeMinMax(minv,maxv);
2345 lengthmax=pow(maxv,(
float)(1/3.0))*3;
2346 if(lengthmax<25)lengthmax=25;
2347 mpCellExplorer->SetLengthMinMax(3,lengthmax);
2348 mpCellExplorer->SetCrystalSystem(HEXAGONAL);
2349 mpCellExplorer->SetCrystalCentering(LATTICE_P);
2350 mpLog->AppendText(wxString::Format(_T(
"HEXAGONAL : V= %6.0f -> %6.0f A^3, max length=%6.2fA"),minv,maxv,lengthmax));
2351 t0=chrono.seconds();
2352 if(dlgProgress.Update(3,wxString::Format(_T(
"HEXAGONAL (%u spurious), V=%6.0f-%6.0f, l<%6.2fA\n")
2353 _T(
"Best Score=%6.1f"),
2354 nbSpurious,minv,maxv,lengthmax,mpCellExplorer->GetBestScore()))==
false)
break;
2355 mpCellExplorer->DicVol(reportOnScore,reportOnDepth,stopOnScore,stopOnDepth);
2356 mpLog->AppendText(wxString::Format(_T(
" -> %3u sols in %6.2fs, best score=%6.1f\n"),
2357 (
unsigned int)(mpCellExplorer->GetSolutions().size()),chrono.seconds()-t0,mpCellExplorer->GetBestScore()));
2360 for(
int lat=0;lat<=5;++lat)
2361 if((mpCellExplorer->GetBestScore()<=stopOnScore)||continueOnSolution)
2365 case 0:cent=LATTICE_P;centc=
'P';
break;
2366 case 1:cent=LATTICE_I;centc=
'I';
break;
2367 case 2:cent=LATTICE_A;centc=
'A';
break;
2368 case 3:cent=LATTICE_B;centc=
'B';
break;
2369 case 4:cent=LATTICE_C;centc=
'C';
break;
2370 case 5:cent=LATTICE_F;centc=
'F';
break;
2374 mpCellExplorer->SetVolumeMinMax(minv,maxv);
2375 lengthmax=pow(maxv,(
float)(1/3.0))*3;
2376 if(lengthmax<25)lengthmax=25;
2377 mpCellExplorer->SetLengthMinMax(3,lengthmax);
2378 mpCellExplorer->SetCrystalSystem(ORTHOROMBIC);
2379 mpCellExplorer->SetCrystalCentering(cent);
2380 mpLog->AppendText(wxString::Format(_T(
"ORTHOROMBIC %c: V= %6.0f -> %6.0f A^3, max length=%6.2fA"),centc,minv,maxv,lengthmax));
2381 t0=chrono.seconds();
2382 if(dlgProgress.Update(4,wxString::Format(_T(
"ORTHOROMBIC %c (%u spurious), V=%6.0f-%6.0f, l<%6.2fA\n")
2383 _T(
"Best Score=%6.1f"),centc,
2384 nbSpurious,minv,maxv,lengthmax,mpCellExplorer->GetBestScore()))==
false)
break;
2385 mpCellExplorer->DicVol(reportOnScore,reportOnDepth,stopOnScore,stopOnDepth);
2386 mpLog->AppendText(wxString::Format(_T(
" -> %3u sols in %6.2fs, best score=%6.1f\n"),
2387 (
unsigned int)(mpCellExplorer->GetSolutions().size()),chrono.seconds()-t0,mpCellExplorer->GetBestScore()));
2389 if(noCentered)
break;
2391 for(
int lat=0;lat<=3;++lat)
2392 if((mpCellExplorer->GetBestScore()<=stopOnScore)||continueOnSolution)
2396 case 0:cent=LATTICE_P;centc=
'P';
break;
2397 case 1:cent=LATTICE_C;centc=
'C';
break;
2398 case 2:cent=LATTICE_I;centc=
'I';
break;
2399 case 3:cent=LATTICE_A;centc=
'A';
break;
2403 mpCellExplorer->SetVolumeMinMax(minv,maxv);
2404 lengthmax=pow(maxv,(
float)(1/3.0))*3;
2405 if(lengthmax<25)lengthmax=25;
2406 mpCellExplorer->SetLengthMinMax(3,lengthmax);
2407 mpCellExplorer->SetCrystalSystem(MONOCLINIC);
2408 mpCellExplorer->SetCrystalCentering(cent);
2409 mpLog->AppendText(wxString::Format(_T(
"MONOCLINIC %c : V= %6.0f -> %6.0f A^3, max length=%6.2fA"),centc,minv,maxv,lengthmax));
2410 t0=chrono.seconds();
2411 if(dlgProgress.Update(5,wxString::Format(_T(
"MONOCLINIC %c (%u spurious), V=%6.0f-%6.0f, l<%6.2fA\n")
2412 _T(
"Best Score=%6.1f"),centc,
2413 nbSpurious,minv,maxv,lengthmax,mpCellExplorer->GetBestScore()))==
false)
break;
2414 mpCellExplorer->DicVol(reportOnScore,reportOnDepth,stopOnScore,stopOnDepth);
2415 mpLog->AppendText(wxString::Format(_T(
" -> %3u sols in %6.2fs, best score=%6.1f\n"),
2416 (
unsigned int)(mpCellExplorer->GetSolutions().size()),chrono.seconds()-t0,mpCellExplorer->GetBestScore()));
2418 if(noCentered)
break;
2422 if((mpCellExplorer->GetBestScore()>=stopOnScore)||(nbSpurious>3))
break;
2423 mpLog->AppendText(wxString::Format(_T(
"\n Trying now with %2u spurious peaks\n"),nbSpurious));
2430 for(vector<PeakList::hkl>::iterator pos=mpPeakList->mvHKL.begin();pos!=mpPeakList->mvHKL.end();++pos)
2431 pos->isSpurious=
false;
2434 double lmin,lmax,amin=90,amax,vmin,vmax,error,stopOnScore,reportOnScore;
2435 long nbspurious,nbPeak,stopOnDepth,reportOnDepth;
2436 s=mpLengthMin->GetValue();s.ToDouble(&lmin);
2437 s=mpLengthMax->GetValue();s.ToDouble(&lmax);
2439 s=mpAngleMax->GetValue();s.ToDouble(&amax);
2440 s=mpVolumeMin->GetValue();s.ToDouble(&vmin);
2441 s=mpVolumeMax->GetValue();s.ToDouble(&vmax);
2442 s=mpNbSpurious->GetValue();s.ToLong( urious);
2443 s=mpNbPeak->GetValue();s.ToLong(&nbPeak);
2444 s=mpErrorD->GetValue();s.ToDouble(&error);
2445 s=mpStopOnScore->GetValue();s.ToDouble(&stopOnScore);
2446 s=mpStopOnDepth->GetValue();s.ToLong(&stopOnDepth);
2447 s=mpReportOnScore->GetValue();s.ToDouble(&reportOnScore);
2448 s=mpReportOnDepth->GetValue();s.ToLong(&reportOnDepth);
2451 if(mpPeakList->GetPeakList().size()>nbPeak) mpPeakList->GetPeakList().resize(nbPeak);
2453 mpCellExplorer =
new CellExplorer(*mpPeakList,(
CrystalSystem)(mpBravais->GetSelection()),0);
2455 mpCellExplorer->SetLengthMinMax((
float)lmin,(
float)lmax);
2456 mpCellExplorer->SetAngleMinMax((
float)amin*DEG2RAD,(
float)amax*DEG2RAD);
2457 mpCellExplorer->SetVolumeMinMax((
float)vmin,(
float)vmax);
2458 mpCellExplorer->SetNbSpurious((
unsigned int)nbspurious);
2459 mpCellExplorer->SetD2Error((
float)(error*error));
2461 mpCellExplorer->SetCrystalCentering(LATTICE_P);
2463 cout<<lmin<<
" "<<lmax<<
" "<<amin<<
" "<<amax<<
" "<<vmin<<
" "<<vmax<<
" "<<(
unsigned int)nbspurious<<
" "<<error*error<<endl;
2465 mpCellExplorer->DicVol(reportOnScore,reportOnDepth,stopOnScore,stopOnDepth);
2467 if(mpAlgorithm->GetSelection()==0) mpCellExplorer->DicVol(reportOnScore,reportOnDepth,stopOnScore,stopOnDepth);
2470 for(
unsigned int i=0;i<20;++i)
2472 mpCellExplorer->Evolution(5000,
true,0.7,0.5,50);
2473 if(mpCellExplorer->GetBestScore()>stopOnScore)
break;
2478 mpLog->AppendText(wxString::Format(_T(
"Finished indexing, bestscore=%6.1f, elapsed time=%6.2fs\n"),
2479 mpCellExplorer->GetBestScore(),chrono.seconds()));
2481 mpCellExplorer->ReduceSolutions();
2482 if(mpCellExplorer->GetSolutions().size()>0)
2487 for(list<pair<RecUnitCell,float> >::const_iterator pos=mpCellExplorer->GetSolutions().begin();
2488 pos!=mpCellExplorer->GetSolutions().end();++pos)
2490 vector<float> uc=pos->first.DirectUnitCell();
2491 if(pos==mpCellExplorer->GetSolutions().begin()) bestvol=uc[6]*.99999;
2492 const float relvol=uc[6]/bestvol;
2494 switch(pos->first.mlattice)
2496 case TRICLINIC:sys=
"TRICLINIC";
break;
2497 case MONOCLINIC:sys=
"MONOCLINIC";
break;
2498 case ORTHOROMBIC:sys=
"ORTHOROMBIC";
break;
2499 case HEXAGONAL:sys=
"HEXAGONAL";
break;
2500 case RHOMBOEDRAL:sys=
"RHOMBOEDRAL";
break;
2501 case TETRAGONAL:sys=
"TETRAGONAL";
break;
2502 case CUBIC:sys=
"CUBIC";
break;
2505 switch(pos->first.mCentering)
2507 case LATTICE_P:centc=
'P';
break;
2508 case LATTICE_I:centc=
'I';
break;
2509 case LATTICE_A:centc=
'A';
break;
2510 case LATTICE_B:centc=
'B';
break;
2511 case LATTICE_C:centc=
'C';
break;
2512 case LATTICE_F:centc=
'F';
break;
2515 sprintf(buf,
"Score=%6.1f V=%6.1f(%3.1fV) %6.3f %6.3f %6.3f %6.2f %6.2f %6.2f %s %c",pos->second,
2516 uc[6],relvol,uc[0],uc[1],uc[2],uc[3]*RAD2DEG,uc[4]*RAD2DEG,uc[5]*RAD2DEG,sys.c_str(),centc);
2518 sols.Add(wxString::FromAscii(buf));
2523 if(mpGraph!=0) mpGraph->Refresh(FALSE);
2525 void WXCellExplorer::OnSelectCell(wxCommandEvent &event)
2527 VFN_DEBUG_ENTRY(
"WXCellExplorer::OnSelectCell()",7)
2528 const
int choice=mpCell->GetSelection();
2529 if(choice!=wxNOT_FOUND)
2533 s=mpNbSpurious->GetValue();s.ToLong( urious);
2535 list<pair<RecUnitCell,float> >::const_iterator pos=mpCellExplorer->GetSolutions().begin();
2536 for(
int i=0;i<choice;++i)++pos;
2538 Score(*mpPeakList,pos->first,nbspurious,
true,
true,
true);
2542 list<pair<RecUnitCell,float> >::const_iterator pos=mpCellExplorer->GetSolutions().begin();
2543 for(
int i=0;i<choice;++i)++pos;
2544 vector<float> uc=pos->first.DirectUnitCell();
2545 mpCrystal->GetPar(
"a").SetValue(uc[0]);
2546 mpCrystal->GetPar(
"b").SetValue(uc[1]);
2547 mpCrystal->GetPar(
"c").SetValue(uc[2]);
2548 mpCrystal->GetPar(
"alpha").SetValue(uc[3]);
2549 mpCrystal->GetPar(
"beta").SetValue(uc[4]);
2550 mpCrystal->GetPar(
"gamma").SetValue(uc[5]);
2551 switch(pos->first.mlattice)
2553 case TRICLINIC:mpCrystal->GetSpaceGroup().ChangeSpaceGroup(
"P-1");
break;
2554 case MONOCLINIC:mpCrystal->GetSpaceGroup().ChangeSpaceGroup(
"P2/m");
break;
2555 case ORTHOROMBIC:mpCrystal->GetSpaceGroup().ChangeSpaceGroup(
"Pmmm");
break;
2556 case HEXAGONAL:mpCrystal->GetSpaceGroup().ChangeSpaceGroup(
"P6/mmm");
break;
2557 case RHOMBOEDRAL:mpCrystal->GetSpaceGroup().ChangeSpaceGroup(
"R-3m");
break;
2558 case TETRAGONAL:mpCrystal->GetSpaceGroup().ChangeSpaceGroup(
"P4/mmm");
break;
2559 case CUBIC:mpCrystal->GetSpaceGroup().ChangeSpaceGroup(
"Pm-3m");
break;
2561 mpCrystal->UpdateDisplay();
2564 if(mpAutomaticLeBail->GetValue())
2566 VFN_DEBUG_MESSAGE(
"WXCellExplorer::OnSelectCell():auto-Le Bail",7);
2568 const bool fitzero=
true,
2573 fitdispltransp=
true,
2577 wxProgressDialog dlgProgress(_T(
"Le Bail and Profile Fitting"),_T(
"Le Bail Fitting, cycle #0/20"),
2578 25,
this,wxPD_AUTO_HIDE|wxPD_ELAPSED_TIME|wxPD_CAN_ABORT);
2579 mpDiff->SetExtractionMode(
true,
true);
2580 VFN_DEBUG_MESSAGE(
"WXCellExplorer::OnSelectCell():auto-Le Bail",7);
2582 mpLog->AppendText(wxString::Format(_T(
"Starting 20 Le Bail cycles\n")));
2583 for(
int i=0;i<10;++i)
2585 VFN_DEBUG_MESSAGE(
"WXCellExplorer::OnSelectCell():auto-Le Bail #"<<i,7);
2586 mpDiff->ExtractLeBail(2);
2587 mpDiff->GetParentPowderPattern().FitScaleFactorForRw();
2588 VFN_DEBUG_MESSAGE(
"WXCellExplorer::OnSelectCell():auto-Le Bail #"<<i,7);
2589 mpDiff->GetParentPowderPattern().UpdateDisplay();
2590 if(dlgProgress.Update(i,wxString::Format(_T(
"Le Bail Fitting, cycle #%d/20"),i*2))==
false)
return;
2592 mpLog->AppendText(wxString::Format(_T(
" => Rwp=%5.3f%%, GoF=%7.3f\n"),
2593 mpDiff->GetParentPowderPattern().GetRw()*100,
2594 mpDiff->GetParentPowderPattern().GetChi2()
2595 /mpDiff->GetParentPowderPattern().GetNbPointUsed()));
2597 LSQNumObj lsqobj(
"Profile Fitting object");
2598 lsqobj.SetRefinedObj(mpDiff->GetParentPowderPattern(),0,
true,
true);
2599 lsqobj.PrepareRefParList(
true);
2605 lsqobj.SetParIsUsed(gpRefParTypeUnitCell,
true);
2610 if(fitzero) lsqobj.SetParIsFixed(
"Zero",
false);
2611 if(fitwidth0) lsqobj.SetParIsFixed(
"W",
false);
2612 if(fitzero||fitwidth0)
2614 mpLog->AppendText(wxString::Format(_T(
"Fitting zero shift && constant width\n")));
2615 if(dlgProgress.Update(11,_T(
"Fitting zero shift && constant width"))==
false)
return;
2616 lsqobj.Refine(5,
true,
false);
2617 mpDiff->GetParentPowderPattern().FitScaleFactorForRw();
2618 mpDiff->GetParentPowderPattern().UpdateDisplay();
2619 mpLog->AppendText(wxString::Format(_T(
" => Rwp=%6.3f%%, GoF=%7.3f\n"),
2620 mpDiff->GetParentPowderPattern().GetRw()*100,
2621 mpDiff->GetParentPowderPattern().GetChi2()
2622 /mpDiff->GetParentPowderPattern().GetNbPointUsed()));
2624 if(fitwidth) lsqobj.SetParIsFixed(
"U",
false);
2625 if(fitwidth) lsqobj.SetParIsFixed(
"V",
false);
2626 if(fiteta) lsqobj.SetParIsFixed(
"Eta0",
false);
2627 if(fitwidth||fiteta)
2629 mpLog->AppendText(wxString::Format(_T(
"Fitting width and gaussian/lorentzian fixed mix\n")));
2630 if(dlgProgress.Update(12,_T(
"Fitting variable width and gaussian/lorentzian fixed mix"))==
false)
return;
2631 lsqobj.Refine(5,
true,
false);
2632 mpDiff->GetParentPowderPattern().FitScaleFactorForRw();
2633 mpDiff->GetParentPowderPattern().UpdateDisplay();
2634 mpLog->AppendText(wxString::Format(_T(
" => Rwp=%6.3f%%, GoF=%7.3f\n"),
2635 mpDiff->GetParentPowderPattern().GetRw()*100,
2636 mpDiff->GetParentPowderPattern().GetChi2()
2637 /mpDiff->GetParentPowderPattern().GetNbPointUsed()));
2640 if(fiteta) lsqobj.SetParIsFixed(
"Eta1",
false);
2643 mpLog->AppendText(wxString::Format(_T(
"Fitting variable width and gaussian/lorentzian mix\n")));
2644 if(dlgProgress.Update(13,_T(
"Fitting variable width and gaussian/lorentzian mix"))==
false)
return;
2645 lsqobj.Refine(5,
true,
false);
2646 mpDiff->GetParentPowderPattern().FitScaleFactorForRw();
2647 mpDiff->GetParentPowderPattern().UpdateDisplay();
2648 mpLog->AppendText(wxString::Format(_T(
" => Rwp=%6.3f%%, GoF=%7.3f\n"),
2649 mpDiff->GetParentPowderPattern().GetRw()*100,
2650 mpDiff->GetParentPowderPattern().GetChi2()
2651 /mpDiff->GetParentPowderPattern().GetNbPointUsed()));
2654 if(fitasym) lsqobj.SetParIsFixed(
"Asym0",
false);
2655 if(fitasym) lsqobj.SetParIsFixed(
"Asym1",
false);
2656 if(fitasym) lsqobj.SetParIsFixed(
"Asym2",
false);
2657 if(fitdispltransp) lsqobj.SetParIsFixed(
"2ThetaDispl",
false);
2658 if(fitdispltransp) lsqobj.SetParIsFixed(
"2ThetaTransp",
false);
2659 if(fitdispltransp||fitasym)
2661 mpLog->AppendText(wxString::Format(_T(
"Fitting assymetry and sample displacement/transparency\n")));
2662 if(dlgProgress.Update(14,_T(
"Fitting assymetry and sample displacement/transparency"))==
false)
return;
2663 lsqobj.Refine(5,
true,
false);
2664 mpDiff->GetParentPowderPattern().FitScaleFactorForRw();
2665 mpDiff->GetParentPowderPattern().UpdateDisplay();
2666 mpLog->AppendText(wxString::Format(_T(
" => Rwp=%6.3f%%, GoF=%7.3f\n"),
2667 mpDiff->GetParentPowderPattern().GetRw()*100,
2668 mpDiff->GetParentPowderPattern().GetChi2()
2669 /mpDiff->GetParentPowderPattern().GetNbPointUsed()));
2676 const unsigned int nbcomp= mpGraph->GetWXPowderPattern().GetPowderPattern().GetNbPowderPatternComponent();
2677 for(
unsigned int i=0;i<nbcomp;++i)
2678 if(mpGraph->GetWXPowderPattern().GetPowderPattern().GetPowderPatternComponent(i).GetClassName()==
"PowderPatternBackground")
2680 PowderPatternBackground *pback=
dynamic_cast<PowderPatternBackground *
>
2681 (&(mpGraph->GetWXPowderPattern().GetPowderPattern().GetPowderPatternComponent(i)));
2682 pback->FixParametersBeyondMaxresolution(lsqobj.GetCompiledRefinedObj());
2685 mpLog->AppendText(wxString::Format(_T(
"Fitting background\n")));
2686 if(dlgProgress.Update(15,_T(
"Fitting background"))==
false)
return;
2687 lsqobj.Refine(5,
true,
false);
2688 mpDiff->GetParentPowderPattern().FitScaleFactorForRw();
2689 mpDiff->GetParentPowderPattern().UpdateDisplay();
2690 mpLog->AppendText(wxString::Format(_T(
" => Rwp=%6.3f%%, GoF=%7.3f\n"),
2691 mpDiff->GetParentPowderPattern().GetRw()*100,
2692 mpDiff->GetParentPowderPattern().GetChi2()
2693 /mpDiff->GetParentPowderPattern().GetNbPointUsed()));
2696 if(fitcell) lsqobj.SetParIsFixed(gpRefParTypeUnitCell,
false);
2699 mpLog->AppendText(wxString::Format(_T(
"Fitting unit cell\n")));
2700 if(dlgProgress.Update(16,_T(
"Fitting unit cell"))==
false)
return;
2701 lsqobj.Refine(5,
true,
false);
2702 mpDiff->GetParentPowderPattern().FitScaleFactorForRw();
2703 mpDiff->GetParentPowderPattern().UpdateDisplay();
2704 mpLog->AppendText(wxString::Format(_T(
" => Rwp=%6.3f%%, GoF=%7.3f\n"),
2705 mpDiff->GetParentPowderPattern().GetRw()*100,
2706 mpDiff->GetParentPowderPattern().GetChi2()
2707 /mpDiff->GetParentPowderPattern().GetNbPointUsed()));
2710 mpDiff->SetExtractionMode(
true,
true);
2711 mpLog->AppendText(wxString::Format(_T(
"Starting 10 Le Bail cycles\n")));
2712 for(
int i=17;i<22;++i)
2714 if(dlgProgress.Update(i,wxString::Format(_T(
"Le Bail Fitting, cycle #%d/10"),(i-17)*2))==
false)
return;
2715 mpDiff->ExtractLeBail(2);
2716 mpDiff->GetParentPowderPattern().FitScaleFactorForRw();
2717 mpDiff->GetParentPowderPattern().UpdateDisplay();
2719 mpLog->AppendText(wxString::Format(_T(
" => Rwp=%5.3f%%, GoF=%7.3f\n"),
2720 mpDiff->GetParentPowderPattern().GetRw()*100,
2721 mpDiff->GetParentPowderPattern().GetChi2()
2722 /mpDiff->GetParentPowderPattern().GetNbPointUsed()));
2724 mpLog->AppendText(wxString::Format(_T(
"Last fit...\n")));
2725 if(dlgProgress.Update(23,_T(
"Last fit..."))==
false)
return;
2726 lsqobj.Refine(5,
true,
false);
2727 mpDiff->GetParentPowderPattern().FitScaleFactorForRw();
2728 mpLog->AppendText(wxString::Format(_T(
" => Rwp=%5.3f%%, GoF=%7.3f\n"),
2729 mpDiff->GetParentPowderPattern().GetRw()*100,
2730 mpDiff->GetParentPowderPattern().GetChi2()
2731 /mpDiff->GetParentPowderPattern().GetNbPointUsed()));
2732 mpDiff->GetParentPowderPattern().UpdateDisplay();
2733 mpCrystal->UpdateDisplay();
2736 catch(
const ObjCrystException &except)
2738 mpLog->AppendText(wxString::Format(_T(
" OOPS : refinement diverged ! Aborting.")));
2740 if(mpGraph!=0) mpGraph->Refresh(FALSE);
2743 VFN_DEBUG_EXIT(
"WXCellExplorer::OnSelectCell",7)
2745 void WXCellExplorer::OnApplyCell(wxCommandEvent &event)
2747 const int choice=mpCell->GetSelection();
2748 if((mpCrystal!=0)&&(choice!=wxNOT_FOUND))
2750 list<pair<RecUnitCell,float> >::const_iterator pos=mpCellExplorer->GetSolutions().begin();
2751 for(
int i=0;i<choice;++i)++pos;
2752 vector<float> uc=pos->first.DirectUnitCell();
2753 mpCrystal->GetPar(
"a").SetValue(uc[0]);
2754 mpCrystal->GetPar(
"b").SetValue(uc[1]);
2755 mpCrystal->GetPar(
"c").SetValue(uc[2]);
2756 mpCrystal->GetPar(
"alpha").SetValue(uc[3]);
2757 mpCrystal->GetPar(
"beta").SetValue(uc[4]);
2758 mpCrystal->GetPar(
"gamma").SetValue(uc[5]);
2759 mpCrystal->UpdateDisplay();
2762 wxCommandEvent ev(ID_POWDERGRAPH_MENU_UPDATE);
2763 mpGraph->OnUpdate(ev);
2768 void WXCellExplorer::OnChooseCrystal(wxCommandEvent &event)
2770 VFN_DEBUG_MESSAGE(
"WXCellExplorer::OnChooseCrystal()",6)
2773 mpCrystal=dynamic_cast<Crystal*>
2775 "Choose a Crystal Structure:",choice));
2776 if(0==mpCrystal) return;
2777 mpFieldCrystal->SetValue(mpCrystal->GetName());
2780 void WXCellExplorer::OnAutoLeBail(wxCommandEvent &event)
2784 mpAutomaticLeBail->SetValue(
false);
2787 VFN_DEBUG_ENTRY(
"WXCellExplorer::OnAutoLeBail()",7)
2789 const
unsigned int nbcomp= mpGraph->GetWXPowderPattern().GetPowderPattern().GetNbPowderPatternComponent();
2790 bool needBackground=true;
2791 for(
unsigned int i=0;i<nbcomp;++i)
2792 if(mpGraph->GetWXPowderPattern().GetPowderPattern().GetPowderPatternComponent(i).GetClassName()=="PowderPatternBackground")
2794 needBackground=
false;
2799 int answer =wxMessageBox(_T(
"To automatically run profile-fitting\n")
2800 _T(
"and Le Bail extraction, you must have\n")
2801 _T(
"defined a background phase for the pattern\n")
2802 _T(
"and you will need to choose a crystal phase\n\n")
2803 _T(
"Do you want to do that now ?"),
2804 _T(
"Add Background ?"),wxYES_NO|wxICON_QUESTION);
2807 mpAutomaticLeBail->SetValue(
false);
2811 mpGraph->GetWXPowderPattern().OnMenuAddCompBackgdBayesian(ev);
2816 if(gCrystalRegistry.GetNb()==0)
2818 mpCrystal=
new Crystal(4,5,6,
"P1");
2819 mpCrystal->SetName(
"Indexing Result");
2820 wxTheApp->GetTopWindow()->Layout();
2821 wxTheApp->GetTopWindow()->SendSizeEvent();
2825 int answer =wxMessageBox(_T(
"To automatically run profile-fitting\n")
2826 _T(
"and Le Bail extraction, you must have\n")
2827 _T(
"defined a Crystal phase to apply the cell to\n\n")
2828 _T(
"Do you want to use an EXISTING crystal structure ?\n")
2829 _T(
"(otherwise a new one will be created for you)"),
2830 _T(
"Select Crystal ?"),wxYES_NO|wxICON_QUESTION);
2833 mpCrystal=
new Crystal(4,5,6,
"P1");
2834 mpCrystal->SetName(
"Indexing Result");
2835 wxTheApp->GetTopWindow()->Layout();
2836 wxTheApp->GetTopWindow()->SendSizeEvent();
2841 this->OnChooseCrystal(ev);
2846 bool needPowderPatternDiffraction=
true;
2847 unsigned int nbPowderPatternDiffraction=0;
2848 for(
unsigned int i=0;i<nbcomp;++i)
2849 if(mpGraph->GetWXPowderPattern().GetPowderPattern().GetPowderPatternComponent(i).GetClassName()==
"PowderPatternDiffraction")
2851 nbPowderPatternDiffraction++;
2852 mpDiff=
dynamic_cast<PowderPatternDiffraction*
>
2853 (&(mpGraph->GetWXPowderPattern().GetPowderPattern().GetPowderPatternComponent(i)));
2854 if(&(mpDiff->GetCrystal())==mpCrystal)
2856 needPowderPatternDiffraction=
false;
2860 VFN_DEBUG_MESSAGE(
"WXCellExplorer::OnAutoLeBail():needPowderPatternDiffraction=="<<needPowderPatternDiffraction,7)
2861 if(needPowderPatternDiffraction)
2863 if(nbPowderPatternDiffraction>0)
2865 int answer =wxMessageBox(_T(
"To automatically run profile-fitting\n")
2866 _T(
"and Le Bail extraction, you must assign\n")
2867 _T(
"the Crystal to a Diffraction Component\n\n")
2868 _T(
"Do you want to use an already existing one ?"),
2869 _T(
"Use Crystal Phase ?"),wxYES_NO|wxICON_QUESTION);
2874 for(
unsigned int i=0;i<nbcomp;++i)
2875 if(mpGraph->GetWXPowderPattern().GetPowderPattern().GetPowderPatternComponent(i).GetClassName()==
"PowderPatternDiffraction")
2877 mpDiff=
dynamic_cast<PowderPatternDiffraction*
>
2878 (&(mpGraph->GetWXPowderPattern().GetPowderPattern().GetPowderPatternComponent(i)));
2879 mpDiff->SetCrystal(*mpCrystal);
2887 VFN_DEBUG_MESSAGE(
"WXCellExplorer::OnAutoLeBail():Create PowderPatternDiffraction",7)
2888 mpDiff=new PowderPatternDiffraction;
2889 mpDiff->SetCrystal(*mpCrystal);
2890 mpGraph->GetWXPowderPattern().GetPowderPattern().AddPowderPatternComponent(*mpDiff);
2891 if(mpGraph->GetWXPowderPattern().GetPowderPattern().GetRadiation().GetWavelengthType()==WAVELENGTH_TOF)
2893 wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED,ID_POWDERDIFF_PROFILE_DEPV);
2894 wxPostEvent(mpDiff->WXGet(),event);
2896 mpGraph->GetWXPowderPattern().GetPowderPattern().Prepare();
2897 mpGraph->GetWXPowderPattern().CrystUpdate();
2898 wxTheApp->GetTopWindow()->Layout();
2899 wxTheApp->GetTopWindow()->SendSizeEvent();
2903 mpDiff->GetParentPowderPattern().SetMaxSinThetaOvLambda(0.25);
2905 if(mpCell->GetSelection()>=0)
2907 VFN_DEBUG_MESSAGE(
"WXCellExplorer::OnAutoLeBail()->OnSelectCell()",7)
2908 cout<<mpCell->GetSelection()<<endl;
2910 this->OnSelectCell(ev);
2912 VFN_DEBUG_EXIT("WXCellExplorer::OnAutoLeBail()",7)
2917 void WXPowderPatternGraph::OnIndex(wxCommandEvent& WXUNUSED(event))
2919 wxFrame *mpFrame=
new wxFrame(
this,-1,_T(
"Fox cell Explorer (EXPERIMENTAL)"));
2920 WXCellExplorer *mpWXCellExplorer;
2921 mpWXCellExplorer=
new WXCellExplorer(mpFrame,mPeakList,
this);
2922 mpFrame->Show(TRUE);
2925 void WXPowderPatternGraph::OnChangeScale(wxCommandEvent& event)
2927 VFN_DEBUG_MESSAGE(
"WXPowderPatternGraph::OnChangeScale()",10)
2928 if(event.GetId()==ID_POWDERGRAPH_MENU_XSCALE_DATA) mXScale=0;
2929 if(event.GetId()==ID_POWDERGRAPH_MENU_XSCALE_D) mXScale=1;
2930 if(event.GetId()==ID_POWDERGRAPH_MENU_XSCALE_2PID) mXScale=2;
2931 if(event.GetId()==ID_POWDERGRAPH_MENU_YSCALE_LINEAR)mYScale=0;
2932 if(event.GetId()==ID_POWDERGRAPH_MENU_YSCALE_SQRT) mYScale=1;
2933 if(event.GetId()==ID_POWDERGRAPH_MENU_YSCALE_LOG10) mYScale=2;
2935 mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_XSCALE_DATA, TRUE);
2936 mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_XSCALE_D, TRUE);
2937 mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_XSCALE_2PID, TRUE);
2938 mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_YSCALE_LINEAR, TRUE);
2939 mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_YSCALE_SQRT, TRUE);
2940 mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_YSCALE_LOG10, TRUE);
2942 if(mXScale==0) mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_XSCALE_DATA, FALSE);
2943 if(mXScale==1) mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_XSCALE_D, FALSE);
2944 if(mXScale==2) mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_XSCALE_2PID, FALSE);
2945 if(mYScale==0)mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_YSCALE_LINEAR, FALSE);
2946 if(mYScale==1) mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_YSCALE_SQRT, FALSE);
2947 if(mYScale==2) mpPopUpMenu->Enable(ID_POWDERGRAPH_MENU_YSCALE_LOG10, FALSE);
2949 this->Refresh(false);
2954 wxFrame *pFrame=
new wxFrame(
this,-1,_T(
"Profile Fitting"));
2955 WXProfileFitting *pFit;
2956 pFit=
new WXProfileFitting(pFrame,&(this->GetWXPowderPattern().GetPowderPattern()));
2960 void WXPowderPatternGraph::OnKeyDown(wxKeyEvent& event)
2962 wxMutexLocker mlock(
mMutex);
2963 const long nbPoint=mX.numElements();
2965 switch(event.GetKeyCode())
2969 const REAL range=mMaxX-mMinX;
2971 if(mX(nbPoint-1)>mX(0))
2973 if(mMinX<mX(0)) mMinX=mX(0);
2977 if(mMinX<mX(nbPoint-1)) mMinX=mX(nbPoint-1);
2984 const REAL range=mMaxX-mMinX;
2986 if(mX(nbPoint-1)>mX(0))
2988 if(mMaxX>=mX(nbPoint-1)) mMaxX=mX(nbPoint-1);
2992 if(mMaxX>=mX(0)) mMaxX=mX(0);
2999 REAL max=mObs.max(),min=mObs.min();
3000 if(min<1e-6*max)min=1e-6*max;
3003 const REAL range=log10(max)-log10(min);
3004 mMinIntensity*=pow(10,range/8);
3005 mMaxIntensity*=pow(10,range/8);
3008 const REAL range=mMaxIntensity-mMinIntensity;
3009 mMinIntensity+=range/8;
3010 mMaxIntensity+=range/8;
3015 REAL max=mObs.max(),min=mObs.min();
3016 if(min<1e-6*max)min=1e-6*max;
3019 const REAL range=log10(max)-log10(min);
3020 mMinIntensity*=pow(10,-range/8);
3021 mMaxIntensity*=pow(10,-range/8);
3024 const REAL range=mMaxIntensity-mMinIntensity;
3025 mMinIntensity-=range/8;
3026 if(mMinIntensity<1e-6*max) mMinIntensity=1e-6*max;
3027 mMaxIntensity=mMinIntensity+range;
3032 if(abs(mMaxX-mMinX)>1)
3034 const REAL halfrange=(mMaxX-mMinX)/2;
3035 const REAL middle=(mMaxX+mMinX)/2;
3036 mMinX= (long)(middle-halfrange*4./5.);
3037 mMaxX = (long)(middle+halfrange*4./5.);
3043 const REAL halfrange=(mMaxX-mMinX)/2;
3044 const REAL middle=(mMaxX+mMinX)/2;
3045 mMinX= (long)(middle-halfrange*5./4.);
3046 mMaxX = (long)(middle+halfrange*5./4.);
3047 if(mX(nbPoint-1)>mX(0))
3049 if(mMinX<mX(0)) mMinX=mX(0);
3050 if(mMaxX>mX(nbPoint-1)) mMaxX=mX(nbPoint-1);
3054 if(mMinX<mX(nbPoint-1)) mMinX=mX(nbPoint-1);
3055 if(mMaxX>mX(0)) mMaxX=mX(0);
3061 const REAL range=mMaxIntensity-mMinIntensity;
3062 mMaxIntensity=mMinIntensity+range*4./5.;
3067 const REAL range=mMaxIntensity-mMinIntensity;
3068 mMaxIntensity=mMinIntensity+range*5./4.;
3073 VFN_DEBUG_MESSAGE(
"WXPowderPatternGraph::OnKeyDown(): no command for key #"<<event.GetKeyCode(),5);
3074 cout<<
"WXPowderPatternGraph::OnKeyDown(): no command for key #"<<
event.GetKeyCode()<<endl;
3077 mClockAxisLimits.Click();
3078 wxUpdateUIEvent ev(ID_POWDER_GRAPH_NEW_PATTERN);
3079 wxPostEvent(
this,ev);
3083 void WXPowderPatternGraph::OnSize(wxSizeEvent& event)
3085 this->Refresh(
false);
3088 WXPowderPattern& WXPowderPatternGraph::GetWXPowderPattern(){
return *mpPattern;}
3089 const WXPowderPattern& WXPowderPatternGraph::GetWXPowderPattern()
const{
return *mpPattern;}
3092 const CrystVector_REAL &obs,
3093 const CrystVector_REAL &calc,
3094 const CrystVector_REAL &sigma,
3095 const CrystVector_REAL &chi2Cumul)
3097 VFN_DEBUG_ENTRY(
"WXPowderPatternGraph::SetPattern(x,obs,calc,sigma)",4)
3100 if(mpPattern->GetPowderPattern().GetRadiation().GetWavelengthType()!=WAVELENGTH_TOF) mX*=RAD2DEG;
3106 mChi2Cumul=chi2Cumul;
3110 ||(mpPattern->GetPowderPattern().GetClockPowderPatternPar()>mClockAxisLimits))
3113 this->ResetAxisLimits();
3117 mvLabelList.clear();
3118 for(
unsigned int i=0;i<mpPattern->GetPowderPattern().GetNbPowderPatternComponent();++i)
3119 mvLabelList.push_back(mpPattern->GetPowderPattern()
3120 .GetPowderPatternComponent(i).GetPatternLabelList());
3126 if(
true==wxThread::IsMain())
3128 this->Refresh(
false);
3132 wxUpdateUIEvent event(ID_POWDER_GRAPH_NEW_PATTERN);
3133 wxPostEvent(
this,event);
3136 VFN_DEBUG_EXIT(
"WXPowderPatternGraph::SetPattern(x,obs,calc,sigma)"<<mX.numElements()<<
","<<mCalc.numElements()<<
","<<mObs.numElements()<<
","<<mSigma.numElements()<<
",",4)
3141 VFN_DEBUG_MESSAGE(
"WXPowderPatternGraph::SetPattern()",5)
3142 this->Refresh(
false);
3147 wxMutexLocker mlock(
mMutex);
3148 mMaxIntensity=mObs.max();
3149 mMinIntensity=mObs.min();
3150 const float max=mObs.max();
3151 const float min=mObs.min();
3152 if(max>mMaxIntensity) mMaxIntensity=max;
3153 if(min<mMinIntensity) mMinIntensity=min;
3154 if(mMinIntensity<=0) mMinIntensity=max/1e6;
3155 mMaxIntensity=mMaxIntensity+(mMaxIntensity-mMinIntensity)*0.1;
3158 mDefaultIntensityScale=
true;
3159 mClockAxisLimits.Click();
3160 VFN_DEBUG_MESSAGE(
"WXPowderPatternGraph::ResetAxisLimits():"<<mMinIntensity<<
","<<mMaxIntensity<<
","<<mMinX<<
","<<mMaxX,10)
3164 wxCoord width,height;
3165 this->GetSize(&width, &height);
3166 REAL xs=x,minx=mMinX,maxx=mMaxX;
3170 if(mpPattern->GetPowderPattern().GetRadiation().GetWavelengthType()!=WAVELENGTH_TOF)
3172 d=2*mpPattern->GetPowderPattern().X2STOL(xs*DEG2RAD);
3173 mind=2*mpPattern->GetPowderPattern().X2STOL(minx*DEG2RAD);
3174 maxd=2*mpPattern->GetPowderPattern().X2STOL(maxx*DEG2RAD);
3178 d=2*mpPattern->GetPowderPattern().X2STOL(xs);
3179 mind=2*mpPattern->GetPowderPattern().X2STOL(minx);
3180 maxd=2*mpPattern->GetPowderPattern().X2STOL(maxx);
3182 if(mXScale==1) {xs=d;minx=mind;maxx=maxd;}
3183 if(mXScale==2) {xs=2*M_PI*d;minx=2*M_PI*mind;maxx=2*M_PI*maxd;}
3184 return (
long)(mMargin*3+(xs-minx)*(width-3*mMargin)/(maxx-minx));
3188 return this->Data2ScreenX(mX(x));
3192 wxCoord width,height;
3193 this->GetSize(&width, &height);
3194 REAL ys=y,miny=mMinIntensity,maxy=mMaxIntensity;
3197 if(mYScale==1) {ys=sqrt(ys) ;miny=sqrt(miny) ;maxy=sqrt(maxy);}
3198 if(mYScale==2) {ys=log10(ys);miny=log10(miny);maxy=log10(maxy);}
3199 return (
long)(height-mMargin-(ys-miny)*(height-2*mMargin)/(maxy-miny));
3203 wxCoord width,height;
3204 this->GetSize(&width, &height);
3205 REAL minx=mMinX,maxx=mMaxX;
3207 if(mpPattern->GetPowderPattern().GetRadiation().GetWavelengthType()!=WAVELENGTH_TOF)
3209 mind=2*mpPattern->GetPowderPattern().X2STOL(minx*DEG2RAD);
3210 maxd=2*mpPattern->GetPowderPattern().X2STOL(maxx*DEG2RAD);
3214 mind=2*mpPattern->GetPowderPattern().X2STOL(minx);
3215 maxd=2*mpPattern->GetPowderPattern().X2STOL(maxx);
3221 REAL stol=(minx+(x-mMargin*3)*(maxx-minx)/(REAL)(width-3*mMargin))/2;
3222 if(mpPattern->GetPowderPattern().GetRadiation().GetWavelengthType()!=WAVELENGTH_TOF)
3223 return mpPattern->GetPowderPattern().STOL2X(stol)*RAD2DEG;
3225 return mpPattern->GetPowderPattern().STOL2X(stol);
3231 REAL stol=(minx+(x-mMargin*3)*(maxx-minx)/(REAL)(width-3*mMargin))/(4*M_PI);
3232 if(mpPattern->GetPowderPattern().GetRadiation().GetWavelengthType()!=WAVELENGTH_TOF)
3233 return mpPattern->GetPowderPattern().STOL2X(stol)*RAD2DEG;
3235 return mpPattern->GetPowderPattern().STOL2X(stol);
3237 return mMinX+(x-mMargin*3)*(mMaxX-mMinX)/(REAL)(width-3*mMargin);
3241 wxCoord width,height;
3242 this->GetSize(&width, &height);
3243 REAL miny=mMinIntensity,maxy=mMaxIntensity;
3244 if(mYScale==1) {miny=sqrt(miny) ;maxy=sqrt(maxy);}
3245 if(mYScale==2) {miny=log10(miny);maxy=log10(maxy);}
3246 REAL ys=miny+(height-mMargin-y)*(maxy-miny)/(REAL)(height-2*mMargin);
3247 if(mYScale==1) ys=ys*ys;
3248 if(mYScale==2) ys=pow((
float)10,(
float)ys);
3257 static const long ID_POWDERBACKGROUND_GRID=
WXCRYST_ID();
3258 static const long ID_POWDERBACKGROUND_NEWBAYESIAN=
WXCRYST_ID();
3261 EVT_MENU(ID_POWDERBACKGROUND_IMPORT,
3263 EVT_MENU(ID_POWDERBACKGROUND_OPTIMIZEBAYESIAN,
3265 EVT_GRID_CMD_CELL_CHANGE(ID_POWDERBACKGROUND_GRID,
3267 EVT_MENU(ID_POWDERBACKGROUND_NEWBAYESIAN,
3272 PowderPatternBackground *b):
3277 mpMenuBar->
AddMenu(
"Object",ID_REFOBJ_MENU_OBJ);
3278 mpMenuBar->
AddMenuItem(ID_REFOBJ_MENU_OBJ,ID_POWDERBACKGROUND_IMPORT,
"Import");
3279 mpMenuBar->
AddMenuItem(ID_REFOBJ_MENU_OBJ,ID_POWDERBACKGROUND_OPTIMIZEBAYESIAN,
3280 "Bayesian Optimization");
3281 mpMenuBar->
AddMenuItem(ID_REFOBJ_MENU_OBJ,ID_POWDERBACKGROUND_NEWBAYESIAN,
3282 "New Automatic Background (Change Number of Points)");
3283 VFN_DEBUG_MESSAGE(mpMenuBar->GetSize().GetWidth()<<
","<<mpMenuBar->GetSize().GetHeight(),10);
3288 #ifdef USE_BACKGROUND_MAXLIKE_ERROR
3290 ->GetPar(
"ML Model Error").wxCreate(
this);
3291 mpSizer->Add(pFieldModelSigma,0,wxALIGN_LEFT);
3295 wxGridCellAttr* cellAttrFloat =
new wxGridCellAttr;
3296 cellAttrFloat->SetRenderer(
new wxGridCellFloatRenderer(10,3));
3297 cellAttrFloat->SetEditor(
new wxGridCellFloatEditor(10,3));
3299 mpGridBackgroundPoint=
new wxGrid(
this,ID_POWDERBACKGROUND_GRID);
3300 mpGridBackgroundPoint->SetSize(400,300);
3301 mpGridBackgroundPoint->EnableScrolling(
true,
true);
3302 mpGridBackgroundPoint->SetSizeHints(-1,300,-1,300);
3303 mpGridBackgroundPoint->SetDefaultColSize(150);
3304 mpGridBackgroundPoint->CreateGrid(0,2);
3305 mpGridBackgroundPoint->SetColAttr(0,cellAttrFloat);
3306 mpGridBackgroundPoint->SetColAttr(1,cellAttrFloat->Clone());
3307 mpGridBackgroundPoint->SetColLabelValue(0,_T(
"Position"));
3308 mpGridBackgroundPoint->SetColLabelValue(1,_T(
"Intensity"));
3309 mpGridBackgroundPoint->AutoSizeRows();
3310 mpSizer->Add(mpGridBackgroundPoint,0,wxALIGN_LEFT);
3315 void WXPowderPatternBackground::OnMenuImportUserBackground(wxCommandEvent & WXUNUSED(event))
3317 VFN_DEBUG_MESSAGE(
"WXPowderPatternBackground::OnMenuImportUserBackground()",6)
3318 wxFileDialog *open= new wxFileDialog(this,_T("Choose background file with 2Theta Ibackgd"),
3319 _T(""),_T(""),_T("*.*"),wxFD_OPEN | wxFD_FILE_MUST_EXIST);
3320 if(open->ShowModal() != wxID_OK) return;
3321 mpPowderPatternBackground->ImportUserBackground(
string(open->GetPath().ToAscii()));
3324 void WXPowderPatternBackground::OnMenuOptimizeBayesianBackground(wxCommandEvent & WXUNUSED(event))
3326 VFN_DEBUG_ENTRY(
"WXPowderPatternBackground::OnMenuOptimizeBayesianBackground()",6)
3327 mpPowderPatternBackground->UnFixAllPar();
3328 mpPowderPatternBackground->OptimizeBayesianBackground();
3329 mpPowderPatternBackground->FixAllPar();
3330 this->CrystUpdate();
3331 VFN_DEBUG_EXIT("WXPowderPatternBackground::OnMenuOptimizeBayesianBackground()",6)
3333 void WXPowderPatternBackground::OnMenuAutomaticBayesianBackground(wxCommandEvent & WXUNUSED(event))
3335 VFN_DEBUG_ENTRY(
"WXPowderPatternBackground::OnMenuAutomaticBayesianBackground()",6)
3338 long nbPointSpline=20;
3339 wxString mes(_T("Number of Interpolation Points"));
3341 s.Printf(_T("%ld"),nbPointSpline);
3342 wxTextEntryDialog dialog(this,mes,_T("Automatic Bayesian (David-Sivia) Background"),
3344 if(wxID_OK!=dialog.ShowModal())
3346 VFN_DEBUG_EXIT(
"WXPowderPatternBackground::OnMenuAutomaticBayesianBackground():Canceled",6)
3349 dialog.GetValue().ToLong(&nbPointSpline);
3350 wxProgressDialog dlgProgress(_T("Automatic Bayesian Background"),_T("Automatic Background, Initializing..."),
3351 4,this,wxPD_AUTO_HIDE|wxPD_ELAPSED_TIME|wxPD_CAN_ABORT);
3352 if(nbPointSpline<2) nbPointSpline=2;
3354 CrystVector_REAL x(nbPointSpline),backgd(nbPointSpline);
3355 const CrystVector_REAL *pObs=&(mpPowderPatternBackground->GetParentPowderPattern().GetPowderPatternObs());
3356 const unsigned long nbPoint=mpPowderPatternBackground->GetParentPowderPattern().GetNbPoint();
3357 const float xmin=mpPowderPatternBackground->GetParentPowderPattern()
3358 .GetPowderPatternX()(0),
3359 xmax=mpPowderPatternBackground->GetParentPowderPattern()
3360 .GetPowderPatternX()(nbPoint-1);
3361 for(
int i=0;i<nbPointSpline;i++)
3363 x(i)=xmin+(xmax-xmin)/(REAL)(nbPointSpline-1)*REAL(i);
3364 REAL x1=xmin+(xmax-xmin)/(REAL)(nbPointSpline-1)*REAL(i-.2);
3365 REAL x2=xmin+(xmax-xmin)/(REAL)(nbPointSpline-1)*REAL(i+.2);
3366 long n1=(long)(mpPowderPatternBackground->GetParentPowderPattern().X2Pixel(x1));
3367 long n2=(long)(mpPowderPatternBackground->GetParentPowderPattern().X2Pixel(x2));
3369 if(n2>(
long)nbPoint)n2=nbPoint;
3370 backgd(i)=(*pObs)(n1);
3371 for(
long j=n1;j<n2;j++)
3372 if((*pObs)(j)<backgd(i))backgd(i)=(*pObs)(j);
3374 mpPowderPatternBackground->SetInterpPoints(x,backgd);
3377 mpPowderPatternBackground->UnFixAllPar();
3378 mpPowderPatternBackground->GetOption(0).SetChoice(0);
3379 if(dlgProgress.Update(1,_T(
"Automatic Background: Optimizing Linear Model..."))==
false)
return;
3380 mpPowderPatternBackground->OptimizeBayesianBackground();
3381 mpPowderPatternBackground->GetOption(0).SetChoice(1);
3382 if(dlgProgress.Update(2,_T(
"Automatic Background: Optimizing Spline Model..."))==
false)
return;
3383 mpPowderPatternBackground->OptimizeBayesianBackground();
3384 mpPowderPatternBackground->FixAllPar();
3387 VFN_DEBUG_EXIT(
"WXPowderPatternBackground::OnMenuAutomaticBayesianBackground()",6)
3389 void WXPowderPatternBackground::OnEditGridBackgroundPoint(wxGridEvent &e)
3391 if(mIsSelfUpdating)
return;
3392 VFN_DEBUG_ENTRY(
"WXPowderPatternBackground::OnEditGridBackgroundPoint():"<<e.GetRow()<<
","<<e.GetCol(),10)
3393 const long r=e.GetRow();
3394 const long c=e.GetCol();
3395 wxString s=mpGridBackgroundPoint->GetCellValue(r,c);
3399 if(mpPowderPatternBackground->GetParentPowderPattern().GetRadiation().GetWavelengthType()!=WAVELENGTH_TOF)f=DEG2RAD;
3404 if(d!=mBackgroundInterpPointX(r))
3405 mBackgroundInterpPointX(r)=d*f;
3409 if(d!=mBackgroundInterpPointX(r))
3410 mBackgroundInterpPointIntensity(r)=d;
3413 mpPowderPatternBackground->SetInterpPoints(mBackgroundInterpPointX,
3414 mBackgroundInterpPointIntensity);
3416 mBackgroundInterpPointX =*(mpPowderPatternBackground->GetInterpPoints().first);
3417 mBackgroundInterpPointIntensity=*(mpPowderPatternBackground->GetInterpPoints().second);
3421 mpPowderPatternBackground->GetParentPowderPattern().UpdateDisplay();
3422 VFN_DEBUG_EXIT(
"WXPowderPatternBackground::OnEditGridBackgroundPoint():"<<e.GetRow()<<
","<<e.GetCol(),10)
3429 if(
false==mpPowderPatternBackground->IsBeingRefined())
3431 const long diff=mpPowderPatternBackground->GetInterpPoints().first->numElements()
3432 -mpGridBackgroundPoint->GetNumberRows();
3436 mpGridBackgroundPoint->AppendRows(diff);
3441 mpGridBackgroundPoint->DeleteRows(0,-diff);
3444 if( (MaxDifference(mBackgroundInterpPointX ,
3445 *(mpPowderPatternBackground->GetInterpPoints().first )))
3446 ||(MaxDifference(mBackgroundInterpPointIntensity,
3447 *(mpPowderPatternBackground->GetInterpPoints().second))))
3451 mBackgroundInterpPointX =*(mpPowderPatternBackground->GetInterpPoints().first);
3452 mBackgroundInterpPointIntensity=*(mpPowderPatternBackground->GetInterpPoints().second);
3455 if(lock)
mMutex.Unlock();
3464 if(mpPowderPatternBackground->GetParentPowderPattern().GetRadiation().GetWavelengthType()!=WAVELENGTH_TOF)f=RAD2DEG;
3465 const long nb=mBackgroundInterpPointX.numElements();
3466 mIsSelfUpdating=
true;
3467 for(
long i=0;i<nb;++i)
3470 tmp.Printf(_T(
"%f"),f*mBackgroundInterpPointX(i));
3471 mpGridBackgroundPoint->SetCellValue(i,0,tmp);
3472 tmp.Printf(_T(
"%f"),mBackgroundInterpPointIntensity(i));
3473 mpGridBackgroundPoint->SetCellValue(i,1,tmp);
3475 mIsSelfUpdating=
false;
3480 if(lock)
mMutex.Unlock();
3483 bool WXPowderPatternBackground::Enable(
bool e)
3485 if(0!=mpGridBackgroundPoint) mpGridBackgroundPoint->Enable(e);
3486 return this->::wxWindow::Enable(e);
3494 WXTexturePhaseMarchDollase::WXTexturePhaseMarchDollase(wxWindow *parent,
3495 TexturePhaseMarchDollase *pObj,
3496 TextureMarchDollase* pTex):
3499 VFN_DEBUG_ENTRY(
"WXTexturePhaseMarchDollase::WXTexturePhaseMarchDollase()",5)
3500 mpSizer=new wxBoxSizer(wxHORIZONTAL);
3501 this->SetSizer(mpSizer);
3503 WXCrystObjBasic* pFieldFraction=pTex->GetPar(&(pObj->mFraction)).WXCreate(this);
3504 mpSizer->Add(pFieldFraction,0,wxALIGN_LEFT);
3505 mList.Add(pFieldFraction);
3507 WXCrystObjBasic* pFieldMarch=pTex->GetPar(&(pObj->mMarchCoeff)).WXCreate(this);
3508 mpSizer->Add(pFieldMarch,0,wxALIGN_LEFT);
3509 mList.Add(pFieldMarch);
3512 mpSizer->Add(pFieldH,0,wxALIGN_LEFT);
3516 mpSizer->Add(pFieldK,0,wxALIGN_LEFT);
3520 mpSizer->Add(pFieldL,0,wxALIGN_LEFT);
3523 this->CrystUpdate(true);
3524 VFN_DEBUG_EXIT("WXTexturePhaseMarchDollase::WXTexturePhaseMarchDollase()",5)
3527 WXTexturePhaseMarchDollase::~WXTexturePhaseMarchDollase()
3529 mpTexturePhaseMarchDollase->WXNotifyDelete();
3535 if(lock)
mMutex.Unlock();
3541 if(lock)
mMutex.Unlock();
3558 VFN_DEBUG_ENTRY(
"WXTextureMarchDollase::WXTextureMarchDollase()",5)
3560 mpMenuBar->AddMenu("Phases",ID_REFOBJ_MENU_OBJ);
3561 mpMenuBar->AddMenuItem(ID_REFOBJ_MENU_OBJ,ID_POWDERTEXTURE_MENU_ADDPHASE,
3565 =mpTextureMarchDollase->mPhaseRegistry.WXCreate(this);
3566 mpSizer->Add(pWXPhaseRegistry,0,wxALIGN_LEFT);
3567 mList.Add(pWXPhaseRegistry);
3568 this->CrystUpdate(true);
3569 this->
SetToolTip(_T("Texture for this crystalline phase.\n")
3570 _T("You can describe the preferred orientation using ")
3571 _T("the March-Dollase model (use the menu).\n\n")
3572 _T("Although possible, it is not recommended to enable ")
3573 _T("the global optimization of texture parameters, ")
3574 _T("as it is *extremely* slow"));
3577 void WXTextureMarchDollase::OnAddTexturePhase(wxCommandEvent & WXUNUSED(event))
3579 VFN_DEBUG_ENTRY(
"WXTextureMarchDollase::OnAddTexturePhase()",5)
3580 mpTextureMarchDollase->AddPhase(0.,1.,1,0,0);
3581 VFN_DEBUG_EXIT("WXTextureMarchDollase::OnAddTexturePhase()",5)
3583 void WXTextureMarchDollase::OnDeleteTexturePhase(wxCommandEvent & WXUNUSED(event))
3592 WXTextureEllipsoid::WXTextureEllipsoid(wxWindow *parent, TextureEllipsoid *pObj):
3595 VFN_DEBUG_ENTRY(
"WXTextureEllipsoid::WXTextureEllipsoid()",6)
3596 mpWXTitle->SetLabel("Texture ellipsoid");
3597 mpWXTitle->SetForegroundColour(wxColour(0,0,255));
3599 wxBoxSizer* sizer1=new wxBoxSizer(wxHORIZONTAL);
3600 WXCrystObjBasic* pFieldEPR1=mpTextureEllipsoid->GetPar((
long)0).WXCreate(this);
3601 WXCrystObjBasic* pFieldEPR2=mpTextureEllipsoid->GetPar(1).WXCreate(this);
3602 WXCrystObjBasic* pFieldEPR3=mpTextureEllipsoid->GetPar(2).WXCreate(this);
3603 sizer1->Add(pFieldEPR1,0);
3604 sizer1->Add(pFieldEPR2,0);
3605 sizer1->Add(pFieldEPR3,0);
3606 mList.Add(pFieldEPR1);
3607 mList.Add(pFieldEPR2);
3608 mList.Add(pFieldEPR3);
3609 mpSizer->Add(sizer1);
3610 pFieldEPR1->
SetToolTip(_T("Texture Ellipsoidal function parameters:\n")
3611 _T("Icorr = Iobs[ 1 + (EPR1*h^2 + EPR2*k^2 + EPR3*l^2 + EPR4*2hk + EPR5*2hl + EPR6*2kl) * 0.001d^2 ]^-1.5"));
3612 pFieldEPR2->
SetToolTip(_T("Texture Ellipsoidal function parameters:\n")
3613 _T("Icorr = Iobs[ 1 + (EPR1*h^2 + EPR2*k^2 + EPR3*l^2 + EPR4*2hk + EPR5*2hl + EPR6*2kl) * 0.001d^2 ]^-1.5"));
3614 pFieldEPR3->
SetToolTip(_T("Texture Ellipsoidal function parameters:\n")
3615 _T("Icorr = Iobs[ 1 + (EPR1*h^2 + EPR2*k^2 + EPR3*l^2 + EPR4*2hk + EPR5*2hl + EPR6*2kl) * 0.001d^2 ]^-1.5"));
3617 wxBoxSizer* sizer2=new wxBoxSizer(wxHORIZONTAL);
3618 WXCrystObjBasic* pFieldEPR4=mpTextureEllipsoid->GetPar(3).WXCreate(this);
3619 WXCrystObjBasic* pFieldEPR5=mpTextureEllipsoid->GetPar(4).WXCreate(this);
3620 WXCrystObjBasic* pFieldEPR6=mpTextureEllipsoid->GetPar(5).WXCreate(this);
3621 sizer2->Add(pFieldEPR4,0);
3622 sizer2->Add(pFieldEPR5,0);
3623 sizer2->Add(pFieldEPR6,0);
3624 mList.Add(pFieldEPR4);
3625 mList.Add(pFieldEPR5);
3626 mList.Add(pFieldEPR6);
3627 mpSizer->Add(sizer2);
3628 pFieldEPR4->
SetToolTip(_T("Texture Ellipsoidal function parameters:\n")
3629 _T("Icorr = Iobs[ 1 + (EPR1*h^2 + EPR2*k^2 + EPR3*l^2 + EPR4*2hk + EPR5*2hl + EPR6*2kl) * 0.001d^2 ]^-1.5"));
3630 pFieldEPR5->
SetToolTip(_T("Texture Ellipsoidal function parameters:\n")
3631 _T("Icorr = Iobs[ 1 + (EPR1*h^2 + EPR2*k^2 + EPR3*l^2 + EPR4*2hk + EPR5*2hl + EPR6*2kl) * 0.001d^2 ]^-1.5"));
3632 pFieldEPR6->
SetToolTip(_T("Texture Ellipsoidal function parameters:\n")
3633 _T("Icorr = Iobs[ 1 + (EPR1*h^2 + EPR2*k^2 + EPR3*l^2 + EPR4*2hk + EPR5*2hl + EPR6*2kl) * 0.001d^2 ]^-1.5"));
3635 this->CrystUpdate(true);
3636 VFN_DEBUG_EXIT("WXTextureEllipsoid::WXTextureEllipsoid()",6)
3638 WXTextureEllipsoid::~WXTextureEllipsoid()
3640 mpTextureEllipsoid->WXNotifyDelete();
3653 static const long ID_POWDERDIFF_PROFILE=
WXCRYST_ID();
3654 static const long ID_POWDERDIFF_PROFILE_PV=
WXCRYST_ID();
3655 static const long ID_POWDERDIFF_PROFILE_PV_ANISO=
WXCRYST_ID();
3656 static const long ID_POWDERDIFF_LEBAIL=
WXCRYST_ID();
3657 static const long ID_POWDERDIFF_PROFILEFITTINGMODE=
WXCRYST_ID();
3658 static const long ID_POWDERDIFF_USELOCALLATTICEPAR=
WXCRYST_ID();
3662 EVT_MENU(ID_POWDERDIFF_SAVEHKLFCALC,
3674 PowderPatternDiffraction *p):
3676 mFreezeLatticePar(false),mFrozenLatticePar(6),mNeedLayout(false)
3678 VFN_DEBUG_ENTRY(
"WXPowderPatternDiffraction::WXPowderPatternDiffraction()",6)
3679 mpWXTitle->SetForegroundColour(wxColour(0,255,0));
3681 mpMenuBar->AddMenu("File",ID_REFOBJ_MENU_OBJ);
3682 mpMenuBar->AddMenuItem(ID_REFOBJ_MENU_OBJ,ID_POWDERDIFF_SAVEHKLFCALC,
3684 mpMenuBar->AddMenu("Profile",ID_POWDERDIFF_PROFILE);
3685 mpMenuBar->AddMenuItem(ID_POWDERDIFF_PROFILE,ID_POWDERDIFF_PROFILE_PV,
3686 "Pseudo-Voigt (X-Ray & monochromatic neutron)");
3687 mpMenuBar->AddMenuItem(ID_POWDERDIFF_PROFILE,ID_POWDERDIFF_PROFILE_PV_ANISO,
3688 "Anisotropic Pseudo-Voigt (X-Ray & monochromatic neutron)");
3689 mpMenuBar->AddMenuItem(ID_POWDERDIFF_PROFILE,ID_POWDERDIFF_PROFILE_DEPV,
3690 "Double-Exponential Pseudo-Voigt (neutron TOF)");
3691 mpMenuBar->GetMenu(ID_POWDERDIFF_PROFILE).AppendSeparator();
3692 mpMenuBar->AddMenuItem(ID_POWDERDIFF_PROFILE,ID_POWDERDIFF_LEBAIL,
3693 "Profile Fitting + Le Bail Extraction");
3698 mpProfileFittingMode= new wxCheckBox(this,ID_POWDERDIFF_PROFILEFITTINGMODE,
3699 _T("Profile Fitting (Le Bail) Mode"));
3700 mpSizer->Add(mpProfileFittingMode,0,wxALIGN_LEFT);
3703 mpSizer->Add(mpFieldCrystal,0,wxALIGN_LEFT);
3704 mList.Add(mpFieldCrystal);
3705 mpFieldCrystal->
SetToolTip(_T("Crystal structure for this diffraction phase\n")
3706 _T("Click on the button to select another structure"));
3708 wxSizer *pSizerFreezePar=new wxBoxSizer(wxHORIZONTAL);
3709 mpFreezeLatticePar= new wxCheckBox(this,ID_POWDERDIFF_USELOCALLATTICEPAR, _T("Freeze lattice par."));
3710 pSizerFreezePar->Add(mpFreezeLatticePar);
3711 mpGridFrozenLatticePar=new wxGrid(this,-1,wxDefaultPosition,wxDefaultSize);
3712 mpGridFrozenLatticePar->SetColLabelSize(0);
3713 mpGridFrozenLatticePar->SetRowLabelSize(0);
3714 mpGridFrozenLatticePar->DisableDragRowSize();
3715 pSizerFreezePar->Add(mpGridFrozenLatticePar);
3716 mpGridFrozenLatticePar->SetDefaultEditor(new wxGridCellFloatEditor(7,4));
3717 mpGridFrozenLatticePar->SetDefaultRenderer(new wxGridCellFloatRenderer(7,4));
3718 mpGridFrozenLatticePar->EnableScrolling(false,false);
3719 mpGridFrozenLatticePar->ShowScrollbars(wxSHOW_SB_NEVER ,wxSHOW_SB_NEVER );
3720 mpGridFrozenLatticePar->CreateGrid(1,6);
3721 mpGridFrozenLatticePar->SetDefaultColSize(60);
3722 mpGridFrozenLatticePar->EnableEditing(false);
3723 mpSizer->AddSpacer(1);
3724 mpSizer->Add(pSizerFreezePar);
3725 mpSizer->AddSpacer(1);
3729 =mpPowderPatternDiffraction->GetPar(&(mpPowderPatternDiffraction->mGlobalBiso))
3731 mList.Add(fieldGlobalBiso);
3732 mpSizer->Add(fieldGlobalBiso);
3734 WXTextureMarchDollase* pTexMD
3735 =new WXTextureMarchDollase(this,&(mpPowderPatternDiffraction->mCorrTextureMarchDollase));
3737 mpSizer->Add(pTexMD);
3739 WXTextureEllipsoid* pTexEllips
3740 =new WXTextureEllipsoid(this,&(mpPowderPatternDiffraction->mCorrTextureEllipsoid));
3741 mList.Add(pTexEllips);
3742 mpSizer->Add(pTexEllips);
3745 if(mpPowderPatternDiffraction->mpReflectionProfile!=0)
3747 VFN_DEBUG_ENTRY(
"WXPowderPatternDiffraction::WXPowderPatternDiffraction()",6)
3749 ->mpReflectionProfile->WXCreate(this);
3750 mpSizer->Add(pWXProf);
3755 this->CrystUpdate(true);
3756 VFN_DEBUG_EXIT("WXPowderPatternDiffraction::WXPowderPatternDiffraction()",6)
3759 void WXPowderPatternDiffraction::OnChangeCrystal(wxCommandEvent & WXUNUSED(event))
3761 VFN_DEBUG_MESSAGE(
"WXPowderPatternDiffraction::OnChangeCrystal()",6)
3764 Crystal *cryst=dynamic_cast<Crystal*>
3766 "Choose a Crystal Structure:",choice));
3767 if(0==cryst) return;
3768 mpPowderPatternDiffraction->SetCrystal(*cryst);
3769 this->CrystUpdate(true);
3771 void WXPowderPatternDiffraction::OnMenuSaveHKLFcalc(wxCommandEvent & WXUNUSED(event))
3773 VFN_DEBUG_MESSAGE(
"WXPowderPatternDiffraction::OnMenuSaveHKLFcalc()",6)
3775 wxFileDialog save(this,_T("Choose a file to save to"),_T(""),_T(""),_T("*.txt"),wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
3776 if(save.ShowModal() != wxID_OK) return;
3778 ofstream out(save.GetPath().ToAscii());
3780 mpPowderPatternDiffraction->PrintFhklCalc(out);
3784 void WXPowderPatternDiffraction::CrystUpdate(const
bool uui,const
bool lock)
3786 VFN_DEBUG_MESSAGE(
"WXPowderPatternDiffraction::CrystUpdate()",10)
3788 for(
unsigned int i=0;i<6;i++) mFrozenLatticePar(i)=mpPowderPatternDiffraction->GetFrozenLatticePar(i);
3789 if(mFreezeLatticePar!=mpPowderPatternDiffraction->FreezeLatticePar())
3791 mFreezeLatticePar=mpPowderPatternDiffraction->FreezeLatticePar();
3795 if(lock)
mMutex.Unlock();
3800 VFN_DEBUG_MESSAGE(
"WXPowderPatternDiffraction::UpdateUI()",10)
3802 mpFieldCrystal->SetValue(mpPowderPatternDiffraction->GetCrystal().GetName());
3803 mpProfileFittingMode->SetValue(mpPowderPatternDiffraction->GetExtractionMode());
3804 mpPowderPatternDiffraction->mCorrTextureEllipsoid.UpdateEllipsoidPar();
3805 mpGridFrozenLatticePar->Show(mFreezeLatticePar);
3806 if(mFreezeLatticePar)
3808 for(
unsigned int i=0;i<3;++i) mpGridFrozenLatticePar->SetCellValue(0, i, wxString::Format(
"%.4f",mFrozenLatticePar(i)));
3809 for(
unsigned int i=3;i<6;++i) mpGridFrozenLatticePar->SetCellValue(0, i, wxString::Format(
"%.3f",mFrozenLatticePar(i)*180/M_PI));
3811 mpFreezeLatticePar->SetValue(mFreezeLatticePar);
3814 VFN_DEBUG_MESSAGE(
"WXPowderPatternDiffraction::UpdateUI():Layout !", 10)
3818 if(lock)
mMutex.Unlock();
3821 bool WXPowderPatternDiffraction::Enable(
bool e)
3823 if(0!=mpGridFrozenLatticePar) mpGridFrozenLatticePar->Enable(e);
3824 return this->::wxWindow::Enable(e);
3827 void WXPowderPatternDiffraction::OnChangeProfile(wxCommandEvent & event)
3829 VFN_DEBUG_ENTRY(
"WXPowderPatternDiffraction::OnChangeProfile()",6)
3831 if(event.GetId()==ID_POWDERDIFF_PROFILE_PV)
3833 if(mpPowderPatternDiffraction->mpReflectionProfile==0)
3835 ReflectionProfilePseudoVoigt *p=
new ReflectionProfilePseudoVoigt;
3836 mpPowderPatternDiffraction->SetProfile(p);
3840 if(mpPowderPatternDiffraction->mpReflectionProfile->GetClassName()
3841 !=
"ReflectionProfilePseudoVoigt")
3843 ReflectionProfilePseudoVoigt *p=
new ReflectionProfilePseudoVoigt;
3844 if(mpPowderPatternDiffraction->mpReflectionProfile->GetClassName()==
"ReflectionProfilePseudoVoigtAnisotropic")
3846 p->GetPar(
"U").SetValue(mpPowderPatternDiffraction->mpReflectionProfile->GetPar(
"U").GetValue());
3847 p->GetPar(
"V").SetValue(mpPowderPatternDiffraction->mpReflectionProfile->GetPar(
"V").GetValue());
3848 p->GetPar(
"W").SetValue(mpPowderPatternDiffraction->mpReflectionProfile->GetPar(
"W").GetValue());
3849 p->GetPar(
"Eta0").SetValue(mpPowderPatternDiffraction->mpReflectionProfile->GetPar(
"Eta0").GetValue());
3850 p->GetPar(
"Eta1").SetValue(mpPowderPatternDiffraction->mpReflectionProfile->GetPar(
"Eta1").GetValue());
3851 p->GetPar(
"Asym0").SetValue(mpPowderPatternDiffraction->mpReflectionProfile->GetPar(
"Asym0").GetValue());
3852 p->GetPar(
"Asym1").SetValue(mpPowderPatternDiffraction->mpReflectionProfile->GetPar(
"Asym1").GetValue());
3853 p->GetPar(
"Asym2").SetValue(mpPowderPatternDiffraction->mpReflectionProfile->GetPar(
"Asym2").GetValue());
3855 mpPowderPatternDiffraction->SetProfile(p);
3859 if(event.GetId()==ID_POWDERDIFF_PROFILE_PV_ANISO)
3861 if(mpPowderPatternDiffraction->mpReflectionProfile==0)
3863 ReflectionProfilePseudoVoigtAnisotropic *p=
new ReflectionProfilePseudoVoigtAnisotropic;
3864 mpPowderPatternDiffraction->SetProfile(p);
3868 if(mpPowderPatternDiffraction->mpReflectionProfile->GetClassName()
3869 !=
"ReflectionProfilePseudoVoigtAnisotropic")
3871 ReflectionProfilePseudoVoigtAnisotropic *p=
new ReflectionProfilePseudoVoigtAnisotropic;
3872 if(mpPowderPatternDiffraction->mpReflectionProfile->GetClassName()==
"ReflectionProfilePseudoVoigt")
3874 p->GetPar(
"U").SetValue(mpPowderPatternDiffraction->mpReflectionProfile->GetPar(
"U").GetValue());
3875 p->GetPar(
"V").SetValue(mpPowderPatternDiffraction->mpReflectionProfile->GetPar(
"V").GetValue());
3876 p->GetPar(
"W").SetValue(mpPowderPatternDiffraction->mpReflectionProfile->GetPar(
"W").GetValue());
3877 p->GetPar(
"Eta0").SetValue(mpPowderPatternDiffraction->mpReflectionProfile->GetPar(
"Eta0").GetValue());
3878 p->GetPar(
"Eta1").SetValue(mpPowderPatternDiffraction->mpReflectionProfile->GetPar(
"Eta1").GetValue());
3879 p->GetPar(
"Asym0").SetValue(mpPowderPatternDiffraction->mpReflectionProfile->GetPar(
"Asym0").GetValue());
3880 p->GetPar(
"Asym1").SetValue(mpPowderPatternDiffraction->mpReflectionProfile->GetPar(
"Asym1").GetValue());
3881 p->GetPar(
"Asym2").SetValue(mpPowderPatternDiffraction->mpReflectionProfile->GetPar(
"Asym2").GetValue());
3882 p->GetPar(
"X").SetValue(sqrt(mpPowderPatternDiffraction->mpReflectionProfile->GetPar(
"W").GetValue()));
3884 mpPowderPatternDiffraction->SetProfile(p);
3888 if(event.GetId()==ID_POWDERDIFF_PROFILE_DEPV)
3890 if(mpPowderPatternDiffraction->mpReflectionProfile==0)
3892 ReflectionProfileDoubleExponentialPseudoVoigt *p=
3893 new ReflectionProfileDoubleExponentialPseudoVoigt
3894 (mpPowderPatternDiffraction->GetCrystal());
3895 mpPowderPatternDiffraction->SetProfile(p);
3899 if(mpPowderPatternDiffraction->mpReflectionProfile->GetClassName()
3900 !=
"ReflectionProfileDoubleExponentialPseudoVoigt")
3902 ReflectionProfileDoubleExponentialPseudoVoigt *p=
3903 new ReflectionProfileDoubleExponentialPseudoVoigt
3904 (mpPowderPatternDiffraction->GetCrystal());
3905 mpPowderPatternDiffraction->SetProfile(p);
3911 mpPowderPatternDiffraction->mpReflectionProfile->WXCreate(
this);
3912 mList.
Add(mpPowderPatternDiffraction->mpReflectionProfile->WXGet());
3913 mpSizer->Add(mpPowderPatternDiffraction->mpReflectionProfile->WXGet());
3914 wxTheApp->GetTopWindow()->Layout();
3915 wxTheApp->GetTopWindow()->SendSizeEvent();
3916 mpPowderPatternDiffraction->GetParentPowderPattern().UpdateDisplay();
3918 VFN_DEBUG_EXIT(
"WXPowderPatternDiffraction::OnChangeProfile()",6)
3922 static const long ID_PROFILEFITTING_RUN= WXCRYST_ID();
3923 static const long ID_PROFILEFITTING_RUN_MANUAL= WXCRYST_ID();
3924 static const long ID_PROFILEFITTING_EXPLORE_SPG= WXCRYST_ID();
3925 static const long ID_PROFILEFITTING_EXPLORE_SPG_QUICK= WXCRYST_ID();
3927 BEGIN_EVENT_TABLE(WXProfileFitting, wxWindow)
3928 EVT_BUTTON(ID_PROFILEFITTING_RUN, WXProfileFitting::OnFit)
3929 EVT_BUTTON(ID_PROFILEFITTING_RUN_MANUAL, WXProfileFitting::OnFit)
3930 EVT_BUTTON(ID_PROFILEFITTING_EXPLORE_SPG, WXProfileFitting::OnExploreSpacegroups)
3931 EVT_BUTTON(ID_PROFILEFITTING_EXPLORE_SPG_QUICK, WXProfileFitting::OnExploreSpacegroups)
3934 WXProfileFitting::WXProfileFitting(wxWindow *parent,PowderPattern *pPattern,PowderPatternDiffraction *pDiff):
3935 wxWindow(parent,-1),mpPattern(pPattern),mpDiff(pDiff),mLSQ("Profile Fitting
object"),mpList(0)
3937 wxBoxSizer *pSizer0=
new wxBoxSizer(wxVERTICAL);
3938 this->SetSizer(pSizer0);
3940 wxNotebook *pNotebook =
new wxNotebook(
this, -1,wxDefaultPosition,wxSize(600,400));
3941 pSizer0->Add(pNotebook,0,wxALIGN_CENTER);
3943 wxWindow *pQuick=
new wxWindow(pNotebook,-1);
3944 pNotebook->AddPage(pQuick,_T(
"Quick Fit"),
true);
3945 wxBoxSizer *pSizer=
new wxBoxSizer(wxVERTICAL);
3947 wxButton *pButton1=
new wxButton(pQuick,ID_PROFILEFITTING_RUN,_T(
"Le Bail + Fit Profile !"));
3948 pSizer->Add(pButton1,0,wxALIGN_CENTER);
3952 wxArrayString choices;
3954 unsigned int nb=mpPattern->GetNbPowderPatternComponent();
3955 for(
unsigned int i=0;i<nb;++i)
3956 if(mpPattern->GetPowderPatternComponent(i).GetClassName()==string(
"PowderPatternDiffraction"))
3958 pDiff=
dynamic_cast<PowderPatternDiffraction*
>(&(mpPattern->GetPowderPatternComponent(i)));
3961 cout<<
"WXProfileFitting::WXProfileFitting():"<<pDiff<<
":"<<mpPattern->GetPowderPatternComponent(i).GetName()
3962 <<
","<<pDiff->GetCrystal().GetName()<<endl;
3963 choices.Add(wxString::FromAscii(pDiff->GetCrystal().GetName().c_str())
3964 +wxString::Format(_T(
", a=%6.3f b=%6.3f c=%6.3f"),
3965 pDiff->GetCrystal().GetLatticePar(0),
3966 pDiff->GetCrystal().GetLatticePar(1),
3967 pDiff->GetCrystal().GetLatticePar(2)));
3972 if(choices.GetCount()==0)
3974 wxMessageBox(_T(
"To run Le Bail & Profile fitting, you \n")
3975 _T(
"need at least one crystalline phase !"),
3976 _T(
"Missing crystalline phase !"),
3977 wxYES_NO|wxICON_ERROR);
3978 this->GetParent()->Destroy();
3981 if(choices.GetCount()==1)
3983 cout<<
"WXProfileFitting::WXProfileFitting():"<<choices[0]<<
","<<pDiff<<endl;
3988 wxStaticText *pLabel=
new wxStaticText(pQuick,-1,_T(
"Crystalline Phase to Fit:"));
3989 pSizer->Add(pLabel,0,wxALIGN_CENTER);
3991 mpList=
new wxListBox(pQuick,-1,wxDefaultPosition,wxSize(-1,80),choices,wxLB_SINGLE);
3992 mpList->SetSelection(0);
3993 pSizer->Add(mpList,0,wxALIGN_CENTER);
3999 wxArrayInt selections;
4000 mpList->GetSelections(selections);
4001 const int choice=selections[0];
4003 unsigned int nb=mpPattern->GetNbPowderPatternComponent();
4004 for(
unsigned int i=0;i<nb;++i)
4005 if(mpPattern->GetPowderPatternComponent(i).GetClassName()==string(
"PowderPatternDiffraction"))
4007 pDiff=
dynamic_cast<PowderPatternDiffraction*
>(&(mpPattern->GetPowderPatternComponent(i)));
4008 cout<<
"WXProfileFitting::WXProfileFitting():"<<pDiff<<
":"<<mpPattern->GetPowderPatternComponent(i).GetName()<<endl;
4014 cout<<
"Chosen:"<<mpPattern->GetPowderPatternComponent(i).GetName()<<endl;
4017 cout<<
"Not chosen:"<<mpPattern->GetPowderPatternComponent(i).GetName()<<endl;
4021 wxArrayString fitChoices;
4022 if(mpDiff->GetProfile().GetClassName()==
"ReflectionProfileDoubleExponentialPseudoVoigt")
4024 fitChoices.Add(_T(
"Fit Zero shift"));
4025 fitChoices.Add(_T(
"Fit Instrumental Width (alpha1,beta0,beta1)"));
4026 fitChoices.Add(_T(
"Fit Size/Strain Broadening (sigma1,gamma2)"));
4027 fitChoices.Add(_T(
"Fit Background"));
4028 fitChoices.Add(_T(
"Fit Unit Cell"));
4032 fitChoices.Add(_T(
"Fit Zero shift"));
4033 fitChoices.Add(_T(
"Fit Constant Width"));
4034 fitChoices.Add(_T(
"Fit Variable Width"));
4035 fitChoices.Add(_T(
"Fit Gaussian-Lorentzian Mixing"));
4036 fitChoices.Add(_T(
"Fit Asymmetric parameters"));
4037 fitChoices.Add(_T(
"Fit Displacement+Transparency"));
4038 fitChoices.Add(_T(
"Fit Background"));
4039 fitChoices.Add(_T(
"Fit Unit Cell"));
4041 mpFitCheckList=
new wxCheckListBox(pQuick,-1,wxDefaultPosition,wxDefaultSize,fitChoices);
4042 if(mpDiff->GetProfile().GetClassName()==
"ReflectionProfileDoubleExponentialPseudoVoigt")
4044 mpFitCheckList->Check(0,
false);
4045 mpFitCheckList->Check(1,
false);
4046 mpFitCheckList->Check(2,
true);
4047 mpFitCheckList->Check(3,
true);
4048 mpFitCheckList->Check(4,
true);
4052 mpFitCheckList->Check(0,
true);
4053 mpFitCheckList->Check(1,
true);
4054 mpFitCheckList->Check(2,
true);
4055 mpFitCheckList->Check(3,
true);
4056 mpFitCheckList->Check(4,
true);
4057 mpFitCheckList->Check(5,
true);
4058 mpFitCheckList->Check(6,
true);
4059 mpFitCheckList->Check(7,
true);
4061 pSizer->Add(mpFitCheckList,1,wxEXPAND|wxALIGN_CENTER);
4063 pQuick->SetSizer(pSizer);
4064 pSizer->SetSizeHints(pQuick);
4069 mLSQ.SetRefinedObj(pDiff->GetParentPowderPattern(),0,
true,
true);
4070 mLSQ.PrepareRefParList(
true);
4077 mLSQ.SetParIsUsed(gpRefParTypeScatt,
false);
4078 mLSQ.SetParIsUsed(gpRefParTypeScattPow,
false);
4082 wxScrolledWindow *pManual=
new wxScrolledWindow(pNotebook,-1,wxDefaultPosition,
4083 wxSize(400,250),wxHSCROLL | wxVSCROLL);
4084 wxBoxSizer *pSizerManual=
new wxBoxSizer(wxVERTICAL);
4086 wxButton *pButton2=
new wxButton(pManual,ID_PROFILEFITTING_RUN_MANUAL,_T(
"Le Bail + Fit Profile !"));
4087 pSizerManual->Add(pButton2,0,wxALIGN_CENTER);
4089 pSizerManual->Add(mLSQ.WXCreate(pManual),0,wxALIGN_CENTER);
4090 mLSQ.WXGet()->CrystUpdate(
true,
true);
4091 pManual->SetScrollRate(10,10);
4092 pManual->SetSizer(pSizerManual);
4094 pSizerManual->FitInside(pManual);
4096 pNotebook->AddPage(pManual,_T(
"Manual Fit"),
true);
4099 wxScrolledWindow *pSpgExplor=
new wxScrolledWindow(pNotebook,-1,wxDefaultPosition,
4100 wxSize(600,250),wxHSCROLL | wxVSCROLL);
4101 wxBoxSizer *pSizerSpgExplor=
new wxBoxSizer(wxVERTICAL);
4103 wxButton *pButton3=
new wxButton(pSpgExplor,ID_PROFILEFITTING_EXPLORE_SPG,_T(
"Try all possible spacegroups - Le Bail + Least Squares (SLOW)"));
4104 pSizerSpgExplor->Add(pButton3,0,wxALIGN_CENTER);
4105 wxButton *pButton4=
new wxButton(pSpgExplor,ID_PROFILEFITTING_EXPLORE_SPG_QUICK,_T(
"Try all possible spacegroups - Le Bail only"));
4106 pSizerSpgExplor->Add(pButton4,0,wxALIGN_CENTER);
4108 pSpgExplor->SetSizer(pSizerSpgExplor);
4109 pSpgExplor->Layout();
4110 pSizerSpgExplor->FitInside(pSpgExplor);
4112 pNotebook->AddPage(pSpgExplor,_T(
"Spacegroup Explorer"),
true);
4114 pNotebook->ChangeSelection(0);
4115 mpLog =
new wxTextCtrl(
this,-1,_T(
""),wxDefaultPosition,wxSize(600,300),wxTE_MULTILINE|wxTE_READONLY|wxTE_DONTWRAP);
4116 mpLog->SetFont(wxFont(9,wxTELETYPE,wxFONTSTYLE_NORMAL,wxFONTWEIGHT_NORMAL));
4117 pSizer0->Add(mpLog,0,wxALIGN_CENTER|wxEXPAND);
4121 pSizer0->SetSizeHints(
this);
4123 pSizer0->Fit(this->GetParent());
4127 WXProfileFitting::~WXProfileFitting()
4129 if(mpDiff!=0) mpDiff->SetExtractionMode(
false);
4132 unsigned int nb=mpPattern->GetNbPowderPatternComponent();
4133 for(
unsigned int i=0;i<nb;++i)
4134 if(mpPattern->GetPowderPatternComponent(i).GetClassName()==string(
"PowderPatternDiffraction"))
4136 PowderPatternDiffraction *pDiff=
dynamic_cast<PowderPatternDiffraction*
>(&(mpPattern->GetPowderPatternComponent(i)));
4137 if(pDiff!=0) pDiff->SetExtractionMode(
false);
4140 mpPattern->UpdateDisplay();
4143 void WXProfileFitting::OnFit(wxCommandEvent &event)
4146 map<PowderPatternDiffraction *,bool> vpDiff;
4150 wxArrayInt selections;
4151 mpList->GetSelections(selections);
4152 const int choice=selections[0];
4154 unsigned int nb=mpPattern->GetNbPowderPatternComponent();
4155 for(
unsigned int i=0;i<nb;++i)
4156 if(mpPattern->GetPowderPatternComponent(i).GetClassName()==string(
"PowderPatternDiffraction"))
4158 PowderPatternDiffraction *pDiff=
dynamic_cast<PowderPatternDiffraction*
>(&(mpPattern->GetPowderPatternComponent(i)));
4159 cout<<
"WXProfileFitting::WXProfileFitting():"<<pDiff<<
":"<<mpPattern->GetPowderPatternComponent(i).GetName()<<endl;
4162 if(ct++==choice) vpDiff[pDiff]=
true;
4163 else vpDiff[pDiff]=
false;
4169 unsigned int nb=mpPattern->GetNbPowderPatternComponent();
4170 for(
unsigned int i=0;i<nb;++i)
4171 if(mpPattern->GetPowderPatternComponent(i).GetClassName()==string(
"PowderPatternDiffraction"))
4173 PowderPatternDiffraction *pDiff=
dynamic_cast<PowderPatternDiffraction*
>(&(mpPattern->GetPowderPatternComponent(i)));
4174 cout<<
"WXProfileFitting::WXProfileFitting():"<<pDiff<<
":"<<mpPattern->GetPowderPatternComponent(i).GetName()<<endl;
4177 if(pDiff==mpDiff) vpDiff[pDiff]=
true;
4178 else vpDiff[pDiff]=
false;
4183 if(mpDiff!=0) pDiff=mpDiff;
4186 unsigned int nb=mpPattern->GetNbPowderPatternComponent();
4188 const unsigned int n0=mpList->GetSelection();
4189 for(
unsigned int i=0;i<nb;++i)
4191 if(mpPattern->GetPowderPatternComponent(i).GetClassName()==string(
"PowderPatternDiffraction"))
4193 pDiff=
dynamic_cast<PowderPatternDiffraction*
>(&(mpPattern->GetPowderPatternComponent(i)));
4202 cout<<
"Selected PowderPatternDiffraction:"<<mpDiff->GetName()<<
","<<mpDiff->GetCrystal().GetName()<<endl;
4204 for(map<PowderPatternDiffraction *,bool>::iterator pos=vpDiff.begin();pos!=vpDiff.end();++pos)
4205 if(pos->second) pos->first->SetExtractionMode(
true,
true);
4207 mpLog->AppendText(wxString::Format(_T(
"Starting 20 Le Bail cycles\n")));
4208 wxProgressDialog dlgProgress(_T(
"Le Bail and Profile Fitting"),_T(
"Le Bail Fitting, cycle #0/20"),
4209 18,
this,wxPD_AUTO_HIDE|wxPD_ELAPSED_TIME|wxPD_CAN_ABORT);
4210 for(
int i=0;i<10;++i)
4212 for(map<PowderPatternDiffraction *,bool>::iterator pos=vpDiff.begin();pos!=vpDiff.end();++pos)
4215 pos->first->ExtractLeBail(2);
4216 pos->first->GetParentPowderPattern().FitScaleFactorForRw();
4217 pos->first->GetParentPowderPattern().UpdateDisplay();
4219 if(dlgProgress.Update(i,wxString::Format(_T(
"Le Bail Fitting, cycle #%d/20"),i*2))==
false)
return;
4221 mpLog->AppendText(wxString::Format(_T(
" => Rwp=%5.3f%%, GoF=%7.3f\n"),
4222 mpDiff->GetParentPowderPattern().GetRw()*100,
4223 mpDiff->GetParentPowderPattern().GetChi2()
4224 /mpDiff->GetParentPowderPattern().GetNbPointUsed()));
4226 if(event.GetId()==ID_PROFILEFITTING_RUN)
4228 bool fitzero=
false,fitwidth0=
false,fitwidth=
false,fiteta=
false,
4229 fitasym=
false,fitdispltransp=
false,fitbackgd=
false,fitcell=
false,
4230 fitanisotropic=
false,
4231 fitTOFInstWidth=
false,fitTOFBroadening=
false;
4233 if(mpDiff->GetProfile().GetClassName()==
"ReflectionProfileDoubleExponentialPseudoVoigt")
4235 mpDiff->GetProfile().Print();
4236 fitzero=mpFitCheckList->IsChecked(0);
4237 fitTOFInstWidth=mpFitCheckList->IsChecked(1);
4238 fitTOFBroadening=mpFitCheckList->IsChecked(2);
4239 fitbackgd=mpFitCheckList->IsChecked(3);
4240 fitcell=mpFitCheckList->IsChecked(4);
4244 fitzero=mpFitCheckList->IsChecked(0);
4245 fitwidth0=mpFitCheckList->IsChecked(1);
4246 fitwidth=mpFitCheckList->IsChecked(2);
4247 fiteta=mpFitCheckList->IsChecked(3);
4248 fitasym=mpFitCheckList->IsChecked(4);
4249 fitdispltransp=mpFitCheckList->IsChecked(5);
4250 fitbackgd=mpFitCheckList->IsChecked(6);
4251 fitcell=mpFitCheckList->IsChecked(7);
4256 if(fitzero) mLSQ.SetParIsFixed(mpDiff->GetParentPowderPattern().GetPar(
"Zero"),
false);
4258 for(map<PowderPatternDiffraction *,bool>::iterator pos=vpDiff.begin();pos!=vpDiff.end();++pos)
4259 if(pos->second) mLSQ.SetParIsFixed(pos->first->GetProfile().GetPar(
"W"),
false);
4261 for(map<PowderPatternDiffraction *,bool>::iterator pos=vpDiff.begin();pos!=vpDiff.end();++pos)
4262 if((pos->second) && (pos->first->GetProfile().GetClassName()==
"ReflectionProfilePseudoVoigtAnisotropic"))
4263 mLSQ.SetParIsFixed(pos->first->GetProfile().GetPar(
"X"),
false);
4264 if(fitzero||fitwidth0)
4266 mpLog->AppendText(wxString::Format(_T(
"Fitting zero shift && constant width\n")));
4267 if(dlgProgress.Update(11,_T(
"Fitting zero shift && constant width"))==
false)
return;
4268 mLSQ.Refine(5,
true,
false);
4269 mpDiff->ExtractLeBail(2);
4270 mpDiff->GetParentPowderPattern().UpdateDisplay();
4271 mpLog->AppendText(wxString::Format(_T(
" => Rwp=%6.3f%%, GoF=%7.3f\n"),
4272 mpDiff->GetParentPowderPattern().GetRw()*100,
4273 mpDiff->GetParentPowderPattern().GetChi2()
4274 /mpDiff->GetParentPowderPattern().GetNbPointUsed()));
4277 for(map<PowderPatternDiffraction *,bool>::iterator pos=vpDiff.begin();pos!=vpDiff.end();++pos)
4278 if(pos->second) mLSQ.SetParIsFixed(pos->first->GetProfile().GetPar(
"U"),
false);
4280 for(map<PowderPatternDiffraction *,bool>::iterator pos=vpDiff.begin();pos!=vpDiff.end();++pos)
4281 if(pos->second) mLSQ.SetParIsFixed(pos->first->GetProfile().GetPar(
"V"),
false);
4283 for(map<PowderPatternDiffraction *,bool>::iterator pos=vpDiff.begin();pos!=vpDiff.end();++pos)
4284 if((pos->second) && (pos->first->GetProfile().GetClassName()==
"ReflectionProfilePseudoVoigtAnisotropic"))
4285 mLSQ.SetParIsFixed(pos->first->GetProfile().GetPar(
"Y"),
false);
4287 for(map<PowderPatternDiffraction *,bool>::iterator pos=vpDiff.begin();pos!=vpDiff.end();++pos)
4288 if((pos->second) && (pos->first->GetProfile().GetClassName()==
"ReflectionProfilePseudoVoigtAnisotropic"))
4289 mLSQ.SetParIsFixed(pos->first->GetProfile().GetPar(
"P"),
false);
4291 for(map<PowderPatternDiffraction *,bool>::iterator pos=vpDiff.begin();pos!=vpDiff.end();++pos)
4292 if(pos->second) mLSQ.SetParIsFixed(pos->first->GetProfile().GetPar(
"Eta0"),
false);
4293 if(fitwidth||fiteta)
4295 mpLog->AppendText(wxString::Format(_T(
"Fitting width and gaussian/lorentzian fixed mix\n")));
4296 if(dlgProgress.Update(12,_T(
"Fitting variable width and gaussian/lorentzian fixed mix"))==
false)
return;
4297 mLSQ.Refine(5,
true,
false);
4298 mpDiff->ExtractLeBail(2);
4299 mpDiff->GetParentPowderPattern().UpdateDisplay();
4300 mpLog->AppendText(wxString::Format(_T(
" => Rwp=%6.3f%%, GoF=%7.3f\n"),
4301 mpDiff->GetParentPowderPattern().GetRw()*100,
4302 mpDiff->GetParentPowderPattern().GetChi2()
4303 /mpDiff->GetParentPowderPattern().GetNbPointUsed()));
4308 mpDiff->GetProfile().Print();
4309 for(map<PowderPatternDiffraction *,bool>::iterator pos=vpDiff.begin();pos!=vpDiff.end();++pos)
4312 mLSQ.SetParIsFixed(pos->first->GetProfile().GetPar(
"Alpha1"),
false);
4313 mLSQ.SetParIsFixed(pos->first->GetProfile().GetPar(
"Beta0"),
false);
4314 mLSQ.SetParIsFixed(pos->first->GetProfile().GetPar(
"Beta1"),
false);
4316 mpLog->AppendText(wxString::Format(_T(
"Fitting TOF instrumental width (alpha1,beta0,beta1)\n")));
4317 if(dlgProgress.Update(12,_T(
"Fitting TOF instrumental width (alpha1,beta0,beta1)"))==
false)
return;
4318 mLSQ.Refine(5,
true,
false);
4319 mpDiff->ExtractLeBail(2);
4320 mpDiff->GetParentPowderPattern().UpdateDisplay();
4321 mpLog->AppendText(wxString::Format(_T(
" => Rwp=%6.3f%%, GoF=%7.3f\n"),
4322 mpDiff->GetParentPowderPattern().GetRw()*100,
4323 mpDiff->GetParentPowderPattern().GetChi2()
4324 /mpDiff->GetParentPowderPattern().GetNbPointUsed()));
4326 if(fitTOFBroadening)
4328 mpDiff->GetProfile().Print();
4329 for(map<PowderPatternDiffraction *,bool>::iterator pos=vpDiff.begin();pos!=vpDiff.end();++pos)
4332 mLSQ.SetParIsFixed(pos->first->GetProfile().GetPar(
"GaussianSigma1"),
false);
4337 mpLog->AppendText(wxString::Format(_T(
"Fitting size/strain broadening parameters (sigma1,gamma2)\n")));
4338 if(dlgProgress.Update(12,_T(
"Fitting size/strain broadening parameters (sigma1,gamma2)"))==
false)
return;
4339 mLSQ.Refine(5,
true,
false);
4340 mpDiff->ExtractLeBail(2);
4341 mpDiff->GetParentPowderPattern().UpdateDisplay();
4342 mpLog->AppendText(wxString::Format(_T(
" => Rwp=%6.3f%%, GoF=%7.3f\n"),
4343 mpDiff->GetParentPowderPattern().GetRw()*100,
4344 mpDiff->GetParentPowderPattern().GetChi2()
4345 /mpDiff->GetParentPowderPattern().GetNbPointUsed()));
4346 for(map<PowderPatternDiffraction *,bool>::iterator pos=vpDiff.begin();pos!=vpDiff.end();++pos)
4348 mLSQ.SetParIsFixed(pos->first->GetProfile().GetPar(
"GaussianSigma1"),
true);
4351 if(fiteta) mLSQ.SetParIsFixed(mpDiff->GetProfile().GetPar(
"Eta1"),
false);
4354 mpLog->AppendText(wxString::Format(_T(
"Fitting gaussian/lorentzian mix\n")));
4355 if(dlgProgress.Update(13,_T(
"Fitting variable width and gaussian/lorentzian mix"))==
false)
return;
4356 mLSQ.Refine(5,
true,
false);
4357 mpDiff->ExtractLeBail(2);
4358 mpDiff->GetParentPowderPattern().UpdateDisplay();
4359 mpLog->AppendText(wxString::Format(_T(
" => Rwp=%6.3f%%, GoF=%7.3f\n"),
4360 mpDiff->GetParentPowderPattern().GetRw()*100,
4361 mpDiff->GetParentPowderPattern().GetChi2()
4362 /mpDiff->GetParentPowderPattern().GetNbPointUsed()));
4366 for(map<PowderPatternDiffraction *,bool>::iterator pos=vpDiff.begin();pos!=vpDiff.end();++pos)
4367 if(pos->second) mLSQ.SetParIsFixed(pos->first->GetProfile().GetPar(
"Asym0"),
false);
4369 for(map<PowderPatternDiffraction *,bool>::iterator pos=vpDiff.begin();pos!=vpDiff.end();++pos)
4370 if(pos->second) mLSQ.SetParIsFixed(pos->first->GetProfile().GetPar(
"Asym1"),
false);
4372 for(map<PowderPatternDiffraction *,bool>::iterator pos=vpDiff.begin();pos!=vpDiff.end();++pos)
4373 if(pos->second) mLSQ.SetParIsFixed(pos->first->GetProfile().GetPar(
"Asym2"),
false);
4375 for(map<PowderPatternDiffraction *,bool>::iterator pos=vpDiff.begin();pos!=vpDiff.end();++pos)
4376 if(pos->second) mLSQ.SetParIsFixed(pos->first->GetParentPowderPattern().GetPar(
"2ThetaDispl"),
false);
4378 for(map<PowderPatternDiffraction *,bool>::iterator pos=vpDiff.begin();pos!=vpDiff.end();++pos)
4379 if(pos->second) mLSQ.SetParIsFixed(pos->first->GetParentPowderPattern().GetPar(
"2ThetaTransp"),
false);
4380 if(fitdispltransp||fitasym)
4382 mpLog->AppendText(wxString::Format(_T(
"Fitting assymetry and sample displacement/transparency\n")));
4383 if(dlgProgress.Update(14,_T(
"Fitting assymetry and sample displacement/transparency"))==
false)
return;
4384 mLSQ.Refine(5,
true,
false);
4385 mpDiff->ExtractLeBail(2);
4386 mpDiff->GetParentPowderPattern().UpdateDisplay();
4387 mpLog->AppendText(wxString::Format(_T(
" => Rwp=%6.3f%%, GoF=%7.3f\n"),
4388 mpDiff->GetParentPowderPattern().GetRw()*100,
4389 mpDiff->GetParentPowderPattern().GetChi2()
4390 /mpDiff->GetParentPowderPattern().GetNbPointUsed()));
4397 const unsigned int nbcomp= mpDiff->GetParentPowderPattern().GetNbPowderPatternComponent();
4398 for(
unsigned int i=0;i<nbcomp;++i)
4399 if(mpDiff->GetParentPowderPattern().GetPowderPatternComponent(i).GetClassName()==
"PowderPatternBackground")
4401 PowderPatternBackground *pback=
dynamic_cast<PowderPatternBackground *
>
4402 (&(mpDiff->GetParentPowderPattern().GetPowderPatternComponent(i)));
4403 pback->FixParametersBeyondMaxresolution(mLSQ.GetCompiledRefinedObj());
4406 mpLog->AppendText(wxString::Format(_T(
"Fitting background\n")));
4407 if(dlgProgress.Update(15,_T(
"Fitting background"))==
false)
return;
4408 mLSQ.Refine(5,
true,
false);
4409 mpDiff->ExtractLeBail(2);
4410 mpDiff->GetParentPowderPattern().UpdateDisplay();
4411 mpLog->AppendText(wxString::Format(_T(
" => Rwp=%6.3f%%, GoF=%7.3f\n"),
4412 mpDiff->GetParentPowderPattern().GetRw()*100,
4413 mpDiff->GetParentPowderPattern().GetChi2()
4414 /mpDiff->GetParentPowderPattern().GetNbPointUsed()));
4419 mLSQ.SetParIsFixed(gpRefParTypeUnitCell,
false);
4422 for(map<PowderPatternDiffraction *,bool>::iterator pos=vpDiff.begin();pos!=vpDiff.end();++pos)
4423 if(!(pos->second)) mLSQ.SetParIsFixed(pos->first->GetCrystal(),
true);
4425 mpLog->AppendText(wxString::Format(_T(
"Fitting unit cell\n")));
4426 if(dlgProgress.Update(16,_T(
"Fitting unit cell"))==
false)
return;
4427 mLSQ.Refine(5,
true,
false);
4428 mpDiff->ExtractLeBail(2);
4429 mpDiff->GetParentPowderPattern().UpdateDisplay();
4430 mpLog->AppendText(wxString::Format(_T(
" => Rwp=%6.3f%%, GoF=%7.3f\n"),
4431 mpDiff->GetParentPowderPattern().GetRw()*100,
4432 mpDiff->GetParentPowderPattern().GetChi2()
4433 /mpDiff->GetParentPowderPattern().GetNbPointUsed()));
4436 catch(
const ObjCrystException &except)
4438 mpLog->AppendText(wxString::Format(_T(
" OOPS : refinement diverged ! Aborting.\n")));
4445 mpLog->AppendText(wxString::Format(_T(
"Profile fitting (manual):\n")));
4446 mpLog->AppendText(wxString::Format(_T(
" Initial values: Rwp=%6.3f%%, GoF=%7.3f\n"),
4447 mpDiff->GetParentPowderPattern().GetRw()*100,
4448 mpDiff->GetParentPowderPattern().GetChi2()
4449 /mpDiff->GetParentPowderPattern().GetNbPointUsed()));
4450 mpLog->AppendText(wxString::Format(_T(
"3 LSQ cycles...\n")));
4451 mLSQ.Refine(3,
true,
false);
4452 mpLog->AppendText(wxString::Format(_T(
" => Rwp=%6.3f%%, GoF=%7.3f\n"),
4453 mpDiff->GetParentPowderPattern().GetRw()*100,
4454 mpDiff->GetParentPowderPattern().GetChi2()
4455 /mpDiff->GetParentPowderPattern().GetNbPointUsed()));
4456 mpLog->AppendText(wxString::Format(_T(
"2 Le Bail cycles...\n")));
4457 if(dlgProgress.Update(9,_T(
"Manual Le Bail + Profile fitting"))==
false)
return;
4458 mpDiff->ExtractLeBail(2);
4459 mpLog->AppendText(wxString::Format(_T(
" => Rwp=%6.3f%%, GoF=%7.3f\n"),
4460 mpDiff->GetParentPowderPattern().GetRw()*100,
4461 mpDiff->GetParentPowderPattern().GetChi2()
4462 /mpDiff->GetParentPowderPattern().GetNbPointUsed()));
4463 mpLog->AppendText(wxString::Format(_T(
"3 LSQ cycles...\n")));
4464 if(dlgProgress.Update(13,_T(
"Manual Le Bail + Profile fitting"))==
false)
return;
4465 mLSQ.Refine(3,
true,
false);
4466 if(dlgProgress.Update(17,_T(
"Manual Le Bail + Profile fitting"))==
false)
return;
4467 mpDiff->GetParentPowderPattern().UpdateDisplay();
4468 mpLog->AppendText(wxString::Format(_T(
" => Rwp=%6.3f%%, GoF=%7.3f\n"),
4469 mpDiff->GetParentPowderPattern().GetRw()*100,
4470 mpDiff->GetParentPowderPattern().GetChi2()
4471 /mpDiff->GetParentPowderPattern().GetNbPointUsed()));
4473 catch(
const ObjCrystException &except)
4475 mpLog->AppendText(wxString::Format(_T(
" OOPS : refinement diverged ! Aborting.\n")));
4478 mLSQ.WXGet()->CrystUpdate(
true,
true);
4479 mpDiff->GetCrystal().UpdateDisplay();
4484 SPGScore(
const string &s,
const REAL r,
const REAL g,
const unsigned int nbextinct):
4485 hm(s),rw(r),gof(g),nbextinct446(nbextinct)
4489 unsigned int nbextinct446;
4492 bool compareSPGScore(
const SPGScore &s1,
const SPGScore &s2)
4494 return s1.gof < s2.gof;
4497 std::vector<bool> spgExtinctionFingerprint(Crystal &c,cctbx::sgtbx::space_group &spg)
4500 std::vector<bool> fingerprint(5*5*7-1+6);
4502 fingerprint[i++]=c.GetPar(
"a").IsUsed();
4503 fingerprint[i++]=c.GetPar(
"b").IsUsed();
4504 fingerprint[i++]=c.GetPar(
"c").IsUsed();
4505 fingerprint[i++]=c.GetPar(
"alpha").IsUsed();
4506 fingerprint[i++]=c.GetPar(
"beta").IsUsed();
4507 fingerprint[i++]=c.GetPar(
"gamma").IsUsed();
4508 for(
long h=0;h<5;++h)
4509 for(
long k=0;k<5;++k)
4510 for (
long l=0;l<7;++l)
4512 if((h+k+l)==0)
continue;
4513 cctbx::miller::index<long> hkl(scitbx::vec3<long>(h,k,l));
4514 if(i>=fingerprint.size()) cout<<
"WHOOOOOOOOOOOOOPS"<<endl;
4515 fingerprint[i++] =spg.is_sys_absent(hkl);
4520 void WXProfileFitting::OnExploreSpacegroups(wxCommandEvent &event)
4522 TAU_PROFILE(
"WXProfileFitting::OnExploreSpacegroups()",
"void (wxCommandEvent &)",TAU_DEFAULT);
4523 TAU_PROFILE_TIMER(timer1,
"WXProfileFitting::OnExploreSpacegroups()LSQ-P1",
"", TAU_FIELD);
4524 TAU_PROFILE_TIMER(timer2,
"WXProfileFitting::OnExploreSpacegroups()LSQ1",
"", TAU_FIELD);
4525 TAU_PROFILE_TIMER(timer3,
"WXProfileFitting::OnExploreSpacegroups()LSQ2",
"", TAU_FIELD);
4526 PowderPatternDiffraction *pDiff=0;
4527 if(mpDiff!=0) pDiff=mpDiff;
4530 unsigned int nb=mpPattern->GetNbPowderPatternComponent();
4532 const unsigned int n0=mpList->GetSelection();
4533 for(
unsigned int i=0;i<nb;++i)
4535 if(mpPattern->GetPowderPatternComponent(i).GetClassName()==string(
"PowderPatternDiffraction"))
4537 pDiff=
dynamic_cast<PowderPatternDiffraction*
>(&(mpPattern->GetPowderPatternComponent(i)));
4545 cout<<
"Selected PowderPatternDiffraction:"<<pDiff->GetName()<<
","<<pDiff->GetCrystal().GetName()<<endl;
4547 pDiff->SetExtractionMode(
true,
true);
4548 Crystal *pCrystal=&(pDiff->GetCrystal());
4551 const REAL a=pCrystal->GetLatticePar(0),
4552 b=pCrystal->GetLatticePar(1),
4553 c=pCrystal->GetLatticePar(2),
4554 d=pCrystal->GetLatticePar(3),
4555 e=pCrystal->GetLatticePar(4),
4556 f=pCrystal->GetLatticePar(5);
4557 const string spgname=pCrystal->GetSpaceGroup().GetName();
4558 const string name=pCrystal->GetName();
4560 const cctbx::uctbx::unit_cell uc(scitbx::af::double6(a,b,c,d*RAD2DEG,e*RAD2DEG,f*RAD2DEG));
4562 cctbx::sgtbx::space_group_symbol_iterator it=cctbx::sgtbx::space_group_symbol_iterator();
4565 unsigned int nbspg=0;
4569 cctbx::sgtbx::space_group_symbols s=it.next();
4570 if(s.number()==0)
break;
4571 cctbx::sgtbx::space_group spg(s);
4572 if(spg.is_compatible_unit_cell(uc,0.01,0.1)) nbspg++;
4575 mpLog->AppendText(wxString::Format(_T(
"Beginning spacegroup exploration... %u to go...\n"),nbspg));
4577 unsigned int nbcycle=1;
4578 if(event.GetId()==ID_PROFILEFITTING_EXPLORE_SPG) nbcycle=3;
4579 wxProgressDialog dlgProgress(_T(
"Trying compatible spacegroups"),_T(
"Starting........\n......\n......"),
4580 nbspg*nbcycle,
this,wxPD_AUTO_HIDE|wxPD_ELAPSED_TIME|wxPD_CAN_ABORT);
4582 list<SPGScore> vSPG;
4586 std::map<std::vector<bool>,SPGScore> vSPGExtinctionFingerprint;
4588 it=cctbx::sgtbx::space_group_symbol_iterator();
4591 bool user_stop=
false;
4594 cctbx::sgtbx::space_group_symbols s=it.next();
4595 if(s.number()==0)
break;
4596 cctbx::sgtbx::space_group spg(s);
4597 bool compat=spg.is_compatible_unit_cell(uc,0.01,0.1);
4601 const string hm=s.universal_hermann_mauguin();
4602 cout<<s.number()<<
","<<hm.c_str()<<
","<<(int)compat<<endl;
4603 pCrystal->Init(a,b,c,d,e,f,hm,name);
4604 mpLog->AppendText(wxString::Format(_T(
" (#%3d) %-14s:"),s.number(),wxString::FromAscii(hm.c_str()).c_str()));
4605 std::vector<bool> fgp=spgExtinctionFingerprint(*pCrystal,spg);
4606 std::map<std::vector<bool>,SPGScore>::iterator posfgp=vSPGExtinctionFingerprint.find(fgp);
4607 if(posfgp!=vSPGExtinctionFingerprint.end())
4609 vSPG.push_back(SPGScore(hm.c_str(),posfgp->second.rw,posfgp->second.gof,posfgp->second.nbextinct446));
4610 cout<<
"Spacegroup:"<<hm<<
" has same extinctions as:"<<posfgp->second.hm<<endl;
4611 mpLog->AppendText(_T(
" same as:")+wxString::FromAscii(posfgp->second.hm.c_str())+_T(
"\n"));
4615 pDiff->GetParentPowderPattern().UpdateDisplay();
4616 for(
unsigned int j=0;j<nbcycle;j++)
4619 pDiff->SetExtractionMode(
true,
true);
4620 const float t0=chrono.seconds();
4621 cout<<
"Doing Le Bail, t="<<
FormatFloat(t0,6,2)<<
"s";
4622 pDiff->ExtractLeBail(5);
4623 cout<<
", dt="<<
FormatFloat(chrono.seconds()-t0,6,2)<<
"s"<<endl;
4624 pDiff->GetParentPowderPattern().FitScaleFactorForRw();
4625 if(event.GetId()==ID_PROFILEFITTING_EXPLORE_SPG)
4628 TAU_PROFILE_START(timer2);
4629 lsq.SetRefinedObj(pDiff->GetParentPowderPattern(),0,
true,
true);
4630 lsq.PrepareRefParList(
true);
4634 if(s.number()==1) lsq.SetParIsFixed(
"Zero",
false);
4635 lsq.SetParIsFixed(gpRefParTypeUnitCell,
false);
4636 lsq.Refine(2,
true,
true);
4637 TAU_PROFILE_STOP(timer2);
4640 TAU_PROFILE_START(timer1);
4641 lsq.SetParIsFixed(
"2ThetaDispl",
false);
4642 lsq.SetParIsFixed(
"2ThetaTransp",
false);
4643 lsq.Refine(2,
true,
true);
4646 const unsigned int nbcomp= pDiff->GetParentPowderPattern().GetNbPowderPatternComponent();
4647 for(
unsigned int i=0;i<nbcomp;++i)
4648 if(pDiff->GetParentPowderPattern().GetPowderPatternComponent(i).GetClassName()==
"PowderPatternBackground")
4650 PowderPatternBackground *pback=
dynamic_cast<PowderPatternBackground *
>
4651 (&(pDiff->GetParentPowderPattern().GetPowderPatternComponent(i)));
4652 pback->FixParametersBeyondMaxresolution(lsq.GetCompiledRefinedObj());
4654 lsq.Refine(2,
true,
false);
4655 TAU_PROFILE_STOP(timer1);
4658 pDiff->SetExtractionMode(
true,
true);
4659 pDiff->ExtractLeBail(5);
4660 TAU_PROFILE_START(timer3);
4661 lsq.Refine(3,
true,
true);
4662 TAU_PROFILE_STOP(timer3);
4664 pDiff->GetParentPowderPattern().FitScaleFactorForRw();
4666 pDiff->GetParentPowderPattern().UpdateDisplay();
4667 const REAL rw=pDiff->GetParentPowderPattern().GetRw()*100;
4668 const REAL gof=pDiff->GetParentPowderPattern().GetChi2()
4669 /(pDiff->GetParentPowderPattern().GetNbPointUsed()-pDiff->GetNbReflBelowMaxSinThetaOvLambda());
4670 if(dlgProgress.Update(i*nbcycle+j,wxString::FromAscii(hm.c_str())+wxString::Format(_T(
" (cycle #%u)\n Rwp=%5.2f%%\n GoF=%9.2f"),
4671 j,rw,gof))==
false) user_stop=
true;
4673 if(user_stop)
break;
4675 if(user_stop)
break;
4676 const REAL rw=pDiff->GetParentPowderPattern().GetRw()*100;
4677 const REAL gof=pDiff->GetParentPowderPattern().GetChi2()
4678 /(pDiff->GetParentPowderPattern().GetNbPointUsed()-pDiff->GetNbReflBelowMaxSinThetaOvLambda());
4679 unsigned int nbextinct446=0;
4680 for(
unsigned int i=6;i<fgp.size();++i) nbextinct446+=(
unsigned int)(fgp[i]);
4681 vSPG.push_back(SPGScore(hm.c_str(),rw,gof,nbextinct446));
4682 mpLog->AppendText(wxString::Format(_T(
" Rwp= %5.2f%% GoF=%9.2f (%2u extinct refls)\n"),rw,gof,nbextinct446));
4683 vSPGExtinctionFingerprint.insert(make_pair(fgp,SPGScore(hm.c_str(),rw,gof,nbextinct446)));
4686 if(user_stop)
break;
4689 vSPG.sort(compareSPGScore);
4690 mpLog->AppendText(wxString::Format(_T(
"\n\n BEST Solutions, from min_GoF to 2*min_Gof:\n")));
4691 mpLog->AppendText(wxString::Format(_T(
"\n\'extinct refls\' gives the number of extinct reflections\n")));
4692 mpLog->AppendText(wxString::Format(_T(
"for 0<=H<=4 0<=K<=4 0<=L<=6 \n\n")));
4693 for(list<SPGScore>::const_iterator pos=vSPG.begin();pos!=vSPG.end();++pos)
4695 if(pos->gof>(2*vSPG.begin()->gof))
break;
4696 mpLog->AppendText(wxString::Format(_T(
" Rwp= %5.2f%% GoF=%9.2f: (extinct refls=%2u )"),pos->rw,pos->gof,pos->nbextinct446)+wxString::FromAscii(pos->hm.c_str())+_T(
" \n"));
4699 pCrystal->Init(a,b,c,d,e,f,spgname,name);
4700 pDiff->GetParentPowderPattern().UpdateDisplay();
4701 pDiff->SetExtractionMode(
true,
true);
4702 pDiff->ExtractLeBail(5);
4703 pDiff->GetParentPowderPattern().UpdateDisplay();
4708 if((event.GetId()==ID_POWDERDIFF_PROFILEFITTINGMODE)&&(mpProfileFittingMode->GetValue()==
false))
4710 mpPowderPatternDiffraction->SetExtractionMode(
false);
4711 mpPowderPatternDiffraction->GetParentPowderPattern().UpdateDisplay();
4714 mpPowderPatternDiffraction->SetExtractionMode(
true,
false);
4715 wxFrame *pFrame=
new wxFrame(
this,-1,_T(
"Profile Fitting"));
4716 WXProfileFitting *pFit;
4717 pFit=
new WXProfileFitting(pFrame,&(mpPowderPatternDiffraction->GetParentPowderPattern()),mpPowderPatternDiffraction);
4723 mpPowderPatternDiffraction->FreezeLatticePar(mpFreezeLatticePar->GetValue());
4735 VFN_DEBUG_ENTRY(
"WXProfilePseudoVoigt::WXProfilePseudoVoigt()",6)
4736 mpWXTitle->SetLabel("Pseudo-Voigt profile");
4737 mpWXTitle->SetForegroundColour(wxColour(0,0,255));
4739 wxBoxSizer* sizer1=new wxBoxSizer(wxHORIZONTAL);
4740 WXCrystObjBasic* pFieldCagliotiU=mpProfile->GetPar("U").WXCreate(this);
4741 WXCrystObjBasic* pFieldCagliotiV=mpProfile->GetPar("V").WXCreate(this);
4742 WXCrystObjBasic* pFieldCagliotiW=mpProfile->GetPar("W").WXCreate(this);;
4743 sizer1->Add(pFieldCagliotiU,0);
4744 sizer1->Add(pFieldCagliotiV,0);
4745 sizer1->Add(pFieldCagliotiW,0);
4746 mList.Add(pFieldCagliotiU);
4747 mList.Add(pFieldCagliotiV);
4748 mList.Add(pFieldCagliotiW);
4749 mpSizer->Add(sizer1);
4750 pFieldCagliotiU->
SetToolTip(_T("Width Parameters (Caglioti's law):\n")
4751 _T("fwhm=[W+V*tan(theta)+U*tan^2(theta)]^1/2"));
4752 pFieldCagliotiV->
SetToolTip(_T("Width Parameters (Caglioti's law):\n")
4753 _T("fwhm=[W+V*tan(theta)+U*tan^2(theta)]^1/2"));
4754 pFieldCagliotiW->
SetToolTip(_T("Width Parameters (Caglioti's law):\n")
4755 _T("fwhm=[W+V*tan(theta)+U*tan^2(theta)]^1/2"));
4757 wxBoxSizer* sizer2=new wxBoxSizer(wxHORIZONTAL);
4760 sizer2->Add(pFieldEta0,0);
4761 sizer2->Add(pFieldEta1,0);
4762 mList.Add(pFieldEta0);
4763 mList.Add(pFieldEta1);
4764 mpSizer->Add(sizer2);
4765 pFieldEta0->
SetToolTip(_T("Gaussian/Lorentzian mixing parameters:\n")
4766 _T(" PV(x) = eta*L(x) + (1-eta)*G(x)\n\n")
4767 _T("eta=Eta0+Eta11*2theta"));
4768 pFieldEta1->
SetToolTip(_T("Gaussian/Lorentzian mixing parameters:\n")
4769 _T(" PV(x) = eta*L(x) + (1-eta)*G(x)\n\n")
4770 _T("eta=Eta0+Eta11*2theta"));
4772 wxBoxSizer* sizer3=new wxBoxSizer(wxHORIZONTAL);
4785 WXCrystObjBasic* pFieldAsym0=mpProfile->GetPar("Asym0").WXCreate(this);
4786 WXCrystObjBasic* pFieldAsym1=mpProfile->GetPar("Asym1").WXCreate(this);
4787 WXCrystObjBasic* pFieldAsym2=mpProfile->GetPar("Asym2").WXCreate(this);
4788 sizer3->Add(pFieldAsym0,0);
4789 sizer3->Add(pFieldAsym1,0);
4790 sizer3->Add(pFieldAsym2,0);
4791 mList.Add(pFieldAsym0);
4792 mList.Add(pFieldAsym1);
4793 mList.Add(pFieldAsym2);
4794 mpSizer->Add(sizer3);
4796 pFieldAsym0->
SetToolTip(_T("Asymmetry parameters:\n\n")
4797 _T("A=A0+A1/sin(2theta)+A2/sin^2(2theta) "));
4798 pFieldAsym1->
SetToolTip(_T("Asymmetry parameters:\n\n")
4799 _T("A=A0+A1/sin(2theta)+A2/sin^2(2theta) "));
4800 pFieldAsym2->
SetToolTip(_T("Asymmetry parameters:\n\n")
4801 _T("A=A0+A1/sin(2theta)+A2/sin^2(2theta) "));
4803 this->CrystUpdate(true);
4806 WXProfilePseudoVoigt::~WXProfilePseudoVoigt()
4808 mpProfile->WXNotifyDelete();
4823 VFN_DEBUG_ENTRY(
"WXProfilePseudoVoigtAnisotropic::WXProfilePseudoVoigtAnisotropic()",6)
4824 mpWXTitle->SetLabel("Pseudo-Voigt Anisotropic profile");
4825 mpWXTitle->SetForegroundColour(wxColour(0,0,255));
4827 wxBoxSizer* sizer1=new wxBoxSizer(wxHORIZONTAL);
4828 WXCrystObjBasic* pFieldCagliotiU=mpProfile->GetPar("U").WXCreate(this);
4829 WXCrystObjBasic* pFieldCagliotiV=mpProfile->GetPar("V").WXCreate(this);
4830 WXCrystObjBasic* pFieldCagliotiW=mpProfile->GetPar("W").WXCreate(this);;
4831 WXCrystObjBasic* pFieldScherrerP=mpProfile->GetPar("P").WXCreate(this);;
4832 sizer1->Add(pFieldCagliotiU,0);
4833 sizer1->Add(pFieldCagliotiV,0);
4834 sizer1->Add(pFieldCagliotiW,0);
4835 sizer1->Add(pFieldScherrerP,0);
4836 mList.Add(pFieldCagliotiU);
4837 mList.Add(pFieldCagliotiV);
4838 mList.Add(pFieldCagliotiW);
4839 mList.Add(pFieldScherrerP);
4840 mpSizer->Add(sizer1);
4841 pFieldCagliotiU->
SetToolTip(_T("Gaussian Width Parameters:\n")
4842 _T("fwhm=[W+V*tan(theta)+U*tan^2(theta)+P/cos^2(theta)]^1/2"));
4843 pFieldCagliotiV->
SetToolTip(_T("Gaussian Width Parameters:\n")
4844 _T("fwhm=[W+V*tan(theta)+U*tan^2(theta)+P/cos^2(theta)]^1/2"));
4845 pFieldCagliotiW->
SetToolTip(_T("Gaussian Width Parameters:\n")
4846 _T("fwhm=[W+V*tan(theta)+U*tan^2(theta)+P/cos^2(theta)]^1/2"));
4847 pFieldScherrerP->
SetToolTip(_T("Gaussian Width Parameters:\n")
4848 _T("fwhm=[W+V*tan(theta)+U*tan^2(theta)+P/cos^2(theta)]^1/2"));
4850 wxBoxSizer* sizer2=new wxBoxSizer(wxHORIZONTAL);
4855 sizer2->Add(pFieldEta0,0);
4856 sizer2->Add(pFieldEta1,0);
4857 sizer2->Add(pFieldX,0);
4858 sizer2->Add(pFieldY,0);
4861 mList.Add(pFieldEta0);
4862 mList.Add(pFieldEta1);
4863 mpSizer->Add(sizer2);
4864 pFieldEta0->
SetToolTip(_T("Gaussian/Lorentzian mixing parameters:\n")
4865 _T(" PV(x) = eta*L(x) + (1-eta)*G(x)\n\n")
4866 _T("eta=Eta0+Eta11*2theta"));
4868 pFieldEta1->
SetToolTip(_T("Gaussian/Lorentzian mixing parameters:\n")
4869 _T(" PV(x) = eta*L(x) + (1-eta)*G(x)\n\n")
4870 _T("eta=Eta0+Eta1*2theta"));
4872 pFieldX->
SetToolTip(_T("Lorentzian width:\n")
4873 _T(" FWHM(x) = X/cos(theta) + (Y + gam_L/sin^2(theta))*tan(theta)\n\n")
4874 _T("gam_L=gam_hh*H^2 + gam_kk*K^2 + gam_ll*L^2\n")
4875 _T(" +gam_hk*HK + gam_hl*HL + gam_kl*HL"));
4877 pFieldY->
SetToolTip(_T("Lorentzian width:\n")
4878 _T(" FWHM(x) = X/cos(theta) + (Y + gam_L/sin^2(theta))*tan(theta)\n\n")
4879 _T("gam_L=gam_hh*H^2 + gam_kk*K^2 + gam_ll*L^2\n")
4880 _T(" +gam_hk*HK + gam_hl*HL + gam_kl*HL"));
4883 wxBoxSizer* sizerA=new wxBoxSizer(wxHORIZONTAL);
4890 sizerA->Add(pFieldGHH,0);
4891 sizerA->Add(pFieldGKK,0);
4892 sizerA->Add(pFieldGLL,0);
4893 sizerA->Add(pFieldGHK,0);
4894 sizerA->Add(pFieldGHL,0);
4895 sizerA->Add(pFieldGKL,0);
4896 mList.Add(pFieldGHH);
4897 mList.Add(pFieldGKK);
4898 mList.Add(pFieldGLL);
4899 mList.Add(pFieldGHK);
4900 mList.Add(pFieldGHL);
4901 mList.Add(pFieldGKL);
4902 mpSizer->Add(sizerA);
4903 pFieldGHH->
SetToolTip(_T("Lorentzian width:\n")
4904 _T(" FWHM(x) = X/cos(theta) + (Y + gam_L/sin^2(theta))*tan(theta)\n\n")
4905 _T("gam_L=gam_hh*H^2 + gam_kk*K^2 + gam_ll*L^2\n")
4906 _T(" +gam_hk*HK + gam_hl*HL + gam_kl*HL"));
4907 pFieldGKK->
SetToolTip(_T("Lorentzian width:\n")
4908 _T(" FWHM(x) = X/cos(theta) + (Y + gam_L/sin^2(theta))*tan(theta)\n\n")
4909 _T("gam_L=gam_hh*H^2 + gam_kk*K^2 + gam_ll*L^2\n")
4910 _T(" +gam_hk*HK + gam_hl*HL + gam_kl*HL"));
4911 pFieldGLL->
SetToolTip(_T("Lorentzian width:\n")
4912 _T(" FWHM(x) = X/cos(theta) + (Y + gam_L/sin^2(theta))*tan(theta)\n\n")
4913 _T("gam_L=gam_hh*H^2 + gam_kk*K^2 + gam_ll*L^2\n")
4914 _T(" +gam_hk*HK + gam_hl*HL + gam_kl*HL"));
4915 pFieldGHK->
SetToolTip(_T("Lorentzian width:\n")
4916 _T(" FWHM(x) = X/cos(theta) + (Y + gam_L/sin^2(theta))*tan(theta)\n\n")
4917 _T("gam_L=gam_hh*H^2 + gam_kk*K^2 + gam_ll*L^2\n")
4918 _T(" +gam_hk*HK + gam_hl*HL + gam_kl*HL"));
4919 pFieldGHL->
SetToolTip(_T("Lorentzian width:\n")
4920 _T(" FWHM(x) = X/cos(theta) + (Y + gam_L/sin^2(theta))*tan(theta)\n\n")
4921 _T("gam_L=gam_hh*H^2 + gam_kk*K^2 + gam_ll*L^2\n")
4922 _T(" +gam_hk*HK + gam_hl*HL + gam_kl*HL"));
4923 pFieldGKL->
SetToolTip(_T("Lorentzian width:\n")
4924 _T(" FWHM(x) = X/cos(theta) + (Y + gam_L/sin^2(theta))*tan(theta)\n\n")
4925 _T("gam_L=gam_hh*H^2 + gam_kk*K^2 + gam_ll*L^2\n")
4926 _T(" +gam_hk*HK + gam_hl*HL + gam_kl*HL"));
4929 wxBoxSizer* sizer3=new wxBoxSizer(wxHORIZONTAL);
4930 WXCrystObjBasic* pFieldAsym0=mpProfile->GetPar("Asym0").WXCreate(this);
4931 WXCrystObjBasic* pFieldAsym1=mpProfile->GetPar("Asym1").WXCreate(this);
4932 WXCrystObjBasic* pFieldAsym2=mpProfile->GetPar("Asym2").WXCreate(this);
4933 sizer3->Add(pFieldAsym0,0);
4934 sizer3->Add(pFieldAsym1,0);
4935 sizer3->Add(pFieldAsym2,0);
4936 mList.Add(pFieldAsym0);
4937 mList.Add(pFieldAsym1);
4938 mList.Add(pFieldAsym2);
4939 mpSizer->Add(sizer3);
4941 pFieldAsym0->
SetToolTip(_T("Asymmetry parameters:\n\n")
4942 _T("A=A0+A1/sin(2theta)+A2/sin^2(2theta) "));
4943 pFieldAsym1->
SetToolTip(_T("Asymmetry parameters:\n\n")
4944 _T("A=A0+A1/sin(2theta)+A2/sin^2(2theta) "));
4945 pFieldAsym2->
SetToolTip(_T("Asymmetry parameters:\n\n")
4946 _T("A=A0+A1/sin(2theta)+A2/sin^2(2theta) "));
4948 this->CrystUpdate(true);
4952 WXProfilePseudoVoigtAnisotropic::~WXProfilePseudoVoigtAnisotropic()
4954 mpProfile->WXNotifyDelete();
4967 WXProfileDoubleExponentialPseudoVoigt::WXProfileDoubleExponentialPseudoVoigt
4971 VFN_DEBUG_ENTRY(
"WXProfileDoubleExponentialPseudoVoigt::WXProfileDoubleExponentialPseudoVoigt()",6)
4972 mpWXTitle->SetLabel("Double-Exponential Pseudo-Voigt profile (for neutron TOF)");
4973 mpWXTitle->SetForegroundColour(wxColour(0,0,255));
4975 wxBoxSizer* sizer1=new wxBoxSizer(wxHORIZONTAL);
4976 WXCrystObjBasic* pFieldCagliotiA0=mpProfile->GetPar("Alpha0").WXCreate(this);
4977 WXCrystObjBasic* pFieldCagliotiA =mpProfile->GetPar("Alpha1").WXCreate(this);
4978 WXCrystObjBasic* pFieldCagliotiB0=mpProfile->GetPar("Beta0").WXCreate(this);
4979 WXCrystObjBasic* pFieldCagliotiB1=mpProfile->GetPar("Beta1").WXCreate(this);
4980 sizer1->Add(pFieldCagliotiA0,0);
4981 sizer1->Add(pFieldCagliotiA,0);
4982 sizer1->Add(pFieldCagliotiB0,0);
4983 sizer1->Add(pFieldCagliotiB1,0);
4984 mList.Add(pFieldCagliotiA0);
4985 mList.Add(pFieldCagliotiA);
4986 mList.Add(pFieldCagliotiB0);
4987 mList.Add(pFieldCagliotiB1);
4988 mpSizer->Add(sizer1);
4990 wxBoxSizer* sizer2=new wxBoxSizer(wxHORIZONTAL);
4991 WXCrystObjBasic* pFieldSigma0=mpProfile->GetPar("GaussianSigma0").WXCreate(this);
4992 WXCrystObjBasic* pFieldSigma1=mpProfile->GetPar("GaussianSigma1").WXCreate(this);
4993 WXCrystObjBasic* pFieldSigma2=mpProfile->GetPar("GaussianSigma2").WXCreate(this);
4994 sizer2->Add(pFieldSigma0,0);
4995 sizer2->Add(pFieldSigma1,0);
4996 sizer2->Add(pFieldSigma2,0);
4997 mList.Add(pFieldSigma0);
4998 mList.Add(pFieldSigma1);
4999 mList.Add(pFieldSigma2);
5000 mpSizer->Add(sizer2);
5002 wxBoxSizer* sizer3=new wxBoxSizer(wxHORIZONTAL);
5003 WXCrystObjBasic* pFieldGamma0=mpProfile->GetPar("LorentzianGamma0").WXCreate(this);
5004 WXCrystObjBasic* pFieldGamma1=mpProfile->GetPar("LorentzianGamma1").WXCreate(this);
5005 WXCrystObjBasic* pFieldGamma2=mpProfile->GetPar("LorentzianGamma2").WXCreate(this);
5006 sizer3->Add(pFieldGamma0,0);
5007 sizer3->Add(pFieldGamma1,0);
5008 sizer3->Add(pFieldGamma2,0);
5009 mList.Add(pFieldGamma0);
5010 mList.Add(pFieldGamma1);
5011 mList.Add(pFieldGamma2);
5012 mpSizer->Add(sizer3);
5014 this->CrystUpdate(true);
5017 WXProfileDoubleExponentialPseudoVoigt::~WXProfileDoubleExponentialPseudoVoigt()
5019 mpProfile->WXNotifyDelete();
void FitScaleFactorForR() const
Fit the scale(s) factor of each component to minimize R.
virtual void UpdateUI(const bool mutexlock=false)
Update the User Interface, if necessary.
void OnUpdate(wxCommandEvent &WXUNUSED(event))
Update the powder spectrum, at the user's request.
Texture correction using the March-Dollase model.
virtual void UpdateUI(const bool mutexlock=false)
Update the User Interface, if necessary.
T * WXDialogChooseFromRegistry(ObjRegistry< T > ®, wxWindow *parent, const string &message, int &choice)
This function allows to pick up one object in a registry.
const CrystVector_REAL & GetPowderPatternCalc() const
Get the calculated powder pattern.
long Data2ScreenY(const REAL y) const
Convert Y data (intensity) coordinate to screen coordinate (pixel)
Pseudo-Voigt reflection profile, with 6-parameters anisotropic Lorentzian broadening and Toraya asymm...
virtual void UpdateDisplay() const
If there is an interface, this should be automatically be called each time there is a 'new...
Double-Exponential Pseudo-Voigt profile for TOF.
void WXCrystValidateAllUserInput()
This function validates all user input (in a WXField) not yet taken into account, if needs be...
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.
void PrepareRefParList(const bool copy_param=false)
Prepare the full parameter list for the refinement.
Class to pick one choice...
const Radiation & GetRadiation() const
Neutron or x-ray experiment ?
virtual void UpdateUI(const bool mutexlock=false)
Update the User Interface, if necessary.
virtual bool OnChangeName(const int id)
When a WXFieldName has been changed by the user, it is handled here.
void OnRedrawNewPattern(wxUpdateUIEvent &WXUNUSED(event))
Redraw the pattern (special function to ensure complete redrawing under windows...)
void SetRefinedObj(RefinableObj &obj, const unsigned int LSQFuncIndex=0, const bool init=true, const bool recursive=false)
Choose the object to refine.
void OnLeBail(wxCommandEvent &event)
Perform Le Bail extraction.
void Add(WXCrystObjBasic *)
Add an object to the list.
Class to display a Powder Pattern (calc,obs) in a graphic window.
bool mNeedUpdateUI
Do we need to update the display ?
void ResetAxisLimits()
Reset the limits of the axis to full range.
virtual void UpdateUI(const bool mutexlock=false)
Update the User Interface, if necessary.
Simple chronometer class, with microsecond precision.
virtual bool OnChangeName(const int id)
When a WXFieldName has been changed by the user, it is handled here.
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...
Class to display a Powder Pattern Background.
One texture phase for the March-Dollase model.
Algorithm class to find the correct indexing from observed peak positions.
virtual void SetToolTip(const wxString &tip)
Set tooltip for this window.
virtual bool OnChangeName(const int id)
When a WXFieldName has been changed by the user, it is handled here.
void OnChangePeak(wxCommandEvent &WXUNUSED(event))
Add or remove peak.
Phase to compute a background contribution to a powder pattern using an interpolation.
std::map< wxWindowID, std::pair< wxPoint, wxSize > > gvWindowPosition
Used to remember window positions.
REAL GetChi2_Option() const
Return the conventionnal or integrated Chi^2, depending on the option.
float EstimateCellVolume(const float dmin, const float dmax, const float nbrefl, const CrystalSystem system, const CrystalCentering centering, const float kappa)
Estimate volume from number of peaks at a given dmin See J.
Class to display a Powder Pattern Pseudo-Voigt Profile with Anisotropic broadening.
CrystalSystem
Different lattice types.
Class to compute the contribution to a powder pattern from a crystalline phase.
WXFieldName * mpWXTitle
The title.
const RefParType * gpRefParTypeScattDataProfile
Type for reflection profile.
void SetPowderPatternObs(const CrystVector_REAL &obs)
Set observed powder pattern from vector array.
This displays all components of a ObjCryst++ Registry.
bool GetExtractionMode() const
Return true if in extraction mode, i.e. using extracted intensities instead of computed structure fac...
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...
void CrystUpdate(const bool updateUI=false, const bool mutexlock=false)
Forces all objects in the list to update.
REAL GetR() const
Unweighted R-factor.
void OnMenuLeBail(wxCommandEvent &event)
Profile fitting & Le Bail intensity extraction.
Generic Refinable Object.
WXCrystObjBasicList mList
All windows but the title and collapse button are in this list.
const RefParType * gpRefParTypeScattDataScale
Type for scattering data scale factors.
Class to store positions of observed reflections.
Class to display the Preferred Orientation Correction using the March-Dollase parametrization.
ObjRegistry< Crystal > gCrystalRegistry("List of all Crystals")
Global registry for all Crystal objects.
Class to display a Powder Pattern for a crystalline phase.
void SetParIsFixed(const std::string &parName, const bool fix)
Fix one parameter.
const RefParType * gpRefParTypeScattDataBackground
Parameter type for background intensity.
Abstract base class for all objects in wxCryst.
float Score(const PeakList &dhkl, const RecUnitCell &rpar, const unsigned int nbSpurious, const bool verbose, const bool storehkl, const bool storePredictedHKL)
Compute score for a candidate RecUnitCell and a PeakList.
void OnPaint(wxPaintEvent &WXUNUSED(event))
Redraw the spectrum.
WX Class for PowderPattern objects.
void AddMenuItem(const int menuId, int id, const string &item, const string &help="", const bool checkable=false)
Add an entry to a menu.
void CalcPowderPattern() const
Calc the powder pattern.
REAL GetRw() const
Get the weighted R-factor.
REAL Screen2DataY(const long y) const
Convert Y screen coordinate (pixel) to data (intensity) coordinate.
const CrystVector_REAL & GetPowderPatternX() const
Get the vector of X (2theta or time-of-flight) coordinates.
virtual bool SetForegroundColour(const wxColour &colour)
Change the colour of the field's title.
void ImportPowderPatternCIF(const CIF &cif)
Import CIF powder pattern data.
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...
WavelengthType GetWavelengthType() const
Get the Wavelength type (monochromatic, Alpha1+Alpha2, Time Of Flight...)
void AddPowderPatternComponent(PowderPatternComponent &)
Add a component (phase, backround) to this pattern.
WXCrystObj(wxWindow *parent, int orient=wxHORIZONTAL, bool showName=true)
Constructor, with a.
void UpdateUI(const bool mutexlock=false)
Update the User Interface, if necessary.
virtual bool OnChangeName(const int id)
When a WXFieldName has been changed by the user, it is handled here.
long Point2ScreenX(const long x) const
Convert X data (as data point index) to screen coordinate (pixel)
WXCrystObjBasic(wxWindow *parent)
Constructor.
void SetRadiationType(const RadiationType radiation)
Set the radiation type.
void OnMouseWheel(wxMouseEvent &event)
Wheel wan be used to scroll the pattern.
output a number as a formatted float:
Class to display a Powder Pattern Pseudo-Voigt Profile.
Base class for all displayed ObjCryst objects (with a title, and a sizer to stack objects)...
long Data2ScreenX(const REAL x) const
Convert X data (2theta) coordinate to screen coordinate (pixel)
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...
Main CIF class - parses the stream and separates data blocks, comments, items, loops.
void SetPattern(const CrystVector_REAL &obs, const CrystVector_REAL &calc, const REAL tthetaMin, const REAL tthetaStep, const CrystVector_REAL &sigma, const CrystVector_REAL &chi2Cumul)
Update the pattern.
const CrystVector_REAL & GetPowderPatternObs() const
Get the observed powder pattern.
virtual void UpdateUI(const bool mutexlock=false)
Update the User Interface, if necessary.
const Crystal & GetCrystal() const
Const access to the data's crystal.
const CrystVector_REAL & GetChi2Cumul() const
Get the powder pattern cumulative Chi^2.
void AddMenu(const string &name, const int menuId, const string &help="")
Add a menu.
const CrystVector_REAL & GetPowderPatternVariance() const
Get the variance (obs+model) for each point of the powder pattern.
The base wxCryst class for all RefinableObj objects.
REAL Screen2DataX(const long x) const
Convert X screen coordinate (pixel) to data (2theta) coordinate.
Exception class for ObjCryst++ library.
Class to automatically assign a unique wxID to each window.
The namespace which includes all objects (crystallographic and algorithmic) in ObjCryst++.
wxBoxSizer * mpTopSizer
Top sizer including the title and WXCrystObj::mpSizer.
virtual const string & GetName() const
Name of the object.
unsigned long GetNbPoint() const
Number of points ?
void OnFreezeLatticePar(wxCommandEvent &event)
Freeze lattice parameter, which will not follow anymore the Crystal Unitcell values.
Class to display a Powder Pattern Pseudo-Voigt Profile.
Pseudo-Voigt reflection profile.
Crystal class: Unit cell, spacegroup, scatterers.
void SetWavelengthType(const WavelengthType &type)
Set the Wavelength type (monochromatic, Alpha1+Alpha2, Time Of Flight...)
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...
(Quick & dirty) Least-Squares Refinement Object with Numerical derivatives
REAL GetChi2() const
Return conventionnal Chi^2.
void FitScaleFactorForRw() const
Fit the scale(s) factor of each component to minimize Rw.
void ExportFullprof(const std::string &prefix) const
Export powder pattern & crystal structure in Fullprof format.
const RefParType * gpRefParTypeObjCryst
Top RefParType for the ObjCryst++ library.
void Refine(int nbCycle=1, bool useLevenbergMarquardt=false, const bool silent=false, const bool callBeginEndOptimization=true, const float minChi2var=0.01)
Do the refinement.
void UpdateUI(const bool mutexlock=false)
Forces all objects in the list to update.
void OnMouse(wxMouseEvent &event)
Display the Theta and intensity values at the mouse position, in the status bar.