This is a description of level1 package's data retrieval from the archives for both CRIS and SIS. It will cover both the C libraries and the corresponding routines in IDL. Differences between CRIS and SIS and C and IDL will be noted where necessary.
${ACE_WARE}/lib/and are called
libCrisGetData.a libSisGetData.a libUtilities.aand the associated header files
crisGetData.h sisGetData.h utilities.hare at
${ACE_WARE}/include/level1/prototype/Definitions of the CRIS and SIS data structures can be found in
${ACE_WARE}/include/structures/ ${ACE_WARE}/include/structures/cris/ ${ACE_WARE}/include/structures/sis/
The actual code for all level1 package routines is kept in
${ACE_WARE}/pkgs/level1/src/lib/For download and remote installation of these libraries, see the ACEware packages installation notes. Also, mostly for the purposes of porting the libraries, here is the documentation on the low level C routines used in the libraries.
${ACE_WARE}/idl/level1/lib/Definitions for all the IDL structs for the CRIS/SIS data are in
${ACE_WARE}/idl/structures/
All data structs also have a time interval in which they are valid. Most of the data structs have a constant periododicity, such as an event cycle's 256 second period or a summary's 1 second period. A few data structs, such as command table structs do not have a constant periododicity, but instead have an explicit end time stamp associated with the data. In the descriptions here, "endSecond" will refer either to ((secondsSince1996 - 1 sec) + period) for those structs with a constant periododicity, or to the ending time stamp in non-periodic data structs.
A general rule we decided upon when returning data structs is that we always return an array of structs (even when you think you are only asking for an individual struct). The last struct in this array will always be a zeroed struct. It is easy to spot because it will be the only struct in the array which has a time stamp equal to 0.
There are 2 reasons for this. First, it is an easy way in IDL and C to deal with the case of no data being found. In this case, you will get an array of length 1, whose only element is the terminal zeroed structure. Second, there is the possibility due to quirks in the spacecraft clock and/or other anomolies that more than one struct will be tagged as valid during a particular interval which would usually just have a single valid struct. All such structs will be returned to the user who must decide what to do with them.
In order to make it easy to shift from archive to archive in cases where different tests may be being performed on archiving data, the user needs to set the environment variable L1_CRIS_DATA_BASE_DIRECTORY to access CRIS archives and L1_SIS_DATA_BASE_DIRECTORY to access SIS archives. For example,
setenv L1_SIS_DATA_BASE_DIRECTORY ${ACE_DATA}/level1/data/sis3
Also note that there are many utility routines available for dealing with times and dates in the C utilities library and the IDL utilities library. E.g., determing the start secondsSince1996 for a particular day will not be difficult.
C only: the argument "autoMemoryFreeFlag" in the routines below is required for handling the issue of memory management. When a large array is allocated in C, it should be deallocated when the array is no longer needed. If autoMemoryFreeFlag is set (meaning autoMemoryFreeFlag = 1), the routine will automatically deallocate the memory for the array it last passed back to the user before allocating memory for the new array it will now return. This means that anything pointing to the old array will no longer be valid. If the user wishes to keep data from a previous call available past a subsequent call to the same routine, they should pass autoMemoryFreeFlag = 0. The pointer returned to the user will not be tracked by the subroutine, and the user will assume the responsibility for freeing the allocated memory when they have finished with the data.
struct BrowseCris *getBrowseParamStruct_c(secondsSince1996, autoMemoryFreeFlag); struct L1CrisCommandEcho *getCmdEchoStruct_c(secondsSince1996, autoMemoryFreeFlag); struct L1CrisCommandTable *getCmdTableStruct_c(secondsSince1996, autoMemoryFreeFlag); struct L1CrisCommandTableA *getCmdTableStruct_A_c(secondsSince1996, autoMemoryFreeFlag); struct L1CrisDiagnosticEvent *getDiagnosticEventStruct_c(secondsSince1996, autoMemoryFreeFlag); struct L1CrisEventCycle *getEventCycleStruct_c(secondsSince1996, autoMemoryFreeFlag); struct L1CrisHighPriorityRate *getHiRateStruct_c(secondsSince1996, autoMemoryFreeFlag); struct L1CrisHskp *getHskpStruct_c(secondsSince1996, autoMemoryFreeFlag); struct L1CrisLowPriorityRate *getLoRateStruct_c(secondsSince1996, autoMemoryFreeFlag); struct L1CrisSubset *getSubsetStruct_c(secondsSince1996, autoMemoryFreeFlag); struct L1CrisSummary *getSummaryStruct_c(secondsSince1996, autoMemoryFreeFlag);
struct BrowseSis *getBrowseParamStruct_s(secondsSince1996, autoMemoryFreeFlag); struct L1SisCommandEcho *getCmdEchoStruct_s(secondsSince1996, autoMemoryFreeFlag); struct L1SisCommandTable *getCmdTableStruct_s(secondsSince1996, autoMemoryFreeFlag); struct L1SisDacOffset0 *getDacOffset0Struct_s(secondsSince1996, autoMemoryFreeFlag); struct L1SisDacOffset1 *getDacOffset1Struct_s(secondsSince1996, autoMemoryFreeFlag); struct L1SisDiagnosticEvent *getDiagnosticEventStruct_s(secondsSince1996, autoMemoryFreeFlag); struct L1SisEventCycle *getEventCycleStruct_s(secondsSince1996, autoMemoryFreeFlag); struct L1SisHighPriorityRate *getHiRateStruct_s(secondsSince1996, autoMemoryFreeFlag); struct L1SisHskp *getHskpStruct_s(secondsSince1996, autoMemoryFreeFlag); struct L1SisLowPriorityRate *getLoRateStruct_s(secondsSince1996, autoMemoryFreeFlag); struct L1SisSubset *getSubsetStruct_s(secondsSince1996, autoMemoryFreeFlag); struct L1SisSummary *getSummaryStruct_s(secondsSince1996, autoMemoryFreeFlag);
The getEvents routines return an array of event structures uncompressed from the event cycle pointed to by secondsSince1996.
Important note: Because uncompressed event structures will be too large if arbitrary start and stop times are used, this is the only direct way to get events. I.e., there are no getGroupEvents or getDaysEvents routines. The sample code in this section shows how to step through a day's worth of events using the getEvents routines.
Also, be aware that a data struct which is valid at secondsSince1996Stop will not be returned unless it is the same data struct which is valid at secondsSince1996Start. See note below for more details.
There is no getGroupEvents because the event arrays will be too large. To access events, the Getting Events section above.
struct BrowseCris *getGroupBrowseParams_c(secondsSince1996Start, secondsSince1996Stop, autoMemoryFreeFlag); struct L1CrisCommandEcho *getGroupCmdEchoes_c(secondsSince1996Start, secondsSince1996Stop, autoMemoryFreeFlag); struct L1CrisCommandTable *getGroupCmdTables_c(secondsSince1996Start, secondsSince1996Stop, autoMemoryFreeFlag); struct L1CrisCommandTableA *getGroupCmdTables_A_c(secondsSince1996Start, secondsSince1996Stop, autoMemoryFreeFlag); struct L1CrisDiagnosticEvent *getGroupDiagnosticEvents_c(secondsSince1996Start, secondsSince1996Stop, autoMemoryFreeFlag); struct L1CrisHighPriorityRate *getGroupHiRates_c(secondsSince1996Start, secondsSince1996Stop, autoMemoryFreeFlag); struct L1CrisHskp *getGroupHskps_c(secondsSince1996Start, secondsSince1996Stop, autoMemoryFreeFlag); struct L1CrisLowPriorityRate *getGroupLoRates_c(secondsSince1996Start, secondsSince1996Stop, autoMemoryFreeFlag); struct L1CrisSubset *getGroupSubsets_c(secondsSince1996Start, secondsSince1996Stop, autoMemoryFreeFlag); struct L1CrisSummary *getGroupSummarys_c(secondsSince1996Start, secondsSince1996Stop, autoMemoryFreeFlag);
struct BrowseSis *getGroupBrowseParams_s(secondsSince1996Start, secondsSince1996Stop, autoMemoryFreeFlag); struct L1SisCommandEcho *getGroupCmdEchoes_s(secondsSince1996Start, secondsSince1996Stop, autoMemoryFreeFlag); struct L1SisCommandTable *getGroupCmdTables_s(secondsSince1996Start, secondsSince1996Stop, autoMemoryFreeFlag); struct L1SisDacOffset0 *getGroupDacOffset0s_s(secondsSince1996Start, secondsSince1996Stop, autoMemoryFreeFlag); struct L1SisDacOffset1 *getGroupDacOffset1s_s(secondsSince1996Start, secondsSince1996Stop, autoMemoryFreeFlag); struct L1SisDiagnosticEvent *getGroupDiagnosticEvents_s(secondsSince1996Start, secondsSince1996Stop, autoMemoryFreeFlag); struct L1SisHighPriorityRate *getGroupHiRates_s(secondsSince1996Start, secondsSince1996Stop, autoMemoryFreeFlag); struct L1SisHskp *getGroupHskps_s(secondsSince1996Start, secondsSince1996Stop, autoMemoryFreeFlag); struct L1SisLowPriorityRate *getGroupLoRates_s(secondsSince1996Start, secondsSince1996Stop, autoMemoryFreeFlag); struct L1SisSubset *getGroupSubsets_s(secondsSince1996Start, secondsSince1996Stop, autoMemoryFreeFlag); struct L1SisSummary *getGroupSummarys_s(secondsSince1996Start, secondsSince1996Stop, autoMemoryFreeFlag);
IMPORTANT NOTE: (both C and IDL)
The structs array will always contain the data struct which was valid (see
notes above for definition of "valid") at secondsSince1996Start if such a
struct exists, no matter what value secondsSince1996Stop has. Then, if
there are more structs time stamped before secondsSince1996Stop, they will
be included as well. If the last struct is valid at secondsSince1996Stop,
it WILL NOT be included in the structs array. The reason for this is
to prevent seemingly contiguous time interval requests from getting
overlapping data. In order to be sure you are getting all of the data
as you process contiguous time intervals, a subsequent call to a get_group
routine should have a secondsSince1996Start value EQUAL to the last
call's secondsSince1996Stop value.
But this does not remove all ambiguity, because if the time interval
secondsSince1996Start to secondsSince1996Stop is smaller than the time
a single data struct is valid, then such a call will return the struct
valid at secondsSince1996Start, and the subsequent call to the next
contiguous time interval could also return said data struct. Obviously,
this is a silly case which can easily be avoided by being sure your
time interval secondsSince1996Start to secondsSince1996Stop is longer
than a single cycle.
Important!: You need to understand how a full day's worth of data is defined- The first struct in the array returned by these routines is the data struct which is valid (if such exists) at the zeroth second of the day in question. The last (non-zero) struct returned in this array will be the latest data struct which does not overlap into the next day. What this means is that usually the time stamp on the first struct will be slightly earlier than the 0th second of the day in question. (The only times this will not be true is if either a data struct is time stamped exactly at the day's 0th second, or if there is no data struct valid at that 0th second.)
The array of structs returned by these routines will (as usual) terminate in a zeroed struct.
Again, there is no get_days_events routine because of the size of the array which would be returned. (See Getting Events above.)
The input aceTimeStructForDay is an {AceTime} struct defined as
data_struct = {AceTime, $ year: 0L, $ month: 0L, $ day: 0L, $ hour: 0L, $ min: 0L, $ sec: 0L}and can be set as is shown in the Sample code.
Return to level1 Documentation Table of Contents
bruce