Skip to content

Commit

Permalink
Added get_point_source_response_per_image_pixel and merge_psr_to_exte…
Browse files Browse the repository at this point in the history
…nded_source_response. Modified get_extended_source_response in FullDetectorResponse
  • Loading branch information
hiyoneda committed Jan 23, 2025
1 parent 6ff1ef8 commit 7a73ac8
Showing 1 changed file with 142 additions and 29 deletions.
171 changes: 142 additions & 29 deletions cosipy/response/FullDetectorResponse.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import numpy as np
import mhealpy as hp
from mhealpy import HealpixBase, HealpixMap
import glob

from scipy.special import erf

Expand Down Expand Up @@ -916,61 +917,173 @@ def get_point_source_response(self,
else:
return psr

def get_extended_source_response(self, orientation, coordsys = 'galactic', nside_model = None, nside_scatt_map = None, Earth_occ = True):
def _setup_extended_source_response_params(self, coordsys, nside_image, nside_scatt_map):
"""
Convolve the all-sky detector response with exposure over the sky
sky location.
Validate coordinate system and setup NSIDE parameters for extended source response generation.
Provide a spacecraft attitude map.
Parameters
----------
coordsys : str
Coordinate system to be used (currently only 'galactic' is supported)
nside_image : int or None
NSIDE parameter for the image reconstruction.
If None, uses the full detector response's NSIDE.
nside_scatt_map : int or None
NSIDE parameter for scatt map generation.
If None, uses the full detector response's NSIDE.
Returns
-------
tuple
(coordsys, nside_image, nside_scatt_map) : validated parameters
"""
if coordsys != 'galactic':
raise ValueError(f'The coordsys {coordsys} not currently supported')

Check warning on line 941 in cosipy/response/FullDetectorResponse.py

View check run for this annotation

Codecov / codecov/patch

cosipy/response/FullDetectorResponse.py#L940-L941

Added lines #L940 - L941 were not covered by tests

if nside_image is None:
nside_image = self.nside

Check warning on line 944 in cosipy/response/FullDetectorResponse.py

View check run for this annotation

Codecov / codecov/patch

cosipy/response/FullDetectorResponse.py#L943-L944

Added lines #L943 - L944 were not covered by tests

if nside_scatt_map is None:
nside_scatt_map = self.nside

Check warning on line 947 in cosipy/response/FullDetectorResponse.py

View check run for this annotation

Codecov / codecov/patch

cosipy/response/FullDetectorResponse.py#L946-L947

Added lines #L946 - L947 were not covered by tests

return coordsys, nside_image, nside_scatt_map

Check warning on line 949 in cosipy/response/FullDetectorResponse.py

View check run for this annotation

Codecov / codecov/patch

cosipy/response/FullDetectorResponse.py#L949

Added line #L949 was not covered by tests

def get_point_source_response_per_image_pixel(self, ipix_image, orientation, coordsys = 'galactic', nside_image = None, nside_scatt_map = None, Earth_occ = True):
"""
Generate point source response for a specific HEALPix pixel by convolving
the all-sky detector response with exposure.
Parameters
----------
ipix_image : int
HEALPix pixel index
orientation : cosipy.spacecraftfile.SpacecraftFile
Spacecraft attitude information
coordsys : str, default 'galactic'
Currently, only 'galactic' is supported.
nside_model: int, default None
NSIDE of the image to be reconstructed.
If it is None, NSIDE of the full detector response will be used.
nside_scatt_map: int, default None
NSIDE to be used when generating the scatt maps.
If it is None, NSIDE of the full detector response will be used.
Coordinate system (currently only 'galactic' is supported)
nside_image : int, optional
NSIDE parameter for image reconstruction.
If None, uses the detector response's NSIDE.
nside_scatt_map : int, optional
NSIDE parameter for scatt map generation.
If None, uses the detector response's NSIDE.
Earth_occ : bool, default True
Option to include Earth occultation in the respeonce.
Whether to include Earth occultation in the response
Returns
-------
:py:class:`ExtendedSourceResponse`
:py:class:`PointSourceResponse`
Point source response for the specified pixel
"""
coordsys, nside_image, nside_scatt_map = self._setup_extended_source_response_params(coordsys, nside_image, nside_scatt_map)

Check warning on line 978 in cosipy/response/FullDetectorResponse.py

View check run for this annotation

Codecov / codecov/patch

cosipy/response/FullDetectorResponse.py#L978

Added line #L978 was not covered by tests

if coordsys != 'galactic':
raise ValueError(f'The coordsys {coordsys} not currently supported')
image_axes = HealpixAxis(nside = nside_image, coordsys = coordsys, scheme='ring', label = 'NuLambda') # The label should be 'lb' in the future

Check warning on line 980 in cosipy/response/FullDetectorResponse.py

View check run for this annotation

Codecov / codecov/patch

cosipy/response/FullDetectorResponse.py#L980

Added line #L980 was not covered by tests

if nside_model is None:
nside_model = self.nside
coord = image_axes.pix2skycoord(ipix_image)

Check warning on line 982 in cosipy/response/FullDetectorResponse.py

View check run for this annotation

Codecov / codecov/patch

cosipy/response/FullDetectorResponse.py#L982

Added line #L982 was not covered by tests

if nside_scatt_map is None:
nside_scatt_map = self.nside
scatt_map = orientation.get_scatt_map(target_coord = coord,

Check warning on line 984 in cosipy/response/FullDetectorResponse.py

View check run for this annotation

Codecov / codecov/patch

cosipy/response/FullDetectorResponse.py#L984

Added line #L984 was not covered by tests
nside = nside_scatt_map,
scheme='ring',
coordsys=coordsys,
earth_occ=Earth_occ)

psr = self.get_point_source_response(coord = coord, scatt_map = scatt_map, Earth_occ = Earth_occ)

Check warning on line 990 in cosipy/response/FullDetectorResponse.py

View check run for this annotation

Codecov / codecov/patch

cosipy/response/FullDetectorResponse.py#L990

Added line #L990 was not covered by tests

axes = [HealpixAxis(nside = nside_model, coordsys = coordsys, scheme='ring', label = 'NuLambda')] # The label should be 'lb' in the future
return psr

Check warning on line 992 in cosipy/response/FullDetectorResponse.py

View check run for this annotation

Codecov / codecov/patch

cosipy/response/FullDetectorResponse.py#L992

Added line #L992 was not covered by tests

def get_extended_source_response(self, orientation, coordsys = 'galactic', nside_image = None, nside_scatt_map = None, Earth_occ = True):
"""
Generate extended source response by convolving the all-sky detector
response with exposure over the entire sky.
Parameters
----------
orientation : cosipy.spacecraftfile.SpacecraftFile
Spacecraft attitude information
coordsys : str, default 'galactic'
Coordinate system (currently only 'galactic' is supported)
nside_image : int, optional
NSIDE parameter for image reconstruction.
If None, uses the detector response's NSIDE.
nside_scatt_map : int, optional
NSIDE parameter for scatt map generation.
If None, uses the detector response's NSIDE.
Earth_occ : bool, default True
Whether to include Earth occultation in the response
Returns
-------
:py:class:`ExtendedSourceResponse`
Extended source response covering the entire sky
"""
coordsys, nside_image, nside_scatt_map = self._setup_extended_source_response_params(coordsys, nside_image, nside_scatt_map)

Check warning on line 1019 in cosipy/response/FullDetectorResponse.py

View check run for this annotation

Codecov / codecov/patch

cosipy/response/FullDetectorResponse.py#L1019

Added line #L1019 was not covered by tests

axes = [HealpixAxis(nside = nside_image, coordsys = coordsys, scheme='ring', label = 'NuLambda')] # The label should be 'lb' in the future
axes += list(self.axes[1:])
axes[-1].coordsys = coordsys

Check warning on line 1023 in cosipy/response/FullDetectorResponse.py

View check run for this annotation

Codecov / codecov/patch

cosipy/response/FullDetectorResponse.py#L1021-L1023

Added lines #L1021 - L1023 were not covered by tests

extended_source_response = ExtendedSourceResponse(axes, unit = u.Unit("cm2 s"))

Check warning on line 1025 in cosipy/response/FullDetectorResponse.py

View check run for this annotation

Codecov / codecov/patch

cosipy/response/FullDetectorResponse.py#L1025

Added line #L1025 was not covered by tests

for ipix in tqdm(range(hp.nside2npix(nside_model))):
for ipix in tqdm(range(hp.nside2npix(nside_image))):

Check warning on line 1027 in cosipy/response/FullDetectorResponse.py

View check run for this annotation

Codecov / codecov/patch

cosipy/response/FullDetectorResponse.py#L1027

Added line #L1027 was not covered by tests

coord = extended_source_response.axes[0].pix2skycoord(ipix)
psr = self.get_point_source_response_per_image_pixel(ipix, orientation, coordsys = coordsys,

Check warning on line 1029 in cosipy/response/FullDetectorResponse.py

View check run for this annotation

Codecov / codecov/patch

cosipy/response/FullDetectorResponse.py#L1029

Added line #L1029 was not covered by tests
nside_image = nside_image, nside_scatt_map = nside_scatt_map, Earth_occ = Earth_occ)

scatt_map = orientation.get_scatt_map(target_coord = coord,
nside = nside_scatt_map,
scheme='ring',
coordsys=coordsys,
earth_occ=Earth_occ)
extended_source_response[ipix] = psr.contents

Check warning on line 1032 in cosipy/response/FullDetectorResponse.py

View check run for this annotation

Codecov / codecov/patch

cosipy/response/FullDetectorResponse.py#L1032

Added line #L1032 was not covered by tests

psr = self.get_point_source_response(coord = coord, scatt_map = scatt_map, Earth_occ = Earth_occ)
return extended_source_response

Check warning on line 1034 in cosipy/response/FullDetectorResponse.py

View check run for this annotation

Codecov / codecov/patch

cosipy/response/FullDetectorResponse.py#L1034

Added line #L1034 was not covered by tests

def merge_psr_to_extended_source_response(self, basename, coordsys = 'galactic', nside_image = None):
"""
Create extended source response by merging multiple point source responses.
Reads point source response files matching the pattern `basename` + index + file_extension.
For example, with basename='histograms/hist_', filenames are expected to be like 'histograms/hist_00001.hdf5'.
Parameters
----------
basename : str
Base filename pattern for point source response files
coordsys : str, default 'galactic'
Coordinate system (currently only 'galactic' is supported)
nside_image : int, optional
NSIDE parameter for image reconstruction.
If None, uses the detector response's NSIDE.
Returns
-------
:py:class:`ExtendedSourceResponse`
Combined extended source response
"""
coordsys, nside_image, _ = self._setup_extended_source_response_params(coordsys, nside_image, None)

Check warning on line 1058 in cosipy/response/FullDetectorResponse.py

View check run for this annotation

Codecov / codecov/patch

cosipy/response/FullDetectorResponse.py#L1058

Added line #L1058 was not covered by tests

psr_files = glob.glob(basename + "*")

Check warning on line 1060 in cosipy/response/FullDetectorResponse.py

View check run for this annotation

Codecov / codecov/patch

cosipy/response/FullDetectorResponse.py#L1060

Added line #L1060 was not covered by tests

if not psr_files:
raise FileNotFoundError(f"No files found matching pattern {basename}*")

Check warning on line 1063 in cosipy/response/FullDetectorResponse.py

View check run for this annotation

Codecov / codecov/patch

cosipy/response/FullDetectorResponse.py#L1062-L1063

Added lines #L1062 - L1063 were not covered by tests

axes = [HealpixAxis(nside = nside_image, coordsys = coordsys, scheme='ring', label = 'NuLambda')] # The label should be 'lb' in the future
axes += list(self.axes[1:])
axes[-1].coordsys = coordsys

Check warning on line 1067 in cosipy/response/FullDetectorResponse.py

View check run for this annotation

Codecov / codecov/patch

cosipy/response/FullDetectorResponse.py#L1065-L1067

Added lines #L1065 - L1067 were not covered by tests

extended_source_response = ExtendedSourceResponse(axes, unit = u.Unit("cm2 s"))

Check warning on line 1069 in cosipy/response/FullDetectorResponse.py

View check run for this annotation

Codecov / codecov/patch

cosipy/response/FullDetectorResponse.py#L1069

Added line #L1069 was not covered by tests

filled_pixels = []

Check warning on line 1071 in cosipy/response/FullDetectorResponse.py

View check run for this annotation

Codecov / codecov/patch

cosipy/response/FullDetectorResponse.py#L1071

Added line #L1071 was not covered by tests

for filename in psr_files:

Check warning on line 1073 in cosipy/response/FullDetectorResponse.py

View check run for this annotation

Codecov / codecov/patch

cosipy/response/FullDetectorResponse.py#L1073

Added line #L1073 was not covered by tests

ipix = int(filename[len(basename):].split(".")[0])

Check warning on line 1075 in cosipy/response/FullDetectorResponse.py

View check run for this annotation

Codecov / codecov/patch

cosipy/response/FullDetectorResponse.py#L1075

Added line #L1075 was not covered by tests

psr = Histogram.open(filename)

Check warning on line 1077 in cosipy/response/FullDetectorResponse.py

View check run for this annotation

Codecov / codecov/patch

cosipy/response/FullDetectorResponse.py#L1077

Added line #L1077 was not covered by tests

extended_source_response[ipix] = psr.contents

Check warning on line 1079 in cosipy/response/FullDetectorResponse.py

View check run for this annotation

Codecov / codecov/patch

cosipy/response/FullDetectorResponse.py#L1079

Added line #L1079 was not covered by tests

filled_pixels.append(ipix)

Check warning on line 1081 in cosipy/response/FullDetectorResponse.py

View check run for this annotation

Codecov / codecov/patch

cosipy/response/FullDetectorResponse.py#L1081

Added line #L1081 was not covered by tests

expected_pixels = set(range(extended_source_response.axes[0].npix))
if set(filled_pixels) != expected_pixels:
raise ValueError(f"Missing pixels in the response files. Expected {extended_source_response.axes[0].npix} pixels, got {len(filled_pixels)} pixels")

Check warning on line 1085 in cosipy/response/FullDetectorResponse.py

View check run for this annotation

Codecov / codecov/patch

cosipy/response/FullDetectorResponse.py#L1083-L1085

Added lines #L1083 - L1085 were not covered by tests

return extended_source_response

Check warning on line 1087 in cosipy/response/FullDetectorResponse.py

View check run for this annotation

Codecov / codecov/patch

cosipy/response/FullDetectorResponse.py#L1087

Added line #L1087 was not covered by tests

@staticmethod
Expand Down

0 comments on commit 7a73ac8

Please sign in to comment.