public void ValueOf() { GeometricParity odd = GeometricParity.ValueOf(-1); GeometricParity even = GeometricParity.ValueOf(1); Assert.AreEqual(-1, odd.Parity); Assert.AreEqual(+1, even.Parity); }
/// <summary> /// Create an encoder for the <see cref="ITetrahedralChirality"/> element. /// </summary> /// <param name="tc">stereo element from an atom container</param> /// <param name="atomToIndex">map of atoms to indices</param> /// <returns>a new geometry encoder</returns> private static GeometryEncoder Encoder(ITetrahedralChirality tc, IDictionary <IAtom, int> atomToIndex) { var ligands = tc.Ligands; var centre = atomToIndex[tc.ChiralAtom]; var indices = new int[4]; int offset = -1; { int i = 0; foreach (var ligand in ligands) { indices[i] = atomToIndex[ligands[i]]; if (indices[i] == centre) { offset = i; } i++; } } // convert clockwise/anticlockwise to -1/+1 var parity = tc.Stereo == TetrahedralStereo.Clockwise ? -1 : 1; // now if any atom is the centre (indicating an implicit // hydrogen) we need to adjust the indicies and the parity if (offset >= 0) { // remove the 'implicit' central from the first 3 vertices for (int i = offset; i < indices.Length - 1; i++) { indices[i] = indices[i + 1]; } // we now take how many vertices we moved which is // 3 (last index) minus the index where we started. if the // value is odd we invert the parity (odd number of // inversions) if ((3 - offset) % 2 == 1) { parity *= -1; } // trim the array to size we don't include the last (implicit) // vertex when checking the invariants var sindices = new int[indices.Length - 1]; Array.Copy(indices, sindices, indices.Length - 1); indices = sindices; } return(new GeometryEncoder(centre, new BasicPermutationParity(indices), GeometricParity.ValueOf(parity))); }
/// <summary> /// Create an encoder for the <see cref="IDoubleBondStereochemistry"/> element. /// </summary> /// <param name="dbs">stereo element from an atom container</param> /// <param name="atomToIndex">map of atoms to indices</param> /// <param name="graph">adjacency list of connected vertices</param> /// <returns>a new geometry encoder</returns> private static GeometryEncoder GetEncoder(IDoubleBondStereochemistry dbs, IDictionary <IAtom, int> atomToIndex, int[][] graph) { var db = dbs.StereoBond; var u = atomToIndex[db.Begin]; var v = atomToIndex[db.End]; // we now need to expand our view of the environment - the vertex arrays // 'us' and <paramref name="vs"/> hold the neighbors of each end point of the double bond // (<paramref name="u"/> or 'v'). The first neighbor is always the one stored in the // stereo element. The second is the other non-double bonded vertex // which we must find from the neighbors list (findOther). If there is // no additional atom attached (or perhaps it is an implicit Hydrogen) // we use either double bond end point. var bs = dbs.Bonds; var us = new int[2]; var vs = new int[2]; us[0] = atomToIndex[bs[0].GetOther(db.Begin)]; us[1] = graph[u].Length == 2 ? u : FindOther(graph[u], v, us[0]); vs[0] = atomToIndex[bs[1].GetOther(db.End)]; vs[1] = graph[v].Length == 2 ? v : FindOther(graph[v], u, vs[0]); var parity = dbs.Stereo == DoubleBondConformation.Opposite ? +1 : -1; var geomParity = GeometricParity.ValueOf(parity); // the permutation parity is combined - but note we only use this if we // haven't used <paramref name="u"/> or 'v' as place holders (i.e. implicit hydrogens) // otherwise there is only '1' and the parity is just '1' (identity) PermutationParity permParity = new CombinedPermutationParity(us[1] == u ? BasicPermutationParity.Identity : new BasicPermutationParity(us), vs[1] == v ? BasicPermutationParity.Identity : new BasicPermutationParity(vs)); return(new GeometryEncoder(new int[] { u, v }, permParity, geomParity)); }