-
Notifications
You must be signed in to change notification settings - Fork 22
IDEX Update event time calculation #2664
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -95,8 +95,8 @@ def __init__(self, packet_file: str | Path) -> None: | |||||||||||||||
| data.attrs = self.idex_attrs.get_global_attributes( | ||||||||||||||||
| f"imap_idex_{level}_evt" | ||||||||||||||||
| ) | ||||||||||||||||
| data["epoch"] = calculate_idex_epoch_time( | ||||||||||||||||
| data["shcoarse"], data["shfine"] | ||||||||||||||||
| data["epoch"] = calculate_idex_event_time( | ||||||||||||||||
| data["shfine"].data, data["shcoarse"].data | ||||||||||||||||
| ) | ||||||||||||||||
| data["epoch"].attrs = epoch_attrs | ||||||||||||||||
| self.data.append(data) | ||||||||||||||||
|
|
@@ -107,8 +107,8 @@ def __init__(self, packet_file: str | Path) -> None: | |||||||||||||||
| data.attrs = self.idex_attrs.get_global_attributes( | ||||||||||||||||
| f"imap_idex_{level}_catlst" | ||||||||||||||||
| ) | ||||||||||||||||
| data["epoch"] = calculate_idex_epoch_time( | ||||||||||||||||
| data["shcoarse"], data["shfine"] | ||||||||||||||||
| data["epoch"] = calculate_idex_event_time( | ||||||||||||||||
| data["shfine"].data, data["shcoarse"].data | ||||||||||||||||
| ) | ||||||||||||||||
| data["epoch"].attrs = epoch_attrs | ||||||||||||||||
| self.data.append(data) | ||||||||||||||||
|
|
@@ -248,35 +248,55 @@ def _read_waveform_bits(waveform_raw: str, high_sample: bool = True) -> list[int | |||||||||||||||
| return ints | ||||||||||||||||
|
|
||||||||||||||||
|
|
||||||||||||||||
| def calculate_idex_epoch_time( | ||||||||||||||||
| shcoarse_time: float | np.ndarray, shfine_time: float | np.ndarray | ||||||||||||||||
| def calculate_idex_event_time( | ||||||||||||||||
| fine_time_subs: np.ndarray, | ||||||||||||||||
| coarse_time_sec1: np.ndarray, | ||||||||||||||||
| coarse_time_sec2: np.ndarray | None = None, | ||||||||||||||||
| ) -> npt.NDArray[np.int64]: | ||||||||||||||||
| """ | ||||||||||||||||
| Calculate the epoch time from the FPGA header time variables. | ||||||||||||||||
|
|
||||||||||||||||
| We are given the MET seconds, we need to convert it to nanoseconds in j2000. IDEX | ||||||||||||||||
| epoch is calculated with shcoarse and shfine time values. The shcoarse time counts | ||||||||||||||||
| the number of whole seconds elapsed since the epoch (Jan 1st 2010), while shfine | ||||||||||||||||
| time counts the number of additional 20-microsecond intervals beyond the whole | ||||||||||||||||
| seconds. Together, these time measurements establish when a dust event took place. | ||||||||||||||||
| For science packets, we are given the MET seconds, we need to convert it to | ||||||||||||||||
| nanoseconds in j2000. The idx__txhdrtimesec1 and idx__txhdrtimesec2 variables count | ||||||||||||||||
| the number of whole seconds elapsed since the epoch (Jan 1st 2010), while | ||||||||||||||||
| idx__txhdrtimesubs time counts the number of additional 20-microsecond intervals | ||||||||||||||||
| beyond the whole seconds. Together, these time measurements establish when a dust | ||||||||||||||||
| event took place. | ||||||||||||||||
|
|
||||||||||||||||
| The elapsed seconds are stored as a 32-bit unsigned integer that is split across | ||||||||||||||||
| two 16-bit words for packetization. As a result, idx__txhdrtimesec1 represents | ||||||||||||||||
| multiples of 2^16 seconds, while idx_txhdrtimesec2 represents the remaining seconds | ||||||||||||||||
| within that range. This necessitates scaling the upper word by 2^16 = 65,536 when | ||||||||||||||||
| reconstructing the full seconds counter. | ||||||||||||||||
|
|
||||||||||||||||
| For housekeeping packets, use the shcoarse and shfine variables instead. | ||||||||||||||||
|
|
||||||||||||||||
| Parameters | ||||||||||||||||
| ---------- | ||||||||||||||||
| shcoarse_time : float, numpy.ndarray | ||||||||||||||||
| The coarse time value from the FPGA header. Number of seconds since epoch. | ||||||||||||||||
| shfine_time : float, numpy.ndarray | ||||||||||||||||
| The fine time value from the FPGA header. Number of 20 microsecond "ticks" since | ||||||||||||||||
| the last second. | ||||||||||||||||
| fine_time_subs : numpy.ndarray, optional | ||||||||||||||||
| The lower 16 bits of the coarse event time. | ||||||||||||||||
| coarse_time_sec1 : numpy.ndarray | ||||||||||||||||
| The fine event time in 20-microsecond intervals. | ||||||||||||||||
| coarse_time_sec2 : numpy.ndarray | ||||||||||||||||
| The upper 16 bits of the coarse event time. | ||||||||||||||||
|
|
||||||||||||||||
| Returns | ||||||||||||||||
| ------- | ||||||||||||||||
| numpy.ndarray[numpy.int64] | ||||||||||||||||
| The mission elapsed time converted to nanoseconds since the J2000 epoch | ||||||||||||||||
| in the terrestrial time (TT) timescale. | ||||||||||||||||
| """ | ||||||||||||||||
| # Get met time in seconds including shfine (number of 20 microsecond ticks) | ||||||||||||||||
| met = shcoarse_time + shfine_time * 20e-6 | ||||||||||||||||
| return met_to_ttj2000ns(met) | ||||||||||||||||
| if coarse_time_sec2 is not None: | ||||||||||||||||
| # Reconstruct the total seconds from the two 16-bit words | ||||||||||||||||
| coarse_event_time = 65536 * coarse_time_sec1 + coarse_time_sec2 | ||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am little curious why they want to multiply coarse second time with 65536. I have seen this number is CoDICE and they are doing this: Can you check with them if 65536 should be applied to |
||||||||||||||||
| else: | ||||||||||||||||
| # Use coarse_time_sec1 as the full coarse time (e.g., for housekeeping) | ||||||||||||||||
| coarse_event_time = coarse_time_sec1 | ||||||||||||||||
|
|
||||||||||||||||
| # Calculate the fine event time in seconds | ||||||||||||||||
| fine_event_time = fine_time_subs * 20e-6 | ||||||||||||||||
|
|
||||||||||||||||
| return met_to_ttj2000ns(coarse_event_time + fine_event_time) | ||||||||||||||||
|
|
||||||||||||||||
|
|
||||||||||||||||
| class RawDustEvent: | ||||||||||||||||
|
|
@@ -357,8 +377,10 @@ def __init__(self, header_packet: space_packet_parser.SpacePacket) -> None: | |||||||||||||||
| """ | ||||||||||||||||
| # Calculate the impact time in seconds since epoch | ||||||||||||||||
| self.impact_time = 0 | ||||||||||||||||
| self.impact_time = calculate_idex_epoch_time( | ||||||||||||||||
| header_packet["SHCOARSE"], header_packet["SHFINE"] | ||||||||||||||||
| self.impact_time = calculate_idex_event_time( | ||||||||||||||||
| header_packet["IDX__TXHDRTIMESUBS"], | ||||||||||||||||
| header_packet["IDX__TXHDRTIMESEC1"], | ||||||||||||||||
| header_packet["IDX__TXHDRTIMESEC2"], | ||||||||||||||||
|
Comment on lines
+380
to
+383
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a comment here about what these times are, but I think this might be clearer what is going on (to me at least). You are left-shifting the first timer to the first 16 bits to make a 32-bit integer, so I'd use the bitwise operators (you might need to do this on
Suggested change
|
||||||||||||||||
| ) | ||||||||||||||||
| self.event_number = header_packet["IDX__SCI0EVTNUM"] | ||||||||||||||||
|
|
||||||||||||||||
|
|
||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't optional anymore since it is the first argument, the final coarse_time_sec2 is optional now though.