construct a new Molecule

User dfeb81947d

05-04-2005 16:02:33

Hello everybody,





I have a table of MolAtom, MolBond and CEdge.


How could I construct a new Molecule from those tables?


Is the order of each element in the table is important?


For example, could I sort randomly the atoms and/or the bonds and/or the edges?





Thank you very much for your answer.


Best Regards


Jacques

ChemAxon fb166edcbd

07-04-2005 10:43:26

I am not sure what you mean by "table of MolAtom, MolBond and CEdge", in this answer I assume that you have an array of MolAtoms and an array of MolBonds. In this case you can simply add these by





Code:
CGraph.add(CNode node)



http://www.chemaxon.com/marvin/doc/api/chemaxon/struc/CGraph.html#add(chemaxon.struc.CNode)





and





Code:
CGraph.add(CEdge edge)



http://www.chemaxon.com/marvin/doc/api/chemaxon/struc/CGraph.html#add(chemaxon.struc.CEdge)





to a Molecule object simply created by its default constructor:





Code:
Molecule()



http://www.chemaxon.com/marvin/doc/api/chemaxon/struc/Molecule.html#Molecule()





or created based on another Molecule object by:





Code:
Molecule.newInstance()



http://www.chemaxon.com/marvin/doc/api/chemaxon/struc/Molecule.html#newInstance()





which copies the origin coordinates and the moelcule dimension.





The order is not important but it is better to add the endpoint nodes of an edge before adding the edge itself.





Please write if this has not answered all your questions.

User dfeb81947d

07-04-2005 17:09:31

Hi,





thank you for your help





so this should work:


Code:



CEdge[] edge = mol.getEdgeArray();


Molecule newM = new Molecule();


for (int i=edge.length-1;i==0;i--) {


   newM.add(edge[i]);


}






or this





Code:



MolAtom atom = mol.getAtomArray();


Molecule newM2 = new Molecule();


for (i=atom.length-1;i==0;i--) {


   newM2.add(atom[i]);


}


System.out.println(newM2.toFormat("mol"));



but actually it gives an empty molecule.





I think there is something I didn't understood.


Sorry for those questions about structures of molecular graph.





Best Regards

ChemAxon fb166edcbd

07-04-2005 18:55:14

The main problem is a typing mistake in your loop condition


("i==0" -> "i>=0"):


instead of


Code:



for (i=atom.length-1;i==0;i--) {


   newM2.add(atom[i]);


}





you should write


Code:



for (i=atom.length-1;i>=0;i--) {


   newM2.add(atom[i]);


}





because you get an empty loop with the "i==0" condition.





If you just want to copy the molecule then simply use


Code:



Molecule newM2 = (Molecule) mol.clone();








Another possible problem in your code segment is that if you add atoms / bonds of a molecule to another molecule then your original molecule will be corrupted, since atom / bond objects can only belong to one molecule object at a time. If you want to keep the original molecule as well, then clone() its atoms:


Code:



for (i=atom.length-1;i>=0;i--) {


   newM2.add((MolAtom) atom[i].clone());


}





However, this is problematic if you want to add the bonds since you cannot easily identify the previously cloned copy of its endpoint atoms. Therefore for the bonds I suggest that you should read the btab or ctab returned by


Code:
CGraph.getBtab()
and
Code:
CGraph.getCtab()



http://www.chemaxon.com/marvin/doc/api/chemaxon/struc/CGraph.html#getBtab()


http://www.chemaxon.com/marvin/doc/api/chemaxon/struc/CGraph.html#getCtab()


and create new bonds with the new atoms and with bond type returned by


Code:
MolBond.getType()



http://www.chemaxon.com/marvin/doc/api/chemaxon/struc/MolBond.html#getType():


Code:



MolBond bond = new MolBond(atom1, atom2);


bond.setType(type);


newM2.add(bond);





See


http://www.chemaxon.com/marvin/doc/api/chemaxon/struc/MolBond.html#setType(int)


Note that atom1 and atom2 should be added beforehand and to identify atoms in the new and the original molecule it is useful to preserve the atom order by previously adding atoms according to their original order:





Code:



for (i=0;i<atom.length;i++) {


   newM2.add((MolAtom) atom[i].clone());


}








If you give some more details about the purpose of your code then I can write you some specific example code.

User dfeb81947d

08-04-2005 08:54:20

in fact, my goal was to create a molfile from a molfile through a Molecule object whose atoms order (in atom table) is different from the original one (with the connectivity table follow the new order of the atoms)


for example I want to convert :
Quote:



Marvin 04080510502D





3 2 0 0 0 0 999 V2000


-3.8125 0.8438 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0


-3.0980 1.2563 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0


-3.0980 2.0813 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0


1 2 1 0 0 0 0


2 3 2 0 0 0 0


M END
into
Quote:



Marvin 04080510512D





3 2 0 0 0 0 999 V2000


-1.1250 0.5625 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0


-0.3000 0.5625 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0


0.1125 -0.1520 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0


1 2 2 0 0 0 0


2 3 1 0 0 0 0


M END
with using a java method to randomly shuffle the order of the atom table and connectivity table of a molecule.





Best Regards


Jacques

User dfeb81947d

08-04-2005 09:57:18

if I do like that:


Code:
   private static String randomizeAtomsBonds(Molecule mol) {


      int i = 0;


      Molecule newM = new Molecule();


      MolAtomt[] a = randomizeArray(mol.getAtomArray());


      for (i=0;i<a.length;i++) {


         newM.add(a[i]);


      }


      CEdge e = mol.getEdgeArray();


      for (i=0;i<e.length;i++) {


         newM.add(e[i]);


      }


      return newM.toFormat("mol");


   }





it works well.


But the connectivity table is also shuffle without any order.


For exemple the first atom linked to the second don't seems to have the connectivity description on the first line.





Is it possible to separate the molecule into all of his functionnal group and to reassemble them in a random order?





Thnak you very much for your help.

ChemAxon fb166edcbd

08-04-2005 21:08:53

Your code will make a similar molecule to the original one. The only difference will be the atom order but the molecule will represent the same chemical structure as the original one. If you want to shuffle the atoms and keep the bond table in the sense that the i-th atom is connected to the j-th atom in the new molecule if and only if the i-th atom is connected to the j-th atom in the original molecule then you need to create a new bond in place of each original bond because the endpoint atoms will be different. I attach a test code with a test molecule:





Code:



 java MolTest test.mol > output.mol








You can see that the molecule structures and the atom orders are different while the bond tables is the same. Instead of random reordering I simply reversed the atom order.


I added the atom clones instead of the original atoms to preserve the integrity of the original molecule.





I do not understand your second question:
Jacques wrote:



Is it possible to separate the molecule into all of his functionnal group and to reassemble them in a random order?


What do you mean on "functional group"?





You can use


Code:



Molecule.convertToFrags()





http://www.chemaxon.com/marvin/doc/api/chemaxon/struc/Molecule.html#convertToFrags()





to convert a molecule to an array of its connected fragments and then use


Code:



CGraph.fuse(CGraph)





http://www.chemaxon.com/marvin/doc/api/chemaxon/struc/CGraph.html#fuse(chemaxon.struc.CGraph)





to fuse some or all of these parts to a new molecule:





Code:



Molecule m = mol.newInstance();


Molecule[] frags = mol.convertToFrags();


shuffleFragments(frags); // shuffle the array in some way


for (int i=0; i < frags.length; ++i) {


      m.fuse(frags[i]);


}








Note, that the original molecule cannot be used after calling convertToFrags() because its atoms are moved to the created fragment molecules.

ChemAxon fb166edcbd

08-04-2005 21:38:39

Back to your original code: if you want to shuffle the atoms and keep the original bonds, that is, preserve the chemical structure while adjusting the bond table to the new atom order, then your code will exactly do that. I also modified my test code to do the same and borrowed your test molecule:





Code:



java MolTest test.mol > output.mol








For me the order of the lines bond table looks the same, ie, correspond to each other:





test.mol:


Code:



 


  Marvin  04080523252D


 


  3  2  0  0  0  0            999 V2000


   -1.1184   -0.0066    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0


   -0.7928    1.0164    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0


   -1.8914    0.9540    0.0000 O   0  0  0  0  0  0  0  0  0  0  0  0


  1  2  1  0  0  0  0


  2  3  2  0  0  0  0


M  END








output.mol:


Code:



 


  Marvin  04080523252D


 


  3  2  0  0  0  0            999 V2000


   -1.4535    0.7331    0.0000 O   0  0  0  0  0  0  0  0  0  0  0  0


   -0.6092    0.7811    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0


   -0.8595   -0.0051    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0


  3  2  1  0  0  0  0


  2  1  2  0  0  0  0


M  END








and also tested with some other inputs and always happened like this.


Although there is no official guarantee, in our MolExport code the bonds are written according to their order in the bond array. Therefore if you add the bonds to the new molecule in the same order then the bond order in the two bond tables should correspond to each other.





I attach this test code and test molecules.

User dfeb81947d

11-04-2005 10:52:13

Hi,





Thank you for your help.
Nora wrote:
then you need to create a new bond in place of each original bond because the endpoint atoms will be different
actually I wanted a molecules which is exactly the same as the first one, but which molfile is different with tha atoms order.


But thanks to this code I understand much better how Molecular Graph works.
Nora wrote:



I do not understand your second question:
Jacques wrote:



Is it possible to separate the molecule into all of his functionnal group and to reassemble them in a random order?


What do you mean on "functional group"?


I was thinking about chemical fragment that compose a molecule (phenol, benzyl, alkyl, ...) which are not disconnected.


I cut the original molecule into those chemical part, and reassemble them into an other order.


the purpose is still to have a molecule that is the same as the first one but with the order of the atoms different than the first one.


But in that way there is a logic in linking the different groups together.





your last test code looks the same as mine... is it on purpose?





Thank you again for your help.

ChemAxon fb166edcbd

11-04-2005 15:24:09

Quote:



Your last test code looks the same as mine... is it on purpose?


Yes, I just wanted to demonstrate that for me the bond orders correspond to each other.





I have spoken to a collague and there is a better solution, using


Code:



CGraph.setNode(int, CNode)





http://www.chemaxon.com/marvin/doc/api/chemaxon/struc/CGraph.html#setNode(int, chemaxon.struc.CNode)





You need only to use this method to alter the atom order, leave the bonds as they are.


You can also alter the order of the edges by


Code:



CGraph.setEdge(int, CEdge)





http://www.chemaxon.com/marvin/doc/api/chemaxon/struc/CGraph.html#setEdge(int, chemaxon.struc.CEdge)





I attach the test code (this only reverses the atom order, leaves edges as they are).





test.mol


Code:



 


  Marvin  04080523252D


 


  3  2  0  0  0  0            999 V2000


   -1.1184   -0.0066    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0


   -0.7928    1.0164    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0


   -1.8914    0.9540    0.0000 O   0  0  0  0  0  0  0  0  0  0  0  0


  1  2  1  0  0  0  0


  2  3  2  0  0  0  0


M  END








java AtomRearranger test.mol


Code:



 


  Marvin  04110517112D


 


  3  2  0  0  0  0            999 V2000


   -1.4535    0.7331    0.0000 O   0  0  0  0  0  0  0  0  0  0  0  0


   -0.6092    0.7811    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0


   -0.8595   -0.0051    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0


  3  2  1  0  0  0  0


  2  1  2  0  0  0  0


M  END








It is also possible to alter the row order in the molfile manually / by shell script


but in that case you have to modify the bond table accordingly.





Remark: for 0-dimensional molecules (e.g. molecules read from SMILES) the parity flags should be modified to preserve the chirality data. For 2-dimensional molecules this is not needed since chirality is read from the atom coordinates in that case.


I can give you the code that sets the parity flags if you need it, I did not build it in the test code because it is a bit complicated and probably is not needed in your case since you read molfiles.

User dfeb81947d

18-04-2005 07:28:12

Thank you so far,


I understanbd now how the structure of Molecular Graph works.


Thank you again.