Blame view

stim/visualization/swc.h 5.33 KB
1599ae65   Jiaming Guo   add swc.h and fun...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  #ifndef STIM_SWC_H
  #define STIM_SWC_H
  
  #include <vector>
  #include <fstream>
  #include <sstream>
  #include <iostream>
  
  //STIM includes
  #include <stim/math/vec3.h>
  #include <stim/parser/parser.h>
  
  namespace stim {
  	namespace swc_tree {
  		template <typename T>
  		class swc_node {
  
  		protected:
  			enum neuronal_type { SWC_UNDEFINED, SWC_SOMA, SWC_AXON, SWC_DENDRITE, SWC_APICAL_DENDRITE, SWC_FORK_POINT, SWC_END_POINT, SWC_CUSTOM };		// eight types
  			enum node_information { INTEGER_LABEL, NEURONAL_TYPE, X_COORDINATE, Y_COORDINATE, Z_COORDINATE, RADIUS, PARENT_LABEL }; 
  
  		public:
58674036   Jiaming Guo   fix minor error f...
23
  			int idx;							// the index of current node start from 1(original index from the file)
1599ae65   Jiaming Guo   add swc.h and fun...
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
  			neuronal_type type;					// the type of neuronal segmemt
  			stim::vec3<T> point;				// the point coordinates 
  			T radius;							// the radius at current node
  			int parent_idx;						// parent idx of current node, -1 when it is origin(soma)
  			int level;							// tree level
  			std::vector<int> son_idx;			// son idx of current node
  
  			swc_node() {						// default constructor
  				idx = -1;						// set to default -1
  				parent_idx = -1;				// set to origin -1
  				level = -1;						// set to default -1
  				type = SWC_UNDEFINED;			// set to undefined type
  				radius = 0;						// set to 0
  			}
  			
  			void get_node(std::string line) {	// get information from the node point we got
  				
  				// create a vector to store the information of one node point
  				std::vector<std::string> p = stim::parser::split(line, ' ');
  
  				// for each information contained in the node point we got
  				for (unsigned int i = 0; i < p.size(); i++) {
  					std::stringstream ss(p[i]);	// create a stringstream object for casting
58674036   Jiaming Guo   fix minor error f...
47
  
1599ae65   Jiaming Guo   add swc.h and fun...
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
  					// store different information
  					switch (i) {
  					case INTEGER_LABEL:
  						ss >> idx;				// cast the stringstream to the correct numerical value
  						break;
  					case NEURONAL_TYPE:
  						int tmp_type;
  						ss >> tmp_type;			// cast the stringstream to the correct numerical value
  						type = (neuronal_type)tmp_type;
  						break;
  					case X_COORDINATE:
  						T tmp_X;
  						ss >> tmp_X;			// cast the stringstream to the correct numerical value
  						point[0] = tmp_X;		// store the X_coordinate in vec3[0]
  						break;
  					case Y_COORDINATE:
  						T tmp_Y;
  						ss >> tmp_Y;			// cast the stringstream to the correct numerical value
  						point[1] = tmp_Y;		// store the Y_coordinate in vec3[1]
  						break;
  					case Z_COORDINATE:
  						T tmp_Z;
  						ss >> tmp_Z;			// cast the stringstream to the correct numerical value
  						point[2] = tmp_Z;		// store the Z_coordinate in vec3[2]
  						break;
  					case RADIUS:
  						ss >> radius;			// cast the stringstream to the correct numerical value
  						break;
  					case PARENT_LABEL:
  						ss >> parent_idx;		// cast the stringstream to the correct numerical value
  						break;
  					}
  				}
  			}
  		};
  	}		// end of namespace swc_tree
  
  	template <typename T>
  	class swc {
  	public:
ee17b90b   Jiaming Guo   make it compatibl...
88
  		std::vector< typename swc_tree::swc_node<T> > node;
1599ae65   Jiaming Guo   add swc.h and fun...
89
90
91
92
93
94
95
96
97
98
  		swc() {};									// default constructor
  
  		// load the swc as tree nodes
  		void load(std::string filename) {
  
  			// load the file
  			std::ifstream infile(filename.c_str());
  
  			// if the file is invalid, throw an error
  			if (!infile) {
da89bce9   Jiaming Guo   fixed splitting bugs
99
  				std::cerr << "STIM::SWC Error loading file" << filename << std::endl;
1599ae65   Jiaming Guo   add swc.h and fun...
100
101
102
103
104
105
  				exit(-1);
  			}
  
  			std::string line;
  			// skip comment
  			while (getline(infile, line)) {
58674036   Jiaming Guo   fix minor error f...
106
107
  				if ('#' == line[0] || line.empty())			// if it is comment line or empty line
  					continue;								// keep read
1599ae65   Jiaming Guo   add swc.h and fun...
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
  				else
  					break;
  			}
  
  			unsigned int l = 0;				// number of nodes
  
  			// get rid of the first/origin node
  			swc_tree::swc_node<T> new_node;
  			new_node.get_node(line);
  			l++;
  			node.push_back(new_node);		// push back the first node
  
  			getline(infile, line);			// get a new line
  			// keep reading the following node point information as string
  			while (!line.empty()) {			// test for the last empty line
  				l++;						// still remaining node to be read
  
  				swc_tree::swc_node<T> next_node;
  				next_node.get_node(line);
  				node.push_back(next_node);
  
  				getline(infile, line);		// get a new line
  			}
  		}
  
  		// read the head comment from swc file
  		void read_comment(std::string filename) {
  
  			// load the file
  			std::ifstream infile(filename.c_str());
  
  			// if the file is invalid, throw an error
  			if (!infile) {
da89bce9   Jiaming Guo   fixed splitting bugs
141
  				std::cerr << "STIM::SWC Error loading file" << filename << std::endl;
1599ae65   Jiaming Guo   add swc.h and fun...
142
143
144
145
146
  				exit(1);
  			}
  
  			std::string line;
  			while (getline(infile, line)) {
58674036   Jiaming Guo   fix minor error f...
147
  				if ('#' == line[0] || line.empty()) {
1599ae65   Jiaming Guo   add swc.h and fun...
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
  					std::cout << line << std::endl;			// print the comment line by line
  				}
  				else
  					break;									// break when reaches to node information
  			}
  		}
  
  		// link those nodes to create a tree
  		void create_tree() {
  			unsigned n = node.size();								// get the total number of node point
  			int cur_level = 0;
  			
  			// build the origin(soma)
  			node[0].level = cur_level;
  
  			// go through follow nodes
  			for (unsigned i = 1; i < n; i++) {
  				if (node[i].parent_idx != node[i - 1].parent_idx)
  					cur_level = node[node[i].parent_idx - 1].level + 1;
  				node[i].level = cur_level;
58674036   Jiaming Guo   fix minor error f...
168
  				int tmp_parent_idx = node[i].parent_idx - 1;		// get the parent node loop idx of current node
1599ae65   Jiaming Guo   add swc.h and fun...
169
170
171
172
173
174
175
176
177
178
179
180
181
182
  				node[tmp_parent_idx].son_idx.push_back(i + 1);		// son_idx stores the real idx = loop idx + 1
  			}
  		}
  
  		// return the number of point in swc
  		unsigned int numL() {
  			return node.size();
  		}
  
  
  	};
  }		// end of namespace stim
  
  #endif