41 #define G_CUBE "ctbin::cube(int&)"
42 #define G_GET_PARAMETERS "ctbin::get_parameters()"
43 #define G_FILL_CUBE "ctbin::fill_cube(GCTAObservation*)"
44 #define G_SET_WEIGHTS "ctbin::set_weights(GCTAObservation*)"
204 this->GApplication::clear();
239 log_header1(TERSE, gammalib::number(
"Find unbinned observation",
243 std::vector<GCTAObservation*> obs_list(0);
244 double mean_ra = 0.0;
245 double mean_dec = 0.0;
250 obs_list.push_back(
obs);
253 const GCTAPointing& pnt =
obs->pointing();
256 mean_ra += pnt.dir().ra_deg();
257 mean_dec += pnt.dir().dec_deg();
260 std::string msg =
" Including unbinned "+
obs->instrument()+
262 log_string(NORMAL, msg);
267 int nobs = obs_list.size();
271 mean_ra /= double(nobs);
272 mean_dec /= double(nobs);
280 int ncubes = (
m_stack) ? 1 : nobs;
283 m_counts = std::vector<GSkyMap>(ncubes);
284 m_weights = std::vector<GSkyMap>(ncubes);
285 m_cubes = std::vector<GCTAEventCube>(ncubes);
297 use = (*this)[
"usepnt"].boolean() ?
"yes" :
"no";
304 log_header3(NORMAL,
"Summary");
305 log_value(NORMAL,
"Number of observations", nobs);
306 log_value(NORMAL,
"Mean pointing",
m_mean_pnt.print());
307 log_value(NORMAL,
"Use mean pointing", use);
310 log_header1(TERSE, gammalib::number(
"Bin observation", nobs));
313 #pragma omp parallel for
314 for (
int i = 0; i < nobs; ++i) {
317 GCTAObservation*
obs = obs_list[i];
323 #pragma omp critical(ctbin_run)
336 obs->dispose_events();
341 for (
int i = 0; i < nobs; ++i) {
344 GCTAObservation*
obs = obs_list[i];
347 GGti gti = obs->gti();
351 if (
m_gti.is_empty()) {
352 m_gti.reference(gti.reference());
371 for (
int iebin = 0; iebin <
m_ebounds.size(); ++iebin) {
372 double livetime_ebin = 0.0;
373 for (
int i = 0; i < obs_list.size(); ++i) {
374 std::vector<bool> usage =
377 livetime_ebin += obs_list[i]->livetime();
382 for (
int pixel = 0; pixel <
m_counts[0].npix(); ++pixel) {
399 for (
int i = 0; i < nobs; ++i) {
402 GCTAObservation*
obs = obs_list[i];
419 std::string inst = gammalib::tolower(obs->instrument());
420 std::string
id = gammalib::tolower(obs->id());
421 inst = gammalib::replace_segment(inst,
" ",
"_");
422 id = gammalib::replace_segment(
id,
" ",
"_");
423 std::string filename =
m_prefix + inst;
425 filename +=
"_" + id;
430 obs->eventfile(filename);
463 if (index < 0 || index >=
cubes()) {
464 throw GException::out_of_range(
G_CUBE,
"Cube index", index,
cubes());
483 log_header1(TERSE,
"Save counts cube");
490 if ((*
this)[
"outobs"].is_valid() &&
m_obs.size() > 0) {
493 GFilename outobs = (*this)[
"outobs"].filename();
496 GCTAObservation*
obs =
dynamic_cast<GCTAObservation*
>(
m_obs[0]);
502 log_value(NORMAL,
"Counts cube file", outobs.url());
505 obs->save(outobs, clobber());
521 for (
int i = 0; i <
m_obs.size(); ++i) {
524 GCTAObservation*
obs =
dynamic_cast<GCTAObservation*
>(
m_obs[i]);
530 std::string filename = obs->eventfile();
533 obs->save(filename, clobber());
543 if ((*
this)[
"outobs"].is_valid()) {
546 std::string outobs = (*this)[
"outobs"].filename();
570 log_header1(TERSE,
"Publish counts cube");
573 std::string user_name(name);
574 if (user_name.empty()) {
579 log_value(NORMAL,
"Counts cube name", user_name);
691 m_stack = (*this)[
"stack"].boolean();
692 m_prefix = (*this)[
"prefix"].string();
695 m_publish = (*this)[
"publish"].boolean();
696 m_chatter =
static_cast<GChatter
>((*this)[
"chatter"].integer());
700 (*this)[
"outobs"].query();
705 int nthreads = (*this)[
"nthreads"].integer();
707 omp_set_num_threads(nthreads);
736 m_dirs.resize(map.npix());
739 for (
int pixel = 0; pixel < map.npix(); ++pixel) {
740 m_dirs[pixel] = map.inx2dir(pixel);
760 std::string coordsys = (*this)[
"coordsys"].string();
761 std::string proj = (*this)[
"proj"].string();
769 if ((*
this)[
"usepnt"].
boolean()) {
773 if (gammalib::toupper(coordsys) ==
"GAL") {
787 const GCTAPointing& pnt = obs->pointing();
790 if (gammalib::toupper(coordsys) ==
"GAL") {
791 xref = pnt.dir().l_deg();
792 yref = pnt.dir().b_deg();
795 xref = pnt.dir().ra_deg();
796 yref = pnt.dir().dec_deg();
805 xref = (*this)[
"xref"].real();
806 yref = (*this)[
"yref"].real();
810 double binsz = (*this)[
"binsz"].real();
811 int nxpix = (*this)[
"nxpix"].integer();
812 int nypix = (*this)[
"nypix"].integer();
818 GSkyMap
cube = GSkyMap(proj, coordsys, xref, yref, -binsz, binsz,
819 nxpix, nypix, ebounds.size());
841 const GCTAEventList* events =
dynamic_cast<const GCTAEventList*
>
843 if (events == NULL) {
844 std::string msg =
"CTA Observation does not contain an event "
845 "list. An event list is needed to fill the "
851 const GCTARoi& roi = obs->roi();
854 if (!roi.is_valid()) {
855 std::string msg =
"No valid RoI found in input observation "
856 "\""+obs->name()+
"\". Run ctselect to specify "
857 "an RoI for this observation before running "
866 int num_outside_roi = 0;
867 int num_invalid_wcs = 0;
868 int num_outside_map = 0;
869 int num_outside_ebds = 0;
873 double pixel_x_max = counts.nx() - 0.5;
874 double pixel_y_max = counts.ny() - 0.5;
877 for (
int i = 0; i < events->size(); ++i) {
880 const GCTAEventAtom*
event = (*events)[i];
883 GCTAInstDir* inst = (GCTAInstDir*)&(event->dir());
884 GSkyDir dir = inst->dir();
887 if (roi.centre().dir().dist_deg(dir) > roi.radius()) {
895 pixel = counts.dir2pix(dir);
897 catch (std::exception &e) {
904 if (pixel.x() < -0.5 || pixel.x() > pixel_x_max ||
905 pixel.y() < -0.5 || pixel.y() > pixel_y_max) {
911 int iebin =
m_ebounds.index(event->energy());
916 if (iebin == -1 || !usage[iebin]) {
923 counts(pixel, iebin) += 1.0;
931 #pragma omp critical(ctbin_fill_cube)
934 log_value(NORMAL,
"Events in list", obs->events()->size());
935 log_value(NORMAL,
"Events in cube", num_in_map);
936 log_value(NORMAL,
"Events outside RoI", num_outside_roi);
937 log_value(NORMAL,
"Events with invalid WCS", num_invalid_wcs);
938 log_value(NORMAL,
"Events outside cube area", num_outside_map);
939 log_value(NORMAL,
"Events outside energy bins", num_outside_ebds);
962 const GCTARoi& roi = obs->roi();
965 if (!roi.is_valid()) {
966 std::string msg =
"No valid RoI found in input observation "
967 "\""+obs->name()+
"\". Run ctselect to specify "
968 "an RoI for this observation before running "
974 GSkyDir roi_centre = roi.centre().dir();
975 double roi_radius = roi.radius() * gammalib::deg2rad;
984 for (
int pixel = 0; pixel < weights.npix(); ++pixel) {
988 if (
m_dirs[pixel].dist(roi_centre) > roi_radius) {
993 if (roi_centre.dist(weights.inx2dir(pixel)) > roi_radius) {
999 for (
int iebin = 0; iebin <
m_ebounds.size(); ++iebin){
1002 if (!usage[iebin]) {
1007 weights(pixel, iebin) = 1.0;
1038 if (
m_obs.size() == 1) {
1041 GCTAObservation*
obs =
dynamic_cast<GCTAObservation*
>(
m_obs[0]);
1045 if (obs->eventtype() ==
"EventList") {
1079 GObservations container;
1082 GCTAObservation
obs;
1091 double number = 0.0;
1092 std::string instrument =
"";
1093 for (
int i = 0; i <
m_obs.size(); ++i) {
1094 GCTAObservation* cta =
dynamic_cast<GCTAObservation*
>(
m_obs[i]);
1095 if ((cta != NULL) && (cta->eventtype() ==
"EventList")) {
1096 ra += cta->pointing().dir().ra();
1097 dec += cta->pointing().dir().dec();
1099 if (instrument.empty()) {
1100 instrument = cta->instrument();
1108 if (instrument.empty()) {
1113 GCTAPointing pointing(dir);
1119 obs.instrument(instrument);
1120 obs.pointing(pointing);
1121 obs.ra_obj(dir.ra_deg());
1122 obs.dec_obj(dir.dec_deg());
1128 container.models(
m_obs.models());
1131 container.append(obs);
1134 for (
int i = 0; i <
m_obs.size(); ++i) {
1135 GCTAObservation* obs =
dynamic_cast<GCTAObservation*
>(
m_obs[i]);
1137 container.append(*
m_obs[i]);
1139 else if (obs->eventtype() !=
"EventList") {
1140 container.append(*
m_obs[i]);
void init_members(void)
Initialise class members.
void clear(void)
Clear event binning tool.
GEbounds m_ebounds
Energy boundaries.
virtual ~ctbin(void)
Destructor.
const GObservations & obs(void) const
Return observation container.
GCTAObservation * next_unbinned_observation(void)
Return next unbinned CTA observation.
std::vector< GSkyDir > m_dirs
Cached GSkyDir for all pixels.
void free_members(void)
Delete class members.
ctbin(void)
Void constructor.
bool m_stack
Output one stacked cube or multiple cubes.
void set_weights(const GCTAObservation *obs, GSkyMap &weights)
Set counts cube weights for a given observation.
std::vector< GCTAEventCube > m_cubes
Event cubes.
Base class for observation tools.
void copy_members(const ctbin &app)
Copy class members.
ctbin & operator=(const ctbin &app)
Assignment operator.
void free_members(void)
Delete class members.
void init_members(void)
Initialise class members.
GCTAObservation * first_unbinned_observation(void)
Return first unbinned CTA observation.
GSkyDir m_mean_pnt
Mean pointing.
const GCTAEventCube & cube(const int &index=0) const
Return event cube at index.
void save(void)
Save counts cube.
std::vector< GSkyMap > m_weights
List of event cube weights.
ctobservation & operator=(const ctobservation &app)
Assignment operator.
GGti m_gti
Stacked Good time intervals.
void init_sky_dir_cache(void)
Initialise sky direction cache for cube stack.
bool m_publish
Publish counts cube?
int cubes(void) const
Return number of event cubes.
void get_parameters(void)
Get application parameters.
void fill_cube(const GCTAObservation *obs, GSkyMap &counts)
Fill events into counts cube.
Event binning tool definition.
double m_ontime
Total ontime.
void publish(const std::string &name="")
Publish counts cube.
void obs_cube_stacked(void)
Create output observation container.
GObservations m_obs
Observation container.
std::vector< GSkyMap > m_counts
List of event cube counts.
void process(void)
Process the event binning tool.
double m_livetime
Total livetime.
GChatter m_chatter
Chattiness.
GSkyMap create_cube(const GCTAObservation *obs)
Create counts cube sky map for current observation.
std::string m_prefix
Prefix for multiple cubes.