icecube-skyreader 1.3.2__tar.gz → 1.3.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {icecube-skyreader-1.3.2 → icecube-skyreader-1.3.3}/PKG-INFO +1 -1
- {icecube-skyreader-1.3.2 → icecube-skyreader-1.3.3}/icecube_skyreader.egg-info/PKG-INFO +1 -1
- {icecube-skyreader-1.3.2 → icecube-skyreader-1.3.3}/skyreader/__init__.py +1 -1
- {icecube-skyreader-1.3.2 → icecube-skyreader-1.3.3}/skyreader/plot/plot.py +28 -153
- {icecube-skyreader-1.3.2 → icecube-skyreader-1.3.3}/skyreader/plot/plotting_tools.py +5 -1
- {icecube-skyreader-1.3.2 → icecube-skyreader-1.3.3}/skyreader/utils/handle_map_data.py +10 -6
- {icecube-skyreader-1.3.2 → icecube-skyreader-1.3.3}/LICENSE +0 -0
- {icecube-skyreader-1.3.2 → icecube-skyreader-1.3.3}/README.md +0 -0
- {icecube-skyreader-1.3.2 → icecube-skyreader-1.3.3}/icecube_skyreader.egg-info/SOURCES.txt +0 -0
- {icecube-skyreader-1.3.2 → icecube-skyreader-1.3.3}/icecube_skyreader.egg-info/dependency_links.txt +0 -0
- {icecube-skyreader-1.3.2 → icecube-skyreader-1.3.3}/icecube_skyreader.egg-info/requires.txt +0 -0
- {icecube-skyreader-1.3.2 → icecube-skyreader-1.3.3}/icecube_skyreader.egg-info/top_level.txt +0 -0
- {icecube-skyreader-1.3.2 → icecube-skyreader-1.3.3}/setup.cfg +0 -0
- {icecube-skyreader-1.3.2 → icecube-skyreader-1.3.3}/setup.py +0 -0
- {icecube-skyreader-1.3.2 → icecube-skyreader-1.3.3}/skyreader/event_metadata.py +0 -0
- {icecube-skyreader-1.3.2 → icecube-skyreader-1.3.3}/skyreader/plot/__init__.py +0 -0
- {icecube-skyreader-1.3.2 → icecube-skyreader-1.3.3}/skyreader/py.typed +0 -0
- {icecube-skyreader-1.3.2 → icecube-skyreader-1.3.3}/skyreader/result.py +0 -0
- {icecube-skyreader-1.3.2 → icecube-skyreader-1.3.3}/skyreader/utils/__init__.py +0 -0
- {icecube-skyreader-1.3.2 → icecube-skyreader-1.3.3}/skyreader/utils/areas.py +0 -0
|
@@ -17,7 +17,7 @@ __all__ = [
|
|
|
17
17
|
# is zero for an official release, positive for a development branch,
|
|
18
18
|
# or negative for a release candidate or beta (after the base version
|
|
19
19
|
# number has been incremented)
|
|
20
|
-
__version__ = "1.3.
|
|
20
|
+
__version__ = "1.3.3"
|
|
21
21
|
version_info = (
|
|
22
22
|
int(__version__.split(".")[0]),
|
|
23
23
|
int(__version__.split(".")[1]),
|
|
@@ -21,7 +21,6 @@ from matplotlib.projections import projection_registry # type: ignore[import]
|
|
|
21
21
|
|
|
22
22
|
from .plotting_tools import (
|
|
23
23
|
AstroMollweideAxes,
|
|
24
|
-
DecFormatter,
|
|
25
24
|
format_fits_header,
|
|
26
25
|
hp_ticklabels,
|
|
27
26
|
plot_catalog
|
|
@@ -42,7 +41,7 @@ LOGGER = logging.getLogger("skyreader.plot")
|
|
|
42
41
|
class SkyScanPlotter:
|
|
43
42
|
PLOT_SIZE_Y_IN: float = 3.85
|
|
44
43
|
PLOT_SIZE_X_IN: float = 6
|
|
45
|
-
PLOT_DPI_STANDARD =
|
|
44
|
+
PLOT_DPI_STANDARD = 300
|
|
46
45
|
PLOT_DPI_ZOOMED = 1200
|
|
47
46
|
PLOT_COLORMAP = matplotlib.colormaps['plasma_r']
|
|
48
47
|
|
|
@@ -55,7 +54,6 @@ class SkyScanPlotter:
|
|
|
55
54
|
def create_plot(
|
|
56
55
|
self,
|
|
57
56
|
result: SkyScanResult,
|
|
58
|
-
dozoom: bool = False,
|
|
59
57
|
systematics: bool = False,
|
|
60
58
|
llh_map: bool = True,
|
|
61
59
|
angular_error_floor: Union[None, float] = None,
|
|
@@ -65,7 +63,7 @@ class SkyScanPlotter:
|
|
|
65
63
|
PLOT_DPI_STANDARD and PLOT_DPI_ZOOMED. Zoomed mode is very inefficient
|
|
66
64
|
as the meshgrid is created for the full sky.
|
|
67
65
|
"""
|
|
68
|
-
dpi = self.PLOT_DPI_STANDARD
|
|
66
|
+
dpi = self.PLOT_DPI_STANDARD
|
|
69
67
|
|
|
70
68
|
# number of grid points along RA coordinate
|
|
71
69
|
xsize = int(self.PLOT_SIZE_X_IN * dpi)
|
|
@@ -90,11 +88,7 @@ class SkyScanPlotter:
|
|
|
90
88
|
mjd_str = f"MJD: {event_metadata.mjd}"
|
|
91
89
|
plot_title = f"{run_str} {evt_str} {typ_str} {mjd_str}"
|
|
92
90
|
|
|
93
|
-
|
|
94
|
-
addition_to_filename = 'plot_zoomed_legacy.'
|
|
95
|
-
else:
|
|
96
|
-
addition_to_filename = ''
|
|
97
|
-
plot_filename = f"{unique_id}.{addition_to_filename}pdf"
|
|
91
|
+
plot_filename = f"{unique_id}.pdf"
|
|
98
92
|
LOGGER.info(f"saving plot to {plot_filename}")
|
|
99
93
|
|
|
100
94
|
grid_value, grid_ra, grid_dec, equatorial_map, _ = extract_map(
|
|
@@ -107,8 +101,6 @@ class SkyScanPlotter:
|
|
|
107
101
|
grid_pix = healpy.ang2pix(max(nsides), np.pi/2. - DEC, RA)
|
|
108
102
|
plotting_map = equatorial_map[grid_pix]
|
|
109
103
|
|
|
110
|
-
min_value = grid_value[0] # for probability map, this is actually
|
|
111
|
-
# the max_value
|
|
112
104
|
min_dec = grid_dec[0]
|
|
113
105
|
min_ra = grid_ra[0]
|
|
114
106
|
|
|
@@ -118,12 +110,6 @@ class SkyScanPlotter:
|
|
|
118
110
|
LOGGER.info(f"min Dec: {min_dec * 180./np.pi} deg")
|
|
119
111
|
|
|
120
112
|
# renormalize
|
|
121
|
-
if dozoom:
|
|
122
|
-
plotting_map = plotting_map - min_value
|
|
123
|
-
equatorial_map = equatorial_map - min_value
|
|
124
|
-
vmin = 0.
|
|
125
|
-
vmax = 50
|
|
126
|
-
map_to_plot = plotting_map
|
|
127
113
|
if llh_map:
|
|
128
114
|
cmap = self.PLOT_COLORMAP
|
|
129
115
|
text_colorbar = r"$-2 \ln(L)$"
|
|
@@ -162,11 +148,8 @@ class SkyScanPlotter:
|
|
|
162
148
|
|
|
163
149
|
ax = None
|
|
164
150
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
else:
|
|
168
|
-
cmap.set_over(alpha=0.) # make underflows transparent
|
|
169
|
-
ax = fig.add_subplot(111, projection='astro mollweide')
|
|
151
|
+
cmap.set_over(alpha=0.) # make underflows transparent
|
|
152
|
+
ax = fig.add_subplot(111, projection='astro mollweide')
|
|
170
153
|
|
|
171
154
|
# rasterized makes the map bitmap while the labels remain vectorial
|
|
172
155
|
# flip longitude to the astro convention
|
|
@@ -185,124 +168,26 @@ class SkyScanPlotter:
|
|
|
185
168
|
contour_levels, contour_labels, contour_colors
|
|
186
169
|
) = get_contour_levels(equatorial_map, llh_map, systematics)
|
|
187
170
|
|
|
188
|
-
leg_element = []
|
|
189
|
-
cs_collections = []
|
|
190
171
|
for level, color in zip(contour_levels, contour_colors):
|
|
191
172
|
if not llh_map:
|
|
192
173
|
level = np.log10(level)
|
|
193
|
-
|
|
174
|
+
ax.contour(
|
|
194
175
|
ra, dec, map_to_plot, levels=[level], colors=[color]
|
|
195
176
|
)
|
|
196
|
-
cs_collections.append(contour_set.collections[0])
|
|
197
|
-
e, _ = contour_set.legend_elements()
|
|
198
|
-
leg_element.append(e[0])
|
|
199
|
-
|
|
200
|
-
if not dozoom:
|
|
201
|
-
# graticule
|
|
202
|
-
if isinstance(ax, AstroMollweideAxes):
|
|
203
|
-
# mypy guard
|
|
204
|
-
ax.set_longitude_grid(30)
|
|
205
|
-
ax.set_latitude_grid(30)
|
|
206
|
-
cb = fig.colorbar(
|
|
207
|
-
image,
|
|
208
|
-
orientation='horizontal',
|
|
209
|
-
shrink=.6,
|
|
210
|
-
pad=0.05,
|
|
211
|
-
ticks=[vmin, vmax],
|
|
212
|
-
)
|
|
213
|
-
cb.ax.xaxis.set_label_text(text_colorbar)
|
|
214
|
-
else:
|
|
215
|
-
ax.set_xlabel('right ascension')
|
|
216
|
-
ax.set_ylabel('declination')
|
|
217
|
-
cb = fig.colorbar(
|
|
218
|
-
image, orientation='horizontal', shrink=.6, pad=0.13
|
|
219
|
-
)
|
|
220
|
-
cb.ax.xaxis.set_label_text(r"$-2 \Delta \ln (L)$")
|
|
221
|
-
|
|
222
|
-
leg_labels = []
|
|
223
|
-
for i in range(len(contour_labels)):
|
|
224
|
-
vs = cs_collections[i].get_paths()[0].vertices
|
|
225
|
-
# Compute area enclosed by vertices.
|
|
226
|
-
# Take absolute values to be independent of orientation of
|
|
227
|
-
# the boundary integral.
|
|
228
|
-
contour_area = abs(calculate_area(vs)) # in square-radians
|
|
229
|
-
# convert to square-degrees
|
|
230
|
-
contour_area_sqdeg = contour_area*(180.*180.)/(np.pi*np.pi)
|
|
231
|
-
|
|
232
|
-
area_string = f"area: {contour_area_sqdeg:.2f}sqdeg"
|
|
233
|
-
leg_labels.append(
|
|
234
|
-
f'{contour_labels[i]} - {area_string}'
|
|
235
|
-
)
|
|
236
|
-
|
|
237
|
-
ax.scatter(
|
|
238
|
-
min_ra,
|
|
239
|
-
min_dec,
|
|
240
|
-
s=20,
|
|
241
|
-
marker='*',
|
|
242
|
-
color='black',
|
|
243
|
-
label=r'scan best-fit',
|
|
244
|
-
zorder=2
|
|
245
|
-
)
|
|
246
|
-
ax.legend(
|
|
247
|
-
leg_element,
|
|
248
|
-
leg_labels,
|
|
249
|
-
loc='lower right',
|
|
250
|
-
fontsize=8,
|
|
251
|
-
scatterpoints=1,
|
|
252
|
-
ncol=2
|
|
253
|
-
)
|
|
254
|
-
|
|
255
|
-
LOGGER.info(f"Contour Area (90%): {contour_area_sqdeg} "
|
|
256
|
-
f"degrees (cartesian) "
|
|
257
|
-
f"{contour_area_sqdeg * np.cos(min_dec)**2} "
|
|
258
|
-
"degrees (scaled)")
|
|
259
|
-
x_width = 1.6 * np.sqrt(contour_area_sqdeg)
|
|
260
|
-
LOGGER.info(f"x width is {x_width}")
|
|
261
|
-
if np.isnan(x_width):
|
|
262
|
-
# this get called only when contour_area / x_width is
|
|
263
|
-
# NaN so possibly never invoked in typical situations
|
|
264
|
-
raise RuntimeError(
|
|
265
|
-
"Estimated area / width is NaN and the fallback logic "
|
|
266
|
-
"for this scenario is no longer supported. If you "
|
|
267
|
-
"encounter this error raise an issue to SkyReader."
|
|
268
|
-
)
|
|
269
|
-
# mypy error: "QuadContourSet" has no attribute "allsegs"
|
|
270
|
-
# [attr-defined]. This attribute is likely deprecated but
|
|
271
|
-
# this scenario is rarely (if ever) hit original code is
|
|
272
|
-
# kept commented for the time being
|
|
273
|
-
|
|
274
|
-
# note: contour_set is re-assigned at every iteration of
|
|
275
|
-
# the loop on contour_levels, contour_colors, so this
|
|
276
|
-
# effectively corresponds to the last contour_set
|
|
277
|
-
# x_width = 1.6*(max(contour_set.allsegs[i][0][:,0]) -
|
|
278
|
-
# min(contour_set.allsegs[i][0][:,0]))
|
|
279
|
-
|
|
280
|
-
y_width = 0.5 * x_width
|
|
281
|
-
|
|
282
|
-
lower_x = max(min_ra - x_width*np.pi/180., 0.)
|
|
283
|
-
upper_x = min(min_ra + x_width*np.pi/180., 2 * np.pi)
|
|
284
|
-
lower_y = max(min_dec - y_width*np.pi/180., -np.pi/2.)
|
|
285
|
-
upper_y = min(min_dec + y_width*np.pi/180., np.pi/2.)
|
|
286
177
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
ax.
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
ax.xaxis.set_major_locator(
|
|
301
|
-
matplotlib.ticker.MultipleLocator(base=tick_label_grid)
|
|
302
|
-
)
|
|
303
|
-
ax.yaxis.set_major_locator(
|
|
304
|
-
matplotlib.ticker.MultipleLocator(base=tick_label_grid)
|
|
305
|
-
)
|
|
178
|
+
# graticule
|
|
179
|
+
if isinstance(ax, AstroMollweideAxes):
|
|
180
|
+
# mypy guard
|
|
181
|
+
ax.set_longitude_grid(30)
|
|
182
|
+
ax.set_latitude_grid(30)
|
|
183
|
+
cb = fig.colorbar(
|
|
184
|
+
image,
|
|
185
|
+
orientation='horizontal',
|
|
186
|
+
shrink=.6,
|
|
187
|
+
pad=0.05,
|
|
188
|
+
ticks=[vmin, vmax],
|
|
189
|
+
)
|
|
190
|
+
cb.ax.xaxis.set_label_text(text_colorbar)
|
|
306
191
|
|
|
307
192
|
# cb.ax.xaxis.labelpad = -8
|
|
308
193
|
# workaround for issue with viewers, see colorbar docstring
|
|
@@ -311,9 +196,6 @@ class SkyScanPlotter:
|
|
|
311
196
|
if isinstance(cb.solids, matplotlib.collections.QuadMesh):
|
|
312
197
|
cb.solids.set_edgecolor("face")
|
|
313
198
|
|
|
314
|
-
if dozoom:
|
|
315
|
-
ax.set_aspect('equal')
|
|
316
|
-
|
|
317
199
|
ax.tick_params(axis='x', labelsize=10)
|
|
318
200
|
ax.tick_params(axis='y', labelsize=10)
|
|
319
201
|
|
|
@@ -333,20 +215,12 @@ class SkyScanPlotter:
|
|
|
333
215
|
|
|
334
216
|
# remove white space around figure
|
|
335
217
|
spacing = 0.01
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
)
|
|
343
|
-
else:
|
|
344
|
-
fig.subplots_adjust(
|
|
345
|
-
bottom=spacing,
|
|
346
|
-
top=0.92-spacing,
|
|
347
|
-
left=spacing+0.1,
|
|
348
|
-
right=1.-spacing
|
|
349
|
-
)
|
|
218
|
+
fig.subplots_adjust(
|
|
219
|
+
bottom=spacing,
|
|
220
|
+
top=1.-spacing,
|
|
221
|
+
left=spacing+0.04,
|
|
222
|
+
right=1.-spacing
|
|
223
|
+
)
|
|
350
224
|
|
|
351
225
|
# set the title
|
|
352
226
|
fig.suptitle(plot_title)
|
|
@@ -812,7 +686,7 @@ class SkyScanPlotter:
|
|
|
812
686
|
plt.legend(fontsize=6, loc="lower left")
|
|
813
687
|
|
|
814
688
|
# save flattened map
|
|
815
|
-
equatorial_map, column_names = prepare_flattened_map(
|
|
689
|
+
equatorial_map, column_names, column_units = prepare_flattened_map(
|
|
816
690
|
equatorial_map, llh_map
|
|
817
691
|
)
|
|
818
692
|
if llh_map:
|
|
@@ -825,8 +699,9 @@ class SkyScanPlotter:
|
|
|
825
699
|
equatorial_map,
|
|
826
700
|
coord='C',
|
|
827
701
|
column_names=column_names,
|
|
702
|
+
column_units=column_units,
|
|
828
703
|
extra_header=fits_header,
|
|
829
|
-
overwrite=True
|
|
704
|
+
overwrite=True,
|
|
830
705
|
)
|
|
831
706
|
multiorder_map, column_names = prepare_multiorder_map(
|
|
832
707
|
grid_value, uniq_array, llh_map, column_names
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
# flake8: noqa
|
|
5
5
|
|
|
6
6
|
import astropy.io.fits as pyfits # type: ignore[import]
|
|
7
|
+
from astropy.time import Time # type: ignore[import]
|
|
7
8
|
import healpy # type: ignore[import]
|
|
8
9
|
import matplotlib # type: ignore[import]
|
|
9
10
|
import matplotlib.patheffects as path_effects # type: ignore[import]
|
|
@@ -28,11 +29,14 @@ def format_fits_header(
|
|
|
28
29
|
else:
|
|
29
30
|
uncertainty_comment = 'Highest posterior density 90% credible region'
|
|
30
31
|
|
|
32
|
+
t = Time(mjd, format="mjd")
|
|
33
|
+
|
|
31
34
|
header = [
|
|
32
35
|
('RUNID', run_id),
|
|
33
36
|
('EVENTID', event_id),
|
|
34
37
|
('SENDER', 'IceCube Collaboration'),
|
|
35
|
-
('
|
|
38
|
+
('DATE-OBS', t.isot, 'UTC date of the observation'),
|
|
39
|
+
('MJD-OBS', mjd, 'modified Julian date of the observation'),
|
|
36
40
|
('I3TYPE', f'{event_type}','Alert Type'),
|
|
37
41
|
('RA', np.round(ra,2),'Degree'),
|
|
38
42
|
('DEC', np.round(dec,2),'Degree'),
|
|
@@ -362,20 +362,22 @@ def clean_data_multiorder_map(
|
|
|
362
362
|
def prepare_flattened_map(
|
|
363
363
|
equatorial_map: np.ndarray,
|
|
364
364
|
llh_map: bool,
|
|
365
|
-
) -> Tuple[np.ndarray, List[str]]:
|
|
365
|
+
) -> Tuple[np.ndarray, List[str], Union[List[str], None]]:
|
|
366
366
|
"""
|
|
367
367
|
Create the healpix map that needs to be saved keeping
|
|
368
368
|
into account if it is a probability or a llh map
|
|
369
369
|
"""
|
|
370
370
|
if llh_map:
|
|
371
371
|
column_names = ['2DLLH']
|
|
372
|
+
column_units = None
|
|
372
373
|
else:
|
|
373
374
|
# avoid excessively heavy data format for the flattened map
|
|
374
375
|
equatorial_map[equatorial_map < 1e-16] = np.nanmean(
|
|
375
376
|
equatorial_map[equatorial_map < 1e-16]
|
|
376
377
|
)
|
|
377
|
-
column_names = ["
|
|
378
|
-
|
|
378
|
+
column_names = ["PROB"]
|
|
379
|
+
column_units = ["pix-1"]
|
|
380
|
+
return equatorial_map, column_names, column_units
|
|
379
381
|
|
|
380
382
|
|
|
381
383
|
def prepare_multiorder_map(
|
|
@@ -400,8 +402,10 @@ def prepare_multiorder_map(
|
|
|
400
402
|
max_nside = np.max(all_nsides)
|
|
401
403
|
multiorder_map = mhealpy.HealpixMap(
|
|
402
404
|
grid_value / healpy.nside2pixarea(
|
|
403
|
-
max_nside, degrees=
|
|
404
|
-
),
|
|
405
|
+
max_nside, degrees=False,
|
|
406
|
+
),
|
|
407
|
+
uniq_array,
|
|
408
|
+
unit="sr-1"
|
|
405
409
|
)
|
|
406
|
-
column_names = [
|
|
410
|
+
column_names = ["PROBDENSITY"]
|
|
407
411
|
return multiorder_map, column_names
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{icecube-skyreader-1.3.2 → icecube-skyreader-1.3.3}/icecube_skyreader.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
{icecube-skyreader-1.3.2 → icecube-skyreader-1.3.3}/icecube_skyreader.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|