FOX/ObjCryst++  2022
wxZScatterer.cpp
1 /* ObjCryst++ Object-Oriented Crystallographic Library
2  (c) 2000-2002 Vincent Favre-Nicolin vincefn@users.sourceforge.net
3  2000-2001 University of Geneva (Switzerland)
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19 
20 #include <stdio.h> //for sprintf()
21 #include <fstream>
22 
23 // wx headers, with or without precompilation
24 #include "wx/wxprec.h"
25 #ifdef __BORLANDC__
26  #pragma hdrstop
27 #endif
28 #ifndef WX_PRECOMP
29  #include "wx/wx.h"
30 #endif
31 
32 #include "ObjCryst/wxCryst/wxZScatterer.h"
33 #include "ObjCryst/ObjCryst/Molecule.h"
34 
35 //Fixes for Cygwin; where do those stupid macros come from ? Somewhere in wxMSW headers
36 #ifdef max
37 #undef max
38 #endif
39 #ifdef min
40 #undef min
41 #endif
42 #ifdef DrawText
43 #undef DrawText
44 #endif
45 
46 namespace ObjCryst
47 {
48 
50 //
51 // WXZAtom
52 //
54 static const long ID_ZATOM_NAME= WXCRYST_ID();
55 static const long ID_ZATOM_SCATTPOW=WXCRYST_ID();
56 static const long ID_ZATOM_BOND= WXCRYST_ID();
57 static const long ID_ZATOM_ANGLE= WXCRYST_ID();
58 static const long ID_ZATOM_DIHED= WXCRYST_ID();
59 
60 BEGIN_EVENT_TABLE(WXZAtom,wxWindow)
61  EVT_BUTTON(ID_ZATOM_SCATTPOW, WXZAtom::OnChangeScattPow)
62 END_EVENT_TABLE()
63 
64 WXZAtom::WXZAtom(wxWindow* parent, ZAtom *obj):
65 WXCrystObjBasic(parent),mpZAtom(obj)
66 {
67  VFN_DEBUG_ENTRY("WXZAtom::WXZAtom()",6)
68  mpSizer=new wxBoxSizer(wxHORIZONTAL);
69 
70  mpFieldName=new WXFieldString(this, mpZAtom->mName,ID_ZATOM_NAME,80,true);
71  mpSizer->Add(mpFieldName,0,wxALIGN_LEFT);
72  mpFieldScattPower=new WXFieldChoice(this,ID_ZATOM_SCATTPOW,"Type:",60);
73  mpSizer->Add(mpFieldScattPower,0,wxALIGN_LEFT);
74  mList.Add(mpFieldScattPower);
75 
76  if(0<mpZAtom->GetZScatterer().GetZAtomRegistry().Find(*mpZAtom))
77  {
78  RefinablePar *par=&(mpZAtom->GetZScatterer().GetPar(&(mpZAtom->mBondLength)));
79  par->SetName("Bond(w/"+(mpZAtom->GetZScatterer().GetZAtomRegistry()
80  .GetObj(mpZAtom->GetZBondAtom())).GetName()+")");
81  WXCrystObjBasic* pFieldBond=par->WXCreate(this);
82  mpSizer->Add(pFieldBond,0,wxALIGN_LEFT);
83  mList.Add(pFieldBond);
84  }
85 
86  if(1<mpZAtom->GetZScatterer().GetZAtomRegistry().Find(*mpZAtom))
87  {
88  RefinablePar *par=&(mpZAtom->GetZScatterer().GetPar(&(mpZAtom->mAngle)));
89  par->SetName("Angle(w/"+(mpZAtom->GetZScatterer().GetZAtomRegistry()
90  .GetObj(mpZAtom->GetZAngleAtom())).GetName()+")");
91  WXCrystObjBasic* pFieldAngle
92  =par->WXCreate(this);
93  mpSizer->Add(pFieldAngle,0,wxALIGN_LEFT);
94  mList.Add(pFieldAngle);
95  }
96  if(2<mpZAtom->GetZScatterer().GetZAtomRegistry().Find(*mpZAtom))
97  {
98  RefinablePar *par=&(mpZAtom->GetZScatterer().GetPar(&(mpZAtom->mDihed)));
99  par->SetName("DihedralAngle(w/"+(mpZAtom->GetZScatterer().GetZAtomRegistry()
100  .GetObj(mpZAtom->GetZDihedralAngleAtom())).GetName()+")");
101  WXCrystObjBasic* pFieldDihed=par->WXCreate(this);
102  mpSizer->Add(pFieldDihed,0,wxALIGN_LEFT);
103  mList.Add(pFieldDihed);
104  }
105  {
106  RefinablePar *par=&(mpZAtom->GetZScatterer().GetPar(&(mpZAtom->mOccupancy)));
107  par->SetName("Occup.");
108  WXCrystObjBasic* pFieldOccup=par->WXCreate(this);
109  mpSizer->Add(pFieldOccup,0,wxALIGN_LEFT);
110  mList.Add(pFieldOccup);
111  }
112 
113  this->SetSizer(mpSizer);
114 
115  this->BottomLayout(0);
116  this->CrystUpdate(true);
117  VFN_DEBUG_EXIT("WXZAtom::WXZAtom()",6)
118 }
119 
120 void WXZAtom::CrystUpdate(const bool uui,const bool lock)
121 {
122  VFN_DEBUG_ENTRY("WXZAtom::CrystUpdate()",6)
123  if(lock) mMutex.Lock();
124  mList.CrystUpdate(uui,false);
125  if(lock) mMutex.Unlock();
126  VFN_DEBUG_EXIT("WXZAtom::CrystUpdate()",6)
127 }
128 
129 void WXZAtom::UpdateUI(const bool lock)
130 {
131  VFN_DEBUG_ENTRY("WXZAtom::UpdateUI()",6)
132  if(lock) mMutex.Lock();
133  mList.UpdateUI(false);
134  mpFieldName->SetValue(mpZAtom->GetName().c_str());
135  if(0!=mpZAtom->GetScatteringPower())
136  mpFieldScattPower->SetValue(mpZAtom->GetScatteringPower()->GetName());
137  else
138  mpFieldScattPower->SetValue("Dummy");
139  if(lock) mMutex.Unlock();
140  VFN_DEBUG_EXIT("WXZAtom::UpdateUI()",6)
141 }
142 
143 void WXZAtom::OnChangeScattPow(wxCommandEvent & WXUNUSED(event))
144 {
145  VFN_DEBUG_MESSAGE("WXAtom::OnChangeScattPow()",6)
147  int choice;
149  mpZAtom->GetZScatterer().GetCrystal().GetScatteringPowerRegistry(),
150  (wxWindow*)this,"Choose a new Scattering Power",choice);
151  if(0==scatt) return;
152  mpZAtom->SetScatteringPower(scatt);
153  this->CrystUpdate(true);
154  this->UpdateUI(true);
155 }
157 //
158 // WXZScatterer
159 //
161 static const long ID_ZSCATTERER_MENU_ATOM= WXCRYST_ID();
162 static const long ID_ZSCATTERER_MENU_ATOM_ADD= WXCRYST_ID();
163 static const long ID_ZSCATTERER_MENU_ATOM_CHANGE_PIVOT= WXCRYST_ID();
164 static const long ID_ZSCATTERER_MENU_PAR_LIMITS_RELAT_BOND= WXCRYST_ID();
165 static const long ID_ZSCATTERER_MENU_PAR_LIMITS_RELAT_ANGLE=WXCRYST_ID();
166 static const long ID_ZSCATTERER_MENU_PAR_LIMITS_RELAT_DIHED=WXCRYST_ID();
167 static const long ID_ZSCATTERER_MENU_FILE= WXCRYST_ID();
168 static const long ID_ZSCATTERER_MENU_IMPORT_FHZ= WXCRYST_ID();
169 static const long ID_ZSCATTERER_MENU_EXPORT_FHZ= WXCRYST_ID();
170 static const long ID_ZSCATTERER_MENU_CONVERT2MOLECULE= WXCRYST_ID();
171 BEGIN_EVENT_TABLE(WXZScatterer,wxWindow)
172  EVT_BUTTON(ID_WXOBJ_COLLAPSE, WXCrystObj::OnToggleCollapse)
173  EVT_MENU(ID_REFOBJ_MENU_PAR_FIXALL, WXRefinableObj::OnMenuFixAllPar)
174  EVT_MENU(ID_REFOBJ_MENU_PAR_UNFIXALL, WXRefinableObj::OnMenuUnFixAllPar)
175  EVT_MENU(ID_REFOBJ_MENU_PAR_RANDOMIZE, WXRefinableObj::OnMenuParRandomize)
176  EVT_MENU(ID_ZSCATTERER_MENU_PAR_LIMITS_RELAT_BOND, WXZScatterer::OnMenuSetLimits)
177  EVT_MENU(ID_ZSCATTERER_MENU_PAR_LIMITS_RELAT_ANGLE, WXZScatterer::OnMenuSetLimits)
178  EVT_MENU(ID_ZSCATTERER_MENU_PAR_LIMITS_RELAT_DIHED, WXZScatterer::OnMenuSetLimits)
179  EVT_MENU(ID_ZSCATTERER_MENU_ATOM_ADD, WXZScatterer::OnMenuAddZAtom)
180  EVT_MENU(ID_ZSCATTERER_MENU_ATOM_CHANGE_PIVOT, WXZScatterer::OnMenuChangePivotAtom)
181  EVT_MENU(ID_ZSCATTERER_MENU_IMPORT_FHZ, WXZScatterer::OnMenuImportZMatrix)
182  EVT_MENU(ID_ZSCATTERER_MENU_EXPORT_FHZ, WXZScatterer::OnMenuExportZMatrix)
183  EVT_MENU(ID_ZSCATTERER_MENU_CONVERT2MOLECULE, WXZScatterer::OnMenuConvert2Molecule)
184 END_EVENT_TABLE()
185 
186 WXZScatterer::WXZScatterer(wxWindow* parent, ZScatterer *obj):
187 WXScatterer(parent,obj),mpZScatterer(obj)
188 {
189  VFN_DEBUG_MESSAGE("WXZScatterer::WXZScatterer()",6)
190  //Menus
191  mpMenuBar->AddMenu("Import/Export",ID_ZSCATTERER_MENU_FILE);
192  mpMenuBar->AddMenuItem(ID_ZSCATTERER_MENU_FILE,
193  ID_ZSCATTERER_MENU_IMPORT_FHZ,
194  "Import Fenske-Hall Zmatrix");
195  mpMenuBar->AddMenuItem(ID_ZSCATTERER_MENU_FILE,
196  ID_ZSCATTERER_MENU_EXPORT_FHZ,
197  "Save as Fenske-Hall Zmatrix");
198  mpMenuBar->AddMenuItem(ID_ZSCATTERER_MENU_FILE,
199  ID_ZSCATTERER_MENU_CONVERT2MOLECULE,
200  "Convert to Molecule");
201  mpMenuBar->AddMenu("Parameters",ID_REFOBJ_MENU_PAR);
202  mpMenuBar->AddMenuItem(ID_REFOBJ_MENU_PAR,ID_REFOBJ_MENU_PAR_FIXALL,"Fix all");
203  mpMenuBar->AddMenuItem(ID_REFOBJ_MENU_PAR,ID_REFOBJ_MENU_PAR_UNFIXALL,"Unfix all");
204  mpMenuBar->AddMenuItem(ID_REFOBJ_MENU_PAR,ID_REFOBJ_MENU_PAR_RANDOMIZE,
205  "Randomize Configuration");
206  mpMenuBar->AddMenuItem(ID_REFOBJ_MENU_PAR,ID_ZSCATTERER_MENU_PAR_LIMITS_RELAT_BOND,
207  "Set limits (relative) on all bondlengths");
208  mpMenuBar->AddMenuItem(ID_REFOBJ_MENU_PAR,ID_ZSCATTERER_MENU_PAR_LIMITS_RELAT_ANGLE,
209  "Set limits (relative) on all bond angles");
210  mpMenuBar->AddMenuItem(ID_REFOBJ_MENU_PAR,ID_ZSCATTERER_MENU_PAR_LIMITS_RELAT_DIHED,
211  "Set limits (relative) on all dihedral angles");
212  mpMenuBar->AddMenu("Atom",ID_ZSCATTERER_MENU_ATOM);
213  mpMenuBar->AddMenuItem(ID_ZSCATTERER_MENU_ATOM,ID_ZSCATTERER_MENU_ATOM_ADD,
214  "Add an Atom");
215  mpMenuBar->AddMenuItem(ID_ZSCATTERER_MENU_ATOM,ID_ZSCATTERER_MENU_ATOM_CHANGE_PIVOT,
216  "Change Pivot Atom");
217  //mpSizer->SetItemMinSize(mpMenuBar,
218  // mpMenuBar->GetSize().GetWidth(),
219  // mpMenuBar->GetSize().GetHeight());
220  //Orientation
221  wxBoxSizer* sizer=new wxBoxSizer(wxHORIZONTAL);
222 
223  WXCrystObjBasic* pFieldPhi =mpZScatterer->GetPar(&(mpZScatterer->mPhi)).WXCreate(this);
224  WXCrystObjBasic* pFieldChi =mpZScatterer->GetPar(&(mpZScatterer->mChi)).WXCreate(this);
225  WXCrystObjBasic* pFieldPsi =mpZScatterer->GetPar(&(mpZScatterer->mPsi)).WXCreate(this);
226 
227  sizer->Add(pFieldPhi ,0,wxALIGN_CENTER);
228  sizer->Add(pFieldChi ,0,wxALIGN_CENTER);
229  sizer->Add(pFieldPsi ,0,wxALIGN_CENTER);
230 
231  mpSizer->Add(sizer,0,wxALIGN_LEFT);
232  mList.Add(pFieldPhi);
233  mList.Add(pFieldChi);
234  mList.Add(pFieldPsi);
235  //Atoms
236  mpWXZAtomRegistry=mpZScatterer->mZAtomRegistry.WXCreate(this);
237  mpSizer->Add(mpWXZAtomRegistry,0,wxALIGN_LEFT);
238  mList.Add(mpWXZAtomRegistry);
239 
240  this->BottomLayout(0);
241  this->CrystUpdate(true);
242 }
243 
244 void WXZScatterer::OnMenuAddZAtom(wxCommandEvent & WXUNUSED(event))
245 {
246  VFN_DEBUG_ENTRY("WXZScatterer::OnMenuAddZAtom()",6)
248 
249  int choice;
250  int bondAtomId=0;
251  double bondLength;
252  int angleAtomId=0;;
253  double angle;
254  int dihedAtomId=0;;
255  double dihed;
256  //Scattering power
258  mpZScatterer->GetCrystal().GetScatteringPowerRegistry(),
259  this,"Choose an atom type (ScatteringPower):",choice);
260  if(0==scattPow)
261  {
262  VFN_DEBUG_EXIT("WXZScatterer::OnMenuAddZAtom():Cancelled",6)
263  return;
264  }
265  //Bond atom
266  if(0<mpZScatterer->GetZAtomRegistry().GetNb())
267  {
268 
269  const ZAtom *bondAtom=WXDialogChooseFromRegistry(mpZScatterer->GetZAtomRegistry(),
270  this,"Choose the bonded atom",bondAtomId);
271  if(0==bondAtom)
272  {
273  VFN_DEBUG_EXIT("WXZScatterer::OnMenuAddZAtom():Cancelled",6)
274  return;
275  }
276  //Bond length
277  wxTextEntryDialog bondLengthDialog(this,_T("Enter bond length (Angstroems)"),
278  _T("Bond length"),_T("1.5"),wxOK | wxCANCEL);
279  bondLengthDialog.SetTextValidator(wxTextValidator(wxFILTER_NUMERIC));
280  if(wxID_OK!=bondLengthDialog.ShowModal())
281  {
282  VFN_DEBUG_EXIT("WXZScatterer::OnMenuAddZAtom():Cancelled",6)
283  return;
284  }
285  bondLengthDialog.GetValue().ToDouble(&bondLength);
286  }
287  //angle atom
288  if(1<mpZScatterer->GetZAtomRegistry().GetNb())
289  {
290  const ZAtom *angleAtom=WXDialogChooseFromRegistry(mpZScatterer->GetZAtomRegistry(),
291  this,"Angle Atom",angleAtomId);
292  if(0==angleAtom)
293  {
294  VFN_DEBUG_EXIT("WXZScatterer::OnMenuAddZAtom():Cancelled",6)
295  return;
296  }
297  //angle
298  wxTextEntryDialog angleDialog(this,_T("Enter bond angle (degrees)"),
299  _T("Bond Angle"),_T("110"),wxOK | wxCANCEL);
300  angleDialog.SetTextValidator(wxTextValidator(wxFILTER_NUMERIC));
301  if(wxID_OK!=angleDialog.ShowModal())
302  {
303  VFN_DEBUG_EXIT("WXZScatterer::OnMenuAddZAtom():Cancelled",6)
304  return;
305  }
306  angleDialog.GetValue().ToDouble(&angle);
307  }
308  //dihedral atom
309  if(2<mpZScatterer->GetZAtomRegistry().GetNb())
310  {
311  const ZAtom *dihedAtom=WXDialogChooseFromRegistry(mpZScatterer->GetZAtomRegistry(),
312  this,"Dihedral angle Atom",dihedAtomId);
313  if(0==dihedAtom)
314  {
315  VFN_DEBUG_EXIT("WXZScatterer::OnMenuAddZAtom():Cancelled",6)
316  return;
317  }
318  //dihedral angle
319  wxTextEntryDialog dihedDialog(this,_T("Enter dihedral angle (degrees)"),
320  _T("Dihedral Angle"),_T("0"),wxOK | wxCANCEL);
321  dihedDialog.SetTextValidator(wxTextValidator(wxFILTER_NUMERIC));
322  if(wxID_OK!=dihedDialog.ShowModal())
323  {
324  VFN_DEBUG_EXIT("WXZScatterer::OnMenuAddZAtom():Cancelled",6)
325  return;
326  }
327  dihedDialog.GetValue().ToDouble(&dihed);
328  }
329  // Check all atoms are different
330  if(1<mpZScatterer->GetZAtomRegistry().GetNb())
331  if(bondAtomId==angleAtomId)
332  {
333  wxMessageDialog dumbUser(this,_T("Bond, angle an dihedral atoms *must* be different"),
334  _T("Whooops"),wxOK|wxICON_EXCLAMATION);
335  dumbUser.ShowModal();
336  return;
337  }
338  if(2<mpZScatterer->GetZAtomRegistry().GetNb())
339  if((bondAtomId==angleAtomId)||(bondAtomId==dihedAtomId)||(angleAtomId==dihedAtomId))
340  {
341  wxMessageDialog dumbUser(this,_T("Bond, angle an dihedral atoms *must* be different"),
342  _T("Whooops"),wxOK|wxICON_EXCLAMATION);
343  dumbUser.ShowModal();
344  return;
345  }
346  char buf [5];
347  sprintf(buf,"%d",mpZScatterer->GetNbComponent()+1);
348  mpZScatterer->AddAtom (scattPow->GetName()+(string)buf,
349  scattPow,
350  bondAtomId,bondLength,
351  angleAtomId,angle*DEG2RAD,
352  dihedAtomId,dihed*DEG2RAD,
353  1.);
354  this->CrystUpdate(true);
355  VFN_DEBUG_EXIT("WXZScatterer::OnMenuAddZAtom()",6)
356 }
357 
358 void WXZScatterer::OnMenuSetLimits(wxCommandEvent & event)
359 {//:TODO: Need to
360  VFN_DEBUG_ENTRY("WXZScatterer::OnMenuSetLimits()",6)
362  if(event.GetId()==ID_ZSCATTERER_MENU_PAR_LIMITS_RELAT_BOND)
363  {
364  double limit=.1;
365  wxTextEntryDialog limitDialog(this,_T("Enter maximum shift in Angstroems\n The limits are taken symmetrically around current position:\n X0-l < X < X0+l "),
366  _T("Set limits (relative) for bondlengths"),_T(".1"),wxOK | wxCANCEL);
367  limitDialog.SetTextValidator(wxTextValidator(wxFILTER_NUMERIC));
368  if(wxID_OK!=limitDialog.ShowModal())
369  {
370  VFN_DEBUG_EXIT("WXZScatterer::OnMenuSetLimits():Cancelled",6)
371  return;
372  }
373  limitDialog.GetValue().ToDouble(&limit);
374  if(limit<=0)
375  {
376  wxMessageDialog dumbUser(this,_T("Limit must be > 0 !"),
377  _T("Whooops"),wxOK|wxICON_EXCLAMATION);
378  dumbUser.ShowModal();
379  return;
380  }
381  mpZScatterer->SetLimitsRelative(gpRefParTypeScattConformBondLength,-limit,limit);
382  }
383  if(event.GetId()==ID_ZSCATTERER_MENU_PAR_LIMITS_RELAT_ANGLE)
384  {
385  double limit=5;
386  wxTextEntryDialog limitDialog(this,_T("Enter maximum shift in Degrees\n The limits are taken symmetrically around current position:\n X0-l < X < X0+l "),
387  _T("Set limits (relative) for bond angles"),_T(".1"),wxOK | wxCANCEL);
388  limitDialog.SetTextValidator(wxTextValidator(wxFILTER_NUMERIC));
389  if(wxID_OK!=limitDialog.ShowModal())
390  {
391  VFN_DEBUG_EXIT("WXZScatterer::OnMenuSetLimits():Cancelled",6)
392  return;
393  }
394  limitDialog.GetValue().ToDouble(&limit);
395  if(limit<=0)
396  {
397  wxMessageDialog dumbUser(this,_T("Limit must be > 0 !"),
398  _T("Whooops"),wxOK|wxICON_EXCLAMATION);
399  dumbUser.ShowModal();
400  return;
401  }
402  limit *=DEG2RAD;
403  mpZScatterer->SetLimitsRelative(gpRefParTypeScattConformBondAngle,-limit,limit);
404  }
405  if(event.GetId()==ID_ZSCATTERER_MENU_PAR_LIMITS_RELAT_DIHED)
406  {
407  double limit=5;
408  wxTextEntryDialog limitDialog(this,_T("Enter maximum shift in Degrees\n The limits are taken symmetrically around current position:\n X0-l < X < X0+l "),
409  _T("Set limits (relative) for dihedral angles"),_T(".1"),wxOK | wxCANCEL);
410  limitDialog.SetTextValidator(wxTextValidator(wxFILTER_NUMERIC));
411  if(wxID_OK!=limitDialog.ShowModal())
412  {
413  VFN_DEBUG_EXIT("WXZScatterer::OnMenuSetLimits():Cancelled",6)
414  return;
415  }
416  limitDialog.GetValue().ToDouble(&limit);
417  if(limit<=0)
418  {
419  wxMessageDialog dumbUser(this,_T("Limit must be > 0 !"),
420  _T("Whooops"),wxOK|wxICON_EXCLAMATION);
421  dumbUser.ShowModal();
422  return;
423  }
424  limit *=DEG2RAD;
425  mpZScatterer->SetLimitsRelative(gpRefParTypeScattConformDihedAngle,-limit,limit);
426  }
427 }
428 
429 void WXZScatterer::OnMenuChangePivotAtom(wxCommandEvent &WXUNUSED(event))
430 {
432  int pivot=mpZScatterer->mCenterAtomIndex;
433  const ZAtom *atom=WXDialogChooseFromRegistry(mpZScatterer->GetZAtomRegistry(),
434  this,"Choose the new Pivot atom",pivot);
435  if(0==atom)
436  {
437  VFN_DEBUG_EXIT("WXZScatterer::OnMenuAddZAtom():Cancelled",6)
438  return;
439  }
440  mpZScatterer->mCenterAtomIndex=pivot;
441  mpZScatterer->mClockScatterer.Click();
442 }
443 
444 void WXZScatterer::OnMenuImportZMatrix(wxCommandEvent &WXUNUSED(event))
445 {
446  wxFileDialog open(this,_T("Choose a file"),_T(""),_T(""),_T("*.fhz"),
447  wxFD_OPEN | wxFD_FILE_MUST_EXIST);
448  if(open.ShowModal() != wxID_OK) return;
449  ifstream fin (open.GetPath().ToAscii());
450  if(!fin)
451  {
452  throw ObjCrystException("WXZScatterer::OnMenuImportZMatrix() : \
453 Error opening file for input:"+string(open.GetPath().ToAscii()));
454  }
455  mpZScatterer->ImportFenskeHallZMatrix(fin);
456  fin.close();
457 }
458 void WXZScatterer::OnMenuExportZMatrix(wxCommandEvent &WXUNUSED(event))
459 {
460  wxFileDialog save(this,_T("Choose a file"),_T(""),_T(""),_T("*.fhz"),wxFD_SAVE);
461  if(save.ShowModal() != wxID_OK) return;
462  ofstream fout (save.GetPath().ToAscii());
463  if(!fout)
464  {
465  throw ObjCrystException("WXZScatterer::OnMenuExportZMatrix() : \
466 Error opening file for input:"+string(save.GetPath().ToAscii()));
467  }
468  fout.imbue(std::locale::classic());
469  mpZScatterer->ExportFenskeHallZMatrix(fout);
470  fout.close();
471 }
472 
473 void WXZScatterer::OnMenuConvert2Molecule(wxCommandEvent &WXUNUSED(event))
474 {
475  Molecule *mol=ZScatterer2Molecule(mpZScatterer);
476  mpZScatterer->GetCrystal().RemoveScatterer(mpZScatterer);
477  mol->GetCrystal().AddScatterer(mol);
478  //mol->GetCrystal().UpdateDisplay();
479 }
480 
481 }// namespace
The namespace which includes all objects (crystallographic and algorithmic) in ObjCryst++.
Definition: doc-main.h:25
void WXCrystValidateAllUserInput()
This function validates all user input (in a WXField) not yet taken into account, if needs be.
Definition: wxCryst.cpp:258
Molecule * ZScatterer2Molecule(ZScatterer *scatt)
Converter from ZScatterer to a Molecule object.
Definition: Molecule.cpp:7949
T * WXDialogChooseFromRegistry(ObjRegistry< T > &reg, wxWindow *parent, const string &message, int &choice)
This function allows to pick up one object in a registry.
The basic atom scatterer, in a crystal.
Definition: Atom.h:58
Molecule : class for complex scatterer descriptions using cartesian coordinates with bond length/angl...
Definition: Molecule.h:760
Abstract Base Class to describe the scattering power of any Scatterer component in a crystal.
Class for individual atoms in a ZScatterer Object.
Definition: ZScatterer.h:87
ZScatterer: the basic type of complex scatterers, where atom positions are defined using a standard "...
Definition: ZScatterer.h:191
Class to automatically assign a unique wxID to each window.
Definition: wxCryst.h:75
Abstract base class for all objects in wxCryst.
Definition: wxCryst.h:128
CrystMutex mMutex
Mutex used to lock data when preparing to update the UI in non-main thread.
Definition: wxCryst.h:189
void UpdateUI(const bool mutexlock=false)
Forces all objects in the list to update.
Definition: wxCryst.cpp:234
void CrystUpdate(const bool updateUI=false, const bool mutexlock=false)
Forces all objects in the list to update.
Definition: wxCryst.cpp:224
Base class for all displayed ObjCryst objects (with a title, and a sizer to stack objects).
Definition: wxCryst.h:249
The base wxCryst class for all RefinableObj objects.
base wxCryst class for Scatterers
Definition: wxScatterer.h:36
virtual void UpdateUI(const bool mutexlock=false)
Update the User Interface, if necessary.
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...
wxCryst class for ZScatterer objects
Definition: wxZScatterer.h:48