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); }
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); }