Package org.jmol.modelsetbio

Source Code of org.jmol.modelsetbio.NucleicMonomer

/* $RCSfile$
* $Author: hansonr $
* $Date: 2007-02-26 22:47:27 -0600 (Mon, 26 Feb 2007) $
* $Revision: 6957 $

*
* Copyright (C) 2004-2005  The Jmol Development Team
*
* Contact: jmol-developers@lists.sf.net
*
*  This library is free software; you can redistribute it and/or
*  modify it under the terms of the GNU Lesser General Public
*  License as published by the Free Software Foundation; either
*  version 2.1 of the License, or (at your option) any later version.
*
*  This library is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
*  Lesser General Public License for more details.
*
*  You should have received a copy of the GNU Lesser General Public
*  License along with this library; if not, write to the Free Software
*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jmol.modelsetbio;


import java.util.List;
import javax.vecmath.Point3f;
import javax.vecmath.Vector3f;

import org.jmol.modelset.Atom;
import org.jmol.modelset.Bond;
import org.jmol.modelset.Group;
import org.jmol.modelset.Chain;
import org.jmol.util.Quaternion;
import org.jmol.viewer.JmolConstants;

public class NucleicMonomer extends PhosphorusMonomer {

  final static byte C6 = 1;
  private final static byte O2Pr = 2;
  private final static byte C5 = 3;
  private final static byte N1 = 4;
  private final static byte C2 = 5;
  private final static byte N3 = 6;
  private final static byte C4 = 7;
  private final static byte O2 = 8;
  private final static byte N7 = 9;
  private final static byte C8 = 10;
  private final static byte N9 = 11
  private final static byte O4 = 12;
  private final static byte O6 = 13;
  private final static byte N4 = 14;
  private final static byte NP = 15;
  private final static byte N6 = 16;
  private final static byte N2 = 17;
  private final static byte H5T = 18;
  private final static byte O5Pr = 19;
  private final static byte H3T = 20;
  private final static byte O3Pr = 21;
  private final static byte C3Pr = 22;
  private final static byte O1P = 23;
  private final static byte O2P = 24;
  private final static byte C1P = 25;
  private final static byte C4P = 26;
  //private final static byte S4 = 25;
  //private final static byte O5T = 26;
  //private final static byte OP1 = 27;
  //private final static byte OP2 = 28;
  //private final static byte HO3Pr = 29;
  //private final static byte HO5Pr = 30;
  
  // negative values are optional
  final static byte[] interestingNucleicAtomIDs = {
    ~JmolConstants.ATOMID_NUCLEIC_PHOSPHORUS,    //  the lead, POSSIBLY P, maybe H5T or O5T
    JmolConstants.ATOMID_C6,   // 1 the wing man, c6

    ~JmolConstants.ATOMID_O2_PRIME, // 2  O2' for RNA

    JmolConstants.ATOMID_C5,   //  3 C5
    JmolConstants.ATOMID_N1,   //  4 N1
    JmolConstants.ATOMID_C2,   //  5 C2
    JmolConstants.ATOMID_N3,   //  6 N3
    JmolConstants.ATOMID_C4,   //  7 C4

    ~JmolConstants.ATOMID_O2,  //  8 O2

    ~JmolConstants.ATOMID_N7,  // 9 N7
    ~JmolConstants.ATOMID_C8,  // 10 C8
    ~JmolConstants.ATOMID_N9,  // 11 C9

    ~JmolConstants.ATOMID_O4,  // 12 O4   U (& ! C5M)
    ~JmolConstants.ATOMID_O6,  // 13 O6   I (& ! N2)
    ~JmolConstants.ATOMID_N4,  // 14 N4   C
    ~JmolConstants.ATOMID_NUCLEIC_PHOSPHORUS, // 15
    ~JmolConstants.ATOMID_N6,  // 16 N6   A
    ~JmolConstants.ATOMID_N2,  // 17 N2   G

    ~JmolConstants.ATOMID_H5T_TERMINUS, // 18 H5T terminus
    ~JmolConstants.ATOMID_O5_PRIME,     // 19 O5' terminus

    ~JmolConstants.ATOMID_H3T_TERMINUS, // 20 H3T terminus
    JmolConstants.ATOMID_O3_PRIME,      // 21 O3' terminus
    JmolConstants.ATOMID_C3_PRIME,      // 22 C3'
   
    ~JmolConstants.ATOMID_O1P,  // 23 Phosphorus O1
    ~JmolConstants.ATOMID_O2P,  // 24 Phosphorus O2

    ~JmolConstants.ATOMID_C1_PRIME,  // 25 ribose C1'
    ~JmolConstants.ATOMID_C4_PRIME,  // 26 ribose C4'

    // unused:

    //~JmolConstants.ATOMID_S4,  // 15 S4   tU
    //~JmolConstants.ATOMID_O5T_TERMINUS, // 26 O5T terminus

    // alternative designations:
   
    //~JmolConstants.ATOMID_OP1,  // 27 Phosphorus O1 (new)
    //~JmolConstants.ATOMID_OP2,  // 28 Phosphorus O2 (new)

    //~JmolConstants.ATOMID_HO3_PRIME, // 29 HO3' terminus (new)
    //~JmolConstants.ATOMID_HO5_PRIME, // 29 HO3' terminus (new)
   
  };

  public static Monomer
    validateAndAllocate(Chain chain, String group3, int seqcode,
                        int firstAtomIndex, int lastAtomIndex,
                        int[] specialAtomIndexes) {

    byte[] offsets = scanForOffsets(firstAtomIndex,
                                    specialAtomIndexes,
                                    interestingNucleicAtomIDs);

    if (offsets == null)
      return null;
    if (!checkOptional(offsets, O5Pr, firstAtomIndex,
        specialAtomIndexes[JmolConstants.ATOMID_O5T_TERMINUS]))
      return null;
    checkOptional(offsets, H3T, firstAtomIndex,
        specialAtomIndexes[JmolConstants.ATOMID_HO3_PRIME]);
    checkOptional(offsets, H5T, firstAtomIndex,
        specialAtomIndexes[JmolConstants.ATOMID_HO5_PRIME]);
    checkOptional(offsets, O1P, firstAtomIndex,
        specialAtomIndexes[JmolConstants.ATOMID_OP1]);
    checkOptional(offsets, O2P, firstAtomIndex,
        specialAtomIndexes[JmolConstants.ATOMID_OP2]);

    NucleicMonomer nucleicMonomer =
      new NucleicMonomer(chain, group3, seqcode,
                         firstAtomIndex, lastAtomIndex, offsets);
    return nucleicMonomer;
  }

  ////////////////////////////////////////////////////////////////

  private boolean hasRnaO2Prime;

  NucleicMonomer(Chain chain, String group3, int seqcode,
                 int firstAtomIndex, int lastAtomIndex,
                 byte[] offsets) {
    super(chain, group3, seqcode,
          firstAtomIndex, lastAtomIndex, offsets);
    if (offsets[NP] == -1 && (offsets[0] = offsets[H5T]) == -1) {
        offsets[0] = offsets[O5Pr];
        leadAtomIndex = firstAtomIndex + (offsets[0] & 0xFF);
    }
    this.hasRnaO2Prime = offsets[O2Pr] != -1;
    this.isPyrimidine = offsets[O2] != -1;
    this.isPurine =
      offsets[N7] != -1 && offsets[C8] != -1 && offsets[N9] != -1;
  }

  public boolean isNucleicMonomer() { return true; }

 
  public boolean isDna() { return !hasRnaO2Prime; }

 
  public boolean isRna() { return hasRnaO2Prime; }

 
  public boolean isPurine() { return isPurine; }

 
  public boolean isPyrimidine() { return isPyrimidine; }

  public boolean isGuanine() { return offsets[N2] != -1; }

 
  public byte getProteinStructureType() {
    return (hasRnaO2Prime
            ? JmolConstants.PROTEIN_STRUCTURE_RNA
            : JmolConstants.PROTEIN_STRUCTURE_DNA);
  }

    ////////////////////////////////////////////////////////////////

  Atom getC1P() {
    return getAtomFromOffsetIndex(C1P);
  }

  Atom getC2() {
    return getAtomFromOffsetIndex(C2);
  }

  Atom getC4P() {
    return getAtomFromOffsetIndex(C4P);
  }

  Atom getN1() {
    return getAtomFromOffsetIndex(N1);
  }

  Atom getN3() {
    return getAtomFromOffsetIndex(N3);
  }

  Atom getN2() {
    return getAtomFromOffsetIndex(N2);
  }

  Atom getN4() {
    return getAtomFromOffsetIndex(N4);
  }

  Atom getN6() {
    return getAtomFromOffsetIndex(N6);
  }

  Atom getO2() {
    return getAtomFromOffsetIndex(O2);
  }

  Atom getO4() {
    return getAtomFromOffsetIndex(O4);
  }

  Atom getO6() {
    return getAtomFromOffsetIndex(O6);
  }

 
  Atom getTerminatorAtom() {
    return getAtomFromOffsetIndex(offsets[H3T] != -1 ? H3T : O3Pr);
  }

  private final static byte[] ring6OffsetIndexes = {C5, C6, N1, C2, N3, C4};

  public void getBaseRing6Points(Point3f[] ring6Points) {
    for (int i = 6; --i >= 0; )
      ring6Points[i] = getAtomFromOffsetIndex(ring6OffsetIndexes[i]);
  }
 
  private final static byte[] ring5OffsetIndexes = {C5, N7, C8, N9, C4};

  public boolean maybeGetBaseRing5Points(Point3f[] ring5Points) {
    if (isPurine)
      for (int i = 5; --i >= 0; )
        ring5Points[i] = getAtomFromOffsetIndex(ring5OffsetIndexes[i]);
    return isPurine;
  }

  private final static byte[] heavyAtomIndexes = {
    /*C1P Sarver: apparently not!,*/
    C5, C6, N1, C2, N3, C4, // all
    N9, C8, N7, // purine
    N6, // A
    N4, // C
    O2, // C, T, U
    O4, // T, U
    N2, O6, // G
    };

  ////////////////////////////////////////////////////////////////

 
  boolean isConnectedAfter(Monomer possiblyPreviousMonomer) {
    if (possiblyPreviousMonomer == null)
      return true;
    Atom myPhosphorusAtom = getAtomFromOffsetIndex(NP);
    if (myPhosphorusAtom == null)
      return false;
    if (! (possiblyPreviousMonomer instanceof NucleicMonomer))
      return false;
    NucleicMonomer other = (NucleicMonomer)possiblyPreviousMonomer;
    if (other.getAtomFromOffsetIndex(O3Pr).isBonded(myPhosphorusAtom))
      return true;
    return super.isConnectedAfter(possiblyPreviousMonomer);
  }

  ////////////////////////////////////////////////////////////////

 
  public void findNearestAtomIndex(int x, int y, Atom[] closest,
                            short madBegin, short madEnd) {
    Atom competitor = closest[0];
    Atom lead = getLeadAtom();
    Atom o5prime = getAtomFromOffsetIndex(O5Pr);
    Atom c3prime = getAtomFromOffsetIndex(C3Pr);
    short mar = (short)(madBegin / 2);
    if (mar < 1900)
      mar = 1900;
    int radius = scaleToScreen(lead.screenZ, mar);
    if (radius < 4)
      radius = 4;
    if (isCursorOnTopOf(lead, x, y, radius, competitor)
        || isCursorOnTopOf(o5prime, x, y, radius, competitor)
        || isCursorOnTopOf(c3prime, x, y, radius, competitor))
      closest[0] = lead;
  }
 
  public void setModelClickability() {
    Atom atom;
    if (isAtomHidden(leadAtomIndex))
      return;
    for (int i = 6; --i >= 0;) {
      atom = getAtomFromOffsetIndex(ring6OffsetIndexes[i]);
      atom.setClickable(JmolConstants.CARTOON_VISIBILITY_FLAG);
    }
    if (isPurine)
      for (int i = 4; --i >= 1;) {
        atom = getAtomFromOffsetIndex(ring5OffsetIndexes[i]);
        atom.setClickable(JmolConstants.CARTOON_VISIBILITY_FLAG);
      }
  }
  Atom getN0() {
    return (getAtomFromOffsetIndex(isPurine ? N9 : N1));
  }
 
  public Object getHelixData(int tokType, char qType, int mStep) {
    return getHelixData2(tokType, qType, mStep);
  }
  
  Point3f baseCenter; 

 
  Point3f getQuaternionFrameCenter(char qType) {
    switch (qType) {
    case 'x':
    case 'a':
    case 'b':
    case 'p':
      return getP();
    case 'c':
      // Sarver's base center; does not include C4'
      if (baseCenter == null) {
        int n = 0;
        baseCenter = new Point3f();
        for (int i = 0; i < heavyAtomIndexes.length; i++) {
          Atom a = getAtomFromOffsetIndex(heavyAtomIndexes[i]);
          if (a == null)
            continue;
          baseCenter.add(a);
          n++;
        }
        baseCenter.scale(1f / n);
      }
      return baseCenter;
    case 'n':
    default:
      return getN0();
    }
  }

 
  public Quaternion getQuaternion(char qType) {
    // quaternionFrame 'c' from 
    // Sarver M, Zirbel CL, Stombaugh J, Mokdad A, Leontis NB.
    // FR3D: finding local and composite recurrent structural motifs in RNA 3D structures.
    // J. Math. Biol. (2006) 215-252
    // quaternionFrame 'n' same, but with N1/N9 as base atom (only different for DRAW)
    Atom ptA = null, ptB = null, ptNorP;
    boolean yBased = false;
    boolean reverseY = false;
    switch (qType) {
    case 'a': // alternative C4' - P - C4'
      //   (C4_i-1 - P_i - C4_i), with Y P_i - C4_i     
      ptNorP = getP();
      if (monomerIndex == 0 || ptNorP == null)
        return null;
      yBased = true;
      ptA = ((NucleicMonomer) bioPolymer.monomers[monomerIndex - 1]).getC4P();
      ptB = getC4P();
      break;
    case 'x':
      // P[i]-C4'[i]-P[i+1]
      ptNorP = getP();
      if (monomerIndex == bioPolymer.monomerCount - 1 || ptNorP == null)
        return null;
      ptA = ((NucleicMonomer) bioPolymer.monomers[monomerIndex + 1]).getP();
      ptB = getC4P();
      break;
    case 'b': // phosphorus backbone
      return super.getQuaternion(qType);
    case 'c': // Sarver-defined, with Y in the C1'-N1/9 direction, x toward C2 (W-C edge)
    case 'n': // same, just different quaternion center
      // N0 = (purine N9, pyrimidine N1):
      ptNorP = getN0();
      if (ptNorP == null)
        return null;
      yBased = true;
      reverseY = true;
      // vB = -(N0-C1P)
      // vA = vB x (vB x (N0-C2))
      ptA = getAtomFromOffsetIndex(C2);
      ptB = getAtomFromOffsetIndex(C1P);
      break;
    case 'p': // phosphorus tetrahedron
      // O1P - P - O2P
      ptNorP = getP();
      if (ptNorP == null)
        return null;
      Atom p1 = getAtomFromOffsetIndex(O1P);
      Atom p2 = getAtomFromOffsetIndex(O2P);
      Bond[] bonds = ptNorP.getBonds();
      if (bonds == null)
        return null;
      Group g = ptNorP.getGroup();
      for (int i = 0; i < bonds.length; i++) {
        Atom atom = bonds[i].getOtherAtom(ptNorP);
        if (p1 != null && atom.index == p1.index)
          continue;
        if (p2 != null && atom.index == p2.index)
          continue;
        if (atom.getGroup() == g)
          ptB = atom;
        else
          ptA = atom;
      }
      break;
    case 'q': // Quine
      return null;
    default:
      ptNorP = getN0();
      if (ptNorP == null)
        return null;
      if (isPurine) {
        // 11.9.34 experimenting:
        // vA = N9--C2 // was N9--C4
        // vB = N9--N7 // was N9--C8
        ptA = getAtomFromOffsetIndex(C2);
        ptB = getAtomFromOffsetIndex(N7);
      } else {
        // 11.9.34 experimenting:
        // vA = N1--N3 // was N1--C2
        // vB = N1--C6
        ptA = getAtomFromOffsetIndex(N3);
        ptB = getAtomFromOffsetIndex(C6);
      }
      break;
    }
    if (ptA == null || ptB == null)
      return null;

    Vector3f vA = new Vector3f(ptA);
    vA.sub(ptNorP);

    Vector3f vB = new Vector3f(ptB);
    vB.sub(ptNorP);
    if (reverseY)
      vB.scale(-1);
    return Quaternion.getQuaternionFrame(vA, vB, null, yBased);
  }
public boolean isCrossLinked(Group g) {
    if (!(g instanceof NucleicMonomer) || isPurine == g.isPurine())
      return false;
    NucleicMonomer otherNucleotide = (isPurine ? (NucleicMonomer) g : this);
    NucleicMonomer myNucleotide = (isPurine ? this : (NucleicMonomer) g);
    Atom myN1 = myNucleotide.getN1();
    Atom otherN3 = otherNucleotide.getN3();
    return (myN1.isBonded(otherN3));
  }
 
  public boolean getCrossLinkLeadAtomIndexes(List vReturn) {
    Atom N = (isPurine ? getN1() : getN3());
    //System.out.println(N.getInfo());
    Bond[] bonds = N.getBonds();
    if (bonds == null)
      return false;
    boolean haveCrossLinks = false;
    for (int i = 0; i < bonds.length; i++) {
      //System.out.println(bonds[i].getOtherAtom(N).getInfo());
      if (bonds[i].isHydrogen()) {
        Atom N2 = bonds[i].getOtherAtom(N);
        Group g = N2.getGroup();
        if (!(g instanceof NucleicMonomer))
          continue;
        NucleicMonomer m = (NucleicMonomer) g;
        if ((isPurine ? m.getN3() : m.getN1()) == N2) {
          if (vReturn == null)
            return true;
          vReturn.add(Integer.valueOf(m.leadAtomIndex));
          haveCrossLinks = true;
        }
      }
    }
    return haveCrossLinks;
  }

  public boolean getEdgePoints(Point3f[] pts) {
    pts[0] = getLeadAtom();
    pts[1] = getC4P();
    pts[2] = pts[5] = getC1P();
    switch (getGroup1()) {
    case 'C':
      pts[3] = getO2();
      pts[4] = getN4();
      return true;
    case 'A':
      pts[3] = getC2();
      pts[4] = getN6();
      return true;
    case 'G':
    case 'I':
      pts[3] = getC2();
      pts[4] = getO6();
      return true;
    case 'T':
    case 'U':
      pts[3] = getO2();
      pts[4] = getO4();
      return true;
    default:
      return false;
    }   
  }
}
TOP

Related Classes of org.jmol.modelsetbio.NucleicMonomer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.