00001
00055 #include "apbscfg.h"
00056 #include "apbs/apbs.h"
00057
00058 VEMBED(rcsid="$Id: analysis.c 1552 2010-02-10 17:46:27Z yhuang01 $")
00059
00060
00064 void usage(int rc) {
00065 char *usage = "\n\
00066 A program to calculate various metrics for a scalar field\n\
00067 Usage: analysis <req args> [opts]\n\
00068 where <req args> are the required arguments:\n\
00069 --format=<format> The input file format. Acceptable values include\n\
00070 dx OpenDX format\n\
00071 --scalar=<path> The path to the scalar data file\n\
00072 and where [opts] are the options:\n\
00073 --help Print this message\n\
00074 --mask=<path> A file with scalar values specifying a \"mask\" or\n\
00075 characteristic function for the similarity calculation. This file\n\
00076 contains values between 1 and 0 which are multiplied against the\n\
00077 scalar data set analysis calculations are performed.\n\
00078 \n";
00079
00080 Vnm_print(2, usage);
00081 exit(rc);
00082 }
00083
00090 int readGrid(Vgrid **grid, char *path, Vdata_Format format) {
00091
00092 *grid = Vgrid_ctor(0, 0, 0,
00093 0.0, 0.0, 0.0,
00094 0.0, 0.0, 0.0,
00095 VNULL);
00096
00097 switch (format) {
00098 case VDF_DX:
00099 return Vgrid_readDX(*grid, "FILE", "ASC", VNULL, path);
00100 break;
00101 case VDF_UHBD:
00102 Vnm_print(2, "Sorry, UHBD input not supported yet!\n");
00103 return 0;
00104 break;
00105 case VDF_AVS:
00106 Vnm_print(2, "Sorry, AVS input not supported yet!\n");
00107 return 0;
00108 break;
00109 default:
00110 Vnm_print(2, "Unknown data format (%d)!\n", format);
00111 return 0;
00112 }
00113
00114 return 1;
00115 }
00116
00117 int main(int argc, char **argv) {
00118
00119
00120 int i, j, k, onGridS, onGridV, nx, ny, nz;
00121 double hx, hy, hzed, xmin, ymin, zmin, dvol, svol, gvol;
00122 double norm_L1, norm_L2, snorm_H1, norm_H1, norm_Linf;
00123 double maxS, maxSpt[3], maxG2, maxG2pt[3];
00124 double minS, minSpt[3], minG2, minG2pt[3];
00125 int haveMaxS, haveMaxG2, haveMinS, haveMinG2;
00126 double val, sval, mval, pt[3];
00127 double gval2, gval[3];
00128 Vgrid *scalar, *mask;
00129 char scalarPath[VMAX_ARGLEN];
00130 int gotScalar = 0;
00131 char maskPath[VMAX_ARGLEN];
00132 int gotMask = 0;
00133 Vdata_Format format;
00134 int gotFormat = 0;
00135 char *tstr, *targ;
00136
00137
00138 Vio_start();
00139
00140 for (i=1; i<argc; i++) {
00141 targ = argv[i];
00142
00143 tstr = strstr(targ, "format");
00144 if (tstr != NULL) {
00145 tstr = tstr + 7;
00146 if (strcmp(tstr, "dx") == 0) {
00147 format = VDF_DX;
00148 gotFormat = 1;
00149 } else {
00150 Vnm_print(2, "Error! Unknown format (%s)!\n", tstr);
00151 usage(2);
00152 }
00153 }
00154
00155 tstr = strstr(targ, "scalar");
00156 if (tstr != NULL) {
00157 tstr = tstr + 7;
00158 strncpy(scalarPath, tstr, VMAX_ARGLEN);
00159 gotScalar = 1;
00160 }
00161
00162 tstr = strstr(targ, "help");
00163 if (tstr != NULL) usage(0);
00164
00165 tstr = strstr(targ, "mask");
00166 if (tstr != NULL) {
00167 tstr = tstr + 5;
00168 strncpy(maskPath, tstr, VMAX_ARGLEN);
00169 gotMask = 1;
00170 }
00171 }
00172
00173 if (!gotFormat) {
00174 Vnm_print(2, "Error! --format not specified!\n");
00175 usage(2);
00176 } else {
00177 switch (format) {
00178 case VDF_DX:
00179 Vnm_print(1, "format: OpenDX\n");
00180 break;
00181 case VDF_UHBD:
00182 Vnm_print(1, "format: UHBD\n");
00183 break;
00184 case VDF_AVS:
00185 Vnm_print(1, "format: AVS\n");
00186 break;
00187 default:
00188 Vnm_print(2, "Error! Unknown format (%d)!\n", format);
00189 usage(2);
00190 }
00191 }
00192 if (!gotScalar) {
00193 Vnm_print(2, "Error! --scalar not specified!\n");
00194 usage(2);
00195 } else {
00196 Vnm_print(1, "Data set: %s\n", scalarPath);
00197 }
00198 if (gotMask) {
00199 Vnm_print(1, "Mask: %s\n", maskPath);
00200 }
00201
00202
00203 Vnm_print(1, "Reading scalar data set from %s...\n", scalarPath);
00204 if (!readGrid(&scalar, scalarPath, format)) {
00205 Vnm_print(2, "Error reading scalar data set!\n");
00206 return 2;
00207 }
00208 Vnm_print(1, "Read %d x %d x %d grid.\n",
00209 scalar->nx, scalar->ny, scalar->nz);
00210
00211
00212 if (gotMask) {
00213 Vnm_print(1, "Reading mask data set from %s...\n", maskPath);
00214 if (!readGrid(&mask, maskPath, format)) {
00215 Vnm_print(2, "Error reading mask data set!\n");
00216 return 2;
00217 }
00218 Vnm_print(1, "Read %d x %d x %d grid.\n",
00219 mask->nx, mask->ny, mask->nz);
00220 }
00221
00222
00223 Vnm_print(1, "Calculating metrics...\n");
00224 nx = scalar->nx; ny = scalar->ny; nz = scalar->nz;
00225 hx = scalar->hx; hy = scalar->hy; hzed = scalar->hzed;
00226 dvol = (hx*hy*hzed);
00227 xmin = scalar->xmin; ymin = scalar->ymin; zmin = scalar->zmin;
00228 norm_L1 = 0; norm_L2 = 0; snorm_H1 = 0; norm_H1 = 0;
00229 haveMaxS = 0; haveMinS = 0; haveMaxG2 = 0; haveMinG2 = 0;
00230 svol = 0; gvol = 0;
00231 for (i=0; i<nx; i++) {
00232 pt[0] = i*hx + xmin;
00233 for (j=0; j<ny; j++) {
00234 pt[1] = j*hy + ymin;
00235 for (k=0; k<nz; k++) {
00236
00237
00238 pt[2] = k*hzed + zmin;
00239 onGridS = Vgrid_value(scalar, pt, &sval);
00240 onGridV = Vgrid_gradient(scalar, pt, gval);
00241 if (onGridV) {
00242 gval2 = 0.0;
00243 gval2 = VSQR(gval[0]) + VSQR(gval[1]) + VSQR(gval[2]);
00244 } else gval2 = 0.0;
00245 if (gotMask) onGridS = Vgrid_value(mask, pt, &mval);
00246 else mval = 1.0;
00247
00248
00249 if (mval > 0) {
00250 if ((!haveMaxS) || (sval > maxS) ) {
00251 haveMaxS = 1;
00252 maxS = sval;
00253 maxSpt[0] = pt[0];
00254 maxSpt[1] = pt[1];
00255 maxSpt[2] = pt[2];
00256 }
00257 if ((!haveMinS) || (sval < minS) ) {
00258 haveMinS = 1;
00259 minS = sval;
00260 minSpt[0] = pt[0];
00261 minSpt[1] = pt[1];
00262 minSpt[2] = pt[2];
00263 }
00264 if ((!haveMaxG2) || (gval2 > maxG2) ) {
00265 haveMaxG2 = 1;
00266 maxG2 = gval2;
00267 maxG2pt[0] = pt[0];
00268 maxG2pt[1] = pt[1];
00269 maxG2pt[2] = pt[2];
00270 }
00271 if ((!haveMinG2) || (gval2 < minG2) ) {
00272 haveMinG2 = 1;
00273 minG2 = gval2;
00274 minG2pt[0] = pt[0];
00275 minG2pt[1] = pt[1];
00276 minG2pt[2] = pt[2];
00277 }
00278 }
00279
00280 if (onGridS) {
00281 val = sval*mval;
00282
00283
00284 norm_L2 += VSQR(val);
00285
00286 norm_L1 += VABS(val);
00287
00288 svol += dvol;
00289
00290 }
00291
00292 if (onGridV && onGridS) {
00293 val = mval*(VSQR(gval[0]) + VSQR(gval[1]) + VSQR(gval[2]));
00294 snorm_H1 += VSQR(val);
00295 gvol += dvol;
00296 }
00297 }
00298 }
00299 }
00300 norm_Linf = VMAX2(VABS(maxS), VABS(minS));
00301 norm_L2 = VSQRT(norm_L2*dvol);
00302 norm_L1 = (norm_L1*dvol);
00303 snorm_H1 = VSQRT(snorm_H1*dvol);
00304 norm_H1 = VSQRT(VSQR(snorm_H1)+VSQR(norm_L2));
00305
00306 Vnm_print(1, "Volume used to calculate L2 and L1 norms = %1.12E\n",
00307 svol);
00308 Vnm_print(1, "Volume used to calculate H1 norms = %1.12E\n",
00309 gvol);
00310 Vnm_print(1, "Max scalar value = %1.12E\n",
00311 maxS);
00312 Vnm_print(1, "Max scalar value location = (%4.3f, %4.3f, %4.3f)\n",
00313 maxSpt[0], maxSpt[1], maxSpt[2]);
00314 Vnm_print(1, "Min scalar value = %1.12E\n",
00315 minS);
00316 Vnm_print(1, "Min scalar value location = (%4.3f, %4.3f, %4.3f)\n",
00317 minSpt[0], minSpt[1], minSpt[2]);
00318 Vnm_print(1, "Max gradient-squared value = %1.12E\n",
00319 maxG2);
00320 Vnm_print(1, "Max gradient-squared value location = (%4.3f, %4.3f, %4.3f)\n",
00321 maxG2pt[0], maxG2pt[1], maxG2pt[2]);
00322 Vnm_print(1, "Min gradient-squared value = %1.12E\n",
00323 minG2);
00324 Vnm_print(1, "Min gradient-squared value location = (%4.3f, %4.3f, %4.3f)\n",
00325 minG2pt[0], minG2pt[1], minG2pt[2]);
00326 Vnm_print(1, "L2 norm = %1.12E\n",
00327 norm_L2);
00328 Vnm_print(1, "L1 norm = %1.12E\n",
00329 norm_L1);
00330 Vnm_print(1, "Linf norm = %1.12E\n",
00331 norm_Linf);
00332 Vnm_print(1, "H1 semi-norm = %1.12E\n",
00333 snorm_H1);
00334 Vnm_print(1, "H1 norm = %1.12E\n",
00335 norm_H1);
00336
00337 return 0;
00338 }