41#define G_GET_PARAMETERS "ctmodel::get_parameters()"
42#define G_GET_OBS "ctmodel::get_obs()"
43#define G_FILL_CUBE "ctmodel::fill_cube(GCTAObservation*)"
195 this->GApplication::clear();
236 log_header1(TERSE,
"Generate model cube");
244 #pragma omp for schedule(static,1)
245 for (
int i = 0; i <
m_obs.size(); ++i) {
248 GCTAObservation*
obs =
dynamic_cast<GCTAObservation*
>(
m_obs[i]);
253 std::string msg =
" Skipping "+
m_obs[i]->instrument()+
255 log_string(NORMAL, msg);
266 else if (
obs->eventtype() ==
"CountsCube") {
268 std::string msg =
" Skipping binned "+
m_obs[i]->instrument()+
270 log_string(NORMAL, msg);
279 if (
obs->eventfile().length() > 0 &&
obs->eventfile().exists()) {
280 obs->dispose_events();
289 log_header1(NORMAL,
"Model cube");
290 log_string(NORMAL,
m_cube.print());
314 log_header1(TERSE,
"Save model cube");
317 if ((*
this)[
"outcube"].is_valid() &&
m_cube.size() > 0) {
320 m_outcube = (*this)[
"outcube"].filename();
327 for (
int i = 0; i < fits.size(); ++i) {
328 fits[i]->card(
"RA_PNT",
m_ra_pnt,
"[deg] Pointing Right Ascension");
329 fits[i]->card(
"DEC_PNT",
m_dec_pnt,
"[deg] Pointing Declination");
341 fname.append(
" (cube is empty, no file created)");
343 log_value(NORMAL,
"Model cube file", fname);
358 log_header1(TERSE,
"Publish model cube");
361 std::string user_name(name);
362 if (user_name.empty()) {
367 log_value(NORMAL,
"Model cube name", user_name);
370 m_cube.counts().publish(user_name);
390 for (
int i = 0; i <
m_cube.size(); ++i) {
493 if (
m_obs.size() == 0) {
510 GCTAObservation*
obs =
dynamic_cast<GCTAObservation*
>(
m_obs[0]);
516 if (
obs->eventtype() ==
"CountsCube") {
519 GCTAEventCube* evtcube =
dynamic_cast<GCTAEventCube*
>
520 (
const_cast<GEvents*
>(
obs->events()));
536 if (
m_obs.models().size() == 0) {
539 std::string inmodel = (*this)[
"inmodel"].filename();
542 m_obs.models(inmodel);
556 if ((*
this)[
"incube"].is_valid()) {
559 std::string incube = (*this)[
"incube"].filename();
565 for (
int i = 0; i <
m_cube.size(); ++i) {
582 m_publish = (*this)[
"publish"].boolean();
583 m_chatter =
static_cast<GChatter
>((*this)[
"chatter"].integer());
587 (*this)[
"outcube"].query();
611 int nthreads = (*this)[
"nthreads"].integer();
613 omp_set_num_threads(nthreads);
652 if ((*
this)[
"inobs"].is_undefined()) {
656 if ((*
this)[
"expcube"].is_valid() &&
657 (*
this)[
"psfcube"].is_valid() &&
658 (*
this)[
"bkgcube"].is_valid()) {
662 bool query_edisp = (*this)[
"edisp"].boolean();
663 GFilename expcube = (*this)[
"expcube"].filename();
664 GFilename psfcube = (*this)[
"psfcube"].filename();
665 if (query_edisp && (*
this)[
"edispcube"].is_valid()) {
666 edispcube = (*this)[
"edispcube"].filename();
668 GFilename bkgcube = (*this)[
"bkgcube"].filename();
671 GCTACubeExposure exposure(expcube);
672 GCTACubePsf psf(psfcube);
673 GCTACubeBackground background(bkgcube);
679 GSkyMap map(
"CAR",
"GAL",0.0,0.0,1.0,1.0,1,1,ebounds.size());
682 GCTAEventCube
cube(map, ebounds, exposure.gti());
689 cta.instrument((*
this)[
"instrument"].
string());
696 if ((*
this)[
"edispcube"].is_valid()) {
699 GCTACubeEdisp edisp(edispcube);
702 cta.response(exposure, psf, edisp, background);
708 std::string msg =
"Energy dispersion requested but no "
709 "energy dispersion cube was specified.";
710 throw GException::invalid_value(
G_GET_OBS, msg);
717 cta.response(exposure, psf, background);
751 std::string filename = (*this)[
"inobs"].filename();
755 if (GFilename(filename).is_fits()) {
778 m_obs.load(filename);
813 int nebins =
m_cube.ebins();
822 for (
int i = 0; i < npix; ++i) {
825 GCTAEventBin* bin =
m_cube[i];
828 m_dir.push_back(bin->dir());
834 for (
int iebin = 0, ibin = 0; iebin < nebins; ++iebin, ibin += npix) {
837 GCTAEventBin* bin =
m_cube[ibin];
868 int nebins =
m_cube.ebins();
872 const GCTAPointing& pnt =
obs->pointing();
879 const GGti& gti =
obs->events()->gti();
880 const GEbounds& obs_ebounds =
obs->ebounds();
883 const GEbounds& cube_ebounds =
m_cube.ebounds();
892 if (
obs->eventtype() ==
"EventList") {
898 int num_outside_ebds = 0;
899 int num_outside_roi = 0;
905 double* pixels =
const_cast<double*
>(
m_cube.counts().pixels());
912 bin.ontime(
obs->ontime());
916 bool obs_is_cube = (
obs->eventtype() ==
"CountsCube");
919 for (
int i = 0; i < npix; ++i) {
923 if (roi.is_valid() && !roi.contains(
m_dir[i])) {
924 num_outside_roi += nebins;
930 GCTAInstDir dir = pnt.instdir(
m_dir[i].dir());
938 for (
int iebin = 0, ibin = i; iebin < nebins; ++iebin, ibin += npix) {
956 bin.weight(
m_cube[ibin]->weight());
960 double model =
models.eval(bin, *
obs) * bin.size();
966 #pragma omp critical(ctmodel_fill_cube)
967 pixels[ibin] += model;
977 #pragma omp critical(ctmodel_fill_cube)
987 #pragma omp critical(ctmodel_fill_cube)
990 log_value(NORMAL,
"Model events in cube", sum);
991 log_value(NORMAL,
"Bins outside energy range", num_outside_ebds);
992 log_value(NORMAL,
"Bins outside RoI", num_outside_roi);
997 log_header2(EXPLICIT,
"Model cube");
1020 GModels excluded_models;
1026 if (!roi.is_valid()) {
1027 return excluded_models;
1034 GSkyRegionCircle obsreg(roi.centre().dir(), roi.radius()+0.5);
1037 for (
int i = 0; i < all_models.size(); ++i) {
1040 GModelSky* model =
dynamic_cast<GModelSky*
>(all_models[i]);
1043 if (model == NULL) {
1049 if (!(model->spatial()->code() == GMODEL_SPATIAL_DIFFUSE) &&
1050 (!model->spatial()->region()->overlaps(obsreg))) {
1053 excluded_models.append(*model);
1056 all_models.remove(i);
1065 return excluded_models;
Model cube generation tool.
double m_dec_pnt
Declination Ascension of pointing.
GFilename m_outcube
Output model cube.
const GCTAEventCube & cube(void) const
Return model cube.
void get_parameters(void)
Get application parameters.
void process(void)
Generate the model map(s)
void save(void)
Save model cube.
GModels trim_models(GModels &all_models, const GCTARoi &roi)
Find the models falling inside a defined region of interest.
std::vector< GEnergy > m_energy
Cube energies.
std::vector< GEnergy > m_ewidth
Cube energy widths.
void init_members(void)
Initialise class members.
void copy_members(const ctmodel &app)
Copy class members.
ctmodel & operator=(const ctmodel &app)
Assignment operator.
void extract_cube_properties(void)
Extract cube properties in data members.
void publish(const std::string &name="")
Publish model cube.
GChatter m_chatter
Chattiness.
bool m_has_cube
Signal if cube exists.
void free_members(void)
Delete class members.
void clear(void)
Clear ctmodel tool.
ctmodel(void)
Void constructor.
bool m_append_cube
Signal to append cube.
GCTAEventCube m_cube
Model cube.
void get_obs(void)
Get observation container.
std::vector< GCTAInstDir > m_dir
Cube directions.
void fill_cube(const GCTAObservation *obs, GModels &models)
Fill models into model cube.
virtual ~ctmodel(void)
Destructor.
std::vector< double > m_solidangle
Cube solid angles.
bool m_apply_edisp
Apply energy dispersion?
double m_ra_pnt
Right Ascension of pointing.
GGti m_gti
Model cube GTIs.
bool m_publish
Publish model cube?
void models(const GModels &models)
Set models.
bool m_binned
Signal binned mode.
Base class for observation tools.
void free_members(void)
Delete class members.
ctobservation & operator=(const ctobservation &app)
Assignment operator.
GObservations m_obs
Observation container.
const GObservations & obs(void) const
Return observation container.
void set_obs_bounds()
Set observation boundaries for CTA observations.
void init_members(void)
Initialise class members.
const GEnergy g_energy_margin(1.0e-12, "TeV")
Model cube generation tool definition.