00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <math.h>
00024 #include <stdlib.h>
00025 #include <stdio.h>
00026 #include <ctype.h>
00027 #include <string.h>
00028
00029 #if defined(ARCH_AIX4)
00030 #include <strings.h>
00031 #endif
00032
00033 #include "Atom.h"
00034 #include "AtomSel.h"
00035 #include "DrawMolecule.h"
00036 #include "MoleculeList.h"
00037 #include "VMDApp.h"
00038 #include "Inform.h"
00039 #include "SymbolTable.h"
00040 #include "ParseTree.h"
00041 #include "JRegex.h"
00042 #include "VolumetricData.h"
00043 #include "PeriodicTable.h"
00044 #include "DrawRingsUtils.h"
00045
00046
00047 static int atomsel_all(void * ,int, int *) {
00048 return 1;
00049 }
00050
00051
00052 static int atomsel_none(void *, int num, int *flgs) {
00053 for (int i=num-1; i>=0; i--) {
00054 flgs[i] = FALSE;
00055 }
00056 return 1;
00057 }
00058
00059 #define generic_atom_data(fctnname, datatype, field) \
00060 static int fctnname(void *v, int num, datatype *data, int *flgs) { \
00061 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol; \
00062 for (int i=0; i<num; i++) { \
00063 if (flgs[i]) { \
00064 data[i] = atom_sel_mol->atom(i)->field; \
00065 } \
00066 } \
00067 return 1; \
00068 }
00069
00070
00071 #define generic_set_atom_data(fctnname, datatype, fieldtype, field) \
00072 static int fctnname(void *v, int num, datatype *data, int *flgs) { \
00073 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol; \
00074 int i; \
00075 for (i=0; i<num; i++) { \
00076 if (flgs[i]) { \
00077 atom_sel_mol->atom(i)->field = (fieldtype) data[i]; \
00078 } \
00079 } \
00080 return 1; \
00081 }
00082
00083
00084
00085 static int atomsel_name(void *v, int num, const char **data, int *flgs) {
00086 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00087 for (int i=0; i<num; i++) {
00088 if (flgs[i])
00089 data[i] = (atom_sel_mol->atomNames).name(
00090 atom_sel_mol->atom(i)->nameindex);
00091 }
00092 return 1;
00093 }
00094
00095
00096
00097 static int atomsel_type(void *v, int num, const char **data, int *flgs) {
00098 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00099 for (int i=0; i<num; i++) {
00100 if (flgs[i])
00101 data[i] = (atom_sel_mol->atomTypes).name(
00102 atom_sel_mol->atom(i)->typeindex);
00103 }
00104 return 1;
00105 }
00106
00107
00108
00109 static int atomsel_backbonetype(void *v, int num, const char **data, int *flgs) {
00110 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00111 for (int i=0; i<num; i++) {
00112 if (flgs[i]) {
00113 switch (atom_sel_mol->atom(i)->atomType) {
00114 case ATOMNORMAL:
00115 data[i] = "normal";
00116 break;
00117
00118 case ATOMPROTEINBACK:
00119 data[i] = "proteinback";
00120 break;
00121
00122 case ATOMNUCLEICBACK:
00123 data[i] = "nucleicback";
00124 break;
00125
00126 case ATOMHYDROGEN:
00127 data[i] = "hydrogen";
00128 break;
00129
00130 default:
00131 data[i] = "unknown";
00132 break;
00133 }
00134 }
00135 }
00136 return 1;
00137 }
00138
00139
00140
00141
00142 static int atomsel_residuetype(void *v, int num, const char **data, int *flgs) {
00143 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00144 for (int i=0; i<num; i++) {
00145 if (flgs[i]) {
00146 switch (atom_sel_mol->atom(i)->residueType) {
00147 case RESNOTHING:
00148 data[i] = "nothing";
00149 break;
00150
00151 case RESPROTEIN:
00152 data[i] = "protein";
00153 break;
00154
00155 case RESNUCLEIC:
00156 data[i] = "nucleic";
00157 break;
00158
00159 case RESWATERS:
00160 data[i] = "waters";
00161 break;
00162
00163 default:
00164 data[i] = "unknown";
00165 break;
00166 }
00167 }
00168 }
00169 return 1;
00170 }
00171
00172
00173
00174 generic_atom_data(atomsel_atomicnumber, int, atomicnumber)
00175
00176 static int atomsel_set_atomicnumber(void *v, int num, int *data, int *flgs) {
00177 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00178 int i;
00179 for (i=0; i<num; i++) {
00180 if (flgs[i]) {
00181 atom_sel_mol->atom(i)->atomicnumber = (int) data[i];
00182 }
00183 }
00184
00185 atom_sel_mol->set_dataset_flag(BaseMolecule::ATOMICNUMBER);
00186 return 1;
00187 }
00188
00189
00190
00191 static int atomsel_element(void *v, int num, const char **data, int *flgs) {
00192 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00193 for (int i=0; i<num; i++) {
00194 if (flgs[i])
00195 data[i] = get_pte_label(atom_sel_mol->atom(i)->atomicnumber);
00196 }
00197 return 1;
00198 }
00199 static int atomsel_set_element(void *v, int num, const char **data, int *flgs) {
00200 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00201 for (int i=0; i<num; i++) {
00202 if (flgs[i]) {
00203 int idx = get_pte_idx_from_string((const char *)(data[i]));
00204 atom_sel_mol->atom(i)->atomicnumber = idx;
00205 }
00206 }
00207
00208 atom_sel_mol->set_dataset_flag(BaseMolecule::ATOMICNUMBER);
00209 return 1;
00210 }
00211
00212
00213
00214 static int atomsel_index(void *v, int num, int *data, int *flgs) {
00215 for (int i=0; i<num; i++) {
00216 if (flgs[i]) {
00217 data[i] = i;
00218 }
00219 }
00220 return 1;
00221 }
00222
00223
00224
00225 static int atomsel_serial(void *v, int num, int *data, int *flgs) {
00226 for (int i=0; i<num; i++) {
00227 if (flgs[i]) {
00228 data[i] = i + 1;
00229 }
00230 }
00231 return 1;
00232 }
00233
00234
00235
00236 static int atomsel_fragment(void *v, int num, int *data, int *flgs) {
00237 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00238 for (int i=0; i<num; i++) {
00239 if (flgs[i]) {
00240 int residue = atom_sel_mol->atom(i)->uniq_resid;
00241 data[i] = (atom_sel_mol->residue(residue))->fragment;
00242 }
00243 }
00244 return 1;
00245 }
00246
00247
00248
00249 generic_atom_data(atomsel_numbonds, int, bonds)
00250
00251
00252
00253 generic_atom_data(atomsel_residue, int, uniq_resid)
00254
00255
00256
00257 static int atomsel_resname(void *v, int num, const char **data, int *flgs) {
00258 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00259 for (int i=0; i<num; i++) {
00260 if (flgs[i])
00261 data[i] = (atom_sel_mol->resNames).name(
00262 atom_sel_mol->atom(i)->resnameindex);
00263 }
00264 return 1;
00265 }
00266
00267
00268
00269 static int atomsel_altloc(void *v, int num, const char **data, int *flgs) {
00270 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00271 for (int i=0; i<num; i++) {
00272 if (flgs[i])
00273 data[i] = (atom_sel_mol->altlocNames).name(
00274 atom_sel_mol->atom(i)->altlocindex);
00275 }
00276 return 1;
00277 }
00278 static int atomsel_set_altloc(void *v, int num, const char **data, int *flgs) {
00279 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00280 NameList<int> &arr = atom_sel_mol->altlocNames;
00281 for (int i=0; i<num; i++) {
00282 if (flgs[i]) {
00283 int ind = arr.add_name((const char *)(data[i]), arr.num());
00284 atom_sel_mol->atom(i)->altlocindex = ind;
00285 }
00286 }
00287
00288 atom_sel_mol->set_dataset_flag(BaseMolecule::ALTLOC);
00289 return 1;
00290 }
00291
00292
00293
00294 generic_atom_data(atomsel_insertion, const char *, insertionstr)
00295
00296
00297
00298 static int atomsel_chain(void *v, int num, const char **data, int *flgs) {
00299 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00300 for (int i=0; i<num; i++) {
00301 if (flgs[i])
00302 data[i] = (atom_sel_mol->chainNames).name(
00303 atom_sel_mol->atom(i)->chainindex);
00304 }
00305 return 1;
00306 }
00307
00308
00309
00310 static int atomsel_segname(void *v, int num, const char **data, int *flgs) {
00311 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00312 for (int i=0; i<num; i++) {
00313 if (flgs[i])
00314 data[i] = (atom_sel_mol->segNames).name(
00315 atom_sel_mol->atom(i)->segnameindex);
00316 }
00317 return 1;
00318 }
00319
00320
00321
00322 static int atomsel_set_name(void *v, int num, const char **data, int *flgs) {
00323 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00324 NameList<int> &arr = atom_sel_mol->atomNames;
00325 for (int i=0; i<num; i++) {
00326 if (flgs[i]) {
00327 int ind = arr.add_name((const char *)(data[i]), arr.num());
00328 atom_sel_mol->atom(i)->nameindex = ind;
00329 }
00330 }
00331 return 1;
00332 }
00333
00334 static int atomsel_set_type(void *v, int num, const char **data, int *flgs) {
00335 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00336 NameList<int> &arr = atom_sel_mol->atomTypes;
00337 for (int i=0; i<num; i++) {
00338 if (flgs[i]) {
00339 int ind = arr.add_name((const char *)(data[i]), arr.num());
00340 atom_sel_mol->atom(i)->typeindex = ind;
00341 }
00342 }
00343 return 1;
00344 }
00345
00346 static int atomsel_set_resname(void *v, int num, const char **data, int *flgs) {
00347 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00348 NameList<int> &arr = atom_sel_mol->resNames;
00349 for (int i=0; i<num; i++) {
00350 if (flgs[i]) {
00351 int ind = arr.add_name((const char *)(data[i]), arr.num());
00352 atom_sel_mol->atom(i)->resnameindex = ind;
00353 }
00354 }
00355 return 1;
00356 }
00357
00358 static int atomsel_set_chain(void *v, int num, const char **data, int *flgs) {
00359 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00360 NameList<int> &arr = atom_sel_mol->chainNames;
00361 for (int i=0; i<num; i++) {
00362 if (flgs[i]) {
00363 int ind = arr.add_name((const char *)(data[i]), arr.num());
00364 atom_sel_mol->atom(i)->chainindex = ind;
00365 }
00366 }
00367 return 1;
00368 }
00369
00370 static int atomsel_set_segname(void *v, int num, const char **data, int *flgs) {
00371 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00372 NameList<int> &arr = atom_sel_mol->segNames;
00373 for (int i=0; i<num; i++) {
00374 if (flgs[i]) {
00375 int ind = arr.add_name((const char *)(data[i]), arr.num());
00376 atom_sel_mol->atom(i)->segnameindex = ind;
00377 }
00378 }
00379 return 1;
00380 }
00381
00382
00383
00384 static int atomsel_radius(void *v, int num, double *data, int *flgs) {
00385 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00386 float *radius = atom_sel_mol->radius();
00387 for (int i=0; i<num; i++)
00388 if (flgs[i]) data[i] = radius[i];
00389 return 1;
00390 }
00391 static int atomsel_set_radius(void *v, int num, double *data, int *flgs) {
00392 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00393 float *radius = atom_sel_mol->radius();
00394 for (int i=0; i<num; i++)
00395 if (flgs[i]) radius[i] = (float) data[i];
00396
00397
00398 atom_sel_mol->set_dataset_flag(BaseMolecule::RADIUS);
00399
00400
00401 atom_sel_mol->set_radii_changed();
00402
00403 return 1;
00404 }
00405
00406
00407
00408 static int atomsel_mass(void *v, int num, double *data, int *flgs) {
00409 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00410 float *mass = atom_sel_mol->mass();
00411 for (int i=0; i<num; i++)
00412 if (flgs[i]) data[i] = mass[i];
00413 return 1;
00414 }
00415 static int atomsel_set_mass(void *v, int num, double *data, int *flgs) {
00416 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00417 float *mass = atom_sel_mol->mass();
00418 for (int i=0; i<num; i++)
00419 if (flgs[i]) mass[i] = (float) data[i];
00420
00421 atom_sel_mol->set_dataset_flag(BaseMolecule::MASS);
00422 return 1;
00423 }
00424
00425
00426
00427 static int atomsel_charge(void *v, int num, double *data, int *flgs) {
00428 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00429 float *charge = atom_sel_mol->charge();
00430 for (int i=0; i<num; i++)
00431 if (flgs[i]) data[i] = charge[i];
00432 return 1;
00433 }
00434 static int atomsel_set_charge(void *v, int num, double *data, int *flgs) {
00435 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00436 float *charge = atom_sel_mol->charge();
00437 for (int i=0; i<num; i++)
00438 if (flgs[i]) charge[i] = (float) data[i];
00439
00440 atom_sel_mol->set_dataset_flag(BaseMolecule::CHARGE);
00441 return 1;
00442 }
00443
00444
00445
00446 static int atomsel_beta(void *v, int num, double *data, int *flgs) {
00447 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00448 float *beta = atom_sel_mol->beta();
00449 for (int i=0; i<num; i++)
00450 if (flgs[i]) data[i] = beta[i];
00451 return 1;
00452 }
00453 static int atomsel_set_beta(void *v, int num, double *data, int *flgs) {
00454 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00455 float *beta = atom_sel_mol->beta();
00456 for (int i=0; i<num; i++)
00457 if (flgs[i]) beta[i] = (float) data[i];
00458
00459 atom_sel_mol->set_dataset_flag(BaseMolecule::BFACTOR);
00460 return 1;
00461 }
00462
00463
00464
00465 static int atomsel_occupancy(void *v, int num, double *data, int *flgs) {
00466 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00467 float *occupancy = atom_sel_mol->occupancy();
00468 for (int i=0; i<num; i++)
00469 if (flgs[i]) data[i] = occupancy[i];
00470 return 1;
00471 }
00472 static int atomsel_set_occupancy(void *v, int num, double *data, int *flgs) {
00473 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00474 float *occupancy = atom_sel_mol->occupancy();
00475 for (int i=0; i<num; i++)
00476 if (flgs[i]) occupancy[i] = (float) data[i];
00477
00478 atom_sel_mol->set_dataset_flag(BaseMolecule::OCCUPANCY);
00479 return 1;
00480 }
00481
00482
00483
00484 static int atomsel_resid(void *v, int num, int *data, int *flgs) {
00485 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00486 for (int i=0; i<num; i++) {
00487 if (flgs[i]) {
00488 data[i] = atom_sel_mol->atom(i)->resid;
00489 }
00490 }
00491 return 1;
00492 }
00493 static int atomsel_set_resid(void *v, int num, int *data, int *flgs) {
00494 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00495 for (int i=0; i<num; i++) {
00496 if (flgs[i])
00497 atom_sel_mol->atom(i)->resid = data[i];
00498 }
00499 return 1;
00500 }
00501
00502
00503
00504 #define generic_atom_boolean(fctnname, comparison) \
00505 static int fctnname(void *v, int num, int *flgs) { \
00506 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol; \
00507 for (int i=0; i<num; i++) { \
00508 if (flgs[i]) { \
00509 flgs[i] = atom_sel_mol->atom(i)->comparison; \
00510 } \
00511 } \
00512 return 1; \
00513 }
00514
00515
00516 static int atomsel_backbone(void *v, int num, int *flgs) {
00517 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00518 for (int i=0; i<num; i++) {
00519 if (flgs[i]) {
00520 const MolAtom *a = atom_sel_mol->atom(i);
00521 flgs[i] = (a->atomType == ATOMPROTEINBACK ||
00522 a->atomType == ATOMNUCLEICBACK);
00523 }
00524 }
00525 return 1;
00526 }
00527
00528
00529 generic_atom_boolean(atomsel_hydrogen, atomType == ATOMHYDROGEN)
00530
00531
00532
00533 generic_atom_boolean(atomsel_protein, residueType == RESPROTEIN)
00534
00535
00536
00537 generic_atom_boolean(atomsel_nucleic, residueType == RESNUCLEIC)
00538
00539
00540
00541 generic_atom_boolean(atomsel_water, residueType == RESWATERS)
00542
00543 #define generic_sstruct_boolean(fctnname, comparison) \
00544 static int fctnname(void *v, int num, int *flgs) { \
00545 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol; \
00546 atom_sel_mol->need_secondary_structure(1); \
00547 for (int i=0; i<num; i++) { \
00548 int s; \
00549 if (flgs[i]) { \
00550 s = atom_sel_mol->residue( \
00551 atom_sel_mol->atom(i)->uniq_resid \
00552 )->sstruct; \
00553 if (!comparison) { \
00554 flgs[i] = 0; \
00555 } \
00556 } \
00557 } \
00558 return 1; \
00559 }
00560
00561
00562
00563 #define generic_set_sstruct_boolean(fctnname, newval) \
00564 static int fctnname(void *v, int num, int *data, int *flgs) { \
00565 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol; \
00566 atom_sel_mol->need_secondary_structure(0); \
00567 for (int i=0; i<num; i++) { \
00568 if (flgs[i] && data[i]) { \
00569 atom_sel_mol->residue(atom_sel_mol->atom(i)->uniq_resid) \
00570 ->sstruct = newval; \
00571 } \
00572 } \
00573 return 1; \
00574 }
00575
00576
00577
00578
00579 static void recursive_find_sidechain_atoms(BaseMolecule *mol, int *sidechain,
00580 int atom_index) {
00581
00582 if (sidechain[atom_index] == 2)
00583 return;
00584
00585
00586 MolAtom *atom = mol->atom(atom_index);
00587 if (atom->atomType == ATOMPROTEINBACK ||
00588 atom->atomType == ATOMNUCLEICBACK) return;
00589
00590
00591 sidechain[atom_index] = 2;
00592
00593
00594 for (int i=0; i<atom->bonds; i++) {
00595 recursive_find_sidechain_atoms(mol, sidechain, atom->bondTo[i]);
00596 }
00597 }
00598
00599
00600
00601 static void find_sidechain_atoms(BaseMolecule *mol, int *sidechain) {
00602 for (int i=0; i<mol->nAtoms; i++) {
00603 if (sidechain[i] == 1) {
00604 recursive_find_sidechain_atoms(mol, sidechain, i);
00605 }
00606 }
00607 }
00608
00609
00610
00611
00612
00613
00614 static int atomsel_sidechain(void *v, int num, int *flgs) {
00615 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00616 const float *mass = atom_sel_mol->mass();
00617 int *seed = new int[num];
00618 int i;
00619
00620
00621 for (i=0; i<num; i++) {
00622 seed[i] = 0;
00623 }
00624
00625
00626 int CA = atom_sel_mol->atomNames.typecode((char *) "CA");
00627
00628
00629 for (int pfrag=atom_sel_mol->pfragList.num()-1; pfrag>=0; pfrag--) {
00630
00631 Fragment &frag = *(atom_sel_mol->pfragList[pfrag]);
00632 for (int res = frag.num()-1; res >=0; res--) {
00633
00634 int atomid = atom_sel_mol->find_atom_in_residue(CA, frag[res]);
00635 if (atomid < 0) {
00636 msgErr << "atomselection: sidechain: cannot find CA" << sendmsg;
00637 continue;
00638 }
00639
00640 MolAtom *atom = atom_sel_mol->atom(atomid);
00641 int b1 = -1, b2 = -1;
00642 for (i=0; i<atom->bonds; i++) {
00643 int bondtype = atom_sel_mol->atom(atom->bondTo[i])->atomType;
00644 if (bondtype == ATOMNORMAL || bondtype == ATOMHYDROGEN) {
00645 if (b1 == -1) {
00646 b1 = atom->bondTo[i];
00647 } else {
00648 if (b2 == -1) {
00649 b2 = atom->bondTo[i];
00650 } else {
00651 msgErr << "atomselection: sidechain: protein residue index "
00652 << res << ", C-alpha index " << i << " has more than "
00653 << "two non-backbone bonds; ignoring the others"
00654 << sendmsg;
00655 }
00656 }
00657 }
00658 }
00659 if (b1 == -1)
00660 continue;
00661
00662 if (b2 != -1) {
00663
00664 int c1 = atom_sel_mol->atom(b1)->bonds;
00665 int c2 = atom_sel_mol->atom(b2)->bonds;
00666 if (c1 == 1 && c2 > 1) {
00667 b1 = b2;
00668 } else if (c2 == 1 && c1 > 1) {
00669 b1 = b1;
00670 } else if (c1 ==1 && c2 == 1) {
00671
00672 float m1 = mass[b1];
00673 float m2 = mass[b2];
00674 if (m1 > 2.3 && m2 <= 2.3) {
00675 b1 = b2;
00676 } else if (m2 > 2.3 && m1 <= 2.3) {
00677 b1 = b1;
00678 } else if (m1 <= 2.0 && m2 <= 2.3) {
00679
00680 if (strcmp(
00681 (atom_sel_mol->atomNames).name(atom_sel_mol->atom(b1)->nameindex),
00682 (atom_sel_mol->atomNames).name(atom_sel_mol->atom(b2)->nameindex)
00683 ) > 0) {
00684 b1 = b2;
00685 }
00686 } else {
00687 msgErr << "atomselect: sidechain: protein residue index "
00688 << res << ", C-alpha index " << i << " has sidechain-like "
00689 << "atom (indices " << b1 << " and " << b2 << "), and "
00690 << "I cannot determine which to call a sidechain -- "
00691 << "I'll guess" << sendmsg;
00692 if (strcmp(
00693 (atom_sel_mol->atomNames).name(atom_sel_mol->atom(b1)->nameindex),
00694 (atom_sel_mol->atomNames).name(atom_sel_mol->atom(b2)->nameindex)
00695 ) > 0) {
00696 b1 = b2;
00697 }
00698 }
00699 }
00700 }
00701 seed[b1] = 1;
00702
00703 }
00704 }
00705
00706
00707 find_sidechain_atoms(atom_sel_mol, seed);
00708
00709
00710 for (i=0; i<num; i++) {
00711 if (flgs[i])
00712 flgs[i] = (seed[i] != 0);
00713 }
00714
00715 delete [] seed;
00716
00717 return 1;
00718 }
00719
00720
00721
00722 generic_sstruct_boolean(atomsel_helix, (s == SS_HELIX_ALPHA ||
00723 s == SS_HELIX_3_10 ||
00724 s == SS_HELIX_PI))
00725 generic_sstruct_boolean(atomsel_alpha_helix, (s == SS_HELIX_ALPHA))
00726 generic_sstruct_boolean(atomsel_3_10_helix, (s == SS_HELIX_3_10))
00727 generic_sstruct_boolean(atomsel_pi_helix, (s == SS_HELIX_PI))
00728
00729
00730 generic_set_sstruct_boolean(atomsel_set_helix, SS_HELIX_ALPHA)
00731
00732 generic_set_sstruct_boolean(atomsel_set_3_10_helix, SS_HELIX_3_10)
00733
00734 generic_set_sstruct_boolean(atomsel_set_pi_helix, SS_HELIX_PI)
00735
00736
00737 generic_sstruct_boolean(atomsel_sheet, (s == SS_BETA ||
00738 s == SS_BRIDGE ))
00739 generic_sstruct_boolean(atomsel_extended_sheet, (s == SS_BETA))
00740 generic_sstruct_boolean(atomsel_bridge_sheet, (s == SS_BRIDGE ))
00741
00742
00743 generic_set_sstruct_boolean(atomsel_set_sheet, SS_BETA)
00744 generic_set_sstruct_boolean(atomsel_set_bridge_sheet, SS_BRIDGE)
00745
00746
00747 generic_sstruct_boolean(atomsel_coil, (s == SS_COIL))
00748
00749
00750 generic_set_sstruct_boolean(atomsel_set_coil, SS_COIL)
00751
00752
00753 generic_sstruct_boolean(atomsel_turn, (s == SS_TURN))
00754
00755
00756 generic_set_sstruct_boolean(atomsel_set_turn, SS_TURN)
00757
00758
00759 static int atomsel_sstruct(void *v, int num, const char **data, int *flgs) {
00760 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00761 atom_sel_mol->need_secondary_structure(1);
00762 for (int i=0; i<num; i++) {
00763 if (flgs[i]) {
00764 switch(atom_sel_mol->residue(atom_sel_mol->atom(i)->uniq_resid)->sstruct) {
00765 case SS_HELIX_ALPHA: data[i] = "H"; break;
00766 case SS_HELIX_3_10 : data[i] = "G"; break;
00767 case SS_HELIX_PI : data[i] = "I"; break;
00768 case SS_BETA : data[i] = "E"; break;
00769 case SS_BRIDGE : data[i] = "B"; break;
00770 case SS_TURN : data[i] = "T"; break;
00771 default:
00772 case SS_COIL : data[i] = "C"; break;
00773 }
00774 }
00775 }
00776 return 1;
00777 }
00778
00779
00780
00781 static int atomsel_set_sstruct(void *v, int num, const char **data, int *flgs) {
00782 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00783 char c;
00784
00785
00786 atom_sel_mol->need_secondary_structure(0);
00787 for (int i=0; i<num; i++) {
00788 if (flgs[i]) {
00789 if (strlen(data[i]) == 0) {
00790 msgErr << "cannot set a 0 length secondary structure string"
00791 << sendmsg;
00792 } else {
00793 c = ((const char *) data[i])[0];
00794 if (strlen(data[i]) > 1) {
00795 while (1) {
00796 if (!strcasecmp((const char *) data[i], "helix")) { c = 'H'; break;}
00797 if (!strcasecmp((const char *) data[i], "alpha")) { c = 'H'; break;}
00798 if (!strcasecmp((const char *) data[i], "alpha_helix")) { c = 'H'; break;}
00799 if (!strcasecmp((const char *) data[i], "alphahelix")) { c = 'H'; break;}
00800 if (!strcasecmp((const char *) data[i], "alpha helix")) { c = 'H'; break;}
00801
00802 if (!strcasecmp((const char *) data[i], "pi")) { c = 'I'; break;}
00803 if (!strcasecmp((const char *) data[i], "pi_helix")) { c = 'I'; break;}
00804 if (!strcasecmp((const char *) data[i], "pihelix")) { c = 'I'; break;}
00805 if (!strcasecmp((const char *) data[i], "pi helix")) { c = 'I'; break;}
00806
00807 if (!strcasecmp((const char *) data[i], "310")) { c = 'G'; break;}
00808 if (!strcasecmp((const char *) data[i], "310_helix")) { c = 'G'; break;}
00809 if (!strcasecmp((const char *) data[i], "3_10")) { c = 'G'; break;}
00810 if (!strcasecmp((const char *) data[i], "3")) { c = 'G'; break;}
00811 if (!strcasecmp((const char *) data[i], "310 helix")) { c = 'G'; break;}
00812 if (!strcasecmp((const char *) data[i], "3_10_helix")){ c = 'G'; break;}
00813 if (!strcasecmp((const char *) data[i], "3_10 helix")){ c = 'G'; break;}
00814 if (!strcasecmp((const char *) data[i], "3 10 helix")){ c = 'G'; break;}
00815 if (!strcasecmp((const char *) data[i], "helix_3_10")){ c = 'G'; break;}
00816 if (!strcasecmp((const char *) data[i], "helix 3 10")){ c = 'G'; break;}
00817 if (!strcasecmp((const char *) data[i], "helix3_10")) { c = 'G'; break;}
00818 if (!strcasecmp((const char *) data[i], "helix310")) { c = 'G'; break;}
00819
00820 if (!strcasecmp((const char *) data[i], "beta")) { c = 'E'; break;}
00821 if (!strcasecmp((const char *) data[i], "betasheet")) { c = 'E'; break;}
00822 if (!strcasecmp((const char *) data[i], "beta_sheet")){ c = 'E'; break;}
00823 if (!strcasecmp((const char *) data[i], "beta sheet")){ c = 'E'; break;}
00824 if (!strcasecmp((const char *) data[i], "sheet")) { c = 'E'; break;}
00825 if (!strcasecmp((const char *) data[i], "strand")) { c = 'E'; break;}
00826 if (!strcasecmp((const char *) data[i], "beta_strand")) { c = 'E'; break;}
00827 if (!strcasecmp((const char *) data[i], "beta strand")) { c = 'E'; break;}
00828
00829 if (!strcasecmp((const char *) data[i], "turn")) { c = 'T'; break;}
00830
00831 if (!strcasecmp((const char *) data[i], "coil")) { c = 'C'; break;}
00832 if (!strcasecmp((const char *) data[i], "unknown")) { c = 'C'; break;}
00833 c = 'X';
00834 break;
00835 }
00836 }
00837
00838 int s = SS_COIL;
00839 switch ( c ) {
00840 case 'H':
00841 case 'h': s = SS_HELIX_ALPHA; break;
00842 case '3':
00843 case 'G':
00844 case 'g': s = SS_HELIX_3_10; break;
00845 case 'P':
00846 case 'p':
00847 case 'I':
00848 case 'i': s = SS_HELIX_PI; break;
00849 case 'S':
00850 case 's':
00851 case 'E':
00852 case 'e': s = SS_BETA; break;
00853 case 'B':
00854 case 'b': s = SS_BRIDGE; break;
00855 case 'T':
00856 case 't': s = SS_TURN; break;
00857 case 'L':
00858 case 'l':
00859 case 'C':
00860 case 'c': s = SS_COIL; break;
00861 default: {
00862 msgErr << "Unknown sstruct assignment: '"
00863 << (const char *) data[i] << "'" << sendmsg;
00864 s = SS_COIL; break;
00865 }
00866 }
00867 atom_sel_mol->residue(atom_sel_mol->atom(i)->uniq_resid)->sstruct = s;
00868 }
00869 }
00870 }
00871 return 1;
00872 }
00873
00874
00876
00877
00878 static void mark_atoms_given_residue(DrawMolecule *mol, int residue, int *on)
00879 {
00880 ResizeArray<int> *atoms = &(mol->residueList[residue]->atoms);
00881 for (int i= atoms->num()-1; i>=0; i--) {
00882 on[(*atoms)[i]] = TRUE;
00883 }
00884 }
00885
00886
00887
00888 #define fragment_data(fctn, fragtype) \
00889 static int fctn(void *v, int num, int *data, int *) \
00890 { \
00891 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol; \
00892 int *tmp = new int[num]; \
00893 int i; \
00894 for (i=num-1; i>=0; i--) { \
00895 tmp[i] = 0; \
00896 data[i] = -1; \
00897 } \
00898 \
00899 for ( i=atom_sel_mol->fragtype.num()-1; i>=0; i--) { \
00900 \
00901 int j; \
00902 for (j=atom_sel_mol->fragtype[i]->num()-1; j>=0; j--) { \
00903 \
00904 mark_atoms_given_residue(atom_sel_mol,(*atom_sel_mol->fragtype[i])[j], tmp); \
00905 } \
00906 \
00907 for (j=num-1; j>=0; j--) { \
00908 if (tmp[j]) { \
00909 data[j] = i; \
00910 tmp[j] = 0; \
00911 } \
00912 } \
00913 } \
00914 delete [] tmp; \
00915 return 1; \
00916 }
00917
00918 fragment_data(atomsel_pfrag, pfragList)
00919 fragment_data(atomsel_nfrag, nfragList)
00920
00921 static Timestep *selframe(DrawMolecule *atom_sel_mol, int which_frame) {
00922 Timestep *r;
00923 switch (which_frame) {
00924 case AtomSel::TS_LAST: r = atom_sel_mol->get_last_frame(); break;
00925
00926 case AtomSel::TS_NOW : r = atom_sel_mol->current(); break;
00927 default: {
00928 if (!atom_sel_mol->get_frame(which_frame)) {
00929 r = atom_sel_mol->get_last_frame();
00930
00931 } else {
00932 r = atom_sel_mol->get_frame(which_frame);
00933 }
00934 }
00935 }
00936 return r;
00937 }
00938
00939
00940 #if defined(VMDWITHCARBS)
00941
00942 static int atomsel_pucker(void *v, int num, double *data, int *flgs) {
00943 int i;
00944 SmallRing *ring;
00945 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00946 memset(data, 0, num*sizeof(double));
00947 int which_frame = ((atomsel_ctxt *)v)->which_frame;
00948 Timestep *ts = selframe(atom_sel_mol, which_frame);
00949 if (!ts || !ts->pos) {
00950 return 1;
00951 }
00952
00953
00954
00955
00956 atom_sel_mol->find_small_rings_and_links(5, 6);
00957
00958 for (i=0; i < atom_sel_mol->smallringList.num(); i++) {
00959 ring = atom_sel_mol->smallringList[i];
00960 int N = ring->num();
00961
00962
00963 if (N >= 5 && N <= 6) {
00964 float pucker = hill_reilly_ring_pucker((*ring), ts->pos);
00965
00966 int j;
00967 for (j=0; j<N; j++) {
00968 int ind = (*ring)[j];
00969 if (flgs[ind])
00970 data[ind] = pucker;
00971 }
00972 }
00973 }
00974
00975 return 1;
00976 }
00977 #endif
00978
00979 static int atomsel_user(void *v, int num, double *data, int *flgs) {
00980 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00981 int which_frame = ((atomsel_ctxt *)v)->which_frame;
00982 Timestep *ts = selframe(atom_sel_mol, which_frame);
00983 if (!ts || !ts->user) {
00984 memset(data, 0, num*sizeof(double));
00985 return 1;
00986 }
00987 for (int i=0; i<num; i++) {
00988 if (flgs[i]) {
00989 data[i] = ts->user[i];
00990 }
00991 }
00992 return 1;
00993 }
00994 static int atomsel_set_user(void *v, int num, double *data, int *flgs) {
00995 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00996 int which_frame = ((atomsel_ctxt *)v)->which_frame;
00997 Timestep *ts = selframe(atom_sel_mol, which_frame);
00998 if (!ts) return 0;
00999 if (!ts->user) {
01000 ts->user= new float[num];
01001 memset(ts->user, 0, num*sizeof(float));
01002 }
01003 for (int i=0; i<num; i++) {
01004 if (flgs[i]) {
01005 ts->user[i] = (float)data[i];
01006 }
01007 }
01008 return 1;
01009 }
01010
01011 static int atomsel_user2(void *v, int num, double *data, int *flgs) {
01012 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
01013 int which_frame = ((atomsel_ctxt *)v)->which_frame;
01014 Timestep *ts = selframe(atom_sel_mol, which_frame);
01015 if (!ts || !ts->user2) {
01016 memset(data, 0, num*sizeof(double));
01017 return 1;
01018 }
01019 for (int i=0; i<num; i++) {
01020 if (flgs[i]) {
01021 data[i] = ts->user2[i];
01022 }
01023 }
01024 return 1;
01025 }
01026 static int atomsel_set_user2(void *v, int num, double *data, int *flgs) {
01027 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
01028 int which_frame = ((atomsel_ctxt *)v)->which_frame;
01029 Timestep *ts = selframe(atom_sel_mol, which_frame);
01030 if (!ts) return 0;
01031 if (!ts->user2) {
01032 ts->user2= new float[num];
01033 memset(ts->user2, 0, num*sizeof(float));
01034 }
01035 for (int i=0; i<num; i++) {
01036 if (flgs[i]) {
01037 ts->user2[i] = (float)data[i];
01038 }
01039 }
01040 return 1;
01041 }
01042
01043 static int atomsel_user3(void *v, int num, double *data, int *flgs) {
01044 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
01045 int which_frame = ((atomsel_ctxt *)v)->which_frame;
01046 Timestep *ts = selframe(atom_sel_mol, which_frame);
01047 if (!ts || !ts->user3) {
01048 memset(data, 0, num*sizeof(double));
01049 return 1;
01050 }
01051 for (int i=0; i<num; i++) {
01052 if (flgs[i]) {
01053 data[i] = ts->user3[i];
01054 }
01055 }
01056 return 1;
01057 }
01058 static int atomsel_set_user3(void *v, int num, double *data, int *flgs) {
01059 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
01060 int which_frame = ((atomsel_ctxt *)v)->which_frame;
01061 Timestep *ts = selframe(atom_sel_mol, which_frame);
01062 if (!ts) return 0;
01063 if (!ts->user3) {
01064 ts->user3= new float[num];
01065 memset(ts->user3, 0, num*sizeof(float));
01066 }
01067 for (int i=0; i<num; i++) {
01068 if (flgs[i]) {
01069 ts->user3[i] = (float)data[i];
01070 }
01071 }
01072 return 1;
01073 }
01074
01075 static int atomsel_user4(void *v, int num, double *data, int *flgs) {
01076 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
01077 int which_frame = ((atomsel_ctxt *)v)->which_frame;
01078 Timestep *ts = selframe(atom_sel_mol, which_frame);
01079 if (!ts || !ts->user4) {
01080 memset(data, 0, num*sizeof(double));
01081 return 1;
01082 }
01083 for (int i=0; i<num; i++) {
01084 if (flgs[i]) {
01085 data[i] = ts->user4[i];
01086 }
01087 }
01088 return 1;
01089 }
01090 static int atomsel_set_user4(void *v, int num, double *data, int *flgs) {
01091 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
01092 int which_frame = ((atomsel_ctxt *)v)->which_frame;
01093 Timestep *ts = selframe(atom_sel_mol, which_frame);
01094 if (!ts) return 0;
01095 if (!ts->user4) {
01096 ts->user4= new float[num];
01097 memset(ts->user4, 0, num*sizeof(float));
01098 }
01099 for (int i=0; i<num; i++) {
01100 if (flgs[i]) {
01101 ts->user4[i] = (float)data[i];
01102 }
01103 }
01104 return 1;
01105 }
01106
01107
01108
01109 static int atomsel_xpos(void *v, int num, double *data, int *flgs) {
01110 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
01111 int which_frame = ((atomsel_ctxt *)v)->which_frame;
01112 Timestep *ts = selframe(atom_sel_mol, which_frame);
01113 int i;
01114 if (!ts) {
01115 for (i=0; i<num; i++)
01116 if (flgs[i]) data[i] = 0.0;
01117 return 0;
01118 }
01119 for (i=0; i<num; i++) {
01120 if (flgs[i]) {
01121 data[i] = ts->pos[3*i + 0];
01122 }
01123 }
01124 return 1;
01125 }
01126
01127 static int atomsel_ypos(void *v, int num, double *data, int *flgs) {
01128 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
01129 int which_frame = ((atomsel_ctxt *)v)->which_frame;
01130 Timestep *ts = selframe(atom_sel_mol, which_frame);
01131 int i;
01132 if (!ts) {
01133 for (i=0; i<num; i++)
01134 if (flgs[i]) data[i] = 0.0;
01135 return 0;
01136 }
01137 for (i=0; i<num; i++) {
01138 if (flgs[i]) {
01139 data[i] = ts->pos[3*i + 1];
01140 }
01141 }
01142 return 1;
01143 }
01144
01145 static int atomsel_zpos(void *v, int num, double *data, int *flgs) {
01146 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
01147 int which_frame = ((atomsel_ctxt *)v)->which_frame;
01148 Timestep *ts = selframe(atom_sel_mol, which_frame);
01149 int i;
01150 if (!ts) {
01151 for (i=0; i<num; i++)
01152 if (flgs[i]) data[i] = 0.0;
01153 return 0;
01154 }
01155 for (i=0; i<num; i++) {
01156 if (flgs[i]) {
01157 data[i] = ts->pos[3*i + 2];
01158 }
01159 }
01160 return 1;
01161 }
01162
01163 static int atomsel_ufx(void *v, int num, double *data, int *flgs) {
01164 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
01165 int which_frame = ((atomsel_ctxt *)v)->which_frame;
01166 Timestep *ts = selframe(atom_sel_mol, which_frame);
01167 int i;
01168 if (!ts || !ts->force) {
01169 for (i=0; i<num; i++)
01170 if (flgs[i]) data[i] = 0.0;
01171 return 0;
01172 }
01173 for (i=0; i<num; i++) {
01174 if (flgs[i]) {
01175 data[i] = ts->force[3*i + 0];
01176 }
01177 }
01178 return 1;
01179 }
01180
01181 static int atomsel_ufy(void *v, int num, double *data, int *flgs) {
01182 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
01183 int which_frame = ((atomsel_ctxt *)v)->which_frame;
01184 Timestep *ts = selframe(atom_sel_mol, which_frame);
01185 int i;
01186 if (!ts || !ts->force) {
01187 for (i=0; i<num; i++)
01188 if (flgs[i]) data[i] = 0.0;
01189 return 0;
01190 }
01191 for (i=0; i<num; i++) {
01192 if (flgs[i]) {
01193 data[i] = ts->force[3*i + 1];
01194 }
01195 }
01196 return 1;
01197 }
01198
01199 static int atomsel_ufz(void *v, int num, double *data, int *flgs) {
01200 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
01201 int which_frame = ((atomsel_ctxt *)v)->which_frame;
01202 Timestep *ts = selframe(atom_sel_mol, which_frame);
01203 int i;
01204 if (!ts || !ts->force) {
01205 for (i=0; i<num; i++)
01206 if (flgs[i]) data[i] = 0.0;
01207 return 0;
01208 }
01209 for (i=0; i<num; i++) {
01210 if (flgs[i]) {
01211 data[i] = ts->force[3*i + 2];
01212 }
01213 }
01214 return 1;
01215 }
01216
01217 #define atomsel_get_vel(name, offset) \
01218 static int atomsel_##name(void *v, int num, double *data, int *flgs) { \
01219 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol; \
01220 int which_frame = ((atomsel_ctxt *)v)->which_frame; \
01221 Timestep *ts = selframe(atom_sel_mol, which_frame); \
01222 int i; \
01223 if (!ts || !ts->vel) { \
01224 for (i=0; i<num; i++) \
01225 if (flgs[i]) data[i] = 0.0; \
01226 return 0; \
01227 } \
01228 for (i=0; i<num; i++) { \
01229 if (flgs[i]) { \
01230 data[i] = ts->vel[3*i + (offset)]; \
01231 } \
01232 } \
01233 return 1; \
01234 }
01235
01236 atomsel_get_vel(vx, 0)
01237 atomsel_get_vel(vy, 1)
01238 atomsel_get_vel(vz, 2)
01239
01240 static int atomsel_phi(void *v, int num, double *data, int *flgs) {
01241 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
01242 int which_frame = ((atomsel_ctxt *)v)->which_frame;
01243 Timestep *ts = selframe(atom_sel_mol, which_frame);
01244 int i;
01245 if (!ts) {
01246 for (i=0; i<num; i++) data[i] = 0;
01247 return 0;
01248 }
01249 const float *r = ts->pos;
01250 for (i=0; i<num; i++) {
01251 if (!flgs[i]) continue;
01252 MolAtom *atom = atom_sel_mol->atom(i);
01253 int resid = atom->uniq_resid;
01254 int N = atom_sel_mol->find_atom_in_residue("N", resid);
01255 int CA = atom_sel_mol->find_atom_in_residue("CA", resid);
01256 int C = atom_sel_mol->find_atom_in_residue("C", resid);
01257
01258
01259
01260 if (N < 0) {
01261 data[i] = 0;
01262 continue;
01263 }
01264 MolAtom *atomN = atom_sel_mol->atom(N);
01265 int cprev = -1;
01266 for (int j=0; j<atomN->bonds; j++) {
01267 int aindex = atomN->bondTo[j];
01268 int nameindex = atom_sel_mol->atom(aindex)->nameindex;
01269 if (!strcmp(atom_sel_mol->atomNames.name(nameindex), "C")) {
01270 cprev = aindex;
01271 break;
01272 }
01273 }
01274 if (cprev >= 0 && CA >= 0 && C >= 0)
01275 data[i] = dihedral(r+3*cprev, r+3*N, r+3*CA, r+3*C);
01276 else
01277 data[i] = 0.0;
01278 }
01279 return 0;
01280 }
01281
01282 static int atomsel_psi(void *v, int num, double *data, int *flgs) {
01283 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
01284 int which_frame = ((atomsel_ctxt *)v)->which_frame;
01285 Timestep *ts = selframe(atom_sel_mol, which_frame);
01286 int i;
01287 if (!ts) {
01288 for (i=0; i<num; i++) data[i] = 0;
01289 return 0;
01290 }
01291 const float *r = ts->pos;
01292 for (i=0; i<num; i++) {
01293 if (!flgs[i]) continue;
01294 MolAtom *atom = atom_sel_mol->atom(i);
01295 int resid = atom->uniq_resid;
01296 int N = atom_sel_mol->find_atom_in_residue("N", resid);
01297 int CA = atom_sel_mol->find_atom_in_residue("CA", resid);
01298 int C = atom_sel_mol->find_atom_in_residue("C", resid);
01299
01300
01301
01302 if (C < 0) {
01303 data[i] = 0;
01304 continue;
01305 }
01306 MolAtom *atomC = atom_sel_mol->atom(C);
01307 int nextn = -1;
01308 for (int j=0; j<atomC->bonds; j++) {
01309 int aindex = atomC->bondTo[j];
01310 int nameindex = atom_sel_mol->atom(aindex)->nameindex;
01311 if (!strcmp(atom_sel_mol->atomNames.name(nameindex), "N")) {
01312 nextn = aindex;
01313 break;
01314 }
01315 }
01316 if (nextn >= 0 && N >= 0 && CA >= 0)
01317 data[i] = dihedral(r+3*N, r+3*CA, r+3*C, r+3*nextn);
01318 else
01319 data[i] = 0.0;
01320 }
01321 return 0;
01322 }
01323
01324 static int atomsel_set_phi(void *v, int num, double *data, int *flgs) {
01325
01326
01327
01328
01329
01330
01331
01332 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
01333 SymbolTable *table = ((atomsel_ctxt *)v)->table;
01334 int which_frame = ((atomsel_ctxt *)v)->which_frame;
01335 Timestep *ts = selframe(atom_sel_mol, which_frame);
01336 int i;
01337 if (!ts) {
01338 return 0;
01339 }
01340 float *r = ts->pos;
01341
01342
01343
01344
01345 for (i=0; i<atom_sel_mol->fragList.num(); i++) {
01346 Fragment *frag = atom_sel_mol->fragList[i];
01347 int nfragres = frag->residues.num();
01348 if (nfragres < 2) continue;
01349 int C = atom_sel_mol->find_atom_in_residue("C", frag->residues[0]);
01350
01351 for (int ires = 1; ires < nfragres; ires++) {
01352 int resid = frag->residues[ires];
01353 int cprev = C;
01354 int N = atom_sel_mol->find_atom_in_residue("N", resid);
01355 int CA = atom_sel_mol->find_atom_in_residue("CA", resid);
01356 C = atom_sel_mol->find_atom_in_residue("C", resid);
01357 if (cprev < 0 || N < 0 || CA < 0 || C < 0) continue;
01358 if (!flgs[CA]) continue;
01359 float CApos[3], Npos[3], axis[3];
01360 vec_copy(CApos, r+3*CA);
01361 vec_copy(Npos, r+3*N);
01362 vec_sub(axis, Npos, CApos);
01363 vec_normalize(axis);
01364 double oldphi = dihedral(r+3*cprev, Npos, CApos, r+3*C);
01365
01366
01367
01368
01369 AtomSel *nterm = new AtomSel(table, atom_sel_mol->id());
01370 char buf[100];
01371 sprintf(buf,
01372 "(fragment %d and residue < %d) or (residue %d and name N NH CA)",
01373 i, resid, resid);
01374 if (nterm->change(buf, atom_sel_mol) == AtomSel::NO_PARSE) {
01375 msgErr << "set phi: internal atom selection error" << sendmsg;
01376 msgErr << buf << sendmsg;
01377 delete nterm;
01378 continue;
01379 }
01380 Matrix4 mat;
01381 mat.transvec(axis[0], axis[1], axis[2]);
01382 mat.rot((float) (data[CA]-oldphi), 'x');
01383 mat.transvecinv(axis[0], axis[1], axis[2]);
01384
01385 for (int j=0; j<num; j++) {
01386 if (nterm->on[j]) {
01387 float *pos = r+3*j;
01388 vec_sub(pos, pos, CApos);
01389 mat.multpoint3d(pos, pos);
01390 vec_add(pos, pos, CApos);
01391 }
01392 }
01393 delete nterm;
01394 }
01395 }
01396 return 0;
01397 }
01398
01399 static int atomsel_set_psi(void *v, int num, double *data, int *flgs) {
01400 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
01401 SymbolTable *table = ((atomsel_ctxt *)v)->table;
01402 int which_frame = ((atomsel_ctxt *)v)->which_frame;
01403 Timestep *ts = selframe(atom_sel_mol, which_frame);
01404 if (!ts) {
01405 return 0;
01406 }
01407 float *r = ts->pos;
01408
01409 for (int i=0; i<atom_sel_mol->fragList.num(); i++) {
01410 Fragment *frag = atom_sel_mol->fragList[i];
01411 int nfragres = frag->residues.num();
01412 if (nfragres < 2) continue;
01413 int N = atom_sel_mol->find_atom_in_residue("N", frag->residues[nfragres-1]);
01414 for (int ires = nfragres-2; ires >= 0; ires--) {
01415 int resid = frag->residues[ires];
01416 int nextn = N;
01417 N = atom_sel_mol->find_atom_in_residue("N", resid);
01418 int CA = atom_sel_mol->find_atom_in_residue("CA", resid);
01419 int C = atom_sel_mol->find_atom_in_residue("C", resid);
01420 if (nextn < 0 || N < 0 || CA < 0 || C < 0) continue;
01421 if (!flgs[CA]) continue;
01422 float CApos[3], Cpos[3], axis[3];
01423 vec_copy(CApos, r+3*CA);
01424 vec_copy(Cpos, r+3*C);
01425 vec_sub(axis, Cpos, CApos);
01426 vec_normalize(axis);
01427 double oldpsi = dihedral(r+3*N, CApos, Cpos, r+3*nextn);
01428
01429 AtomSel *cterm = new AtomSel(table, atom_sel_mol->id());
01430 char buf[100];
01431 sprintf(buf,
01432 "(fragment %d and residue > %d) or (residue %d and name CA C O)",
01433 i, resid, resid);
01434 if (cterm->change(buf, atom_sel_mol) == AtomSel::NO_PARSE) {
01435 msgErr << "set psi: internal atom selection error" << sendmsg;
01436 msgErr << buf << sendmsg;
01437 delete cterm;
01438 continue;
01439 }
01440
01441 Matrix4 mat;
01442 mat.transvec(axis[0], axis[1], axis[2]);
01443 mat.rot((float) (data[CA]-oldpsi), 'x');
01444 mat.transvecinv(axis[0], axis[1], axis[2]);
01445
01446 for (int j=0; j<num; j++) {
01447 if (cterm->on[j]) {
01448 float *pos = r+3*j;
01449 vec_sub(pos, pos, CApos);
01450 mat.multpoint3d(pos, pos);
01451 vec_add(pos, pos, CApos);
01452 }
01453 }
01454 delete cterm;
01455 }
01456 }
01457 return 0;
01458 }
01459
01460 #define set_position_data(fctn, offset) \
01461 static int fctn(void *v, int num, double *data, int *flgs) \
01462 { \
01463 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol; \
01464 int which_frame = ((atomsel_ctxt *)v)->which_frame; \
01465 Timestep *ts = selframe(atom_sel_mol, which_frame); \
01466 if (!ts) return 0; \
01467 for (int i=num-1; i>=0; i--) { \
01468 if (flgs[i]) { \
01469 ts->pos[3*i + offset] = (float) data[i]; \
01470 } \
01471 } \
01472 return 1; \
01473 }
01474
01475
01476 set_position_data(atomsel_set_xpos, 0)
01477 set_position_data(atomsel_set_ypos, 1)
01478 set_position_data(atomsel_set_zpos, 2)
01479
01480 #define set_force_data(fctn, offset) \
01481 static int fctn(void *v, int num, double *data, int *flgs) \
01482 { \
01483 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol; \
01484 int which_frame = ((atomsel_ctxt *)v)->which_frame; \
01485 Timestep *ts = selframe(atom_sel_mol, which_frame); \
01486 if (!ts) return 0; \
01487 if (!ts->force) { \
01488 ts->force = new float[3*num]; \
01489 memset(ts->force, 0, 3*num*sizeof(float)); \
01490 } \
01491 for (int i=num-1; i>=0; i--) { \
01492 if (flgs[i]) { \
01493 ts->force[3*i + offset] = (float) data[i]; \
01494 } \
01495 } \
01496 return 1; \
01497 }
01498
01499 set_force_data(atomsel_set_ufx, 0)
01500 set_force_data(atomsel_set_ufy, 1)
01501 set_force_data(atomsel_set_ufz, 2)
01502
01503 #define set_vel_data(fctn, offset) \
01504 static int fctn(void *v, int num, double *data, int *flgs) \
01505 { \
01506 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol; \
01507 int which_frame = ((atomsel_ctxt *)v)->which_frame; \
01508 Timestep *ts = selframe(atom_sel_mol, which_frame); \
01509 if (!ts) return 0; \
01510 if (!ts->vel) { \
01511 ts->vel= new float[3*num]; \
01512 memset(ts->vel, 0, 3*num*sizeof(float)); \
01513 } \
01514 for (int i=num-1; i>=0; i--) { \
01515 if (flgs[i]) { \
01516 ts->vel[3*i + offset] = (float) data[i]; \
01517 } \
01518 } \
01519 return 1; \
01520 }
01521
01522 set_vel_data(atomsel_set_vx, 0)
01523 set_vel_data(atomsel_set_vy, 1)
01524 set_vel_data(atomsel_set_vz, 2)
01525
01526 extern "C" {
01527 double atomsel_square(double x) { return x*x; }
01528 }
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548 static int atomsel_sequence(void *v, int argc, const char **argv, int *types,
01549 int num, int *flgs)
01550 {
01551 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
01552 int i;
01553
01554 int *selected = new int[num];
01555 for (i=0; i<num; i++) {
01556 selected[i] = FALSE;
01557 }
01558
01559 JRegex **regex = (JRegex **) malloc( argc * sizeof(JRegex *));
01560 int num_r = 0;
01561 {
01562 JString pattern;
01563 for (i=0; i<argc; i++) {
01564 pattern = argv[i];
01565 if (types[i] >= 3) {
01566 pattern += ".*";
01567 pattern += argv[++i];
01568 }
01569 regex[num_r] = new JRegex(pattern);
01570 num_r ++;
01571 }
01572 }
01573 if (num_r == 0) {
01574 return 0;
01575 }
01576
01577
01578
01579 for (int fragcount=0; fragcount <2; fragcount++) {
01580 int pcount = atom_sel_mol->pfragList.num();
01581 int ncount = atom_sel_mol->nfragList.num();
01582 for (i=0; i< (fragcount == 0 ? pcount : ncount); i++) {
01583 int size = (fragcount == 0 ? atom_sel_mol->pfragList[i]->num()
01584 : atom_sel_mol->nfragList[i]->num());
01585 char *s = new char[size+1];
01586 char *t = s;
01587 int *mark = new int[size];
01588
01589 for (int j=0; j<size; j++) {
01590 int residuenum = ((fragcount == 0) ?
01591 (*atom_sel_mol->pfragList[i])[j] :
01592 (*atom_sel_mol->nfragList[i])[j]);
01593 int atomnum = (atom_sel_mol->residueList[residuenum]->atoms[0]);
01594 MolAtom *atom = atom_sel_mol->atom(atomnum);
01595 const char *resname = (atom_sel_mol->resNames).name(atom->resnameindex);
01596 mark[j] = FALSE;
01597 if (fragcount == 0) {
01598
01599
01600 if (!strcasecmp( resname, "GLY")) {*t++ = 'G'; continue;}
01601 if (!strcasecmp( resname, "ALA")) {*t++ = 'A'; continue;}
01602 if (!strcasecmp( resname, "VAL")) {*t++ = 'V'; continue;}
01603 if (!strcasecmp( resname, "PHE")) {*t++ = 'F'; continue;}
01604 if (!strcasecmp( resname, "PRO")) {*t++ = 'P'; continue;}
01605 if (!strcasecmp( resname, "MET")) {*t++ = 'M'; continue;}
01606 if (!strcasecmp( resname, "ILE")) {*t++ = 'I'; continue;}
01607 if (!strcasecmp( resname, "LEU")) {*t++ = 'L'; continue;}
01608 if (!strcasecmp( resname, "ASP")) {*t++ = 'D'; continue;}
01609 if (!strcasecmp( resname, "GLU")) {*t++ = 'E'; continue;}
01610 if (!strcasecmp( resname, "LYS")) {*t++ = 'K'; continue;}
01611 if (!strcasecmp( resname, "ARG")) {*t++ = 'R'; continue;}
01612 if (!strcasecmp( resname, "SER")) {*t++ = 'S'; continue;}
01613 if (!strcasecmp( resname, "THR")) {*t++ = 'T'; continue;}
01614 if (!strcasecmp( resname, "TYR")) {*t++ = 'Y'; continue;}
01615 if (!strcasecmp( resname, "HIS")) {*t++ = 'H'; continue;}
01616 if (!strcasecmp( resname, "CYS")) {*t++ = 'C'; continue;}
01617 if (!strcasecmp( resname, "ASN")) {*t++ = 'N'; continue;}
01618 if (!strcasecmp( resname, "GLN")) {*t++ = 'Q'; continue;}
01619 if (!strcasecmp( resname, "TRP")) {*t++ = 'W'; continue;}
01620
01621 if (!strcasecmp( resname, "HSE")) {*t++ = 'H'; continue;}
01622 if (!strcasecmp( resname, "HSD")) {*t++ = 'H'; continue;}
01623 if (!strcasecmp( resname, "HSP")) {*t++ = 'H'; continue;}
01624
01625 if (!strcasecmp( resname, "CYX")) {*t++ = 'C'; continue;}
01626 } else {
01627
01628 if (!strcasecmp( resname, "ADE")) {*t++ = 'A'; continue;}
01629 if (!strcasecmp( resname, "A")) {*t++ = 'A'; continue;}
01630 if (!strcasecmp( resname, "THY")) {*t++ = 'T'; continue;}
01631 if (!strcasecmp( resname, "T")) {*t++ = 'T'; continue;}
01632 if (!strcasecmp( resname, "CYT")) {*t++ = 'C'; continue;}
01633 if (!strcasecmp( resname, "C")) {*t++ = 'C'; continue;}
01634 if (!strcasecmp( resname, "GUA")) {*t++ = 'G'; continue;}
01635 if (!strcasecmp( resname, "G")) {*t++ = 'G'; continue;}
01636 }
01637
01638 *t++ = 'X';
01639 }
01640 *t = 0;
01641
01642
01643
01644 for (int r=0; r<num_r; r++) {
01645 int len, start = 0, offset;
01646 while ((offset = (regex[r]->search(s, strlen(s), len, start)))
01647 != -1) {
01648
01649
01650
01651 for (int loop=offset; loop<offset+len; loop++) {
01652 mark[loop] = 1;
01653 }
01654 start = offset+len;
01655 }
01656 }
01657
01658
01659
01660 for (int marked=0; marked<size; marked++) {
01661 if (mark[marked]) {
01662 int residuenum = (fragcount == 0 ?
01663 (*atom_sel_mol->pfragList[i])[marked] :
01664 (*atom_sel_mol->nfragList[i])[marked]);
01665 for (int atomloop=0;
01666 atomloop< atom_sel_mol->residueList[residuenum]->
01667 atoms.num(); atomloop++) {
01668 selected[atom_sel_mol->residueList[residuenum]->
01669 atoms[atomloop]]=TRUE;
01670 }
01671 }
01672 }
01673 delete [] mark;
01674 delete [] s;
01675 }
01676 }
01677
01678
01679
01680 for (i=0; i<num_r; i++) {
01681 delete regex[i];
01682 }
01683
01684 for (i=0; i<num; i++) {
01685 flgs[i] = flgs[i] && selected[i];
01686 }
01687 return 1;
01688 }
01689
01690
01692
01693
01694
01695
01696
01697
01698
01699 static int atomsel_rasmol_primitive(void *v, int argc, const char **argv, int *,
01700 int num, int *flgs)
01701 {
01702 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
01703 SymbolTable *table = ((atomsel_ctxt *)v)->table;
01704
01705
01706 for (int word=0; word<argc; word++) {
01707 const char *rnm0 = argv[word];
01708 const char *rnm1;
01709 const char *rid0, *rid1;
01710 if (*rnm0 == '*') {
01711 rnm1 = rnm0 + 1;
01712 rid0 = rnm1;
01713 } else if (*rnm0 == '[') {
01714 rnm0++;
01715 rnm1 = rnm0;
01716 while (*rnm1 && *rnm1 != ']') {
01717 rnm1 ++;
01718 }
01719 if (rnm1 == rnm0) {
01720 rid0 = rnm1;
01721 } else {
01722 if (*rnm1==']') {
01723 rid0 = rnm1+1;
01724 } else {
01725 rid0 = rnm1;
01726 }
01727 }
01728 } else {
01729 rnm1 = rnm0;
01730 while (isalpha(*rnm1) || *rnm1 == '?') {
01731 rnm1++;
01732 }
01733 rid0 = rnm1;
01734 }
01735
01736
01737
01738 rid1 = rid0;
01739 if (*rid1 == '*') {
01740 rid1++;
01741 } else {
01742 while (isdigit(*rid1)) {
01743 rid1++;
01744 }
01745 }
01746
01747
01748 const char *chn0, *chn1;
01749 if (*rid1 == ':') {
01750 chn0 = rid1 + 1;
01751 } else {
01752 chn0 = rid1;
01753 }
01754
01755
01756
01757 chn1 = chn0;
01758 while (*chn1 && *chn1 != '.') {
01759 chn1++;
01760 }
01761
01762 const char *nm0, *nm1;
01763 if (*chn1 == '.') {
01764 nm0 = chn1 + 1;
01765 } else {
01766 nm0 = chn1;
01767 }
01768 nm1 = nm0;
01769
01770 while (*nm1) {
01771 nm1++;
01772 }
01773
01774
01775
01776 JString resname, resid, chain, name;
01777 const char *s;
01778 for (s=rnm0; s<rnm1; s++) {
01779 resname += *s;
01780 }
01781 for (s=rid0; s<rid1; s++) {
01782 resid += *s;
01783 }
01784 for (s=chn0; s<chn1; s++) {
01785 chain += *s;
01786 }
01787 for (s=nm0; s<nm1; s++) {
01788 name += *s;
01789 }
01790
01791
01792
01793
01794
01795
01796
01797 if (resname == "*") resname = "";
01798 if (resid == "*") resid = "";
01799 if (chain == "*") chain = "";
01800 if (name == "*") name = "";
01801 resname.gsub("?", ".?"); resname.gsub("*", ".*");
01802 resid.gsub("?", ".?"); resid.gsub("*", ".*");
01803 chain.gsub("?", ".?"); chain.gsub("*", ".*");
01804 name.gsub("?", ".?"); name.gsub("*", ".*");
01805
01806 resname.upcase();
01807 resid.upcase();
01808 chain.upcase();
01809 name.upcase();
01810
01811
01812 JString search;
01813 if (resname != "") {
01814 search = "resname ";
01815 search += '"';
01816 search += resname;
01817 search += '"';
01818 }
01819 if (resid != "") {
01820 if (search != "") {
01821 search += " and resid ";
01822 } else {
01823 search = "resid ";
01824 }
01825 search += '"';
01826 search += resid;
01827 search += '"';
01828 }
01829
01830 int is_segname = chain.length() > 1;
01831 if (chain != "") {
01832 if (search != "") {
01833 search += (is_segname ? " and segname " : " and chain ");
01834 } else {
01835 search = (is_segname ? "segname " : "chain ");
01836 }
01837 search += '"';
01838 search += chain;
01839 search += '"';
01840 }
01841 if (name != "") {
01842 if (search != "") {
01843 search += " and name ";
01844 } else {
01845 search = "name ";
01846 }
01847 search += '"';
01848 search += name;
01849 search += '"';
01850 }
01851 msgInfo << "Search = " << search << sendmsg;
01852
01853 if (search == "") {
01854 search = "all";
01855 }
01856
01857 AtomSel *atomSel = new AtomSel(table, atom_sel_mol->id());
01858 if (atomSel->change((const char *) search, atom_sel_mol) ==
01859 AtomSel::NO_PARSE) {
01860 msgErr << "rasmol: cannot understand: " << argv[word] << sendmsg;
01861 delete atomSel;
01862 continue;
01863 }
01864
01865
01866 {
01867 for (int i=0; i<num; i++) {
01868 flgs[i] = flgs[i] && atomSel->on[i];
01869 }
01870 }
01871 delete atomSel;
01872 }
01873 return 1;
01874 }
01875
01876 int atomsel_custom_singleword(void *v, int num, int *flgs) {
01877 SymbolTable *table = ((atomsel_ctxt *)v)->table;
01878 const char *singleword = ((atomsel_ctxt *)v)->singleword;
01879 if (!singleword) {
01880 msgErr << "Internal error, atom selection macro called without context"
01881 << sendmsg;
01882 return 0;
01883 }
01884 const char *macro = table->get_custom_singleword(singleword);
01885 if (!macro) {
01886 msgErr << "Internal error, atom selection macro has lost its defintion."
01887 << sendmsg;
01888 return 0;
01889 }
01890
01891 DrawMolecule *mol = ((atomsel_ctxt *)v)->atom_sel_mol;
01892 AtomSel *atomSel = new AtomSel(table, mol->id());
01893 atomSel->which_frame = ((atomsel_ctxt *)v)->which_frame;
01894 if (atomSel->change(macro, mol) == AtomSel::NO_PARSE) {
01895 msgErr << "Unable to parse macro: " << macro << sendmsg;
01896 delete atomSel;
01897 return 0;
01898 }
01899 for (int i=0; i<num; i++) {
01900 flgs[i] = flgs[i] && atomSel->on[i];
01901 }
01902 delete atomSel;
01903 return 1;
01904 }
01905
01906
01907
01908
01909
01910
01911
01912
01913
01914
01915
01916
01917
01918
01919
01920
01921
01922
01923
01924
01925
01926
01927
01928
01929 #ifndef NAN //not a number
01930 const float NAN = sqrtf(-1.f);
01931 #endif
01932
01933
01934 static int atomsel_volume_array(void *v, int num, double *data, int *flgs, int array_index) {
01935 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
01936 int which_frame = ((atomsel_ctxt *)v)->which_frame;
01937 Timestep *ts = selframe(atom_sel_mol, which_frame);
01938 const VolumetricData *voldata = atom_sel_mol->get_volume_data(array_index);
01939 int i;
01940 if (!ts || !voldata) {
01941 if (!ts) msgErr << "atomselect: non-existent timestep." << sendmsg;
01942 if (!voldata) msgErr << "atomselect: volumetric map volume#" << array_index << " does not exist." << sendmsg;
01943 for (i=0; i<num; i++) if (flgs[i]) data[i] = NAN;
01944 return 0;
01945 }
01946 for (i=0; i<num; i++) {
01947 if (flgs[i])
01948 data[i] = voldata->voxel_value_from_coord(ts->pos[3*i], ts->pos[3*i+1], ts->pos[3*i+2]);
01949 }
01950 return 1;
01951 }
01952
01953
01954 static int atomsel_interp_volume_array(void *v, int num, double *data, int *flgs, int array_index) {
01955 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
01956 int which_frame = ((atomsel_ctxt *)v)->which_frame;
01957 Timestep *ts = selframe(atom_sel_mol, which_frame);
01958 const VolumetricData *voldata = atom_sel_mol->get_volume_data(array_index);
01959 int i;
01960 if (!ts || !voldata) {
01961 if (!ts) msgErr << "atomselect: non-existent timestep." << sendmsg;
01962 if (!voldata) msgErr << "atomselect: volumetric map volume#" << array_index << " does not exist." << sendmsg;
01963 for (i=0; i<num; i++) if (flgs[i]) data[i] = NAN;
01964 return 0;
01965 }
01966 for (i=0; i<num; i++) {
01967 if (flgs[i])
01968 data[i] = voldata->voxel_value_interpolate_from_coord(ts->pos[3*i], ts->pos[3*i+1], ts->pos[3*i+2]);
01969 }
01970 return 1;
01971 }
01972
01973
01974 static int atomsel_gridindex_array(void *v, int num, double *data, int *flgs, int array_index) {
01975 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
01976 int which_frame = ((atomsel_ctxt *)v)->which_frame;
01977 Timestep *ts = selframe(atom_sel_mol, which_frame);
01978 const VolumetricData *voldata = atom_sel_mol->get_volume_data(array_index);
01979 int i;
01980 if (!ts || !voldata) {
01981 if (!ts) msgErr << "atomselect: non-existent timestep." << sendmsg;
01982 if (!voldata) msgErr << "atomselect: volumetric map volume#" << array_index << " does not exist." << sendmsg;
01983 for (i=0; i<num; i++) if (flgs[i]) data[i] = NAN;
01984 return 0;
01985 }
01986 for (i=0; i<num; i++) {
01987 if (flgs[i])
01988 data[i] = voldata->voxel_index_from_coord(ts->pos[3*i], ts->pos[3*i+1], ts->pos[3*i+2]);
01989 }
01990 return 1;
01991 }
01992
01993
01994 static int atomsel_gridindex0(void *v, int num, double *data, int *flgs) {
01995 return atomsel_gridindex_array(v, num, data, flgs, 0);
01996 }
01997 static int atomsel_gridindex1(void *v, int num, double *data, int *flgs) {
01998 return atomsel_gridindex_array(v, num, data, flgs, 1);
01999 }
02000 static int atomsel_gridindex2(void *v, int num, double *data, int *flgs) {
02001 return atomsel_gridindex_array(v, num, data, flgs, 2);
02002 }
02003 static int atomsel_gridindex3(void *v, int num, double *data, int *flgs) {
02004 return atomsel_gridindex_array(v, num, data, flgs, 3);
02005 }
02006 static int atomsel_gridindex4(void *v, int num, double *data, int *flgs) {
02007 return atomsel_gridindex_array(v, num, data, flgs, 4);
02008 }
02009 static int atomsel_gridindex5(void *v, int num, double *data, int *flgs) {
02010 return atomsel_gridindex_array(v, num, data, flgs, 5);
02011 }
02012 static int atomsel_gridindex6(void *v, int num, double *data, int *flgs) {
02013 return atomsel_gridindex_array(v, num, data, flgs, 6);
02014 }
02015 static int atomsel_gridindex7(void *v, int num, double *data, int *flgs) {
02016 return atomsel_gridindex_array(v, num, data, flgs, 7);
02017 }
02018
02019
02020
02021 static int atomsel_volume0(void *v, int num, double *data, int *flgs) {
02022 return atomsel_volume_array(v, num, data, flgs, 0);
02023 }
02024 static int atomsel_volume1(void *v, int num, double *data, int *flgs) {
02025 return atomsel_volume_array(v, num, data, flgs, 1);
02026 }
02027 static int atomsel_volume2(void *v, int num, double *data, int *flgs) {
02028 return atomsel_volume_array(v, num, data, flgs, 2);
02029 }
02030 static int atomsel_volume3(void *v, int num, double *data, int *flgs) {
02031 return atomsel_volume_array(v, num, data, flgs, 3);
02032 }
02033 static int atomsel_volume4(void *v, int num, double *data, int *flgs) {
02034 return atomsel_volume_array(v, num, data, flgs, 4);
02035 }
02036 static int atomsel_volume5(void *v, int num, double *data, int *flgs) {
02037 return atomsel_volume_array(v, num, data, flgs, 5);
02038 }
02039 static int atomsel_volume6(void *v, int num, double *data, int *flgs) {
02040 return atomsel_volume_array(v, num, data, flgs, 6);
02041 }
02042 static int atomsel_volume7(void *v, int num, double *data, int *flgs) {
02043 return atomsel_volume_array(v, num, data, flgs, 7);
02044 }
02045
02046
02047
02048 static int atomsel_interp_volume0(void *v, int num, double *data, int *flgs) {
02049 return atomsel_interp_volume_array(v, num, data, flgs, 0);
02050 }
02051 static int atomsel_interp_volume1(void *v, int num, double *data, int *flgs) {
02052 return atomsel_interp_volume_array(v, num, data, flgs, 1);
02053 }
02054 static int atomsel_interp_volume2(void *v, int num, double *data, int *flgs) {
02055 return atomsel_interp_volume_array(v, num, data, flgs, 2);
02056 }
02057 static int atomsel_interp_volume3(void *v, int num, double *data, int *flgs) {
02058 return atomsel_interp_volume_array(v, num, data, flgs, 3);
02059 }
02060 static int atomsel_interp_volume4(void *v, int num, double *data, int *flgs) {
02061 return atomsel_interp_volume_array(v, num, data, flgs, 4);
02062 }
02063 static int atomsel_interp_volume5(void *v, int num, double *data, int *flgs) {
02064 return atomsel_interp_volume_array(v, num, data, flgs, 5);
02065 }
02066 static int atomsel_interp_volume6(void *v, int num, double *data, int *flgs) {
02067 return atomsel_interp_volume_array(v, num, data, flgs, 6);
02068 }
02069 static int atomsel_interp_volume7(void *v, int num, double *data, int *flgs) {
02070 return atomsel_interp_volume_array(v, num, data, flgs, 7);
02071 }
02072
02073
02074
02075
02076 void atomSelParser_init(SymbolTable *atomSelParser) {
02077 atomSelParser->add_keyword("name", atomsel_name, atomsel_set_name);
02078 atomSelParser->add_keyword("type", atomsel_type, atomsel_set_type);
02079
02080
02081 atomSelParser->add_keyword("backbonetype", atomsel_backbonetype, NULL);
02082 atomSelParser->add_keyword("residuetype", atomsel_residuetype, NULL);
02083
02084 atomSelParser->add_keyword("index", atomsel_index, NULL);
02085 atomSelParser->add_keyword("serial", atomsel_serial, NULL);
02086 atomSelParser->add_keyword("atomicnumber", atomsel_atomicnumber, atomsel_set_atomicnumber);
02087 atomSelParser->add_keyword("element", atomsel_element, atomsel_set_element);
02088 atomSelParser->add_keyword("residue", atomsel_residue, NULL);
02089 atomSelParser->add_keyword("resname", atomsel_resname, atomsel_set_resname);
02090 atomSelParser->add_keyword("altloc", atomsel_altloc, atomsel_set_altloc);
02091 atomSelParser->add_keyword("resid", atomsel_resid, atomsel_set_resid);
02092 atomSelParser->add_keyword("insertion", atomsel_insertion, NULL);
02093 atomSelParser->add_keyword("chain", atomsel_chain, atomsel_set_chain);
02094 atomSelParser->add_keyword("segname", atomsel_segname, atomsel_set_segname);
02095 atomSelParser->add_keyword("segid", atomsel_segname, atomsel_set_segname);
02096
02097 atomSelParser->add_singleword("all", atomsel_all, NULL);
02098 atomSelParser->add_singleword("none", atomsel_none, NULL);
02099
02100 atomSelParser->add_keyword("fragment", atomsel_fragment, NULL);
02101 atomSelParser->add_keyword("pfrag", atomsel_pfrag, NULL);
02102 atomSelParser->add_keyword("nfrag", atomsel_nfrag, NULL);
02103 atomSelParser->add_keyword("numbonds", atomsel_numbonds, NULL);
02104
02105 atomSelParser->add_singleword("backbone", atomsel_backbone, NULL);
02106 atomSelParser->add_singleword("sidechain",
02107 atomsel_sidechain, NULL);
02108 atomSelParser->add_singleword("protein", atomsel_protein, NULL);
02109 atomSelParser->add_singleword("nucleic", atomsel_nucleic, NULL);
02110 atomSelParser->add_singleword("water", atomsel_water, NULL);
02111 atomSelParser->add_singleword("waters", atomsel_water, NULL);
02112 atomSelParser->add_singleword("vmd_fast_hydrogen", atomsel_hydrogen, NULL);
02113
02114
02115 atomSelParser->add_singleword("helix",
02116 atomsel_helix, atomsel_set_helix);
02117 atomSelParser->add_singleword("alpha_helix",
02118 atomsel_alpha_helix, atomsel_set_helix);
02119 atomSelParser->add_singleword("helix_3_10",
02120 atomsel_3_10_helix, atomsel_set_3_10_helix);
02121 atomSelParser->add_singleword("pi_helix",
02122 atomsel_pi_helix, atomsel_set_pi_helix);
02123 atomSelParser->add_singleword("sheet", atomsel_sheet, atomsel_set_sheet);
02124 atomSelParser->add_singleword("betasheet", atomsel_sheet, atomsel_set_sheet);
02125 atomSelParser->add_singleword("beta_sheet",atomsel_sheet, atomsel_set_sheet);
02126 atomSelParser->add_singleword("extended_beta", atomsel_extended_sheet,
02127 atomsel_set_sheet);
02128 atomSelParser->add_singleword("bridge_beta", atomsel_bridge_sheet,
02129 atomsel_set_bridge_sheet);
02130 atomSelParser->add_singleword("turn", atomsel_turn, atomsel_set_turn);
02131 atomSelParser->add_singleword("coil", atomsel_coil, atomsel_set_coil);
02132 atomSelParser->add_keyword("structure",atomsel_sstruct, atomsel_set_sstruct);
02133
02134 #if defined(VMDWITHCARBS)
02135 atomSelParser->add_keyword("pucker", atomsel_pucker, NULL);
02136 #endif
02137
02138 atomSelParser->add_keyword("user", atomsel_user, atomsel_set_user);
02139 atomSelParser->add_keyword("user2", atomsel_user2, atomsel_set_user2);
02140 atomSelParser->add_keyword("user3", atomsel_user3, atomsel_set_user3);
02141 atomSelParser->add_keyword("user4", atomsel_user4, atomsel_set_user4);
02142
02143 atomSelParser->add_keyword("x", atomsel_xpos, atomsel_set_xpos);
02144 atomSelParser->add_keyword("y", atomsel_ypos, atomsel_set_ypos);
02145 atomSelParser->add_keyword("z", atomsel_zpos, atomsel_set_zpos);
02146 atomSelParser->add_keyword("vx", atomsel_vx, atomsel_set_vx);
02147 atomSelParser->add_keyword("vy", atomsel_vy, atomsel_set_vy);
02148 atomSelParser->add_keyword("vz", atomsel_vz, atomsel_set_vz);
02149 atomSelParser->add_keyword("ufx", atomsel_ufx, atomsel_set_ufx);
02150 atomSelParser->add_keyword("ufy", atomsel_ufy, atomsel_set_ufy);
02151 atomSelParser->add_keyword("ufz", atomsel_ufz, atomsel_set_ufz);
02152 atomSelParser->add_keyword("phi", atomsel_phi, atomsel_set_phi);
02153 atomSelParser->add_keyword("psi", atomsel_psi, atomsel_set_psi);
02154 atomSelParser->add_keyword("radius", atomsel_radius,
02155 atomsel_set_radius);
02156 atomSelParser->add_keyword("mass", atomsel_mass, atomsel_set_mass);
02157 atomSelParser->add_keyword("charge", atomsel_charge,
02158 atomsel_set_charge);
02159 atomSelParser->add_keyword("beta", atomsel_beta, atomsel_set_beta);
02160 atomSelParser->add_keyword("occupancy",
02161 atomsel_occupancy, atomsel_set_occupancy);
02162
02163 atomSelParser->add_stringfctn("sequence", atomsel_sequence);
02164 atomSelParser->add_stringfctn("rasmol",
02165 atomsel_rasmol_primitive);
02166
02167
02169
02170
02171
02172
02173
02174
02175
02176
02177 atomSelParser->add_cfunction("sqr", atomsel_square);
02178 atomSelParser->add_cfunction("sqrt", sqrt);
02179 atomSelParser->add_cfunction("abs", fabs);
02180 atomSelParser->add_cfunction("floor", floor);
02181 atomSelParser->add_cfunction("ceil", ceil);
02182 atomSelParser->add_cfunction("sin", sin);
02183 atomSelParser->add_cfunction("cos", cos);
02184 atomSelParser->add_cfunction("tan", tan);
02185 atomSelParser->add_cfunction("atan", atan);
02186 atomSelParser->add_cfunction("asin", asin);
02187 atomSelParser->add_cfunction("acos", acos);
02188 atomSelParser->add_cfunction("sinh", sinh);
02189 atomSelParser->add_cfunction("cosh", cosh);
02190 atomSelParser->add_cfunction("tanh", tanh);
02191 atomSelParser->add_cfunction("exp", exp);
02192 atomSelParser->add_cfunction("log", log);
02193 atomSelParser->add_cfunction("log10", log10);
02194
02195
02196
02197 atomSelParser->add_keyword("volindex0", atomsel_gridindex0, NULL);
02198 atomSelParser->add_keyword("volindex1", atomsel_gridindex1, NULL);
02199 atomSelParser->add_keyword("volindex2", atomsel_gridindex2, NULL);
02200 atomSelParser->add_keyword("volindex3", atomsel_gridindex3, NULL);
02201 atomSelParser->add_keyword("volindex4", atomsel_gridindex4, NULL);
02202 atomSelParser->add_keyword("volindex5", atomsel_gridindex5, NULL);
02203 atomSelParser->add_keyword("volindex6", atomsel_gridindex6, NULL);
02204 atomSelParser->add_keyword("volindex7", atomsel_gridindex7, NULL);
02205 atomSelParser->add_keyword("vol0", atomsel_volume0, NULL);
02206 atomSelParser->add_keyword("vol1", atomsel_volume1, NULL);
02207 atomSelParser->add_keyword("vol2", atomsel_volume2, NULL);
02208 atomSelParser->add_keyword("vol3", atomsel_volume3, NULL);
02209 atomSelParser->add_keyword("vol4", atomsel_volume4, NULL);
02210 atomSelParser->add_keyword("vol5", atomsel_volume5, NULL);
02211 atomSelParser->add_keyword("vol6", atomsel_volume6, NULL);
02212 atomSelParser->add_keyword("vol7", atomsel_volume7, NULL);
02213 atomSelParser->add_keyword("interpvol0", atomsel_interp_volume0, NULL);
02214 atomSelParser->add_keyword("interpvol1", atomsel_interp_volume1, NULL);
02215 atomSelParser->add_keyword("interpvol2", atomsel_interp_volume2, NULL);
02216 atomSelParser->add_keyword("interpvol3", atomsel_interp_volume3, NULL);
02217 atomSelParser->add_keyword("interpvol4", atomsel_interp_volume4, NULL);
02218 atomSelParser->add_keyword("interpvol5", atomsel_interp_volume5, NULL);
02219 atomSelParser->add_keyword("interpvol6", atomsel_interp_volume6, NULL);
02220 atomSelParser->add_keyword("interpvol7", atomsel_interp_volume7, NULL);
02221 }
02222
02223
02225
02226 AtomSel::AtomSel(SymbolTable *st, int id)
02227 : ID(id) {
02228
02229
02230 table = st;
02231 selected = NO_PARSE;
02232 firstsel = 0;
02233 lastsel = NO_PARSE;
02234 on = NULL;
02235 cmdStr = NULL;
02236 tree = NULL;
02237 num_atoms = 0;
02238 which_frame = TS_NOW;
02239 do_update = 0;
02240 }
02241
02242
02243 AtomSel::~AtomSel(void) {
02244 table = NULL;
02245 num_atoms = 0;
02246 selected = NO_PARSE;
02247 firstsel = 0;
02248 lastsel = NO_PARSE;
02249 delete [] on;
02250 on = NULL;
02251 delete tree;
02252 delete [] cmdStr;
02253 }
02254
02255 int AtomSel::change(const char *newcmd, DrawMolecule *mol) {
02256 if (newcmd) {
02257 ParseTree *newtree = table->parse(newcmd);
02258 if (!newtree) {
02259 return NO_PARSE;
02260 }
02261 delete [] cmdStr;
02262 cmdStr = stringdup(newcmd);
02263 delete tree;
02264 tree = newtree;
02265 }
02266
02267
02268 atomsel_ctxt context(table, mol, which_frame, NULL);
02269
02270
02271 if (num_atoms != mol->nAtoms || (on == NULL)) {
02272 if (on) delete [] on;
02273 on = new int[mol->nAtoms];
02274 num_atoms = mol->nAtoms;
02275 }
02276
02277 tree->use_context(&context);
02278 int rc = tree->evaluate(mol->nAtoms, on);
02279
02280
02281 int ret_code = rc ? PARSE_SUCCESS : NO_EVAL;
02282
02283
02284
02285 selected = 0;
02286 firstsel = 0;
02287 lastsel = NO_PARSE;
02288 int i;
02289
02290
02291 for (i=0; i<num_atoms; i++) if (on[i]) break;
02292
02293
02294
02295 if (i == num_atoms)
02296 return ret_code;
02297 else
02298 firstsel = i;
02299
02300
02301
02302 for (i=firstsel; i<num_atoms; i++) {
02303 selected += on[i];
02304 if (on[i])
02305 lastsel = i;
02306 }
02307
02308 return ret_code;
02309 }
02310
02311
02312
02313 float *AtomSel::coordinates(MoleculeList *mlist) const {
02314 Timestep *ts = timestep(mlist);
02315 if (ts) return ts->pos;
02316 return NULL;
02317 }
02318
02319
02320
02321 Timestep *AtomSel::timestep(MoleculeList *mlist) const {
02322 DrawMolecule *mymol = mlist->mol_from_id(molid());
02323
02324 if (!mymol) {
02325 msgErr << "No molecule" << sendmsg;
02326 return NULL;
02327 }
02328
02329 switch (which_frame) {
02330 case TS_LAST:
02331 return mymol->get_last_frame();
02332
02333 case TS_NOW:
02334 return mymol->current();
02335
02336 default:
02337
02338 if (!mymol->get_frame(which_frame)) {
02339 return mymol->get_last_frame();
02340 }
02341 }
02342
02343 return mymol->get_frame(which_frame);
02344 }
02345
02346
02347 int AtomSel::get_frame_value(const char *s, int *val) {
02348 *val = 1;
02349 if (!strcmp(s, "last")) {
02350 *val = TS_LAST;
02351 }
02352 if (!strcmp(s, "first")) {
02353 *val = 0;
02354 }
02355 if (!strcmp(s, "now")) {
02356 *val = TS_NOW;
02357 }
02358 if (*val == 1) {
02359 int new_frame = atoi(s);
02360 *val = new_frame;
02361 if (new_frame < 0) {
02362 return -1;
02363 }
02364 }
02365 return 0;
02366 }