ecallistolib 0.2.1__tar.gz → 0.2.2__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.
- {ecallistolib-0.2.1/src/ecallistolib.egg-info → ecallistolib-0.2.2}/PKG-INFO +53 -39
- {ecallistolib-0.2.1 → ecallistolib-0.2.2}/README.md +52 -38
- {ecallistolib-0.2.1 → ecallistolib-0.2.2}/pyproject.toml +1 -1
- {ecallistolib-0.2.1 → ecallistolib-0.2.2/src/ecallistolib.egg-info}/PKG-INFO +53 -39
- {ecallistolib-0.2.1 → ecallistolib-0.2.2}/LICENSE +0 -0
- {ecallistolib-0.2.1 → ecallistolib-0.2.2}/setup.cfg +0 -0
- {ecallistolib-0.2.1 → ecallistolib-0.2.2}/src/ecallistolib/__init__.py +0 -0
- {ecallistolib-0.2.1 → ecallistolib-0.2.2}/src/ecallistolib/combine.py +0 -0
- {ecallistolib-0.2.1 → ecallistolib-0.2.2}/src/ecallistolib/crop.py +0 -0
- {ecallistolib-0.2.1 → ecallistolib-0.2.2}/src/ecallistolib/download.py +0 -0
- {ecallistolib-0.2.1 → ecallistolib-0.2.2}/src/ecallistolib/exceptions.py +0 -0
- {ecallistolib-0.2.1 → ecallistolib-0.2.2}/src/ecallistolib/io.py +0 -0
- {ecallistolib-0.2.1 → ecallistolib-0.2.2}/src/ecallistolib/models.py +0 -0
- {ecallistolib-0.2.1 → ecallistolib-0.2.2}/src/ecallistolib/plotting.py +0 -0
- {ecallistolib-0.2.1 → ecallistolib-0.2.2}/src/ecallistolib/processing.py +0 -0
- {ecallistolib-0.2.1 → ecallistolib-0.2.2}/src/ecallistolib.egg-info/SOURCES.txt +0 -0
- {ecallistolib-0.2.1 → ecallistolib-0.2.2}/src/ecallistolib.egg-info/dependency_links.txt +0 -0
- {ecallistolib-0.2.1 → ecallistolib-0.2.2}/src/ecallistolib.egg-info/requires.txt +0 -0
- {ecallistolib-0.2.1 → ecallistolib-0.2.2}/src/ecallistolib.egg-info/top_level.txt +0 -0
- {ecallistolib-0.2.1 → ecallistolib-0.2.2}/tests/test_crop.py +0 -0
- {ecallistolib-0.2.1 → ecallistolib-0.2.2}/tests/test_exceptions.py +0 -0
- {ecallistolib-0.2.1 → ecallistolib-0.2.2}/tests/test_imports.py +0 -0
- {ecallistolib-0.2.1 → ecallistolib-0.2.2}/tests/test_integration.py +0 -0
- {ecallistolib-0.2.1 → ecallistolib-0.2.2}/tests/test_io.py +0 -0
- {ecallistolib-0.2.1 → ecallistolib-0.2.2}/tests/test_models.py +0 -0
- {ecallistolib-0.2.1 → ecallistolib-0.2.2}/tests/test_plotting.py +0 -0
- {ecallistolib-0.2.1 → ecallistolib-0.2.2}/tests/test_processing.py +0 -0
- {ecallistolib-0.2.1 → ecallistolib-0.2.2}/tests/test_smoke.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ecallistolib
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Tools to download, read, process, and plot e-CALLISTO FITS dynamic spectra.
|
|
5
5
|
Author: Sahan S. Liyanage
|
|
6
6
|
License: MIT
|
|
@@ -70,6 +70,20 @@ A Python library to **download**, **read**, **process**, and **plot** e-CALLISTO
|
|
|
70
70
|
|
|
71
71
|
## Installation
|
|
72
72
|
|
|
73
|
+
|
|
74
|
+
### From PyPI (Stable)
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
pip install ecallistolib
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Optional Dependencies
|
|
81
|
+
|
|
82
|
+
Install optional features as needed:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
pip install ecallistolib"[download,plot]"
|
|
86
|
+
```
|
|
73
87
|
### From Source (Development)
|
|
74
88
|
|
|
75
89
|
```bash
|
|
@@ -240,7 +254,7 @@ spectrum = ecl.read_fits("my_spectrum.fit.gz")
|
|
|
240
254
|
cropped = ecl.crop_frequency(spectrum, freq_min=100, freq_max=300)
|
|
241
255
|
|
|
242
256
|
# Crop to specific time range (in seconds)
|
|
243
|
-
cropped =
|
|
257
|
+
cropped = ecl.crop_time(spectrum, time_min=10, time_max=60)
|
|
244
258
|
|
|
245
259
|
# Crop both axes at once
|
|
246
260
|
cropped = ecl.crop(spectrum, freq_range=(100, 300), time_range=(10, 60))
|
|
@@ -325,15 +339,15 @@ Create dynamic spectrum visualizations with full customization:
|
|
|
325
339
|
import ecallistolib as ecl
|
|
326
340
|
import matplotlib.pyplot as plt
|
|
327
341
|
|
|
328
|
-
spectrum =
|
|
329
|
-
cleaned =
|
|
342
|
+
spectrum = ecl.read_fits("my_spectrum.fit.gz")
|
|
343
|
+
cleaned = ecl.noise_reduce_mean_clip(spectrum)
|
|
330
344
|
|
|
331
345
|
# Basic plot
|
|
332
|
-
fig, ax, im =
|
|
346
|
+
fig, ax, im = ecl.plot_dynamic_spectrum(cleaned, title="Solar Radio Observation")
|
|
333
347
|
plt.show()
|
|
334
348
|
|
|
335
349
|
# Customized plot with clipping values, colormap, and figure size
|
|
336
|
-
fig, ax, im =
|
|
350
|
+
fig, ax, im = ecl.plot_dynamic_spectrum(
|
|
337
351
|
cleaned,
|
|
338
352
|
title="Type III Solar Burst",
|
|
339
353
|
cmap="magma", # Matplotlib colormap
|
|
@@ -348,12 +362,12 @@ plt.savefig("spectrum.png", dpi=150, bbox_inches="tight")
|
|
|
348
362
|
#### Plotting Raw Data
|
|
349
363
|
|
|
350
364
|
```python
|
|
351
|
-
import ecallistolib as
|
|
365
|
+
import ecallistolib as ecl
|
|
352
366
|
|
|
353
|
-
spectrum =
|
|
367
|
+
spectrum = ecl.read_fits("my_spectrum.fit.gz")
|
|
354
368
|
|
|
355
369
|
# Plot raw spectrum without any processing
|
|
356
|
-
fig, ax, im =
|
|
370
|
+
fig, ax, im = ecl.plot_raw_spectrum(
|
|
357
371
|
spectrum,
|
|
358
372
|
title="Raw Spectrum",
|
|
359
373
|
cmap="viridis",
|
|
@@ -364,12 +378,12 @@ fig, ax, im = ecf.plot_raw_spectrum(
|
|
|
364
378
|
#### Plotting Background Subtracted (Before Clipping)
|
|
365
379
|
|
|
366
380
|
```python
|
|
367
|
-
import ecallistolib as
|
|
381
|
+
import ecallistolib as ecl
|
|
368
382
|
|
|
369
|
-
spectrum =
|
|
383
|
+
spectrum = ecl.read_fits("my_spectrum.fit.gz")
|
|
370
384
|
|
|
371
385
|
# Plot after background subtraction but before clipping
|
|
372
|
-
fig, ax, im =
|
|
386
|
+
fig, ax, im = ecl.plot_background_subtracted(
|
|
373
387
|
spectrum,
|
|
374
388
|
vmin=-10,
|
|
375
389
|
vmax=30,
|
|
@@ -382,15 +396,15 @@ fig, ax, im = ecf.plot_background_subtracted(
|
|
|
382
396
|
Display time in seconds or Universal Time (UT):
|
|
383
397
|
|
|
384
398
|
```python
|
|
385
|
-
import ecallistolib as
|
|
399
|
+
import ecallistolib as ecl
|
|
386
400
|
|
|
387
|
-
spectrum =
|
|
401
|
+
spectrum = ecl.read_fits("my_spectrum.fit.gz")
|
|
388
402
|
|
|
389
403
|
# Default: time in seconds
|
|
390
|
-
|
|
404
|
+
ecl.plot_dynamic_spectrum(spectrum, time_format="seconds")
|
|
391
405
|
|
|
392
406
|
# Time in UT format (HH:MM:SS)
|
|
393
|
-
|
|
407
|
+
ecl.plot_dynamic_spectrum(spectrum, time_format="ut")
|
|
394
408
|
```
|
|
395
409
|
|
|
396
410
|
#### Time Axis Converter
|
|
@@ -398,12 +412,12 @@ ecf.plot_dynamic_spectrum(spectrum, time_format="ut")
|
|
|
398
412
|
Convert between elapsed seconds and UT time programmatically:
|
|
399
413
|
|
|
400
414
|
```python
|
|
401
|
-
import ecallistolib as
|
|
415
|
+
import ecallistolib as ecl
|
|
402
416
|
|
|
403
|
-
spectrum =
|
|
417
|
+
spectrum = ecl.read_fits("my_spectrum.fit.gz")
|
|
404
418
|
|
|
405
419
|
# Create converter from spectrum metadata
|
|
406
|
-
converter =
|
|
420
|
+
converter = ecl.TimeAxisConverter.from_dynamic_spectrum(spectrum)
|
|
407
421
|
|
|
408
422
|
# Convert seconds to UT
|
|
409
423
|
print(converter.seconds_to_ut(100)) # "12:01:40"
|
|
@@ -418,16 +432,16 @@ print(converter.ut_to_seconds("13:00:00")) # 3600.0
|
|
|
418
432
|
|
|
419
433
|
```python
|
|
420
434
|
import matplotlib.pyplot as plt
|
|
421
|
-
import ecallistolib as
|
|
435
|
+
import ecallistolib as ecl
|
|
422
436
|
|
|
423
437
|
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
|
|
424
438
|
|
|
425
|
-
spectrum1 =
|
|
426
|
-
spectrum2 =
|
|
439
|
+
spectrum1 = ecl.read_fits("file1.fit.gz")
|
|
440
|
+
spectrum2 = ecl.read_fits("file2.fit.gz")
|
|
427
441
|
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
442
|
+
ecl.plot_raw_spectrum(spectrum1, ax=axes[0], title="Raw")
|
|
443
|
+
ecl.plot_dynamic_spectrum(
|
|
444
|
+
ecl.noise_reduce_mean_clip(spectrum2),
|
|
431
445
|
ax=axes[1],
|
|
432
446
|
title="Noise Reduced",
|
|
433
447
|
vmin=-5, vmax=20
|
|
@@ -705,18 +719,18 @@ The library provides a hierarchy of custom exceptions for robust error handling:
|
|
|
705
719
|
#### Error Handling Example
|
|
706
720
|
|
|
707
721
|
```python
|
|
708
|
-
import ecallistolib as
|
|
722
|
+
import ecallistolib as ecl
|
|
709
723
|
from ecallistolib import InvalidFITSError, CropError
|
|
710
724
|
|
|
711
725
|
try:
|
|
712
|
-
spectrum =
|
|
726
|
+
spectrum = ecl.read_fits("corrupted_file.fit")
|
|
713
727
|
except FileNotFoundError:
|
|
714
728
|
print("File not found")
|
|
715
729
|
except InvalidFITSError as e:
|
|
716
730
|
print(f"Invalid FITS file: {e}")
|
|
717
731
|
|
|
718
732
|
try:
|
|
719
|
-
cropped =
|
|
733
|
+
cropped = ecl.crop(spectrum, freq_range=(1000, 2000)) # Out of range
|
|
720
734
|
except CropError as e:
|
|
721
735
|
print(f"Cropping failed: {e}")
|
|
722
736
|
```
|
|
@@ -729,24 +743,24 @@ except CropError as e:
|
|
|
729
743
|
|
|
730
744
|
```python
|
|
731
745
|
from datetime import date
|
|
732
|
-
import ecallistolib as
|
|
746
|
+
import ecallistolib as ecl
|
|
733
747
|
import matplotlib.pyplot as plt
|
|
734
748
|
|
|
735
749
|
# 1. Download data
|
|
736
|
-
remote =
|
|
737
|
-
paths =
|
|
750
|
+
remote = ecl.list_remote_fits(date(2023, 6, 15), hour=12, station_substring="alaska")
|
|
751
|
+
paths = ecl.download_files(remote[:2], out_dir="./data")
|
|
738
752
|
|
|
739
753
|
# 2. Read and combine
|
|
740
|
-
if
|
|
741
|
-
spectrum =
|
|
754
|
+
if ecl.can_combine_time(paths):
|
|
755
|
+
spectrum = ecl.combine_time(paths)
|
|
742
756
|
else:
|
|
743
|
-
spectrum =
|
|
757
|
+
spectrum = ecl.read_fits(paths[0])
|
|
744
758
|
|
|
745
759
|
# 3. Process
|
|
746
|
-
cleaned =
|
|
760
|
+
cleaned = ecl.noise_reduce_mean_clip(spectrum)
|
|
747
761
|
|
|
748
762
|
# 4. Plot
|
|
749
|
-
fig, ax, im =
|
|
763
|
+
fig, ax, im = ecl.plot_dynamic_spectrum(
|
|
750
764
|
cleaned,
|
|
751
765
|
title=f"e-CALLISTO Observation - {spectrum.meta.get('station', 'Unknown')}",
|
|
752
766
|
cmap="plasma"
|
|
@@ -758,9 +772,9 @@ plt.show()
|
|
|
758
772
|
### Working with Metadata
|
|
759
773
|
|
|
760
774
|
```python
|
|
761
|
-
import ecallistolib as
|
|
775
|
+
import ecallistolib as ecl
|
|
762
776
|
|
|
763
|
-
spectrum =
|
|
777
|
+
spectrum = ecl.read_fits("my_file.fit.gz")
|
|
764
778
|
|
|
765
779
|
# Access metadata
|
|
766
780
|
print(f"Station: {spectrum.meta.get('station')}")
|
|
@@ -768,7 +782,7 @@ print(f"Date: {spectrum.meta.get('date')}")
|
|
|
768
782
|
print(f"UT Start: {spectrum.meta.get('ut_start_sec')} seconds")
|
|
769
783
|
|
|
770
784
|
# After processing, metadata is preserved and extended
|
|
771
|
-
processed =
|
|
785
|
+
processed = ecl.noise_reduce_mean_clip(spectrum)
|
|
772
786
|
print(f"Processing applied: {processed.meta.get('noise_reduction')}")
|
|
773
787
|
```
|
|
774
788
|
|
|
@@ -50,6 +50,20 @@ A Python library to **download**, **read**, **process**, and **plot** e-CALLISTO
|
|
|
50
50
|
|
|
51
51
|
## Installation
|
|
52
52
|
|
|
53
|
+
|
|
54
|
+
### From PyPI (Stable)
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
pip install ecallistolib
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Optional Dependencies
|
|
61
|
+
|
|
62
|
+
Install optional features as needed:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
pip install ecallistolib"[download,plot]"
|
|
66
|
+
```
|
|
53
67
|
### From Source (Development)
|
|
54
68
|
|
|
55
69
|
```bash
|
|
@@ -220,7 +234,7 @@ spectrum = ecl.read_fits("my_spectrum.fit.gz")
|
|
|
220
234
|
cropped = ecl.crop_frequency(spectrum, freq_min=100, freq_max=300)
|
|
221
235
|
|
|
222
236
|
# Crop to specific time range (in seconds)
|
|
223
|
-
cropped =
|
|
237
|
+
cropped = ecl.crop_time(spectrum, time_min=10, time_max=60)
|
|
224
238
|
|
|
225
239
|
# Crop both axes at once
|
|
226
240
|
cropped = ecl.crop(spectrum, freq_range=(100, 300), time_range=(10, 60))
|
|
@@ -305,15 +319,15 @@ Create dynamic spectrum visualizations with full customization:
|
|
|
305
319
|
import ecallistolib as ecl
|
|
306
320
|
import matplotlib.pyplot as plt
|
|
307
321
|
|
|
308
|
-
spectrum =
|
|
309
|
-
cleaned =
|
|
322
|
+
spectrum = ecl.read_fits("my_spectrum.fit.gz")
|
|
323
|
+
cleaned = ecl.noise_reduce_mean_clip(spectrum)
|
|
310
324
|
|
|
311
325
|
# Basic plot
|
|
312
|
-
fig, ax, im =
|
|
326
|
+
fig, ax, im = ecl.plot_dynamic_spectrum(cleaned, title="Solar Radio Observation")
|
|
313
327
|
plt.show()
|
|
314
328
|
|
|
315
329
|
# Customized plot with clipping values, colormap, and figure size
|
|
316
|
-
fig, ax, im =
|
|
330
|
+
fig, ax, im = ecl.plot_dynamic_spectrum(
|
|
317
331
|
cleaned,
|
|
318
332
|
title="Type III Solar Burst",
|
|
319
333
|
cmap="magma", # Matplotlib colormap
|
|
@@ -328,12 +342,12 @@ plt.savefig("spectrum.png", dpi=150, bbox_inches="tight")
|
|
|
328
342
|
#### Plotting Raw Data
|
|
329
343
|
|
|
330
344
|
```python
|
|
331
|
-
import ecallistolib as
|
|
345
|
+
import ecallistolib as ecl
|
|
332
346
|
|
|
333
|
-
spectrum =
|
|
347
|
+
spectrum = ecl.read_fits("my_spectrum.fit.gz")
|
|
334
348
|
|
|
335
349
|
# Plot raw spectrum without any processing
|
|
336
|
-
fig, ax, im =
|
|
350
|
+
fig, ax, im = ecl.plot_raw_spectrum(
|
|
337
351
|
spectrum,
|
|
338
352
|
title="Raw Spectrum",
|
|
339
353
|
cmap="viridis",
|
|
@@ -344,12 +358,12 @@ fig, ax, im = ecf.plot_raw_spectrum(
|
|
|
344
358
|
#### Plotting Background Subtracted (Before Clipping)
|
|
345
359
|
|
|
346
360
|
```python
|
|
347
|
-
import ecallistolib as
|
|
361
|
+
import ecallistolib as ecl
|
|
348
362
|
|
|
349
|
-
spectrum =
|
|
363
|
+
spectrum = ecl.read_fits("my_spectrum.fit.gz")
|
|
350
364
|
|
|
351
365
|
# Plot after background subtraction but before clipping
|
|
352
|
-
fig, ax, im =
|
|
366
|
+
fig, ax, im = ecl.plot_background_subtracted(
|
|
353
367
|
spectrum,
|
|
354
368
|
vmin=-10,
|
|
355
369
|
vmax=30,
|
|
@@ -362,15 +376,15 @@ fig, ax, im = ecf.plot_background_subtracted(
|
|
|
362
376
|
Display time in seconds or Universal Time (UT):
|
|
363
377
|
|
|
364
378
|
```python
|
|
365
|
-
import ecallistolib as
|
|
379
|
+
import ecallistolib as ecl
|
|
366
380
|
|
|
367
|
-
spectrum =
|
|
381
|
+
spectrum = ecl.read_fits("my_spectrum.fit.gz")
|
|
368
382
|
|
|
369
383
|
# Default: time in seconds
|
|
370
|
-
|
|
384
|
+
ecl.plot_dynamic_spectrum(spectrum, time_format="seconds")
|
|
371
385
|
|
|
372
386
|
# Time in UT format (HH:MM:SS)
|
|
373
|
-
|
|
387
|
+
ecl.plot_dynamic_spectrum(spectrum, time_format="ut")
|
|
374
388
|
```
|
|
375
389
|
|
|
376
390
|
#### Time Axis Converter
|
|
@@ -378,12 +392,12 @@ ecf.plot_dynamic_spectrum(spectrum, time_format="ut")
|
|
|
378
392
|
Convert between elapsed seconds and UT time programmatically:
|
|
379
393
|
|
|
380
394
|
```python
|
|
381
|
-
import ecallistolib as
|
|
395
|
+
import ecallistolib as ecl
|
|
382
396
|
|
|
383
|
-
spectrum =
|
|
397
|
+
spectrum = ecl.read_fits("my_spectrum.fit.gz")
|
|
384
398
|
|
|
385
399
|
# Create converter from spectrum metadata
|
|
386
|
-
converter =
|
|
400
|
+
converter = ecl.TimeAxisConverter.from_dynamic_spectrum(spectrum)
|
|
387
401
|
|
|
388
402
|
# Convert seconds to UT
|
|
389
403
|
print(converter.seconds_to_ut(100)) # "12:01:40"
|
|
@@ -398,16 +412,16 @@ print(converter.ut_to_seconds("13:00:00")) # 3600.0
|
|
|
398
412
|
|
|
399
413
|
```python
|
|
400
414
|
import matplotlib.pyplot as plt
|
|
401
|
-
import ecallistolib as
|
|
415
|
+
import ecallistolib as ecl
|
|
402
416
|
|
|
403
417
|
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
|
|
404
418
|
|
|
405
|
-
spectrum1 =
|
|
406
|
-
spectrum2 =
|
|
419
|
+
spectrum1 = ecl.read_fits("file1.fit.gz")
|
|
420
|
+
spectrum2 = ecl.read_fits("file2.fit.gz")
|
|
407
421
|
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
422
|
+
ecl.plot_raw_spectrum(spectrum1, ax=axes[0], title="Raw")
|
|
423
|
+
ecl.plot_dynamic_spectrum(
|
|
424
|
+
ecl.noise_reduce_mean_clip(spectrum2),
|
|
411
425
|
ax=axes[1],
|
|
412
426
|
title="Noise Reduced",
|
|
413
427
|
vmin=-5, vmax=20
|
|
@@ -685,18 +699,18 @@ The library provides a hierarchy of custom exceptions for robust error handling:
|
|
|
685
699
|
#### Error Handling Example
|
|
686
700
|
|
|
687
701
|
```python
|
|
688
|
-
import ecallistolib as
|
|
702
|
+
import ecallistolib as ecl
|
|
689
703
|
from ecallistolib import InvalidFITSError, CropError
|
|
690
704
|
|
|
691
705
|
try:
|
|
692
|
-
spectrum =
|
|
706
|
+
spectrum = ecl.read_fits("corrupted_file.fit")
|
|
693
707
|
except FileNotFoundError:
|
|
694
708
|
print("File not found")
|
|
695
709
|
except InvalidFITSError as e:
|
|
696
710
|
print(f"Invalid FITS file: {e}")
|
|
697
711
|
|
|
698
712
|
try:
|
|
699
|
-
cropped =
|
|
713
|
+
cropped = ecl.crop(spectrum, freq_range=(1000, 2000)) # Out of range
|
|
700
714
|
except CropError as e:
|
|
701
715
|
print(f"Cropping failed: {e}")
|
|
702
716
|
```
|
|
@@ -709,24 +723,24 @@ except CropError as e:
|
|
|
709
723
|
|
|
710
724
|
```python
|
|
711
725
|
from datetime import date
|
|
712
|
-
import ecallistolib as
|
|
726
|
+
import ecallistolib as ecl
|
|
713
727
|
import matplotlib.pyplot as plt
|
|
714
728
|
|
|
715
729
|
# 1. Download data
|
|
716
|
-
remote =
|
|
717
|
-
paths =
|
|
730
|
+
remote = ecl.list_remote_fits(date(2023, 6, 15), hour=12, station_substring="alaska")
|
|
731
|
+
paths = ecl.download_files(remote[:2], out_dir="./data")
|
|
718
732
|
|
|
719
733
|
# 2. Read and combine
|
|
720
|
-
if
|
|
721
|
-
spectrum =
|
|
734
|
+
if ecl.can_combine_time(paths):
|
|
735
|
+
spectrum = ecl.combine_time(paths)
|
|
722
736
|
else:
|
|
723
|
-
spectrum =
|
|
737
|
+
spectrum = ecl.read_fits(paths[0])
|
|
724
738
|
|
|
725
739
|
# 3. Process
|
|
726
|
-
cleaned =
|
|
740
|
+
cleaned = ecl.noise_reduce_mean_clip(spectrum)
|
|
727
741
|
|
|
728
742
|
# 4. Plot
|
|
729
|
-
fig, ax, im =
|
|
743
|
+
fig, ax, im = ecl.plot_dynamic_spectrum(
|
|
730
744
|
cleaned,
|
|
731
745
|
title=f"e-CALLISTO Observation - {spectrum.meta.get('station', 'Unknown')}",
|
|
732
746
|
cmap="plasma"
|
|
@@ -738,9 +752,9 @@ plt.show()
|
|
|
738
752
|
### Working with Metadata
|
|
739
753
|
|
|
740
754
|
```python
|
|
741
|
-
import ecallistolib as
|
|
755
|
+
import ecallistolib as ecl
|
|
742
756
|
|
|
743
|
-
spectrum =
|
|
757
|
+
spectrum = ecl.read_fits("my_file.fit.gz")
|
|
744
758
|
|
|
745
759
|
# Access metadata
|
|
746
760
|
print(f"Station: {spectrum.meta.get('station')}")
|
|
@@ -748,7 +762,7 @@ print(f"Date: {spectrum.meta.get('date')}")
|
|
|
748
762
|
print(f"UT Start: {spectrum.meta.get('ut_start_sec')} seconds")
|
|
749
763
|
|
|
750
764
|
# After processing, metadata is preserved and extended
|
|
751
|
-
processed =
|
|
765
|
+
processed = ecl.noise_reduce_mean_clip(spectrum)
|
|
752
766
|
print(f"Processing applied: {processed.meta.get('noise_reduction')}")
|
|
753
767
|
```
|
|
754
768
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ecallistolib
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Tools to download, read, process, and plot e-CALLISTO FITS dynamic spectra.
|
|
5
5
|
Author: Sahan S. Liyanage
|
|
6
6
|
License: MIT
|
|
@@ -70,6 +70,20 @@ A Python library to **download**, **read**, **process**, and **plot** e-CALLISTO
|
|
|
70
70
|
|
|
71
71
|
## Installation
|
|
72
72
|
|
|
73
|
+
|
|
74
|
+
### From PyPI (Stable)
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
pip install ecallistolib
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Optional Dependencies
|
|
81
|
+
|
|
82
|
+
Install optional features as needed:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
pip install ecallistolib"[download,plot]"
|
|
86
|
+
```
|
|
73
87
|
### From Source (Development)
|
|
74
88
|
|
|
75
89
|
```bash
|
|
@@ -240,7 +254,7 @@ spectrum = ecl.read_fits("my_spectrum.fit.gz")
|
|
|
240
254
|
cropped = ecl.crop_frequency(spectrum, freq_min=100, freq_max=300)
|
|
241
255
|
|
|
242
256
|
# Crop to specific time range (in seconds)
|
|
243
|
-
cropped =
|
|
257
|
+
cropped = ecl.crop_time(spectrum, time_min=10, time_max=60)
|
|
244
258
|
|
|
245
259
|
# Crop both axes at once
|
|
246
260
|
cropped = ecl.crop(spectrum, freq_range=(100, 300), time_range=(10, 60))
|
|
@@ -325,15 +339,15 @@ Create dynamic spectrum visualizations with full customization:
|
|
|
325
339
|
import ecallistolib as ecl
|
|
326
340
|
import matplotlib.pyplot as plt
|
|
327
341
|
|
|
328
|
-
spectrum =
|
|
329
|
-
cleaned =
|
|
342
|
+
spectrum = ecl.read_fits("my_spectrum.fit.gz")
|
|
343
|
+
cleaned = ecl.noise_reduce_mean_clip(spectrum)
|
|
330
344
|
|
|
331
345
|
# Basic plot
|
|
332
|
-
fig, ax, im =
|
|
346
|
+
fig, ax, im = ecl.plot_dynamic_spectrum(cleaned, title="Solar Radio Observation")
|
|
333
347
|
plt.show()
|
|
334
348
|
|
|
335
349
|
# Customized plot with clipping values, colormap, and figure size
|
|
336
|
-
fig, ax, im =
|
|
350
|
+
fig, ax, im = ecl.plot_dynamic_spectrum(
|
|
337
351
|
cleaned,
|
|
338
352
|
title="Type III Solar Burst",
|
|
339
353
|
cmap="magma", # Matplotlib colormap
|
|
@@ -348,12 +362,12 @@ plt.savefig("spectrum.png", dpi=150, bbox_inches="tight")
|
|
|
348
362
|
#### Plotting Raw Data
|
|
349
363
|
|
|
350
364
|
```python
|
|
351
|
-
import ecallistolib as
|
|
365
|
+
import ecallistolib as ecl
|
|
352
366
|
|
|
353
|
-
spectrum =
|
|
367
|
+
spectrum = ecl.read_fits("my_spectrum.fit.gz")
|
|
354
368
|
|
|
355
369
|
# Plot raw spectrum without any processing
|
|
356
|
-
fig, ax, im =
|
|
370
|
+
fig, ax, im = ecl.plot_raw_spectrum(
|
|
357
371
|
spectrum,
|
|
358
372
|
title="Raw Spectrum",
|
|
359
373
|
cmap="viridis",
|
|
@@ -364,12 +378,12 @@ fig, ax, im = ecf.plot_raw_spectrum(
|
|
|
364
378
|
#### Plotting Background Subtracted (Before Clipping)
|
|
365
379
|
|
|
366
380
|
```python
|
|
367
|
-
import ecallistolib as
|
|
381
|
+
import ecallistolib as ecl
|
|
368
382
|
|
|
369
|
-
spectrum =
|
|
383
|
+
spectrum = ecl.read_fits("my_spectrum.fit.gz")
|
|
370
384
|
|
|
371
385
|
# Plot after background subtraction but before clipping
|
|
372
|
-
fig, ax, im =
|
|
386
|
+
fig, ax, im = ecl.plot_background_subtracted(
|
|
373
387
|
spectrum,
|
|
374
388
|
vmin=-10,
|
|
375
389
|
vmax=30,
|
|
@@ -382,15 +396,15 @@ fig, ax, im = ecf.plot_background_subtracted(
|
|
|
382
396
|
Display time in seconds or Universal Time (UT):
|
|
383
397
|
|
|
384
398
|
```python
|
|
385
|
-
import ecallistolib as
|
|
399
|
+
import ecallistolib as ecl
|
|
386
400
|
|
|
387
|
-
spectrum =
|
|
401
|
+
spectrum = ecl.read_fits("my_spectrum.fit.gz")
|
|
388
402
|
|
|
389
403
|
# Default: time in seconds
|
|
390
|
-
|
|
404
|
+
ecl.plot_dynamic_spectrum(spectrum, time_format="seconds")
|
|
391
405
|
|
|
392
406
|
# Time in UT format (HH:MM:SS)
|
|
393
|
-
|
|
407
|
+
ecl.plot_dynamic_spectrum(spectrum, time_format="ut")
|
|
394
408
|
```
|
|
395
409
|
|
|
396
410
|
#### Time Axis Converter
|
|
@@ -398,12 +412,12 @@ ecf.plot_dynamic_spectrum(spectrum, time_format="ut")
|
|
|
398
412
|
Convert between elapsed seconds and UT time programmatically:
|
|
399
413
|
|
|
400
414
|
```python
|
|
401
|
-
import ecallistolib as
|
|
415
|
+
import ecallistolib as ecl
|
|
402
416
|
|
|
403
|
-
spectrum =
|
|
417
|
+
spectrum = ecl.read_fits("my_spectrum.fit.gz")
|
|
404
418
|
|
|
405
419
|
# Create converter from spectrum metadata
|
|
406
|
-
converter =
|
|
420
|
+
converter = ecl.TimeAxisConverter.from_dynamic_spectrum(spectrum)
|
|
407
421
|
|
|
408
422
|
# Convert seconds to UT
|
|
409
423
|
print(converter.seconds_to_ut(100)) # "12:01:40"
|
|
@@ -418,16 +432,16 @@ print(converter.ut_to_seconds("13:00:00")) # 3600.0
|
|
|
418
432
|
|
|
419
433
|
```python
|
|
420
434
|
import matplotlib.pyplot as plt
|
|
421
|
-
import ecallistolib as
|
|
435
|
+
import ecallistolib as ecl
|
|
422
436
|
|
|
423
437
|
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
|
|
424
438
|
|
|
425
|
-
spectrum1 =
|
|
426
|
-
spectrum2 =
|
|
439
|
+
spectrum1 = ecl.read_fits("file1.fit.gz")
|
|
440
|
+
spectrum2 = ecl.read_fits("file2.fit.gz")
|
|
427
441
|
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
442
|
+
ecl.plot_raw_spectrum(spectrum1, ax=axes[0], title="Raw")
|
|
443
|
+
ecl.plot_dynamic_spectrum(
|
|
444
|
+
ecl.noise_reduce_mean_clip(spectrum2),
|
|
431
445
|
ax=axes[1],
|
|
432
446
|
title="Noise Reduced",
|
|
433
447
|
vmin=-5, vmax=20
|
|
@@ -705,18 +719,18 @@ The library provides a hierarchy of custom exceptions for robust error handling:
|
|
|
705
719
|
#### Error Handling Example
|
|
706
720
|
|
|
707
721
|
```python
|
|
708
|
-
import ecallistolib as
|
|
722
|
+
import ecallistolib as ecl
|
|
709
723
|
from ecallistolib import InvalidFITSError, CropError
|
|
710
724
|
|
|
711
725
|
try:
|
|
712
|
-
spectrum =
|
|
726
|
+
spectrum = ecl.read_fits("corrupted_file.fit")
|
|
713
727
|
except FileNotFoundError:
|
|
714
728
|
print("File not found")
|
|
715
729
|
except InvalidFITSError as e:
|
|
716
730
|
print(f"Invalid FITS file: {e}")
|
|
717
731
|
|
|
718
732
|
try:
|
|
719
|
-
cropped =
|
|
733
|
+
cropped = ecl.crop(spectrum, freq_range=(1000, 2000)) # Out of range
|
|
720
734
|
except CropError as e:
|
|
721
735
|
print(f"Cropping failed: {e}")
|
|
722
736
|
```
|
|
@@ -729,24 +743,24 @@ except CropError as e:
|
|
|
729
743
|
|
|
730
744
|
```python
|
|
731
745
|
from datetime import date
|
|
732
|
-
import ecallistolib as
|
|
746
|
+
import ecallistolib as ecl
|
|
733
747
|
import matplotlib.pyplot as plt
|
|
734
748
|
|
|
735
749
|
# 1. Download data
|
|
736
|
-
remote =
|
|
737
|
-
paths =
|
|
750
|
+
remote = ecl.list_remote_fits(date(2023, 6, 15), hour=12, station_substring="alaska")
|
|
751
|
+
paths = ecl.download_files(remote[:2], out_dir="./data")
|
|
738
752
|
|
|
739
753
|
# 2. Read and combine
|
|
740
|
-
if
|
|
741
|
-
spectrum =
|
|
754
|
+
if ecl.can_combine_time(paths):
|
|
755
|
+
spectrum = ecl.combine_time(paths)
|
|
742
756
|
else:
|
|
743
|
-
spectrum =
|
|
757
|
+
spectrum = ecl.read_fits(paths[0])
|
|
744
758
|
|
|
745
759
|
# 3. Process
|
|
746
|
-
cleaned =
|
|
760
|
+
cleaned = ecl.noise_reduce_mean_clip(spectrum)
|
|
747
761
|
|
|
748
762
|
# 4. Plot
|
|
749
|
-
fig, ax, im =
|
|
763
|
+
fig, ax, im = ecl.plot_dynamic_spectrum(
|
|
750
764
|
cleaned,
|
|
751
765
|
title=f"e-CALLISTO Observation - {spectrum.meta.get('station', 'Unknown')}",
|
|
752
766
|
cmap="plasma"
|
|
@@ -758,9 +772,9 @@ plt.show()
|
|
|
758
772
|
### Working with Metadata
|
|
759
773
|
|
|
760
774
|
```python
|
|
761
|
-
import ecallistolib as
|
|
775
|
+
import ecallistolib as ecl
|
|
762
776
|
|
|
763
|
-
spectrum =
|
|
777
|
+
spectrum = ecl.read_fits("my_file.fit.gz")
|
|
764
778
|
|
|
765
779
|
# Access metadata
|
|
766
780
|
print(f"Station: {spectrum.meta.get('station')}")
|
|
@@ -768,7 +782,7 @@ print(f"Date: {spectrum.meta.get('date')}")
|
|
|
768
782
|
print(f"UT Start: {spectrum.meta.get('ut_start_sec')} seconds")
|
|
769
783
|
|
|
770
784
|
# After processing, metadata is preserved and extended
|
|
771
|
-
processed =
|
|
785
|
+
processed = ecl.noise_reduce_mean_clip(spectrum)
|
|
772
786
|
print(f"Processing applied: {processed.meta.get('noise_reduction')}")
|
|
773
787
|
```
|
|
774
788
|
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|