Blame view

stim/biomodels/cellset.h 6.79 KB
f5d463e5   David Mayerich   added the stim::c...
1
2
3
4
5
  #ifndef STIM_CELLSET_H
  #define STIM_CELLSET_H
  
  #include <stim/math/vec3.h>
  #include <vector>
42b3c74f   Pavel Govyadinov   Included list in ...
6
  #include <list>
f5d463e5   David Mayerich   added the stim::c...
7
8
9
10
11
12
13
14
15
16
17
18
  #include <unordered_map>
  #include <fstream>
  
  namespace stim{
  
  class cellset{
  private:
  	static const char delim = ' ';
  protected:
  	std::vector<double*> cells;							//vector storing field data for each cell
  	std::unordered_map<std::string, size_t> fields;		//unordered map storing field->index information for each field
  	size_t ip[3];										//hard code to position indices (for speed)
8b899c24   David Mayerich   fixed asynchronou...
19
  
f5d463e5   David Mayerich   added the stim::c...
20
21
22
  	void init(){
  
  	}
5db80c2e   David Mayerich   add cells to a ce...
23
24
25
26
27
28
29
30
31
32
33
34
35
36
  
  	/// Initialize fields for a standard cell set containing three points and a radius
  	void init_p3(){
  		fields.insert(std::pair<std::string, size_t>("x", 0));
  		ip[0] = 0;
  		fields.insert(std::pair<std::string, size_t>("y", 1));
  		ip[1] = 1;
  		fields.insert(std::pair<std::string, size_t>("z", 2));
  		ip[2] = 2;
  	}
  
  	void init_p3r(){
  		init_p3();
  		fields.insert(std::pair<std::string, size_t>("radius", 3));
18cb8a07   Pavel Govyadinov   changed the wrong...
37
  		ip[3] = 3;
5db80c2e   David Mayerich   add cells to a ce...
38
  	}
f5d463e5   David Mayerich   added the stim::c...
39
40
41
42
43
44
45
46
47
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
88
89
90
91
92
93
94
95
96
97
98
99
100
  public:
  	/// Constructor - create an empty cell set
  	cellset(){
  		init();
  	}
  
  	/// Constructor - load a cellset from a file
  	cellset(std::string filename){
  		init();											//initialize an empty cellset
  		load(filename);									//load the cellset from an existing file
  	}
  	
  	/// Loads a cellset from a file
  	void load(std::string filename){
  		std::ifstream infile(filename);
  		std::string header;								//allocate space for the file header
  		std::getline(infile, header);					//get the file header
  
  		// break the header into fields
  		std::stringstream ss(header);					//create a string stream
  		std::string field;								//store a single field name
  		size_t i = 0;									//current field index
  		while (std::getline(ss, field, delim)) {		//split the header into individual fields
  			std::pair<std::string, size_t> p(field, i);	//create a pair associating the header name with the index
  			fields.insert(p);							//insert the pair into the fields map
  			i++;										//increment the data index
  		}
  		size_t nfields = fields.size();					//store the number of fields for each cell
  
  		//load each cell and all associated fields
  		std::string cell_line;							//string holds all information for a cell
  		std::list<std::string> cell_list;				//list will be temporary storage for the cell fields
  		while(std::getline(infile, cell_line)){			//for each cell entry
  			cell_list.push_back(cell_line);				//push the cell entry into the list
  		}
  
  		//convert the list into actual data
  		size_t ncells = cell_list.size();				//count the number of cells
  		cells.resize(ncells);							//allocate enough space in the array to store all cells
  		for(size_t c = 0; c < ncells; c++){				//for each cell entry in the list
  			cells[c] = (double*) malloc(sizeof(double) * nfields);	//allocate enough space for each field
  			std::stringstream fss(cell_list.front());	//turn the string representing the cell list into a stringstream
  			for(size_t f = 0; f < nfields; f++){		//for each field
  				fss>>cells[c][f];						//load the field
  			}
  			cell_list.pop_front();						//pop the read string off of the front of the list
  		}
  		infile.close();									//close the input file
  
  		ip[0] = fields["x"];							//hard code the position indices for speed
  		ip[1] = fields["y"];							//	this assumes all cells have positions
  		ip[2] = fields["z"];
  	}
  
  	/// Return the value a specified field for a cell
  	/// @param c is the cell index
  	/// @param f is the field
  	double value(size_t c, std::string f){
  		size_t idx = fields[f];
  		return cells[c][idx];
  	}
  
8b899c24   David Mayerich   fixed asynchronou...
101
102
103
104
105
106
107
  	/// returns an ID used to look up a field
  	bool exists(std::string f){
  		std::unordered_map<std::string, size_t>::iterator iter = fields.find(f);
  		if(iter == fields.end()) return false;
  		else return true;
  	}
  
f5d463e5   David Mayerich   added the stim::c...
108
109
110
111
112
113
114
115
116
117
118
119
  	/// Return the position of cell [i]
  	stim::vec3<double> p(size_t i){
  		stim::vec3<double> pos(cells[i][ip[0]], cells[i][ip[1]], cells[i][ip[2]]);
  		return pos;
  	}
  
  	/// Return the number of cells in the set
  	size_t size(){
  		return cells.size();
  	}
  
  	/// Return the maximum value of a field in this cell set
8b7d6f9a   David Mayerich   light modificatio...
120
  	double maximum(std::string field){
f5d463e5   David Mayerich   added the stim::c...
121
122
123
124
125
126
127
128
129
130
131
132
  		size_t idx = fields[field];						//get the field index
  		size_t ncells = cells.size();					//get the total number of cells
  		double maxval, val;								//stores the current and maximum values
  		for(size_t c = 0; c < ncells; c++){				//for each cell
  			val = cells[c][idx];						//get the field value for this cell
  			if(c == 0) maxval = val;					//if this is the first cell, just assign the maximum
  			else if(val > maxval) maxval = val;			//	otherwise text for the size of val and assign it as appropriate
  		}
  		return maxval;
  	}
  
  	/// Return the maximum value of a field in this cell set
8b7d6f9a   David Mayerich   light modificatio...
133
  	double minimum(std::string field){
f5d463e5   David Mayerich   added the stim::c...
134
135
136
137
138
139
140
141
142
143
144
  		size_t idx = fields[field];						//get the field index
  		size_t ncells = cells.size();					//get the total number of cells
  		double minval, val;								//stores the current and maximum values
  		for(size_t c = 0; c < ncells; c++){				//for each cell
  			val = cells[c][idx];						//get the field value for this cell
  			if(c == 0) minval = val;					//if this is the first cell, just assign the maximum
  			else if(val < minval) minval = val;			//	otherwise text for the size of val and assign it as appropriate
  		}
  		return minval;
  	}
  
5db80c2e   David Mayerich   add cells to a ce...
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
  	/// adds a cell to the cell set
  	void add(double x, double y, double z, double r = 0){
  
  		if(cells.size() == 0){							//if the cell set is empty
  			if(r == 0)									//if the radius is zero
  				init_p3();								//initialize without a radius
  			else
  				init_p3r();								//otherwise initialize with a radius
  		}
  
  		size_t nf = fields.size();						//get the number of fields
  		size_t bytes = sizeof(double) * nf;				//get the size of a cell field
  		double* newcell = (double*) malloc(bytes);		//allocate memory for the new cell
  		memset(newcell, 0, bytes);						//initialize all fields to zero
  		newcell[ip[0]] = x;
  		newcell[ip[1]] = y;
  		newcell[ip[2]] = z;
  
  		if(r != 0){										//if the user specifies a radius
  			size_t ir = fields["radius"];				//get the index for the radius field
  			newcell[ir] = r;							//add the radius to the field
  		}
  		cells.push_back(newcell);						//push the new memory entry into the cell array
  	}
  
6deb168a   Laila Saadatifard   add save to cells...
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
  void save(std::string filename){
  
  		
  		size_t ncells = cells.size();	// get the number of cells
  		std::ofstream file(filename);	//open a file to store the cell's coordinates
  		if (file.is_open()) {
  		
  			file << "x y z radius\n";	//write the file header
  			for (size_t c=0; c < ncells; c++){   //for each cell
  				if (cells[c][ip[3]] != NULL)	//check if for the current cell, radius has been assigned
  					file << cells[c][ip[0]]  << delim << cells[c][ip[1]] << delim << cells[c][ip[2]] << delim << cells[c][ip[3]] << '\n' ;
  				else							//check if for the current cell, radius has not been assigned, set radius to zero
  					file << cells[c][ip[0]]  << delim << cells[c][ip[1]] << delim << cells[c][ip[2]] << delim << 0 << '\n' ;
  			}
  			
  		}
  			file.close();
  
  	}
  	
f5d463e5   David Mayerich   added the stim::c...
190
191
192
193
  
  };		//end class cellset
  };		//end namespace stim
  
42b3c74f   Pavel Govyadinov   Included list in ...
194
  #endif