Commit 030a746c04abc8d91e82dc4717288f9fdc5d1ec2

Authored by Jürgen Knödlseder
1 parent d69e7faa

Integrate code

... ... @@ -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)
... ...
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&amp; 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&amp; 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&amp; 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&amp; 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&amp; 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&amp; obs, GRan&amp; 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&amp; obs, GRan&amp; 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&amp; obs, GRan&amp; 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  
... ...