1# CHART Table definition files for raw or derived tables or views
  2
  3namespace xsi = "http://www.w3.org/2001/XMLSchema-instance"
  4
  5start = table
  6
  7table = element table  {
  8    # attribute xmlns:xsi { "http://www.w3.org/2001/XMLSchema-instance" } &
  9    attribute xsi:noNamespaceSchemaLocation { text } &
 10        # "http://chart/eps/schemas/table.xsd" |
 11        # "http://chart/s3/schemas/table.xsd" |
 12        # "http://chart/msg/schemas/table.xsd" } &
 13        # "http://chart/gsasr/schemas/table.xsd" } &
 14
 15    ## table description string
 16    element description { text } &
 17
 18    ## Link to wiki or other page describing this table.
 19    element url { text }? &
 20
 21    ## nominal frequency for this table. Should be set to a reasonable value even for tables with
 22    ## irregular frequency
 23    element period { xsd:duration }? &  # frequency should be forced for ts tables
 24
 25    ## true if this table does not have a regular frequency
 26    element regular { xsd:boolean }? &
 27
 28    ## Mark flat tables as spare, meaning they get an extra per-column CNT (count)
 29    ## statistic
 30    element sparse { xsd:boolean }? &
 31
 32    ## true if this ts table has an associated calibration view
 33    element has-cal { xsd:boolean }? &
 34
 35    ## basic table usage
 36    element type { "raw" | "view" | "derived" | "storage" | "stats" }? &
 37
 38    ## table should have day/night regions computed in extended statistics table
 39    ## could be merged with stats-storage?
 40    element day-night-stats { xsd:boolean }? &
 41
 42    ## override the default datatype for `sensing_time` field
 43    element sensing-time-type { "datetime" | "datetime_ms" | "datetime_us" }? &
 44
 45    ## allow to hide in plot tool tree view
 46    element visible { xsd:boolean }? &
 47
 48    ## MSG specific
 49    element source { "DP" }? &
 50
 51    ## for Views, list each <source-table> here
 52    ## Not to be used with sys, raw or derived tables
 53    element source-table { text }* &  # view only
 54
 55    ## for time-series tables with >250 fields which must have seperate _MINS, _MAXS, _AVGS
 56    ## and _STDS tables for orbital stats.
 57    ## Not used in sys tables
 58    element stats-storage { 'none' | 'single' | 'split' }? &  # ts only
 59
 60    ## Allow tables to declare their stats are stored in a separate, explicitly defined
 61    ## table instead of an automatically generated one
 62    element stats-table { text }? &
 63
 64    ## For 'tables' stored inside a JSONB column, specify a different table to hold
 65    ## parameter name<->keymap lookups. Other table must have a fixed definition;
 66    ## see chartjcs project or documentation for details.
 67    ## Set as an attribute of the table not the individual column
 68    element keycodes { test }? &
 69
 70    ## Specify the underlying database table name to associate with this table
 71    element db-name { text }? &
 72
 73    ## configure hashed split parameters for JSONB stats table
 74    element split-params {
 75        # Number of hash bins
 76        element bins { xsd:unsignedInt } &
 77        # Database table name template (Python format(); use "i" as variable)
 78        element db-name-template { text }
 79    }? &
 80
 81    ## all-points table type
 82    element storage { 'timeseries' | 'key-value' | 'jsonb' }? &
 83
 84    ## some types of storage (JSONB and custom) need a parameter to give the actual
 85    ## table the data is stored in
 86    element storage-table { text }? &
 87
 88    ## column in storage table used to hold JSONB values
 89    element storage-column { text }? &
 90
 91    ## (unused) display name for storage
 92    element label { text }? &
 93
 94    ## For tables storing PUS statistics we record the column used for the
 95    ## structures. This is set in the all-points table using the stats,
 96    ## not in the stats table
 97    element stats-column { text }? &
 98
 99    ## Index definitions are optional for timeseries tables and if given, replace the default
100    ## index. For system tables no indexes are created by default and all required indexes
101    ## must be given
102    element index {
103       element name { text }? &
104       element type { "normal" | "unique" | "primary-key" }? &
105       element field { text }+ &
106       element compress { xsd:integer }? &
107       element sid-fields { empty }?
108    }* &
109
110    ## For raw tables we can specifcy the source SF00 file
111    element source-sf00 {  # raw only
112        ## SF00 assembly ID identifiing the data type of input file
113        element assembly-id { xsd:unsignedInt } &
114
115        ## name of SF00 file. Should match values in common/sf.py.
116        element name { text } &
117
118        ## field description
119        element description { text }? &
120
121        ## snack length in bytes, excluding header
122        element length { xsd:unsignedInt }? &
123
124        ## frequency of the input SF00 file
125        element period { xsd:duration } &
126
127        ## To ingest a snack using multiple repeated sections instead of just mapping a single
128        ## snack to a single table row
129        element repeat { xsd:unsignedInt }? &
130
131        ## If `repeat` is used set the byte delta between repeats
132        element stride { xsd:unsignedInt }? &
133
134        ## allows snacks to be ingested conditionally
135        element condition { test }? &
136
137        ## time-offset is applied to the GRH timestamp of each snack as it is ingested
138        element time-offset { xsd:duration }?  # ts only
139    }? &
140
141    ## List of fields to be included in a unique index
142    ## sys tables only.
143    #element unique {
144    #    element name { text }+
145    #}? &
146    group* &
147    field* &
148
149    ## for Views only, the SQL source
150    element view-sql { text }?  # views only
151}
152
153## fields can be grouped, recursively
154group = element group {
155   element description { text }? &
156   element name { text } &
157   group* &
158   field*
159}
160
161## fields can exist inside a table or a group
162field = element field {
163    ## field name
164    element name { text } &
165
166    ## for keyvalue stores only the key
167    element key { xsd:integer }? &
168
169   ## MSG uses these, currently for information only
170   element category { text }? &
171
172    ## field data type
173    element datatype {
174        "boolean" |
175        "int" |
176        "uint" |
177        "float" |
178        "double" |
179        "hirs-signed" |  # special type of signed integer in HIRS raw data; see ICD
180        "inverted-uint" |  # unsigned integer with inverted bits, used in SEM data
181        "MIL1750a" |  # floating point encoding
182        "string" |
183        "unicode" |
184        "xml" |
185        "date" |
186        "datetime" |
187        "datetime_ms" |
188        "jsonb" |
189        "gen_datetime" |  # sys only
190        "autoincrement "}? &  # sys only
191
192    ## Database engine compression method for column
193    element compression { "default" | "none" | "lz4" }? &
194
195    ## if we need to use a non-standard method to read binary values into this field
196    element decoder {
197        "hirs-signed" |
198        "inverted-uint" |
199        "MIL1750a"
200    }? &
201
202    ## define special display criteria
203    element display { "pidref" }? &
204
205    ## for int and string types, give the size in chars (string) or bits (int or uint)
206    element length { xsd:unsignedInt { maxInclusive="10000" } }? &  # length also used by string
207
208    ## field description
209    element description { text }? &
210
211    ## name of calibration function
212    element calibration-name { text }? &
213
214    ## do we allow NULL values?
215    element allow-null { xsd:boolean }? &
216
217    ## allow indexes to be declared for individual fields inline
218    element index {
219        "true" |
220        "primary-key" }? &  # sys only
221
222    ## field unit
223    element unit { text }? &
224
225    ## restrict the field values to a list of enumerated values
226    element choices {
227        element description { text }? &
228        element item {
229            ## value is required for raw tables only
230            element value { xsd:integer }? &
231
232            ## for names representing a range of values
233            element min-value { xsd:integer }? &
234
235            ## for names representing a range of values
236            element max-value { xsd:integer }? &
237
238            ## value name
239            element name { text } &
240
241            ## description of item
242            element description { text }?
243        }+
244    }? &
245
246    ## name of calibration function
247    element calibration { text }? &
248    element position { xsd:unsignedInt }? &  # raw only
249    ## Apply a bitwise AND against eaw values
250    element mask { text }? &  # raw only
251    ## Apply a bit shift to raw values
252    element shift { xsd:unsignedInt }? &  # raw only
253    element validity-group { text }? &  # raw only
254    element validity-group-prime { text }? &  # raw only
255    ## Ingested data of this value will be recorded as database NULLs
256    element invalid { text }? &
257    element limits | raw-limits {
258        element red {
259            ## many limits values must be evaluated i.e. 10-25
260            element low { text }? &  # xsd:float
261            element high { text }?
262        }? &
263        element yellow {
264            element low { text }? &
265            element high { text }?
266        }?
267    }? &
268    element hidden { xsd:boolean }? &
269    element default { text }? &
270    ## For PUS ingestion of datetime objects we allow the number of bytes of coarse
271    ## time (seconds) to be specified. Remaining bytes are fine time (proportion of
272    # second)
273    element coarse-time-length { xsd:unsignedInt }? &
274    ## For PUS ingestion a parameter may be defined as deduced, meaning it is a debug
275    ## parameter based on the definition given by the value of a different parameter
276    element related { text }?
277}
278
279## tests are applied against individual bytes
280test = element test {
281    ## byte offset to be tested
282    element position { xsd:unsignedInt } &
283    element shift { xsd:unsignedInt }? &
284    element mask { text }? & (
285## a clause can use either <equals> a specific value, or give a range from <min-value>
286## to <max-value>. Unbounded ranges can be specified by omitting either min or max value
287        element equals { xsd:unsignedInt } |
288        (element min-value { xsd:unsignedInt }? &
289            element max-value { xsd:unsignedInt }?
290        ) )
291}* &
292    element and { test* }* &
293    element or { test* }*