Home → Documentation Home → Simulation Capabilities → Data Record |
---|
Data Recording provides the capability to specify any number of data recording groups, each with an unlimited number of parameter references, and with each group recording at different frequencies to different files in different formats.
All data is written to the simulation output directory.
Trick allows recording in three different formats. Each recording group is readable by different external tools outside of Trick.
DRHDF5 recording support is off by default. To enable DRHDF5 support Trick must be built with HDF5 support. Go to http://www.hdf5group.org and download the latest pre-built hdf5 package for your system. Source packages are available as well. We recommend getting the static library packages above the shared. Static packages make your executable larger, but you will not have to deal with LD_LIBRARY issues. The HDF5 package may be installed anywhere on your system. To tell Trick you have HDF5 run ${TRICK_HOME}/configure --with-hdf5=/path/to/hdf5. Re-compile Trick to enable HDF5 support.
To create a new recording group, in the Python input file instantiate a new group by format name: <variable_name> = trick.<data_record_format>() ;
For example:
drg = trick.DRBinary() ;
Note: drg is just an example name. Any name may be used.
To add variables to the recording group call the drg.add_variable("<string_of_variable_name>") method of the recording group. For example:
drg.add_variable("ball.obj.state.output.position[0]")
drg.add_variable("ball.obj.state.output.position[1]")
In this example position
is an array of floating point numbers. DO NOT ATTEMPT TO DATA RECORD C OR C++ STRINGS. THIS HAS BEEN OBSERVED TO CREATE MEMORY ISSUES AND TRICK DOES NOT CURRENTLY PROVIDE ERROR CHECKING FOR THIS UNSUPPORTED USE CASE
An optional alias may also be specified in the method as drg.add_variable("<string_of_variable_name>" [, "
If an alias is present as a second argument, the alias name will be used in the data recording file instead of the actual variable name.
For example:
drg.add_variable("ball.obj.state.output.position[0]", "x_pos")
drg.add_variable("ball.obj.state.output.position[1]", "y_pos")
Only individual primitive types can be recorded. Arrays, strings/char *, structured objects, or STL types are not supported.
To change the recording rate call the set_cycle() method of the recording group.
drg.set_cycle(0.01)
Data recording groups have three buffering options:
To set the buffering technique call the set_buffer_type(trick.<buffering_option>) method of the recording group. For example:
drg.set_buffer_type(trick.DR_Buffer)
All buffering options (except for DR_No_Buffer) have a maximum amount of memory allocated to holding data. See Trick::DataRecordGroup::set_max_buffer_size for buffer size information.
Data recording groups have three recording frequency options:
To set the recording frequency call the set_freq(trick.<frequency_option>) method of the recording group. For example:
drg.set_freq(trick.DR_Changes)
For DR_Changes or DR_Changes_Step, to specify parameter(s) to watch that will control when the variables added with add_variable are recorded, call the add_change_variable(string) method of the recording group. For example:
drg.add_change_variable("ball.obj.state.output.velocity[0]")
So if we assume the add_variable statements from the example in @ref S_7_8_3 "7.8.3" combined with the above add_change_variable statement, then ball.obj.state.output.position[0] and ball.obj.state.output.position[1] will be recorded only when ball.obj.state.output.velocity[0] changes. Multiple parameters may be watched by adding more change variables, in which case data will be recorded when any of the watched variable values change.
At any time during the simulation, model code or the input processor can turn on/off individual recording groups as well as record a single point of data.
/* C code */
dr_enable_group("<group_name>") ;
dr_disable_group("<group_name>") ;
dr_record_now_group("<group_name>") ;
This is the Python input file version:
# Python code
trick.dr_enable_group("<group_name>") ; # same as <group_name>.enable()
trick.dr_disable_group("<group_name>") ; # same as <group_name>.disable()
trick.dr_record_now_group("<group_name>") ;
To change the thread that the data recording group runs on use the DataRecordGroup::set_thread method. The thread number follows the same numbering as the child threads in the S_define file. This must be done before the add_data_record_group function is called. Trick does not provide data locks for data record groups. It is up to the user to ensure that the data recorded on any thread (including the master) is ready in order for data recording to record a time homogeneous set of data.
drg.set_thread(<thread_number>)
The default job class of a data record group is "data_record". This job class is run after all of the cyclic job classes have completed. The job class of the data record group can be changed through the set_job_class method. The data recording job will be added to the end of the job class queue it is set.
drg.set_job_class(<string class_name>)
The default size of a data record is 1 GiB. A new size can be set through the set_max_file_size method. For unlimited size, pass 0.
drg.set_max_file_size(<uint64 file_size_in_bytes>)
This is an example of a data recording group in the input file
# Data recording HDF5 test
drg0 = trick.DRHDF5("Ball")
drg0.add_variable("ball.obj.state.output.position[0]")
drg0.add_variable("ball.obj.state.output.position[1]")
drg0.add_variable("ball.obj.state.output.velocity[0]")
drg0.add_variable("ball.obj.state.output.velocity[1]")
drg0.add_variable("ball.obj.state.output.acceleration[0]")
drg0.add_variable("ball.obj.state.output.acceleration[1]")
drg0.set_cycle(0.01)
drg0.freq = trick.DR_Always
trick.add_data_record_group(drg0, trick.DR_Buffer)
# This line is to tell python not to free this memory when drg0 goes out of scope
drg0.thisown = 0
Create a new data recording group:
Trick::DRAscii::DRAscii(string in_name);
Trick::DRBinary::DRBinary(string in_name);
Trick::DRHDF5::DRHDF5(string in_name);
This list of routines is for all recording formats:
int dr_disable_group( const char * in_name );
int dr_enable_group( const char * in_name );
int dr_record_now_group( const char * in_name );
int Trick::DataRecordGroup::add_variable
int Trick::DataRecordGroup::add_change_variable
int Trick::DataRecordGroup::disable
int Trick::DataRecordGroup::enable
int Trick::DataRecordGroup::set_cycle
int Trick::DataRecordGroup::set_freq
int Trick::DataRecordGroup::set_job_class
int Trick::DataRecordGroup::set_max_buffer_size
This list of routines provide file size configuration for Ascii and Binary:
int set_max_size_record_group (const char * in_name, uint64_t bytes ) ;
int dr_set_max_file_size ( uint64_t bytes ) ;
int Trick::DataRecordGroup::set_max_file_size
This list of routines provide some additional configuration for DR_Ascii format only:
int Trick::DRAscii::set_ascii_double_format
int Trick::DRAscii::set_ascii_float_format
int Trick::DRAscii::set_delimiter
int Trick::DataRecordGroup::set_single_prec_only
The DRAscii recording format is a comma separated value file named log_<group_name>.csv. The contents of this file type are readable by the Trick Data Products packages, ascii editors, and Microsoft Excel. The format of the file follows. Users are able to change the comma delimiter to another string. Changing the delimiter will change the file extension from ".csv" to ".txt".
name_1 {units_1},name_2 {units_2},etc...
value1,value2,etc...
value1,value2,etc...
value1,value2,etc...
value1,value2,etc...
The DRBinary recording format is a Trick simulation specific format. Files written in this format are named log_<group_name>.trk. The contents of this file type are readable by the Trick Data Products packages from Trick 07 to the current version. The format of the file follows.
Value | Description | Type | #Bytes |
---|---|---|---|
Trick-<vv>-<e> | <vv> is trick version (2 chars, "07" or "10"). <e> is endianness (1 char) 'L' -> little endian, and 'B' -> big endian. | char | 10 |
numparms | Number of recorded variables | char | 4 |
List of Variable Descriptors | Variable-Descriptor-List | ||
List Data Records | Data-Record-List | ||
EOF | End of File |
A Variable-Descriptor-List is a sequence of Variable-Descriptors. The number of descriptors in the list is specified by numparms. The list describes each of the recorded variables, starting with the simulation time variable.
Value | Description | Type | #Bytes |
---|---|---|---|
Time-Variable-Descriptor | Descriptor for Variable # 1. This first descriptor always represents the simulation time variable. | Variable-Descriptor | 34 |
... | ... | ... | ... |
Descriptor for Variable # numparms | Variable-Descriptor | variable |
A Variable-Descriptor describes a recorded variable.
Value | Description | Type | Bytes |
---|---|---|---|
namelen | Length of Variable Name | int | 4 |
name | Variable Name | namelen | |
unitlen | Length of Variable Units | int | 4 |
unit | Variable Units | unitlen | |
type | Variable Type (see Notes 2. & 3.) | int | 4 |
sizeof(type) | Variable Type Size | int | 4 |
Notes:
Value | Description | Type | Bytes |
---|---|---|---|
17 | Length of Variable Name | int | 4 |
sys.exec.out.time |
Variable Name | char | 17 |
1 | Length of Variable Units | int | 4 |
s |
Variable Units (see Note 1.) | char | 1 |
11 | Variable Type | int | 4 |
8 | Variable Type Size | int | 4 |
Notes:
A Data-Record-List contains a collection of Data-Records, at regular times.
Value | Description | Type | Bytes |
---|---|---|---|
Data-Record #1 | Data-Record | ||
... | ... | ... | ... |
Data-Record #Last | Data-Record |
A Data-Record contains a collection of values for each of the variables we are recording, at a specific time.
Value | Description | Type | Bytes |
---|---|---|---|
time | Value of Variable #1 (time) | typeof( Variable#1 ) | sizeof( typeof( Variable#1)) = 8 |
... | ... | ... | ... |
value | Value of Variable #numparms | typeof( Variable#numparms) | sizeof( type-of( Variable#numparms)) |
The following data-types were used in Trick-07 data recording files (that is for, vv = "07").
Type value | Data Type |
---|---|
0 | char |
1 | unsigned char |
2 | string (char*) |
3 | short |
4 | unsigned short |
5 | int |
6 | unsigned int |
7 | long |
8 | unsigned long |
9 | float |
10 | double |
11 | Bit field |
12 | unsigned Bit field |
13 | long long |
14 | unsigned long long |
17 | Boolean (C++) |
The following data-types are used in Trick versions >= 10, that is for, vv = "10".
Type value | Data Type |
---|---|
1 | char |
2 | unsigned char |
4 | short |
5 | unsigned short |
6 | int |
7 | unsigned int |
8 | long |
9 | unsigned long |
10 | float |
11 | double |
12 | Bit field |
13 | unsigned Bit field |
14 | long long |
15 | unsigned long long |
17 | Boolean (C++)`` |
HDF5 recording format is an industry conforming HDF5 formatted file. Files written in this format are named log_<group_name>.h5. The contents of this file type are readable by the Trick Data Products packages from Trick 07 to the current version. The contents of the file are binary and is not included here. The HDF5 layout of the file follows.
GROUP "/" {
GROUP "header" {
DATASET "file_names" {
"param_1_file_name", "param_2_file_name", etc...
}
DATASET "param_names" {
"param_1_name", "param_2_name", etc...
}
DATASET "param_types" {
"param_1_type", "param_2_type", etc...
}
DATASET "param_units" {
"param_1_units", "param_2_units", etc...
}
}
DATASET "parameter #1" {
value1 , value2 , value3 , etc...
}
DATASET "parameter #2" {
value1 , value2 , value3 , etc...
}
.
.
.
DATASET "parameter #n" {
value1 , value2 , value3 , etc...
}
}
Data recording groups are able to be checkpointed, reloaded, and restarted without any interaction by the user. When a checkpoint is loaded that includes data recording, the data recording groups will be initiated and begin recording at the time in the checkpoint. For example, if a checkpoint was dumped when t=5, when the checkpoint is loaded into another run, it will data record starting at t=5, no matter what time in the run it was loaded or whether the run was already data recording. Loading a checkpoint will overwrite any data recording files that were being recorded before the load.
Loading a checkpoint with different data recording groups than the current run will overwrite the current data recording groups.
Refer to test/SIM_checkpoint_data_recording to see expected behavior in action. Overall, the loading a checkpoint should completely overwrite any other data recording the sim is currently doing, and the new recording will start at the time in the checkpoint. If you come across different behavior, please open an issue.