-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLocalModel.cpp
More file actions
141 lines (103 loc) · 4.07 KB
/
LocalModel.cpp
File metadata and controls
141 lines (103 loc) · 4.07 KB
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
/*
This file is part of the RELXILL model code.
RELXILL is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
any later version.
RELXILL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
For a copy of the GNU General Public License see
<http://www.gnu.org/licenses/>.
Copyright 2022 Thomas Dauser, Remeis Observatory & ECAP
*/
#include "LocalModel.h"
#include "XspecSpectrum.h"
#include <stdexcept>
#include <iostream>
/*
* @brief calculate line model
*/
void LocalModel::line_model(const XspecSpectrum &spectrum) {
relParam *rel_param = LocalModel::get_rel_params();
// relline_base calculates the line for 1keV -> shift the energy grid accordingly
spectrum.shift_energy_grid_1keV(rel_param->lineE);
int status = EXIT_SUCCESS;
relline_base(spectrum.energy, spectrum.flux, spectrum.num_flux_bins(), rel_param, &status);
if (status != EXIT_SUCCESS) {
throw std::exception();
}
delete rel_param;
}
/*
* @brief calculate relxill model
*/
void LocalModel::relxill_model(const XspecSpectrum &spectrum) {
int status = EXIT_SUCCESS;
if (m_model_params.irradiation() == T_Irrad::Const){
relParam *rel_param = LocalModel::get_rel_params();
xillParam *xill_param = LocalModel::get_xill_params();
relxill_bb_kernel(spectrum.energy, spectrum.flux, spectrum.num_flux_bins(), xill_param, rel_param, &status);
delete rel_param;
delete xill_param;
} else {
relxill_kernel(spectrum, m_model_params, &status);
}
if (status != EXIT_SUCCESS) {
throw std::exception();
}
}
/**
* @brief calculate convolution of a given spectrum
* @description note the model is only defined in the 0.01-1000 keV energy range and will
* return 0 outside this range (see function relconv_kernel for more details)
*/
void LocalModel::conv_model(const XspecSpectrum &spectrum) {
if (calcSum(spectrum.flux, spectrum.num_flux_bins()) <= 0.0) {
throw ModelEvalFailed("input flux for convolution model needs to be >0");
}
relParam *rel_param = LocalModel::get_rel_params();
int status = EXIT_SUCCESS;
relconv_kernel(spectrum.energy, spectrum.flux, spectrum.num_flux_bins(), rel_param, &status);
if (status != EXIT_SUCCESS) {
throw ModelEvalFailed("executing convolution failed");
}
delete rel_param;
}
/**
* @brief calculate xillver model
*/
void LocalModel::xillver_model(const XspecSpectrum &spectrum) {
xillParam *xill_param = LocalModel::get_xill_params();
int status = EXIT_SUCCESS;
xillver_base(spectrum.energy, spectrum.num_flux_bins(), spectrum.flux, xill_param, &status);
if (status != EXIT_SUCCESS) {
throw std::exception();
}
delete xill_param;
}
/**
* Wrapper function, which can be called from any C-type local model function as
* required by Xspec
* @param model_name: unique name of the model
* @param parameter_values: input parameter_values array (size can be determined from the model definition for the model_name)
* @param xspec_energy[num_flux_bins]: input energy grid
* @param xspec_flux[num_flux_bins]: - flux array (already allocated), used to return the calculated values
* - for convolution models this is also the input flux
* @param num_flux_bins
*/
void xspec_C_wrapper_eval_model(ModelName model_name,
const double *parameter_values,
double *xspec_flux,
int num_flux_bins,
const double *xspec_energy) {
try {
LocalModel local_model{parameter_values, model_name};
XspecSpectrum spectrum{xspec_energy, xspec_flux, static_cast<size_t>(num_flux_bins)};
local_model.eval_model(spectrum);
} catch (ModelNotFound &e) {
std::cout << e.what();
}
// TODO: what should we do if the evaluation fails? return zeros?
}