Commit cd21731005495d04311938244f29acbe07a08bca

Authored by knodlseder
1 parent d33354d2

Implement deadtime correction.

The deadtime is controlled using the deadc parameter. An additional MC process decides whether a photon event or a background event falls within a dead period of the system or not.
src/ctobssim/ctobssim.cpp
1 /*************************************************************************** 1 /***************************************************************************
2 * ctobssim - CTA observation simulator tool * 2 * ctobssim - CTA observation simulator tool *
3 * ----------------------------------------------------------------------- * 3 * ----------------------------------------------------------------------- *
4 - * copyright (C) 2011 by Juergen Knoedlseder * 4 + * copyright (C) 2011-2012 by Juergen Knoedlseder *
5 * ----------------------------------------------------------------------- * 5 * ----------------------------------------------------------------------- *
6 * * 6 * *
7 * This program is free software: you can redistribute it and/or modify * 7 * This program is free software: you can redistribute it and/or modify *
@@ -241,20 +241,24 @@ void ctobssim::run(void) @@ -241,20 +241,24 @@ void ctobssim::run(void)
241 // Write observation(s) into logger 241 // Write observation(s) into logger
242 if (logTerse()) { 242 if (logTerse()) {
243 log << std::endl; 243 log << std::endl;
244 - if (m_obs.size() > 1) 244 + if (m_obs.size() > 1) {
245 log.header1("Observations"); 245 log.header1("Observations");
246 - else 246 + }
  247 + else {
247 log.header1("Observation"); 248 log.header1("Observation");
  249 + }
248 log << m_obs << std::endl; 250 log << m_obs << std::endl;
249 } 251 }
250 252
251 // Write header 253 // Write header
252 if (logTerse()) { 254 if (logTerse()) {
253 log << std::endl; 255 log << std::endl;
254 - if (m_obs.size() > 1) 256 + if (m_obs.size() > 1) {
255 log.header1("Simulate observations"); 257 log.header1("Simulate observations");
256 - else 258 + }
  259 + else {
257 log.header1("Simulate observation"); 260 log.header1("Simulate observation");
  261 + }
258 } 262 }
259 263
260 // Loop over all observation in the container 264 // Loop over all observation in the container
@@ -268,17 +272,15 @@ void ctobssim::run(void) @@ -268,17 +272,15 @@ void ctobssim::run(void)
268 272
269 // Write header for observation 273 // Write header for observation
270 if (logTerse()) { 274 if (logTerse()) {
271 - if (obs->name().length() > 1) 275 + if (obs->name().length() > 1) {
272 log.header3("Observation "+obs->name()); 276 log.header3("Observation "+obs->name());
273 - else 277 + }
  278 + else {
274 log.header3("Observation"); 279 log.header3("Observation");
  280 + }
275 } 281 }
276 282
277 - // Simulate photons  
278 - //GPhotons photons = simulate_photons(obs, m_obs.models());  
279 -  
280 // Simulate source events 283 // Simulate source events
281 - //simulate_source(obs, photons);  
282 simulate_source(obs, m_obs.models()); 284 simulate_source(obs, m_obs.models());
283 285
284 // Simulate source events 286 // Simulate source events
@@ -297,16 +299,21 @@ void ctobssim::run(void) @@ -297,16 +299,21 @@ void ctobssim::run(void)
297 * @brief Save simulated observation 299 * @brief Save simulated observation
298 * 300 *
299 * This method saves the results. 301 * This method saves the results.
  302 + *
  303 + * @todo Implement XML file output in case that on observation list is
  304 + * provided on input.
300 ***************************************************************************/ 305 ***************************************************************************/
301 void ctobssim::save(void) 306 void ctobssim::save(void)
302 { 307 {
303 // Write header 308 // Write header
304 if (logTerse()) { 309 if (logTerse()) {
305 log << std::endl; 310 log << std::endl;
306 - if (m_obs.size() > 1) 311 + if (m_obs.size() > 1) {
307 log.header1("Save observations"); 312 log.header1("Save observations");
308 - else 313 + }
  314 + else {
309 log.header1("Save observation"); 315 log.header1("Save observation");
  316 + }
310 } 317 }
311 318
312 // Get output filename 319 // Get output filename
@@ -325,8 +332,9 @@ void ctobssim::save(void) @@ -325,8 +332,9 @@ void ctobssim::save(void)
325 // Set filename. If more than one file will be created an 332 // Set filename. If more than one file will be created an
326 // index "_xxx" will be appended. 333 // index "_xxx" will be appended.
327 std::string filename = m_outfile; 334 std::string filename = m_outfile;
328 - if (file_num > 0) 335 + if (file_num > 0) {
329 filename += "_"+str(file_num); 336 filename += "_"+str(file_num);
  337 + }
330 338
331 // Save file 339 // Save file
332 obs->save(filename, clobber()); 340 obs->save(filename, clobber());
@@ -403,7 +411,13 @@ void ctobssim::get_parameters(void) @@ -403,7 +411,13 @@ void ctobssim::get_parameters(void)
403 /***********************************************************************//** 411 /***********************************************************************//**
404 * @brief Set empty CTA event list 412 * @brief Set empty CTA event list
405 * 413 *
406 - * @param[in] obs Attach empty event list to CTA observation 414 + * @param[in] obs CTA observation.
  415 + *
  416 + * Attaches an empty event list to CTA observation. The method also sets the
  417 + * pointing direction using the m_ra and m_dec members, the ROI based on
  418 + * m_ra, m_dec and m_rad, a single GTI based on m_tmin and m_tmax, and a
  419 + * single energy boundary based on m_emin and m_emax. The method furthermore
  420 + * sets the ontime, livetime and deadtime correction factor.
407 ***************************************************************************/ 421 ***************************************************************************/
408 void ctobssim::set_list(GCTAObservation* obs) 422 void ctobssim::set_list(GCTAObservation* obs)
409 { 423 {
@@ -411,13 +425,14 @@ void ctobssim::set_list(GCTAObservation* obs) @@ -411,13 +425,14 @@ void ctobssim::set_list(GCTAObservation* obs)
411 if (obs != NULL) { 425 if (obs != NULL) {
412 426
413 // Get CTA observation parameters 427 // Get CTA observation parameters
414 - m_ra = (*this)["ra"].real();  
415 - m_dec = (*this)["dec"].real();  
416 - m_rad = (*this)["rad"].real();  
417 - m_tmin = (*this)["tmin"].real();  
418 - m_tmax = (*this)["tmax"].real();  
419 - m_emin = (*this)["emin"].real();  
420 - m_emax = (*this)["emax"].real(); 428 + m_ra = (*this)["ra"].real();
  429 + m_dec = (*this)["dec"].real();
  430 + m_rad = (*this)["rad"].real();
  431 + m_tmin = (*this)["tmin"].real();
  432 + m_tmax = (*this)["tmax"].real();
  433 + m_emin = (*this)["emin"].real();
  434 + m_emax = (*this)["emax"].real();
  435 + m_deadc = (*this)["deadc"].real();
421 436
422 // Allocate CTA event list 437 // Allocate CTA event list
423 GCTAEventList events; 438 GCTAEventList events;
@@ -458,6 +473,11 @@ void ctobssim::set_list(GCTAObservation* obs) @@ -458,6 +473,11 @@ void ctobssim::set_list(GCTAObservation* obs)
458 473
459 // Attach event list to CTA observation 474 // Attach event list to CTA observation
460 obs->events(&events); 475 obs->events(&events);
  476 +
  477 + // Set observation ontime, livetime and deadtime correction factor
  478 + obs->ontime(gti.ontime());
  479 + obs->livetime(gti.ontime()*m_deadc);
  480 + obs->deadc(m_deadc);
461 481
462 } // endif: oberservation was valid 482 } // endif: oberservation was valid
463 483
@@ -511,8 +531,9 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels&amp; models) @@ -511,8 +531,9 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels&amp; models)
511 531
512 // Make sure that the observation holds a CTA event list. If this 532 // Make sure that the observation holds a CTA event list. If this
513 // is not the case then allocate and attach a CTA event list now. 533 // is not the case then allocate and attach a CTA event list now.
514 - if (dynamic_cast<const GCTAEventList*>(obs->events()) == NULL) 534 + if (dynamic_cast<const GCTAEventList*>(obs->events()) == NULL) {
515 set_list(obs); 535 set_list(obs);
  536 + }
516 537
517 // Get pointer on event list (circumvent const correctness) 538 // Get pointer on event list (circumvent const correctness)
518 GCTAEventList* events = (GCTAEventList*)(obs->events()); 539 GCTAEventList* events = (GCTAEventList*)(obs->events());
@@ -584,15 +605,17 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels&amp; models) @@ -584,15 +605,17 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels&amp; models)
584 GTime tstart = tmin; 605 GTime tstart = tmin;
585 GTime tstop = tstart + m_time_max; 606 GTime tstop = tstart + m_time_max;
586 607
587 - // Initialise cumulative photon counter 608 + // Initialise cumulative photon counters
588 int nphotons = 0; 609 int nphotons = 0;
  610 + int ndeadc = 0;
589 611
590 // Loop over time slices 612 // Loop over time slices
591 while (tstart < tmax) { 613 while (tstart < tmax) {
592 614
593 // Make sure that tstop <= tmax 615 // Make sure that tstop <= tmax
594 - if (tstop > tmax) 616 + if (tstop > tmax) {
595 tstop = tmax; 617 tstop = tmax;
  618 + }
596 619
597 // Dump time slice 620 // Dump time slice
598 if (logExplicit()) { 621 if (logExplicit()) {
@@ -609,17 +632,28 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels&amp; models) @@ -609,17 +632,28 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels&amp; models)
609 emin, emax, 632 emin, emax,
610 tstart, tstop, m_ran); 633 tstart, tstop, m_ran);
611 634
612 - // Bookkeeping of simulated number of photons  
613 - nphotons += photons.size();  
614 -  
615 // Simulate events from photons 635 // Simulate events from photons
616 for (int i = 0; i < photons.size(); ++i) { 636 for (int i = 0; i < photons.size(); ++i) {
  637 +
  638 + // Apply deadtime correction
  639 + if (m_deadc < 1.0) {
  640 + if (m_ran.uniform() > m_deadc) {
  641 + ndeadc++;
  642 + continue;
  643 + }
  644 + }
  645 +
  646 + // Increment photon counter
  647 + nphotons++;
  648 +
  649 + // Simulate event
617 GCTAEventAtom* event = rsp->mc(m_area, photons[i], *pnt, m_ran); 650 GCTAEventAtom* event = rsp->mc(m_area, photons[i], *pnt, m_ran);
618 if (event != NULL) { 651 if (event != NULL) {
619 events->append(*event); 652 events->append(*event);
620 delete event; 653 delete event;
621 } 654 }
622 - } 655 +
  656 + } // endfor: looped over events
623 657
624 // Go to next time slice 658 // Go to next time slice
625 tstart = tstop; 659 tstart = tstop;
@@ -639,13 +673,21 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels&amp; models) @@ -639,13 +673,21 @@ void ctobssim::simulate_source(GCTAObservation* obs, const GModels&amp; models)
639 if (logNormal()) { 673 if (logNormal()) {
640 log << parformat("MC source photons"); 674 log << parformat("MC source photons");
641 log << str(nphotons); 675 log << str(nphotons);
642 - if (model->name().length() > 0) 676 + if (model->name().length() > 0) {
643 log << " [" << model->name() << "]"; 677 log << " [" << model->name() << "]";
  678 + }
  679 + log << std::endl;
  680 + log << parformat("MC photons during deadtime");
  681 + log << str(ndeadc);
  682 + if (model->name().length() > 0) {
  683 + log << " [" << model->name() << "]";
  684 + }
644 log << std::endl; 685 log << std::endl;
645 log << parformat("MC source events"); 686 log << parformat("MC source events");
646 log << str(events->size()); 687 log << str(events->size());
647 - if (model->name().length() > 0) 688 + if (model->name().length() > 0) {
648 log << " [" << model->name() << "]"; 689 log << " [" << model->name() << "]";
  690 + }
649 log << std::endl; 691 log << std::endl;
650 } 692 }
651 693
@@ -709,8 +751,9 @@ void ctobssim::simulate_background(GCTAObservation* obs, const GModels&amp; models) @@ -709,8 +751,9 @@ void ctobssim::simulate_background(GCTAObservation* obs, const GModels&amp; models)
709 751
710 // Make sure that the observation holds a CTA event list. If this 752 // Make sure that the observation holds a CTA event list. If this
711 // is not the case then allocate and attach a CTA event list now. 753 // is not the case then allocate and attach a CTA event list now.
712 - if (dynamic_cast<const GCTAEventList*>(obs->events()) == NULL) 754 + if (dynamic_cast<const GCTAEventList*>(obs->events()) == NULL) {
713 set_list(obs); 755 set_list(obs);
  756 + }
714 757
715 // Get pointer on event list (circumvent const correctness) 758 // Get pointer on event list (circumvent const correctness)
716 GCTAEventList* events = (GCTAEventList*)(obs->events()); 759 GCTAEventList* events = (GCTAEventList*)(obs->events());
@@ -731,14 +774,35 @@ void ctobssim::simulate_background(GCTAObservation* obs, const GModels&amp; models) @@ -731,14 +774,35 @@ void ctobssim::simulate_background(GCTAObservation* obs, const GModels&amp; models)
731 // Reserves space for events 774 // Reserves space for events
732 events->reserve(list->size()+events->size()); 775 events->reserve(list->size()+events->size());
733 776
  777 + // Initialise event counters
  778 + int nevents = 0;
  779 + int ndeadc = 0;
  780 +
734 // Append events 781 // Append events
735 - for (int k = 0; k < list->size(); k++) 782 + for (int k = 0; k < list->size(); k++) {
  783 +
  784 + // Apply deadtime correction
  785 + if (m_deadc < 1.0) {
  786 + if (m_ran.uniform() > m_deadc) {
  787 + ndeadc++;
  788 + continue;
  789 + }
  790 + }
  791 +
  792 + // Increment background event counter
  793 + nevents++;
  794 +
  795 + // Append event
736 events->append(*((*list)[k])); 796 events->append(*((*list)[k]));
737 797
  798 + } // endfor: looped over all events
  799 +
738 // Dump simulation results 800 // Dump simulation results
739 if (logNormal()) { 801 if (logNormal()) {
740 log << parformat("MC background events"); 802 log << parformat("MC background events");
741 - log << str(list->size()) << std::endl; 803 + log << str(nevents) << std::endl;
  804 + log << parformat("MC events during deadtime");
  805 + log << str(ndeadc) << std::endl;
742 } 806 }
743 807
744 // Free event list 808 // Free event list
@@ -769,23 +833,26 @@ void ctobssim::simulate_background(GCTAObservation* obs, const GModels&amp; models) @@ -769,23 +833,26 @@ void ctobssim::simulate_background(GCTAObservation* obs, const GModels&amp; models)
769 ***************************************************************************/ 833 ***************************************************************************/
770 void ctobssim::init_members(void) 834 void ctobssim::init_members(void)
771 { 835 {
772 - // Initialise members 836 + // Initialise user parameters
773 m_infile.clear(); 837 m_infile.clear();
774 m_outfile.clear(); 838 m_outfile.clear();
775 m_caldb.clear(); 839 m_caldb.clear();
776 m_irf.clear(); 840 m_irf.clear();
  841 + m_seed = 1;
  842 + m_ra = 0.0;
  843 + m_dec = 0.0;
  844 + m_rad = 0.0;
  845 + m_tmin = 0.0;
  846 + m_tmax = 0.0;
  847 + m_emin = 0.0;
  848 + m_emax = 0.0;
  849 + m_deadc = 1.0;
  850 +
  851 + // Initialise protected members
777 m_obs.clear(); 852 m_obs.clear();
778 - m_seed = 1;  
779 - m_ra = 0.0;  
780 - m_dec = 0.0;  
781 - m_rad = 0.0;  
782 - m_tmin = 0.0;  
783 - m_tmax = 0.0;  
784 - m_emin = 0.0;  
785 - m_emax = 0.0;  
786 853
787 // Set fixed parameters 854 // Set fixed parameters
788 - m_area = 19634954.0 * 1.0e4; //!< pi*(2500^2) m^2 855 + m_area = 19634954.0 * 1.0e4; //!< pi*(2500^2) m^2
789 m_time_max.met(1800.0); //!< Maximum length of time slice (s) 856 m_time_max.met(1800.0); //!< Maximum length of time slice (s)
790 857
791 // Set logger properties 858 // Set logger properties
@@ -803,12 +870,11 @@ void ctobssim::init_members(void) @@ -803,12 +870,11 @@ void ctobssim::init_members(void)
803 ***************************************************************************/ 870 ***************************************************************************/
804 void ctobssim::copy_members(const ctobssim& app) 871 void ctobssim::copy_members(const ctobssim& app)
805 { 872 {
806 - // Copy attributes 873 + // Copy user parameters
807 m_infile = app.m_infile; 874 m_infile = app.m_infile;
808 m_outfile = app.m_outfile; 875 m_outfile = app.m_outfile;
809 m_caldb = app.m_caldb; 876 m_caldb = app.m_caldb;
810 m_irf = app.m_irf; 877 m_irf = app.m_irf;
811 - m_obs = app.m_obs;  
812 m_seed = app.m_seed; 878 m_seed = app.m_seed;
813 m_ra = app.m_ra; 879 m_ra = app.m_ra;
814 m_dec = app.m_dec; 880 m_dec = app.m_dec;
@@ -817,8 +883,13 @@ void ctobssim::copy_members(const ctobssim&amp; app) @@ -817,8 +883,13 @@ void ctobssim::copy_members(const ctobssim&amp; app)
817 m_tmax = app.m_tmax; 883 m_tmax = app.m_tmax;
818 m_emin = app.m_emin; 884 m_emin = app.m_emin;
819 m_emax = app.m_emax; 885 m_emax = app.m_emax;
  886 + m_deadc = app.m_deadc;
  887 +
  888 + // Copy protected members
820 m_area = app.m_area; 889 m_area = app.m_area;
821 m_time_max = app.m_time_max; 890 m_time_max = app.m_time_max;
  891 + m_ran = app.m_ran;
  892 + m_obs = app.m_obs;
822 893
823 // Return 894 // Return
824 return; 895 return;
@@ -831,8 +902,9 @@ void ctobssim::copy_members(const ctobssim&amp; app) @@ -831,8 +902,9 @@ void ctobssim::copy_members(const ctobssim&amp; app)
831 void ctobssim::free_members(void) 902 void ctobssim::free_members(void)
832 { 903 {
833 // Write separator into logger 904 // Write separator into logger
834 - if (logTerse()) 905 + if (logTerse()) {
835 log << std::endl; 906 log << std::endl;
  907 + }
836 908
837 // Return 909 // Return
838 return; 910 return;
src/ctobssim/ctobssim.hpp
1 /*************************************************************************** 1 /***************************************************************************
2 * ctobssim - CTA observation simulator tool * 2 * ctobssim - CTA observation simulator tool *
3 * ----------------------------------------------------------------------- * 3 * ----------------------------------------------------------------------- *
4 - * copyright (C) 2011 by Juergen Knoedlseder * 4 + * copyright (C) 2011-2012 by Juergen Knoedlseder *
5 * ----------------------------------------------------------------------- * 5 * ----------------------------------------------------------------------- *
6 * * 6 * *
7 * This program is free software: you can redistribute it and/or modify * 7 * This program is free software: you can redistribute it and/or modify *
@@ -33,7 +33,7 @@ @@ -33,7 +33,7 @@
33 33
34 /* __Definitions _________________________________________________________ */ 34 /* __Definitions _________________________________________________________ */
35 #define CTOBSSIM_NAME "ctobssim" 35 #define CTOBSSIM_NAME "ctobssim"
36 -#define CTOBSSIM_VERSION "00-03-01" 36 +#define CTOBSSIM_VERSION "00-04-00"
37 37
38 38
39 /***********************************************************************//** 39 /***********************************************************************//**
@@ -89,6 +89,7 @@ protected: @@ -89,6 +89,7 @@ protected:
89 double m_tmax; //!< Stop time (MET) 89 double m_tmax; //!< Stop time (MET)
90 double m_emin; //!< Lower energy (TeV) 90 double m_emin; //!< Lower energy (TeV)
91 double m_emax; //!< Upper energy (TeV) 91 double m_emax; //!< Upper energy (TeV)
  92 + double m_deadc; //!< Average deadtime correction
92 93
93 // Protected members 94 // Protected members
94 double m_area; //!< Surface area for simulation (cm2) 95 double m_area; //!< Surface area for simulation (cm2)