Package org.jmol.viewer

Source Code of org.jmol.viewer.DataManager

/* $RCSfile$
* $Author: hansonr $
* $Date: 2007-10-03 20:53:36 -0500 (Wed, 03 Oct 2007) $
* $Revision: 8351 $
*
* Copyright (C) 2003-2005  Miguel, 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.viewer;

import java.util.BitSet;
import java.util.Enumeration;
import java.util.Hashtable;

import org.jmol.modelset.AtomCollection;
import org.jmol.script.Token;
import org.jmol.util.ArrayUtil;
import org.jmol.util.BitSetUtil;
import org.jmol.util.Elements;
import org.jmol.util.Escape;
import org.jmol.util.Logger;
import org.jmol.util.Parser;


/*
* a class for storing and retrieving user data,
* including atom-related and color-related data
*
*/

class DataManager {

  private Hashtable dataValues = new Hashtable();

  Viewer viewer;
  DataManager(Viewer viewer) {
    this.viewer = viewer;
  }

  void clear() {
    dataValues.clear();
  }
 
  void setData(String type, Object[] data, int atomCount, int matchField,
               int matchFieldColumnCount, int field, int fieldColumnCount) {
    //Eval
    /*
     * data[0] -- label
     * data[1] -- string or float[] or float[][]
     * data[2] -- selection bitset or int[] atomMap when field > 0
     *
     * matchField = data must match atomNo in this column, >= 1
     * field = column containing the data, >= 1:
     *   0 ==> values are a simple list; clear the data
     *   Integer.MAX_VALUE ==> values are a simple list; don't clear the data
     *   Integer.MIN_VALUE ==> one SINGLE data value should be used for all selected atoms
     */
    if (type == null) {
      clear();
      return;
    }
    type = type.toLowerCase();
    if (type.equals("element_vdw")) {
      String stringData = ((String) data[1]).trim();
      if (stringData.length() == 0) {
        userVdwMars = null;
        userVdws = null;
        bsUserVdws = null;
        return;
      }
      if (bsUserVdws == null)
        setUserVdw(defaultVdw);
      Parser.parseFloatArrayFromMatchAndField(stringData, bsUserVdws, 1, 0,
          (int[]) data[2], 2, 0, userVdws, 1);
      for (int i = userVdws.length; --i >= 0;)
        userVdwMars[i] = (int) (userVdws[i] * 1000);
      return;
    }
    if (data[2] != null && atomCount > 0) {
      boolean createNew = (matchField != 0 || field != Integer.MIN_VALUE
          && field != Integer.MAX_VALUE);
      Object[] oldData = (Object[]) dataValues.get(type);
      BitSet bs;
      float[] f = (oldData == null || createNew ? new float[atomCount]
          : ArrayUtil.ensureLength(((float[]) oldData[1]), atomCount));

      // check to see if the data COULD be interpreted as a string of float values
      // and if so, do that. This pre-fetches the tokens in that case.

      String stringData = (data[1] instanceof String ? (String) data[1] : null);
      float[] floatData = (data[1] instanceof float[] ? (float[]) data[1] : null);
      String[] strData = null;
      if (field == Integer.MIN_VALUE
          && (strData = Parser.getTokens(stringData)).length > 1)
        field = 0;

      if (field == Integer.MIN_VALUE) {
        // set the selected data elements to a single value
        bs = (BitSet) data[2];
        Parser.setSelectedFloats(Parser.parseFloat(stringData), bs, f);
      } else if (field == 0 || field == Integer.MAX_VALUE) {
        // just get the selected token values
        bs = (BitSet) data[2];
        if (floatData != null) {
          for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i + 1))
            f[i] = floatData[i];
        } else {
          Parser.parseFloatArray(strData == null ? Parser.getTokens(stringData)
            : strData, bs, f);
        }
      } else if (matchField <= 0) {
        // get the specified field >= 1 for the selected atoms
        bs = (BitSet) data[2];
        Parser.parseFloatArrayFromMatchAndField(stringData, bs, 0, 0, null,
            field, fieldColumnCount, f, 1);
      } else {
        // get the selected field, with an integer match in a specified field
        // in this case, bs is created and indicates which data points were set
        int[] iData = (int[]) data[2];
        Parser.parseFloatArrayFromMatchAndField(stringData, null, matchField,
            matchFieldColumnCount, iData, field, fieldColumnCount, f, 1);
        bs = new BitSet();
        for (int i = iData.length; --i >= 0;)
          if (iData[i] >= 0)
            bs.set(iData[i]);
      }
      if (oldData != null && oldData[2] instanceof BitSet && !createNew)
        bs.or((BitSet) (oldData[2]));
      data[2] = bs;
      data[1] = f;
      if (type.indexOf("property_atom.") == 0) {
        int tok = Token.getSettableTokFromString(type = type.substring(14));
        if (tok == Token.nada) {
          Logger.error("Unknown atom property: " + type);
          return;
        }
        int nValues = bs.cardinality();
        float[] fValues = new float[nValues];
        for (int n = 0, i = bs.nextSetBit(0); n < nValues; i = bs
            .nextSetBit(i + 1))
          fValues[n++] = f[i];
        viewer.setAtomProperty(bs, tok, 0, 0, null, fValues, null);
        return;
      }
    }
    dataValues.put(type, data);
  }

  Object[] getData(String type) {
    if (dataValues == null || type == null)
      return null;
    if (type.equalsIgnoreCase("types")) {
      String[] info = new String[2];
      info[0] = "types";
      info[1] = "";
      int n = 0;
      Enumeration e = (dataValues.keys());
      while (e.hasMoreElements())
        info[1] += (n++ > 0 ? "\n" : "") + e.nextElement();
      return info;
    }
    return (Object[]) dataValues.get(type);
  }

  float[] getDataFloat(String label) {
    if (dataValues == null)
      return null;
    Object[] data = getData(label);
    if (data == null || !(data[1] instanceof float[]))
      return null;
    return (float[]) data[1];
  }

  float getDataFloat(String label, int atomIndex) {
    if (dataValues != null) {
      Object[] data = getData(label);
      if (data != null && data[1] instanceof float[]) {
        float[] f = (float[]) data[1];
        if (atomIndex < f.length)
          return f[atomIndex];
      }
    }
    return Float.NaN;
  }

  float[][] getDataFloat2D(String label) {
    if (dataValues == null)
      return null;
    Object[] data = getData(label);
    if (data == null || !(data[1] instanceof float[][]))
      return null;
    return (float[][]) data[1];
  }

  float[][][] getDataFloat3D(String label) {
    if (dataValues == null)
      return null;
    Object[] data = getData(label);
    if (data == null || !(data[1] instanceof float[][][]))
      return null;
    return (float[][][]) data[1];
  }

  void deleteModelAtoms(int firstAtomIndex, int nAtoms, BitSet bsDeleted) {
    if (dataValues == null)
      return;
    Enumeration e = (dataValues.keys());
    while (e.hasMoreElements()) {
      String name = (String) e.nextElement();
      if (name.indexOf("property_") == 0) {
        Object[] obj = (Object[]) dataValues.get(name);
        BitSetUtil.deleteBits((BitSet) obj[2], bsDeleted);
        if (obj[1] instanceof float[]) {
          obj[1] = ArrayUtil.deleteElements((float[]) obj[1], firstAtomIndex, nAtoms);
        } else if (obj[1] instanceof float[][]){
          obj[1] = ArrayUtil.deleteElements((float[][]) obj[1], firstAtomIndex, nAtoms);
        } else {
          // is there anything else??
        }
      }
    }   
  }

  void getDataState(StringBuffer state, StringBuffer sfunc, String atomProps) {
    if (dataValues == null)
      return;
    Enumeration e = (dataValues.keys());
    StringBuffer sb = new StringBuffer();
    int n = 0;
    if (atomProps.length() > 0) {
      n = 1;
      sb.append(atomProps);
    }
    while (e.hasMoreElements()) {
      String name = (String) e.nextElement();
      if (name.indexOf("property_") == 0) {
        n++;
        Object[] obj = (Object[]) dataValues.get(name);
        Object data = obj[1];
        if (data instanceof float[]) {
          viewer.getAtomicPropertyState(sb, AtomCollection.TAINT_MAX,
              (BitSet) obj[2],
              name, (float[]) data);
          sb.append("\n");
        } else {
          sb.append("\n").append(Escape.encapsulateData(name, data));
        }
      } else if (name.indexOf("data2d") == 0) {
        Object data = ((Object[]) dataValues.get(name))[1];
        if (data instanceof float[][]) {
          n++;
          sb.append("\n").append(Escape.encapsulateData(name, data));
        }
      }
    }
   
    if (userVdws != null) {
      String info = getDefaultVdwNameOrData(JmolConstants.VDW_USER, bsUserVdws);
      if (info.length() > 0) {
        n++;
        sb.append(info);
      }
    }
   
    if (n == 0)
      return;
    if (sfunc != null)
      state.append("function _setDataState() {\n");
    state.append(sb)
    if (sfunc != null) {
      sfunc.append("  _setDataState;\n");
      state.append("}\n\n");
    }
  }

  private float[] userVdws;
  int[] userVdwMars;
  int defaultVdw = JmolConstants.VDW_JMOL;
  BitSet bsUserVdws;
 
  private void setUserVdw(int iMode) {
    userVdwMars = new int[Elements.elementNumberMax];
    userVdws = new float[Elements.elementNumberMax];
    bsUserVdws = new BitSet();
    if (iMode == JmolConstants.VDW_USER)
      iMode = JmolConstants.VDW_JMOL;
    for (int i = 1; i < Elements.elementNumberMax; i++) {
      userVdwMars[i] = JmolConstants.getVanderwaalsMar(i, iMode);
      userVdws[i] = userVdwMars[i] / 1000f;
    }
  }

  void setDefaultVdw(int iType) {
    // only allowed types here are VDW_JMOL, VDW_BABEL, VDW_RASMOL, VDW_USER, VDW_AUTO
    switch (iType) {
    case JmolConstants.VDW_JMOL:
    case JmolConstants.VDW_BABEL:
    case JmolConstants.VDW_RASMOL:
    case JmolConstants.VDW_AUTO:
      break;
    default:
      iType = JmolConstants.VDW_JMOL;
    }
    if (iType != defaultVdw && iType == JmolConstants.VDW_USER 
        && bsUserVdws == null)
      setUserVdw(defaultVdw);
    defaultVdw = iType;   
  }

  String getDefaultVdwNameOrData(int iType, BitSet bs) {
    // called by getDataState and via Viewer: Eval.calculate,
    // Eval.show, StateManager.getLoadState, Viewer.setDefaultVdw
    switch (iType) {
    case Integer.MIN_VALUE:
      // iMode Integer.MIN_VALUE -- just the name
      return JmolConstants.vdwLabels[defaultVdw];
    case Integer.MAX_VALUE:
      // iMode = Integer.MAX_VALUE -- user, only selected
      if ((bs = bsUserVdws) == null)
        return "";
      iType = JmolConstants.VDW_USER;
      break;
    case JmolConstants.VDW_AUTO:
    case JmolConstants.VDW_UNKNOWN:
      iType = defaultVdw;
      break;
    }
    if (iType == JmolConstants.VDW_USER && bsUserVdws == null) {
      setUserVdw(defaultVdw);
    }
    StringBuffer sb = new StringBuffer(JmolConstants.vdwLabels[iType] + "\n");
    boolean isAll = (bs == null);
    int i0 = (isAll ? 1 : bs.nextSetBit(0));
    int i1 = (isAll ? Elements.elementNumberMax : bs.length());
    for (int i = i0; i < i1 && i >= 0; i = (isAll ? i + 1 : bs
        .nextSetBit(i + 1)))
      sb.append(i).append('\t').append(
          iType == JmolConstants.VDW_USER ? userVdws[i] : JmolConstants
              .getVanderwaalsMar(i, iType) / 1000f).append('\t').append(
          Elements.elementSymbolFromNumber(i)).append('\n');
    return (bs == null ? sb.toString() : "\n  DATA \"element_vdw\"\n"
        + sb.append("  end \"element_vdw\";\n\n").toString());
  }

  static void getInlineData(StringBuffer loadScript, String strModel, boolean isAppend, String loadFilter) {
    String tag = (isAppend ? "append" : "model") + " inline";
    loadScript.append("load data \"").append(tag).append("\"\n")
        .append(strModel).append("end \"").append(tag)
        .append(loadFilter == null || loadFilter.length() == 0 ? "" : " filter" + Escape.escape(loadFilter))
        .append("\";");
  }
}
TOP

Related Classes of org.jmol.viewer.DataManager

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.