1<?xml version="1.0" encoding="UTF-8"?>
  2<!-- CHART Table definition files for raw or derived tables or views -->
  3<grammar xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
  4  <start>
  5    <ref name="table"/>
  6  </start>
  7  <define name="table">
  8    <element name="table">
  9      <interleave>
 10        <!-- attribute xmlns:xsi { "http://www.w3.org/2001/XMLSchema-instance" } & -->
 11        <attribute name="xsi:noNamespaceSchemaLocation"/>
 12        <!--
 13          "http://chart/eps/schemas/table.xsd" |
 14          "http://chart/s3/schemas/table.xsd" |
 15          "http://chart/msg/schemas/table.xsd" } &
 16          "http://chart/gsasr/schemas/table.xsd" } &
 17        -->
 18        <element name="description">
 19          <a:documentation>table description string</a:documentation>
 20          <text/>
 21        </element>
 22        <optional>
 23          <element name="url">
 24            <a:documentation>Link to wiki or other page describing this table.</a:documentation>
 25            <text/>
 26          </element>
 27        </optional>
 28        <optional>
 29          <element name="period">
 30            <a:documentation>nominal frequency for this table. Should be set to a reasonable value even for tables with
 31irregular frequency</a:documentation>
 32            <data type="duration"/>
 33          </element>
 34        </optional>
 35        <optional>
 36          <!-- frequency should be forced for ts tables -->
 37          <element name="regular">
 38            <a:documentation>true if this table does not have a regular frequency</a:documentation>
 39            <data type="boolean"/>
 40          </element>
 41        </optional>
 42        <optional>
 43          <element name="sparse">
 44            <a:documentation>Mark flat tables as spare, meaning they get an extra per-column CNT (count)
 45statistic</a:documentation>
 46            <data type="boolean"/>
 47          </element>
 48        </optional>
 49        <optional>
 50          <element name="has-cal">
 51            <a:documentation>true if this ts table has an associated calibration view</a:documentation>
 52            <data type="boolean"/>
 53          </element>
 54        </optional>
 55        <optional>
 56          <element name="type">
 57            <a:documentation>basic table usage</a:documentation>
 58            <choice>
 59              <value>raw</value>
 60              <value>view</value>
 61              <value>derived</value>
 62              <value>storage</value>
 63              <value>stats</value>
 64            </choice>
 65          </element>
 66        </optional>
 67        <optional>
 68          <element name="day-night-stats">
 69            <a:documentation>table should have day/night regions computed in extended statistics table
 70could be merged with stats-storage?</a:documentation>
 71            <data type="boolean"/>
 72          </element>
 73        </optional>
 74        <optional>
 75          <element name="sensing-time-type">
 76            <a:documentation>override the default datatype for `sensing_time` field</a:documentation>
 77            <choice>
 78              <value>datetime</value>
 79              <value>datetime_ms</value>
 80              <value>datetime_us</value>
 81            </choice>
 82          </element>
 83        </optional>
 84        <optional>
 85          <element name="visible">
 86            <a:documentation>allow to hide in plot tool tree view</a:documentation>
 87            <data type="boolean"/>
 88          </element>
 89        </optional>
 90        <optional>
 91          <element name="source">
 92            <a:documentation>MSG specific</a:documentation>
 93            <value>DP</value>
 94          </element>
 95        </optional>
 96        <zeroOrMore>
 97          <element name="source-table">
 98            <a:documentation>for Views, list each &lt;source-table&gt; here
 99Not to be used with sys, raw or derived tables</a:documentation>
100            <text/>
101          </element>
102        </zeroOrMore>
103        <optional>
104          <!-- view only -->
105          <element name="stats-storage">
106            <a:documentation>for time-series tables with &gt;250 fields which must have seperate _MINS, _MAXS, _AVGS
107and _STDS tables for orbital stats.
108Not used in sys tables</a:documentation>
109            <choice>
110              <value>none</value>
111              <value>single</value>
112              <value>split</value>
113            </choice>
114          </element>
115        </optional>
116        <optional>
117          <!-- ts only -->
118          <element name="stats-table">
119            <a:documentation>Allow tables to declare their stats are stored in a separate, explicitly defined
120table instead of an automatically generated one</a:documentation>
121            <text/>
122          </element>
123        </optional>
124        <optional>
125          <element name="keycodes">
126            <a:documentation>For 'tables' stored inside a JSONB column, specify a different table to hold
127parameter name&lt;-&gt;keymap lookups. Other table must have a fixed definition;
128see chartjcs project or documentation for details.
129Set as an attribute of the table not the individual column</a:documentation>
130            <ref name="test"/>
131          </element>
132        </optional>
133        <optional>
134          <element name="db-name">
135            <a:documentation>Specify the underlying database table name to associate with this table</a:documentation>
136            <text/>
137          </element>
138        </optional>
139        <optional>
140          <element name="split-params">
141            <a:documentation>configure hashed split parameters for JSONB stats table</a:documentation>
142            <interleave>
143              <!-- Number of hash bins -->
144              <element name="bins">
145                <data type="unsignedInt"/>
146              </element>
147              <!-- Database table name template (Python format(); use "i" as variable) -->
148              <element name="db-name-template">
149                <text/>
150              </element>
151            </interleave>
152          </element>
153        </optional>
154        <optional>
155          <element name="storage">
156            <a:documentation>all-points table type</a:documentation>
157            <choice>
158              <value>timeseries</value>
159              <value>key-value</value>
160              <value>jsonb</value>
161            </choice>
162          </element>
163        </optional>
164        <optional>
165          <element name="storage-table">
166            <a:documentation>some types of storage (JSONB and custom) need a parameter to give the actual
167table the data is stored in</a:documentation>
168            <text/>
169          </element>
170        </optional>
171        <optional>
172          <element name="storage-column">
173            <a:documentation>column in storage table used to hold JSONB values</a:documentation>
174            <text/>
175          </element>
176        </optional>
177        <optional>
178          <element name="label">
179            <a:documentation>(unused) display name for storage</a:documentation>
180            <text/>
181          </element>
182        </optional>
183        <optional>
184          <element name="stats-column">
185            <a:documentation>For tables storing PUS statistics we record the column used for the
186structures. This is set in the all-points table using the stats,
187not in the stats table</a:documentation>
188            <text/>
189          </element>
190        </optional>
191        <zeroOrMore>
192          <element name="index">
193            <a:documentation>Index definitions are optional for timeseries tables and if given, replace the default
194index. For system tables no indexes are created by default and all required indexes
195must be given</a:documentation>
196            <interleave>
197              <optional>
198                <element name="name">
199                  <text/>
200                </element>
201              </optional>
202              <optional>
203                <element name="type">
204                  <choice>
205                    <value>normal</value>
206                    <value>unique</value>
207                    <value>primary-key</value>
208                  </choice>
209                </element>
210              </optional>
211              <oneOrMore>
212                <element name="field">
213                  <text/>
214                </element>
215              </oneOrMore>
216              <optional>
217                <element name="compress">
218                  <data type="integer"/>
219                </element>
220              </optional>
221              <optional>
222                <element name="sid-fields">
223                  <empty/>
224                </element>
225              </optional>
226            </interleave>
227          </element>
228        </zeroOrMore>
229        <optional>
230          <element name="source-sf00">
231            <a:documentation>For raw tables we can specifcy the source SF00 file</a:documentation>
232            <interleave>
233              <!-- raw only -->
234              <element name="assembly-id">
235                <a:documentation>SF00 assembly ID identifiing the data type of input file</a:documentation>
236                <data type="unsignedInt"/>
237              </element>
238              <element name="name">
239                <a:documentation>name of SF00 file. Should match values in common/sf.py.</a:documentation>
240                <text/>
241              </element>
242              <optional>
243                <element name="description">
244                  <a:documentation>field description</a:documentation>
245                  <text/>
246                </element>
247              </optional>
248              <optional>
249                <element name="length">
250                  <a:documentation>snack length in bytes, excluding header</a:documentation>
251                  <data type="unsignedInt"/>
252                </element>
253              </optional>
254              <element name="period">
255                <a:documentation>frequency of the input SF00 file</a:documentation>
256                <data type="duration"/>
257              </element>
258              <optional>
259                <element name="repeat">
260                  <a:documentation>To ingest a snack using multiple repeated sections instead of just mapping a single
261snack to a single table row</a:documentation>
262                  <data type="unsignedInt"/>
263                </element>
264              </optional>
265              <optional>
266                <element name="stride">
267                  <a:documentation>If `repeat` is used set the byte delta between repeats</a:documentation>
268                  <data type="unsignedInt"/>
269                </element>
270              </optional>
271              <optional>
272                <element name="condition">
273                  <a:documentation>allows snacks to be ingested conditionally</a:documentation>
274                  <ref name="test"/>
275                </element>
276              </optional>
277              <optional>
278                <element name="time-offset">
279                  <a:documentation>time-offset is applied to the GRH timestamp of each snack as it is ingested</a:documentation>
280                  <data type="duration"/>
281                </element>
282              </optional>
283            </interleave>
284            <!-- ts only -->
285          </element>
286        </optional>
287        <zeroOrMore>
288          <!--
289            element unique {
290               element name { text }+
291            }? &
292          -->
293          <ref name="group">
294            <a:documentation>List of fields to be included in a unique index
295sys tables only.</a:documentation>
296          </ref>
297        </zeroOrMore>
298        <zeroOrMore>
299          <ref name="field"/>
300        </zeroOrMore>
301        <optional>
302          <element name="view-sql">
303            <a:documentation>for Views only, the SQL source</a:documentation>
304            <text/>
305          </element>
306        </optional>
307      </interleave>
308      <!-- views only -->
309    </element>
310  </define>
311  <define name="group">
312    <a:documentation>fields can be grouped, recursively</a:documentation>
313    <element name="group">
314      <interleave>
315        <optional>
316          <element name="description">
317            <text/>
318          </element>
319        </optional>
320        <element name="name">
321          <text/>
322        </element>
323        <zeroOrMore>
324          <ref name="group"/>
325        </zeroOrMore>
326        <zeroOrMore>
327          <ref name="field"/>
328        </zeroOrMore>
329      </interleave>
330    </element>
331  </define>
332  <define name="field">
333    <a:documentation>fields can exist inside a table or a group</a:documentation>
334    <element name="field">
335      <interleave>
336        <element name="name">
337          <a:documentation>field name</a:documentation>
338          <text/>
339        </element>
340        <optional>
341          <element name="key">
342            <a:documentation>for keyvalue stores only the key</a:documentation>
343            <data type="integer"/>
344          </element>
345        </optional>
346        <optional>
347          <element name="category">
348            <a:documentation>MSG uses these, currently for information only</a:documentation>
349            <text/>
350          </element>
351        </optional>
352        <optional>
353          <element name="datatype">
354            <a:documentation>field data type</a:documentation>
355            <choice>
356              <value>boolean</value>
357              <value>int</value>
358              <value>uint</value>
359              <value>float</value>
360              <value>double</value>
361              <value>hirs-signed</value>
362              <!-- special type of signed integer in HIRS raw data; see ICD -->
363              <value>inverted-uint</value>
364              <!-- unsigned integer with inverted bits, used in SEM data -->
365              <value>MIL1750a</value>
366              <!-- floating point encoding -->
367              <value>string</value>
368              <value>unicode</value>
369              <value>xml</value>
370              <value>date</value>
371              <value>datetime</value>
372              <value>datetime_ms</value>
373              <value>jsonb</value>
374              <value>gen_datetime</value>
375              <!-- sys only -->
376              <value>autoincrement </value>
377            </choice>
378          </element>
379        </optional>
380        <optional>
381          <!-- sys only -->
382          <element name="compression">
383            <a:documentation>Database engine compression method for column</a:documentation>
384            <choice>
385              <value>default</value>
386              <value>none</value>
387              <value>lz4</value>
388            </choice>
389          </element>
390        </optional>
391        <optional>
392          <element name="decoder">
393            <a:documentation>if we need to use a non-standard method to read binary values into this field</a:documentation>
394            <choice>
395              <value>hirs-signed</value>
396              <value>inverted-uint</value>
397              <value>MIL1750a</value>
398            </choice>
399          </element>
400        </optional>
401        <optional>
402          <element name="display">
403            <a:documentation>define special display criteria</a:documentation>
404            <value>pidref</value>
405          </element>
406        </optional>
407        <optional>
408          <element name="length">
409            <a:documentation>for int and string types, give the size in chars (string) or bits (int or uint)</a:documentation>
410            <data type="unsignedInt">
411              <param name="maxInclusive">10000</param>
412            </data>
413          </element>
414        </optional>
415        <optional>
416          <!-- length also used by string -->
417          <element name="description">
418            <a:documentation>field description</a:documentation>
419            <text/>
420          </element>
421        </optional>
422        <optional>
423          <element name="calibration-name">
424            <a:documentation>name of calibration function</a:documentation>
425            <text/>
426          </element>
427        </optional>
428        <optional>
429          <element name="allow-null">
430            <a:documentation>do we allow NULL values?</a:documentation>
431            <data type="boolean"/>
432          </element>
433        </optional>
434        <optional>
435          <element name="index">
436            <a:documentation>allow indexes to be declared for individual fields inline</a:documentation>
437            <choice>
438              <value>true</value>
439              <value>primary-key</value>
440            </choice>
441          </element>
442        </optional>
443        <optional>
444          <!-- sys only -->
445          <element name="unit">
446            <a:documentation>field unit</a:documentation>
447            <text/>
448          </element>
449        </optional>
450        <optional>
451          <element name="choices">
452            <a:documentation>restrict the field values to a list of enumerated values</a:documentation>
453            <interleave>
454              <optional>
455                <element name="description">
456                  <text/>
457                </element>
458              </optional>
459              <oneOrMore>
460                <element name="item">
461                  <interleave>
462                    <optional>
463                      <element name="value">
464                        <a:documentation>value is required for raw tables only</a:documentation>
465                        <data type="integer"/>
466                      </element>
467                    </optional>
468                    <optional>
469                      <element name="min-value">
470                        <a:documentation>for names representing a range of values</a:documentation>
471                        <data type="integer"/>
472                      </element>
473                    </optional>
474                    <optional>
475                      <element name="max-value">
476                        <a:documentation>for names representing a range of values</a:documentation>
477                        <data type="integer"/>
478                      </element>
479                    </optional>
480                    <element name="name">
481                      <a:documentation>value name</a:documentation>
482                      <text/>
483                    </element>
484                    <optional>
485                      <element name="description">
486                        <a:documentation>description of item</a:documentation>
487                        <text/>
488                      </element>
489                    </optional>
490                  </interleave>
491                </element>
492              </oneOrMore>
493            </interleave>
494          </element>
495        </optional>
496        <optional>
497          <element name="calibration">
498            <a:documentation>name of calibration function</a:documentation>
499            <text/>
500          </element>
501        </optional>
502        <optional>
503          <element name="position">
504            <data type="unsignedInt"/>
505          </element>
506        </optional>
507        <optional>
508          <!-- raw only -->
509          <element name="mask">
510            <a:documentation>Apply a bitwise AND against eaw values</a:documentation>
511            <text/>
512          </element>
513        </optional>
514        <optional>
515          <!-- raw only -->
516          <element name="shift">
517            <a:documentation>Apply a bit shift to raw values</a:documentation>
518            <data type="unsignedInt"/>
519          </element>
520        </optional>
521        <optional>
522          <!-- raw only -->
523          <element name="validity-group">
524            <text/>
525          </element>
526        </optional>
527        <optional>
528          <!-- raw only -->
529          <element name="validity-group-prime">
530            <text/>
531          </element>
532        </optional>
533        <optional>
534          <!-- raw only -->
535          <element name="invalid">
536            <a:documentation>Ingested data of this value will be recorded as database NULLs</a:documentation>
537            <text/>
538          </element>
539        </optional>
540        <optional>
541          <element>
542            <choice>
543              <name>limits</name>
544              <name>raw-limits</name>
545            </choice>
546            <interleave>
547              <optional>
548                <element name="red">
549                  <interleave>
550                    <optional>
551                      <element name="low">
552                        <a:documentation>many limits values must be evaluated i.e. 10-25</a:documentation>
553                        <text/>
554                      </element>
555                    </optional>
556                    <optional>
557                      <!-- xsd:float -->
558                      <element name="high">
559                        <text/>
560                      </element>
561                    </optional>
562                  </interleave>
563                </element>
564              </optional>
565              <optional>
566                <element name="yellow">
567                  <interleave>
568                    <optional>
569                      <element name="low">
570                        <text/>
571                      </element>
572                    </optional>
573                    <optional>
574                      <element name="high">
575                        <text/>
576                      </element>
577                    </optional>
578                  </interleave>
579                </element>
580              </optional>
581            </interleave>
582          </element>
583        </optional>
584        <optional>
585          <element name="hidden">
586            <data type="boolean"/>
587          </element>
588        </optional>
589        <optional>
590          <element name="default">
591            <text/>
592          </element>
593        </optional>
594        <optional>
595          <!-- second) -->
596          <element name="coarse-time-length">
597            <a:documentation>For PUS ingestion of datetime objects we allow the number of bytes of coarse
598time (seconds) to be specified. Remaining bytes are fine time (proportion of</a:documentation>
599            <data type="unsignedInt"/>
600          </element>
601        </optional>
602        <optional>
603          <element name="related">
604            <a:documentation>For PUS ingestion a parameter may be defined as deduced, meaning it is a debug
605parameter based on the definition given by the value of a different parameter</a:documentation>
606            <text/>
607          </element>
608        </optional>
609      </interleave>
610    </element>
611  </define>
612  <define name="test">
613    <a:documentation>tests are applied against individual bytes</a:documentation>
614    <interleave>
615      <zeroOrMore>
616        <element name="test">
617          <interleave>
618            <element name="position">
619              <a:documentation>byte offset to be tested</a:documentation>
620              <data type="unsignedInt"/>
621            </element>
622            <optional>
623              <element name="shift">
624                <data type="unsignedInt"/>
625              </element>
626            </optional>
627            <optional>
628              <element name="mask">
629                <text/>
630              </element>
631            </optional>
632            <choice>
633              <element name="equals">
634                <a:documentation>a clause can use either &lt;equals&gt; a specific value, or give a range from &lt;min-value&gt;
635to &lt;max-value&gt;. Unbounded ranges can be specified by omitting either min or max value</a:documentation>
636                <data type="unsignedInt"/>
637              </element>
638              <interleave>
639                <optional>
640                  <element name="min-value">
641                    <data type="unsignedInt"/>
642                  </element>
643                </optional>
644                <optional>
645                  <element name="max-value">
646                    <data type="unsignedInt"/>
647                  </element>
648                </optional>
649              </interleave>
650            </choice>
651          </interleave>
652        </element>
653      </zeroOrMore>
654      <zeroOrMore>
655        <element name="and">
656          <zeroOrMore>
657            <ref name="test"/>
658          </zeroOrMore>
659        </element>
660      </zeroOrMore>
661      <zeroOrMore>
662        <element name="or">
663          <zeroOrMore>
664            <ref name="test"/>
665          </zeroOrMore>
666        </element>
667      </zeroOrMore>
668    </interleave>
669  </define>
670</grammar>