Calculation of Chiral Centers

User d68ef9d5a9

13-10-2004 20:08:07

Hi,





I have this compound smiles ClC1NCCC1Br to create a Molecule object through MolHandler class without speciyfying the chirality of any carbon. But I need to find out how many chiral centers in this molecule. What is the best way to calculate that?





Thanks in advance.





Ben Li


Neurogen Corporation

ChemAxon 25dcd765a3

13-10-2004 22:47:06

Hi,





Actually there is no ready made function, which returns this answer in any dimension.


The constitutionally different atoms can be find if you look the graph invariants of the atoms.


Run through the atoms, check if the atom has less than 2 implicit and explicit H, the number of ligands is equally 4 and the ligands' graph invariants are different. If all off these are met then the atom has tetrahedral chirality.


Code:



// I suppose you have a Molecule mol = ....


     int ac = mol.getAtomCount();


     int[] canbeChiral = new int[ac];


     int[] grinv0 = new int[ac];


     mol.calcDehydrogenizedGrinv(grinv0);





     for (int i = 0; i < ac; i++) {


       MolAtom atom = mol.getAtom(i);


       int [] an = ctab[i];


       int eH=0;   //expicit H


       for (int j=0; j<an.length; j++){


           MolAtom a = mol.getAtom(an[j]);


           if (a.getAtno()==1 && a.getMassno()==0)


               eH++;


       }


       int nLigands = an.length;


       int iH = atom.getImplicitHcount();


       boolean canbech = true; // this atom can be chiral


       canbech = (iH+eH<2 && (nLigands+iH)==4);


            if (canbech){


                 canbech = !graphInvCheck(an);


            }


      canbeChiral[i] = canbech;


    }





boolean graphInvCheck(int [] an) {


    int a = grinv0[an[0]];


    int b = grinv0[an[1]];


    int c = grinv0[an[2]];


    if (an.length == 4) {


        int d = grinv0[an[3]];


        if (a == d || b == d || c == d)


            return true;


     }


     return a == b || a == c || b == c;


}








All the best


Andras

User 870ab5b546

15-10-2004 17:22:01

I would try this algorithm:





Code:
Call your structure, S.


Call the number of carbon atoms in S, c.





int stereocenters = 0


for (int n = 1; n <= c; n++) {


   Convert S to S1 by changing one of the bonds to atom n to an up bond.


   If query S matches target S1 then stereocenters++


}


ChemAxon a3d59b832c

17-10-2004 08:22:56

bobgr wrote:
I would try this algorithm:





Code:
Call your structure, S.


Call the number of carbon atoms in S, c.





int stereocenters = 0


for (int n = 1; n <= c; n++) {


   Convert S to S1 by changing one of the bonds to atom n to an up bond.


   If query S matches target S1 then stereocenters++


}


I am afraid this will not work. Ben's structures do not contain any chiral specification, so they will sure match to any chiral version. And regardless the up bond has any sense or not.





Furthermore, structural searching is a very useful, but relatively costly operation, volfi's solution is much more effective.

User 870ab5b546

18-10-2004 14:03:58

Szabolcs wrote:
I am afraid this will not work. Ben's structures do not contain any chiral specification, so they will sure match to any chiral version. And regardless the up bond has any sense or not.





Furthermore, structural searching is a very useful, but relatively costly operation, volfi's solution is much more effective.
Sorry, it should have been:





Code:
Call your structure, S.


Call the number of carbon atoms in S, c.





int stereocenters = 0


for (int n = 1; n <= c; n++) {


   Convert S to S1 by changing one of the bonds to atom n to an Up bond.


   If query S1 matches target S then stereocenters++


}








According to the JChem user's guide (http://www.jchem.com/doc/user/Query.html#chirality), a query structure with a stereocenter with configuration specified will not match a target structure that has no configuration specified at the same stereocenter. If the atom in question is not a stereocenter, then changing a bond to Up won't make a difference, and there will be a match.





As for efficiency, it seems to me that doing a single match per C atom is better than comparing every non-H ligand to the others on each and every C atom, as in Volfi's algorithm.

ChemAxon a3d59b832c

18-10-2004 14:33:54

bobgr wrote:
According to the JChem user's guide (http://www.jchem.com/doc/user/Query.html#chirality), a query structure with a stereocenter with configuration specified will not match a target structure that has no configuration specified at the same stereocenter. If the atom in question is not a stereocenter, then changing a bond to Up won't make a difference, and there will be a match.
I am with you now. This latter algorithm makes sense.
bobgr wrote:



As for efficiency, it seems to me that doing a single match per C atom is better than comparing every non-H ligand to the others on each and every C atom, as in Volfi's algorithm.
Unfortunately, MolSearch have to prepare for every kind of matches, so for example different permutations of the target atoms. For this reason it makes computations magnitudes larger than in volfi's piece of code.





I just realized that self-overlapping molecules can behave unexpectedly in your algorithm. The addMatch() method of MolSearch can fix that and boosts performance, too:





http://www.jchem.com/doc/api/chemaxon/sss/search/MolSearch.html#addMatch(int[],%20int[],%20int)

User d68ef9d5a9

16-11-2004 19:54:55

Alright, thanks to volfi for some clarification of my concerns. The algorithm should be





Molecule mol=.....


int ac = mol.getAtomCount();


boolean [] canbeChiral = new boolean [ac];


int[][] ctab = mol.getCtab();


int[] grinv0 = new int[ac];


mol.calcDehydrogenizedGrinv(grinv0);





for (int i = 0; i < ac; i++) {


MolAtom atom = mol.getAtom(i);


int [] an = ctab;


int eH=0; //expicit H


for (int j=0; j<an.length; j++){


MolAtom a = mol.getAtom(an[j]);


if (a.getAtno()==1 && a.getMassno()==0)


eH++;


}


int nLigands = an.length;


int iH = atom.getImplicitHcount();


boolean canbech = true; // this atom can be chiral


canbech = (iH+eH<2 && (nLigands+iH)==4);


if (canbech){


canbech = !graphInvCheck(an, grinv0);


}


canbeChiral = canbech;


......








private boolean graphInvCheck(int [] an) {


int a = grinv0[an[0]];


int b = grinv0[an[1]];


int c = grinv0[an[2]];


if (an.length == 4) {


int d = grinv0[an[3]];


if (a == d || b == d || c == d)


return true;


}


return a == b || a == c || b == c;


}








However, we may be able to use getChirality method in Molecule class to do the similar thing.





Molecule mol=.....


int ac = mol.getAtomCount();


int [] canbeChiral = new int [ac];


for (int i=0; i<ac, i++){


canbeChiral=mol.getChirality(i);


//value will be 0 for non-chiral, 128 or 256 for R or S, and 48 for //unspecified


}





My question is that which algorithm is quick in terms of performance. Are there any potential problems to use mol.getChirality(i)?





Ben Li


Neurogen Corporation

ChemAxon 25dcd765a3

16-11-2004 21:31:46

Quote:



My question is that which algorithm is quick in terms of performance. Are there any potential problems to use mol.getChirality(i)?


The chirality calculation does the same algorithm before starting to order the atoms according to the CIP rules. So the chirality calculation much more slower.

User d68ef9d5a9

16-11-2004 22:00:52

Thanks.





But the getChirality(int i) does provide more information about the chiral center, such as what chirality the atom is, or if the chirality is defined. The algorithm is probably better to answer my initial question of how many centers a molecule has.





What is CIP rules? How does the getChirality method use these rules?





Ben Li

ChemAxon 25dcd765a3

17-11-2004 08:15:55

If you need only the existence of chiral centers then the algorithm is enough. If you want to know the chirality of the atom if specified, then I suggest to use getChirality.





CIP: Cahn-Ingold-Prelog priority rules





To determine chirality of an atom:





1. Identify the chirality centers (most commonly an sp3 C with 4 different groups attached)


2. Assign the priority to each group (high = 1, low = 4) based on atomic number of the atom attached to the chirality center (this is the first rule of CIP, to see all of them check Chemical Books)


3. Position the lowest priority group away from you as if you were looking along the sigma bond from the center to the 4th priority atom.


4. For the other 3 groups, determine the direction of high to low priority (1 to 3)


5. If this is clockwise, then the center is R (Latin: rectus = right)


6. If this is counter clockwise, then it is S (Latin: sinister = left)

ChemAxon 25dcd765a3

18-11-2004 08:24:52

One other thing!





The chirality calculation will work on 0D molecules (SMILES strings) on the upcoming release only.

ChemAxon a3d59b832c

17-08-2006 07:59:47

The identification of assymetric atoms is already available in the TopologyAnalyser plugin: TopologyAnalyser.isAsymmetricAtom(int a)





Check out its API documentation:


http://www.chemaxon.com/marvin/doc/api/chemaxon/calculations/TopologyAnalyser.html#isAsymmetricAtom(int)








Best regards,


Szabolcs