Commit c4c3ef0d03affb1b7a42d608b0eee0b1efe3f499

Authored by Jürgen Knödlseder
1 parent 8dab5cb9

Complete ctexpcube tools and add unit test.

The ctexpcube tool is now functional, a unit test has been added.
pyext/ctexpcube.i 0 → 100644
  1 +/***************************************************************************
  2 + * ctexpcube - CTA exposure cube tool *
  3 + * ----------------------------------------------------------------------- *
  4 + * copyright (C) 2014 by Juergen Knoedlseder *
  5 + * ----------------------------------------------------------------------- *
  6 + * *
  7 + * This program is free software: you can redistribute it and/or modify *
  8 + * it under the terms of the GNU General Public License as published by *
  9 + * the Free Software Foundation, either version 3 of the License, or *
  10 + * (at your option) any later version. *
  11 + * *
  12 + * This program is distributed in the hope that it will be useful, *
  13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  15 + * GNU General Public License for more details. *
  16 + * *
  17 + * You should have received a copy of the GNU General Public License *
  18 + * along with this program. If not, see <http://www.gnu.org/licenses/>. *
  19 + * *
  20 + ***************************************************************************/
  21 +/**
  22 + * @file ctexpcube.i
  23 + * @brief CTA exposure cube tool definition
  24 + * @author Juergen Knoedlseder
  25 + */
  26 +%{
  27 +/* Put headers and other declarations here that are needed for compilation */
  28 +#include "ctexpcube.hpp"
  29 +#include "GTools.hpp"
  30 +%}
  31 +
  32 +
  33 +/***********************************************************************//**
  34 + * @class ctexpcube
  35 + *
  36 + * @brief CTA exposure cube tool
  37 + ***************************************************************************/
  38 +class ctexpcube : public GApplication {
  39 +
  40 +public:
  41 + // Constructors and destructors
  42 + ctexpcube(void);
  43 + explicit ctexpcube(GObservations obs);
  44 + ctexpcube(int argc, char *argv[]);
  45 + ctexpcube(const ctexpcube& app);
  46 + virtual ~ctexpcube(void);
  47 +
  48 + // Operators
  49 + ctexpcube& operator=(const ctexpcube& app);
  50 +
  51 + // Methods
  52 + void clear(void);
  53 + void execute(void);
  54 + void run(void);
  55 + void save(void);
  56 + GObservations& obs(void);
  57 + void get_parameters(void);
  58 + void get_obs(void);
  59 + void set_response(void);
  60 + void get_ebounds(void);
  61 + void set_from_cntmap(const std::string& filename);
  62 +};
  63 +
  64 +
  65 +/***********************************************************************//**
  66 + * @brief CTA exposure map tool Python extension
  67 + ***************************************************************************/
  68 +%extend ctexpcube {
  69 + ctexpcube copy() {
  70 + return (*self);
  71 + }
  72 +}
... ...
pyext/ctools/ctools.i
1 1 /***************************************************************************
2 2 * ctools - SWIG file *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2010-2013 by Juergen Knoedlseder *
  4 + * copyright (C) 2010-2014 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -51,3 +51,4 @@
51 51 %include "ctmodel.i"
52 52 %include "ctselect.i"
53 53 %include "ctskymap.i"
  54 +%include "ctexpcube.i"
... ...
src/ctexpcube/ctexpcube
No preview for this file type
src/ctexpcube/ctexpcube.cpp
... ... @@ -31,13 +31,12 @@
31 31 #include <cstdio>
32 32 #include "ctexpcube.hpp"
33 33 #include "GTools.hpp"
  34 +#include "GWcs.hpp"
34 35  
35 36 /* __ Method name definitions ____________________________________________ */
36 37 #define G_GET_EBOUNDS "ctexpcube::get_ebounds()"
37   -
38   -
39   -#define G_SETUP_OBS "ctexpcube::setup_obs()"
40   -#define G_MODEL_MAP "ctexpcube::model_map(GCTAObservation*)"
  38 +#define G_GET_PARAMETERS "ctexpcube::get_parameters()"
  39 +#define G_SET_FROM_CNTMAP "ctexpcube::set_from_cntmap(std::string&)"
41 40  
42 41 /* __ Debug definitions __________________________________________________ */
43 42  
... ... @@ -276,37 +275,8 @@ void ctexpcube::run(void)
276 275 log.header1("Generate exposure cube");
277 276 }
278 277  
279   - // Initialise observation counter
280   - int n_observations = 0;
281   -
282   - // Loop over all observations in the container
283   - for (int i = 0; i < m_obs.size(); ++i) {
284   -
285   - // Get CTA observation
286   - GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[i]);
287   -
288   - // Continue only if observation is a CTA observation
289   - if (obs != NULL) {
290   -
291   - // Write header for observation
292   - if (logTerse()) {
293   - if (obs->name().length() > 1) {
294   - log.header3("Observation "+obs->name());
295   - }
296   - else {
297   - log.header3("Observation");
298   - }
299   - }
300   -
301   - // Increment number of observations
302   - n_observations++;
303   -
304   - // Generate exposure cube
305   - //model_map(obs, m_obs.models());
306   -
307   - } // endif: CTA observation found
308   -
309   - } // endfor: looped over observations
  278 + // Fill exposure
  279 + m_expcube.fill(m_obs);
310 280  
311 281 // Restore energy dispersion flag for all CTA observations
312 282 for (int i = 0; i < m_obs.size(); ++i) {
... ... @@ -349,24 +319,27 @@ void ctexpcube::save(void)
349 319 *
350 320 * Get all task parameters from parameter file or (if required) by querying
351 321 * the user. The parameters are read in the correct order.
  322 + *
  323 + * @todo Setup exposure cube from counts map
352 324 ***************************************************************************/
353 325 void ctexpcube::get_parameters(void)
354 326 {
355 327 // If we do not have any observations in the container then get an
356 328 // input file name or observation descriptor file
357 329 if (m_obs.size() == 0) {
358   - m_infile = (*this)["infile"].filename();
  330 + get_obs();
359 331 }
360 332  
361   - // Read response parameters
362   - m_caldb = (*this)["caldb"].string();
363   - m_irf = (*this)["irf"].string();
  333 + // Make sure that response is set
  334 + set_response();
  335 +
  336 + // Read energy dispersion flag
364 337 m_apply_edisp = (*this)["edisp"].boolean();
365 338  
366 339 // If no counts map is specified then setup the exposure cube from
367 340 // the user parameters
368   - m_cntmap = (*this)["cntmap"].filename();
369   - if ((m_cntmap == "NONE") || (gammalib::strip_whitespace(m_cntmap) == "")) {
  341 + std::string cntmap = (*this)["cntmap"].filename();
  342 + if ((cntmap == "NONE") || (gammalib::strip_whitespace(cntmap) == "")) {
370 343  
371 344 // Get user parameters for counts map definition
372 345 std::string wcs = (*this)["proj"].string();
... ... @@ -388,6 +361,10 @@ void ctexpcube::get_parameters(void)
388 361  
389 362 // ... otherwise setup the exposure cube from the counts map
390 363 else {
  364 +
  365 + // Set exposure cube from counts map
  366 + set_from_cntmap(cntmap);
  367 +
391 368 }
392 369  
393 370 // Read output filename (if needed)
... ... @@ -401,8 +378,98 @@ void ctexpcube::get_parameters(void)
401 378  
402 379  
403 380 /***********************************************************************//**
  381 + * @brief Get observation definition
  382 + *
  383 + * Get observation definition from the user parameters.
  384 + ***************************************************************************/
  385 +void ctexpcube::get_obs(void)
  386 +{
  387 + // Get input filename
  388 + std::string filename = (*this)["infile"].filename();
  389 +
  390 + // Try first to open as FITS file
  391 + try {
  392 +
  393 + // Allocate CTA observation
  394 + GCTAObservation obs;
  395 +
  396 + // Load input file in CTA observation
  397 + obs.load(filename);
  398 +
  399 + // Append CTA observation to container
  400 + m_obs.append(obs);
  401 +
  402 +
  403 + }
  404 +
  405 + // ... otherwise try to open as XML file
  406 + catch (GException::fits_open_error &e) {
  407 +
  408 + // Load observations from XML file
  409 + m_obs.load(filename);
  410 +
  411 + }
  412 +
  413 + // Return
  414 + return;
  415 +}
  416 +
  417 +
  418 +/***********************************************************************//**
  419 + * @brief Set observation response
  420 + *
  421 + * Set response for all observations that so have no response.
  422 + ***************************************************************************/
  423 +void ctexpcube::set_response(void)
  424 +{
  425 + // Loop over all observations
  426 + for (int i = 0; i < m_obs.size(); ++i) {
  427 +
  428 + // Is this observation a CTA observation?
  429 + GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[i]);
  430 +
  431 + // Yes ...
  432 + if (obs != NULL) {
  433 +
  434 + // Set response if it isn't set already
  435 + if (obs->response().aeff() == NULL) {
  436 +
  437 + // Load response information
  438 + std::string database = (*this)["caldb"].string();
  439 + std::string irf = (*this)["irf"].string();
  440 +
  441 + // Set calibration database. If specified parameter is a
  442 + // directory then use this as the pathname to the calibration
  443 + // database. Otherwise interpret this as the instrument name,
  444 + // the mission being "cta"
  445 + GCaldb caldb;
  446 + if (gammalib::dir_exists(database)) {
  447 + caldb.rootdir(database);
  448 + }
  449 + else {
  450 + caldb.open("cta", database);
  451 + }
  452 +
  453 + // Set reponse
  454 + obs->response(irf, caldb);
  455 +
  456 + } // endif: observation already has a response
  457 +
  458 + } // endif: observation was a CTA observation
  459 +
  460 + } // endfor: looped over all observations
  461 +
  462 + // Return
  463 + return;
  464 +}
  465 +
  466 +
  467 +/***********************************************************************//**
404 468 * @brief Get energy boundaries from parameters
405 469 *
  470 + * @exception GException::invalid_value
  471 + * Invalid extension name encountered.
  472 + *
406 473 * Get the energy boundaries from the user parameters.
407 474 ***************************************************************************/
408 475 void ctexpcube::get_ebounds(void)
... ... @@ -467,6 +534,74 @@ void ctexpcube::get_ebounds(void)
467 534 }
468 535  
469 536  
  537 +/***********************************************************************//**
  538 + * @brief Set exposure cube definition from counts map
  539 + *
  540 + * @exception GException::invalid_value
  541 + * Invalid counts map projection or invalid events encountered.
  542 + *
  543 + * Set exposure cube definition from counts map.
  544 + ***************************************************************************/
  545 +void ctexpcube::set_from_cntmap(const std::string& filename)
  546 +{
  547 + // Allocate CTA observation
  548 + GCTAObservation obs;
  549 +
  550 + // Load counts map in CTA observation
  551 + obs.load(filename);
  552 +
  553 + // Set exposure cube from counts map
  554 + const GCTAEventCube* cube = dynamic_cast<const GCTAEventCube*>(obs.events());
  555 +
  556 + // Continue only if cube is valid
  557 + if (cube != NULL) {
  558 +
  559 + // Get sky map projection
  560 + const GWcs* wcs = dynamic_cast<const GWcs*>(cube->map().projection());
  561 +
  562 + // Continue only if projection is valid
  563 + if (wcs != NULL) {
  564 +
  565 + // Get user parameters for counts map definition
  566 + std::string proj = wcs->code();
  567 + std::string coordsys = wcs->coordsys();
  568 + double xref = wcs->crval(0);
  569 + double yref = wcs->crval(1);
  570 + double dx = wcs->cdelt(0);
  571 + double dy = wcs->cdelt(1);
  572 + int nx = cube->map().nx();
  573 + int ny = cube->map().ny();
  574 +
  575 + // Get energy definition
  576 + m_ebounds = cube->ebounds();
  577 +
  578 + // Define exposure cube
  579 + m_expcube = GCTAExposure(proj, coordsys, xref, yref,
  580 + dx, dy, nx, ny,
  581 + m_ebounds);
  582 +
  583 + } // endif: WCS projection was valid
  584 +
  585 + // ... projection is not of WCS type
  586 + else {
  587 + std::string msg = "Counts map project is not of WCS type.";
  588 + throw GException::invalid_value(G_SET_FROM_CNTMAP, msg);
  589 + }
  590 +
  591 + } // endif: observation contained an events cube
  592 +
  593 + // ... there is not events cube
  594 + else {
  595 + std::string msg = "No events cube found in file \""
  596 + ""+filename+"\".";
  597 + throw GException::invalid_value(G_SET_FROM_CNTMAP, msg);
  598 + }
  599 +
  600 + // Return
  601 + return;
  602 +}
  603 +
  604 +
470 605 /*==========================================================================
471 606 = =
472 607 = Private methods =
... ... @@ -479,10 +614,7 @@ void ctexpcube::get_ebounds(void)
479 614 void ctexpcube::init_members(void)
480 615 {
481 616 // Initialise members
482   - m_infile.clear();
483 617 m_outfile.clear();
484   - m_caldb.clear();
485   - m_irf.clear();
486 618 m_apply_edisp = false;
487 619  
488 620 // Initialise protected members
... ... @@ -507,10 +639,7 @@ void ctexpcube::init_members(void)
507 639 void ctexpcube::copy_members(const ctexpcube& app)
508 640 {
509 641 // Copy attributes
510   - m_infile = app.m_infile;
511 642 m_outfile = app.m_outfile;
512   - m_caldb = app.m_caldb;
513   - m_irf = app.m_irf;
514 643 m_apply_edisp = app.m_apply_edisp;
515 644  
516 645 // Copy protected members
... ...
src/ctexpcube/ctexpcube.hpp
... ... @@ -61,7 +61,10 @@ public:
61 61 void save(void);
62 62 GObservations& obs(void) { return m_obs; }
63 63 void get_parameters(void);
  64 + void get_obs(void);
  65 + void set_response(void);
64 66 void get_ebounds(void);
  67 + void set_from_cntmap(const std::string& filename);
65 68  
66 69 protected:
67 70 // Protected methods
... ... @@ -70,11 +73,7 @@ protected:
70 73 void free_members(void);
71 74  
72 75 // User parameters
73   - std::string m_infile; //!< Input counts map or XML file
74   - std::string m_cntmap; //!< Counts map for exposure cube definition
75 76 std::string m_outfile; //!< Output exposure cube file
76   - std::string m_caldb; //!< Calibration database
77   - std::string m_irf; //!< Instrument response functions
78 77 bool m_apply_edisp; //!< Apply energy dispersion?
79 78  
80 79 // Protected members
... ...
src/ctexpcube/ctexpcube.par
... ... @@ -17,7 +17,7 @@
17 17 #
18 18 # General parameters
19 19 #===================
20   -infile, f, a, "NONE",,, "Input event list, counts map or observation definition file"
  20 +infile, f, a, "NONE",,, "Observation definition file"
21 21 cntmap, f, a, "NONE",,, "Counts map for exposure cube definition"
22 22 outfile, f, a, "expcube.fits",,, "Output exposure cube file"
23 23 caldb, s, a, "dummy",,, "Calibration database"
... ...
test/test_ctools.sh
... ... @@ -2,7 +2,7 @@
2 2 # ==========================================================================
3 3 # This script tests all ctools
4 4 #
5   -# Copyright (C) 2011-2012 Juergen Knoedlseder
  5 +# Copyright (C) 2011-2014 Juergen Knoedlseder
6 6 #
7 7 # This program is free software: you can redistribute it and/or modify
8 8 # it under the terms of the GNU General Public License as published by
... ... @@ -40,6 +40,7 @@ ctmodel=../src/ctmodel/ctmodel
40 40 ctobssim=../src/ctobssim/ctobssim
41 41 ctselect=../src/ctselect/ctselect
42 42 ctskymap=../src/ctskymap/ctskymap
  43 +ctexpcube=../src/ctexpcube/ctexpcube
43 44  
44 45  
45 46 #
... ... @@ -340,4 +341,49 @@ else
340 341 exit 1
341 342 fi
342 343 $ECHO " ok"
343   -#sleep 100
  344 +
  345 +
  346 +#
  347 +# Test ctexpcube
  348 +# ==============
  349 +$ECHO -n "Test ctexpcube: "
  350 +#
  351 +# Run 1
  352 +$ctexpcube infile="data/crab_events.fits" \
  353 + cntmap="NONE" \
  354 + outfile="expcube1.fits" \
  355 + caldb="irf" \
  356 + irf="cta_dummy_irf" \
  357 + emin=0.1 \
  358 + emax=100.0 \
  359 + enumbins=20 \
  360 + nxpix=200 \
  361 + nypix=200 \
  362 + binsz=0.02 \
  363 + coordsys="CEL" \
  364 + xref=83.63 \
  365 + yref=22.01 \
  366 + proj="CAR"
  367 +$ECHO -n "."
  368 +if [ -s "expcube1.fits" ]
  369 +then
  370 + $ECHO -n "."
  371 +else
  372 + $ECHO " expcube1.fits file is not valid"
  373 + exit 1
  374 +fi
  375 +#
  376 +# Run 2
  377 +$ctexpcube infile="data/crab_events.fits" \
  378 + cntmap="data/crab_cntmap.fits" \
  379 + outfile="expcube2.fits" \
  380 + caldb="irf" \
  381 + irf="cta_dummy_irf"
  382 +$ECHO -n "."
  383 +if [ -s "expcube2.fits" ]
  384 +then
  385 + $ECHO -n "."
  386 +else
  387 + $ECHO " expcube2.fits file is not valid"
  388 + exit 1
  389 +fi
... ...