Commit 56501d1eec6814ec9e4a9bb644d6a534c09981fa

Authored by Jürgen Knödlseder
1 parent e6c90a83

Correct sensitivity computation in cssens and show proper column in show_sensitivity.py.

examples/show_sensitivity.py
@@ -99,7 +99,7 @@ def show_sensitivity(sensitivity, filename): @@ -99,7 +99,7 @@ def show_sensitivity(sensitivity, filename):
99 plt.grid() 99 plt.grid()
100 100
101 # Show differential sensitivity 101 # Show differential sensitivity
102 - plt.plot(sensitivity['energy'], sensitivity['eflux'], 'ro-') 102 + plt.plot(sensitivity['energy'], sensitivity['sensitivity'], 'ro-')
103 103
104 # Set labels 104 # Set labels
105 plt.xlabel("Energy (TeV)") 105 plt.xlabel("Energy (TeV)")
pyext/ctools/obsutils.py
@@ -26,7 +26,7 @@ import math @@ -26,7 +26,7 @@ import math
26 # ===================== # 26 # ===================== #
27 # Simulate observations # 27 # Simulate observations #
28 # ===================== # 28 # ===================== #
29 -def sim(obs, log=False, debug=False, edisp=False, seed=0, nbins=0, 29 +def sim(obs, log=False, debug=False, chatter=2, edisp=False, seed=0, nbins=0,
30 binsz=0.05, npix=200, proj="TAN", coord="GAL"): 30 binsz=0.05, npix=200, proj="TAN", coord="GAL"):
31 """ 31 """
32 Simulate events for all observations in the container. 32 Simulate events for all observations in the container.
@@ -55,6 +55,9 @@ def sim(obs, log=False, debug=False, edisp=False, seed=0, nbins=0, @@ -55,6 +55,9 @@ def sim(obs, log=False, debug=False, edisp=False, seed=0, nbins=0,
55 # Optionally switch-on debugging model 55 # Optionally switch-on debugging model
56 if debug: 56 if debug:
57 sim["debug"].boolean(True) 57 sim["debug"].boolean(True)
  58 +
  59 + # Set chatter level
  60 + sim["chatter"].chatter = chatter
58 61
59 # Run ctobssim application. This will loop over all observations in the 62 # Run ctobssim application. This will loop over all observations in the
60 # container and simulation the events for each observation. Note that 63 # container and simulation the events for each observation. Note that
@@ -101,6 +104,9 @@ def sim(obs, log=False, debug=False, edisp=False, seed=0, nbins=0, @@ -101,6 +104,9 @@ def sim(obs, log=False, debug=False, edisp=False, seed=0, nbins=0,
101 if debug: 104 if debug:
102 bin["debug"].boolean(True) 105 bin["debug"].boolean(True)
103 106
  107 + # Set chatter level
  108 + bin["chatter"].chatter = chatter
  109 +
104 # Run ctbin application. This will loop over all observations in 110 # Run ctbin application. This will loop over all observations in
105 # the container and bin the events in counts maps 111 # the container and bin the events in counts maps
106 bin.run() 112 bin.run()
@@ -127,7 +133,7 @@ def sim(obs, log=False, debug=False, edisp=False, seed=0, nbins=0, @@ -127,7 +133,7 @@ def sim(obs, log=False, debug=False, edisp=False, seed=0, nbins=0,
127 # ================ # 133 # ================ #
128 # Fit observations # 134 # Fit observations #
129 # ================ # 135 # ================ #
130 -def fit(obs, log=False, debug=False, edisp=False): 136 +def fit(obs, log=False, debug=False, chatter=2, edisp=False):
131 """ 137 """
132 Perform maximum likelihood fitting of observations in the container. 138 Perform maximum likelihood fitting of observations in the container.
133 139
@@ -148,6 +154,9 @@ def fit(obs, log=False, debug=False, edisp=False): @@ -148,6 +154,9 @@ def fit(obs, log=False, debug=False, edisp=False):
148 # Optionally switch-on debugging model 154 # Optionally switch-on debugging model
149 if debug: 155 if debug:
150 like["debug"].boolean(True) 156 like["debug"].boolean(True)
  157 +
  158 + # Set chatter level
  159 + like["chatter"].chatter = chatter
151 160
152 # Optionally apply energy dispersion 161 # Optionally apply energy dispersion
153 like["edisp"].boolean(edisp) 162 like["edisp"].boolean(edisp)
scripts/cssens.py
@@ -200,7 +200,8 @@ class cssens(ctools.cscript): @@ -200,7 +200,8 @@ class cssens(ctools.cscript):
200 self.log("\n") 200 self.log("\n")
201 201
202 # Initialise script 202 # Initialise script
203 - colnames = ['loge', 'emin', 'emax', 'crab', 'pflux', 'eflux', 'diffSens'] 203 + colnames = ['loge', 'emin', 'emax', 'crab_flux', 'photon_flux', \
  204 + 'energy_flux', 'sensitivity']
204 results = [] 205 results = []
205 206
206 # Initialise models 207 # Initialise models
@@ -412,18 +413,10 @@ class cssens(ctools.cscript): @@ -412,18 +413,10 @@ class cssens(ctools.cscript):
412 # Set energy boundaries 413 # Set energy boundaries
413 self.set_obs_ebounds(emin, emax) 414 self.set_obs_ebounds(emin, emax)
414 415
415 - # Determine energy boundaries from first observation in  
416 - # the container  
417 - #for run in obs:  
418 - # emin = run.events().ebounds().emin()  
419 - # emax = run.events().ebounds().emax()  
420 - # loge = math.log10(math.sqrt(emin.TeV()*emax.TeV()))  
421 - # erg_mean = math.pow(10.0, loge) * tev2erg  
422 - # erg_width = (emax.TeV()-emin.TeV()) * tev2erg  
423 - # break 416 + # Determine energy boundaries from first observation in the container
424 loge = math.log10(math.sqrt(emin.TeV()*emax.TeV())) 417 loge = math.log10(math.sqrt(emin.TeV()*emax.TeV()))
425 - erg_mean = math.pow(10.0, loge) * tev2erg  
426 - erg_width = (emax.TeV()-emin.TeV()) * tev2erg 418 + e_mean = math.pow(10.0, loge)
  419 + erg_mean = e_mean * tev2erg
427 420
428 # Compute Crab unit (this is the factor with which the Prefactor needs 421 # Compute Crab unit (this is the factor with which the Prefactor needs
429 # to be multiplied to get 1 Crab 422 # to be multiplied to get 1 Crab
@@ -446,12 +439,12 @@ class cssens(ctools.cscript): @@ -446,12 +439,12 @@ class cssens(ctools.cscript):
446 self.log("\n") 439 self.log("\n")
447 440
448 # Initialise loop 441 # Initialise loop
449 - flux_value = []  
450 - pflux_value = []  
451 - eflux_value = []  
452 - diffSens_value = []  
453 - iter = 0  
454 - test_cflux = 0.1 # This is the initial test flux in Crab units (100 mCrab) 442 + crab_flux_value = []
  443 + photon_flux_value = []
  444 + energy_flux_value = []
  445 + sensitivity_value = []
  446 + iter = 0
  447 + test_crab_flux = 0.1 # Initial test flux in Crab units (100 mCrab)
455 448
456 # Loop until we break 449 # Loop until we break
457 while True: 450 while True:
@@ -463,13 +456,13 @@ class cssens(ctools.cscript): @@ -463,13 +456,13 @@ class cssens(ctools.cscript):
463 if self.logExplicit(): 456 if self.logExplicit():
464 self.log.header2("Iteration "+str(iter)) 457 self.log.header2("Iteration "+str(iter))
465 458
466 - # Set test flux 459 + # Set source model. crab_prefactor is the Prefactor that
  460 + # corresponds to 1 Crab
467 src_model = full_model.copy() 461 src_model = full_model.copy()
468 crab_prefactor = src_model[self.m_srcname]['Prefactor'].value() * crab_unit 462 crab_prefactor = src_model[self.m_srcname]['Prefactor'].value() * crab_unit
469 - src_model[self.m_srcname]['Prefactor'].value(crab_prefactor * test_cflux) 463 + src_model[self.m_srcname]['Prefactor'].value(crab_prefactor * test_crab_flux)
470 obs.models(src_model) 464 obs.models(src_model)
471 465
472 -  
473 # Simulate events 466 # Simulate events
474 sim = obsutils.sim(obs, nbins=self.m_enumbins, seed=iter, \ 467 sim = obsutils.sim(obs, nbins=self.m_enumbins, seed=iter, \
475 binsz=self.m_binsz, npix=self.m_npix, \ 468 binsz=self.m_binsz, npix=self.m_npix, \
@@ -572,48 +565,45 @@ class cssens(ctools.cscript): @@ -572,48 +565,45 @@ class cssens(ctools.cscript):
572 continue 565 continue
573 566
574 # Get fitted Crab, photon and energy fluxes 567 # Get fitted Crab, photon and energy fluxes
575 - cflux = result_all[self.m_srcname]['Prefactor'].value() / crab_prefactor  
576 - cflux_err = result_all[self.m_srcname]['Prefactor'].error() / crab_prefactor  
577 - pflux = result_all[self.m_srcname].spectral().flux(emin, emax)  
578 - eflux = result_all[self.m_srcname].spectral().eflux(emin, emax) 568 + crab_flux = result_all[self.m_srcname]['Prefactor'].value() / crab_prefactor
  569 + crab_flux_err = result_all[self.m_srcname]['Prefactor'].error() / crab_prefactor
  570 + photon_flux = result_all[self.m_srcname].spectral().flux(emin, emax)
  571 + energy_flux = result_all[self.m_srcname].spectral().eflux(emin, emax)
579 572
580 - # Compute differential sensitivity  
581 - diffSens = pflux / erg_width * erg_mean*erg_mean 573 + # Compute differential sensitivity in unit erg/cm2/s
  574 + energy = gammalib.GEnergy(e_mean, "TeV")
  575 + time = gammalib.GTime()
  576 + sensitivity = result_all[self.m_srcname].spectral().eval(energy, time) * \
  577 + erg_mean*erg_mean * 1.0e6
582 578
583 # Compute flux correction factor based on average TS 579 # Compute flux correction factor based on average TS
584 correct = 1.0 580 correct = 1.0
585 if ts > 0: 581 if ts > 0:
586 correct = math.sqrt(self.m_ts_thres/ts) 582 correct = math.sqrt(self.m_ts_thres/ts)
587 - #if self.m_use_ts:  
588 - # if ts > 0:  
589 - # correct = math.sqrt(self.m_ts_thres/ts)  
590 - #else:  
591 - # if cflux > 0 and cflux_err > 0:  
592 - # correct = math.sqrt(self.m_ts_thres)/(cflux/cflux_err)  
593 583
594 # Compute extrapolated fluxes 584 # Compute extrapolated fluxes
595 - flux = correct * cflux  
596 - pflux = correct * pflux  
597 - eflux = correct * eflux  
598 - diffSens = correct * diffSens  
599 - flux_value.append(flux)  
600 - pflux_value.append(pflux)  
601 - eflux_value.append(eflux)  
602 - diffSens_value.append(diffSens) 585 + crab_flux = correct * crab_flux
  586 + photon_flux = correct * photon_flux
  587 + energy_flux = correct * energy_flux
  588 + sensitivity = correct * sensitivity
  589 + crab_flux_value.append(crab_flux)
  590 + photon_flux_value.append(photon_flux)
  591 + energy_flux_value.append(energy_flux)
  592 + sensitivity_value.append(sensitivity)
603 593
604 # Write background and test source fit results 594 # Write background and test source fit results
605 if self.logExplicit(): 595 if self.logExplicit():
606 self.log.parformat("Photon flux") 596 self.log.parformat("Photon flux")
607 - self.log(pflux) 597 + self.log(photon_flux)
608 self.log(" ph/cm2/s\n") 598 self.log(" ph/cm2/s\n")
609 self.log.parformat("Energy flux") 599 self.log.parformat("Energy flux")
610 - self.log(eflux) 600 + self.log(energy_flux)
611 self.log(" erg/cm2/s\n") 601 self.log(" erg/cm2/s\n")
612 self.log.parformat("Crab flux") 602 self.log.parformat("Crab flux")
613 - self.log(cflux*1000.0) 603 + self.log(crab_flux*1000.0)
614 self.log(" mCrab\n") 604 self.log(" mCrab\n")
615 self.log.parformat("Differential sensitivity") 605 self.log.parformat("Differential sensitivity")
616 - self.log(diffSens) 606 + self.log(sensitivity)
617 self.log(" erg/cm2/s\n") 607 self.log(" erg/cm2/s\n")
618 for model in result_all: 608 for model in result_all:
619 self.log.parformat("Model") 609 self.log.parformat("Model")
@@ -629,40 +619,40 @@ class cssens(ctools.cscript): @@ -629,40 +619,40 @@ class cssens(ctools.cscript):
629 self.log("corr=") 619 self.log("corr=")
630 self.log(correct) 620 self.log(correct)
631 self.log(" ") 621 self.log(" ")
632 - self.log(pflux) 622 + self.log(photon_flux)
633 self.log(" ph/cm2/s = ") 623 self.log(" ph/cm2/s = ")
634 - self.log(eflux) 624 + self.log(energy_flux)
635 self.log(" erg/cm2/s = ") 625 self.log(" erg/cm2/s = ")
636 - self.log(cflux*1000.0) 626 + self.log(crab_flux*1000.0)
637 self.log(" mCrab = ") 627 self.log(" mCrab = ")
638 - self.log(diffSens) 628 + self.log(sensitivity)
639 self.log(" erg/cm2/s\n") 629 self.log(" erg/cm2/s\n")
640 630
641 # Compute sliding average of extrapolated fitted prefactor, 631 # Compute sliding average of extrapolated fitted prefactor,
642 # photon and energy flux. This damps out fluctuations and 632 # photon and energy flux. This damps out fluctuations and
643 # improves convergence 633 # improves convergence
644 - flux = 0.0  
645 - pflux = 0.0  
646 - eflux = 0.0  
647 - diffSens = 0.0  
648 - num = 0.0 634 + crab_flux = 0.0
  635 + photon_flux = 0.0
  636 + energy_flux = 0.0
  637 + sensitivity = 0.0
  638 + num = 0.0
649 for k in range(self.m_num_avg): 639 for k in range(self.m_num_avg):
650 - inx = len(flux_value) - k - 1 640 + inx = len(crab_flux_value) - k - 1
651 if inx >= 0: 641 if inx >= 0:
652 - flux += flux_value[inx]  
653 - pflux += pflux_value[inx]  
654 - eflux += eflux_value[inx]  
655 - diffSens += diffSens_value[inx] 642 + crab_flux += crab_flux_value[inx]
  643 + photon_flux += photon_flux_value[inx]
  644 + energy_flux += energy_flux_value[inx]
  645 + sensitivity += sensitivity_value[inx]
656 num += 1.0 646 num += 1.0
657 - flux /= num  
658 - pflux /= num  
659 - eflux /= num  
660 - diffSens /= num 647 + crab_flux /= num
  648 + photon_flux /= num
  649 + energy_flux /= num
  650 + sensitivity /= num
661 651
662 # Compare average flux to last average 652 # Compare average flux to last average
663 if iter > self.m_num_avg: 653 if iter > self.m_num_avg:
664 - if test_cflux > 0:  
665 - ratio = flux/test_cflux 654 + if test_crab_flux > 0:
  655 + ratio = crab_flux/test_crab_flux
666 656
667 # We have 2 convergence criteria: 657 # We have 2 convergence criteria:
668 # 1. The average flux does not change 658 # 1. The average flux does not change
@@ -678,7 +668,7 @@ class cssens(ctools.cscript): @@ -678,7 +668,7 @@ class cssens(ctools.cscript):
678 break 668 break
679 669
680 # Use average for next iteration 670 # Use average for next iteration
681 - test_cflux = flux 671 + test_crab_flux = crab_flux
682 672
683 # Exit loop if number of trials exhausted 673 # Exit loop if number of trials exhausted
684 if (iter >= self.m_max_iter): 674 if (iter >= self.m_max_iter):
@@ -693,16 +683,16 @@ class cssens(ctools.cscript): @@ -693,16 +683,16 @@ class cssens(ctools.cscript):
693 self.log(ts) 683 self.log(ts)
694 self.log("\n") 684 self.log("\n")
695 self.log.parformat("Photon flux") 685 self.log.parformat("Photon flux")
696 - self.log(pflux) 686 + self.log(photon_flux)
697 self.log(" ph/cm2/s\n") 687 self.log(" ph/cm2/s\n")
698 self.log.parformat("Energy flux") 688 self.log.parformat("Energy flux")
699 - self.log(eflux) 689 + self.log(energy_flux)
700 self.log(" erg/cm2/s\n") 690 self.log(" erg/cm2/s\n")
701 self.log.parformat("Crab flux") 691 self.log.parformat("Crab flux")
702 - self.log(cflux*1000.0) 692 + self.log(crab_flux*1000.0)
703 self.log(" mCrab\n") 693 self.log(" mCrab\n")
704 self.log.parformat("Differential sensitivity") 694 self.log.parformat("Differential sensitivity")
705 - self.log(diffSens) 695 + self.log(sensitivity)
706 self.log(" erg/cm2/s\n") 696 self.log(" erg/cm2/s\n")
707 self.log.parformat("Number of simulated events") 697 self.log.parformat("Number of simulated events")
708 self.log(nevents) 698 self.log(nevents)
@@ -736,8 +726,9 @@ class cssens(ctools.cscript): @@ -736,8 +726,9 @@ class cssens(ctools.cscript):
736 726
737 # Store result 727 # Store result
738 result = {'loge': loge, 'emin': emin.TeV(), 'emax': emax.TeV(), \ 728 result = {'loge': loge, 'emin': emin.TeV(), 'emax': emax.TeV(), \
739 - 'crab': flux, 'pflux': pflux, 'eflux': eflux, \  
740 - 'diffSens': diffSens} 729 + 'crab_flux': crab_flux, 'photon_flux': photon_flux, \
  730 + 'energy_flux': energy_flux, \
  731 + 'sensitivity': sensitivity}
741 732
742 # Return result 733 # Return result
743 return result 734 return result