Commit 920a7c64f0ae151d90186c1fb308a391085ea026

Authored by David Mayerich
2 parents 93503ec6 79143d0b

Merge branch 'master' of https://github.com/stimlab/stim

envi/binary.h
... ... @@ -112,21 +112,21 @@ public:
112 112 }
113 113  
114 114 //save one band from the memory to the file
115   - bool writeZ( T * p, unsigned int page){
  115 + bool write_page( T * p, unsigned int page){
116 116  
117 117 if(p == NULL){
118 118 std::cout<<"ERROR: unable to write into file, empty pointer"<<std::endl;
119 119 exit(1);
120 120 }
121 121  
122   - file.seekg(R[1] * R[0] * page * sizeof(T), std::ios::beg); //write into memory from the binary file
123   - file.write((char *)p, R[0] * R[1] * sizeof(T));
  122 + file.seekg(R[1] * R[0] * page * sizeof(T), std::ios::beg); //seek to the desired location on disk
  123 + file.write((char *)p, R[0] * R[1] * sizeof(T)); //write binary data
124 124  
125 125 return true;
126 126 }
127 127  
128 128 //save one band of the file into the memory, and return the pointer
129   - bool saveZ( T * p, unsigned int page){
  129 + bool read_page( T * p, unsigned int page){
130 130  
131 131 if (page >= R[2]){ //make sure the bank number is right
132 132 std::cout<<"ERROR: page out of range"<<std::endl;
... ... @@ -140,7 +140,7 @@ public:
140 140 }
141 141  
142 142 //saves a hyperplane orthogonal to dimension d at intersection n
143   - bool getSlice(T * dest, unsigned int d, unsigned int n){
  143 + bool read_plane(T * dest, unsigned int d, unsigned int n){
144 144  
145 145 //reset the file pointer back to the beginning of the file
146 146 file.seekg(0, std::ios::beg);
... ... @@ -167,7 +167,7 @@ public:
167 167 }
168 168  
169 169 //save one pixel of the file into the memory, and return the pointer
170   - bool saveXY(T * p, unsigned x, unsigned y){
  170 + bool read_spectrum(T * p, unsigned x, unsigned y){
171 171  
172 172 unsigned int i;
173 173  
... ... @@ -186,17 +186,6 @@ public:
186 186 return true;
187 187 }
188 188  
189   - /*bool open(std::string filename, unsigned int X, unsigned int h = 0){
190   - return open(filename, vec<unsigned int, 1>(X), h);
191   - }
192   -
193   - bool open(std::string filename, unsigned int X, unsigned int Y, unsigned int h = 0){
194   - return open(filename, vec<unsigned int, 2>(X, Y), h);
195   - }
196   -
197   - bool open(std::string filename, unsigned int X, unsigned int Y, unsigned int Z, unsigned int h = 0){
198   - return open(filename, vec<unsigned int, 3>(X, Y, Z), h);
199   - }*/
200 189  
201 190 };
202 191  
... ...
grids/grid_data.cuh deleted
1   -#ifndef STIM_GRID_DATA_CUH
2   -#define STIM_GRID_DATA_CUH
3   -
4   -#include <vector>
5   -#include <string>
6   -#include <sstream>
7   -
8   -#include "../cuda/threads.h"
9   -#include "../cuda/error.h"
10   -#include "../cuda/devices.h"
11   -
12   -
13   -namespace stim{
14   -
15   -//This object describes a generic D-dimensional grid containing data of type T
16   - // data can be stored on the GPU or CPU (and transferred between the two)
17   - // data can be loaded in the form of images
18   - // data can be saved in the form of binary files
19   -template<typename T, unsigned int D = 1>
20   -class grid_data{
21   -
22   -protected:
23   -
24   - unsigned long R[D]; //elements in each dimension
25   - T* ptr; //pointer to the data (on the GPU or CPU)
26   - bool gpu; //true if the data is on the GPU
27   -
28   -};
29   -
30   -}
31   -
32   -
33   -#endif
34 0 \ No newline at end of file
grids/grid_data.h 0 → 100644
  1 +#ifndef STIM_GRID_DATA_CUH
  2 +#define STIM_GRID_DATA_CUH
  3 +
  4 +#include <vector>
  5 +#include <string>
  6 +#include <sstream>
  7 +#include <fstream>
  8 +
  9 +#include "../cuda/threads.h"
  10 +#include "../cuda/error.h"
  11 +#include "../cuda/devices.h"
  12 +#include "../math/vector.h"
  13 +
  14 +
  15 +namespace stim{
  16 +
  17 +//This object describes a generic D-dimensional grid containing data of type T
  18 + // data can be loaded in the form of images
  19 + // data can be saved in the form of binary files
  20 +template<typename T, unsigned int D = 1>
  21 +class grid_data{
  22 +
  23 +protected:
  24 +
  25 + stim::vec<unsigned long, D> R; //elements in each dimension
  26 + T* ptr; //pointer to the data (on the GPU or CPU)
  27 +
  28 + //return the total number of values in the binary file
  29 + unsigned long samples(){
  30 +
  31 + unsigned long s = 1;
  32 + for(unsigned int d = 0; d < D; d++)
  33 + s *= R[d];
  34 +
  35 + return s;
  36 +
  37 + }
  38 +
  39 +public:
  40 +
  41 + //write data to disk
  42 + void write(std::string filename){
  43 +
  44 + std::fstream file;
  45 +
  46 + //open the file as binary for reading
  47 + file.open(filename.c_str(), std::ios::out | std::ios::binary);
  48 +
  49 + //write file to disk
  50 + file.write((char *)ptr, samples() * sizeof(T));
  51 + }
  52 +
  53 + //load a binary file from disk
  54 + // header size is in bytes
  55 + void read(std::string filename, stim::vec<unsigned long, D> S, unsigned long header = 0){
  56 +
  57 + R = S; //set the sample resolution
  58 +
  59 + std::fstream file;
  60 +
  61 + //open the file as binary for writing
  62 + file.open(filename.c_str(), std::ios::in | std::ios::binary);
  63 +
  64 + //seek past the header
  65 + file.seekg(header, std::ios::beg);
  66 +
  67 + //read the data
  68 + file.read((char *)ptr, samples() * sizeof(T));
  69 + }
  70 +
  71 +
  72 +
  73 +};
  74 +
  75 +}
  76 +
  77 +
  78 +#endif
... ...
grids/image_stack.h
1 1 #ifndef STIM_IMAGE_STACK_H
2 2 #define STIM_IMAGE_STACK_H
3 3  
  4 +#include "../parser/wildcards.h"
  5 +#include "../parser/filename.h"
  6 +#include "../grids/grid_data.h"
  7 +#include "../image/image.h"
4 8  
5 9 namespace stim{
6 10  
7 11 //this creates a class that can be used to load 3D grid data from stacks of images
  12 +// The class uses a 4D grid_data object, where the first dimension is color
8 13 template<typename T>
9   -class image_stack : public virtual grid_data<T, 3>{
  14 +class image_stack : public virtual grid_data<T, 4>{
  15 +
  16 + enum image_type {stimAuto, stimMono, stimRGB, stimRGBA};
  17 +
  18 +protected:
  19 + using grid_data<T, 4>::R;
  20 + using grid_data<T, 4>::ptr;
  21 + using grid_data<T, 4>::samples;
  22 +
  23 +public:
  24 +
  25 + void load_images(std::string file_mask){
  26 +
  27 + stim::filename file_path(file_mask);
  28 +
  29 + //if the file path is relative, update it with the current working directory
  30 + if(file_path.is_relative()){
  31 + stim::filename wd = stim::filename::cwd();
  32 + file_path = wd.get_relative(file_mask);
  33 + }
  34 +
  35 + //get the list of files
  36 + std::vector<stim::filename> file_list = file_path.get_list();
  37 +
  38 + //if there are no matching files, exit
  39 + if(file_list.size() == 0){
  40 + std::cout<<"STIM ERROR (image_stack): No matching files for loading a stack."<<std::endl;
  41 + exit(1);
  42 + }
  43 +
  44 + //load the first image and set all of the image_stack properties
  45 + std::cout<<"File to Load: "<<file_list[0].str()<<std::endl;
  46 + stim::image<T> I(file_list[0].str());
  47 +
  48 + //set the image resolution and number of channels
  49 + R[0] = I.channels();
  50 + R[1] = I.width();
  51 + R[2] = I.height();
  52 + R[3] = file_list.size();
  53 +
  54 + //allocate storage space
  55 + ptr = (T*)malloc(sizeof(T) * samples());
  56 +
  57 + //load and copy each image into the grid
  58 + for(unsigned int i = 0; i<R[3]; i++){
  59 +
  60 + //load the image
  61 + stim::image<T> I(file_list[i].str());
  62 +
  63 + //retrieve the interlaced data from the image - store it in the grid
  64 + I.data_interleaved(&ptr[ i * R[0] * R[1] * R[2] ]);
  65 + }
  66 + }
  67 +
  68 + void save_image(std::string file_name, unsigned int i){
  69 +
  70 + //create an image
  71 + stim::image<T> I;
  72 +
  73 + //retrieve the interlaced data from the image - store it in the grid
  74 + I.set_interleaved(&ptr[ i * R[0] * R[1] * R[2] ], R[1], R[2], R[0]);
  75 +
  76 + I.save(file_name);
  77 + }
  78 +
  79 + void save_images(std::string file_mask){
  80 +
  81 + stim::filename file_path(file_mask);
  82 +
  83 + //if the file path is relative, update it with the current working directory
  84 + if(file_path.is_relative()){
  85 + stim::filename wd = stim::filename::cwd();
  86 + file_path = wd.get_relative(file_mask);
  87 + }
  88 +
  89 + //create a list of file names
  90 + std::vector<std::string> file_list = stim::wildcards::increment(file_path.str(), 0, R[3]-1, 1);
  91 +
  92 + for(int i=0; i<R[3]; i++)
  93 + save_image(file_list[i], i);
  94 + }
  95 +
  96 +
  97 +
  98 +
10 99  
11 100 };
12 101  
13 102  
14 103 }
15 104  
16   -#endif
17 105 \ No newline at end of file
  106 +#endif
... ...
image/image.h
... ... @@ -37,7 +37,7 @@ public:
37 37 img.save(filename.c_str());
38 38 }
39 39  
40   - //create an image from an interlaced buffer
  40 + //create an image from an interleaved buffer
41 41 void set_interleaved(T* buffer, unsigned int width, unsigned int height, unsigned int channels = 1){
42 42  
43 43 unsigned char* non_interleaved = (unsigned char*)malloc(width * height * 3);
... ... @@ -53,8 +53,34 @@ public:
53 53 }
54 54  
55 55 //returns a pointer to the first pixel of the image data
56   - T* data(){
57   - return img.data();
  56 + void data_noninterleaved(T* data){
  57 + memcpy(data, img.data(), sizeof(T) * size());
  58 + }
  59 +
  60 + void data_interleaved(T* data){
  61 +
  62 + unsigned int C = channels();
  63 + unsigned int X = size();
  64 +
  65 + T* ptr = img.data();
  66 +
  67 + //for each channel
  68 + for(unsigned int c = 0; c < C; c++)
  69 + //convert each pixel
  70 + for(unsigned int x = 0; x < X; x++)
  71 + data[x * C + c] = ptr[c * X + x];
  72 + }
  73 +
  74 + unsigned int channels(){
  75 + return (unsigned int)img.spectrum();
  76 + }
  77 +
  78 + unsigned int width(){
  79 + return img.width();
  80 + }
  81 +
  82 + unsigned int height(){
  83 + return img.height();
58 84 }
59 85  
60 86 //returns the size (number of values) of the image
... ...
ui/arguments.h renamed to parser/arguments.h
... ... @@ -417,7 +417,7 @@ namespace stim{
417 417 {
418 418 int i = find(opts.begin(), opts.end(), _name) - opts.begin();
419 419  
420   - if(i < 0)
  420 + if(i < 0 || i >= opts.size())
421 421 {
422 422 std::cout<<"ERROR - Unspecified parameter name: "<<_name<<std::endl;
423 423 exit(1);
... ...
parser/filename.h 0 → 100644
  1 +#ifndef STIM_FILENAME_H
  2 +#define STIM_FILENAME_H
  3 +
  4 +#include <stdio.h> /* defines FILENAME_MAX */
  5 +#ifdef _WIN32
  6 + #include <direct.h>
  7 + #define GetCurrentDir _getcwd
  8 + #define STIM_FILENAME_DIV '\\'
  9 +#else
  10 + #include <unistd.h>
  11 + #define GetCurrentDir getcwd
  12 + #define STIM_FILENAME_DIV '/'
  13 + #endif
  14 +
  15 +#include <string>
  16 +#include <sstream>
  17 +#include <vector>
  18 +#include <stack>
  19 +#include <algorithm>
  20 +
  21 +#include "../parser/parser.h"
  22 +
  23 +#include <boost/filesystem.hpp>
  24 +
  25 +namespace stim{
  26 +
  27 +//filename class designed to work with both Windows and Unix
  28 +
  29 +class filename{
  30 +
  31 +private:
  32 + void init(){
  33 +
  34 + absolute = false;
  35 +
  36 + }
  37 +
  38 +protected:
  39 +
  40 + std::string drive; //drive letter (for Windows)
  41 + std::vector<std::string> path; //directory hierarchy
  42 + std::string prefix; //file prefix (without extension)
  43 + std::string ext; //file extension
  44 +
  45 + bool absolute; //filename is an absolute path
  46 +
  47 + //replace any incorrect dividers with the appropriate version for the OS
  48 + std::string parse_div(std::string s) {
  49 + #ifdef _WIN32
  50 + std::replace( s.begin(), s.end(), '/', '\\');
  51 + #else
  52 + std::replace( s.begin(), s.end(), '\\', '/');
  53 + #endif
  54 +
  55 + return s;
  56 + }
  57 +
  58 + //parse the file name (prefix and extension)
  59 + void parse_name(std::string fname){
  60 +
  61 + //find the extension
  62 + size_t xpos = fname.find_last_of('.'); //find the position of the extension period (if there is one)
  63 + if(xpos != std::string::npos){ //split the prefix and extension
  64 + prefix = fname.substr(0, xpos);
  65 + ext = fname.substr(xpos + 1);
  66 + }
  67 + else
  68 + prefix = fname;
  69 + }
  70 +
  71 + //parse a file locator string
  72 + void parse(std::string loc){
  73 +
  74 + //determine the drive (if Windows)
  75 + drive = "";
  76 + #ifdef _WIN32
  77 + //if the second character is a colon, the character right before it is the drive
  78 + if(loc[1] == ':'){
  79 + absolute = true; //this is an absolute path
  80 + drive = loc[0]; //copy the drive letter
  81 + loc = loc.substr(3); //remove the drive information from the locator string
  82 + }
  83 + #else
  84 + if(loc[0] == STIM_FILENAME_DIV){
  85 + absolute = true;
  86 + loc = loc.substr(1);
  87 + }
  88 + #endif
  89 +
  90 + //determine the file name
  91 + std::string fname = loc.substr( loc.find_last_of(STIM_FILENAME_DIV) + 1 ); //find the file name (including extension)
  92 +
  93 + //parse the file name
  94 + parse_name(fname);
  95 +
  96 + //find the directory hierarchy
  97 + std::string dir = loc.substr(0, loc.find_last_of(STIM_FILENAME_DIV) + 1 );
  98 + path = stim::parser::split(dir, STIM_FILENAME_DIV);
  99 + }
  100 +
  101 +public:
  102 +
  103 + filename(){
  104 + init();
  105 + }
  106 +
  107 + filename(std::string loc){
  108 + init();
  109 + parse(loc);
  110 + }
  111 +
  112 +
  113 +
  114 + std::string get_name(){
  115 + if(prefix == "" && ext == "")
  116 + return "";
  117 + else
  118 + return prefix + "." + ext;
  119 + }
  120 +
  121 + std::string get_extension(){
  122 + return ext;
  123 + }
  124 +
  125 + std::string get_prefix(){
  126 + return prefix;
  127 + }
  128 +
  129 + std::string dir(){
  130 + std::stringstream ss;
  131 +
  132 + //if the path is absolute
  133 + if(absolute){
  134 + //output the drive letter if in Windows
  135 + #ifdef _WIN32
  136 + ss<<drive<<":";
  137 + #endif
  138 + ss<<STIM_FILENAME_DIV;
  139 + }
  140 +
  141 + //output the directory
  142 + for(unsigned int d = 0; d < path.size(); d++)
  143 + ss<<path[d]<<STIM_FILENAME_DIV;
  144 +
  145 + return ss.str();
  146 +
  147 + }
  148 +
  149 + std::string str(){
  150 +
  151 + std::stringstream ss;
  152 +
  153 + ss<<dir()<<get_name();
  154 +
  155 + return ss.str();
  156 + }
  157 +
  158 + //get a list of files matching the current tamplate
  159 + std::vector<stim::filename> get_list(){
  160 +
  161 + boost::filesystem::path p(dir()); //create a path from the current filename
  162 +
  163 + std::vector<stim::filename> file_list;
  164 +
  165 + if(boost::filesystem::exists(p)){
  166 + if(boost::filesystem::is_directory(p)){
  167 +
  168 + typedef std::vector<boost::filesystem::path> vec; // store paths,
  169 + vec v; // so we can sort them later
  170 +
  171 + std::copy(boost::filesystem::directory_iterator(p), boost::filesystem::directory_iterator(), back_inserter(v));
  172 +
  173 + std::sort(v.begin(), v.end()); // sort, since directory iteration
  174 + // is not ordered on some file systems
  175 +
  176 + //compare file names to the current template (look for wild cards)
  177 + for (vec::const_iterator it(v.begin()), it_end(v.end()); it != it_end; ++it)
  178 + {
  179 +
  180 + //if the filename is a wild card *or* it matches the read file name
  181 + if( prefix == "*" || prefix == (*it).filename().stem().string()){
  182 +
  183 + //if the extension is a wild card *or* it matches the read file extension
  184 + if( ext == "*" || "." + ext == (*it).filename().extension().string()){
  185 +
  186 + file_list.push_back((*it).string()); //include it in the final list
  187 + }
  188 + }
  189 +
  190 + }
  191 + }
  192 + }
  193 +
  194 + return file_list;
  195 + }
  196 +
  197 + //gets the current working directory
  198 + static stim::filename cwd(){
  199 +
  200 +
  201 + char cCurrentPath[FILENAME_MAX];
  202 +
  203 + if (!GetCurrentDir(cCurrentPath, sizeof(cCurrentPath))){
  204 + std::cout<<"ERROR getting current working directory."<<std::endl;
  205 + exit(1);
  206 + }
  207 +
  208 + std::cout<<cCurrentPath<<std::endl;
  209 + return stim::filename(std::string(cCurrentPath) + STIM_FILENAME_DIV);
  210 + }
  211 +
  212 + void set_name(std::string fname){
  213 + parse_name(fname);
  214 + }
  215 +
  216 + //get a path relative to the current one
  217 + stim::filename get_relative(std::string rel){
  218 +
  219 + std::vector<std::string> rel_path = stim::parser::split(rel, STIM_FILENAME_DIV);
  220 +
  221 + //if the relative path doesn't contain a file, add a blank string to be used as the filename
  222 + if(rel[rel.size()-1] == STIM_FILENAME_DIV)
  223 + rel_path.push_back("");
  224 +
  225 + //create a stack representing the current absolute path
  226 + std::stack<std::string, std::vector<std::string> > s(path);
  227 +
  228 + //for each token in the relative path
  229 + for(int d=0; d<rel_path.size() - 1; d++){
  230 +
  231 + //if the token is a double-dot, pop a directory off of the stack
  232 + if(rel_path[d] == "..")
  233 + s.pop();
  234 + else
  235 + s.push(rel_path[d]);
  236 + }
  237 +
  238 + std::string* end = &s.top() + 1;
  239 + std::string* begin = end - s.size();
  240 + std::vector<std::string> result_path(begin, end);
  241 +
  242 + //create a new path to be returned
  243 + stim::filename result = *this;
  244 + result.path = result_path;
  245 + result.set_name(rel_path.back());
  246 +
  247 + return result;
  248 + }
  249 +
  250 + bool is_relative(){
  251 + return !absolute;
  252 + }
  253 +
  254 + bool is_absolute(){
  255 + return absolute;
  256 + }
  257 +
  258 +
  259 +
  260 +
  261 +
  262 +
  263 +
  264 +
  265 +
  266 +};
  267 +
  268 +
  269 +} //end namespace stim
  270 +
  271 +#endif
... ...
parser/parser.h 0 → 100644
  1 +#ifndef STIM_PARSER_H
  2 +#define STIM_PARSER_H
  3 +
  4 +namespace stim{
  5 +
  6 +class parser{
  7 +
  8 +public:
  9 +
  10 + static std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {
  11 + std::stringstream ss(s);
  12 + std::string item;
  13 + while (std::getline(ss, item, delim)) {
  14 + elems.push_back(item);
  15 + }
  16 + return elems;
  17 + }
  18 +
  19 + static std::vector<std::string> split(const std::string &s, char delim) {
  20 + std::vector<std::string> elems;
  21 + split(s, delim, elems);
  22 + return elems;
  23 + }
  24 +
  25 +};
  26 +
  27 +} //end namespace stim
  28 +
  29 +#endif
0 30 \ No newline at end of file
... ...
parser/wildcards.h 0 → 100644
  1 +#ifndef STIM_WILDCARDS_H
  2 +#define STIM_WILDCARDS_H
  3 +
  4 +#include <sstream>
  5 +#include <iomanip>
  6 +
  7 +
  8 +//#include <boost/regex.hpp>
  9 +
  10 +namespace stim{
  11 +
  12 +class wildcards{
  13 +public:
  14 + //generate a sequence of strings where '?' is replaced by integer increments
  15 + static std::vector<std::string> increment(std::string input,
  16 + unsigned int start,
  17 + unsigned int end,
  18 + unsigned int step){
  19 +
  20 + size_t a = input.find_first_of('?'); //find the first ?
  21 + size_t b = input.find_last_of('?'); //find the last ?
  22 + size_t n = b - a + 1; //calculate the number of ?
  23 +
  24 + std::string str_a = input.substr(0, a); //split the strings along the wildcard
  25 + std::string str_b = input.substr(b + 1, std::string::npos);
  26 +
  27 + //create a vector to hold the output strings
  28 + std::vector<std::string> out;
  29 +
  30 + //create a stringstream to handle the padding
  31 + for (unsigned int i = start; i <= end; i += step){
  32 +
  33 + std::stringstream ss;
  34 + ss << str_a
  35 + << std::setfill('0')
  36 + << std::setw(n)
  37 + << i
  38 + << str_b;
  39 +
  40 + out.push_back(ss.str());
  41 + }
  42 +
  43 + return out;
  44 +
  45 +
  46 + }
  47 +/*
  48 + //returns a list of files that match the specified wildcards in 'd'
  49 + static std::vector<std::string> get_file_list(std::string s){
  50 +
  51 + stim::filename f(s);
  52 + std::string target_path(f.dir());
  53 + boost::regex filter(f.name());
  54 +
  55 + std::vector< std::string > all_matching_files;
  56 +
  57 + boost::filesystem::directory_iterator end_itr; // Default ctor yields past-the-end
  58 + for( boost::filesystem::directory_iterator i( target_path ); i != end_itr; ++i )
  59 + {
  60 + // Skip if not a file
  61 + if( !boost::filesystem::is_regular_file( i->status() ) ) continue;
  62 +
  63 + boost::smatch what;
  64 +
  65 + // Skip if no match
  66 + if( !boost::regex_match( i->path().filename().string(), what, filter ) ) continue;
  67 +
  68 + // File matches, store it
  69 + all_matching_files.push_back( i->path().filename().string() );
  70 + }
  71 +
  72 + return all_matching_files;
  73 +
  74 + }
  75 +*/
  76 +
  77 +};
  78 +
  79 +
  80 +} //end namespace stim
  81 +
  82 +#endif
... ...