00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <stdio.h>
00023 #include <stdlib.h>
00024 #include <string.h>
00025 #include <float.h>
00026 #include "Inform.h"
00027 #include "utilities.h"
00028
00029
00030 #include "AtomSel.h"
00031 #include "VMDApp.h"
00032 #include "MoleculeList.h"
00033 #include "VolumetricData.h"
00034 #include "VolMapCreate.h"
00035
00036 #include "CUDAMDFF.h"
00037 #include "MDFF.h"
00038 #include <math.h>
00039 #include <tcl.h>
00040 #include "TclCommands.h"
00041 #include "Measure.h"
00042 #include "MolFilePlugin.h"
00043
00044 #include <iostream>
00045 #include <string>
00046 #include <sstream>
00047 #include "Voltool.h"
00048
00051 void init_from_intersection(VolumetricData *mapA, const VolumetricData *mapB, VolumetricData *newvol) {
00052 int d;
00053
00054
00055
00056
00057
00058 for (d=0; d<3; d++) {
00059 newvol->origin[d] = MAX(mapA->origin[d], mapB->origin[d]);
00060 newvol->xaxis[d] = MAX(MIN(mapA->origin[d]+mapA->xaxis[d], mapB->origin[d]+mapB->xaxis[d]), newvol->origin[d]);
00061 newvol->yaxis[d] = MAX(MIN(mapA->origin[d]+mapA->yaxis[d], mapB->origin[d]+mapB->yaxis[d]), newvol->origin[d]);
00062 newvol->zaxis[d] = MAX(MIN(mapA->origin[d]+mapA->zaxis[d], mapB->origin[d]+mapB->zaxis[d]), newvol->origin[d]);
00063 }
00064
00065 vec_sub(newvol->xaxis, newvol->xaxis, newvol->origin);
00066 vec_sub(newvol->yaxis, newvol->yaxis, newvol->origin);
00067 vec_sub(newvol->zaxis, newvol->zaxis, newvol->origin);
00068
00069 newvol->xsize = (int) MAX(dot_prod(newvol->xaxis,mapA->xaxis)*mapA->xsize/dot_prod(mapA->xaxis,mapA->xaxis), \
00070 dot_prod(newvol->xaxis,mapB->xaxis)*mapB->xsize/dot_prod(mapB->xaxis,mapB->xaxis));
00071 newvol->ysize = (int) MAX(dot_prod(newvol->yaxis,mapA->yaxis)*mapA->ysize/dot_prod(mapA->yaxis,mapA->yaxis), \
00072 dot_prod(newvol->yaxis,mapB->yaxis)*mapB->ysize/dot_prod(mapB->yaxis,mapB->yaxis));
00073 newvol->zsize = (int) MAX(dot_prod(newvol->zaxis,mapA->zaxis)*mapA->zsize/dot_prod(mapA->zaxis,mapA->zaxis), \
00074 dot_prod(newvol->zaxis,mapB->zaxis)*mapB->zsize/dot_prod(mapB->zaxis,mapB->zaxis));
00075
00076 if (newvol->data) delete[] newvol->data;
00077 newvol->data = new float[newvol->gridsize()];
00078 }
00079
00082 void init_from_intersection(VolumetricData *mapA, VolumetricData *mapB, VolumetricData *newvol) {
00083 int d;
00084
00085
00086
00087
00088
00089 for (d=0; d<3; d++) {
00090 newvol->origin[d] = MAX(mapA->origin[d], mapB->origin[d]);
00091 newvol->xaxis[d] = MAX(MIN(mapA->origin[d]+mapA->xaxis[d], mapB->origin[d]+mapB->xaxis[d]), newvol->origin[d]);
00092 newvol->yaxis[d] = MAX(MIN(mapA->origin[d]+mapA->yaxis[d], mapB->origin[d]+mapB->yaxis[d]), newvol->origin[d]);
00093 newvol->zaxis[d] = MAX(MIN(mapA->origin[d]+mapA->zaxis[d], mapB->origin[d]+mapB->zaxis[d]), newvol->origin[d]);
00094 }
00095
00096 vec_sub(newvol->xaxis, newvol->xaxis, newvol->origin);
00097 vec_sub(newvol->yaxis, newvol->yaxis, newvol->origin);
00098 vec_sub(newvol->zaxis, newvol->zaxis, newvol->origin);
00099
00100 newvol->xsize = (int) MAX(dot_prod(newvol->xaxis,mapA->xaxis)*mapA->xsize/dot_prod(mapA->xaxis,mapA->xaxis), \
00101 dot_prod(newvol->xaxis,mapB->xaxis)*mapB->xsize/dot_prod(mapB->xaxis,mapB->xaxis));
00102 newvol->ysize = (int) MAX(dot_prod(newvol->yaxis,mapA->yaxis)*mapA->ysize/dot_prod(mapA->yaxis,mapA->yaxis), \
00103 dot_prod(newvol->yaxis,mapB->yaxis)*mapB->ysize/dot_prod(mapB->yaxis,mapB->yaxis));
00104 newvol->zsize = (int) MAX(dot_prod(newvol->zaxis,mapA->zaxis)*mapA->zsize/dot_prod(mapA->zaxis,mapA->zaxis), \
00105 dot_prod(newvol->zaxis,mapB->zaxis)*mapB->zsize/dot_prod(mapB->zaxis,mapB->zaxis));
00106
00107 if (newvol->data) delete[] newvol->data;
00108 newvol->data = new float[newvol->gridsize()];
00109 }
00110
00111
00114 void init_from_union(VolumetricData *mapA, const VolumetricData *mapB, VolumetricData *newvol) {
00115
00116
00117
00118
00119 vec_zero(newvol->xaxis);
00120 vec_zero(newvol->yaxis);
00121 vec_zero(newvol->zaxis);
00122
00123 int d;
00124 for (d=0; d<3; d++) {
00125 newvol->origin[d] = MIN(mapA->origin[d], mapB->origin[d]);
00126 }
00127 d=0;
00128 newvol->xaxis[d] = MAX(MAX(mapA->origin[d]+mapA->xaxis[d], mapB->origin[d]+mapB->xaxis[d]), newvol->origin[d]);
00129 d=1;
00130 newvol->yaxis[d] = MAX(MAX(mapA->origin[d]+mapA->yaxis[d], mapB->origin[d]+mapB->yaxis[d]), newvol->origin[d]);
00131 d=2;
00132 newvol->zaxis[d] = MAX(MAX(mapA->origin[d]+mapA->zaxis[d], mapB->origin[d]+mapB->zaxis[d]), newvol->origin[d]);
00133
00134 newvol->xaxis[0] -= newvol->origin[0];
00135 newvol->yaxis[1] -= newvol->origin[1];
00136 newvol->zaxis[2] -= newvol->origin[2];
00137
00138 newvol->xsize = (int) MAX(dot_prod(newvol->xaxis,mapA->xaxis)*mapA->xsize/dot_prod(mapA->xaxis,mapA->xaxis), \
00139 dot_prod(newvol->xaxis,mapB->xaxis)*mapB->xsize/dot_prod(mapB->xaxis,mapB->xaxis));
00140 newvol->ysize = (int) MAX(dot_prod(newvol->yaxis,mapA->yaxis)*mapA->ysize/dot_prod(mapA->yaxis,mapA->yaxis), \
00141 dot_prod(newvol->yaxis,mapB->yaxis)*mapB->ysize/dot_prod(mapB->yaxis,mapB->yaxis));
00142 newvol->zsize = (int) MAX(dot_prod(newvol->zaxis,mapA->zaxis)*mapA->zsize/dot_prod(mapA->zaxis,mapA->zaxis), \
00143 dot_prod(newvol->zaxis,mapB->zaxis)*mapB->zsize/dot_prod(mapB->zaxis,mapB->zaxis));
00144
00145 if (newvol->data) delete[] newvol->data;
00146 newvol->data = new float[newvol->gridsize()];
00147 }
00148
00149 void init_from_identity(VolumetricData *mapA, VolumetricData *newvol) {
00150
00151 vec_copy(newvol->origin, mapA->origin);
00152 vec_copy(newvol->xaxis, mapA->xaxis);
00153 vec_copy(newvol->yaxis, mapA->yaxis);
00154 vec_copy(newvol->zaxis, mapA->zaxis);
00155
00156 newvol->xsize = mapA->xsize;
00157 newvol->ysize = mapA->ysize;
00158 newvol->zsize = mapA->zsize;
00159
00160 if (newvol->data) delete[] newvol->data;
00161 newvol->data = new float[newvol->gridsize()];
00162 }
00163
00164
00167 void init_from_union(VolumetricData *mapA, VolumetricData *mapB, VolumetricData *newvol) {
00168
00169
00170
00171
00172 vec_zero(newvol->xaxis);
00173 vec_zero(newvol->yaxis);
00174 vec_zero(newvol->zaxis);
00175
00176 int d;
00177 for (d=0; d<3; d++) {
00178 newvol->origin[d] = MIN(mapA->origin[d], mapB->origin[d]);
00179 }
00180 d=0;
00181 newvol->xaxis[d] = MAX(MAX(mapA->origin[d]+mapA->xaxis[d], mapB->origin[d]+mapB->xaxis[d]), newvol->origin[d]);
00182 d=1;
00183 newvol->yaxis[d] = MAX(MAX(mapA->origin[d]+mapA->yaxis[d], mapB->origin[d]+mapB->yaxis[d]), newvol->origin[d]);
00184 d=2;
00185 newvol->zaxis[d] = MAX(MAX(mapA->origin[d]+mapA->zaxis[d], mapB->origin[d]+mapB->zaxis[d]), newvol->origin[d]);
00186
00187 newvol->xaxis[0] -= newvol->origin[0];
00188 newvol->yaxis[1] -= newvol->origin[1];
00189 newvol->zaxis[2] -= newvol->origin[2];
00190
00191 newvol->xsize = (int) MAX(dot_prod(newvol->xaxis,mapA->xaxis)*mapA->xsize/dot_prod(mapA->xaxis,mapA->xaxis), \
00192 dot_prod(newvol->xaxis,mapB->xaxis)*mapB->xsize/dot_prod(mapB->xaxis,mapB->xaxis));
00193 newvol->ysize = (int) MAX(dot_prod(newvol->yaxis,mapA->yaxis)*mapA->ysize/dot_prod(mapA->yaxis,mapA->yaxis), \
00194 dot_prod(newvol->yaxis,mapB->yaxis)*mapB->ysize/dot_prod(mapB->yaxis,mapB->yaxis));
00195 newvol->zsize = (int) MAX(dot_prod(newvol->zaxis,mapA->zaxis)*mapA->zsize/dot_prod(mapA->zaxis,mapA->zaxis), \
00196 dot_prod(newvol->zaxis,mapB->zaxis)*mapB->zsize/dot_prod(mapB->zaxis,mapB->zaxis));
00197
00198 if (newvol->data) delete[] newvol->data;
00199 newvol->data = new float[newvol->gridsize()];
00200 }
00201
00202 VolumetricData * init_new_volume(){
00203 double origin[3] = {0., 0., 0.};
00204 double xaxis[3] = {0., 0., 0.};
00205 double yaxis[3] = {0., 0., 0.};
00206 double zaxis[3] = {0., 0., 0.};
00207 int numvoxels [3] = {0, 0, 0};
00208 float *data = NULL;
00209 VolumetricData *newvol = new VolumetricData("density map", origin, xaxis, yaxis, zaxis,
00210 numvoxels[0], numvoxels[1], numvoxels[2],
00211 data);
00212 return newvol;
00213 }
00214
00215
00216 int init_new_volume_molecule(VMDApp *app, VolumetricData *newvol, const char *name){
00217 int newvolmolid = app->molecule_new(name,0,1);
00218
00219 app->molecule_add_volumetric(newvolmolid, "density newvol", newvol->origin,
00220 newvol->xaxis, newvol->yaxis, newvol->zaxis, newvol->xsize, newvol->ysize,
00221 newvol->zsize, newvol->data);
00222 app->molecule_set_style("Isosurface");
00223 app->molecule_addrep(newvolmolid);
00224
00225 return newvolmolid;
00226 }
00227
00228
00229 void vol_com(VolumetricData *vol, float *com){
00230 float ix,iy,iz;
00231
00232 vec_zero(com);
00233 double mass = 0.0;
00234
00235 for (int i = 0; i < vol->gridsize(); i++) {
00236 float m = vol->data[i];
00237 vol->voxel_coord(i, ix, iy, iz);
00238 float coord[3] = {ix,iy,iz};
00239 mass = mass+m;
00240 vec_scale(coord, m, coord);
00241 vec_add(com, com, coord);
00242
00243 }
00244
00245 float scale = 1.0f/float(mass);
00246 vec_scale(com, scale, com);
00247 }
00248
00249 void add(VolumetricData *mapA, VolumetricData *mapB, VolumetricData *newvol, bool interp, bool USE_UNION) {
00250
00251
00252
00253
00254
00255 if ( USE_UNION) {
00256
00257 init_from_union(mapA, mapB, newvol);
00258 } else {
00259
00260 init_from_intersection(mapA, mapB, newvol);
00261 }
00262 for (long i=0; i<newvol->gridsize(); i++){
00263 float x, y, z;
00264 newvol->voxel_coord(i, x, y, z);
00265
00266 if (interp) newvol->data[i] = \
00267 mapA->voxel_value_interpolate_from_coord_safe(x,y,z) + \
00268 mapB->voxel_value_interpolate_from_coord_safe(x,y,z);
00269 else newvol->data[i] = \
00270 mapA->voxel_value_from_coord_safe(x,y,z) + \
00271 mapB->voxel_value_from_coord_safe(x,y,z);
00272 }
00273
00274 }
00275
00276 void subtract(VolumetricData *mapA, VolumetricData *mapB, VolumetricData *newvol, bool interp, bool USE_UNION) {
00277
00278
00279
00280
00281
00282 if ( USE_UNION) {
00283
00284 init_from_union(mapA, mapB, newvol);
00285 } else {
00286
00287 init_from_intersection(mapA, mapB, newvol);
00288 }
00289 for (long i=0; i<newvol->gridsize(); i++){
00290 float x, y, z;
00291 newvol->voxel_coord(i, x, y, z);
00292
00293 if (interp) newvol->data[i] = \
00294 mapA->voxel_value_interpolate_from_coord_safe(x,y,z) - \
00295 mapB->voxel_value_interpolate_from_coord_safe(x,y,z);
00296 else newvol->data[i] = \
00297 mapA->voxel_value_from_coord_safe(x,y,z) - \
00298 mapB->voxel_value_from_coord_safe(x,y,z);
00299 }
00300
00301 }
00302
00303 void multiply(VolumetricData *mapA, VolumetricData *mapB, VolumetricData *newvol, bool interp, bool USE_UNION) {
00304
00305
00306
00307
00308
00309 if ( USE_UNION) {
00310
00311 init_from_union(mapA, mapB, newvol);
00312 for (long i=0; i<newvol->gridsize(); i++){
00313 float x, y, z;
00314 float voxelA, voxelB;
00315 newvol->voxel_coord(i, x, y, z);
00316 if (interp) {
00317 voxelA = mapA->voxel_value_interpolate_from_coord(x,y,z);
00318 voxelB = mapB->voxel_value_interpolate_from_coord(x,y,z);
00319 } else {
00320 voxelA = mapA->voxel_value_from_coord(x,y,z);
00321 voxelB = mapB->voxel_value_from_coord(x,y,z);
00322 }
00323
00324 if (!myisnan(voxelA) && !myisnan(voxelB))
00325 newvol->data[i] = voxelA * voxelB;
00326 else if (!myisnan(voxelA) && myisnan(voxelB))
00327 newvol->data[i] = voxelA;
00328 else if (myisnan(voxelA) && !myisnan(voxelB))
00329 newvol->data[i] = voxelB;
00330 else
00331 newvol->data[i] = 0.;
00332 }
00333 } else {
00334
00335 init_from_intersection(mapA, mapB, newvol);
00336
00337 for (long i=0; i<newvol->gridsize(); i++){
00338 float x, y, z;
00339 newvol->voxel_coord(i, x, y, z);
00340
00341 if (interp) newvol->data[i] = \
00342 mapA->voxel_value_interpolate_from_coord(x,y,z) * \
00343 mapB->voxel_value_interpolate_from_coord(x,y,z);
00344 else newvol->data[i] = \
00345 mapA->voxel_value_from_coord(x,y,z) * \
00346 mapB->voxel_value_from_coord(x,y,z);
00347 }
00348
00349 }
00350 }
00351
00352 void average(VolumetricData *mapA, VolumetricData *mapB, VolumetricData *newvol, bool interp, bool USE_UNION) {
00353
00354
00355
00356
00357
00358 if ( USE_UNION) {
00359
00360 init_from_union(mapA, mapB, newvol);
00361 } else {
00362
00363 init_from_intersection(mapA, mapB, newvol);
00364 }
00365 for (long i=0; i<newvol->gridsize(); i++){
00366 float x, y, z;
00367 newvol->voxel_coord(i, x, y, z);
00368
00369 if (interp) newvol->data[i] = \
00370 (mapA->voxel_value_interpolate_from_coord_safe(x,y,z) + \
00371 mapB->voxel_value_interpolate_from_coord_safe(x,y,z))*0.5f;
00372 else newvol->data[i] = \
00373 (mapA->voxel_value_from_coord_safe(x,y,z) + \
00374 mapB->voxel_value_from_coord_safe(x,y,z))*0.5f;
00375 }
00376
00377 }
00378
00379 void vol_moveto(VolumetricData *vol, float *com, float *pos){
00380 float origin[3] = {0.0, 0.0, 0.0};
00381 origin[0] = (float)vol->origin[0];
00382 origin[1] = (float)vol->origin[1];
00383 origin[2] = (float)vol->origin[2];
00384
00385 float transvector[3];
00386 vec_sub(transvector, pos, com);
00387 vec_add(origin, origin, transvector);
00388 vol->origin[0] = origin[0];
00389 vol->origin[1] = origin[1];
00390 vol->origin[2] = origin[2];
00391 }
00392
00393
00394
00395
00396
00397
00398
00399 void vol_move(VolumetricData *vol, float *mat){
00400 float origin[3] = {0.0, 0.0, 0.0};
00401 origin[0] = (float)vol->origin[0];
00402 origin[1] = (float)vol->origin[1];
00403 origin[2] = (float)vol->origin[2];
00404
00405 float transvector[3] = {mat[12], mat[13], mat[14]};
00406
00407 float npoint[3];
00408
00409
00410
00411 npoint[0]=origin[0]*mat[0]+origin[1]*mat[4]+origin[2]*mat[8];
00412 npoint[1]=origin[0]*mat[1]+origin[1]*mat[5]+origin[2]*mat[9];
00413 npoint[2]=origin[0]*mat[2]+origin[1]*mat[6]+origin[2]*mat[10];
00414
00415 vec_add(origin, npoint, transvector);
00416 vol->origin[0] = origin[0];
00417 vol->origin[1] = origin[1];
00418 vol->origin[2] = origin[2];
00419
00420
00421 double deltax[3] = {vol->xaxis[0],vol->xaxis[1],vol->xaxis[2]};
00422 double deltay[3] = {vol->yaxis[0],vol->yaxis[1],vol->yaxis[2]};
00423 double deltaz[3] = {vol->zaxis[0],vol->zaxis[1],vol->zaxis[2]};
00424
00425 float npointx[3];
00426 float npointy[3];
00427 float npointz[3];
00428 vectrans(npointx, mat, deltax);
00429 vectrans(npointy, mat, deltay);
00430 vectrans(npointz, mat, deltaz);
00431
00432 for (int i = 0; i<3; i++){
00433 vol->xaxis[i] = npointx[i];
00434 vol->yaxis[i] = npointy[i];
00435 vol->zaxis[i] = npointz[i];
00436 }
00437
00438 }
00439
00443 void histogram( VolumetricData *vol, int nbins, long *bins, float *midpts) {
00444
00445 float min, max;
00446 vol->datarange(min, max);
00447
00448 double binwidth = (max-min)/nbins;
00449
00450 double binwidthinv = 1/binwidth;
00451
00452
00453 memset(bins, 0, nbins*sizeof(long));
00454
00455
00456 for (long i=0; i<vol->gridsize(); i++)
00457 bins[long((vol->data[i]-min)*binwidthinv)]++;
00458
00459 for (int j = 0; j < nbins; j++)
00460 midpts[j] = float(min + (0.5f*binwidth) + (j*binwidth));
00461 }
00462
00464 int write_file(VMDApp *app, Molecule *volmol, int volid, const char* filename) {
00465
00466
00467
00468
00469 char* ext = (char *)strrchr(filename, '.');
00470
00471
00472
00473
00474
00475 ext = &ext[1];
00476
00477 vmdplugin_t *p = app->get_plugin("mol file reader", ext);
00478
00479 if (!p) {
00480 p = app->get_plugin("mol file converter", ext);
00481 }
00482
00483 MolFilePlugin *plugin = NULL;
00484
00485 if (p) {
00486 plugin = new MolFilePlugin(p);
00487 }
00488
00489 if (plugin != NULL){
00490 int natom = 0;
00491 int filehandler = plugin->init_write(filename, natom);
00492 if (filehandler == MOLFILE_ERROR) {
00493 return 0;
00494 }
00495
00496 plugin->write_volumetric(volmol, volid);
00497 }
00498
00499 return 1;
00500
00501 }