Blame view

stim/optics_old/material.h 3.49 KB
8e4f8364   David Mayerich   started a new opt...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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
101
102
103
104
105
106
107
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
141
142
143
144
145
146
147
148
149
150
151
152
153
  #ifndef RTS_MATERIAL_H
  #define RTS_MATERIAL_H
  
  #include <vector>
  #include <ostream>
  #include <iostream>
  #include <fstream>
  #include <complex>
  #include <algorithm>
  #include <sstream>
  #include "../math/complex.h"
  #include "../math/constants.h"
  #include "../math/function.h"
  
  namespace stim{
  
  //Material class - default representation for the material property is the refractive index (RI)
  template<typename T>
  class material : public function< T, complex<T> >{
  
  public:
      enum wave_property{microns, inverse_cm};
      enum material_property{ri, absorbance};
  
  private:
  
      using function< T, complex<T> >::X;
      using function< T, complex<T> >::Y;
      using function< T, complex<T> >::insert;
      using function< T, complex<T> >::bounding;
  
      std::string name;	//name for the material (defaults to file name)
  
      void process_header(std::string str, wave_property& wp, material_property& mp){
  
      	std::stringstream ss(str);	//create a stream from the data string
      	std::string line;
      	std::getline(ss, line);		//get the first line as a string
  		while(line[0] == '#'){		//continue looping while the line is a comment
  
  			std::stringstream lstream(line);	//create a stream from the line
  			lstream.ignore();					//ignore the first character ('#')
  
  			std::string prop;		//get the property name
  			lstream>>prop;
  
  			if(prop == "X"){
  				std::string wp_name;
  				lstream>>wp_name;
  				if(wp_name == "microns") wp = microns;
  				else if(wp_name == "inverse_cm") wp = inverse_cm;
  			}
  			else if(prop == "Y"){
  				std::string mp_name;
  				lstream>>mp_name;
  				if(mp_name == "ri") mp = ri;
  				else if(mp_name == "absorbance") mp = absorbance;
  			}
  
  			std::getline(ss, line);		//get the next line
  		}
  
  		function< T, stim::complex<T> >::process_string(str);
  	}
  
      void from_inverse_cm(){
      	//convert inverse centimeters to wavelength (in microns)
      	for(unsigned int i=0; i<X.size(); i++)
      		X[i] = 10000 / X[i];
  
      	//reverse the function array
      	std::reverse(X.begin(), X.end());
      	std::reverse(Y.begin(), Y.end());
  
      }
  
      void init(){
      	bounding[0] = bounding[1] = stim::complex<T>(1, 0);
      }
  
  
  public:
  
      material(std::string filename, wave_property wp, material_property mp){
      	name = filename;
      	load(filename, wp, mp);
      }
  
      material(std::string filename){
      	name = filename;
      	load(filename);
      }
  
      material(){
      	init();
      }
  
      complex<T> getN(T lambda){
      	return function< T, complex<T> >::linear(lambda);
      }
  
      void load(std::string filename, wave_property wp, material_property mp){
  
      	//load the file as a function
      	function< T, complex<T> >::load(filename);
      }
  
      void load(std::string filename){
  
      	wave_property wp = inverse_cm;
      	material_property mp = ri;
      	//turn the file into a string
      	std::ifstream t(filename.c_str());	//open the file as a stream
  
      	if(!t){
      		std::cout<<"ERROR: Couldn't open the material file '"<<filename<<"'"<<std::endl;
      		exit(1);
      	}
  		std::string str((std::istreambuf_iterator<char>(t)),
  		std::istreambuf_iterator<char>());
  
  		//process the header information
  		process_header(str, wp, mp);
  
  		//convert units
  		if(wp == inverse_cm)
  			from_inverse_cm();
  		//set the bounding values
  		bounding[0] = Y[0];
  		bounding[1] = Y.back();
      }
      std::string str(){
      	std::stringstream ss;
      	ss<<name<<std::endl;
      	ss<<function< T, complex<T> >::str();
      	return ss.str();
      }
      std::string get_name(){
      	return name;
      }
  
      void set_name(std::string str){
      	name = str;
      }
  
  };
  
  }
  
  
  
  
  #endif