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_flags(void *v, int num, int *data, int *flgs, int idx) {
00485 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00486 unsigned char *flags = atom_sel_mol->flags();
00487
00488 printf("atomflags: %d\n", idx);
00489 for (int i=0; i<num; i++) {
00490 if (flgs[i]) {
00491 data[i] = (flags[i] >> idx) & 0x1U;
00492
00493 }
00494 }
00495 return 1;
00496 }
00497 static int atomsel_set_flags(void *v, int num, int *data, int *flgs, int idx) {
00498 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00499 unsigned char *flags = atom_sel_mol->flags();
00500 for (int i=0; i<num; i++) {
00501 if (flgs[i]) {
00502 unsigned int val = (data[i] != 0);
00503 flags[i] = (flags[i] & (0xff ^ (0x1U << idx))) | (val << idx);
00504 }
00505 }
00506
00507
00508 atom_sel_mol->set_dataset_flag(BaseMolecule::ATOMFLAGS);
00509 return 1;
00510 }
00511
00512
00513
00514
00515
00516 static int atomsel_flag0(void *v, int num, int *data, int *flgs) {
00517 return atomsel_flags(v, num, data, flgs, 0);
00518 }
00519 static int atomsel_set_flag0(void *v, int num, int *data, int *flgs) {
00520 return atomsel_set_flags(v, num, data, flgs, 0);
00521 }
00522
00523 static int atomsel_flag1(void *v, int num, int *data, int *flgs) {
00524 return atomsel_flags(v, num, data, flgs, 1);
00525 }
00526 static int atomsel_set_flag1(void *v, int num, int *data, int *flgs) {
00527 return atomsel_set_flags(v, num, data, flgs, 1);
00528 }
00529
00530 static int atomsel_flag2(void *v, int num, int *data, int *flgs) {
00531 return atomsel_flags(v, num, data, flgs, 2);
00532 }
00533 static int atomsel_set_flag2(void *v, int num, int *data, int *flgs) {
00534 return atomsel_set_flags(v, num, data, flgs, 2);
00535 }
00536
00537 static int atomsel_flag3(void *v, int num, int *data, int *flgs) {
00538 return atomsel_flags(v, num, data, flgs, 3);
00539 }
00540 static int atomsel_set_flag3(void *v, int num, int *data, int *flgs) {
00541 return atomsel_set_flags(v, num, data, flgs, 3);
00542 }
00543
00544 static int atomsel_flag4(void *v, int num, int *data, int *flgs) {
00545 return atomsel_flags(v, num, data, flgs, 4);
00546 }
00547 static int atomsel_set_flag4(void *v, int num, int *data, int *flgs) {
00548 return atomsel_set_flags(v, num, data, flgs, 4);
00549 }
00550
00551 static int atomsel_flag5(void *v, int num, int *data, int *flgs) {
00552 return atomsel_flags(v, num, data, flgs, 5);
00553 }
00554 static int atomsel_set_flag5(void *v, int num, int *data, int *flgs) {
00555 return atomsel_set_flags(v, num, data, flgs, 5);
00556 }
00557
00558 static int atomsel_flag6(void *v, int num, int *data, int *flgs) {
00559 return atomsel_flags(v, num, data, flgs, 6);
00560 }
00561 static int atomsel_set_flag6(void *v, int num, int *data, int *flgs) {
00562 return atomsel_set_flags(v, num, data, flgs, 6);
00563 }
00564
00565 static int atomsel_flag7(void *v, int num, int *data, int *flgs) {
00566 return atomsel_flags(v, num, data, flgs, 7);
00567 }
00568 static int atomsel_set_flag7(void *v, int num, int *data, int *flgs) {
00569 return atomsel_set_flags(v, num, data, flgs, 7);
00570 }
00571
00572
00573
00574
00575 static int atomsel_resid(void *v, int num, int *data, int *flgs) {
00576 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00577 for (int i=0; i<num; i++) {
00578 if (flgs[i]) {
00579 data[i] = atom_sel_mol->atom(i)->resid;
00580 }
00581 }
00582 return 1;
00583 }
00584 static int atomsel_set_resid(void *v, int num, int *data, int *flgs) {
00585 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00586 for (int i=0; i<num; i++) {
00587 if (flgs[i])
00588 atom_sel_mol->atom(i)->resid = data[i];
00589 }
00590 return 1;
00591 }
00592
00593
00594
00595 #define generic_atom_boolean(fctnname, comparison) \
00596 static int fctnname(void *v, int num, int *flgs) { \
00597 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol; \
00598 for (int i=0; i<num; i++) { \
00599 if (flgs[i]) { \
00600 flgs[i] = atom_sel_mol->atom(i)->comparison; \
00601 } \
00602 } \
00603 return 1; \
00604 }
00605
00606
00607 static int atomsel_backbone(void *v, int num, int *flgs) {
00608 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00609 for (int i=0; i<num; i++) {
00610 if (flgs[i]) {
00611 const MolAtom *a = atom_sel_mol->atom(i);
00612 flgs[i] = (a->atomType == ATOMPROTEINBACK ||
00613 a->atomType == ATOMNUCLEICBACK);
00614 }
00615 }
00616 return 1;
00617 }
00618
00619
00620 generic_atom_boolean(atomsel_hydrogen, atomType == ATOMHYDROGEN)
00621
00622
00623
00624 generic_atom_boolean(atomsel_protein, residueType == RESPROTEIN)
00625
00626
00627
00628 generic_atom_boolean(atomsel_nucleic, residueType == RESNUCLEIC)
00629
00630
00631
00632 generic_atom_boolean(atomsel_water, residueType == RESWATERS)
00633
00634 #define generic_sstruct_boolean(fctnname, comparison) \
00635 static int fctnname(void *v, int num, int *flgs) { \
00636 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol; \
00637 atom_sel_mol->need_secondary_structure(1); \
00638 for (int i=0; i<num; i++) { \
00639 int s; \
00640 if (flgs[i]) { \
00641 s = atom_sel_mol->residue( \
00642 atom_sel_mol->atom(i)->uniq_resid \
00643 )->sstruct; \
00644 if (!comparison) { \
00645 flgs[i] = 0; \
00646 } \
00647 } \
00648 } \
00649 return 1; \
00650 }
00651
00652
00653
00654 #define generic_set_sstruct_boolean(fctnname, newval) \
00655 static int fctnname(void *v, int num, int *data, int *flgs) { \
00656 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol; \
00657 atom_sel_mol->need_secondary_structure(0); \
00658 for (int i=0; i<num; i++) { \
00659 if (flgs[i] && data[i]) { \
00660 atom_sel_mol->residue(atom_sel_mol->atom(i)->uniq_resid) \
00661 ->sstruct = newval; \
00662 } \
00663 } \
00664 return 1; \
00665 }
00666
00667
00668
00669
00670 static void recursive_find_sidechain_atoms(BaseMolecule *mol, int *sidechain,
00671 int atom_index) {
00672
00673 if (sidechain[atom_index] == 2)
00674 return;
00675
00676
00677 MolAtom *atom = mol->atom(atom_index);
00678 if (atom->atomType == ATOMPROTEINBACK ||
00679 atom->atomType == ATOMNUCLEICBACK) return;
00680
00681
00682 sidechain[atom_index] = 2;
00683
00684
00685 for (int i=0; i<atom->bonds; i++) {
00686 recursive_find_sidechain_atoms(mol, sidechain, atom->bondTo[i]);
00687 }
00688 }
00689
00690
00691
00692 static void find_sidechain_atoms(BaseMolecule *mol, int *sidechain) {
00693 for (int i=0; i<mol->nAtoms; i++) {
00694 if (sidechain[i] == 1) {
00695 recursive_find_sidechain_atoms(mol, sidechain, i);
00696 }
00697 }
00698 }
00699
00700
00701
00702
00703
00704
00705 static int atomsel_sidechain(void *v, int num, int *flgs) {
00706 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00707 const float *mass = atom_sel_mol->mass();
00708 int i;
00709
00710
00711 int *seed = new int[num];
00712 memset(seed, 0, num * sizeof(int));
00713
00714
00715 int CA = atom_sel_mol->atomNames.typecode((char *) "CA");
00716
00717
00718 for (int pfrag=atom_sel_mol->pfragList.num()-1; pfrag>=0; pfrag--) {
00719
00720 Fragment &frag = *(atom_sel_mol->pfragList[pfrag]);
00721 for (int res = frag.num()-1; res >=0; res--) {
00722
00723 int atomid = atom_sel_mol->find_atom_in_residue(CA, frag[res]);
00724 if (atomid < 0) {
00725 msgErr << "atomselection: sidechain: cannot find CA" << sendmsg;
00726 continue;
00727 }
00728
00729 MolAtom *atom = atom_sel_mol->atom(atomid);
00730 int b1 = -1, b2 = -1;
00731 for (i=0; i<atom->bonds; i++) {
00732 int bondtype = atom_sel_mol->atom(atom->bondTo[i])->atomType;
00733 if (bondtype == ATOMNORMAL || bondtype == ATOMHYDROGEN) {
00734 if (b1 == -1) {
00735 b1 = atom->bondTo[i];
00736 } else {
00737 if (b2 == -1) {
00738 b2 = atom->bondTo[i];
00739 } else {
00740 msgErr << "atomselection: sidechain: protein residue index "
00741 << res << ", C-alpha index " << i << " has more than "
00742 << "two non-backbone bonds; ignoring the others"
00743 << sendmsg;
00744 }
00745 }
00746 }
00747 }
00748 if (b1 == -1)
00749 continue;
00750
00751 if (b2 != -1) {
00752
00753 int c1 = atom_sel_mol->atom(b1)->bonds;
00754 int c2 = atom_sel_mol->atom(b2)->bonds;
00755 if (c1 == 1 && c2 > 1) {
00756 b1 = b2;
00757 } else if (c2 == 1 && c1 > 1) {
00758 #if 1
00759
00760 seed[b1] = 1;
00761 continue;
00762 #else
00763 b1 = b1;
00764 #endif
00765 } else if (c1 ==1 && c2 == 1) {
00766
00767 float m1 = mass[b1];
00768 float m2 = mass[b2];
00769 if (m1 > 2.3 && m2 <= 2.3) {
00770 b1 = b2;
00771 } else if (m2 > 2.3 && m1 <= 2.3) {
00772 #if 1
00773
00774 seed[b1] = 1;
00775 continue;
00776 #else
00777 b1 = b1;
00778 #endif
00779 } else if (m1 <= 2.0 && m2 <= 2.3) {
00780
00781 if (strcmp(
00782 (atom_sel_mol->atomNames).name(atom_sel_mol->atom(b1)->nameindex),
00783 (atom_sel_mol->atomNames).name(atom_sel_mol->atom(b2)->nameindex)
00784 ) > 0) {
00785 b1 = b2;
00786 }
00787 } else {
00788 msgErr << "atomselect: sidechain: protein residue index "
00789 << res << ", C-alpha index " << i << " has sidechain-like "
00790 << "atom (indices " << b1 << " and " << b2 << "), and "
00791 << "I cannot determine which to call a sidechain -- "
00792 << "I'll guess" << sendmsg;
00793 if (strcmp(
00794 (atom_sel_mol->atomNames).name(atom_sel_mol->atom(b1)->nameindex),
00795 (atom_sel_mol->atomNames).name(atom_sel_mol->atom(b2)->nameindex)
00796 ) > 0) {
00797 b1 = b2;
00798 }
00799 }
00800 }
00801 }
00802 seed[b1] = 1;
00803
00804 }
00805 }
00806
00807
00808 find_sidechain_atoms(atom_sel_mol, seed);
00809
00810
00811 for (i=0; i<num; i++) {
00812 if (flgs[i])
00813 flgs[i] = (seed[i] != 0);
00814 }
00815
00816 delete [] seed;
00817
00818 return 1;
00819 }
00820
00821
00822
00823 generic_sstruct_boolean(atomsel_helix, (s == SS_HELIX_ALPHA ||
00824 s == SS_HELIX_3_10 ||
00825 s == SS_HELIX_PI))
00826 generic_sstruct_boolean(atomsel_alpha_helix, (s == SS_HELIX_ALPHA))
00827 generic_sstruct_boolean(atomsel_3_10_helix, (s == SS_HELIX_3_10))
00828 generic_sstruct_boolean(atomsel_pi_helix, (s == SS_HELIX_PI))
00829
00830
00831 generic_set_sstruct_boolean(atomsel_set_helix, SS_HELIX_ALPHA)
00832
00833 generic_set_sstruct_boolean(atomsel_set_3_10_helix, SS_HELIX_3_10)
00834
00835 generic_set_sstruct_boolean(atomsel_set_pi_helix, SS_HELIX_PI)
00836
00837
00838 generic_sstruct_boolean(atomsel_sheet, (s == SS_BETA ||
00839 s == SS_BRIDGE ))
00840 generic_sstruct_boolean(atomsel_extended_sheet, (s == SS_BETA))
00841 generic_sstruct_boolean(atomsel_bridge_sheet, (s == SS_BRIDGE ))
00842
00843
00844 generic_set_sstruct_boolean(atomsel_set_sheet, SS_BETA)
00845 generic_set_sstruct_boolean(atomsel_set_bridge_sheet, SS_BRIDGE)
00846
00847
00848 generic_sstruct_boolean(atomsel_coil, (s == SS_COIL))
00849
00850
00851 generic_set_sstruct_boolean(atomsel_set_coil, SS_COIL)
00852
00853
00854 generic_sstruct_boolean(atomsel_turn, (s == SS_TURN))
00855
00856
00857 generic_set_sstruct_boolean(atomsel_set_turn, SS_TURN)
00858
00859
00860 static int atomsel_sstruct(void *v, int num, const char **data, int *flgs) {
00861 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00862 atom_sel_mol->need_secondary_structure(1);
00863 for (int i=0; i<num; i++) {
00864 if (flgs[i]) {
00865 switch(atom_sel_mol->residue(atom_sel_mol->atom(i)->uniq_resid)->sstruct) {
00866 case SS_HELIX_ALPHA: data[i] = "H"; break;
00867 case SS_HELIX_3_10 : data[i] = "G"; break;
00868 case SS_HELIX_PI : data[i] = "I"; break;
00869 case SS_BETA : data[i] = "E"; break;
00870 case SS_BRIDGE : data[i] = "B"; break;
00871 case SS_TURN : data[i] = "T"; break;
00872 default:
00873 case SS_COIL : data[i] = "C"; break;
00874 }
00875 }
00876 }
00877 return 1;
00878 }
00879
00880
00881
00882 static int atomsel_set_sstruct(void *v, int num, const char **data, int *flgs) {
00883 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
00884 char c;
00885
00886
00887 atom_sel_mol->need_secondary_structure(0);
00888 for (int i=0; i<num; i++) {
00889 if (flgs[i]) {
00890 if (strlen(data[i]) == 0) {
00891 msgErr << "cannot set a 0 length secondary structure string"
00892 << sendmsg;
00893 } else {
00894 c = ((const char *) data[i])[0];
00895 if (strlen(data[i]) > 1) {
00896 while (1) {
00897 if (!strcasecmp((const char *) data[i], "helix")) { c = 'H'; break;}
00898 if (!strcasecmp((const char *) data[i], "alpha")) { c = 'H'; break;}
00899 if (!strcasecmp((const char *) data[i], "alpha_helix")) { c = 'H'; break;}
00900 if (!strcasecmp((const char *) data[i], "alphahelix")) { c = 'H'; break;}
00901 if (!strcasecmp((const char *) data[i], "alpha helix")) { c = 'H'; break;}
00902
00903 if (!strcasecmp((const char *) data[i], "pi")) { c = 'I'; break;}
00904 if (!strcasecmp((const char *) data[i], "pi_helix")) { c = 'I'; break;}
00905 if (!strcasecmp((const char *) data[i], "pihelix")) { c = 'I'; break;}
00906 if (!strcasecmp((const char *) data[i], "pi helix")) { c = 'I'; break;}
00907
00908 if (!strcasecmp((const char *) data[i], "310")) { c = 'G'; break;}
00909 if (!strcasecmp((const char *) data[i], "310_helix")) { c = 'G'; break;}
00910 if (!strcasecmp((const char *) data[i], "3_10")) { c = 'G'; break;}
00911 if (!strcasecmp((const char *) data[i], "3")) { c = 'G'; break;}
00912 if (!strcasecmp((const char *) data[i], "310 helix")) { c = 'G'; break;}
00913 if (!strcasecmp((const char *) data[i], "3_10_helix")){ c = 'G'; break;}
00914 if (!strcasecmp((const char *) data[i], "3_10 helix")){ c = 'G'; break;}
00915 if (!strcasecmp((const char *) data[i], "3 10 helix")){ c = 'G'; break;}
00916 if (!strcasecmp((const char *) data[i], "helix_3_10")){ c = 'G'; break;}
00917 if (!strcasecmp((const char *) data[i], "helix 3 10")){ c = 'G'; break;}
00918 if (!strcasecmp((const char *) data[i], "helix3_10")) { c = 'G'; break;}
00919 if (!strcasecmp((const char *) data[i], "helix310")) { c = 'G'; break;}
00920
00921 if (!strcasecmp((const char *) data[i], "beta")) { c = 'E'; break;}
00922 if (!strcasecmp((const char *) data[i], "betasheet")) { c = 'E'; break;}
00923 if (!strcasecmp((const char *) data[i], "beta_sheet")){ c = 'E'; break;}
00924 if (!strcasecmp((const char *) data[i], "beta sheet")){ c = 'E'; break;}
00925 if (!strcasecmp((const char *) data[i], "sheet")) { c = 'E'; break;}
00926 if (!strcasecmp((const char *) data[i], "strand")) { c = 'E'; break;}
00927 if (!strcasecmp((const char *) data[i], "beta_strand")) { c = 'E'; break;}
00928 if (!strcasecmp((const char *) data[i], "beta strand")) { c = 'E'; break;}
00929
00930 if (!strcasecmp((const char *) data[i], "turn")) { c = 'T'; break;}
00931
00932 if (!strcasecmp((const char *) data[i], "coil")) { c = 'C'; break;}
00933 if (!strcasecmp((const char *) data[i], "unknown")) { c = 'C'; break;}
00934 c = 'X';
00935 break;
00936 }
00937 }
00938
00939 int s = SS_COIL;
00940 switch ( c ) {
00941 case 'H':
00942 case 'h': s = SS_HELIX_ALPHA; break;
00943 case '3':
00944 case 'G':
00945 case 'g': s = SS_HELIX_3_10; break;
00946 case 'P':
00947 case 'p':
00948 case 'I':
00949 case 'i': s = SS_HELIX_PI; break;
00950 case 'S':
00951 case 's':
00952 case 'E':
00953 case 'e': s = SS_BETA; break;
00954 case 'B':
00955 case 'b': s = SS_BRIDGE; break;
00956 case 'T':
00957 case 't': s = SS_TURN; break;
00958 case 'L':
00959 case 'l':
00960 case 'C':
00961 case 'c': s = SS_COIL; break;
00962 default: {
00963 msgErr << "Unknown sstruct assignment: '"
00964 << (const char *) data[i] << "'" << sendmsg;
00965 s = SS_COIL; break;
00966 }
00967 }
00968 atom_sel_mol->residue(atom_sel_mol->atom(i)->uniq_resid)->sstruct = s;
00969 }
00970 }
00971 }
00972 return 1;
00973 }
00974
00975
00977
00978
00979 static void mark_atoms_given_residue(DrawMolecule *mol, int residue, int *on)
00980 {
00981 ResizeArray<int> *atoms = &(mol->residueList[residue]->atoms);
00982 for (int i= atoms->num()-1; i>=0; i--) {
00983 on[(*atoms)[i]] = TRUE;
00984 }
00985 }
00986
00987
00988
00989 #define fragment_data(fctn, fragtype) \
00990 static int fctn(void *v, int num, int *data, int *) \
00991 { \
00992 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol; \
00993 int *tmp = new int[num]; \
00994 int i; \
00995 for (i=num-1; i>=0; i--) { \
00996 tmp[i] = 0; \
00997 data[i] = -1; \
00998 } \
00999 \
01000 for ( i=atom_sel_mol->fragtype.num()-1; i>=0; i--) { \
01001 \
01002 int j; \
01003 for (j=atom_sel_mol->fragtype[i]->num()-1; j>=0; j--) { \
01004 \
01005 mark_atoms_given_residue(atom_sel_mol,(*atom_sel_mol->fragtype[i])[j], tmp); \
01006 } \
01007 \
01008 for (j=num-1; j>=0; j--) { \
01009 if (tmp[j]) { \
01010 data[j] = i; \
01011 tmp[j] = 0; \
01012 } \
01013 } \
01014 } \
01015 delete [] tmp; \
01016 return 1; \
01017 }
01018
01019 fragment_data(atomsel_pfrag, pfragList)
01020 fragment_data(atomsel_nfrag, nfragList)
01021
01022 static Timestep *selframe(DrawMolecule *atom_sel_mol, int which_frame) {
01023 Timestep *r;
01024 switch (which_frame) {
01025 case AtomSel::TS_LAST: r = atom_sel_mol->get_last_frame(); break;
01026
01027 case AtomSel::TS_NOW : r = atom_sel_mol->current(); break;
01028 default: {
01029 if (!atom_sel_mol->get_frame(which_frame)) {
01030 r = atom_sel_mol->get_last_frame();
01031
01032 } else {
01033 r = atom_sel_mol->get_frame(which_frame);
01034 }
01035 }
01036 }
01037 return r;
01038 }
01039
01040
01041 #if defined(VMDWITHCARBS)
01042
01043 static int atomsel_pucker(void *v, int num, double *data, int *flgs) {
01044 int i;
01045 SmallRing *ring;
01046 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
01047 memset(data, 0, num*sizeof(double));
01048 int which_frame = ((atomsel_ctxt *)v)->which_frame;
01049 Timestep *ts = selframe(atom_sel_mol, which_frame);
01050 if (!ts || !ts->pos) {
01051 return 1;
01052 }
01053
01054
01055
01056
01057 atom_sel_mol->find_small_rings_and_links(5, 6);
01058
01059 for (i=0; i < atom_sel_mol->smallringList.num(); i++) {
01060 ring = atom_sel_mol->smallringList[i];
01061 int N = ring->num();
01062
01063
01064 if (N >= 5 && N <= 6) {
01065 float pucker = hill_reilly_ring_pucker((*ring), ts->pos);
01066
01067 int j;
01068 for (j=0; j<N; j++) {
01069 int ind = (*ring)[j];
01070 if (flgs[ind])
01071 data[ind] = pucker;
01072 }
01073 }
01074 }
01075
01076 return 1;
01077 }
01078 #endif
01079
01080 static int atomsel_user(void *v, int num, double *data, int *flgs) {
01081 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
01082 int which_frame = ((atomsel_ctxt *)v)->which_frame;
01083 Timestep *ts = selframe(atom_sel_mol, which_frame);
01084 if (!ts || !ts->user) {
01085 memset(data, 0, num*sizeof(double));
01086 return 1;
01087 }
01088 for (int i=0; i<num; i++) {
01089 if (flgs[i]) {
01090 data[i] = ts->user[i];
01091 }
01092 }
01093 return 1;
01094 }
01095 static int atomsel_set_user(void *v, int num, double *data, int *flgs) {
01096 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
01097 int which_frame = ((atomsel_ctxt *)v)->which_frame;
01098 Timestep *ts = selframe(atom_sel_mol, which_frame);
01099 if (!ts) return 0;
01100 if (!ts->user) {
01101 ts->user= new float[num];
01102 memset(ts->user, 0, num*sizeof(float));
01103 }
01104 for (int i=0; i<num; i++) {
01105 if (flgs[i]) {
01106 ts->user[i] = (float)data[i];
01107 }
01108 }
01109 return 1;
01110 }
01111
01112 static int atomsel_user2(void *v, int num, double *data, int *flgs) {
01113 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
01114 int which_frame = ((atomsel_ctxt *)v)->which_frame;
01115 Timestep *ts = selframe(atom_sel_mol, which_frame);
01116 if (!ts || !ts->user2) {
01117 memset(data, 0, num*sizeof(double));
01118 return 1;
01119 }
01120 for (int i=0; i<num; i++) {
01121 if (flgs[i]) {
01122 data[i] = ts->user2[i];
01123 }
01124 }
01125 return 1;
01126 }
01127 static int atomsel_set_user2(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 if (!ts) return 0;
01132 if (!ts->user2) {
01133 ts->user2= new float[num];
01134 memset(ts->user2, 0, num*sizeof(float));
01135 }
01136 for (int i=0; i<num; i++) {
01137 if (flgs[i]) {
01138 ts->user2[i] = (float)data[i];
01139 }
01140 }
01141 return 1;
01142 }
01143
01144 static int atomsel_user3(void *v, int num, double *data, int *flgs) {
01145 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
01146 int which_frame = ((atomsel_ctxt *)v)->which_frame;
01147 Timestep *ts = selframe(atom_sel_mol, which_frame);
01148 if (!ts || !ts->user3) {
01149 memset(data, 0, num*sizeof(double));
01150 return 1;
01151 }
01152 for (int i=0; i<num; i++) {
01153 if (flgs[i]) {
01154 data[i] = ts->user3[i];
01155 }
01156 }
01157 return 1;
01158 }
01159 static int atomsel_set_user3(void *v, int num, double *data, int *flgs) {
01160 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
01161 int which_frame = ((atomsel_ctxt *)v)->which_frame;
01162 Timestep *ts = selframe(atom_sel_mol, which_frame);
01163 if (!ts) return 0;
01164 if (!ts->user3) {
01165 ts->user3= new float[num];
01166 memset(ts->user3, 0, num*sizeof(float));
01167 }
01168 for (int i=0; i<num; i++) {
01169 if (flgs[i]) {
01170 ts->user3[i] = (float)data[i];
01171 }
01172 }
01173 return 1;
01174 }
01175
01176 static int atomsel_user4(void *v, int num, double *data, int *flgs) {
01177 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
01178 int which_frame = ((atomsel_ctxt *)v)->which_frame;
01179 Timestep *ts = selframe(atom_sel_mol, which_frame);
01180 if (!ts || !ts->user4) {
01181 memset(data, 0, num*sizeof(double));
01182 return 1;
01183 }
01184 for (int i=0; i<num; i++) {
01185 if (flgs[i]) {
01186 data[i] = ts->user4[i];
01187 }
01188 }
01189 return 1;
01190 }
01191 static int atomsel_set_user4(void *v, int num, double *data, int *flgs) {
01192 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
01193 int which_frame = ((atomsel_ctxt *)v)->which_frame;
01194 Timestep *ts = selframe(atom_sel_mol, which_frame);
01195 if (!ts) return 0;
01196 if (!ts->user4) {
01197 ts->user4= new float[num];
01198 memset(ts->user4, 0, num*sizeof(float));
01199 }
01200 for (int i=0; i<num; i++) {
01201 if (flgs[i]) {
01202 ts->user4[i] = (float)data[i];
01203 }
01204 }
01205 return 1;
01206 }
01207
01208
01209
01210 static int atomsel_xpos(void *v, int num, double *data, int *flgs) {
01211 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
01212 int which_frame = ((atomsel_ctxt *)v)->which_frame;
01213 Timestep *ts = selframe(atom_sel_mol, which_frame);
01214 int i;
01215 if (!ts) {
01216 for (i=0; i<num; i++)
01217 if (flgs[i]) data[i] = 0.0;
01218 return 0;
01219 }
01220 for (i=0; i<num; i++) {
01221 if (flgs[i]) {
01222 data[i] = ts->pos[3L*i ];
01223 }
01224 }
01225 return 1;
01226 }
01227
01228 static int atomsel_ypos(void *v, int num, double *data, int *flgs) {
01229 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
01230 int which_frame = ((atomsel_ctxt *)v)->which_frame;
01231 Timestep *ts = selframe(atom_sel_mol, which_frame);
01232 int i;
01233 if (!ts) {
01234 for (i=0; i<num; i++)
01235 if (flgs[i]) data[i] = 0.0;
01236 return 0;
01237 }
01238 for (i=0; i<num; i++) {
01239 if (flgs[i]) {
01240 data[i] = ts->pos[3L*i + 1L];
01241 }
01242 }
01243 return 1;
01244 }
01245
01246 static int atomsel_zpos(void *v, int num, double *data, int *flgs) {
01247 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
01248 int which_frame = ((atomsel_ctxt *)v)->which_frame;
01249 Timestep *ts = selframe(atom_sel_mol, which_frame);
01250 int i;
01251 if (!ts) {
01252 for (i=0; i<num; i++)
01253 if (flgs[i]) data[i] = 0.0;
01254 return 0;
01255 }
01256 for (i=0; i<num; i++) {
01257 if (flgs[i]) {
01258 data[i] = ts->pos[3L*i + 2L];
01259 }
01260 }
01261 return 1;
01262 }
01263
01264 static int atomsel_ufx(void *v, int num, double *data, int *flgs) {
01265 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
01266 int which_frame = ((atomsel_ctxt *)v)->which_frame;
01267 Timestep *ts = selframe(atom_sel_mol, which_frame);
01268 int i;
01269 if (!ts || !ts->force) {
01270 for (i=0; i<num; i++)
01271 if (flgs[i]) data[i] = 0.0;
01272 return 0;
01273 }
01274 for (i=0; i<num; i++) {
01275 if (flgs[i]) {
01276 data[i] = ts->force[3L*i ];
01277 }
01278 }
01279 return 1;
01280 }
01281
01282 static int atomsel_ufy(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 || !ts->force) {
01288 for (i=0; i<num; i++)
01289 if (flgs[i]) data[i] = 0.0;
01290 return 0;
01291 }
01292 for (i=0; i<num; i++) {
01293 if (flgs[i]) {
01294 data[i] = ts->force[3L*i + 1L];
01295 }
01296 }
01297 return 1;
01298 }
01299
01300 static int atomsel_ufz(void *v, int num, double *data, int *flgs) {
01301 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
01302 int which_frame = ((atomsel_ctxt *)v)->which_frame;
01303 Timestep *ts = selframe(atom_sel_mol, which_frame);
01304 int i;
01305 if (!ts || !ts->force) {
01306 for (i=0; i<num; i++)
01307 if (flgs[i]) data[i] = 0.0;
01308 return 0;
01309 }
01310 for (i=0; i<num; i++) {
01311 if (flgs[i]) {
01312 data[i] = ts->force[3L*i + 2L];
01313 }
01314 }
01315 return 1;
01316 }
01317
01318 #define atomsel_get_vel(name, offset) \
01319 static int atomsel_##name(void *v, int num, double *data, int *flgs) { \
01320 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol; \
01321 int which_frame = ((atomsel_ctxt *)v)->which_frame; \
01322 Timestep *ts = selframe(atom_sel_mol, which_frame); \
01323 int i; \
01324 if (!ts || !ts->vel) { \
01325 for (i=0; i<num; i++) \
01326 if (flgs[i]) data[i] = 0.0; \
01327 return 0; \
01328 } \
01329 for (i=0; i<num; i++) { \
01330 if (flgs[i]) { \
01331 data[i] = ts->vel[3L*i + (offset)]; \
01332 } \
01333 } \
01334 return 1; \
01335 }
01336
01337 atomsel_get_vel(vx, 0)
01338 atomsel_get_vel(vy, 1)
01339 atomsel_get_vel(vz, 2)
01340
01341 static int atomsel_phi(void *v, int num, double *data, int *flgs) {
01342 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
01343 int which_frame = ((atomsel_ctxt *)v)->which_frame;
01344 Timestep *ts = selframe(atom_sel_mol, which_frame);
01345 int i;
01346 if (!ts) {
01347 for (i=0; i<num; i++) data[i] = 0;
01348 return 0;
01349 }
01350 const float *r = ts->pos;
01351 for (i=0; i<num; i++) {
01352 if (!flgs[i]) continue;
01353 MolAtom *atom = atom_sel_mol->atom(i);
01354 int resid = atom->uniq_resid;
01355 int N = atom_sel_mol->find_atom_in_residue("N", resid);
01356 int CA = atom_sel_mol->find_atom_in_residue("CA", resid);
01357 int C = atom_sel_mol->find_atom_in_residue("C", resid);
01358
01359
01360
01361 if (N < 0) {
01362 data[i] = 0;
01363 continue;
01364 }
01365 MolAtom *atomN = atom_sel_mol->atom(N);
01366 int cprev = -1;
01367 for (int j=0; j<atomN->bonds; j++) {
01368 int aindex = atomN->bondTo[j];
01369 int nameindex = atom_sel_mol->atom(aindex)->nameindex;
01370 if (!strcmp(atom_sel_mol->atomNames.name(nameindex), "C")) {
01371 cprev = aindex;
01372 break;
01373 }
01374 }
01375 if (cprev >= 0 && CA >= 0 && C >= 0)
01376 data[i] = dihedral(r+3L*cprev, r+3L*N, r+3L*CA, r+3L*C);
01377 else
01378 data[i] = 0.0;
01379 }
01380 return 0;
01381 }
01382
01383 static int atomsel_psi(void *v, int num, double *data, int *flgs) {
01384 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
01385 int which_frame = ((atomsel_ctxt *)v)->which_frame;
01386 Timestep *ts = selframe(atom_sel_mol, which_frame);
01387 int i;
01388 if (!ts) {
01389 for (i=0; i<num; i++) data[i] = 0;
01390 return 0;
01391 }
01392 const float *r = ts->pos;
01393 for (i=0; i<num; i++) {
01394 if (!flgs[i]) continue;
01395 MolAtom *atom = atom_sel_mol->atom(i);
01396 int resid = atom->uniq_resid;
01397 int N = atom_sel_mol->find_atom_in_residue("N", resid);
01398 int CA = atom_sel_mol->find_atom_in_residue("CA", resid);
01399 int C = atom_sel_mol->find_atom_in_residue("C", resid);
01400
01401
01402
01403 if (C < 0) {
01404 data[i] = 0;
01405 continue;
01406 }
01407 MolAtom *atomC = atom_sel_mol->atom(C);
01408 int nextn = -1;
01409 for (int j=0; j<atomC->bonds; j++) {
01410 int aindex = atomC->bondTo[j];
01411 int nameindex = atom_sel_mol->atom(aindex)->nameindex;
01412 if (!strcmp(atom_sel_mol->atomNames.name(nameindex), "N")) {
01413 nextn = aindex;
01414 break;
01415 }
01416 }
01417 if (nextn >= 0 && N >= 0 && CA >= 0)
01418 data[i] = dihedral(r+3L*N, r+3L*CA, r+3L*C, r+3L*nextn);
01419 else
01420 data[i] = 0.0;
01421 }
01422 return 0;
01423 }
01424
01425 static int atomsel_set_phi(void *v, int num, double *data, int *flgs) {
01426
01427
01428
01429
01430
01431
01432
01433 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
01434 SymbolTable *table = ((atomsel_ctxt *)v)->table;
01435 int which_frame = ((atomsel_ctxt *)v)->which_frame;
01436 Timestep *ts = selframe(atom_sel_mol, which_frame);
01437 int i;
01438 if (!ts) {
01439 return 0;
01440 }
01441 float *r = ts->pos;
01442
01443
01444
01445
01446 for (i=0; i<atom_sel_mol->fragList.num(); i++) {
01447 Fragment *frag = atom_sel_mol->fragList[i];
01448 int nfragres = frag->residues.num();
01449 if (nfragres < 2) continue;
01450 int C = atom_sel_mol->find_atom_in_residue("C", frag->residues[0]);
01451
01452 for (int ires = 1; ires < nfragres; ires++) {
01453 int resid = frag->residues[ires];
01454 int cprev = C;
01455 int N = atom_sel_mol->find_atom_in_residue("N", resid);
01456 int CA = atom_sel_mol->find_atom_in_residue("CA", resid);
01457 C = atom_sel_mol->find_atom_in_residue("C", resid);
01458 if (cprev < 0 || N < 0 || CA < 0 || C < 0) continue;
01459 if (!flgs[CA]) continue;
01460 float CApos[3], Npos[3], axis[3];
01461 vec_copy(CApos, r+3L*CA);
01462 vec_copy(Npos, r+3L*N);
01463 vec_sub(axis, Npos, CApos);
01464 vec_normalize(axis);
01465 double oldphi = dihedral(r+3L*cprev, Npos, CApos, r+3L*C);
01466
01467
01468
01469
01470 AtomSel *nterm = new AtomSel(atom_sel_mol->app,
01471 table, atom_sel_mol->id());
01472 char buf[100];
01473 sprintf(buf,
01474 "(fragment %d and residue < %d) or (residue %d and name N NH CA)",
01475 i, resid, resid);
01476 if (nterm->change(buf, atom_sel_mol) == AtomSel::NO_PARSE) {
01477 msgErr << "set phi: internal atom selection error" << sendmsg;
01478 msgErr << buf << sendmsg;
01479 delete nterm;
01480 continue;
01481 }
01482 Matrix4 mat;
01483 mat.transvec(axis[0], axis[1], axis[2]);
01484 mat.rot((float) (data[CA]-oldphi), 'x');
01485 mat.transvecinv(axis[0], axis[1], axis[2]);
01486
01487 for (int j=0; j<num; j++) {
01488 if (nterm->on[j]) {
01489 float *pos = r+3L*j;
01490 vec_sub(pos, pos, CApos);
01491 mat.multpoint3d(pos, pos);
01492 vec_add(pos, pos, CApos);
01493 }
01494 }
01495 delete nterm;
01496 }
01497 }
01498 return 0;
01499 }
01500
01501 static int atomsel_set_psi(void *v, int num, double *data, int *flgs) {
01502 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
01503 SymbolTable *table = ((atomsel_ctxt *)v)->table;
01504 int which_frame = ((atomsel_ctxt *)v)->which_frame;
01505 Timestep *ts = selframe(atom_sel_mol, which_frame);
01506 if (!ts) {
01507 return 0;
01508 }
01509 float *r = ts->pos;
01510
01511 for (int i=0; i<atom_sel_mol->fragList.num(); i++) {
01512 Fragment *frag = atom_sel_mol->fragList[i];
01513 int nfragres = frag->residues.num();
01514 if (nfragres < 2) continue;
01515 int N = atom_sel_mol->find_atom_in_residue("N", frag->residues[nfragres-1]);
01516 for (int ires = nfragres-2; ires >= 0; ires--) {
01517 int resid = frag->residues[ires];
01518 int nextn = N;
01519 N = atom_sel_mol->find_atom_in_residue("N", resid);
01520 int CA = atom_sel_mol->find_atom_in_residue("CA", resid);
01521 int C = atom_sel_mol->find_atom_in_residue("C", resid);
01522 if (nextn < 0 || N < 0 || CA < 0 || C < 0) continue;
01523 if (!flgs[CA]) continue;
01524 float CApos[3], Cpos[3], axis[3];
01525 vec_copy(CApos, r+3L*CA);
01526 vec_copy(Cpos, r+3L*C);
01527 vec_sub(axis, Cpos, CApos);
01528 vec_normalize(axis);
01529 double oldpsi = dihedral(r+3L*N, CApos, Cpos, r+3L*nextn);
01530
01531 AtomSel *cterm = new AtomSel(atom_sel_mol->app,
01532 table, atom_sel_mol->id());
01533 char buf[100];
01534 sprintf(buf,
01535 "(fragment %d and residue > %d) or (residue %d and name CA C O)",
01536 i, resid, resid);
01537 if (cterm->change(buf, atom_sel_mol) == AtomSel::NO_PARSE) {
01538 msgErr << "set psi: internal atom selection error" << sendmsg;
01539 msgErr << buf << sendmsg;
01540 delete cterm;
01541 continue;
01542 }
01543
01544 Matrix4 mat;
01545 mat.transvec(axis[0], axis[1], axis[2]);
01546 mat.rot((float) (data[CA]-oldpsi), 'x');
01547 mat.transvecinv(axis[0], axis[1], axis[2]);
01548
01549 for (int j=0; j<num; j++) {
01550 if (cterm->on[j]) {
01551 float *pos = r+3L*j;
01552 vec_sub(pos, pos, CApos);
01553 mat.multpoint3d(pos, pos);
01554 vec_add(pos, pos, CApos);
01555 }
01556 }
01557 delete cterm;
01558 }
01559 }
01560 return 0;
01561 }
01562
01563 #define set_position_data(fctn, offset) \
01564 static int fctn(void *v, int num, double *data, int *flgs) \
01565 { \
01566 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol; \
01567 int which_frame = ((atomsel_ctxt *)v)->which_frame; \
01568 Timestep *ts = selframe(atom_sel_mol, which_frame); \
01569 if (!ts) return 0; \
01570 for (int i=num-1; i>=0; i--) { \
01571 if (flgs[i]) { \
01572 ts->pos[3L*i + offset] = (float) data[i]; \
01573 } \
01574 } \
01575 return 1; \
01576 }
01577
01578
01579 set_position_data(atomsel_set_xpos, 0)
01580 set_position_data(atomsel_set_ypos, 1)
01581 set_position_data(atomsel_set_zpos, 2)
01582
01583 #define set_force_data(fctn, offset) \
01584 static int fctn(void *v, int num, double *data, int *flgs) \
01585 { \
01586 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol; \
01587 int which_frame = ((atomsel_ctxt *)v)->which_frame; \
01588 Timestep *ts = selframe(atom_sel_mol, which_frame); \
01589 if (!ts) return 0; \
01590 if (!ts->force) { \
01591 ts->force = new float[3L*num]; \
01592 memset(ts->force, 0, 3L*num*sizeof(float)); \
01593 } \
01594 for (int i=num-1; i>=0; i--) { \
01595 if (flgs[i]) { \
01596 ts->force[3L*i + offset] = (float) data[i]; \
01597 } \
01598 } \
01599 return 1; \
01600 }
01601
01602 set_force_data(atomsel_set_ufx, 0)
01603 set_force_data(atomsel_set_ufy, 1)
01604 set_force_data(atomsel_set_ufz, 2)
01605
01606 #define set_vel_data(fctn, offset) \
01607 static int fctn(void *v, int num, double *data, int *flgs) \
01608 { \
01609 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol; \
01610 int which_frame = ((atomsel_ctxt *)v)->which_frame; \
01611 Timestep *ts = selframe(atom_sel_mol, which_frame); \
01612 if (!ts) return 0; \
01613 if (!ts->vel) { \
01614 ts->vel= new float[3L*num]; \
01615 memset(ts->vel, 0, 3L*num*sizeof(float)); \
01616 } \
01617 for (int i=num-1; i>=0; i--) { \
01618 if (flgs[i]) { \
01619 ts->vel[3L*i + offset] = (float) data[i]; \
01620 } \
01621 } \
01622 return 1; \
01623 }
01624
01625 set_vel_data(atomsel_set_vx, 0)
01626 set_vel_data(atomsel_set_vy, 1)
01627 set_vel_data(atomsel_set_vz, 2)
01628
01629 extern "C" {
01630 double atomsel_square(double x) { return x*x; }
01631 }
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650
01651 static int atomsel_sequence(void *v, int argc, const char **argv, int *types,
01652 int num, int *flgs)
01653 {
01654 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
01655 int i;
01656
01657 int *selected = new int[num];
01658 for (i=0; i<num; i++) {
01659 selected[i] = FALSE;
01660 }
01661
01662 JRegex **regex = (JRegex **) malloc( argc * sizeof(JRegex *));
01663 int num_r = 0;
01664 {
01665 JString pattern;
01666 for (i=0; i<argc; i++) {
01667 pattern = argv[i];
01668 if (types[i] >= 3) {
01669 pattern += ".*";
01670 pattern += argv[++i];
01671 }
01672 regex[num_r] = new JRegex(pattern);
01673 num_r ++;
01674 }
01675 }
01676 if (num_r == 0) {
01677 return 0;
01678 }
01679
01680
01681
01682 for (int fragcount=0; fragcount <2; fragcount++) {
01683 int pcount = atom_sel_mol->pfragList.num();
01684 int ncount = atom_sel_mol->nfragList.num();
01685 for (i=0; i< (fragcount == 0 ? pcount : ncount); i++) {
01686 int size = (fragcount == 0 ? atom_sel_mol->pfragList[i]->num()
01687 : atom_sel_mol->nfragList[i]->num());
01688 char *s = new char[size+1];
01689 char *t = s;
01690 int *mark = new int[size];
01691
01692 for (int j=0; j<size; j++) {
01693 int residuenum = ((fragcount == 0) ?
01694 (*atom_sel_mol->pfragList[i])[j] :
01695 (*atom_sel_mol->nfragList[i])[j]);
01696 int atomnum = (atom_sel_mol->residueList[residuenum]->atoms[0]);
01697 MolAtom *atom = atom_sel_mol->atom(atomnum);
01698 const char *resname = (atom_sel_mol->resNames).name(atom->resnameindex);
01699 mark[j] = FALSE;
01700 if (fragcount == 0) {
01701
01702
01703 if (!strcasecmp( resname, "GLY")) {*t++ = 'G'; continue;}
01704 if (!strcasecmp( resname, "ALA")) {*t++ = 'A'; continue;}
01705 if (!strcasecmp( resname, "VAL")) {*t++ = 'V'; continue;}
01706 if (!strcasecmp( resname, "PHE")) {*t++ = 'F'; continue;}
01707 if (!strcasecmp( resname, "PRO")) {*t++ = 'P'; continue;}
01708 if (!strcasecmp( resname, "MET")) {*t++ = 'M'; continue;}
01709 if (!strcasecmp( resname, "ILE")) {*t++ = 'I'; continue;}
01710 if (!strcasecmp( resname, "LEU")) {*t++ = 'L'; continue;}
01711 if (!strcasecmp( resname, "ASP")) {*t++ = 'D'; continue;}
01712 if (!strcasecmp( resname, "GLU")) {*t++ = 'E'; continue;}
01713 if (!strcasecmp( resname, "LYS")) {*t++ = 'K'; continue;}
01714 if (!strcasecmp( resname, "ARG")) {*t++ = 'R'; continue;}
01715 if (!strcasecmp( resname, "SER")) {*t++ = 'S'; continue;}
01716 if (!strcasecmp( resname, "THR")) {*t++ = 'T'; continue;}
01717 if (!strcasecmp( resname, "TYR")) {*t++ = 'Y'; continue;}
01718 if (!strcasecmp( resname, "HIS")) {*t++ = 'H'; continue;}
01719 if (!strcasecmp( resname, "CYS")) {*t++ = 'C'; continue;}
01720 if (!strcasecmp( resname, "ASN")) {*t++ = 'N'; continue;}
01721 if (!strcasecmp( resname, "GLN")) {*t++ = 'Q'; continue;}
01722 if (!strcasecmp( resname, "TRP")) {*t++ = 'W'; continue;}
01723
01724 if (!strcasecmp( resname, "HSE")) {*t++ = 'H'; continue;}
01725 if (!strcasecmp( resname, "HSD")) {*t++ = 'H'; continue;}
01726 if (!strcasecmp( resname, "HSP")) {*t++ = 'H'; continue;}
01727
01728 if (!strcasecmp( resname, "CYX")) {*t++ = 'C'; continue;}
01729 } else {
01730
01731 if (!strcasecmp( resname, "ADE")) {*t++ = 'A'; continue;}
01732 if (!strcasecmp( resname, "A")) {*t++ = 'A'; continue;}
01733 if (!strcasecmp( resname, "THY")) {*t++ = 'T'; continue;}
01734 if (!strcasecmp( resname, "T")) {*t++ = 'T'; continue;}
01735 if (!strcasecmp( resname, "CYT")) {*t++ = 'C'; continue;}
01736 if (!strcasecmp( resname, "C")) {*t++ = 'C'; continue;}
01737 if (!strcasecmp( resname, "GUA")) {*t++ = 'G'; continue;}
01738 if (!strcasecmp( resname, "G")) {*t++ = 'G'; continue;}
01739 if (!strcasecmp( resname, "URA")) {*t++ = 'U'; continue;}
01740 if (!strcasecmp( resname, "U")) {*t++ = 'U'; continue;}
01741 }
01742
01743 *t++ = 'X';
01744 }
01745 *t = 0;
01746
01747
01748
01749 for (int r=0; r<num_r; r++) {
01750 int len, start = 0, offset;
01751 while ((offset = (regex[r]->search(s, strlen(s), len, start)))
01752 != -1) {
01753
01754
01755
01756 for (int loop=offset; loop<offset+len; loop++) {
01757 mark[loop] = 1;
01758 }
01759 start = offset+len;
01760 }
01761 }
01762
01763
01764
01765 for (int marked=0; marked<size; marked++) {
01766 if (mark[marked]) {
01767 int residuenum = (fragcount == 0 ?
01768 (*atom_sel_mol->pfragList[i])[marked] :
01769 (*atom_sel_mol->nfragList[i])[marked]);
01770 for (int atomloop=0;
01771 atomloop< atom_sel_mol->residueList[residuenum]->
01772 atoms.num(); atomloop++) {
01773 selected[atom_sel_mol->residueList[residuenum]->
01774 atoms[atomloop]]=TRUE;
01775 }
01776 }
01777 }
01778 delete [] mark;
01779 delete [] s;
01780 }
01781 }
01782
01783
01784
01785 for (i=0; i<num_r; i++) {
01786 delete regex[i];
01787 }
01788
01789 for (i=0; i<num; i++) {
01790 flgs[i] = flgs[i] && selected[i];
01791 }
01792 return 1;
01793 }
01794
01795
01797
01798
01799
01800
01801
01802
01803
01804 static int atomsel_rasmol_primitive(void *v, int argc, const char **argv, int *,
01805 int num, int *flgs)
01806 {
01807 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
01808 SymbolTable *table = ((atomsel_ctxt *)v)->table;
01809
01810
01811 for (int word=0; word<argc; word++) {
01812 const char *rnm0 = argv[word];
01813 const char *rnm1;
01814 const char *rid0, *rid1;
01815 if (*rnm0 == '*') {
01816 rnm1 = rnm0 + 1;
01817 rid0 = rnm1;
01818 } else if (*rnm0 == '[') {
01819 rnm0++;
01820 rnm1 = rnm0;
01821 while (*rnm1 && *rnm1 != ']') {
01822 rnm1 ++;
01823 }
01824 if (rnm1 == rnm0) {
01825 rid0 = rnm1;
01826 } else {
01827 if (*rnm1==']') {
01828 rid0 = rnm1+1;
01829 } else {
01830 rid0 = rnm1;
01831 }
01832 }
01833 } else {
01834 rnm1 = rnm0;
01835 while (isalpha(*rnm1) || *rnm1 == '?') {
01836 rnm1++;
01837 }
01838 rid0 = rnm1;
01839 }
01840
01841
01842
01843 rid1 = rid0;
01844 if (*rid1 == '*') {
01845 rid1++;
01846 } else {
01847 while (isdigit(*rid1)) {
01848 rid1++;
01849 }
01850 }
01851
01852
01853 const char *chn0, *chn1;
01854 if (*rid1 == ':') {
01855 chn0 = rid1 + 1;
01856 } else {
01857 chn0 = rid1;
01858 }
01859
01860
01861
01862 chn1 = chn0;
01863 while (*chn1 && *chn1 != '.') {
01864 chn1++;
01865 }
01866
01867 const char *nm0, *nm1;
01868 if (*chn1 == '.') {
01869 nm0 = chn1 + 1;
01870 } else {
01871 nm0 = chn1;
01872 }
01873 nm1 = nm0;
01874
01875 while (*nm1) {
01876 nm1++;
01877 }
01878
01879
01880
01881 JString resname, resid, chain, name;
01882 const char *s;
01883 for (s=rnm0; s<rnm1; s++) {
01884 resname += *s;
01885 }
01886 for (s=rid0; s<rid1; s++) {
01887 resid += *s;
01888 }
01889 for (s=chn0; s<chn1; s++) {
01890 chain += *s;
01891 }
01892 for (s=nm0; s<nm1; s++) {
01893 name += *s;
01894 }
01895
01896
01897
01898
01899
01900
01901
01902 if (resname == "*") resname = "";
01903 if (resid == "*") resid = "";
01904 if (chain == "*") chain = "";
01905 if (name == "*") name = "";
01906 resname.gsub("?", ".?"); resname.gsub("*", ".*");
01907 resid.gsub("?", ".?"); resid.gsub("*", ".*");
01908 chain.gsub("?", ".?"); chain.gsub("*", ".*");
01909 name.gsub("?", ".?"); name.gsub("*", ".*");
01910
01911 resname.upcase();
01912 resid.upcase();
01913 chain.upcase();
01914 name.upcase();
01915
01916
01917 JString search;
01918 if (resname != "") {
01919 search = "resname ";
01920 search += '"';
01921 search += resname;
01922 search += '"';
01923 }
01924 if (resid != "") {
01925 if (search != "") {
01926 search += " and resid ";
01927 } else {
01928 search = "resid ";
01929 }
01930 search += '"';
01931 search += resid;
01932 search += '"';
01933 }
01934
01935 int is_segname = chain.length() > 1;
01936 if (chain != "") {
01937 if (search != "") {
01938 search += (is_segname ? " and segname " : " and chain ");
01939 } else {
01940 search = (is_segname ? "segname " : "chain ");
01941 }
01942 search += '"';
01943 search += chain;
01944 search += '"';
01945 }
01946 if (name != "") {
01947 if (search != "") {
01948 search += " and name ";
01949 } else {
01950 search = "name ";
01951 }
01952 search += '"';
01953 search += name;
01954 search += '"';
01955 }
01956 msgInfo << "Search = " << search << sendmsg;
01957
01958 if (search == "") {
01959 search = "all";
01960 }
01961
01962 AtomSel *atomSel = new AtomSel(atom_sel_mol->app,
01963 table, atom_sel_mol->id());
01964 if (atomSel->change((const char *) search, atom_sel_mol) ==
01965 AtomSel::NO_PARSE) {
01966 msgErr << "rasmol: cannot understand: " << argv[word] << sendmsg;
01967 delete atomSel;
01968 continue;
01969 }
01970
01971
01972 {
01973 for (int i=0; i<num; i++) {
01974 flgs[i] = flgs[i] && atomSel->on[i];
01975 }
01976 }
01977 delete atomSel;
01978 }
01979 return 1;
01980 }
01981
01982 int atomsel_custom_singleword(void *v, int num, int *flgs) {
01983 SymbolTable *table = ((atomsel_ctxt *)v)->table;
01984 const char *singleword = ((atomsel_ctxt *)v)->singleword;
01985 if (!singleword) {
01986 msgErr << "Internal error, atom selection macro called without context"
01987 << sendmsg;
01988 return 0;
01989 }
01990 const char *macro = table->get_custom_singleword(singleword);
01991 if (!macro) {
01992 msgErr << "Internal error, atom selection macro has lost its defintion."
01993 << sendmsg;
01994 return 0;
01995 }
01996
01997 DrawMolecule *mol = ((atomsel_ctxt *)v)->atom_sel_mol;
01998 AtomSel *atomSel = new AtomSel(mol->app, table, mol->id());
01999 atomSel->which_frame = ((atomsel_ctxt *)v)->which_frame;
02000 if (atomSel->change(macro, mol) == AtomSel::NO_PARSE) {
02001 msgErr << "Unable to parse macro: " << macro << sendmsg;
02002 delete atomSel;
02003 return 0;
02004 }
02005 for (int i=0; i<num; i++) {
02006 flgs[i] = flgs[i] && atomSel->on[i];
02007 }
02008 delete atomSel;
02009 return 1;
02010 }
02011
02012
02013
02014
02015
02016
02017
02018
02019
02020
02021
02022
02023
02024
02025
02026
02027
02028
02029
02030
02031
02032
02033
02034
02035 #ifndef NAN //not a number
02036 const float NAN = sqrtf(-1.f);
02037 #endif
02038
02039
02040 static int atomsel_volume_array(void *v, int num, double *data, int *flgs, int array_index) {
02041 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
02042 int which_frame = ((atomsel_ctxt *)v)->which_frame;
02043 Timestep *ts = selframe(atom_sel_mol, which_frame);
02044 const VolumetricData *voldata = atom_sel_mol->get_volume_data(array_index);
02045 int i;
02046 if (!ts || !voldata) {
02047 if (!ts) msgErr << "atomselect: non-existent timestep." << sendmsg;
02048 if (!voldata) msgErr << "atomselect: volumetric map volume#" << array_index << " does not exist." << sendmsg;
02049 for (i=0; i<num; i++) if (flgs[i]) data[i] = NAN;
02050 return 0;
02051 }
02052 for (i=0; i<num; i++) {
02053 if (flgs[i])
02054 data[i] = voldata->voxel_value_from_coord(ts->pos[3L*i], ts->pos[3L*i+1], ts->pos[3L*i+2]);
02055 }
02056 return 1;
02057 }
02058
02059
02060 static int atomsel_interp_volume_array(void *v, int num, double *data, int *flgs, int array_index) {
02061 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
02062 int which_frame = ((atomsel_ctxt *)v)->which_frame;
02063 Timestep *ts = selframe(atom_sel_mol, which_frame);
02064 const VolumetricData *voldata = atom_sel_mol->get_volume_data(array_index);
02065 int i;
02066 if (!ts || !voldata) {
02067 if (!ts) msgErr << "atomselect: non-existent timestep." << sendmsg;
02068 if (!voldata) msgErr << "atomselect: volumetric map volume#" << array_index << " does not exist." << sendmsg;
02069 for (i=0; i<num; i++) if (flgs[i]) data[i] = NAN;
02070 return 0;
02071 }
02072 for (i=0; i<num; i++) {
02073 if (flgs[i])
02074 data[i] = voldata->voxel_value_interpolate_from_coord(ts->pos[3L*i], ts->pos[3L*i+1], ts->pos[3L*i+2]);
02075 }
02076 return 1;
02077 }
02078
02079
02080 static int atomsel_gridindex_array(void *v, int num, double *data, int *flgs, int array_index) {
02081 DrawMolecule *atom_sel_mol = ((atomsel_ctxt *)v)->atom_sel_mol;
02082 int which_frame = ((atomsel_ctxt *)v)->which_frame;
02083 Timestep *ts = selframe(atom_sel_mol, which_frame);
02084 const VolumetricData *voldata = atom_sel_mol->get_volume_data(array_index);
02085 int i;
02086 if (!ts || !voldata) {
02087 if (!ts) msgErr << "atomselect: non-existent timestep." << sendmsg;
02088 if (!voldata) msgErr << "atomselect: volumetric map volume#" << array_index << " does not exist." << sendmsg;
02089 for (i=0; i<num; i++) if (flgs[i]) data[i] = NAN;
02090 return 0;
02091 }
02092 for (i=0; i<num; i++) {
02093 if (flgs[i])
02094 data[i] = double(voldata->voxel_index_from_coord(ts->pos[3L*i], ts->pos[3L*i+1], ts->pos[3L*i+2]));
02095 }
02096 return 1;
02097 }
02098
02099
02100 static int atomsel_gridindex0(void *v, int num, double *data, int *flgs) {
02101 return atomsel_gridindex_array(v, num, data, flgs, 0);
02102 }
02103 static int atomsel_gridindex1(void *v, int num, double *data, int *flgs) {
02104 return atomsel_gridindex_array(v, num, data, flgs, 1);
02105 }
02106 static int atomsel_gridindex2(void *v, int num, double *data, int *flgs) {
02107 return atomsel_gridindex_array(v, num, data, flgs, 2);
02108 }
02109 static int atomsel_gridindex3(void *v, int num, double *data, int *flgs) {
02110 return atomsel_gridindex_array(v, num, data, flgs, 3);
02111 }
02112 static int atomsel_gridindex4(void *v, int num, double *data, int *flgs) {
02113 return atomsel_gridindex_array(v, num, data, flgs, 4);
02114 }
02115 static int atomsel_gridindex5(void *v, int num, double *data, int *flgs) {
02116 return atomsel_gridindex_array(v, num, data, flgs, 5);
02117 }
02118 static int atomsel_gridindex6(void *v, int num, double *data, int *flgs) {
02119 return atomsel_gridindex_array(v, num, data, flgs, 6);
02120 }
02121 static int atomsel_gridindex7(void *v, int num, double *data, int *flgs) {
02122 return atomsel_gridindex_array(v, num, data, flgs, 7);
02123 }
02124
02125
02126
02127 static int atomsel_volume0(void *v, int num, double *data, int *flgs) {
02128 return atomsel_volume_array(v, num, data, flgs, 0);
02129 }
02130 static int atomsel_volume1(void *v, int num, double *data, int *flgs) {
02131 return atomsel_volume_array(v, num, data, flgs, 1);
02132 }
02133 static int atomsel_volume2(void *v, int num, double *data, int *flgs) {
02134 return atomsel_volume_array(v, num, data, flgs, 2);
02135 }
02136 static int atomsel_volume3(void *v, int num, double *data, int *flgs) {
02137 return atomsel_volume_array(v, num, data, flgs, 3);
02138 }
02139 static int atomsel_volume4(void *v, int num, double *data, int *flgs) {
02140 return atomsel_volume_array(v, num, data, flgs, 4);
02141 }
02142 static int atomsel_volume5(void *v, int num, double *data, int *flgs) {
02143 return atomsel_volume_array(v, num, data, flgs, 5);
02144 }
02145 static int atomsel_volume6(void *v, int num, double *data, int *flgs) {
02146 return atomsel_volume_array(v, num, data, flgs, 6);
02147 }
02148 static int atomsel_volume7(void *v, int num, double *data, int *flgs) {
02149 return atomsel_volume_array(v, num, data, flgs, 7);
02150 }
02151
02152
02153
02154 static int atomsel_interp_volume0(void *v, int num, double *data, int *flgs) {
02155 return atomsel_interp_volume_array(v, num, data, flgs, 0);
02156 }
02157 static int atomsel_interp_volume1(void *v, int num, double *data, int *flgs) {
02158 return atomsel_interp_volume_array(v, num, data, flgs, 1);
02159 }
02160 static int atomsel_interp_volume2(void *v, int num, double *data, int *flgs) {
02161 return atomsel_interp_volume_array(v, num, data, flgs, 2);
02162 }
02163 static int atomsel_interp_volume3(void *v, int num, double *data, int *flgs) {
02164 return atomsel_interp_volume_array(v, num, data, flgs, 3);
02165 }
02166 static int atomsel_interp_volume4(void *v, int num, double *data, int *flgs) {
02167 return atomsel_interp_volume_array(v, num, data, flgs, 4);
02168 }
02169 static int atomsel_interp_volume5(void *v, int num, double *data, int *flgs) {
02170 return atomsel_interp_volume_array(v, num, data, flgs, 5);
02171 }
02172 static int atomsel_interp_volume6(void *v, int num, double *data, int *flgs) {
02173 return atomsel_interp_volume_array(v, num, data, flgs, 6);
02174 }
02175 static int atomsel_interp_volume7(void *v, int num, double *data, int *flgs) {
02176 return atomsel_interp_volume_array(v, num, data, flgs, 7);
02177 }
02178
02179
02180
02181
02182 void atomSelParser_init(SymbolTable *atomSelParser) {
02183 atomSelParser->add_keyword("name", atomsel_name, atomsel_set_name);
02184 atomSelParser->add_keyword("type", atomsel_type, atomsel_set_type);
02185
02186
02187 atomSelParser->add_keyword("backbonetype", atomsel_backbonetype, NULL);
02188 atomSelParser->add_keyword("residuetype", atomsel_residuetype, NULL);
02189
02190 atomSelParser->add_keyword("index", atomsel_index, NULL);
02191 atomSelParser->add_keyword("serial", atomsel_serial, NULL);
02192 atomSelParser->add_keyword("atomicnumber", atomsel_atomicnumber, atomsel_set_atomicnumber);
02193 atomSelParser->add_keyword("element", atomsel_element, atomsel_set_element);
02194 atomSelParser->add_keyword("residue", atomsel_residue, NULL);
02195 atomSelParser->add_keyword("resname", atomsel_resname, atomsel_set_resname);
02196 atomSelParser->add_keyword("altloc", atomsel_altloc, atomsel_set_altloc);
02197 atomSelParser->add_keyword("resid", atomsel_resid, atomsel_set_resid);
02198 atomSelParser->add_keyword("insertion", atomsel_insertion, NULL);
02199 atomSelParser->add_keyword("chain", atomsel_chain, atomsel_set_chain);
02200 atomSelParser->add_keyword("segname", atomsel_segname, atomsel_set_segname);
02201 atomSelParser->add_keyword("segid", atomsel_segname, atomsel_set_segname);
02202
02203 atomSelParser->add_singleword("all", atomsel_all, NULL);
02204 atomSelParser->add_singleword("none", atomsel_none, NULL);
02205
02206 atomSelParser->add_keyword("fragment", atomsel_fragment, NULL);
02207 atomSelParser->add_keyword("pfrag", atomsel_pfrag, NULL);
02208 atomSelParser->add_keyword("nfrag", atomsel_nfrag, NULL);
02209 atomSelParser->add_keyword("numbonds", atomsel_numbonds, NULL);
02210
02211 atomSelParser->add_singleword("backbone", atomsel_backbone, NULL);
02212 atomSelParser->add_singleword("sidechain",
02213 atomsel_sidechain, NULL);
02214 atomSelParser->add_singleword("protein", atomsel_protein, NULL);
02215 atomSelParser->add_singleword("nucleic", atomsel_nucleic, NULL);
02216 atomSelParser->add_singleword("water", atomsel_water, NULL);
02217 atomSelParser->add_singleword("waters", atomsel_water, NULL);
02218 atomSelParser->add_singleword("vmd_fast_hydrogen", atomsel_hydrogen, NULL);
02219
02220
02221 atomSelParser->add_singleword("helix",
02222 atomsel_helix, atomsel_set_helix);
02223 atomSelParser->add_singleword("alpha_helix",
02224 atomsel_alpha_helix, atomsel_set_helix);
02225 atomSelParser->add_singleword("helix_3_10",
02226 atomsel_3_10_helix, atomsel_set_3_10_helix);
02227 atomSelParser->add_singleword("pi_helix",
02228 atomsel_pi_helix, atomsel_set_pi_helix);
02229 atomSelParser->add_singleword("sheet", atomsel_sheet, atomsel_set_sheet);
02230 atomSelParser->add_singleword("betasheet", atomsel_sheet, atomsel_set_sheet);
02231 atomSelParser->add_singleword("beta_sheet",atomsel_sheet, atomsel_set_sheet);
02232 atomSelParser->add_singleword("extended_beta", atomsel_extended_sheet,
02233 atomsel_set_sheet);
02234 atomSelParser->add_singleword("bridge_beta", atomsel_bridge_sheet,
02235 atomsel_set_bridge_sheet);
02236 atomSelParser->add_singleword("turn", atomsel_turn, atomsel_set_turn);
02237 atomSelParser->add_singleword("coil", atomsel_coil, atomsel_set_coil);
02238 atomSelParser->add_keyword("structure",atomsel_sstruct, atomsel_set_sstruct);
02239
02240 #if defined(VMDWITHCARBS)
02241 atomSelParser->add_keyword("pucker", atomsel_pucker, NULL);
02242 #endif
02243
02244 atomSelParser->add_keyword("user", atomsel_user, atomsel_set_user);
02245 atomSelParser->add_keyword("user2", atomsel_user2, atomsel_set_user2);
02246 atomSelParser->add_keyword("user3", atomsel_user3, atomsel_set_user3);
02247 atomSelParser->add_keyword("user4", atomsel_user4, atomsel_set_user4);
02248
02249 atomSelParser->add_keyword("x", atomsel_xpos, atomsel_set_xpos);
02250 atomSelParser->add_keyword("y", atomsel_ypos, atomsel_set_ypos);
02251 atomSelParser->add_keyword("z", atomsel_zpos, atomsel_set_zpos);
02252 atomSelParser->add_keyword("vx", atomsel_vx, atomsel_set_vx);
02253 atomSelParser->add_keyword("vy", atomsel_vy, atomsel_set_vy);
02254 atomSelParser->add_keyword("vz", atomsel_vz, atomsel_set_vz);
02255 atomSelParser->add_keyword("ufx", atomsel_ufx, atomsel_set_ufx);
02256 atomSelParser->add_keyword("ufy", atomsel_ufy, atomsel_set_ufy);
02257 atomSelParser->add_keyword("ufz", atomsel_ufz, atomsel_set_ufz);
02258 atomSelParser->add_keyword("phi", atomsel_phi, atomsel_set_phi);
02259 atomSelParser->add_keyword("psi", atomsel_psi, atomsel_set_psi);
02260 atomSelParser->add_keyword("radius", atomsel_radius,
02261 atomsel_set_radius);
02262 atomSelParser->add_keyword("mass", atomsel_mass, atomsel_set_mass);
02263 atomSelParser->add_keyword("charge", atomsel_charge,
02264 atomsel_set_charge);
02265 atomSelParser->add_keyword("beta", atomsel_beta, atomsel_set_beta);
02266 atomSelParser->add_keyword("occupancy",
02267 atomsel_occupancy, atomsel_set_occupancy);
02268
02269 atomSelParser->add_keyword("flag0", atomsel_flag0, atomsel_set_flag0);
02270 atomSelParser->add_keyword("flag1", atomsel_flag1, atomsel_set_flag1);
02271 atomSelParser->add_keyword("flag2", atomsel_flag2, atomsel_set_flag2);
02272 atomSelParser->add_keyword("flag3", atomsel_flag3, atomsel_set_flag3);
02273 atomSelParser->add_keyword("flag4", atomsel_flag4, atomsel_set_flag4);
02274 atomSelParser->add_keyword("flag5", atomsel_flag5, atomsel_set_flag5);
02275 atomSelParser->add_keyword("flag6", atomsel_flag6, atomsel_set_flag6);
02276 atomSelParser->add_keyword("flag7", atomsel_flag7, atomsel_set_flag7);
02277
02278 atomSelParser->add_stringfctn("sequence", atomsel_sequence);
02279 atomSelParser->add_stringfctn("rasmol",
02280 atomsel_rasmol_primitive);
02281
02282
02284
02285
02286
02287
02288
02289
02290
02291
02292 atomSelParser->add_cfunction("sqr", atomsel_square);
02293 atomSelParser->add_cfunction("sqrt", sqrt);
02294 atomSelParser->add_cfunction("abs", fabs);
02295 atomSelParser->add_cfunction("floor", floor);
02296 atomSelParser->add_cfunction("ceil", ceil);
02297 atomSelParser->add_cfunction("sin", sin);
02298 atomSelParser->add_cfunction("cos", cos);
02299 atomSelParser->add_cfunction("tan", tan);
02300 atomSelParser->add_cfunction("atan", atan);
02301 atomSelParser->add_cfunction("asin", asin);
02302 atomSelParser->add_cfunction("acos", acos);
02303 atomSelParser->add_cfunction("sinh", sinh);
02304 atomSelParser->add_cfunction("cosh", cosh);
02305 atomSelParser->add_cfunction("tanh", tanh);
02306 atomSelParser->add_cfunction("exp", exp);
02307 atomSelParser->add_cfunction("log", log);
02308 atomSelParser->add_cfunction("log10", log10);
02309
02310
02311
02312 atomSelParser->add_keyword("volindex0", atomsel_gridindex0, NULL);
02313 atomSelParser->add_keyword("volindex1", atomsel_gridindex1, NULL);
02314 atomSelParser->add_keyword("volindex2", atomsel_gridindex2, NULL);
02315 atomSelParser->add_keyword("volindex3", atomsel_gridindex3, NULL);
02316 atomSelParser->add_keyword("volindex4", atomsel_gridindex4, NULL);
02317 atomSelParser->add_keyword("volindex5", atomsel_gridindex5, NULL);
02318 atomSelParser->add_keyword("volindex6", atomsel_gridindex6, NULL);
02319 atomSelParser->add_keyword("volindex7", atomsel_gridindex7, NULL);
02320 atomSelParser->add_keyword("vol0", atomsel_volume0, NULL);
02321 atomSelParser->add_keyword("vol1", atomsel_volume1, NULL);
02322 atomSelParser->add_keyword("vol2", atomsel_volume2, NULL);
02323 atomSelParser->add_keyword("vol3", atomsel_volume3, NULL);
02324 atomSelParser->add_keyword("vol4", atomsel_volume4, NULL);
02325 atomSelParser->add_keyword("vol5", atomsel_volume5, NULL);
02326 atomSelParser->add_keyword("vol6", atomsel_volume6, NULL);
02327 atomSelParser->add_keyword("vol7", atomsel_volume7, NULL);
02328 atomSelParser->add_keyword("interpvol0", atomsel_interp_volume0, NULL);
02329 atomSelParser->add_keyword("interpvol1", atomsel_interp_volume1, NULL);
02330 atomSelParser->add_keyword("interpvol2", atomsel_interp_volume2, NULL);
02331 atomSelParser->add_keyword("interpvol3", atomsel_interp_volume3, NULL);
02332 atomSelParser->add_keyword("interpvol4", atomsel_interp_volume4, NULL);
02333 atomSelParser->add_keyword("interpvol5", atomsel_interp_volume5, NULL);
02334 atomSelParser->add_keyword("interpvol6", atomsel_interp_volume6, NULL);
02335 atomSelParser->add_keyword("interpvol7", atomsel_interp_volume7, NULL);
02336 }
02337
02338
02340
02341 AtomSel::AtomSel(VMDApp *vmdapp, SymbolTable *st, int id)
02342 : ID(id) {
02343
02344
02345 app = vmdapp;
02346 table = st;
02347 selected = NO_PARSE;
02348 firstsel = 0;
02349 lastsel = NO_PARSE;
02350 on = NULL;
02351 on256 = NULL;
02352 cmdStr = NULL;
02353 tree = NULL;
02354 num_atoms = 0;
02355 num_atoms256 = 0;
02356 which_frame = TS_NOW;
02357 do_update = 0;
02358 }
02359
02360
02361 AtomSel::~AtomSel(void) {
02362 table = NULL;
02363 num_atoms = 0;
02364 num_atoms256 = 0;
02365 selected = NO_PARSE;
02366 firstsel = 0;
02367 lastsel = NO_PARSE;
02368 delete [] on;
02369 on = NULL;
02370 delete [] on256;
02371 on256 = NULL;
02372 delete tree;
02373 delete [] cmdStr;
02374 }
02375
02376 int AtomSel::change(const char *newcmd, DrawMolecule *mol) {
02377 if (newcmd) {
02378 ParseTree *newtree = table->parse(newcmd);
02379 if (!newtree) {
02380 return NO_PARSE;
02381 }
02382 delete [] cmdStr;
02383 cmdStr = stringdup(newcmd);
02384 delete tree;
02385 tree = newtree;
02386 }
02387
02388
02389 atomsel_ctxt context(table, mol, which_frame, NULL);
02390
02391
02392 if (num_atoms != mol->nAtoms || (on == NULL)) {
02393 if (on) delete [] on;
02394 on = new int[mol->nAtoms];
02395 num_atoms = mol->nAtoms;
02396 }
02397
02398 tree->use_context(&context);
02399 int rc = tree->evaluate(mol->nAtoms, on);
02400
02401
02402 int ret_code = rc ? PARSE_SUCCESS : NO_EVAL;
02403
02404
02405
02406 selected = 0;
02407 firstsel = 0;
02408 lastsel = -1;
02409
02410
02411 if (analyze_selection_aligned_dispatch(app->cpucaps, num_atoms, on, &firstsel, &lastsel, &selected))
02412 return ret_code;
02413
02414 #if 0
02415
02416 num_atoms256 = num_atoms >> 8;
02417 if (on256) delete [] on256;
02418 on256 = new unsigned int[num_atoms256];
02419
02420 int firstblk = firstsel >> 8;
02421 int lastblk = lastsel >> 8;
02422 for (int blk=firstblk; blk<=lastblk; blk++) {
02423
02424 int firstatom = blk << 8;
02425 int lastatom = ((blk+1) << 8) - 1;
02426 int blkcnt = 0;
02427 int i=0;
02428
02429 on256 = 0;
02430 for (i=firstatom; i<=lastatom; i++) {
02431 if (on[i]) {
02432
02433
02434 on256[blk] = 1 << 24;
02435
02436 break;
02437 }
02438 }
02439
02440 #if 0
02441
02442
02443
02444
02445
02446
02447
02448
02449
02450 on[i] |= (i & 0xFF) << 8;
02451 for (; i<=lastatom; i++) {
02452 if (on[i]) {
02453 blkcnt++;
02454 }
02455 }
02456 on[i] |= (i & 0xFF) << 16;
02457 on[i] |= (blkcnt & 0xFF);
02458 #endif
02459
02460 }
02461 #endif
02462
02463 return ret_code;
02464 }
02465
02466
02467
02468 float *AtomSel::coordinates(MoleculeList *mlist) const {
02469 Timestep *ts = timestep(mlist);
02470 if (ts) return ts->pos;
02471 return NULL;
02472 }
02473
02474
02475
02476 Timestep *AtomSel::timestep(MoleculeList *mlist) const {
02477 DrawMolecule *mymol = mlist->mol_from_id(molid());
02478
02479 if (!mymol) {
02480 msgErr << "No molecule" << sendmsg;
02481 return NULL;
02482 }
02483
02484 switch (which_frame) {
02485 case TS_LAST:
02486 return mymol->get_last_frame();
02487
02488 case TS_NOW:
02489 return mymol->current();
02490
02491 default:
02492
02493 if (!mymol->get_frame(which_frame)) {
02494 return mymol->get_last_frame();
02495 }
02496 }
02497
02498 return mymol->get_frame(which_frame);
02499 }
02500
02501
02502 int AtomSel::get_frame_value(const char *s, int *val) {
02503 *val = 1;
02504 if (!strcmp(s, "last")) {
02505 *val = TS_LAST;
02506 }
02507 if (!strcmp(s, "first")) {
02508 *val = 0;
02509 }
02510 if (!strcmp(s, "now")) {
02511 *val = TS_NOW;
02512 }
02513 if (*val == 1) {
02514 int new_frame = atoi(s);
02515 *val = new_frame;
02516 if (new_frame < 0) {
02517 return -1;
02518 }
02519 }
02520 return 0;
02521 }