Commit b621fc01d46c65b11690a49d0767c8a935081683
1 parent
acab87bd
added upper limit computation
Showing
2 changed files
with
54 additions
and
21 deletions
cscripts/csscs.par
| ... | ... | @@ -27,7 +27,7 @@ caldb, s, a, prod2,,, "Calibration database" |
| 27 | 27 | irf, s, a, South_0.5h,,, "Instrument response function" |
| 28 | 28 | inexclusion, f, a, NONE,,, "Exclusion regions TODO: add meaningful default" |
| 29 | 29 | edisp, b, h, no,,, "Apply energy dispersion?" |
| 30 | -outfile, f, a, map.fits,,, "Output map" | |
| 30 | +outfile, f, a, maps.fits,,, "Output maps" | |
| 31 | 31 | |
| 32 | 32 | # |
| 33 | 33 | # Script parameters |
| ... | ... | @@ -56,9 +56,9 @@ etruemin, r, h, 0.01,,, "Minimum true energy (TeV)" |
| 56 | 56 | etruemax, r, h, 300.0,,, "Maximum true energy (TeV)" |
| 57 | 57 | etruebins, i, h, 30,,, "Number of bins per decade for true energy bins" |
| 58 | 58 | calc_ts, b, h, yes,,, "Compute TS value in each bin" |
| 59 | -calc_ulim, b, h, yes,,, "Compute upper limit in each bin" | |
| 60 | -fix_srcs, b, h, yes,,, "Fix other skymodel parameters" | |
| 61 | -fix_bkg, b, h, no,,, "Fix background parameters" | |
| 59 | +calc_ulim, b, h, no,,, "Compute upper limit in each bin" | |
| 60 | +fix_srcs, b, h, yes,,, "Fix other skymodel normalisations" | |
| 61 | +fix_bkg, b, h, no,,, "Fix background normalisation" | |
| 62 | 62 | |
| 63 | 63 | # |
| 64 | 64 | # Standard parameters | ... | ... |
cscripts/csscs.py
| ... | ... | @@ -498,7 +498,7 @@ class csscs(ctools.csobservation): |
| 498 | 498 | result[name] = {'flux' : 0.0, |
| 499 | 499 | 'flux_err': 0.0, |
| 500 | 500 | 'TS' : 0.0, |
| 501 | - 'ulimit' : 0.0} | |
| 501 | + 'ulimit' : -1.0} | |
| 502 | 502 | |
| 503 | 503 | # Mask observations |
| 504 | 504 | self._log_header3(gammalib.EXPLICIT, 'Masking observations') |
| ... | ... | @@ -542,10 +542,12 @@ class csscs(ctools.csobservation): |
| 542 | 542 | # Get flux |
| 543 | 543 | # Integrate spectral model between emin and emax |
| 544 | 544 | flux = source.spectral().flux(emin,emax) |
| 545 | - # Multiply by flux from spatial component in ROI | |
| 546 | - flux *= source.spatial().flux(roi) | |
| 547 | - # Divide by solid angle of ROI | |
| 548 | - flux /= gammalib.twopi * (1 - math.cos(math.radians(self['rad'].real()))) | |
| 545 | + # Calculate correction factor | |
| 546 | + # Spatial model flux over ROI divided by ROI solid angle | |
| 547 | + corr_factor = source.spatial().flux(roi) | |
| 548 | + corr_factor /= gammalib.twopi * (1 - math.cos(math.radians(self['rad'].real()))) | |
| 549 | + # Multiply flux by correction factor | |
| 550 | + flux *= corr_factor | |
| 549 | 551 | result[name]['flux'] = flux |
| 550 | 552 | |
| 551 | 553 | # Get flux error |
| ... | ... | @@ -564,8 +566,35 @@ class csscs(ctools.csobservation): |
| 564 | 566 | if self['calc_ts'].boolean(): |
| 565 | 567 | result[name]['TS'] = source.ts() |
| 566 | 568 | |
| 567 | - # Upper limit | |
| 568 | - # TODO | |
| 569 | + # If requested compute upper flux limit | |
| 570 | + if self['calc_ulim'].boolean(): | |
| 571 | + | |
| 572 | + # Logging information | |
| 573 | + self._log_header3(gammalib.EXPLICIT, | |
| 574 | + 'Computing upper limit for source ' + name) | |
| 575 | + | |
| 576 | + # Create upper limit object | |
| 577 | + ulimit = ctools.ctulimit(like.obs()) | |
| 578 | + ulimit['srcname'] = name | |
| 579 | + ulimit['emin'] = self['emin'].real() | |
| 580 | + ulimit['emax'] = self['emax'].real() | |
| 581 | + | |
| 582 | + # If chatter level is verbose and debugging is requested | |
| 583 | + # then switch also on the debug model in ctulimit | |
| 584 | + if self._logVerbose() and self._logDebug(): | |
| 585 | + ulimit['debug'] = True | |
| 586 | + | |
| 587 | + # Try to run upper limit and catch exceptions | |
| 588 | + try: | |
| 589 | + ulimit.run() | |
| 590 | + ulimit_value = ulimit.flux_ulimit() | |
| 591 | + # Multiply by correction factor to get flux per solid angle in ROI | |
| 592 | + ulimit_value *= corr_factor | |
| 593 | + result[name]['ulimit'] = ulimit_value | |
| 594 | + except: | |
| 595 | + self._log_string(gammalib.EXPLICIT, 'Upper limit ' | |
| 596 | + 'calculation failed.') | |
| 597 | + | |
| 569 | 598 | |
| 570 | 599 | else: |
| 571 | 600 | value = 'Likelihood is zero. Bin is skipped.' |
| ... | ... | @@ -604,24 +633,22 @@ class csscs(ctools.csobservation): |
| 604 | 633 | # Loop over target sources |
| 605 | 634 | for s, name in enumerate(self._srcnames): |
| 606 | 635 | |
| 607 | - # Create minimal set of skymaps to store fluxes and flux errors | |
| 636 | + # Create skymaps to store results | |
| 637 | + # Maps for TS and upper limits created and filled to avoid if statements | |
| 638 | + # Will not be saved in the end if not requested | |
| 608 | 639 | fmap = self._create_map() |
| 609 | 640 | errmap = self._create_map() |
| 610 | - | |
| 611 | - #Create map for TS | |
| 612 | - if self['calc_ts'].boolean(): | |
| 613 | - tsmap = self._create_map() | |
| 641 | + tsmap = self._create_map() | |
| 642 | + ulmap = self._create_map() | |
| 614 | 643 | |
| 615 | 644 | # Loop over pixels and fill maps |
| 616 | 645 | for inx in range(fmap.npix()): |
| 617 | 646 | |
| 618 | - # Fill flux and flux error | |
| 647 | + # Fill maps | |
| 619 | 648 | fmap[inx,0] = results[inx][name]['flux'] |
| 620 | 649 | errmap[inx, 0] = results[inx][name]['flux_error'] |
| 621 | - | |
| 622 | - # If requested fill TS | |
| 623 | - if self['calc_ts'].boolean(): | |
| 624 | - tsmap[inx, 0] = results[inx][name]['TS'] | |
| 650 | + tsmap[inx, 0] = results[inx][name]['TS'] | |
| 651 | + ulmap[inx, 0] = results[inx][name]['ulimit'] | |
| 625 | 652 | |
| 626 | 653 | # Write maps to Fits |
| 627 | 654 | fhdu = fmap.write(fits, name + ' FLUX') |
| ... | ... | @@ -638,6 +665,12 @@ class csscs(ctools.csobservation): |
| 638 | 665 | tshdu = tsmap.write(fits, name + ' TS') |
| 639 | 666 | tshdu.header().append(roiszcard) |
| 640 | 667 | |
| 668 | + # If requested write upper limit map to fits | |
| 669 | + if self['calc_ulim'].boolean(): | |
| 670 | + ulhdu = ulmap.write(fits, name + ' FLUX UPPER LIMIT') | |
| 671 | + ulhdu.header().append(fcard) | |
| 672 | + ulhdu.header().append(roiszcard) | |
| 673 | + | |
| 641 | 674 | # Return |
| 642 | 675 | return fits |
| 643 | 676 | ... | ... |