00001
00054 #include "apbscfg.h"
00055 #include "apbs/apbs.h"
00056
00057 #define SHORTINT short
00058 #define IJK(i,j,k) (((k)*(nx)*(ny))+((j)*(nx))+(i))
00059 #define INTERVAL(x,a,b) (((x) >= (a)) && ((x) <= (b)))
00060
00061 VEMBED(rcsid="$Id: mergedx.c 1552 2010-02-10 17:46:27Z yhuang01 $")
00062
00063 VPRIVATE int Vgrid_readDXhead(Vgrid *thee,
00064 const char *iodev, const char *iofmt, const char *thost, const char *fname);
00065 VPRIVATE int Vgrid_value2(Vgrid *thee, double pt[3], double *value);
00066 VPRIVATE int Char_parseARGV(int argc, char **argv, int *nx, int *ny, int *nz,
00067 int *pad, char ***fnams, int *numfnams, char *outname, int *vflag);
00068
00069 VPRIVATE char *MCwhiteChars = " =,;\t\n";
00070 VPRIVATE char *MCcommChars = "#%";
00071
00072 int main(int argc, char **argv) {
00073
00074
00075 int i, j, k, vlev = 1, vvlev = 0, vflag = 1;
00076 int nx, ny, nz, count, numfnams;
00077 double pt[3],value;
00078 double xmin, ymin, zmin, xmax, ymax, zmax;
00079 char **fnams = VNULL;
00080 SHORTINT *carray = VNULL;
00081 char *usage0 = "[FLAGS] nx ny nz file1.dx [file2.dx ...]\n";
00082 char *req0 = "nx ny nz Grid points on the merged grid";
00083 char *req1 = "file1.dx Names of unmerged grid files";
00084 char *flag0 = "-v Verbose (default: off)";
00085 char *flag1 = "-quiet Silent (default: off)";
00086 char *flag2 = "-pad integer Num. of pad grid points (default: 1 )";
00087 char *flag3 = "-o filename.dx Output file (default: gridmerged.dx)";
00088 char *note0 = "Each subgrid is extended by the number of pad points,";
00089 char *note1 = "which is often necessary to fill gaps between the grids.";
00090 char *note2 = "Any overlap between subgrids is resolved by averaging.";
00091 char *snam = "# main: ";
00092 char outname[80];
00093 Vgrid *grid, *mgrid;
00094 int pad = 1;
00095
00096 Vio_start();
00097 sprintf(outname,"gridmerged.dx");
00098
00099
00100 printf("WARNING: mergedx is deprecated. Please consider using mergedx2\n");
00101
00102
00103
00104 if ( Char_parseARGV(argc, argv, &nx, &ny, &nz, &pad,
00105 &fnams, &numfnams, outname, &vflag) != 0 ) {
00106 Vnm_print(2,"\nImproper or Unrecognized Switches?\nUsage: ");
00107 Vnm_print(2,"%s %s\n",argv[0],usage0);
00108 Vnm_print(2,"Input:\t\t%s\n\t\t%s\n\n", req0, req1);
00109 Vnm_print(2,"Flags:\t\t%s\n\t\t%s\n\t\t%s\n\t\t%s\n\n",
00110 flag0, flag1, flag2, flag3);
00111 Vnm_print(2,"Notes:\t\t%s\n\t\t%s\n\t\t%s\n",
00112 note0, note1, note2);
00113 return -1;
00114 }
00115
00116 if (vflag == 1) {
00117 vlev = 1;
00118 vvlev = 0;
00119 } else if (vflag) {
00120 vlev = 2;
00121 vvlev = 2;
00122 } else {
00123 vlev = 0;
00124 vvlev = 0;
00125 }
00126
00127
00128 mgrid = Vgrid_ctor(nx, ny, nz, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, VNULL);
00129 mgrid->xmin = VLARGE; mgrid->xmax = -VLARGE;
00130 mgrid->ymin = VLARGE; mgrid->ymax = -VLARGE;
00131 mgrid->zmin = VLARGE; mgrid->zmax = -VLARGE;
00132
00133
00134 Vnm_print(vlev, "%s Reading Headers...\n",snam);
00135 grid = Vgrid_ctor(0, 0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, VNULL);
00136 for(count=0; count<numfnams; count++) {
00137 Vnm_print(vvlev, "%s Reading header from %s...\n",snam,
00138 fnams[count]);
00139 Vnm_tstart(26, "HEADER READ");
00140 Vgrid_readDXhead(grid, "FILE", "ASC", VNULL, fnams[count]);
00141 Vnm_tstop(26, "HEADER READ");
00142
00143 if( grid->xmin < mgrid->xmin ) mgrid->xmin = grid->xmin;
00144 if( grid->xmax > mgrid->xmax ) mgrid->xmax = grid->xmax;
00145 if( grid->ymin < mgrid->ymin ) mgrid->ymin = grid->ymin;
00146 if( grid->ymax > mgrid->ymax ) mgrid->ymax = grid->ymax;
00147 if( grid->zmin < mgrid->zmin ) mgrid->zmin = grid->zmin;
00148 if( grid->zmax > mgrid->zmax ) mgrid->zmax = grid->zmax;
00149 }
00150
00151
00152 mgrid->hx = (mgrid->xmax - mgrid->xmin)/(mgrid->nx - 1);
00153 mgrid->hy = (mgrid->ymax - mgrid->ymin)/(mgrid->ny - 1);
00154 mgrid->hzed = (mgrid->zmax - mgrid->zmin)/(mgrid->nz - 1);
00155
00156
00157 Vnm_print(vlev, "%s Dimensions of the merged grid\n",snam);
00158 Vnm_print(vlev, "%s nx = %d, ny = %d, nz = %d\n",snam,
00159 mgrid->nx, mgrid->ny, mgrid->nz);
00160 Vnm_print(vlev, "%s hx = %g, hy = %g, hz = %g\n",snam,
00161 mgrid->hx, mgrid->hy, mgrid->hzed);
00162 Vnm_print(vlev, "%s xmin = %g, ymin = %g, zmin = %g\n",snam,
00163 mgrid->xmin, mgrid-> ymin, mgrid->zmin);
00164 Vnm_print(vlev, "%s xmax = %g, ymax = %g, zmax = %g\n",snam,
00165 mgrid->xmax, mgrid-> ymax, mgrid->zmax);
00166
00167 mgrid->data = (double *)
00168 Vmem_malloc(mgrid->mem,(mgrid->nx*mgrid->ny*mgrid->nz),sizeof(double));
00169 mgrid->ctordata = 1;
00170 carray = (SHORTINT *)
00171 Vmem_malloc(VNULL, (mgrid->nx*mgrid->ny*mgrid->nz), sizeof(SHORTINT) );
00172
00173
00174 nx = mgrid->nx;
00175 ny = mgrid->ny;
00176 nz = mgrid->nz;
00177 for (i=0; i<nx; i++) {
00178 for (j=0; j<ny; j++) {
00179 for (k=0; k<nz; k++) {
00180 (mgrid->data)[IJK(i,j,k)] = 0.0;
00181 carray[IJK(i,j,k)] = 0;
00182 }
00183 }
00184 }
00185
00186
00187 Vnm_print(vlev, "%s Reading and Merging...\n",snam);
00188 for (count=0; count<numfnams; count++) {
00189 Vnm_print(vvlev, "%s Reading data from %s...\n",snam,fnams[count]);
00190 Vnm_tstart(26, "DATA READ");
00191 Vgrid_readDX(grid, "FILE", "ASC", VNULL, fnams[count]);
00192 Vnm_tstop(26, "DATA READ");
00193 Vnm_print(vvlev, "%s Merging data from %s...\n",snam,fnams[count]);
00194 Vnm_tstart(26, "MERGING");
00195 xmin = grid->xmin - pad*grid->hx - VSMALL;
00196 ymin = grid->ymin - pad*grid->hy - VSMALL;
00197 zmin = grid->zmin - pad*grid->hzed - VSMALL;
00198 xmax = grid->xmax + pad*grid->hx + VSMALL;
00199 ymax = grid->ymax + pad*grid->hy + VSMALL;
00200 zmax = grid->zmax + pad*grid->hzed + VSMALL;
00201 Vnm_print(vvlev, "%s MIN (%g,%g,%g) IMIN (%g,%g,%g)\n",snam,
00202 grid->xmin,grid->ymin,grid->zmin,xmin,ymin,zmin);
00203 Vnm_print(vvlev, "%s MAX (%g,%g,%g) IMAX (%g,%g,%g)\n",snam,
00204 grid->xmax,grid->ymax,grid->zmax,xmax,ymax,zmax);
00205 for (i=0; i<nx; i++) {
00206 pt[0] = mgrid->xmin + i*mgrid->hx;
00207 if(INTERVAL(pt[0],xmin,xmax)) {
00208 for (j=0; j<ny; j++) {
00209 pt[1] = mgrid->ymin + j*mgrid->hy;
00210 if(INTERVAL(pt[1],ymin,ymax)) {
00211 for (k=0; k<nz; k++) {
00212 pt[2] = mgrid->zmin + k*mgrid->hzed;
00213 if(INTERVAL(pt[2],zmin,zmax)) {
00214 if (Vgrid_value2(grid, pt, &value)) {
00215 (mgrid->data)[IJK(i,j,k)] += value;
00216 carray[IJK(i,j,k)] += 1;
00217 }
00218 }
00219 }
00220 }
00221 }
00222 }
00223 }
00224 Vnm_tstop(26, "MERGING");
00225 Vmem_free(grid->mem,(grid->nx*grid->ny*grid->nz), sizeof(double),
00226 (void **)&(grid->data));
00227 grid->readdata = 0;
00228 grid->ctordata = 0;
00229 }
00230 Vgrid_dtor( &grid );
00231
00232 mgrid->readdata = 1;
00233
00234
00235 nx = mgrid->nx;
00236 ny = mgrid->ny;
00237 nz = mgrid->nz;
00238 for (i=0; i<nx; i++) {
00239 for (j=0; j<ny; j++) {
00240 for (k=0; k<nz; k++) {
00241 if ( carray[IJK(i,j,k)] >= 1 ) {
00242 (mgrid->data)[IJK(i,j,k)] /= carray[IJK(i,j,k)];
00243 } else {
00244 Vnm_print(2,"%s %s %s (%g,%g,%g)\n",snam,
00245 "Warning: ",
00246 "Gap in subgrids at point",
00247 mgrid->xmin + i*mgrid->hx,
00248 mgrid->ymin + j*mgrid->hy,
00249 mgrid->zmin + k*mgrid->hzed );
00250 }
00251 }
00252 }
00253 }
00254
00255
00256 Vnm_print(vlev, "%s Writing...\n",snam);
00257 Vnm_print(vvlev, "%s Writing merged data to %s...\n",snam,outname);
00258 Vgrid_writeDX(mgrid, "FILE", "ASC", VNULL, outname,"mergedx",VNULL);
00259
00260 Vmem_free(VNULL,(mgrid->nx*mgrid->ny*mgrid->nz), sizeof(SHORTINT),
00261 (void **)&(carray));
00262 Vgrid_dtor( &mgrid );
00263
00264 if ( vflag > 1 ) {
00265 Vnm_print(2,"%s Memory Profiling Information\n",snam);
00266 Vnm_print(2,"# --------------------------------------"
00267 "--------------------------------------\n");
00268 Vnm_print(2,"# Footprint Areas Malloc Free"
00269 " Highwater Class\n");
00270 Vnm_print(2,"# --------------------------------------"
00271 "--------------------------------------\n");
00272 Vmem_print(VNULL);
00273 Vmem_printTotal();
00274 Vnm_print(2,"# --------------------------------------"
00275 "--------------------------------------\n");
00276 }
00277
00278 return 0;
00279 }
00280
00281
00282
00283
00284
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296 if (thee->data != VNULL) {
00297 Vnm_print(1, "%s destroying existing data!\n",snam);
00298 Vmem_free(thee->mem, (thee->nx*thee->ny*thee->nz), sizeof(double),
00299 (void **)&(thee->data)); }
00300 thee->readdata = 0;
00301 thee->ctordata = 0;
00302
00303
00304 sock = Vio_ctor(iodev,iofmt,thost,fname,"r");
00305 if (sock == VNULL) {
00306 Vnm_print(2, "%s Problem opening virtual socket %s\n",snam,fname);
00307 return 0;
00308 }
00309 if (Vio_accept(sock, 0) < 0) {
00310 Vnm_print(2, "%s Problem accepting virtual socket %s\n",snam,fname);
00311 return 0;
00312 }
00313
00314 Vio_setWhiteChars(sock, MCwhiteChars);
00315 Vio_setCommChars(sock, MCcommChars);
00316
00317
00318
00319 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
00320 VJMPERR1(!strcmp(tok, "object"));
00321
00322 VJMPERR2(1 == Vio_scanf(sock, "%d", &itmp));
00323
00324 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
00325 VJMPERR1(!strcmp(tok, "class"));
00326
00327 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
00328 VJMPERR1(!strcmp(tok, "gridpositions"));
00329
00330 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
00331 VJMPERR1(!strcmp(tok, "counts"));
00332
00333 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
00334 VJMPERR1(1 == sscanf(tok, "%d", &(thee->nx)));
00335
00336 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
00337 VJMPERR1(1 == sscanf(tok, "%d", &(thee->ny)));
00338
00339 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
00340 VJMPERR1(1 == sscanf(tok, "%d", &(thee->nz)));
00341 Vnm_print(0, "%s Grid dimensions %d x %d x %d grid\n",snam,
00342 thee->nx, thee->ny, thee->nz);
00343
00344 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
00345 VJMPERR1(!strcmp(tok, "origin"));
00346
00347 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
00348 VJMPERR1(1 == sscanf(tok, "%lf", &(thee->xmin)));
00349
00350 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
00351 VJMPERR1(1 == sscanf(tok, "%lf", &(thee->ymin)));
00352
00353 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
00354 VJMPERR1(1 == sscanf(tok, "%lf", &(thee->zmin)));
00355 Vnm_print(0, "%s Grid origin = (%g, %g, %g)\n",snam,
00356 thee->xmin, thee->ymin, thee->zmin);
00357
00358 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
00359 VJMPERR1(!strcmp(tok, "delta"));
00360
00361 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
00362 VJMPERR1(1 == sscanf(tok, "%lf", &(thee->hx)));
00363
00364 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
00365 VJMPERR1(1 == sscanf(tok, "%lf", &dtmp));
00366 VJMPERR1(dtmp == 0.0);
00367
00368 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
00369 VJMPERR1(1 == sscanf(tok, "%lf", &dtmp));
00370 VJMPERR1(dtmp == 0.0);
00371
00372 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
00373 VJMPERR1(!strcmp(tok, "delta"));
00374
00375 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
00376 VJMPERR1(1 == sscanf(tok, "%lf", &dtmp));
00377 VJMPERR1(dtmp == 0.0);
00378
00379 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
00380 VJMPERR1(1 == sscanf(tok, "%lf", &(thee->hy)));
00381
00382 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
00383 VJMPERR1(1 == sscanf(tok, "%lf", &dtmp));
00384 VJMPERR1(dtmp == 0.0);
00385
00386 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
00387 VJMPERR1(!strcmp(tok, "delta"));
00388
00389 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
00390 VJMPERR1(1 == sscanf(tok, "%lf", &dtmp));
00391 VJMPERR1(dtmp == 0.0);
00392
00393 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
00394 VJMPERR1(1 == sscanf(tok, "%lf", &dtmp));
00395 VJMPERR1(dtmp == 0.0);
00396
00397 VJMPERR2(1 == Vio_scanf(sock, "%s", tok));
00398 VJMPERR1(1 == sscanf(tok, "%lf", &(thee->hzed)));
00399 Vnm_print(0, "%s Grid spacings = (%g, %g, %g)\n",snam,
00400 thee->hx, thee->hy, thee->hzed);
00401
00402 thee->xmax = thee->xmin + (thee->nx-1)*thee->hx;
00403 thee->ymax = thee->ymin + (thee->ny-1)*thee->hy;
00404 thee->zmax = thee->zmin + (thee->nz-1)*thee->hzed;
00405
00406
00407 Vio_acceptFree(sock);
00408 Vio_dtor(&sock);
00409
00410 return 1;
00411
00412 VERROR1:
00413 Vio_dtor(&sock);
00414 Vnm_print(2, "%s Format problem with input file <%s>\n",snam,fname);
00415 return 0;
00416
00417 VERROR2:
00418 Vio_dtor(&sock);
00419 Vnm_print(2, "%s I/O problem with input file <%s>\n",snam,fname);
00420 return 0;
00421 }
00422
00423
00424
00425
00426
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460 if ( ilo < 0 ) {
00461 ilo = 0;
00462 ihi = ilo + 1;
00463 ifloat = (double)(ilo);
00464 } else if ( ihi >= nx ) {
00465 ihi = nx - 1;
00466 ilo = ihi - 1;
00467 ifloat = (double)(ihi);
00468 }
00469 if ( jlo < 0 ) {
00470 jlo = 0;
00471 jhi = jlo + 1;
00472 jfloat = (double)(jlo);
00473 } else if ( jhi >= ny ) {
00474 jhi = ny - 1;
00475 jlo = jhi - 1;
00476 jfloat = (double)(jhi);
00477 }
00478 if ( klo < 0 ) {
00479 klo = 0;
00480 khi = klo + 1;
00481 kfloat = (double)(klo);
00482 } else if ( khi >= nz ) {
00483 khi = nz - 1;
00484 klo = khi - 1;
00485 kfloat = (double)(khi);
00486 }
00487
00488
00489 if ((ihi<nx) && (jhi<ny) && (khi<nz) &&
00490 (ilo>=0) && (jlo>=0) && (klo>=0)) {
00491 dx = ifloat - (double)(ilo);
00492 dy = jfloat - (double)(jlo);
00493 dz = kfloat - (double)(klo);
00494 u = dx *dy *dz *(thee->data[IJK(ihi,jhi,khi)])
00495 + dx *(1.0-dy)*dz *(thee->data[IJK(ihi,jlo,khi)])
00496 + dx *dy *(1.0-dz)*(thee->data[IJK(ihi,jhi,klo)])
00497 + dx *(1.0-dy)*(1.0-dz)*(thee->data[IJK(ihi,jlo,klo)])
00498 + (1.0-dx)*dy *dz *(thee->data[IJK(ilo,jhi,khi)])
00499 + (1.0-dx)*(1.0-dy)*dz *(thee->data[IJK(ilo,jlo,khi)])
00500 + (1.0-dx)*dy *(1.0-dz)*(thee->data[IJK(ilo,jhi,klo)])
00501 + (1.0-dx)*(1.0-dy)*(1.0-dz)*(thee->data[IJK(ilo,jlo,klo)]);
00502
00503 *value = u;
00504 return 1;
00505
00506 }
00507
00508 *value = 0.0;
00509 return 0;
00510 }
00511
00512 VPRIVATE int Char_parseARGV(int argc, char **argv,
00513 int *nx, int *ny, int *nz, int *pad, char ***fnams, int *numfnams,
00514 char *outname, int *vflag)
00515 {
00516 int i, j, hflag, nflags, sflag;
00517
00518 i = 1;
00519 hflag = 0;
00520 nflags = 0;
00521 while( i < argc ) {
00522 if( argv[i][0] == '-' ) {
00523 nflags++;
00524 if (!strcmp(argv[i],"-v")) {
00525 (*vflag) = 2;
00526 } else if (!strcmp(argv[i],"-quiet")) {
00527 (*vflag) = 0;
00528 } else if (!strcmp(argv[i],"-o")) {
00529 i++;
00530 if( i < argc ) {
00531 nflags++;
00532 sprintf(outname,"%s",argv[i]);
00533 }
00534 } else if (!strcmp(argv[i],"-pad")) {
00535 i++;
00536 if( i < argc ) {
00537 nflags++;
00538 (*pad) = atoi(argv[i]);
00539 }
00540 } else {
00541 hflag = 1;
00542 }
00543 }
00544 i++;
00545 }
00546
00547
00548 if ((argc - nflags) < 5 || hflag) {
00549 return 1;
00550 }
00551
00552
00553 i = 1;
00554 j = 0;
00555 hflag = 0;
00556 sflag = 1;
00557 while(i<argc && sflag) {
00558 if( argv[i][0] == '-' ) {
00559 j++;
00560 if (!strcmp(argv[i],"-o")) {
00561 i++;
00562 j++;
00563 } else if (!strcmp(argv[i],"-pad")) {
00564 i++;
00565 j++;
00566 }
00567 } else {
00568 if( (i+2) < argc && nflags == j) {
00569 (*nx) = atoi(argv[i]);
00570 (*ny) = atoi(argv[i+1]);
00571 (*nz) = atoi(argv[i+2]);
00572 i += 2;
00573 } else {
00574 hflag = 1;
00575 }
00576 sflag = 0;
00577 }
00578 i++;
00579 }
00580
00581 if (hflag) {
00582 return 1;
00583 }
00584
00585 (*fnams) = &(argv[i]);
00586 (*numfnams) = argc - i;
00587
00588 return 0;
00589 }
00590