9
9
import named_arrays as na
10
10
import msfc_ccd
11
11
from .._sensors import AbstractSensor
12
+ from ._vectors import ImageHeader
12
13
from ._images import AbstractImageData
13
14
14
15
__all__ = [
@@ -24,17 +25,6 @@ class AbstractSensorData(
24
25
An interface for representing data captured by an entire image sensor.
25
26
"""
26
27
27
- @property
28
- def pixel (self ) -> dict [str , na .AbstractScalarArray ]:
29
- axis_x = self .axis_x
30
- axis_y = self .axis_y
31
- shape = self .data .shape
32
- shape_img = {
33
- axis_x : shape [axis_x ],
34
- axis_y : shape [axis_y ],
35
- }
36
- return na .indices (shape_img )
37
-
38
28
def taps (
39
29
self ,
40
30
axis_tap_x : str = "tap_x" ,
@@ -61,57 +51,37 @@ def taps(
61
51
num_tap_x = self .sensor .num_tap_x
62
52
num_tap_y = self .sensor .num_tap_y
63
53
64
- shape_img = {axis_x : num_x , axis_y : num_y }
65
-
66
54
num_x_new = num_x // num_tap_x
67
55
num_y_new = num_y // num_tap_y
68
56
69
- slice_left_x = slice ( None , num_x_new )
70
- slice_left_y = slice ( None , num_y_new )
57
+ range_left_x = na . arange ( 0 , num_x_new , axis = axis_x )
58
+ range_left_y = na . arange ( 0 , num_y_new , axis = axis_y )
71
59
72
- slice_right_x = slice ( None , num_x_new - 1 , - 1 )
73
- slice_right_y = slice ( None , num_y_new - 1 , - 1 )
60
+ range_right_x = na . arange ( num_x - 1 , num_x_new - 1 , axis = axis_x , step = - 1 )
61
+ range_right_y = na . arange ( num_y - 1 , num_y_new - 1 , axis = axis_y , step = - 1 )
74
62
75
- slices_x = [slice_left_x , slice_right_x ]
76
- slices_y = [slice_left_y , slice_right_y ]
63
+ ranges_x = [range_left_x , range_right_x ]
64
+ ranges_y = [range_left_y , range_right_y ]
77
65
78
- pixel = self .pixel
66
+ indices_x = na .stack (ranges_x , axis = axis_tap_x )
67
+ indices_y = na .stack (ranges_y , axis = axis_tap_y )
79
68
80
- for ax in pixel :
81
- p = pixel [ax ].broadcast_to (shape_img )
82
- pixel [ax ] = na .stack (
83
- arrays = [
84
- na .stack (
85
- arrays = [p [{axis_x : sx , axis_y : sy }] for sy in slices_y ],
86
- axis = axis_tap_y ,
87
- )
88
- for sx in slices_x
89
- ],
90
- axis = axis_tap_x ,
91
- )
69
+ indices = {
70
+ axis_x : indices_x ,
71
+ axis_y : indices_y ,
72
+ }
92
73
93
74
return msfc_ccd .TapData (
94
- data = self .data [pixel ],
95
- pixel = pixel ,
75
+ inputs = dataclasses .replace (
76
+ self .inputs ,
77
+ pixel = self .inputs .pixel [indices ],
78
+ ),
79
+ outputs = self .outputs [indices ],
96
80
axis_x = self .axis_x ,
97
81
axis_y = self .axis_y ,
98
82
axis_tap_x = axis_tap_x ,
99
83
axis_tap_y = axis_tap_y ,
100
- time = self .time ,
101
- timedelta = self .timedelta ,
102
- timedelta_requested = self .timedelta_requested ,
103
84
sensor = self .sensor ,
104
- serial_number = self .serial_number ,
105
- run_mode = self .run_mode ,
106
- status = self .status ,
107
- voltage_fpga_vccint = self .voltage_fpga_vccint ,
108
- voltage_fpga_vccaux = self .voltage_fpga_vccaux ,
109
- voltage_fpga_vccbram = self .voltage_fpga_vccbram ,
110
- temperature_fpga = self .temperature_fpga ,
111
- temperature_adc_1 = self .temperature_adc_1 ,
112
- temperature_adc_2 = self .temperature_adc_2 ,
113
- temperature_adc_3 = self .temperature_adc_3 ,
114
- temperature_adc_4 = self .temperature_adc_4 ,
115
85
)
116
86
117
87
@@ -151,15 +121,22 @@ class SensorData(
151
121
constrained_layout=True,
152
122
)
153
123
im = na.plt.imshow(
154
- image.data ,
124
+ image.outputs ,
155
125
axis_x=axis_x,
156
126
axis_y=axis_y,
157
127
ax=ax,
158
128
);
159
129
"""
160
130
161
- data : na .AbstractScalar = dataclasses .MISSING
162
- """The underlying array storing the image data."""
131
+ inputs : ImageHeader = dataclasses .MISSING
132
+ """
133
+ A vector which contains the time and index of each pixel in the set of images.
134
+ """
135
+
136
+ outputs : na .ScalarArray = dataclasses .MISSING
137
+ """
138
+ The underlying array storing the image data
139
+ """
163
140
164
141
axis_x : str = dataclasses .MISSING
165
142
"""
@@ -173,51 +150,9 @@ class SensorData(
173
150
the images.
174
151
"""
175
152
176
- time : astropy .time .Time | na .AbstractScalar = dataclasses .MISSING
177
- """The time in UTC at the midpoint of the exposure."""
178
-
179
- timedelta : u .Quantity | na .AbstractScalar = dataclasses .MISSING
180
- """The measured exposure time of each image."""
181
-
182
- timedelta_requested : u .Quantity | na .AbstractScalar = dataclasses .MISSING
183
- """The requested exposure time of each image."""
184
-
185
153
sensor : AbstractSensor = dataclasses .MISSING
186
154
"""A model of the sensor used to capture these images."""
187
155
188
- serial_number : None | str | na .AbstractScalar = None
189
- """The serial number of the camera that captured each image."""
190
-
191
- run_mode : None | str | na .AbstractScalar = None
192
- """The Run Mode of the camera when each image was captured."""
193
-
194
- status : None | str | na .AbstractScalar = None
195
- """The status of the camera while each image was being captured."""
196
-
197
- voltage_fpga_vccint : u .Quantity | na .AbstractScalar = 0
198
- """The VCCINT voltage of the FPGA when each image was captured."""
199
-
200
- voltage_fpga_vccaux : u .Quantity | na .AbstractScalar = 0
201
- """The VCCAUX voltage of the FPGA when each image was captured."""
202
-
203
- voltage_fpga_vccbram : u .Quantity | na .AbstractScalar = 0
204
- """The VCCBRAM voltage of the FPGA when each image was captured."""
205
-
206
- temperature_fpga : u .Quantity | na .AbstractScalar = 0
207
- """The temperature of the FPGA when each image was captured."""
208
-
209
- temperature_adc_1 : u .Quantity | na .AbstractScalar = 0
210
- """Temperature 1 of the ADC when each image was captured."""
211
-
212
- temperature_adc_2 : u .Quantity | na .AbstractScalar = 0
213
- """Temperature 2 of the ADC when each image was captured."""
214
-
215
- temperature_adc_3 : u .Quantity | na .AbstractScalar = 0
216
- """Temperature 3 of the ADC when each image was captured."""
217
-
218
- temperature_adc_4 : u .Quantity | na .AbstractScalar = 0
219
- """Temperature 4 of the ADC when each image was captured."""
220
-
221
156
@classmethod
222
157
def _calibrate_timedelta (cls , value : int ) -> u .Quantity :
223
158
return value * 0.000000025 * u .s
@@ -338,23 +273,40 @@ def from_fits(
338
273
temperature_adc_3 = cls ._calibrate_temperature_adc_234 (temperature_adc_3 )
339
274
temperature_adc_4 = cls ._calibrate_temperature_adc_234 (temperature_adc_4 )
340
275
276
+ shape = data .shape
277
+
278
+ shape_img = {
279
+ axis_x : shape [axis_x ],
280
+ axis_y : shape [axis_y ],
281
+ }
282
+
283
+ pixel = na .indices (shape_img )
284
+
285
+ pixel = na .Cartesian2dVectorArray (
286
+ x = pixel [axis_x ],
287
+ y = pixel [axis_y ],
288
+ )
289
+
341
290
return cls (
342
- data = data ,
291
+ inputs = ImageHeader (
292
+ pixel = pixel ,
293
+ time = time ,
294
+ timedelta = timedelta ,
295
+ timedelta_requested = timedelta_requested ,
296
+ serial_number = serial_number ,
297
+ run_mode = run_mode ,
298
+ status = status ,
299
+ voltage_fpga_vccint = voltage_fpga_vccint ,
300
+ voltage_fpga_vccaux = voltage_fpga_vccaux ,
301
+ voltage_fpga_vccbram = voltage_fpga_vccbram ,
302
+ temperature_fpga = temperature_fpga ,
303
+ temperature_adc_1 = temperature_adc_1 ,
304
+ temperature_adc_2 = temperature_adc_2 ,
305
+ temperature_adc_3 = temperature_adc_3 ,
306
+ temperature_adc_4 = temperature_adc_4 ,
307
+ ),
308
+ outputs = data ,
343
309
axis_x = axis_x ,
344
310
axis_y = axis_y ,
345
- time = time ,
346
- timedelta = timedelta ,
347
- timedelta_requested = timedelta_requested ,
348
311
sensor = sensor ,
349
- serial_number = serial_number ,
350
- run_mode = run_mode ,
351
- status = status ,
352
- voltage_fpga_vccint = voltage_fpga_vccint ,
353
- voltage_fpga_vccaux = voltage_fpga_vccaux ,
354
- voltage_fpga_vccbram = voltage_fpga_vccbram ,
355
- temperature_fpga = temperature_fpga ,
356
- temperature_adc_1 = temperature_adc_1 ,
357
- temperature_adc_2 = temperature_adc_2 ,
358
- temperature_adc_3 = temperature_adc_3 ,
359
- temperature_adc_4 = temperature_adc_4 ,
360
312
)
0 commit comments