Commit 00eb682565259cb617d3c9e675fe609204d58290

Authored by Pavel Govyadinov
2 parents c4887649 5687cf1b

Merge branch 'master' of git.stim.ee.uh.edu:codebase/stimlib

cmake/FindANN.cmake 0 → 100644
  1 +# - Try to find ANN
  2 +# Once done this will define
  3 +#
  4 +# ANN_FOUND - system has ANN
  5 +# ANN_INCLUDE_DIR - the ANN include directory
  6 +# ANN_LIBRARY - Link these to use ANN
  7 +#
  8 +
  9 +IF (ANN_INCLUDE_DIRS)
  10 + # Already in cache, be silent
  11 + SET(ANN_FIND_QUIETLY TRUE)
  12 +ENDIF (ANN_INCLUDE_DIRS)
  13 +
  14 +FIND_PATH( ANN_INCLUDE_DIR ANN/ANN.h
  15 + PATHS "/usr/include" "C:/libs/ANN/include")
  16 +
  17 +if( WIN32 )
  18 +
  19 + set(ANN_LIBRARY $ENV{ANN_PATH}\\ANN.lib)
  20 + set(ANN_INCLUDE_DIR $ENV{ANN_PATH})
  21 +
  22 +
  23 + # Store the library dir. May be used for linking to dll!
  24 + # GET_FILENAME_COMPONENT( ANN_LIBRARY_DIR ${ANN_LIBRARY} PATH )
  25 +
  26 + find_package_handle_standard_args(ANN DEFAULT_MSG ANN_INCLUDE_DIR)
  27 +
  28 +else (WIN32)
  29 +
  30 + FIND_LIBRARY( ANN_LIBRARY
  31 + NAMES ann ANN
  32 + PATHS /lib /usr/lib /usr/lib64 /usr/local/lib )
  33 +
  34 +endif( WIN32)
  35 +
  36 +
  37 +IF (ANN_INCLUDE_DIR AND ANN_LIBRARY)
  38 + SET(ANN_FOUND TRUE)
  39 +ELSE (ANN_INCLUDE_DIR AND ANN_LIBRARY)
  40 + SET( ANN_FOUND FALSE )
  41 +ENDIF (ANN_INCLUDE_DIR AND ANN_LIBRARY)
  42 +
... ...
FindSTIM.cmake renamed to cmake/FindSTIM.cmake
stim/biomodels/network.h 0 → 100644
  1 +#ifndef STIM_NETWORK_H
  2 +#define STIM_NETWORK_H
  3 +
  4 +#include <stim/math/vector.h>
  5 +#include <stim/visualization/obj.h>
  6 +#include <list>
  7 +#include <ANN/ANN.h>
  8 +
  9 +namespace stim{
  10 +
  11 +/** This class provides an interface for dealing with biological networks.
  12 + * It takes the following aspects into account:
  13 + * 1) Network geometry and centerlines
  14 + * 2) Network connectivity (a graph structure can be extracted)
  15 + * 3) Network surface structure (the surface is represented as a triangular mesh and referenced to the centerline)
  16 + */
  17 +
  18 +template<typename T>
  19 +class network{
  20 +
  21 + //helper classes
  22 + /// Stores information about a geometric point on the network centerline (including point position and radius)
  23 + //template<typename T>
  24 + class point : public stim::vec<T>{
  25 +
  26 + public:
  27 + T r;
  28 +
  29 + point() : stim::vec<T>(){}
  30 +
  31 + //casting constructor
  32 + point(stim::vec<T> rhs) : stim::vec<T>(rhs){}
  33 + };
  34 +
  35 + //template<typename T>
  36 + class t_node;
  37 + class fiber;
  38 +
  39 + //create typedefs for the iterators to simplify the network code
  40 + typedef typename std::list< fiber >::iterator fiber_i;
  41 + typedef typename std::list< t_node >::iterator t_node_i;
  42 +
  43 + /// Stores information about a single capillary (a length of vessel between two branch or end points)
  44 + //template<typename T>
  45 + class fiber{
  46 +
  47 + public:
  48 + std::list< point > P; //geometric point positions
  49 +
  50 + typename std::list< t_node >::iterator n[2]; //indices to terminal nodes
  51 + unsigned int id;
  52 +
  53 + public:
  54 +
  55 + /// Calculate the length of the fiber and return it.
  56 + T length(){
  57 +
  58 + point p0, p1;
  59 + T l = 0; //initialize the length to zero
  60 +
  61 + //for each point
  62 + typename std::list< point >::iterator i; //create a point iterator
  63 + for(i = P.begin(); i != P.end(); i++){ //for each point in the fiber
  64 +
  65 + if(i == P.begin()) //if this is the first point, just store it
  66 + p1 = *i;
  67 + else{ //if this is any other point
  68 + p0 = p1; //shift p1->p0
  69 + p1 = *i; //set p1 to the new point
  70 + l += (p1 - p0).len(); //add the length of p1 - p0 to the running sum
  71 + }
  72 + }
  73 +
  74 + return l; //return the length
  75 + }
  76 +
  77 + T radius(T& length){
  78 +
  79 + point p0, p1; //temporary variables to store point positions
  80 + T r0, r1; //temporary variables to store radii at points
  81 + T l, r; //temporary variable to store the length and average radius of a fiber segment
  82 + T length_sum = 0; //initialize the length to zero
  83 + T radius_sum = 0; //initialize the radius sum to zero
  84 +
  85 + //for each point
  86 + typename std::list< point >::iterator i; //create a point iterator
  87 + for(i = P.begin(); i != P.end(); i++){ //for each point in the fiber
  88 +
  89 + if(i == P.begin()){ //if this is the first point, just store it
  90 + p1 = *i;
  91 + r1 = i->r;
  92 + }
  93 + else{ //if this is any other point
  94 + p0 = p1; //shift p1->p0 and r1->r0
  95 + r0 = r1;
  96 + p1 = *i; //set p1 to the new point
  97 + r1 = i->r; //and r1
  98 +
  99 + l = (p1 - p0).len(); //calculate the length of the p0-p1 segment
  100 + r = (r0 + r1) / 2; //calculate the average radius of the segment
  101 +
  102 + radius_sum += r * l; //add the radius scaled by the length to a running sum
  103 + length_sum += l; //add the length of p1 - p0 to the running sum
  104 + }
  105 + }
  106 +
  107 + length = length_sum; //store the total length
  108 + return radius_sum / length; //return the average radius of the fiber
  109 + }
  110 +
  111 + std::string str(){
  112 + std::stringstream ss;
  113 +
  114 + //create an iterator for the point list
  115 + typename std::list<point>::iterator i;
  116 + for(i = P.begin(); i != P.end(); i++){
  117 + ss<<i->str()<<" r = "<<i->r<<std::endl;
  118 + }
  119 +
  120 + return ss.str();
  121 + }
  122 + };
  123 +
  124 + /// Terminal node for a capillary. This is analogous to a graph vertex and contains a list of edge indices.
  125 + //template<typename T>
  126 + class t_node{
  127 +
  128 + public:
  129 +
  130 + unsigned int id;
  131 +
  132 + //lists of edge indices for capillaries
  133 + //the "in" and "out" just indicate how the geometry is defined:
  134 + // edges in the "in" list are geometrically oriented such that the terminal node is last
  135 + // edges in the "out" list are geometrically oriented such that the terminal node is first
  136 + std::list< fiber_i > in; //edge indices for incoming capillaries
  137 + std::list< fiber_i > out; //edge indices for outgoing capillaries
  138 +
  139 + std::string str(){
  140 +
  141 + std::stringstream ss;
  142 +
  143 + ss<<id<<": "; //output the node ID
  144 +
  145 + //output the IDs for both lists
  146 + typename std::list< fiber_i >::iterator f;
  147 +
  148 + for(f = in.begin(); f != in.end(); f++){
  149 +
  150 + if(f != in.begin())
  151 + ss<<", ";
  152 + ss<<(*f)->n[0]->id;
  153 + }
  154 +
  155 + //if there are nodes in both lists, separate them by a comma
  156 + if(out.size() > 0 && in.size() > 0)
  157 + ss<<", ";
  158 +
  159 + for(f = out.begin(); f != out.end(); f++){
  160 +
  161 + if(f != out.begin())
  162 + ss<<", ";
  163 + ss<<(*f)->n[1]->id;
  164 + }
  165 +
  166 +
  167 + return ss.str();
  168 +
  169 +
  170 +
  171 + }
  172 + };
  173 +
  174 +
  175 +
  176 +
  177 +protected:
  178 +
  179 + //list of terminal nodes
  180 + std::list<t_node> N;
  181 +
  182 + //list of fibers
  183 + std::list<fiber> F;
  184 +
  185 + /// Sets a unique ID for each terminal node and fiber
  186 + void set_names(){
  187 +
  188 + unsigned int i;
  189 +
  190 + i = 0;
  191 + for(t_node_i ti = N.begin(); ti != N.end(); ti++)
  192 + ti->id = i++;
  193 +
  194 + i = 0;
  195 + for(fiber_i fi = F.begin(); fi != F.end(); fi++)
  196 + fi->id = i++;
  197 + }
  198 +
  199 +public:
  200 +
  201 + std::string str(){
  202 +
  203 +
  204 + //assign names to elements of the network
  205 + set_names();
  206 +
  207 + //create a stringstream for output
  208 + std::stringstream ss;
  209 +
  210 + //output the nodes
  211 + ss<<"Nodes----------------------------"<<std::endl;
  212 + for(t_node_i i = N.begin(); i != N.end(); i++){
  213 + ss<<i->str()<<std::endl;
  214 + }
  215 +
  216 + //output the fibers
  217 + ss<<std::endl<<"Fibers---------------------------"<<std::endl;
  218 +
  219 + T length, radius;
  220 + //output every fiber
  221 + for(fiber_i f = F.begin(); f != F.end(); f++){
  222 +
  223 + //calculate the length and average radius
  224 + radius = f->radius(length);
  225 +
  226 + //output the IDs of the terminal nodes
  227 + ss<<f->n[0]->id<<" -- "<<f->n[1]->id<<": length = "<<length<<", average radius = "<<radius<<std::endl;
  228 + }
  229 +
  230 + return ss.str();
  231 + }
  232 +
  233 + /// Load a network from an OBJ object
  234 + void load( stim::obj<T> object){
  235 +
  236 + //get the number of vertices in the object
  237 + unsigned int nV = object.numV();
  238 +
  239 + //allocate an array of pointers to nodes, which will be used to preserve connectivity
  240 + //initiate all values to T.end()
  241 + std::vector< t_node_i > node_hash(nV, N.end());
  242 +
  243 + unsigned int nL = object.numL(); //get the number of lines in the OBJ
  244 +
  245 + //for each line in the OBJ structure
  246 + for(unsigned int li = 0; li < nL; li++){
  247 +
  248 + F.push_back(fiber()); //push a new fiber onto the fiber list
  249 +
  250 + fiber_i f = --(F.end()); //get an iterator to the new fiber
  251 +
  252 + //----------Handle the terminating nodes for the fiber
  253 +
  254 + //get the indices of the line vertices
  255 + std::vector< unsigned int > Li = object.getL_Vi(li);
  256 + unsigned int i0 = Li.front() - 1;
  257 + unsigned int i1 = Li.back() - 1;
  258 +
  259 + //deal with the first end point of the capillary
  260 + if(node_hash[i0] != N.end()){ //if the node has been used before
  261 + (*f).n[0] = node_hash[i0]; //assign the node to the new capillary
  262 + (*node_hash[i0]).out.push_back(f); //add an out pointer to the existing node
  263 + }
  264 + else{ //otherwise
  265 + N.push_back(t_node()); //create a new node and add it to the node list
  266 + t_node_i t = --(N.end()); //get an iterator to the new node
  267 + node_hash[i0] = t; //add a pointer to the new node to the hash list
  268 + (*f).n[0] = t; //add a pointer to the new node to the capillary
  269 + (*t).out.push_back(f); //add a pointer to the capillary to the new node
  270 + }
  271 +
  272 + //deal with the last end point of the capillary
  273 + if(node_hash[i1] != N.end()){
  274 + (*f).n[1] = node_hash[i1];
  275 + (*node_hash[i1]).in.push_back(f);
  276 + }
  277 + else{
  278 + N.push_back(t_node());
  279 + t_node_i t = --(N.end());
  280 + node_hash[i1] = t; //add the new node to the hash list
  281 + (*f).n[1] = t;
  282 + (*t).in.push_back(f);
  283 + }
  284 +
  285 + //-------------Handle the geometric points for the fiber
  286 + std::vector< vec<T> > L = object.getL_V(li);
  287 + std::vector< vec<T> > R = object.getL_VT(li);
  288 +
  289 + unsigned int nP = L.size(); //get the number of geometric points in the fiber
  290 + //for each vertex in the fiber
  291 + for(unsigned int pi = 0; pi < nP; pi++){
  292 + point p = (point)L[pi]; //move the geometric coordinates into a point structure
  293 + p.r = R[pi][0]; //store the radius
  294 + f->P.push_back(p); //push the point onto the current fiber
  295 + }
  296 + }
  297 +
  298 + } //end load()
  299 +
  300 + /// This function returns the information necessary for a simple graph-based physical (ex. fluid) simulation.
  301 +
  302 + /// @param n0 is a array which will contain the list of source nodes
  303 + /// @param n1 is a array which will contain the list of destination nodes
  304 + /// @param length is a array containing the lengths of fibers in the network
  305 + /// @param radius is a array containing the average radii of fibers in the network
  306 + void build_simgraph(std::vector<unsigned int>& n0, std::vector<unsigned int>& n1, std::vector<T>& length, std::vector<T>& radius){
  307 +
  308 + //determine the number of fibers in the network
  309 + unsigned int nF = F.size();
  310 +
  311 + //allocate the necessary space to store the fiber information
  312 + n0.resize(nF);
  313 + n1.resize(nF);
  314 + length.resize(nF);
  315 + radius.resize(nF);
  316 +
  317 + //assign names (identifiers) to the network components
  318 + set_names();
  319 +
  320 + //fill the arrays
  321 + unsigned int i = 0;
  322 + T l, r;
  323 + for(fiber_i f = F.begin(); f != F.end(); f++){
  324 + n0[i] = f->n[0]->id; //get the identifiers for the first and second nodes for the current fiber
  325 + n1[i] = f->n[1]->id;
  326 +
  327 + r = f->radius(l); //get the length and radius of the capillary (calculated at the same time)
  328 +
  329 + radius[i] = r; //store the radius in the output array
  330 + length[i] = l; //store the length in the output array
  331 +
  332 + i++; //increment the array index
  333 + }
  334 +
  335 +
  336 + }
  337 +
  338 +};
  339 +
  340 +}; //end namespace stim
  341 +
  342 +
  343 +#endif
... ...
stim/envi/bil.h
... ... @@ -826,7 +826,7 @@ public:
826 826 }
827 827  
828 828 ///Saves to disk only those spectra corresponding to mask values != 0
829   - bool sift_mask(std::string outfile, unsigned char* p){
  829 + bool sift(std::string outfile, unsigned char* p){
830 830 // Assume X() = X, Y() = Y, Z() = Z.
831 831 std::ofstream target(outfile.c_str(), std::ios::binary);
832 832  
... ...
stim/envi/binary.h
... ... @@ -100,7 +100,7 @@ public:
100 100 /// @param filename is the name of the binary file
101 101 /// @param r is a STIM vector specifying the size of the binary file along each dimension
102 102 /// @param h is the length (in bytes) of any header file (default zero)
103   - bool open(std::string filename, vec<unsigned int, D> r, unsigned int h = 0){
  103 + bool open(std::string filename, vec<unsigned int> r, unsigned int h = 0){
104 104  
105 105 for(unsigned int i = 0; i < D; i++) //set the dimensions of the binary file object
106 106 R[i] = r[i];
... ... @@ -117,7 +117,7 @@ public:
117 117 /// @param filename is the name of the binary file to be created
118 118 /// @param r is a STIM vector specifying the size of the file along each dimension
119 119 /// @offset specifies how many bytes to offset the file (used to leave room for a header)
120   - bool create(std::string filename, vec<unsigned int, D> r, unsigned int offset = 0){
  120 + bool create(std::string filename, vec<unsigned int> r, unsigned int offset = 0){
121 121  
122 122 std::ofstream target(filename.c_str(), std::ios::binary);
123 123  
... ...
stim/envi/bip.h
... ... @@ -836,8 +836,8 @@ public:
836 836 }
837 837  
838 838  
839   - ///Saves to disk only those spectra corresponding to mask values != 0
840   - bool sift_mask(std::string outfile, unsigned char* p){
  839 + /// Saves to disk only those spectra corresponding to mask values != 0
  840 + bool sift(std::string outfile, unsigned char* p){
841 841 // Assume X() = X, Y() = Y, Z() = Z.
842 842 std::ofstream target(outfile.c_str(), std::ios::binary);
843 843  
... ...
stim/envi/bsq.h
... ... @@ -759,8 +759,8 @@ public:
759 759 return true;
760 760 }
761 761  
762   - ///Saves to disk only those spectra corresponding to mask values != 0
763   - bool sift_mask(std::string outfile, unsigned char* p){
  762 + /// Saves to disk only those spectra corresponding to mask values != 0
  763 + bool sift(std::string outfile, unsigned char* p){
764 764 std::ofstream target(outfile.c_str(), std::ios::binary);
765 765 // open a band (XY plane)
766 766 unsigned XY = X() * Y(); //Number of XY pixels
... ... @@ -788,6 +788,57 @@ public:
788 788 return true;
789 789 }
790 790  
  791 + /// Generates a spectral image from a matrix of spectral values in lexicographic order and a mask
  792 + bool unsift(std::string outfile, unsigned char* p, unsigned int samples, unsigned int lines){
  793 +
  794 + //create a binary output stream
  795 + std::ofstream target(outfile.c_str(), std::ios::binary);
  796 +
  797 + //make sure that there's only one line
  798 + if(Y() != 1){
  799 + std::cout<<"ERROR in stim::bsq::sift() - number of lines does not equal 1"<<std::endl;
  800 + return false;
  801 + }
  802 +
  803 + std::cout<<"started sifting"<<std::endl;
  804 +
  805 + //get the number of pixels and bands in the input image
  806 + unsigned int P = X(); //Number of pixels
  807 + unsigned int B = Z(); //number of bands
  808 + unsigned int XY = samples * lines; //total number of pixels in an unsifted image
  809 +
  810 + // allocate memory for a sifted band
  811 + T * sifted = (T*)malloc(P * sizeof(T)); //allocate memory for a band
  812 +
  813 + //allocate memory for an unsifted band image
  814 + T* unsifted = (T*) malloc(XY * sizeof(T));
  815 +
  816 + //for each band
  817 + for(unsigned int b = 0; b < B; b++){
  818 +
  819 + //set the unsifted index value to zero
  820 + unsigned int i = 0;
  821 +
  822 + //retrieve the sifted band (masked pixels only)
  823 + band_index(sifted, b);
  824 +
  825 + //for each pixel in the final image (treat it as a 1D image)
  826 + for(unsigned int xi = 0; xi < XY; xi++){
  827 + if( p[xi] == 0 )
  828 + unsifted[xi] = 0;
  829 + else{
  830 + unsifted[xi] = sifted[i];
  831 + i++;
  832 + }
  833 + }
  834 +
  835 + //write the band image to disk
  836 + target.write(reinterpret_cast<const char*>(unsifted), sizeof(T) * XY);
  837 + }
  838 +
  839 + return true;
  840 + }
  841 +
791 842  
792 843 /// Calculate the mean band value (average along B) at each pixel location.
793 844  
... ...
stim/envi/envi.h
... ... @@ -373,32 +373,48 @@ public:
373 373 }
374 374  
375 375 /// sift-mask saves in an array only those spectra corresponding to nonzero values of the mask.
376   - bool sift_mask(std::string outfile, unsigned char* p)
  376 + bool sift(std::string outfile, unsigned char* p)
377 377 {
378 378  
  379 + //calculate the number of non-zero values in the mask
  380 + unsigned int nnz = 0;
  381 + unsigned int npixels = header.lines * header.samples;
  382 + for(unsigned int i = 0; i < npixels; i++)
  383 + if( p[i] > 0 ) nnz++;
  384 +
  385 + //create a new header
  386 + envi_header new_header = header;
  387 +
  388 + //set the number of lines to 1 (this is a matrix with 1 line and N samples)
  389 + new_header.lines = 1;
  390 + new_header.samples = nnz;
  391 + new_header.save(outfile + ".hdr");
  392 +
  393 + std::cout<<"Saved: "<<outfile+".hdr"<<std::endl;
  394 +
379 395 if (header.interleave == envi_header::BSQ){ //if the infile is bsq file
380 396 if (header.data_type == envi_header::float32)
381   - return ((bsq<float>*)file)->sift_mask(outfile, p);
  397 + return ((bsq<float>*)file)->sift(outfile, p);
382 398 else if (header.data_type == envi_header::float64)
383   - return ((bsq<double>*)file)->sift_mask(outfile, p);
  399 + return ((bsq<double>*)file)->sift(outfile, p);
384 400 else
385 401 std::cout << "ERROR: unidentified data type" << std::endl;
386 402 }
387 403  
388 404 else if (header.interleave == envi_header::BIL){ //if the infile is bil file
389 405 if (header.data_type == envi_header::float32)
390   - return ((bil<float>*)file)->sift_mask(outfile, p);
  406 + return ((bil<float>*)file)->sift(outfile, p);
391 407 else if (header.data_type == envi_header::float64)
392   - return ((bil<double>*)file)->sift_mask(outfile, p);
  408 + return ((bil<double>*)file)->sift(outfile, p);
393 409 else
394 410 std::cout << "ERROR: unidentified data type" << std::endl;
395 411 }
396 412  
397 413 else if (header.interleave == envi_header::BIP){ //if the infile is bip file
398 414 if (header.data_type == envi_header::float32)
399   - return ((bip<float>*)file)->sift_mask(outfile, p);
  415 + return ((bip<float>*)file)->sift(outfile, p);
400 416 else if (header.data_type == envi_header::float64)
401   - return ((bip<double>*)file)->sift_mask(outfile, p);
  417 + return ((bip<double>*)file)->sift(outfile, p);
402 418 else
403 419 std::cout << "ERROR: unidentified data type" << std::endl;
404 420 }
... ... @@ -407,9 +423,48 @@ public:
407 423 std::cout << "ERROR: unidentified file type" << std::endl;
408 424 exit(1);
409 425 }
  426 +
  427 +
410 428 return false;
411 429 }
412 430  
  431 + bool unsift(std::string outfile, unsigned char* mask, unsigned int samples, unsigned int lines){
  432 +
  433 + //create a new header
  434 + envi_header new_header = header;
  435 +
  436 + //set the number of lines and samples in the output file (that's all that changes)
  437 + new_header.lines = lines;
  438 + new_header.samples = samples;
  439 + new_header.save(outfile + ".hdr");
  440 +
  441 +
  442 + if (header.interleave == envi_header::BSQ){ //if the infile is bsq file
  443 + if (header.data_type == envi_header::float32)
  444 + return ((bsq<float>*)file)->unsift(outfile, mask, samples, lines);
  445 + else if (header.data_type == envi_header::float64)
  446 + return ((bsq<double>*)file)->unsift(outfile, mask, samples, lines);
  447 + else
  448 + std::cout << "ERROR: unidentified data type" << std::endl;
  449 + }
  450 +
  451 + else if (header.interleave == envi_header::BIL){ //if the infile is bil file
  452 +
  453 + std::cout << "ERROR in stim::envi::unsift - BIL files aren't supported yet" << std::endl;
  454 + }
  455 +
  456 + else if (header.interleave == envi_header::BIP){ //if the infile is bip file
  457 +
  458 + std::cout << "ERROR in stim::envi::unsift - BIP files aren't supported yet" << std::endl;
  459 + }
  460 +
  461 + else{
  462 + std::cout << "ERROR: unidentified file type" << std::endl;
  463 + exit(1);
  464 + }
  465 +
  466 + }
  467 +
413 468 /// Compute the ratio of two baseline-corrected peaks. The result is stored in a pre-allocated array.
414 469  
415 470 /// @param lb1 is the label value for the left baseline point for the first peak (numerator)
... ...
stim/image/image.h
... ... @@ -28,6 +28,11 @@ public:
28 28 img.load(filename.c_str());
29 29 }
30 30  
  31 + /// Constructor initializes an image to a given size
  32 + image(unsigned int x, unsigned int y = 1, unsigned int z = 1){
  33 + img = cimg_library::CImg<T>(x, y, z);
  34 + }
  35 +
31 36 //Load an image from a file
32 37 void load(std::string filename){
33 38 img.load(filename.c_str());
... ... @@ -72,6 +77,17 @@ public:
72 77 data[x * C + c] = ptr[c * X + x];
73 78 }
74 79  
  80 + image<T> channel(unsigned int c){
  81 +
  82 + //create a new image
  83 + image<T> single;
  84 +
  85 + single.img = img.channel(c);
  86 +
  87 + return single;
  88 +
  89 + }
  90 +
75 91 unsigned int channels(){
76 92 return (unsigned int)img.spectrum();
77 93 }
... ...
stim/math/mathvec.h renamed to stim/math/vector.h
stim/visualization/colormap.h
... ... @@ -287,7 +287,7 @@ static void cpu2cpu(T* cpuSource, unsigned char* cpuDest, unsigned int nVals, T
287 287 }
288 288  
289 289 template<class T>
290   -static void cpu2cpu(T* cpuSource, unsigned char* cpuDest, unsigned int nVals, colormapType cm = cmGrayscale)//, bool positive = false)
  290 +static void cpu2cpu(T* cpuSource, unsigned char* cpuDest, unsigned int nVals, colormapType cm = cmGrayscale)
291 291 {
292 292 //computes the max and min range automatically
293 293  
... ... @@ -329,13 +329,13 @@ static void cpu2image(T* cpuSource, std::string fileDest, unsigned int x_size, u
329 329 }
330 330  
331 331 template<typename T>
332   -static void cpu2image(T* cpuSource, std::string fileDest, unsigned int x_size, unsigned int y_size, colormapType cm = cmGrayscale, bool positive = false)
  332 +static void cpu2image(T* cpuSource, std::string fileDest, unsigned int x_size, unsigned int y_size, colormapType cm = cmGrayscale)
333 333 {
334 334 //allocate a color buffer
335 335 unsigned char* cpuBuffer = (unsigned char*) malloc(sizeof(unsigned char) * 3 * x_size * y_size);
336 336  
337 337 //do the mapping
338   - cpu2cpu<T>(cpuSource, cpuBuffer, x_size * y_size, cm, positive);
  338 + cpu2cpu<T>(cpuSource, cpuBuffer, x_size * y_size, cm);
339 339  
340 340 //copy the buffer to an image
341 341 buffer2image(cpuBuffer, fileDest, x_size, y_size);
... ...
stim/visualization/obj.h
... ... @@ -6,7 +6,7 @@
6 6 #include <fstream>
7 7 #include <stdlib.h>
8 8 #include <stim/parser/parser.h>
9   -#include <stim/math/mathvec.h>
  9 +#include <stim/math/vector.h>
10 10  
11 11 namespace stim{
12 12  
... ... @@ -600,9 +600,42 @@ public:
600 600 }
601 601  
602 602 return l;
  603 + }
  604 +
  605 + /// Returns a vector containing the list of texture coordinates associated with each point of a line.
  606 +
  607 + /// @param i is the index of the desired line
  608 + std::vector< stim::vec<T> > getL_VT(unsigned int i){
  609 +
  610 + //get the number of points in the specified line
  611 + unsigned int nP = L[i].size();
  612 +
  613 + //create a vector of points
  614 + std::vector< stim::vec<T> > l;
  615 +
  616 + //set the size of the vector
  617 + l.resize(nP);
  618 +
  619 + //copy the points from the point list to the stim vector
  620 + unsigned int pi;
  621 + for(unsigned int p = 0; p < nP; p++){
  622 +
  623 + //get the index of the geometry point
  624 + pi = L[i][p][1] - 1;
  625 +
  626 + //get the coordinates of the current point
  627 + stim::vec<T> newP = VT[pi];
  628 +
  629 + //copy the point into the vector
  630 + l[p] = newP;
  631 + }
  632 +
  633 + return l;
603 634  
604 635 }
605 636  
  637 +
  638 +
606 639 };
607 640  
608 641  
... ...