21 #include "wx/wxprec.h"
28 #include "wx/notebook.h"
29 #include "wx/minifram.h"
30 #include <wx/wfstream.h>
31 #include "wx/progdlg.h"
36 #include "ObjCryst/wxCryst/wxMolecule.h"
37 #include "ObjCryst/RefinableObj/LSQNumObj.h"
38 #include "ObjCryst/Quirks/Chronometer.h"
39 #include "ObjCryst/Quirks/VFNStreamFormat.h"
45 template<
class T> T
const* WXDialogChooseFromVector(
const vector<T*> ®,wxWindow*parent,
46 const string &message,
int &choice)
48 wxString *choices =
new wxString[reg.size()];
49 for(
unsigned int i=0;i<reg.size();i++)
50 choices[i]= wxString::FromAscii((reg[i]->GetName()).c_str());
51 wxSingleChoiceDialog dialog
52 (parent,message.c_str(),
"Choose",reg.size(),choices,NULL,wxOK | wxCANCEL);
53 dialog.SetSize(300,300);
54 if(wxID_OK!=dialog.ShowModal())
return 0;
55 choice=dialog.GetSelection();
60 template<
class T> T * WXDialogChooseFromVector(vector<T*> ®,wxWindow*parent,
61 const string &message,
int &choice)
63 wxString *choices =
new wxString[reg.size()];
64 for(
unsigned int i=0;i<reg.size();i++)
65 choices[i]= wxString::FromAscii((reg[i]->GetName()).c_str());
66 #if wxCHECK_VERSION( 2, 9, 4 )
67 wxSingleChoiceDialog dialog
68 (parent, wxString::FromAscii(message.c_str()),_T(
"Choose"),reg.size(),choices,(
void**)NULL,wxOK | wxCANCEL);
70 wxSingleChoiceDialog dialog
71 (parent, wxString::FromAscii(message.c_str()),_T(
"Choose"),reg.size(),choices,NULL,wxOK | wxCANCEL);
73 dialog.SetSize(300,300);
74 if(wxID_OK!=dialog.ShowModal())
return 0;
75 choice=dialog.GetSelection();
80 template<
class T> list<T *> WXDialogChooseMultipleFromVector(vector<T*> ®,wxWindow*parent,
81 const string &message)
83 wxString *choices =
new wxString[reg.size()];
84 for(
unsigned int i=0;i<reg.size();i++)
85 choices[i]= wxString::FromAscii((reg[i]->GetName()).c_str());
86 wxMultiChoiceDialog_ListBox dialog
87 (parent, wxString::FromAscii(message.c_str()),_T(
"Choose"),reg.size(),choices);
89 wxArrayInt choice=dialog.GetSelections();
91 for(
unsigned int i=0;i<choice.GetCount();++i) vChoice.push_back(reg[choice.Item(i)]);
95 template<
class T> list<T const*> WXDialogChooseMultipleFromVector(
const vector<T*> ®,wxWindow*parent,
96 const string &message)
98 wxString *choices =
new wxString[reg.size()];
99 for(
unsigned int i=0;i<reg.size();i++)
100 choices[i]= wxString::FromAscii((reg[i]->GetName()).c_str());
101 wxMultiChoiceDialog_ListBox dialog
102 (parent, wxString::FromAscii(message.c_str()),_T(
"Choose"),reg.size(),choices);
104 wxArrayInt choice=dialog.GetSelections();
105 list<T const*> vChoice;
106 for(
unsigned int i=0;i<choice.GetCount();++i) vChoice.push_back(reg[choice.Item(i)]);
112 string CompressString(
const string &s,
const string &c)
115 string::size_type idx=0;
116 while(idx!=string::npos)
119 if(idx!=string::npos) sc.erase(idx,c.size());
124 list<string> SplitString(
const string &str,
const string &separator)
126 string::size_type idx0=(string::size_type) 0;
127 string::size_type idx1=(string::size_type) 0;
129 while((idx1!=string::npos)&&(idx0<str.size()))
131 idx1=str.find(separator,idx0);
132 if(idx1==string::npos) l.push_back(str.substr(idx0,idx1));
133 if(idx1>idx0) l.push_back(str.substr(idx0,idx1-idx0));
146 WXMolScrolledWindow::WXMolScrolledWindow(wxWindow* parent, WXMolecule* pWXMol,
long id):
147 wxGrid(parent,id),mpWXMolecule(pWXMol)
149 WXMolScrolledWindow::~WXMolScrolledWindow()
151 mpWXMolecule->NotifyDeleteListWin(
this);
158 static const long ID_MOLATOM_SCATTPOW=WXCRYST_ID();
159 static const long ID_MOLATOM_NAME=WXCRYST_ID();
161 BEGIN_EVENT_TABLE(WXMolAtom,wxWindow)
162 EVT_BUTTON(ID_MOLATOM_SCATTPOW, WXMolAtom::OnChangeScattPow)
165 WXMolAtom::WXMolAtom(wxWindow *parent, MolAtom*obj):
166 WXCrystObjBasic(parent),mpMolAtom(obj)
168 VFN_DEBUG_ENTRY(
"WXMolAtom::WXMolAtom():"<<obj->GetName(),6)
169 mpSizer=new wxBoxSizer(wxHORIZONTAL);
170 wxStaticText* label=new wxStaticText(this,-1,_T("Atom"));
173 mpFieldName=
new WXFieldString(
this, mpMolAtom->GetName(),ID_MOLATOM_NAME,80,
true);
174 mpSizer->Add(mpFieldName,0,wxALIGN_CENTER);
175 mpFieldScattPower=
new WXFieldChoice(
this,ID_MOLATOM_SCATTPOW,
"Type:",60);
176 mpSizer->Add(mpFieldScattPower,0,wxALIGN_CENTER);
177 mList.Add(mpFieldScattPower);
178 if(mpMolAtom->IsDummy())
179 mpFieldScattPower->SetValue(
"Dummy");
181 mpFieldScattPower->SetValue(mpMolAtom->GetScatteringPower().GetName());
184 WXCrystObjBasic* pFieldX=mpMolAtom->GetMolecule().GetPar(&(mpMolAtom->X())).WXCreate(
this);
185 mpSizer->Add(pFieldX,0,wxALIGN_CENTER);
189 WXCrystObjBasic* pFieldY=mpMolAtom->GetMolecule().GetPar(&(mpMolAtom->Y())).WXCreate(
this);
190 mpSizer->Add(pFieldY,0,wxALIGN_CENTER);
194 WXCrystObjBasic* pFieldZ=mpMolAtom->GetMolecule().GetPar(&(mpMolAtom->Z())).WXCreate(
this);
195 mpSizer->Add(pFieldZ,0,wxALIGN_CENTER);
199 this->SetSizer(mpSizer);
201 this->CrystUpdate(
true);
202 VFN_DEBUG_EXIT(
"WXMolAtom::WXMolAtom():"<<obj->GetName(),6)
205 WXMolAtom::~WXMolAtom()
207 mpMolAtom->WXNotifyDelete();
210 void WXMolAtom::CrystUpdate(
const bool uui,
const bool lock)
212 VFN_DEBUG_ENTRY(
"WXMolAtom::CrystUpdate()",5)
213 if(lock) mMutex.Lock();
214 mList.CrystUpdate(uui,
false);
215 if(lock) mMutex.Unlock();
216 VFN_DEBUG_EXIT(
"WXMolAtom::CrystUpdate()",5)
219 void WXMolAtom::UpdateUI(
const bool lock)
221 VFN_DEBUG_ENTRY(
"WXMolAtom::UpdateUI()",5)
222 if(lock) mMutex.Lock();
223 mList.UpdateUI(
false);
224 mpFieldName->SetValue(mpMolAtom->GetName().c_str());
225 if(mpMolAtom->IsDummy())
226 mpFieldScattPower->SetValue(
"Dummy");
228 mpFieldScattPower->SetValue(mpMolAtom->GetScatteringPower().GetName());
229 if(lock) mMutex.Unlock();
230 VFN_DEBUG_EXIT(
"WXMolAtom::UpdateUI()",5)
233 void WXMolAtom::OnChangeScattPow(wxCommandEvent & WXUNUSED(event))
235 VFN_DEBUG_ENTRY(
"WXMolAtom::OnChangeScattPow()",6)
236 WXCrystValidateAllUserInput();
239 mpMolAtom->GetMolecule().GetCrystal().GetScatteringPowerRegistry(),
240 (wxWindow*)this,"Choose a new Scattering Power",choice);
242 mpMolAtom->SetScatteringPower(*scatt);
243 this->CrystUpdate(true);
244 this->UpdateUI(true);
245 VFN_DEBUG_EXIT("
WXMolAtom::OnChangeScattPow()",6)
257 EVT_BUTTON(ID_MOLBOND_ATOM1,
WXMolBond::OnChangeAtom)
258 EVT_BUTTON(ID_MOLBOND_ATOM2,
WXMolBond::OnChangeAtom)
259 EVT_CHECKBOX(ID_MOLBOND_FREEBUTTON,
WXMolBond::OnToggleFree)
265 VFN_DEBUG_ENTRY(
"WXMolBond::WXMolBond():"<<obj->GetName(),6)
266 mpSizer=new wxBoxSizer(wxHORIZONTAL);
268 mpButtonFree=
new wxCheckBox(
this,ID_MOLBOND_FREEBUTTON,_T(
""),wxDefaultPosition, wxDefaultSize);
270 mpSizer->Add(mpButtonFree,0,wxALIGN_CENTER);
272 mpFieldAtom1=
new WXFieldChoice(
this,ID_MOLBOND_ATOM1,
"Bond:",60);
273 mpFieldAtom1->SetValue(mpMolBond->GetAtom1().GetName());
274 mpSizer->Add(mpFieldAtom1,0,wxALIGN_CENTER);
275 mList.Add(mpFieldAtom1);
277 mpFieldAtom2=
new WXFieldChoice(
this,ID_MOLBOND_ATOM2,
"-",60);
278 mpFieldAtom2->SetValue(mpMolBond->GetAtom2().GetName());
279 mpSizer->Add(mpFieldAtom2,0,wxALIGN_CENTER);
280 mList.Add(mpFieldAtom2);
284 mpSizer->Add(value,0,wxALIGN_CENTER);
289 mpSizer->Add(length,0,wxALIGN_CENTER);
294 mpSizer->Add(delta,0,wxALIGN_CENTER);
299 mpSizer->Add(sigma,0,wxALIGN_CENTER);
302 this->SetSizer(mpSizer);
304 this->CrystUpdate(
true,
true);
305 VFN_DEBUG_EXIT(
"WXMolBond::WXMolBond():"<<obj->GetName(),6)
307 WXMolBond::~WXMolBond()
309 mpMolBond->WXNotifyDelete();
312 void WXMolBond::CrystUpdate(
const bool uui,
const bool lock)
314 VFN_DEBUG_ENTRY(
"WXMolBond::CrystUpdate()",5)
315 if(lock) mMutex.Lock();
316 mValue=mpMolBond->GetLength();
317 mList.CrystUpdate(uui,
false);
318 if(lock) mMutex.Unlock();
319 VFN_DEBUG_EXIT(
"WXMolBond::CrystUpdate()",5)
322 void WXMolBond::UpdateUI(
const bool lock)
324 VFN_DEBUG_ENTRY(
"WXMolBond::UpdateUI()",5)
325 if(lock) mMutex.Lock();
326 if(0!=mpButtonFree) mpButtonFree->SetValue(mpMolBond->IsFreeTorsion());
327 mList.UpdateUI(
false);
328 mpFieldAtom1->SetValue(mpMolBond->GetAtom1().GetName().c_str());
329 mpFieldAtom2->SetValue(mpMolBond->GetAtom2().GetName().c_str());
330 if(lock) mMutex.Unlock();
331 VFN_DEBUG_EXIT(
"WXMolBond::UpdateUI()",5)
334 void WXMolBond::OnChangeAtom(wxCommandEvent &event)
336 VFN_DEBUG_ENTRY(
"WXMolBond::OnChangeAtom()",6)
337 WXCrystValidateAllUserInput();
339 MolAtom *const at=WXDialogChooseFromVector(mpMolBond->GetMolecule().GetAtomList(),
340 (wxWindow*)this,"Choose a new
Atom",choice);
342 if((
long)ID_MOLBOND_ATOM1==event.GetId())
344 if(at==&(mpMolBond->GetAtom2()))
346 wxMessageDialog dumbUser(
this,_T(
"The two atoms must be different !"),
347 _T(
"Whooops"),wxOK|wxICON_EXCLAMATION);
348 dumbUser.ShowModal();
351 mpMolBond->SetAtom1(*at);
353 if((
long)ID_MOLBOND_ATOM2==event.GetId())
355 if(at==&(mpMolBond->GetAtom1()))
357 wxMessageDialog dumbUser(
this,_T(
"The two atoms must be different !"),
358 _T(
"Whooops"),wxOK|wxICON_EXCLAMATION);
359 dumbUser.ShowModal();
362 mpMolBond->SetAtom2(*at);
365 this->CrystUpdate(
true);
366 this->UpdateUI(
true);
367 VFN_DEBUG_EXIT(
"WXMolBond::OnChangeScattPow()",6)
370 void WXMolBond::OnToggleFree(wxCommandEvent & WXUNUSED(event))
372 VFN_DEBUG_MESSAGE(
"WXMolBond::OnToggleFree()",6)
373 if(0!=mpButtonFree) mpMolBond->SetFreeTorsion(mpButtonFree->GetValue());
386 EVT_BUTTON(ID_MOLBONDANGLE_ATOM1, WXMolBondAngle::OnChangeAtom)
387 EVT_BUTTON(ID_MOLBONDANGLE_ATOM2, WXMolBondAngle::OnChangeAtom)
388 EVT_BUTTON(ID_MOLBONDANGLE_ATOM3, WXMolBondAngle::OnChangeAtom)
394 VFN_DEBUG_ENTRY(
"WXMolBondAngle::WXMolBond():"<<obj->GetName(),6)
395 mpSizer=new wxBoxSizer(wxHORIZONTAL);
397 mpFieldAtom1=new
WXFieldChoice(this,ID_MOLBONDANGLE_ATOM1,"Bond Angle:",60);
398 mpFieldAtom1->SetValue(mpMolBondAngle->GetAtom1().GetName());
399 mpSizer->Add(mpFieldAtom1,0,wxALIGN_CENTER);
400 mList.Add(mpFieldAtom1);
402 mpFieldAtom2=new
WXFieldChoice(this,ID_MOLBONDANGLE_ATOM2,"-",60);
403 mpFieldAtom2->SetValue(mpMolBondAngle->GetAtom2().GetName());
404 mpSizer->Add(mpFieldAtom2,0,wxALIGN_CENTER);
405 mList.Add(mpFieldAtom2);
407 mpFieldAtom3=new
WXFieldChoice(this,ID_MOLBONDANGLE_ATOM3,"-",60);
408 mpFieldAtom3->SetValue(mpMolBondAngle->GetAtom3().GetName());
409 mpSizer->Add(mpFieldAtom3,0,wxALIGN_CENTER);
410 mList.Add(mpFieldAtom3);
413 new
WXFieldPar<REAL>(this,"Angle=",-1,&mValue);
414 value->SetHumanValueScale(RAD2DEG);
415 mpSizer->Add(value,0,wxALIGN_CENTER);
420 angle->SetHumanValueScale(RAD2DEG);
421 mpSizer->Add(angle,0,wxALIGN_CENTER);
426 delta->SetHumanValueScale(RAD2DEG);
427 mpSizer->Add(delta,0,wxALIGN_CENTER);
432 sigma->SetHumanValueScale(RAD2DEG);
433 mpSizer->Add(sigma,0,wxALIGN_CENTER);
436 this->SetSizer(mpSizer);
438 this->CrystUpdate(true,true);
444 mpMolBondAngle->WXNotifyDelete();
447 void WXMolBondAngle::CrystUpdate(
const bool uui,
const bool lock)
449 VFN_DEBUG_ENTRY(
"WXMolBondAngle::CrystUpdate()",5)
450 if(lock) mMutex.Lock();
451 mValue=mpMolBondAngle->GetAngle();
452 mList.CrystUpdate(uui,
false);
453 if(lock) mMutex.Unlock();
454 VFN_DEBUG_EXIT(
"WXMolBondAngle::CrystUpdate()",5)
457 void WXMolBondAngle::UpdateUI(
const bool lock)
459 VFN_DEBUG_ENTRY(
"WXMolBondAngle::UpdateUI()",5)
460 if(lock) mMutex.Lock();
461 mList.UpdateUI(
false);
462 mpFieldAtom1->SetValue(mpMolBondAngle->GetAtom1().GetName().c_str());
463 mpFieldAtom2->SetValue(mpMolBondAngle->GetAtom2().GetName().c_str());
464 mpFieldAtom3->SetValue(mpMolBondAngle->GetAtom3().GetName().c_str());
465 if(lock) mMutex.Unlock();
466 VFN_DEBUG_EXIT(
"WXMolBondAngle::UpdateUI()",5)
469 void WXMolBondAngle::OnChangeAtom(wxCommandEvent &event)
471 VFN_DEBUG_ENTRY(
"WXMolBondAngle::OnChangeAtom()",6)
472 WXCrystValidateAllUserInput();
474 MolAtom *const at=WXDialogChooseFromVector(mpMolBondAngle->GetMolecule().GetAtomList(),
475 (wxWindow*)this,"Choose a new
Atom",choice);
477 if((
long)ID_MOLBONDANGLE_ATOM1==event.GetId())
479 if((at==&(mpMolBondAngle->GetAtom2()) )||(at==&(mpMolBondAngle->GetAtom3())) )
481 wxMessageDialog dumbUser(
this,_T(
"The three atoms must be different !"),
482 _T(
"Whooops"),wxOK|wxICON_EXCLAMATION);
483 dumbUser.ShowModal();
486 mpMolBondAngle->SetAtom1(*at);
488 if((
long)ID_MOLBONDANGLE_ATOM2==event.GetId())
490 if((at==&(mpMolBondAngle->GetAtom1()) )||(at==&(mpMolBondAngle->GetAtom3())) )
492 wxMessageDialog dumbUser(
this,_T(
"The three atoms must be different !"),
493 _T(
"Whooops"),wxOK|wxICON_EXCLAMATION);
494 dumbUser.ShowModal();
497 mpMolBondAngle->SetAtom2(*at);
499 if((
long)ID_MOLBONDANGLE_ATOM3==event.GetId())
501 if((at==&(mpMolBondAngle->GetAtom1()) )||(at==&(mpMolBondAngle->GetAtom2())) )
503 wxMessageDialog dumbUser(
this,_T(
"The three atoms must be different !"),
504 _T(
"Whooops"),wxOK|wxICON_EXCLAMATION);
505 dumbUser.ShowModal();
508 mpMolBondAngle->SetAtom3(*at);
511 this->CrystUpdate(
true);
512 this->UpdateUI(
true);
513 VFN_DEBUG_EXIT(
"WXMolBondAngle::OnChangeScattPow()",6)
520 WXCRYST_ID ID_MOLDIHEDRALANGLE_ATOM1;
521 WXCRYST_ID ID_MOLDIHEDRALANGLE_ATOM2;
522 WXCRYST_ID ID_MOLDIHEDRALANGLE_ATOM3;
523 WXCRYST_ID ID_MOLDIHEDRALANGLE_ATOM4;
525 BEGIN_EVENT_TABLE(WXMolDihedralAngle,wxWindow)
526 EVT_BUTTON(ID_MOLDIHEDRALANGLE_ATOM1, WXMolDihedralAngle::OnChangeAtom)
527 EVT_BUTTON(ID_MOLDIHEDRALANGLE_ATOM2, WXMolDihedralAngle::OnChangeAtom)
528 EVT_BUTTON(ID_MOLDIHEDRALANGLE_ATOM3, WXMolDihedralAngle::OnChangeAtom)
529 EVT_BUTTON(ID_MOLDIHEDRALANGLE_ATOM4, WXMolDihedralAngle::OnChangeAtom)
532 WXMolDihedralAngle::WXMolDihedralAngle(wxWindow *parent, MolDihedralAngle*obj):
533 WXCrystObjBasic(parent),mpMolDihedralAngle(obj)
535 VFN_DEBUG_ENTRY(
"WXMolDihedralAngle::WXMolBond()",6)
536 mpSizer=new wxBoxSizer(wxHORIZONTAL);
538 mpFieldAtom1=new WXFieldChoice(this,ID_MOLDIHEDRALANGLE_ATOM1,"Dihedral Angle:",60);
539 mpFieldAtom1->SetValue(mpMolDihedralAngle->GetAtom1().GetName());
540 mpSizer->Add(mpFieldAtom1,0,wxALIGN_CENTER);
541 mList.Add(mpFieldAtom1);
543 mpFieldAtom2=new WXFieldChoice(this,ID_MOLDIHEDRALANGLE_ATOM2,"-",60);
544 mpFieldAtom2->SetValue(mpMolDihedralAngle->GetAtom2().GetName());
545 mpSizer->Add(mpFieldAtom2,0,wxALIGN_CENTER);
546 mList.Add(mpFieldAtom2);
548 mpFieldAtom3=new WXFieldChoice(this,ID_MOLDIHEDRALANGLE_ATOM3,"-",60);
549 mpFieldAtom3->SetValue(mpMolDihedralAngle->GetAtom3().GetName());
550 mpSizer->Add(mpFieldAtom3,0,wxALIGN_CENTER);
551 mList.Add(mpFieldAtom3);
553 mpFieldAtom4=new WXFieldChoice(this,ID_MOLDIHEDRALANGLE_ATOM4,"-",60);
554 mpFieldAtom4->SetValue(mpMolDihedralAngle->GetAtom4().GetName());
555 mpSizer->Add(mpFieldAtom4,0,wxALIGN_CENTER);
556 mList.Add(mpFieldAtom4);
558 WXFieldPar<REAL> *value=
559 new WXFieldPar<REAL>(this,"Angle=",-1,&mValue);
560 value->SetHumanValueScale(RAD2DEG);
561 mpSizer->Add(value,0,wxALIGN_CENTER);
564 WXFieldPar<REAL> *angle=
565 new WXFieldPar<REAL>(this,"Restraint:",-1,&(mpMolDihedralAngle->Angle0()));
566 angle->SetHumanValueScale(RAD2DEG);
567 mpSizer->Add(angle,0,wxALIGN_CENTER);
570 WXFieldPar<REAL> *delta=
571 new WXFieldPar<REAL>(this,",delta=",-1,&(mpMolDihedralAngle->AngleDelta()));
572 delta->SetHumanValueScale(RAD2DEG);
573 mpSizer->Add(delta,0,wxALIGN_CENTER);
576 WXFieldPar<REAL> *sigma=
577 new WXFieldPar<REAL>(this,",sigma=",-1,&(mpMolDihedralAngle->AngleSigma()));
578 sigma->SetHumanValueScale(RAD2DEG);
579 mpSizer->Add(sigma,0,wxALIGN_CENTER);
582 this->SetSizer(mpSizer);
584 this->CrystUpdate(true);
585 VFN_DEBUG_EXIT("WXMolDihedralAngle::WXMolBond():"<<obj->GetName(),6)
588 WXMolDihedralAngle::~WXMolDihedralAngle()
590 mpMolDihedralAngle->WXNotifyDelete();
593 void WXMolDihedralAngle::CrystUpdate(
const bool uui,
const bool lock)
595 VFN_DEBUG_ENTRY(
"WXMolDihedralAngle::CrystUpdate()",5)
596 if(lock) mMutex.Lock();
597 mValue=mpMolDihedralAngle->GetAngle();
598 mList.CrystUpdate(uui,
false);
599 if(lock) mMutex.Unlock();
600 VFN_DEBUG_EXIT(
"WXMolDihedralAngle::CrystUpdate()",5)
603 void WXMolDihedralAngle::UpdateUI(
const bool lock)
605 VFN_DEBUG_ENTRY(
"WXMolDihedralAngle::UpdateUI()",5)
606 if(lock) mMutex.Lock();
607 mList.UpdateUI(
false);
608 mpFieldAtom1->SetValue(mpMolDihedralAngle->GetAtom1().GetName().c_str());
609 mpFieldAtom2->SetValue(mpMolDihedralAngle->GetAtom2().GetName().c_str());
610 mpFieldAtom3->SetValue(mpMolDihedralAngle->GetAtom3().GetName().c_str());
611 if(lock) mMutex.Unlock();
612 VFN_DEBUG_EXIT(
"WXMolDihedralAngle::UpdateUI()",5)
615 void WXMolDihedralAngle::OnChangeAtom(wxCommandEvent &event)
617 VFN_DEBUG_ENTRY(
"WXMolDihedralAngle::OnChangeAtom()",6)
618 WXCrystValidateAllUserInput();
620 MolAtom *const at=WXDialogChooseFromVector(mpMolDihedralAngle->GetMolecule().GetAtomList(),
621 (wxWindow*)this,"Choose a new
Atom",choice);
623 if((
long)ID_MOLDIHEDRALANGLE_ATOM1==event.GetId())
625 if( (at==&(mpMolDihedralAngle->GetAtom2()))
626 ||(at==&(mpMolDihedralAngle->GetAtom3()))
627 ||(at==&(mpMolDihedralAngle->GetAtom4())) )
629 wxMessageDialog dumbUser(
this,_T(
"The four atoms must be different !"),
630 _T(
"Whooops"),wxOK|wxICON_EXCLAMATION);
631 dumbUser.ShowModal();
634 mpMolDihedralAngle->SetAtom1(*at);
636 if((
long)ID_MOLDIHEDRALANGLE_ATOM2==event.GetId())
638 if( (at==&(mpMolDihedralAngle->GetAtom1()))
639 ||(at==&(mpMolDihedralAngle->GetAtom3()))
640 ||(at==&(mpMolDihedralAngle->GetAtom4())) )
642 wxMessageDialog dumbUser(
this,_T(
"The four atoms must be different !"),
643 _T(
"Whooops"),wxOK|wxICON_EXCLAMATION);
644 dumbUser.ShowModal();
647 mpMolDihedralAngle->SetAtom2(*at);
649 if((
long)ID_MOLDIHEDRALANGLE_ATOM3==event.GetId())
651 if( (at==&(mpMolDihedralAngle->GetAtom1()))
652 ||(at==&(mpMolDihedralAngle->GetAtom2()))
653 ||(at==&(mpMolDihedralAngle->GetAtom4())) )
655 wxMessageDialog dumbUser(
this,_T(
"The four atoms must be different !"),
656 _T(
"Whooops"),wxOK|wxICON_EXCLAMATION);
657 dumbUser.ShowModal();
660 mpMolDihedralAngle->SetAtom3(*at);
662 if((
long)ID_MOLDIHEDRALANGLE_ATOM4==event.GetId())
664 if( (at==&(mpMolDihedralAngle->GetAtom1()))
665 ||(at==&(mpMolDihedralAngle->GetAtom2()))
666 ||(at==&(mpMolDihedralAngle->GetAtom3())) )
668 wxMessageDialog dumbUser(
this,_T(
"The four atoms must be different !"),
669 _T(
"Whooops"),wxOK|wxICON_EXCLAMATION);
670 dumbUser.ShowModal();
673 mpMolDihedralAngle->SetAtom4(*at);
676 this->CrystUpdate(
true);
677 this->UpdateUI(
true);
678 VFN_DEBUG_EXIT(
"WXMolDihedralAngle::OnChangeScattPow()",6)
686 WXMolecule::CellAtom::CellAtom():
687 mpAtom(0),mName(
""),mpScatteringPower(0),mX(0),mY(0),mZ(0),mNeedUpdateUI(true)
690 WXMolecule::CellBond::CellBond():
691 mpBond(0),mAtom1(
""),mAtom2(
""),
692 mLength(0),mLength0(0),mSigma(0),mDelta(0),mNeedUpdateUI(true)
695 WXMolecule::CellBondAngle::CellBondAngle():
696 mpBondAngle(0),mAtom1(
""),mAtom2(
""),mAtom3(
""),
697 mAngle(0),mAngle0(0),mSigma(0),mDelta(0),mNeedUpdateUI(true)
700 WXMolecule::CellDihedralAngle::CellDihedralAngle():
701 mpDihedralAngle(0),mAtom1(
""),mAtom2(
""),mAtom3(
""),mAtom4(
""),
702 mAngle(0),mAngle0(0),mSigma(0),mDelta(0),mNeedUpdateUI(true)
705 WXMolecule::CellRigidGroup::CellRigidGroup():
706 mpGroup(0),mNeedUpdateUI(false)
716 WXCRYST_ID ID_MENU_OPTIMIZECONFORMATION;
717 WXCRYST_ID ID_MENU_SETLIMITS;
718 WXCRYST_ID ID_MOLECULE_MENU_FILE;
719 WXCRYST_ID ID_MOLECULE_MENU_FILE_2ZMATRIX;
720 WXCRYST_ID ID_MOLECULE_MENU_FILE_2ZMATRIXNAMED;
721 WXCRYST_ID ID_MOLECULE_MENU_PAR_MDTEST;
722 WXCRYST_ID ID_MOLECULE_MENU_FORMULA;
723 WXCRYST_ID ID_MOLECULE_MENU_FORMULA_OPTIMIZECONFORMATION;
724 WXCRYST_ID ID_MOLECULE_MENU_FORMULA_STATUS;
725 WXCRYST_ID ID_MOLECULE_MENU_EXPORT_RESTRAINTS;
726 WXCRYST_ID ID_MOLECULE_MENU_FORMULA_ADD_ATOM;
727 WXCRYST_ID ID_MOLECULE_MENU_FORMULA_ADD_BOND;
728 WXCRYST_ID ID_MOLECULE_MENU_FORMULA_ADD_ANGLE;
729 WXCRYST_ID ID_MOLECULE_MENU_FORMULA_ADD_DIHEDRAL;
730 WXCRYST_ID ID_MOLECULE_MENU_FORMULA_ADD_RIGID_GROUP;
731 WXCRYST_ID ID_MOLECULE_MENU_FORMULA_ADD_NONFLIP_ATOM;
732 WXCRYST_ID ID_MOLECULE_MENU_FORMULA_RIGIDIFY_WITH_DIHEDRALANGLES;
733 WXCRYST_ID ID_MOLECULE_MENU_FORMULA_TEST;
734 WXCRYST_ID ID_MOLECULE_MENU_FORMULA_REMOVE_ATOM;
735 WXCRYST_ID ID_MOLECULE_MENU_FORMULA_REMOVE_BOND;
736 WXCRYST_ID ID_MOLECULE_MENU_FORMULA_REMOVE_ANGLE;
737 WXCRYST_ID ID_MOLECULE_MENU_FORMULA_REMOVE_DIHEDRAL;
738 WXCRYST_ID ID_MOLECULE_MENU_FORMULA_REMOVE_RIGID_GROUP;
739 WXCRYST_ID ID_MOLECULE_MENU_FORMULA_REMOVE_NONFLIPATOM;
740 WXCRYST_ID ID_MOLECULE_MENU_FORMULA_SHOW_RESTRAINT;
741 WXCRYST_ID ID_MOLECULE_MENU_FORMULA_SET_DELTA_SIGMA;
742 WXCRYST_ID ID_MOLECULE_MENU_GEOMETRY;
743 WXCRYST_ID ID_MOLECULE_MENU_GEOMETRY_ROTATE_BOND;
744 WXCRYST_ID ID_MOLECULE_MENU_GEOMETRY_ROTATE_DIHED;
746 WXCRYST_ID ID_MOLECULE_CHANGE_CENTER_ATOM;
749 WXCRYST_ID ID_WINDOW_ATOM;
750 WXCRYST_ID ID_WINDOW_BONDLENGTH;
751 WXCRYST_ID ID_WINDOW_BONDANGLE;
752 WXCRYST_ID ID_WINDOW_DIHEDRALANGLE;
753 WXCRYST_ID ID_WINDOW_RIGIDGROUP;
754 WXCRYST_ID ID_WINDOW_NONFLIPATOM;
756 BEGIN_EVENT_TABLE(WXMolecule,wxWindow)
758 EVT_MENU(ID_REFOBJ_MENU_PAR_FIXALL, WXRefinableObj::OnMenuFixAllPar)
759 EVT_MENU(ID_REFOBJ_MENU_PAR_UNFIXALL, WXRefinableObj::OnMenuUnFixAllPar)
760 EVT_MENU(ID_REFOBJ_MENU_PAR_RANDOMIZE, WXRefinableObj::OnMenuParRandomize)
761 EVT_MENU(ID_MOLECULE_MENU_PAR_MDTEST, WXMolecule::OnMenuMDTest)
762 EVT_MENU(ID_MOLECULE_MENU_FORMULA_OPTIMIZECONFORMATION,WXMolecule::OnMenuOptimizeConformation)
763 EVT_MENU(ID_MOLECULE_MENU_FORMULA_STATUS, WXMolecule::OnMenuPrintRestraintStatus)
764 EVT_MENU(ID_MOLECULE_MENU_EXPORT_RESTRAINTS, WXMolecule::OnMenuExportRestraints)
765 EVT_MENU(ID_MOLECULE_MENU_FORMULA_ADD_ATOM, WXMolecule::OnMenuAddAtom)
766 EVT_MENU(ID_MOLECULE_MENU_FORMULA_ADD_BOND, WXMolecule::OnMenuAddBond)
767 EVT_MENU(ID_MOLECULE_MENU_FORMULA_ADD_ANGLE, WXMolecule::OnMenuAddAngle)
768 EVT_MENU(ID_MOLECULE_MENU_FORMULA_ADD_DIHEDRAL, WXMolecule::OnMenuAddDihedralAngle)
769 EVT_MENU(ID_MOLECULE_MENU_FORMULA_ADD_RIGID_GROUP, WXMolecule::OnMenuAddRigidGroup)
770 EVT_MENU(ID_MOLECULE_MENU_FORMULA_ADD_NONFLIP_ATOM, WXMolecule::OnMenuAddNonFlipAtom)
771 EVT_MENU(ID_MOLECULE_MENU_FORMULA_RIGIDIFY_WITH_DIHEDRALANGLES,WXMolecule::OnMenuRigidfyWithDihedralAngles)
772 EVT_MENU(ID_MOLECULE_MENU_FORMULA_REMOVE_ATOM, WXMolecule::OnMenuRemoveAtom)
773 EVT_MENU(ID_MOLECULE_MENU_FORMULA_REMOVE_BOND, WXMolecule::OnMenuRemoveBond)
774 EVT_MENU(ID_MOLECULE_MENU_FORMULA_REMOVE_ANGLE, WXMolecule::OnMenuRemoveAngle)
775 EVT_MENU(ID_MOLECULE_MENU_FORMULA_REMOVE_DIHEDRAL, WXMolecule::OnMenuRemoveDihedralAngle)
776 EVT_MENU(ID_MOLECULE_MENU_FORMULA_REMOVE_RIGID_GROUP, WXMolecule::OnMenuRemoveRigidGroup)
777 EVT_MENU(ID_MOLECULE_MENU_FORMULA_REMOVE_NONFLIPATOM, WXMolecule::OnMenuRemoveNonFlipAtom)
778 EVT_MENU(ID_MOLECULE_MENU_FORMULA_TEST , WXMolecule::OnMenuTest)
779 EVT_MENU(ID_MENU_SETLIMITS, WXMolecule::OnMenuSetLimits)
780 EVT_MENU(ID_MOLECULE_MENU_FORMULA_SHOW_RESTRAINT, WXMolecule::OnMenuShowRestraintWindow)
781 EVT_MENU(ID_MOLECULE_MENU_FORMULA_SET_DELTA_SIGMA ,WXMolecule::OnMenuSetDeltaSigma)
782 EVT_MENU(ID_MOLECULE_MENU_FILE_2ZMATRIX, WXMolecule::OnMenuExport2ZMatrix)
783 EVT_MENU(ID_MOLECULE_MENU_FILE_2ZMATRIXNAMED, WXMolecule::OnMenuExport2ZMatrix)
784 EVT_MENU(ID_MOLECULE_MENU_GEOMETRY_ROTATE_BOND, WXMolecule::OnMenuRotate)
785 EVT_MENU(ID_MOLECULE_MENU_GEOMETRY_ROTATE_DIHED, WXMolecule::OnMenuRotate)
786 EVT_GRID_CMD_CELL_CHANGED(ID_WINDOW_ATOM, WXMolecule::OnEditGridAtom)
787 EVT_GRID_CMD_CELL_CHANGED(ID_WINDOW_BONDLENGTH, WXMolecule::OnEditGridBondLength)
788 EVT_GRID_CMD_CELL_CHANGED(ID_WINDOW_BONDANGLE, WXMolecule::OnEditGridBondAngle)
789 EVT_GRID_CMD_CELL_CHANGED(ID_WINDOW_DIHEDRALANGLE, WXMolecule::OnEditGridDihedralAngle)
790 EVT_GRID_CMD_CELL_CHANGED(ID_WINDOW_RIGIDGROUP, WXMolecule::OnEditGridRigidGroup)
791 EVT_BUTTON(ID_MOLECULE_CHANGE_CENTER_ATOM, WXMolecule::OnChangeCenterAtom)
794 WXMolecule::WXMolecule(wxWindow *parent, Molecule *mol):
795 WXScatterer(parent,mol),mpMolecule(mol),
796 mpBondWin(0),mpAngleWin(0),mpDihedralAngleWin(0),mpRigidGroupWin(0),mpNonFlipAtomWin(0),mIsSelfUpdating(false)
798 VFN_DEBUG_ENTRY(
"WXMolecule::WXMolecule():"<<mol->GetName(),6)
800 mpMenuBar->AddMenu("File",ID_MOLECULE_MENU_FILE);
801 mpMenuBar->AddMenuItem(ID_MOLECULE_MENU_FILE,ID_MOLECULE_MENU_FILE_2ZMATRIX,"Export to Fenske-Hall Z-Matrix");
802 mpMenuBar->AddMenuItem(ID_MOLECULE_MENU_FILE,ID_MOLECULE_MENU_FILE_2ZMATRIXNAMED,"Export to Z-Matrix with atom names");
803 mpMenuBar->AddMenu("Parameters",ID_REFOBJ_MENU_PAR);
804 mpMenuBar->AddMenuItem(ID_REFOBJ_MENU_PAR,ID_REFOBJ_MENU_PAR_FIXALL,"Fix all");
805 mpMenuBar->AddMenuItem(ID_REFOBJ_MENU_PAR,ID_REFOBJ_MENU_PAR_UNFIXALL,"Unfix all");
806 mpMenuBar->AddMenuItem(ID_REFOBJ_MENU_PAR,ID_REFOBJ_MENU_PAR_RANDOMIZE,
807 "Randomize Configuration");
808 mpMenuBar->AddMenuItem(ID_REFOBJ_MENU_PAR,ID_MOLECULE_MENU_PAR_MDTEST,
809 "Test Molecular Dynamics moves for 30s");
810 mpMenuBar->AddMenu("Formula && Restraints",ID_MOLECULE_MENU_FORMULA);
811 mpMenuBar->AddMenuItem(ID_MOLECULE_MENU_FORMULA,ID_MOLECULE_MENU_FORMULA_OPTIMIZECONFORMATION,
812 "Optimize Starting Conformation");
813 mpMenuBar->AddMenuItem(ID_MOLECULE_MENU_FORMULA,ID_MOLECULE_MENU_FORMULA_SET_DELTA_SIGMA,
814 "Set Restraints delta && sigma for all bonds && angles");
815 mpMenuBar->AddMenuItem(ID_MOLECULE_MENU_FORMULA,ID_MOLECULE_MENU_FORMULA_STATUS,
816 "Print Detailed Restraint Values");
817 mpMenuBar->AddMenuItem(ID_MOLECULE_MENU_FORMULA,ID_MOLECULE_MENU_EXPORT_RESTRAINTS,
818 "Export Restraints in CVS File format");
819 mpMenuBar->GetMenu(ID_MOLECULE_MENU_FORMULA).AppendSeparator();
820 mpMenuBar->AddMenuItem(ID_MOLECULE_MENU_FORMULA,ID_MOLECULE_MENU_FORMULA_ADD_ATOM,
822 mpMenuBar->AddMenuItem(ID_MOLECULE_MENU_FORMULA,ID_MOLECULE_MENU_FORMULA_ADD_BOND,
823 "Add Bond Restraint");
824 mpMenuBar->AddMenuItem(ID_MOLECULE_MENU_FORMULA,ID_MOLECULE_MENU_FORMULA_ADD_ANGLE,
825 "Add Bond Angle Restraint");
826 mpMenuBar->AddMenuItem(ID_MOLECULE_MENU_FORMULA,ID_MOLECULE_MENU_FORMULA_ADD_DIHEDRAL,
827 "Add Dihedral Angle Restraint");
828 mpMenuBar->AddMenuItem(ID_MOLECULE_MENU_FORMULA,ID_MOLECULE_MENU_FORMULA_ADD_RIGID_GROUP,
830 mpMenuBar->AddMenuItem(ID_MOLECULE_MENU_FORMULA,ID_MOLECULE_MENU_FORMULA_ADD_NONFLIP_ATOM,
831 "Add Non-Flip (optically active) Atom");
832 mpMenuBar->AddMenuItem(ID_MOLECULE_MENU_FORMULA,ID_MOLECULE_MENU_FORMULA_RIGIDIFY_WITH_DIHEDRALANGLES,
833 "Rigidify with Dihedral Angles");
834 mpMenuBar->GetMenu(ID_MOLECULE_MENU_FORMULA).AppendSeparator();
835 mpMenuBar->AddMenuItem(ID_MOLECULE_MENU_FORMULA,ID_MOLECULE_MENU_FORMULA_REMOVE_ATOM,
837 mpMenuBar->AddMenuItem(ID_MOLECULE_MENU_FORMULA,ID_MOLECULE_MENU_FORMULA_REMOVE_BOND,
838 "Remove a Bond Restraint");
839 mpMenuBar->AddMenuItem(ID_MOLECULE_MENU_FORMULA,ID_MOLECULE_MENU_FORMULA_REMOVE_ANGLE,
840 "Remove a Bond Angle Restraint");
841 mpMenuBar->AddMenuItem(ID_MOLECULE_MENU_FORMULA,ID_MOLECULE_MENU_FORMULA_REMOVE_DIHEDRAL,
842 "Remove a Dihedral Angle Restraint");
843 mpMenuBar->AddMenuItem(ID_MOLECULE_MENU_FORMULA,ID_MOLECULE_MENU_FORMULA_REMOVE_RIGID_GROUP,
844 "Remove Rigid Group");
845 mpMenuBar->AddMenuItem(ID_MOLECULE_MENU_FORMULA,ID_MOLECULE_MENU_FORMULA_REMOVE_NONFLIPATOM,
846 "Remove Non-Flip (optically active) Atom");
848 mpMenuBar->GetMenu(ID_MOLECULE_MENU_FORMULA).AppendSeparator();
849 mpMenuBar->AddMenuItem(ID_MOLECULE_MENU_FORMULA,ID_MOLECULE_MENU_FORMULA_SHOW_RESTRAINT,
850 "Show Restraint Window");
852 mpMenuBar->AddMenuItem(ID_MOLECULE_MENU_FORMULA,ID_MOLECULE_MENU_FORMULA_TEST,"Debug Test");
854 mpMenuBar->AddMenu("Manipulate Geometry",ID_MOLECULE_MENU_GEOMETRY);
855 mpMenuBar->AddMenuItem(ID_MOLECULE_MENU_GEOMETRY,ID_MOLECULE_MENU_GEOMETRY_ROTATE_BOND,
856 "Rotate around bond");
857 mpMenuBar->AddMenuItem(ID_MOLECULE_MENU_GEOMETRY,ID_MOLECULE_MENU_GEOMETRY_ROTATE_DIHED,
858 "Set dihedral angle");
862 WXFieldPar<REAL> *pLLKScale= new WXFieldPar<REAL>(this,"Log(likelihood) scale",-1,&(mpMolecule->mLogLikelihoodScale));
863 mList.Add(pLLKScale);
864 mpSizer->Add(pLLKScale,0,wxALIGN_LEFT);
865 pLLKScale->SetToolTip(_T("The log(likelihood) of the molecule, i.e. the sum\n")
866 _T("of the restraints costs for all bonds and angles \n")
867 _T("are multiplied by this scale.\n\n")
868 _T("The default value is 1.\n\n")
869 _T("Multiplying this value by 4 is equivalent to dividing the\n")
870 _T("sigma of all bonds and angles by a factor 2.\n")
871 _T("This can be increased if the molecule presents too\n")
872 _T("much distortion.\n\n")
873 _T("Note that a too large value (e.g.>100) will decrease the\n")
874 _T("convergence speed of the algorithm, as distortion of the\n")
875 _T("structure is necessary for an efficient minimisation."));
878 wxBoxSizer* pMDSizer=new wxBoxSizer(wxHORIZONTAL);
879 WXFieldPar<REAL> *pWXFieldMDEnergy=
880 new WXFieldPar<REAL>(this,"MD moves Energy",-1,&(mpMolecule->mMDMoveEnergy));
881 WXFieldPar<REAL> *pWXFieldMDFrequency=
882 new WXFieldPar<REAL>(this,"MD moves frequency",-1,&(mpMolecule->mMDMoveFreq));
883 pMDSizer->Add(pWXFieldMDFrequency);
884 pMDSizer->Add(pWXFieldMDEnergy);
885 mpSizer->Add(pMDSizer,0,wxALIGN_LEFT);
886 mList.Add(pWXFieldMDEnergy);
887 mList.Add(pWXFieldMDFrequency);
889 pWXFieldMDFrequency->SetToolTip(_T("Frequency of Molecular Dynamics Moves (0.0-1.0)\n\n")
890 _T("MD moves are used to alter the conformation of atom groups \n")
891 _T("which cannot be changed by simple bond distance\n")
892 _T("or bond angle changes.\n\n")
893 _T("MD moves are CPU intensive, so a slow value (0.05) is recommended\n")
894 _T("Larger frequencies can be used for constrained molecules,\n")
895 _T("e.g. with large, flexible cycles."));
896 pWXFieldMDEnergy->SetToolTip(_T("Energy of Molecule for Molecular Dynamics Moves\n\n")
897 _T("Standard amplitude=40. \n")
898 _T("Small amplitude=10. (small distortion of the Molecule)\n")
899 _T("Large amplitude=400. (large distortion of the Molecule)"));
901 mpFieldCenterAtom=new WXFieldChoice(this,ID_MOLECULE_CHANGE_CENTER_ATOM,"Center Atom:",240);
902 if(mpMolecule->GetCenterAtom()!=0)
903 mpFieldCenterAtom->SetValue(mpMolecule->GetCenterAtom()->GetName());
904 else mpFieldCenterAtom->SetValue("Click to choose an atom !");
905 mpSizer->Add(mpFieldCenterAtom,0,wxALIGN_LEFT);
906 mList.Add(mpFieldCenterAtom);
908 wxGridCellAttr* cellAttrName = new wxGridCellAttr;
909 cellAttrName->SetRenderer(new wxGridCellStringRenderer);
910 cellAttrName->SetEditor(new wxGridCellTextEditor);
911 wxGridCellAttr* cellAttrFloat = new wxGridCellAttr;
912 cellAttrFloat->SetRenderer(new wxGridCellFloatRenderer(6,3));
913 cellAttrFloat->SetEditor(new wxGridCellFloatEditor(6,3));
915 mpAtomWin= new WXMolScrolledWindow(this,this,ID_WINDOW_ATOM);
917 mpAtomWin->EnableScrolling(true,true);
919 mpAtomWin->CreateGrid(0,6);
920 mpAtomWin->SetRowLabelSize(40);
921 mpAtomWin->SetDefaultColSize(60);
922 mpAtomWin->SetColAttr(0,cellAttrName);
923 mpAtomWin->SetColAttr(1,cellAttrName->Clone());
924 mpAtomWin->SetColAttr(2,cellAttrFloat);
925 mpAtomWin->SetColAttr(3,cellAttrFloat->Clone());
926 mpAtomWin->SetColAttr(4,cellAttrFloat->Clone());
927 mpAtomWin->SetColAttr(5,cellAttrFloat->Clone());
928 mpAtomWin->SetColLabelValue(0,_T("Name"));
929 mpAtomWin->SetColLabelValue(1,_T("Type"));
930 mpAtomWin->SetColLabelValue(2,_T("X"));
931 mpAtomWin->SetColLabelValue(3,_T("Y"));
932 mpAtomWin->SetColLabelValue(4,_T("Z"));
933 mpAtomWin->SetColLabelValue(5,_T("Occup"));
934 mpAtomWin->AutoSizeRows();
935 mpSizer->Add(mpAtomWin,0,wxALIGN_LEFT);
936 this->CrystUpdate(true);
937 VFN_DEBUG_EXIT("WXMolecule::WXMolecule():"<<mol->GetName(),6)
940 WXMolecule::~WXMolecule()
942 VFN_DEBUG_ENTRY(
"WXMolecule::~WXMolecule()",10)
943 if(0!=mpBondWin) mpBondWin->GetParent()->Destroy();
944 VFN_DEBUG_EXIT("WXMolecule::~WXMolecule()",10)
947 void WXMolecule::OnMenuOptimizeConformation(wxCommandEvent & WXUNUSED(event))
949 VFN_DEBUG_ENTRY(
"WXMolecule::OnMenuOptimizeConformation()",5)
951 mpMolecule->OptimizeConformation(20000,mpMolecule->GetAtomList().size());
952 mpMolecule->OptimizeConformationSteepestDescent(0.01,100);
953 mpMolecule->RestraintStatus(cout);
956 lsq.SetRefinedObj(*mpMolecule);
957 lsq.PrepareRefParList(true);
959 lsq.SetParIsUsed(gpRefParTypeScattConform,true);
960 try {lsq.Refine(10,
true,
false);}
961 catch(
const ObjCrystException &except){}
962 mpMolecule->GetCrystal().UpdateDisplay();
963 mpMolecule->RestraintStatus(cout);
965 mpMolecule->GetCrystal().UpdateDisplay();
967 VFN_DEBUG_EXIT(
"WXMolecule::OnMenuOptimizeConformation()",5)
969 void WXMolecule::OnMenuExportRestraints(wxCommandEvent & WXUNUSED(event))
971 VFN_DEBUG_ENTRY(
"WXMolecule::OnMenuExportRestraints()",5)
975 mpMolecule->RestraintExport(ss);
977 wxFileDialog open(this,_T("Choose File to save restraints:"),
978 _T(""),_T(""),_T("*.csv"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
979 if(open.ShowModal() != wxID_OK) return;
980 wxString name=open.GetPath();
981 if(name.substr(name.size()-4,4)!=_T(".csv"))
983 cout<<name<<
" -> "<<name+_T(
".csv")<<endl;
984 name=name+_T(
".csv");
987 wxFileOutputStream ostream(name.c_str());
988 ostream.Write(ss.str().c_str(),ss.str().size());
990 VFN_DEBUG_EXIT(
"WXMolecule::OnMenuExportRestraints()",5)
992 void WXMolecule::OnMenuPrintRestraintStatus(wxCommandEvent & WXUNUSED(event))
994 VFN_DEBUG_ENTRY(
"WXMolecule::OnMenuPrintRestraintStatus()",5)
996 mpMolecule->RestraintStatus(cout);
997 VFN_DEBUG_EXIT("WXMolecule::OnMenuPrintRestraintStatus()",5)
1000 void WXMolecule::OnMenuAddAtom(wxCommandEvent & WXUNUSED(event))
1002 VFN_DEBUG_ENTRY(
"WXMolecule::OnMenuAddAtom()",6)
1006 mpMolecule->GetCrystal().GetScatteringPowerRegistry(),
1007 (wxWindow*)this,"Choose a new Scattering Power",choice);
1008 if(0==scatt) return;
1009 long num=mpMolecule->GetAtomList().size();
1012 wxString lastAtom=wxString::FromAscii(mpMolecule->GetAtom(num-1).GetName().c_str());
1015 if(lastAtom.size()==0)
break;
1016 if(lastAtom.IsNumber())
1018 lastAtom.ToLong(&num);
1021 lastAtom.erase(0,1);
1026 mpMolecule->AddAtom(0.,0.,0.,scatt,scatt->GetName()+st.str());
1027 VFN_DEBUG_EXIT(
"WXMolecule::OnMenuAddAtom()",6)
1030 void WXMolecule::OnMenuAddBond(wxCommandEvent & WXUNUSED(event))
1032 VFN_DEBUG_ENTRY(
"WXMolecule::OnMenuAddBond()",6)
1035 vector<MolAtom*> v=mpMolecule->GetAtomList();
1036 MolAtom *at1=WXDialogChooseFromVector(v,
1037 (wxWindow*)this,"Choose the first Atom",choice);
1039 MolAtom *at2=WXDialogChooseFromVector(v,
1040 (wxWindow*)this,"Choose the second Atom",choice);
1045 wxMessageDialog dumbUser(
this,_T(
"The two atoms must be different !"),
1046 _T(
"Whooops"),wxOK|wxICON_EXCLAMATION);
1047 dumbUser.ShowModal();
1050 static double d=1.5;
1052 s.Printf(_T(
"%6.3f"),d);
1055 string mes=
"Enter bond distance (Angstroems) for "+at1->GetName()+
"-"+at2->GetName();
1056 wxTextEntryDialog dialog(
this,wxString::FromAscii(mes.c_str()),
1057 _T(
"Bond distance"),s,wxOK | wxCANCEL);
1058 dialog.SetTextValidator(wxTextValidator(wxFILTER_NUMERIC));
1059 if(wxID_OK!=dialog.ShowModal())
1061 VFN_DEBUG_EXIT(
"WXMolecule::OnMenuAddBond():Canceled",6)
1064 dialog.GetValue().ToDouble(&d);
1066 mpMolecule->AddBond(*at1,*at2,d,.01,.02,1.);
1067 VFN_DEBUG_EXIT("WXMolecule::OnMenuAddBond()",6)
1070 void WXMolecule::OnMenuAddAngle(wxCommandEvent & WXUNUSED(event))
1072 VFN_DEBUG_ENTRY(
"WXMolecule::OnMenuAddBond()",6)
1075 vector<MolAtom*> v=mpMolecule->GetAtomList();
1076 MolAtom *at1=WXDialogChooseFromVector(v,
1077 (wxWindow*)this,"Choose the first Atom",choice);
1079 MolAtom *at2=WXDialogChooseFromVector(v,
1080 (wxWindow*)this,"Choose the second Atom",choice);
1083 MolAtom *at3=WXDialogChooseFromVector(v,
1084 (wxWindow*)this,"Choose the third Atom",choice);
1087 if( (at1==at2) || (at1==at3) ||(at2==at3))
1089 wxMessageDialog dumbUser(
this,_T(
"The three atoms must be different !"),
1090 _T(
"Whooops"),wxOK|wxICON_EXCLAMATION);
1091 dumbUser.ShowModal();
1095 static double a=109.5;
1097 s.Printf(_T(
"%6.2f"),a);
1098 string mes=
"Enter bond angle (degrees) for "+at1->GetName()
1100 +
"-"+at3->GetName();
1101 wxTextEntryDialog dialog(
this,wxString::FromAscii(mes.c_str()),
1102 _T(
"Bond angle"),s,wxOK | wxCANCEL);
1103 dialog.SetTextValidator(wxTextValidator(wxFILTER_NUMERIC));
1104 if(wxID_OK!=dialog.ShowModal())
1106 VFN_DEBUG_EXIT(
"WXMolecule::OnMenuAddAngle():Canceled",6)
1109 dialog.GetValue().ToDouble(&a);
1111 mpMolecule->AddBondAngle(*at1,*at2,*at3,a*DEG2RAD,.01,0.02);
1112 VFN_DEBUG_EXIT("WXMolecule::OnMenuAddBond()",6)
1115 void WXMolecule::OnMenuAddDihedralAngle(wxCommandEvent & WXUNUSED(event))
1117 VFN_DEBUG_ENTRY(
"WXMolecule::OnMenuAddDihedralAngle()",6)
1120 vector<MolAtom*> v=mpMolecule->GetAtomList();
1121 MolAtom *at1=WXDialogChooseFromVector(v,
1122 (wxWindow*)this,"Choose the first Atom",choice);
1124 MolAtom *at2=WXDialogChooseFromVector(v,
1125 (wxWindow*)this,"Choose the second Atom",choice);
1128 MolAtom *at3=WXDialogChooseFromVector(v,
1129 (wxWindow*)this,"Choose the third Atom",choice);
1132 MolAtom *at4=WXDialogChooseFromVector(v,
1133 (wxWindow*)this,"Choose the fourth Atom",choice);
1136 if( (at1==at2) || (at1==at3) || (at1==at4) || (at2==at3) || (at2==at4) || (at3==at4))
1138 wxMessageDialog dumbUser(
this,_T(
"The atoms must be different !"),
1139 _T(
"Whooops"),wxOK|wxICON_EXCLAMATION);
1140 dumbUser.ShowModal();
1144 static double a=180;
1146 s.Printf(_T(
"%6.2f"),a);
1147 string mes=
"Enter dihedral angle (degrees) for "+at1->GetName()
1150 +
"-"+at4->GetName();
1151 wxTextEntryDialog dialog(
this,_T(
"Enter dihedral angle (degrees)"),
1152 _T(
"Bond angle"),s,wxOK | wxCANCEL);
1153 dialog.SetTextValidator(wxTextValidator(wxFILTER_NUMERIC));
1154 if(wxID_OK!=dialog.ShowModal())
1156 VFN_DEBUG_EXIT(
"WXMolecule::OnMenuAddDihedralAngle():Canceled",6)
1159 dialog.GetValue().ToDouble(&a);
1161 mpMolecule->AddDihedralAngle(*at1,*at2,*at3,*at4,a*DEG2RAD,.01,.02);
1162 VFN_DEBUG_EXIT("WXMolecule::OnMenuAddDihedralAngle()",6)
1165 void WXMolecule::OnMenuAddRigidGroup(wxCommandEvent & WXUNUSED(event))
1167 VFN_DEBUG_ENTRY(
"WXMolecule::OnMenuAddRigidGroup()",6)
1169 list<MolAtom*> l=WXDialogChooseMultipleFromVector(mpMolecule->GetAtomList(),this,
1170 "Choose atoms in the rigid group");
1172 for(list<MolAtom*>::const_iterator pos=l.begin();pos!=l.end();++pos) s.insert(*pos);
1173 mpMolecule->AddRigidGroup(s);
1174 VFN_DEBUG_EXIT("WXMolecule::OnMenuAddRigidGroup()",6)
1177 void WXMolecule::OnMenuAddNonFlipAtom(wxCommandEvent & WXUNUSED(event))
1179 VFN_DEBUG_ENTRY(
"WXMolecule::OnMenuAddNonFlipAtom()",6)
1183 for(vector<MolAtom*>::const_iterator pos=mpMolecule->GetAtomList().begin();pos!=mpMolecule->GetAtomList().end();++pos)
1185 if((*pos)->IsNonFlipAtom()==
false) v.push_back(*pos);
1188 MolAtom *at1=WXDialogChooseFromVector(v,
1189 (wxWindow*)
this,
"Choose the Optically active Atom",choice);
1192 wxMessageDialog dumbUser(
this,_T(
"No atom selected !"),
1193 _T(
"Whooops"),wxOK|wxICON_EXCLAMATION);
1194 dumbUser.ShowModal();
1198 at1->SetNonFlipAtom(
true);
1200 VFN_DEBUG_EXIT(
"WXMolecule::OnMenuAddNonFlipAtom()",6)
1203 void WXMolecule::OnMenuRemoveAtom(wxCommandEvent & WXUNUSED(event))
1205 VFN_DEBUG_ENTRY(
"WXMolecule::OnMenuRemoveAtom()",6)
1207 vector<MolAtom*> v=mpMolecule->GetAtomList();
1208 list<MolAtom*> vAt=WXDialogChooseMultipleFromVector(v,(wxWindow*)this,
1209 "Choose the Atom(s) to be removed");
1210 if(0==vAt.size()) return;
1211 for(list<MolAtom*>::iterator pos=vAt.begin();pos!=vAt.end();++pos) mpMolecule->RemoveAtom(**pos);
1213 VFN_DEBUG_EXIT("WXMolecule::OnMenuRemoveAtom()",6)
1216 void WXMolecule::OnMenuRemoveBond(wxCommandEvent & WXUNUSED(event))
1218 VFN_DEBUG_ENTRY(
"WXMolecule::OnMenuRemoveBond()",6)
1220 vector<MolBond*> v=mpMolecule->GetBondList();
1221 list<MolBond*> vBond=WXDialogChooseMultipleFromVector(v,(wxWindow*)this,
1222 "Choose the Bond(s) to be removed");
1223 if(0==vBond.size()) return;
1224 const
int answer =wxMessageBox
1225 (_T("Remove Bond and Dihedral Angles involving the deleted Bond(s) (if any) ?"),
1226 _T("Delete related Restraints ?"),wxYES_NO, this);
1227 for(list<MolBond*>::iterator pos=vBond.begin();pos!=vBond.end();++pos)
1231 const MolAtom *pAtom1= &((*pos)->GetAtom1());
1232 const MolAtom *pAtom2= &((*pos)->GetAtom2());
1233 for(vector<MolBondAngle*>::iterator posb=mpMolecule->GetBondAngleList().begin();
1234 posb!=mpMolecule->GetBondAngleList().end();)
1236 if( ( (pAtom1==&((*posb)->GetAtom1())) && (pAtom2==&((*posb)->GetAtom2())) )
1237 ||( (pAtom1==&((*posb)->GetAtom2())) && (pAtom2==&((*posb)->GetAtom1())) )
1238 ||( (pAtom1==&((*posb)->GetAtom2())) && (pAtom2==&((*posb)->GetAtom3())) )
1239 ||( (pAtom1==&((*posb)->GetAtom3())) && (pAtom2==&((*posb)->GetAtom2())) ))
1240 posb=mpMolecule->RemoveBondAngle(**posb);
1243 for(vector<MolDihedralAngle*>::iterator posb=mpMolecule->GetDihedralAngleList().begin();
1244 posb!=mpMolecule->GetDihedralAngleList().end();)
1246 if( ( (pAtom1==&((*posb)->GetAtom1())) && (pAtom2==&((*posb)->GetAtom2())) )
1247 ||( (pAtom1==&((*posb)->GetAtom2())) && (pAtom2==&((*posb)->GetAtom1())) )
1248 ||( (pAtom1==&((*posb)->GetAtom2())) && (pAtom2==&((*posb)->GetAtom3())) )
1249 ||( (pAtom1==&((*posb)->GetAtom3())) && (pAtom2==&((*posb)->GetAtom2())) )
1250 ||( (pAtom1==&((*posb)->GetAtom3())) && (pAtom2==&((*posb)->GetAtom4())) )
1251 ||( (pAtom1==&((*posb)->GetAtom4())) && (pAtom2==&((*posb)->GetAtom3())) ))
1252 posb=mpMolecule->RemoveDihedralAngle(**posb);
1256 mpMolecule->RemoveBond(**pos);
1259 VFN_DEBUG_EXIT(
"WXMolecule::OnMenuRemoveBond()",6)
1262 void WXMolecule::OnMenuRemoveAngle(wxCommandEvent & WXUNUSED(event))
1264 VFN_DEBUG_ENTRY(
"WXMolecule::OnMenuRemoveAngle()",6)
1266 vector<MolBondAngle*> v=mpMolecule->GetBondAngleList();
1267 list<MolBondAngle*> vAngle=WXDialogChooseMultipleFromVector(v,(wxWindow*)this,
1268 "Choose the Bond Angle(s) to be removed");
1269 if(0==vAngle.size()) return;
1270 for(list<MolBondAngle*>::iterator pos=vAngle.begin();pos!=vAngle.end();++pos)
1271 mpMolecule->RemoveBondAngle(**pos);
1273 VFN_DEBUG_EXIT("WXMolecule::OnMenuRemoveAngle()",6)
1276 void WXMolecule::OnMenuRemoveDihedralAngle(wxCommandEvent & WXUNUSED(event))
1278 VFN_DEBUG_ENTRY(
"WXMolecule::OnMenuRemoveDihedralAngle()",6)
1280 vector<MolDihedralAngle*> v=mpMolecule->GetDihedralAngleList();
1281 list<MolDihedralAngle*> vAngle=WXDialogChooseMultipleFromVector(v,(wxWindow*)this,
1282 "Choose the Dihedral Angle(s) to be removed");
1283 if(0==vAngle.size()) return;
1284 for(list<MolDihedralAngle*>::iterator pos=vAngle.begin();pos!=vAngle.end();++pos)
1285 mpMolecule->RemoveDihedralAngle(**pos);
1287 VFN_DEBUG_EXIT("WXMolecule::OnMenuRemoveDihedralAngle()",6)
1290 void WXMolecule::OnMenuRemoveNonFlipAtom(wxCommandEvent & WXUNUSED(event))
1292 VFN_DEBUG_ENTRY(
"WXMolecule::OnMenuRemoveNonFlipAtom()",6)
1296 for(vector<MolAtom*>::const_iterator pos=mpMolecule->GetAtomList().begin();pos!=mpMolecule->GetAtomList().end();++pos)
1298 if((*pos)->IsNonFlipAtom()) v.push_back(*pos);
1302 wxMessageDialog dumbUser(
this,_T(
"The list of optically active atoms is empty !"),
1303 _T(
"Whooops"),wxOK|wxICON_EXCLAMATION);
1304 dumbUser.ShowModal();
1307 MolAtom *at1=WXDialogChooseFromVector(v, (wxWindow*)
this,
"Choose the Optically active Atom to be removed",choice);
1309 wxMessageDialog dumbUser(
this,_T(
"No atom selected !"),
1310 _T(
"Whooops"),wxOK|wxICON_EXCLAMATION);
1311 dumbUser.ShowModal();
1315 at1->SetNonFlipAtom(
false);
1317 VFN_DEBUG_EXIT(
"WXMolecule::OnMenuRemoveNonFlipAtom()",6)
1320 void WXMolecule::OnMenuRemoveRigidGroup(wxCommandEvent & WXUNUSED(event))
1322 VFN_DEBUG_ENTRY(
"WXMolecule::OnMenuRemoveRigidGroup()",6)
1324 vector<RigidGroup*> v=mpMolecule->GetRigidGroupList();
1325 list<RigidGroup*> vGroup=WXDialogChooseMultipleFromVector(v,(wxWindow*)this,
1326 "Choose the Rigid Group(s) to be removed");
1327 if(0==vGroup.size()) return;
1328 for(list<RigidGroup*>::iterator pos=vGroup.begin();pos!=vGroup.end();++pos)
1329 mpMolecule->RemoveRigidGroup(**pos);
1331 VFN_DEBUG_EXIT("WXMolecule::OnMenuRemoveRigidGroup()",6)
1371 void WXMolecule::OnEditGridAtom(wxGridEvent &e)
1374 VFN_DEBUG_ENTRY(
"WXMolecule::OnEditGridAtom():"<<e.GetRow()<<
","<<e.GetCol(),10)
1376 const
long r=e.GetRow();
1377 const
long c=e.GetCol();
1380 wxString s=mpAtomWin->GetCellValue(r,c);
1382 mpMolecule->GetAtomList()[r]->SetName(
string(s.ToAscii()));
1386 wxString s=mpAtomWin->GetCellValue(r,c);
1391 long p=mpMolecule->GetCrystal().GetScatteringPowerRegistry().Find(
string(s.ToAscii()));
1392 if(p>=0) mpMolecule->GetAtomList()[r]->SetScatteringPower(
1393 mpMolecule->GetCrystal().GetScatteringPowerRegistry().GetObj(p));
1395 catch(ObjCrystException){};
1400 wxString s=mpAtomWin->GetCellValue(r,c);
1405 mpMolecule->GetAtomList()[r]->SetX(d);
1410 wxString s=mpAtomWin->GetCellValue(r,c);
1415 mpMolecule->GetAtomList()[r]->SetY(d);
1420 wxString s=mpAtomWin->GetCellValue(r,c);
1425 mpMolecule->GetAtomList()[r]->SetZ(d);
1430 wxString s=mpAtomWin->GetCellValue(r,c);
1438 mpMolecule->GetAtomList()[r]->SetOccupancy(d);
1442 mpMolecule->GetCrystal().UpdateDisplay();
1443 VFN_DEBUG_EXIT(
"WXMolecule::OnEditGridAtom():"<<e.GetRow()<<
","<<e.GetCol(),10)
1446 void WXMolecule::OnEditGridBondLength(wxGridEvent &e)
1449 VFN_DEBUG_ENTRY(
"WXMolecule::OnEditGridBondLength():"<<e.GetRow()<<
","<<e.GetCol(),10)
1451 const
long r=e.GetRow();
1452 const
long c=e.GetCol();
1455 wxString s=mpBondWin->GetCellValue(r,c);
1456 vector<MolAtom*>::reverse_iterator at=mpMolecule->FindAtom(
string(s.ToAscii()));
1457 if(at!=mpMolecule->GetAtomList().rend())
1459 if(*at!=&(mpMolecule->GetBondList()[r]->GetAtom2()))
1460 mpMolecule->GetBondList()[r]->SetAtom1(**at);
1462 mpBondWin->SetCellValue(r,c,wxString::FromAscii(mpMolecule->GetBondList()[r]->GetAtom1().GetName().c_str()));
1465 mpBondWin->SetCellValue(r,c,wxString::FromAscii(mpMolecule->GetBondList()[r]->GetAtom1().GetName().c_str()));
1469 wxString s=mpBondWin->GetCellValue(r,c);
1470 vector<MolAtom*>::reverse_iterator at=mpMolecule->FindAtom(
string(s.ToAscii()));
1471 if(at!=mpMolecule->GetAtomList().rend())
1473 if(*at!=&(mpMolecule->GetBondList()[r]->GetAtom1()))
1474 mpMolecule->GetBondList()[r]->SetAtom2(**at);
1476 mpBondWin->SetCellValue(r,c,wxString::FromAscii(mpMolecule->GetBondList()[r]->GetAtom2().GetName().c_str()));
1479 mpBondWin->SetCellValue(r,c,wxString::FromAscii(mpMolecule->GetBondList()[r]->GetAtom2().GetName().c_str()));
1483 wxString s=mpBondWin->GetCellValue(r,c);
1488 if(d>0) mpMolecule->GetBondList()[r]->SetLength0(d);
1493 wxString s=mpBondWin->GetCellValue(r,c);
1498 if(d>0) mpMolecule->GetBondList()[r]->SetLengthSigma(d);
1503 wxString s=mpBondWin->GetCellValue(r,c);
1508 if(d>0) mpMolecule->GetBondList()[r]->SetLengthDelta(d);
1512 VFN_DEBUG_EXIT(
"WXMolecule::OnEditGridBondLength():"<<e.GetRow()<<
","<<e.GetCol(),10)
1515 void WXMolecule::OnEditGridBondAngle(wxGridEvent &e)
1518 VFN_DEBUG_ENTRY(
"WXMolecule::OnEditGridBondAngle():"<<e.GetRow()<<
","<<e.GetCol(),10)
1520 const
long r=e.GetRow();
1521 const
long c=e.GetCol();
1524 wxString s=mpAngleWin->GetCellValue(r,c);
1525 vector<MolAtom*>::reverse_iterator at=mpMolecule->FindAtom(
string(s.ToAscii()));
1526 if(at!=mpMolecule->GetAtomList().rend())
1528 if( (*at!=&(mpMolecule->GetBondAngleList()[r]->GetAtom2()))
1529 &&(*at!=&(mpMolecule->GetBondAngleList()[r]->GetAtom3())))
1530 mpMolecule->GetBondAngleList()[r]->SetAtom1(**at);
1532 mpAngleWin->SetCellValue(r,c,wxString::FromAscii(mpMolecule->GetBondAngleList()[r]->GetAtom1().GetName().c_str()));
1535 mpAngleWin->SetCellValue(r,c,wxString::FromAscii(mpMolecule->GetBondAngleList()[r]->GetAtom1().GetName().c_str()));
1539 wxString s=mpAngleWin->GetCellValue(r,c);
1540 vector<MolAtom*>::reverse_iterator at=mpMolecule->FindAtom(
string(s.ToAscii()));
1541 if(at!=mpMolecule->GetAtomList().rend())
1543 if( (*at!=&(mpMolecule->GetBondAngleList()[r]->GetAtom1()))
1544 &&(*at!=&(mpMolecule->GetBondAngleList()[r]->GetAtom3())))
1545 mpMolecule->GetBondAngleList()[r]->SetAtom2(**at);
1547 mpAngleWin->SetCellValue(r,c,wxString::FromAscii(mpMolecule->GetBondAngleList()[r]->GetAtom2().GetName().c_str()));
1550 mpAngleWin->SetCellValue(r,c,wxString::FromAscii(mpMolecule->GetBondAngleList()[r]->GetAtom2().GetName().c_str()));
1554 wxString s=mpAngleWin->GetCellValue(r,c);
1555 vector<MolAtom*>::reverse_iterator at=mpMolecule->FindAtom(
string(s.ToAscii()));
1556 if(at!=mpMolecule->GetAtomList().rend())
1558 if( (*at!=&(mpMolecule->GetBondAngleList()[r]->GetAtom1()))
1559 &&(*at!=&(mpMolecule->GetBondAngleList()[r]->GetAtom2())))
1560 mpMolecule->GetBondAngleList()[r]->SetAtom3(**at);
1562 mpAngleWin->SetCellValue(r,c,wxString::FromAscii(mpMolecule->GetBondAngleList()[r]->GetAtom3().GetName().c_str()));
1565 mpAngleWin->SetCellValue(r,c,wxString::FromAscii(mpMolecule->GetBondAngleList()[r]->GetAtom2().GetName().c_str()));
1569 wxString s=mpAngleWin->GetCellValue(r,c);
1574 if(d>0) mpMolecule->GetBondAngleList()[r]->SetAngle0(d*DEG2RAD);
1579 wxString s=mpAngleWin->GetCellValue(r,c);
1584 if(d>0) mpMolecule->GetBondAngleList()[r]->SetAngleSigma(d*DEG2RAD);
1589 wxString s=mpAngleWin->GetCellValue(r,c);
1594 if(d>0) mpMolecule->GetBondAngleList()[r]->SetAngleDelta(d*DEG2RAD);
1598 VFN_DEBUG_EXIT(
"WXMolecule::OnEditGridBondAngle():"<<e.GetRow()<<
","<<e.GetCol(),10)
1601 void WXMolecule::OnEditGridDihedralAngle(wxGridEvent &e)
1604 VFN_DEBUG_ENTRY(
"WXMolecule::OnEditGridDihedralAngle():"<<e.GetRow()<<
","<<e.GetCol(),10)
1606 const
long r=e.GetRow();
1607 const
long c=e.GetCol();
1610 wxString s=mpDihedralAngleWin->GetCellValue(r,c);
1611 vector<MolAtom*>::reverse_iterator at=mpMolecule->FindAtom(
string(s.ToAscii()));
1612 if(at!=mpMolecule->GetAtomList().rend())
1614 if( (*at!=&(mpMolecule->GetDihedralAngleList()[r]->GetAtom2()))
1615 &&(*at!=&(mpMolecule->GetDihedralAngleList()[r]->GetAtom3())))
1616 mpMolecule->GetDihedralAngleList()[r]->SetAtom1(**at);
1618 mpDihedralAngleWin->SetCellValue(r,c,wxString::FromAscii(mpMolecule->GetDihedralAngleList()[r]->GetAtom1().GetName().c_str()));
1621 mpDihedralAngleWin->SetCellValue(r,c,wxString::FromAscii(mpMolecule->GetDihedralAngleList()[r]->GetAtom1().GetName().c_str()));
1625 wxString s=mpDihedralAngleWin->GetCellValue(r,c);
1626 vector<MolAtom*>::reverse_iterator at=mpMolecule->FindAtom(
string(s.ToAscii()));
1627 if(at!=mpMolecule->GetAtomList().rend())
1629 if( (*at!=&(mpMolecule->GetDihedralAngleList()[r]->GetAtom1()))
1630 &&(*at!=&(mpMolecule->GetDihedralAngleList()[r]->GetAtom3())))
1631 mpMolecule->GetDihedralAngleList()[r]->SetAtom2(**at);
1633 mpDihedralAngleWin->SetCellValue(r,c,wxString::FromAscii(mpMolecule->GetDihedralAngleList()[r]->GetAtom2().GetName().c_str()));
1636 mpDihedralAngleWin->SetCellValue(r,c,wxString::FromAscii(mpMolecule->GetDihedralAngleList()[r]->GetAtom2().GetName().c_str()));
1640 wxString s=mpDihedralAngleWin->GetCellValue(r,c);
1641 vector<MolAtom*>::reverse_iterator at=mpMolecule->FindAtom(
string(s.ToAscii()));
1642 if(at!=mpMolecule->GetAtomList().rend())
1644 if( (*at!=&(mpMolecule->GetDihedralAngleList()[r]->GetAtom1()))
1645 &&(*at!=&(mpMolecule->GetDihedralAngleList()[r]->GetAtom2())))
1646 mpMolecule->GetDihedralAngleList()[r]->SetAtom3(**at);
1648 mpDihedralAngleWin->SetCellValue(r,c,wxString::FromAscii(mpMolecule->GetDihedralAngleList()[r]->GetAtom3().GetName().c_str()));
1651 mpDihedralAngleWin->SetCellValue(r,c,wxString::FromAscii(mpMolecule->GetDihedralAngleList()[r]->GetAtom3().GetName().c_str()));
1655 wxString s=mpDihedralAngleWin->GetCellValue(r,c);
1656 vector<MolAtom*>::reverse_iterator at=mpMolecule->FindAtom(
string(s.ToAscii()));
1657 if(at!=mpMolecule->GetAtomList().rend())
1659 if( (*at!=&(mpMolecule->GetDihedralAngleList()[r]->GetAtom1()))
1660 &&(*at!=&(mpMolecule->GetDihedralAngleList()[r]->GetAtom2())))
1661 mpMolecule->GetDihedralAngleList()[r]->SetAtom4(**at);
1663 mpDihedralAngleWin->SetCellValue(r,c,wxString::FromAscii(mpMolecule->GetDihedralAngleList()[r]->GetAtom4().GetName().c_str()));
1666 mpDihedralAngleWin->SetCellValue(r,c,wxString::FromAscii(mpMolecule->GetDihedralAngleList()[r]->GetAtom4().GetName().c_str()));
1670 wxString s=mpDihedralAngleWin->GetCellValue(r,c);
1675 mpMolecule->GetDihedralAngleList()[r]->SetAngle0(d*DEG2RAD);
1680 wxString s=mpDihedralAngleWin->GetCellValue(r,c);
1685 if(d>0) mpMolecule->GetDihedralAngleList()[r]->SetAngleSigma(d*DEG2RAD);
1690 wxString s=mpDihedralAngleWin->GetCellValue(r,c);
1695 if(d>0) mpMolecule->GetDihedralAngleList()[r]->SetAngleDelta(d*DEG2RAD);
1699 VFN_DEBUG_EXIT(
"WXMolecule::OnEditGridDihedralAngle():"<<e.GetRow()<<
","<<e.GetCol(),10)
1702 void WXMolecule::OnEditGridRigidGroup(wxGridEvent &e)
1705 VFN_DEBUG_ENTRY(
"WXMolecule::OnEditGridRigidGroup():"<<e.GetRow()<<
","<<e.GetCol(),10)
1708 const
long r=e.GetRow();
1709 const
long c=e.GetCol();
1710 wxString s=mpRigidGroupWin->GetCellValue(r,c);
1711 list<
string> l=SplitString(CompressString(
string(s.ToAscii())," "),",");
1713 for(list<
string>::const_iterator pos=l.begin();pos!=l.end();++pos)
1715 vector<MolAtom*>::reverse_iterator rpos=mpMolecule->FindAtom(*pos);
1716 if(rpos!=mpMolecule->GetAtomList().rend()) rg.insert(*rpos);
1717 else cout<<*pos<<
" : NOT FOUND"<<endl;;
1719 set<MolAtom *> *pold=(set<MolAtom *>*) mpMolecule->GetRigidGroupList()[r];
1720 set<MolAtom *> *pnew=(set<MolAtom *>*) &rg;
1725 mpMolecule->GetRigidGroupClock().Click();
1728 VFN_DEBUG_EXIT(
"WXMolecule::OnEditGridRigidGroup():"<<e.GetRow()<<
","<<e.GetCol(),10)
1731 void WXMolecule::OnMenuExport2ZMatrix(wxCommandEvent &event)
1733 VFN_DEBUG_MESSAGE(
"WXMolecule::OnMenuExport2ZMatrix()",6)
1734 const vector<MolZAtom> *pz=&(mpMolecule->AsZMatrix(true));
1736 if(event.GetId()==ID_MOLECULE_MENU_FILE_2ZMATRIX)
1738 wxFileDialog open(
this,_T(
"Choose a file to save the Z-matrix to"),_T(
""),_T(
""),_T(
"*.fhz"),
1739 wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
1740 if(open.ShowModal() != wxID_OK)
return;
1741 ofstream fout (open.GetPath().ToAscii());
1742 fout.imbue(std::locale::classic());
1747 fout<<mpMolecule->GetName()<<endl<<pz->size()<<endl;
1749 for(vector<MolZAtom>::const_iterator pos=pz->begin();pos!=pz->end();++pos)
1751 tmp.Printf(_T(
"%-2s %2lu"),pos->mpPow->GetSymbol().c_str(),pos->mBondAtom+1);
1758 tmp.Printf(_T(
" %2lu"),pos->mBondAngleAtom+1);
1759 fout<<tmp<<
FormatFloat(pos->mBondAngle*RAD2DEG,8,3);;
1774 wxFileDialog open(
this,_T(
"Choose a file to save the (named) Z-matrix to"),_T(
""),_T(
""),_T(
"*.zmat"),
1775 wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
1777 if(open.ShowModal() != wxID_OK)
return;
1779 unsigned long nbchar=0;
1780 for(vector<MolAtom*>::const_iterator pos=mpMolecule->GetAtomList().begin();
1781 pos!=mpMolecule->GetAtomList().end();++pos)
1782 if(nbchar<(*pos)->GetName().size()) nbchar=(*pos)->GetName().size();
1784 ofstream fout (open.GetPath().ToAscii());
1785 fout.imbue(std::locale::classic());
1790 fout<<mpMolecule->GetName()<<endl<<pz->size()<<endl;
1792 for(vector<MolZAtom>::const_iterator pos=pz->begin();pos!=pz->end();++pos)
1795 fout<<mpMolecule->GetAtomList()[i]->GetName();
1796 tmp.Printf(_T(
" %2s "),pos->mpPow->GetSymbol().c_str());
1799 fout<<mpMolecule->GetAtomList()[pos->mBondAtom]->GetName()<<
" ";
1806 fout<<mpMolecule->GetAtomList()[pos->mBondAngleAtom]->GetName();
1807 fout<<
" "<<
FormatFloat(pos->mBondAngle*RAD2DEG,8,3)<<
" ";
1811 fout<<mpMolecule->GetAtomList()[pos->mDihedralAtom]->GetName();
1812 fout<<
" "<<
FormatFloat(pos->mDihedralAngle*RAD2DEG,8,3)<<
" ";
1824 void WXMolecule::OnMenuTest(wxCommandEvent & WXUNUSED(event))
1826 VFN_DEBUG_ENTRY(
"WXMolecule::OnMenuTest()",6)
1829 mpMolecule->BuildRingList();
1830 mpMolecule->BuildStretchModeBondLength();
1831 mpMolecule->BuildStretchModeBondAngle();
1832 mpMolecule->BuildStretchModeTorsion();
1833 mpMolecule->BuildStretchModeTwist();
1836 mpMolecule->BuildFlipGroup();
1837 mpMolecule->TuneGlobalOptimRotationAmplitude();
1840 mpMolecule->BuildStretchModeGroups();
1842 for(list<StretchModeTorsion>::iterator pos=mpMolecule->GetStretchModeTorsionList().begin();
1843 pos!=mpMolecule->GetStretchModeTorsionList().end();++pos)
1845 if((pos->mpAtom1->GetName()==
"C12")&&(pos->mpAtom2->GetName()==
"N13"))
1848 cout<<pos->mpDihedralAngle->GetAngle()*RAD2DEG;
1849 mpMolecule->RotateAtomGroup(*(pos->mpAtom1),*(pos->mpAtom2),pos->mvRotatedAtomList,2*M_PI/10,
true);
1850 cout<<
" -> "<<pos->mpDihedralAngle->GetAngle()*RAD2DEG
1851 <<
", llk="<<pos->mpDihedralAngle->GetLogLikelihood()<<endl;
1854 mpMolecule->GetCrystal().UpdateDisplay();
1857 mpMolecule->BeginOptimization(
true);
1858 for(REAL amplitude=0.1;amplitude<10;amplitude*=1.5)
1860 REAL maxLLK=0,llk,ave=0.0;
1861 for(
unsigned long i=0;i<1000;i++)
1863 mpMolecule->BeginGlobalOptRandomMove();
1865 llk=mpMolecule->GetLogLikelihood();
1867 if(llk>maxLLK) maxLLK=llk;
1869 mpMolecule->GetCrystal().UpdateDisplay();
1871 cout<<
"Amplitude="<<amplitude<<
", <LLK>= "<<ave/1000<<
", Max LLK= "<<maxLLK<<endl;
1873 mpMolecule->EndOptimization();
1875 VFN_DEBUG_EXIT(
"WXMolecule::OnMenuTest()",6)
1878 class MoleculeMDTestThread:
public wxThread
1881 MoleculeMDTestThread(Molecule &mol,
float seconds):
1882 wxThread(wxTHREAD_DETACHED),mpMolecule(&mol),mSeconds(seconds){};
1883 virtual void *Entry()
1885 cout<<endl<<
"Entering refinement thread "<<endl<<endl;
1886 const map<MolAtom *,set<MolAtom *> > *pConnect=&(mpMolecule-> GetConnectivityTable());
1888 float dt0=chrono.seconds();
1890 while(chrono.seconds()<30)
1892 cout<<
"MD Test, cycle #"<<ct++<<endl;
1896 REAL xmin=(*mpMolecule->mvMDFullAtomGroup.begin())->GetX();
1897 REAL xmax=(*mpMolecule->mvMDFullAtomGroup.begin())->GetX();
1898 REAL ymin=(*mpMolecule->mvMDFullAtomGroup.begin())->GetY();
1899 REAL ymax=(*mpMolecule->mvMDFullAtomGroup.begin())->GetY();
1900 REAL zmin=(*mpMolecule->mvMDFullAtomGroup.begin())->GetZ();
1901 REAL zmax=(*mpMolecule->mvMDFullAtomGroup.begin())->GetZ();
1902 for(set<MolAtom*>::iterator at=mpMolecule->mvMDFullAtomGroup.begin();at!=mpMolecule->mvMDFullAtomGroup.end();++at)
1904 if((*at)->GetX()<xmin) xmin=(*at)->GetX();
1905 if((*at)->GetX()>xmax) xmax=(*at)->GetX();
1906 if((*at)->GetY()<ymin) ymin=(*at)->GetY();
1907 if((*at)->GetY()>ymax) ymax=(*at)->GetY();
1908 if((*at)->GetZ()<zmin) zmin=(*at)->GetZ();
1909 if((*at)->GetZ()>zmax) zmax=(*at)->GetZ();
1912 REAL dx=(xmax-xmin)/5.,dy=(ymax-ymin)/5.,dz=(zmax-zmin)/5.;
1916 const REAL xc=xmin+rand()/(REAL)RAND_MAX*(xmax-xmin);
1917 const REAL yc=ymin+rand()/(REAL)RAND_MAX*(ymax-ymin);
1918 const REAL zc=zmin+rand()/(REAL)RAND_MAX*(zmax-zmin);
1919 map<MolAtom*,XYZ> v0;
1920 const REAL ax=-4.*log(2.)/(dx*dx);
1921 const REAL ay=-4.*log(2.)/(dy*dy);
1922 const REAL az=-4.*log(2.)/(dz*dz);
1926 ux=REAL(rand()-RAND_MAX/2);
1927 uy=REAL(rand()-RAND_MAX/2);
1928 uz=REAL(rand()-RAND_MAX/2);
1929 n=sqrt(ux*ux+uy*uy+uz*uz);
1931 ux=ux/n;uy=uy/n;uz=uz/n;
1933 for(set<MolAtom*>::iterator at=mpMolecule->mvMDFullAtomGroup.begin();at!=mpMolecule->mvMDFullAtomGroup.end();++at)
1934 v0[*at]=XYZ(ux*exp(ax*((*at)->GetX()-xc)*((*at)->GetX()-xc)),
1935 uy*exp(ay*((*at)->GetY()-yc)*((*at)->GetY()-yc)),
1936 uz*exp(az*((*at)->GetZ()-zc)*((*at)->GetZ()-zc)));
1938 for(set<MolAtom*>::iterator at=mpMolecule->mvMDFullAtomGroup.begin();at!=mpMolecule->mvMDFullAtomGroup.end();++at)
1939 v0[*at]=XYZ(((*at)->GetX()-xc)*ux*exp(ax*((*at)->GetX()-xc)*((*at)->GetX()-xc)),
1940 ((*at)->GetY()-yc)*uy*exp(ay*((*at)->GetY()-yc)*((*at)->GetY()-yc)),
1941 ((*at)->GetZ()-zc)*uz*exp(az*((*at)->GetZ()-zc)*((*at)->GetZ()-zc)));
1943 map<MolAtom*,XYZ> v0;
1945 for(set<MolAtom*>::iterator at=mpMolecule->mvMDFullAtomGroup.begin();at!=mpMolecule->mvMDFullAtomGroup.end();++at)
1947 map<MolAtom*,unsigned long> pushedAtoms;
1948 unsigned long idx=rand()%v0.size();
1949 set<MolAtom*>::iterator at0=mpMolecule->mvMDFullAtomGroup.begin();
1950 for(
unsigned int i=0;i<idx;i++) at0++;
1951 const REAL xc=(*at0)->GetX();
1952 const REAL yc=(*at0)->GetY();
1953 const REAL zc=(*at0)->GetZ();
1958 ux=REAL(rand()-RAND_MAX/2);
1959 uy=REAL(rand()-RAND_MAX/2);
1960 uz=REAL(rand()-RAND_MAX/2);
1961 n=sqrt(ux*ux+uy*uy+uz*uz);
1963 ux=ux/n;uy=uy/n;uz=uz/n;
1964 const REAL a=-4.*log(2.)/(2*2);
1966 for(map<MolAtom*,unsigned long>::iterator at=pushedAtoms.begin() ;at!=pushedAtoms.end();++at)
1967 v0[at->first]=XYZ(ux*exp(a*(at->first->GetX()-xc)*(at->first->GetX()-xc)),
1968 uy*exp(a*(at->first->GetY()-yc)*(at->first->GetY()-yc)),
1969 uz*exp(a*(at->first->GetZ()-zc)*(at->first->GetZ()-zc)));
1971 for(map<MolAtom*,unsigned long>::iterator at=pushedAtoms.begin() ;at!=pushedAtoms.end();++at)
1972 v0[at->first]=XYZ((at->first->GetX()-xc)*ux*exp(a*(at->first->GetX()-xc)*(at->first->GetX()-xc)),
1973 (at->first->GetY()-yc)*uy*exp(a*(at->first->GetY()-yc)*(at->first->GetY()-yc)),
1974 (at->first->GetZ()-zc)*uz*exp(a*(at->first->GetZ()-zc)*(at->first->GetZ()-zc)));
1977 const REAL nrj0=40*( mpMolecule->GetBondList().size()
1978 +mpMolecule->GetBondAngleList().size()
1979 +mpMolecule->GetDihedralAngleList().size());
1980 map<RigidGroup*,std::pair<XYZ,XYZ> > vr;
1981 mpMolecule->MolecularDynamicsEvolve(v0, 200,0.004,
1982 mpMolecule->GetBondList(),
1983 mpMolecule->GetBondAngleList(),
1984 mpMolecule->GetDihedralAngleList(),
1989 if((chrono.seconds()-dt0)>0.05) {mpMolecule->GetCrystal().UpdateDisplay();dt0=chrono.seconds();}
1993 virtual void OnExit()
1995 cout <<endl<<
"Exiting refinement thread "<<endl<<endl;
1999 Molecule *mpMolecule;
2004 void WXMolecule::OnMenuMDTest(wxCommandEvent & WXUNUSED(event))
2006 VFN_DEBUG_ENTRY(
"WXMolecule::OnMenuMDTest()",6)
2009 wxProgressDialog dlgProgress(_T(
"Beginning MD Test..."),_T(
"Building Flip Groups"),
2010 7,
this,wxPD_AUTO_HIDE|wxPD_ELAPSED_TIME);
2011 mpMolecule->BuildFlipGroup();
2012 dlgProgress.Update(0,_T(
"Build Ring List")) ;
2013 mpMolecule->BuildRingList();
2014 dlgProgress.Update(1,_T(
"Build Stretch Modes: Bond Length")) ;
2015 mpMolecule->BuildStretchModeBondLength();
2016 dlgProgress.Update(2,_T(
"Build Stretch Modes: Bond Angle")) ;
2017 mpMolecule->BuildStretchModeBondAngle();
2018 dlgProgress.Update(3,_T(
"Build Stretch Modes: Torsion")) ;
2019 mpMolecule->BuildStretchModeTorsion();
2021 dlgProgress.Update(4,_T(
"Build Stretch Modes: Optimize Rotation Amplitudes")) ;
2022 mpMolecule->TuneGlobalOptimRotationAmplitude();
2023 dlgProgress.Update(5,_T(
"Build Stretch Modes Groups")) ;
2024 mpMolecule->BuildStretchModeGroups();
2025 dlgProgress.Update(6,_T(
"Build MD Atom Groups")) ;
2026 mpMolecule->BuildMDAtomGroups();
2029 MoleculeMDTestThread *pTest =
new MoleculeMDTestThread(*mpMolecule,30);
2030 if(pTest->Create() != wxTHREAD_NO_ERROR)
2031 wxLogError(_T(
"Can't create test optimization thread"));
2033 VFN_DEBUG_EXIT(
"WXMolecule::OnMenuMDTest()",6)
2036 static const long ID_MOLECULE_ROTATE_BOND_GO =WXCRYST_ID();
2037 static const long ID_MOLECULE_ROTATE_BOND_ATOMS=WXCRYST_ID();
2039 class WXMoleculeRotation:
public wxWindow
2042 WXMoleculeRotation(wxWindow *parent, Molecule &mol):
2043 wxWindow(parent,-1),mBondListClock(mol.GetBondListClock()),mpMol(&mol)
2045 VFN_DEBUG_ENTRY(
"WXMoleculeRotation::WXMoleculeRotation()",10)
2046 this->SetFont(wxFont(8,wxTELETYPE,wxFONTSTYLE_NORMAL,wxFONTWEIGHT_NORMAL));
2048 wxArrayString choices;
2049 for(vector<MolBond*>::const_iterator pos=mol.GetBondList().begin();pos!=mol.GetBondList().end();++pos)
2050 choices.Add(wxString::FromAscii((*pos)->GetName().c_str()));
2052 wxBoxSizer* pSizer=new wxBoxSizer(wxHORIZONTAL);
2054 wxBoxSizer* pSizer1=new wxBoxSizer(wxVERTICAL);
2055 pSizer1->Add(new wxStaticText(this,-1,_T("Select bond:")),0,wxALIGN_CENTER);
2056 mpBond= new wxChoice(this,ID_MOLECULE_ROTATE_BOND_ATOMS,wxDefaultPosition,wxDefaultSize,choices);
2057 mpBond->SetSelection(0);
2058 pSizer1->Add(mpBond,0,wxALIGN_CENTER);
2059 pSizer->Add(pSizer1,0,wxALIGN_CENTER);
2061 wxBoxSizer* pSizer2=new wxBoxSizer(wxVERTICAL);
2062 pSizer2->Add(new wxStaticText(this,-1,_T("Atoms to rotate:")),0,wxALIGN_CENTER);
2063 mpRotatedAtoms= new wxListBox(this,-1,wxDefaultPosition,wxSize(150,60));
2064 pSizer2->Add(mpRotatedAtoms,0,wxALIGN_CENTER);
2065 pSizer->Add(pSizer2,0,wxALIGN_CENTER);
2067 wxBoxSizer* pSizer3=new wxBoxSizer(wxVERTICAL);
2068 pSizer3->Add(new wxStaticText(this,-1,_T("Amplitude:")),0,wxALIGN_CENTER);
2069 mpAngle=new wxTextCtrl(this,-1,_T("10"), wxDefaultPosition,
2070 wxDefaultSize, 0, wxTextValidator(wxFILTER_NUMERIC));
2071 pSizer3->Add(mpAngle,0,wxALIGN_CENTER);
2072 pSizer->Add(pSizer3,0,wxALIGN_CENTER);
2074 wxButton *pButtonRotate=new wxButton(this,ID_MOLECULE_ROTATE_BOND_GO,_T("Rotate !"));
2075 pSizer->Add(pButtonRotate,0,wxALIGN_CENTER);
2077 this->SetSizer(pSizer);
2078 this->SetAutoLayout(true);
2079 pSizer->SetSizeHints(this);
2080 pSizer->SetSizeHints(parent);
2082 wxCommandEvent ev(wxEVT_COMMAND_CHOICE_SELECTED,ID_MOLECULE_ROTATE_BOND_ATOMS);
2083 wxPostEvent(this,ev);
2084 VFN_DEBUG_EXIT("WXMoleculeRotation::WXMoleculeRotation()",10)
2087 void OnRotate(wxCommandEvent &event)
2089 if(mBondListClock<mpMol->GetBondListClock())
2091 cout<<
" The bond list has changed !"<<endl;
2092 this->GetParent()->Destroy();
2095 VFN_DEBUG_MESSAGE(
"WXMoleculeRotation::OnRotate()",10)
2097 unsigned int bond=mpBond->GetSelection();
2098 unsigned int choice=mpRotatedAtoms->GetSelection();
2100 mpAngle->GetValue().ToDouble(&angle);
2101 mpMol->RotateAtomGroup(mpMol->GetBondList()[bond]->GetAtom1(),
2102 mpMol->GetBondList()[bond]->GetAtom2(),
2103 mvpRotatedAtoms[choice], angle*DEG2RAD, true);
2104 mpMol->GetCrystal().UpdateDisplay();
2106 void OnSelectBond(wxCommandEvent &event)
2108 if(mBondListClock<mpMol->GetBondListClock())
2110 cout<<
" The bond list has changed !"<<endl;
2111 this->GetParent()->Destroy();
2114 VFN_DEBUG_MESSAGE(
"WXMoleculeRotation::OnSelectBond()",10)
2116 const
unsigned int choice=mpBond->GetSelection();
2117 MolAtom *pAt1=&(mpMol->GetBondList()[choice]->GetAtom1());
2118 MolAtom *pAt2=&(mpMol->GetBondList()[choice]->GetAtom2());
2119 mpMol->BuildConnectivityTable();
2121 mvpRotatedAtoms.clear();
2122 mvpRotatedAtoms.resize(2);
2123 mvpRotatedAtoms[0].insert(pAt1);
2126 mvpRotatedAtoms[1].insert(pAt2);
2129 wxArrayString choices;
2131 set<MolAtom *>::const_iterator pos=mvpRotatedAtoms[0].begin();
2132 wxString choice1(wxString::FromAscii((*pos++)->GetName().c_str()));
2133 for(;pos!=mvpRotatedAtoms[0].end();++pos)
2134 choice1 +=_T("-")+wxString::FromAscii((*pos)->GetName().c_str());
2135 choices.Add(choice1);
2137 pos=mvpRotatedAtoms[1].begin();
2138 wxString choice2(wxString::FromAscii((*pos++)->GetName().c_str()));
2139 for(;pos!=mvpRotatedAtoms[1].end();++pos)
2140 choice2 +=_T("-")+wxString::FromAscii((*pos)->GetName().c_str());
2141 choices.Add(choice2);
2143 mpRotatedAtoms->Set(choices);
2144 mpRotatedAtoms->SetSelection(0);
2148 const RefinableObjClock& mBondListClock;
2151 wxListBox *mpRotatedAtoms;
2152 vector<set<MolAtom *> > mvpRotatedAtoms;
2153 wxTextCtrl *mpAngle;
2154 DECLARE_EVENT_TABLE()
2156 BEGIN_EVENT_TABLE(WXMoleculeRotation,wxWindow)
2157 EVT_BUTTON(ID_MOLECULE_ROTATE_BOND_GO, WXMoleculeRotation::OnRotate)
2158 EVT_CHOICE(ID_MOLECULE_ROTATE_BOND_ATOMS, WXMoleculeRotation::OnSelectBond)
2161 static const
long ID_MOLECULE_ROTATE_DIHED_GO =WXCRYST_ID();
2162 static const
long ID_MOLECULE_ROTATE_DIHED_ATOMS=WXCRYST_ID();
2164 class WXMoleculeRotationDihed:public wxWindow
2167 WXMoleculeRotationDihed(wxWindow *parent, Molecule &mol):
2168 wxWindow(parent,-1),mBondListClock(mol.GetBondListClock()),mpMol(&mol)
2170 VFN_DEBUG_ENTRY(
"WXMoleculeRotationDihed::WXMoleculeRotationDihed()",10)
2171 this->SetFont(wxFont(8,wxTELETYPE,wxFONTSTYLE_NORMAL,wxFONTWEIGHT_NORMAL));
2173 wxArrayString choices;
2175 for(vector<MolBondAngle*>::const_iterator pos=mol.GetBondAngleList().begin();pos!=mol.GetBondAngleList().end();++pos)
2177 MolAtom *pAt1=&((*pos)->GetAtom1());
2178 MolAtom *pAt2=&((*pos)->GetAtom2());
2179 MolAtom *pAt3=&((*pos)->GetAtom3());
2180 const set<MolAtom * > *pConn=&(mpMol->GetConnectivityTable().find(pAt3)->second);
2181 for(set<MolAtom * >::const_iterator neigh=pConn->begin();neigh!=pConn->end();++neigh)
2183 if( (*neigh==pAt1) || (*neigh==pAt2) )
continue;
2184 mvDihed.push_back(MolDihedralAngle(*pAt1,*pAt2,*pAt3,**neigh,0,.001,.001,*mpMol));
2185 choices.Add(wxString::FromAscii(mvDihed.back().GetName().c_str()));
2189 wxBoxSizer* pSizer=
new wxBoxSizer(wxHORIZONTAL);
2191 wxBoxSizer* pSizer1=
new wxBoxSizer(wxVERTICAL);
2192 pSizer1->Add(
new wxStaticText(
this,-1,_T(
"Dihedral Angle:")),0,wxALIGN_CENTER);
2193 mpDihed=
new wxChoice(
this,ID_MOLECULE_ROTATE_DIHED_ATOMS,wxDefaultPosition,wxDefaultSize,choices);
2194 mpDihed->SetSelection(0);
2195 pSizer1->Add(mpDihed,0,wxALIGN_CENTER);
2196 pSizer->Add(pSizer1,0,wxALIGN_CENTER);
2198 wxBoxSizer* pSizer2=
new wxBoxSizer(wxVERTICAL);
2199 pSizer2->Add(
new wxStaticText(
this,-1,_T(
"Atoms to rotate:")),0,wxALIGN_CENTER);
2200 mpRotatedAtoms=
new wxListBox(
this,-1,wxDefaultPosition,wxSize(150,60));
2201 pSizer2->Add(mpRotatedAtoms,0,wxALIGN_CENTER);
2202 pSizer->Add(pSizer2,0,wxALIGN_CENTER);
2204 wxBoxSizer* pSizer3=
new wxBoxSizer(wxVERTICAL);
2205 pSizer3->Add(
new wxStaticText(
this,-1,_T(
"Angle:")),0,wxALIGN_CENTER);
2206 mpAngle=
new wxTextCtrl(
this,-1,_T(
"10"), wxDefaultPosition,
2207 wxDefaultSize, 0, wxTextValidator(wxFILTER_NUMERIC));
2208 pSizer3->Add(mpAngle,0,wxALIGN_CENTER);
2209 pSizer->Add(pSizer3,0,wxALIGN_CENTER);
2211 wxButton *pButtonRotate=
new wxButton(
this,ID_MOLECULE_ROTATE_DIHED_GO,_T(
"Set angle !"));
2212 pSizer->Add(pButtonRotate,0,wxALIGN_CENTER);
2214 this->SetSizer(pSizer);
2215 this->SetAutoLayout(
true);
2216 pSizer->SetSizeHints(
this);
2217 pSizer->SetSizeHints(parent);
2219 wxCommandEvent ev(wxEVT_COMMAND_CHOICE_SELECTED,ID_MOLECULE_ROTATE_DIHED_ATOMS);
2220 wxPostEvent(
this,ev);
2221 VFN_DEBUG_EXIT(
"WXMoleculeRotationDihed::WXMoleculeRotationDihed()",10)
2224 void OnRotate(wxCommandEvent &event)
2226 if(mBondListClock<mpMol->GetBondListClock())
2228 cout<<
" The bond list has changed !"<<endl;
2229 this->GetParent()->Destroy();
2232 VFN_DEBUG_MESSAGE(
"WXMoleculeRotationDihed::OnRotate()",10)
2234 MolDihedralAngle *pDihed=&mvDihed[mpDihed->GetSelection()];
2235 unsigned int choice=mpRotatedAtoms->GetSelection();
2237 mpAngle->GetValue().ToDouble(&angle);
2239 angle-=pDihed->GetAngle();
2241 if(mvpRotatedAtoms[choice].find(&(pDihed->GetAtom1()))!=mvpRotatedAtoms[choice].end()) angle*=-1;
2243 mpMol->RotateAtomGroup(pDihed->GetAtom2(),
2245 mvpRotatedAtoms[choice], angle, true);
2246 mpMol->GetCrystal().UpdateDisplay();
2248 void OnSelectDihed(wxCommandEvent &event)
2250 if(mBondListClock<mpMol->GetBondListClock())
2252 cout<<
" The bond list has changed !"<<endl;
2253 this->GetParent()->Destroy();
2256 VFN_DEBUG_MESSAGE(
"WXMoleculeRotationDihed::OnSelectBond()",10)
2258 MolDihedralAngle *pDihed=&mvDihed[mpDihed->GetSelection()];
2259 MolAtom *pAt1=&(pDihed->GetAtom1());
2260 MolAtom *pAt2=&(pDihed->GetAtom2());
2261 MolAtom *pAt3=&(pDihed->GetAtom3());
2262 MolAtom *pAt4=&(pDihed->GetAtom4());
2263 mpMol->BuildConnectivityTable();
2265 mvpRotatedAtoms.clear();
2266 mvpRotatedAtoms.resize(2);
2268 mvpRotatedAtoms[0].insert(pAt1);
2269 mvpRotatedAtoms[0].insert(pAt2);
2271 mvpRotatedAtoms[0].erase(pAt1);
2272 mvpRotatedAtoms[0].erase(pAt2);
2274 mvpRotatedAtoms[1].insert(pAt4);
2275 mvpRotatedAtoms[1].insert(pAt3);
2277 mvpRotatedAtoms[1].erase(pAt4);
2278 mvpRotatedAtoms[1].erase(pAt3);
2280 wxArrayString choices;
2282 set<MolAtom *>::const_iterator pos=mvpRotatedAtoms[0].begin();
2283 wxString choice1(wxString::FromAscii((*pos++)->GetName().c_str()));
2284 for(;pos!=mvpRotatedAtoms[0].end();++pos)
2285 choice1 +=_T("-")+wxString::FromAscii((*pos)->GetName().c_str());
2286 choices.Add(choice1);
2288 pos=mvpRotatedAtoms[1].begin();
2289 wxString choice2(wxString::FromAscii((*pos++)->GetName().c_str()));
2290 for(;pos!=mvpRotatedAtoms[1].end();++pos)
2291 choice2 +=_T("-")+wxString::FromAscii((*pos)->GetName().c_str());
2292 choices.Add(choice2);
2294 mpRotatedAtoms->Set(choices);
2295 mpRotatedAtoms->SetSelection(0);
2296 mpAngle->SetValue(wxString::Format(_T("%6.2f"),pDihed->GetAngle()*RAD2DEG));
2300 const RefinableObjClock& mBondListClock;
2302 vector<MolDihedralAngle > mvDihed;
2304 wxListBox *mpRotatedAtoms;
2305 vector<set<MolAtom *> > mvpRotatedAtoms;
2306 wxTextCtrl *mpAngle;
2307 DECLARE_EVENT_TABLE()
2309 BEGIN_EVENT_TABLE(WXMoleculeRotationDihed,wxWindow)
2310 EVT_BUTTON(ID_MOLECULE_ROTATE_DIHED_GO, WXMoleculeRotationDihed::OnRotate)
2311 EVT_CHOICE(ID_MOLECULE_ROTATE_DIHED_ATOMS, WXMoleculeRotationDihed::OnSelectDihed)
2314 void WXMolecule::OnMenuRotate(wxCommandEvent &event)
2316 VFN_DEBUG_ENTRY(
"WXMolecule::OnMenuRotate()",10)
2318 if(event.GetId()==ID_MOLECULE_MENU_GEOMETRY_ROTATE_BOND)
2321 wxFrame *frame=
new wxMiniFrame(
this,-1,_T(
"Rotate around bond"),wxDefaultPosition,
2322 wxDefaultSize,wxCLOSE_BOX|wxSTAY_ON_TOP|wxCAPTION);
2324 wxFrame *frame=
new wxFrame(
this,-1,_T(
"Rotate around bond"),wxDefaultPosition,
2327 WXMoleculeRotation * wxMolRot;
2328 wxMolRot=
new WXMoleculeRotation(frame,*mpMolecule);
2331 if(event.GetId()==ID_MOLECULE_MENU_GEOMETRY_ROTATE_DIHED)
2334 wxFrame *frame=
new wxMiniFrame(
this,-1,_T(
"Change dihedral angle"),wxDefaultPosition,
2335 wxDefaultSize,wxCLOSE_BOX|wxSTAY_ON_TOP|wxCAPTION);
2337 wxFrame *frame=
new wxFrame(
this,-1,_T(
"Change dihedral angle"),wxDefaultPosition,
2340 WXMoleculeRotationDihed * wxMolRot;
2341 wxMolRot=
new WXMoleculeRotationDihed(frame,*mpMolecule);
2344 VFN_DEBUG_EXIT(
"WXMolecule::OnMenuRotate()",10)
2348 void WXMolecule::OnMenuSetLimits(wxCommandEvent &event)
2354 VFN_DEBUG_ENTRY(
"WXMolecule::CrystUpdate()",6)
2356 if(
false==mpMolecule->IsBeingRefined())
2361 for(list<CellAtom>::iterator pos=
mvpAtom.begin();pos!=
mvpAtom.end();)
2363 if(i>=mpMolecule->GetAtomList().size())
2366 mpAtomWin->DeleteRows(i);
2370 if(pos->mpAtom!=mpMolecule->GetAtomList()[i])
2373 mpAtomWin->DeleteRows(i);
2386 for(list<CellBond>::iterator pos=
mvpBond.begin();pos!=
mvpBond.end();)
2388 if(i>=mpMolecule->GetBondList().size())
2391 mpBondWin->DeleteRows(i);
2395 if(pos->mpBond!=mpMolecule->GetBondList()[i])
2398 mpBondWin->DeleteRows(i);
2413 if(i>=mpMolecule->GetBondAngleList().size())
2416 mpAngleWin->DeleteRows(i);
2420 if(pos->mpBondAngle!=mpMolecule->GetBondAngleList()[i])
2423 mpAngleWin->DeleteRows(i);
2433 if(0!=mpDihedralAngleWin)
2438 if(i>=mpMolecule->GetDihedralAngleList().size())
2441 mpDihedralAngleWin->DeleteRows(i);
2445 if(pos->mpDihedralAngle!=mpMolecule->GetDihedralAngleList()[i])
2448 mpDihedralAngleWin->DeleteRows(i);
2458 if(0!=mpRigidGroupWin)
2463 if(i>=mpMolecule->GetRigidGroupList().size())
2466 mpRigidGroupWin->DeleteRows(i);
2470 if(pos->mpGroup!=mpMolecule->GetRigidGroupList()[i])
2473 mpRigidGroupWin->DeleteRows(i);
2483 if(0!=mpNonFlipAtomWin)
2485 if(mpNonFlipAtomWin->GetNumberRows()>0)
2486 mpNonFlipAtomWin->DeleteRows(0, mpNonFlipAtomWin->GetNumberRows(),
true);
2490 bool needLayout=
false;
2491 for(
unsigned long i=
mvpAtom.size();i<mpMolecule->GetAtomList().size();++i)
2493 VFN_DEBUG_MESSAGE(
"WXMolecule::CrystUpdate():Atom not found",5)
2494 mpAtomWin->AppendRows();
2496 mvpAtom.back().mpAtom=mpMolecule->GetAtomList()[i];
2503 mpAtomWin->FitInside();
2509 for(
unsigned long i=
mvpBond.size();i<mpMolecule->GetBondList().size();++i)
2511 VFN_DEBUG_MESSAGE(
"WXMolecule::CrystUpdate():Bond not found",5)
2512 mpBondWin->AppendRows();
2514 mvpBond.back().mpBond=mpMolecule->GetBondList()[i];
2519 for(
unsigned long i=
mvpBondAngle.size();i<mpMolecule->GetBondAngleList().size();++i)
2521 VFN_DEBUG_MESSAGE(
"WXMolecule::CrystUpdate():Bond Angle not found",5)
2522 mpAngleWin->AppendRows();
2524 mvpBondAngle.back().mpBondAngle=mpMolecule->GetBondAngleList()[i];
2527 if(0!=mpDihedralAngleWin)
2529 for(
unsigned long i=
mvpDihedralAngle.size();i<mpMolecule->GetDihedralAngleList().size();++i)
2531 VFN_DEBUG_MESSAGE(
"WXMolecule::CrystUpdate():Dihedral Angle not found",5)
2532 mpDihedralAngleWin->AppendRows();
2534 mvpDihedralAngle.back().mpDihedralAngle=mpMolecule->GetDihedralAngleList()[i];
2537 if(0!=mpRigidGroupWin)
2539 for(
unsigned long i=
mvpRigidGroup.size();i<mpMolecule->GetRigidGroupList().size();++i)
2541 VFN_DEBUG_MESSAGE(
"WXMolecule::CrystUpdate():Rigid Group not found",5)
2542 mpRigidGroupWin->AppendRows();
2544 mvpRigidGroup.back().mpGroup=mpMolecule->GetRigidGroupList()[i];
2549 if(*(pos->mpGroup) != pos->mGroupCopy)
2551 pos->mGroupCopy=*(pos->mpGroup);
2552 pos->mNeedUpdateUI=
true;
2556 if(0!=mpNonFlipAtomWin)
2558 vector<MolAtom*> v = mpMolecule->GetAtomList();
2560 for(std::vector<MolAtom*>::const_iterator pos=mpMolecule->GetAtomList().begin();pos!=mpMolecule->GetAtomList().end();++pos)
2562 if((*pos)->IsNonFlipAtom())
2564 mpNonFlipAtomWin->AppendRows(1,
true);
2565 mpNonFlipAtomWin->SetCellValue(i, 0, (*pos)->GetName());
2573 for(list<CellAtom>::iterator pos=
mvpAtom.begin();pos!=
mvpAtom.end();++pos)
2575 const string name=pos->mpAtom->GetName();
2577 const REAL x=pos->mpAtom->X();
2578 const REAL y=pos->mpAtom->Y();
2579 const REAL z=pos->mpAtom->Z();
2580 const REAL occ=pos->mpAtom->GetOccupancy();
2581 if( (name !=pos->mName)
2582 ||(pow !=pos->mpScatteringPower)
2586 ||(occ !=pos->mOcc))
2589 pos->mpScatteringPower =pow;
2594 pos->mNeedUpdateUI=
true;
2600 for(list<CellBond>::iterator pos=
mvpBond.begin();pos!=
mvpBond.end();++pos)
2602 const string atom1=pos->mpBond->GetAtom1().
GetName();
2603 const string atom2=pos->mpBond->GetAtom2().GetName();
2604 const REAL length =pos->mpBond->GetLength();
2605 const REAL length0 =pos->mpBond->GetLength0();
2606 const REAL sigma =pos->mpBond->GetLengthSigma();
2607 const REAL delta =pos->mpBond->GetLengthDelta();
2608 if( (atom1 !=pos->mAtom1)
2609 ||(atom2 !=pos->mAtom2)
2610 ||(length !=pos->mLength)
2611 ||(length0!=pos->mLength0)
2612 ||(sigma !=pos->mSigma)
2613 ||(delta !=pos->mDelta))
2615 VFN_DEBUG_MESSAGE(
"WXMolecule::CrystUpdate():"<<atom1<<
"-"<<atom2<<
":"<<length,4)
2618 pos->mLength =length;
2619 pos->mLength0=length0;
2622 pos->mNeedUpdateUI=
true;
2630 const string atom1=pos->mpBondAngle->GetAtom1().GetName();
2631 const string atom2=pos->mpBondAngle->GetAtom2().GetName();
2632 const string atom3=pos->mpBondAngle->GetAtom3().GetName();
2633 const REAL angle =pos->mpBondAngle->GetAngle();
2634 const REAL angle0 =pos->mpBondAngle->GetAngle0();
2635 const REAL sigma =pos->mpBondAngle->GetAngleSigma();
2636 const REAL delta =pos->mpBondAngle->GetAngleDelta();
2637 if( (atom1 !=pos->mAtom1)
2638 ||(atom2 !=pos->mAtom2)
2639 ||(atom3 !=pos->mAtom3)
2640 ||(angle !=pos->mAngle)
2641 ||(angle0!=pos->mAngle0)
2642 ||(sigma !=pos->mSigma)
2643 ||(delta !=pos->mDelta))
2649 pos->mAngle0=angle0;
2652 pos->mNeedUpdateUI=
true;
2656 if(0!=mpDihedralAngleWin)
2660 const string atom1=pos->mpDihedralAngle->GetAtom1().GetName();
2661 const string atom2=pos->mpDihedralAngle->GetAtom2().GetName();
2662 const string atom3=pos->mpDihedralAngle->GetAtom3().GetName();
2663 const string atom4=pos->mpDihedralAngle->GetAtom4().GetName();
2664 const REAL angle =pos->mpDihedralAngle->GetAngle();
2665 const REAL angle0 =pos->mpDihedralAngle->GetAngle0();
2666 const REAL sigma =pos->mpDihedralAngle->GetAngleSigma();
2667 const REAL delta =pos->mpDihedralAngle->GetAngleDelta();
2668 if( (atom1 !=pos->mAtom1)
2669 ||(atom2 !=pos->mAtom2)
2670 ||(atom3 !=pos->mAtom3)
2671 ||(atom4 !=pos->mAtom4)
2672 ||(angle !=pos->mAngle)
2673 ||(angle0!=pos->mAngle0)
2674 ||(sigma !=pos->mSigma)
2675 ||(delta !=pos->mDelta))
2682 pos->mAngle0=angle0;
2685 pos->mNeedUpdateUI=
true;
2689 if(0!=mpNonFlipAtomWin)
2694 if(lock)
mMutex.Unlock();
2695 VFN_DEBUG_EXIT(
"WXMolecule::CrystUpdate()",6)
2698 void WXMolecule::OnMenuShowRestraintWindow(wxCommandEvent &event)
2700 if(0!=mpBondWin)
return;
2703 wxFrame *frame=
new wxFrame(
this,-1,_T(
"Restraints for: ")+wxString::FromAscii(mpMolecule->GetName().c_str()),
2704 wxDefaultPosition,wxSize(800,300));
2706 wxNotebook *notebook =
new wxNotebook(frame, -1);
2709 wxGridCellAttr* cellAttrName =
new wxGridCellAttr;
2710 cellAttrName->SetRenderer(
new wxGridCellStringRenderer);
2711 cellAttrName->SetEditor(
new wxGridCellTextEditor);
2712 wxGridCellAttr* cellAttrFloat =
new wxGridCellAttr;
2713 cellAttrFloat->SetRenderer(
new wxGridCellFloatRenderer(-1,3));
2714 cellAttrFloat->SetEditor(
new wxGridCellFloatEditor);
2715 wxGridCellAttr* cellAttrFloatReadOnly =
new wxGridCellAttr;
2716 cellAttrFloatReadOnly->SetRenderer(
new wxGridCellFloatRenderer(-1,3));
2717 cellAttrFloatReadOnly->SetEditor(
new wxGridCellFloatEditor);
2718 cellAttrFloatReadOnly->SetReadOnly();
2721 notebook->AddPage(mpBondWin, _T(
"Bond Lengths"),
true);
2722 mpBondWin->CreateGrid(0,6);
2723 mpBondWin->SetColSize(0,80);
2724 mpBondWin->SetColAttr(0,cellAttrName);
2725 mpBondWin->SetColAttr(1,cellAttrName->Clone());
2726 mpBondWin->SetColAttr(2,cellAttrFloatReadOnly);
2727 mpBondWin->SetColAttr(3,cellAttrFloat);
2728 mpBondWin->SetColAttr(4,cellAttrFloat->Clone());
2729 mpBondWin->SetColAttr(5,cellAttrFloat->Clone());
2730 mpBondWin->SetColLabelValue(0,_T(
"Atom1"));
2731 mpBondWin->SetColLabelValue(1,_T(
"Atom2"));
2732 mpBondWin->SetColLabelValue(2,_T(
"Length"));
2733 mpBondWin->SetColLabelValue(3,_T(
"Restraint"));
2734 mpBondWin->SetColLabelValue(4,_T(
"Sigma"));
2735 mpBondWin->SetColLabelValue(5,_T(
"Delta"));
2736 mpBondWin->AutoSizeRows();
2740 wxGridCellAttr* cellAttrName =
new wxGridCellAttr;
2741 cellAttrName->SetRenderer(
new wxGridCellStringRenderer);
2742 cellAttrName->SetEditor(
new wxGridCellTextEditor);
2743 wxGridCellAttr* cellAttrFloat =
new wxGridCellAttr;
2744 cellAttrFloat->SetRenderer(
new wxGridCellFloatRenderer(-1,3));
2745 cellAttrFloat->SetEditor(
new wxGridCellFloatEditor);
2746 wxGridCellAttr* cellAttrFloatReadOnly =
new wxGridCellAttr;
2747 cellAttrFloatReadOnly->SetRenderer(
new wxGridCellFloatRenderer(-1,3));
2748 cellAttrFloatReadOnly->SetEditor(
new wxGridCellFloatEditor);
2749 cellAttrFloatReadOnly->SetReadOnly();
2751 mpAngleWin =
new WXMolScrolledWindow(notebook,
this,ID_WINDOW_BONDANGLE);
2752 notebook->AddPage(mpAngleWin, _T(
"Bond Angles"),
true);
2753 mpAngleWin->CreateGrid(0,7);
2754 mpAngleWin->SetColSize(0,80);
2755 mpAngleWin->SetColAttr(0,cellAttrName);
2756 mpAngleWin->SetColAttr(1,cellAttrName->Clone());
2757 mpAngleWin->SetColAttr(2,cellAttrName->Clone());
2758 mpAngleWin->SetColAttr(3,cellAttrFloatReadOnly);
2759 mpAngleWin->SetColAttr(4,cellAttrFloat);
2760 mpAngleWin->SetColAttr(5,cellAttrFloat->Clone());
2761 mpAngleWin->SetColAttr(6,cellAttrFloat->Clone());
2762 mpAngleWin->SetColLabelValue(0,_T(
"Atom1"));
2763 mpAngleWin->SetColLabelValue(1,_T(
"Atom2"));
2764 mpAngleWin->SetColLabelValue(2,_T(
"Atom3"));
2765 mpAngleWin->SetColLabelValue(3,_T(
"Angle"));
2766 mpAngleWin->SetColLabelValue(4,_T(
"Restraint"));
2767 mpAngleWin->SetColLabelValue(5,_T(
"Sigma"));
2768 mpAngleWin->SetColLabelValue(6,_T(
"Delta"));
2769 mpAngleWin->AutoSizeRows();
2773 wxGridCellAttr* cellAttrName =
new wxGridCellAttr;
2774 cellAttrName->SetRenderer(
new wxGridCellStringRenderer);
2775 cellAttrName->SetEditor(
new wxGridCellTextEditor);
2776 wxGridCellAttr* cellAttrFloat =
new wxGridCellAttr;
2777 cellAttrFloat->SetRenderer(
new wxGridCellFloatRenderer(-1,3));
2778 cellAttrFloat->SetEditor(
new wxGridCellFloatEditor);
2779 wxGridCellAttr* cellAttrFloatReadOnly =
new wxGridCellAttr;
2780 cellAttrFloatReadOnly->SetRenderer(
new wxGridCellFloatRenderer(-1,3));
2781 cellAttrFloatReadOnly->SetEditor(
new wxGridCellFloatEditor);
2782 cellAttrFloatReadOnly->SetReadOnly();
2784 mpDihedralAngleWin =
new WXMolScrolledWindow(notebook,
this,ID_WINDOW_DIHEDRALANGLE);
2785 notebook->AddPage(mpDihedralAngleWin, _T(
"Dihedral Angles"),
true);
2786 mpDihedralAngleWin->CreateGrid(0,8);
2787 mpDihedralAngleWin->SetColSize(0,80);
2788 mpDihedralAngleWin->SetColAttr(0,cellAttrName);
2789 mpDihedralAngleWin->SetColAttr(1,cellAttrName->Clone());
2790 mpDihedralAngleWin->SetColAttr(2,cellAttrName->Clone());
2791 mpDihedralAngleWin->SetColAttr(3,cellAttrName->Clone());
2792 mpDihedralAngleWin->SetColAttr(4,cellAttrFloatReadOnly);
2793 mpDihedralAngleWin->SetColAttr(5,cellAttrFloat);
2794 mpDihedralAngleWin->SetColAttr(6,cellAttrFloat->Clone());
2795 mpDihedralAngleWin->SetColAttr(7,cellAttrFloat->Clone());
2796 mpDihedralAngleWin->SetColLabelValue(0,_T(
"Atom1"));
2797 mpDihedralAngleWin->SetColLabelValue(1,_T(
"Atom2"));
2798 mpDihedralAngleWin->SetColLabelValue(2,_T(
"Atom3"));
2799 mpDihedralAngleWin->SetColLabelValue(3,_T(
"Atom4"));
2800 mpDihedralAngleWin->SetColLabelValue(4,_T(
"Angle"));
2801 mpDihedralAngleWin->SetColLabelValue(5,_T(
"Restraint"));
2802 mpDihedralAngleWin->SetColLabelValue(6,_T(
"Sigma"));
2803 mpDihedralAngleWin->SetColLabelValue(7,_T(
"Delta"));
2804 mpDihedralAngleWin->AutoSizeRows();
2808 wxGridCellAttr* cellAttrName =
new wxGridCellAttr;
2809 cellAttrName->SetRenderer(
new wxGridCellStringRenderer);
2810 cellAttrName->SetEditor(
new wxGridCellTextEditor);
2812 mpRigidGroupWin =
new WXMolScrolledWindow(notebook,
this,ID_WINDOW_RIGIDGROUP);
2813 notebook->AddPage(mpRigidGroupWin, _T(
"Rigid Groups"),
true);
2814 mpRigidGroupWin->CreateGrid(0,1);
2815 mpRigidGroupWin->SetColMinimalWidth(0,600);
2816 mpRigidGroupWin->SetColSize(0,600);
2817 mpRigidGroupWin->SetColAttr(0,cellAttrName);
2818 mpRigidGroupWin->SetColLabelValue(0,_T(
"Atoms in Rigid Group"));
2825 wxGridCellAttr* cellAttrName =
new wxGridCellAttr;
2826 cellAttrName->SetReadOnly();
2827 cellAttrName->SetRenderer(
new wxGridCellStringRenderer);
2828 cellAttrName->SetEditor(
new wxGridCellTextEditor);
2830 mpNonFlipAtomWin =
new WXMolScrolledWindow(notebook,
this,ID_WINDOW_NONFLIPATOM);
2831 notebook->AddPage(mpNonFlipAtomWin, _T(
"Optically active atoms"),
true);
2832 mpNonFlipAtomWin->CreateGrid(0,1);
2833 mpNonFlipAtomWin->SetColMinimalWidth(0,600);
2834 mpNonFlipAtomWin->SetColSize(0,600);
2835 mpNonFlipAtomWin->SetColAttr(0,cellAttrName);
2836 mpNonFlipAtomWin->SetColLabelValue(0,_T(
"Optically active atom"));
2838 notebook->SetSelection(0);
2844 void WXMolecule::OnMenuRigidfyWithDihedralAngles(wxCommandEvent & WXUNUSED(event))
2846 VFN_DEBUG_ENTRY(
"WXMolecule::OnMenuRigidfyWithDihedralAngles()",6)
2849 msg.Printf( _T("This will add all possible dihedral angles,\n")
2850 _T("in practice making the Molecule rigid\n\n")
2851 _T("Are you sure you want to proceed ?")
2854 wxMessageDialog w(this,msg,_T("Warning !"),wxYES_NO|wxNO_DEFAULT|wxICON_EXCLAMATION);
2855 int result=w.ShowModal();
2856 if(wxID_YES==result) mpMolecule->RigidifyWithDihedralAngles();
2858 VFN_DEBUG_EXIT("WXMolecule::OnMenuRigidfyWithDihedralAngles()",6)
2861 void WXMolecule::OnMenuSetDeltaSigma(wxCommandEvent &event)
2863 VFN_DEBUG_ENTRY(
"WXMolecule::OnMenuSetDeltaSigma()",6)
2865 double sigma=0.01,delta=0.02;
2868 s.Printf(_T(
"%f"),delta);
2869 wxString title=_T(
"Choose 'delta' value");
2871 info.Printf(_T(
"The 'delta' value is the allowed range \n")
2872 _T(
"(without penalty) around the expected value.\n\n")
2873 _T(
"It is by default equal to 0.02, in Angstroems for bond lengths,\n")
2874 _T(
"and in radians for angles (0.02rad = 1.15deg)\n\n")
2875 _T(
"DO NOT TRY TO CHANGE THE DEFAULT VALUE\n")
2876 _T(
"UNLESS YOU REALLY KNOW WHAT YOU ARE DOING\n")
2877 _T(
"Fox has been optimized with the default values...")
2879 wxTextEntryDialog dialog(
this,info,title,s,wxOK|wxCANCEL);
2880 dialog.SetTextValidator(wxTextValidator(wxFILTER_NUMERIC));
2881 if(wxID_OK!=dialog.ShowModal())
2883 VFN_DEBUG_EXIT(
"WXMolecule::OnMenuSetDeltaSigma():Canceled",6)
2886 dialog.GetValue().ToDouble(&delta);
2890 s.Printf(_T(
"%f"),sigma);
2891 wxString title=_T(
"Choose 'sigma' value");
2893 info.Printf(_T(
"The 'sigma' value is used to compute \n")
2894 _T(
"penalty)around the expected value\n\n")
2895 _T(
"It is by default equal to 0.01, in Angstroems for bond angles,\n")
2896 _T(
"and in radians for angles (0.01rad = 0.57deg)\n\n")
2897 _T(
"DO NOT TRY TO CHANGE THE DEFAULT VALUE\n")
2898 _T(
"UNLESS YOU REALLY KNOW WHAT YOU ARE DOING\n")
2899 _T(
"Fox has been optimized with the default values...")
2901 wxTextEntryDialog dialog(
this,info,title.c_str(),s,wxOK|wxCANCEL);
2902 dialog.SetTextValidator(wxTextValidator(wxFILTER_NUMERIC));
2903 if(wxID_OK!=dialog.ShowModal())
2905 VFN_DEBUG_EXIT(
"WXMolecule::OnMenuSetDeltaSigma():Canceled",6)
2908 dialog.GetValue().ToDouble(&sigma);
2910 for(vector<MolBond*>::iterator pos=mpMolecule->GetBondList().begin();
2911 pos != mpMolecule->GetBondList().end();++pos)
2913 (*pos)->SetLengthDelta(delta);
2914 (*pos)->SetLengthSigma(sigma);
2916 for(vector<MolBondAngle*>::iterator pos=mpMolecule->GetBondAngleList().begin();
2917 pos != mpMolecule->GetBondAngleList().end();++pos)
2919 (*pos)->SetAngleDelta(delta*DEG2RAD);
2920 (*pos)->SetAngleSigma(sigma*DEG2RAD);
2922 for(vector<MolDihedralAngle*>::iterator pos=mpMolecule->GetDihedralAngleList().begin();
2923 pos != mpMolecule->GetDihedralAngleList().end();++pos)
2928 mpMolecule->GetBondListClock().Click();
2930 VFN_DEBUG_EXIT(
"WXMolecule::OnMenuSetDeltaSigma()",6)
2933 void WXMolecule::OnChangeCenterAtom(wxCommandEvent &event)
2937 MolAtom *
const at=WXDialogChooseFromVector(mpMolecule->GetAtomList(),
2938 (wxWindow*)
this,
"Choose a new Atom",choice);
2940 mpMolecule->SetCenterAtom(*at);
2945 VFN_DEBUG_ENTRY(
"WXMolecule::NotifyDeleteListWin()",6)
2948 VFN_DEBUG_MESSAGE(
"WXMolecule::NotifyDeleteListWin(): Bond List window",5)
2954 VFN_DEBUG_MESSAGE(
"WXMolecule::NotifyDeleteListWin(): Angle List window",5)
2958 if(win==mpDihedralAngleWin)
2960 VFN_DEBUG_MESSAGE(
"WXMolecule::NotifyDeleteListWin(): Dihedral Angle List window",5)
2961 mpDihedralAngleWin=0;
2964 if(win==mpRigidGroupWin)
2966 VFN_DEBUG_MESSAGE(
"WXMolecule::NotifyDeleteListWin(): Dihedral Angle List window",5)
2970 if(win==mpNonFlipAtomWin)
2972 VFN_DEBUG_MESSAGE(
"WXMolecule::NotifyDeleteListWin(): non-flip atom list window",5)
2975 VFN_DEBUG_EXIT(
"WXMolecule::NotifyDeleteListWin()",6)
2980 VFN_DEBUG_ENTRY(
"WXMolecule::UpdateUI()",5)
2983 for(list<CellAtom>::iterator pos=
mvpAtom.begin();pos!=
mvpAtom.end();++pos)
2985 if(pos->mNeedUpdateUI==
true)
2988 mpAtomWin->SetCellValue(i, 0, wxString::FromAscii(pos->mName.c_str()));
2989 mpAtomWin->SetCellValue(i, 1, wxString::FromAscii(pos->mpScatteringPower->GetName().c_str()));
2991 tmp.Printf(_T(
"%.3f"),pos->mX);
2992 mpAtomWin->SetCellValue(i, 2, tmp);
2993 tmp.Printf(_T(
"%.3f"),pos->mY);
2994 mpAtomWin->SetCellValue(i, 3, tmp);
2995 tmp.Printf(_T(
"%.3f"),pos->mZ);
2996 mpAtomWin->SetCellValue(i, 4, tmp);
2997 tmp.Printf(_T(
"%.3f"),pos->mOcc);
2998 mpAtomWin->SetCellValue(i, 5, tmp);
3007 for(list<CellBond>::iterator pos=
mvpBond.begin();pos!=
mvpBond.end();++pos)
3009 if(pos->mNeedUpdateUI==
true)
3012 mpBondWin->SetCellValue(i, 0, wxString::FromAscii(pos->mAtom1.c_str()));
3013 mpBondWin->SetCellValue(i, 1, wxString::FromAscii(pos->mAtom2.c_str()));
3015 tmp.Printf(_T(
"%f"),pos->mLength);
3016 mpBondWin->SetCellValue(i, 2, tmp);
3017 tmp.Printf(_T(
"%f"),pos->mLength0);
3018 mpBondWin->SetCellValue(i, 3, tmp);
3019 tmp.Printf(_T(
"%f"),pos->mSigma);
3020 mpBondWin->SetCellValue(i, 4, tmp);
3021 tmp.Printf(_T(
"%f"),pos->mDelta);
3022 mpBondWin->SetCellValue(i, 5, tmp);
3033 if(pos->mNeedUpdateUI==
true)
3036 mpAngleWin->SetCellValue(i, 0, wxString::FromAscii(pos->mAtom1.c_str()));
3037 mpAngleWin->SetCellValue(i, 1, wxString::FromAscii(pos->mAtom2.c_str()));
3038 mpAngleWin->SetCellValue(i, 2, wxString::FromAscii(pos->mAtom3.c_str()));
3040 tmp.Printf(_T(
"%f"),pos->mAngle*RAD2DEG);
3041 mpAngleWin->SetCellValue(i, 3, tmp);
3042 tmp.Printf(_T(
"%f"),pos->mAngle0*RAD2DEG);
3043 mpAngleWin->SetCellValue(i, 4, tmp);
3044 tmp.Printf(_T(
"%f"),pos->mSigma*RAD2DEG);
3045 mpAngleWin->SetCellValue(i, 5, tmp);
3046 tmp.Printf(_T(
"%f"),pos->mDelta*RAD2DEG);
3047 mpAngleWin->SetCellValue(i, 6, tmp);
3053 if(0!=mpDihedralAngleWin)
3058 if(pos->mNeedUpdateUI==
true)
3061 mpDihedralAngleWin->SetCellValue(i, 0, wxString::FromAscii(pos->mAtom1.c_str()));
3062 mpDihedralAngleWin->SetCellValue(i, 1, wxString::FromAscii(pos->mAtom2.c_str()));
3063 mpDihedralAngleWin->SetCellValue(i, 2, wxString::FromAscii(pos->mAtom3.c_str()));
3064 mpDihedralAngleWin->SetCellValue(i, 3, wxString::FromAscii(pos->mAtom4.c_str()));
3066 tmp.Printf(_T(
"%f"),pos->mAngle*RAD2DEG);
3067 mpDihedralAngleWin->SetCellValue(i, 4, tmp);
3068 tmp.Printf(_T(
"%f"),pos->mAngle0*RAD2DEG);
3069 mpDihedralAngleWin->SetCellValue(i, 5, tmp);
3070 tmp.Printf(_T(
"%f"),pos->mSigma*RAD2DEG);
3071 mpDihedralAngleWin->SetCellValue(i, 6, tmp);
3072 tmp.Printf(_T(
"%f"),pos->mDelta*RAD2DEG);
3073 mpDihedralAngleWin->SetCellValue(i, 7, tmp);
3079 if(0!=mpRigidGroupWin)
3084 if(pos->mNeedUpdateUI==
true)
3087 mpRigidGroupWin->SetCellValue(i, 0, wxString::FromAscii(pos->mpGroup->GetName().c_str()));
3093 if(0!=mpNonFlipAtomWin)
3098 if(mpMolecule->GetCenterAtom()!=0)
3105 if(lock)
mMutex.Unlock();
3107 VFN_DEBUG_EXIT(
"WXMolecule::UpdateUI()",5)
3110 bool WXMolecule::Enable(
bool e)
3112 if(0!=mpAtomWin) mpAtomWin ->Enable(e);
3113 if(0!=mpBondWin) mpBondWin ->Enable(e);
3114 if(0!=mpAngleWin) mpAngleWin ->Enable(e);
3115 if(0!=mpDihedralAngleWin)mpDihedralAngleWin->Enable(e);
3116 if(0!=mpRigidGroupWin) mpRigidGroupWin ->Enable(e);
3117 return this->::wxWindow::Enable(e);
The namespace which includes all objects (crystallographic and algorithmic) in ObjCryst++.
void WXCrystValidateAllUserInput()
This function validates all user input (in a WXField) not yet taken into account, if needs be.
const RefParType * gpRefParTypeObjCryst
Top RefParType for the ObjCryst++ library.
void ExpandAtomGroupRecursive(MolAtom *atom, const map< MolAtom *, set< MolAtom * > > &connect, set< MolAtom * > &atomlist, const MolAtom *finalAtom)
Build recursively a list of atoms, starting from a one atom, and given a connectivity table.
T * WXDialogChooseFromRegistry(ObjRegistry< T > ®, 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.
MolAtom : atom inside a Molecule.
Bond between two atoms, also a restraint on the associated bond length.
Bond angle restraint between 3 atoms.
Abstract Base Class to describe the scattering power of any Scatterer component in a crystal.
Restraint: generic class for a restraint of a given model.
virtual const string & GetName() const
Name of the object.
Simple chronometer class, with microsecond precision.
output a number as a formatted integer:
output a number as a formatted float:
Class to automatically assign a unique wxID to each window.
Abstract base class for all objects in wxCryst.
CrystMutex mMutex
Mutex used to lock data when preparing to update the UI in non-main thread.
void OnToggleCollapse(wxCommandEvent &WXUNUSED(event))
Only display the title, and collapse everything else.
Class to pick one choice...
void SetValue(const string &)
Used by the owner to change the name of the choice.
wx class for MolAtom objects
wx class for MolBond objects
wx class for MolBondAngle objects
std::list< CellRigidGroup > mvpRigidGroup
Displayed list of Dihedral angles.
void NotifyDeleteListWin(WXMolScrolledWindow *win)
Notify that either the bond, bond angle or dihedral angle list window has been destroyed.
std::list< CellDihedralAngle > mvpDihedralAngle
Displayed list of Dihedral angles.
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...
WXFieldChoice * mpFieldCenterAtom
Center atom.
std::list< CellAtom > mvpAtom
Displayed list of atoms.
std::list< CellBondAngle > mvpBondAngle
Displayed list of bond angle.
std::list< CellBond > mvpBond
Displayed list of bonds, in the order they appear.
virtual void UpdateUI(const bool mutexlock=false)
Update the User Interface, if necessary.
bool mIsSelfUpdating
Flag to indicate whether we are updating values in the wxGrid data.
Structure to store the Atom parameters.
Structure to store the bond current values.
Structure to store the bond angles current values.
Structure to store the dihedral angles current values.
virtual void CrystUpdate(const bool updateUI=false, const bool mutexlock=false)
Get new values to be displayed from the underlying object, and raise flag if an UI update is necessar...
virtual void UpdateUI(const bool mutexlock=false)
Update the User Interface, if necessary.