[ghemical-devel] Avalanche of Love (Bond Constraints)

Donald Ephraim Curtis donald-curtis at uiowa.edu
Fri Mar 17 16:24:29 EST 2006


It is here, and I'm sure there is going to need to be some tweaks.  I'll 
try to make my English clear here so we're all on the same page.

I added constraints to libghemical.  This means there is now a 
'constraint' class that handles constraints between two bonds.  It 
*should* be able to handle torsions and all that other good chemistry 
stuff i have no idea about.  For now it only handles holding the atom 
distance constraints (i shouldn't say bond constraints cause you can 
constrain non-bonded atoms also.

So, the one thing to note is the engines.  engine.cpp handles bringing 
in the data to the engine, and so, no engine really HAS to use the 
constraints.  it's up to that specific engine whether it does or 
doesn't.  This is directed more at Tommi;  if you are afraid of these 
constraints effecting the calculations then we can make a modified 
engine that uses constraints.  However, if you don't constrain anything 
it doesn't effect anything, in fact no modifications to the specific 
engines need to be made to work in their original form (tripos52 and 
default).  When you constrain two "non-bonded" atoms, it treats them 
like they are bonded in the engine.  I am not sure of the effects of 
this, we (us here at uiowa) decided that would be a good solution as the 
constant on bonds overwrites any non-bonded attributes.

Take a look through the code and let me know what you think, it's a lot 
to swallow.

Also, in your graphics view you don't need to make a PopupHandler for 
each menu, they can all use the same one, you should be able to see 
that.  You have ChainsPopupHandler, ViewsPopupHandler.... etc etc and 
they could all use my generic PopupHandler easily.

Best Wishes,

Donald Ephraim Curtis
-------------- next part --------------
? src/constraint_dialog.cpp
? src/constraint_dialog.glade
? src/constraint_dialog.h
Index: src/Makefile.am
===================================================================
RCS file: /cvsroot/ghemical/src/Makefile.am,v
retrieving revision 1.2.2.3
diff -r1.2.2.3 Makefile.am
27a28
> 	constraint_dialog.h constraint_dialog.cpp \
47a49
> 	constraint_dialog.glade \
Index: src/gtk_graphics_view.cpp
===================================================================
RCS file: /cvsroot/ghemical/src/Attic/gtk_graphics_view.cpp,v
retrieving revision 1.11.2.1
diff -r1.11.2.1 gtk_graphics_view.cpp
177a178,179
> 	{ "ConstrainMenu", NULL, "_Constrain" },
> 	{ "ConstrainBondLength", NULL, "Constrain Bond Length...", NULL, "Constrain Bond Length...", (GCallback) gtk_project::popup_ConstrainBondLength },
346a349,351
> "    <menu action='ConstrainMenu'>"
> "      <menuitem action='ConstrainBondLength'/>"
> "    </menu>"
Index: src/gtk_project.cpp
===================================================================
RCS file: /cvsroot/ghemical/src/gtk_project.cpp,v
retrieving revision 1.8.2.4
diff -r1.8.2.4 gtk_project.cpp
38a39
> #include "constraint_dialog.h"
1111a1113,1122
> void gtk_project::popup_ConstrainBondLength(GtkWidget *, gpointer data)
> {
> 	gtk_graphics_view * gv = gtk_graphics_view::GetGV((GtkWidget *) data);
> 	gtk_project * prj = dynamic_cast<gtk_project *>(gv->prj);
> 	if (prj)
> 	{
> 		new constraint_dialog(prj);
> 	}
> }
> 
Index: src/gtk_project.h
===================================================================
RCS file: /cvsroot/ghemical/src/gtk_project.h,v
retrieving revision 1.10.2.2
diff -r1.10.2.2 gtk_project.h
216a217
> 	static void popup_ConstrainBondLength(GtkWidget *, gpointer);
Index: src/gtk_project_view.cpp
===================================================================
RCS file: /cvsroot/ghemical/src/Attic/gtk_project_view.cpp,v
retrieving revision 1.6.2.5
diff -r1.6.2.5 gtk_project_view.cpp
105a106,120
> // the constraints-menu...
> // ^^^^^^^^^^^^^^^^^
> 
> GtkActionEntry gtk_project_view::constraints_entries[] =
> {
> 	{ "constraints_DeleteConstraint", NULL, "_Delete Constraint", "<control>D", "Delete this constraint", (GCallback) gtk_project_view::constraints_DeleteConstraint },
> };
> 
> const char * gtk_project_view::constraints_ui_description =
> "<ui>"
> "  <popup name='gpvConstraintsMenu'>"
> "    <menuitem action='constraints_DeleteConstraint'/>"
> "  </popup>"
> "</ui>";
> 
318a334,375
> 
> 	// "constraints"-page
> 	constraints_store = gtk_list_store_new (4, G_TYPE_POINTER, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_FLOAT);
> 	constraints_widget = gtk_tree_view_new_with_model(GTK_TREE_MODEL(constraints_store));
> 	gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(constraints_widget), TRUE);
> 
> 	renderer = gtk_cell_renderer_text_new();	// index1
> 	column = gtk_tree_view_column_new_with_attributes("Atom Index #1", renderer, "text", 1, NULL);
> 	gtk_tree_view_append_column(GTK_TREE_VIEW(constraints_widget), column);
> 	
> 	renderer = gtk_cell_renderer_text_new();	// index2
> 	column = gtk_tree_view_column_new_with_attributes("Atom Index #2", renderer, "text", 2, NULL);
> 	gtk_tree_view_append_column(GTK_TREE_VIEW(constraints_widget), column);
> 	
> 	renderer = gtk_cell_renderer_text_new();	// length
> 	g_object_set(renderer, "editable", TRUE, NULL);
> 	g_signal_connect(GTK_OBJECT(renderer), "edited", G_CALLBACK(constraints_ModifyConstraint), (gpointer *) constraints_store);
> 	column = gtk_tree_view_column_new_with_attributes("Length", renderer, "text", 3, NULL);
> 	gtk_tree_view_append_column(GTK_TREE_VIEW(constraints_widget), column);
> 
> 	constraints_label = gtk_label_new("Constraints");
> 	constraints_sw = gtk_scrolled_window_new(NULL, NULL);
> 	gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(constraints_sw), GTK_SHADOW_ETCHED_IN);
> 	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(constraints_sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
> 	gtk_container_add(GTK_CONTAINER(constraints_sw), constraints_widget);
> 	gtk_notebook_append_page(GTK_NOTEBOOK(view_widget), constraints_sw, constraints_label);
> action_group = gtk_action_group_new("gpvConstraintsActions");
> gtk_action_group_add_actions(action_group, constraints_entries, G_N_ELEMENTS(constraints_entries), GTK_WIDGET(constraints_widget));
> gtk_ui_manager_insert_action_group(gtk_app::GetUIManager(), action_group, 0);
> error = NULL;
> if (!gtk_ui_manager_add_ui_from_string(gtk_app::GetUIManager(), constraints_ui_description, -1, & error))
> {
> 	g_message("Building gpv Constraints menu failed : %s", error->message);
> 	g_error_free(error); exit(EXIT_FAILURE);
> }
> constraints_menu = gtk_ui_manager_get_widget(gtk_app::GetUIManager(), "/gpvConstraintsMenu");
> g_signal_connect(GTK_OBJECT(constraints_widget), "button_press_event", G_CALLBACK(PopupHandler), constraints_menu);
> 
> 	gtk_widget_show(constraints_widget);
> 	gtk_widget_show(constraints_label);
> 	gtk_widget_show(constraints_sw);
> 	
1036a1094,1225
> void gtk_project_view::ConstraintAdded(constraint * p1)
> {
> 	/* for now this function should go through all
> 	 * the constraints.  why?  well, if two atoms are constrained
> 	 * then they get new values, not really added, modified
> 	 * and it doesn't make sense to check for that here.  there
> 	 * needs to be a rethinking here anyways *shrug*
> 	 */
> 	GtkTreeIter iter;
> 	gtk_project *prj = dynamic_cast<gtk_project*>(GetProject());
> 
> 	gtk_list_store_clear(constraints_store);
> 	for(iter_constl it1 = prj->GetConstraintsBegin(); it1 != prj->GetConstraintsEnd(); it1++)
> 	{
> 		gtk_list_store_append(constraints_store, &iter);
> 		gtk_list_store_set(constraints_store, &iter, 0, &(*it1), 1, (*it1).atmr[0]->index, 2, (*it1).atmr[1]->index, 3, (*it1).GetValue(), -1);
> 	}
> }
> 
> void gtk_project_view::ConstraintUpdateItem(constraint * p1)
> {
> 	GtkTreeIter iter;
> 	constraint *c1;
> 	gboolean valid;
> 	valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(constraints_store), &iter);
> 
> 	while ( valid )
> 	{
> 		gtk_tree_model_get(GTK_TREE_MODEL(constraints_store), &iter, 0, &c1, -1);
> 
> 		if( *c1 == *p1 ) 
> 		{
> 			gtk_list_store_set(constraints_store, &iter, 1, c1->atmr[0]->index, 2, c1->atmr[1]->index, 3, c1->GetValue(), -1);
> 			break;
> 		}
> 		valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(constraints_store), &iter);
> 	}
> }
> 
> void gtk_project_view::ConstraintRemoved(constraint * p1)
> {
> 	GtkTreeIter iter;
> 	constraint *c1;
> 	gboolean valid;
> 	valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(constraints_store), &iter);
> 
> 	while ( valid )
> 	{
> 		gtk_tree_model_get(GTK_TREE_MODEL(constraints_store), &iter, 0, &c1, -1);
> 
> 		if( *c1 == *p1 ) valid = gtk_list_store_remove(constraints_store, &iter);
> 		else valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(constraints_store), &iter);
> 	}
> }
> 
> // generic popup handler
> gint gtk_project_view::PopupHandler(GtkWidget * widget, GdkEvent * event, gpointer data)
> {
> 	if (event->type == GDK_BUTTON_PRESS)
> 	{
> 		GdkEventButton * event_button = (GdkEventButton *) event;
> 		if (event_button->button == 3)
> 		{
> 			// gtk_project_view * gpv = GetInstance(); 
> 			GtkMenu *menu = GTK_MENU(data);
> 			gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, event_button->button, event_button->time);
> 			return TRUE;
> 		}
> 	}
> 	
> 	return FALSE;
> }
> 
> void gtk_project_view::constraints_ModifyConstraint(GtkWidget * widget, gchar *path, gchar *value, gpointer data)
> {
> 	GtkTreeIter iter;
> 	constraint *c1;
> 	gtk_project_view *gpv = GetInstance();
> 
> 	gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(data), &iter, path);
> 
> 	gtk_tree_model_get(GTK_TREE_MODEL(data), &iter, 0, &c1, -1);
> 
> 	c1->SetValue(atof(value));
> 
> 	gtk_list_store_set(GTK_LIST_STORE(data), &iter, 3, c1->GetValue(), -1);
> 
> 	// we have to do this because our project has no function to update constraints
> 	// TODO: add functionality prj->UpdateConstraint( c1, val )
> 	gpv->prj->SystemWasModified();
> }
> 
> void gtk_project_view::constraints_DeleteConstraint(GtkWidget * widget, gpointer data)
> {
> 	printf("called\n");
> 	gtk_project_view * gpv = GetInstance();
> 
> 	GtkTreeSelection * sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(data));
> 
> 	// this call is the same as model = GK_TREE_MODEL(gpv->constraints_store)
> 	// we don't even need this anyways, we get it from the gk_tree_selection_get_selected
> 	//GtkTreeModel * model = gtk_tree_view_get_model(GTK_TREE_VIEW(data)); 
> 	
> 	GtkTreeModel *model;
> 	GtkTreeIter iter;
> 	constraint *c1;
> 	
> // assume that tsel is in mode GTK_SELECTION_SINGLE (as it seems to be); this is the simplest case...
> // here the equivalence test of GtkTreeIter is a bit uncertain... need to test any other records???
> 	
> 	bool has_item = gtk_tree_selection_get_selected(sel, & model, & iter);
> 	if (has_item)
> 	{
> 		gtk_tree_model_get(model, &iter, 0, &c1, -1);
> 
> 		printf("got c1: %d %d %f\n", c1->atmr[0]->index, c1->atmr[1]->index, c1->GetValue());
> 
> 		// *sigh* we have to find the iterator to remove
> 		for( iter_constl it1 = gpv->prj->GetConstraintsBegin(); 
> 	 	     it1 != gpv->prj->GetConstraintsEnd(); )
> 		{
> 			// tell our project to remove the constraint
> 			if( c1 == &(* it1) ) {
> 				gpv->prj->RemoveConstraint(it1); 
> 				it1 = gpv->prj->GetConstraintsBegin();
> 			}
> 			else { it1++; }
> 		}
> 
> 	}
> }
> 
Index: src/gtk_project_view.h
===================================================================
RCS file: /cvsroot/ghemical/src/Attic/gtk_project_view.h,v
retrieving revision 1.8.2.2
diff -r1.8.2.2 gtk_project_view.h
83a84,86
> 	static GtkActionEntry constraints_entries[];
> 	static const char * constraints_ui_description;
> 	
120a124,129
> 	GtkListStore * constraints_store;
> 	GtkWidget * constraints_widget;
> 	GtkWidget * constraints_label;
> GtkWidget * constraints_menu;
> 	GtkWidget * constraints_sw;
> 	
171a181,187
> 
> 	void ConstraintAdded(constraint *);				// virtual
> 	void ConstraintUpdateItem(constraint *);			// virtual
> 	void ConstraintRemoved(constraint *);			// virtual
> 	static gint PopupHandler(GtkWidget *, GdkEvent *, gpointer);
> 	static void constraints_ModifyConstraint(GtkWidget * , gchar *, gchar *, gpointer );
> 	static void constraints_DeleteConstraint(GtkWidget *, gpointer);
Index: src/project.cpp
===================================================================
RCS file: /cvsroot/ghemical/src/project.cpp,v
retrieving revision 1.53.2.9
diff -r1.53.2.9 project.cpp
462a463,474
> void project::AddConstraint(constraint & p1)
> {
> 	model::AddConstraint(p1);
> 	if( pv != NULL) pv->ConstraintAdded(& constraint_list.back());
> }
> 
> void project::RemoveConstraint(iter_constl p1)
> {
> 	if (pv != NULL) pv->ConstraintRemoved(& (* p1));
> 	model::RemoveConstraint(p1);
> }
> 
3399a3412
> 				for (iter_constl it1 = constraint_list.begin();it1 != constraint_list.end();it1++) if (pv != NULL) pv->ConstraintUpdateItem(& (* it1));
Index: src/project.h
===================================================================
RCS file: /cvsroot/ghemical/src/project.h,v
retrieving revision 1.33.2.2
diff -r1.33.2.2 project.h
250a251,253
> 	void AddConstraint(constraint &);		// virtual
> 	void RemoveConstraint(iter_constl);	// virtual
> 	
Index: src/views.h
===================================================================
RCS file: /cvsroot/ghemical/src/Attic/views.h,v
retrieving revision 1.15
diff -r1.15 views.h
125a126,129
> 
> 	virtual void ConstraintAdded(constraint *) = 0;
> 	virtual void ConstraintUpdateItem(constraint *) = 0;	///< updates the properties of an existing object.
> 	virtual void ConstraintRemoved(constraint *) = 0;
-------------- next part --------------
? src/constraint.cpp
? src/constraint.h
Index: src/Makefile.am
===================================================================
RCS file: /cvsroot/libghemical/src/Makefile.am,v
retrieving revision 1.10
diff -r1.10 Makefile.am
9a10
> 	constraint.h constraint.cpp \
46a48
> 	constraint.h \
Index: src/atom.cpp
===================================================================
RCS file: /cvsroot/libghemical/src/atom.cpp,v
retrieving revision 1.13
diff -r1.13 atom.cpp
415a416,427
> bool atom::GetSelected() const
> {
> 	if (flags & ATOMFLAG_USER_SELECTED) return true;
> 	return false;
> }
> 
> void atom::SetSelected(bool l)
> {
> 	if(l) flags |= ATOMFLAG_USER_SELECTED;
> 	else flags &= ~ATOMFLAG_USER_SELECTED;
> }
> 
Index: src/atom.h
===================================================================
RCS file: /cvsroot/libghemical/src/atom.h,v
retrieving revision 1.22
diff -r1.22 atom.h
183,184c183,184
< 	bool GetLocked(void) const;
< 	void SetLocked(bool);
---
> 	bool GetSelected(void) const;
> 	void SetSelected(bool);
187a188,190
> 
> 	bool GetLocked(void) const;
> 	void SetLocked(bool);
Index: src/eng1_mm.h
===================================================================
RCS file: /cvsroot/libghemical/src/eng1_mm.h,v
retrieving revision 1.19
diff -r1.19 eng1_mm.h
25a26
> #include "constraint.h"
Index: src/eng1_mm_default.cpp
===================================================================
RCS file: /cvsroot/libghemical/src/eng1_mm_default.cpp,v
retrieving revision 1.27
diff -r1.27 eng1_mm_default.cpp
37a38
> 	constraint ** consttab = GetSetup()->GetConstraints();
56c57
< 	
---
> 
> 		// check constraints - if it's constrained, then set the optimal distance.
> 		for (i32s n2 = 0;n2 < GetSetup()->GetConstraintCount();n2++)
> 		{
> 			if( (consttab[n2]->atmr[0] == bndtab[n1]->atmr[0] && 
> 			   consttab[n2]->atmr[1] == bndtab[n1]->atmr[1]) ||
> 			   (consttab[n2]->atmr[0] == bndtab[n1]->atmr[1] && 
> 			   consttab[n2]->atmr[1] == bndtab[n1]->atmr[0]) )
> 			{
> 				newbt1.opt = consttab[n2]->GetValue();
> 				break;
> 			}
> 		}
> 
117a133,215
> 	// again, here we're treating non-bonded atoms as bonded IF they 
> 	// are not connected.  *NOTE* i need a better way to do this.
> 	for (i32s n1 = 0;n1 < GetSetup()->GetConstraintCount();n1++)
> 	{
> 		bool bond_check = false;
> 		for (i32s n2 = 0;n2 < GetSetup()->GetMMBondCount();n2++)
> 		{
> 			// check constraints agaist bondedness
> 			if( (consttab[n1]->atmr[0] == bndtab[n2]->atmr[0] && 
> 			   consttab[n1]->atmr[1] == bndtab[n2]->atmr[1]) ||
> 			   (consttab[n1]->atmr[0] == bndtab[n2]->atmr[1] && 
> 			   consttab[n1]->atmr[1] == bndtab[n2]->atmr[0]) )
> 			{
> 				bond_check=true;
> 				break;
> 			}
> 		}
> 
> 		if(bond_check) { continue; }
> 
> 		i32s local_ind1 = 0;
> 		while (local_ind1 < GetSetup()->GetMMAtomCount())
> 		{
> 			if (atmtab[local_ind1] == consttab[n1]->atmr[0]) break;
> 			else local_ind1++;
> 		}
> 		if (local_ind1 >= GetSetup()->GetMMAtomCount())
> 		{
> 			cout << "BUG: local_ind1 search failed!" << endl;
> 			exit(EXIT_FAILURE);
> 		}
> 		
> 		i32s local_ind2 = 0;
> 		while (local_ind2 < GetSetup()->GetMMAtomCount())
> 		{
> 			if (atmtab[local_ind2] == consttab[n1]->atmr[1]) break;
> 			else local_ind2++;
> 		}
> 		if (local_ind2 >= GetSetup()->GetMMAtomCount())
> 		{
> 			cout << "BUG: local_ind2 search failed!" << endl;
> 			exit(EXIT_FAILURE);
> 		}
> 		
> 		mm_default_bt1 newbt1;
> 		newbt1.atmi[0] = local_ind1;		// this is a local index...
> 		newbt1.atmi[1] = local_ind2;		// this is a local index...
> 		
> 		bool success = false;
> 		if (dynamic_cast<setup1_mm *>(GetSetup())->EnableExceptions())
> 		{
> 			i32s bt = BONDTYPE_SINGLE;
> 			
> 			success = default_tables::GetInstance()->e_Init(this, & newbt1, bt);
> 		}
> 		else
> 		{
> 			default_bs_query query; query.strict = false;
> 			query.atmtp[0] = atmtab[newbt1.atmi[0]]->atmtp;
> 			query.atmtp[1] = atmtab[newbt1.atmi[1]]->atmtp;
> 			query.bndtp = BONDTYPE_SINGLE;
> 			
> 			default_tables::GetInstance()->DoParamSearch(& query);
> 			if (query.index != NOT_DEFINED) success = true;
> 
> 			newbt1.opt = query.opt;
> 
> 			newbt1.fc = query.fc;
> 		}
> 
> 
> 		newbt1.opt = consttab[n1]->GetValue();
> 
> 	// write temporary index information into the bond objects; this is needed below and is just for convenience.
> 	// write temporary index information into the bond objects; this is needed below and is just for convenience.
> 	// write temporary index information into the bond objects; this is needed below and is just for convenience.
> 		
> 		// This shouldn't be used.
> 		//bndtab[n1]->tmp_bt1_index = bt1_vector.size();	// the bond objects are modified here!!!
> 		
> 		bt1_err += !success;
> 		bt1_vector.push_back(newbt1);
> 	}
Index: src/eng1_mm_default.h
===================================================================
RCS file: /cvsroot/libghemical/src/eng1_mm_default.h,v
retrieving revision 1.14
diff -r1.14 eng1_mm_default.h
68a69,70
> 	
> 	bool constraint;
Index: src/eng1_mm_tripos52.cpp
===================================================================
RCS file: /cvsroot/libghemical/src/eng1_mm_tripos52.cpp,v
retrieving revision 1.10
diff -r1.10 eng1_mm_tripos52.cpp
60a61,107
> 
> 		// check constraints - if it's constrained, then set the optimal distance.
> 		for (iter_constl it2 = mdl->GetConstraintsBegin(); it2 != mdl->GetConstraintsEnd(); it2++)
> 		{
> 			if( ((*it2).atmr[0] == (*it1).atmr[0] && 
> 			   (*it2).atmr[1] == (*it1).atmr[1]) ||
> 			   ((*it2).atmr[0] == (*it1).atmr[1] && 
> 			   (*it2).atmr[1] == (*it1).atmr[0]) )
> 			{
> 				newbt1.opt = (*it2).GetValue();
> 				break;
> 			}
> 		}
> 
> 		bt1_vector.push_back(newbt1);
> 	}
> 
> 	// again, here we're treating non-bonded atoms as bonded IF they 
> 	// are not connected.  *NOTE* i need a better way to do this.
> 	for (iter_constl it1 = mdl->GetConstraintsBegin(); it1 != mdl->GetConstraintsEnd(); it1++)
> 	{
> 		bool bond_check = false;
> 		for (iter_bl it2 = mdl->GetBondsBegin();it2 != mdl->GetBondsEnd();it2++)
> 		{
> 			// check constraints agaist bondedness
> 			if( ((*it1).atmr[0] == (*it2).atmr[0] && 
> 			   (*it1).atmr[1] == (*it2).atmr[1]) ||
> 			   ((*it1).atmr[0] == (*it2).atmr[1] && 
> 			   (*it1).atmr[1] == (*it2).atmr[0]) )
> 			{
> 				bond_check=true;
> 				break;
> 			}
> 		}
> 
> 		if(bond_check) { continue; }
> 
> 		mm_tripos52_bt1 newbt1;
> 		newbt1.atmi[0] = (* it1).atmr[0]->index;
> 		newbt1.atmi[1] = (* it1).atmr[1]->index;
> 		
> 		i32s bt = BONDTYPE_SINGLE;
> 		
> 		bt1_err += !tripos52_tables::GetInstance()->Init(this, & newbt1, bt);
> 
> 		newbt1.opt = (*it1).GetValue();
> 
Index: src/eng1_qm.h
===================================================================
RCS file: /cvsroot/libghemical/src/eng1_qm.h,v
retrieving revision 1.9
diff -r1.9 eng1_qm.h
22a23
> #include "constraint.h"
Index: src/engine.cpp
===================================================================
RCS file: /cvsroot/libghemical/src/engine.cpp,v
retrieving revision 1.22
diff -r1.22 engine.cpp
26a27
> 	consttab = NULL; nconst = NOT_DEFINED;
50a52
> 	if (consttab != NULL) { delete[] consttab; consttab = NULL;}
262a265,270
> 
> 	nconst = 0;
> 	consttab = new constraint*[mdl->GetConstraintCount()];
> 	iter_constl itc = mdl->GetConstraintsBegin();
> 	while (itc != mdl->GetConstraintsEnd())
> 	{ consttab[nconst++] = &(* itc++); }
Index: src/engine.h
===================================================================
RCS file: /cvsroot/libghemical/src/engine.h,v
retrieving revision 1.32
diff -r1.32 engine.h
28a29
> class constraint;	// constraint.h
71a73,74
> 
> 	constraint ** consttab; i32s nconst;
86a90,92
> 
> 	constraint ** GetConstraints(void) { return consttab; }
> 	i32s GetConstraintCount(void) { return nconst; }
Index: src/model.cpp
===================================================================
RCS file: /cvsroot/libghemical/src/model.cpp,v
retrieving revision 1.66
diff -r1.66 model.cpp
616a617,624
> 
> 	// remove any constraints that are impacted by the atom removal 
> 	iter_constl it2;
> 	while((it2 = FindAtomConstraint((* it1))) != constraint_list.end())
> 	{
> 	//	it2 = FindAtomConstraint((* it1));
> 		RemoveConstraint(it2);
> 	}
631a640,648
> iter_constl model::FindAtomConstraint(atom & p1)
> {
> 	for(iter_constl it2 = constraint_list.begin(); it2 != constraint_list.end(); it2++ )
> 	{
> 		if( (* it2).atmr[0] == &p1 || (* it2).atmr[1] == &p1 ) { return it2; }
> 	}
> 	
> }
> 
694a712,757
> void model::AddConstraint(constraint & p1)
> {
> 	if (p1.atmr[0] == p1.atmr[1])
> 	{
> 		cout << "BUG1: tried to add an invalid constraint at model::AddConstraint()!" << endl;
> 		exit(EXIT_FAILURE);
> 	}
> 
> 	for(iter_constl it1 = GetConstraintsBegin(); it1 != GetConstraintsEnd(); it1++)
> 	{
> 		if( ((* it1).atmr[0] == p1.atmr[0] && (* it1).atmr[1] == p1.atmr[1]) ||
> 		    ((* it1).atmr[1] == p1.atmr[0] && (* it1).atmr[0] == p1.atmr[1]) )
> 		{
> 			SystemWasModified();
> 			(* it1).SetValue(p1.GetValue());
> 			// delete &p1;
> 			return;
> 		}
> 	}
> 	
> 	// not sure if we need this but it makes sense so i'll leave it -dc
> 	if (p1.atmr[0]->mdl != p1.atmr[1]->mdl || p1.atmr[0]->mdl == NULL)
> 	{
> 		//cout << "BUG2: tried to add an invalid bond at model::AddBond()!" << endl;
> 		//exit(EXIT_FAILURE);
> 		
> 		cout << "AddBond mdl check ; " << p1.atmr[0]->mdl << " " << p1.atmr[1]->mdl << endl;
> 	}
> 	
> 	SystemWasModified();
> 	
> 	constraint_list.push_back(p1);
> 
> 	return;
> 	
> }
> 
> void model::RemoveConstraint(iter_constl it1)
> {
> 	SystemWasModified();
> 	
> 	constraint_list.erase(it1);
> 
> 	return;
> }
> 
759a823,829
> 
> 	// do this last as ideally removing the atoms should get all the constraints
> 	while (!constraint_list.empty())
> 	{
> 		iter_constl it1 = constraint_list.begin();
> 		RemoveConstraint(it1);
> 	}
Index: src/model.h
===================================================================
RCS file: /cvsroot/libghemical/src/model.h,v
retrieving revision 1.48
diff -r1.48 model.h
65a66
> 	list<constraint> constraint_list;
227a229,232
> 	virtual iter_constl model::FindAtomConstraint(atom &);
> 	virtual void AddConstraint(constraint &);		///< This will add neighbor infos for both atoms and add the new bond into the bond list.
> 	virtual void RemoveConstraint(iter_constl);	///< This will remove infos from the atoms and erase bond from the bond list.
> 
241a247,249
> 	iter_constl GetConstraintsBegin(void) { return constraint_list.begin(); }	//const;
> 	iter_constl GetConstraintsEnd(void) { return constraint_list.end(); }		//const;
> 	
243a252
> 	constraint & GetLastConstraint(void) { return constraint_list.back(); }
255a265
> 	i32s GetConstraintCount(void) { return constraint_list.size(); }	///< This will return constraint_list.size().
Index: src/seqbuild.h
===================================================================
RCS file: /cvsroot/libghemical/src/seqbuild.h,v
retrieving revision 1.12
diff -r1.12 seqbuild.h
29a30
> #include "constraint.h"
Index: src/typerule.h
===================================================================
RCS file: /cvsroot/libghemical/src/typerule.h,v
retrieving revision 1.7
diff -r1.7 typerule.h
22a23
> #include "constraint.h"
Index: src/utility.h
===================================================================
RCS file: /cvsroot/libghemical/src/utility.h,v
retrieving revision 1.9
diff -r1.9 utility.h
21a22
> #include "constraint.h"
-------------- next part --------------
// CONSTRAINT.CPP

// Copyright (C) 1998 Tommi Hassinen.

// This program is free software; you can redistribute it and/or modify it
// under the terms of the license (GNU GPL) which comes with this package.

/*################################################################################################*/

#include "constraint.h"

/*################################################################################################*/

constraint::constraint(void)
{
	atmr[0] = atmr[1] = NULL;
	value = 0.0;
}

constraint::constraint(atom * p1, atom * p2, float p3)
{
	atmr[0] = p1; atmr[1] = p2;
	value = p3;
}

constraint::constraint(const constraint & p1)
{
	atmr[0] = p1.atmr[0]; atmr[1] = p1.atmr[1]; 
	value = p1.value;
}

constraint::~constraint(void)
{
}

bool constraint::operator==(const constraint & p1) const
{
	if (atmr[0] == p1.atmr[0] && atmr[1] == p1.atmr[1] && value == p1.value ) return true;
	if (atmr[0] == p1.atmr[1] && atmr[1] == p1.atmr[0] && value == p1.value ) return true;
	
	return false;
}

float constraint::GetValue() const
{
	return value;
}

void constraint::SetValue(const float p1)
{
	value = p1;
}

/*################################################################################################*/

// eof
-------------- next part --------------
// CONSTRAINT.H : the constraint-related classes.

// Copyright (C) 1998 Tommi Hassinen.

// This program is free software; you can redistribute it and/or modify it
// under the terms of the license (GNU GPL) which comes with this package.

/*################################################################################################*/

#ifndef CONSTRAINT_H
#define CONSTRAINT_H

#include "libghemicaldefine.h"
//#include "libghemicalconfig2.h"

/*################################################################################################*/

class atom;	// atom.h

#include "typedef.h"

#include <list>
#include <vector>
using namespace std;

/*################################################################################################*/

class constraint
{
	public:		// TODO : not properly divided in public/protected data.
	
	atom * atmr[2];
	
	
/// A temporary variable used when creating molecular mechanics energy terms.
/** This variable is not otherwise used or initialized, and it is not saved. */
	
	public:
	
	constraint(void);
	constraint(atom *, atom *, float);
	constraint(const constraint &);
	~constraint(void);

	//bool operator<(const constraint &) const;	///< Using molecule numbers.
	bool operator==(const constraint &) const;	///< Using all.

	float GetValue(void) const;
	void SetValue(const float);

	private:

	float value;
};

/*################################################################################################*/

typedef list<constraint>::iterator iter_constl;		// constl = constraint list

typedef constraint * ref_constraint;

/*################################################################################################*/

#endif	// CONSTRAINT_H

// eof
-------------- next part --------------
// GAMESS_DIALOG.CPP

// Copyright (C) 2002 Tommi Hassinen.

// This program is free software; you can redistribute it and/or modify it
// under the terms of the license (GNU GPL) which comes with this package.

/*################################################################################################*/

#include "filetrans.h"
#include "constraint_dialog.h"

#include <ghemical/eng1_mm.h>

#include <iostream>
#include <sstream>
#include <string>


#include <gtk/gtk.h>
using namespace std;


constraint_dialog::constraint_dialog(gtk_project * p1) : glade_dialog("glade/constraint_dialog.glade")
{
	prj = p1;
	dialog = glade_xml_get_widget(xml, "constraint_dialog");
	if (dialog == NULL) { cout << "constraint_dialog : glade_xml_get_widget() failed!!!" << endl; return; }
	
	// connect the handlers...
	

	    GtkWidget * option_menu;
	    unsigned int i;

	    glade_xml_signal_connect_data(xml, "on_constraint_ok_clicked", (GtkSignalFunc) handler_ButtonOk, (gpointer)this);
	    glade_xml_signal_connect_data(xml, "on_constraint_cancel_clicked", (GtkSignalFunc) handler_ButtonCancel, (gpointer)this);

	setup1_mm * owner = dynamic_cast<setup1_mm *>(prj->GetCurrentSetup());
	if (owner != NULL)
	{
		// do we need this anymore?
		// owner->UpdateIndex();

		// collect our selected atoms
		iter_al it1;
		int count = 0;
		for(it1 = prj->GetAtomsBegin(); 
				it1 != prj->GetAtomsEnd() && count <= 4;
				it1++)
		{
			if( (*it1).GetSelected() ) {
				atoms[count] = &(*it1);
				printf("%d - %d\n", atoms[count]->index, (*it1).index);
				count++;
			}
		}

		if( count != 2 )
		{
			prj->PrintToLog("Please select exactly two atoms.\n");
			gtk_widget_destroy(dialog);
			return;
		}
		/*
		else
		{

			iter_mm1cl it2;
			bonded = false;
			*/
			/* check if the atoms are bonded, this is for gamess input */
			/*
			for(it2 = atoms[0]->cr_list.begin(); 
					it2 !=  atoms[0]->cr_list.end();
					it2++)
			{
				if( it2->atmr->index == atoms[1]->index ) {
					bonded = true;
					break;
				}
			}
			if( it2 == atoms[0]->cr_list.end() )
			{
				prj->PrintToLog("Atoms must be connected\n");
				gtk_widget_destroy(dialog);
				return;
			}
			*/
		/*
		}
		*/
			

	}
	
		
	// gnome_dialog_run(GNOME_DIALOG(dialog));		// MODAL
	gtk_dialog_run(GTK_DIALOG(dialog));	// MODAL
	// gtk_widget_destroy(dialog);		// MODAL
}

constraint_dialog::~constraint_dialog()
{
}


void constraint_dialog::handler_ButtonOk(GtkWidget *widget, gpointer data)
{
	constraint_dialog * ref = (constraint_dialog *) data;
	cout << "handler_ButtonOK() : ref = " << ref << endl;

	GtkWidget *constraint_value = glade_xml_get_widget(ref->xml, "constraint_value");
	
	setup1_mm * owner = dynamic_cast<setup1_mm *>(ref->prj->GetCurrentSetup());
	if (!owner) cout << "ERROR: cast failed in constraint_dialog::handler_ButtonOK()." << endl;

	if (owner != NULL)
	{
		f64 f = 0.0;
		const gchar * buffer;
		buffer = gtk_entry_get_text(GTK_ENTRY(constraint_value)); 
		printf("buffer: %s\n", buffer);
		f = atof(buffer);
		printf("Got f:%f\n", f);
		if( f != 0.0 )
		{
			/* convert from angstroms to nm */
			f = f/10;
			constraint c(ref->atoms[0], ref->atoms[1], f);
			ref->prj->AddConstraint(c);
			printf("Added Constraint %d - %d - %f\n", ref->atoms[0]->index, ref->atoms[1]->index, f);
		}

	}

	
	printf("Constraint List:\n");

	for(iter_constl it1 = ref->prj->GetConstraintsBegin();
			it1 != ref->prj->GetConstraintsEnd();
			it1++ )
	{
		//printf(".\n");
		printf("%d - %d - %f\n", (*it1).atmr[0]->index, (*it1).atmr[1]->index, (*it1).GetValue());
		
	}
	gtk_widget_destroy(ref->dialog);

}

void constraint_dialog::handler_ButtonCancel(GtkWidget *widget, gpointer data)
{
	constraint_dialog * ref = (constraint_dialog *) data;
	cout << "handler_ButtonCancel() : ref = " << ref << endl;
	
	// close the dialog...
	//
	
	gtk_widget_destroy(ref->dialog);
}

/*################################################################################################*/

// eof
-------------- next part --------------
A non-text attachment was scrubbed...
Name: constraint_dialog.glade
Type: text/xml
Size: 6114 bytes
Desc: not available
Url : http://bioinformatics.org/pipermail/ghemical-devel/attachments/20060317/63ba50c2/constraint_dialog-0001.xml
-------------- next part --------------
// CONFIG_MM1_DIALOG.H : write a short description here...

// Copyright (C) 2002 Tommi Hassinen.

// This program is free software; you can redistribute it and/or modify it
// under the terms of the license (GNU GPL) which comes with this package.

/*################################################################################################*/

#ifndef CONSTRAINT_DIALOG_H
#define CONSTRAINT_DIALOG_H

#include <gtk/gtk.h>
#include <glade/glade.h>
#include "glade_dialog.h"
#include "gtk_project.h"
#include "filetrans.h"

class constraint_dialog;

/*################################################################################################*/

class constraint_dialog : public glade_dialog
{
	protected:
	
	GtkWidget * dialog;
	gtk_project * prj;
	
	atom *atoms[4];

	public:
	static ostringstream backupstr;
	static int charge;
	
	constraint_dialog(gtk_project *);
	~constraint_dialog(void);

	static void handler_ButtonOk(GtkWidget *, gpointer);
	static void handler_ButtonCancel(GtkWidget *, gpointer);

};

/*################################################################################################*/

#endif	// CONSTRAINT_DIALOG_H

// eof


More information about the ghemical-devel mailing list