00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <tcl.h>
00028 #include "TclCommands.h"
00029 #include "AtomSel.h"
00030 #include "VMDApp.h"
00031 #include "MoleculeList.h"
00032 #include "Molecule.h"
00033 #include "VolumetricData.h"
00034 #include "VolMapCreate.h"
00035 #include "QuickSurf.h"
00036 #include <math.h>
00037 #include "MeasureVolInterior.h"
00038 #include "utilities.h"
00039
00040 #include <sstream>
00041 #include <string>
00042
00043 #define MIN(X,Y) (((X)<(Y))? (X) : (Y))
00044
00045 typedef struct{
00046 const VolumetricData *volmapA;
00047 VolumetricData *targetVol;
00048 VolumetricData *pmap;
00049 float *targetPmap;
00050 float *targetMap;
00051 const float *testMap;
00052 const int *numvoxels;
00053 float isovalue;
00054 wkf_mutex_t mtx;
00055 const float *rayDir;
00056 long Nout;
00057 } volinparms;
00058
00059
00060 static void * volinthread_prob(void *voidparms) {
00061 wkf_tasktile_t tile;
00062 volinparms *parms = NULL;
00063 wkf_threadlaunch_getdata(voidparms, (void **) &parms);
00064
00065 int gx,gy,gz;
00066 long Nout=0l;
00067 while (wkf_threadlaunch_next_tile(voidparms, 16384, &tile) != WKF_SCHED_DONE) {
00068 int myx;
00069 int xsize = parms->numvoxels[0];
00070 int ysize = parms->numvoxels[1];
00071 int xysize = ysize*xsize;
00072 for (myx=tile.start; myx<tile.end; myx++) {
00073 gz = myx / (xysize);
00074 gy = (myx % (xysize)) / xsize;
00075 gx = myx % xsize;
00076
00077
00078 float voxelA = parms->targetMap[myx];
00079 if (voxelA != PROTEINVOXEL) {
00080 int coord[3] = {gx, gy, gz};
00081 int step[3];
00082 float rayOrig[3] = {gx + 0.5f, gy + 0.5f, gz + 0.5f};
00083 float deltaDist[3];
00084 float next[3];
00085
00086 for (int ii = 0; ii < 3; ii++) {
00087
00088
00089
00090
00091
00092
00093
00094
00095 const float x = (parms->rayDir[ii] != 0.0f) ? (parms->rayDir[0] / parms->rayDir[ii]) : parms->rayDir[0];
00096 const float y = (parms->rayDir[ii] != 0.0f) ? (parms->rayDir[1] / parms->rayDir[ii]) : parms->rayDir[1];
00097 const float z = (parms->rayDir[ii] != 0.0f) ? (parms->rayDir[2] / parms->rayDir[ii]) : parms->rayDir[2];
00098 deltaDist[ii] = sqrtf(x*x + y*y + z*z);
00099 if (parms->rayDir[ii] < 0.f) {
00100 step[ii] = -1;
00101 next[ii] = (rayOrig[ii] - coord[ii]) * deltaDist[ii];
00102 } else {
00103 step[ii] = 1;
00104 next[ii] = (coord[ii] + 1.f - rayOrig[ii]) * deltaDist[ii];
00105 }
00106 }
00107
00108 int hit=0;
00109 while(hit==0) {
00110
00111 int side=0;
00112 for (int ii=1; ii < 3; ii++) {
00113 if (next[side] > next[ii]) {
00114 side=ii;
00115 }
00116 }
00117 next[side] += deltaDist[side];
00118 coord[side] += step[side];
00119
00120
00121 if (coord[side] < 0 || coord[side] >= parms->numvoxels[side] ) {
00122
00123 Nout+=1l;
00124 break;
00125 }
00126
00127
00128 if (parms->testMap[coord[2]*xysize + coord[1]*xsize + coord[0]] >= parms->isovalue) {
00129 hit=1;
00130 parms->targetPmap[myx] += 1.0f;
00131 }
00132 }
00133 }
00134 }
00135 }
00136
00137
00138
00139 wkf_mutex_lock(&parms->mtx);
00140 parms->Nout += Nout;
00141 wkf_mutex_unlock(&parms->mtx);
00142
00143 return NULL;
00144 }
00145
00146
00147 static void * volinthread(void *voidparms) {
00148 wkf_tasktile_t tile;
00149 volinparms *parms = NULL;
00150 wkf_threadlaunch_getdata(voidparms, (void **) &parms);
00151
00152 int gx,gy,gz;
00153 long Nout=0l;
00154 while (wkf_threadlaunch_next_tile(voidparms, 16384, &tile) != WKF_SCHED_DONE) {
00155 int myx;
00156 int xsize = parms->numvoxels[0];
00157 int ysize = parms->numvoxels[1];
00158 int xysize = ysize*xsize;
00159 for (myx=tile.start; myx<tile.end; myx++) {
00160 gz = myx / (xysize);
00161 gy = (myx % (xysize)) / xsize;
00162 gx = myx % xsize;
00163
00164
00165
00166 float voxelA = parms->targetMap[myx];
00167 if (voxelA != EXTERIORVOXEL) {
00168 int coord[3] = {gx, gy, gz};
00169 int step[3];
00170 float rayOrig[3] = {gx + 0.5f, gy + 0.5f, gz + 0.5f} ;
00171 float deltaDist[3];
00172 float next[3];
00173
00174 for (int ii = 0; ii < 3; ii++) {
00175
00176
00177
00178
00179
00180
00181
00182
00183 const float x = (parms->rayDir[ii] != 0.0f) ? (parms->rayDir[0] / parms->rayDir[ii]) : parms->rayDir[0];
00184 const float y = (parms->rayDir[ii] != 0.0f) ? (parms->rayDir[1] / parms->rayDir[ii]) : parms->rayDir[1];
00185 const float z = (parms->rayDir[ii] != 0.0f) ? (parms->rayDir[2] / parms->rayDir[ii]) : parms->rayDir[2];
00186 deltaDist[ii] = sqrtf(x*x + y*y + z*z);
00187 if (parms->rayDir[ii] < 0.f) {
00188 step[ii] = -1;
00189 next[ii] = (rayOrig[ii] - coord[ii]) * deltaDist[ii];
00190 } else {
00191 step[ii] = 1;
00192 next[ii] = (coord[ii] + 1.f - rayOrig[ii]) * deltaDist[ii];
00193 }
00194 }
00195
00196 int hit=0;
00197 while(hit==0) {
00198
00199 int side=0;
00200 for (int ii=1; ii < 3; ii++) {
00201 if (next[side] > next[ii]) {
00202 side=ii;
00203 }
00204 }
00205 next[side] += deltaDist[side];
00206 coord[side] += step[side];
00207
00208
00209 if (coord[side] < 0 || coord[side] >= parms->numvoxels[side] ) {
00210 parms->targetMap[myx]=EXTERIORVOXEL;
00211 Nout+=1l;
00212 break;
00213 }
00214
00215
00216 if (parms->testMap[coord[2]*xysize + coord[1]*xsize + coord[0]] >= parms->isovalue) {
00217 hit=1;
00218 }
00219 }
00220 }
00221 }
00222 }
00223
00224
00225
00226 wkf_mutex_lock(&parms->mtx);
00227 parms->Nout += Nout;
00228 wkf_mutex_unlock(&parms->mtx);
00229
00230 return NULL;
00231 }
00232
00233
00234 long volin_threaded_prob(const VolumetricData *volmapA, VolumetricData *targetVol,
00235 VolumetricData *targetPvol, float _isovalue, float *rayDir) {
00236 volinparms parms;
00237 memset(&parms, 0, sizeof(parms));
00238 parms.testMap = volmapA->data;
00239 parms.targetMap = targetVol->data;
00240 parms.targetPmap = targetPvol->data;
00241 int numvoxels [] = {volmapA->xsize, volmapA->ysize, volmapA->zsize};
00242 parms.numvoxels = numvoxels;
00243 parms.targetVol = targetVol;
00244 parms.volmapA = volmapA;
00245 parms.isovalue = _isovalue;
00246 parms.rayDir = rayDir;
00247 parms.Nout=0;
00248
00249 long Nout;
00250 int physprocs = wkf_thread_numprocessors();
00251 int maxprocs = physprocs;
00252 float *voltexmap = NULL;
00253
00254
00255
00256
00257
00258
00259
00260
00261 while (maxprocs > 40)
00262 maxprocs /= 2;
00263
00264
00265
00266
00267
00268
00269 long volsz = numvoxels[0] * numvoxels[1] * numvoxels[2];
00270 long volmemsz = sizeof(float) * volsz;
00271 long volmemszkb = volmemsz / 1024;
00272 long volmemtexszkb = volmemszkb + ((voltexmap != NULL) ? 3*volmemszkb : 0);
00273
00274
00275
00276
00277 long vmdcorefree = -1;
00278
00279 #if defined(ARCH_BLUEWATERS) || defined(ARCH_CRAY_XC) || defined(ARCH_CRAY_XK) || defined(ARCH_LINUXAMD64) || defined(ARCH_SOLARIS2_64) || defined(ARCH_SOLARISX86_64) || defined(ARCH_AIX6_64) || defined(ARCH_MACOSXARM64) || defined(ARCH_MACOSXX86_64)
00280
00281
00282
00283
00284
00285
00286 vmdcorefree = vmd_get_avail_physmem_mb();
00287 #endif
00288
00289 if (vmdcorefree >= 0) {
00290
00291
00292
00293
00294 while ((volmemtexszkb * maxprocs) > (1024*vmdcorefree/4)) {
00295 maxprocs /= 2;
00296 }
00297 } else {
00298
00299 while ((volmemtexszkb * maxprocs) > (2 * 1024 * 1024))
00300 maxprocs /= 2;
00301 }
00302
00303 if (maxprocs < 1)
00304 maxprocs = 1;
00305 int numprocs = maxprocs;
00306 wkf_mutex_init(&parms.mtx);
00307 wkf_tasktile_t tile;
00308 tile.start = 0;
00309 tile.end = volsz;
00310 wkf_threadlaunch(numprocs, &parms, volinthread_prob, &tile);
00311 wkf_mutex_destroy(&parms.mtx);
00312 Nout=parms.Nout;
00313
00314 return Nout;
00315 }
00316
00317
00318 long volin_threaded(const VolumetricData *volmapA, VolumetricData *targetVol,
00319 float _isovalue, float *rayDir) {
00320 volinparms parms;
00321 memset(&parms, 0, sizeof(parms));
00322 parms.testMap = volmapA->data;
00323 parms.targetMap = targetVol->data;
00324 int numvoxels [] = {volmapA->xsize, volmapA->ysize, volmapA->zsize};
00325 parms.numvoxels = numvoxels;
00326 parms.targetVol = targetVol;
00327 parms.volmapA = volmapA;
00328 parms.isovalue = _isovalue;
00329 parms.rayDir = rayDir;
00330 parms.Nout=0;
00331
00332 long Nout;
00333 int physprocs = wkf_thread_numprocessors();
00334 int maxprocs = physprocs;
00335 float *voltexmap = NULL;
00336
00337
00338
00339
00340
00341
00342
00343
00344 while (maxprocs > 40)
00345 maxprocs /= 2;
00346
00347
00348
00349
00350
00351
00352 long volsz = numvoxels[0] * numvoxels[1] * numvoxels[2];
00353 long volmemsz = sizeof(float) * volsz;
00354 long volmemszkb = volmemsz / 1024;
00355 long volmemtexszkb = volmemszkb + ((voltexmap != NULL) ? 3*volmemszkb : 0);
00356
00357
00358
00359
00360 long vmdcorefree = -1;
00361
00362 #if defined(ARCH_BLUEWATERS) || defined(ARCH_CRAY_XC) || defined(ARCH_CRAY_XK) || defined(ARCH_LINUXAMD64) || defined(ARCH_SOLARIS2_64) || defined(ARCH_SOLARISX86_64) || defined(ARCH_AIX6_64) || defined(MARCOSXARM64) || defined(ARCH_MACOSXX86_64)
00363
00364
00365
00366
00367
00368
00369 vmdcorefree = vmd_get_avail_physmem_mb();
00370 #endif
00371
00372 if (vmdcorefree >= 0) {
00373
00374
00375
00376
00377 while ((volmemtexszkb * maxprocs) > (1024*vmdcorefree/4)) {
00378 maxprocs /= 2;
00379 }
00380 } else {
00381
00382 while ((volmemtexszkb * maxprocs) > (2 * 1024 * 1024))
00383 maxprocs /= 2;
00384 }
00385
00386 if (maxprocs < 1)
00387 maxprocs = 1;
00388 int numprocs = maxprocs;
00389 wkf_mutex_init(&parms.mtx);
00390 wkf_tasktile_t tile;
00391 tile.start = 0;
00392 tile.end = volsz;
00393 wkf_threadlaunch(numprocs, &parms, volinthread, &tile);
00394 wkf_mutex_destroy(&parms.mtx);
00395 Nout=parms.Nout;
00396
00397 return Nout;
00398 }
00399
00400
00401 VolumetricData* CreateEmptyGrid(const VolumetricData *volmapA) {
00402 VolumetricData *targetVol;
00403 float *volmap;
00404
00405 long volsz=volmapA->xsize * volmapA->ysize * volmapA->zsize;
00406
00407 volmap = new float[volsz];
00408
00409 memset(volmap, 0, sizeof(float)*volsz);
00410
00411
00412 targetVol = new VolumetricData("inout map", volmapA->origin,
00413 volmapA->xaxis, volmapA->yaxis, volmapA->zaxis,
00414 volmapA->xsize, volmapA->ysize, volmapA->zsize,
00415 volmap);
00416 return targetVol;
00417 }
00418
00419
00420 VolumetricData* CreateProbGrid(const VolumetricData *volmapA) {
00421 VolumetricData *targetPvol;
00422 float *volmap;
00423
00424 long volsz=volmapA->xsize * volmapA->ysize * volmapA->zsize;
00425
00426 volmap = new float[volsz];
00427
00428 memset(volmap, 0, sizeof(float)*volsz);
00429
00430
00431 targetPvol = new VolumetricData("P(in) map", volmapA->origin,
00432 volmapA->xaxis, volmapA->yaxis, volmapA->zaxis,
00433 volmapA->xsize, volmapA->ysize, volmapA->zsize,
00434 volmap);
00435 return targetPvol;
00436 }
00437
00438
00439 VolumetricData* normalize_pmap(const VolumetricData *volmapA, int nrays) {
00440 long gridsz = volmapA->gridsize();
00441 const float* map = volmapA->data;
00442 float *volmap;
00443
00444 VolumetricData *targetPmap;
00445
00446 long volsz = volmapA->xsize * volmapA->ysize * volmapA->zsize;
00447 volmap = new float[volsz];
00448 memset(volmap, 0, sizeof(float)*volsz);
00449
00450 float nrays_inv = 1.0f / float(nrays);
00451 for (long l=0; l<gridsz; l++) {
00452 volmap[l] = map[l] * nrays_inv;
00453 }
00454
00455 targetPmap = new VolumetricData("P(in) map", volmapA->origin,
00456 volmapA->xaxis, volmapA->yaxis, volmapA->zaxis,
00457 volmapA->xsize, volmapA->ysize, volmapA->zsize,
00458 volmap);
00459 return targetPmap;
00460 }
00461
00462
00463 void VolIn_CleanGrid(VolumetricData *volmapA) {
00464 long volsz=volmapA->xsize * volmapA->ysize * volmapA->zsize;
00465 memset(volmapA->data, 0, sizeof(float)*volsz);
00466 }
00467
00468
00469 long countIsoGrids(const VolumetricData *volmapA, const float _isovalue) {
00470 long volInIso=0;
00471 long gridsize = volmapA->gridsize();
00472 const float* map=volmapA->data;
00473
00474 for (long l=0; l<gridsize; l++) {
00475 if (map[l] == _isovalue) volInIso += 1;
00476 }
00477
00478 return volInIso;
00479 }
00480
00481
00482 long markIsoGrid(const VolumetricData *volmapA, VolumetricData *targetVol,
00483 const float _isovalue) {
00484 long nVoxels=0;
00485
00486 long gridsize = volmapA->gridsize();
00487 const float *map=volmapA->data;
00488 float* targetmap=targetVol->data;
00489
00490 for (long l=0; l<gridsize; l++) {
00491 if (map[l] >= _isovalue) {
00492 targetmap[l]=PROTEINVOXEL;
00493 nVoxels+=1;
00494 }
00495 }
00496
00497 return nVoxels;
00498 }
00499
00500
00501 long RaycastGrid(const VolumetricData *volmapA, VolumetricData *targetVol,
00502 float _isovalue, float *rayDir) {
00503 int volDimens[3];
00504
00505
00506 float *map=targetVol->data;
00507 volDimens[0]=volmapA->xsize;
00508 volDimens[1]=volmapA->ysize;
00509 volDimens[2]=volmapA->zsize;
00510
00511 float isovalue=_isovalue;
00512
00513
00514 for (int k=0; k < volDimens[2]; k++) {
00515 for (int j=0; j < volDimens[1]; j++) {
00516 long voxrowaddr = k*volDimens[0]*volDimens[1] + j*volDimens[0];
00517 for (int i=0; i < volDimens[0]; i++) {
00518 long voxeladdr = voxrowaddr + i;
00519 if (map[voxeladdr] != EXTERIORVOXEL) {
00520 float deltaDist[3];
00521 float next[3];
00522 int coord[3] = { i,j,k };
00523 int step[3];
00524 float rayOrig[3] = { i + 0.5f , j + 0.5f , k + 0.5f } ;
00525
00526 for (int ii = 0; ii < 3; ii++) {
00527 const float x = (rayDir[0] / rayDir[ii]);
00528 const float y = (rayDir[1] / rayDir[ii]);
00529 const float z = (rayDir[2] / rayDir[ii]);
00530 deltaDist[ii] = sqrtf(x*x + y*y + z*z);
00531 if (rayDir[ii] < 0.f) {
00532 step[ii] = -1;
00533 next[ii] = (rayOrig[ii] - coord[ii]) * deltaDist[ii];
00534 } else {
00535 step[ii] = 1;
00536 next[ii] = (coord[ii] + 1.f - rayOrig[ii]) * deltaDist[ii];
00537 }
00538 }
00539
00540 int hit=0;
00541 while (hit==0) {
00542
00543 int side=0;
00544 for (int ii=1; ii<3; ii++) {
00545 if (next[side] > next[ii]) {
00546 side=ii;
00547 }
00548 }
00549 next[side] += deltaDist[side];
00550 coord[side] += step[side];
00551
00552
00553 if (coord[side] < 0 || coord[side] >= volDimens[side] ) {
00554 map[voxeladdr]=EXTERIORVOXEL;
00555 break;
00556 }
00557
00558
00559 if (volmapA->data[coord[2]*volDimens[0]*volDimens[1] + coord[1]*volDimens[0] + coord[0]] > isovalue) {
00560 hit=1;
00561 }
00562 }
00563 }
00564 }
00565 }
00566 }
00567
00568 return 0;
00569 }
00570
00571
00572 VolumetricData* process_pmap (const VolumetricData *pmap, float cutoff) {
00573 long gridsz=pmap->gridsize();
00574 const float* map=pmap->data;
00575 float *volmap;
00576
00577 VolumetricData *targetPmap;
00578
00579 long volsz = pmap->xsize*pmap->ysize*pmap->zsize;
00580 volmap = new float[volsz];
00581 memset(volmap, 0, sizeof(float)*volsz);
00582
00583 for (long l=0; l<gridsz; l++) {
00584 if (map[l]==0.0f) {
00585 volmap[l]=PROTEINVOXEL;
00586 } else if ((map[l]-cutoff) >= VOLMAPTOLERANCE) {
00587 volmap[l]=INTERIORVOXEL;
00588 } else if ((map[l]-cutoff) <= VOLMAPTOLERANCE) {
00589 volmap[l]=EXTERIORVOXEL;
00590 }
00591 }
00592
00593 targetPmap = new VolumetricData("ProcMap", pmap->origin,
00594 pmap->xaxis, pmap->yaxis, pmap->zaxis,
00595 pmap->xsize, pmap->ysize, pmap->zsize,
00596 volmap);
00597
00598 return targetPmap;
00599 }
00600
00601
00602 long vol_probability(const VolumetricData* probmap, float cutoff, float gspace) {
00603 long Nvox=0;
00604 long gridsz=probmap->gridsize();
00605 const float* map=probmap->data;
00606
00607 for (long l=0; l<gridsz; l++) {
00608 if (map[l] >= cutoff) {
00609 Nvox++;
00610 }
00611 }
00612 return Nvox;
00613 }
00614
00615
00616 bool isfloat(char* opt) {
00617 std::istringstream iss(opt);
00618 float f;
00619 iss >> std::noskipws >> f;
00620 return iss.eof() && !iss.fail();
00621 }
00622
00623