FOX/ObjCryst++  1.10.X (development)
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 {
49 Molecule *ZScatterer2Molecule(ZScatterer *scatt);
50 
52 {
53  VFN_DEBUG_ENTRY("ZScatterer2Molecule()",6)
54  Molecule *mol=new Molecule(scatt->GetCrystal(),scatt->GetName());
55  const unsigned long nb=scatt->GetZAtomRegistry().GetNb();
56  REAL x0=0,y0=0,z0=0;
57  for(unsigned int i=0;i<nb;++i)
58  {
59  const REAL x=scatt->GetZAtomX(i);
60  const REAL y=scatt->GetZAtomY(i);
61  const REAL z=scatt->GetZAtomZ(i);
62  x0+=x;
63  y0+=y;
64  z0+=z;
65  mol->AddAtom(x,y,z,scatt->GetZAtomRegistry().GetObj(i).GetScatteringPower(),
66  scatt->GetZAtomRegistry().GetObj(i).GetName());
67 
68  #if 0
69  if(i>0)
70  {
71  const RefinablePar* pLength=&(scatt->GetPar(&(scatt->GetZAtomRegistry()
72  .GetObj(i).GetZBondLength())));
73  if(pLength->IsFixed())
74  mol->AddBond(mol->GetAtom(i),mol->GetAtom(scatt->GetZBondAtom(i)),
75  pLength->GetValue(),.01,.02,false);
76  else
77  if(pLength->IsLimited())
78  mol->AddBond(mol->GetAtom(i),mol->GetAtom(scatt->GetZBondAtom(i)),
79  (pLength->GetMin()+pLength->GetMax())/2.,.01,.02,false);
80  }
81  if(i>1)
82  {
83  const RefinablePar* pAngle=&(scatt->GetPar(&(scatt->GetZAtomRegistry()
84  .GetObj(i).GetZAngle())));
85  if(pAngle->IsFixed())
86  mol->AddBondAngle(mol->GetAtom(i),mol->GetAtom(scatt->GetZBondAtom(i)),
87  mol->GetAtom(scatt->GetZAngleAtom(i)),
88  pAngle->GetValue(),.01,.02,false);
89  else
90  if(pAngle->IsLimited())
91  mol->AddBondAngle(mol->GetAtom(i),mol->GetAtom(scatt->GetZBondAtom(i)),
92  mol->GetAtom(scatt->GetZAngleAtom(i)),
93  (pAngle->GetMin()+pAngle->GetMax())/2.,.01,.02,false);
94  }
95  if(i>2)
96  {
97  const RefinablePar* pDihed=&(scatt->GetPar(&(scatt->GetZAtomRegistry()
98  .GetObj(i).GetZDihedralAngle())));
99  MolAtom *p1=&(mol->GetAtom(i));
100  MolAtom *p2=&(mol->GetAtom(scatt->GetZBondAtom(i)));
101  MolAtom *p3=&(mol->GetAtom(scatt->GetZAngleAtom(i)));
102  MolAtom *p4=&(mol->GetAtom(scatt->GetZDihedralAngleAtom(i)));
103  if( (fabs(GetBondAngle(*p1,*p2,*p3)-M_PI)>0.3)
104  &&(fabs(GetBondAngle(*p1,*p2,*p4)-M_PI)>0.3)
105  &&(fabs(GetBondAngle(*p1,*p3,*p4)-M_PI)>0.3)
106  &&(fabs(GetBondAngle(*p2,*p3,*p4)-M_PI)>0.3))
107  {
108  if(pDihed->IsFixed())
109  mol->AddDihedralAngle(*p1,*p2,*p3,*p4,pDihed->GetValue(),.01,.02,false);
110  else
111  if(((pDihed->GetMax()-pDihed->GetMax())<0.3)&&(i>2)&&(pDihed->IsLimited()))
112  mol->AddDihedralAngle(*p1,*p2,*p3,*p4,
113  (pDihed->GetMin()+pDihed->GetMax())/2.,.01,.02,false);
114  }
115  }
116  #endif
117  mol->GetAtom(i).SetOccupancy(scatt->GetZAtomRegistry().GetObj(i).GetOccupancy());
118  }
119 
120  CrystVector_REAL x(nb),y(nb),z(nb),radius(nb);
121  vector<pair<const ScatteringPowerAtom *,long> > scattpow(nb);
122  for(unsigned int i=0;i<nb;++i)
123  {
124  x(i)=mol->GetAtom(i).GetX();
125  y(i)=mol->GetAtom(i).GetY();
126  z(i)=mol->GetAtom(i).GetZ();
127  if(mol->GetAtom(i).IsDummy())
128  {
129  radius(i)=-1;
130  scattpow[i].first=0;
131  }
132  else
133  {
134  radius(i)=mol->GetAtom(i).GetScatteringPower().GetRadius();
135  scattpow[i].first=dynamic_cast<const ScatteringPowerAtom *>
136  (&(mol->GetAtom(i).GetScatteringPower()));
137  scattpow[i].second=scattpow[i].first->GetAtomicNumber();
138  }
139  }
140  for(unsigned int i=0;i<nb;++i)
141  {
142  if(scattpow[i].first==0) continue;
143  const REAL x1=x(i),y1=y(i),z1=z(i);
144  x += -x1;
145  y += -y1;
146  z += -z1;
147  for(unsigned int j=i+1;j<nb;++j)
148  {
149  if(scattpow[j].first==0) continue;
150  const REAL dist=sqrt(x(j)*x(j)+y(j)*y(j)+z(j)*z(j));
151  //cout<<" -> d="<<dist<<"("<<radius(i)<<","<<radius(j)<<"):"<<scattpow[i].second<<","<<scattpow[j].second<<endl;
152  if(dist<(1.10*(radius(i)+radius(j))))
153  {
154  if((1!=scattpow[i].second)||(1!=scattpow[j].second))
155  {
156  mol->AddBond(mol->GetAtom(i),mol->GetAtom(j),dist,.01,.02,false);
157  }
158  }
159  }
160  x += x1;
161  y += y1;
162  z += z1;
163  }
164  mol->BuildConnectivityTable();
165  for(map<MolAtom*,set<MolAtom*> >::const_iterator pos=mol->GetConnectivityTable().begin();
166  pos!=mol->GetConnectivityTable().end();++pos)
167  {
168  for(set<MolAtom*>::const_iterator pos1=pos->second.begin();
169  pos1!=pos->second.end();++pos1)
170  {
171  for(set<MolAtom*>::const_iterator pos2=pos1;
172  pos2!=pos->second.end();++pos2)
173  {
174  if(pos2==pos1) continue;
175  if(mol->FindBondAngle(**pos1,*(pos->first),**pos2)== mol->GetBondAngleList().end())
176  mol->AddBondAngle(**pos1,*(pos->first),**pos2,
177  GetBondAngle(**pos1,*(pos->first),**pos2),0.01,0.02,false);
178  }
179  }
180  }
181  x0 /= nb;
182  y0 /= nb;
183  z0 /= nb;
184  mol->GetCrystal().OrthonormalToFractionalCoords(x0,y0,z0);
185  mol->SetX(x0);
186  mol->SetY(y0);
187  mol->SetZ(z0);
188  mol->UpdateDisplay();
189  VFN_DEBUG_EXIT("ZScatterer2Molecule()",6)
190  return mol;
191 }
192 
194 //
195 // WXZAtom
196 //
198 static const long ID_ZATOM_NAME= WXCRYST_ID();
199 static const long ID_ZATOM_SCATTPOW=WXCRYST_ID();
200 static const long ID_ZATOM_BOND= WXCRYST_ID();
201 static const long ID_ZATOM_ANGLE= WXCRYST_ID();
202 static const long ID_ZATOM_DIHED= WXCRYST_ID();
203 
204 BEGIN_EVENT_TABLE(WXZAtom,wxWindow)
205  EVT_BUTTON(ID_ZATOM_SCATTPOW, WXZAtom::OnChangeScattPow)
206 END_EVENT_TABLE()
207 
208 WXZAtom::WXZAtom(wxWindow* parent, ZAtom *obj):
209 WXCrystObjBasic(parent),mpZAtom(obj)
210 {
211  VFN_DEBUG_ENTRY("WXZAtom::WXZAtom()",6)
212  mpSizer=new wxBoxSizer(wxHORIZONTAL);
213 
214  mpFieldName=new WXFieldString(this, mpZAtom->mName,ID_ZATOM_NAME,80,true);
215  mpSizer->Add(mpFieldName,0,wxALIGN_LEFT);
216  mpFieldScattPower=new WXFieldChoice(this,ID_ZATOM_SCATTPOW,"Type:",60);
217  mpSizer->Add(mpFieldScattPower,0,wxALIGN_LEFT);
218  mList.Add(mpFieldScattPower);
219 
220  if(0<mpZAtom->GetZScatterer().GetZAtomRegistry().Find(*mpZAtom))
221  {
222  RefinablePar *par=&(mpZAtom->GetZScatterer().GetPar(&(mpZAtom->mBondLength)));
223  par->SetName("Bond(w/"+(mpZAtom->GetZScatterer().GetZAtomRegistry()
224  .GetObj(mpZAtom->GetZBondAtom())).GetName()+")");
225  WXCrystObjBasic* pFieldBond=par->WXCreate(this);
226  mpSizer->Add(pFieldBond,0,wxALIGN_LEFT);
227  mList.Add(pFieldBond);
228  }
229 
230  if(1<mpZAtom->GetZScatterer().GetZAtomRegistry().Find(*mpZAtom))
231  {
232  RefinablePar *par=&(mpZAtom->GetZScatterer().GetPar(&(mpZAtom->mAngle)));
233  par->SetName("Angle(w/"+(mpZAtom->GetZScatterer().GetZAtomRegistry()
234  .GetObj(mpZAtom->GetZAngleAtom())).GetName()+")");
235  WXCrystObjBasic* pFieldAngle
236  =par->WXCreate(this);
237  mpSizer->Add(pFieldAngle,0,wxALIGN_LEFT);
238  mList.Add(pFieldAngle);
239  }
240  if(2<mpZAtom->GetZScatterer().GetZAtomRegistry().Find(*mpZAtom))
241  {
242  RefinablePar *par=&(mpZAtom->GetZScatterer().GetPar(&(mpZAtom->mDihed)));
243  par->SetName("DihedralAngle(w/"+(mpZAtom->GetZScatterer().GetZAtomRegistry()
244  .GetObj(mpZAtom->GetZDihedralAngleAtom())).GetName()+")");
245  WXCrystObjBasic* pFieldDihed=par->WXCreate(this);
246  mpSizer->Add(pFieldDihed,0,wxALIGN_LEFT);
247  mList.Add(pFieldDihed);
248  }
249  {
250  RefinablePar *par=&(mpZAtom->GetZScatterer().GetPar(&(mpZAtom->mOccupancy)));
251  par->SetName("Occup.");
252  WXCrystObjBasic* pFieldOccup=par->WXCreate(this);
253  mpSizer->Add(pFieldOccup,0,wxALIGN_LEFT);
254  mList.Add(pFieldOccup);
255  }
256 
257  this->SetSizer(mpSizer);
258 
259  this->BottomLayout(0);
260  this->CrystUpdate(true);
261  VFN_DEBUG_EXIT("WXZAtom::WXZAtom()",6)
262 }
263 
264 void WXZAtom::CrystUpdate(const bool uui,const bool lock)
265 {
266  VFN_DEBUG_ENTRY("WXZAtom::CrystUpdate()",6)
267  if(lock) mMutex.Lock();
268  mList.CrystUpdate(uui,false);
269  if(lock) mMutex.Unlock();
270  VFN_DEBUG_EXIT("WXZAtom::CrystUpdate()",6)
271 }
272 
273 void WXZAtom::UpdateUI(const bool lock)
274 {
275  VFN_DEBUG_ENTRY("WXZAtom::UpdateUI()",6)
276  if(lock) mMutex.Lock();
277  mList.UpdateUI(false);
278  mpFieldName->SetValue(mpZAtom->GetName().c_str());
279  if(0!=mpZAtom->GetScatteringPower())
280  mpFieldScattPower->SetValue(mpZAtom->GetScatteringPower()->GetName());
281  else
282  mpFieldScattPower->SetValue("Dummy");
283  if(lock) mMutex.Unlock();
284  VFN_DEBUG_EXIT("WXZAtom::UpdateUI()",6)
285 }
286 
287 void WXZAtom::OnChangeScattPow(wxCommandEvent & WXUNUSED(event))
288 {
289  VFN_DEBUG_MESSAGE("WXAtom::OnChangeScattPow()",6)
291  int choice;
293  mpZAtom->GetZScatterer().GetCrystal().GetScatteringPowerRegistry(),
294  (wxWindow*)this,"Choose a new Scattering Power",choice);
295  if(0==scatt) return;
296  mpZAtom->SetScatteringPower(scatt);
297  this->CrystUpdate(true);
298  this->UpdateUI(true);
299 }
301 //
302 // WXZScatterer
303 //
305 static const long ID_ZSCATTERER_MENU_ATOM= WXCRYST_ID();
306 static const long ID_ZSCATTERER_MENU_ATOM_ADD= WXCRYST_ID();
307 static const long ID_ZSCATTERER_MENU_ATOM_CHANGE_PIVOT= WXCRYST_ID();
308 static const long ID_ZSCATTERER_MENU_PAR_LIMITS_RELAT_BOND= WXCRYST_ID();
309 static const long ID_ZSCATTERER_MENU_PAR_LIMITS_RELAT_ANGLE=WXCRYST_ID();
310 static const long ID_ZSCATTERER_MENU_PAR_LIMITS_RELAT_DIHED=WXCRYST_ID();
311 static const long ID_ZSCATTERER_MENU_FILE= WXCRYST_ID();
312 static const long ID_ZSCATTERER_MENU_IMPORT_FHZ= WXCRYST_ID();
313 static const long ID_ZSCATTERER_MENU_EXPORT_FHZ= WXCRYST_ID();
314 static const long ID_ZSCATTERER_MENU_CONVERT2MOLECULE= WXCRYST_ID();
315 BEGIN_EVENT_TABLE(WXZScatterer,wxWindow)
316  EVT_BUTTON(ID_WXOBJ_COLLAPSE, WXCrystObj::OnToggleCollapse)
317  EVT_MENU(ID_REFOBJ_MENU_PAR_FIXALL, WXRefinableObj::OnMenuFixAllPar)
318  EVT_MENU(ID_REFOBJ_MENU_PAR_UNFIXALL, WXRefinableObj::OnMenuUnFixAllPar)
319  EVT_MENU(ID_REFOBJ_MENU_PAR_RANDOMIZE, WXRefinableObj::OnMenuParRandomize)
320  EVT_MENU(ID_ZSCATTERER_MENU_PAR_LIMITS_RELAT_BOND, WXZScatterer::OnMenuSetLimits)
321  EVT_MENU(ID_ZSCATTERER_MENU_PAR_LIMITS_RELAT_ANGLE, WXZScatterer::OnMenuSetLimits)
322  EVT_MENU(ID_ZSCATTERER_MENU_PAR_LIMITS_RELAT_DIHED, WXZScatterer::OnMenuSetLimits)
323  EVT_MENU(ID_ZSCATTERER_MENU_ATOM_ADD, WXZScatterer::OnMenuAddZAtom)
324  EVT_MENU(ID_ZSCATTERER_MENU_ATOM_CHANGE_PIVOT, WXZScatterer::OnMenuChangePivotAtom)
325  EVT_MENU(ID_ZSCATTERER_MENU_IMPORT_FHZ, WXZScatterer::OnMenuImportZMatrix)
326  EVT_MENU(ID_ZSCATTERER_MENU_EXPORT_FHZ, WXZScatterer::OnMenuExportZMatrix)
327  EVT_MENU(ID_ZSCATTERER_MENU_CONVERT2MOLECULE, WXZScatterer::OnMenuConvert2Molecule)
328 END_EVENT_TABLE()
329 
330 WXZScatterer::WXZScatterer(wxWindow* parent, ZScatterer *obj):
331 WXScatterer(parent,obj),mpZScatterer(obj)
332 {
333  VFN_DEBUG_MESSAGE("WXZScatterer::WXZScatterer()",6)
334  //Menus
335  mpMenuBar->AddMenu("Import/Export",ID_ZSCATTERER_MENU_FILE);
336  mpMenuBar->AddMenuItem(ID_ZSCATTERER_MENU_FILE,
337  ID_ZSCATTERER_MENU_IMPORT_FHZ,
338  "Import Fenske-Hall Zmatrix");
339  mpMenuBar->AddMenuItem(ID_ZSCATTERER_MENU_FILE,
340  ID_ZSCATTERER_MENU_EXPORT_FHZ,
341  "Save as Fenske-Hall Zmatrix");
342  mpMenuBar->AddMenuItem(ID_ZSCATTERER_MENU_FILE,
343  ID_ZSCATTERER_MENU_CONVERT2MOLECULE,
344  "Convert to Molecule");
345  mpMenuBar->AddMenu("Parameters",ID_REFOBJ_MENU_PAR);
346  mpMenuBar->AddMenuItem(ID_REFOBJ_MENU_PAR,ID_REFOBJ_MENU_PAR_FIXALL,"Fix all");
347  mpMenuBar->AddMenuItem(ID_REFOBJ_MENU_PAR,ID_REFOBJ_MENU_PAR_UNFIXALL,"Unfix all");
348  mpMenuBar->AddMenuItem(ID_REFOBJ_MENU_PAR,ID_REFOBJ_MENU_PAR_RANDOMIZE,
349  "Randomize Configuration");
350  mpMenuBar->AddMenuItem(ID_REFOBJ_MENU_PAR,ID_ZSCATTERER_MENU_PAR_LIMITS_RELAT_BOND,
351  "Set limits (relative) on all bondlengths");
352  mpMenuBar->AddMenuItem(ID_REFOBJ_MENU_PAR,ID_ZSCATTERER_MENU_PAR_LIMITS_RELAT_ANGLE,
353  "Set limits (relative) on all bond angles");
354  mpMenuBar->AddMenuItem(ID_REFOBJ_MENU_PAR,ID_ZSCATTERER_MENU_PAR_LIMITS_RELAT_DIHED,
355  "Set limits (relative) on all dihedral angles");
356  mpMenuBar->AddMenu("Atom",ID_ZSCATTERER_MENU_ATOM);
357  mpMenuBar->AddMenuItem(ID_ZSCATTERER_MENU_ATOM,ID_ZSCATTERER_MENU_ATOM_ADD,
358  "Add an Atom");
359  mpMenuBar->AddMenuItem(ID_ZSCATTERER_MENU_ATOM,ID_ZSCATTERER_MENU_ATOM_CHANGE_PIVOT,
360  "Change Pivot Atom");
361  //mpSizer->SetItemMinSize(mpMenuBar,
362  // mpMenuBar->GetSize().GetWidth(),
363  // mpMenuBar->GetSize().GetHeight());
364  //Orientation
365  wxBoxSizer* sizer=new wxBoxSizer(wxHORIZONTAL);
366 
367  WXCrystObjBasic* pFieldPhi =mpZScatterer->GetPar(&(mpZScatterer->mPhi)).WXCreate(this);
368  WXCrystObjBasic* pFieldChi =mpZScatterer->GetPar(&(mpZScatterer->mChi)).WXCreate(this);
369  WXCrystObjBasic* pFieldPsi =mpZScatterer->GetPar(&(mpZScatterer->mPsi)).WXCreate(this);
370 
371  sizer->Add(pFieldPhi ,0,wxALIGN_CENTER);
372  sizer->Add(pFieldChi ,0,wxALIGN_CENTER);
373  sizer->Add(pFieldPsi ,0,wxALIGN_CENTER);
374 
375  mpSizer->Add(sizer,0,wxALIGN_LEFT);
376  mList.Add(pFieldPhi);
377  mList.Add(pFieldChi);
378  mList.Add(pFieldPsi);
379  //Atoms
380  mpWXZAtomRegistry=mpZScatterer->mZAtomRegistry.WXCreate(this);
381  mpSizer->Add(mpWXZAtomRegistry,0,wxALIGN_LEFT);
382  mList.Add(mpWXZAtomRegistry);
383 
384  this->BottomLayout(0);
385  this->CrystUpdate(true);
386 }
387 
388 void WXZScatterer::OnMenuAddZAtom(wxCommandEvent & WXUNUSED(event))
389 {
390  VFN_DEBUG_ENTRY("WXZScatterer::OnMenuAddZAtom()",6)
392 
393  int choice;
394  int bondAtomId=0;
395  double bondLength;
396  int angleAtomId=0;;
397  double angle;
398  int dihedAtomId=0;;
399  double dihed;
400  //Scattering power
402  mpZScatterer->GetCrystal().GetScatteringPowerRegistry(),
403  this,"Choose an atom type (ScatteringPower):",choice);
404  if(0==scattPow)
405  {
406  VFN_DEBUG_EXIT("WXZScatterer::OnMenuAddZAtom():Cancelled",6)
407  return;
408  }
409  //Bond atom
410  if(0<mpZScatterer->GetZAtomRegistry().GetNb())
411  {
412 
413  const ZAtom *bondAtom=WXDialogChooseFromRegistry(mpZScatterer->GetZAtomRegistry(),
414  this,"Choose the bonded atom",bondAtomId);
415  if(0==bondAtom)
416  {
417  VFN_DEBUG_EXIT("WXZScatterer::OnMenuAddZAtom():Cancelled",6)
418  return;
419  }
420  //Bond length
421  wxTextEntryDialog bondLengthDialog(this,_T("Enter bond length (Angstroems)"),
422  _T("Bond length"),_T("1.5"),wxOK | wxCANCEL);
423  if(wxID_OK!=bondLengthDialog.ShowModal())
424  {
425  VFN_DEBUG_EXIT("WXZScatterer::OnMenuAddZAtom():Cancelled",6)
426  return;
427  }
428  bondLengthDialog.GetValue().ToDouble(&bondLength);
429  }
430  //angle atom
431  if(1<mpZScatterer->GetZAtomRegistry().GetNb())
432  {
433  const ZAtom *angleAtom=WXDialogChooseFromRegistry(mpZScatterer->GetZAtomRegistry(),
434  this,"Angle Atom",angleAtomId);
435  if(0==angleAtom)
436  {
437  VFN_DEBUG_EXIT("WXZScatterer::OnMenuAddZAtom():Cancelled",6)
438  return;
439  }
440  //angle
441  wxTextEntryDialog angleDialog(this,_T("Enter bond angle (degrees)"),
442  _T("Bond Angle"),_T("110"),wxOK | wxCANCEL);
443  if(wxID_OK!=angleDialog.ShowModal())
444  {
445  VFN_DEBUG_EXIT("WXZScatterer::OnMenuAddZAtom():Cancelled",6)
446  return;
447  }
448  angleDialog.GetValue().ToDouble(&angle);
449  }
450  //dihedral atom
451  if(2<mpZScatterer->GetZAtomRegistry().GetNb())
452  {
453  const ZAtom *dihedAtom=WXDialogChooseFromRegistry(mpZScatterer->GetZAtomRegistry(),
454  this,"Dihedral angle Atom",dihedAtomId);
455  if(0==dihedAtom)
456  {
457  VFN_DEBUG_EXIT("WXZScatterer::OnMenuAddZAtom():Cancelled",6)
458  return;
459  }
460  //dihedral angle
461  wxTextEntryDialog dihedDialog(this,_T("Enter dihedral angle (degrees)"),
462  _T("Dihedral Angle"),_T("0"),wxOK | wxCANCEL);
463  if(wxID_OK!=dihedDialog.ShowModal())
464  {
465  VFN_DEBUG_EXIT("WXZScatterer::OnMenuAddZAtom():Cancelled",6)
466  return;
467  }
468  dihedDialog.GetValue().ToDouble(&dihed);
469  }
470  // Check all atoms are different
471  if(1<mpZScatterer->GetZAtomRegistry().GetNb())
472  if(bondAtomId==angleAtomId)
473  {
474  wxMessageDialog dumbUser(this,_T("Bond, angle an dihedral atoms *must* be different"),
475  _T("Whooops"),wxOK|wxICON_EXCLAMATION);
476  dumbUser.ShowModal();
477  return;
478  }
479  if(2<mpZScatterer->GetZAtomRegistry().GetNb())
480  if((bondAtomId==angleAtomId)||(bondAtomId==dihedAtomId)||(angleAtomId==dihedAtomId))
481  {
482  wxMessageDialog dumbUser(this,_T("Bond, angle an dihedral atoms *must* be different"),
483  _T("Whooops"),wxOK|wxICON_EXCLAMATION);
484  dumbUser.ShowModal();
485  return;
486  }
487  char buf [5];
488  sprintf(buf,"%d",mpZScatterer->GetNbComponent()+1);
489  mpZScatterer->AddAtom (scattPow->GetName()+(string)buf,
490  scattPow,
491  bondAtomId,bondLength,
492  angleAtomId,angle*DEG2RAD,
493  dihedAtomId,dihed*DEG2RAD,
494  1.);
495  this->CrystUpdate(true);
496  VFN_DEBUG_EXIT("WXZScatterer::OnMenuAddZAtom()",6)
497 }
498 
499 void WXZScatterer::OnMenuSetLimits(wxCommandEvent & event)
500 {//:TODO: Need to
501  VFN_DEBUG_ENTRY("WXZScatterer::OnMenuSetLimits()",6)
503  if(event.GetId()==ID_ZSCATTERER_MENU_PAR_LIMITS_RELAT_BOND)
504  {
505  double limit=.1;
506  wxTextEntryDialog limitDialog(this,_T("Enter maximum shift in Angstroems\n The limits are taken symmetrically around current position:\n X0-l < X < X0+l "),
507  _T("Set limits (relative) for bondlengths"),_T(".1"),wxOK | wxCANCEL);
508  if(wxID_OK!=limitDialog.ShowModal())
509  {
510  VFN_DEBUG_EXIT("WXZScatterer::OnMenuSetLimits():Cancelled",6)
511  return;
512  }
513  limitDialog.GetValue().ToDouble(&limit);
514  if(limit<=0)
515  {
516  wxMessageDialog dumbUser(this,_T("Limit must be > 0 !"),
517  _T("Whooops"),wxOK|wxICON_EXCLAMATION);
518  dumbUser.ShowModal();
519  return;
520  }
521  mpZScatterer->SetLimitsRelative(gpRefParTypeScattConformBondLength,-limit,limit);
522  }
523  if(event.GetId()==ID_ZSCATTERER_MENU_PAR_LIMITS_RELAT_ANGLE)
524  {
525  double limit=5;
526  wxTextEntryDialog limitDialog(this,_T("Enter maximum shift in Degrees\n The limits are taken symmetrically around current position:\n X0-l < X < X0+l "),
527  _T("Set limits (relative) for bond angles"),_T(".1"),wxOK | wxCANCEL);
528  if(wxID_OK!=limitDialog.ShowModal())
529  {
530  VFN_DEBUG_EXIT("WXZScatterer::OnMenuSetLimits():Cancelled",6)
531  return;
532  }
533  limitDialog.GetValue().ToDouble(&limit);
534  if(limit<=0)
535  {
536  wxMessageDialog dumbUser(this,_T("Limit must be > 0 !"),
537  _T("Whooops"),wxOK|wxICON_EXCLAMATION);
538  dumbUser.ShowModal();
539  return;
540  }
541  limit *=DEG2RAD;
542  mpZScatterer->SetLimitsRelative(gpRefParTypeScattConformBondAngle,-limit,limit);
543  }
544  if(event.GetId()==ID_ZSCATTERER_MENU_PAR_LIMITS_RELAT_DIHED)
545  {
546  double limit=5;
547  wxTextEntryDialog limitDialog(this,_T("Enter maximum shift in Degrees\n The limits are taken symmetrically around current position:\n X0-l < X < X0+l "),
548  _T("Set limits (relative) for dihedral angles"),_T(".1"),wxOK | wxCANCEL);
549  if(wxID_OK!=limitDialog.ShowModal())
550  {
551  VFN_DEBUG_EXIT("WXZScatterer::OnMenuSetLimits():Cancelled",6)
552  return;
553  }
554  limitDialog.GetValue().ToDouble(&limit);
555  if(limit<=0)
556  {
557  wxMessageDialog dumbUser(this,_T("Limit must be > 0 !"),
558  _T("Whooops"),wxOK|wxICON_EXCLAMATION);
559  dumbUser.ShowModal();
560  return;
561  }
562  limit *=DEG2RAD;
563  mpZScatterer->SetLimitsRelative(gpRefParTypeScattConformDihedAngle,-limit,limit);
564  }
565 }
566 
567 void WXZScatterer::OnMenuChangePivotAtom(wxCommandEvent &WXUNUSED(event))
568 {
570  int pivot=mpZScatterer->mCenterAtomIndex;
571  const ZAtom *atom=WXDialogChooseFromRegistry(mpZScatterer->GetZAtomRegistry(),
572  this,"Choose the new Pivot atom",pivot);
573  if(0==atom)
574  {
575  VFN_DEBUG_EXIT("WXZScatterer::OnMenuAddZAtom():Cancelled",6)
576  return;
577  }
578  mpZScatterer->mCenterAtomIndex=pivot;
579  mpZScatterer->mClockScatterer.Click();
580 }
581 
582 void WXZScatterer::OnMenuImportZMatrix(wxCommandEvent &WXUNUSED(event))
583 {
584  wxFileDialog open(this,_T("Choose a file"),_T(""),_T(""),_T("*.fhz"),
585  wxFD_OPEN | wxFD_FILE_MUST_EXIST);
586  if(open.ShowModal() != wxID_OK) return;
587  ifstream fin (open.GetPath().ToAscii());
588  if(!fin)
589  {
590  throw ObjCrystException("WXZScatterer::OnMenuImportZMatrix() : \
591 Error opening file for input:"+string(open.GetPath().ToAscii()));
592  }
593  mpZScatterer->ImportFenskeHallZMatrix(fin);
594  fin.close();
595 }
596 void WXZScatterer::OnMenuExportZMatrix(wxCommandEvent &WXUNUSED(event))
597 {
598  wxFileDialog save(this,_T("Choose a file"),_T(""),_T(""),_T("*.fhz"),wxFD_SAVE);
599  if(save.ShowModal() != wxID_OK) return;
600  ofstream fout (save.GetPath().ToAscii());
601  if(!fout)
602  {
603  throw ObjCrystException("WXZScatterer::OnMenuExportZMatrix() : \
604 Error opening file for input:"+string(save.GetPath().ToAscii()));
605  }
606  mpZScatterer->ExportFenskeHallZMatrix(fout);
607  fout.close();
608 }
609 
610 void WXZScatterer::OnMenuConvert2Molecule(wxCommandEvent &WXUNUSED(event))
611 {
612  Molecule *mol=ZScatterer2Molecule(mpZScatterer);
613  mpZScatterer->GetCrystal().RemoveScatterer(mpZScatterer);
614  mol->GetCrystal().AddScatterer(mol);
615  //mol->GetCrystal().UpdateDisplay();
616 }
617 
618 }// namespace
619 
620 
621 
622 
623 
624 
625 
626 
627 
628 
629 
630 
T * WXDialogChooseFromRegistry(ObjRegistry< T > &reg, wxWindow *parent, const string &message, int &choice)
This function allows to pick up one object in a registry.
REAL GetZAtomY(const int i) const
Get the Y fractionnal coordinate of atom i.
Definition: ZScatterer.cpp:439
REAL GetMin() const
Minimum value allowed (if limited or periodic)
void WXCrystValidateAllUserInput()
This function validates all user input (in a WXField) not yet taken into account, if needs be...
Definition: wxCryst.cpp:257
CrystMutex mMutex
Mutex used to lock data when preparing to update the UI in non-main thread.
Definition: wxCryst.h:189
void OrthonormalToFractionalCoords(REAL &x, REAL &y, REAL &z) const
Get fractional cartesian coordinates for a set of (x,y,z) orthonormal coordinates.
Definition: UnitCell.cpp:271
REAL GetZAtomZ(const int i) const
Get the Z fractionnal coordinate of atom i.
Definition: ZScatterer.cpp:440
void AddBondAngle(MolAtom &atom1, MolAtom &atom2, MolAtom &atom3, const REAL angle, const REAL sigma, const REAL delta, const bool updateDisplay=true)
Add a bond angle restraint.
Definition: Molecule.cpp:3976
wxCryst class for ZScatterer objects
Definition: wxZScatterer.h:46
RefinablePar & GetPar(const long i)
Access all parameters in the order they were inputted.
virtual REAL GetRadius() const =0
Return the physical radius of this type of scatterer (for 3D display purposes).
void AddDihedralAngle(MolAtom &atom1, MolAtom &atom2, MolAtom &atom3, MolAtom &atom4, const REAL angle, const REAL sigma, const REAL delta, const bool updateDisplay=true)
Add a dihedral angle restraint.
Definition: Molecule.cpp:4022
void CrystUpdate(const bool updateUI=false, const bool mutexlock=false)
Forces all objects in the list to update.
Definition: wxCryst.cpp:223
void AddAtom(const REAL x, const REAL y, const REAL z, const ScatteringPower *pPow, const string &name, const bool updateDisplay=true)
Add an atom.
Definition: Molecule.cpp:3786
Abstract base class for all objects in wxCryst.
Definition: wxCryst.h:127
The basic atom scatterer, in a crystal.
Definition: Atom.h:57
REAL GetBondAngle(const MolAtom &at1, const MolAtom &at2, const MolAtom &at3)
Get The Bond Angle of 3 atoms.
Definition: Molecule.cpp:95
Molecule : class for complex scatterer descriptions using cartesian coordinates with bond length/angl...
Definition: Molecule.h:731
Class for individual atoms in a ZScatterer Object.
Definition: ZScatterer.h:86
virtual void SetY(const REAL y)
Y coordinate (fractionnal) of the scatterer (for complex scatterers, this corresponds to the position...
Definition: Scatterer.cpp:110
REAL GetMax() const
Get the maximum value allowed (if limited)
Base class for all displayed ObjCryst objects (with a title, and a sizer to stack objects)...
Definition: wxCryst.h:248
MolAtom : atom inside a Molecule.
Definition: Molecule.h:58
const map< MolAtom *, set< MolAtom * > > & GetConnectivityTable()
Get the connectivity table.
Definition: Molecule.cpp:4574
virtual void SetX(const REAL x)
X coordinate (fractionnal) of the scatterer (for complex scatterers, this corresponds to the position...
Definition: Scatterer.cpp:109
The base wxCryst class for all RefinableObj objects.
long GetZBondAtom(const int i) const
Index of the 1st atom used to define the i-th atom in the Z-Matrix (the one from which the bondlength...
Definition: ZScatterer.cpp:441
ZScatterer: the basic type of complex scatterers, where atom positions are defined using a standard "...
Definition: ZScatterer.h:190
const Crystal & GetCrystal() const
In which crystal is this Scatterer included ?
Definition: Scatterer.cpp:137
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...
int GetAtomicNumber() const
Atomic number for this atom.
vector< MolBondAngle * >::const_iterator FindBondAngle(const MolAtom &at1, const MolAtom &at0, const MolAtom &at2) const
Searches whether a bond between three atoms already exists, searching for either (at1,at2,at3) and (at3,at2,at1), as these are equivalent.
Definition: Molecule.cpp:4007
Class to automatically assign a unique wxID to each window.
Definition: wxCryst.h:74
The namespace which includes all objects (crystallographic and algorithmic) in ObjCryst++.
Definition: Atom.cpp:47
The Scattering Power for an Atom.
void BuildConnectivityTable() const
Build the Connectivity table.
Definition: Molecule.cpp:5299
Generic class for parameters of refinable objects.
Definition: RefinableObj.h:223
Molecule * ZScatterer2Molecule(ZScatterer *scatt)
Conversion from ZScatterer to the newer Molecule object. (in WXZScatterer.cpp)
virtual const string & GetName() const
Name of the object.
REAL GetValue() const
of the parameter.
virtual void UpdateDisplay() const
If there is an interface, this should be automatically be called each time there is a 'new...
Definition: Molecule.cpp:2379
virtual void UpdateUI(const bool mutexlock=false)
Update the User Interface, if necessary.
const ObjRegistry< ZAtom > & GetZAtomRegistry() const
Access to the registry of ZAtoms.
Definition: ZScatterer.cpp:466
long GetZDihedralAngleAtom(const int i) const
Index of the 3rd atom used to define the i-th atom in the Z-Matrix (the one from which the dihedral a...
Definition: ZScatterer.cpp:447
REAL GetZAtomX(const int i) const
Get the X fractionnal coordinate of atom i.
Definition: ZScatterer.cpp:438
long GetZAngleAtom(const int i) const
Index of the 2nd atom used to define the i-th atom in the Z-Matrix (the one from which the angle is c...
Definition: ZScatterer.cpp:444
bool IsDummy() const
Returns true if this is a dummy atom, i.e.
Definition: Molecule.cpp:249
void AddBond(MolAtom &atom1, MolAtom &atom2, const REAL length, const REAL sigma, const REAL delta, const REAL bondOrder=1., const bool updateDisplay=true)
Add a bond.
Definition: Molecule.cpp:3923
virtual void SetZ(const REAL z)
Z coordinate (fractionnal) of the scatterer (for complex scatterers, this corresponds to the position...
Definition: Scatterer.cpp:111
void UpdateUI(const bool mutexlock=false)
Forces all objects in the list to update.
Definition: wxCryst.cpp:233
base wxCryst class for Scatterers
Definition: wxScatterer.h:35
Abstract Base Class to describe the scattering power of any Scatterer component in a crystal...