Commit 48f356fa76f70ecaa96732fdfcc7cefb8c49ca34
1 parent
e318123b
bug fixes for FFT in stim::agilent_binary
Showing
5 changed files
with
81 additions
and
17 deletions
Show diff stats
1 | +function S = loadAgilent(filename) | ||
2 | + | ||
3 | +fid = fopen(filename); %open the file for reading | ||
4 | +fseek(fid, 9, 'bof'); %skip past the first 9 bytes of the header | ||
5 | + | ||
6 | +bands = fread(fid, 1, 'int16'); %read the number of bands in the file | ||
7 | +fseek(fid, 13, 'cof'); %skip the next 13 bytes in the header | ||
8 | + | ||
9 | +samples = fread(fid, 1, 'int16'); %read the number of samples (X) | ||
10 | +lines = fread(fid, 1, 'int16'); %read the number of lines (Y) | ||
11 | + | ||
12 | +fseek(fid, 1020, 'bof'); %skip past the entire header | ||
13 | +S = fread(fid, [samples lines*bands], 'float32'); %read all the data | ||
14 | +S = reshape(S, [samples, lines, bands]); | ||
15 | +fclose(fid); %close the file | ||
16 | + | ||
17 | + |
stim/envi/agilent_binary.h
@@ -35,26 +35,28 @@ public: | @@ -35,26 +35,28 @@ public: | ||
35 | void alloc(){ | 35 | void alloc(){ |
36 | ptr = (T*) malloc(bytes()); | 36 | ptr = (T*) malloc(bytes()); |
37 | } | 37 | } |
38 | - void alloc(short x, short y, short z){ | 38 | + void alloc(size_t x, size_t y, size_t z){ |
39 | R[0] = x; | 39 | R[0] = x; |
40 | R[1] = y; | 40 | R[1] = y; |
41 | R[2] = z; | 41 | R[2] = z; |
42 | alloc(); | 42 | alloc(); |
43 | } | 43 | } |
44 | 44 | ||
45 | + /// Create a deep copy of an agileng_binary object | ||
45 | void deep_copy(agilent_binary<T>* dst, const agilent_binary<T>* src){ | 46 | void deep_copy(agilent_binary<T>* dst, const agilent_binary<T>* src){ |
46 | dst->alloc(src->R[0], src->R[1], src->R[2]); //allocate memory | 47 | dst->alloc(src->R[0], src->R[1], src->R[2]); //allocate memory |
47 | memcpy(dst->ptr, src->ptr, bytes()); //copy the data | 48 | memcpy(dst->ptr, src->ptr, bytes()); //copy the data |
48 | memcpy(dst->Z, src->Z, sizeof(double) * 2); //copy the data z range | 49 | memcpy(dst->Z, src->Z, sizeof(double) * 2); //copy the data z range |
49 | } | 50 | } |
50 | 51 | ||
52 | + /// Default constructor, sets the resolution to zero and the data pointer to NULL | ||
51 | agilent_binary(){ | 53 | agilent_binary(){ |
52 | - memset(R, 0, sizeof(short) * 3); //set the resolution to zero | 54 | + memset(R, 0, sizeof(size_t) * 3); //set the resolution to zero |
53 | ptr = NULL; | 55 | ptr = NULL; |
54 | } | 56 | } |
55 | 57 | ||
56 | /// Constructor with resolution | 58 | /// Constructor with resolution |
57 | - agilent_binary(short x, short y, short z){ | 59 | + agilent_binary(size_t x, size_t y, size_t z){ |
58 | alloc(x, y, z); | 60 | alloc(x, y, z); |
59 | } | 61 | } |
60 | 62 | ||
@@ -109,13 +111,11 @@ public: | @@ -109,13 +111,11 @@ public: | ||
109 | 111 | ||
110 | char zero = 0; | 112 | char zero = 0; |
111 | for(size_t i = 0; i < 9; i++) outfile.write(&zero, 1); //write 9 zeros | 113 | for(size_t i = 0; i < 9; i++) outfile.write(&zero, 1); //write 9 zeros |
112 | - outfile.write((char*)&R[0], 2); | 114 | + outfile.write((char*)&R[2], 2); |
113 | for(size_t i = 0; i < 13; i++) outfile.write(&zero, 1); //write 13 zeros | 115 | for(size_t i = 0; i < 13; i++) outfile.write(&zero, 1); //write 13 zeros |
116 | + outfile.write((char*)&R[0], 2); | ||
114 | outfile.write((char*)&R[1], 2); | 117 | outfile.write((char*)&R[1], 2); |
115 | - outfile.write((char*)&R[2], 2); | ||
116 | for(size_t i = 0; i < 992; i++) outfile.write(&zero, 1); //write 992 zeros | 118 | for(size_t i = 0; i < 992; i++) outfile.write(&zero, 1); //write 992 zeros |
117 | - //char zerovec[1020]; | ||
118 | - //outfile.write((char*)zerovec, 1020); | ||
119 | 119 | ||
120 | size_t b = bytes(); | 120 | size_t b = bytes(); |
121 | outfile.write((char*)ptr, b); //write the data to the output file | 121 | outfile.write((char*)ptr, b); //write the data to the output file |
@@ -149,7 +149,7 @@ public: | @@ -149,7 +149,7 @@ public: | ||
149 | 149 | ||
150 | #ifdef CUDA_FOUND | 150 | #ifdef CUDA_FOUND |
151 | /// Perform an FFT and return a binary file with bands in the specified range | 151 | /// Perform an FFT and return a binary file with bands in the specified range |
152 | - agilent_binary<T> fft(float band_min, float band_max){ | 152 | + agilent_binary<T> fft(double band_min, double band_max, double ELWN = 15798, int UDR = 2){ |
153 | auto total_start = std::chrono::high_resolution_clock::now(); | 153 | auto total_start = std::chrono::high_resolution_clock::now(); |
154 | 154 | ||
155 | auto start = std::chrono::high_resolution_clock::now(); | 155 | auto start = std::chrono::high_resolution_clock::now(); |
@@ -177,8 +177,8 @@ public: | @@ -177,8 +177,8 @@ public: | ||
177 | 177 | ||
178 | start = std::chrono::high_resolution_clock::now(); | 178 | start = std::chrono::high_resolution_clock::now(); |
179 | int N[1]; //create an array with the interferogram size (required for cuFFT input) | 179 | int N[1]; //create an array with the interferogram size (required for cuFFT input) |
180 | - N[0] = R[2]; //set the only array value to the interferogram size | ||
181 | - if(cufftPlanMany(&plan, 1, N, NULL, 1, R[2], NULL, 1, R[2], CUFFT_R2C, batch) != CUFFT_SUCCESS){ | 180 | + N[0] = (int)R[2]; //set the only array value to the interferogram size |
181 | + if(cufftPlanMany(&plan, 1, N, NULL, 1, (int)R[2], NULL, 1, (int)R[2], CUFFT_R2C, (int)batch) != CUFFT_SUCCESS){ | ||
182 | std::cout<<"cuFFT Error: unable to create 1D plan."<<std::endl; | 182 | std::cout<<"cuFFT Error: unable to create 1D plan."<<std::endl; |
183 | exit(1); | 183 | exit(1); |
184 | } | 184 | } |
@@ -199,12 +199,13 @@ public: | @@ -199,12 +199,13 @@ public: | ||
199 | std::complex<T>* cpu_fft = (std::complex<T>*) malloc( R[0] * R[1] * (R[2]/2+1) * sizeof(std::complex<T>) ); | 199 | std::complex<T>* cpu_fft = (std::complex<T>*) malloc( R[0] * R[1] * (R[2]/2+1) * sizeof(std::complex<T>) ); |
200 | HANDLE_ERROR(cudaMemcpy(cpu_fft, gpu_fft, R[0] * R[1] * (R[2]/2+1) * sizeof(cufftComplex), cudaMemcpyDeviceToHost)); //copy data from the host to the device | 200 | HANDLE_ERROR(cudaMemcpy(cpu_fft, gpu_fft, R[0] * R[1] * (R[2]/2+1) * sizeof(cufftComplex), cudaMemcpyDeviceToHost)); //copy data from the host to the device |
201 | 201 | ||
202 | - double int_delta = 0.00012656; //interferogram sample spacing in centimeters | 202 | + //double int_delta = 0.00012656; //interferogram sample spacing in centimeters |
203 | + double int_delta = (1.0 / ELWN) * ((double)UDR / 2.0); //calculate the interferogram spacing | ||
203 | double int_length = int_delta * R[2]; //interferogram length in centimeters | 204 | double int_length = int_delta * R[2]; //interferogram length in centimeters |
204 | double fft_delta = 1/int_length; //spectrum spacing (in inverse centimeters, wavenumber | 205 | double fft_delta = 1/int_length; //spectrum spacing (in inverse centimeters, wavenumber |
205 | 206 | ||
206 | - size_t start_i = std::ceil(band_min / fft_delta); //calculate the first band to store | ||
207 | - size_t size_i = std::floor(band_max / fft_delta) - start_i; //calculate the number of bands to store | 207 | + size_t start_i = (size_t)std::ceil(band_min / fft_delta); //calculate the first band to store |
208 | + size_t size_i = (size_t)std::floor(band_max / fft_delta) - start_i; //calculate the number of bands to store | ||
208 | size_t end_i = start_i + size_i; //last band number | 209 | size_t end_i = start_i + size_i; //last band number |
209 | agilent_binary<T> result(R[0], R[1], size_i); | 210 | agilent_binary<T> result(R[0], R[1], size_i); |
210 | result.Z[0] = start_i * fft_delta; //set the range for the FFT result | 211 | result.Z[0] = start_i * fft_delta; //set the range for the FFT result |
stim/envi/envi.h
@@ -7,6 +7,7 @@ | @@ -7,6 +7,7 @@ | ||
7 | #include "../envi/bil.h" | 7 | #include "../envi/bil.h" |
8 | #include "../math/fd_coefficients.h" | 8 | #include "../math/fd_coefficients.h" |
9 | #include <iostream> | 9 | #include <iostream> |
10 | +#include <fstream> | ||
10 | //#include "../image/image.h" | 11 | //#include "../image/image.h" |
11 | 12 | ||
12 | namespace stim{ | 13 | namespace stim{ |
@@ -224,6 +225,37 @@ public: | @@ -224,6 +225,37 @@ public: | ||
224 | 225 | ||
225 | } | 226 | } |
226 | 227 | ||
228 | + /// Open an Agilent binary file as an ENVI stream | ||
229 | + bool open_agilent(std::string filename){ | ||
230 | + fname = filename; //store the file name | ||
231 | + | ||
232 | + //Open the file temporarily to get the header information | ||
233 | + FILE* f = fopen(filename.c_str(), "r"); //open the binary file for reading | ||
234 | + if(f == NULL) return false; //return false if no file is opened | ||
235 | + | ||
236 | + fseek(f, 9, SEEK_SET); //seek to the number of bands | ||
237 | + short b; //allocate space for the number of bands | ||
238 | + fread(&b, sizeof(short), 1, f); //read the number of bands | ||
239 | + fseek(f, 13, SEEK_CUR); //skip the the x and y dimensions | ||
240 | + short x, y; | ||
241 | + fread(&x, sizeof(short), 1, f); //read the image x and y size | ||
242 | + fread(&y, sizeof(short), 1, f); | ||
243 | + fclose(f); //close the file | ||
244 | + | ||
245 | + //store the information from the Agilent header in the ENVI header | ||
246 | + header.bands = b; | ||
247 | + header.samples = x; | ||
248 | + header.lines = y; | ||
249 | + header.data_type = envi_header::float32; //all values are 32-bit floats | ||
250 | + header.header_offset = 1020; //number of bytes in an Agilent binary header | ||
251 | + header.interleave = envi_header::BSQ; //all Agilent binary files are BSQ | ||
252 | + | ||
253 | + allocate(); //allocate the streaming file object | ||
254 | + open(); //open the file for streaming | ||
255 | + | ||
256 | + return true; | ||
257 | + } | ||
258 | + | ||
227 | /// Open an existing ENVI file given the filename and a header structure | 259 | /// Open an existing ENVI file given the filename and a header structure |
228 | 260 | ||
229 | /// @param filename is the name of the ENVI binary file | 261 | /// @param filename is the name of the ENVI binary file |
@@ -257,7 +289,6 @@ public: | @@ -257,7 +289,6 @@ public: | ||
257 | //header.load(headername); | 289 | //header.load(headername); |
258 | 290 | ||
259 | return open(filename, h); | 291 | return open(filename, h); |
260 | - | ||
261 | } | 292 | } |
262 | 293 | ||
263 | /// Normalize a hyperspectral ENVI file given a band number and threshold. | 294 | /// Normalize a hyperspectral ENVI file given a band number and threshold. |
stim/envi/envi_header.h
@@ -440,9 +440,24 @@ struct envi_header | @@ -440,9 +440,24 @@ struct envi_header | ||
440 | } | 440 | } |
441 | 441 | ||
442 | /// Convert a wavelength to a band index (or a pair of surrounding band indices) | 442 | /// Convert a wavelength to a band index (or a pair of surrounding band indices) |
443 | + /// if the file doesn't specify wavelengths, w is assumed to be a band index | ||
443 | std::vector<size_t> band_index(double w){ | 444 | std::vector<size_t> band_index(double w){ |
444 | std::vector<size_t> idx; //create an empty array of indices | 445 | std::vector<size_t> idx; //create an empty array of indices |
445 | - if(w < wavelength[0] || w > wavelength[bands-1]) return idx; //if the wavelength range is outside of the file, return an empty array | 446 | + if(wavelength.size() == 0){ //if a wavelength vector doesn't exist, assume the passed value is a band |
447 | + if(w < 0 || w > bands-1) return idx; //if the band is outside the given band range, return an empty vector | ||
448 | + size_t low, high; //allocate space for the floor and ceiling | ||
449 | + low = std::floor(w); //calculate the floor | ||
450 | + high = std::ceil(w); //calculate the ceiling | ||
451 | + if(low == high) //if the floor and ceiling are the same | ||
452 | + idx.push_back(low); //return a vector with one element (the given w matches a band exactly) | ||
453 | + else{ | ||
454 | + idx.resize(2); //otherwise return the floor and ceiling | ||
455 | + idx[0] = low; | ||
456 | + idx[1] = high; | ||
457 | + } | ||
458 | + return idx; | ||
459 | + } | ||
460 | + else if(w < wavelength[0] || w > wavelength[bands-1]) return idx; //if the wavelength range is outside of the file, return an empty array | ||
446 | 461 | ||
447 | for(size_t b = 0; b < bands; b++){ //for each band in the wavelength vector | 462 | for(size_t b = 0; b < bands; b++){ //for each band in the wavelength vector |
448 | if(wavelength[b] == w){ //if an exact match is found | 463 | if(wavelength[b] == w){ //if an exact match is found |
stim/math/vec3.h
@@ -216,7 +216,7 @@ public: | @@ -216,7 +216,7 @@ public: | ||
216 | return result; | 216 | return result; |
217 | } | 217 | } |
218 | 218 | ||
219 | -#ifndef __NVCC__ | 219 | +//#ifndef __NVCC__ |
220 | /// Outputs the vector as a string | 220 | /// Outputs the vector as a string |
221 | std::string str() const{ | 221 | std::string str() const{ |
222 | std::stringstream ss; | 222 | std::stringstream ss; |
@@ -234,7 +234,7 @@ public: | @@ -234,7 +234,7 @@ public: | ||
234 | 234 | ||
235 | return ss.str(); | 235 | return ss.str(); |
236 | } | 236 | } |
237 | -#endif | 237 | +//#endif |
238 | 238 | ||
239 | size_t size(){ return 3; } | 239 | size_t size(){ return 3; } |
240 | 240 |