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

AtomColor.C

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

Generated on Fri Mar 29 02:44:31 2024 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002