TCDSolar / stixpy

STIX data analysis in python
https://stixpy.readthedocs.io/
BSD 3-Clause "New" or "Revised" License
17 stars 20 forks source link

`create_meta_pixels` should check the time bins edges (rather than just center) to return time mask #133

Open hayesla opened 2 weeks ago

hayesla commented 2 weeks ago

Currently, in create_meta_pixels to find the data that is contained within the times and energies, only the center of the time bins are checked.

For example here: https://github.com/TCDSolar/stixpy/blob/main/stixpy/calibration/visibility.py#L119

the time-range passed is only checked against the center time of the data bins. However, if the bins are large (e.g. 20s or something), then the time-range passed could be within the bin, however it isn't satisfied by the center value.

For example: In this extreme example, this data only have one time bin, which is quite large (890s). Following the logic from L119 from the visibility.py, this isn't satisfied

>>> time_range = ["2023-04-01T07:32:17.850", "2023-04-01T07:35:37.850"]
>>> pixel_data = Product("https://pub099.cs.technik.fhnw.ch/data/fits/L1/2023/04/01/SCI/solo_L1_stix-sci-xray-cpd_20230401T073020-20230401T074511_V02_2304011277-50312.fits")

>>> t_mask = (pixel_data.times >= Time(time_range[0])) & (pixel_data.times <= Time(time_range[1]))
>>> t_mask
array([False])

however, its just because the center of the time bin is:

>>> pixel_data.times
<Time object: scale='utc' format='isot' value=['2023-04-01T07:37:45.999']>

however the passed time_range is within the bin of the data (here as its only one time point):

>>> pixel_data.time_range
   <sunpy.time.timerange.TimeRange object at 0x1180da180>
    Start: 2023-04-01 07:30:20
    End:   2023-04-01 07:45:11
    Center:2023-04-01 07:37:45
    Duration:0.010309027777777757 days or
           0.24741666666666617 hours or
           14.84499999999997 minutes or
           890.6999999999982 seconds

so it really should be checking that the passed time range is withing the edge of the bins, something like pixel.start_times and pixel.end_times? This could be inferred from the duration.

For context, this is what the IDL software does as far as I know.

hayesla commented 2 weeks ago

like a simple solution would be something like:

pixel_starts = pixel_data.times - pixel_data.durtaion/2
pixel_ends = pixel_data.times + pixel_data.durtaion/2

t_mask = (pixel_starts >= Time(time_range[0])) & (pixel_ends <= Time(time_range[1]))

what do you think @samaloney ?

hannahc243 commented 2 weeks ago

We also need to consider bins where the time range is inside the bin edges so I think the following three cases should work

t_mask_1 = (pixel_starts >= Time(time_range[0])) & (pixel_ends <= Time(time_range[1]))
t_mask_2 = (Time(time_range[0]) - pixel_starts < pixel_data.durtaion) & (Time(time_range[0]) - pixel_starts > 0 * u.s)
t_mask_3 = (pixel_ends - Time(time_range[1]) < pixel_data.durtaion) & (pixel_ends - Time(time_range[0]) > 0 * u.s) 

t_mask = np.logical_or(t_mask_1, t_mask_2, t_mask_3)
samaloney commented 1 week ago

Yes I think this is similar to what we currently do in the client but for file start/end

https://github.com/TCDSolar/stixpy/blob/ba0ef1c9d3e53946128afd2c3c117f5cbfd6fe82/stixpy/net/client.py#L107-L115

I'm down to one hand for a while, broken finger, so things are a bit slow myside.