Commit 0c2bbeee19cc10e2e6dbef625f1276914ce468da

Authored by Jürgen Knödlseder
1 parent 3d6b4b92

Adapt time slice duration to model flux.

The time slice duration is now adapted to the source model flux. The m_max_photons member now defines the maximum number of photons that should be simulated in one slice. This prevents core dumps due to memory allocation problems in case that large fluxes have been specified.

This partially adresses feature #807.
src/ctobssim/ctobssim.cpp
... ... @@ -289,6 +289,9 @@ void ctobssim::run(void)
289 289 {
290 290 // Each thread will have it's own logger to avoid conflicts
291 291 GLog wrklog;
  292 + if (logDebug()) {
  293 + wrklog.cout(true);
  294 + }
292 295  
293 296 // Copy configuration from application logger to thread logger
294 297 wrklog.date(log.date());
... ... @@ -689,12 +692,28 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels& models,
689 692 // If we have a sky model then simulate photons
690 693 if (model != NULL) {
691 694  
  695 + // Determine duration of a time slice by limiting the
  696 + // number of simulated photons to m_max_photons.
  697 + // The photon rate is estimated from the model flux
  698 + // and used to set the duration of the time slice.
  699 + double flux = model->spectral()->flux(emin, emax);
  700 + double rate = flux * m_area;
  701 + double duration = 1800.0; // default: 1800 sec
  702 + if (rate > 0.0) {
  703 + duration = m_max_photons / rate;
  704 + if (duration < 1.0) { // not <1 sec
  705 + duration = 1.0;
  706 + }
  707 + else if (duration > 180000.0) { // not >50 hr
  708 + duration = 180000.0;
  709 + }
  710 + }
  711 + GTime tslice(duration, "sec");
  712 +
692 713 // To reduce memory requirements we split long time
693   - // intervals into several slices. The maximum length
694   - // of a slice is determined by the fixed parameter
695   - // m_time_max
  714 + // intervals into several slices.
696 715 GTime tstart = tmin;
697   - GTime tstop = tstart + m_time_max;
  716 + GTime tstop = tstart + tslice;
698 717  
699 718 // Initialise cumulative photon counters
700 719 int nphotons = 0;
... ... @@ -709,7 +728,7 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels&amp; models,
709 728  
710 729 // Dump time slice
711 730 if (logExplicit()) {
712   - if (tmax - tmin > m_time_max) {
  731 + if (tmax - tmin > tslice) {
713 732 indent++;
714 733 wrklog->indent(indent);
715 734 }
... ... @@ -725,6 +744,16 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels&amp; models,
725 744 emin, emax,
726 745 tstart, tstop, ran);
727 746  
  747 + // Dump number of simulated photons
  748 + if (logExplicit()) {
  749 + *wrklog << gammalib::parformat("MC source photons/slice", indent);
  750 + *wrklog << photons.size();
  751 + if (model->name().length() > 0) {
  752 + *wrklog << " [" << model->name() << "]";
  753 + }
  754 + *wrklog << std::endl;
  755 + }
  756 +
728 757 // Simulate events from photons
729 758 for (int i = 0; i < photons.size(); ++i) {
730 759  
... ... @@ -752,11 +781,11 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels&amp; models,
752 781  
753 782 // Go to next time slice
754 783 tstart = tstop;
755   - tstop = tstart + m_time_max;
  784 + tstop = tstart + tslice;
756 785  
757 786 // Reset indentation
758 787 if (logExplicit()) {
759   - if (tmax - tmin > m_time_max) {
  788 + if (tmax - tmin > tslice) {
760 789 indent--;
761 790 wrklog->indent(indent);
762 791 }
... ... @@ -961,8 +990,8 @@ void ctobssim::init_members(void)
961 990 m_read_ahead = false;
962 991  
963 992 // Set fixed parameters
964   - m_area = 19634954.0 * 1.0e4; //!< pi*(2500^2) m^2
965   - m_time_max.secs(1800.0); //!< Maximum length of time slice (s)
  993 + m_area = 19634954.0 * 1.0e4; //!< pi*(2500^2) m^2
  994 + m_max_photons = 1000000; //!< Maximum number of photons / time slice
966 995  
967 996 // Set CTA time reference. G_CTA_MJDREF is the CTA reference MJD,
968 997 // which is defined in GCTALib.hpp. This is somehow a kluge. We need
... ... @@ -1004,14 +1033,14 @@ void ctobssim::copy_members(const ctobssim&amp; app)
1004 1033 m_deadc = app.m_deadc;
1005 1034  
1006 1035 // Copy protected members
1007   - m_area = app.m_area;
1008   - m_time_max = app.m_time_max;
1009   - m_rans = app.m_rans;
1010   - m_obs = app.m_obs;
1011   - m_use_xml = app.m_use_xml;
1012   - m_read_ahead = app.m_read_ahead;
1013   - m_cta_ref = app.m_cta_ref;
1014   - m_event_id = app.m_event_id;
  1036 + m_area = app.m_area;
  1037 + m_max_photons = app.m_max_photons;
  1038 + m_rans = app.m_rans;
  1039 + m_obs = app.m_obs;
  1040 + m_use_xml = app.m_use_xml;
  1041 + m_read_ahead = app.m_read_ahead;
  1042 + m_cta_ref = app.m_cta_ref;
  1043 + m_event_id = app.m_event_id;
1015 1044  
1016 1045 // Return
1017 1046 return;
... ...
src/ctobssim/ctobssim.hpp
... ... @@ -95,14 +95,14 @@ protected:
95 95 double m_deadc; //!< Average deadtime correction
96 96  
97 97 // Protected members
98   - double m_area; //!< Surface area for simulation (cm2)
99   - GTime m_time_max; //!< Maximum length of time slice (sec)
100   - std::vector<GRan> m_rans; //!< Random number generators
101   - GObservations m_obs; //!< Observation container
102   - bool m_use_xml; //!< Use XML file instead of FITS file
103   - bool m_read_ahead; //!< Read ahead parameters
104   - GTimeReference m_cta_ref; //!< CTA time reference
105   - int m_event_id; //!< Event identifier
  98 + double m_area; //!< Surface area for simulation (cm2)
  99 + int m_max_photons; //!< Maximum number of photons/slice
  100 + std::vector<GRan> m_rans; //!< Random number generators
  101 + GObservations m_obs; //!< Observation container
  102 + bool m_use_xml; //!< Use XML file instead of FITS file
  103 + bool m_read_ahead; //!< Read ahead parameters
  104 + GTimeReference m_cta_ref; //!< CTA time reference
  105 + int m_event_id; //!< Event identifier
106 106 };
107 107  
108 108 #endif /* CTOBSSIM_HPP */
... ...