Main Page   Namespace List   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-2011 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.100 $      $Date: 2011/03/05 17:15: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", "Fragment",
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   "Name",          "Type",          "Element",
00056   "ResName",       "ResType",       "ResID",    
00057   "Chain",         "SegName",       "Conformation",
00058   "Molecule",      "Secondary Structure", 
00059   "ColorID",       "Beta",          "Occupancy", 
00060   "Mass",          "Charge",   
00061   "Position/Radial", "Position/X", "Position/Y", "Position/Z", 
00062   "Trajectory/User/User", "Trajectory/User/User2", "Trajectory/User/User3", "Trajectory/User/User4",
00063   "Fragment", "Index",  "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[FRAGMENT], CMDLEN)) {
00188     newMethod = FRAGMENT;
00189   } else if(!strupncmp(argv[0], AtomColorName[POS], CMDLEN)) {
00190     newMethod = POS;
00191   } else if(!strupncmp(argv[0], AtomColorName[POSX], CMDLEN)) {
00192     newMethod = POSX;
00193   } else if(!strupncmp(argv[0], AtomColorName[POSY], CMDLEN)) {
00194     newMethod = POSY;
00195   } else if(!strupncmp(argv[0], AtomColorName[POSZ], CMDLEN)) {
00196     newMethod = POSZ;
00197   } else if(!strupncmp(argv[0], AtomColorName[INDEX], CMDLEN)) {
00198     newMethod = INDEX;
00199   } else if(!strupncmp(argv[0], AtomColorName[BACKBONE], CMDLEN)) {
00200     newMethod = BACKBONE;
00201   } else if(!strupncmp(argv[0], AtomColorName[THROB], CMDLEN)) {
00202     newMethod = THROB;
00203   } else if(!strupncmp(argv[0], AtomColorName[PHYSICALTIME], CMDLEN)) {
00204     newMethod = PHYSICALTIME;
00205   } else if(!strupncmp(argv[0], AtomColorName[TIMESTEP], CMDLEN)) {
00206     newMethod = TIMESTEP;
00207   } else if(!strupncmp(argv[0], AtomColorName[VELOCITY], CMDLEN)) {
00208     newMethod = VELOCITY;
00209   } else if(!strupncmp(argv[0], AtomColorName[VOLUME], CMDLEN) && argc > 1) {
00210     newMethod = VOLUME;
00211     newVol = atoi(argv[1]);
00212   } else {
00213     // unknown representation
00214     ok = FALSE;
00215   }
00216 
00217   // check the command was not too long
00218   ok = ok && ((((newMethod == COLORID) || 
00219                 (newMethod == VOLUME)) && argc < 4) || 
00220                 (newMethod != COLORID && argc < 3));
00221 
00222   // print error message if necessary
00223   if (!ok) {
00224     msgErr << "Incorrect atom color method command '" << newcmd << "'";
00225     msgErr << sendmsg;
00226   } else {
00227     // command was successful, save new settings
00228     colorMethod = newMethod;
00229     colIndex = newIndex;
00230     volIndex = newVol;
00231     strcpy(cmdStr, newcmd);
00232 
00233     // range check colorid index    
00234     if (colIndex < 0)
00235       colIndex = 0;
00236     else if (colIndex > VISCLRS)
00237       colIndex = VISCLRS;
00238 
00239     // range check volume index    
00240     if (volIndex < 0)
00241       volIndex = 0;
00242 
00243     need_recalc_minmax = TRUE;
00244   }
00245 
00246   // delete parsing space
00247   delete [] cmdStrTok;
00248   return ok;
00249 }
00250 
00251 
00253 
00254 // equal operator, to change the current settings.  Does NOT change the
00255 // current molecule, molecule list, or color list.
00256 AtomColor& AtomColor::operator=(const AtomColor &ar) {
00257 
00258   // copy values
00259   if(cmdStr != ar.cmdStr)
00260     strcpy(cmdStr, ar.cmdStr);
00261   colorMethod = ar.colorMethod;
00262   colIndex = ar.colIndex;
00263   volIndex = ar.volIndex;
00264   
00265   // update current colors based on new settings
00266   need_recalc_minmax = TRUE;
00267   find(mol);  
00268     
00269   return *this;
00270 }
00271 
00272 int AtomColor::current_color_use(int ccat) {
00273 
00274   if((colorMethod==MOLECULE&& ccat==molList->colorCatIndex[MLCAT_MOLECULES])
00275     || (colorMethod==CONFORMATION&& ccat==molList->colorCatIndex[MLCAT_CONFORMATIONS])
00276     || (colorMethod==NAME&& ccat==molList->colorCatIndex[MLCAT_NAMES])
00277     || (colorMethod==TYPE&& ccat==molList->colorCatIndex[MLCAT_TYPES])
00278     || (colorMethod==ELEMENT&& ccat==molList->colorCatIndex[MLCAT_ELEMENTS])
00279     || (colorMethod==RESNAME&& ccat==molList->colorCatIndex[MLCAT_RESNAMES])
00280     || (colorMethod==RESTYPE&& ccat==molList->colorCatIndex[MLCAT_RESTYPES])
00281     || (colorMethod==CHAIN&& ccat==molList->colorCatIndex[MLCAT_CHAINS])
00282     || (colorMethod==SEGNAME&& ccat==molList->colorCatIndex[MLCAT_SEGNAMES])
00283     || (colorMethod==BACKBONE&& ccat==molList->colorCatIndex[MLCAT_SPECIAL])
00284     || (colorMethod==STRUCTURE&& ccat==molList->colorCatIndex[MLCAT_SSTRUCT])
00285     ) {
00286       return TRUE;
00287   }
00288   
00289   return FALSE;
00290 }
00291 
00292 // find the color index for the atoms of the given molecule.  Return success.
00293 int AtomColor::find(DrawMolecule *m) {
00294   int dindex;
00295 
00296   // make sure things are OK
00297   if(!m || !molList)
00298     return FALSE;
00299     
00300   // save new molecule, and remove old storage if necessary  
00301   if(color && mol && nAtoms != m->nAtoms) {
00302     delete [] color;
00303     color = NULL;
00304   }
00305 
00306   // allocate new storage
00307   mol = m;
00308   nAtoms = m->nAtoms;
00309   if(!color)
00310     color = new int[nAtoms];
00311 
00312   if (need_recalc_minmax) {
00313     //initialize color scale for Color Methods that don't support them 
00314     minRange = 0.;  
00315     maxRange = 0.;
00316   }
00317   
00318   // check for special cases
00319   if(colorMethod == MOLECULE) {
00320     char buf[20];
00321     sprintf(buf, "%d", mol->id());
00322     dindex = scene->category_item_value(molList->colorCatIndex[MLCAT_MOLECULES],
00323         buf);
00324     colIndex = dindex;
00325 
00326     for(int i=0; i < nAtoms; color[i++] = dindex) ;
00327 
00328   } else if(colorMethod == COLORID) {
00329     dindex = colIndex;
00330     for(int i=0; i < nAtoms; i++) {
00331       color[i] = dindex;
00332     }
00333   } else if(colorMethod == THROB) {
00334     double timeval, t;
00335     t = time_of_day();
00336     timeval = fmod((t / 2.0), 1.0) * 254; 
00337 
00338     // loop every 255 time steps
00339     float scalefac = (float)(MAPCLRS-1) / 255.0f;
00340     dindex = MAPCOLOR((int)(0.5 + timeval*scalefac));
00341 
00342     for(int i=0; i < nAtoms; i++) {
00343       color[i] = dindex;
00344     }
00345   } else if(colorMethod == PHYSICALTIME) {
00346     dindex = MAPCOLOR(MAPCLRS/2);
00347 
00348     // if a timestep is current and we have a nonzero range, assign a color
00349     // otherwise set coloring to midrange
00350     Timestep *ts = mol->current();
00351     if (ts && maxRange > minRange) {
00352       float scalefac = (float)(MAPCLRS-1) / (maxRange - minRange);
00353       int dindex2 = (int)(scalefac * ts->physical_time - minRange);
00354 
00355       // dindex2 might be out of range because of user-specified min/max,
00356       // so clamp it.
00357       if (dindex2 < 0)
00358         dindex2 = 0;
00359       else if (dindex2 >= MAPCLRS) 
00360         dindex2 = MAPCLRS-1;
00361 
00362       dindex = MAPCOLOR(dindex2);
00363     }
00364 
00365     // assign the final color
00366     for(int i=0; i < nAtoms; i++) {
00367       color[i] = dindex;
00368     }
00369   } else if(colorMethod == TIMESTEP) {
00370     float scalefac = (float)(MAPCLRS-1) / ((float) mol->numframes());
00371     dindex = MAPCOLOR((int)(0.5f + (mol->frame() * scalefac)));
00372     for(int i=0; i < nAtoms; i++) {
00373       color[i] = dindex;
00374     }
00375   } else if(colorMethod == VOLUME) {
00376     // Must use a white color so that the 3-D texture map can be 
00377     // 'modulated' onto the lit surface, preserving shading results
00378     dindex = scene->nearest_index(1.0, 1.0, 1.0); 
00379     for(int i=0; i < nAtoms; i++) {
00380       color[i] = dindex;
00381     }
00382 
00383     // Get min/max values from selected volume
00384     if (need_recalc_minmax && mol->num_volume_data()) {
00385       const VolumetricData *v = mol->get_volume_data(volIndex);
00386       if (v != NULL) {
00387         minRange = v->datamin;
00388         maxRange = v->datamax;
00389       }
00390 
00391       need_recalc_minmax = FALSE;
00392     }
00393   } else if(colorMethod == BACKBONE) {
00394     int regc = scene->category_item_value(molList->colorCatIndex[MLCAT_SPECIAL],
00395                 "Nonback");
00396     int proc = scene->category_item_value(molList->colorCatIndex[MLCAT_SPECIAL],
00397                 "Proback");
00398     int dnac = scene->category_item_value(molList->colorCatIndex[MLCAT_SPECIAL],
00399                 "Nucback");
00400     for (int i=0; i < nAtoms; i++) {
00401       MolAtom *a = mol->atom(i);
00402       int c = regc;
00403       if (a->atomType == ATOMPROTEINBACK ||
00404           a->atomType == ATOMNUCLEICBACK) {  // is this a backbone atom?
00405         // only color it as a backbone atom if it is actually connected 
00406         // to other backbone atoms
00407         // XXX why don't we just trust the value of atomType?
00408         for(int j=0; j < a->bonds; j++) {
00409           int bondtype = mol->atom(a->bondTo[j])->atomType;
00410           if (bondtype == ATOMPROTEINBACK) {
00411             c = proc;
00412             break;
00413           } else if (bondtype == ATOMNUCLEICBACK) {
00414             c = dnac;
00415             break;
00416           }
00417         }
00418       }
00419       color[i] = c;
00420     }
00421   } else if (colorMethod == STRUCTURE) {
00422     int ind = molList->colorCatIndex[MLCAT_SSTRUCT];
00423     int alpha_helix = scene->category_item_value(ind, "Alpha Helix");
00424     int helix_3_10 = scene->category_item_value(ind, "3_10_Helix");
00425     int pi_helix = scene->category_item_value(ind, "Pi_Helix");
00426     int extended_beta = scene->category_item_value(ind, "Extended_Beta");
00427     int bridge_beta = scene->category_item_value(ind, "Bridge_Beta");
00428     int turn = scene->category_item_value(ind, "Turn");
00429     int coil = scene->category_item_value(ind, "Coil");
00430     mol->need_secondary_structure(1); // make sure I have secondary structure
00431     for (int i=0; i<nAtoms; i++) {
00432       Residue *a = mol->residue(mol->atom(i)->uniq_resid);
00433       switch (a->sstruct) {
00434       case SS_HELIX_ALPHA: color[i] = alpha_helix; break;
00435       case SS_HELIX_3_10: color[i] = helix_3_10; break;
00436       case SS_HELIX_PI: color[i] = pi_helix; break;
00437       case SS_BETA: color[i] = extended_beta; break;
00438       case SS_BRIDGE: color[i] = bridge_beta; break;
00439       case SS_TURN: color[i] = turn; break;
00440       case SS_COIL: 
00441       default: color[i] = coil; break;
00442       }
00443     }
00444   } else if(colorMethod == RESID) {
00445     for(int i=0; i < nAtoms; i++) {
00446       dindex = (mol->atom(i))->resid % VISCLRS;
00447       while (dindex < 0) dindex += VISCLRS;
00448       color[i] = dindex;
00449     }
00450     
00451   } else if ((colorMethod >= BETA && colorMethod <= INDEX) ||
00452               colorMethod == VELOCITY) {
00453     // These all color floating point ranges.
00454     // The method is:
00455     //  1) get the array of values from either
00456     //    a) the symbol table
00457     //    b) compute the distance value
00458     //  2) find the min/max
00459     //  3) set the colors
00460     // If no timestep, just color by molecule
00461     
00462     // first find current timestep
00463     const Timestep *ts = mol->current();
00464     if (!ts) {
00465       // no timestep is current; set coloring by molecule and return
00466       ColorMethod oldMethod = colorMethod;
00467       colorMethod = MOLECULE;
00468       find(mol);
00469       colorMethod = oldMethod;
00470       return TRUE;
00471     }
00472     // get the data and find the min/max values
00473     float data_min, data_max;
00474     float *data = new float[nAtoms];
00475     if (colorMethod == POS) { 
00476       float *pos = mol->current()->pos;
00477       float cov[3];
00478       float tmp[3];
00479 
00480       mol->cov(cov[0], cov[1], cov[2]);
00481       vec_sub(tmp, cov, pos);
00482       data[0] = data_min = data_max = norm(tmp);
00483       for (int i=1; i<nAtoms; i++) {
00484         pos += 3;
00485         vec_sub(tmp, cov, pos);
00486         data[i] = norm(tmp);
00487         if (data_min > data[i]) data_min = data[i];
00488         if (data_max < data[i]) data_max = data[i];
00489       }
00490     } else if (colorMethod == POSX) { 
00491       float *pos = mol->current()->pos;
00492       data[0] = data_min = data_max = pos[0];
00493       for (int i=1; i<nAtoms; i++) {
00494         pos += 3;
00495         data[i] = pos[0];
00496         if (data_min > data[i]) data_min = data[i];
00497         if (data_max < data[i]) data_max = data[i];
00498       }
00499     } else if (colorMethod == POSY) { 
00500       float *pos = mol->current()->pos;
00501       data[0] = data_min = data_max = pos[1];
00502       for (int i=1; i<nAtoms; i++) {
00503         pos += 3;
00504         data[i] = pos[1];
00505         if (data_min > data[i]) data_min = data[i];
00506         if (data_max < data[i]) data_max = data[i];
00507       }
00508     } else if (colorMethod == POSZ) { 
00509       float *pos = mol->current()->pos;
00510       data[0] = data_min = data_max = pos[2];
00511       for (int i=1; i<nAtoms; i++) {
00512         pos += 3;
00513         data[i] = pos[2];
00514         if (data_min > data[i]) data_min = data[i];
00515         if (data_max < data[i]) data_max = data[i];
00516       }
00517     } else if (colorMethod == FRAGMENT) {
00518       data_min = 0;
00519       data_max = (float) (mol->nFragments-1);
00520       for (int i=0; i<mol->nAtoms; i++) {
00521         data[i] = (float) mol->residue(mol->atom(i)->uniq_resid)->fragment;
00522       }
00523     } else if (colorMethod == INDEX) {
00524       data_min = 0;
00525       data_max = (float) (nAtoms-1);
00526       for (int i=0; i<nAtoms; i++) 
00527         data[i] = (float) i;
00528     } else if (colorMethod == USER || colorMethod == USER2 || 
00529                colorMethod == USER3 || colorMethod == USER4) {
00530       const float *user = NULL;
00531       if (colorMethod == USER)
00532         user = mol->current()->user;
00533       else if (colorMethod == USER2)
00534         user = mol->current()->user2;
00535       else if (colorMethod == USER3)
00536         user = mol->current()->user3;
00537       else if (colorMethod == USER4)
00538         user = mol->current()->user4;
00539 
00540       if (!user) {
00541         memset(data, 0, nAtoms*sizeof(float));
00542         data_min = data_max = 0;
00543       } else {
00544         memcpy(data, user, nAtoms*sizeof(float));
00545         data_min = data_max = data[0];
00546         for (int i=1; i<nAtoms; i++) {
00547           if (data_min > data[i]) data_min = data[i];
00548           if (data_max < data[i]) data_max = data[i];
00549         }
00550       }
00551     } else if (colorMethod == VELOCITY) { 
00552       float *vel = mol->current()->vel;
00553 
00554       if (!vel) {
00555         memset(data, 0, nAtoms*sizeof(float));
00556         data_min = data_max = 0;
00557       } else {
00558         data[0] = data_min = data_max = norm(vel);
00559         for (int i=1; i<nAtoms; i++) {
00560           vel += 3;
00561           data[i] = norm(vel);
00562           if (data_min > data[i]) data_min = data[i];
00563           if (data_max < data[i]) data_max = data[i];
00564         }
00565       }
00566     } else {
00567       const float *atomfield;
00568       switch (colorMethod) {
00569       case BETA: atomfield = mol->beta(); break;
00570       case OCCUP: atomfield = mol->occupancy(); break;
00571       case MASS: atomfield = mol->mass(); break;
00572       case CHARGE: atomfield = mol->charge(); break;
00573       default: atomfield = mol->mass(); 
00574       }
00575       // XXX memcpy because we always free later...
00576       memcpy(data, atomfield, nAtoms*sizeof(float));
00577       data_min = data_max = data[0];
00578       for (int i=1; i < nAtoms; i++) {
00579         if (data_min > data[i]) data_min = data[i];
00580         if (data_max < data[i]) data_max = data[i];
00581       }
00582     }
00583 
00584     if (need_recalc_minmax) {
00585       minRange = data_min;
00586       maxRange = data_max;
00587       need_recalc_minmax = FALSE;
00588     } else {
00589       data_min = minRange;
00590       data_max = maxRange;
00591     }
00592 
00593     // 3) define the colors
00594     if (data_min == data_max) {
00595       for (int i=0; i<nAtoms; i++) {
00596         color[i] = MAPCOLOR(MAPCLRS/2);
00597       }
00598     } else {
00599       float scalefac = (float)(MAPCLRS-1) / (data_max - data_min);
00600       int dindex2;
00601       for (int i=0; i<nAtoms; i++) {
00602         dindex2 = (int)(scalefac * (data[i] - data_min));
00603         // dindex2 might be out of range because of user-specified min/max,
00604         // so clamp it.
00605         if (dindex2 < 0)
00606           dindex2 = 0;
00607         else if (dindex2 >= MAPCLRS) 
00608           dindex2 = MAPCLRS-1;
00609         color[i] = MAPCOLOR(dindex2);
00610       }
00611     }
00612     delete [] data;
00613 
00614   } else if(colorMethod == NAME) {
00615     int ind = molList->colorCatIndex[MLCAT_NAMES];
00616     for (int i=0; i < nAtoms; i++) {
00617       dindex = scene->category_item_value(ind,
00618           (mol->atomNames).data((mol->atom(i))->nameindex));
00619       color[i] = dindex;
00620     }
00621     
00622   } else if(colorMethod == CONFORMATION) {
00623     int i;
00624     int ind = molList->colorCatIndex[MLCAT_CONFORMATIONS];
00625     int allconf = scene->category_item_value(ind, "all");
00626 
00627     NameList<int> *molnames = &(mol->altlocNames);
00628     int alltypecode = molnames->typecode("");
00629 
00630     for(i=0; i < nAtoms; i++) {
00631       int atomidx = (mol->altlocNames).data((mol->atom(i))->altlocindex);
00632       if (atomidx == alltypecode)
00633         dindex = allconf;
00634       else
00635         dindex = scene->category_item_value(ind, atomidx);
00636       color[i] = dindex;
00637     }
00638     
00639   } else if(colorMethod == TYPE) {
00640     int ind = molList->colorCatIndex[MLCAT_TYPES];
00641     for(int i=0; i < nAtoms; i++) {
00642       dindex = scene->category_item_value(ind,
00643           (mol->atomTypes).data((mol->atom(i))->typeindex));
00644       color[i] = dindex;
00645     }
00646 
00647   } else if(colorMethod == ELEMENT) {
00648     int ind = molList->colorCatIndex[MLCAT_ELEMENTS];
00649     for(int i=0; i < nAtoms; i++) {
00650       dindex = scene->category_item_value(ind, 
00651           get_pte_label(mol->atom(i)->atomicnumber));
00652       color[i] = dindex;
00653     }
00654     
00655   } else if(colorMethod == RESNAME) {
00656     int ind = molList->colorCatIndex[MLCAT_RESNAMES];
00657     for(int i=0; i < nAtoms; i++) {
00658       dindex=scene->category_item_value(ind,
00659           (mol->resNames).data((mol->atom(i))->resnameindex));
00660       color[i] = dindex;
00661     }
00662     
00663   } else if(colorMethod == RESTYPE) {
00664     int ind = molList->colorCatIndex[MLCAT_RESTYPES];
00665     for(int i=0; i < nAtoms; i++) {
00666       dindex=scene->category_item_value(ind,
00667                 (molList->resTypes).data((mol->resNames).name(mol->atom(i)->resnameindex)));
00668       color[i] = dindex;
00669     }
00670     
00671   } else if(colorMethod == CHAIN) {
00672     int ind = molList->colorCatIndex[MLCAT_CHAINS];
00673     for(int i=0; i < nAtoms; i++) {
00674       dindex=scene->category_item_value(ind,
00675           (mol->chainNames).data((mol->atom(i))->chainindex));
00676       color[i] = dindex;
00677     }
00678 
00679   } else if(colorMethod == SEGNAME) {
00680     int ind = molList->colorCatIndex[MLCAT_SEGNAMES];
00681     for(int i=0; i < nAtoms; i++) {
00682       dindex=scene->category_item_value(ind,
00683           (mol->segNames).data((mol->atom(i))->segnameindex));
00684       color[i] = dindex;
00685     }
00686 
00687   } else {
00688     msgErr << "Unknown coloring method " << (int)colorMethod << " in AtomColor.";
00689     msgErr << sendmsg;
00690     return FALSE;
00691   }
00692     
00693   return TRUE;
00694 }
00695 
00696 int AtomColor::uses_colorscale() const {
00697   return ((colorMethod >= BETA && colorMethod <= INDEX) || 
00698            colorMethod == VOLUME);
00699 }
00700 

Generated on Wed May 16 01:48:58 2012 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002