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