Package org.jmol.modelsetbio

Source Code of org.jmol.modelsetbio.Monomer

/* $RCSfile$
* $Author: hansonr $
* $Date: 2007-02-15 11:45:59 -0600 (Thu, 15 Feb 2007) $
* $Revision: 6834 $
*
* 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 org.jmol.modelset.Atom;
import org.jmol.modelset.Bond;
import org.jmol.modelset.Chain;
import org.jmol.modelset.Group;

import org.jmol.util.Logger;
import org.jmol.util.Measure;
import org.jmol.util.Quaternion;
import org.jmol.viewer.JmolConstants;
import org.jmol.script.Token;

import java.util.Hashtable;
import java.util.BitSet;
import java.util.List;
import java.util.Map;

import javax.vecmath.Point3f;

public abstract class Monomer extends Group {

  BioPolymer bioPolymer;

  protected final byte[] offsets;

  protected Monomer(Chain chain, String group3, int seqcode,
          int firstAtomIndex, int lastAtomIndex,
          byte[] interestingAtomOffsets) {
    super(chain, group3, seqcode, firstAtomIndex, lastAtomIndex);
    offsets = interestingAtomOffsets;
    leadAtomIndex = firstAtomIndex + (offsets[0] & 0xFF);
  }

  int monomerIndex;
 
  void setBioPolymer(BioPolymer polymer, int index) {
    this.bioPolymer = polymer;
    monomerIndex = index;
  }


  public int getSelectedMonomerCount() {
    return bioPolymer.getSelectedMonomerCount();
  }
 

  public int getSelectedMonomerIndex() {
    return (monomerIndex >= 0 && bioPolymer.isMonomerSelected(monomerIndex) ? monomerIndex : -1);
  }
 
  public BioPolymer getBioPolymer() {
    return bioPolymer;
  }
 

  public int getBioPolymerLength() {
    return bioPolymer == null ? 0 : bioPolymer.monomerCount;
  }


  public int getMonomerIndex() {
    return monomerIndex;
  }


  public int getBioPolymerIndexInModel() {
    return (bioPolymer == null ? -1 : bioPolymer.bioPolymerIndexInModel);
  }
 

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

  protected static byte[] scanForOffsets(int firstAtomIndex,
                               int[] specialAtomIndexes,
                               byte[] interestingAtomIDs) {
    /*
     * from validateAndAllocate in AminoMonomer or NucleicMonomer extensions
     *
     * sets offsets for the FIRST conformation ONLY
     * (provided that the conformation is listed first in each atom case)
     * 
     *  specialAtomIndexes[] corrolates with JmolConstants.specialAtomNames[]
     *  and is set up back in the calling frame.distinguishAndPropagateGroups
     */
    int interestingCount = interestingAtomIDs.length;
    byte[] offsets = new byte[interestingCount];
    for (int i = interestingCount; --i >= 0; ) {
      int atomIndex;
      int atomID = interestingAtomIDs[i];
      // mth 2004 06 09
      // use ~ instead of - as the optional indicator
      // because I got hosed by a missing comma
      // in an interestingAtomIDs table
      if (atomID < 0) {
        atomIndex = specialAtomIndexes[~atomID]; // optional
      } else {
        atomIndex = specialAtomIndexes[atomID]// required
        if (atomIndex < 0)
          return null;
      }
      int offset;
      if (atomIndex < 0)
        offset = 255;
      else {
        offset = atomIndex - firstAtomIndex;
        if (offset < 0 || offset > 254) {
          Logger.warn("Monomer.scanForOffsets i="+i+" atomID="+atomID+" atomIndex:"+atomIndex+" firstAtomIndex:"+firstAtomIndex+" offset out of 0-254 range. Groups aren't organized correctly. Is this really a protein?: "+offset);
          if (atomID < 0) {
            offset = 255; //it was optional anyway RMH
          } else {
            //throw new NullPointerException();
          }
        }
      }
      offsets[i] = (byte)offset;
    }
    return offsets;
  }

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


  public boolean isProtein() {
    return isAmino;
  }
  ////////////////////////////////////////////////////////////////

  /**
   * @param proteinstructure
   *
   */
  void setStructure(ProteinStructure proteinstructure) { }

  public ProteinStructure getProteinStructure() { return null; }

  public byte getProteinStructureType() { return JmolConstants.PROTEIN_STRUCTURE_NONE; }
  public boolean isHelix() { return false; }
  public boolean isSheet() { return false; }

  public void setProteinStructureId(int id) { }

  ////////////////////////////////////////////////////////////////
/*
  public final Atom getAtomFromOffset(byte offset) {
    if (offset == -1)
      return null;
    return chain.frame.atoms[firstAtomIndex + (offset & 0xFF)];
  }

  public final Point3f getAtomPointFromOffset(byte offset) {
    if (offset == -1)
      return null;
    return chain.frame.atoms[firstAtomIndex + (offset & 0xFF)];
  }
*/
 
  ////////////////////////////////////////////////////////////////

  protected final Atom getAtomFromOffsetIndex(int offsetIndex) {
    if (offsetIndex > offsets.length)
      return null;
    int offset = offsets[offsetIndex] & 0xFF;
    if (offset == 255)
      return null;
    return chain.getAtom(firstAtomIndex + offset);
  }

  protected final Atom getSpecialAtom(byte[] interestingIDs, byte specialAtomID) {
    for (int i = interestingIDs.length; --i >= 0; ) {
      int interestingID = interestingIDs[i];
      if (interestingID < 0)
        interestingID = -interestingID;
      if (specialAtomID == interestingID) {
        int offset = offsets[i] & 0xFF;
        if (offset == 255)
          return null;
        return chain.getAtom(firstAtomIndex + offset);
      }
    }
    return null;
  }

  protected final Point3f getSpecialAtomPoint(byte[] interestingIDs,
                                    byte specialAtomID) {
    for (int i = interestingIDs.length; --i >= 0; ) {
      int interestingID = interestingIDs[i];
      if (interestingID < 0)
        interestingID = -interestingID;
      if (specialAtomID == interestingID) {
        int offset = offsets[i] & 0xFF;
        if (offset == 255)
          return null;
        return chain.getAtom(firstAtomIndex + offset);
      }
    }
    return null;
  }
/*
  public Atom getAtom(byte specialAtomID) { return null; }

  protected Point3f getAtomPoint(byte specialAtomID) { return null; }
*/
 

  public boolean isLeadAtom(int atomIndex) {
    return atomIndex == leadAtomIndex;
  }


  public final Atom getLeadAtom() {
    return getAtomFromOffsetIndex(0);
  }


  public final Atom getWingAtom() {
    return getAtomFromOffsetIndex(1);
  }

  Atom getInitiatorAtom() {
    return getLeadAtom();
  }
 
  Atom getTerminatorAtom() {
    return getLeadAtom();
  }

  abstract boolean isConnectedAfter(Monomer possiblyPreviousMonomer);

  /**
   * Selects LeadAtom when this Monomer is clicked iff it is
   * closer to the user.
   *
   * @param x
   * @param y
   * @param closest
   * @param madBegin
   * @param madEnd
   */
  void findNearestAtomIndex(int x, int y, Atom[] closest,
                            short madBegin, short madEnd) {
  }


  protected boolean calcBioParameters() {
    return bioPolymer.calcParameters();
  }


  public boolean haveParameters() {
    return bioPolymer.haveParameters;
  }
 
  public Map getMyInfo() {
    Map info = new Hashtable();
    char chainID = chain.getChainID();
    info.put("chain", (chainID == '\0' ? "" : "" + chainID));
    int seqNum = getSeqNumber();
    char insCode = getInsertionCode();
    if (seqNum > 0)     
      info.put("sequenceNumber", Integer.valueOf(seqNum));
    if (insCode != 0)     
      info.put("insertionCode","" + insCode);
    info.put("atomInfo1", chain.getAtom(firstAtomIndex).getInfo());
    info.put("atomInfo2", chain.getAtom(lastAtomIndex).getInfo());
    info.put("_apt1", Integer.valueOf(firstAtomIndex));
    info.put("_apt2", Integer.valueOf(lastAtomIndex));
    info.put("atomIndex1", Integer.valueOf(firstAtomIndex));
    info.put("atomIndex2", Integer.valueOf(lastAtomIndex));
    float f = getGroupParameter(Token.phi);
    if (!Float.isNaN(f))
      info.put("phi", new Float(f));
    f = getGroupParameter(Token.psi);
    if (!Float.isNaN(f))
      info.put("psi", new Float(f));
    f = getGroupParameter(Token.eta);
    if (!Float.isNaN(f))
      info.put("mu", new Float(f));
    f = getGroupParameter(Token.theta);
    if (!Float.isNaN(f))
      info.put("theta", new Float(f));
    ProteinStructure structure = getProteinStructure();
    if(structure != null) {
      info.put("structureId", Integer.valueOf(structure.uniqueID));
      info.put("structureType", JmolConstants.getProteinStructureName(structure.type, false));
    }
    info.put("shapeVisibilityFlags", Integer.valueOf(shapeVisibilityFlags));
    return info;
  }
 

  public String getStructureId() {
    ProteinStructure structure = getProteinStructure();
    return (structure == null ? "" : JmolConstants.getProteinStructureName(structure.type, false));
  }

  /**
   * clear out bits that are not associated with the nth conformation
   * counting for each residue from the beginning of the file listing
   *
   *
   * @param atoms
   * @param bsConformation
   * @param conformationIndex   will be >= 0
   */
  void getConformation(Atom[] atoms, BitSet bsConformation, int conformationIndex) {

    // A        A
    // A        B
    // A        A
    // B  or    B
    // B        A
    // B        B
   
    char ch = '\0';
    for (int i = firstAtomIndex; i <= lastAtomIndex; i++) {
      Atom atom = atoms[i];
      char altloc = atom.getAlternateLocationID();
      // ignore atoms that have no designation
      if (altloc == '\0')
        continue;
      // count down until we get the desired index into the list
      if (conformationIndex >= 0 && altloc != ch) {
        ch = altloc;
        conformationIndex--;
      }
      if (conformationIndex < 0 && altloc != ch)
        bsConformation.clear(i);
    }
  }

  final void updateOffsetsForAlternativeLocations(Atom[] atoms, BitSet bsSelected) {
      for (int offsetIndex = offsets.length; --offsetIndex >= 0;) {
        int offset = offsets[offsetIndex] & 0xFF;
        if (offset == 255)
          continue;
        int iThis = firstAtomIndex + offset;
        Atom atom = atoms[iThis];
        if (atom.getAlternateLocationID() == 0)
          continue;
        // scan entire group list to ensure including all of
        // this atom's alternate conformation locations.
        // (PDB order may be AAAAABBBBB, not ABABABABAB)
        int nScan = lastAtomIndex - firstAtomIndex;
        for (int i = 1; i <= nScan; i++) {
          int iNew = iThis + i;
          if (iNew > lastAtomIndex)
            iNew -= nScan + 1;
          int offsetNew = iNew - firstAtomIndex;
          if (offsetNew < 0 || offsetNew > 255 || iNew == iThis
              || !bsSelected.get(iNew))
            continue;
          if (atoms[iNew].atomID != atoms[iThis].atomID
              || atoms[iNew].atomID == 0
                  && !atoms[iNew].getAtomName().equals(atoms[iThis].getAtomName()))
            continue;
          if (Logger.debugging)
            Logger.debug("Chain.udateOffsetsForAlternativeLocation " + atoms[iNew] + " was " + atoms[iThis]);
          offsets[offsetIndex] = (byte) offsetNew;
          break;
        }
      }

  }
   
  final void getMonomerSequenceAtoms(BitSet bsInclude, BitSet bsResult) {
    for (int j = firstAtomIndex; j <= lastAtomIndex; j++)
      if (bsInclude.get(j))
        bsResult.set(j);
  }
 
  protected final static boolean checkOptional(byte[]offsets, byte atom,
                                               int firstAtomIndex,
                                               int index) {
    if (offsets[atom] >= 0)
      return true;
    if (index < 0)
      return false;
    offsets[atom] = (byte)(index - firstAtomIndex);
    return true;
  }

  /**
   *
   * @param qtype
   * @return center
   */
  Point3f getQuaternionFrameCenter(char qtype) {
    return null;
  }

  protected Object getHelixData2(int tokType, char qType, int mStep) {
    int iPrev = monomerIndex - mStep;
    Monomer prev = (mStep < 1 || monomerIndex <= 0 ? null : bioPolymer.monomers[iPrev]);
    Quaternion q2 = getQuaternion(qType);
    Quaternion q1 = (mStep < 1 ? Quaternion.getQuaternionFrame(JmolConstants.axisX, JmolConstants.axisY, JmolConstants.axisZ, false)
        : prev == null ? null : prev.getQuaternion(qType));
    if (q1 == null || q2 == null)
      return super.getHelixData(tokType, qType, mStep);
    Point3f a = (mStep < 1 ? new Point3f(0, 0, 0) : prev.getQuaternionFrameCenter(qType));
    Point3f b = getQuaternionFrameCenter(qType);
    if (a == null || b == null)
      return super.getHelixData(tokType, qType, mStep);
    return Measure.computeHelicalAxis(tokType == Token.draw ? "helixaxis" + getUniqueID() : null,
        tokType, a, b, q2.div(q1));
  }

  public String getUniqueID() {
    char cid = getChainID();
    Atom a = getLeadAtom();
    String id = (a == null ? "" : "_" + a.getModelIndex()) + "_" + getResno()
        + (cid == '\0' ? "" : "" + cid);
    cid = (a == null ? '\0' : getLeadAtom().getAlternateLocationID());
    if (cid != '\0')
      id += cid;
    return id;
  }
 

  public boolean isCrossLinked(Group g) {
    for (int i = firstAtomIndex; i <= lastAtomIndex; i++)
      if (getCrossLink(i, null, g))
          return true;
    return false;
  }

  public boolean getCrossLinkLeadAtomIndexes(List vReturn) {   
   for (int i = firstAtomIndex; i <= lastAtomIndex; i++)
      if (getCrossLink(i, vReturn) && vReturn == null)
          return true;
    return false;
 

  protected boolean getCrossLink(int i, List vReturn) {
    return getCrossLink(i, vReturn, null);
  }
 
  private boolean getCrossLink(int i, List vReturn, Group group) {
    // vReturn null --> just checking for connection to previous group
    // not obvious from PDB file for carbohydrates
    Atom atom = chain.getAtom(i);
    Bond[] bonds = atom.getBonds();
    int ibp = getBioPolymerIndexInModel();
    if (ibp < 0 || bonds == null)
      return false;
    boolean haveCrossLink = false;
    boolean checkPrevious = (vReturn == null && group == null);
    for (int j = 0; j < bonds.length; j++) {
      Atom a = bonds[j].getOtherAtom(atom);
      Group g = a.getGroup();
      if (group != null && g != group)
        continue;
      int iPolymer = g.getBioPolymerIndexInModel();
      int igroup = g.getMonomerIndex();
      if (checkPrevious) {
        if (iPolymer == ibp && igroup == monomerIndex - 1)
          return true;
      } else if (iPolymer >= 0
          && igroup >= 0
          && (iPolymer != ibp || igroup < monomerIndex - 1 || igroup > monomerIndex + 1)) {
        haveCrossLink = true;
        if (group != null)
          break;
        vReturn.add(Integer.valueOf(g.leadAtomIndex));
      }
    }
    return haveCrossLink;
  }
 

  public boolean isConnectedPrevious() {
    return true; // but not nec. for carbohydrates... see 1k7c
  }

}
 

TOP

Related Classes of org.jmol.modelsetbio.Monomer

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.