cellset.h 4.48 KB
#ifndef STIM_CELLSET_H
#define STIM_CELLSET_H

#include <stim/math/vec3.h>
#include <vector>
#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)
	void init(){

	}
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];
	}

	/// 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
	double max(std::string field){
		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
	double min(std::string field){
		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;
	}


};		//end class cellset
};		//end namespace stim

#endif