mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
cahoyAlbedos.hpp
Go to the documentation of this file.
1 /** \file cahoyAlbedos.hpp
2  * \author Jared R. Males
3  * \brief Type definitions for the Cahoy et al 2010 albedo spectra
4  * \ingroup astrophot
5  *
6  */
7 
8 #ifndef mx_astro_cahoyAlbedos_hpp
9 #define mx_astro_cahoyAlbedos_hpp
10 
11 #include "units.hpp"
12 #include "../ioutils/readColumns.hpp"
13 
14 namespace mx
15 {
16 namespace astro
17 {
18 
19 /// An albedo spectrum directly from the Cahoy et al (2010) \cite cahoy_2010 grid.
20 /**
21  * \ingroup astrophot_spectra
22  */
23 template<typename _units>
25 {
26  typedef _units units;
27  typedef typename units::realT realT;
28 
29  typedef struct
30  {
31  realT sep; ///< The separation, in AU. Can be 0.8, 2.0, 5.0, or 10.0.
32  int metal; ///< The metallicty. Can be 1, 3, 10, or 30.
33  realT phase; ///< The phase. Must be one of the values in the grid: 0.0, 0.1745, 0.3491, 0.5236, 0.6981, 0.8727, 1.0472, 1.2217, 1.3963,1.5708,1.7453,1.9199, 2.0944, 2.2689, 2.4435, 2.6180, 2.7925,2.9671, 3.139.
34  }
35  paramsT;
36 
37  static const bool freq = false;
38 
39  ///Convert from um to SI m
40  static constexpr realT wavelengthUnits = static_cast<realT>(1e6);
41 
42  ///Geometric albedos are dimensionless.
43  static constexpr realT fluxUnits = static_cast<realT>(1);
44 
45  static constexpr const char * dataDirEnvVar = "CAHOYALBEDO_DATADIR";
46 
47  ///The file name is constructed from the paramerters sep, metal, and phase.
48  static std::string fileName( const paramsT & params )
49  {
50  std::string fname;
51 
52  if(params.sep == 0.8)
53  {
54  fname = "0.8";
55  }
56  else if(params.sep == 2.0)
57  {
58  fname = "2.0";
59  }
60  else if(params.sep == 5.0)
61  {
62  fname = "5";
63  }
64  else if(params.sep == 10.0)
65  {
66  fname = "10";
67  }
68  else
69  {
70  mxError("cahoyAlbedos::fileName", MXE_INVALIDARG, "invalid separation (params.sep)");
71  return "";
72  }
73 
74  fname += "au_";
75  fname += ioutils::convertToString<int>(params.metal);
76  fname += "x_albedos/00_Spectral_Albedos ";
77 
78  char pstr[9];
79  snprintf(pstr, 9, "%0.5f", params.phase);
80 
81  fname+=pstr;
82 
83  fname += ".txt";
84 
85  return fname;
86 
87  }
88 
89  ///Read the spectrum from the file specified by path. Extra columns are discarded.
90  static int readSpectrum( std::vector<realT> & rawLambda,
91  std::vector<realT> & rawSpectrum,
92  const std::string & path,
93  const paramsT & params
94  )
95  {
97 
98  return ioutils::readColumns(path, sk, rawLambda, sk, rawSpectrum);
99  }
100 
101 };
102 
103 /// A class to manage interpolation in separation and phase on the albedo spectrum grid from Cahoy et al (2010) \cite cahoy_2010.
104 /** Usage:
105  \code
106  std::vector<double> lambda;
107  math::vectorScale(lambda, 100000, 4e-12, 600e-9); //Construct the wavelength scale
108 
109  cahoyGrid<units::si<double>> grid;
110  grid.loadGrid(3, lambda); //Open the grid for 3x metallicity, pre-interpolating on the wavelength scale.
111 
112  grid.setParameters({1.0, 0.1}); //Set the separation to 1.0 AU, and the phase angle to 0.1 radians.
113  grid.setSpectrum(lambda); //Perform the interpolation. Note that lambda is only used for a size check here.
114 
115  \endcode
116  * After the above steps you now have the Ag spectrum at 1.0 AU and 0.1 radians phase on the lambda scale.
117  *
118  * \ingroup astrophot
119  */
120 template<typename _units>
121 struct cahoyGrid : public baseSpectrum<typename _units::realT>
122 {
123  typedef _units units;
124  typedef typename units::realT realT;
125 
126  typedef struct
127  {
128  realT sep;
129  realT phase;
130  } paramsT;
131 
132  paramsT _params;
133 
134  std::vector<realT> _sep;
135  std::vector<realT> _phase;
136 
137  std::vector<realT> _lambda;
138  std::vector<std::vector<std::vector<realT>>> _ag;
139 
140  ///Load the grid into memory for one of the metallicities and pre-interpolate onto the wavelength scale.
141  int loadGrid( int metal, ///< [in] the metalicity, can be 1, 3, 10 or 30.
142  std::vector<realT> & lambda ///< [in] the wavelength scale.
143  )
144  {
145  _sep = {0.8, 2.0, 2.0, 5.0, 10.0}; //2 is in there twice to prepare for transition distance.
146  _phase = {0.0, 0.1745, 0.3491, 0.5236, 0.6981, 0.8727, 1.0472, 1.2217, 1.3963,1.5708,1.7453,1.9199, 2.0944, 2.2689, 2.4435, 2.6180, 2.7925,2.9671, 3.139};
147 
148  _ag.resize( _sep.size());
149  for(int i=0; i< _ag.size(); ++i) _ag[i].resize(_phase.size());
150 
152 
153  for(int i=0; i< _sep.size(); ++i)
154  {
155  for(int j=0; j < _phase.size(); ++j)
156  {
157  rawSpect.setParameters({_sep[i], metal, _phase[j]});
158  if( rawSpect.setSpectrum(lambda) < 0)
159  {
160  mxError("cahoGrid::loadGrid", MXE_FILERERR, "Error reading albedo spectrum.");
161  return -1;
162  }
163 
164  _ag[i][j] = rawSpect._spectrum;
165  }
166  }
167 
168  _sep[1] = 1.0; //The transition from cloudy to not-cloudy occurs here.
169 
170  this->_spectrum.resize(lambda.size());
171  return 0;
172  }
173 
174 
175  ///Set the separatio and phase of the spectrum.
176  int setParameters( const paramsT & params /**< [in] Struct containting the separation and phase of the spectrum */)
177  {
178  _params = params;
179 
180  return 0;
181  }
182 
183  ///Get an interpolated spectrum at arbitrary non-grid point using bilinear interpolation.
184  /** If outside the endpoints of the grid, the grid is simply extended (i.e. constant albedo).
185  */
186  int setSpectrum( std::vector<realT> & lambda /**< [in] the wavelength grid. Must be the same as used for construction and/or openGrid*/)
187  {
188  int i_l, i_u, j_l, j_u;
189  realT phase, sep;
190 
191 
192  if(lambda.size() != this->_spectrum.size())
193  {
194  mxError("cahoyGrid::setSpectrum", MXE_INVALIDARG, "wavelength grid (lambda) is not the same size as used for openGrid, or loadGrid not yet called.");
195  return -1;
196  }
197 
198  //Normalize phase
199  phase = fmod(_params.phase, math::pi<realT>());
200  if(phase < 0) phase += math::pi<realT>();
201 
202  sep = _params.sep;
203 
204  i_l = _sep.size()-1;
205  while( _sep[i_l] > sep && i_l > 0) --i_l;
206 
207  i_u = 0;
208  while( i_u < _sep.size()-1)
209  {
210  if(_sep[i_u] >= sep) break;
211  ++i_u;
212  }
213 
214  j_l = _phase.size()-1;
215  while( j_l > 0)
216  {
217  if(_phase[j_l] <= phase) break;
218  --j_l;
219  }
220 
221  j_u = 0;
222  while( j_u < _phase.size()-1)
223  {
224  if(_phase[j_u] >= phase) break;
225  ++j_u;
226  }
227 
228  realT x = sep - _sep[i_l];
229  if(x < 0) x = 0;
230 
231  realT y = (phase - _phase[j_l]);
232  if(y < 0) y = 0;
233 
234  realT x0, x1;
235 
236  for(int i=0; i< this->_spectrum.size(); ++i)
237  {
238  x0 = _ag[i_l][j_l][i];
239  x1 = _ag[i_u][j_l][i];
240 
241  if(y != 0 && j_u != j_l)
242  {
243  x0 += (_ag[i_l][j_u][i] - _ag[i_l][j_l][i])*y/(_phase[j_u] - _phase[j_l]);
244  x1 += (_ag[i_u][j_u][i] - _ag[i_u][j_l][i])*y/(_phase[j_u] - _phase[j_l]);
245  }
246  if( x == 0 || i_u==i_l ) this->_spectrum[i] = x0;
247  else this->_spectrum[i] = x0 + (x1-x0)*x/( _sep[i_u] - _sep[i_l]);
248  }
249 
250  return 0;
251  }
252 
253 };
254 
255 } //namespace mx
256 
257 } //namespace astro
258 
259 #endif //mx_astro_cahoyAlbedos_hpp
int readColumns(const std::string &fname, arrTs &... arrays)
Read in columns from a text file.
The mxlib c++ namespace.
Definition: mxError.hpp:107
Class to manage an astronomical spectrum.
int setSpectrum(gridT &lambda)
Load the spectrum and interpolate it onto a wavelength scale.
int setParameters(const paramsT &params)
Set the parameters of the spectrum, using the underlying spectrums parameter type.
Base spectrum class which provides manipulation and characterization functionality.
std::vector< realT > _spectrum
Contains the spectrum after it is set.
A class to manage interpolation in separation and phase on the albedo spectrum grid from Cahoy et al ...
int loadGrid(int metal, std::vector< realT > &lambda)
Load the grid into memory for one of the metallicities and pre-interpolate onto the wavelength scale.
int setSpectrum(std::vector< realT > &lambda)
Get an interpolated spectrum at arbitrary non-grid point using bilinear interpolation.
int setParameters(const paramsT &params)
Set the separatio and phase of the spectrum.
An albedo spectrum directly from the Cahoy et al (2010) grid.
static constexpr realT fluxUnits
Geometric albedos are dimensionless.
static int readSpectrum(std::vector< realT > &rawLambda, std::vector< realT > &rawSpectrum, const std::string &path, const paramsT &params)
Read the spectrum from the file specified by path. Extra columns are discarded.
static std::string fileName(const paramsT &params)
The file name is constructed from the paramerters sep, metal, and phase.
static constexpr realT wavelengthUnits
Convert from um to SI m.
A dummy class to allow mx::readColumns to skip a column(s) in a file without requiring memory allocat...
Unit specifications and conversions.