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 99 plt.grid()
100 100  
101 101 # Show differential sensitivity
102   - plt.plot(sensitivity['energy'], sensitivity['eflux'], 'ro-')
  102 + plt.plot(sensitivity['energy'], sensitivity['sensitivity'], 'ro-')
103 103  
104 104 # Set labels
105 105 plt.xlabel("Energy (TeV)")
... ...
pyext/ctools/obsutils.py
... ... @@ -26,7 +26,7 @@ import math
26 26 # ===================== #
27 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 30 binsz=0.05, npix=200, proj="TAN", coord="GAL"):
31 31 """
32 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 55 # Optionally switch-on debugging model
56 56 if debug:
57 57 sim["debug"].boolean(True)
  58 +
  59 + # Set chatter level
  60 + sim["chatter"].chatter = chatter
58 61  
59 62 # Run ctobssim application. This will loop over all observations in the
60 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 104 if debug:
102 105 bin["debug"].boolean(True)
103 106  
  107 + # Set chatter level
  108 + bin["chatter"].chatter = chatter
  109 +
104 110 # Run ctbin application. This will loop over all observations in
105 111 # the container and bin the events in counts maps
106 112 bin.run()
... ... @@ -127,7 +133,7 @@ def sim(obs, log=False, debug=False, edisp=False, seed=0, nbins=0,
127 133 # ================ #
128 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 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 154 # Optionally switch-on debugging model
149 155 if debug:
150 156 like["debug"].boolean(True)
  157 +
  158 + # Set chatter level
  159 + like["chatter"].chatter = chatter
151 160  
152 161 # Optionally apply energy dispersion
153 162 like["edisp"].boolean(edisp)
... ...
scripts/cssens.py
... ... @@ -200,7 +200,8 @@ class cssens(ctools.cscript):
200 200 self.log("\n")
201 201  
202 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 205 results = []
205 206  
206 207 # Initialise models
... ... @@ -412,18 +413,10 @@ class cssens(ctools.cscript):
412 413 # Set energy boundaries
413 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 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 421 # Compute Crab unit (this is the factor with which the Prefactor needs
429 422 # to be multiplied to get 1 Crab
... ... @@ -446,12 +439,12 @@ class cssens(ctools.cscript):
446 439 self.log("\n")
447 440  
448 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 449 # Loop until we break
457 450 while True:
... ... @@ -463,13 +456,13 @@ class cssens(ctools.cscript):
463 456 if self.logExplicit():
464 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 461 src_model = full_model.copy()
468 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 464 obs.models(src_model)
471 465  
472   -
473 466 # Simulate events
474 467 sim = obsutils.sim(obs, nbins=self.m_enumbins, seed=iter, \
475 468 binsz=self.m_binsz, npix=self.m_npix, \
... ... @@ -572,48 +565,45 @@ class cssens(ctools.cscript):
572 565 continue
573 566  
574 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 579 # Compute flux correction factor based on average TS
584 580 correct = 1.0
585 581 if ts > 0:
586 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 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 594 # Write background and test source fit results
605 595 if self.logExplicit():
606 596 self.log.parformat("Photon flux")
607   - self.log(pflux)
  597 + self.log(photon_flux)
608 598 self.log(" ph/cm2/s\n")
609 599 self.log.parformat("Energy flux")
610   - self.log(eflux)
  600 + self.log(energy_flux)
611 601 self.log(" erg/cm2/s\n")
612 602 self.log.parformat("Crab flux")
613   - self.log(cflux*1000.0)
  603 + self.log(crab_flux*1000.0)
614 604 self.log(" mCrab\n")
615 605 self.log.parformat("Differential sensitivity")
616   - self.log(diffSens)
  606 + self.log(sensitivity)
617 607 self.log(" erg/cm2/s\n")
618 608 for model in result_all:
619 609 self.log.parformat("Model")
... ... @@ -629,40 +619,40 @@ class cssens(ctools.cscript):
629 619 self.log("corr=")
630 620 self.log(correct)
631 621 self.log(" ")
632   - self.log(pflux)
  622 + self.log(photon_flux)
633 623 self.log(" ph/cm2/s = ")
634   - self.log(eflux)
  624 + self.log(energy_flux)
635 625 self.log(" erg/cm2/s = ")
636   - self.log(cflux*1000.0)
  626 + self.log(crab_flux*1000.0)
637 627 self.log(" mCrab = ")
638   - self.log(diffSens)
  628 + self.log(sensitivity)
639 629 self.log(" erg/cm2/s\n")
640 630  
641 631 # Compute sliding average of extrapolated fitted prefactor,
642 632 # photon and energy flux. This damps out fluctuations and
643 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 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 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 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 652 # Compare average flux to last average
663 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 657 # We have 2 convergence criteria:
668 658 # 1. The average flux does not change
... ... @@ -678,7 +668,7 @@ class cssens(ctools.cscript):
678 668 break
679 669  
680 670 # Use average for next iteration
681   - test_cflux = flux
  671 + test_crab_flux = crab_flux
682 672  
683 673 # Exit loop if number of trials exhausted
684 674 if (iter >= self.m_max_iter):
... ... @@ -693,16 +683,16 @@ class cssens(ctools.cscript):
693 683 self.log(ts)
694 684 self.log("\n")
695 685 self.log.parformat("Photon flux")
696   - self.log(pflux)
  686 + self.log(photon_flux)
697 687 self.log(" ph/cm2/s\n")
698 688 self.log.parformat("Energy flux")
699   - self.log(eflux)
  689 + self.log(energy_flux)
700 690 self.log(" erg/cm2/s\n")
701 691 self.log.parformat("Crab flux")
702   - self.log(cflux*1000.0)
  692 + self.log(crab_flux*1000.0)
703 693 self.log(" mCrab\n")
704 694 self.log.parformat("Differential sensitivity")
705   - self.log(diffSens)
  695 + self.log(sensitivity)
706 696 self.log(" erg/cm2/s\n")
707 697 self.log.parformat("Number of simulated events")
708 698 self.log(nevents)
... ... @@ -736,8 +726,9 @@ class cssens(ctools.cscript):
736 726  
737 727 # Store result
738 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 733 # Return result
743 734 return result
... ...