mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
phoenixSpectrum.hpp
1 /** \file phoenixSpectra.hpp
2  * \author Jared R. Males
3  * \brief Utilities for working with spectra from phoenix code.
4  * \ingroup astrophot
5  *
6  */
7 
8 #ifndef phoenixSpectrum_hpp
9 #define phoenixSpectrum_hpp
10 
11 
12 #include "../math/vectorUtils.hpp"
13 #include "../ioutils/fileUtils.hpp"
14 
15 namespace mx
16 {
17 namespace astro
18 {
19 
20 /// A spectrum from the Phoenix model, for use with ioutils::astro::astroSpectrum.
21 /** \ingroup astrophot_spectra
22  */
23 template<typename _units>
25 {
26  typedef _units units;
27  typedef typename units::realT realT;
28 
29  static const bool freq = false;
30 
31  ///Convert from A to SI m
32  static constexpr realT wavelengthUnits = static_cast<realT>(1e10);
33 
34  ///Convert from erg s-1 cm-2 A-1 to SI W m-3
35  static constexpr realT fluxUnits = static_cast<realT>(1e7) / (static_cast<realT>(1e4)*static_cast<realT>(1e10));
36 
37  static constexpr const char * dataDirEnvVar = "PHOENIX_DATADIR";
38 
39  typedef std::string paramsT; ///< The parameter is a string name.
40 
41  static std::string fileName( const std::string & name )
42  {
43  return name;
44  }
45 
46  static int readSpectrum( std::vector<realT> & rawLambda,
47  std::vector<realT> & rawSpectrum,
48  const std::string & path ,
49  const paramsT & params ///< [in] the parameters are passed in case needed to construct the spectrum
50  )
51  {
52  if( ioutils::readColumns(path, rawSpectrum) < 0) return -1;
53 
54  if( ioutils::readColumns(ioutils::parentPath(path) + "/wavelength.dat", rawLambda) < 0) return -1;
55 
56  return 0;
57  }
58 
59  static void scaleSpectrum( std::vector<realT> & spectrum,
60  realT radius,
61  realT distance
62  )
63  {
64  for(int i=0; i < spectrum.size(); ++i)
65  {
66  spectrum[i] *= pow( radius / distance * ( constants::radJupiter<units>() / constants::parsec<units>()), 2);
67  }
68  }
69 
70 };
71 
72 ///Read in, crop, scale, and re-write a Phoenix spectrum data file.
73 /** For working with spectra obtained from: http://perso.ens-lyon.fr/france.allard/
74  *
75  * The Phoenix spectra contain many columns of line data which are not often used, are
76  * not necessarily sorted by wavelength, and are sometimes formated so that points with leading
77  * minus signs are not in a separate column. We also have to change the fortan D to e.
78  *
79  * We also want to apply the dilution factor and take the power of 10.
80  *
81  * This function deals with these issues, producing a two-column space-delimited
82  * file in a specified wavelength range.
83  *
84  * References:
85  * - https://phoenix.ens-lyon.fr/Grids/BT-Settl/README
86  * - https://phoenix.ens-lyon.fr/Grids/FORMAT
87  *
88  * NOTE: This overwrites the input file!
89  *
90  *
91  * \tparam floatT the floating point type in which to work
92  *
93  * \ingroup astrophot_spectra
94  */
95 template<typename floatT>
96 void rewritePhoenixSpectrum( const std::string & filename, ///< [in.out] complete name of the file to rewrite
97  floatT lmin, ///< [in] minimum wavelength to rewrite [microns]
98  floatT lmax, ///< [in] maximum wavelemngth to rewrite [microns]
99  int sepWavelength = 0, ///< [in] [optional] controls how wavelength is handled. 0=> wavelength is included in file as first column. 1=> wavelength is written to a separate 'wavelength.dat' file. -1=> means don't write wavelength.
100  floatT DF = -8.0 ///< [in] [optional] the dilution factor. See references.
101  )
102 {
103  float lambda, flambda;
104 
105  std::ifstream fin;
106 
107  fin.open(filename);
108 
109  if(!fin.good())
110  {
111  std::cerr << "Error opening file: " << filename << "\n";
112  return;
113  }
114 
115  std::vector<floatT> lambdas;
116  std::vector<floatT> flambdas;
117 
118  int lineSize = 1024;
119  char line[lineSize];
120  std::string sline;
121 
122  fin.getline(line, lineSize);
123  sline = line;
124 
125  if(sline.length() < 25)
126  {
127  std::cerr << "Error reading file: " << filename << "\n";
128  }
129 
130  lambda = ioutils::convertFromString<floatT>(sline.substr(1,12));
131 
132  //First have to diagnose if this has the column problem
133  int nst;
134  if(sline[13] == '-') nst = 13;
135  else nst = 14;
136 
137  //convert the D to e
138  size_t dpos = sline.find('D', nst);
139  sline[dpos] = 'e';
140 
141 
142  flambda = ioutils::convertFromString<floatT>(sline.substr(nst,12));
143 
144  if(lambda >= lmin*1e4 && lambda <= lmax*1e4)
145  {
146  lambdas.push_back(lambda);
147  flambdas.push_back(flambda);
148  }
149 
150  fin.getline(line, lineSize);
151  sline = line;
152 
153  while(fin.good())
154  {
155  if(sline.length() < 25) continue;
156 
157  dpos = sline.find('D', nst);
158  sline[dpos] = 'e';
159 
160  lambda = ioutils::convertFromString<floatT>(sline.substr(1,12));
161  flambda = ioutils::convertFromString<floatT>(sline.substr(nst,12));
162 
163  if(lambda >= lmin*1e4 && lambda <= lmax*1e4)
164  {
165  lambdas.push_back(lambda);
166  flambdas.push_back(flambda);
167  }
168 
169  fin.getline(line, lineSize);
170  sline = line;
171  }
172 
173  fin.close();
174 
175  std::vector<size_t> idx = math::vectorSortOrder(lambdas);
176 
177  std::ofstream fout;
178 
179  std::string fname = filename;// + ".t";
180  fout.open(filename);
181  fout.precision(10);
182 
183  for(int i=0;i<lambdas.size(); ++i)
184  {
185  if(sepWavelength == 0)
186  {
187  fout << lambdas[idx[i]] << " ";
188  }
189  fout << pow(10, flambdas[idx[i]] + DF) << "\n";
190  }
191  fout.close();
192 
193  if(sepWavelength == 1)
194  {
195  fname = ioutils::parentPath(filename) + "/wavelength.dat";
196 
197  fout.open(fname);
198  fout.precision(10);
199  for(int i=0;i<lambdas.size(); ++i)
200  {
201  fout << lambdas[idx[i]] << "\n";
202  }
203  fout.close();
204  }
205 
206 } //rewritePhoenixSpectrum
207 
208 ///Call rewritePhoenixSpectrum for all files in a directory.
209 /** \ingroup astropho_spectra
210  */
211 template<typename floatT>
212 void rewritePhoenixSpectrumBatch( const std::string & dir,
213  floatT lmin,
214  floatT lmax,
215  floatT DF = -8.0
216  )
217 {
218  std::vector<std::string> flist = ioutils::getFileNames(dir, "lte", "", ".7");
219 
220  int sepWavelength = 1;
221  for(int i=0; i< flist.size(); ++i)
222  {
223  rewritePhoenixSpectrum( flist[i], lmin, lmax, sepWavelength, DF);
224  if(i == 0) sepWavelength = -1;
225  }
226 }
227 
228 } //namespace astro
229 } //namespace mx
230 
231 #endif //phoenixSpectrum_hpp
232 
int readColumns(const std::string &fname, arrTs &... arrays)
Read in columns from a text file.
void rewritePhoenixSpectrum(const std::string &filename, floatT lmin, floatT lmax, int sepWavelength=0, floatT DF=-8.0)
Read in, crop, scale, and re-write a Phoenix spectrum data file.
std::vector< std::string > getFileNames(const std::string &directory, const std::string &prefix, const std::string &substr, const std::string &extension)
Get a list of file names from the specified directory, specifying a prefix, a substring to match,...
Definition: fileUtils.cpp:85
std::string parentPath(const std::string &fname)
Get the parent path from a filename.
Definition: fileUtils.cpp:77
std::vector< size_t > vectorSortOrder(std::vector< memberT > const &values)
Return the indices of the vector in sorted order, without altering the vector itself.
Definition: vectorUtils.hpp:92
The mxlib c++ namespace.
Definition: mxError.hpp:107
A spectrum from the Phoenix model, for use with ioutils::astro::astroSpectrum.
static constexpr realT fluxUnits
Convert from erg s-1 cm-2 A-1 to SI W m-3.
static int readSpectrum(std::vector< realT > &rawLambda, std::vector< realT > &rawSpectrum, const std::string &path, const paramsT &params)
static constexpr realT wavelengthUnits
Convert from A to SI m.
std::string paramsT
The parameter is a string name.