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,6 +289,9 @@ void ctobssim::run(void)
289 { 289 {
290 // Each thread will have it's own logger to avoid conflicts 290 // Each thread will have it's own logger to avoid conflicts
291 GLog wrklog; 291 GLog wrklog;
  292 + if (logDebug()) {
  293 + wrklog.cout(true);
  294 + }
292 295
293 // Copy configuration from application logger to thread logger 296 // Copy configuration from application logger to thread logger
294 wrklog.date(log.date()); 297 wrklog.date(log.date());
@@ -689,12 +692,28 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels& models, @@ -689,12 +692,28 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels& models,
689 // If we have a sky model then simulate photons 692 // If we have a sky model then simulate photons
690 if (model != NULL) { 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 // To reduce memory requirements we split long time 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 GTime tstart = tmin; 715 GTime tstart = tmin;
697 - GTime tstop = tstart + m_time_max; 716 + GTime tstop = tstart + tslice;
698 717
699 // Initialise cumulative photon counters 718 // Initialise cumulative photon counters
700 int nphotons = 0; 719 int nphotons = 0;
@@ -709,7 +728,7 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels&amp; models, @@ -709,7 +728,7 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels&amp; models,
709 728
710 // Dump time slice 729 // Dump time slice
711 if (logExplicit()) { 730 if (logExplicit()) {
712 - if (tmax - tmin > m_time_max) { 731 + if (tmax - tmin > tslice) {
713 indent++; 732 indent++;
714 wrklog->indent(indent); 733 wrklog->indent(indent);
715 } 734 }
@@ -725,6 +744,16 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels&amp; models, @@ -725,6 +744,16 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels&amp; models,
725 emin, emax, 744 emin, emax,
726 tstart, tstop, ran); 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 // Simulate events from photons 757 // Simulate events from photons
729 for (int i = 0; i < photons.size(); ++i) { 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,11 +781,11 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels&amp; models,
752 781
753 // Go to next time slice 782 // Go to next time slice
754 tstart = tstop; 783 tstart = tstop;
755 - tstop = tstart + m_time_max; 784 + tstop = tstart + tslice;
756 785
757 // Reset indentation 786 // Reset indentation
758 if (logExplicit()) { 787 if (logExplicit()) {
759 - if (tmax - tmin > m_time_max) { 788 + if (tmax - tmin > tslice) {
760 indent--; 789 indent--;
761 wrklog->indent(indent); 790 wrklog->indent(indent);
762 } 791 }
@@ -961,8 +990,8 @@ void ctobssim::init_members(void) @@ -961,8 +990,8 @@ void ctobssim::init_members(void)
961 m_read_ahead = false; 990 m_read_ahead = false;
962 991
963 // Set fixed parameters 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 // Set CTA time reference. G_CTA_MJDREF is the CTA reference MJD, 996 // Set CTA time reference. G_CTA_MJDREF is the CTA reference MJD,
968 // which is defined in GCTALib.hpp. This is somehow a kluge. We need 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,14 +1033,14 @@ void ctobssim::copy_members(const ctobssim&amp; app)
1004 m_deadc = app.m_deadc; 1033 m_deadc = app.m_deadc;
1005 1034
1006 // Copy protected members 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 // Return 1045 // Return
1017 return; 1046 return;
src/ctobssim/ctobssim.hpp
@@ -95,14 +95,14 @@ protected: @@ -95,14 +95,14 @@ protected:
95 double m_deadc; //!< Average deadtime correction 95 double m_deadc; //!< Average deadtime correction
96 96
97 // Protected members 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 #endif /* CTOBSSIM_HPP */ 108 #endif /* CTOBSSIM_HPP */