int iiMRCopenNew(ImodImageFile *inFile, const char *mode) { errno = 0; inFile->fp = fopen(inFile->filename, mode); if (!inFile->fp) { b3dError(stderr, "ERROR: iiMRCopenNew - Could not open %s%s%s\n" , inFile->filename, errno ? " - system message: " : "", errno ? strerror(errno) : ""); return 1; } inFile->header = (char *)malloc(sizeof(MrcHeader)); if (!inFile->header) { b3dError(stderr, "ERROR: iiMRCopenNew - Allocating MRC header\n"); return 1; } mrc_head_new((MrcHeader *)inFile->header, 1, 1, 1, 0); iiMRCsetIOFuncs(inFile, 0); ((MrcHeader *)(inFile->header))->fp = inFile->fp; inFile->file = IIFILE_MRC; return 0; }
/*! * 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); }
/* * Sets up output size and file header based on output options * Returns first z section to write, or negative for error. */ int set_output_options(ClipOptions *opt, MrcHeader *hout) { int z = 0; /* create a new file */ if (!opt->add2file){ mrc_head_new(hout, opt->ox, opt->oy, opt->oz, opt->mode); if (mrc_head_write(hout->fp, hout)) return -1; } else { if ((opt->ox != hout->nx) || (opt->oy != hout->ny)){ opt->ox = hout->nx; opt->oy = hout->ny; show_warning("clip - Appended file can't change size."); } if (opt->mode != hout->mode){ opt->mode = hout->mode; show_warning("clip - Appended file can't change mode."); } if (IP_APPEND_ADD == opt->add2file){ /* If appending, scale mean down so complete mean can be computed by adding slice mean / new nz */ z = hout->nz; hout->nz += opt->oz; hout->amean = z * hout->amean / hout->nz; } else{ z = opt->isec; hout->nz = opt->oz + opt->isec; } if (mrc_head_write(hout->fp, hout)) return -1; /* DNM 1/15/05: removed the calculation of data size and file seek */ } return(z); }
/* 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); }