Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
281 commits
Select commit Hold shift + click to select a range
3b81c91
Slightly faster this way
israelmcmc May 3, 2025
6719cb9
Working version. Runs but some results are nan. Still checking.
israelmcmc May 4, 2025
a7b1d4f
Move 3ML plugin in preparation for generic plugin
israelmcmc May 4, 2025
b604db0
Forgot to commit this one on 6719cb9108582880135b7f492029775bee455c75
israelmcmc May 4, 2025
b526255
Finish moving to generic plugin. Work as well as before. Still some n…
israelmcmc May 4, 2025
8229d96
Automatically handle bare background to 3ML Parameter conversion. Fix…
israelmcmc May 4, 2025
627ca84
Fix some issues. Change defaults of free norm parameters. Runs and co…
israelmcmc May 4, 2025
7955cf2
Allows to set full new parameter
israelmcmc May 4, 2025
4eed795
Reproduce the GRB tutorial fit results.
israelmcmc May 4, 2025
db1badf
Change name of normalized bkg distributions
israelmcmc May 4, 2025
c2ed9c6
Take fudge value out of the generic likelihood calculation, and appli…
israelmcmc May 4, 2025
2647602
Rename example. more generic than cosi
israelmcmc May 4, 2025
c43d40d
Cleanup a little. Change bkg default label.
israelmcmc May 4, 2025
4947be0
Rename SpacecraftFile to SpacecraftHistory, since it no longer needs …
israelmcmc May 5, 2025
5bc9423
Move PolarizationASAD to different module to avoid circular import
israelmcmc May 6, 2025
c39d23d
Move RspArfRmfConverter to different module to avoid circular import
israelmcmc May 6, 2025
b9b34f6
Histpy polarization axis (draft)
israelmcmc May 28, 2025
a5b67bf
Generate PSR from a generic BinnedInstrumentResponseInterface.
israelmcmc Jun 3, 2025
87975c8
Small type annotation
israelmcmc Jun 27, 2025
3c0eb88
Axes check
israelmcmc Jun 27, 2025
c7ec659
Remove BinnedThreeMLPointSourceResponseLocal in favor of a general on…
israelmcmc Jun 30, 2025
214f2ae
Change name from model response to model folding.
israelmcmc Jun 30, 2025
860627b
BinnedInstrumentResponse can now handle data in inertial coordinates.
israelmcmc Jul 14, 2025
e4a8d9c
Debugging changes. Still wip.
israelmcmc Jul 15, 2025
9f3ef28
Make copy param optional
israelmcmc Jul 16, 2025
53bf6ad
Fix exception name
israelmcmc Jul 17, 2025
d4b2264
Fix transformation of the orbit location as specified in an .ori file…
israelmcmc Jul 18, 2025
3a0e9ba
Fix bug with gcrs in cartesian
israelmcmc Jul 18, 2025
ac7f843
Rever to being an example of the GRB fit only, and not Crab as well
israelmcmc Jul 18, 2025
00c5c43
Add working example of Crab fit using new interfaces.
israelmcmc Jul 18, 2025
5c1013d
Also move the toy example
israelmcmc Jul 18, 2025
f50f7bf
Pass around the BinnedDataInterface implementation instead of the bar…
israelmcmc Jul 21, 2025
a983e47
Remove the need for a full direction axis for a POINTSourceResponse
israelmcmc Jul 21, 2025
dca817d
Unbinned data interface
israelmcmc Jul 24, 2025
fcdca5f
Machinery for unbinned toy example is now working
israelmcmc Jul 25, 2025
35b52d4
Update dwell time map analysis to new signatures developed for the sc…
israelmcmc Jul 25, 2025
d177485
Use the more general iterables instead of numpy arrays for interfaces
israelmcmc Aug 7, 2025
217979b
Use set_data() instead of expectations(data).
israelmcmc Sep 25, 2025
954bd15
Add tstart/tstop for all data types
israelmcmc Sep 26, 2025
e7a100b
Change meaning of nevents to mean events after selection
israelmcmc Sep 29, 2025
60d9028
Rework unbinned data interfaces
israelmcmc Sep 29, 2025
d18f0d3
Simplify interfaces. Remove set_data and other methods not strictly n…
israelmcmc Oct 1, 2025
ee95e39
Attempt to make crab example reproducible.
israelmcmc Oct 1, 2025
98eeb13
Keep the simplification by removing set_data/response/bkg from likeli…
israelmcmc Oct 1, 2025
edf1157
Improve event selector and event metadata interface
israelmcmc Oct 1, 2025
443571c
work out toy example time selection
israelmcmc Oct 2, 2025
d6d3974
Use main() in toy
israelmcmc Oct 2, 2025
63a948d
Optimize the selection of toy example
israelmcmc Oct 2, 2025
b65695a
Rework of events stream to make it possible to cache and add DC3 data…
israelmcmc Oct 3, 2025
f85069f
Add time selection to crab unbinned example
israelmcmc Oct 3, 2025
ce44166
Merge branch 'refs/heads/develop' into interfaces
israelmcmc Oct 4, 2025
1921e6e
Changes to make interfaces work with latest develop branch
israelmcmc Oct 4, 2025
5facc13
PSR interp trapz wip. Need to fix a few stuff still, but existing exa…
israelmcmc Oct 7, 2025
90c09e1
Handle measurement phase-space
israelmcmc Oct 8, 2025
9ec0c41
unbinned model folding. bkg wip
israelmcmc Oct 8, 2025
dabc8a7
unbinned background. both expectation dentisty and event probability.…
israelmcmc Oct 10, 2025
ba8511e
Fix unbinned toy model and signal-only crab unbinned fit
israelmcmc Oct 17, 2025
080c86e
Fix crab unbinned. 50% error, I think due to inputs
israelmcmc Oct 18, 2025
bacdb91
All interfaces examples working
israelmcmc Oct 18, 2025
306bcf4
clean up toy example a little
israelmcmc Oct 18, 2025
5912a90
change ncounts to expected counts and remote start/stop from expectat…
israelmcmc Oct 19, 2025
2eeba64
fit one full orbit
israelmcmc Oct 20, 2025
1930985
Merge branch 'gti' into gti_interface
hiyoneda Oct 20, 2025
62079b3
Modifed GTI class
hiyoneda Oct 20, 2025
5750ba7
Added EventSelectorGTI
hiyoneda Oct 20, 2025
d3251eb
Add MutliTimeSelector, removed GTISelector
hiyoneda Oct 21, 2025
f64cd6a
Modified GoodTimeInterval
hiyoneda Oct 21, 2025
8716aed
Removed unnecessary functions for GoodTimeIntervals for this PR
hiyoneda Oct 21, 2025
a1b0e8a
Fix issue with sum of expectations densities. Caught by Pascal.
israelmcmc Oct 22, 2025
b68d242
commit
GallegoSav Oct 22, 2025
c9281dc
Update example_crab_fit_threeml_plugin_interfaces.py
GallegoSav Oct 22, 2025
a115f5b
Update example_crab_fit_threeml_plugin_interfaces.py
GallegoSav Oct 22, 2025
063f725
Merge pull request #4 from hiyoneda/gti_interface
israelmcmc Oct 23, 2025
6af64ce
Fix bug preventing arbitrary name for single component bkg
israelmcmc Oct 23, 2025
0be411f
Single or multiple bkg
israelmcmc Oct 23, 2025
c0a3b81
Merge branch 'multiplebck_savitri' into interfaces
israelmcmc Oct 23, 2025
9dfacba
update histpy version to the one with timeaxis
israelmcmc Oct 23, 2025
007eb44
sort -> _sort (GTI)
hiyoneda Oct 24, 2025
4836366
Replace an original TimeSelector with MultiTimeSelector;MultiTimeSele…
hiyoneda Oct 24, 2025
1ed6dca
Fix bug. SkyCoord takes latitude, not colatitude. Found by Pascal.
nlopez-code Oct 24, 2025
5f1892d
Decouple conventions from astropy
israelmcmc Oct 26, 2025
27917c8
doc random event. wip
israelmcmc Oct 26, 2025
e574ad8
Add photons with polarization
israelmcmc Oct 26, 2025
1994b0c
WIP. Most distributions ready for the ideal response.
israelmcmc Oct 26, 2025
be356d1
Revert. The number of detected events is handled the effective area. …
israelmcmc Oct 27, 2025
baf805b
Added the method apply_gti to SpacecraftHistory
hiyoneda Oct 28, 2025
99c230e
Relative coordinates
israelmcmc Oct 28, 2025
a061b98
Faster conversion by avoiding intermediate perpendicular vector step.…
israelmcmc Oct 29, 2025
a5780ff
ideal response random event working!
israelmcmc Oct 29, 2025
09cbaf2
ideal response pdf working!
israelmcmc Oct 30, 2025
b16324f
Polarized and unpolarized version
israelmcmc Oct 31, 2025
fd5495a
Merge pull request #7 from hiyoneda/spacecrafthistory_with_gti
israelmcmc Oct 31, 2025
b44f36b
Revert "Added the method apply_gti to SpacecraftHistory"
israelmcmc Oct 31, 2025
c5d8e82
Merge pull request #8 from israelmcmc/revert-7-spacecrafthistory_with…
israelmcmc Oct 31, 2025
f0e1519
Merge pull request #6 from hiyoneda/gti_interface
israelmcmc Oct 31, 2025
cdee6c4
Added the method apply_gti to SpacecraftHistory
hiyoneda Oct 28, 2025
db9d000
Protect unbinned likelihood from ill defined expectation
israelmcmc Nov 3, 2025
8f4918e
Add missing event type
israelmcmc Nov 3, 2025
5d63189
Working example of ideal irf
israelmcmc Nov 3, 2025
d8f1547
convenience function to get array of all values
israelmcmc Nov 3, 2025
fc913af
Ideal response analysis. All working.
israelmcmc Nov 3, 2025
0dcbddb
Match FWHM 3deg
israelmcmc Nov 4, 2025
15ddd5e
Clean example a little bit
israelmcmc Nov 4, 2025
40d0de0
get nevents
israelmcmc Nov 4, 2025
dce3ee7
Add tests for SCHistory attitude and location interpolation
israelmcmc Jan 14, 2026
907f3ee
Bring back improvements to SpacecraftHistory interpolations (back whe…
israelmcmc Jan 14, 2026
6c7c53e
Merge branch 'develop' into interfaces_dev_merge
israelmcmc Jan 14, 2026
363b256
Make interpolation work with multiple inputs
israelmcmc Jan 14, 2026
317ab82
Make crab binned fit work with latest develop
israelmcmc Jan 26, 2026
225a575
add the threeml extendedsource response interface for using extended …
GallegoSav Jan 28, 2026
87d3286
correct missing line in init
GallegoSav Jan 28, 2026
7e9e987
Merge branch 'develop' into interfaces_devmerge
israelmcmc Jan 28, 2026
4dbfbee
Merge develop nd fix some unit test (not everyone yet)
israelmcmc Jan 30, 2026
e019541
Fix bug from develop-interfaces merge. GCRS only has "distance" in sp…
israelmcmc Feb 2, 2026
f1176f6
Allow to use already cached numpy arrays.
israelmcmc Feb 9, 2026
c77cfe2
TimeTagEmCDSEventDataInSCFrameFromArrays is now initialized from bare…
israelmcmc Feb 10, 2026
35f87e2
Specify if we have a response that can handle direction+energy or onl…
israelmcmc Feb 10, 2026
407d088
Fix some bugs in event selection after latest refactoring.
israelmcmc Feb 11, 2026
c1774bb
Fix bug. Opposite condition.
israelmcmc Feb 11, 2026
59deab9
Add simple ChainEventSelectors
israelmcmc Feb 11, 2026
8bcbcb9
Merge pull request #12 from israelmcmc/interfaces_numpy_iterables
israelmcmc Feb 11, 2026
134467c
Fix test_orthographic_projection_default
israelmcmc Feb 11, 2026
57ee61e
Fix test_stereographic_projection_default
israelmcmc Feb 11, 2026
939daec
Fix type hints and mixins order
israelmcmc Feb 11, 2026
63c0dbb
typos
israelmcmc Feb 11, 2026
100ef08
Fix test_pa_transformation
israelmcmc Feb 11, 2026
a603e39
Fix test_get_point_source_response
israelmcmc Feb 12, 2026
000c123
Polarized response now works for polarization = None (equivalent to P…
israelmcmc Feb 12, 2026
b357d94
Fix test_inject_model (orientation not needed since it's using pre-co…
israelmcmc Feb 12, 2026
5898251
fix test_arf_rmf_converter.py by updating values to those in develop …
israelmcmc Feb 12, 2026
0dfa39c
Fix leftover broken test from handling polarization=None with polariz…
israelmcmc Feb 12, 2026
55a1756
Fix tsmap tests by bring back changes in develop
israelmcmc Feb 12, 2026
7e53743
No need for global variable
israelmcmc Feb 12, 2026
4b4fdb8
Updating test, still failing
israelmcmc Feb 13, 2026
65bb4e1
Move initial guess slightly away from true values
israelmcmc Feb 13, 2026
1302e85
Fix bug. Empty was initializing to random number while the code expec…
israelmcmc Feb 16, 2026
2fb2835
Improve handling of tests variable. Maybe fixing some issues as well.
israelmcmc Feb 16, 2026
872ac30
Temporary workaround for 3ML circular import while waiting for release.
israelmcmc Feb 16, 2026
9a64821
Revert "Temporary workaround for 3ML circular import while waiting fo…
israelmcmc Feb 16, 2026
6ee14e6
Temporary workaround for 3ML circular import while waiting for release.
israelmcmc Feb 16, 2026
94ac356
Merge remote-tracking branch 'fork/pull/9/head' into interfaces_PR9_gti
israelmcmc Feb 16, 2026
4468590
Use the new GTI in unbinned Crab example
israelmcmc Feb 16, 2026
8242728
Add a EmCDSEventDataInSCFrameFromArrays , and make TimeTagEmCDSEventD…
israelmcmc Feb 16, 2026
97a373c
Fix bug. Introduced during EmCDSEventInSCFrame/TimeTagEmCDSEventInSCF…
israelmcmc Feb 17, 2026
43faf53
Merge remote-tracking branch 'fork/savitri_interfaces_extended' into …
israelmcmc Feb 17, 2026
deee9f0
Move setup.py to .toml file. Supports poetry and setuptools.
israelmcmc Feb 18, 2026
4732437
Update python version in unit tests.
israelmcmc Feb 18, 2026
c9a79af
Merge pull request #13 from israelmcmc/interfaces_toml
israelmcmc Feb 18, 2026
96954f5
Add pytorch as optional dependency. Add unit test using it.
israelmcmc Feb 18, 2026
09f6602
Update name of unit_tests_ml.yml
israelmcmc Feb 18, 2026
63347d9
Merge pull request #14 from israelmcmc/interfaces_ml
israelmcmc Feb 18, 2026
70756b2
Modify BinnedExpectationInterfaces
israelmcmc Feb 19, 2026
1ad3aa5
Fix test. Broken in 70756b2a7a3d519b786433280fe5d85e5118756a
israelmcmc Feb 19, 2026
67e48bd
Crab spectral fit tutorial working with new interfaces.
israelmcmc Feb 19, 2026
9ed1a5f
Crab spectral fit tutorial working with new interfaces. Now for real.
israelmcmc Feb 19, 2026
ed651df
Update ASAD method notebook to work with interfaces
eneights Feb 20, 2026
0d52aad
Merge pull request #15 from eneights/interfaces
israelmcmc Feb 20, 2026
e1d3274
* Reintroduce exposure, earth occ, and scatt_map speedups to
Feb 21, 2026
eb67737
add new test data file from develop
Feb 21, 2026
84a5e97
update remaining API usage of get_dwell_map
Feb 21, 2026
fed9271
cleanup imports for XSpec test cases
Feb 21, 2026
a512b95
Make a valiant (but unsuccessful) attempt to recover the
Feb 21, 2026
0ff6a03
record complaints about .altitude and .earth_zenith
Feb 21, 2026
60a6a2f
minor test case cleanups
Feb 21, 2026
3274dfb
* add type annotations to more of SpacecraftHistory
Feb 21, 2026
735f1d5
get_source_visibility() should not need a separate earth_occ parameter.
Feb 21, 2026
2724e79
* work around bug with overwrite processing in Astropy Table FITS I/O
Feb 21, 2026
99b83f8
extended source tutorial update
GallegoSav Feb 23, 2026
5f874cc
update run tutorials
GallegoSav Feb 23, 2026
2f98c24
bring response conversion code up to develop + relative response patch
Feb 23, 2026
18311a1
add actual RspConverter change
Feb 23, 2026
3ce5abd
add test case files for relative response
Feb 23, 2026
e3fc286
add test case from develop for RspConverter norms
Feb 23, 2026
2620fdf
Merge pull request #18 from McKelvey-Engineering-CSE/interfaces-rsp-c…
israelmcmc Feb 23, 2026
d8d5eb9
* use Israel's code to convert more accurately between
Feb 24, 2026
3eaaac4
convert users of .ori files in Python code (note notebook code)
Feb 24, 2026
37f0b6a
Add FITS versions of test case files
Feb 24, 2026
be83dd4
Make sure test case YAML files refer to FITS orientation files
Feb 24, 2026
3ac5e53
Merge branch 'interfaces' into interfaces-sc-fixes
Feb 24, 2026
df90255
Fix bug. This line wasn't updated after the get_basis_local change of…
israelmcmc Feb 24, 2026
6f1af19
* Astropy's coordinate concatenation is deprecated. Use np.concatenate
Feb 24, 2026
de7b690
upgrade the run tutorial
GallegoSav Feb 24, 2026
2d5ec0a
replace fits by ori
GallegoSav Feb 24, 2026
9be6f99
Merge pull request #16 from McKelvey-Engineering-CSE/interfaces-sc-fixes
israelmcmc Feb 24, 2026
5472300
Merge pull request #17 from GallegoSav/interfaces
israelmcmc Feb 24, 2026
ef7708a
Fix error in point source response
eneights Feb 24, 2026
33cfae1
Add MLM notebook
eneights Feb 24, 2026
7076a13
Add MLM unit test
eneights Feb 24, 2026
279e0a2
Add MLM test data
eneights Feb 24, 2026
70cd1bc
Fix polarization handling in 3ML psr
eneights Feb 24, 2026
41dd134
Update for astropy>=7.2.0
israelmcmc Feb 24, 2026
a6d9b1e
* FITS orientation files should store a unit for *every* column, and
Feb 25, 2026
1135ef7
Make sure altitude is saved as a Quantity, not a Distance
Feb 25, 2026
19d492e
add light_curves folder
albiciaco Feb 25, 2026
0e3a835
don't copy data as it is about to be written out to FITS file
Feb 25, 2026
c87273a
remove a couple more copies in open()
Feb 25, 2026
ba0e774
Fix for new version of astropy.
israelmcmc Feb 25, 2026
e962a09
Roll back to .ori. Faster for now since it doesn't load the whole file
israelmcmc Feb 25, 2026
1d13e08
upgrade gal diff continuum tutorial
GallegoSav Feb 26, 2026
98c3e91
blabla
GallegoSav Feb 26, 2026
27ef8b8
Fix polarization handling
eneights Feb 26, 2026
d590775
Fix polarization handling
eneights Feb 26, 2026
97af516
Fix kwargs typing for BackgroundInterface. See PEP 692
israelmcmc Feb 26, 2026
d14e194
Fix ref_vector property. It was causing a RecursionError while callin…
israelmcmc Feb 26, 2026
d6138c4
Merge pull request #19 from McKelvey-Engineering-CSE/interfaces-unitfix
israelmcmc Feb 26, 2026
02f3546
Update to newest threeml release.
israelmcmc Feb 26, 2026
8c2ba42
Merge pull request #21 from israelmcmc/interfaces_update_threeml
israelmcmc Feb 26, 2026
8643225
Save tutorial as python script as well. Convert also to html before e…
israelmcmc Feb 26, 2026
a7df68b
Revert to using TiemAxis.find_bin instead of np.searchsorted (faster)
israelmcmc Feb 26, 2026
9e8b08f
Fix file name
israelmcmc Feb 26, 2026
686659c
update light curve tutorial to interfaces
albiciaco Feb 27, 2026
82de300
Refactor fitting and IO modules to use SpacecraftHistory and update f…
albiciaco Feb 27, 2026
37f1f44
update app tutorial to interfaces
albiciaco Feb 27, 2026
8f6ebe2
Merge 98c3e91c3c640f11597a62462b25ba460e19a83f into 9e8b08f1e84bce1ee…
GallegoSav Feb 27, 2026
6e9bf69
Changes to relative path so it works with run_tutorials.py
israelmcmc Feb 27, 2026
aebc58a
Merge remote-tracking branch 'israel/interfaces' into interfaces
eneights Feb 27, 2026
9ea4a6e
Fix bug
eneights Feb 27, 2026
0a4d43d
Add MLM polarization notebook
eneights Feb 27, 2026
f32e8e1
Update to handle polarization
eneights Feb 27, 2026
be98fd6
Fix unit test
eneights Feb 27, 2026
3820315
Fix typos
eneights Feb 27, 2026
2257a4a
Fix psr test
eneights Feb 27, 2026
8a45d03
Fix bug. Handle case when source is None.
israelmcmc Feb 27, 2026
174d602
PA fix
eneights Feb 27, 2026
89a04be
Fix terrible awful performance bug caused by comparing two
Mar 2, 2026
4a24198
fix the spacecraft tuto
GallegoSav Mar 2, 2026
22c4645
Merge pull request #23 from eneights/interfaces
israelmcmc Mar 2, 2026
f684c95
Merge 37f1f447f2ad7233c9ba94c394c04893d27f1630 into 22c46458701263d0c…
albiciaco Mar 2, 2026
32daca1
Merge branch 'interfaces' into interfaces
israelmcmc Mar 2, 2026
fb09325
Merge 32daca1381feffc841448282e252f635d943af9f into 22c46458701263d0c…
GallegoSav Mar 2, 2026
236caef
Remove get_target_in_sc_frame from tutorial since it was deprecated i…
israelmcmc Mar 2, 2026
be6aa13
Merge pull request #24 from McKelvey-Engineering-CSE/if-interp-fix
israelmcmc Mar 2, 2026
7fbc3cf
Vectorize SumExpectationDensity in expectation_interface
Mar 3, 2026
3f650d3
Update checksum
israelmcmc Mar 3, 2026
b4c5bec
Finished refactoring the SpectralFit_GRB tutorial. Everything seems g…
jbotha-sketch Mar 3, 2026
b09e10a
Add lightcurves tutorial to run_tutorials.yml
israelmcmc Mar 4, 2026
d9f7b02
Merge branch 'interfaces_PR22' into interfaces
israelmcmc Mar 4, 2026
d9c0c21
Merge 7fbc3cf002089cd4795723ff2fd387cb93bef910 into d9f7b020b99d47014…
scipascal Mar 4, 2026
1a150c2
Document new vectorize flag
israelmcmc Mar 4, 2026
37ffc36
Potentially fixed the issue with the last plot. I believe I made some…
jbotha-sketch Mar 4, 2026
70e8358
Renamed SpectralFit_GRB_new.ipynb to SpectralFit_GRB_ipynb and delete…
jbotha-sketch Mar 4, 2026
e4e6dbf
Remove duplicate SpectralFit_GRB_new notebook
jbotha-sketch Mar 4, 2026
20210a4
Merge e4e6dbfd916b5b4f7f4fd87b160ef72c96e9a318 into 1a150c2a8cddf3c94…
jbotha-sketch Mar 4, 2026
dc8cf38
Updated source_injector.py and the Point_source_injector.ipynb tutori…
krishnatejavedula Mar 5, 2026
40e37b9
Merge dc8cf383bb080ef05a993fe12a16070414dd8abb into 1a150c2a8cddf3c94…
krishnatejavedula Mar 5, 2026
3c4cee4
Fix spectral_fit_grb in run_tutorials.yml
israelmcmc Mar 5, 2026
3f11916
Fix bugs in get_source_visibility
israelmcmc Mar 6, 2026
ecb1cb6
Remove also magic lines, not just magic cells
israelmcmc Mar 6, 2026
9ba8855
Merge remote-tracking branch 'fork/pull/29/merge' into interfaces_PR29
israelmcmc Mar 6, 2026
21a35c7
Use earth_occ = True again now that SpacecraftHistory was fixed in 3f…
israelmcmc Mar 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/unit_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.10"]
python-version: ["3.12"]

steps:
- uses: actions/checkout@v4
Expand Down
34 changes: 34 additions & 0 deletions .github/workflows/unit_tests_ml.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: unit_tests_ml

on: [push, pull_request]

jobs:
tests:

runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.12"]

steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Display Python version
run: python -c "import sys; print(sys.version)"
- name: Install
run: |
python -m pip install --upgrade pip
pip install ".[ml]"
- name: Tests
run: |
pip install pytest pytest-cov
pytest tests --junitxml=junit/test-results.xml --cov=cosipy --cov-report=xml --cov-report=html
- name: Codecov
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: true

12 changes: 9 additions & 3 deletions cosipy/__init__.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
from ._version import __version__
try:
from importlib import metadata
__version__ = metadata.version("cosipy")
except metadata.PackageNotFoundError:
# Handle cases where the package is not installed (e.g., running directly from source)
__version__ = "unknown"

from .response import DetectorResponse

from .spacecraftfile import *

from .data_io import DataIO
from .data_io import UnBinnedData
from .data_io import BinnedData
from .data_io import ReadTraTest

from .threeml import COSILike
from .threeml import Band_Eflux

from .spacecraftfile import SpacecraftFile
from .spacecraftfile import SpacecraftHistory

from .ts_map import FastTSMap, MOCTSMap

Expand Down
2 changes: 1 addition & 1 deletion cosipy/background_estimation/ContinuumEstimation.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def calc_psr(self, sc_orientation, detector_response, coord, nside=16):
----------
ori_file : str
Full path to orienation file.
sc_orientation : cosipy.spacecraftfile.SpacecraftFile
sc_orientation : cosipy.spacecraftfile.SpacecraftHistory
Spacecraft orientation object.
detector_response : str
Full path to detector response file.
Expand Down
1 change: 1 addition & 0 deletions cosipy/background_estimation/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
from .LineBackgroundEstimation import LineBackgroundEstimation
from .ContinuumEstimation import ContinuumEstimation
from .free_norm_threeml_binned_bkg import *
303 changes: 303 additions & 0 deletions cosipy/background_estimation/free_norm_threeml_binned_bkg.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,303 @@
import itertools
from typing import Dict, Tuple, Union, Any, Type, Optional, Iterable

import numpy as np
from astromodels import Parameter
from astropy.coordinates import SkyCoord, CartesianRepresentation, UnitSphericalRepresentation
from astropy.time import Time
from histpy import Histogram
from histpy import Axes

from astropy import units as u
from scoords import SpacecraftFrame

from cosipy import SpacecraftHistory
from cosipy.data_io.EmCDSUnbinnedData import TimeTagEmCDSEventInSCFrame
from cosipy.interfaces import BinnedBackgroundInterface, BinnedDataInterface, DataInterface, BackgroundDensityInterface, \
BackgroundInterface, EventInterface

__all__ = ["FreeNormBinnedBackground"]

from cosipy.interfaces.data_interface import TimeTagEmCDSEventDataInSCFrameInterface

from cosipy.interfaces.event import TimeTagEmCDSEventInSCFrameInterface
from cosipy.util.iterables import itertools_batched

class FreeNormBackground(BackgroundInterface):
"""
This must translate to/from regular parameters
with arbitrary type from/to 3ML parameters

Default to "bkg_norm" is there was a single unlabeled component
"""

_default_label = 'bkg_norm'

def __init__(self,
distribution:Union[Histogram, Dict[str, Histogram]],
sc_history:SpacecraftHistory,
copy = True):
"""

Parameters
----------
distribution
sc_history
copy: copy hist distribution
"""

if isinstance(distribution, Histogram):
# Single component
self._distributions = {self._default_label: distribution}
self._norms = np.ones(1) # Hz. Each component
self._norm = 1 # Hz. Total
self._single_component = True
else:
# Multiple label components.
self._distributions = distribution
self._norms = np.ones(self.ncomponents) # Hz Each component
self._norm = np.sum(self._norms) # Hz. Total
self._single_component = False

self._labels = tuple(self._distributions.keys())

# Normalize
# Unit: second
self._livetime = sc_history.cumulative_livetime().to_value(u.s)
for label,dist in self._distributions.items():
dist_norm = np.sum(dist)
if copy:
self._distributions[label] = dist/dist_norm
else:
dist /= dist_norm

# These will be densify anyway since _expectation is dense
# And histpy doesn't yet handle this operation efficiently
# See Histogram._inplace_operation_handle_sparse()
# Do it once and for all
for label, bkg in self._distributions.items():
if bkg.is_sparse:
self._distributions[label] = bkg.to_dense()

if self.ncomponents == 0:
raise ValueError("You need to input at least one components")

self._axes = None
for bkg in self._distributions.values():
if self._axes is None:
self._axes = bkg.axes
else:
if self._axes != bkg.axes:
raise ValueError("All background components mus have the same axes")

@property
def norm(self):
"""
Sum of all rates
"""

return u.Quantity(self._norm, u.Hz)

@property
def norms(self):
if self._single_component:
return {self._default_label: u.Quantity(self._norms[0], u.Hz)}
else:
return {l:u.Quantity(n, u.Hz, copy = None) for l,n in zip(self.labels,self._norms)}

@property
def ncomponents(self):
return len(self._distributions)

@property
def axes(self):
return self._axes

@property
def labels(self):
return self._labels

def set_norm(self, norm: Union[u.Quantity, Dict[str, u.Quantity]]):

if self._single_component:
if isinstance(norm, dict):
self._norms[0] = norm[self._default_label].to_value(u.Hz)
else:
self._norms[0] = norm.to_value(u.Hz)
else:
# Multiple
if not isinstance(norm, dict):
raise TypeError("This a multi-component background. Provide labeled norm values in a dictionary")

for label,norm_i in norm.items():
if label not in self.labels:
raise ValueError(f"Norm {label} not in {self.labels}")

self._norms[self.labels.index(label)] = norm_i.to_value(u.Hz)

self._norm = sum(n for n in self._norms)

def set_parameters(self, **parameters:u.Quantity) -> None:
"""
Same keys as background components
"""

self.set_norm(parameters)

@property
def parameters(self) -> Dict[str, u.Quantity]:
return self.norms

class FreeNormBinnedBackground(FreeNormBackground, BinnedBackgroundInterface):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

# Cache
self._expectation = None
self._last_norm_values = None

def expectation(self, copy:bool = True)->Histogram:
"""

Parameters
----------
copy:
If True, it will return an array that the user if free to modify.
Otherwise, it will result a reference, possible to the cache, that
the user should not modify

Returns
-------

"""

# Check if we can use the cache
if self._expectation is None:
# First call. Initialize
self._expectation = Histogram(self.axes)

elif self.norms == self._last_norm_values:
# No changes. Use cache
if copy:
return self._expectation.copy()
else:
return self._expectation

else:
# First call or norms have change. Recalculate
self._expectation.clear()

# Compute expectation
for label,bkg in self._distributions.items():
norm = self._norms[self.labels.index(label)]
self._expectation += bkg * norm * self._livetime

# Cache. Regular copy is enough since norm values are float en not mutable
self._last_norm_values = self.norms.copy()

if copy:
return self._expectation.copy()
else:
return self._expectation


class FreeNormBackgroundInterpolatedDensityTimeTagEmCDS(FreeNormBackground, BackgroundDensityInterface):

@property
def event_type(self) -> Type[EventInterface]:
return TimeTagEmCDSEventInSCFrameInterface

def __init__(self,
data:TimeTagEmCDSEventDataInSCFrameInterface,
distribution:Union[Histogram, Dict[str, Histogram]],
sc_history:SpacecraftHistory,
copy=True,
batch_size = 100000,
*args,
**kwargs):

super().__init__(distribution, sc_history,
copy=copy, *args, **kwargs)

# We need the density per phase space for the specific measurement units TimeTagEmCDSEventInSCFrameInterface
# Energy: keV
# Phi: rad
# PsiChi: sr (for the phase space. The axis is a HealpixAxis)
# Time: seconds (taken into account by the norm (a rate) unit)

psichi_frame = None

for label,dist in self._distributions.items():

dist = self._distributions[label] = dist.project('Em', 'Phi', 'PsiChi')

dist.axes['Em'] = dist.axes['Em'].to(u.keV).to(None, copy=False, update=False)
dist.axes['Phi'] = dist.axes['Phi'].to(u.rad).to(None, copy=False, update=False)

energy_phase_space = dist.axes['Em'].widths
phi_phase_space = dist.axes['Phi'].widths
psichi_phase_space = dist.axes['PsiChi'].pixarea().to_value(u.sr)

if psichi_frame is None:
psichi_frame = dist.axes['PsiChi'].coordsys
else:
if psichi_frame != dist.axes['PsiChi'].coordsys:
raise ValueError("All PsiChi axes must be in the same frame")

dist /= dist.axes.expand_dims(energy_phase_space, 'Em')
dist /= dist.axes.expand_dims(phi_phase_space, 'Phi')
dist /= psichi_phase_space

# Compute the probabilities once and for all
# TODO: account for livetime
self._prob = [[] for _ in range(self.ncomponents)]

for events_chunk in itertools_batched(data, batch_size):

jd1, jd2, energy,phi, psichi_lon, psichi_lat = np.asarray([[
event.jd1,
event.jd2,
event.energy_keV,
event.scattering_angle_rad,
event.scattered_lon_rad_sc,
event.scattered_lat_rad_sc]
for event in events_chunk], dtype=float).transpose()

times = Time(jd1, jd2, format = 'jd')

# Transform local to inertial
sc_psichi_coord = SkyCoord(psichi_lon, psichi_lat, unit=u.rad, frame=SpacecraftFrame())
sc_psichi_vec = sc_psichi_coord.cartesian.xyz.value
attitudes = sc_history.interp_attitude(times).transform_to(psichi_frame)
inertial_psichi_vec = attitudes.rot.apply(sc_psichi_vec.transpose())
inertial_psichi_sph = UnitSphericalRepresentation.from_cartesian(CartesianRepresentation(*inertial_psichi_vec.transpose()))
inertial_psichi_coord = SkyCoord(inertial_psichi_sph, frame = psichi_frame)

for label,dist in self._distributions.items():
prob = dist.interp(energy, phi, inertial_psichi_coord)
self._prob[self.labels.index(label)].extend(prob)

self._prob = np.asarray(self._prob)

def expected_counts(self) -> float:
"""
Total expected counts
"""
return self._livetime * self._norm

def expectation_density(self) -> Iterable[float]:
"""
Return the expected number of counts density from the start-th event
to the stop-th event. This equals the event probabiliy times the number of events
"""

# Multiply each probability by the norm, and then sum
return np.tensordot(self._prob, self._norms, axes = (0,0))







Loading