/*! * Returns a slice with the gradient of the input slice [sin], or NULL for * error. The gradient is the absolute value of the difference * between the current and next pixel, averaged over the X and Y direction. */ Islice *sliceGradient(Islice *sin) { Islice *s; int i, j; Ival val, nval, gval; s = sliceCreate(sin->xsize, sin->ysize, sin->mode); if (!s) return(NULL); /* Store gradient in X */ for(j = 0; j < sin->ysize; j++){ for(i = 0; i < sin->xsize - 1; i++){ sliceGetVal(sin, i, j, val); sliceGetVal(sin, i+1, j, nval); val[0] = nval[0] - val[0]; if (val[0] < 0) val[0] *= -1; slicePutVal(s, i, j, val); } } /* Get gradient in Y and average with the one in X, copy last line */ for(i = 0; i < sin->xsize; i++){ for(j = 0; j < sin->ysize - 1; j++){ sliceGetVal(sin, i, j, val); sliceGetVal(sin, i, j + 1, nval); sliceGetVal(s, i, j, gval); val[0] = nval[0] - val[0]; if (val[0] < 0) val[0] *= -1; gval[0] = (val[0] + gval[0]) / 2; slicePutVal(s, i, j, gval); } sliceGetVal(s, i, j - 1, val); slicePutVal(s, i, j, val); } /* Copy last column over too */ for(j = 0; j < sin->ysize; j++){ sliceGetVal(s, sin->xsize - 2, j, val); slicePutVal(s, sin->xsize - 1, j, val); } sliceMMM(s); return(s); }
/*! * Writes the data from [slice] into a new MRC file whose name is given in * [filename]. Returns -1 for error opening the file, -2 for error writing * header, or an error from ferror if there is an error writing the data. * Unused as of 2/3/07, but seems usable. */ int sliceWriteMRCfile(char *filename, Islice *slice) { MrcHeader hout; FILE *fp = fopen(filename, "wb"); int error; if (!fp) return -1; mrc_head_new(&hout, slice->xsize, slice->ysize, 1, slice->mode); sliceMMM(slice); hout.amin = slice->min; hout.amax = slice->max; hout.amean = slice->mean; if (mrc_head_write(fp, &hout)) { fclose(fp); return -2; } b3dFwrite(slice->data.b, slice->dsize, slice->csize * slice->xsize * slice->ysize, fp); error = ferror(fp); fclose(fp); return(error); }
/* Write the data volume with potential padding */ int grap_volume_write(Istack *v, MrcHeader *hout, ClipOptions *opt) { FILE *fp = hout->fp; int zs, ks, z; int k; float min, max, mean, zscale; Islice *s, *ps = NULL; int labels; if (opt->mode == IP_DEFAULT) opt->mode = v->vol[0]->mode; if (opt->ox == IP_DEFAULT) opt->ox = v->vol[0]->xsize; if (opt->oy == IP_DEFAULT) opt->oy = v->vol[0]->ysize; if (opt->oz == IP_DEFAULT) opt->oz = v->zsize; if (v->vol[0]->mode != opt->mode) for(k = 0; k < v->zsize; k++){ sliceNewMode(v->vol[k], opt->mode); } /* calculate min, max, mean of volume. */ sliceMMM(v->vol[0]); min = v->vol[0]->min; max = v->vol[0]->max; mean = v->vol[0]->mean; for(k = 1; k < v->zsize; k++){ sliceMMM(v->vol[k]); min = B3DMIN(min, v->vol[k]->min); max = B3DMAX(max, v->vol[k]->max); mean += v->vol[k]->mean; } mean /= (float)v->zsize; /* DNM 6/26/02: do not make a new header if appending or overwriting! */ switch(opt->add2file){ case IP_APPEND_OVERWRITE: ks = opt->isec; hout->nz = ks + opt->oz; opt->ox = hout->nx; opt->oy = hout->ny; if (hout->mode != v->vol[0]->mode){ fprintf(stderr, "overwriting requires data modes to be the same.\n"); return(-1); } /* DNM 6/26/02: fix min and max, also fix mz and zlen */ /* DNM 9/13/02: oops, had xlen instead of zlen */ /* todo: recalc mmm. This is a start but not much */ hout->amin = B3DMIN(min, hout->amin); hout->amax = B3DMAX(max, hout->amax); zscale = hout->zlen / hout->mz; hout->mz = hout->nz; hout->zlen = hout->mz * zscale; break; case IP_APPEND_ADD: ks = hout->nz; hout->nz = hout->nz + opt->oz; opt->ox = hout->nx; opt->oy = hout->ny; if (hout->mode != v->vol[0]->mode){ fprintf(stderr, "inserting requires data modes to be the same.\n"); return(-1); } hout->amin = B3DMIN(min, hout->amin); hout->amax = B3DMAX(max, hout->amax); hout->amean = ((hout->amean * ks) + (mean * opt->oz)) / hout->nz; zscale = hout->zlen / hout->mz; hout->mz = hout->nz; hout->zlen = hout->mz * zscale; break; case IP_APPEND_FALSE: /* New file: reinitialize header but preserve the labels, set min/max/mean */ labels = hout->nlabl; mrc_head_new(hout, opt->ox, opt->oy, opt->oz, v->vol[0]->mode); hout->nlabl = labels; hout->amin = min; hout->amax = max; hout->amean = mean; ks = 0; } if (opt->pad == IP_DEFAULT) opt->pad = hout->amean; if (mrc_head_write(fp, hout)) return -1; zs = (v->zsize - opt->oz) / 2; for (k = ks, z = zs; k < hout->nz; k++, z++) { /* printf("%d %d\n", k, z);*/ /* Write blank slice outside z range */ if ((z < 0) || (z >= v->zsize)) { if (!ps) { ps = clipBlankSlice(hout, opt); if (!ps) return -1; } if (mrc_write_slice((void *)ps->data.b, fp, hout, k, 'z')) return (-1); } else { /* Resize slice only if necessary */ s = v->vol[z]; if (opt->ox != v->vol[0]->xsize || opt->oy != v->vol[0]->ysize) { v->vol[z]->mean = opt->pad; s = mrc_slice_resize(v->vol[z], opt->ox, opt->oy); if (!s){ fprintf(stderr, "volume_write: error resizing slice.\n"); return(-1); } } if (mrc_write_slice((void *)s->data.b, fp, hout, k, 'z')) return (-1); if (opt->ox != v->vol[0]->xsize || opt->oy != v->vol[0]->ysize) sliceFree(s); } } if (ps) sliceFree(ps); return(0); }
/* * Write one slice to output file * kSec is the index of the sections being processed, * zWrite is address of z value at which to write, maintained here * freeSlice 1 indicates to free the slice when done */ int clipWriteSlice(Islice *slice, MrcHeader *hout, ClipOptions *opt, int kSec, int *zWrite, int freeSlice) { Islice *ps = NULL; Islice *s; int z; int blankBefore = 0; int blankAfter = 0; /* Ignore if output size is smaller than # being processed */ if (kSec < (opt->nofsecs - opt->oz) / 2 || kSec >= (opt->nofsecs - opt->oz) / 2 + opt->oz) { if (freeSlice) sliceFree(slice); return 0; } /* determine if blank slices need to be written before or after this slice */ if (opt->oz > opt->nofsecs) { if (!kSec) { if (opt->outBefore == IP_DEFAULT) blankBefore = (opt->oz - opt->nofsecs) / 2; else blankBefore = opt->outBefore; } if (kSec == opt->nofsecs - 1) { if (opt->outAfter == IP_DEFAULT) blankAfter = opt->oz - opt->nofsecs - (opt->oz - opt->nofsecs) / 2; else blankAfter = opt->outAfter; } if (blankBefore || blankAfter) { ps = clipBlankSlice(hout, opt); if (!ps) return -1; } } /* Write blank slices before */ for (z = 0; z < blankBefore; z++) if (mrc_write_slice((void *)ps->data.b, hout->fp, hout, (*zWrite)++, 'z')) return -1; /* convert slice to output mode if needed */ if (slice->mode != opt->mode && sliceNewMode(slice, opt->mode) < 0) return -1; /* Resize slice if necessary */ s = slice; if (opt->ox != slice->xsize || opt->oy != slice->ysize) { slice->mean = opt->pad; s = mrc_slice_resize(slice, opt->ox, opt->oy); if (!s) { fprintf(stderr, "clipWriteSlice: error resizing slice.\n"); return(-1); } } /* maintain min & max, add to mean unless overwriting */ sliceMMM(s); hout->amin = B3DMIN(hout->amin, s->min); hout->amax = B3DMAX(hout->amax, s->max); if (opt->add2file != IP_APPEND_OVERWRITE) hout->amean += (s->mean + (blankBefore + blankAfter) * opt->pad) / hout->nz; /* Write slice, free slices as needed */ if (mrc_write_slice((void *)s->data.b, hout->fp, hout, (*zWrite)++, 'z')) return -1; if (opt->ox != slice->xsize || opt->oy != slice->ysize) sliceFree(s); if (freeSlice) sliceFree(slice); /* Write blank slices after */ for (z = 0; z < blankAfter; z++) if (mrc_write_slice((void *)ps->data.b, hout->fp, hout, (*zWrite)++, 'z')) return -1; if (ps) sliceFree(ps); return 0; }