Exemplo n.º 1
0
long read_ALOS_data_SS (FILE *imagefile, FILE *outfile, struct PRM *prm, long *byte_offset, 
                        int *nsub, int *burst_skip, int *num_burst) {

	char *data, *shift_data, *gap_data;
	int	header_size;		/* file header size          720 bytes */
	int	line_prefix_size; 	/* line header size           412 bytes*/
	int     record_length0;		/* data record size start  10788 bytes */
	int	totrecl;		/* total record length	   11200 bytes = line_prefix_size + record_length */
	int	record_length1;		/* data record size curr.  10788 bytes */
	int	line_suffix_size;	/* number of bytes after data 36 bytes */
	int	kswath0=0;		/* subswath at start of file */
	int	skip_swath;             /* number of subswaths to skip to get to desired subswath */
	int	skiprecl;               /* number of lines to skip to get to desired subswath */
	int	data_length;		/* bytes of data			*/
	int     n = 1, ishift, shift, shift0;
	int	k, kburst = 0, totburst = 0;
	int	j, ngap, nlines = 0, ntot;
	int	nprfchange, nburstchange;

	double 	tbias = 0.0, get_clock();
	double  ttot=0.,dt=0.,tgap=0.;		/* total time, burst interval, burst gap, fractional gap */
	settable(12345);

	if (debug) fprintf(stderr,".... reading header \n");

	/* read header information */
	read_sardata_info(imagefile, prm, &header_size, &line_prefix_size);
	assign_sardata_params(prm, line_prefix_size, &line_suffix_size, &record_length0);
	totrecl = line_prefix_size + record_length0;
	set_file_position(imagefile, byte_offset, header_size);

	/* get the sarting burst number and the PRF information for all the bursts and rewind the file */
	for (k=0;k<5;k++) totburst = totburst + n_burst[k];
	for(j = 0; j < totburst; j++) {
		if ( fread((void *) &sdr,sizeof(struct sardata_info), 1, imagefile) !=1 ) break;
		fseek(imagefile, record_length0, SEEK_CUR);
		if (swap) swap_ALOS_data_info(&sdr);
		for (k=0;k<5;k++) {
			if(sdr.n_data_pixels == n_data_burst[k]) {
				PRF[k]=sdr.PRF;
				if(j == 0) kswath0 = k;
			}
		}
	}

        /* get the time interval of a burst  and rewind the file */
	dt = 0.;
	for (k=0;k<5;k++) if(PRF[k] > 0.)  dt = dt + (double)n_burst[k]/(0.001*PRF[k]);
 	tgap = dt - (double)n_burst[*nsub]/(0.001*PRF[*nsub]);
        ngap = (int)(tgap*(0.001*PRF[*nsub])+0.5);
	prm->num_valid_az = 6*(n_burst[*nsub] + ngap);    /* use 6 bursts per aperture */
	rewind(imagefile);
	fseek(imagefile, header_size, SEEK_SET);
	if (verbose) fprintf(stderr," totburst start_busrt# burstcycle_time %d %d %f \n", totburst, kswath0, dt);

	/* set the total number of lines output based on the number of patches requested or default 1000 */
	ntot = *num_burst * (n_burst[*nsub] + ngap);
	if (verbose) fprintf(stderr," dt, tgap, n_burst, ngap ,ntot %f %f %d %d %d %d \n", dt, tgap, n_burst[*nsub], ngap, prm->num_valid_az,ntot);

	/* allocate the memory for data */
	if ((data = (char *) malloc(record_length0)) == NULL) die("couldn't allocate memory for input indata.\n","");
	if ((shift_data = (char *) malloc(record_length0)) == NULL) die("couldn't allocate memory for input indata.\n","");
	if ((gap_data = (char *) malloc(record_length0)) == NULL) die("couldn't allocate memory for input indata.\n","");

	/* seek to beginning of next burst of sub swath nsub, read the line header, reset the parameters, and set the counters */
	skip_swath = ((*nsub +5) - kswath0)%5;
	skiprecl = 0;
	for( k = kswath0; k < kswath0 + skip_swath; k++) skiprecl = skiprecl + n_burst[k%5];
	skiprecl = skiprecl + *burst_skip * totburst;
	if (verbose) fprintf(stderr, " skip_swath skiprecl %d %d \n",skip_swath, skiprecl);
	fseek(imagefile,skiprecl*totrecl, SEEK_CUR);

        /* recalculate the PRF at the new skip location */
	for(j = 0; j < totburst; j++) {
		if ( fread((void *) &sdr,sizeof(struct sardata_info), 1, imagefile) !=1 ) break;
		fseek(imagefile, record_length0, SEEK_CUR);
		if (swap) swap_ALOS_data_info(&sdr);
		for (k=0;k<5;k++) {
			if(sdr.n_data_pixels == n_data_burst[k]) {
				PRF[k]=sdr.PRF;
			}
		}
	}
        /* get the time interval of a burst at the new skip location and rewind the file */
	dt = 0.;
	for (k=0;k<5;k++) if(PRF[k] > 0.)  dt = dt + (double)n_burst[k]/(0.001*PRF[k]);
 	tgap = dt - (double)n_burst[*nsub]/(0.001*PRF[*nsub]);
        ngap = (int)(tgap*(0.001*PRF[*nsub])+0.5);
	prm->num_valid_az = 6*(n_burst[*nsub] + ngap);    /* use 6 bursts per aperture */
	if (verbose) fprintf(stderr," totburst start_busrt# burstcycle_time %d %d %f \n", totburst, kswath0, dt);

	/* rewind and seek again to start in the correct location */
	rewind(imagefile);
	fseek(imagefile, header_size, SEEK_SET);
	fseek(imagefile,skiprecl*totrecl, SEEK_CUR);
	
        /* read the line header and set the parameters for this subswath */
	fread((void *) &sdr,line_prefix_size, 1, imagefile);
	if (swap) swap_ALOS_data_info(&sdr);
        prm->clock_start =  get_clock(sdr, tbias);
        prm->SC_clock_start = ((double) sdr.sensor_acquisition_year)*1000 + prm->clock_start;
	prm->prf = sdr.PRF;
	if(prm->near_range < 0) prm->near_range = sdr.slant_range;
	fseek(imagefile, -1*line_prefix_size, SEEK_CUR);
	n = sdr.sequence_number -1;
	//m = sdr.sequence_number;
	*byte_offset = ftell(imagefile);
	if (verbose) fprintf(stderr," n skiprecl byte_offset %d %d %ld \n", n, skiprecl, *byte_offset);

	/* now start at the beginning but with the intervals known */
	if (verbose) fprintf(stderr,".... reading data (byte %ld) \n",ftell(imagefile));
	shift0 = 0;
  	//m = 0;

	/* read the rest of the file */
	while ( (fread((void *) &sdr,sizeof(struct sardata_info), 1, imagefile)) == 1 ) {
        	n++;
		if (swap) swap_ALOS_data_info(&sdr);

	/* check to make sure there is no prf-change in any of the subswaths */
		for (k=0;k<5;k++) {
			if(sdr.n_data_pixels == n_data_burst[k]) {
          		if ((sdr.PRF) != PRF[k]) {
				PRF[*nsub] = 0.;
			}
			}
		}

		/* detect a different subswath and skip intil the next subswath */
		if(sdr.n_data_pixels == n_data_burst[*nsub]) {

			kburst++;

          		if (sdr.sequence_number != n) printf(" missing line: n, seq# %d %d \n", n, sdr.sequence_number);

			/* check for changes in record_length and PRF */
          		record_length1 = sdr.record_length - line_prefix_size;
          		if (record_length0  != record_length1)  die("record_length changed",""); 

			/* if prf changes exit */
          		if ((sdr.PRF) != PRF[*nsub]) {
				fprintf(stderr," ERROR  PRF changed, oldPRF, newPRF %f %f \n",PRF[*nsub]*.001,sdr.PRF*.001);
				*byte_offset=ftell(imagefile);
				nprfchange = (*byte_offset - header_size)/totrecl;
				nburstchange = nprfchange/totburst;
				fprintf(stderr," rec# burst# %d %d \n",nprfchange,nburstchange);
                                break;
			}

			/* check shift to see if it varies from beginning or from command line value */
			check_shift(prm, &shift, &ishift, &shift0, record_length1);
		
			if ((verbose) && (n/2000.0 == n/2000)) {
				fprintf(stderr," Working on line %d prf %f record length %d slant_range %d \n"
				,sdr.sequence_number, 0.001*sdr.PRF, record_length1, sdr.slant_range);
			}

			/* read data (and trailing bytes) */
          		if ( fread ((char *) data, record_length1, (size_t) 1, imagefile) != 1 ) break;

			data_length = 2*n_data_burst[*nsub];

			/* write line header to output data  */
          		fwrite((void *) &sdr, line_prefix_size, 1, outfile);
			nlines++;

			/* check to see if this is enough data */
			if(nlines >= ntot) break;

			/* Shimada says the first 13 lines are bad.  I only saw 11 bad. shift these lines outside the window */
			if(kburst < 12) ishift = data_length;
			/* ishift and write the data */
			fill_shift_data(shift, ishift, data_length, line_suffix_size, record_length1, data, shift_data, outfile); 

			/* if kburst it equal to the length of this burst then write the appropriate number of zero lines */
			if(kburst == n_burst[*nsub]) {
				ttot = ttot + dt;
				if(verbose) fprintf(stderr," %d %d %f %f %d %f \n",*nsub+1,kburst,dt,tgap,ngap,ttot);
				kburst = 0;
			/* write the appropriate number of zero lines  */
				for(j=0;j<ngap;j++) {
          				fwrite((void *) &sdr, line_prefix_size, 1, outfile);
					nlines++;
				/* set the gap data to 15.5 */
					for (k=0;k<record_length0;k++) gap_data[k]=NULL_DATA+znew%2;
					fwrite((char *) gap_data, record_length1, 1, outfile); 
				}
			}
		}
		else {
			record_length1 = sdr.record_length - line_prefix_size;
			if ( fread ((char *) data, record_length1, (size_t) 1, imagefile) != 1 ) break;
		}
	}
      
	/* calculate end time and fix prf */
	prm->prf = 0.001*PRF[*nsub];

        prm->clock_stop =  get_clock(sdr, tbias);
        prm->SC_clock_stop = ((double) sdr.sensor_acquisition_year)*1000 + prm->clock_stop;

	/* m is non-zero only in the event of a prf change */
	prm->num_lines = nlines-1;
	prm->num_patches = (int)((1.0*prm->num_lines)/(1.0*prm->num_valid_az));
	if (prm->num_lines == 0) prm->num_lines = 1;

	if (verbose) print_params(prm); 

	free(data);
	free(shift_data);
	fclose (outfile);

	return(*byte_offset);
}
Exemplo n.º 2
0
VIO_Status gradient3D_volume(FILE *ifd, 
                                VIO_Volume data, 
                                int xyzv[VIO_MAX_DIMENSIONS],
                                char *infile,
                                char *outfile, 
                                int ndim,
                                char *history,
                                int curvature_flg)

{ 
  float 
    *fdata,                        /* floating point storage for blurred volume */
    *f_ptr,                        /* pointer to fdata */
    tmp,
    max_val, 
    min_val,
    
    *dat_vector,                /* temp storage of original row, col or slice vect. */
    *dat_vecto2,                /* storage of result of dat_vector*kern                 */
    *kern;                        /* convolution kernel                               */
  int                                
    total_voxels,                
    vector_size_data,                /* original size of row, col or slice vector        */
    array_size_pow2,                /* actual size of vector/kernel data used in FFT    */
                                /* routines - needs to be a power of two            */
    array_size;

  int   
    data_offset;                /* offset required to place original data (size n)  */
                                /*  into array (size m=2^n) so that data is centered*/

  register int 
    slice_limit,
    row,col,slice,                /* counters to access original data                 */
    vindex;                        /* counter to access vector and vecto2              */

  int 
    slice_size,                        /* size of each data step - in bytes                */
    row_size, col_size;
                

  char
    full_outfilename[256];        /* name of output file */

  progress_struct 
    progress;                        /* used to monitor progress of calculations         */

  VIO_Status 
    status;
  
  int
    sizes[3],                        /* number of rows, cols and slices */
    pos[3];                          /* Input order of rows, cols, slices */

  VIO_Real
    steps[3];                        /* size of voxel step from center to center in x,y,z */

  /*---------------------------------------------------------------------------------*/
  /*             start by setting up the raw data.                                   */
  /*---------------------------------------------------------------------------------*/



  get_volume_sizes(data, sizes);          /* rows,cols,slices */
  get_volume_separations(data, steps);
  
  slice_size = sizes[xyzv[VIO_Y]] * sizes[xyzv[VIO_X]];    /* sizeof one slice  */
  col_size   = sizes[xyzv[VIO_Y]];               /* sizeof one column */
  row_size   = sizes[xyzv[VIO_X]];               /* sizeof one row    */
  
  total_voxels = sizes[xyzv[VIO_Y]]*sizes[xyzv[VIO_X]]*sizes[xyzv[VIO_Z]];
  
  ALLOC(fdata, total_voxels);
  f_ptr = fdata;

         /* read in data of input file. */

  set_file_position(ifd,(long)0);
  status = io_binary_data(ifd,READ_FILE, fdata, sizeof(float), total_voxels);
  if (status != OK)
    print_error_and_line_num("problems reading binary data...\n",__FILE__, __LINE__);


  /*--------------------------------------------------------------------------------------*/
  /*                get ready to start up the transformation.                             */
  /*--------------------------------------------------------------------------------------*/
  
  initialize_progress_report( &progress, FALSE, sizes[xyzv[VIO_Z]] + sizes[xyzv[VIO_Y]] + sizes[xyzv[VIO_X]] + 1,
                             "Gradient volume" );


  /* note data is stored by rows (along x), then by cols (along y) then slices (along z) */
  

  /*--------------------------------------------------------------------------------------*/
  /*                start with rows - i.e. the d/dx volume                                */
  /*--------------------------------------------------------------------------------------*/
  
  /*-----------------------------------------------------------------------------*/
  /*             determine   size of data structures needed                      */
  
  vector_size_data = sizes[xyzv[VIO_X]]; 
  
  /*             array_size_pow2 will hold the size of the arrays for FFT convolution,
                 remember that ffts require arrays 2^n in length                          */
  
  array_size_pow2  = next_power_of_two(vector_size_data);
  array_size = 2*array_size_pow2+1;  /* allocate 2*, since each point is a    */
                                     /* complex number for FFT, and the plus 1*/
                                     /* is for the zero offset FFT routine    */

  ALLOC(dat_vector, array_size);
  ALLOC(dat_vecto2, array_size);
  ALLOC(kern      , array_size);
  
  /*    1st calculate kern array for FT of 1st derivitive */
  
  make_kernel_FT(kern,array_size_pow2, ABS(steps[xyzv[VIO_X]]));

  if (curvature_flg)                /* 2nd derivative kernel */
    muli_vects(kern,kern,kern,array_size_pow2);

  /*    calculate offset for original data to be placed in vector            */
  
  data_offset = (array_size_pow2-sizes[xyzv[VIO_X]])/2;
  
  max_val = -FLT_MAX;
  min_val =  FLT_MAX;


  /*    2nd now convolve this kernel with the rows of the dataset            */  
  
  slice_limit = 0;
  switch (ndim) {
  case 1: slice_limit = 0; break;
  case 2: slice_limit = sizes[xyzv[VIO_Z]]; break;
  case 3: slice_limit = sizes[xyzv[VIO_Z]]; break;
  }


  for (slice = 0; slice < slice_limit; slice++) {      /* for each slice */
    
    for (row = 0; row < sizes[xyzv[VIO_Y]]; row++) {           /* for each row   */
      
      f_ptr = fdata + slice*slice_size + row*sizes[xyzv[VIO_X]];
      memset(dat_vector,0,(2*array_size_pow2+1)*sizeof(float));
      
      for (col=0; col< sizes[xyzv[VIO_X]]; col++) {        /* extract the row */
        dat_vector[1 +2*(col+data_offset)  ] = *f_ptr++;
      }
      
      fft1(dat_vector,array_size_pow2,1);
      muli_vects(dat_vecto2,dat_vector,kern,array_size_pow2);
      fft1(dat_vecto2,array_size_pow2,-1);
      
      f_ptr = fdata + slice*slice_size + row*sizes[xyzv[VIO_X]];
      for (col=0; col< sizes[xyzv[VIO_X]]; col++) {        /* put the row back */
        
        vindex = 1 + 2*(col+data_offset);
       *f_ptr = dat_vecto2[vindex]/array_size_pow2;


        if (max_val<*f_ptr) max_val = *f_ptr;
        if (min_val>*f_ptr) min_val = *f_ptr;


        f_ptr++;
      }
      
      
    }
    update_progress_report( &progress, slice+1 );
  }
  
  FREE(dat_vector);
  FREE(dat_vecto2);
  FREE(kern      );
    

  f_ptr = fdata;

  set_volume_real_range(data, min_val, max_val);
  
  
  printf("Making byte volume dx..." );
  for(slice=0; slice<sizes[xyzv[VIO_Z]]; slice++) {
    pos[xyzv[VIO_Z]] = slice;
    for(row=0; row<sizes[xyzv[VIO_Y]]; row++) {
      pos[xyzv[VIO_Y]] = row;
      for(col=0; col<sizes[xyzv[VIO_X]]; col++) {
        pos[xyzv[VIO_X]] = col;
        tmp = CONVERT_VALUE_TO_VOXEL(data, *f_ptr);
        SET_VOXEL_3D( data, pos[0], pos[1], pos[2], tmp);
        f_ptr++;
      }
    }
  }


  if (!curvature_flg)
    sprintf(full_outfilename,"%s_dx.mnc",outfile);
  else
    sprintf(full_outfilename,"%s_dxx.mnc",outfile);

  if (debug)
    print ("dx: min = %f, max = %f\n",min_val, max_val);

  status = output_modified_volume(full_outfilename, NC_UNSPECIFIED, FALSE, 
                                  min_val, max_val, data, infile, history, NULL);

  if (status != OK)
    print_error_and_line_num("problems writing dx gradient data...\n",__FILE__, __LINE__);


  
  /*--------------------------------------------------------------------------------------*/
  /*                 now do cols - i.e. the d/dy volume                                   */
  /*--------------------------------------------------------------------------------------*/
  
  /*-----------------------------------------------------------------------------*/
  /*             determine   size of data structures needed                      */
  

  set_file_position(ifd,0);
  status = io_binary_data(ifd,READ_FILE, fdata, sizeof(float), total_voxels);
  if (status != OK)
    print_error_and_line_num("problems reading binary data...\n",__FILE__, __LINE__);




  
  f_ptr = fdata;

  vector_size_data = sizes[xyzv[VIO_Y]];
  
  /*             array_size_pow2 will hold the size of the arrays for FFT convolution,
                 remember that ffts require arrays 2^n in length                          */
  
  array_size_pow2  = next_power_of_two(vector_size_data);
  array_size = 2*array_size_pow2+1;  /* allocate 2*, since each point is a    */
                                     /* complex number for FFT, and the plus 1*/
                                     /* is for the zero offset FFT routine    */
  
  ALLOC(dat_vector, array_size);
  ALLOC(dat_vecto2, array_size);
  ALLOC(kern      , array_size);
  
  /*    1st calculate kern array for FT of 1st derivitive */
  
  make_kernel_FT(kern,array_size_pow2, ABS(steps[xyzv[VIO_Y]]));
  
  if (curvature_flg)                /* 2nd derivative kernel */
    muli_vects(kern,kern,kern,array_size_pow2);

  /*    calculate offset for original data to be placed in vector            */
  
  data_offset = (array_size_pow2-sizes[xyzv[VIO_Y]])/2;
  
  /*    2nd now convolve this kernel with the rows of the dataset            */
  
  max_val = -FLT_MAX;
  min_val =  FLT_MAX;

  switch (ndim) {
  case 1: slice_limit = 0; break;
  case 2: slice_limit = sizes[xyzv[VIO_Z]]; break;
  case 3: slice_limit = sizes[xyzv[VIO_Z]]; break;
  }

  for (slice = 0; slice < slice_limit; slice++) {      /* for each slice */
    
    for (col = 0; col < sizes[xyzv[VIO_X]]; col++) {           /* for each col   */
      
      /*         f_ptr = fdata + slice*slice_size + row*sizeof(float); */
      
      f_ptr = fdata + slice*slice_size + col;
      
      
      memset(dat_vector,0,(2*array_size_pow2+1)*sizeof(float));
      
      for (row=0; row< sizes[xyzv[VIO_Y]]; row++) {        /* extract the col */
        dat_vector[1 +2*(row+data_offset) ] = *f_ptr;
        f_ptr += row_size;
      }
      
      
      fft1(dat_vector,array_size_pow2,1);
      muli_vects(dat_vecto2,dat_vector,kern,array_size_pow2);
      fft1(dat_vecto2,array_size_pow2,-1);
      
      f_ptr = fdata + slice*slice_size + col;
      for (row=0; row< sizes[xyzv[VIO_Y]]; row++) {        /* put the col back */
        
        vindex = 1 + 2*(row+data_offset);
        
        *f_ptr = dat_vecto2[vindex]/array_size_pow2;
        
        if (max_val<*f_ptr) max_val = *f_ptr;
        if (min_val>*f_ptr) min_val = *f_ptr;

        f_ptr += row_size;
        
        
      }
      
    }
    update_progress_report( &progress, slice+sizes[xyzv[VIO_Z]]+1 );
    
  }
  
  FREE(dat_vector);
  FREE(dat_vecto2);
  FREE(kern      );
  
  f_ptr = fdata;
  
  set_volume_real_range(data, min_val, max_val);


  printf("Making byte volume dy..." );
  for(slice=0; slice<sizes[xyzv[VIO_Z]]; slice++) {
    pos[xyzv[VIO_Z]] = slice;
    for(row=0; row<sizes[xyzv[VIO_Y]]; row++) {
      pos[xyzv[VIO_Y]] = row;
      for(col=0; col<sizes[xyzv[VIO_X]]; col++) {
        pos[xyzv[VIO_X]] = col;
        tmp = CONVERT_VALUE_TO_VOXEL(data, *f_ptr);
        SET_VOXEL_3D( data, pos[0], pos[1], pos[2], tmp);
        f_ptr++;
      }
    }
  }

  if (!curvature_flg)
    sprintf(full_outfilename,"%s_dy.mnc",outfile);
  else
    sprintf(full_outfilename,"%s_dyy.mnc",outfile);


  if (debug)
    print ("dy: min = %f, max = %f\n",min_val, max_val);

  status = output_modified_volume(full_outfilename, NC_UNSPECIFIED, FALSE, 
                                  min_val, max_val, data, infile, history, NULL);
  if (status != OK)
    print_error_and_line_num("problems writing dy gradient data...",__FILE__, __LINE__);
  
  
  /*--------------------------------------------------------------------------------------*/
  /*                 now do slices - i.e. the d/dz volume                                 */
  /*--------------------------------------------------------------------------------------*/
  
  /*-----------------------------------------------------------------------------*/
  /*             determine   size of data structures needed                      */


  set_file_position(ifd,0);
  status = io_binary_data(ifd,READ_FILE, fdata, sizeof(float), total_voxels);
  if (status != OK)
    print_error_and_line_num("problems reading binary data...\n",__FILE__, __LINE__);
  f_ptr = fdata;
  
  vector_size_data = sizes[xyzv[VIO_Z]];

  /*             array_size_pow2 will hold the size of the arrays for FFT convolution,
                 remember that ffts require arrays 2^n in length                          */
  
  array_size_pow2  = next_power_of_two(vector_size_data);
  array_size = 2*array_size_pow2+1;  /* allocate 2*, since each point is a    */
                                     /* complex number for FFT, and the plus 1*/
                                     /* is for the zero offset FFT routine    */
  
  ALLOC(dat_vector, array_size);
  ALLOC(dat_vecto2, array_size);
  ALLOC(kern      , array_size);

  if (ndim==1 || ndim==3) {
    
    /*    1st calculate kern array for FT of 1st derivitive */
    
    make_kernel_FT(kern,array_size_pow2, ABS(steps[xyzv[VIO_Z]]));

    if (curvature_flg)                /* 2nd derivative kernel */
      muli_vects(kern,kern,kern,array_size_pow2);
    
    /*    calculate offset for original data to be placed in vector            */
    
    data_offset = (array_size_pow2-sizes[xyzv[VIO_Z]])/2;
    
    /*    2nd now convolve this kernel with the slices of the dataset            */
    
    max_val = -FLT_MAX;
    min_val =  FLT_MAX;
    
    
    for (col = 0; col < sizes[xyzv[VIO_X]]; col++) {      /* for each column */
      
      for (row = 0; row < sizes[xyzv[VIO_Y]]; row++) {           /* for each row   */
        
        f_ptr = fdata + col*col_size + row;
        
        memset(dat_vector,0,(2*array_size_pow2+1)*sizeof(float));
        
        for (slice=0; slice< sizes[xyzv[VIO_Z]]; slice++) {        /* extract the slice vector */
          dat_vector[1 +2*(slice+data_offset) ] = *f_ptr;
          f_ptr += slice_size;
        }
        
        fft1(dat_vector,array_size_pow2,1);
        muli_vects(dat_vecto2,dat_vector,kern,array_size_pow2);
        fft1(dat_vecto2,array_size_pow2,-1);
        
        f_ptr = fdata + col*col_size + row;
        
        for (slice=0; slice< sizes[xyzv[VIO_Z]]; slice++) {        /* put the vector back */
          
          vindex = 1 + 2*(slice+data_offset);
          
          *f_ptr = dat_vecto2[vindex]/array_size_pow2;
          
          if (max_val<*f_ptr) max_val = *f_ptr;
          if (min_val>*f_ptr) min_val = *f_ptr;
          
          f_ptr += slice_size;
        }
        
        
      }
      update_progress_report( &progress, col + 2*sizes[xyzv[VIO_Z]] + 1 );
      
    }
    
  }  /* if ndim */
  else {
    max_val = 0.00001;
    min_val = 0.00000;
    
    for (col = 0; col < sizes[xyzv[VIO_X]]; col++) {      /* for each column */
      for (row = 0; row < sizes[xyzv[VIO_Y]]; row++) {           /* for each row   */
        *f_ptr = 0.0;
        f_ptr++;
      }
    }
  }
  
  
  FREE(dat_vector);
  FREE(dat_vecto2);
  FREE(kern      );
  
  
/* set up the correct info to copy the data back out in mnc */

  f_ptr = fdata;
  
  set_volume_real_range(data, min_val, max_val);


  printf("Making byte volume dz..." );
  for(slice=0; slice<sizes[xyzv[VIO_Z]]; slice++) {
    pos[xyzv[VIO_Z]] = slice;
    for(row=0; row<sizes[xyzv[VIO_Y]]; row++) {
      pos[xyzv[VIO_Y]] = row;
      for(col=0; col<sizes[xyzv[VIO_X]]; col++) {
        pos[xyzv[VIO_X]] = col;
        tmp = CONVERT_VALUE_TO_VOXEL(data, *f_ptr);
        SET_VOXEL_3D( data, pos[0], pos[1], pos[2], tmp);
        f_ptr++;
      }
    }
  }

  if (!curvature_flg)
    sprintf(full_outfilename,"%s_dz.mnc",outfile);
  else
    sprintf(full_outfilename,"%s_dzz.mnc",outfile);


  if (debug)
    print ("dz: min = %f, max = %f\n",min_val, max_val);

  status = output_modified_volume(full_outfilename, NC_UNSPECIFIED, FALSE, 
                                  min_val, max_val, data, infile, history, NULL);

  if (status != OK)
    print_error_and_line_num("problems writing dz gradient data...",__FILE__, __LINE__);



  terminate_progress_report( &progress );

  FREE(fdata);

  return(status);
  
}