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

MDFF.C

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr
00003  *cr            (C) Copyright 1995-2019 The Board of Trustees of the
00004  *cr                        University of Illinois
00005  *cr                         All Rights Reserved
00006  *cr
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  * RCS INFORMATION:
00011  *
00012  *      $RCSfile: MDFF.C,v $
00013  *      $Author: johns $        $Locker:  $             $State: Exp $
00014  *      $Revision: 1.15 $      $Date: 2019/01/17 21:38:55 $
00015  *
00016  ***************************************************************************
00017  * DESCRIPTION:
00018  *   Multi-core CPU versions of MDFF functions
00019  *
00020  * "GPU-Accelerated Analysis and Visualization of Large Structures
00021  *  Solved by Molecular Dynamics Flexible Fitting"
00022  *  John E. Stone, Ryan McGreevy, Barry Isralewitz, and Klaus Schulten.
00023  *  Faraday Discussion 169, 2014. (In press)
00024  *  Online full text available at http://dx.doi.org/10.1039/C4FD00005F
00025  * 
00026  ***************************************************************************/
00027 
00028 #include "AtomSel.h"
00029 #include "VMDApp.h"
00030 #include "MoleculeList.h"
00031 #include "Molecule.h"
00032 #include "VolumetricData.h"
00033 #include "VolMapCreate.h"
00034 #include "QuickSurf.h"
00035 #include <math.h>
00036 #include "MDFF.h"
00037 #include "Voltool.h"
00038 #include <stdio.h>
00039 typedef struct{
00040   double mapA_sum;
00041   double mapB_sum;
00042   double mapA_ss;
00043   double mapB_ss;
00044   double cc;
00045   int size;
00046   const VolumetricData *targetVol;
00047   float *volmap;
00048   const int *numvoxels;
00049   VolumetricData *qsVol;
00050   VolumetricData *newvol;
00051   double threshold;
00052   wkf_mutex_t mtx;
00053 } ccparms;
00054 
00055 static void * correlationthread(void *voidparms) {
00056   wkf_tasktile_t tile;
00057   ccparms *parms = NULL;
00058   wkf_threadlaunch_getdata(voidparms, (void **) &parms);
00059   double lmapA_sum = 0.0f;
00060   double lmapB_sum = 0.0f;
00061   double lmapA_ss = 0.0f;
00062   double lmapB_ss = 0.0f;
00063   double lcc = 0.0f;
00064   int lsize = 0;
00065   while (wkf_threadlaunch_next_tile(voidparms, 16384, &tile) != WKF_SCHED_DONE) { 
00066     int x;
00067     for (x=tile.start; x<tile.end; x++) {
00068       float ix,iy,iz;
00069       voxel_coord(x, ix, iy, iz, parms->newvol);     
00070       float voxelA = parms->qsVol->voxel_value_interpolate_from_coord(ix,iy,iz);
00071       float voxelB = parms->targetVol->voxel_value_interpolate_from_coord(ix,iy,iz);
00072       // checks for nans (nans always false when self compared)
00073       if (!myisnan(voxelB) && !myisnan(voxelA)) {
00074             // Should be voxel B? thresholding simulated aren't we?
00075             // Thats why the old style NaN check is there.
00076 //      } else if(voxelB >= parms->threshold) { 
00077         if (voxelA >= parms->threshold) {
00078           lmapA_sum += voxelA;
00079           lmapB_sum += voxelB;
00080           lmapA_ss += voxelA*voxelA;
00081           lmapB_ss += voxelB*voxelB;
00082           lcc += voxelA*voxelB;
00083           lsize++;
00084         }
00085       }
00086     }
00087   }
00088 
00089   wkf_mutex_lock(&parms->mtx); 
00090   parms->mapA_sum += lmapA_sum;
00091   parms->mapB_sum += lmapB_sum;    
00092   parms->mapA_ss += lmapA_ss;
00093   parms->mapB_ss += lmapB_ss;
00094   parms->cc += lcc;
00095   parms->size += lsize;
00096   wkf_mutex_unlock(&parms->mtx);
00097 
00098   return NULL;
00099 }
00100 
00101 
00102 int cc_threaded(VolumetricData *qsVol, const VolumetricData *targetVol, double *cc, double threshold) {
00103   ccparms parms;
00104   memset(&parms, 0, sizeof(parms));
00105   parms.mapA_sum = 0;
00106   parms.mapB_sum = 0;
00107   parms.mapA_ss = 0;
00108   parms.mapB_ss = 0;
00109   parms.cc = 0;
00110   parms.size = 0;
00111   parms.volmap = qsVol->data;
00112   int numvoxels [] = {qsVol->xsize, qsVol->ysize, qsVol->zsize};
00113   parms.numvoxels = numvoxels;
00114   parms.targetVol = targetVol;
00115   parms.qsVol = qsVol;
00116   parms.threshold = threshold;
00117 
00118   int physprocs = wkf_thread_numprocessors();
00119   int maxprocs = physprocs;
00120  
00121 
00122   //get intersection map so we look at all the overlapping voxels
00123   double origin[3] = {0., 0., 0.};
00124   double xaxis[3] = {0., 0., 0.};
00125   double yaxis[3] = {0., 0., 0.};
00126   double zaxis[3] = {0., 0., 0.};
00127   int numvoxelstmp [3] = {0, 0, 0};
00128   float *data = NULL;
00129   VolumetricData *newvol  = new VolumetricData("density map", origin, xaxis, yaxis, zaxis,
00130                                  numvoxelstmp[0], numvoxelstmp[1], numvoxelstmp[2],
00131                                  data);
00132   init_from_intersection(qsVol, targetVol, newvol);
00133   parms.newvol = newvol;
00134   long volsz = newvol->xsize*newvol->ysize*newvol->zsize;
00135   int numprocs = maxprocs; // ever the optimist
00136   wkf_mutex_init(&parms.mtx);
00137   wkf_tasktile_t tile;
00138   tile.start = 0;
00139   tile.end = volsz;
00140   wkf_threadlaunch(numprocs, &parms, correlationthread, &tile);
00141   wkf_mutex_destroy(&parms.mtx);
00142 
00143   int size = parms.size;
00144   double aMean = parms.mapA_sum/size;
00145   double bMean = parms.mapB_sum/size;
00146   double stdA = sqrt(parms.mapA_ss/size - aMean*aMean);
00147   double stdB = sqrt(parms.mapB_ss/size - bMean*bMean);
00148 
00149   *cc = ((parms.cc) - size*aMean*bMean)/(size * stdA * stdB);
00150   return 0;
00151 }
00152 
00153 
00154 

Generated on Thu Apr 18 02:44:48 2024 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002