#include "stim/parser/filename.h" #include "stim/envi/envi.h" #include "stim/visualization/colormap.h" #include "stim/envi/agilent_binary.h" #include void progress_thread_double(double* e); //progress bar threaded function void mosaic_coord(unsigned int &x, unsigned int &y, stim::filename dmd_filename){ //get the file prefix std::string prefix = dmd_filename.get_prefix(); //these files are in the format: // ???????????_xxxxx_yyyyy.dmd //first find the x coordinate //find the position of the last underscore size_t y_start = prefix.find_last_of("_"); //remove all values between x_start and the end of the string std::string y_string = prefix.substr(y_start + 1); y = atoi(y_string.c_str()); //crop out the x coordinate and the last underscore prefix = prefix.substr(0, y_start); //find the y coordinate using the same method as above size_t x_start = prefix.find_last_of("_"); std::string x_string = prefix.substr(x_start + 1); x = atoi(x_string.c_str()); } //Use the file list to find the number of tiles along each dimension of the mosaic void mosaic_size(unsigned int &sx, unsigned int &sy, std::vector dmd_list){ sx = sy = 0; unsigned int xi, yi; //for each dmd file for(unsigned int i = 0; i < dmd_list.size(); i++){ //find the coordinate of the tile represented by this file mosaic_coord(xi, yi, dmd_list[i]); //if the coordinate is larger than the current max, store it as the current max if(xi > sx) sx = xi; if(yi > sy) sy = yi; } //add 1 to reflect that the indexing starts at 0 sx++; sy++; } void mosaic_agilent(std::string filemask, std::string outfile, size_t &X, size_t &Y, size_t &B){ double progress = 0; std::thread t1(progress_thread_double, &progress); //start the progress bar thread //generate a list of tile files stim::filename f = filemask; //create a filename from the specified file mask if(!f.wildcards()) //if the file name doesn't contain wildcards f = filemask + "/*.dmd"; //default to files of type DMD (generally used as agilent mosaic tiles) } std::vector tile_list = f.get_list(); //create a list of tile files stim::agilent_binary binfile(tile_list[0]); //load the first agilent binary file size_t detector_size = binfile.dim(0); //get the detector size std::cout<<"Building a mosaic with a detector size of "< hdr_list = f.get_list(); //allocate space for a list of headers that match this pattern //if(hdr_list.size() == 0){ //throw an error of a header doesn't exist // std::cout<<"No ENVI header file found. A header file created with Resolutions Pro (export ENVI) provides useful wavelength information. If one is unavailable, use the --create-header option to estimate these properties and create a minimal header file."< envi_list; envi_list.resize(mx * my); //set the length to the number of tiles //open each tile for(unsigned int m = 0; m < mx * my; m++){ envi_list[m].open(tile_list[m].str(), header); envi_list[m].close(); } //calculate the size of a single band of the mosaic X = mx * detector_size; //number of samples Y = my * detector_size; //number of lines size_t type_size = envi_list[0].type_size(); //byte size of the data type size_t tile_width = detector_size * type_size; //byte size of a tile size_t band_width = X * type_size; //byte width of the band image size_t band_size = band_width * Y; //size of the band in bytes //allocate space for a single band of the mosaic char* band = (char*)malloc(band_size); //allocate space for a single tile of the mosaic char* tile_band = (char*)malloc(detector_size * detector_size * type_size); //open a binary file for writing std::ofstream outstream(outfile.c_str(), std::ios::out|std::ios::binary); //***********Combine Tiles into a Band Image********************** //for each band for(size_t b = 0; b < B; b++){ //unsigned int b = 0; //for each tile along y for(size_t yt = 0; yt < my; yt++){ //for each tile along x for(size_t xt = 0; xt < mx; xt++){ envi_list[xt * my + yt].open(); //open the file for reading (windows has a max # of open files) envi_list[xt * my + yt].band_index((void*)tile_band, b); //load the tile image envi_list[xt * my + yt].close(); //close the file size_t x_idx = xt * tile_width; //calculate the position of this line along x in the output image //for each line along y for(size_t y = 0; y < detector_size; y++){ size_t y_idx = ((my-1) - yt) * detector_size + y; //calculate the position of this line along y //calculate the position of this line in the output image size_t dst_i = y_idx * band_width + x_idx; size_t src_i = y * tile_width; memcpy(band + dst_i, tile_band + src_i, tile_width); } } } outstream.write(band, band_size); progress = (double)(b + 1) / header.bands * 100; } progress = 100; //close the binary file outstream.close(); //free the memory allocated for the tile and output bands free(tile_band); free(band); //update and save the header //header.samples = X; //header.lines = Y; //header.header_offset = 0; //the final output doesn't have an offset //header.save(outfile + ".hdr"); t1.join(); //wait for the progress bar thread to finish (it probably already is) } void mosaic_agilent_spectrum(){ } void mosaic_agilent_interferogram(std::string filemask, std::string outfile, double ELWN, int UDR){ size_t X, Y, B; //store the size of the mosaic mosaic_agilent(filemask, outfile, X, Y, B); //generate the mosaic //create the header stim::envi_header header; header.samples = X; header.lines = Y; header.bands = B; double int_delta = (1.0 / ELWN) * ((double)UDR / 2.0); //calculate the interferogram spacing header.set_wavelengths(0, int_delta); header.wavelength_units = "centimeters"; header.save(outfile + ".hdr"); }