PIDF Documentation

written by :
Rudy Frahm, Carrie Gonzalez, Chris Gurgiolo, Joey Mukherjee

Please email corrections/questions/updates to :
Joey Mukherjee

joey@swri.org


Table of Contents

  1. Introduction to the PIDF...
  2. Version
  3. Lineage
  4. Group
  5. Miscellaneous
  6. Imaging
  7. Binning
  8. Units
  9. Sensors
  10. Scan
  11. Calibration Data
  12. Mode
  13. Data Quality
  14. Pitch Angle
  15. Spin Angle
  16. Spacecraft Potential Data
  17. Background Data
  18. Moments
  19. Coordinate System Transformation
  20. Tensor Description
  21. Appendix A (VIDF Tables)
  22. Appendix B (Unit IDs)
  23. Appendix C (Tensor IDs)

  1. Introduction
  2. The Plot Interface Definition File (PIDF) is an optional file under the IDFS format. The word optional in this context means that it is not necessary in the use of any of the IDFS data retrieval software; that is, data in IDFS format can be located through the database, accessed and converted to units without the PIDF. If, however, you plan to use any IDFS based data display or analysis software, the PIDF is required.

    The PIDF is best described as an interface file between the IDFS VIDF definitions and a general user interface to a display or analysis program, providing a large number of display attributes. It is an ASCII file consisting of multiple sections. These are briefly summarized below and later we will give detailed descriptions and examples of the fields contained therein. A working understanding of the terminology used in describing the IDFS data format is assumed throughout this document. Most of this terminology can be found within the IDFS DEFINITION DOCUMENT.

    The PIDF consists of 19 sections or blocks listed below. These may contain multiple entries or a single entry. Block entries for sections 1, 2, 3, 4, 7, and 8 are required of all PIDFs; whereas block entries for sections 5, 6, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 and 19 may appear depending on how variables in the required sections are answered.

    1. The PIDF version number
    2. The hierarchy or lineage associated with this virtual instrument.
    3. Groups into which the VIDF sensors will be divided.
    4. Miscellaneous information describing the virtual instrument and the data usage.
    5. If applicable, information for the binning of the IDFS data.
    6. If applicable, information describing all imaging parameters available.
    7. A detailed description of all of the units which may be formed for the data contained within the virtual instrument.
    8. A detailed description of all of the sensors found in the virtual instrument.
    9. If necessary, a description of the scan parameters associated with virtual instrument sensors.
    10. If necessary, a description of the calibration parameters associated with the virtual instrument.
    11. If necessary, a description of the mode states associated with the virtual instrument.
    12. If necessary, a description of the quality flags associated with the virtual instrument sensors.
    13. If necessary, a description of the pitch angle associated with the virtual instrument.
    14. If necessary, a description of the spin angles (start/stop azimuthal) associated with the virtual instrument.
    15. If necessary, a description of the spacecraft potential data associated with the virtual instrument.
    16. If necessary, a description of the background data associated with the virtual instrument.
    17. If applicable, information describing plasma moments calculations.
    18. If applicable, information describing coordinate system transformation(s).
    19. If applicable, information describing the multi-dimensional data (tensor) that is held within the IDFS data files.

    When it exists, the PIDF file is given the name of the virtual instrument appended by ".pidf.v2". The file is located in the directory indicated in the IDFS database configuration file: DB.cfg.

    Each PIDF file consists of a set of fields, each field occupying a single line. Comments are allowed and are defined as any text following a $ symbol. The $ may occur anywhere on a PIDF line and no PIDF information is allowed following the initiation of a comment. Comments may not be continued; therefore, comments terminate at the end-of-line. Any number of spaces may occur between a line entry and the beginning of a comment.

    Starting with version 2.0 of the PIDF, all PIDF information is kept in a structure like format. The PIDF starts with the keyword "pidf" and then the virtual instrument name followed by an open brace ("{"). All other information is below the opening brace. The PIDF is ended with a closure brace ("}") indicating the end of the PIDF. Each section is broken up into another enclosing set of braces. Entries within each section contain five fields. These five fields are: type, name, equal sign, value, and semicolon. The type describes the class of variable name. Valid types must be one of the four values listed below. The name field contains a PIDF keyword which is defined in the description of each section below. The equal sign field is the PIDF assignment operator and is a "=". The value field contains the quantity to assign the name keyword. Values enclosed within double quotes (") are taken as character strings. While those enclosed within apostrophes (') are interpreted as single characters. Numeric values without a decimal have an integer value and those with a decimal have a real or float value. Examples may be found below under valid types.

    Valid types are :

    For example:

    
    pidf ABCD {
        float version = 2.0;
        int num_sensors = 1;
        struct Sensor1 {
            string name = "CDEF";
        };
    };
    
    

    Entries within a block may be in any order and values may also be in any order or even absent; however, the order of appearance of some fields may be critical in obtaining a proper number result. Any omitted entries may cause the plotting/analysis software to fail.

    If this seems unclear, example PIDFs are plentiful and may shed light on the format.

    In the following text, we will describe each of the entries found within PIDF. The blocks are presented in the order in which they ought to occur in the PIDF file.

    1. Version
    2. A PIDF version consists of a single field described below. The version number is verified by the generic software to assure that all fields can be read and interpreted by the installed PIDF read routine.

      The version number is a floating point value and at this writing, the PIDF version is 2.0.

      float version = 2.0;
      

    3. Lineage
    4. A PIDF lineage (hierarchy) block consists of 6 fields which describe the virtual instrument hierarchy or lineage (describes from where the data is originated). With the exception of the first field, these fields are almost never accessed by any interface program since the interface program must have already obtained this information to open the PIDF file. This information is included within the PIDF simply for completeness.

      All lineage entries are strings of nineteen characters maximum except for the virtual instrument entry which has a maximum of EIGHT characters.

      The entries within the lineage (hierarchy) PIDF information block are described below:

      1. INSTITUTION

        This entry is not truly included in the IDFS lineage, and appears here only for completeness. The institution entry contains a brief abbreviation or acronym of the institution which is responsible for the instrument from which the virtual instrument is derived. The entry value contains the name of the institution. (e.g. "SwRI", "APL", "LPARL", etc.)

      2. PROJECT

        The IDFS project identifier associated with the virtual instrument described in the PIDF. The entry value is: project. (e.g. "UARS", "DE", "DMSP", "ARIA", "GeoSolarInd", etc.)

      3. MISSION

        The IDFS mission identifier associated with the virtual instrument described in the PIDF. The field name is: mission. (e.g. "TSS-1", "TSS-1R", "DMSP-F11", etc.)

      4. EXPERIMENT

        The IDFS experiment identifier associated with the virtual instrument described in the PIDF. The field name is: experiment. (e.g. "PEM", "HALOE", "SSJ4", "SPS", etc.)

      5. INSTRUMENT

        IDFS instrument identifier associated with the virtual instrument described in the PIDF. The field name is: instrument. (e.g. "MEPS", "LEVEL_3AT", "SSJ4", "OA", etc.)

      6. VIRTUAL INSTRUMENT

        IDFS virtual instrument identifier associated with the PIDF. The field name is: vinst. (e.g. "OAUR", "HPSA", "AXSC", "DSTH", etc.) This field can be no longer than eight characters.


      As an example of a lineage block, the PIDF lineage block as taken from the UARS AXIS instrument on the UARS-1 flight:

          string institution = "SwRI";                           $$ institute
          string project = "UARS";                               $$ project
          string mission = "UARS-1";                             $$ mission
          string experiment = "PEM";                             $$ experiment
          string instrument = "AXIS";                            $$ instrument
          string vinst = "AXSA";                                 $$ vinst
      

    5. Group Block
    6. A PIDF group block consists of 2 fields, describing the groupings into which the virtual instrument sensors can be separated. This is useful when the virtual instrument contains a large number of sensors representing a diverse set of measurements. Groups allow an additional level of subdivision within the virtual instrument sensors.

      The first field (num_groups) in the block is an integer number of groups which are defined while the second field (group_name) are strings of group names, each given on a separate line. Group names are at most forty characters.

      Every sensor defined within the PIDF must be assigned to one of the defined groups. It is not unusual for a group to have only a single sensor; however, there must be at least one group.

      There are num_groups lines of group_names strings, each of which contains a short description of the sensor group. This is generally a description of the types of measurements found within that group. The group name is intended to be used along with the sensor component which is discussed later. It is handy to use group names during selection of menu sensors when determining which data is to be plotted.

      The following is the PIDF group block taken from the RETE RTLA (AC wave measurements) virtual instrument on the TSS-1 flight.

          int num_groups = 2;                                    $$ no. groups
          string group_name = "A/C Electric Field";              $$ group name
          string group_name = "A/C Magnetic Field";              $$ group name
      

    7. Miscellaneous
    8. The PIDF miscellaneous block consists of several fields which define general characteristics of the measurements found with the virtual instrument defined within the PIDF. These fields are defined as: flow_into, plot_avail_flag, data_type_mask, instrument_dep, cyclic, min and max.

      The fields within the miscellaneous PIDF information block are described below.

      1. flow_into

        This field describes the relationship between the sensor look directions and the plasma flow direction. In most cases, sensors detect plasma flowing into the sensor, so the sensor look direction is opposite to the plasma flow direction. Some IDFS data sets have sensor definitions parallel to the plasma flow direction. Therefore, it is necessary to define which of the 2 possibilities are defined for the virtual instrument in question. The entry is 'Y' if the sensor look direction is opposite to the plasma flow direction and 'N' if the sensor look direction is parallel to the plasma flow. The default response is 'Y'.

      2. plot_avail_flag

        The plot_avail_flag describes the dependency of the data (how can the data be plotted) described by the IDFS sensors. The field is 8 bits in length and can be entered as a hex value by prefixing the hex number with a "0x". Each item listed below is a separate bit in the value and may be combined as long as the data agrees with the definition. The bit definitions are shown below.

        1. Scalar

          Data can be used in any application in which scalar data is required (e.g line plot displays). This should generally be enabled for any virtual instrument since in all cases, higher dimensional can generally be reduced to scalar data. To specify only scalar data, the value of plot_avail_flag should be 0x1.

        2. Scanning without angular dependence

          Data can be used in any application in which scanning data is required with no requirement on angular information (e.g. spectrogram displays).

          An example may be an instrument like a spectrometer where a value is measured based only on the dependence of one other quantity (the scan value). The scanning value can take many forms. For example, wavelength, altitude, frequency, position, energy, etc., but the data only depends on the scan value.

          To specify scanning without angular dependence, the value of plot_avail_flag should be 0x2.

          In cases where summation or integration can occur over the scan variable, the data may be compressed into a single value, or scalar. In this case, the plot_avail_flag should specify that both the scanning without angular dependence and scalar plotting is available and the value is set to 0x3.

        3. Scanning with angular dependence

          When an instrument is defined to have angular dependency as well as a dependency on scanning, then this bit should be enabled (a value of 0x4). When this value is specified, the appropriate spin and angular offset information must be specified in the data and/or VIDF. For a rotating object, the angle phi lies within the spin plane and the angle theta is perpendicular to the spin place. In general, angular integration may be reduced by removing angular dependency (plot_avail_flag of 0x6) or to a scalar value (plot_avail_flag of 0x7).

          This can be used in any application which requires scanning data that includes angular information (theta or azimuthal) associated with the scan (e.g. scan-angle plots). This should be enabled for any virtual instrument in which the sensor data has a scan dependency attached to it and there is either a spin rate defined in the data record and/or the sensors have a theta constant field defined for them in the VIDF.

        4. Imaging

          The data can be used in any image application. The sensor data has a corresponding set of longitudes and latitudes, occurring either as separate sensors or as calibration data associated with the sensors, it may be displayed or treated as an image. The specification is 0x8; however, data may also include any of the previous definitions.

      3. data_type_mask

        This field describes the type of data contained in the virtual instrument (what type of data can be plotted). The field is 32 bits in length and can be stored as a hex value.

        Types of data defined within the VIDF are: background data, spacecraft potential data, start azimuthal angles, stop azimuthal angles, pitch angles, data quality, mode data, calibration data, scan data, and sensor data. Setting the relevant bit indicates that the type of data is described by the VIDF. The appropriate value of data_type_mask is achieved by combining all the bits from data types described by the IDFS. The bit definitions are shown below.

        1. Data Quality

          Data Quality exists by default in all virtual instruments. If this flag is not set, many display routines will disallow the plotting of the data quality flags. Data quality flags are provided so that indication of data state may be specified. These are commonly used to indicate when data is questionable, artificial, or just bad, The bit value to indicate data quality alone is 0x1. IDFS instruments may or may not contain data quality, but it is always returned even if invalid.

        2. Mode

          The IDFS for this virtual instrument contains mode (status) data if bit value of 0x2 is included in the data type mask. This data is found in the IDFS header record. It is used to indicate the configuration of the instrument producing the data in the IDF files. IDFS instruments may or may not contain mode data.

        3. Calibration Data

          If the IDFS for this virtual instrument contains calibration data, the bit value is 0x4. Calibration data is extra data which describes or is used to correct/adjust sensor data. It may be generated from other data taken at the same time, or from other times and places. An example of calibration data may be a spectrum of falsely identified data which will be subtracted from the sensor data so that it may be automatically adjusted to appropriate values. IDFS instruments may or may not contain calibration data.

        4. Scan Data

          The IDFS for this virtual instrument contains scan data if the data_type_mask includes the bit defined by 0x8. This data is found in the IDFS header record and appears in all virtual instruments which have scan dependence.

        5. Sensor Data

          The IDFS for this virtual contains sensor data. All IDFS virtual instruments, by definition, contain sensor data. This bit (0x10) should always be enabled.

        6. Pitch Angle Data

          The IDFS for this virtual instrument contains Pitch Angle data if the bit defined by 0x20 is set in the data_type_mask. The IDFS data source that is used to compute the pitch angles is defined in the VIDF file.

        7. Start Spin Angle Data

          The IDFS for this virtual instrument returns Start Azimuthal Angle information if the bit defined by 0x40 is set in the data_type_mask. If spin information is returned, both the Start Azimuthal and Stop Azimuthal angles are returned; therefore, both data types should be set.

        8. Stop Spin Angle Data

          The IDFS for this virtual instrument returns Stop Azimuthal Angle information if the bit defined by 0x80 is set in the data_type_mask. If spin information is returned, both the Start Azimuthal and Stop Azimuthal angles are returned; therefore, both data types should be set.

        9. Spacecraft Potential Data

          The IDFS for this virtual instrument contains Spacecraft Potential data if the bit defined by 0x0100 is set in the data_type_mask. The spacecraft potential data may be defined as a constant value in the VIDF file or may come from another IDFS data source that is specified in the VIDF file.

        10. Background Data

          The IDFS for this virtual instrument contains Background data if the bit defined by 0x0200 is set in the data_type_mask. The background data may be defined as a constant value in the VIDF file or may come from another IDFS data source that is specified in the VIDF file.

      4. instrument_dep

        The instrument_dep is a flag indicating the types of functional dependency which is shown by the sensor data. This does not indicate how the dependency occurs, only that it is present.

        There are three methods by which dependencies may exist. The first is through the scan variable, the second is through the presence of an instrument spin rate, and the last is through a dependency on one or more variables which change as a function of sensor. In the latter case the dependencies must be indicated through a VIDF constant field. Examples would be mass, charge, or theta. The field is eight bits in length, stored as an integer and entered as a hex value. The bit definitions are shown below.

        1. Sensor measurements have a scan dependency. (bit 0x01)
        2. Sensor measurements have a theta dependency. (bit 0x02)
        3. Sensor measurements have a phi dependency. (bit 0x04)
        4. Sensor measurements have a mass dependency. (bit 0x08)
        5. Sensor measurements have a charge dependency. (bit 0x10)

        Instruments which generate values which do not depend on anything else are scalar quantities and the value of instrument_dep should be zero (e.g. spacecraft altitude or orbit number). An instrument which sweeps through a set of predefined states, such as a spectrometer, has a scan dependency. If the spacecraft is spinning, the instrument may produce values which are dependent on the angle in the direction of the spin, defined as phi, and the data from the instrument exhibit a phi dependency. Instrument data may also be dependent on the angle perpendicular to the spin plane, called theta. In case of an angular dependency, the proper VIDF and data entries must be defined.

      5. cyclic

        If there is a phi dependence to the data then this field must be included. It is used to indicate whether or not the phi dependence is cyclic. The entry is Y if the phi dependence is cyclic and N if it is not.

      6. Limits on dependency

        When an instrument exhibits dependencies, which was described by the instrument_dep flag above, default ranges for each type of dependence must be supplied. These default ranges are typically chosen to be the overall range of the quantity. For example, if phi dependency is defined and is cyclic, then the limits should be set to 0.0 and 360.0. Any dependency not defined by the instrument_dep flag should have no entry. Each entry is a floating point value and may be entered in scientific notation. Each defined dependency must include both the minimum and maximum value attained by the dependency. Below is a list of the limits which should be included for the appropriate dependency. These values are not order dependent.

        • scan_min & scan_max
        • theta_min & theta_max
        • phi_min & phi_max
        • mass_min & mass_max
        • charge_min & charge_max

        Another example is if altitude is scanned between 50km and 20,000km. The instrument_dep flag should be set to 0x01, the limit dependency for the scan minimum to 50.0, and the limit dependency for the scan maximum to 2.0e4.


      The following is the PIDF miscellaneous block taken from the ROPE RPEA electron spectrometer instruments on the TSS-1 flight. The data has a scan dependency and contains all of the IDFS data types except calibration data, pitch angle, and spin angle data.

          int plot_avail_flag = 0x7;                             $$ plot avail
          int data_type_mask = 0x1B;                             $$ Sen/Scn/Cal/Mode/Qual
          int instrument_dep = 1;                                $$ avg over
          float scan_min = 0.1;                                  $$ scan limits
          float scan_max = 15000.0;                              $$ scan limits
      

    9. Image
    10. The PIDF image block defines the properties which are necessary to create an image from an IDFS data set. If the PIDF field plot_avail_flag does not have the image flag set, then the image block is not included in the PIDF.

      The fields within the PIDF scan block are described below.

      1. Image Formats

        There are two types of image formats. They are pushbroom and snapshot. The image format entry is a character, either a "P" for pushbroom or an "S" for snapshot.

        • PUSHBROOM

          A pushbroom image is constructed from a series of individual measurements, continuously taken, and built up to form an image having no definite start or stop. Each pixel of a pushbroom image is defined as a separate sensor and the image grows continually.

        • SNAPSHOT

          In a snapshot image, the pixels which form the picture have been organized into scan lines, with each scan line represented as a sensor with a scan dependency. The scan steps are the pixels. For a raster device, successive scan lines are obtained by successive acquisitions of a single sensor. For a non-rasterized image, each scan line is represented by a different sensor. Snapshot images generally have a definite start and stop scan line defining an image.

      2. Image Type

        The image type is a character of a value "1" or "2". This value defines the type of an image pixel. If each pixel is characterized by a single value, it is said to be one-dimensional and the image type is "1". If each image pixel is characterized by a set of values, it is said to be two-dimensional and the image type is "2".

        When a pixel is two-dimensional, the image is a collapsed result of its set of values. For example, suppose you have spectrograph images which measures the intensity of light at a series of wavelengths for each pixel. By integration, for each pixel you can determine the total intensity for that wavelength, ranges, and that is your image value. Similarly, if the instrument is an x-ray camera which determines the energy spectrum of each pixel, an image can be created by determining a single value, collapsing over the energy range to one value.

        The advantage in describing data as a two-dimensional image as well as that dependent on for example, scan, is that the full spectral information is not lost. Data can be viewed in image form over different ranges of the scanned variable and the spectral details can be examined on the same data set. Information is not lost since there is no need to create a special data set to be viewed as an image.

      1. num_lat_longs

        This field describes how many pairs of latitude and longitude values are incorporated in an image. The value is expressed as an integer number. For example, a snapshot image may have latitude and longitude pairs in each of the four corners of the image, in which case the num_lat_longs equals four.

        For each pair specified, the following information must be supplied :

      2. lat_loc, long_loc

        Described as a character, this field indicates where in the IDF to find the latitude-longitude pair. The possibilities are in the sensor data (value is a 'S') or in the calibration data (value is a 'C'). The latitude-longitude pairs must be included in the same IDF data file as the image data.

      3. lat_num, long_num

        This field contains an integer value for the sensor number or calibration set number for the latitude/longitude. When combined with the location described above, a description of where to obtain the latitude and longitude is achieved.

      4. lat_unit, long_unit

        This is an integer which describes where to find the information within the Units section of the PIDF for the latitude and longitude. The Units section is described later in this text. Each unit has an associated unit number index and this variable contains the unit number index to be used to interpert the data described by that unit (see the section on Units below).

      5. lat_def, long_def

        An indication of where in the image the latitude/longitude is described is located here in a character string. This character string may have values of "TL", "CT", "TR", "CL", "C", "CR", "BL", "CB", or "BP". They are different combinations of the first letter of the key words Top, Center, and Bottom. These character strings define positions of a square.

        
            TL             CT           TR
            /\             /\           /\
            \/             \/           \/
        
        
        
        CL  /\           C /\           /\ CR
            \/             \/           \/
        
        
        
            /\             /\           /\
            \/             \/           \/
            BL             CB           BR
        
        

      6. bin_type

        This field describes the type of binning to be used when creating the image. As of this writing, no current software supports the bin_type flag. However, it is expressed as a character and can take on only one of three values. The first is an 'N', which means that the data is not to be binned to form the image.

        The second possibility is only valid for snapshot formats and is specified as 'G', for Grid. Under Grid binning, bins are taken as a two dimensional plane for this process. Binning, specified under the sensor section below, is described in the Binning section of the PIDF.

        The third possibility is only valid for pushbroom formats and is specified as 'T', for Track. Under Track binning, bins are taken as a one dimensional perpendicular to the spacecraft track. Binning, specified under the sensor section below, is described in the Binning section of the PIDF.

      7. storage

        Storage is a character string having the values of "CO", "CT", "CS", "SE", "TE", or "V". The storage string describes which pattern is formed by the latitude and longitude pairs. These refer to "C" for center, "T" for top and bottom, "S" for sides, "E" for edge, and "V" for vertices.

        The latitude-longitude pairs describe the geographic position of a pixel. Several pairs which describe pixel positions are assembled together to map the pixel onto the globe. The storage string describes the type of mapping used.

        Referring to the diagram for a pixel definition:

        • storage "CO" means that there is a lat_def and long_def of a "C" only
        • storage "CT" means that there is a lat_def and long_def of a "CT", "C", and "CB" only
        • storage "CS" means that there is a lat_def and long_def of a "CL", "C", and "CR" only
        • storage "SE" means that there is a lat_def and long_def of a "CL" and "CR" only
        • storage "TE" means that there is a lat_def and long_def of a "CT" and "CB" only
        • storage "V" means that there is a lat_def and long_def of a "TL", "TR", "BL", and "BR" only

      The following is a PIDF image block taken from the DE-1 SAIA Probe instrument on the DE satellite.

          struct Image {
      $********************IMAGING INFO*************************************
              char format = 'S';                                $$ Pushbroom Format
              char type = '1';                                  $$ 2-D capability
              int num_lat_longs = 1;                            $$ lat/long pairs
              struct LatLong0 {
                  char lat_loc = 'S';                          $$ center lat
                  int lat_num = 2;                             $$ center lat
                  int lat_unit = 7;                            $$ center lat
                  string lat_def = "C";                        $$ center lat
                  char long_loc = 'S';                         $$ center long
                  int long_num = 1;                            $$ center long
                  int long_unit = 8;                           $$ center long
                  string long_def = "C";                       $$ center long
              };
              char bin_type = 'N';                              $$ Track, Swp, Cen/Sides
              string storage = "C";                             $$ Track, Swp, Cen/Sides
          };
      $*********************************************************************
      

    11. Binning
    12. The PIDF bin block consists of an integer quantifier indicating the number of bin schemes being defined, followed by the binning definitions. Each set of binning definitions give a complete description of a binning scheme to be used for scan-dependent data. Defined bin definition blocks may be referenced in the sensor definition blocks (described below) as being applicable to one or more sensors.

      Binning is used by some applications to define the size and spacing of the returned data values within the virtual instrument. Binning gives the user the ability to condense or expand time-averaged or sample-averaged data.

      Binning is particularly useful when the scan range returned by the virtual instrument is quite variable. This circumvents applications which do not follow changes in the scan range. It is also very useful in reducing a large number of data values so that fewer data points need to be plotted.

      The fields within the PIDF bin block are described below.

      1. num_bin_sets - The number of bin definitions.

        This field is an integer value indicating the number of binning schemes defined. This number should be greater than zero unless there is no defined binning schemes in which case it should be equal to zero. If binning schemes are defined, there needs to be num_bin_sets binning schemes defined using the method, min, max, bin_scaling, and num_bins fields.

      2. method - method used to bin the data. There are two choices.

        1. FIXED_SWEEP - when this method is selected, the data bins are set up according to the information found in the VIDF file. The element swp_len is used to determine the number of bins. The data is stored into the bins by using the values found in the scan_index array as index values into the data bins. The scan_index array is contained in the header record. For scalar instruments, this bin method should always be selected. To select this method, use the number "1" as the value for the method PIDF field.

        2. VARIABLE SWEEP - when this method is selected, the user must specify the number of bins to create (num_bins), the spacing of the bins (bin_scaling), the center value associated with the first bin and the center value associated with the last bin (bin_mnmx). This bin method can be used for vector instruments. The data in a vector data set are taken as a function of a variable M (scan variable).

          If M is allowed to vary over the individual measurement period or if M actually represents a band width, then each element in the vector can be considered to have been accumulated with the interval M - \(*d1 to M + \(*d2. The data is binned using the scan interval for each vector element. In other words, data is placed in all bins which fully or partially contain the scan interval associated with the data. To select this method, use the number "2" as the value for the method PIDF field.

      3. min, max - These keywords define the minimum and maximum center values of the defined binning array and are entered as floating point values. This field is only defined when a method of "2" is selected.

      4. bin_scaling - This keyword is entered as an integer and is used in computing the bin widths. There are two choices:

        1. LINEAR Use "1" to define linear width.

        2. LOG. Use "2" to define logarithmic width. Note that this option cannot be used if either the minimum or maximum value within the min or max field is less than or equal to zero.

          Linear spacing defines a scheme where the lower (upper) edge of the band is determined by subtracting (adding) one-half of the difference between two successive center values from (to) the center value. The same algorithm is used for log spacing, with the log of the center values being utilized. This field is only defined when a bin method of 2 is selected.

      5. num_bins - This definition is entered as an integer and represents the number of contiguous bins contained in the binning array. This value cannot be set to zero. This field is only defined when a bin method of "2" is selected.

      The following is a PIDF bin block taken from the ROPE RPDP Retarding Potential Analyzer instrument on the TSS-1 flight.

      
          int num_bin_sets = 2;                                  $$ no. bin sets
          struct Bin0 {
      $---------------------BIN SET 00--------------------------------------
              int method = 2;                                   $$ bin method
              float min = -100.0;                               $$ bin beg/end
              float max = 100.0;                                $$ bin beg/end
              int bin_scaling = 1;                              $$ bin type
              int num_bins = 256;                               $$ no. of bins
          };
          struct Bin1 {
      $---------------------BIN SET 00--------------------------------------
              int method = 2;                                   $$ bin method
              float min = 0.0;                                  $$ bin beg/end
              float max = 100.0;                                $$ bin beg/end
              int bin_scaling = 1;                              $$ bin type
              int num_bins = 256;                               $$ no. of bins
          };
      
      

    13. Units
    14. The PIDF units block consists of a quantifier, indicating the number of units being defined, followed by the unit definitions. Each unit definition describes how to construct a particular unit from the VIDF tables. In addition it contains suggested default values to be used when plotting converted data as well as textual labels. A detailed discussion of how physical units are derived from VIDF tables is given in Appendix A.

      The fields within the PIDF unit block are described below:

      1. num_units

        1. num_units is an integer value indicating the number of unit definitions to follow.
        2. The maximum number of Units described by a PIDF is 255.
        3. For each unit, there are at least eight fields which comprise a units definition set. There will be a total of num_units units definition sets described by the PIDF.

      2. id

        There is a unique id value for each unit. This value is an integer, normally greater than zero, which is used as an identifier for the plotting software. Units which describe different physical quantities have different id values. A list of currently defined id values are given in Appendix B.

        The unit id is specified to restrict plotting of values having different units of the same graph. There is a wildcard id which has the value of zero. Any id of zero should be able to be plotted with any other unit id.

      3. minimum / maximum

        Values of reasonable minimum and maximum range of the data are specified as floating point numbers. These values are not necessarily the minimum and maximum values of the range for the data, but they can be. These values should reflect the data range which best describes a reasonable range.

        Minimum values should not be equal to maximum values; however, minimum values can be greater than maximum values. This is a handy way of describing an inverted scale (for example, atmospheric pressure is inversely related to altitude).

      4. scaling

        Unit scaling is an integer value of one or two. A value of one means that the data should be scaled linearly and a value of two means that the data should be scaled logarithmically. Data which has a wide dynamic range is best scaled logarithmically; however, logarithmic scaling can not tolerate zero or negative values. It is suggested that for data which can contain both positive and negative values, linear scaling should be used.

      5. unit_label

        The unit_label is a character string having a maximum length of twenty characters. It contains the dimensional specification of the unit in abbreviated format. As an example, meters/second should be m/s, etc. If the measurement is dimensionless, then the word dimensionless or unitless should be given here. Some software look for either of these words as indicating dimensionless data and act appropriately when labeling plots.

      6. long_description

        The long_description is a character string having a maximum length of forty characters. This field gives an appropriate word description of the units being defined. Examples would be: length, acceleration, velocity, distribution function, etc.

      7. short_description

        The short_description is a character string having a maximum length of five characters. This field gives an abbreviated description of the unit. Examples are: raw, len, acc, nflux, vel, df, etc.

      8. num_tables

        When the data system reconstructs data, it uses tables described within the VIDF. The number of tables needed to reconstruct the data are recorded as an integer in the num_tables field. This number is greater than or equal to zero. A zero value means that no tables are to be applied to the data. If tables are needed to describe how to reconstruct the data, then the pair of tbl_app_flag and tbl_app_oper must be defined for each table needed to reconstruct the data.

      9. tbl_app_flag

        The tbl_app_flag is an integer which contains the value of the VIDF table numbers used in the algorithm which will convert the IDFS data into physical units. The tables defined in the VIDF begin at table zero, the first table entered in the VIDF being table zero, the next table one, etc. The tables are applied in the algorithm in the order in which they are listed in this field. If no tables are required this field is omitted.

      10. tbl_app_oper

        The tbl_app_oper is an integer which contains a number to describe the operation performed with the corresponding tbl_app_flag. These values are combinations of integers which describe operations and are defined numerically, however some do have non-numerical equivalents. A complete list of operations is given in Appendix A. The list is dynamic and represents the defined values as of PIDF version 2.0.

      The following is part of a PIDF units block taken from the RETE RTLP Langmuir probe instrument on the TSS-1 flight.

          int num_units = 7;                                     $$ no. units
          struct Unit0 {
      $-------------------------UNIT 00-------------------------------------
              int id = 0;                                       $$ unit id
              float min = 0.0;                                  $$ unit min/max
              float max = 255.0;                                $$ unit min/max
              int unit_scaling = 1;                             $$ unit lin/log
              string unit_label = "Dimensionless";              $$ unit label
              string long_description = "Telemetry";            $$ long desc.
              string short_description = "Raw";                 $$ short desc.
              int num_tables = 0;                               $$ number of tables
          };
          struct Unit1 {
      $-------------------------UNIT 01-------------------------------------
              int id = 0;                                       $$ unit id
              float min = -1.0;                                 $$ unit min/max
              float max = 8.0;                                  $$ unit min/max
              int unit_scaling = 1;                             $$ unit lin/log
              string unit_label = "Dimensionless";              $$ unit label
              string long_description = "Telemetry";            $$ long desc.
              string short_description = "Raw";                 $$ short desc.
              int num_tables = 0;                               $$ number of tables
          };
          struct Unit2 {
      $-------------------------UNIT 02-------------------------------------
              int id = 0;                                       $$ unit id
              float min = -5.0;                                 $$ unit min/max
              float max = 15.0;                                 $$ unit min/max
              int unit_scaling = 1;                             $$ unit lin/log
              string unit_label = "volts";                      $$ unit label
              string long_description = "Voltage";              $$ long desc.
              string short_description = "V";                   $$ short desc.
              int num_tables = 4;                               $$ number of tables
              int tbl_app_flag = 0;                             $$ table numbers
              int tbl_app_flag = 1;                             $$ table numbers
              int tbl_app_flag = 2;                             $$ table numbers
              int tbl_app_flag = 3;                             $$ table numbers
              int tbl_app_oper = 0;                             $$ operations
              int tbl_app_oper = 4;                             $$ operations
              int tbl_app_oper = 3;                             $$ operations
              int tbl_app_oper = 1;                             $$ operations
          };
          struct Unit3 {
      $-------------------------UNIT 03-------------------------------------
              int id = 0;                                       $$ unit id
              float min = -1.0e-5;                              $$ unit min/max
              float max = 1.0e-5;                               $$ unit min/max
              int unit_scaling = 1;                             $$ unit lin/log
              string unit_label = "amps";                       $$ unit label
              string long_description = "current";              $$ long desc.
              string short_description = "I";                   $$ short desc.
              int num_tables = 1;                               $$ number of tables
              int tbl_app_flag = 4;                             $$ table numbers
              int tbl_app_oper = 0;                             $$ operations
          };
          struct Unit4 {
      $-------------------------UNIT 04-------------------------------------
              int id = 0;                                       $$ unit id
              float min = 30.0;                                 $$ unit min/max
              float max = 130.0;                                $$ unit min/max
              int unit_scaling = 1;                             $$ unit lin/log
              string unit_label = "unitless";                   $$ unit label
              string long_description = "unitless";             $$ long desc.
              string short_description = "unitless";            $$ short desc.
              int num_tables = 1;                               $$ number of tables
              int tbl_app_flag = 1;                             $$ table numbers
              int tbl_app_oper = 0;                             $$ operations
          };
          struct Unit5 {
      $-------------------------UNIT 05-------------------------------------
              int id = 0;                                       $$ unit id
              float min = 0.0;                                  $$ unit min/max
              float max = 32.0;                                 $$ unit min/max
              int unit_scaling = 1;                             $$ unit lin/log
              string unit_label = "volts";                      $$ unit label
              string long_description = "Voltage";              $$ long desc.
              string short_description = "V";                   $$ short desc.
              int num_tables = 1;                               $$ number of tables
              int tbl_app_flag = 2;                             $$ table numbers
              int tbl_app_oper = 0;                             $$ operations
          };
          struct Unit6 {
      $-------------------------UNIT 06--------------------------------------
              int id = 0;                                       $$ unit id
              float min = -5.0;                                 $$ unit min/max
              float max = 15.0;                                 $$ unit min/max
              int unit_scaling = 1;                             $$ unit lin/log
              string unit_label = "volts";                      $$ unit label
              string long_description = "Voltage";              $$ long desc.
              string short_description = "V";                   $$ short desc.
              int num_tables = 1;                               $$ number of tables
              int tbl_app_flag = 3;                             $$ table numbers
              int tbl_app_oper = 0;                             $$ operations
          };
      

    15. Sensors
    16. The PIDF sensor block consists of a quantifier to indicate the number of sensors being defined followed by the sets of definitions for each sensor. Each sensor definition set describes information related to the sensor. Included within the set of sensor definitions are those describing names for the sensor, the source for the sensor, the proper associated index for that sensor, and definitions which describe the Units into which the measurements can be transformed. In addition, there are four other definitions relating to the sensor which define dependencies. These include descriptions on whether sensor data should be displayed, additional index for an independent (or scan) definition, and an index relating the sensor to a particular scheme defined in the binning section.

      The fields within the sensor PIDF information block are described below:

      1. num_sensors

        The number of sets of sensor definitions included in the PIDF is entered as an integer. The number of definitions required to describe each set depend on values assigned to controlling definitions. Controlling definitions influence whether other definition fields are required. All possible definitions which describe the set of definitions required to describe a single sensor are listed below. The set of definitions are repeated num_sensors times.

      2. name

        This definition is a character string with a maximum of twenty characters long that gives a description of the sensor name in words. The name of the sensor appears on most plots and should describe the sensor well enough so that it can be distinguished when plotting similar data from other sensors. Since this description is meant to be used in conjunction with plots, it should not be overly long.

      3. component

        This definition is a character string with a maximum of twenty characters long and describes the component of the sensor described by these definitions. The group name, sensor name, and component name are meant to be complementary. The sensor name is roughly equivalent to the combination of the group name and component name. Generally, the sensor name is placed on the plot, whereas the group name and component name are for menu use. This dual naming allows the user to have a more detailed description of the sensors than the more terse name displayed on the plot. This is done to allow the names displayed on the plot to be as short as possible.

        The component name need not include information which is present within the group name. As an example, the three sensors which belong to a group defined as VECTOR VELOCITY, may have component names X, Y, and Z. The component names do not refer to velocity since this information is contained in the group name. It is assumed that the group name is displayed simultaneously with the component name if this sensor naming convention is displayed on a plot.

        One group name may describe many sensors. The component name is used to distinguish these sensors. A group name is more general whereas a component name is more specific. There are such cases where there exists only one sensor in a group and the group name is an adequate description of the sensor. In this case, the component name should be set to N/A. Interface programs should interpret an N/A to indicate that the component name is not applicable and react accordingly.

        A comment: the group name together with the component name may be used to describe a sensor measurement in place of the name label. This depends on the application and how it chooses to use information provided in the PIDF.

      4. source

        This definition is an ASCII character indicating the data source location within the IDFS hierarchy. There are two possible answers :

        1. V - indicating that the sensor is an IDFS data source.
        2. S - indicating that the sensor is an SCF data source.

      5. scf_filename

        For an IDFS data source, this is an unused field and should be set to N/A. For a SCF data source, this should be the name of a valid SCF file.

      6. pidf_sensor_num

        The pidf_sensor_num is an integer and reflects a sequential number indicating which sensor is described. Valid numbers begin with zero and conclude with num_sensors - 1. There should be one set of sensor definitions for each pidf_sensor_num. In the structure of the PIDF, each sensor is assigned and described by a set of definitions. This set of definitions is described by a struct statement and given a label. That label should correspond to the pidf_sensor_num and has the prefix Sensor. For example, the twenty-first PIDF sensor has a "int pidf_sensor_num = 20" and the set of Sensor definitions is labeled with "struct Sensor20 {". A unique PIDF sensor number must be defined for each set of sensor definitions in the PIDF.

        WARNING - this is a critical input which may generate unpredictable results if the value assigned to pidf_sensor_num and label to the set of sensor definitions do not agree.

      7. vidf_sensor_num

        This definition is an integer describing the source sensor number. For the case where the set of sensor definitions describe a sensor contained within a VIDF, this field reflects the sensor described within the VIDF. This is the position of the sensor within the sensor the sen_names field of the VIDF (Note that the first sensor in the VIDF is sensor number zero). For the case where the set of sensor definitions describe a sensor contained within an SCF description, this field reflects the sensor number of the SCF output variable (the SCF output sensors are numbered starting at zero).

      8. group_num

        This definition is an integer describing the number of the group to which the sensor is associated. The group number is determined by the position of the group within the group name list. Note that the first group name within this list is group number zero.

      9. display_flag

        This definition is an integer which controls the plotting of data. The choices available for this field are:

        • 0 - Sensor should not be included in sensor lists.
        • 1 - Sensor should be included in sensor lists.

        It can be used to prevent a sensor whose data may be questionable or which may not be appropriate for display (example memory readout data) from being shown in a list of plottable sensors. In general this field should be ignored in favor of the VIDF sen_status which gives the same information, but as a function of time. It is preferable that if a sensor is not to be accessible for reasons other than data quality that it not be included in the PIDF.

      10. scan_block_info

        This definition is an integer which connects the sensor to a scan definition. If the PIDF field data_type_mask has the scan flag set, then this field indicates which block of scan information is applicable for use with this sensor. If the scan flag has not been set then this field is not included in the sensor block.

      11. num_units

        This definition is an integer which indicates how many units may be displayed by the sensor. If there are units defined for the sensor, then the num_units is set to zero.

      12. unit_number

        This definition is an integer and indicates a unit number within the PIDF in which data from the sensor man be displayed. The number of separate unit_number definitions is described by the value of the variable num_units.

      13. binning_index

        For the vector sensor, different binning schemes may be defined; however, if binning is defined, then each vector sensor definition must include the binning_index keyword and is of the format

        int binning_index = N;

        Each binning_index value N is an integer that identifies which binning definition is to be used (refer to section 7 - Binning). For each vector sensor definition, there should be one binning_index definition for each scan unit definition pointed to in the scan_block_info keyword. The binning_index definition is not included if there are zero bin sets defined. Binning should not be defined for scalar sensors; therefore, the binning_index definition is not included in scalar sensor definitions.

      The following is an example PIDF sensors block containing four sensors. All four sensors use the same scan_block_info definition and in this case, there are 3 scan units defined, each with its own binning scheme.

          int num_sensors = 4;                                   $$ no. of sensors
          struct Sensor0 {
      $----------------------SENSOR 00--------------------------------------
              string name = "ISen/0";                           $$ sensor name
              string component = "N/A";                         $$ component name
              char source = 'V';                                $$ Vidf/Scf Source
              string scf_filename = "N/A";                      $$ Scf Source Id
              int pidf_sensor_num = 0;                          $$ pidf sensor num
              int vidf_sensor_num = 0;                          $$ sensor vidf no.
              int group_num = 0;                                $$ sensor group no.
              int display_flag = 1;                             $$ display bit
              int scan_block_info = 0;                          $$ Sweep Index
              int num_units = 2;                                $$ no. of units
              int unit_number = 0;                              $$ indices to units
              int unit_number = 1;                              $$ indices to units
              int binning_index = 0;                            $$ binning index
              int binning_index = 1;                            $$ binning index
              int binning_index = 2;                            $$ binning index
          };
          struct Sensor1 {
      $----------------------SENSOR 00------------------------------------
              string name = "ISEN/1";                           $$ sensor name
              string component = "N/A";                         $$ component name
              char source = 'V';                                $$ Vidf/Scf Source
              string scf_filename = "N/A";                      $$ Scf Source Id
              int pidf_sensor_num = 1;                          $$ pidf sensor num
              int vidf_sensor_num = 1;                          $$ sensor vidf no.
              int group_num = 1;                                $$ sensor group no.
              int display_flag = 1;                             $$ display bit
              int scan_block_info = 0;                          $$ Sweep Index
              int num_units = 2;                                $$ no. of units
              int unit_number = 0;                              $$ indices to units
              int unit_number = 1;                              $$ indices to units
              int binning_index = 0;                            $$ binning index
              int binning_index = 1;                            $$ binning index
              int binning_index = 2;                            $$ binning index
          };
          struct Sensor2 {
      $----------------------SENSOR 00------------------------------------
              string name = "ISEN/2";                           $$ sensor name
              string component = "N/A";                         $$ component name
              char source = 'V';                                $$ Vidf/Scf Source
              string scf_filename = "N/A";                      $$ Scf Source Id
              int pidf_sensor_num = 2;                          $$ pidf sensor num
              int vidf_sensor_num = 2;                          $$ sensor vidf no.
              int group_num = 2;                                $$ sensor group no.
              int display_flag = 1;                             $$ display bit
              int scan_block_info = 0;                          $$ Sweep Index
              int num_units = 2;                                $$ no. of units
              int unit_number = 0;                              $$ indices to units
              int unit_number = 1;                              $$ indices to units
              int binning_index = 0;                            $$ binning index
              int binning_index = 1;                            $$ binning index
              int binning_index = 2;                            $$ binning index
          };
          struct Sensor3 {
      $----------------------SENSOR 00------------------------------------
              string name = "ISEN/3";                           $$ sensor name
              string component = "N/A";                         $$ component name
              char source = 'V';                                $$ Vidf/Scf Source
              string scf_filename = "N/A";                      $$ Scf Source Id
              int pidf_sensor_num = 3;                          $$ pidf sensor num
              int vidf_sensor_num = 3;                          $$ sensor vidf no.
              int group_num = 3;                                $$ sensor group no.
              int display_flag = 1;                             $$ display bit
              int scan_block_info = 0;                          $$ Sweep Index
              int num_units = 2;                                $$ no. of units
              int unit_number = 0;                              $$ indices to units
              int unit_number = 1;                              $$ indices to units
              int binning_index = 0;                            $$ binning index
              int binning_index = 1;                            $$ binning index
              int binning_index = 2;                            $$ binning index
          };
      

    17. Scan
    18. The PIDF scan block is a set of definitions for each set of scan ranges. The word "scan" is used here to indicate that it is the variable which is independent (or scanned) in a measurement. Scalars do not have a scan dependency. Examples of scan dependencies are: frequency, energy, altitude, current, etc.; and represents a parameter controlled by the instrument.

      The PIDF scan block consists of a quantifier, indicating the number of scans being defined, followed by the scan definitions. Each scan definition describes a set of scan measurements applicable for one or more of the defined sensors. If the PIDF field data_type_mask does not have the scan flag set, then the scan block is not included in the PIDF and the scan_block_info definition is not included within the sensor definition above (see section 8). If the PIDF does have data_type_mask, then there is at least one scan block definition set to be described. In this case, each definition set of the sensors must include the scan_block_info definition.

      The fields within the PIDF scan block are described below.

      1. num_scan

        The num_scan is an integer which describes how many definition sets of scanning information are included. The following fields comprise a scan definition set and are repeated num_scan times.

      2. scan_block_num

        This definition is an integer which indicates the scan block set. Each scan block set is described by a structure called scan followed by the scan block number which must be identical to the value of scan_block_num.

        Scan blocks begin counting at zero and are sequential.

      3. num_units

        This definition is an integer which indicates the number of units defined by the scan block.

        Each unit definition is itself a structure which describes how the scan unit is applied. There is a separate structure definition for each unit defined within a scan block with the name ScanUnit followed by the scan unit number. The scan unit number is counted at zero and is continuous.

      4. spacing

        A character that defines the spacing between adjacent scan values. The choices are "L", "I", and "V" where the meanings of these characters are:

        • L - Scan values have equal logarithmic spacing.
        • I - Scan values have equal linear spacing.
        • V - Scan values have variable spacing.

      5. units_index

        An integer indicates the unit number described in the definition of the units which applies to the scan. When computing scan values, it is assumed that the resulting values are the center values of the scan for logarithmic or linearly spaced scan widths. For variable (V) spacing, the scan widths are explicitly defined.

      6. scan_scf_sensor

        For the case where the scan block pertains to a sensor that is an SCF data source, this field reflects the sensor number of the SCF output variable that is to be used as the scan center values. The SCF output sensors are numbered starting at zero.

      7. bin_location

        When variable (V) spacing is requested, this additional character value is required. The bin_location describes the relationship between the scan values (center) and scan widths. The recognized definitions are:

        • U - Scan values are the upper edges of the scan bins and the lower edges of the scan bins are computed by subtracting the scan widths from the scan values.
        • C - Scan values are the centers of the scan bins; that is, one-half of the scan width is added to (subtracted from) the scan value in order to compute the upper (lower) edges of the scan bins.
        • L - Scan values are the lower edges of the scan bins and the upper edges of the scan bins are computed by adding the scan widths to the scan values.
        • E - Scan values are the lower edges of the scan bins and the scan widths are not deltas, but rather, actual values that define the upper edges of the scan bins.
        • A - Scan values for the centers, lower edges and upper edges are explicitly defined within the VIDF. The field units_index pertains to the centers, the field var_units pertains to the lower edges and the field var_units_ub pertains to the upper edges.

      8. var_units

        When variable (V) spacing is requested, this additional integer variable specifies the unit number required to reproduce the scan widths. For the case of variable spacing, the widths returned should be the actual width of the scan values and these do not have to be continuous. When the bin_location is set to 'A', this unit number reproduces the actual lower edges of the scan bins which are specified within the VIDF.

      9. v_scan_scf_sensor

        When variable (V) spacing is requested and the scan block pertains to a sensor that is an SCF data source, this additional integer variable specifies the sensor number of the SCF output variable that is to be used as the scan widths. When the bin_location is set to 'A', this variable defines which SCF output variable returns the actual lower edges of the scan bins. The SCF output sensors are numbered starting at zero.

      10. var_units_ub

        When variable (V) spacing is requested and the bin_location is set to 'A', this additional integer variable specifies the unit number required to reproduce the actual upper edges of the scan bins which are specified within the VIDF.

      11. v_scan_ub_scf_sensor

        When variable (V) spacing is requested, the bin_location is set to 'A', and the scan block pertains to a sensor that is an SCF data source, this additional integer variable specifies the sensor number of the SCF output variable that returns the actual upper edges of the scan bins. The SCF output sensors are numbered starting at zero.


      The following is an example of PIDF scan block taken from the HAPI AXSA instrument on the DE satellite.

          int num_scan = 2;                                      $$ no. of scan blocks
          struct Scan0 {
      $----------------------SCAN BLOCK 00----------------------------------
              int scan_block_num = 0;                           $$ scan block number
              int num_units = 4;                                $$ no. scan of units
              struct ScanUnit0 {
                  char spacing = 'I';                          $$ raw sweep
                  int units_index = 0;                         $$ raw sweep
              };
              struct ScanUnit1 {
                  char spacing = 'L';                          $$ center eV
                  int units_index = 2;                         $$ center eV
              };
              struct ScanUnit2 {
                  char spacing = 'V';                          $$ energy bands
                  int units_index = 2;                         $$ energy bands
                  char bin_location = 'C';                     $$ energy bands
                  int var_units = 3;                           $$ energy bands
              };
              struct ScanUnit3 {
                  char spacing = 'V';                          $$ energy bands
                  int units_index = 2;                         $$ center energies
                  char bin_location = 'A';                     $$ specified in VIDF
                  int var_units = 4;                           $$ lower edges
                  int var_units_ub = 5;                        $$ upper edges
              };
          };
         struct Scan1 {
      $----------------------SCAN BLOCK 01----------------------------------
              int scan_block_num = 1;                            $$ scan block number
              int num_units = 2;                                 $$ number of scans
              struct ScanUnit0 {
                  char spacing = 'L';                            $$ spacing
                  int units_index = 62;                          $$ scan units index
                  int scan_scf_sensor = 3;                       $$ SCF scan output
              };
              struct ScanUnit1 {
                  char spacing = 'V';                            $$ spacing
                  char bin_location = 'C';                       $$ bin location
                  int units_index = 62;                          $$ scan units index
                  int var_units = 64;                            $$ var units index
                  int scan_scf_sensor = 1;                       $$ SCF scan centers
                  int v_scan_scf_sensor = 2;                     $$ SCF scan bands
              };
          };
      

    19. Calibration Data
    20. The PIDF calibration data block is a set of definitions which describe each set of calibration data. Calibration data is any data which is used to adjust or interpret sensor and/or scan data. Examples may be background values which need to be subtracted from the sensor data to adjust or uncover the true measurement and telemetry quality indicators which signify a good or bad measurement.

      The PIDF calibration block consists of a quantifier, indicating the number of calibration sets being defined, followed by the calibration set definitions. Each definition contains a set of textual descriptions, the source for the calibration set, and applicable unit numbers. Note, if in the PIDF field data_type_mask, the calibration flag is not set, then the calibration block is not included in the PIDF.

      The fields within the PIDF calibration block are described below:

      1. num_cals

        The num_cals is an integer which describes how many definition sets of calibration data information are included. The following fields comprise a calibration set definition and are repeated num_cals times.

      2. name

        This definition is a string with a maximum length of forty characters. It is an ASCII description of the calibration set described. The name should be a general description of the calibration data and appropriate for the calibration set descriptions in program interfaces.

      3. short_name

        This definition is a string with a maximum twenty characters. It is a very short abbreviation of the calibration data set name is useful when labeling plots.

      4. pidf_cal_num

        The pidf_cal_num is an integer and reflects a sequential number which indicates the calibration set being described. Valid numbers begin with zero and conclude with num_cals - 1. There should be one set of calibration data definitions for each pidf_cal_num. In the structure of the PIDF, each set of calibration data definitions is described by a struct statement and given a label. That label should correspond to the pidf_cal_num and has the prefix CalSet. For example, the fourteenth PIDF calibration data_set has a "int pidf_cal_num = 13;" and the set of calibration definitions is labeled with "struct CalSet13 {". A unique PIDF calibration data set number is defined for each set of calibration data in the PIDF.

      5. vidf_cal_num

        The definition is an integer describing the calibration data set number contained within the VIDF. This number is its position within the cal_names VIDF field. Note, the first calibration set within this list is calibration set number zero.

      6. num_units

        This definition is an integer which indicates the number of units defined by the calibration set.

      7. unit_number

        This definition is an integer and is repeated num_units times, which specify the unit definitions. Each number is an index into the units block with the the first unit definition being unit zero.

      8. cal_modify_flag

        This definition is a character which indicates whether the calibration set modifies the sensor data or the scan data. The accepted values are:

        • Y - Calibration set modifies sensor data.
        • N - Calibration set modifies scan data.

      9. number_cal_sensors

        If cal_modify_flag indicates that the calibration set modifies sensor data (i.e. cal_modify_flag = 'Y'), then the sensors which the calibration set modifies are listed next. This keyword is an integer which specifies the number of sensors which are modified by calibration data.

      10. cal_based_on_sensor

        This definition is an integer corresponding to a sensor whose data is modified by calibration data. Repeat the keyword number_cal_sensors times. If the calibration set applies to all the sensors, this field can be set to -1 and number_cal_sensors must be set to 1.

      11. source

        This definition is an ASCII character indicating the data source location within the IDFS hierarchy. There are three possible answers :

        1. V - indicating that the calibration set is an IDFS calibration set.
        2. S - indicating that the calibration set is an SCF calibration set.
        3. A - indicating that the calibration set is an auxiliary calibration set which is derived from IDFS or SCF calibration sets.
        For this field, a default value of 'V' for VIDF definition is defined for backwards compatibility; therefore, for IDFS calibration sets, this field is optional.


      The following is a modified PIDF calibration set block taken from the RETE RTLP Langmuir probe instrument on the TSS-1 flight.

          int num_cals = 3;                                      $$ no. of cal. sets
          struct CalSet0 {
      $-----------------------CAL SET 00------------------------------------
              string name = "Sweep Steps";                      $$ cal set name
              string short_name = "SwpStps";                    $$ cal set name
              int pidf_cal_num = 0;                             $$ pidf cal number
              int vidf_cal_num = 0;                             $$ cal set no.
              int num_units = 2;                                $$ no. of units
              int unit_number = 0;                              $$ unit numbers
              int unit_number = 4;                              $$ unit numbers
              char cal_modify_flag = 'N';                       $$ cal based on sensors
              int number_cal_sensors = 1;                       $$ how many sensors
              int cal_based_on_sensor = -1;                     $$ sensors modified
              char source = 'V';                                $$ cal. data source
          };
          struct CalSet1 {
      $-----------------------CAL SET 01------------------------------------
              string name = "Decrement";                        $$ cal set name
              string short_name = "Decre";                      $$ cal set name
              int pidf_cal_num = 1;                             $$ pidf cal number
              int vidf_cal_num = 1;                             $$ cal set no.
              int num_units = 2;                                $$ no. of units
              int unit_number = 0;                              $$ unit numbers
              int unit_number = 5;                              $$ unit numbers
              char cal_modify_flag = 'N';                       $$ cal based on sensors
              int number_cal_sensors = 1;                       $$ how many sensors
              int cal_based_on_sensor = -1;                     $$ sensors modified
              char source = 'V';                                $$ cal. data source
          };
          struct CalSet2 {
      $-----------------------CAL SET 02------------------------------------
              string name = "Sweep Starting Voltage";           $$ cal set name
              string short_name = "Beg/V";                      $$ cal set name
              int pidf_cal_num = 2;                             $$ pidf cal number
              int vidf_cal_num = 2;                             $$ cal set no.
              int num_units = 2;                                $$ no. of units
              int unit_number = 0;                              $$ unit numbers
              int unit_number = 6;                              $$ unit numbers
              char cal_modify_flag = 'N';                       $$ cal based on sensors
              int number_cal_sensors = 1;                       $$ how many sensors
              int cal_based_on_sensor = -1;                     $$ sensors modified
              char source = 'V';                                $$ cal. data source
          };
      

    21. Mode
    22. The PIDF mode block is a set of definitions which describe each set of mode data. Mode data is data which describes the configuration of the instrument taking the data. This might be gain setting, post-acceleration value, operational frequency, etc.

      The PIDF mode block consists of a quantifier, followed by the mode definitions. If in the PIDF field data_type_mask the mode flag is not set, then the mode block is not included in the PIDF.

      The fields within the PIDF mode block are described below.

      1. num_modes

        The num_modes is an integer which describes how many definition sets of modes are included. The following fields comprise a mode definition and are repeated num_modes times.

      2. name

        This definition is a string with a maximum length of forty characters. It is an ASCII description of the mode described. The name should be a general description of the mode and is appropriate for use in mode descriptions in program interfaces.

      3. short_name

        This definition is a string with a maximum length of twenty characters. It is a very short abbreviation of the name of the mode and is useful when labeling plots.

      4. pidf_mode_num

        This pidf_mode_num is an integer and reflects a sequential number which indicates the mode set being described. Valid numbers begin with zero and conclude with num_modes - 1. There should be one set of mode definitions for each pidf_mode_num. In the structure of the PIDF, each set of mode definitions is described by a "struct" statement and given a label. That label should correspond to the pidf_mode_num and has the prefix "Mode". For example, the third PIDF mode set has a "int pidf_mode_num = 2" and the set of mode definitions is labeled with "struct Mode2 {". A unique PIDF mode number is defined for each definition.

      5. vidf_mode_num

        This definition is an integer which describes the number of units defined by the mode set. This number is the position of the mode as found within the status_names VIDF field. The first mode within this list is mode number zero.

      6. num_units

        The definition is an integer which describes the number of units defined by the mode set.

      7. unit_number

        This integer keyword is repeated num_units times. Each number specifies a unit definition which is an index into the PIDF's units block.


      The following is the PIDF mode block taken from the RETE RTLP Langmuir probe instrument on the TSS-1 flight.

          int num_modes = 4;                                     $$ no. of modes
          struct Mode0 {
      $-------------------------MODE 00-------------------------------------
              string name = "Gain";                             $$ mode name
              string short_name = "Gain";                       $$ mode name
              int pidf_mode_num = 0;                            $$ pidf mode number
              int vidf_mode_num = 0;                            $$ mode no.
              int num_units = 1;                                $$ no. of units
              int unit_number = 1;                              $$ unit numbers
          };
          struct Mode1 {
      $-------------------------MODE 01-------------------------------------
              string name = "Calibration";                      $$ mode name
              string short_name = "Cal";                        $$ mode name
              int pidf_mode_num = 1;                            $$ pidf mode number
              int vidf_mode_num = 1;                            $$ mode no.
              int num_units = 1;                                $$ no. of units
              int unit_number = 1;                              $$ unit numbers
          };
          struct Mode2 {
      $-------------------------MODE 02-------------------------------------
              string name = "Shunt Capacitor";                  $$ mode name
              string short_name = "ShuntCap";                   $$ mode name
              int pidf_mode_num = 2;                            $$ pidf mode number
              int vidf_mode_num = 2;                            $$ mode no.
              int num_units = 1;                                $$ no. of units
              int unit_number = 1;                              $$ unit numbers
          };
          struct Mode3 {
      $-------------------------MODE 03-------------------------------------
              string name = "Fine Sweep";                       $$ mode name
              string short_name = "FineSwp";                    $$ mode name
              int pidf_mode_num = 3;                            $$ pidf mode number
              int vidf_mode_num = 3;                            $$ mode no.
              int num_units = 1;                                $$ no. of units
              int unit_number = 1;                              $$ unit numbers
          };
      

    23. Data Quality
    24. The PIDF data quality block describes how the data quality is presented. For a data set to have data quality, it must have the appropriate flag set in the variable described in the section 4, data_type_mask. If this flag is not set then the data quality structure is not included within the PIDF.

      1. name

        This definition is a string with a maximum length of forty characters. It is an ASCII description of the data quality included in the data. This name should be a general description of the quality data since it is likely there are several meanings for different values of the data quality and is appropriate for the quality descriptions in program interfaces.

      2. short_name

        This definition is a string with a maximum length of twenty characters. It is a very short abbreviation of the data quality name and is useful when labeling plots.

      3. num_units

        This definition is an integer which specifies the number of unit definitions contained within the quality block.

      4. unit_number

        This definition is an integer describing a unit number within the units block which is to be used to interpret the quality data. This field is repeated num_units times.


      The following is the PIDF quality block taken from the RETE RTLP Langmuir probe instrument on the TSS-1 flight. It is rare that a quality block looks much different than this with the exception of the location of the appropriate units definition which is basically used to give expected range.

          struct DataQual {
      $*********************************************************************
              string name = "Data Quality";                     $$ dqual name
              string short_name = "Dqual";                      $$ dqual name
              int num_units = 1;                                $$ no. of units
              int unit_number = 1;                              $$ unit numbers
          };
      

    25. Pitch Angle
    26. The PIDF pitch angle block consists of a set of textual descriptions and any applicable unit definitions. For a data set to have a pitch angle block, it must have the appropriate flag set in the PIDF field data_type_mask. If this flag is not set, then the pitch angle block should not be included within the PIDF. The fields within the pitch angle PIDF information block are described below.

      1. name

        This definition is a string with a maximum length of forty characters. It is an ASCII description of the pitch angle included in the data. This name should be a general description of the pitch angle (e.g. "Pitch Angle") as it is used in the program interfaces.

      2. short_name

        This definition is a string with a maximum length of twenty characters. It is a very short abbreviation of the pitch angle name and is useful when labeling plots.

      3. num_units

        This definition is an integer which specifies the number of unit definitions contained within the pitch angle block.

      4. unit_number

        This definition is an integer describing a unit number within the units block which is to be used to interpret the pitch angle data. This field is repeated num_units times.


      The following is the PIDF pitch angle block taken from the ROPE RPEA probe instrument on the TSS-1R flight. It is rare that a pitch angle block looks much different than this with the exception of the location of the appropriate units definition which is basically used to give expected range.

          struct PitchAngle {
      $*********************************************************************
              string name = "Pitch Angle";                      $$ pitch angle name
              string short_name = "PA";                         $$ pitch angle name
              int num_units = 1;                                $$ no. of units
              int unit_number = 16;                             $$ unit numbers
          };
      

    27. Spin Angle
    28. The PIDF spin angle block consists of a set of textual descriptions and any applicable unit definitions. For a data set to have a Spin Angle block, it must have the appropriate flag(s) set in the PIDF field data_type_mask. If the flag(s) is not set, then the Spin Angle block should not be included within the PIDF. The fields within the Spin Angle PIDF information block are described below.

      1. name

        This definition is a string with a maximum length of forty characters. It is an ASCII description of the spin angle data. This name should be a general description of the spin angle which is appropriate for the program interfaces.

      2. short_name

        This definition is a string with a maximum length of twenty characters. It is a very short abbreviation of the spin angle name and is useful when labeling plots.

      3. num_units

        This definition is an integer which specifies the number of unit definitions contained within the spin angle block.

      4. unit_number

        This definition is an integer describing a unit number within the units block which is to be used to interpret the spin angle data. This field is repeated num_units times.


      The following is the PIDF spin angle block taken from the ROPE RPEA probe instrument on the TSS-1R flight. It is rare that a spin angle block looks much different than this with the exception of the location of the appropriate units definition which is basically used to give expected range.

          struct SpinAngle {
      $*********************************************************************
              string name = "Spin Angle";                       $$ spin angle name
              string short_name = "SA";                         $$ spin angle name
              int num_units = 1;                                $$ no. of units
              int unit_number = 17;                             $$ unit numbers
          };
      

    29. Spacecraft Potential Data
    30. The PIDF spacecraft potential block consists of a set of textual descriptions and any applicable unit definitions. For a data set to have a spacecraft potential block, it must have the appropriate flag set in the PIDF field data_type_mask. If this flag is not set, then the spacecraft potential block should not be included within the PIDF. The fields within the spacecraft potential PIDF information block are described below.

      1. name

        This definition is a string with a maximum length of forty characters. It is an ASCII description of the spacecraft potential included in the data. This name should be a general description of the spacecraft potential (e.g. "Spacecraft Potential") as it is used in the program interfaces.

      2. short_name

        This definition is a string with a maximum length of twenty characters. It is a very short abbreviation of the spacecraft potential name and is useful when labeling plots.

      3. num_units

        This definition is an integer which specifies the number of unit definitions contained within the spacecraft potential block.

      4. unit_number

        This definition is an integer describing a unit number within the units block which is to be used to interpret the spacecraft potential data. This field is repeated num_units times.

      5. num_units_use_potential

        This definition is an integer which specifies the number of unit definitions for this virtual instrument which use spacecraft potential data to modify the sensor and/or scan data when converting the data into scientific units.

      6. used_in_unit_number

        This definition is an integer describing a unit number within the units block which utilizes spacecraft potential data to convert the data into scientific units. This field is repeated num_units_use_potential times.


      The following is the PIDF spacecraft potential block taken from the PEACE 3DX1 CPXP1L instrument on the CLUSTER-1 satellite from the CLUSTERII mission.

          struct SCPotential {
      $*********************************************************************
              string name = "Spacecraft Potential";             $$ S/C Potential name
              string short_name = "SP";                         $$ S/C Potential short name
              int num_units = 2;                                $$ num. units
              int unit_number = 44;                             $$ S/C Potential units
              int unit_number = 45;                             $$ S/C Potential units
              int num_units_use_potential = 15;                 $$ how many units use pot.
              int used_in_unit_number = 27;                     $$ pot. used by unit no.
              int used_in_unit_number = 28;                     $$ pot. used by unit no.
              int used_in_unit_number = 29;                     $$ pot. used by unit no.
              int used_in_unit_number = 30;                     $$ pot. used by unit no.
              int used_in_unit_number = 31;                     $$ pot. used by unit no.
              int used_in_unit_number = 32;                     $$ pot. used by unit no.
              int used_in_unit_number = 33;                     $$ pot. used by unit no.
              int used_in_unit_number = 34;                     $$ pot. used by unit no.
              int used_in_unit_number = 35;                     $$ pot. used by unit no.
              int used_in_unit_number = 36;                     $$ pot. used by unit no.
              int used_in_unit_number = 40;                     $$ pot. used by unit no.
              int used_in_unit_number = 41;                     $$ pot. used by unit no.
              int used_in_unit_number = 42;                     $$ pot. used by unit no.
              int used_in_unit_number = 43;                     $$ pot. used by unit no.
              int used_in_unit_number = 45;                     $$ pot. used by unit no.
          };
      

    31. Background Data
    32. The PIDF background block consists of a set of textual descriptions and any applicable unit definitions. For a data set to have a background block, it must have the appropriate flag set in the PIDF field data_type_mask. If this flag is not set, then the background block should not be included within the PIDF. The fields within the background PIDF information block are described below.

      1. name

        This definition is a string with a maximum length of forty characters. It is an ASCII description of the background values included in the data. This name should be a general description of the background (e.g. "Background") as it is used in the program interfaces.

      2. short_name

        This definition is a string with a maximum length of twenty characters. It is a very short abbreviation of the background name and is useful when labeling plots.

      3. num_units

        This definition is an integer which specifies the number of unit definitions contained within the background block.

      4. unit_number

        This definition is an integer describing a unit number within the units block which is to be used to interpret the background data. This field is repeated num_units times.


      The following is the PIDF background block taken from the ASPERA-3 ELS ELSSCIH instrument on the Mars_Express satellite from the MARS mission.

          struct Background {
      $*********************************************************************
              string name = "Background";                       $$ Background name
              string short_name = "BKGD";                       $$ Background short name
              int num_units = 2;                                $$ num. units
              int unit_number = 184;                            $$ Background units
              int unit_number = 185;                            $$ Background units
          };
      

    33. Moments
    34. The PIDF moments block defines the required values for the calculation of plasma moments. These values have PIDF specification so that they can be easily altered.

      The fields within the PIDF moments block are described below.

      1. moment_mass

        For moment calculations, the mass of the species must be defined. The value is a floating point number which represents the actual value of the mass as opposed to an integer number of mass units. The value defined should be the default value to use in moments calculations and is expressed in units of kilograms, kg.

      2. velocity_unit

        This is an integer which describes where to find the information within the Units section of the PIDF for the velocity scan unit. Each unit has an associated unit number index. This variable contains the unit number index which is to be used to interpret the data (see the section on Units above). The Units of the velocity scan unit must be in m/s.

      3. vel_diff_fun_unit

        This is an integer which describes where to find the information within the Units section of the PIDF for the differential number flux unit of the sensor data. Each unit has an associated unit number index. This variable contains the unit number index which is to be used to interpret the data (see the section on Units above). The Units of the differential number flux unit must be in s**3/m**6.

      4. moment_charge

        This is an integer which defines the sign of the plasma charge. This value is used to determine the amount of charge within the plasma. This value is defined in units of charge, or electrostatic units [esu]. Each esu has a unit charge, or 1.602e-19 Coulomb. Negative values indicate negative charged ions or electrons whereas positive values indicate positive ions or protons. Neutral particles are unaffected by the charge on the spacecraft.

      The following is an example of the PIDF moments block.

        struct Moments {
      $********************MOMENTS INFO*************************************
          float moment_mass = 9.11e-31;       $$ mass [kg] to use for moments
          int velocity_unit = 26;             $$ scan unit for moments [m/s]
          int vel_diff_fun_unit = 13;         $$ sensor unit for moments [s**3/m**6]
          int moment_charge = -1;             $$ in units of a charge [esu]
        };
      

      For the above example, units 26 and 13 must be defined in the PIDF.

    35. Coordinate System Transformation
    36. The PIDF coordinate system transformation block defines the required values for the specification of which coordinate system(s) the data can be transformed into.

      The fields within the PIDF coodinate system transformation block are described below.

      1. default_coord_system

        This is a character string that indicates which coordinate system the data is stored under in the IDFS data set.

      2. num_transfer

        This definition is an integer which specifies the number of coordinate systems that the data can be transformed into.

      3. transfer_unit

        This definition is a string describing the coordinate system that the data can be transformed into. This field is repeated num_transfer times. This information is used by applications to display to the user the options that are available for transforming the data into allowable coordinate systems for the data set in question.

      The following is an example of the PIDF coordinate system transformation block.

        struct CoordinateSystem {
              string default_coord_system = "SPACECRAFT";       $$ data in spacecraft
              int num_transfer = 11;                            $$ no. coord. systems
              string transfer_unit = "SPACECRAFT";              $$ Spacecraft coord.
              string transfer_unit = "PMI";                     $$ PMI coord. system
              string transfer_unit = "GEI";                     $$ GEI coord. system
              string transfer_unit = "GEO";                     $$ GEO coord. system
              string transfer_unit = "GSE";                     $$ GSE coord. system
              string transfer_unit = "GSM";                     $$ GSM coord. system
              string transfer_unit = "SM";                      $$ SM coord. system
              string transfer_unit = "MAG";                     $$ MAG coord. system
              string transfer_unit = "HEE";                     $$ HEE coord. system
              string transfer_unit = "HAE";                     $$ HAE coord. system
              string transfer_unit = "HEEQ";                    $$ HEEQ coord. system
         };
      

    37. Tensor Description
    38. The PIDF tensor block is defined when the IDFS data set contains multi-dimensional data (tensor). The PIDF tensor block consists of a quantifier, indicating the number of dimensions being defined, followed by the definition of each individual dimension.

      The fields within the PIDF tensor block are described below.

      1. rank

        This definition is an integer which defines the dimensionality (rank) of the tensor defined within the IDFS data record. This value can be between 1 and 10, with the value 2 representing 2-D or matrix data. The following fields comprise a dimension definition set and are repeated rank times.

      2. name

        This definition is a character string with a maximum length of forty characters. It is an ASCII description of the dimension described. The name should be a general description of the dimension and should be appropriate for tensor dimension identification in program interfaces.

      3. id

        There is a unique id value for each dimension supported within the IDFS paradigm. This value is an integer, normally greater than zero, which is used to uniquely identify one dimension from another. There is a wildcard id which has the value of zero. A list of currently defined id values are given in Appendix C. If the dimension being described is not currently listed amongst these id definitions, this value should be set to zero and the personnel at SwRI should be contacted to expand this list to include the dimension being defined.

      4. length

        This definition is an integer value which defines the number of values that are returned for the dimension being described. This value cannot be set to zero.

      5. values

        This definition is an array of floating point values, with the size of the array set to length. Each dimension that is defined has an associated range for the quantity being reported. This range can be equally divided into length sub-ranges. The floating point values that are defined by this field represent the center value for each sub-range that the dimension covers.

        For example, let's say that the dimension being defined represents Phi Angles. Phi Angles range from 0.0 to 360.0 degrees. If the length of this dimension was set to 4, there would be 4 sub-ranges: 1) 0.0 to 90.0, 2) 90.0 to 180.0, 3) 180.0 to 270.0 and 4) 270.0 to 360.0. The center values for each sub-range would be reported in this field, with the 4 values being 45.0, 135.0, 225.0, and 315.0.

      6. num_units

        This definition is an integer which indicates the number of units defined by the dimension being described. This field is utilized to be consistent with other unit definitions within the PIDF file. Since multi-dimensional data must be stored within the IDFS data record in the unit to be returned, the value for this field must be set to 1. In other words, for multi-dimensional data, there is no conversion of data from one unit to another, unlike other IDFS data parameters.

      7. unit_number

        This definition is an integer and is repeated num_units times, which specify the unit definitions. Each number is an index into the units block with the the first unit definition being unit zero.

      The following is an example of the PIDF tensor block.

        struct Tensor {
              int rank = 2;                                       $$ 2-D matrix (16x16)
              struct TensorDimension0 {
                  string name = "Time Of Flight";                 $$ dimension name
                  int id = 1;                                     $$ dimension id (Time Of Flight)
                  int length = 16;                                $$ 16 elements
                  float values [16] = { 0.5,  1.5,  2.5,  3.5,    $$ bin center values
                                        4.5,  5.5,  6.5,  7.5,
                                        8.5,  9.5, 10.5, 11.5,
                                       12.5, 13.5, 14.5, 15.5};
                  int num_units = 1;                              $$ no. of units
                  int unit_number = 6;                            $$ unit numbers
              };
              struct TensorDimension1 {
                  string name = "Pulse Height Analysis";          $$ dimension name
                  int id = 2;                                     $$ dimension id (Pulse Height Analysis)
                  int length = 16;                                $$ 16 elements
                  float values [16] = { 0.5,  1.5,  2.5,  3.5,    $$ bin center values
                                        4.5,  5.5,  6.5,  7.5,
                                        8.5,  9.5, 10.5, 11.5,
                                       12.5, 13.5, 14.5, 15.5};
                  int num_units = 1;                              $$ no. of units
                  int unit_number = 6;                            $$ unit numbers
              };
          };
      

      For the above example, unit 6 must be defined in the PIDF.

    39. Appendix A
    40. The transformation of IDFS data into physical units occurs through the successive application of tables defined in the VIDF. When the IDFS paradigm was first designed, it was envisioned that all unit conversions could be performed using a maximum of two data buffers (or accumulators). Keeping this in mind, each table application is defined by a four digit operation code. The ones digit specifies one of the defined basic mathematical operations, the hundreds and tens digits are used to indicate extended operations and the thousands place gives information on the data buffer usage. Each operation code must consist of one basic operation and may also include an extended operation.

      The basic operations are listed in the table below. The symbols in parenthesis can be used to indicate the operator within the PIDF when the basic operation is used alone, i.e the numerical operator would be just the simple basic operation with no higher order operations attached. The supported column, indicates whether the operation is currently supported within the current version of the IDFS read routines.

             +--------------------------------------------------+
             |            BASE OPERATOR DEFINITIONS             |
             +-------+----------------------------+-------------+
             |VALUE  |       BASE OPERATION       |  SUPPORTED  |
             +-------+----------------------------+-------------+
             |  0    |         equals (=)         |     yes     |
             +-------+----------------------------+-------------+
             |  1    |        addition (+)        |     yes     |
             +-------+----------------------------+-------------+
             |  2    |      subtraction (-)       |     yes     |
             +-------+----------------------------+-------------+
             |  3    |     multiplication (x)     |     yes     |
             +-------+----------------------------+-------------+
             |  4    |        division (/)        |     yes     |
             +-------+----------------------------+-------------+
             |  5    |      logical and  (&)      |     yes     |
             +-------+----------------------------+-------------+
             |  6    |      logical or  (|)       |     yes     |
             +-------+----------------------------+-------------+
             |  7    |   bit shift right   (>>)   |     yes     |
             +-------+----------------------------+-------------+
             |  8    |    bit shift left  (<<)    |     yes     |
             +-------+----------------------------+-------------+
             |  9    |        modulus (%)         |     yes     |
             +-------+----------------------------+-------------+
      

      All basic operations, except for the equals operator (=), have the operational form:

      DATA BUFFER = DATA BUFFER Basic_oper V(Table)

      where Basic_oper is a defined mathematical operation and V(Table) is the output of one of the VIDF tables.

      The equals operator (value operator) is used to set the buffer currently in use and has the operational form:

      DATA BUFFER = V(Table)

      where V(Table) is the output of one of the VIDF tables.

      The tens and hundreds place of the operation code define the extended operations. Extended operations, which are specified as 2-digit values, are functional operations which modify the buffer in usage. If no extended operation is needed, a zero value should be specified for the tens and hundreds place of the operation code (00). The extended operations are listed in the table below, where B is the current buffer value.

      EXTENDED OPERATIONS
      VALUEOPERATION
      01eB
      02logeB
      0310B
      04log10B
      052B
      06sqrt (B)
      07cos (B)(degrees)
      08sin (B)(degrees)
      09tan (B)(degrees)
      10acos (B)
      11asin (B)
      12atan (B)
      131/B
      14B * data_accum (in seconds)
      15B / data_accum (in seconds)
      16-B
      17B2
      18B - (Stop Azimuthal Angle + Start Azimuthal Angle)/2
      19abs(B)
      20B + Start Azimuthal Angle
      21(int) B
      22(signed)B (8 bit 2's complement)
      23(signed)B (16 bit 2's complement)
      24(signed)B (12 bit 2's complement)
      25(signed)B (24 bit 2's complement)
      26int (B)
      27frac (B)
      28ceil (B)
      29floor (B)
      30erf (B)

      Most of the extended operations are self-explanatory. Extended operations 21 and 26 perform the same function, but use two different methods. Extended operation 21 is simply an integer cast of the floating point value. Extended operation 26 extracts the signed integral value from the floating point value using the modf() function. Extended operation 27 is the complement of extended operation 26, returning the signed fractional value from the floating point value using the modf() function. Extended operations 28 and 29 perform rounding operations, rounding up or down to the nearest integer, respectively. Extended operation 30 returns the error function of B.

      The extended operations are performed after the basic operation has been completed and have the operational form:

      DATA BUFFER = Extended_oper [DATA BUFFER]

      The combination of an extended operation with a base operation combines to yield the form:

      DATA BUFFER = Extended_oper [DATA BUFFER Basic_oper V(Table)]

      Thus, the table is evaluated and then applied to the data buffer using the Basic_oper. Then, the Extended_oper is applied and the result is left in the data buffer. As an example, suppose you are in the process of reconstructing the temperature from a monitor's telemetry value. You have evaluated a table and placed its value in the primary buffer already. Now you want to evaluate a second polynomial, say from table 2 (tbl_app_flag=2), multiply it by the value in the primary buffer and then square the result. In this case, the Extended_oper=17, the Basic_oper=3, which combined, forms the operation code value of tbl_app_oper=173.

      At the bare minimum, there are two supported buffers for use in any algorithm. These are called the primary (or main) buffer and the secondary (or temporary) buffer. Which buffer is currently in use is indicated by the value of the thousands place in the four digit operation code.

       +--------------------------------------------------------------+
       |                           BUFFERS                            |
       +-------+----------+-------------------------------------------+
       |VALUE  |  BUFFER  |                  COMMENTS                 |
       +-------+----------+-------------------------------------------+
       |0xxx   |    1     |  This is the main output buffer. Values   |
       |       |          |  in this buffer are those returned        |
       |       |          |  after all complete                       |
       +-------+----------+-------------------------------------------+
       |1xxx   |    2     |  temporary buffer                         |
       +-------+----------+-------------------------------------------+
       |2xxx   |    1     |  The buffers may be combined in only five |
       |       |          |  different ways.  Each applies a          |
       |       |          |  mathematical operator to buffer 2 (the   |
       |       |          |  temporary buffer) and operates on buffer |
       |       |          |  1 (the main buffer).  The result is      |
       |       |          |  stored in buffer 1.                      |
       +-------+----------+-------------------------------------------+
      

      DATA BUFFER 1 = DATA BUFFER 1 Combine_oper DATA BUFFER 2

      When a combine operation is specified, the corresponding table flag is ignored, but a place holder needs to be included. By convention, a value of -1 is used as a place holder to signify that there is no table corresponding to the operation.

      The five Combine_oper for buffer manipulation are given below.

      Combine Buffers
      Value combine_oper Comment
      2001 addition (+) add together both buffers
      2002 subtraction (-) subtract buffer 2 from buffer 1
      2003 multiplication (x) multiply together both buffers
      2004 division (/) divide buffer 2 into buffer 1
      2005 power function (pow) raise the value in buffer 1 to a given power specified in buffer 2

      An extended operation maybe combined with a buffer Combine_oper. In this case, the extended operation always executes on the primary buffer value after it has been combined with the secondary buffer. As an example, suppose you evaluate a polynomial as a function of the telemetry value and store that in the secondary buffer. Then you evaluate a second polynomial and store its result in the primary buffer. In order to take the ratio of the primary buffer to the secondary buffer and then take the logarithm (basee) of the result, you will want to use a Combine_oper of 2004 with an extended operation of 2x, for a tbl_app_oper of 2024. When using combine operations, the tbl_app_oper must be specified to be ignored (tbl_app_flag=-1). Ignoring the application of a VIDF table can only occur in conjunction with a buffer combination operation.

      If one wished to perform an extended operation on a data buffer in between calculations, one must include a table in the VIDF which always evaluates to unity. This table with a base operation of 3 (multiplication) should be used so that the buffer is not really modified. As an example, where we used tbl_app_flag=-1, tbl_app_oper=2024, we could have specified this as a combination of buffers using tbl_app_flag=-1, tbl_app_oper=2004, and then used the unity table (say table 5) to cause the primary value to remain constant prior to taking the logarithm (base e) of the primary buffer: tbl_app_flag=5, tbl_app_oper=23.

      As the complexity of the data sets being stored in the IDFS format have increased, the restriction of two data buffers for unit conversion has had to be expanded. There are now an additional six data buffers that can be utilized for unit conversion. These six new data buffers are referred to as "advanced" data buffers and are similar to the secondary (or temporary) buffer. That is, the advanced data buffers are simply temporary data buffers and the end result of any algorithm used for unit conversion MUST result in the primary data buffer holding the data value to be returned.

      When the data is to be loaded into one of the advanced data buffers, the data buffer to be used is indicated by the value of the thousands place in the four digit operation code, similar to the secondary buffer, as explained in the table below.

       +--------------------------------------------------------------+
       |                           BUFFERS                            |
       +-------+----------+-------------------------------------------+
       |VALUE  |  BUFFER  |                  COMMENTS                 |
       +-------+----------+-------------------------------------------+
       |3xxx   |    3     |  advanced temporary buffer                |
       +-------+----------+-------------------------------------------+
       |4xxx   |    4     |  advanced temporary buffer                |
       +-------+----------+-------------------------------------------+
       |5xxx   |    5     |  advanced temporary buffer                |
       +-------+----------+-------------------------------------------+
       |6xxx   |    6     |  advanced temporary buffer                |
       +-------+----------+-------------------------------------------+
       |7xxx   |    7     |  advanced temporary buffer                |
       +-------+----------+-------------------------------------------+
       |8xxx   |    8     |  advanced temporary buffer                |
       +-------+----------+-------------------------------------------+
       |9xxx   |    9     |  advanced temporary buffer                |
       +-------+----------+-------------------------------------------+
      

      In order to be backwards compatible with IDFS data sets that adhered to the original two data buffer restriction, the table operation code has been expanded to allow a five digit operation code in order to specify which advanced data buffers are to be utilized for the mathematical operation to be performed. The ones digit still specifies one of the basic mathematical operations defined. The hundreds and tens digits are still used to indicate extended operations. The difference comes into play with the thousands and ten thousands digit. With the new five digit operation code, the ten thousands digit represents the from (or source) data buffer and the thousands digit represents the to (or destination) data buffer. This specification is similar to the Combine_oper scenario, except that in the Combine_oper scenario, the source and destination buffers are pre-determined. Similar to the four digit operation code, each five digit operation code must consist of one basic operation and may have an associated extended operation.

      There are a few restrictions that are placed upon the values allowed for the from and to data buffers. The two data buffers specified within a five digit operation code can not be identical; that is, the value for the from data buffer cannot be equal to the value for the to data buffer (for example, 77xxx is not allowed). In addition, in order to maintain backwards compatibilty, the value for the from data buffer or the value for the value for the to data buffer cannot be 2 (for example, 32xxx is not allowed). The value 2 for a data buffer has a reserved meaning and corresponds to one of the five Combine_oper defined for buffer manipulation between the primary and secondary data buffers. However, the functions that are performed by the five Combine_oper operation codes can be mimiced by specifying which two data buffers are to be accessed to perform the mathematical operations. The last restriction that is placed upon the values allowed for the from and to data buffers is pertinent only to the from data buffer specification. Since the digit operation codes are read in from an ASCII PIDF file, the value for the from data buffer cannot be a zero (0). If this was the case, any leading zero would be ignored and the digit operation code would be considered a four-digit value instead of a five-digit value (for example, 09xxx is not allowed).

      As an example, you want to evaluate table 26 (tbl_app_flag=26) and place its value in advanced data buffer 6. This can be achieved by setting the value of tbl_app_oper=6000. Then, let's say you want to evaluate table 40 (tbl_app_flag=40) and place its value in advanced data buffer 5. This can be achieved by setting the value of tbl_app_oper=5000. Once this is done, you want to evaluate a second polynomial, say from table 39 (tbl_app_flag=39), and add it to the value in advanced data buffer 5 (Basic_oper=1), in which case the value of tbl_app_oper=5001. As a final computation, you want to add the data in advanced buffer 6 to the data in advanced buffer 5. This can be achieved by setting the value of tbl_app_oper=65001 and by setting the value tbl_app_flag=-1. With this five digit operation code, the from buffer is defined as advanced buffer 6 and the to buffer is defined as advanced buffer 5.


      Last updated: 04-10-2013