This page was created by the IDL library routine `mk_html_help2`.

Last modified: Mon Aug 25 17:03:10 2025.

# Directory Listing of Routines

# external/das2pro/src

- DAS2_DOUBLE_TO_TT2000
- DAS2_PARSESTREAM[1]
- DAS2_PARSESTREAM[2]
- DAS2_PARSESTREAM[2]
- DAS2_PARSESTREAM[3]
- DAS2_PARSESTREAM[4]
- DAS2_PARSESTREAM[5]
- DAS2_PARSESTREAM[6]
- DAS2_PARSESTREAM[7]
- DAS2_PARSESTREAM[8]
- DAS2_PARSESTREAM[9]
- DAS2_PARSESTREAM[10]
- DAS2_PARSETIME
- DAS2_READHTTP[1]
- DAS2_READHTTP[2]
- DAS2_TEXT_TO_TT2000
- DAS2DECODER__DEFINE[1]
- DAS2DECODER__DEFINE[2]
- DAS2DECODER__DEFINE[2]
- DAS2DECODER__DEFINE[3]
- DAS2DIM__DEFINE
- DAS2DS__DEFINE[1]
- DAS2DS__DEFINE[2]
- DAS2DS__DEFINE[2]
- DAS2DS__DEFINE[3]
- DAS2PROP__DEFINE
- DAS2VAR__DEFINE[1]
- DAS2VAR__DEFINE[2]
- DAS2VAR__DEFINE[2]

# Routine Descriptions

## DAS2DECODER__DEFINE[1]

[Next Routine] [List of Routines]

     Convert a byte array to an array of given type

     :Private:

     :Params:
        aPktData : in, required, type=byte array
           The binary data for an entire das2 packet
     :Keywords:
        debug : in, optional, hidden, type=bool
           If !true print debugging info to standard error

     :Returns:
        an array of given type, time values are converted to TT2000

     :History:
        Jul. 2018, D. Pisa : original
        May  2019, C. Piker : updates to auto-convert times to TT2000

(See external/das2pro/src/das2decoder__define.pro)

## DAS2DECODER__DEFINE[2]

[Previous Routine] [Next Routine] [List of Routines]

     Initialize a das2 stream data value decoder.  Handles coversion of
     time values to TT2000.

     :Private:

     TODO: This should be in das2_parsestream.pro since it uses packet
           headers.

     :Param:
        hPlane : in, required, type=hash
            A hash as return by xml_parse for the <x>, <y>, <z> or <yscan> plane
            of interest.

(See external/das2pro/src/das2decoder__define.pro)

## DAS2DECODER__DEFINE[2]

[Previous Routine] [Next Routine] [List of Routines]

     Return the total number of bytes converted to data values in each
     invocation of das2decoder::decode.

     :Private:

(See external/das2pro/src/das2decoder__define.pro)

## DAS2DECODER__DEFINE[3]

[Previous Routine] [Next Routine] [List of Routines]

     Data plane decoder object, plain object, does not derive from
     IDL_Object, can't have auto properties

     :Private:

(See external/das2pro/src/das2decoder__define.pro)

## DAS2DIM__DEFINE

[Previous Routine] [Next Routine] [List of Routines]

     Das2 dimension object, provides arrays and properties for a single
     physical dimension, such as Time or Spectral Density

(See external/das2pro/src/das2dim__define.pro)

## DAS2DS__DEFINE[1]

[Previous Routine] [Next Routine] [List of Routines]

     Answers the question, how big are data packets for this dataset.

     Datasets can be parsed from das2 streams.  A stream consists of
     header and data packets.  Each data packet must have a sufficent
     number of data values to increment the highest index of the internal
     data arrays by 1.

     :Returns:
        The number of total bytes in each data packet for this dataset.

(See external/das2pro/src/das2ds__define.pro)

## DAS2DS__DEFINE[2]

[Previous Routine] [Next Routine] [List of Routines]

     Inspect all owned variables and get the index range of the
     overall dataset.  Map sizes to array dimensions using the
     index maps.

     :Private:

(See external/das2pro/src/das2ds__define.pro)

## DAS2DS__DEFINE[2]

[Previous Routine] [Next Routine] [List of Routines]

     Provide the key names for all physical dimensions in the dataset

     :Keywords:
         D : in, type=boolean, optional
            Return just the string ids for the data dimensions

         C : in, type=boolean, optional
            Return just the string ids for the coordinate dimensions

     :Returns:
        list - A list of strings containing the hask keys for the requested
            physical dimensions.

     :Author:
        Chris Piker

(See external/das2pro/src/das2ds__define.pro)

## DAS2DS__DEFINE[3]

[Previous Routine] [Next Routine] [List of Routines]

     Dataset objects (das2ds) explicitly denote, and separate, array index
     dimensions and physical dimensions.

     For each physical space, such as Time or Spectral Density, there is a das2dim
     (das2 dimension) member object of a dataset.  Each dimension may have more
     than one set of applicable values.  For example in the Time dimension there
     may be a set of values that represent when a measurement was taken in UTC
     and, the time uncertianty in seconds.  Each set of measurements and thier
     units are contained within a das2var (das2 variable) object.

     To make plots and analyze data we have to know which values "go together".
     Considering an energy spectra dataset for a moment, we would need to know
     what array index numbers should be used to match a time, with an energy level
     with a count rate, with a look direction.  This is a bookkeeping problem.
     We could solve this problem in a manner similar to the ISTP standard by
     insisting that each dimension of an array correspond with a single physical
     dimension.  Doing so quickly results in display tools confusing index space
     for physical space, a problem that we want to avoid.  Instead, to provide this
     information, an overall dataset index space is defined.  Each variable within
     the dataset provides a mapping between it's array indices and the overall
     dataset index space.  This mapping can be used to correlate values from
     various arrays without constraining the nature of the physical measurements
     contained within the dataset.

     :Author:
        Chris Piker

(See external/das2pro/src/das2ds__define.pro)

## DAS2PROP__DEFINE

[Previous Routine] [Next Routine] [List of Routines]

     Das2 property has a type and value

(See external/das2pro/src/das2prop__define.pro)

## DAS2VAR__DEFINE[1]

[Previous Routine] [Next Routine] [List of Routines]

     Provide index ranges for this variable in terms of the top level dataset
     index space.

     Cordinate variables often have lower dimensional arrays than the data
     variables.  For example, think of an insturment that collects energetic
     partical hit-counts in 45 energy bands once per minute.  The coordinates of
     this dataset would be energy and time, with the data being the count rate.
     An hour's worth of these measurements could be stored in the following
     arrays:

     ```
        aTime    = long64arr(60)
        aEnergy  = fltarr(45)
        aCounts  = intarr(45, 60)
     ```

     Looking at the index ranges for this simple dataeset it's apparent that the
     first index of array aTime must correspond to the second index of array
     aCounts.  To help visualize this mapping, especially when datasets become
     more complex, we could "line-up" all the index ranges to make the mapping
     more explicit:

     ```
     Values   Extents
     ------   -------
     Time     [ - , 60]
     Energy   [ 45, - ]
     Counts   [ 45, 60]
     ```

     This is what the idxmap function outputs, the mapping of index space of a
     single array to the overall dataset index space.  Assume now that these
     arrays are actually the `.values` member of three different das2var objects.
     Calling `.dshape()` would yield the following (without comments of course):

     ```
     print, vTime.dshape()
       -1      0      ; var is degenerate in first dataset index (0 values)
        0     60      ; second dataset index maps to first var index (60 values)

     print, vEnergy.dshape()
        0     45      ; first dataset index maps to first var index (45 values)
       -1      0      ; var is degenerate in the second dataset index (0 values)

     print, vCounts.dshape()
        0     45      ; first dataset index maps to first var index (45 values)
        1     60      ; second dataset index maps to second var index (60 values)
     ```

     :Returns:
       A 2 by N array, where N is the number of independent indexes required to
       correlate all values in a dataset.

     :Author: Chris Piker

(See external/das2pro/src/das2var__define.pro)

## DAS2VAR__DEFINE[2]

[Previous Routine] [Next Routine] [List of Routines]

     Provide access to the underlying value using standard array indexing.

     Due to limitations of the IDL language (i.e. array._overloadBracketsRightSide
     doesn't exist) ranges are only supported up to 3 index dimensions.  To
     get a block range for arrays larger than rank 3 use the .array() method to
     get the array variable directly.

     To avoid suprise return values when gathing a slice of data, the indexmap
     is ignore.  If you are getting single values (not recommended in IDL) and
     wish to work in dataset index space use the .at() method.

(See external/das2pro/src/das2var__define.pro)

## DAS2VAR__DEFINE[2]

[Previous Routine] [Next Routine] [List of Routines]

     Das2 Variable, an array, it's units and it's index map.

(See external/das2pro/src/das2var__define.pro)

## DAS2_DOUBLE_TO_TT2000

[Previous Routine] [Next Routine] [List of Routines]

     Description: Convert a double represeting a binary das2 time value to tt2000

     tt2000 is the number of nano-seconds since 2000-01-01T11:58:55.816

     :Params:
        timeunits: in, required
          This is one of the strings 'us2000', 'mj1958', 't2000' or 't1970'
        value: a DOUBLE value

     To read UTC time strings in a variety of formats use das2_text_to_tt2000
     instead of this function.

     To avoid leap seconds, epoch time is first converted to a calendar
     representation and the broken down calendar time is converted to TT2000
     using the built-in CDF_TT2000 proceedure

(See external/das2pro/src/das2_double_to_tt2000.pro)

## DAS2_PARSESTREAM[10]

[Previous Routine] [Next Routine] [List of Routines]

     Parse the contents of a byte buffer into a list of das2 dataset (das2ds)
     objects.  This is an all-at-once parser that can't handle datasets larger
     than around 1/2 to 1/3 of the host machine's ram.

     :Returns:
        list - a list of das2 dataset (das2ds) objects.

(See external/das2pro/src/das2_parsestream.pro)

## DAS2_PARSESTREAM[1]

[Previous Routine] [Next Routine] [List of Routines]

     Try to determine a decent name for a dimension given a units string,
     return !null if nothing works

     :Private:

(See external/das2pro/src/das2_parsestream.pro)

## DAS2_PARSESTREAM[2]

[Previous Routine] [Next Routine] [List of Routines]

     Inspect the properties sub item of a stream header object hash and
     pull out the requested property value, if present.

     :Private:

     :Params:
        hObj : in, required, type=hash
            A hash, as returned by xml_parse() of the <stream>, <x>, <y>, <z>,
            <yscan> element in question.
        sProp: in, required, type=string
            The property to find

     :Returns:
        !null if the property is not present or a type object
        (int, String, datum, datum range, etc.)

(See external/das2pro/src/das2_parsestream.pro)

## DAS2_PARSESTREAM[2]

[Previous Routine] [Next Routine] [List of Routines]

     Make a new variable given a plane header

     :Private:

(See external/das2pro/src/das2_parsestream.pro)

## DAS2_PARSESTREAM[3]

[Previous Routine] [Next Routine] [List of Routines]

     Given a stream header, a plane header and a plane type,
     make a new physical dimension structure

     :Private:

     :Returns:
        The new dimension

(See external/das2pro/src/das2_parsestream.pro)

## DAS2_PARSESTREAM[4]

[Previous Routine] [Next Routine] [List of Routines]

     When multiple planes of the same type are present in the stream it's possible
     that they are related

(See external/das2pro/src/das2_parsestream.pro)

## DAS2_PARSESTREAM[5]

[Previous Routine] [Next Routine] [List of Routines]

     Add dimenions and variables from a single type of plane to a dataset

     :Private:

     :Params:
        hStream : in, required, type=hash

        hPkt  : in, required, type=hash

        sPlaneType : in, required, type=string
           The plane tag, one of x,y,z,yscan depending on which type of
           planes to find

        sDatAxis : in, required, type=string
           The axis for data from this plane, which is not necessarily
           the plane tag.  For examply yscan data can be either y values
           (waveform) or z values (spectra)

        idxmap : in, required, type=intarr
           How values from this dat array map to overall dataset indices
           since IDL is backwards from everyone else these are easy to
           mix up.

        iOffest : in, required, type=int
           The offset into the packet header for data that has
           already been claimed by other dimensions.  Depends on all
           <x><x>... coming before all <y><y>... before all <z><z>...
           before all <yscan><yscan>... in the packet definition.

           No way to check this currently since we are using xml_parse()
           from IDL that does not preserve this information.

       dataset : in, required, type=das2ds
           The dataset object to receive these new dimensions

     :Keywords:
        FIRST : out, optional, type=das2dim
           Used to save off the first dimension of a type.

     :Returns:
        The new offset into the records for the start of data from other
        dimension sets.

    unction _das2_addDimsFromHdr, $
    hStream, hPkt, sPlaneType, sDatAxis, idxmap, iOffset, sKind, $
    dataset, FIRST=dimFirst

    compile_opt idl2, hidden

    sUnitAttr = '%units'
    if sPlaneType eq 'yscan' then begin
    	sUnitAttr = '%zUnits'
    endif

    bXOffset = !false
    if hStream.haskey('properties') then begin
    	h = hStream['properties']
    	if h.haskey('%renderer') then bXOffset = (h['%renderer'] eq 'waveform')
    	if h.haskey('%String:renderer') then bXOffset = (h['%String:renderer'] eq 'waveform')
    endif

    if ~(hPkt.haskey(sPlaneType)) then return, iOffset

    ; make sure planes are always a list
    lPlanes = hPkt[sPlaneType]
    if typename(lPlanes) ne 'LIST' then lPlanes = list( hPkt[sPlaneType] )

    ; make decoders, variables and dimensions for each plane
    for iPlane=0, n_elements(lPlanes) - 1 do begin

    	hPlane = lPlanes[iPlane]

    	decoder = obj_new('das2decoder', iOffset, hPlane)
    	iOffset += decoder.chunkSize()
    	var = _das2_varFromHdr( hPlane, idxmap, decoder)

    	; Add to an existing dimension (if min/max) or start a new one.

    	; When we restructure das2 streams, dimensions (or some other plane
    	; grouping mechanism) need to be added

    	propSrc = _das2_getProp(hPlane, 'source')
    	propOp  = _das2_getProp(hPlane, 'operation')

    	; get an existing dim...
    	dim = !null
    	if propSrc ne !null then begin
    		if dataset.dims.haskey(propSrc.value) then $
    			dim = dataset.dims[propSrc.value]
    	endif

    	; ...or create a new one
    	if dim eq !null then begin

    		;printf, -2, sDatAxis, sKind, hPlane

    		dim = _das2_dimFromHdr(hStream, sDatAxis, hPlane, sKind)

    		if (sPlaneType eq 'x') && bXOffset && (dimFirst eq !null) then $
    			dim.vars['reference'] = var $
    		else $
    			dim.vars['center'] = var

    		; determining good names for dimensions is not easy...
    		sName = !null
    		if sSrc ne !null then sName = sSrc

    		if sName eq !null then begin
    			if hPlane.haskey('%name') then sName = hPlane['%name']
    		endif
    		if sName eq !null then begin
    			if hPlane.haskey(sUnitAttr) then sName = _das2_nameFromUnits(hPlane[sUnitAttr])
    		endif
    		if sName eq !null then sName = string(sPlaneType, iPlane, format='%s_%d')

    		if dataset.dims.haskey(sName) then $
    			message, 'Error in das2 stream, name '+sName+' repeats in the same packet"

    		dataset.dims[sName] = dim

    		;printf, -2, dataset

    		; Set the name based on the first plane of each kind.
    		; WARNING ASSUMES: _das2_addDimsFromHdr is called in order from
    		;                  <x> ... to <yscan>  This is not the best
    		; idea in the world, but the das2.2 stream format has no concept of
    		; a dataset name.
    		if dimFirst eq !null then dataset.name = sName

    	endif else begin
    		message, 'Peaks-averages datasets such as Voyager SA are not yet supported'
    		sRole = _das2_op2role(propOp)
    		dim.vars[sRole] = var
    	endelse

    	; Save off the first <x><y><z><yscan> dim in case we need to add an offset
    	; variable to it from the ytags
    	if dimFirst eq !null then begin
    		dimFirst = dim
    	endif

    endfor

    return, iOffset
    nd

     --------------------------------------------------------------------------- ;
    +
     Make a new dataset object given stream and packet headers.

     :Private:

     :Params:
        hStrmHdr: in, required, type=hash
           The parsed stream XML header as returned from xml_parse

        hPktHdr: in, required, type=hash
           The parsed packet XML header as returned from xml_parse

     :Keywords:
        DEBUG: in, optional, private, type=bool
           If true print debugging information

     :Author:
        Chris Piker (hence the snark)

(See external/das2pro/src/das2_parsestream.pro)

## DAS2_PARSESTREAM[6]

[Previous Routine] [Next Routine] [List of Routines]

     Parse data for a single packet using the given dataset structure and append
     it to the variable arrays

     note: since das2 streams don't put a length on the data packets there's
           no way to cross check that the stream definition matches the length
           of the data.  All we can do is try to parse it without running of
           the end

     :Private:

(See external/das2pro/src/das2_parsestream.pro)

## DAS2_PARSESTREAM[7]

[Previous Routine] [Next Routine] [List of Routines]

     Convert all the variable value lists to arrays

(See external/das2pro/src/das2_parsestream.pro)

## DAS2_PARSESTREAM[8]

[Previous Routine] [Next Routine] [List of Routines]

     Look to see if a message was an exception, if it was, format it as
     a string and return it.

(See external/das2pro/src/das2_parsestream.pro)

## DAS2_PARSESTREAM[9]

[Previous Routine] [Next Routine] [List of Routines]

     Create a dataset structure from a list of packets.

     :Private:

     :Params:
        pkts : in, required, type=byte array
           A byte vector containing all the packets in a das2 stream, the
           header packet (id [00]) should not be included.

     :Returns:
        list of dataset structures

     :History:
         Jul. 2018, D. Pisa : original
         Nov. 2018, D. Pisa : fixed object.struct conversion for ypackets
         May  2018, C. Piker : refactored

(See external/das2pro/src/das2_parsestream.pro)

## DAS2_PARSETIME

[Previous Routine] [Next Routine] [List of Routines]

     Given a string, parse typical delimited ASCII date/time and
     return year, month, day of month, day of year, hour, minute, second.

     This function loads JULDAY and CALDAT as dependencies and prints error or
     debug messages to stderr.

     :Params:
       timestr: in, required, type=string
    	    Either 4-digit or 2-digit years can be parsed.  4-digit years must be in
          the range range 1900 through 2199, and 2-digit years are only allowed in
          the range 1960 through 2059.

       year: out, required, type=integer
          Year like 2000

    	 month: out, required, type=integer
          Month of year (1 through 12)

       day: out, required, type=integer
          Day of month (1 through 31)

       doy: out, required, type=integer
          Day of year (1 through 366)

       hour: out, required, type=integer
          Hour of day (0 through 23)

       minute: out, required, type=integer
          Minute of hour (0 through 59)

       second: out, required, type=double
          Second of minute (0.0d0 to 61.0d0)

     :Keywords:
        julian: out, optional, type=double
           Double precision fractional Julian Day

        debug: in, optional, type=bool
           Turn on certian debug output strings

     :Returns:
        integer: 0 on success, 1 on failure

     :Examples:
         status = das2_parsetime (timestr, year, month, day_month, day_year $
                  [, hour, minute, second] [, julian=julian] [, /debug])

     :History:
    	2012-10-30, L. Granroth: Rewrite using regex
    	2019-05-23, L. Granroth: Extended to handle nanoseconds

(See external/das2pro/src/das2_parsetime.pro)

## DAS2_READHTTP[1]

[Previous Routine] [Next Routine] [List of Routines]

     Provide feedback that the stream is downloading

     :Private:

(See external/das2pro/src/das2_readhttp.pro)

## DAS2_READHTTP[2]

[Previous Routine] [Next Routine] [List of Routines]

     Request data from a specific das2 server using native HTTP GET parameters

     :Params:
        sUrl:  in, required, type=string
           The full HTTP GET url to retrieve, it doesn't need to be URL encoded
           this function will handle that step

     :Keywords:
        params: in, optional, type=list
        ascii: in, optional, type=boolean
        extras: in, optional, type=list
        verbose: in, optional, type=boolean

     :Returns:
        A list of dataset objects.  Each dataset object corresponds to a single
        packet type in the input.  If no datasets could be retrieved the function
        return an empty list, so ret_val.length = 0.

     :Requires:
        xml_parse: IDL 8.6.1
        IDLnetURL: IDL 6.4

     :Example:
        sServer = 'http://planet.physics.uiowa.edu/das/das2Server'
        sDataset = 'Cassini/RPWS/HiRes_MidFreq_Waveform'
        sBeg = '2008-08-10T09:06'
        sEnd = '2008-08-10T09:13'
        sParams = '10khz'
        sFmt = '%s?server=dataset&dataset=%s&start_time=%s&end_time=%s&params=%s'
        sUrl = string(sServer, sDataset, sMin, sMax, sParams, format=sFmt)

        lDs = das2_readhttp(sUrl, /messages=sMsg)

        if lDs eq !null then begin
           print, sMsg
           stop
        endif

        print, n_elements(lDs), /format="%d datesets read"

        print, lDs[0]

     :History:
        Jul. 2018, D. Pisa : original
        May  2019, C. Piker: refactored

(See external/das2pro/src/das2_readhttp.pro)

## DAS2_TEXT_TO_TT2000

[Previous Routine] [List of Routines]

     Description: Convert a string time value to a cdf_tt2000 epoch time

     tt2000 is the number of nano-seconds since 2000-01-01T11:58:55.816

     :Params:
        sTime: in, required
          This is a string time value such as '2007-001T14:00'

     This function works by calling das2_parsetime to parse time components
     from a variety of string formats, and then calling cdf_tt2000 to get
     the epoch.

     2019-01-24 L. Granroth, original
     2019-05-23 C. Piker,    nano second accuracy fix

(See external/das2pro/src/das2_text_to_tt2000.pro)