Commit 56501d1eec6814ec9e4a9bb644d6a534c09981fa
1 parent
e6c90a83
Correct sensitivity computation in cssens and show proper column in show_sensitivity.py.
Showing
3 changed files
with
75 additions
and
75 deletions
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 |