Blame view

stim/envi/bip.h 32.9 KB
e8eb202f   David Mayerich   added a new ENVI ...
1
2
3
4
  #ifndef STIM_BIP_H
  #define STIM_BIP_H
  
  #include "../envi/envi_header.h"
6aa04ba2   David Mayerich   interleave types
5
  #include "../envi/bil.h"
88c3e636   heziqi   Ziqi added big.h
6
7
8
9
  #include "../envi/binary.h"
  #include <cstring>
  #include <utility>
  
8a86bd56   David Mayerich   changed rts names...
10
  namespace stim{
88c3e636   heziqi   Ziqi added big.h
11
  
a23c4132   David Mayerich   Doxygen comments ...
12
13
14
15
16
17
18
19
  /**
  	The BIP class represents a 3-dimensional binary file stored using band interleaved by pixel (BIP) image encoding. The binary file is stored
  	such that Z-X "frames" are stored sequentially to form an image stack along the y-axis. When accessing the data sequentially on disk,
  	the dimensions read, from fastest to slowest, are Z, X, Y.
  
  	This class is optimized for data streaming, and therefore supports extremely large (terabyte-scale) files. Data is loaded from disk
  	on request. Functions used to access data are written to support efficient reading.
  */
88c3e636   heziqi   Ziqi added big.h
20
21
22
23
24
25
  template <typename T>
  
  class bip: public binary<T> {
  
  protected:
  	
6708cc25   heziqi   Ziqi added envi c...
26
27
28
  	
  	std::vector<double> w; //band wavelength
  	unsigned int offset;		//header offset
88c3e636   heziqi   Ziqi added big.h
29
  
724ec347   David Mayerich   simplified the EN...
30
31
32
33
34
35
36
37
38
39
  	unsigned long X(){
  		return R[1];
  	}
  	unsigned long Y(){
  		return R[2];
  	}
  	unsigned long Z(){
  		return R[0];
  	}
  
cbce396e   David Mayerich   added support for...
40
41
  	using binary<T>::thread_data;
  
88c3e636   heziqi   Ziqi added big.h
42
43
44
45
  public:
  
  	using binary<T>::open;
  	using binary<T>::file;
6708cc25   heziqi   Ziqi added envi c...
46
  	using binary<T>::R;
724ec347   David Mayerich   simplified the EN...
47
  	using binary<T>::read_line_12;
88c3e636   heziqi   Ziqi added big.h
48
  
a23c4132   David Mayerich   Doxygen comments ...
49
50
51
52
53
54
55
56
  	/// Open a data file for reading using the class interface.
  
  	/// @param filename is the name of the binary file on disk
  	/// @param X is the number of samples along dimension 1
  	/// @param Y is the number of samples (lines) along dimension 2
  	/// @param B is the number of samples (bands) along dimension 3
  	/// @param header_offset is the number of bytes (if any) in the binary header
  	/// @param wavelengths is an optional STL vector of size B specifying a numerical label for each band
6708cc25   heziqi   Ziqi added envi c...
57
  	bool open(std::string filename, unsigned int X, unsigned int Y, unsigned int B, unsigned int header_offset, std::vector<double> wavelengths){
88c3e636   heziqi   Ziqi added big.h
58
  
6708cc25   heziqi   Ziqi added envi c...
59
60
61
62
  		//copy the wavelengths to the BSQ file structure
  		w = wavelengths;
  		//copy the offset to the structure
  		offset = header_offset;
88c3e636   heziqi   Ziqi added big.h
63
  
724ec347   David Mayerich   simplified the EN...
64
  		return open(filename, vec<unsigned int>(B, X, Y), header_offset);
88c3e636   heziqi   Ziqi added big.h
65
66
67
  		
  	}
  
a23c4132   David Mayerich   Doxygen comments ...
68
69
70
71
  	/// Retrieve a single band (based on index) and stores it in pre-allocated memory.
  
  	/// @param p is a pointer to an allocated region of memory at least X * Y * sizeof(T) in size.
  	/// @param page <= B is the integer number of the band to be copied.
88c3e636   heziqi   Ziqi added big.h
72
  	bool band_index( T * p, unsigned int page){
724ec347   David Mayerich   simplified the EN...
73
  		return binary<T>::read_plane_0(p, page);
88c3e636   heziqi   Ziqi added big.h
74
75
  	}
  
a23c4132   David Mayerich   Doxygen comments ...
76
77
78
79
  	/// Retrieve a single band (by numerical label) and stores it in pre-allocated memory.
  
  	/// @param p is a pointer to an allocated region of memory at least X * Y * sizeof(T) in size.
  	/// @param wavelength is a floating point value (usually a wavelength in spectral data) used as a label for the band to be copied.
e933c14e   David Mayerich   cleaned up the code
80
  	bool band( T * p, double wavelength){
88c3e636   heziqi   Ziqi added big.h
81
  
ee4dea28   David Mayerich   fixed errors in c...
82
83
84
85
  		//if there are no wavelengths in the BSQ file
  		if(w.size() == 0)
  			return band_index(p, (unsigned int)wavelength);
  
724ec347   David Mayerich   simplified the EN...
86
  		unsigned int XY = X() * Y();	//calculate the number of pixels in a band
88c3e636   heziqi   Ziqi added big.h
87
88
  
  		unsigned page=0;                      //bands around the wavelength
517876d6   heziqi   metrics finished ...
89
  
88c3e636   heziqi   Ziqi added big.h
90
91
92
93
  
  		//get the bands numbers around the wavelength
  
  		//if wavelength is smaller than the first one in header file
6708cc25   heziqi   Ziqi added envi c...
94
  		if ( w[page] > wavelength ){
88c3e636   heziqi   Ziqi added big.h
95
96
97
98
  			band_index(p, page);
  			return true;
  		}
  
6708cc25   heziqi   Ziqi added envi c...
99
  		while( w[page] < wavelength )
88c3e636   heziqi   Ziqi added big.h
100
101
102
  		{
  			page++;
  			//if wavelength is larger than the last wavelength in header file
724ec347   David Mayerich   simplified the EN...
103
104
  			if (page == Z()) {
  				band_index(p, Z()-1);
88c3e636   heziqi   Ziqi added big.h
105
106
107
  				return true;
  			}
  		}
6708cc25   heziqi   Ziqi added envi c...
108
  		if ( wavelength < w[page] )
88c3e636   heziqi   Ziqi added big.h
109
  		{
517876d6   heziqi   metrics finished ...
110
111
  			T * p1;
  			T * p2;
88c3e636   heziqi   Ziqi added big.h
112
113
114
115
116
  			p1=(T*)malloc( XY * sizeof(T));                     //memory allocation
  			p2=(T*)malloc( XY * sizeof(T));
  			band_index(p1, page - 1);
  			band_index(p2, page );
  			for(unsigned i=0; i < XY; i++){
6708cc25   heziqi   Ziqi added envi c...
117
  				double r = (double) (wavelength - w[page-1]) / (double) (w[page] - w[page-1]);
88c3e636   heziqi   Ziqi added big.h
118
119
  				p[i] = (p2[i] - p1[i]) * r + p1[i];
  			}
517876d6   heziqi   metrics finished ...
120
121
  			free(p1);
  			free(p2);
88c3e636   heziqi   Ziqi added big.h
122
123
124
125
126
127
  		}
  		else                           //if the wavelength is equal to a wavelength in header file
  		{
  			band_index(p, page);
  		}
  
88c3e636   heziqi   Ziqi added big.h
128
129
  		return true;
  	}
724ec347   David Mayerich   simplified the EN...
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
  
  	/// Retrieve a single spectrum (Z-axis line) at a given (x, y) location and stores it in pre-allocated memory.
  
  	/// @param p is a pointer to pre-allocated memory at least B * sizeof(T) in size.
  	/// @param x is the x-coordinate (dimension 1) of the spectrum.
  	/// @param y is the y-coordinate (dimension 2) of the spectrum.
  	bool spectrum(T * p, unsigned x, unsigned y){
  		return read_line_12(p, x, y);				//read a line in the binary YZ plane (dimension order for BIP is ZXY)
  	}
  
  	/// Retrieves a band of x values from a given xz plane.
  
  	/// @param p is a pointer to pre-allocated memory at least X * sizeof(T) in size
  	/// @param c is a pointer to an existing XZ plane (size X*Z*sizeof(T))
  	/// @param wavelength is the wavelength of X values to retrieve
  	bool read_x_from_xz(T* p, T* c, double wavelength)
11f177d5   heziqi   Ziqi added functi...
146
  	{
724ec347   David Mayerich   simplified the EN...
147
  		unsigned int B = Z();
11f177d5   heziqi   Ziqi added functi...
148
149
  
  		unsigned page=0;                      //samples around the wavelength
517876d6   heziqi   metrics finished ...
150
  
11f177d5   heziqi   Ziqi added functi...
151
152
153
154
  
  		//get the bands numbers around the wavelength
  
  		//if wavelength is smaller than the first one in header file
6708cc25   heziqi   Ziqi added envi c...
155
  		if ( w[page] > wavelength ){
724ec347   David Mayerich   simplified the EN...
156
  			for(unsigned j = 0; j < X(); j++)
11f177d5   heziqi   Ziqi added functi...
157
158
159
160
161
162
  			{
  				p[j] = c[j * B];
  			}		
  			return true;
  		}
  
6708cc25   heziqi   Ziqi added envi c...
163
  		while( w[page] < wavelength )
11f177d5   heziqi   Ziqi added functi...
164
165
166
167
  		{
  			page++;
  			//if wavelength is larger than the last wavelength in header file
  			if (page == B) {
724ec347   David Mayerich   simplified the EN...
168
  				for(unsigned j = 0; j < X(); j++)
11f177d5   heziqi   Ziqi added functi...
169
170
171
172
173
174
  				{
  					p[j] = c[(j + 1) * B - 1];
  				}
  				return true;
  			}
  		}
6708cc25   heziqi   Ziqi added envi c...
175
  		if ( wavelength < w[page] )
11f177d5   heziqi   Ziqi added functi...
176
  		{
517876d6   heziqi   metrics finished ...
177
178
  			T * p1;
  			T * p2;
724ec347   David Mayerich   simplified the EN...
179
180
  			p1=(T*)malloc( X() * sizeof(T));                     //memory allocation
  			p2=(T*)malloc( X() * sizeof(T));
11f177d5   heziqi   Ziqi added functi...
181
  			//band_index(p1, page - 1);
724ec347   David Mayerich   simplified the EN...
182
  			for(unsigned j = 0; j < X(); j++)
11f177d5   heziqi   Ziqi added functi...
183
184
185
186
  			{
  				p1[j] = c[j * B + page - 1];
  			}
  			//band_index(p2, page );
724ec347   David Mayerich   simplified the EN...
187
  			for(unsigned j = 0; j < X(); j++)
11f177d5   heziqi   Ziqi added functi...
188
189
190
191
  			{
  				p2[j] = c[j * B + page];
  			}
  			
724ec347   David Mayerich   simplified the EN...
192
  			for(unsigned i=0; i < X(); i++){
6708cc25   heziqi   Ziqi added envi c...
193
  				double r = (double) (wavelength - w[page-1]) / (double) (w[page] - w[page-1]);
11f177d5   heziqi   Ziqi added functi...
194
195
  				p[i] = (p2[i] - p1[i]) * r + p1[i];
  			}
517876d6   heziqi   metrics finished ...
196
197
  			free(p1);
  			free(p2);
11f177d5   heziqi   Ziqi added functi...
198
199
200
201
  		}
  		else                           //if the wavelength is equal to a wavelength in header file
  		{
  			//band_index(p, page);
724ec347   David Mayerich   simplified the EN...
202
  			for(unsigned j = 0; j < X(); j++)
11f177d5   heziqi   Ziqi added functi...
203
204
205
206
207
208
209
  			{
  				p[j] = c[j * B + page];
  			}
  		}
  
  		return true;		
  	}
bfe9c6db   heziqi   added feature_mat...
210
  
a23c4132   David Mayerich   Doxygen comments ...
211
212
213
214
  	/// Retrieve a single pixel and stores it in pre-allocated memory.
  
  	/// @param p is a pointer to pre-allocated memory at least sizeof(T) in size.
  	/// @param n is an integer index to the pixel using linear array indexing.
bfe9c6db   heziqi   added feature_mat...
215
216
  	bool pixel(T * p, unsigned n){
  
724ec347   David Mayerich   simplified the EN...
217
  		unsigned bandnum = X() * Y();		//calculate numbers in one band
bfe9c6db   heziqi   added feature_mat...
218
219
220
221
222
  		if ( n >= bandnum){							//make sure the pixel number is right
  			std::cout<<"ERROR: sample or line out of range"<<std::endl;
  			return false;
  		}
  
724ec347   David Mayerich   simplified the EN...
223
224
225
  		file.seekg(n * Z() * sizeof(T), std::ios::beg);           //point to the certain pixel
  		file.read((char *)p, sizeof(T) * Z());
  		return true;
bfe9c6db   heziqi   added feature_mat...
226
  	}
11f177d5   heziqi   Ziqi added functi...
227
228
  	
  	//given a Y ,return a ZX slice
724ec347   David Mayerich   simplified the EN...
229
230
  	bool read_plane_y(T * p, unsigned y){
  		return binary<T>::read_plane_2(p, y);
11f177d5   heziqi   Ziqi added functi...
231
232
  	}
  		
a23c4132   David Mayerich   Doxygen comments ...
233
234
235
236
  	/// Perform baseline correction given a list of baseline points and stores the result in a new BSQ file.
  
  	/// @param outname is the name of the output file used to store the resulting baseline-corrected data.
  	/// @param wls is the list of baseline points based on band labels.	
11f177d5   heziqi   Ziqi added functi...
237
238
  	bool baseline(std::string outname, std::vector<double> wls){
  	
88c3e636   heziqi   Ziqi added big.h
239
240
241
242
243
244
  		unsigned N = wls.size();			//get the number of baseline points
  		
  		std::ofstream target(outname.c_str(), std::ios::binary);	//open the target binary file
  		std::string headername = outname + ".hdr";              //the header file name		
  		
  		//simplify image resolution
724ec347   David Mayerich   simplified the EN...
245
  		unsigned int ZX = Z() * X();		//calculate the number of points in a Y slice
11f177d5   heziqi   Ziqi added functi...
246
  		unsigned int L = ZX * sizeof(T);			//calculate the number of bytes of a Y slice
724ec347   David Mayerich   simplified the EN...
247
  		unsigned int B = Z();
88c3e636   heziqi   Ziqi added big.h
248
  		
11f177d5   heziqi   Ziqi added functi...
249
250
  		T* c;			//pointer to the current Y slice
  		c = (T*)malloc(L);  //memory allocation
88c3e636   heziqi   Ziqi added big.h
251
  		
11f177d5   heziqi   Ziqi added functi...
252
253
  		T* a;			//pointer to the two YZ lines surrounding the current YZ line
  		T* b;
88c3e636   heziqi   Ziqi added big.h
254
  		
724ec347   David Mayerich   simplified the EN...
255
256
  		a = (T*)malloc(X() * sizeof(T));
  		b = (T*)malloc(X() * sizeof(T));
88c3e636   heziqi   Ziqi added big.h
257
  
88c3e636   heziqi   Ziqi added big.h
258
259
260
  
  		double ai, bi;	//stores the two baseline points wavelength surrounding the current band
  		double ci;		//stores the current band's wavelength
f6169dea   heziqi   Ziqi completed bi...
261
  		unsigned control;
88c3e636   heziqi   Ziqi added big.h
262
  
88c3e636   heziqi   Ziqi added big.h
263
264
265
266
  		if (a == NULL || b == NULL || c == NULL){
  			std::cout<<"ERROR: error allocating memory";
  			exit(1);
  		}
11f177d5   heziqi   Ziqi added functi...
267
268
  	//	loop start	correct every y slice
  		
724ec347   David Mayerich   simplified the EN...
269
  		for (unsigned k =0; k < Y(); k++)
11f177d5   heziqi   Ziqi added functi...
270
271
  		{
  			//get the current y slice
724ec347   David Mayerich   simplified the EN...
272
  			read_plane_y(c, k);
11f177d5   heziqi   Ziqi added functi...
273
274
  		
  			//initialize lownum, highnum, low, high		
f6169dea   heziqi   Ziqi completed bi...
275
  			control=0;
6708cc25   heziqi   Ziqi added envi c...
276
  			ai = w[0];
11f177d5   heziqi   Ziqi added functi...
277
  			//if no baseline point is specified at band 0,
88c3e636   heziqi   Ziqi added big.h
278
  			//set the baseline point at band 0 to 0
6708cc25   heziqi   Ziqi added envi c...
279
  			if(wls[0] != w[0]){
11f177d5   heziqi   Ziqi added functi...
280
  				bi = wls[control];			
724ec347   David Mayerich   simplified the EN...
281
  				memset(a, (char)0, X() * sizeof(T) );
11f177d5   heziqi   Ziqi added functi...
282
283
284
285
  			}
  			//else get the low band
  			else{
  				control++;
724ec347   David Mayerich   simplified the EN...
286
  				read_x_from_xz(a, c, ai);
11f177d5   heziqi   Ziqi added functi...
287
288
289
  				bi = wls[control];
  			}
  			//get the high band
724ec347   David Mayerich   simplified the EN...
290
  			read_x_from_xz(b, c, bi);
11f177d5   heziqi   Ziqi added functi...
291
292
293
294
  		
  			//correct every YZ line
  			
  			for(unsigned cii = 0; cii < B; cii++){
11f177d5   heziqi   Ziqi added functi...
295
  				//update baseline points, if necessary
6708cc25   heziqi   Ziqi added envi c...
296
  				if( w[cii] >= bi && cii != B - 1) {
11f177d5   heziqi   Ziqi added functi...
297
298
299
300
301
302
303
304
305
  					//if the high band is now on the last BL point?
  					if (control != N-1) {
  	
  						control++;		//increment the index
  	
  						std::swap(a, b);	//swap the baseline band pointers
  	
  						ai = bi;
  						bi = wls[control];
724ec347   David Mayerich   simplified the EN...
306
  						read_x_from_xz(b, c, bi);
11f177d5   heziqi   Ziqi added functi...
307
308
309
  	
  					}
  					//if the last BL point on the last band of the file?
6708cc25   heziqi   Ziqi added envi c...
310
  					else if ( wls[control] < w[B - 1]) {
11f177d5   heziqi   Ziqi added functi...
311
312
313
  	
  						std::swap(a, b);	//swap the baseline band pointers
  	
724ec347   David Mayerich   simplified the EN...
314
  						memset(b, (char)0, X() * sizeof(T) );	//clear the high band
11f177d5   heziqi   Ziqi added functi...
315
316
  	
  						ai = bi;
6708cc25   heziqi   Ziqi added envi c...
317
  						bi = w[B - 1];
11f177d5   heziqi   Ziqi added functi...
318
  					}
88c3e636   heziqi   Ziqi added big.h
319
  				}
88c3e636   heziqi   Ziqi added big.h
320
  
6708cc25   heziqi   Ziqi added envi c...
321
  				ci = w[cii];
11f177d5   heziqi   Ziqi added functi...
322
323
  			
  				//perform the baseline correction
724ec347   David Mayerich   simplified the EN...
324
  				for(unsigned i=0; i < X(); i++)
11f177d5   heziqi   Ziqi added functi...
325
326
  				{
  					double r = (double) (ci - ai) / (double) (bi - ai);
92e4cf05   heziqi   include file fixed
327
  					c[i * B + cii] =(T) ( c[i * B + cii] - (b[i] - a[i]) * r - a[i] );
11f177d5   heziqi   Ziqi added functi...
328
329
330
  				}
  				
  			}//loop for YZ line end  
11f177d5   heziqi   Ziqi added functi...
331
  			target.write(reinterpret_cast<const char*>(c), L);   //write the corrected data into destination	
cbce396e   David Mayerich   added support for...
332
333
  
  			thread_data = (double)k / Y() * 100;
11f177d5   heziqi   Ziqi added functi...
334
  		}//loop for Y slice end
88c3e636   heziqi   Ziqi added big.h
335
  		
6708cc25   heziqi   Ziqi added envi c...
336
  
88c3e636   heziqi   Ziqi added big.h
337
338
339
340
341
  		
  		free(a);
  		free(b);
  		free(c);
  		target.close();
cbce396e   David Mayerich   added support for...
342
343
  
  		thread_data = 100;
11f177d5   heziqi   Ziqi added functi...
344
345
  		return true;	
  		
88c3e636   heziqi   Ziqi added big.h
346
  	}
11f177d5   heziqi   Ziqi added functi...
347
  		
a23c4132   David Mayerich   Doxygen comments ...
348
349
350
351
352
  	/// Normalize all spectra based on the value of a single band, storing the result in a new BSQ file.
  
  	/// @param outname is the name of the output file used to store the resulting baseline-corrected data.
  	///	@param w is the label specifying the band that the hyperspectral image will be normalized to.
  	///	@param t is a threshold specified such that a spectrum with a value at w less than t is set to zero. Setting this threshold allows the user to limit division by extremely small numbers.
93503ec6   David Mayerich   allowed masking d...
353
  	bool normalize(std::string outname, double w, double t = 0.0)
88c3e636   heziqi   Ziqi added big.h
354
  	{
724ec347   David Mayerich   simplified the EN...
355
356
357
  		unsigned int B = Z();		//calculate the number of bands
  		unsigned int ZX = Z() * X();
  		unsigned int XY = X() * Y();	//calculate the number of pixels in a band
11f177d5   heziqi   Ziqi added functi...
358
359
  		unsigned int S = XY * sizeof(T);		//calculate the number of bytes in a band		
  		unsigned int L = ZX * sizeof(T);
88c3e636   heziqi   Ziqi added big.h
360
361
362
363
  
  		std::ofstream target(outname.c_str(), std::ios::binary);	//open the target binary file
  		std::string headername = outname + ".hdr";              //the header file name
  
11f177d5   heziqi   Ziqi added functi...
364
365
  		T * c;				//pointer to the current ZX slice
  		T * b;				//pointer to the standard band
88c3e636   heziqi   Ziqi added big.h
366
367
  
  		b = (T*)malloc( S );     //memory allocation
11f177d5   heziqi   Ziqi added functi...
368
  		c = (T*)malloc( L ); 
88c3e636   heziqi   Ziqi added big.h
369
  
e933c14e   David Mayerich   cleaned up the code
370
  		band(b, w);             //get the certain band into memory
88c3e636   heziqi   Ziqi added big.h
371
  
724ec347   David Mayerich   simplified the EN...
372
  		for(unsigned j = 0; j < Y(); j++)
88c3e636   heziqi   Ziqi added big.h
373
  		{
724ec347   David Mayerich   simplified the EN...
374
375
376
  			read_plane_y(c, j);
  			unsigned jX = j * X();		//to avoid calculating it many times
  			for(unsigned i = 0; i < X(); i++)
88c3e636   heziqi   Ziqi added big.h
377
  			{
f6169dea   heziqi   Ziqi completed bi...
378
  				unsigned iB = i * B;		
11f177d5   heziqi   Ziqi added functi...
379
380
  				for(unsigned m = 0; m < B; m++)
  				{
93503ec6   David Mayerich   allowed masking d...
381
382
383
384
  					if( b[i+jX] < t )
  						c[m + iB] = (T)0.0;
  					else
  						c[m + iB] = c[m + iB] / b[i + jX];			//perform normalization
11f177d5   heziqi   Ziqi added functi...
385
  				}								
88c3e636   heziqi   Ziqi added big.h
386
  			}
11f177d5   heziqi   Ziqi added functi...
387
  			target.write(reinterpret_cast<const char*>(c), L);   //write normalized data into destination
cbce396e   David Mayerich   added support for...
388
389
  
  			thread_data = (double) j / Y() * 100;
88c3e636   heziqi   Ziqi added big.h
390
  		}
6708cc25   heziqi   Ziqi added envi c...
391
  
88c3e636   heziqi   Ziqi added big.h
392
393
394
395
  		
  		free(b);
  		free(c);
  		target.close();
cbce396e   David Mayerich   added support for...
396
  		thread_data = 100;
88c3e636   heziqi   Ziqi added big.h
397
398
399
  		return true;
  	}
  	
a23c4132   David Mayerich   Doxygen comments ...
400
401
402
  	/// Convert the current BIP file to a BSQ file with the specified file name.
  
  	/// @param outname is the name of the output BSQ file to be saved to disk.
11f177d5   heziqi   Ziqi added functi...
403
  	bool bsq(std::string outname)
f6169dea   heziqi   Ziqi completed bi...
404
405
406
407
408
409
  	{	
  		std::string temp = outname + "_temp";
  		std::string headtemp = temp + ".hdr";
  		//first creat a temporary bil file and convert bip file to bil file
  		bil(temp);
  
8a86bd56   David Mayerich   changed rts names...
410
  		stim::bil<T> n;
724ec347   David Mayerich   simplified the EN...
411
  		if(n.open(temp, X(), Y(), Z(), offset, w)==false){        //open infile
f6169dea   heziqi   Ziqi completed bi...
412
413
414
415
416
417
418
419
420
421
422
  			std::cout<<"ERROR: unable to open input file"<<std::endl;
  			exit(1);
  		}
  		//then convert bil file to bsq file
  		n.bsq(outname);
  		n.close();
  		remove(temp.c_str());
  		remove(headtemp.c_str());
  		return true;
  	}
  
a23c4132   David Mayerich   Doxygen comments ...
423
424
425
  	/// Convert the current BIP file to a BIL file with the specified file name.
  
  	/// @param outname is the name of the output BIL file to be saved to disk.
f6169dea   heziqi   Ziqi completed bi...
426
  	bool bil(std::string outname)
11f177d5   heziqi   Ziqi added functi...
427
  	{
724ec347   David Mayerich   simplified the EN...
428
  		unsigned int S = X() * Z() * sizeof(T);		//calculate the number of bytes in a ZX slice
11f177d5   heziqi   Ziqi added functi...
429
430
431
432
  		
  		std::ofstream target(outname.c_str(), std::ios::binary);
  		std::string headername = outname + ".hdr";
  		
f6169dea   heziqi   Ziqi completed bi...
433
  		T * p;			//pointer to the current ZX slice for bip file
11f177d5   heziqi   Ziqi added functi...
434
  		p = (T*)malloc(S);
f6169dea   heziqi   Ziqi completed bi...
435
436
  		T * q;			//pointer to the current XZ slice for bil file
  		q = (T*)malloc(S);
11f177d5   heziqi   Ziqi added functi...
437
  		
724ec347   David Mayerich   simplified the EN...
438
  		for ( unsigned i = 0; i < Y(); i++)
11f177d5   heziqi   Ziqi added functi...
439
  		{			
724ec347   David Mayerich   simplified the EN...
440
441
  			read_plane_y(p, i);
  			for ( unsigned k = 0; k < Z(); k++)
f6169dea   heziqi   Ziqi completed bi...
442
  			{
724ec347   David Mayerich   simplified the EN...
443
444
445
  				unsigned ks = k * X();
  				for ( unsigned j = 0; j < X(); j++)
  					q[ks + j] = p[k + j * Z()];
cbce396e   David Mayerich   added support for...
446
447
  
  				thread_data = (double)(i * Z() + k) / (Y() * Z()) * 100;
f6169dea   heziqi   Ziqi completed bi...
448
449
  			}
  			target.write(reinterpret_cast<const char*>(q), S);   //write a band data into target file	
11f177d5   heziqi   Ziqi added functi...
450
  		}
f6169dea   heziqi   Ziqi completed bi...
451
  
cbce396e   David Mayerich   added support for...
452
  		thread_data = 100;
11f177d5   heziqi   Ziqi added functi...
453
454
  		
  		free(p);
f6169dea   heziqi   Ziqi completed bi...
455
  		free(q);
11f177d5   heziqi   Ziqi added functi...
456
457
458
  		target.close();
  		return true;
  	}
88c3e636   heziqi   Ziqi added big.h
459
  
a23c4132   David Mayerich   Doxygen comments ...
460
461
462
463
464
465
466
467
  	/// Return a baseline corrected band given two adjacent baseline points and their bands. The result is stored in a pre-allocated array.
  
  	/// @param lb is the label value for the left baseline point
  	/// @param rb is the label value for the right baseline point
  	/// @param lp is a pointer to an array holding the band image for the left baseline point
  	/// @param rp is a pointer to an array holding the band image for the right baseline point
  	/// @param wavelength is the label value for the requested baseline-corrected band
  	/// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size.
20c212c0   heziqi   Ziqi added functi...
468
469
  	bool baseline_band(double lb, double rb, T* lp, T* rp, double wavelength, T* result){
  
724ec347   David Mayerich   simplified the EN...
470
  		unsigned XY = X() * Y();
20c212c0   heziqi   Ziqi added functi...
471
472
473
474
475
476
477
478
479
  		band(result, wavelength);		//get band
  
  		//perform the baseline correction
  		double r = (double) (wavelength - lb) / (double) (rb - lb);
  		for(unsigned i=0; i < XY; i++){
  			result[i] =(T) (result[i] - (rp[i] - lp[i]) * r - lp[i] );
  		}
  		return true;
  	}
517876d6   heziqi   metrics finished ...
480
  	
a23c4132   David Mayerich   Doxygen comments ...
481
482
483
484
485
486
  	/// Return a baseline corrected band given two adjacent baseline points. The result is stored in a pre-allocated array.
  
  	/// @param lb is the label value for the left baseline point
  	/// @param rb is the label value for the right baseline point
  	/// @param bandwavelength is the label value for the desired baseline-corrected band
  	/// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size.
70407ea9   heziqi   Ziqi completed he...
487
  	bool height(double lb, double rb, double bandwavelength, T* result){
20c212c0   heziqi   Ziqi added functi...
488
489
490
  
  		T* lp;
  		T* rp;
724ec347   David Mayerich   simplified the EN...
491
  		unsigned XY = X() * Y();
70407ea9   heziqi   Ziqi completed he...
492
493
494
  		unsigned S = XY * sizeof(T);
  		lp = (T*) malloc(S);			//memory allocation
  		rp = (T*) malloc(S);
20c212c0   heziqi   Ziqi added functi...
495
  
70407ea9   heziqi   Ziqi completed he...
496
  		band(lp, lb);
20c212c0   heziqi   Ziqi added functi...
497
498
499
500
  		band(rp, rb);		
  
  		baseline_band(lb, rb, lp, rp, bandwavelength, result);
  
517876d6   heziqi   metrics finished ...
501
502
  		free(lp);
  		free(rp);
20c212c0   heziqi   Ziqi added functi...
503
504
505
  		return true;
  	}
  
c359422d   heziqi   Ziqi added functi...
506
  
a23c4132   David Mayerich   Doxygen comments ...
507
508
509
510
511
512
513
  	/// Calculate the area under the spectrum between two specified points and stores the result in a pre-allocated array.
  
  	/// @param lb is the label value for the left baseline point
  	/// @param rb is the label value for the right baseline point
  	/// @param lab is the label value for the left bound (start of the integration)
  	/// @param rab is the label value for the right bound (end of the integration)
  	/// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size
70407ea9   heziqi   Ziqi completed he...
514
  	bool area(double lb, double rb, double lab, double rab, T* result){
20c212c0   heziqi   Ziqi added functi...
515
516
517
518
519
  
  		T* lp;	//left band pointer
  		T* rp;	//right band pointer
  		T* cur;		//current band 1
  		T* cur2;	//current band 2
20c212c0   heziqi   Ziqi added functi...
520
  
724ec347   David Mayerich   simplified the EN...
521
  		unsigned XY = X() * Y();
20c212c0   heziqi   Ziqi added functi...
522
523
524
525
526
527
  		unsigned S = XY * sizeof(T);
  
  		lp = (T*) malloc(S);			//memory allocation
  		rp = (T*) malloc(S);
  		cur = (T*) malloc(S);
  		cur2 = (T*) malloc(S);
20c212c0   heziqi   Ziqi added functi...
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
  
  		memset(result, (char)0, S);
  
  		//find the wavelenght position in the whole band
  		unsigned int n = w.size();
  		unsigned int ai = 0;		//left bound position
  		unsigned int bi = n - 1;		//right bound position
  
  
  
  		//to make sure the left and the right bound are in the bandwidth
  		if (lb < w[0] || rb < w[0] || lb > w[n-1] || rb >w[n-1]){
  			std::cout<<"ERROR: left bound or right bound out of bandwidth"<<std::endl;
  			exit(1);
  		}
  		//to make sure rigth bound is bigger than left bound
  		else if(lb > rb){
  			std::cout<<"ERROR: right bound should be bigger than left bound"<<std::endl;
  			exit(1);
  		}
  
  		//get the position of lb and rb
70407ea9   heziqi   Ziqi completed he...
550
  		while (lab >= w[ai]){
20c212c0   heziqi   Ziqi added functi...
551
552
  			ai++;
  		}
70407ea9   heziqi   Ziqi completed he...
553
  		while (rab <= w[bi]){
20c212c0   heziqi   Ziqi added functi...
554
555
556
557
558
559
560
  			bi--;
  		}
  
  		band(lp, lb);
  		band(rp, rb);
  
  		//calculate the beginning and the ending part
70407ea9   heziqi   Ziqi completed he...
561
562
  		baseline_band(lb, rb, lp, rp, rab, cur2);		//ending part
  		baseline_band(lb, rb, lp, rp, w[bi], cur);
20c212c0   heziqi   Ziqi added functi...
563
  		for(unsigned j = 0; j < XY; j++){
70407ea9   heziqi   Ziqi completed he...
564
  			result[j] += (rab - w[bi]) * (cur[j] + cur2[j]) / 2.0;
20c212c0   heziqi   Ziqi added functi...
565
  		}
70407ea9   heziqi   Ziqi completed he...
566
567
  		baseline_band(lb, rb, lp, rp, lab, cur2);		//beginnning part
  		baseline_band(lb, rb, lp, rp, w[ai], cur);
20c212c0   heziqi   Ziqi added functi...
568
  		for(unsigned j = 0; j < XY; j++){	
70407ea9   heziqi   Ziqi completed he...
569
  			result[j] += (w[ai] - lab) * (cur[j] + cur2[j]) / 2.0;
20c212c0   heziqi   Ziqi added functi...
570
  		}
517876d6   heziqi   metrics finished ...
571
  
20c212c0   heziqi   Ziqi added functi...
572
573
574
575
576
577
578
579
580
581
582
  		//calculate the area
  		ai++;
  		for(unsigned i = ai; i <= bi ;i++)
  		{
  			baseline_band(lb, rb, lp, rp, w[ai], cur2);
  			for(unsigned j = 0; j < XY; j++)
  			{
  				result[j] += (w[ai] - w[ai-1]) * (cur[j] + cur2[j]) / 2.0; 
  			}
  			std::swap(cur,cur2);		//swap the band pointers
  		}
70407ea9   heziqi   Ziqi completed he...
583
  
517876d6   heziqi   metrics finished ...
584
585
586
587
  		free(lp);
  		free(rp);
  		free(cur);
  		free(cur2);
20c212c0   heziqi   Ziqi added functi...
588
589
590
  		return true;
  	}
  
a23c4132   David Mayerich   Doxygen comments ...
591
592
593
594
595
596
597
598
599
  	/// Compute the ratio of two baseline-corrected peaks. The result is stored in a pre-allocated array.
  
  	/// @param lb1 is the label value for the left baseline point for the first peak (numerator)
  	/// @param rb1 is the label value for the right baseline point for the first peak (numerator)
  	/// @param pos1 is the label value for the first peak (numerator) position
  	/// @param lb2 is the label value for the left baseline point for the second peak (denominator)
  	/// @param rb2 is the label value for the right baseline point for the second peak (denominator)
  	/// @param pos2 is the label value for the second peak (denominator) position
  	/// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size
70407ea9   heziqi   Ziqi completed he...
600
601
  	bool ph_to_ph(double lb1, double rb1, double pos1, double lb2, double rb2, double pos2, T * result){
  
724ec347   David Mayerich   simplified the EN...
602
603
  		T* p1 = (T*)malloc(X() * Y() * sizeof(T));	
  		T* p2 = (T*)malloc(X() * Y() * sizeof(T));	
70407ea9   heziqi   Ziqi completed he...
604
605
606
607
608
  		
  		//get the two peak band
  		height(lb1, rb1, pos1, p1);
  		height(lb2, rb2, pos2, p2);
  		//calculate the ratio in result
724ec347   David Mayerich   simplified the EN...
609
  		for(unsigned i = 0; i < X() * Y(); i++){
70407ea9   heziqi   Ziqi completed he...
610
611
612
613
614
  			if(p1[i] == 0 && p2[i] ==0)
  				result[i] = 1;
  			else
  				result[i] = p1[i] / p2[i];
  		}
517876d6   heziqi   metrics finished ...
615
616
617
  
  		free(p1);
  		free(p2);
70407ea9   heziqi   Ziqi completed he...
618
619
620
  		return true;	
  	}
  	
a23c4132   David Mayerich   Doxygen comments ...
621
622
623
624
625
626
627
628
629
  	/// Compute the ratio between a peak area and peak height.
  
  	/// @param lb1 is the label value for the left baseline point for the first peak (numerator)
  	/// @param rb1 is the label value for the right baseline point for the first peak (numerator)
  	/// @param pos1 is the label value for the first peak (numerator) position
  	/// @param lb2 is the label value for the left baseline point for the second peak (denominator)
  	/// @param rb2 is the label value for the right baseline point for the second peak (denominator)
  	/// @param pos2 is the label value for the second peak (denominator) position
  	/// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size
70407ea9   heziqi   Ziqi completed he...
630
631
632
  	bool pa_to_ph(double lb1, double rb1, double lab1, double rab1,
  					double lb2, double rb2, double pos, T* result){
  		
724ec347   David Mayerich   simplified the EN...
633
634
  		T* p1 = (T*)malloc(X() * Y() * sizeof(T));	
  		T* p2 = (T*)malloc(X() * Y() * sizeof(T));	
70407ea9   heziqi   Ziqi completed he...
635
636
637
638
639
  		
  		//get the area and the peak band
  		area(lb1, rb1, lab1, rab1, p1);
  		height(lb2, rb2, pos, p2);
  		//calculate the ratio in result
724ec347   David Mayerich   simplified the EN...
640
  		for(unsigned i = 0; i < X() * Y(); i++){
70407ea9   heziqi   Ziqi completed he...
641
642
643
644
645
  			if(p1[i] == 0 && p2[i] ==0)
  				result[i] = 1;
  			else
  				result[i] = p1[i] / p2[i];
  		}
517876d6   heziqi   metrics finished ...
646
647
648
  
  		free(p1);
  		free(p2);
70407ea9   heziqi   Ziqi completed he...
649
650
651
  		return true;	
  	}		
  	
a23c4132   David Mayerich   Doxygen comments ...
652
653
654
655
656
657
658
659
660
661
662
  	/// Compute the ratio between two peak areas.
  
  	/// @param lb1 is the label value for the left baseline point for the first peak (numerator)
  	/// @param rb1 is the label value for the right baseline point for the first peak (numerator)
  	/// @param lab1 is the label value for the left bound (start of the integration) of the first peak (numerator)
  	/// @param rab1 is the label value for the right bound (end of the integration) of the first peak (numerator)
  	/// @param lb2 is the label value for the left baseline point for the second peak (denominator)
  	/// @param rb2 is the label value for the right baseline point for the second peak (denominator)
  	/// @param lab2 is the label value for the left bound (start of the integration) of the second peak (denominator)
  	/// @param rab2 is the label value for the right bound (end of the integration) of the second peak (denominator)	
  	/// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size
70407ea9   heziqi   Ziqi completed he...
663
664
665
  	bool pa_to_pa(double lb1, double rb1, double lab1, double rab1,
  					double lb2, double rb2, double lab2, double rab2, T* result){
  		
724ec347   David Mayerich   simplified the EN...
666
667
  		T* p1 = (T*)malloc(X() * Y() * sizeof(T));	
  		T* p2 = (T*)malloc(X() * Y() * sizeof(T));	
70407ea9   heziqi   Ziqi completed he...
668
669
670
671
672
  		
  		//get the area and the peak band
  		area(lb1, rb1, lab1, rab1, p1);
  		area(lb2, rb2, lab2, rab2, p2);
  		//calculate the ratio in result
724ec347   David Mayerich   simplified the EN...
673
  		for(unsigned i = 0; i < X() * Y(); i++){
70407ea9   heziqi   Ziqi completed he...
674
675
676
677
678
  			if(p1[i] == 0 && p2[i] ==0)
  				result[i] = 1;
  			else
  				result[i] = p1[i] / p2[i];
  		}
517876d6   heziqi   metrics finished ...
679
680
681
  
  		free(p1);
  		free(p2);
70407ea9   heziqi   Ziqi completed he...
682
683
  		return true;	
  	}		
517876d6   heziqi   metrics finished ...
684
  
a23c4132   David Mayerich   Doxygen comments ...
685
686
687
688
689
690
691
  	/// Compute the definite integral of a baseline corrected peak.
  
  	/// @param lb is the label value for the left baseline point
  	/// @param rb is the label value for the right baseline point
  	/// @param lab is the label for the start of the definite integral
  	/// @param rab is the label for the end of the definite integral
  	/// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size
517876d6   heziqi   metrics finished ...
692
693
694
695
696
697
  	bool x_area(double lb, double rb, double lab, double rab, T* result){
  		T* lp;	//left band pointer
  		T* rp;	//right band pointer
  		T* cur;		//current band 1
  		T* cur2;	//current band 2
  
724ec347   David Mayerich   simplified the EN...
698
  		unsigned XY = X() * Y();
517876d6   heziqi   metrics finished ...
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
  		unsigned S = XY * sizeof(T);
  
  		lp = (T*) malloc(S);			//memory allocation
  		rp = (T*) malloc(S);
  		cur = (T*) malloc(S);
  		cur2 = (T*) malloc(S);
  
  		memset(result, (char)0, S);
  
  		//find the wavelenght position in the whole band
  		unsigned int n = w.size();
  		unsigned int ai = 0;		//left bound position
  		unsigned int bi = n - 1;		//right bound position
  
  		//to make sure the left and the right bound are in the bandwidth
  		if (lb < w[0] || rb < w[0] || lb > w[n-1] || rb >w[n-1]){
  			std::cout<<"ERROR: left bound or right bound out of bandwidth"<<std::endl;
  			exit(1);
  		}
  		//to make sure rigth bound is bigger than left bound
  		else if(lb > rb){
  			std::cout<<"ERROR: right bound should be bigger than left bound"<<std::endl;
  			exit(1);
  		}
  
  		//get the position of lb and rb
  		while (lab >= w[ai]){
  			ai++;
  		}
  		while (rab <= w[bi]){
  			bi--;
  		}
  
  		band(lp, lb);
  		band(rp, rb);
  
  		//calculate the beginning and the ending part
  		baseline_band(lb, rb, lp, rp, rab, cur2);		//ending part
  		baseline_band(lb, rb, lp, rp, w[bi], cur);
  		for(unsigned j = 0; j < XY; j++){
  			result[j] += (rab - w[bi]) * (rab + w[bi]) * (cur[j] + cur2[j]) / 4.0;
  		}
  		baseline_band(lb, rb, lp, rp, lab, cur2);		//beginnning part
  		baseline_band(lb, rb, lp, rp, w[ai], cur);
  		for(unsigned j = 0; j < XY; j++){	
  			result[j] += (w[ai] - lab) * (w[ai] + lab) * (cur[j] + cur2[j]) / 4.0;
  		}
  
  		//calculate f(x) times x
  		ai++;
  		for(unsigned i = ai; i <= bi ;i++)
  		{
  			baseline_band(lb, rb, lp, rp, w[ai], cur2);
  			for(unsigned j = 0; j < XY; j++)
  			{
  				result[j] += (w[ai] - w[ai-1]) * (w[ai] + w[ai-1]) * (cur[j] + cur2[j]) / 4.0; 
  			}
  			std::swap(cur,cur2);		//swap the band pointers
  		}
  
  		free(lp);
  		free(rp);
  		free(cur);
  		free(cur2);
  		return true;
  	}
  
a23c4132   David Mayerich   Doxygen comments ...
766
767
768
769
770
771
772
  	/// Compute the centroid of a baseline corrected peak.
  
  	/// @param lb is the label value for the left baseline point
  	/// @param rb is the label value for the right baseline point
  	/// @param lab is the label for the start of the peak
  	/// @param rab is the label for the end of the peak
  	/// @param result is a pointer to a pre-allocated array at least X * Y * sizeof(T) in size
517876d6   heziqi   metrics finished ...
773
  	bool cpoint(double lb, double rb, double lab, double rab, T* result){
724ec347   David Mayerich   simplified the EN...
774
775
  		T* p1 = (T*)malloc(X() * Y() * sizeof(T));	
  		T* p2 = (T*)malloc(X() * Y() * sizeof(T));	
517876d6   heziqi   metrics finished ...
776
777
778
779
780
  		
  		//get the area and the peak band
  		x_area(lb, rb, lab, rab, p1);
  		area(lb, rb, lab, rab, p2);
  		//calculate the ratio in result
724ec347   David Mayerich   simplified the EN...
781
  		for(unsigned i = 0; i < X() * Y(); i++){
517876d6   heziqi   metrics finished ...
782
783
784
785
786
787
788
789
790
791
792
  			if(p1[i] == 0 && p2[i] ==0)
  				result[i] = 1;
  			else
  				result[i] = p1[i] / p2[i];
  		}
  
  		free(p1);
  		free(p2);
  		return true;	
  	}
  
a23c4132   David Mayerich   Doxygen comments ...
793
794
795
796
797
798
799
  	/// Create a mask based on a given band and threshold value.
  
  	/// All pixels in the
  	/// specified band greater than the threshold are true and all pixels less than the threshold are false.
  	/// @param mask_band is the band used to specify the mask
  	/// @param threshold is the threshold used to determine if the mask value is true or false
  	/// @param p is a pointer to a pre-allocated array at least X * Y in size
f4c5d71b   David Mayerich   started working w...
800
  	bool build_mask(double mask_band, double threshold, unsigned char* p){
4a6f666c   heziqi   Added mask method
801
  
724ec347   David Mayerich   simplified the EN...
802
  		T* temp = (T*)malloc(X() * Y() * sizeof(T));		//allocate memory for the certain band
4a6f666c   heziqi   Added mask method
803
804
  		band(temp, mask_band);
  
724ec347   David Mayerich   simplified the EN...
805
  		for (unsigned int i = 0; i < X() * Y();i++) {
4a6f666c   heziqi   Added mask method
806
807
808
809
810
811
  				if (temp[i] < threshold)
  					p[i] = 0;
  				else
  					p[i] = 255;
  		}
  
517876d6   heziqi   metrics finished ...
812
  		free(temp);
4a6f666c   heziqi   Added mask method
813
814
815
816
  		return true;
  
  	}
  
a23c4132   David Mayerich   Doxygen comments ...
817
818
819
820
  	/// Apply a mask file to the BSQ image, setting all values outside the mask to zero.
  
  	/// @param outfile is the name of the masked output file
  	/// @param p is a pointer to memory of size X * Y, where p(i) = 0 for pixels that will be set to zero.
740f8cd2   heziqi   added apply_mask
821
822
823
824
  	bool apply_mask(std::string outfile, unsigned char* p){
  
  		std::ofstream target(outfile.c_str(), std::ios::binary);
  
724ec347   David Mayerich   simplified the EN...
825
  		unsigned ZX = Z() * X();		//calculate the number of values in a page (XZ in BIP)
1a55a328   David Mayerich   Added comments fo...
826
  		unsigned L = ZX * sizeof(T);	//calculate the number of bytes in a page
740f8cd2   heziqi   added apply_mask
827
  
1a55a328   David Mayerich   Added comments fo...
828
  		T * temp = (T*)malloc(L);		//allocate space for that page
740f8cd2   heziqi   added apply_mask
829
  
724ec347   David Mayerich   simplified the EN...
830
  		for (unsigned i = 0; i < Y(); i++)			//for each page (Y in BIP)
740f8cd2   heziqi   added apply_mask
831
  		{
724ec347   David Mayerich   simplified the EN...
832
833
  			read_plane_y(temp, i);							//load that page (it's pointed to by temp)
  			for ( unsigned j = 0; j < X(); j++)	//for each X value
740f8cd2   heziqi   added apply_mask
834
  			{
724ec347   David Mayerich   simplified the EN...
835
  				for (unsigned k = 0; k < Z(); k++)	//for each B value (band)
740f8cd2   heziqi   added apply_mask
836
  				{
724ec347   David Mayerich   simplified the EN...
837
838
  					if (p[i * X() + j] == 0)	//if the mask value is zero
  					temp[j * Z() + k] = 0;			//set the pixel value to zero
1a55a328   David Mayerich   Added comments fo...
839
  				else								//otherwise just continue
740f8cd2   heziqi   added apply_mask
840
841
842
  					continue;
  				}
  			}
1a55a328   David Mayerich   Added comments fo...
843
  			target.write(reinterpret_cast<const char*>(temp), L);   //write the edited band data into target file
740f8cd2   heziqi   added apply_mask
844
  		}
1a55a328   David Mayerich   Added comments fo...
845
846
847
  		target.close();						//close the target file
  		free(temp);							//free allocated memory
  		return true;						//return true
740f8cd2   heziqi   added apply_mask
848
849
  	}
  
e843658b   Brad Deutsch   Previous push did...
850
  
2fcab4f0   David Mayerich   added unsifting f...
851
  	/// Saves to disk only those spectra corresponding to mask values != 0
8550e94f   David Mayerich   added sifting and...
852
853
854
855
856
857
  	bool sift(std::string outfile, unsigned char* mask){
  
  		//reset the file pointer to the beginning of the file
  		file.seekg(0, std::ios::beg);		
  
  		// open an output stream
e843658b   Brad Deutsch   Previous push did...
858
859
  		std::ofstream target(outfile.c_str(), std::ios::binary);
  
8550e94f   David Mayerich   added sifting and...
860
  		//allocate space for a single spectrum
3150c537   David Mayerich   added further pro...
861
  		unsigned long B = Z();
8550e94f   David Mayerich   added sifting and...
862
  		T* spectrum = (T*) malloc(B * sizeof(T));
e843658b   Brad Deutsch   Previous push did...
863
  
8550e94f   David Mayerich   added sifting and...
864
  		//calculate the number of pixels in a band
3150c537   David Mayerich   added further pro...
865
  		unsigned long XY = X() * Y();
e843658b   Brad Deutsch   Previous push did...
866
  
8550e94f   David Mayerich   added sifting and...
867
  		//for each pixel
3150c537   David Mayerich   added further pro...
868
869
  		unsigned long skip = 0;					//number of spectra to skip
  		for(unsigned long x = 0; x < XY; x++){
8550e94f   David Mayerich   added sifting and...
870
871
872
873
874
  
  			//if the current pixel isn't masked
  			if( mask[x] == 0){
  				//increment the number of skipped pixels
  				skip++;
e843658b   Brad Deutsch   Previous push did...
875
  			}
8550e94f   David Mayerich   added sifting and...
876
877
878
879
880
881
882
883
884
885
886
887
888
889
  			//if the current pixel is masked
  			else{
  
  				//skip the intermediate pixels
  				file.seekg(skip * B * sizeof(T), std::ios::cur);
  
  				//set the skip value to zero
  				skip = 0;
  
  				//read this pixel into memory
  				file.read((char *)spectrum, B * sizeof(T));
  
  				//write this pixel out
  				target.write((char *)spectrum, B * sizeof(T));
3150c537   David Mayerich   added further pro...
890
891
  
  				thread_data = (double) x / XY * 100;
8550e94f   David Mayerich   added sifting and...
892
893
  			}
  
e843658b   Brad Deutsch   Previous push did...
894
  		}
8550e94f   David Mayerich   added sifting and...
895
896
  
  		//close the output file
e843658b   Brad Deutsch   Previous push did...
897
  		target.close();
8550e94f   David Mayerich   added sifting and...
898
  		free(spectrum);
cbce396e   David Mayerich   added support for...
899
  
3150c537   David Mayerich   added further pro...
900
901
  		thread_data = 100;
  
cbce396e   David Mayerich   added support for...
902
  		return true;
8550e94f   David Mayerich   added sifting and...
903
904
905
906
907
908
909
910
911
912
913
  	}
  
  	bool unsift(std::string outfile, unsigned char* mask, unsigned int samples, unsigned int lines){
  
  		// open an output stream
  		std::ofstream target(outfile.c_str(), std::ios::binary);
  
  		//reset the file pointer to the beginning of the file
  		file.seekg(0, std::ios::beg);		
  
  		//allocate space for a single spectrum
3150c537   David Mayerich   added further pro...
914
  		unsigned long B = Z();
8550e94f   David Mayerich   added sifting and...
915
916
917
918
919
920
921
  		T* spectrum = (T*) malloc(B * sizeof(T));
  
  		//allocate space for a spectrum of zeros
  		T* zeros = (T*) malloc(B * sizeof(T));
  		memset(zeros, 0, B * sizeof(T));
  
  		//calculate the number of pixels in a band
3150c537   David Mayerich   added further pro...
922
  		unsigned long XY = samples * lines;
8550e94f   David Mayerich   added sifting and...
923
924
  
  		//for each pixel
3150c537   David Mayerich   added further pro...
925
926
  		unsigned long skip = 0;					//number of spectra to skip
  		for(unsigned long x = 0; x < XY; x++){
8550e94f   David Mayerich   added sifting and...
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
  
  			//if the current pixel isn't masked
  			if( mask[x] == 0){
  
  				//write a bunch of zeros
  				target.write((char *)zeros, B * sizeof(T));
  			}
  			//if the current pixel is masked
  			else{
  
  				//read a pixel into memory
  				file.read((char *)spectrum, B * sizeof(T));
  
  				//write this pixel out
  				target.write((char *)spectrum, B * sizeof(T));
  			}
  
3150c537   David Mayerich   added further pro...
944
945
  			thread_data = (double)x / XY * 100;
  
8550e94f   David Mayerich   added sifting and...
946
947
948
949
950
951
  		}
  
  		//close the output file
  		target.close();
  		free(spectrum);
  
3150c537   David Mayerich   added further pro...
952
953
  		thread_data = 100;
  
e843658b   Brad Deutsch   Previous push did...
954
  		return true;
8550e94f   David Mayerich   added sifting and...
955
956
  
  
e843658b   Brad Deutsch   Previous push did...
957
958
959
  	}
  
  
a23c4132   David Mayerich   Doxygen comments ...
960
961
  
  	/// @param p is a pointer to memory of size X * Y * sizeof(T) that will store the band averages.
a43c4fe1   heziqi   Added crop in env...
962
  	bool band_avg(T* p){
724ec347   David Mayerich   simplified the EN...
963
  		unsigned long long XY = X() * Y();
a43c4fe1   heziqi   Added crop in env...
964
  		//get every pixel and calculate average value
724ec347   David Mayerich   simplified the EN...
965
  		T* temp = (T*)malloc(sizeof(T) * Z());
a43c4fe1   heziqi   Added crop in env...
966
967
968
969
970
  		T sum;
  		for (unsigned i = 0; i < XY; i++){
  			pixel(temp, i);
  			//calculate the sum value of every value
  			sum = 0;		//initialize sum value
724ec347   David Mayerich   simplified the EN...
971
972
  			for (unsigned j = 0; j < Z(); j++){
  				sum += temp[j]/(T)Z();
a43c4fe1   heziqi   Added crop in env...
973
974
975
976
977
978
979
  			}
  			p[i] = sum;
  		}
  		free(temp);
  		return true;
  	}
  
a23c4132   David Mayerich   Doxygen comments ...
980
981
982
983
  	/// Calculate the mean value for all masked (or valid) pixels in a band and returns the average spectrum
  
  	/// @param p is a pointer to pre-allocated memory of size [B * sizeof(T)] that stores the mean spectrum
  	/// @param mask is a pointer to memory of size [X * Y] that stores the mask value at each pixel location
a43c4fe1   heziqi   Added crop in env...
984
  	bool avg_band(T*p, unsigned char* mask){
724ec347   David Mayerich   simplified the EN...
985
986
  		unsigned long long XY = X() * Y();
  		T* temp = (T*)malloc(sizeof(T) * Z());
a43c4fe1   heziqi   Added crop in env...
987
  		//Iinitialize
724ec347   David Mayerich   simplified the EN...
988
  		for (unsigned j = 0; j < Z(); j++){
a43c4fe1   heziqi   Added crop in env...
989
990
991
992
993
994
995
996
997
998
999
1000
1001
  			p[j] = 0;
  		}
  		//calculate vaild number in a band
  		unsigned count = 0;
  		for (unsigned j = 0; j < XY; j++){
  			if (mask[j] != 0){
  				count++;
  			}
  		}
  		//calculate average number of a band
  		for (unsigned i = 0; i < XY; i++){
  			if (mask[i] != 0){			
  				pixel(temp, i);
724ec347   David Mayerich   simplified the EN...
1002
  				for (unsigned j = 0; j < Z(); j++){
a43c4fe1   heziqi   Added crop in env...
1003
1004
1005
1006
1007
1008
1009
  					p[j] += temp[j] / (T)count;
  				}
  			}
  		}
  		free(temp);
  		return true;
  	}
a23c4132   David Mayerich   Doxygen comments ...
1010
1011
1012
1013
1014
1015
  	
  	/// Calculate the covariance matrix for all masked pixels in the image.
  
  	/// @param co is a pointer to pre-allocated memory of size [B * B] that stores the resulting covariance matrix
  	/// @param avg is a pointer to memory of size B that stores the average spectrum
  	/// @param mask is a pointer to memory of size [X * Y] that stores the mask value at each pixel location
a43c4fe1   heziqi   Added crop in env...
1016
1017
  	bool co_matrix(T* co, T* avg, unsigned char *mask){
  		//memory allocation
724ec347   David Mayerich   simplified the EN...
1018
1019
  		unsigned long long xy = X() * Y();
  		unsigned int B = Z();
a43c4fe1   heziqi   Added crop in env...
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
  		T* temp = (T*)malloc(sizeof(T) * B);
  		//count vaild pixels in a band
  		unsigned count = 0;
  		for (unsigned j = 0; j < xy; j++){
  			if (mask[j] != 0){
  				count++;
  			}
  		}
  		//initialize correlation matrix
  		for (unsigned i = 0; i < B; i++){
  			for (unsigned k = 0; k < B; k++){
  				co[i * B + k] = 0;
  			}
  		}
  		//calculate correlation coefficient matrix
  		for (unsigned j = 0; j < xy; j++){
  			if (mask[j] != 0){
  				pixel(temp, j);
  				for (unsigned i = 0; i < B; i++){
  					for (unsigned k = i; k < B; k++){
  						co[i * B + k] += (temp[i] - avg[i]) * (temp[k] - avg[k]) / count;
  					}
  				}
  			}
  		}
  		//because correlation matrix is symmetric
  		for (unsigned i = 0; i < B; i++){
  			for (unsigned k = i + 1; k < B; k++){
  				co[k * B + i] = co[i * B + k];
  			}
  		}
  
  		free(temp);
  		return true;
  	}
  
0df38ff3   heziqi   fixed head detached
1056
  
a23c4132   David Mayerich   Doxygen comments ...
1057
1058
1059
1060
1061
1062
1063
  	/// Crop a region of the image and save it to a new file.
  
  	/// @param outfile is the file name for the new cropped image
  	/// @param x0 is the lower-left x pixel coordinate to be included in the cropped image
  	/// @param y0 is the lower-left y pixel coordinate to be included in the cropped image
  	/// @param x1 is the upper-right x pixel coordinate to be included in the cropped image
  	/// @param y1 is the upper-right y pixel coordinate to be included in the cropped image
e9bddc57   David Mayerich   added band croppi...
1064
1065
1066
1067
1068
1069
  	bool crop(std::string outfile, unsigned long long x0,
  								   unsigned long long y0,
  								   unsigned long long x1,
  								   unsigned long long y1,
  								   unsigned long long b0,
  								   unsigned long long b1){
a43c4fe1   heziqi   Added crop in env...
1070
1071
1072
1073
  
  		//calculate the new number of samples and lines
  		unsigned long long sam = x1 - x0;		//samples
  		unsigned long long lin = y1 - y0;		//lines
724ec347   David Mayerich   simplified the EN...
1074
  		unsigned long long L = Z() * sizeof(T);
a43c4fe1   heziqi   Added crop in env...
1075
1076
1077
1078
  		//get specified band and save
  		T* temp = (T*)malloc(L);
  		std::ofstream out(outfile.c_str(), std::ios::binary);
  		//get start
724ec347   David Mayerich   simplified the EN...
1079
  		unsigned long long sp = y0 * X() + x0;		//start pixel
a43c4fe1   heziqi   Added crop in env...
1080
1081
1082
1083
  		for (unsigned i = 0; i < lin; i++)
  		{
  			for (unsigned j = 0; j < sam; j++)
  			{
724ec347   David Mayerich   simplified the EN...
1084
  				pixel(temp, sp + j + i * X());
a43c4fe1   heziqi   Added crop in env...
1085
  				out.write(reinterpret_cast<const char*>(temp), L);   //write slice data into target file	
3150c537   David Mayerich   added further pro...
1086
1087
  
  				thread_data = (double)(i * sam + j) / (lin * sam) * 100;
a43c4fe1   heziqi   Added crop in env...
1088
1089
1090
  			}
  		}
  		free(temp);
3150c537   David Mayerich   added further pro...
1091
1092
  
  		thread_data = 100;
a43c4fe1   heziqi   Added crop in env...
1093
1094
1095
  		return true;
  	}
  
0df38ff3   heziqi   fixed head detached
1096
  
a23c4132   David Mayerich   Doxygen comments ...
1097
  	/// Close the file.
f6169dea   heziqi   Ziqi completed bi...
1098
1099
1100
1101
1102
  	bool close(){
  		file.close();
  		return true;
  	}
  
88c3e636   heziqi   Ziqi added big.h
1103
  	};
6aa04ba2   David Mayerich   interleave types
1104
  }
e8eb202f   David Mayerich   added a new ENVI ...
1105
1106
  
  #endif