Commit 7d43100a324109f10f92d2a4127868f320f39ead

Authored by dmayerich
1 parent 3f56f1f9

allow appending to binary files

defaults.h
... ... @@ -32,6 +32,7 @@
32 32 //default flags
33 33 #define DEFAULT_PLANEWAVE false
34 34 #define DEFAULT_VECTORSIM false
  35 +#define DEFAULT_APPEND false
35 36 //#define DEFAULT_OUTPUT_POINT fileoutStruct::imageObjective
36 37  
37 38  
... ... @@ -72,7 +73,7 @@
72 73 #define DEFAULT_PADDING 1
73 74 #define DEFAULT_SUPERSAMPLE 1
74 75  
75   -#define DEFAULT_INTENSITY_FILE "out_di.bmp"
  76 +#define DEFAULT_INTENSITY_FILE "testappend"
76 77 #define DEFAULT_TRANSMITTANCE_FILE ""
77 78 #define DEFAULT_ABSORBANCE_FILE ""
78 79 #define DEFAULT_NEAR_FILE "out_n.bmp"
... ...
fileout.cu
... ... @@ -113,9 +113,7 @@ void fileoutStruct::saveDetector(microscopeStruct* scope)
113 113 scalarslice I = scope->getIntensity();
114 114  
115 115 if(is_binary(intFile))
116   - I.toEnvi(intFile, scope->nf.lambda);
117   - else
118   - I.toImage(intFile);
  116 + I.toEnvi(intFile, scope->nf.lambda, append);
119 117 }
120 118 //absorbance
121 119 if(absFile != "")
... ... @@ -123,7 +121,7 @@ void fileoutStruct::saveDetector(microscopeStruct* scope)
123 121 scalarslice I = scope->getAbsorbance();
124 122  
125 123 if(is_binary(absFile))
126   - I.toEnvi(absFile, scope->nf.lambda);
  124 + I.toEnvi(absFile, scope->nf.lambda, append);
127 125 else
128 126 I.toImage(absFile);
129 127 }
... ... @@ -133,7 +131,7 @@ void fileoutStruct::saveDetector(microscopeStruct* scope)
133 131 scalarslice I = scope->getTransmittance();
134 132  
135 133 if(is_binary(transFile))
136   - I.toEnvi(transFile, scope->nf.lambda);
  134 + I.toEnvi(transFile, scope->nf.lambda, append);
137 135 else
138 136 I.toImage(transFile);
139 137 }
... ...
fileout.h
... ... @@ -18,7 +18,9 @@ struct fileoutStruct{
18 18 std::string farFile; //far field filename
19 19 std::string intFile; //detector intensity filename
20 20 std::string absFile; //detector absorbance filename
21   - std::string transFile; //detector transmission filename
  21 + std::string transFile; //detector transmission filename
  22 +
  23 + bool append; //append simulation results to existing binary files
22 24  
23 25 //output type
24 26 enum field_type {fieldMag, fieldIntensity, fieldAbsorbance, fieldPolar, fieldImag, fieldReal, fieldAngularSpectrum};
... ...
main.cpp
... ... @@ -19,7 +19,7 @@ microscopeStruct* SCOPE;
19 19 #include "rts/rtsMatrix.h"
20 20 #include "rts/rtsQuaternion.h"
21 21  
22   -#include "rtsEnvi.h"
  22 +#include "envi/rtsEnvi.h"
23 23  
24 24 #include "warnings.h"
25 25  
... ... @@ -60,6 +60,6 @@ int main(int argc, char *argv[])
60 60 SCOPE->destroy();
61 61  
62 62  
63   -
  63 +
64 64  
65 65 }
... ...
options.h
... ... @@ -135,7 +135,7 @@ static void loadMaterials(po::variables_map vm)
135 135 exit(1);
136 136 }
137 137  
138   -
  138 +
139 139 for(int i=0; i<matVec.size(); i+=2)
140 140 {
141 141 rts::material<ptype> newM(vm["lambda"].as<ptype>(), matVec[i], matVec[i+1]);
... ... @@ -252,6 +252,10 @@ static void loadMicroscopeParams(po::variables_map vm)
252 252  
253 253 static void loadOutputParams(po::variables_map vm)
254 254 {
  255 + //append simulation results to previous binary files
  256 + gFileOut.append = DEFAULT_APPEND;
  257 + if(vm.count("append"))
  258 + gFileOut.append = true;
255 259  
256 260 //image parameters
257 261 //component of the field to be saved
... ...
rtsEnvi.h deleted
1   -#ifndef RTS_ENVI_H
2   -#define RTS_ENVI_H
3   -
4   -#include <string>
5   -#include <iostream>
6   -#include <fstream>
7   -#include <sstream>
8   -
9   -/* This is a class for reading and writing ENVI binary files. This class will be updated as needed.
10   -
11   -What this class CAN currently do:
12   - *) Write band images to a BSQ file.
13   - *) Append band images to a BSQ file.
14   -
15   -*/
16   -
17   -//information from an ENVI header file
18   -//A good resource can be found here: http://www.exelisvis.com/docs/enviheaderfiles.html
19   -struct EnviHeader
20   -{
21   - std::string name;
22   -
23   - std::string description;
24   -
25   - unsigned int samples; //x-axis
26   - unsigned int lines; //y-axis
27   - unsigned int bands; //spectral axis
28   - unsigned int header_offset; //header offset for binary file (in bytes)
29   - std::string file_type; //should be "ENVI Standard"
30   - unsigned int data_type; //data representation; common value is 4 (32-bit float)
31   -
32   - enum interleaveType {BIP, BIL, BSQ}; //bip = Z,X,Y; bil = X,Z,Y; bsq = X,Y,Z
33   - interleaveType interleave;
34   -
35   - std::string sensor_type; //not really used
36   -
37   - enum endianType {endianLittle, endianBig};
38   - endianType byte_order; //little = least significant bit first (most systems)
39   -
40   - double x_start, y_start; //coordinates of the upper-left corner of the image
41   - std::string wavelength_units; //stored wavelength units
42   - std::string z_plot_titles[2];
43   -
44   - double pixel_size[2]; //pixel size along X and Y
45   -
46   - std::vector<std::string> band_names; //name for each band in the image
47   - std::vector<double> wavelength; //wavelength for each band
48   -
49   - EnviHeader()
50   - {
51   - name = "";
52   -
53   - //specify default values for a new or empty ENVI file
54   - samples = 0;
55   - lines = 0;
56   - bands = 0;
57   - header_offset = 0;
58   - data_type = 4;
59   - interleave = BSQ;
60   - byte_order = endianLittle;
61   - x_start = y_start = 0;
62   - pixel_size[0] = pixel_size[1] = 1;
63   -
64   - //strings
65   - file_type = "ENVI Standard";
66   - sensor_type = "Unknown";
67   - wavelength_units = "Unknown";
68   - z_plot_titles[0] = z_plot_titles[1] = "Unknown";
69   - }
70   -
71   - std::string trim(std::string line)
72   - {
73   - //trims whitespace from the beginning and end of line
74   - int start_i, end_i;
75   - for(start_i=0; start_i < line.length(); start_i++)
76   - if(line[start_i] != 32)
77   - {
78   - break;
79   - }
80   -
81   - for(end_i = line.length()-1; end_i >= start_i; end_i--)
82   - if(line[end_i] != ' ')
83   - {
84   - break;
85   - }
86   -
87   - return line.substr(start_i, end_i - start_i+1);
88   - }
89   -
90   -
91   - std::string get_token(std::string line)
92   - {
93   - //returns a variable name; in this case we look for the '=' sign
94   - size_t i = line.find_first_of('=');
95   -
96   - std::string result;
97   - if(i != std::string::npos)
98   - result = trim(line.substr(0, i-1));
99   -
100   - return result;
101   - }
102   -
103   - std::string get_data_str(std::string line)
104   - {
105   - size_t i = line.find_first_of('=');
106   -
107   - std::string result;
108   - if(i != std::string::npos)
109   - result = trim(line.substr(i+1));
110   - else
111   - {
112   - std::cout<<"ENVI Header error - data not found for token: "<<get_token(line)<<std::endl;
113   - exit(1);
114   - }
115   - return result;
116   - }
117   -
118   - std::string get_brace_str(std::string token, std::string line, std::ifstream &file)
119   - {
120   - //this function assembles all of the characters between curly braces
121   - //this is how strings are defined within an ENVI file
122   -
123   - std::string result;
124   -
125   - //first, find the starting brace
126   - size_t i;
127   - do
128   - {
129   - i = line.find_first_of('{');
130   - if(i != std::string::npos)
131   - break;
132   - }while(file);
133   -
134   - //if i is still npos, we have reached the end of the file without a brace...something is wrong
135   - if(i == std::string::npos)
136   - {
137   - std::cout<<"ENVI Header error - string token declared without being defined: "<<token<<std::endl;
138   - exit(1);
139   - }
140   - line = line.substr(i+1);
141   -
142   - //copy character data into the result string until we find a closing brace
143   - while(file)
144   - {
145   - i = line.find_first_of('}');
146   -
147   -
148   - if(i != std::string::npos)
149   - {
150   - result += line.substr(0, i);
151   - break;
152   - }
153   - else
154   - result += line;
155   -
156   - getline(file, line);
157   - }
158   -
159   - if(i == std::string::npos)
160   - {
161   - std::cout<<"ENVI Header error - string token declared without a terminating '}': "<<token<<std::endl;
162   - exit(1);
163   - }
164   -
165   - return trim(result);
166   - }
167   -
168   - std::vector<std::string> get_string_seq(std::string token, std::string sequence)
169   - {
170   - //this function returns a sequence of comma-delimited strings
171   - std::vector<std::string> result;
172   -
173   - std::string entry;
174   - size_t i;
175   - do
176   - {
177   - i = sequence.find_first_of(',');
178   - entry = sequence.substr(0, i);
179   - sequence = sequence.substr(i+1);
180   - result.push_back(trim(entry));
181   - }while(i != std::string::npos);
182   -
183   - return result;
184   - }
185   -
186   - std::vector<double> get_double_seq(std::string token, std::string sequence)
187   - {
188   - //this function returns a sequence of comma-delimited strings
189   - std::vector<double> result;
190   -
191   - std::string entry;
192   - size_t i;
193   - do
194   - {
195   - i = sequence.find_first_of(',');
196   - entry = sequence.substr(0, i);
197   - sequence = sequence.substr(i+1);
198   - result.push_back(atof(entry.c_str()));
199   - }while(i != std::string::npos);
200   -
201   - return result;
202   - }
203   -
204   - void load(std::string filename)
205   - {
206   - name = filename;
207   -
208   - //open the header file
209   - std::ifstream file(name.c_str());
210   -
211   - if(!file)
212   - {
213   - std::cout<<"ENVI header file not found: "<<name<<std::endl;
214   - exit(1);
215   - }
216   -
217   - //the first line should just be "ENVI"
218   - std::string line;
219   - getline(file, line);
220   - if(line != "ENVI")
221   - {
222   - std::cout<<"The header doesn't appear to be an ENVI file. The first line should be 'ENVI'."<<std::endl;
223   - exit(1);
224   - }
225   -
226   - //for each line in the file, get the token
227   - std::string token;
228   - while(file)
229   - {
230   -
231   - //get a line
232   - getline(file, line);
233   -
234   - //get the token
235   - token = get_token(line);
236   -
237   - if(token == "description")
238   - description = get_brace_str(token, line, file);
239   - else if(token == "band names")
240   - {
241   - std::string string_sequence = get_brace_str(token, line, file);
242   - band_names = get_string_seq(token, string_sequence);
243   - }
244   - else if(token == "wavelength")
245   - {
246   - std::string string_sequence = get_brace_str(token, line, file);
247   - wavelength = get_double_seq(token, string_sequence);
248   - }
249   - else if(token == "pixel size")
250   - {
251   - std::string string_sequence = get_brace_str(token, line, file);
252   - std::vector<double> pxsize = get_double_seq(token, string_sequence);
253   - pixel_size[0] = pxsize[0];
254   - pixel_size[1] = pxsize[1];
255   - }
256   - else if(token == "z plot titles")
257   - {
258   - std::string string_sequence = get_brace_str(token, line, file);
259   - std::vector<std::string> titles = get_string_seq(token, string_sequence);
260   - z_plot_titles[0] = titles[0];
261   - z_plot_titles[1] = titles[1];
262   - }
263   -
264   - else if(token == "samples")
265   - samples = atoi(get_data_str(line).c_str());
266   - else if(token == "lines")
267   - lines = atoi(get_data_str(line).c_str());
268   - else if(token == "bands")
269   - bands = atoi(get_data_str(line).c_str());
270   - else if(token == "header offset")
271   - header_offset = atoi(get_data_str(line).c_str());
272   - else if(token == "file type")
273   - file_type = get_data_str(line);
274   - else if(token == "data type")
275   - data_type = atoi(get_data_str(line).c_str());
276   - else if(token == "interleave")
277   - {
278   - std::string interleave_str = get_data_str(line);
279   - if(interleave_str == "bip")
280   - interleave = BIP;
281   - else if(interleave_str == "bil")
282   - interleave = BIL;
283   - else if(interleave_str == "bsq")
284   - interleave = BSQ;
285   - }
286   - else if(token == "sensor type")
287   - sensor_type = get_data_str(line);
288   - else if(token == "byte order")
289   - byte_order = (endianType)atoi(get_data_str(line).c_str());
290   - else if(token == "x start")
291   - x_start = atof(get_data_str(line).c_str());
292   - else if(token == "y start")
293   - y_start = atof(get_data_str(line).c_str());
294   - else if(token == "wavelength units")
295   - wavelength_units = get_data_str(line);
296   - }
297   -
298   - //close the file
299   - file.close();
300   - }
301   -
302   - void save(std::string filename)
303   - {
304   - //open a file
305   - std::ofstream outfile(filename.c_str());
306   -
307   - //write the ENVI type identifier
308   - outfile<<"ENVI"<<std::endl;
309   -
310   - //output all of the data
311   - outfile<<"description = {"<<std::endl;
312   - outfile<<" "<<description<<"}"<<std::endl;
313   -
314   - outfile<<"samples = "<<samples<<std::endl;
315   - outfile<<"lines = "<<lines<<std::endl;
316   - outfile<<"bands = "<<bands<<std::endl;
317   - outfile<<"header offset = "<<header_offset<<std::endl;
318   - outfile<<"file type = "<<file_type<<std::endl;
319   - outfile<<"data type = "<<data_type<<std::endl;
320   - outfile<<"interleave = ";
321   - if(interleave == BIP)
322   - outfile<<"bip";
323   - if(interleave == BIL)
324   - outfile<<"bil";
325   - if(interleave == BSQ)
326   - outfile<<"bsq";
327   - outfile<<std::endl;
328   - outfile<<"sensor type = "<<sensor_type<<std::endl;
329   - outfile<<"byte order = "<<byte_order<<std::endl;
330   - outfile<<"x start = "<<x_start<<std::endl;
331   - outfile<<"y start = "<<y_start<<std::endl;
332   - outfile<<"wavelength units = "<<wavelength_units<<std::endl;
333   - outfile<<"z plot titles = {";
334   - outfile<<z_plot_titles[0]<<", "<<z_plot_titles[1]<<"}"<<std::endl;
335   - outfile<<"pixel size = {"<<pixel_size[0]<<", "<<pixel_size[1]<<", units=Meters}"<<std::endl;
336   - if(band_names.size() > 0)
337   - {
338   - outfile<<"band names = {"<<std::endl;
339   - for(int i=0; i<band_names.size(); i++)
340   - {
341   - outfile<<band_names[i];
342   - if(i < band_names.size() - 1)
343   - outfile<<", ";
344   - }
345   - outfile<<"}"<<std::endl;
346   - }
347   - outfile<<"wavelength = {"<<std::endl;
348   - for(int i=0; i<wavelength.size()-1; i++)
349   - outfile<<wavelength[i]<<", ";
350   - outfile<<wavelength.back()<<"}"<<std::endl;
351   -
352   - outfile.close();
353   - }
354   -
355   - void save()
356   - {
357   - std::cout<<"ENVI Header Name: "<<name<<std::endl;
358   - save(name);
359   - }
360   -
361   - //returns the size of a single value (in bytes)
362   - unsigned int valsize()
363   - {
364   - switch(data_type)
365   - {
366   - case 1: //1 = 8-bit byte
367   - return 1;
368   - case 2: //16-bit signed integer
369   - case 12: //16-bit unsigned integer
370   - return 2;
371   - case 3: //32-bit signed long integer
372   - case 4: //32-bit floating point
373   - case 13: //32-bit unsigned long integer
374   - return 4;
375   - case 5: //64-bit double-precision floating point
376   - case 6: //32-bit complex value
377   - case 14: //64-bit signed long integer
378   - case 15: //64-bit unsigned long integer
379   - return 8;
380   - case 9: //64-bit complex value
381   - return 16;
382   - default:
383   - return 0;
384   - }
385   -
386   - }
387   -}; //end EnviHeader
388   -
389   -class EnviFile
390   -{
391   - EnviHeader header;
392   - FILE* data;
393   - std::string mode;
394   -
395   - //a locked file has alread had data written..certain things can't be changed
396   - // accessor functions deal with these issues
397   - bool locked;
398   -
399   - void init()
400   - {
401   - locked = false;
402   - data = NULL;
403   - }
404   -
405   - void readonly()
406   - {
407   - if(mode == "r")
408   - {
409   - std::cout<<"ENVI Error: changes cannot be made to a read-only file."<<std::endl;
410   - exit(1);
411   - }
412   - }
413   -
414   - //this function determines if the current software is capable of the requested change
415   - bool caps(EnviHeader new_header)
416   - {
417   - readonly(); //if the file is read-only, throw an exception
418   -
419   - //we currently only support BSQ
420   - if(new_header.interleave == EnviHeader::BIP || new_header.interleave == EnviHeader::BIL)
421   - {
422   - std::cout<<"This software only supports BSQ.";
423   - return false;
424   - }
425   -
426   - //if the number of bands has changed
427   - if(header.bands != new_header.bands)
428   - {
429   - //the new header must be a BSQ file
430   - if(new_header.interleave != EnviHeader::BSQ)
431   - {
432   - std::cout<<"ENVI Error: can only add bands to a BSQ file."<<std::endl;
433   - return false;
434   - }
435   - }
436   -
437   - //disallow anything that can't be done when the file is locked
438   - if(locked)
439   - {
440   - if(header.lines != new_header.lines)
441   - {
442   - std::cout<<"ENVI Error: cannot change the number of lines in a locked BSQ file."<<std::endl;
443   - return false;
444   - }
445   - if(header.samples != new_header.samples)
446   - {
447   - std::cout<<"ENVI Error: cannot change the number of samples in a locked BSQ file."<<std::endl;
448   - return false;
449   - }
450   - if(header.data_type != new_header.data_type)
451   - {
452   - std::cout<<"ENVI Error: cannot change the data type of a locked file."<<std::endl;
453   - return false;
454   - }
455   - if(header.byte_order != new_header.byte_order)
456   - {
457   - std::cout<<"ENVI Error: cannot change the byte order of a locked file."<<std::endl;
458   - return false;
459   - }
460   - }
461   -
462   - return true;
463   -
464   - }
465   -
466   - EnviHeader load_header(std::string header_file)
467   - {
468   - EnviHeader new_header;
469   - new_header.load(header_file);
470   - return new_header;
471   - }
472   -
473   - void set_header(EnviHeader new_header)
474   - {
475   - if(caps(new_header))
476   - header = new_header;
477   - else
478   - exit(1);
479   - }
480   -
481   -public:
482   -
483   - EnviFile()
484   - {
485   - init();
486   - }
487   -
488   - EnviFile(std::string filename, std::string file_mode = "r")
489   - {
490   - init();
491   - open(filename, filename + ".hdr", file_mode);
492   - }
493   -
494   - void open(std::string file_name, std::string header_name, std::string file_mode = "r")
495   - {
496   - mode = file_mode;
497   -
498   - header.name = header_name;
499   -
500   - //open the data file
501   - data = fopen(file_name.c_str(), mode.c_str());
502   -
503   - //lock the file if we are loading or appending
504   - if(mode == "r" || mode == "a" || mode == "r+" || mode == "a+")
505   - {
506   - locked = true;
507   - //load the ENVI header - failure will cause an exit
508   - set_header(load_header(header_name));
509   - }
510   - else
511   - {
512   - header.name = header_name;
513   - }
514   -
515   -
516   - }
517   -
518   - void setDescription(std::string desc)
519   - {
520   - readonly(); //if the file is read-only, throw an exception
521   - header.description = desc;
522   - }
523   -
524   - void setZPlotTitles(std::string spectrum, std::string value)
525   - {
526   - readonly(); //if the file is read-only, throw an exception
527   - header.z_plot_titles[0] = spectrum;
528   - header.z_plot_titles[1] = value;
529   - }
530   -
531   - void setPixelSize(double sx, double sy)
532   - {
533   - readonly(); //if the file is read-only, throw an exception
534   - header.pixel_size[0] = sx;
535   - header.pixel_size[1] = sy;
536   - }
537   -
538   - void setWavelengthUnits(std::string units)
539   - {
540   - readonly(); //if the file is read-only, throw an exception
541   - header.wavelength_units = units;
542   - }
543   -
544   - void setCoordinates(double x, double y)
545   - {
546   - readonly(); //if the file is read-only, throw an exception
547   - header.x_start = x;
548   - header.y_start = y;
549   - }
550   -
551   - //FUNCTIONS THAT MAY BE DISALLOWED IN A LOCKED FILE
552   - void setSamples(unsigned int samples)
553   - {
554   - EnviHeader newHeader = header;
555   - newHeader.samples = samples;
556   - set_header(newHeader);
557   - }
558   -
559   - void setLines(unsigned int lines)
560   - {
561   - EnviHeader newHeader = header;
562   - newHeader.lines = lines;
563   - set_header(newHeader);
564   - }
565   -
566   - void setBands(unsigned int bands)
567   - {
568   - EnviHeader newHeader = header;
569   - newHeader.bands = bands;
570   - set_header(newHeader);
571   - }
572   -
573   - //DATA MANIPULATION
574   - void addBand(void* band, unsigned int samples, unsigned int lines, double wavelength, std::string band_name ="")
575   - {
576   - //add a band to the file
577   -
578   - EnviHeader newHeader = header;
579   - newHeader.bands++;
580   - newHeader.samples = samples;
581   - newHeader.lines = lines;
582   - newHeader.wavelength.push_back(wavelength);
583   - if(band_name != "")
584   - newHeader.band_names.push_back(band_name);
585   - set_header(newHeader);
586   -
587   - //copy the data to the file
588   - fwrite(band, header.valsize(), samples * lines, data);
589   -
590   - //since data was written, the file must be locked
591   - locked = true;
592   - }
593   -
594   - //close file
595   - void close()
596   - {
597   - std::cout<<"ENVI File Mode: "<<mode<<std::endl;
598   -
599   - //close the data stream
600   - fclose(data);
601   -
602   - //close the header
603   - if(mode != "r")
604   - header.save();
605   - }
606   -
607   -}; //end EnviFile
608   -
609   -
610   -#endif
scalarslice.cu
... ... @@ -2,7 +2,7 @@
2 2  
3 3 #include "rts/cuda_handle_error.h"
4 4 #include "cublas_v2.h"
5   -#include "rtsEnvi.h"
  5 +#include "envi/rtsEnvi.h"
6 6  
7 7 scalarslice::scalarslice(int x, int y)
8 8 {
... ... @@ -54,7 +54,6 @@ void scalarslice::toImage(std::string filename, bool positive, rts::colormap::co
54 54 //retrieve the maximum value
55 55 ptype maxVal;
56 56 HANDLE_ERROR(cudaMemcpy(&maxVal, S + result, sizeof(ptype), cudaMemcpyDeviceToHost));
57   - std::cout<<"Maximum value: "<<maxVal<<std::endl;
58 57  
59 58 //destroy the CUBLAS handle
60 59 cublasDestroy(handle);
... ... @@ -80,11 +79,8 @@ void scalarslice::toEnvi(std::string filename, ptype wavelength, bool append)
80 79 ptype* cpuData = (ptype*) malloc( memsize );
81 80 HANDLE_ERROR(cudaMemcpy( cpuData, S, memsize, cudaMemcpyDeviceToHost));
82 81  
83   - std::cout<<"Adding band."<<std::endl;
84   - std::cout<<"First value: "<<cpuData[0]<<std::endl;
85 82 //add a band to the ENVI file
86 83 outfile.addBand(cpuData, R[0], R[1], wavelength);
87   - std::cout<<"Added band."<<std::endl;
88 84  
89 85 outfile.close();
90 86  
... ...