Commit b554fc2efa1c85d671fd8fc1844fc497b86b6732
1 parent
9617e53e
Allow energy boundaries and energy value FITS file as input to ebinfile parameters (#1978)
Showing
7 changed files
with
98 additions
and
108 deletions
ChangeLog
| 1 | -2017-03-22 | |
| 1 | +2017-03-24 | |
| 2 | 2 | |
| 3 | 3 | * Version 1.3.0 released |
| 4 | 4 | ======================== |
| 5 | 5 | |
| 6 | + Support energy boundary FITS file in ctmapcube (#1978) | |
| 6 | 7 | Add csebins script (#1976) |
| 7 | - Take into account RoI in ctskymap and use numerical integration for IRF (#1975) | |
| 8 | + Consider RoI in ctskymap and use numerical integration for IRF (#1975) | |
| 8 | 9 | Set local language to english (#1370) |
| 9 | 10 | Enhance logfile output of csroot2caldb script |
| 10 | 11 | Set default deadc value to 0.98 (CTA has <2% deadtime) | ... | ... |
NEWS
| 1 | 1 | New Features and Important Changes in ctools 1.3.0.dev1 |
| 2 | 2 | |
| 3 | -22 March 2017 | |
| 3 | +24 March 2017 | |
| 4 | 4 | |
| 5 | 5 | |
| 6 | 6 | Introduction |
| ... | ... | @@ -87,7 +87,8 @@ None |
| 87 | 87 | |
| 88 | 88 | ctmapcube - CTA map cube generation |
| 89 | 89 | ----------------------------------- |
| 90 | -None | |
| 90 | +The tool now supports loading the energy binning definition from an energy | |
| 91 | +boundary FITS file, behaving now similar to the other cube tools (#1978). | |
| 91 | 92 | |
| 92 | 93 | |
| 93 | 94 | ctcubemask - CTA cube filtering | ... | ... |
src/ctmapcube/ctmapcube.cpp
| ... | ... | @@ -349,7 +349,7 @@ void ctmapcube::get_parameters(void) |
| 349 | 349 | } // endif: there were no models |
| 350 | 350 | |
| 351 | 351 | // Get energy binning parameters |
| 352 | - GEnergies energies = create_energies(); | |
| 352 | + GEnergies energies(create_ebounds()); | |
| 353 | 353 | |
| 354 | 354 | // Get spatial binning parameters |
| 355 | 355 | double xref = (*this)["xref"].real(); |
| ... | ... | @@ -386,68 +386,6 @@ void ctmapcube::get_parameters(void) |
| 386 | 386 | |
| 387 | 387 | |
| 388 | 388 | /***********************************************************************//** |
| 389 | - * @brief Create map cube energies from user parameters | |
| 390 | - * | |
| 391 | - * Creates the map cube energies according to the user parameters. If the | |
| 392 | - * @p ebinfile parameter is "FILE" the method loads the energy information | |
| 393 | - * from a FITS file. The name of the FITS file is given by the @p ebinfile | |
| 394 | - * parameter. If no extension name is specified the method will use assume | |
| 395 | - * the name to be `ENERGIES`. | |
| 396 | - * | |
| 397 | - * If the @p ebinfile parameter is "LIN" the method will create a linearly | |
| 398 | - * spaced series of @p enumbins energies in the interval @p emin to @p emax. | |
| 399 | - * Otherwise, the @p ebinfile parameter is assumed to be "LOG" and the method | |
| 400 | - * will create a logarithmically spaced series of @p enumbins energies in the | |
| 401 | - * interval @p emin to @p emax. | |
| 402 | - ***************************************************************************/ | |
| 403 | -GEnergies ctmapcube::create_energies(void) | |
| 404 | -{ | |
| 405 | - // Allocate energies | |
| 406 | - GEnergies energies; | |
| 407 | - | |
| 408 | - // Get energy binning algorithm | |
| 409 | - std::string ebinalg = (*this)["ebinalg"].string(); | |
| 410 | - | |
| 411 | - // If energy binning algorithm is of type "FILE" (case sensitive), then | |
| 412 | - // read energies from FITS file ... | |
| 413 | - if (ebinalg == "FILE") { | |
| 414 | - | |
| 415 | - // Get filename | |
| 416 | - GFilename ebinfile = (*this)["ebinfile"].filename(); | |
| 417 | - | |
| 418 | - // Load energies | |
| 419 | - energies.load(ebinfile); | |
| 420 | - | |
| 421 | - } // endif: ebinalg was "FILE" | |
| 422 | - | |
| 423 | - // ... otherwise use a linear or a logarithmically-spaced energy binning | |
| 424 | - else { | |
| 425 | - | |
| 426 | - // Get task parameters | |
| 427 | - double emin = (*this)["emin"].real(); | |
| 428 | - double emax = (*this)["emax"].real(); | |
| 429 | - int enumbins = (*this)["enumbins"].integer(); | |
| 430 | - | |
| 431 | - // Initialise log mode for ebinning | |
| 432 | - bool log = true; | |
| 433 | - | |
| 434 | - // Check if algorithm is linear | |
| 435 | - if (ebinalg == "LIN") { | |
| 436 | - log = false; | |
| 437 | - } | |
| 438 | - | |
| 439 | - // Setup energies | |
| 440 | - energies = GEnergies(enumbins, GEnergy(emin, "TeV"), | |
| 441 | - GEnergy(emax, "TeV"), log); | |
| 442 | - | |
| 443 | - } // endelse: ebinalg was not "FILE" | |
| 444 | - | |
| 445 | - // Return energies | |
| 446 | - return energies; | |
| 447 | -} | |
| 448 | - | |
| 449 | - | |
| 450 | -/***********************************************************************//** | |
| 451 | 389 | * @brief Generate map cube |
| 452 | 390 | * |
| 453 | 391 | * Generate map cube by looping over all sky models in the container. | ... | ... |
src/ctmapcube/ctmapcube.hpp
| 1 | 1 | /*************************************************************************** |
| 2 | 2 | * ctmapcube - Map cube generation tool * |
| 3 | 3 | * ----------------------------------------------------------------------- * |
| 4 | - * copyright (C) 2016 by Juergen Knoedlseder * | |
| 4 | + * copyright (C) 2016-2017 by Juergen Knoedlseder * | |
| 5 | 5 | * ----------------------------------------------------------------------- * |
| 6 | 6 | * * |
| 7 | 7 | * This program is free software: you can redistribute it and/or modify * |
| ... | ... | @@ -34,7 +34,7 @@ |
| 34 | 34 | |
| 35 | 35 | /* __Definitions _________________________________________________________ */ |
| 36 | 36 | #define CTMAPCUBE_NAME "ctmapcube" |
| 37 | -#define CTMAPCUBE_VERSION "1.2.0" | |
| 37 | +#define CTMAPCUBE_VERSION "1.3.0" | |
| 38 | 38 | |
| 39 | 39 | |
| 40 | 40 | /***********************************************************************//** |
| ... | ... | @@ -64,17 +64,16 @@ public: |
| 64 | 64 | |
| 65 | 65 | protected: |
| 66 | 66 | // Protected methods |
| 67 | - void init_members(void); | |
| 68 | - void copy_members(const ctmapcube& app); | |
| 69 | - void free_members(void); | |
| 70 | - void get_parameters(void); | |
| 71 | - GEnergies create_energies(void); | |
| 72 | - void create_cube(void); | |
| 73 | - void add_model(GModelSky* model); | |
| 74 | - void add_ptsrc_model(GModelSky* model); | |
| 75 | - void get_bounding_circle(GModelSky* model, | |
| 76 | - GSkyDir* dir, | |
| 77 | - double* radius) const; | |
| 67 | + void init_members(void); | |
| 68 | + void copy_members(const ctmapcube& app); | |
| 69 | + void free_members(void); | |
| 70 | + void get_parameters(void); | |
| 71 | + void create_cube(void); | |
| 72 | + void add_model(GModelSky* model); | |
| 73 | + void add_ptsrc_model(GModelSky* model); | |
| 74 | + void get_bounding_circle(GModelSky* model, | |
| 75 | + GSkyDir* dir, | |
| 76 | + double* radius) const; | |
| 78 | 77 | |
| 79 | 78 | // User parameters |
| 80 | 79 | GFilename m_outcube; //!< Output map cube filename | ... | ... |
src/support/ctool.cpp
| ... | ... | @@ -503,15 +503,19 @@ void ctool::setup_models(GObservations& obs, |
| 503 | 503 | * @brief Create energy boundaries from user parameters |
| 504 | 504 | * |
| 505 | 505 | * @exception GException::invalid_value |
| 506 | - * No valid energy boundary extension found. | |
| 506 | + * No valid energy boundary extension found or invalid extension | |
| 507 | + * name. | |
| 507 | 508 | * |
| 508 | 509 | * Get the energy boundaries according to the user parameters. The method |
| 509 | 510 | * supports loading of energy boundary information from the `EBOUNDS` or |
| 510 | - * `ENERGYBINS` extension, or setting energy boundaries using a linear | |
| 511 | - * or logarithmical spacing. | |
| 511 | + * `ENERGYBINS` extension, loading of energy value information from the | |
| 512 | + * `ENERGIES` extension, or setting energy boundaries using a linear or | |
| 513 | + * logarithmical spacing. | |
| 512 | 514 | * |
| 513 | 515 | * The following parameters are read: |
| 516 | + * | |
| 514 | 517 | * ebinalg - Energy binning algorithm |
| 518 | + * ebinfile - Name of file with energy binning | |
| 515 | 519 | * emin - Minimum energy (if ebinalg != FILE) |
| 516 | 520 | * emax - Maximum energy (if ebinalg != FILE) |
| 517 | 521 | * enumbins - Number of energy bins (if ebinalg != FILE) |
| ... | ... | @@ -529,43 +533,72 @@ GEbounds ctool::create_ebounds(void) |
| 529 | 533 | if (ebinalg == "FILE") { |
| 530 | 534 | |
| 531 | 535 | // Get filename |
| 532 | - std::string ebinfile = (*this)["ebinfile"].filename(); | |
| 533 | - | |
| 534 | - // Create filename instance | |
| 535 | - GFilename fname(ebinfile); | |
| 536 | + GFilename ebinfile = (*this)["ebinfile"].filename(); | |
| 536 | 537 | |
| 537 | - // Check if extension name was provided | |
| 538 | - if (!fname.has_extname()) { | |
| 538 | + // If no extension name was provided then use default extension names | |
| 539 | + if (!ebinfile.has_extname()) { | |
| 539 | 540 | |
| 540 | 541 | // Open energy boundary file using the EBOUNDS or ENERGYBINS |
| 541 | - // extension. Throw an exception if opening fails. | |
| 542 | - GFits file(ebinfile); | |
| 542 | + // extension or energy values using the ENERGIES extension. | |
| 543 | + // Throw an exception if opening fails. | |
| 544 | + GFits file(ebinfile.url()); | |
| 543 | 545 | if (file.contains(gammalib::extname_ebounds)) { |
| 544 | 546 | file.close(); |
| 545 | 547 | ebounds.load(ebinfile); |
| 546 | 548 | } |
| 547 | 549 | else if (file.contains("ENERGYBINS")) { |
| 548 | 550 | file.close(); |
| 549 | - ebinfile += "[ENERGYBINS]"; | |
| 551 | + ebinfile = ebinfile.url() + "[ENERGYBINS]"; | |
| 550 | 552 | ebounds.load(ebinfile); |
| 551 | 553 | } |
| 554 | + else if (file.contains(gammalib::extname_energies)) { | |
| 555 | + file.close(); | |
| 556 | + ebounds.set(GEnergies(ebinfile)); | |
| 557 | + } | |
| 552 | 558 | else { |
| 553 | 559 | file.close(); |
| 554 | 560 | std::string msg = "No extension with name \""+ |
| 555 | - gammalib::extname_ebounds+"\" or" | |
| 556 | - " \"ENERGYBINS\" found in FITS file" | |
| 557 | - " \""+ebinfile+"\". An \""+ | |
| 558 | - gammalib::extname_ebounds+"\" or " | |
| 559 | - "\"ENERGYBINS\" extension is required if " | |
| 560 | - "the parameter \"ebinalg\" is set to " | |
| 561 | - "\"FILE\"."; | |
| 561 | + gammalib::extname_ebounds+"\", " | |
| 562 | + "\"ENERGYBINS\" or \""+ | |
| 563 | + gammalib::extname_energies+"\" found in FITS " | |
| 564 | + "file \""+ebinfile+"\". Please specify a " | |
| 565 | + "valid energy binning file."; | |
| 562 | 566 | throw GException::invalid_value(G_CREATE_EBOUNDS, msg); |
| 563 | 567 | } |
| 564 | 568 | } |
| 569 | + | |
| 570 | + // ... otherwise load energy boundaries from filename including | |
| 571 | + // extension | |
| 565 | 572 | else { |
| 566 | - // Load ebounds from filename including extension | |
| 567 | - ebounds.load(ebinfile); | |
| 568 | - } | |
| 573 | + | |
| 574 | + // Open energy boundary file | |
| 575 | + GFits file(ebinfile.url()); | |
| 576 | + | |
| 577 | + // If FITS file does not contain requested extension then throw | |
| 578 | + // an exception | |
| 579 | + if (!file.contains(ebinfile.extname())) { | |
| 580 | + std::string msg = "No extension \""+ebinfile.extname()+"\" " | |
| 581 | + "found in energy binning file \""+ | |
| 582 | + ebinfile.url()+"\". Please provide a valid " | |
| 583 | + "extension name."; | |
| 584 | + throw GException::invalid_value(G_CREATE_EBOUNDS, msg); | |
| 585 | + } | |
| 586 | + | |
| 587 | + // Get table extension | |
| 588 | + GFitsTable& table = *file.table(ebinfile.extname()); | |
| 589 | + | |
| 590 | + // If table contains one column then load energies, otherwise load | |
| 591 | + // energy boundaries. | |
| 592 | + if (table.ncols() == 1) { | |
| 593 | + file.close(); | |
| 594 | + ebounds.set(GEnergies(ebinfile)); | |
| 595 | + } | |
| 596 | + else { | |
| 597 | + file.close(); | |
| 598 | + ebounds.load(ebinfile); | |
| 599 | + } | |
| 600 | + | |
| 601 | + } // endelse: loaded energy boundaries from table extension | |
| 569 | 602 | |
| 570 | 603 | } // endif: ebinalg was "FILE" |
| 571 | 604 | ... | ... |
test/test_cscript.py
| ... | ... | @@ -238,7 +238,13 @@ class Test(test): |
| 238 | 238 | gammalib.GEnergy(10.0,'TeV')) |
| 239 | 239 | ebounds.save('test_ebinfile_ebounds.fits[EBOUNDS]', True) |
| 240 | 240 | ebounds.save('test_ebinfile_energybins.fits[ENERGYBINS]', True) |
| 241 | - ebounds.save('test_ebinfile_energies.fits[ENERGIES]', True) | |
| 241 | + ebounds.save('test_ebinfile_bins.fits[BINS]', True) | |
| 242 | + | |
| 243 | + # Create energy bin file | |
| 244 | + energies = gammalib.GEnergies(2, gammalib.GEnergy(1.0,'TeV'), | |
| 245 | + gammalib.GEnergy(10.0,'TeV')) | |
| 246 | + energies.save('test_ebinfile_energies.fits[ENERGIES]', True) | |
| 247 | + energies.save('test_ebinfile_engs.fits[ENGS]', True) | |
| 242 | 248 | |
| 243 | 249 | # Return |
| 244 | 250 | return |
| ... | ... | @@ -335,16 +341,28 @@ class Test(test): |
| 335 | 341 | self.test_value(ebounds.emin().TeV(), 1.0, 'Check minimum energy') |
| 336 | 342 | self.test_value(ebounds.emax().TeV(), 10.0, 'Check maximum energy') |
| 337 | 343 | |
| 344 | + # Test create_ebounds() method for "ENERGIES" extension | |
| 345 | + ebounds = empty.check_create_ebounds('test_ebinfile_energies.fits') | |
| 346 | + self.test_value(ebounds.size(), 1, 'Check number of energy boundaries') | |
| 347 | + self.test_value(ebounds.emin().TeV(), 1.0, 'Check minimum energy') | |
| 348 | + self.test_value(ebounds.emax().TeV(), 10.0, 'Check maximum energy') | |
| 349 | + | |
| 338 | 350 | # Test create_ebounds() method for invalid extension |
| 339 | 351 | self.test_try('Check create_ebounds() method for invalid extension') |
| 340 | 352 | try: |
| 341 | - empty.check_create_ebounds('test_ebinfile_energies.fits') | |
| 353 | + empty.check_create_ebounds('test_ebinfile_energies.fits[INVALID]') | |
| 342 | 354 | self.test_try_failure('Exception not thrown') |
| 343 | 355 | except ValueError: |
| 344 | 356 | self.test_try_success() |
| 345 | 357 | |
| 346 | - # Test create_ebounds() method for "ENERGIES" extension | |
| 347 | - ebounds = empty.check_create_ebounds('test_ebinfile_energies.fits[ENERGIES]') | |
| 358 | + # Test create_ebounds() method for "BINS" extension | |
| 359 | + ebounds = empty.check_create_ebounds('test_ebinfile_bins.fits[BINS]') | |
| 360 | + self.test_value(ebounds.size(), 1, 'Check number of energy boundaries') | |
| 361 | + self.test_value(ebounds.emin().TeV(), 1.0, 'Check minimum energy') | |
| 362 | + self.test_value(ebounds.emax().TeV(), 10.0, 'Check maximum energy') | |
| 363 | + | |
| 364 | + # Test create_ebounds() method for "ENGS" extension | |
| 365 | + ebounds = empty.check_create_ebounds('test_ebinfile_engs.fits[ENGS]') | |
| 348 | 366 | self.test_value(ebounds.size(), 1, 'Check number of energy boundaries') |
| 349 | 367 | self.test_value(ebounds.emin().TeV(), 1.0, 'Check minimum energy') |
| 350 | 368 | self.test_value(ebounds.emax().TeV(), 10.0, 'Check maximum energy') | ... | ... |
test/test_ctmapcube.py
| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | # ========================================================================== |
| 3 | 3 | # This scripts performs unit tests for the ctmapcube tool. |
| 4 | 4 | # |
| 5 | -# Copyright (C) 2016 Juergen Knoedlseder | |
| 5 | +# Copyright (C) 2016-2017 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 |
| ... | ... | @@ -242,7 +242,7 @@ class Test(test): |
| 242 | 242 | return |
| 243 | 243 | |
| 244 | 244 | # Check map cube |
| 245 | - def _check_cube(self, cube, nmaps=10, npixels=10000): | |
| 245 | + def _check_cube(self, cube, nmaps=11, npixels=10000): | |
| 246 | 246 | """ |
| 247 | 247 | Check map cube |
| 248 | 248 | ... | ... |