Commit 030a746c04abc8d91e82dc4717288f9fdc5d1ec2
1 parent
d69e7faa
Integrate code
Showing
5 changed files
with
80 additions
and
35 deletions
AUTHORS
| ... | ... | @@ -4,6 +4,7 @@ Joshua Cardenzana (jcardenzana@irap.omp.eu) |
| 4 | 4 | Jean-Baptiste Cayrou (cayrou@etud.insa-toulouse.fr) |
| 5 | 5 | Christoph Deil (Christoph.Deil@mpi-hd.mpg.de) |
| 6 | 6 | Alex Donath (Axel.Donath@mpi-hd.mpg.de) |
| 7 | +Stefan Eschbach (stefan.eschbach@fau.de) | |
| 7 | 8 | Florent Forest (florent.forest@isae.fr) |
| 8 | 9 | Lucie Gerard (lucie.gerard@desy.de) |
| 9 | 10 | Tarek Hassan (thassan@ifae.es) | ... | ... |
ChangeLog
| 1 | -2017-03-27 | |
| 1 | +2017-04-07 | |
| 2 | 2 | |
| 3 | 3 | * Version 1.3.0 released |
| 4 | 4 | ========================= |
| 5 | 5 | |
| 6 | + Avoid hang-up of GCTAModelAeffBackground::mc() method (#1988) | |
| 6 | 7 | Enhance precision of GCTAEdisp2D::compute_ebounds_src |
| 7 | 8 | Add conversion methods between GEbounds and GEnergies (#1977) |
| 8 | 9 | Add GModelSpectralSmoothBrokenPlaw class (#1948) | ... | ... |
NEWS
| 1 | 1 | New Features and Important Changes in GammaLib 1.3.0.dev1 |
| 2 | 2 | |
| 3 | -27 March 2017 | |
| 3 | +7 April 2017 | |
| 4 | 4 | |
| 5 | 5 | |
| 6 | 6 | 1. Introduction |
| ... | ... | @@ -160,6 +160,11 @@ method. In addition, the validity range of the table is now stored in members |
| 160 | 160 | of the class, and a non-zero energy dispersion is only returned for valid |
| 161 | 161 | elements of the response table. |
| 162 | 162 | |
| 163 | +The GCTAModelAeffBackground::mc() could get stuck in the rejection loop if the | |
| 164 | +effective area returned is always zero. A counter has been added that leads to | |
| 165 | +the exit of the loop in case that 1000 subsequent zero values are returned | |
| 166 | +(#1988). | |
| 167 | + | |
| 163 | 168 | |
| 164 | 169 | 21. COMPTEL interface |
| 165 | 170 | --------------------- | ... | ... |
inst/cta/src/GCTAModelAeffBackground.cpp
| 1 | 1 | /*************************************************************************** |
| 2 | 2 | * GCTAModelAeffBackground.cpp - CTA Aeff background model class * |
| 3 | 3 | * ----------------------------------------------------------------------- * |
| 4 | - * copyright (C) 2015-2016 by Michael Mayer * | |
| 4 | + * copyright (C) 2015-2017 by Michael Mayer * | |
| 5 | 5 | * ----------------------------------------------------------------------- * |
| 6 | 6 | * * |
| 7 | 7 | * This program is free software: you can redistribute it and/or modify * |
| ... | ... | @@ -509,13 +509,14 @@ GCTAEventList* GCTAModelAeffBackground::mc(const GObservation& obs, |
| 509 | 509 | // Retrieve CTA observation |
| 510 | 510 | const GCTAObservation* cta = dynamic_cast<const GCTAObservation*>(&obs); |
| 511 | 511 | if (cta == NULL) { |
| 512 | - std::string msg = "Specified observation is not a CTA observation.\n" + | |
| 513 | - obs.print(); | |
| 512 | + std::string msg = "Specified observation is not a CTA " | |
| 513 | + "observation.\n" + obs.print(); | |
| 514 | 514 | throw GException::invalid_argument(G_MC, msg); |
| 515 | 515 | } |
| 516 | 516 | |
| 517 | 517 | // Get pointer on CTA IRF response |
| 518 | - const GCTAResponseIrf* rsp = dynamic_cast<const GCTAResponseIrf*>(cta->response()); | |
| 518 | + const GCTAResponseIrf* rsp = | |
| 519 | + dynamic_cast<const GCTAResponseIrf*>(cta->response()); | |
| 519 | 520 | if (rsp == NULL) { |
| 520 | 521 | std::string msg = "Specified observation does not contain" |
| 521 | 522 | " an IRF response.\n" + obs.print(); |
| ... | ... | @@ -534,7 +535,8 @@ GCTAEventList* GCTAModelAeffBackground::mc(const GObservation& obs, |
| 534 | 535 | } |
| 535 | 536 | |
| 536 | 537 | // Retrieve event list to access the ROI, energy boundaries and GTIs |
| 537 | - const GCTAEventList* events = dynamic_cast<const GCTAEventList*>(obs.events()); | |
| 538 | + const GCTAEventList* events = | |
| 539 | + dynamic_cast<const GCTAEventList*>(obs.events()); | |
| 538 | 540 | if (events == NULL) { |
| 539 | 541 | std::string msg = "No CTA event list found in observation.\n" + |
| 540 | 542 | obs.print(); |
| ... | ... | @@ -559,19 +561,21 @@ GCTAEventList* GCTAModelAeffBackground::mc(const GObservation& obs, |
| 559 | 561 | // Set up spectral model to draw random energies from. Here we use |
| 560 | 562 | // a fixed energy sampling for an instance of GModelSpectralNodes. |
| 561 | 563 | // This is analogous to to the GCTAModelIrfBackground::mc method. |
| 562 | - GEbounds spectral_ebounds = GEbounds(m_n_mc_energies, ebounds.emin(), ebounds.emax(), true); | |
| 564 | + // We make sure that only non-negative nodes get appended. | |
| 565 | + GEbounds spectral_ebounds = | |
| 566 | + GEbounds(m_n_mc_energies, ebounds.emin(), ebounds.emax(), true); | |
| 563 | 567 | GModelSpectralNodes spectral; |
| 564 | 568 | for (int i = 0; i < spectral_ebounds.size(); ++i) { |
| 565 | - GEnergy energy = spectral_ebounds.elogmean(i); | |
| 566 | - double intensity = aeff_integral(obs, energy.log10TeV()); | |
| 567 | - double norm = m_spectral->eval(energy, events->tstart()); | |
| 568 | - if(norm * intensity > 0){ | |
| 569 | - spectral.append(energy, norm * intensity); | |
| 570 | - } | |
| 569 | + GEnergy energy = spectral_ebounds.elogmean(i); | |
| 570 | + double intensity = aeff_integral(obs, energy.log10TeV()); | |
| 571 | + double norm = m_spectral->eval(energy, events->tstart()); | |
| 572 | + double arg = norm * intensity; | |
| 573 | + if (arg > 0.0) { | |
| 574 | + spectral.append(energy, arg); | |
| 575 | + } | |
| 571 | 576 | } |
| 572 | - | |
| 573 | - | |
| 574 | - // Loop over all energy boundaries | |
| 577 | + | |
| 578 | + // Loop over all energy bins | |
| 575 | 579 | for (int ieng = 0; ieng < ebounds.size(); ++ieng) { |
| 576 | 580 | |
| 577 | 581 | // Compute the background rate in model within the energy |
| ... | ... | @@ -586,6 +590,11 @@ GCTAEventList* GCTAModelAeffBackground::mc(const GObservation& obs, |
| 586 | 590 | std::cout << "rate=" << rate << " cts/s)" << std::endl; |
| 587 | 591 | #endif |
| 588 | 592 | |
| 593 | + // If the rate is not positive then skip this energy bins | |
| 594 | + if (rate <= 0.0) { | |
| 595 | + continue; | |
| 596 | + } | |
| 597 | + | |
| 589 | 598 | // Loop over all good time intervals |
| 590 | 599 | for (int itime = 0; itime < gti.size(); ++itime) { |
| 591 | 600 | |
| ... | ... | @@ -633,17 +642,24 @@ GCTAEventList* GCTAModelAeffBackground::mc(const GObservation& obs, |
| 633 | 642 | ran); |
| 634 | 643 | |
| 635 | 644 | // Get maximum effective area for rejection method |
| 636 | - double max_aeff = aeff->max(energy.log10TeV(), pnt.zenith(), pnt.azimuth(), false); | |
| 645 | + double max_aeff = aeff->max(energy.log10TeV(), pnt.zenith(), | |
| 646 | + pnt.azimuth(), false); | |
| 647 | + | |
| 648 | + // Skip event if the maximum effective area is not positive | |
| 649 | + if (max_aeff <= 0.0) { | |
| 650 | + continue; | |
| 651 | + } | |
| 637 | 652 | |
| 638 | 653 | // Initialise randomised coordinates |
| 639 | 654 | double offset = 0.0; |
| 640 | 655 | double phi = 0.0; |
| 641 | 656 | |
| 642 | - // Initialise acceptance fraction for rejection method | |
| 657 | + // Initialise acceptance fraction and counter of zeros for | |
| 658 | + // rejection method | |
| 643 | 659 | double acceptance_fraction = 0.0; |
| 660 | + int zeros = 0; | |
| 644 | 661 | |
| 645 | 662 | // Start rejection method loop |
| 646 | - int numberoftrys=0; | |
| 647 | 663 | do { |
| 648 | 664 | |
| 649 | 665 | // Throw random offset and azimuth angle in |
| ... | ... | @@ -653,24 +669,39 @@ GCTAEventList* GCTAModelAeffBackground::mc(const GObservation& obs, |
| 653 | 669 | phi = ran.uniform() * gammalib::twopi; |
| 654 | 670 | |
| 655 | 671 | // Compute function value at this offset angle |
| 656 | - double value = (*aeff)(energy.log10TeV(), offset, phi, pnt.zenith(), pnt.azimuth(), false); | |
| 657 | - | |
| 658 | - // std::cout << "value: " << value << ", max_aeff: " << max_aeff << std::endl; | |
| 659 | - if(numberoftrys==1000&&value==0){ | |
| 660 | - break; | |
| 661 | - } | |
| 672 | + double value = (*aeff)(energy.log10TeV(), offset, phi, | |
| 673 | + pnt.zenith(), pnt.azimuth(), | |
| 674 | + false); | |
| 675 | + | |
| 676 | + // If the value is not positive then increment the | |
| 677 | + // zeros counter and fall through. The counter assures | |
| 678 | + // that this loop does not lock up. | |
| 679 | + if (value <= 0.0) { | |
| 680 | + zeros++; | |
| 681 | + continue; | |
| 682 | + } | |
| 683 | + | |
| 684 | + // Value is non-zero so reset the zeros counter | |
| 685 | + zeros = 0; | |
| 686 | + | |
| 662 | 687 | // Compute acceptance fraction |
| 663 | 688 | acceptance_fraction = value / max_aeff; |
| 664 | - | |
| 665 | - numberoftrys++; | |
| 666 | 689 | |
| 667 | - } while (ran.uniform() > acceptance_fraction); | |
| 690 | + } while ((ran.uniform() > acceptance_fraction) && | |
| 691 | + (zeros < 1000)); | |
| 692 | + | |
| 693 | + // If the zeros counter is non-zero then the loop was | |
| 694 | + // exited due to exhaustion and the event is skipped | |
| 695 | + if (zeros > 0) { | |
| 696 | + continue; | |
| 697 | + } | |
| 668 | 698 | |
| 669 | 699 | // Convert CTA pointing direction in instrument system |
| 670 | 700 | GCTAInstDir mc_dir(pnt.dir()); |
| 671 | 701 | |
| 672 | 702 | // Rotate pointing direction by offset and azimuth angle |
| 673 | - mc_dir.dir().rotate_deg(phi * gammalib::rad2deg, offset * gammalib::rad2deg); | |
| 703 | + mc_dir.dir().rotate_deg(phi * gammalib::rad2deg, | |
| 704 | + offset * gammalib::rad2deg); | |
| 674 | 705 | |
| 675 | 706 | // Compute DETX and DETY coordinates |
| 676 | 707 | double detx(0.0); | ... | ... |
inst/cta/src/GCTAModelIrfBackground.cpp
| 1 | 1 | /*************************************************************************** |
| 2 | 2 | * GCTAModelIrfBackground.cpp - CTA IRF background model class * |
| 3 | 3 | * ----------------------------------------------------------------------- * |
| 4 | - * copyright (C) 2014-2016 by Juergen Knoedlseder * | |
| 4 | + * copyright (C) 2014-2017 by Juergen Knoedlseder * | |
| 5 | 5 | * ----------------------------------------------------------------------- * |
| 6 | 6 | * * |
| 7 | 7 | * This program is free software: you can redistribute it and/or modify * |
| ... | ... | @@ -551,13 +551,14 @@ GCTAEventList* GCTAModelIrfBackground::mc(const GObservation& obs, GRan& ran) co |
| 551 | 551 | // Retrieve CTA observation |
| 552 | 552 | const GCTAObservation* cta = dynamic_cast<const GCTAObservation*>(&obs); |
| 553 | 553 | if (cta == NULL) { |
| 554 | - std::string msg = "Specified observation is not a CTA observation.\n" + | |
| 555 | - obs.print(); | |
| 554 | + std::string msg = "Specified observation is not a CTA " | |
| 555 | + "observation.\n" + obs.print(); | |
| 556 | 556 | throw GException::invalid_argument(G_MC, msg); |
| 557 | 557 | } |
| 558 | 558 | |
| 559 | 559 | // Get pointer on CTA IRF response |
| 560 | - const GCTAResponseIrf* rsp = dynamic_cast<const GCTAResponseIrf*>(cta->response()); | |
| 560 | + const GCTAResponseIrf* rsp = | |
| 561 | + dynamic_cast<const GCTAResponseIrf*>(cta->response()); | |
| 561 | 562 | if (rsp == NULL) { |
| 562 | 563 | std::string msg = "Specified observation does not contain" |
| 563 | 564 | " an IRF response.\n" + obs.print(); |
| ... | ... | @@ -576,7 +577,8 @@ GCTAEventList* GCTAModelIrfBackground::mc(const GObservation& obs, GRan& ran) co |
| 576 | 577 | } |
| 577 | 578 | |
| 578 | 579 | // Retrieve event list to access the ROI, energy boundaries and GTIs |
| 579 | - const GCTAEventList* events = dynamic_cast<const GCTAEventList*>(obs.events()); | |
| 580 | + const GCTAEventList* events = | |
| 581 | + dynamic_cast<const GCTAEventList*>(obs.events()); | |
| 580 | 582 | if (events == NULL) { |
| 581 | 583 | std::string msg = "No CTA event list found in observation.\n" + |
| 582 | 584 | obs.print(); |
| ... | ... | @@ -618,6 +620,11 @@ GCTAEventList* GCTAModelIrfBackground::mc(const GObservation& obs, GRan& ran) co |
| 618 | 620 | std::cout << "rate=" << rate << " cts/s)" << std::endl; |
| 619 | 621 | #endif |
| 620 | 622 | |
| 623 | + // If the rate is not positive then skip this energy bins | |
| 624 | + if (rate <= 0.0) { | |
| 625 | + continue; | |
| 626 | + } | |
| 627 | + | |
| 621 | 628 | // Loop over all good time intervals |
| 622 | 629 | for (int itime = 0; itime < gti.size(); ++itime) { |
| 623 | 630 | ... | ... |