Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

AtomColor.C

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr                                                                       
00003  *cr            (C) Copyright 1995-2008 The Board of Trustees of the           
00004  *cr                        University of Illinois                       
00005  *cr                         All Rights Reserved                        
00006  *cr                                                                   
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  * RCS INFORMATION:
00011  *
00012  *      $RCSfile: AtomColor.C,v $
00013  *      $Author: johns $        $Locker:  $                $State: Exp $
00014  *      $Revision: 1.95 $      $Date: 2008/03/27 19:36:34 $
00015  *
00016  ***************************************************************************
00017  * DESCRIPTION:
00018  * 
00019  * Parse and maintain the data for how a molecule should be colored.
00020  *
00021  ***************************************************************************/
00022 
00023 #include <math.h>
00024 #include <string.h>
00025 #include <stdlib.h>
00026 #include <stdio.h>
00027 #include "AtomColor.h"
00028 #include "DrawMolecule.h"
00029 #include "MoleculeList.h"
00030 #include "Scene.h"
00031 #include "VolumetricData.h"
00032 #include "PeriodicTable.h"
00033 #include "Inform.h"
00034 #include "utilities.h"
00035 #include "config.h"
00036 
00037 //
00038 // XXX global string arrays with text descriptions of coloring methods
00039 //
00040 const char *AtomColorName[AtomColor::TOTAL] = { 
00041   "Name",     "Type",     "Element",
00042   "ResName",  "ResType",  "ResID",    
00043   "Chain", "SegName",  "Conformation",
00044   "Molecule", "Structure", 
00045   "ColorID",  "Beta",     "Occupancy", 
00046   "Mass",     "Charge",   
00047   "Pos",      "PosX",     "PosY",  "PosZ", 
00048   "User",     "User2",    "User3", "User4",
00049   "Index",    "Backbone", "Throb",
00050   "PhysicalTime", "Timestep", "Velocity", "Volume"
00051   };
00052 
00053 // These names are used within GUI menus, so they contain submenu names etc
00054 const char *AtomColorMenuName[AtomColor::TOTAL] = { 
00055   "Atom/Name",          "Atom/Type",          "Atom/Element",
00056   "Residue/ResName",    "Residue/ResType",    "Residue/ResID",    
00057   "Structure/Chain",    "Structure/SegName",  "Structure/Conformation",
00058   "Structure/Molecule", "Structure/Secondary Structure", 
00059   "ColorID",            "Atom/Beta",          "Atom/Occupancy", 
00060   "Atom/Mass",          "Atom/Charge",   
00061   "Position/Radial", "Position/X", "Position/Y", "Position/Z", 
00062   "Trajectory/User/User", "Trajectory/User/User2", "Trajectory/User/User3", "Trajectory/User/User4",
00063   "Atom/Index",  "Structure/Backbone", "Throb",
00064   "Trajectory/Physical Time", "Trajectory/Timestep", "Trajectory/Velocity", "Volume"
00065   };
00066 
00067 
00069 // constructor; parse string and see if OK
00070 AtomColor::AtomColor(MoleculeList *mlist, const Scene *sc) {
00071 
00072   // initialize variables
00073   molList = mlist;
00074   scene = sc;
00075   color = NULL;
00076   colIndex = 0;
00077   volIndex = 0;
00078   nAtoms = 0;
00079   mol = NULL;
00080   colorMethod  = DEFAULT_ATOMCOLOR;
00081   strcpy(cmdStr, AtomColorName[DEFAULT_ATOMCOLOR]);
00082   do_update = 0;
00083   need_recalc_minmax = TRUE;
00084   minRange = maxRange = 0;
00085 }
00086 
00087 
00088 // copy constructor
00089 AtomColor::AtomColor(AtomColor& ar) {
00090   strcpy(cmdStr, ar.cmdStr);
00091   colorMethod = ar.colorMethod;
00092   colIndex = ar.colIndex;
00093   volIndex = ar.volIndex;
00094   scene = ar.scene;
00095   molList = ar.molList;
00096   mol = ar.mol;
00097   if(ar.color) {
00098     nAtoms = ar.nAtoms;
00099     color = new int[nAtoms];
00100     for(int i=0; i < nAtoms; i++)
00101       color[i] = ar.color[i];
00102   } else {
00103     nAtoms = 0;
00104     color = NULL;
00105   }
00106   do_update = ar.do_update;
00107   need_recalc_minmax = TRUE;
00108   minRange = maxRange = 0;
00109 }
00110 
00111 
00112 // destructor; free up space
00113 AtomColor::~AtomColor(void) {
00114   if(color)
00115     delete [] color;
00116 }
00117 
00118 
00120 
00121 // parse the given command, and store results.  Return success.
00122 int AtomColor::parse_cmd(const char *newcmd) {
00123   int argc, ok = TRUE;
00124   char *argv[128], *cmdStrTok = NULL;
00125 
00126   ColorMethod newMethod = colorMethod;
00127   int newIndex = colIndex;
00128   int newVol   = volIndex;
00129  
00130   // make sure the new command is not too long
00131   if(newcmd && strlen(newcmd) > MAX_ATOMCOLOR_CMD) {
00132     msgErr << "Atom coloring method string is too long (over ";
00133     msgErr << MAX_ATOMCOLOR_CMD << " characters)." << sendmsg;
00134     return FALSE;
00135   }
00136 
00137   // tokenize the command
00138   if(!newcmd || !(cmdStrTok = str_tokenize(newcmd, &argc, argv))) {
00139     // no command; keep current settings
00140     return TRUE;
00141   }
00142 
00143   // now parse the command
00144   if(!strupncmp(argv[0], "default", CMDLEN)) {
00145     newMethod = DEFAULT_ATOMCOLOR;
00146   } else if(!strupncmp(argv[0], AtomColorName[NAME], CMDLEN)) {
00147     newMethod = NAME;
00148   } else if(!strupncmp(argv[0], AtomColorName[TYPE], CMDLEN)) {
00149     newMethod = TYPE;
00150   } else if(!strupncmp(argv[0], AtomColorName[ELEMENT], CMDLEN)) {
00151     newMethod = ELEMENT;
00152   } else if(!strupncmp(argv[0], AtomColorName[RESNAME], CMDLEN)) {
00153     newMethod = RESNAME;
00154   } else if(!strupncmp(argv[0], AtomColorName[RESTYPE], CMDLEN)) {
00155     newMethod = RESTYPE;
00156   } else if(!strupncmp(argv[0], AtomColorName[RESID], CMDLEN)) {
00157     newMethod = RESID;
00158   } else if(!strupncmp(argv[0], AtomColorName[CHAIN], CMDLEN)) {
00159     newMethod = CHAIN;
00160   } else if(!strupncmp(argv[0], AtomColorName[SEGNAME], CMDLEN)) {
00161     newMethod = SEGNAME;
00162   } else if(!strupncmp(argv[0], AtomColorName[CONFORMATION], CMDLEN)) {
00163     newMethod = CONFORMATION;
00164   } else if(!strupncmp(argv[0], AtomColorName[MOLECULE], CMDLEN)) {
00165     newMethod = MOLECULE;
00166   } else if(!strupncmp(argv[0], AtomColorName[STRUCTURE], CMDLEN)) {
00167     newMethod = STRUCTURE;
00168   } else if(!strupncmp(argv[0], AtomColorName[COLORID], CMDLEN) && argc > 1) {
00169     newMethod = COLORID;
00170     newIndex = atoi(argv[1]);
00171   } else if(!strupncmp(argv[0], AtomColorName[BETA], CMDLEN)) {
00172     newMethod = BETA;
00173   } else if(!strupncmp(argv[0], AtomColorName[OCCUP], CMDLEN)) {
00174     newMethod = OCCUP;
00175   } else if(!strupncmp(argv[0], AtomColorName[MASS], CMDLEN)) {
00176     newMethod = MASS;
00177   } else if(!strupncmp(argv[0], AtomColorName[CHARGE], CMDLEN)) {
00178     newMethod = CHARGE;
00179   } else if(!strupncmp(argv[0], AtomColorName[USER], CMDLEN)) {
00180     newMethod = USER;
00181   } else if(!strupncmp(argv[0], AtomColorName[USER2], CMDLEN)) {
00182     newMethod = USER2;
00183   } else if(!strupncmp(argv[0], AtomColorName[USER3], CMDLEN)) {
00184     newMethod = USER3;
00185   } else if(!strupncmp(argv[0], AtomColorName[USER4], CMDLEN)) {
00186     newMethod = USER4;
00187   } else if(!strupncmp(argv[0], AtomColorName[POS], CMDLEN)) {
00188     newMethod = POS;
00189   } else if(!strupncmp(argv[0], AtomColorName[POSX], CMDLEN)) {
00190     newMethod = POSX;
00191   } else if(!strupncmp(argv[0], AtomColorName[POSY], CMDLEN)) {
00192     newMethod = POSY;
00193   } else if(!strupncmp(argv[0], AtomColorName[POSZ], CMDLEN)) {
00194     newMethod = POSZ;
00195   } else if(!strupncmp(argv[0], AtomColorName[INDEX], CMDLEN)) {
00196     newMethod = INDEX;
00197   } else if(!strupncmp(argv[0], AtomColorName[BACKBONE], CMDLEN)) {
00198     newMethod = BACKBONE;
00199   } else if(!strupncmp(argv[0], AtomColorName[THROB], CMDLEN)) {
00200     newMethod = THROB;
00201   } else if(!strupncmp(argv[0], AtomColorName[PHYSICALTIME], CMDLEN)) {
00202     newMethod = PHYSICALTIME;
00203   } else if(!strupncmp(argv[0], AtomColorName[TIMESTEP], CMDLEN)) {
00204     newMethod = TIMESTEP;
00205   } else if(!strupncmp(argv[0], AtomColorName[VELOCITY], CMDLEN)) {
00206     newMethod = VELOCITY;
00207   } else if(!strupncmp(argv[0], AtomColorName[VOLUME], CMDLEN) && argc > 1) {
00208     newMethod = VOLUME;
00209     newVol = atoi(argv[1]);
00210   } else {
00211     // unknown representation
00212     ok = FALSE;
00213   }
00214 
00215   // check the command was not too long
00216   ok = ok && ((((newMethod == COLORID) || 
00217                 (newMethod == VOLUME)) && argc < 4) || 
00218                 (newMethod != COLORID && argc < 3));
00219 
00220   // print error message if necessary
00221   if (!ok) {
00222     msgErr << "Incorrect atom color method command '" << newcmd << "'";
00223     msgErr << sendmsg;
00224   } else {
00225     // command was successful, save new settings
00226     colorMethod = newMethod;
00227     colIndex = newIndex;
00228     volIndex = newVol;
00229     strcpy(cmdStr, newcmd);
00230 
00231     // range check colorid index    
00232     if (colIndex < 0)
00233       colIndex = 0;
00234     else if (colIndex > VISCLRS)
00235       colIndex = VISCLRS;
00236 
00237     // range check volume index    
00238     if (volIndex < 0)
00239       volIndex = 0;
00240 
00241     need_recalc_minmax = TRUE;
00242   }
00243 
00244   // delete parsing space
00245   delete [] cmdStrTok;
00246   return ok;
00247 }
00248 
00249 
00251 
00252 // equal operator, to change the current settings.  Does NOT change the
00253 // current molecule, molecule list, or color list.
00254 AtomColor& AtomColor::operator=(const AtomColor &ar) {
00255 
00256   // copy values
00257   if(cmdStr != ar.cmdStr)
00258     strcpy(cmdStr, ar.cmdStr);
00259   colorMethod = ar.colorMethod;
00260   colIndex = ar.colIndex;
00261   volIndex = ar.volIndex;
00262   
00263   // update current colors based on new settings
00264   need_recalc_minmax = TRUE;
00265   find(mol);  
00266     
00267   return *this;
00268 }
00269 
00270 int AtomColor::current_color_use(int ccat) {
00271 
00272   if((colorMethod==MOLECULE&& ccat==molList->colorCatIndex[MLCAT_MOLECULES])
00273     || (colorMethod==CONFORMATION&& ccat==molList->colorCatIndex[MLCAT_CONFORMATIONS])
00274     || (colorMethod==NAME&& ccat==molList->colorCatIndex[MLCAT_NAMES])
00275     || (colorMethod==TYPE&& ccat==molList->colorCatIndex[MLCAT_TYPES])
00276     || (colorMethod==ELEMENT&& ccat==molList->colorCatIndex[MLCAT_ELEMENTS])
00277     || (colorMethod==RESNAME&& ccat==molList->colorCatIndex[MLCAT_RESNAMES])
00278     || (colorMethod==RESTYPE&& ccat==molList->colorCatIndex[MLCAT_RESTYPES])
00279     || (colorMethod==CHAIN&& ccat==molList->colorCatIndex[MLCAT_CHAINS])
00280     || (colorMethod==SEGNAME&& ccat==molList->colorCatIndex[MLCAT_SEGNAMES])
00281     || (colorMethod==BACKBONE&& ccat==molList->colorCatIndex[MLCAT_SPECIAL])
00282     || (colorMethod==STRUCTURE&& ccat==molList->colorCatIndex[MLCAT_SSTRUCT])
00283     ) {
00284       return TRUE;
00285   }
00286   
00287   return FALSE;
00288 }
00289 
00290 // find the color index for the atoms of the given molecule.  Return success.
00291 int AtomColor::find(DrawMolecule *m) {
00292   int dindex;
00293 
00294   // make sure things are OK
00295   if(!m || !molList)
00296     return FALSE;
00297     
00298   // save new molecule, and remove old storage if necessary  
00299   if(color && mol && nAtoms != m->nAtoms) {
00300     delete [] color;
00301     color = NULL;
00302   }
00303 
00304   // allocate new storage
00305   mol = m;
00306   nAtoms = m->nAtoms;
00307   if(!color)
00308     color = new int[nAtoms];
00309 
00310   if (need_recalc_minmax) {
00311     //initialize color scale for Color Methods that don't support them 
00312     minRange = 0.;  
00313     maxRange = 0.;
00314   }
00315   
00316   // check for special cases
00317   if(colorMethod == MOLECULE) {
00318     char buf[20];
00319     sprintf(buf, "%d", mol->id());
00320     dindex = scene->category_item_value(molList->colorCatIndex[MLCAT_MOLECULES],
00321         buf);
00322     colIndex = dindex;
00323 
00324     for(int i=0; i < nAtoms; color[i++] = dindex) ;
00325 
00326   } else if(colorMethod == COLORID) {
00327     dindex = colIndex;
00328     for(int i=0; i < nAtoms; i++) {
00329       color[i] = dindex;
00330     }
00331   } else if(colorMethod == THROB) {
00332     double timeval, t;
00333     t = time_of_day();
00334     timeval = fmod((t / 2.0), 1.0) * 254; 
00335 
00336     // loop every 255 time steps
00337     float scalefac = (float)(MAPCLRS-1) / 255.0f;
00338     dindex = MAPCOLOR((int)(0.5 + timeval*scalefac));
00339 
00340     for(int i=0; i < nAtoms; i++) {
00341       color[i] = dindex;
00342     }
00343   } else if(colorMethod == PHYSICALTIME) {
00344     dindex = MAPCOLOR(MAPCLRS/2);
00345 
00346     // if a timestep is current and we have a nonzero range, assign a color
00347     // otherwise set coloring to midrange
00348     Timestep *ts = mol->current();
00349     if (ts && maxRange > minRange) {
00350       float scalefac = (float)(MAPCLRS-1) / (maxRange - minRange);
00351       int dindex2 = (int)(scalefac * ts->physical_time - minRange);
00352 
00353       // dindex2 might be out of range because of user-specified min/max,
00354       // so clamp it.
00355       if (dindex2 < 0)
00356         dindex2 = 0;
00357       else if (dindex2 >= MAPCLRS) 
00358         dindex2 = MAPCLRS-1;
00359 
00360       dindex = MAPCOLOR(dindex2);
00361     }
00362 
00363     // assign the final color
00364     for(int i=0; i < nAtoms; i++) {
00365       color[i] = dindex;
00366     }
00367   } else if(colorMethod == TIMESTEP) {
00368     float scalefac = (float)(MAPCLRS-1) / ((float) mol->numframes());
00369     dindex = MAPCOLOR((int)(0.5f + (mol->frame() * scalefac)));
00370     for(int i=0; i < nAtoms; i++) {
00371       color[i] = dindex;
00372     }
00373   } else if(colorMethod == VOLUME) {
00374     // Must use a white color so that the 3-D texture map can be 
00375     // 'modulated' onto the lit surface, preserving shading results
00376     dindex = scene->nearest_index(1.0, 1.0, 1.0); 
00377     for(int i=0; i < nAtoms; i++) {
00378       color[i] = dindex;
00379     }
00380 
00381     // Get min/max values from selected volume
00382     if (need_recalc_minmax && mol->num_volume_data()) {
00383       const VolumetricData *v = mol->get_volume_data(volIndex);
00384       if (v != NULL) {
00385         minRange = v->datamin;
00386         maxRange = v->datamax;
00387       }
00388 
00389       need_recalc_minmax = FALSE;
00390     }
00391   } else if(colorMethod == BACKBONE) {
00392     int regc = scene->category_item_value(molList->colorCatIndex[MLCAT_SPECIAL],
00393                 "Nonback");
00394     int proc = scene->category_item_value(molList->colorCatIndex[MLCAT_SPECIAL],
00395                 "Proback");
00396     int dnac = scene->category_item_value(molList->colorCatIndex[MLCAT_SPECIAL],
00397                 "Nucback");
00398     for (int i=0; i < nAtoms; i++) {
00399       MolAtom *a = mol->atom(i);
00400       int c = regc;
00401       if (a->atomType == ATOMPROTEINBACK ||
00402           a->atomType == ATOMNUCLEICBACK) {  // is this a backbone atom?
00403         // only color it as a backbone atom if it is actually connected 
00404         // to other backbone atoms
00405         // XXX why don't we just trust the value of atomType?
00406         for(int j=0; j < a->bonds; j++) {
00407           int bondtype = mol->atom(a->bondTo[j])->atomType;
00408           if (bondtype == ATOMPROTEINBACK) {
00409             c = proc;
00410             break;
00411           } else if (bondtype == ATOMNUCLEICBACK) {
00412             c = dnac;
00413             break;
00414           }
00415         }
00416       }
00417       color[i] = c;
00418     }
00419   } else if (colorMethod == STRUCTURE) {
00420     int ind = molList->colorCatIndex[MLCAT_SSTRUCT];
00421     int alpha_helix = scene->category_item_value(ind, "Alpha Helix");
00422     int helix_3_10 = scene->category_item_value(ind, "3_10_Helix");
00423     int pi_helix = scene->category_item_value(ind, "Pi_Helix");
00424     int extended_beta = scene->category_item_value(ind, "Extended_Beta");
00425     int bridge_beta = scene->category_item_value(ind, "Bridge_Beta");
00426     int turn = scene->category_item_value(ind, "Turn");
00427     int coil = scene->category_item_value(ind, "Coil");
00428     mol->need_secondary_structure(1); // make sure I have secondary structure
00429     for (int i=0; i<nAtoms; i++) {
00430       Residue *a = mol->residue(mol->atom(i)->uniq_resid);
00431       switch (a->sstruct) {
00432       case SS_HELIX_ALPHA: color[i] = alpha_helix; break;
00433       case SS_HELIX_3_10: color[i] = helix_3_10; break;
00434       case SS_HELIX_PI: color[i] = pi_helix; break;
00435       case SS_BETA: color[i] = extended_beta; break;
00436       case SS_BRIDGE: color[i] = bridge_beta; break;
00437       case SS_TURN: color[i] = turn; break;
00438       case SS_COIL: 
00439       default: color[i] = coil; break;
00440       }
00441     }
00442   } else if(colorMethod == RESID) {
00443     for(int i=0; i < nAtoms; i++) {
00444       dindex = (mol->atom(i))->resid % VISCLRS;
00445       while (dindex < 0) dindex += VISCLRS;
00446       color[i] = dindex;
00447     }
00448     
00449   } else if ((colorMethod >= BETA && colorMethod <= INDEX) ||
00450               colorMethod == VELOCITY) {
00451     // These all color floating point ranges.
00452     // The method is:
00453     //  1) get the array of values from either
00454     //    a) the symbol table
00455     //    b) compute the distance value
00456     //  2) find the min/max
00457     //  3) set the colors
00458     // If no timestep, just color by molecule
00459     
00460     // first find current timestep
00461     const Timestep *ts = mol->current();
00462     if (!ts) {
00463       // no timestep is current; set coloring by molecule and return
00464       ColorMethod oldMethod = colorMethod;
00465       colorMethod = MOLECULE;
00466       find(mol);
00467       colorMethod = oldMethod;
00468       return TRUE;
00469     }
00470     // get the data and find the min/max values
00471     float data_min, data_max;
00472     float *data = new float[nAtoms];
00473     if (colorMethod == POS) { 
00474       float *pos = mol->current()->pos;
00475       float cov[3];
00476       float tmp[3];
00477 
00478       mol->cov(cov[0], cov[1], cov[2]);
00479       vec_sub(tmp, cov, pos);
00480       data[0] = data_min = data_max = norm(tmp);
00481       for (int i=1; i<nAtoms; i++) {
00482         pos += 3;
00483         vec_sub(tmp, cov, pos);
00484         data[i] = norm(tmp);
00485         if (data_min > data[i]) data_min = data[i];
00486         if (data_max < data[i]) data_max = data[i];
00487       }
00488     } else if (colorMethod == POSX) { 
00489       float *pos = mol->current()->pos;
00490       data[0] = data_min = data_max = pos[0];
00491       for (int i=1; i<nAtoms; i++) {
00492         pos += 3;
00493         data[i] = pos[0];
00494         if (data_min > data[i]) data_min = data[i];
00495         if (data_max < data[i]) data_max = data[i];
00496       }
00497     } else if (colorMethod == POSY) { 
00498       float *pos = mol->current()->pos;
00499       data[0] = data_min = data_max = pos[1];
00500       for (int i=1; i<nAtoms; i++) {
00501         pos += 3;
00502         data[i] = pos[1];
00503         if (data_min > data[i]) data_min = data[i];
00504         if (data_max < data[i]) data_max = data[i];
00505       }
00506     } else if (colorMethod == POSZ) { 
00507       float *pos = mol->current()->pos;
00508       data[0] = data_min = data_max = pos[2];
00509       for (int i=1; i<nAtoms; i++) {
00510         pos += 3;
00511         data[i] = pos[2];
00512         if (data_min > data[i]) data_min = data[i];
00513         if (data_max < data[i]) data_max = data[i];
00514       }
00515     } else if (colorMethod == INDEX) {
00516       data_min = 0;
00517       data_max = (float) (nAtoms-1);
00518       for (int i=0; i<nAtoms; i++) 
00519         data[i] = (float) i;
00520     } else if (colorMethod == USER || colorMethod == USER2 || 
00521                colorMethod == USER3 || colorMethod == USER4) {
00522       const float *user = NULL;
00523       if (colorMethod == USER)
00524         user = mol->current()->user;
00525       else if (colorMethod == USER2)
00526         user = mol->current()->user2;
00527       else if (colorMethod == USER3)
00528         user = mol->current()->user3;
00529       else if (colorMethod == USER4)
00530         user = mol->current()->user4;
00531 
00532       if (!user) {
00533         memset(data, 0, nAtoms*sizeof(float));
00534         data_min = data_max = 0;
00535       } else {
00536         memcpy(data, user, nAtoms*sizeof(float));
00537         data_min = data_max = data[0];
00538         for (int i=1; i<nAtoms; i++) {
00539           if (data_min > data[i]) data_min = data[i];
00540           if (data_max < data[i]) data_max = data[i];
00541         }
00542       }
00543     } else if (colorMethod == VELOCITY) { 
00544       float *vel = mol->current()->vel;
00545 
00546       if (!vel) {
00547         memset(data, 0, nAtoms*sizeof(float));
00548         data_min = data_max = 0;
00549       } else {
00550         data[0] = data_min = data_max = norm(vel);
00551         for (int i=1; i<nAtoms; i++) {
00552           vel += 3;
00553           data[i] = norm(vel);
00554           if (data_min > data[i]) data_min = data[i];
00555           if (data_max < data[i]) data_max = data[i];
00556         }
00557       }
00558     } else {
00559       const float *atomfield;
00560       switch (colorMethod) {
00561       case BETA: atomfield = mol->beta(); break;
00562       case OCCUP: atomfield = mol->occupancy(); break;
00563       case MASS: atomfield = mol->mass(); break;
00564       case CHARGE: atomfield = mol->charge(); break;
00565       default: atomfield = mol->mass(); 
00566       }
00567       // XXX memcpy because we always free later...
00568       memcpy(data, atomfield, nAtoms*sizeof(float));
00569       data_min = data_max = data[0];
00570       for (int i=1; i < nAtoms; i++) {
00571         if (data_min > data[i]) data_min = data[i];
00572         if (data_max < data[i]) data_max = data[i];
00573       }
00574     }
00575 
00576     if (need_recalc_minmax) {
00577       minRange = data_min;
00578       maxRange = data_max;
00579       need_recalc_minmax = FALSE;
00580     } else {
00581       data_min = minRange;
00582       data_max = maxRange;
00583     }
00584 
00585     // 3) define the colors
00586     if (data_min == data_max) {
00587       for (int i=0; i<nAtoms; i++) {
00588         color[i] = MAPCOLOR(MAPCLRS/2);
00589       }
00590     } else {
00591       float scalefac = (float)(MAPCLRS-1) / (data_max - data_min);
00592       int dindex2;
00593       for (int i=0; i<nAtoms; i++) {
00594         dindex2 = (int)(scalefac * (data[i] - data_min));
00595         // dindex2 might be out of range because of user-specified min/max,
00596         // so clamp it.
00597         if (dindex2 < 0)
00598           dindex2 = 0;
00599         else if (dindex2 >= MAPCLRS) 
00600           dindex2 = MAPCLRS-1;
00601         color[i] = MAPCOLOR(dindex2);
00602       }
00603     }
00604     delete [] data;
00605 
00606   } else if(colorMethod == NAME) {
00607     int ind = molList->colorCatIndex[MLCAT_NAMES];
00608     for (int i=0; i < nAtoms; i++) {
00609       dindex = scene->category_item_value(ind,
00610           (mol->atomNames).data((mol->atom(i))->nameindex));
00611       color[i] = dindex;
00612     }
00613     
00614   } else if(colorMethod == CONFORMATION) {
00615     int i;
00616     int ind = molList->colorCatIndex[MLCAT_CONFORMATIONS];
00617     int allconf = scene->category_item_value(ind, "all");
00618 
00619     NameList<int> *molnames = &(mol->altlocNames);
00620     int alltypecode = molnames->typecode("");
00621 
00622     for(i=0; i < nAtoms; i++) {
00623       int atomidx = (mol->altlocNames).data((mol->atom(i))->altlocindex);
00624       if (atomidx == alltypecode)
00625         dindex = allconf;
00626       else
00627         dindex = scene->category_item_value(ind, atomidx);
00628       color[i] = dindex;
00629     }
00630     
00631   } else if(colorMethod == TYPE) {
00632     int ind = molList->colorCatIndex[MLCAT_TYPES];
00633     for(int i=0; i < nAtoms; i++) {
00634       dindex = scene->category_item_value(ind,
00635           (mol->atomTypes).data((mol->atom(i))->typeindex));
00636       color[i] = dindex;
00637     }
00638 
00639   } else if(colorMethod == ELEMENT) {
00640     int ind = molList->colorCatIndex[MLCAT_ELEMENTS];
00641     for(int i=0; i < nAtoms; i++) {
00642       dindex = scene->category_item_value(ind, 
00643           get_pte_label(mol->atom(i)->atomicnumber));
00644       color[i] = dindex;
00645     }
00646     
00647   } else if(colorMethod == RESNAME) {
00648     int ind = molList->colorCatIndex[MLCAT_RESNAMES];
00649     for(int i=0; i < nAtoms; i++) {
00650       dindex=scene->category_item_value(ind,
00651           (mol->resNames).data((mol->atom(i))->resnameindex));
00652       color[i] = dindex;
00653     }
00654     
00655   } else if(colorMethod == RESTYPE) {
00656     int ind = molList->colorCatIndex[MLCAT_RESTYPES];
00657     for(int i=0; i < nAtoms; i++) {
00658       dindex=scene->category_item_value(ind,
00659                 (molList->resTypes).data((mol->resNames).name(mol->atom(i)->resnameindex)));
00660       color[i] = dindex;
00661     }
00662     
00663   } else if(colorMethod == CHAIN) {
00664     int ind = molList->colorCatIndex[MLCAT_CHAINS];
00665     for(int i=0; i < nAtoms; i++) {
00666       dindex=scene->category_item_value(ind,
00667           (mol->chainNames).data((mol->atom(i))->chainindex));
00668       color[i] = dindex;
00669     }
00670 
00671   } else if(colorMethod == SEGNAME) {
00672     int ind = molList->colorCatIndex[MLCAT_SEGNAMES];
00673     for(int i=0; i < nAtoms; i++) {
00674       dindex=scene->category_item_value(ind,
00675           (mol->segNames).data((mol->atom(i))->segnameindex));
00676       color[i] = dindex;
00677     }
00678 
00679   } else {
00680     msgErr << "Unknown coloring method " << (int)colorMethod << " in AtomColor.";
00681     msgErr << sendmsg;
00682     return FALSE;
00683   }
00684     
00685   return TRUE;
00686 }
00687 
00688 int AtomColor::uses_colorscale() const {
00689   return ((colorMethod >= BETA && colorMethod <= INDEX) || 
00690            colorMethod == VOLUME);
00691 }
00692 

Generated on Thu Jul 3 01:27:16 2008 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002