Program Listing for File helper.cpp¶
↰ Return to documentation for file (src/helper.cpp)
#include "helper.h"
#include <vector>
#include <cmath>
#include <vector>
#include <iterator>
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <cstdlib>
#include <CCfits/FITS.h>
#include <CCfits/ExtHDU.h>
#include <map>
#include <curl/curl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string>
#define FMT_HEADER_ONLY
#include <fmt/format.h>
void vector_to_file(std::vector<double> const &vec, std::string const &filename) {
std::ofstream file(filename);
auto first = true;
for (float f : vec) {
if (!first) { file << ","; }
first = false;
file << f;
}
file << std::endl;
file.close();
}
std::array<double, 6> decompose_matrix(std::array<double, 6> mat) {
/*
* Matrix looks like:
* a b tx = m0 m1 m2
* d e ty m3 m4 m5
*/
double a = mat[0];
double b = mat[1];
double d = mat[3];
double e = mat[4];
double tx = mat[2];
double ty = mat[5];
double sx = sqrt(a * a + d * d);
double sy = sqrt(b * b + e * e);
double phi = atan2(d, a);
if (phi < 0.1)
phi += 2. * M_PI;
double shear = atan2(-b, e) - phi;
if (shear < -6.1)
shear += 2. * M_PI;
std::array<double, 6> result = {sx, sy, shear, phi, tx, ty};
// return <sx, sy, shear, rot, tx ,ty>
return result;
}
std::array<double, 6> compose_matrix(std::vector<double> parameters) {
double sx = parameters[0];
double sy = parameters[1];
double shear = parameters[2];
double rot = parameters[3];
std::array<double, 6> m = {
sx * cos(rot),
-sy * sin(rot + shear),
parameters[4],
sx * sin(rot),
sy * cos(rot + shear),
parameters[5],
};
return m;
}
std::vector<std::size_t> compute_sort_order(const std::vector<double> &v) {
std::vector<std::size_t> indices(v.size());
std::iota(indices.begin(), indices.end(), 0u);
std::sort(indices.begin(), indices.end(), [&](int lhs, int rhs) {
return v[lhs] < v[rhs];
});
std::vector<std::size_t> res(v.size());
for (std::size_t i = 0; i != indices.size(); ++i) {
res[indices[i]] = i;
}
return res;
}
double wrap_rads(double r) {
while (r > M_PI) {
r -= 2 * M_PI;
}
while (r <= -M_PI) {
r += 2 * M_PI;
}
return r;
}
double interpolate(const std::map<double, double> &data,
double x) {
typedef std::map<double, double>::const_iterator i_t;
i_t i = data.upper_bound(x);
if (i == data.end()) {
return (--i)->second;
}
if (i == data.begin()) {
return i->second;
}
i_t l = i;
--l;
const double delta = (x - l->first) / (i->first - l->first);
return delta * i->second + (1 - delta) * l->second;
}
herr_t file_info(hid_t loc_id, const char *name, const H5L_info_t *linfo, void *opdata) {
auto group_names = reinterpret_cast< std::vector<std::string> * >(opdata);
group_names->push_back(name);
return 0;
}
size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream) {
size_t written = fwrite(ptr, size, nmemb, stream);
return written;
}
int download_phoenix(int t_eff, double log_g, double z, double alpha, const std::string path) {
// check for valid inputs:
std::cout << "Trying to download PHOENIX Spectrum with: T_eff=" << t_eff << " log_g=" << log_g << " z=" << z
<< " Alpha=" << alpha << std::endl;
std::vector<int> valid_T;
std::vector<double> valid_g, valid_z, valid_a;
for (int i = 2300; i < 7000; i += 100) { valid_T.push_back(i); }
for (int i = 7000; i < 12200; i += 200) { valid_T.push_back(i); }
for (int i = 0; i < 12; ++i) { valid_g.push_back(i * 0.5); }
for (int i = -4; i < -2; ++i) { valid_z.push_back(i); }
for (int i = -4; i < 3; ++i) { valid_z.push_back(i * 0.5); }
for (int i = -1; i < 7; ++i) { valid_a.push_back(i * 0.5); }
bool found = (std::find(valid_T.begin(), valid_T.end(), t_eff) != valid_T.end());
if (!found) {
std::cout << "Invalid Effective temperature value for Phoenix spectra." << std::endl;
return true;
}
found = (std::find(valid_g.begin(), valid_g.end(), log_g) != valid_g.end());
if (!found) {
std::cout << "Invalid log_g value for Phoenix spectra." << std::endl;
return true;
}
found = (std::find(valid_z.begin(), valid_z.end(), z) != valid_z.end());
if (!found) {
std::cout << "Invalid z value for Phoenix spectra." << std::endl;
return true;
}
found = (std::find(valid_a.begin(), valid_a.end(), alpha) != valid_a.end());
if (!found) {
std::cout << "Invalid alpha value for Phoenix spectra." << std::endl;
return true;
}
std::string baseurl = "ftp://phoenix.astro.physik.uni-goettingen.de/HiResFITS/PHOENIX-ACES-AGSS-COND-2011/";
std::string subgrid = "Z";
(z > 0) ? subgrid += fmt::format("{:+2.1f}", z) : subgrid += fmt::format("{:-2.1f}", z);
(fabs(alpha) < 1E-10) ? subgrid += "" : subgrid += ".Alpha=";
(fabs(alpha) < 1E-10) ? subgrid += "" : subgrid += fmt::format("{:+2.2f}", alpha);
std::string url =
baseurl + subgrid + "/lte" + fmt::format("{:05}", t_eff) + "-" + fmt::format("{:2.2f}", log_g);
(z > 0) ? url += fmt::format("{:+2.1f}", z) : url += fmt::format("{:-2.1f}", z);
(fabs(alpha) < 1E-10) ? url += "" : url += ".Alpha=";
(fabs(alpha) < 1E-10) ? url += "" : url += fmt::format("{:+2.2f}", alpha);
url += ".PHOENIX-ACES-AGSS-COND-2011-HiRes.fits";
std::cout << "Downloading spectra from: " << url
<< std::endl; //cover z = 0 case also see if adding x.0 and + | - is doable
CURL *curl;
FILE *fp;
CURLcode res;
res = CURLE_OK;
remove(path.c_str());
curl = curl_easy_init();
if (curl) {
fp = fopen(path.c_str(), "wb");
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
res = curl_easy_perform(curl);
/* always cleanup */
curl_easy_cleanup(curl);
fclose(fp);
}
return res;
}
int download_wave_grid(std::string path) {
std::string url = "ftp://phoenix.astro.physik.uni-goettingen.de/HiResFITS//WAVE_PHOENIX-ACES-AGSS-COND-2011.fits";
CURL *curl;
FILE *fp;
CURLcode res;
res = CURLE_OK;
curl = curl_easy_init();
if (curl) {
fp = fopen(path.c_str(), "wb");
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
res = curl_easy_perform(curl);
/* always cleanup */
curl_easy_cleanup(curl);
fclose(fp);
}
return res;
}
bool check_for_file(const std::string &path) {
if (FILE *file = fopen(path.c_str(), "r")) {
fclose(file);
return true;
} else {
return false;
}
}
template<typename Out>
void split(const std::string &s, char delim, Out result) {
std::stringstream ss;
ss.str(s);
std::string item;
while (std::getline(ss, item, delim)) {
*(result++) = item;
}
}
std::vector<std::string> split_to_vector(const std::string &s, char delim) {
std::vector<std::string> elems;
split(s, delim, std::back_inserter(elems));
return elems;
}