aeronomy idl routines

Last modified: Thu Mar 16 13:07:05 2023.


List of Routines


Routine Descriptions

ATMCLP - CODED LONG PULSE (RI)

[Next Routine] [List of Routines]
NAME:
atmclp - coded long pulse (ri)
SYNTAX: istat=atmclp(lun,spcBuf1,spcBuf2,nrec=nrec,baudLen=baudLen,
                          spclen=spclen,txSmpSkip=txSmpSkip,$
                          dinfo=dinfo,hdr=hdr,dotm=dotm,tmi=tmi
ARGS:
   lun:    int     lun that points at data file
KEYWORDS:
    nrec:  long    number of records to process (default is 1000).
                   warning.. this is the number of records, not ipps
                   unless ipps/buf = 1.
 baudlen:  float   By default the baudlen is taken from the header. Some
                   of the datataking files have set the baudlen
                   equal to the codelength. If this is found then the
                   baudlen is set by default to 1 usec. You can force the
                   the baudlen by setting this keyword (the units are usecs).
spclen  : long     The length of the spectra to do. By default it is
                   rounded up to the next power of 2.
txSmpSkip:float    The number of usecs to skip before taking the first
                   tx sample. This takes in account the filter delay for the
                   tx samples. The default is 2 usecs.
dotm     :         if set then do detailed tming.. if not, just do
                   total times.
RETURNS:
spcbuf1[spclen,nhghts]: float   the averaged spectra vs heights for the
                                first fifo (normally ch1 for dual beam).
spcbuf2[spclen,nhghts]: float   the averaged spectra vs height if two
                                fifos were used (normally gr for dual beam).
 dinfo  :  {}      Structure holding info that was used in the computation
                   (see below)
 hdr    :  {}      header from the first record averaged. 
 tmI    :  {}      Timing info  (see timing info below for a description). If 
                   dotm=1 then you get detailed info. If not, then just the totals.

DESCRIPTION:
   Input and process coded long pulse data taken in raw data mode with 
the radar interface. It will read nrec records (default 1000) starting
from the current location on disc (pointed to by lun). It will read the
requested number of records into a buffer (so don't make it too large). It
will stop reading prematurely if it finds a data record of a different
type (mracf, power, tp).

   For each ipp the processing step is:
   1. extract the tx samples using txSmpSkip to determine which
      tx Sample to start on.
   2. compute the complex conjugate of these samples.
   3. for each height:
       - multiply the data by the code.
       - zero extend to spclen
       - fft the data
       - compute power and accumulate
       - compute how many samples to skip to get to the next starting
         height (usually baudlen/sampLen).
   4. After accumulating divide by the number of accumulations;
   5. Shift each spectra so that dc is in the center (for a 4096 length
      xform, shift right by 2048)

   6. fill in the dinfo structure with the info that was used for the
      computation. Dinfo contaings:

   GWUSEC      FLOAT     0.200000 
   BAUDLENUSEC FLOAT     1.00000       
   CODELENGW   LONG      2500
   NHGHTS      LONG      601
   HGHTSTEPGW  LONG      5
   IPPAVGED    LONG      1000
   SPCLEN      LONG      4096
   TXSMPSKIP   LONG      10
   NUMFIFO     INT       2

   7. also return the header from the first ipp used in the variable hdr.
      Interesting info is in the sps portion of the header (although the
      baudlen may be incorrect).

WARNING:
   This routine was tested on one set of data (dual beam, 1 ipp/buf, 5Mhz bw, 1 usec
buad). The results looked pretty good (ie we saw the plasma line..), but a detailed 
comparison with the asp version has not been done. 

TIMING INFO:

 Timing info can be returned if tmi=tmi keyword is provided. The tmI 
 structure holds times for different parts of the code. Each time
 structure has the number of times the code was timed, the total sum
 and the total sum of squares. The routine printtmI,tmi can be used
 to print this info out.
    An example output is:

IDL> printtmi,tmi
tmTot:675.096 read: 3.987 

  CODECONJ Ntot:  1000 tmTot:  0.4328 avgTm0.000433 sig:0.000006
    CODEM1 Ntot:601000 tmTot: 51.1495 avgTm0.000085 sig:0.000005
      FFT1 Ntot:601000 tmTot:122.8049 avgTm0.000204 sig:0.000008
    ACCUM1 Ntot:601000 tmTot:135.5683 avgTm0.000226 sig:0.000006
    CODEM2 Ntot:601000 tmTot: 51.2731 avgTm0.000085 sig:0.000004
      FFT2 Ntot:601000 tmTot:122.8776 avgTm0.000204 sig:0.000007
    ACCUM2 Ntot:601000 tmTot:135.2315 avgTm0.000225 sig:0.000006
   BUF1TOT Ntot:601000 tmTot:322.3068 avgTm0.000536 sig:0.000013
   BUF2TOT Ntot:601000 tmTot:322.0795 avgTm0.000536 sig:0.000012

 All times are in seconds. the columns are:

totmeasTm  total wall time
read:      total time for reading data.
sectionNm  The section of code that was timed.
Ntot  is how many times this section was timed., 
tmTot is the total time for this section.
avgTm is the average time for 1 execution of this code
sig   is the sigma for the Ntot measurements

 The sections are:
 CODECONJ : extract and conjugate the tx samples
 CODEM1   : extract hght data, multiply by code, 0 extend.
  FFT1    : compute the fft (using fttw)
  accum1  : compute the power and accumulate
 BUF1TOT  : total time for buf1. includes some data manipulation times
            not included in the above times
 The xxx2 : same as xxx1 but for the second fifo (if present)

totmeasTm : this is just the sum of the measured times. It does not
            include the overhead of timing (about 2usecs per call).


 The example above had 1000 codeconj so 1000 ipps were processed (10 secs
 of data).
 You'll notice that computing the power and accumulating is taking
 longer than the fft. 
 For this computer fftw in C took about 44 usecs for a 1k xform. So it
should take about 211 usecs for a 4k. It is averaging 204 so there doesn't
look like there is any speed up time in the fft.
 Code speedup would probably come by writing an external module
that was passed a tx rec, hght rec, and then it did the fftw and
power, accumulate, returing the averaged buf. This might give you
 50% speed up.

(See /pkg/rsi/local/libao/phil/atm/atmclp.pro)


ATMDCD - DECODE ATM RAWDAT DATA

[Previous Routine] [Next Routine] [List of Routines]
NAME:
atmdcd - decode atm rawdat data
SYNTAX: nipps=atmdcd(d,code,vdcd,nhghts,dcdh=dcdh,firsttime=firsttime,
             use2ndchan=use2ndchan,usecal=usecal,
             barkercode=barkercode,codelen88=codelen88,codelen52=codelen52)
ARGS:
d[n]:{rd}         array of rawdat structures to decode. These are 
                  returned by atmget().
code[codelen]:float  code to use (unless one of the codes has been specified
                  with one of the code keywords.

  KEYWORDS: 
      dcdH:{}     decode structure holding info for future calls
                  using the same data setup. It speeds up future
                  calls by caching the transformed code and other info
                  so they don't need to be compute each time.
 firstTime:       If set, then this is the first call with the data set.
                  If provided, it will load dcdh with info to speed up
                  future calls.
use2ndchan:       if set then decode the 2nd chnannel of the data
                  in d. By default the first channel is always decoded
usecal    :       if set then include any cal samples in the decoding
barkercode:       if set then ignore code[]. Program will generate the
                  barker code and it  use for decoding.
codelen88 :       if set then ignore code[]. Program will generate the
                  88 length code (1 usec meteor observations) and use it
                  for decoding.
codelen52 :       if set then ignore code[]. Program will generate the
                  52 length code used for the dregion and use it for decoding.

           RETURNS:
             nipps:long    number of ipps decoded
vdcd[nhghts,nipps]:complex the decoded voltages
         nhghts   :long    number of heights decoded..
              dcdh:{}     structure holding info to use to speed up
                           calls after the first call. On the first call
                           this is returned to the user. On succeeding 
                           calls it is just an input parameter.

DESCRIPTION:
   Decode a number of ipps from atm rawdat. The user passes in data 
from atmget as well as the code to use. The routine will decode the
ipps and pass the decoded voltages back in vdcd. 

   The program has 3 built in codes. If you set the keyword that corresponds
to one of these codes, then the program will generate the code for you
(and it will ignore whatever you pass in via code). On return, code()
will contain the generated code.

   When decoding you need to zero extend and transform the code. If you
are decoding many records with the same kind of data, you only need to compute
the spectrum of the code once. The program lets you do this by:

1. On the first call the user sets firsttime=1  and puts
   dcdh=dcdh on the call so atmdcd can return info in it.

2. atmdcd zero extends and transforms the code. It places this and
   other info into dcdh which then gets passed back to the user.

3. On subsequent calls the user sets firsttime=0 and passes in dcdh=dcdh.

4. atmget just grabs the cached info from dcdh rather than recomputing
   it.
   
   If you change the data type (hghts, codelen,code, txsamples, channel
to decode, then you must set firsttime=1 again to recompute the new
parameters.

   Description of dcdh structure:

  dcdh.CODELEN  LONG      52 Length of code used
  dcdh.FFTLEN   LONG     512 length of fft used for decoding
  dcdh.DCDHGHTS LONG     349 number of fully decoded hghts
  dcdh.SMPTX    LONG       0 number of tx samples
  dcdh.SMPHGHT  LONG     400 number of sample heights
  dcdh.SMP1IPP  LONG     400 number of samples in ipp
  dcdh.IPPSREC  LONG       4 number of ipps in record
  dcdh.INDFIFO  INT        1 index into d.(indfifo) for data buf to use
  dcdh.FFTSCALE FLOAT 262144. scaling factor for fft (fftlen)^2
  dcdh.SPCCODE  COMPLEX  Array[512] zero exteneded transformed code,conjugated
                             and then scaled by fftscale.

   If this is too confusing, just ignore firsttime= and dcdh=. Everything
will work ok but it'll run a lot slower since it recomputes the code on
each call.

   The last codelen-1 heights are not decoded (since all the data is not
present). The returned array holds hghts:
   0 through Nhghts-(codelen-1) heights

   If a cal is present, then the /usecal keyword will cause the cal
samples to be included in the decoding (this is how the old power profile
program decoded the data).

EXAMPLES:
   1. loop calling atmget and atmdcd. Assume that the data was coded
      with the 52 length d region code. Don't bother to remove the
      digitizer offsets. Assume there are 4 ipps/record and that you
      want 256*300 ipps to process:
      the data.

   firsttime=1                   
   recPerRead=100          ; read 100 records per atmget call
   nreads=100              ; read 100 records per atmget call
   ip=0L
   for i=0,nreads-1 do begin
       istat=atmget(lun,d,nrec=recPerRead,/search)
       nipps=atmdcd(d,code,vdcd,nhght,/codelen52,firsttime=firsttime,dcdh=dcdh)
       firsttime=0                    ; after 1st time use dcdh.
       if i eq 0 then begin            ; first time allocate volt array    
         ippsTot=nreads*recPerRead*d[0].h.ri.ippsperbuf        
         vAr=complexarr(nhght,ippsTot)
       endif
       vAr[*,ip:ip+nipps-1]=vdcd
       ipp+=nipps
   endfor

   The var[ndcdhghts:349,ippsTot:40000.] will use 112 megabytes.

NOTES:
   The current scaling for atmdcd() will decode a code of unit height to
a single range of amplitude codelen.

(See /pkg/rsi/local/libao/phil/atm/atmdcd.pro)


ATMDCDPPSPCAVG - DECODE, COMPUTE PULSE TO PULSE SPC, AND AVG

[Previous Routine] [Next Routine] [List of Routines]
NAME:
atmdcdppspcavg - decode, compute pulse to pulse spc, and avg

SYNTAX: nspc=atmdcdppspcavg(lun,secToAvg,spcLen,spcAvg,h=h,
                   use2ndChn=use2ndChn,useMedian=useMedian,verb=verb,
                   rectype=rectype,spctoavg=spctoavg)
ARGS:
     lun:int      lun for file to process. You should have alread opened it.
secToAvg:float    seconds of data to average spectra over.
  spclen:int      length  for spectra. This is the number of ipps 1
                  spectra will cover.

  KEYWORDS:
use2ndchan:       if set then process the 2nd channel of data (fifo 2). The
                  default is the first channel.
 useMedian:       if set then use the median when averaging the spectra.
                  The default is the mean.
      verb:       if set then print out when we start each block of spectra.
   rectype: string Type of record to process. Use this if different kinds
                  of records are present in the same file. The rectypes
                  are defined in atmget(). For dregino profiles use
                  rpwr88 or r52code. Be careful using this routine with
                  datasets that are not contiguous in time. The spclen must
                  divide evenly into the records for a given time block.
 spcToavg: int    if provided then ignore sectoavg, use this.. works
                  better when ipp is not a submultiple of 1 sec

RETURNS:
      nspc:long   The number of spectra that have been averaged.
spcAvg[spcLen,nhghts]:float  the averaged spectra. One for each decoded
                  height.
         h:{}     The header from the first record input.  

DESCRIPTION:

   Decode a number of ipps from atm rawdat, compute the pulse to pulse
spectra, and then average these together. The user passes in the lun for
the file to process, the seconds of data to process, and the length of the
transform to use for the spectra.

   The routine will process a block of spectra at a time. A block
is defined as the number of spectra that will fit in 700 mb of memory
(or the requested seconds of data if it is smaller).
   For each block of spectra:
 1. the data is input.
 2. the mean value is removed from the complex voltages (dc is removed)
 3. the data is decoded
 4. the transform along the height direction is done for 
    tne number of spc in the block
 5. power is computeded
 6. the spectral power is summed for each height (number of spectra in
    the block).

   If the usemedian keyword is set then step 6 uses the median value for
each spectral height (over the number of spectra in the block). At the
end the median from each block are averaged (weighted by the number of
spectra in each median).

   For a single channel of data (ch or dome), 349 heights, and 1 millisecond
ipps, a block of spectra will be about 2 minutes of data. 

EXAMPLES:
   average 3 minutes of data:
   file='/share/xserve0/aeron5bup/T2166/t2166_21mar2006.023'
   openr,lun,file,/get_lun


   secToAvg=60*3
   spcLen  =512
;
;  this data set has:
;  1. an ipp of 1040 usec, and 400 samples in the first rcv window.
;  2. the codelen is 52. So there are 400-51=349 hghts after decoding.
;  3. 3 minutes of data is 173077 ipps.  This is 339 512 length spectra
;  4. 227 spectra fit in a block of 700Mb . The first block has 227 spectra,
;     the second block has 112 spectra

   
   nspc=atmdcdppspcavg(lun,secToAvg,spcLen,spcAvgMed,/verb,/usemed)
   help,spcavgmed,/st
    SPCAVGMED       FLOAT     = Array[512, 349]

;  make an image of the results

   minval=5e-3
   maxval=1.6e4
   imgdisp,(spcavgMed > minval)

(See /pkg/rsi/local/libao/phil/atm/atmdcdppspcavg.pro)


ATMGET - INPUT 1 OR MORE ATM RECORDS

[Previous Routine] [Next Routine] [List of Routines]
NAME:
atmget - input 1 or more atm records
SYNTAX: istat=atmget(lun,d,nrec=nrec,rectype=rectype,usercodelen=usercodelen,
				      raw=raw,scan=scan,sl=sl,search=search,
					  contiguous=continguous)

ARGS: lun    : unit number for file (already opened)
      d[]    : {atmrec} return data here.

KEYWORDS:
 nrec   : long   number of records to return. The default is 1. If nrec is
                 greater than 1, the routine will skip over any records that
                 do not match the requested record type.
                 Note: The routine will return when: nrec records 
                 of the same type are read,  eof is hit, or a record of
                 the same record type but with a different number of 
                 data elements is found.
                        
rectype : string record type to return. The default is the next 
                 available record. The possible values are:
                 'pwr' : power profile (ap version)
                 'clp' : codedlong pulse (ap version)
                'mracf': mracf (ap version)
                 'dspc': dynamic spectra (ap version)
               'rawdat': raw dat program (any data program)
                'rpwrb': rawDat barker code power profile 
               'rpwr88': rawDat 88 len code (power profile or d-region use)
               'r52code': rawDat 52 length code 
               'rmracf': rawDat mracf;
               'ruser' : rawDat user specified code. You must also
						  set usrcodelen=usercodenlen keyword to the
                         length of the code in bauds
               'rclp': rawDat coded long pulse
               note: rmracf,rpwrb,rpwr88,r52code use the codename to 
                     determine the type of record.
usercodelen: long  if rectype is ruser, you must also set usercodelen
				   to the baud length of the code you want to read
     raw:        if set then return the data in a single float array.
                 By default the routine splits the data in each
                 record into tx,data,noise,cals, etc..
                 (but rawdat,rpwr,rmracf always return just the data)
    scan: long   scan to position to before reading the data.
    sl[]: {scanlist} array returned from getsl(lun). This can be used
                  for random access of files (see generic routines: getsl())
  search:        if set then search for the start of the first header.
                 use this in if the first rec of the file does not start
                 with a header.
 contiguous:     if set then the records returned will be contiguous
                 in time. This is handy when a single file has different types
                 of records in it. Suppose the file holds:
                     200 rclp recs,
                    1024 'rpwr88' recs
                     200 rclp recs,
                    1024 'rpwr88' recs
                     etc.
                 If you set rectype='rpwr88' and ask for 2000 records, then
                 it will return with 1024 records. If contiguous is not set, 
                 then it will read 1024 recs of the first block and then 
                 read the rest from the second 1024 block. This can be a 
                 problem if doing pulse to pulse spectra.
           

                 nrecs=1000. If after
 RETURNS:
  istat : int
           1 - requested number of records found
           2 - req number of recs not found, hit eof, at least 1 record found
           3 - req number of recs not found, hit rec with different data len,
               at least 1 record found
           0 - hit eof, no data returned
          -1 - could not position to scan/rec
          -2 - bad header id in hdr
          -3 - bad program id in header
          -4 - requested rectype='ruser' but forgot to set usercodelen
NOTE:
   For now the rmracf,r

DESCRIPTION:
   Read the next nrec atm records from lun. Start at the current
record position unless the scan keyword is present. Atm files contain
more than 1 kind of data records (eg. pwr, mracf, clp, etc). By default
the record type returned is determined by the first record of the current
read. The user can use the rectype keyword to specify a particular kind
of record type to return.

   The file is left positioned after the last successful record read. If
eof() is hit while trying to complete the current request, the file will
be left positioned at the last successful read of the requested record
type. If the file does not end in this particular record type, then this
will not be at the end of the file.

   The data is returned in an array of structures d[nrec]. Each element
of the structure will contain the header followed by the data arrays. By
default the data arrays are split into tx,data,noise,cals, etc. The
raw keyword will return the data in each record as a single float array.

EXAMPLES:
   To use this routine:
   0. idl
   1. make sure the path to aodefdir() is in your path directory:
       at ao just enter @phil or
       !path='/home/phil/idl/gen' + !path  
       You can also put this in your IDL_STARTUP file if you like.
   2. @atminit     .. sets up the paths, headers for atm processing.
   3. openr,lun,'/share/aeron2/29jun03qz09.greg',/get_lun

    --> get 10 pwr records
    istat=atmget(lun,d,rectype='pwr',nrecs=10)

    --> get 20 mracf records, return in raw mode without splitting
        up the data into tx,data,cals,etc.
    istat=atmget(lun,d,rectype='mracf',nrecs=20,/raw)

 If you want to see each record of a file try:
   rew,lun
   scanlist,lun,/verb,/std
rec:  1 scn:        0 grp:  251 Id:clp      pos:        0 h,dlen:   444 154112
rec:  2 scn:        0 grp:  501 Id:clp      pos:   154556 h,dlen:   444 154112
   The position is the byteoffset in the file for the start of the record.
   h,dlen are the header,data lengths in bytes.

 -------------------------------------------------------------------------
RESTRICTIONS:

1. This routine currently works for the data taken in "raw datataking" mode.
   This uses the pc datataking system in raw datataking mode with the
   processing of the data being done in the PC via asp. The routine 
   will probably not work for the older data taken with the vme array
   processors (the record formats/header info was changed).

2. The routine needs to be positioned at the start of a header. If a 
   file starts with a partial record, use:
      rew,lun
      searchhdr(lun)
   This will position you at the start of the first header. The scan keyword
   allows for random positioning within the file. Unfortunatley, it uses 
   the scannumber keyword in the header and this header element is not
   filled in by the processing programs.

3. Be careful how many records you ask for. You need to have enough
   memory to hold all of them. Typical record lenghths are:
   pwr  : 8628  bytes/rec
   mracf: 11404 bytes/rec  128 spclen by 21  
   clp  : 154556 byes/rec (64 spclen by 602)

   
4. I've tested the routine with mracf,clp, and pwr. Record types of:
   tpsd, dspc are not yet implemented. Raw data (meteors etc..) using rectype
   rawdat will probably work.
 -------------------------------------------------------------------------
DATA FORMAT:

   A typical record will contain a header followed by data. The data 
format will depend on the type of record (pwr,mracf,...) unless the
/raw keyword is used. An example for a power record is:

   d.h               STRUCT    -> HDRPWR Array[1] header
   d.tx              FLOAT     Array[46]          tx samples   
   d.d               FLOAT     Array[1600]        height data
   d.calon           FLOAT     Array[200]         cal on
   d.caloff          FLOAT     Array[200]         cal off

 The same record read using /raw will look like:
   d.H               STRUCT    -> HDRPWR Array[1] header
   d.D1              FLOAT     Array[2046]        all the data
   
 -------------------------------------------------------------------------
HEADERS:

   Each record will have a header containing generic and program specific
entries. The generic parts are :
 h.std (standard header), h.ri , h.sps.
 The program specific headers are:
 h.pwr, h.mracf, h.tpsd,h.clp 

   A description of the generic headers are listed below

 IDL> help,d.h,/st
 ** Structure HDRPWR, 4 tags, length=444, data length=444:
   STD             STRUCT    -> HDRSTD Array[1]    standard header
   RI              STRUCT    -> HDRRIV2 Array[1]   ri header
   PWR             STRUCT    -> HDRSECPWR Array[1] program header (pwr )
   SPS             STRUCT    -> HDRSECSPSBG Array[1] sps header

 -------------------------------------------------------------------------
THE STD HEADER:
 ** Structure HDRSTD, 26 tags, length=128, data length=128:
   HDRMARKER       BYTE    Array[4]        'hdr_'
   HDRLEN          LONG         444        header len bytes
   RECLEN          LONG        8628        reclen bytes
   ID              BYTE     Array[8]       prog id: 'pwr','mracf',etc
   VERSION         BYTE     Array[4]       version
   DATE            LONG           2003185  yyyyddd where ddd is daynumber
   TIME            LONG             70263  time in seconds from midnite ast
   EXPNUMBER       LONG                 0
   SCANNUMBER      LONG                 0
   RECNUMBER       LONG                 0
   STSCANTIME      LONG                 0
   SEC             STRUCT    -> STRSEC Array[1]
   GRPNUM          LONG               500  first record of scan for this data
   GRPTOTRECS      LONG                 1  
   GRPCURREC       LONG                 1
   DATATYPE        BYTE          Array[4]
   AZTTD           LONG           1156032  az pointing direction in .0001 deg
   GRTTD           LONG            150000  za greg in .0001 deg units
   CHTTD           LONG            150002  za ch in .0001 deg units
   POSTMMS         LONG          70262024  millisec from midnite for positions

 -------------------------------------------------------------------------
THE RI HEADER:
 ** Structure HDRRIV2, 12 tags, length=48, data length=48:
   EXTTIMING       LONG                 1  using sps
   SMPMODE         LONG                 1  use gw pulses
   PACKING         LONG                12  12 bit sampling
   MUXANDSUBCYCLDE LONG                 0 
   FIFONUM         LONG                12  use both chan 1,2 (dual beam)
   SMPPAIRIPP      LONG              2046  total samples 1 ipp
   IPPSPERBUF      LONG                 2  ipps per output rec
   IPPNUMSTARTBUF  LONG               999  ipp number from start
   IPP             FLOAT           10000.0 ipp in usec
   GW              FLOAT           2.00000 gw in usec
   STARTON         LONG                 0
   FREE            LONG         544368000
   note: some of the ri header is duplicated in the sps header.
         when in doubt, use the sps header info.
 -------------------------------------------------------------------------
THE SPS HEADER:
 ** Structure HDRSECSPSBG, 16 tags, length=212, data length=212:
   ID              BYTE      Array[4]       section id
   VER             BYTE      Array[4]       version
   IPP             FLOAT           10000.0  ipp in usecs
   GW              FLOAT           2.00000  sample time in usecs
   BAUDLEN         FLOAT           4.00000  baudlen of code in usecs
   BWCODEMHZ       FLOAT          0.250000  bandwidth of code in mhz
   CODELENUSEC     FLOAT           52.0000  codelen in usecs
   TXIPPTORFON     FLOAT           373.000  tx ipp to rf on in usecs
   RFLEN           FLOAT           52.0000  rf len in usecs
   NUMRFPULSES     LONG                 1   number of rf pulses
   MPUNIT          FLOAT           52.0000  multipulse unit
   MPSEQ           LONG      Array[20]      multipulse seq (if mpunt gt 1)
   CODENAME        BYTE      Array[20]      name of code used
   SMPINTXPULSE    LONG                46   samples taken in tx pulse
   NUMRCVWIN       LONG                 2   number of receive windows.
   RCVWIN          STRUCT    -> HDRSPSRCVWIN Array[5]

   The SPS.RCVWIN structure:
  IDL> help,d.h.sps.rcvwin,/st
  ** Structure HDRSPSRCVWIN, 3 tags, length=12, data length=12:
   STARTUSEC       FLOAT           300.000  usecs from start of rf on
   NUMSAMPLES      LONG              1600   number of sample taken
   NUMSAMPLESCAL   LONG                 0   number samples that are cal samples

 -------------------------------------------------------------------------
POWER PROFILE RECORDS:

  istat=atmget(lun,d,rectype='pwr',nrec=10)
  help,d,/st
  Structure <829c52c>, 5 tags, length=8628, data length=8628, refs=1:
   H               STRUCT    -> HDRPWR Array[1] header
   TX              FLOAT     Array[46]      tx samples
   D               FLOAT     Array[1600]    data samples
   CALON           FLOAT     Array[200]     cal ON samples
   CALOFF          FLOAT     Array[200]     cal off samples

   the pwr header d.h.pwr contains:
IDL> help,d.h.pwr,/st
** Structure HDRSECPWR, 14 tags, length=56, data length=56:
   ID              BYTE      Array[4]
   VER             BYTE      Array[4]
   PROGMODE        LONG              1000
   DCDMODE         LONG                 0
   RECTYPE         LONG                 0
   TXSMPSCALE      FLOAT           0.00000
   SPCRECSPERGRP   LONG                 0
   SPCCURREC       LONG                 0
   HIPPSAVGED      LONG              1000
   SPCNUMHEIGHT    LONG                 0
   SPC1STHEIGHT    LONG                 0
   SPCLENFFT       LONG                 0
   SPCAVGED        LONG                 0
   SPCTHISREC      LONG                 0
   only the hippsavged (number of ipps averaged) is filled in.

 -------------------------------------------------------------------------
MRACF RECORDS:
   print,atmget(lun,d,rectype='mracf')
   IDL> help,d,/st
 * Structure <8266f94>, 5 tags, length=11404, data length=11404, refs=1:
   H               STRUCT    -> HDRMRACF Array[1]  header
   TXSPC           FLOAT     Array[128]            spectra of tx samples
   DSPC            FLOAT     Array[128, 16]        16 data spectra of 128 pnts
   NSPC            FLOAT     Array[128, 4]         4 noise spectra of 128 pnts
   DC              FLOAT     Array[46]             dc points (not returned)
   note: the last data spectra d.dspc[*,15] is not computed correctly 
         (it is overlapped with the first noise spectra).

   The mracf header d.h.mracf contains:
   IDL> help,d.h.mracf,/st
** Structure HDRSECMRACF, 20 tags, length=80, data length=80:
   ID              BYTE      Array[4]
   VER             BYTE      Array[4]
   IPPSAVGDATA     LONG              1000      ipps averaged
   IPPSAVGNOISE    LONG                 0
   NUMIFFREQ       LONG                 0
   NUMHEIGHTS      LONG                20      number of heights
   NUMLAGS         LONG                64      number of lags. spclen=2*numlags
   NUMDCPNTS       LONG                 0
   FIRSTTXSMP      LONG                 0
   RECISDATAREC    LONG                 0
   HEIGHTSTHISREC  LONG                 0
   DCPNTSTHISREC   LONG                 0
   TXSPIPP         LONG                 0
   TXHEIGHT        LONG                 0
   NUMFREQSW       LONG                 0
   TXFRQOFF1       FLOAT           0.00000
   TXFRQOFF2       FLOAT           0.00000
   TXFRQOFF3       FLOAT           0.00000
   TXFRQOFF4       FLOAT           0.00000
   FR3             LONG                 0
   the only elements returned are the 3 listed.

 -------------------------------------------------------------------------
CODED LONG PULSE RECORDS:
   print,atmget(lun,d,rectype='clp')
   IDL> help,d,/st
   * Structure <82630e4>, 2 tags, length=154556, data length=154556, refs=1:
   H               STRUCT    -> HDRCLP Array[1]  header 
   DSPC            FLOAT     Array[64, 602]      602 spectra of len 64

   The coded long pulse header contains:
   IDL> help,d.h.clp,/st
   *Structure HDRSECCLP, 14 tags, length=56, data length=56:
   ID              BYTE      Array[4]
   VER             BYTE      Array[4]
   IPPSAVG1FREQ    LONG              1000   ipps averaged
   NUMIFFREQ       LONG                 0
   NUMHEIGHTS      LONG               602   number of heights
   SPC1STHEIGHT    LONG                 0
   SPCHEIGHTSTEP   LONG                 0
   DECIMATEFACTOR  LONG                 8
   ZEROEXTDXFORM   LONG                 0
   FIRSTTXSMP      LONG                 0
   SPCLEN          LONG                64   length of spectra
   DECIMATEDCODELEN
                   LONG                 0
   SPCTHISREC      LONG                 0
   FILL            LONG                 0
   note: the current implementation assumes there are no tx or cal
         samples returned.
 -------------------------------------------------------------------------
RAWDAT RECORDS:
   print,atmget(lun,d,rectype='rawdat')
   IDL> help,d,/st
   * Structure <827d394>, 3 tags, length=123268, data length=123268, refs=1:
   H               STRUCT    -> HDRRD Array[1]  header
   D1              COMPLEX   Array[7680]        channel 1 ch if dual beam
   D2              COMPLEX   Array[7680]        channel 2 gr if dual beam
 
   The rawdat header contains: 
   IDL> help,d.h,/st
   * Structure HDRRD, 3 tags, length=388, data length=388:
   STD             STRUCT    -> HDRSTD Array[1]
   RI              STRUCT    -> HDRRIV2 Array[1]
   SPS             STRUCT    -> HDRSECSPSBG Array[1]
   
   The rawdat program always returns the data as a complex array. It does
not split the data up into cal or noise (as if /raw was always set).

(See /pkg/rsi/local/libao/phil/atm/atmget.pro)


ATMHIST - COMPUTE HISTOGRAM OF SAMPLED VOLTAGES

[Previous Routine] [Next Routine] [List of Routines]
NAME:
atmhist - compute histogram of sampled voltages
SYNTAX: npnts=atmhist(fname,histar,maxtm=maxtm,maxrec=maxrec,maxsmp=maxsmp,$
                       verb=verb,d=d)
ARGS:
   fname:  string  filename to process (must include complete path)
histar[4096,n]: long   contains the returned histograms of the 
                   voltage samples.
                   n=2 if 1 channel is used,
                   n=4 if 2 channels are used (ch and dome)
KEYWORDS:
   maxtm:  float   limit histogram to maxtm seconds of data
                   If nothing specified then maxtm is defaulted to 100 secs.
  maxrec:  float   limit to maxrec records of data
  maxsmp:  float   limit to maxsmp samples of data.
  verb  :          if set then plot the progress in 10% steps..
                   outputing the ipps and samples read so far.

RETURNS:
   npts: double    number of counts is a single histogram.
histar[4096,n] long histogram of the voltages. 
   d[100]:         if supplied then return the first 100 records read
                   in d

DESCRIPTION:
   Compute a histogram of the voltages sampled from an aeronomy rawdata
file. Any transmitter samples are discarded. Any cal samples are included.
The number of samples read depends on the keywords maxtm, maxrec, or
maxsmp. If none of these are set then 100 seconds of data are used.

   The routine will read 100 records at a time computing a cumulative
histogram for the sampled values. The assumptions made by the 
program are:

1. the data is rawdat voltages.

2. All of the records read are the same as the first record of the
   file.

3. The ri is set to 12 bit sampling. Actually this is not a real
   limitation, just that the returned values will only cover part of the
   4096 length histogram.

4. The counts are stored as longs so don't have more than 2^31-1
   counts in any bin.

5. The routine alway reads a multiple of 100 recs so you may get a little
   more data than you asked for.

   The returned data is in histar[4096,n] where:

    0:4095 maps into digitizer levels -2048 to +2047
    n    is:
       for 1 channel  (dome or ch)  n=2
       for 2 channels (dome and ch) n=4
   
   For any pair
    histar[*,0] is the digitizer sampling the real part of the complex num
                q digitizer (right bnc of the pair)
    histar[*,1] is the digitizer sampling the img  part of the complex num
                i digitizer (left bnc of the pair)

EXAMPLES:
   file='/share/aeron5/t2163_19mar2006.003'
   npts=atmhist(file,histar,maxtm=200,/verb)

   x=fingen(4096) - 2048
   plot,x,histar[*,0]
   oplot,x,histar[*,1],color=colph[2]

(See /pkg/rsi/local/libao/phil/atm/atmhist.pro)


ATMPWRCMP - DECODE/COMPUTE POWER PROFILE

[Previous Routine] [Next Routine] [List of Routines]
NAME:
atmpwrcmp - decode/compute power profile
SYNTAX: istat=atmpwrcmp(d,dcdpwr,usecal=usecal)
ARGS:
   d[n] :{rd}   array of rawdat power profile data.
KEYWORDS: 
  usecal:       if set then decode and return the cal with the data.

RETURNS:
   istat   :int    1 ok, 0 error
   dcdpwr[m]:float  array holding decoded power data starting at first
                    height (d.h.sps.rcvwin[0].startusec)
DESCRIPTION:
   Decode and compute power for power profile data using the barker
code or the 88 baud length code. The decoding is done with the 
theoretical codes (not the transmitter samples). All of the
ipps in d[n] are averaged together. By default the routine
decodes only the first receive window. If /usecal is included, then
the cal receive window (if it exists) will be part of the decoding.

EXAMPLE:
   usedome=0
   istat=atmget(lun,d,nrecs=1000,nrectype='rpwrb')
   istat=atmcmppwr(d,dcdpwr,/usecal)

;  figure out how to label the plot

   za=(keyword_set(usedome))?d[0].h.std.grttd/10000. $
                            :d[0].h.std.chttd/10000.
   lab=string(format=$
 '("power profile tm:",a," az:",f6.2," scan:",i9)',$
       fisecmidhms3(d[0].h.std.time),d[0].h.std.azttd*.0001,d[0].h.std.scannumber)

;  compute the height from the range   

   range=(findgen(n_elements(dcdpwr))*d[0].h.sps.gw  + d[0].h.sps.rcvwin[0].startusec)*.15
   hght =range*cos(za*!dtor)
    
   maxhght=(long(hght[n_elements(hght)-1L])+49L)/50L *50L
   maxpow=max(dcdpwr)
   maxpow=long(maxpow+49)/50l * 50
   hor,0,maxpow
   ver,0,maxhght
   plot,dcdpwr,hght,title=lab,xtitle='power',ytitle='altitude [km]' 

(See /pkg/rsi/local/libao/phil/atm/atmpwrcmp.pro)


ATMPWRSCANCAL - GRAB CALS FOR A SET OF RAWDAT POWER SCANS

[Previous Routine] [Next Routine] [List of Routines]
NAME:
atmpwrscancal - grab cals for a set of rawdat power scans
SYNTAX: n=atmpwrscancal(fbase,fnum1,fnum2,calD,maxblks=maxblks,verb=verb,yscale=yscale)
ARGS:
 fbase  :string base name for files to scan. includes directory and fname
                upto the filenumber: eg:"/share/aeron5/t1193_04sep2012.".
 fnum1  : int   first filenumber to scan
 fnum2  : int   last filenumber to scan
KEYWORDS: 
 maxBlks: long  maximum number of blocks to return. The default is 1000.
  verb  :       1-output filenames and block numbers as they are processed
                2-output 1 and plot the cal on,off for each 10 sec block
 yver   :[min,max]  If verb=2 then the the vertical scale for the plotting.
                If not provided, the default is [1000,40000]. The plot uses
                /ylog so you can see the on,and off.
RETURNS:
       n:int    > 0 number of entries in calD[]
                0 error
                -1 - could not open first file fbase+fnum1
                -2 - no  power data found in first file
 calD[n]:{}     caldata for each 10sec block
  				{ fnum: 0L,$
				  blk : 0l,$ ; in file
		           h  :d.h,$ ; header for first rec of 10 sec block
		          nipp: 0L,$ ; we found in this block 
 				 nfifos:0L,$ ; number of fifos 1,2.. 
		         calOn:fltarr(maxipp,nfifos),$ ; holds calOn totPwr each ipp
                                           0=fifo1,1=fifo2. only nipp valid
		        calOff:fltarr(maxipp,nfifos),$ ; holds calOff totPwr each ipp
                                           0=fifo1,1=fifo2
               }
DESCRIPTION:
   Scan rawdat files for power profile blocks (10secs) of data. Compute the power in the
calOn,calOff, and  return it in the calD[n] structure. Each element of calD[] holds the 
information for an entire 10 sec block. A block read will finish after 1000 ipps, or a data record
of a different type (say mracf is found).
	For each block of data, compute the total power for the calOn and calOff of each ipp.
Then average over the calOn, and caloff samples (giving 1 calon,1 caloff value for each ipp,
fifoChan). When averaging, ignore 25 samples at the start of calOn,calOff. This excludes the 
calOn to calOff transition (which differs for the dome and the ch).

 	The returned calD[n] array of structures contains:
calD[n].fnum the filenumber where this block came from
calD[n].blk  the 10sec block within the file where data came from (count from 0)
calD[n].h    the header from the first ipp of the block.
calD[n].nipp the number of valid ipps in calOn,calOff for this block (in case the
             block had less than 1000 ipps before a different record type was found.
calD[n].nfifos  the number of fifos found. This determines the 2nd dimension of 
                calOn[x,nfifos],calOff[x,nfifos]
calD[n].calOn[maxipp,nfifos] Hold the calOn total power for each ipp. [x,0] is fifo1 (ch)
                        [x,1] is fifo2 (dome).
calD[n].calOff[maxipp,nfifos] Hold the calOff total power for each ipp. 

Notes:
0. nfifos, and ipps/buf are taken from the first block of the first file. If this
   configuration changes (between fnum1,fnum2) then it will still use the values from
   the first rec of first block of first file.
1. I've used 10secs of data in the above. It actually is 1000 ipps. If the power ipp is
   different, then the time of each block will will be 1000*ipp.
2. If there are 1000 +n ipps,then a different data rec, you will get a second
   block with only N ipps (maybe there should be a keyword for specifying the minimum
   number of ipps for a block?).
3. The ipps within a block will be contiguous in time (spaced by an ipp). There will
   normally be time gaps between blocks (if they run more that just pwr in the cycle).
   You can look at the time in the header to see the start of each block.

EXAMPLE:
	fbase='/share/aeron5//share/aeron5/t1193_04sep2012.'   ; note the . a the end
   n=atmpwrscancal(fbase,71,99,calD,/verb)

(See /pkg/rsi/local/libao/phil/atm/atmpwrscancal.pro)


METMON - MONITOR METEOR DATA

[Previous Routine] [Next Routine] [List of Routines]
NAME:
metmon - monitor meteor data
SYNTAX: img=metmon(fbase,num,lun=lun,toavg=toavg,numDisp=numDisp,$
                   useCh=useCh,d=d,val=val,pixwin=pixwin,ilim=ilim,$
                   dirhc=dirhc,hc=hc,invert=invert)
ARGS:
  fbase: string Base filename to read from (eg '/share/aeron5/24jul03').
                Do not include the . or file number.
   num : int    file number of file to start on. 

KEYWORDS:
   lun : int    If provided, then process this file from the current 
                position. When done with the file return. In this case
                fbase and num are ignored. You also can not jump to other 
                files from the internal menu.
  toavg: long   number of ipps to average together. The default is 5
numDisp: long   The number of averaged ipps to display in the image. The
                default is 900 averaged ipps.
  useCh:        If set then start displaying the first data channel. This
                is the carriage house in dual beam experiments. The default
                for dual beam is the dome. You can change this from the
                internal menu.
 val[2]: float  Clip the  power (a/d levels squared) to [min,max] and
                then scale to the full range of the display device (
                0 to 255). The default is to clip the power at 6 sigma
                (as measured from the first image).

 pixwin:        if set then use a pixwin when drawing a new image. This
                cuts down on the flashing. It is useful when you are
                averaging only 1 or 2 ipps.
 ilim  : long   if supplied then limit image to these indices of the 
                data rec (0 based).
 dirhc : string directory to start hardcopy
 hc    : in     1 hardcopy on, 0 hardcopy off
 invert:        if set then reverse black, white in lut.
RETURNS:
   img[m,numDisp]:float    the last image displayed.
   d[n]         if this keyword is provided then the data read
                for the last image is returned here.
DESCRIPTION:
   metmon will make continuous images of meteor data. The mean is removed from
the voltages, power is computed, and then toavg ipps are averaged together.
numDisp averaged ipps are then displayed as height versus time. When 
the end of file is hit, the routine will advance to the next filenumber.
If no data is available, the routine will wait until it becomes available.
   The user can modify things by hitting any key and bringing up an
internal menu:

Cmd CurVal   function
 a dome      antenna ch, dome
 f   70      move to new fileNum
 h   0,1     hardcopy on,off
 hd  dirName  directory name for hardcopy
 l           list all files
 n           next file (or quit if 1 file)
 p  recnum   position to rec in file
 pr 0,1      display profiles  in image
 q           to quit
 r           rewind current file
 s  0        single step 0,1 (off,on)
 sc 6        rescale images to nsigmas
 cur         trac cursor
 d           debug. stop in metmon. .continue to continue

 otherkey    continue

The commands are:

 a  dome/ch  This lets you switch between dome and carriage house display

 f  filenum  You can start displaying at the start of a different 
             filenumber. If the new filenumber is illegal then no 
             change is made.

 l           This will list all of the available files starting with
             fbase. The last file will also contain its size.

 n           move to the next file number.
 p  recnum   position to rec in file. Rec num counts from 1
 pr 0,1      Use cursor to display profiles in image. 1 on, 0 off.

 q           quit the routine.

 r           rewind and start over in the current file.

 s  0,1      turn on,off single step mode.When it is on, the routine
             will pause after every image waiting for the user to
             enter return.
 d           debug. This will stop in the metmon routine.

 otherKey    any other key will cause the display to continue.
             This allows you to pause the display to look at it for
             a while.
EXAMPLES:
   An example of using this routine at AO:

 1. slogin to either fusion00,01, or 02
 2. idl
 3. @phil
 4. @atminit
 5. xloadct   .. then click on bw linear for scale color table

 6. setup the parameters for the call..
    file='/share/aeron5/23Dec03T1748' .. this should be the path and
                                         base filename for the files to use.
    usech=1            .. set this to 0 if you want the dome output
    num=272            .. first file number of your experiment to use.
 7.start the program:
       img=metmon(file,num,usech=usech)

 8. Hit any key to bring up the keyboard menu.

 Possible problems:

 By default the lut (color lookup table) is scaled to 6 sigma of the
 first image displayed. If this image has a large meteor in it, the
 other plots may not have the correct contrast. You can fix this by:
 a. hit any key;
 b sc nsig    .. where nsig is the numbers of sigmas to scale the image.
              .. it will the compute the new clipping values from the
                 current image you are looking at.

(See /pkg/rsi/local/libao/phil/atm/metmon.pro)


PLASMACUTOFF - PROCESS SINGLE PULSE PLASMA CUTTOFF DATA

[Previous Routine] [Next Routine] [List of Routines]
NAME:
plasmacutoff - process single pulse plasma cuttoff data
SYNTAX: istat=plasmacuttof(lun,spc,spcH,spcN,spcLen=spcLen,toavg=toavg,$
                           freq=freq,flip=flip,nonoise=nonoise,hdr=hdr)
ARGS:
   lun:    int file descriptor of file to read

KEYWORDS:
  spcLen: long length of transform to do. Default is 2048.
               there must be at least this many samples of data and/or noise
   toavg: long number of ipps to average default is 10000
    flip:      if set then flip the frequency order of the spectra on return.
 nonoise:      if set then do not process the noise samples (even if they are
               present).

RETURNS:
 istat     : int    1 returned ok
                    0 hit eof
                    lt 0 trouble reading a record (bad header, etc)
 spc[m,n,l]: float  height spectra with noise subtraction.
                    m=length of spectra
                    n=number of height spectra computed
                    l=number of antennas: 1 if 1 antenna, 
                                          2 if both antennas (dome is 2nd)
spcH[m,n,l]: float  height spectra without noise subtraction.
spcN[m,l]  : float  noise spectra
freq[m]    : float  frequency of the spectra in Mhz.
    hdr    : {hdr}  header from first record read

DESCRIPTION:
   Input and process single pulse plasma cutoff data. Each record should
contain only 1 ipp of data. The windows in the ipp can be:

 txSamples   - skipped
 hghtSamples - must be at least spcLen samples. The routine will compute
               hghtSamples/spcLen height Spectra

 noiseSamples- if present (and nonoise is not set) then there must be
               at least spclen noise samples. The routine will compute
               (and average together) noiseSamples/spclen noise spectra
               for each ipp.

   The routine will read toavg ipps. For each ipp it will compute the
height spectra and an average noise spectra. It then averages these 
spectra over toavg ipp's. 

   The height spectra with noise removal is returned in:
   spc[spcLen,numHghtSpc,numAntennas]. 

   The height spectra with no noise removed is returned in:
   spcH[spcLen,numHghtSpc,numAntennas]. 

   The noise spectra are returned in :
   spcN[spcLen,numAntennas]. 

   If the sps buffer has two receive windows, then the 2nd window is taken
as the noise samples. If only one receive window is present, no noise
subtraction is done.

   The flip keyword will flip the frequency order of all of the spectra.
If BBM sine (top) goes to digitizer (left) then you probably need 
to set /flip.

EXAMPLE:

idl
@phil
@atminit
openr,lun,'/share/aeron5/24Jul03.070',/get_lun
   .. avg 10000 ipps

istat=plasmacutoff(lun,spc,spch,spcN,spclen=2048,freq=freq,/flip)
ver,0,5e8
hor 
; plot the ch spectra 
stripsxy,freq,spcar[*,*,0],0,1e8,/step
; over plot the dome spectra 
stripsxy,freq,spcar[*,*,1],0,1e8,/step,/over

NOTE:
   The routine will not work:
   1. if there are more than 1 ipp per record.
   2. if there are fewer than spclen data or noise samples

(See /pkg/rsi/local/libao/phil/atm/plasmacutoff.pro)


SHSCLOSE - CLOSE AN ATM SHS FILE

[Previous Routine] [Next Routine] [List of Routines]
NAME:
shsclose - close an atm shs file
SYNTAX: shsclosel,desc,all=all
ARGS:
   desc: {}    descriptor returned by shsopen()
KEYWORDS:
    all:       if set then close all open descriptors.


DESCRIPTION:
   close an atm shs file. This frees up the lun.

(See /pkg/rsi/local/libao/phil/atm/shsclose.pro)


SHSCLP - CODED LONG PULSE (RI)

[Previous Routine] [Next Routine] [List of Routines]
NAME:
shsclp - coded long pulse (ri)
SYNTAX: istat=shsclp(desc,spcBuf1,spcBuf2,ippToAvg=ippToAvg,baudLen=baudLen,
                          spclen=spclen,txSmpSkip=txSmpSkip,nheights=nheights,$
                          dinfo=dinfo,hdr=hdr,dotm=dotm,tmi=tmi,verbose=verbose,$
                          clipRfi=clipRfi,,minipp=minipp,usenoise=usenoise,$
						   dinp=dinp,firstheight=firstheight,doband=doband)
ARGS:
  desc:    struct     desc that points at data file
KEYWORDS:
  ippToAvg:  long    number of ipps toavg. there are  100 ipps/rec so
                    should be a multiple of 100 ipps
 minipp :  long    minimum number contiguous ipps to avg, if not found
                   continue through the file for the next block.
 baudlen:  float   This is actaully the step in the height processing.
                   It defaults to 1 usec
                   lets you override it. The units are usecs.
spclen  : long     The length of the spectra to do. By default it is
                   rounded up to the next power of 2.
txSmpSkip:float    The number of usecs to skip before taking the first
                   tx sample. This takes in account the filter delay for the
                   tx samples. The default is 5 usecs.
nheights: long     limit to 1..nheights.. default is all
dotm     :         if set then do detailed tming.. if not, just do
                   total times.
verbose  :         if set then output start of each rec and start of
                   each ipp modulo 10
cliprfi  : float   if supplied, then clip the spectra of each rfi to 
                   nsig=cliprfi, 0 these voltage points and back xform
                   (unless usenoise is set)
usenoise : int     if true then replace large rms with noise rather
                   than 0 it.
dinp[m]: int       use this at data to process. ippToAvg will be 
                   set to the min of ipptoAvg m*dinp.nipps
firsthght: long    if provided then first height to process. count from 0.
                  default is 0
navgipp  : long   number of navgipp to return. default is 1.
                  use this to return unaveraged ipp
                  set ipptoavg=1 set navgipp=100.. this will return 1 rec
doband   : int     1,2, or 12 to do both bands. does not merge bands def:12
RETURNS:
spcbuf1[spclen,nhghts]: float   the averaged spectra vs heights for the
                                first channel (normally ch1 for dual beam).
spcbuf2[spclen,nhghts]: float   the averaged spectra vs height if two
                                channels were used (normally gr for dual beam).
 dinfo  :  {}      Structure holding info that was used in the computation
                   (see below)
 dhdr   :  {}      header from the first record averaged. 
 tmI    :  {}      Timing info  (see timing info below for a description). If 
                   dotm=1 then you get detailed info. If not, then just the totals.

DESCRIPTION:
   Input and process coded long pulse data taken in raw data mode with 
ryans machine. It will read ippToAvg/100 records (default 10) starting
from the current location on disc (pointed to by desc). It
requested number of records into a buffer (so don't make it too large). It currently
does not check if this is a clp record or not (to be added).

   For each ipp the processing step is:
   1. extract the tx samples using txSmpSkip to determine which
      tx Sample to start on.
   2. compute the complex conjugate of these samples.
   3. for each height:
       - multiply the data by the code.
       - zero extend to spclen
       - fft the data
       - compute power and accumulate
       - compute how many samples to skip to get to the next starting
         height (usually baudlen/sampLen).
   4. After accumulating divide by the number of accumulations;
   5. Shift each spectra so that dc is in the center (for a 4096 length
      xform, shift right by 2048)

   6. fill in the dinfo structure with the info that was used for the
      computation. Dinfo contaings:
dinfo={ $
        gwUsec     : gwUsec,$
        baudLenUsec: baudLenUsec,$
        codeLenGw  : codeLenGw,$
        nhghts     : nhghts,$
        hghtStepGw : hghtStep,$
        ippAvged   : ippAvgd,$
        spcLen     : spclen,$
        txSmpSkip  : txSmpSkipL,$
        numChn     : numChn ,$
          bwMhz   : bw,$
		nsigclip  : nsigclip,$
		ippI      : ippI[ipptoAVg] } ; info on each ipp
 ippI hold info on each ipp:
	clipI={$
		   mean:0.,$; spectral mean
		   rms :0.,$; spectum rms
		   ndel:0. $, ;nchan removed
          rmsLoop:0$; 1 or 2 .. how many times we looped rms
		   }
	a={ rec: 0L,$    in file count from 0
	    ippRec:0L,$; ipp within rec count from 0
		ippCum:0L, ; from start of file  count from 0
		; following computes on spc.. if nsigdel 0.
		clipI   : replicate(clipI,2) $; the 2 chan
		}

   7. also return the header from the first ipp used in the variable hdr.
      Interesting info is in the sps portion of the header (although the
      baudlen may be incorrect).


TIMING INFO:

 Timing info can be returned if tmi=tmi keyword is provided. The tmI 
 structure holds times for different parts of the code. Each time
 structure has the number of times the code was timed, the total sum
 and the total sum of squares. The routine printtmI,tmi can be used
 to print this info out.
    An example output is:

IDL> printtmi,tmi
tmTot:675.096 read: 3.987 

  CODECONJ Ntot:  1000 tmTot:  0.4328 avgTm0.000433 sig:0.000006
    CODEM1 Ntot:601000 tmTot: 51.1495 avgTm0.000085 sig:0.000005
      FFT1 Ntot:601000 tmTot:122.8049 avgTm0.000204 sig:0.000008
    ACCUM1 Ntot:601000 tmTot:135.5683 avgTm0.000226 sig:0.000006
    CODEM2 Ntot:601000 tmTot: 51.2731 avgTm0.000085 sig:0.000004
      FFT2 Ntot:601000 tmTot:122.8776 avgTm0.000204 sig:0.000007
    ACCUM2 Ntot:601000 tmTot:135.2315 avgTm0.000225 sig:0.000006
   BUF1TOT Ntot:601000 tmTot:322.3068 avgTm0.000536 sig:0.000013
   BUF2TOT Ntot:601000 tmTot:322.0795 avgTm0.000536 sig:0.000012

 All times are in seconds. the columns are:

totmeasTm  total wall time
read:      total time for reading data.
sectionNm  The section of code that was timed.
Ntot  is how many times this section was timed., 
tmTot is the total time for this section.
avgTm is the average time for 1 execution of this code
sig   is the sigma for the Ntot measurements

 The sections are:
 CODECONJ : extract and conjugate the tx samples
 CODEM1   : extract hght data, multiply by code, 0 extend.
  FFT1    : compute the fft (using fttw)
  accum1  : compute the power and accumulate
 BUF1TOT  : total time for buf1. includes some data manipulation times
            not included in the above times
 The xxx2 : same as xxx1 but for the second chan (if present)

totmeasTm : this is just the sum of the measured times. It does not
            include the overhead of timing (about 2usecs per call).


 The example above had 1000 codeconj so 1000 ipps were processed (10 secs
 of data).
 You'll notice that computing the power and accumulating is taking
 longer than the fft. 
 For this computer fftw in C took about 44 usecs for a 1k xform. So it
should take about 211 usecs for a 4k. It is averaging 204 so there doesn't
look like there is any speed up time in the fft.
 Code speedup would probably come by writing an external module
that was passed a tx rec, hght rec, and then it did the fftw and
power, accumulate, returing the averaged buf. This might give you
 50% speed up.

(See /pkg/rsi/local/libao/phil/atm/shsclp.pro)


SHSCLPCHKIPP - SEE IF THIS IS CLP IPP

[Previous Routine] [Next Routine] [List of Routines]
NAME:
shsclpchkipp - see if this is clp ipp
SYNTAX: istat=shsclpchkipp(txbuf,smpUsec=smpUsec,codeUsec=codeUsec,$
				corRatio=corRatio,txminpwr=txminpwr)
ARGS:
txbuf[2,N]: short   tx buffer i,q n samples
KEYWORDS:
smpUsec   : float   sample rate in usecs (def=.2 usecs)
codeUsec  : float   codelength in usecs (def=440 usecs)

RETURNS:
istat[n]  : 1 - is a ipp
            0   not a clp ipp
            one for each tx buf passed in
corRatio  :  float  acf of txbuf . 0..1
DESCRIPTION:
  Check to see if this ipp is a clp ipp by looking at the power across the
transmitter pulse
 values used:

  midipp: 150.. must have power .. gets rid of power profile which may have
                                   echo at 440,500
  power : 52 usecs
  clpipp: 440. 
  topSid: 500 usecs
  mracf : 300 usecs
  txSmpDelayUsecs .. usually about 5.6 usecs
  slopEnd : 5 usecs; .. move this far back from falling  edge of pulse before average start
  avgSmpls:100= 20 secs
  make sure power at 440 - 6 usecs
  acf:
  - compute acf for lags 0 .. 50  (0 to 10 usecs)
  - avg lags 20-50 ( 4 to 10 usecs)
  - normalize to 0 lag
    make sure correlation is less than acfLim (.4)
  - this gets rid of topsid.. so i'll remove the topside  limits
  -  mracf, pwr, clp all have low correlation
  

(See /pkg/rsi/local/libao/phil/atm/shsclpchkipp.pro)


SHSCLPIMGMONSCAN - SCAN FOR PROCESSED CLP FILES

[Previous Routine] [Next Routine] [List of Routines]
NAME:
shsclpimgmonscan - scan for processed clp files
SYNTAX: nfiles=shsclpimgmonscan(dir,fbase,fiar,firsttime=firsttime,
		            allhdrs=allhdrs,maximgfile=maximgfile
ARGS:
dir     : string   to search for .hdr files. Include the 
                   '/' at the end of the dir name
fbase   : string   for filename to look for. Include up to the
                   _ before the filenumber digits (see below)
KEYWORDS:
    nrec:  long    number of records to process (default is 1000).
                   warning.. this is the number of records, not ipps
                   unless ipps/buf = 1.
firstTime:         if set then this is the first time the routine
                   is called with this dir,fbase. If not set then
                   fiar will have the info from the previous call.
                   the routine will add new info to this array.
allhdrs:           if set then return all header for each file.
                   Each .shs  file will have multiple 10 sec
                   images generated from it. By default only the
                   first hdr of the .shs file is returned in fiar[i]
                   With allhdrs set, all the headers are returned
                   in fiar[i].hdrs[20]. Leaving this off speeds up
                   the scanning. If you need the az,za,time exactly
                   for each img then turn this on. It only works
                   with firsttime=1
maximgfile:long    max number of images we can have in 1 input file
                   def: 120 (or 1 sec integrations)
RETURNS:
nfiles:  long   number of raw input files found
fiar[nfiles]:{}  stuct holding info on all the image files found:

DESCRIPTION:
	Scan for .shs processed image files. The routine looks for
the .hdr files in the provided dir, fbase. It returns the number
of  input files found (note that there are multipled 10sec img files
for each raw input file.
EXAMPLES:
	dir='/raid/radar/phil/t1193_20120120/'
   fbase='t1193_20jan2012_'
   n=shsclpimgmonscan(dir,fbase,fiar,first=1)
 Structure <170f688>, 4 tags, length=196, data length=196, refs=1:
  FNUM            LONG                 0
   NIMG            LONG                10
   HDR             STRUCT    ->  Array[1]
   IMGNUMAR        LONG      Array[20]

   n=shsclpimgmonscan(dir,fbase,fiar,first=1,/allhdrs) 
   help,fiar,/st
 Structure <19c57b8>, 4 tags, length=2248, data length=2248, refs=1:
p   FNUM            LONG                 0
   NIMG            LONG                10
   HDR             STRUCT    ->  Array[20]
   IMGNUMAR        LONG      Array[20]

Note that without /allhdrs, you only get the header from the
first 10 sec block of the file.

(See /pkg/rsi/local/libao/phil/atm/shsclpimgmonscan.pro)


SHSCLPPARSETMING - PARSE TIMING INFO FROM CLP HDR FILES

[Previous Routine] [Next Routine] [List of Routines]
NAME:	
shsclpparsetming - parse timing info from clp hdr files
SYNTAX:n=shsclpparsetming(dirName,tmIAr)
ARGS:
dirName: string	name of directory holding .hdr files
RETURNS:
	n: long   number of entries found
tmIAr[n]: {}   holds timing info:
DESCRIPTION:
	The clp processing generates a .dcd and a .hdr file for each
integration (usually 10 seconds). This routine will search
all of the .hdr files in a directory and return the timing
info. This info tells how long it took to complete different
parts of the processing.
The tmIAr struct has:
 ;tmI={        wstS:  0.    , $; secs waited before start
               fftU:  0.    , $; usecs for 1 fft
              accumU: 0.    , $; usecs for power and accum 1 height,1 ipp
                ippS: 0.    , $; secs for 1 ipp
                inpS: 0.    , $; secs for input
                outS: 0.    , $; write out time secs
                tmTot:0.}   ; tot tm secs this block

(See /pkg/rsi/local/libao/phil/atm/shsclpparsetming.pro)


SHSCLPQUICKLOOK - COMPUTE A CLP SPECTRA AND DISPLAY IMAGE

[Previous Routine] [Next Routine] [List of Routines]
NAME:
shsclpquicklook - compute a clp spectra and display image
SYNTAX: shsclpquicklook,fnum,fbase,dir0=dir0,$
    fband=fband,doband=doband,
	firstHghtKm=firsthghtKm,lastHghtKm=lastHghtKm,hghtStepUsec=hghtStepUsec,$
    zx=zx,zy=zy,$
    dinfo=dinfo,hdr=hdr,img1=img1,img2=img2 ,
ARGS:
   fnum: long		file number to process. -1 --> last file
  fbase: string    name of subdir in dir0 to search. eg let fbase='expabc'
                   filenum =-1 searches dir0+'expabc/*.shs
                   filenum =val searches dir0+'expabc/expabc_nnn.shs'
KEYWORDS:
   dir0: string    base dir. default: /net/rserv/export/RSERVLV2/daeron/'
   fband: float[2] frequenciy offsets (in Mhz) for bands. def:[-5.5,5.5]
   doband: int     bands to process. 1->band 1, 2-> band 2, 12-> band 1 and 2
                   (12 does not currently merge images).
firstHghtKm:float  first height to display. def=90km.
                   If less than first height then first height will be used.
 lastHghtKm:float  last height to display. def=450Km
                   If greater than last height recorded, then clip to last height.
hghtStepUsec:float Spacing between heights (in usec, not km). def: 2usec
                   the baud is  normally 2usec.
zx          :float  zoom factor in x. def: -5 if zx=0 then use default
zy          :float  zoom factor in y. def: search for zy giving le 790 pixels
RETURNS:
  dinfo: {}	     struct holding info used in compuatation
 hdr   : {}         header read from file
 img1[n,m]: float   img 1 (if selected). this has not been zoomed.
 img2[n,m]: float   img 2 (if selected). this has not been zoomed.
DESCRIPTION:
 	Read and process an echotek clp image. It tries to read
10 secs of data. It will always start at the begining of the 
selected file.

To select the file:
 - dir0: is the directory holding the experiment directories
   the default is /net/rserv/export/RSERVLV2/daeron/. This the destination
   for the copy from daeron to aonet.
   Another alternative would be to read it directly from daeron:
   /net/daeron/data/
 - fbase: is the base filename
   this is the subdirectory in dir0 and well as the start of the filename.
   eg: 'hf_20180315'
 - fnum: this is the file number in the subdirectory to input
   fnum=-1 will use the most recent file.

Bands to process:
   There are normally 2 bands [-5.5,5.5] if up,down or [5.5,9.5] upper band 
  The parameter doband lets you select which bands to process. 
   doband=1 --> process only band 1, doband=2 --> process only band 2,
   doband=12 --> process both bands. By default both  bands are processed.
   Processing fewer bands speeds up the processing.

Heights to process
	By default all heights 90 through 450 km are processed with 2 usec spacing (same as the def baud)
   firstHghtKm  specifies a different first height, Asking for a height before the first available
                height was def to the first height.
   lastHghtKm   specifies a different ending height. asking for a height greater than available will
                default to the last available height
   heightStepUsec: spacing between heights.
 
image zoom
 	zx,zy - x,y image zoom. Positive make the image bigger, neg shrinks the dimension (zoom needs to be integral).
	In x there are 4096 channels. a zoom of -4 would make an image with 1024 horizontal pixels.
   In y, a standard can support 795 pixels (the axis are extra). 
 	if zx=0 or is not supplied then it defaults to -4.
   if zy=0 or is not supplied then the zy is computed such that there are as many pixels as possible and does
   not exceed 795 pixels.
	eg with 90km to 450 km there are (450-90)/.15(km/usec) = 2400 pixels. It would compute zy=-4 giving 600 pixels.
Returned info.
   dinfo
IDL> help,dinfo,/st
** Structure <1c29b08>, 13 tags, length=44056, data length=40050, refs=1:
   GWUSEC          DOUBLE          0.20000000
   BAUDLENUSEC     FLOAT           2.00000
   CODELENGW       LONG              2200
   NHGHTS          LONG              1201
   HGHTSTEPGW      LONG                10
   IPPAVGED        LONG              1000
   SPCLEN          INT           4096
   TXSMPSKIP       LONG                25
   NUMCHN          INT              2
   BWMHZ           DOUBLE           5.0000000
   NSIGCLIP        FLOAT           0.00000
   USENOISE        INT              0
   IPPI            STRUCT    ->  Array[1000]
  hdr: {}
IDL> help,hdr,/st
** Structure <21b62f8>, 18 tags, length=104, data length=90, refs=1:
   TABLEREC        LONG                 0
   TABLESIZE       LONG           9844000
   DATAWIDTH       INT              2
   DATATYPE        STRING    'short'
   NUMDIMS         INT              2
   DIM0            LONG             49220
   DIM1            LONG               200
   NUMCHANNELS     INT              2
   TXSTART         LONG                 0
   TXLEN           LONG              5200
   DATASTART       LONG              6000
   DATALEN         LONG             44000
   NOISESTART      LONG             50000
   NOISELEN        LONG                20
   SYSTIME         STRING    '09:30:07'
   AZ              FLOAT           347.997
   ZAGREG          FLOAT           1.10000
   ZACH            FLOAT           12.0000

 img1[n,m] : float   image band 1 (if processed)
 img2[n,m] : float   image band 2 (if processed)

 Time to compute:
 cpu   time  nbands hgtStep  hghtrange
       min           usec      km
megs3  3:30   2       4       90 -690
megs3  2:10   2       4       90-450
megs3  1:07   1       4       90-450
megs3  2:12   1       2       90-450

(See /pkg/rsi/local/libao/phil/atm/shsclpquicklook.pro)


SHSCMPREC - COMPUTE CURRENT RECORD POSITION

[Previous Routine] [Next Routine] [List of Routines]
NAME:
shscmprec - compute current record position
SYNTAX: currec=shscmprec(desc)
RETURNS:
   currentrec: long  current record we are about to read. 
                     count from 0

DESCRIPTION:
   Compute the record we are about to read. count from
0. If we are in the middle of a record, return the current record
(removing the fractional part
from the first record of the file.

(See /pkg/rsi/local/libao/phil/atm/shscmprec.pro)


SHSFINDTM - FIND FILE,REC FOR A GIVEN TIME

[Previous Routine] [Next Routine] [List of Routines]
NAME:
shsfindtm - find file,rec for a given time
SYNTAX: istat=shsfindtm(yymmdd,hhmmss,fI,indFile,indrec)
ARGS:
yymmdd: long date we want
hhmmss: long time (ast) we want
fI[n] : {}   array of struct returned from shsscandir()
RETURNS:
istat  : int   0 this date does not occur in dir
               -1 time is before beginning of first file
               -2 time is after the end of last file
indFile: long  index into fI[] for file we want.. cnts from 0
INDREC : long  record we want in file (cnt from 0)

(See /pkg/rsi/local/libao/phil/atm/shsfindtm.pro)


SHSGET - INPUT ATM SHS DATA

[Previous Routine] [Next Routine] [List of Routines]
NAME:
shsget - input atm shs data
SYNTAX: istat=shsget(desc,d,nrec=nrec,posrec=posrec)
ARGS:
   desc: {}         stucture returned by shsopen

KEYWORDS:
   nrec:   long    number of records (hdr/data) to input
 posrec:   long    position to this record before reading (count from 0).
                   if posrec is not supplied or it is set < 0 then the
                   next record will be read.
RETURNS:
   istat: > 0 number of recs found
   d[nrec]:  {shsdat}  structure holding data

DESCRIPTION:
   Input data from the file pointed to by desc (desc is a structure
returned by shsopen()). The data is returned in the structure d. d will
hold one record from the .shs file. A record will have multiple ipps
(for 10 millisec ipps there are 100 records .. 1 second of data).
If nrec=n is provided with n gt 1 then d[n] will be an array.
    The user can optionally position in the file before reading
with the posrec= keywword. 

   The data format on disc is:
   primary header

   datahdr
   data
    slop

EXAMPLES:
   file='/mnt/daeron/testCont/meteor_08oct2011_000.shs'
   istat=shsopen(file,desc)
;   read in the next record:
   nrec=shsget(lun,d)

; The d struct contains:

  help,d,/st
   DHDR            STRUCT    ->  Array[1]
   NIPPS           LONG               100
   D1              STRUCT    ->  Array[1]
   D2              STRUCT    ->  Array[1]

 help,d.d1,/st
   TX              INT       Array[2, 100, 100]
   DAT             INT       Array[2, 16100, 100]
   CAL             INT       Array[2, 10, 100]

 D1 holds the data for channel 1, D2 has the data for channel 2.
 The data is returned as complex so:
  d1.dat[i0,i1,i2]  where
   i0 - 2= the i,q complex samples
   i1 - 16100= the data  samples in 1 ipp
   i3 - 100 = the 100 ipps in a record

   To read multiple records:
   nrec=shsget(lun,d,nrec=3)
; in this case d will be an array of structs: d[3]...


NOTES:
 31aug11.. i was interpreting the tx skip variables incorrectly
           the txskip,  only tell you
           the timing offsets. the data is packed together
           txlen,datalen,noiseLen

(See /pkg/rsi/local/libao/phil/atm/shsget.pro)


SHSGETSPC - INPUT DECODED SPECTRA

[Previous Routine] [Next Routine] [List of Routines]
NAME:
shsgetspc - input decoded spectra
SYNTAX: nspc=shsgetspc(dir,fbase,spcar,freq,hdr)
ARGS:
dir    :string    directory holding file
fbase  :string    file basename (see below)
RETURNS:
 nspc  : long     < 0 error.. 
                  > 0  number of spectra in array
spcar[nchn,nspc]:float  spectra
freq[nchn]: float   freq for spectra
hdr       : {}     header info

DESCRIPTION:
   Read a shs decoded averaged spectra file (typically avged for 10 secs).
This has been processed by clp1shs.c program.
	The user inputs the directory and base filename (see below).
The spectra, freq array, and header struct will be returned.
	This routine is normally used for debugging...
EXAMPLE:
  Suppose the integrated files you want are:
/net/rserv2/data/atm/clp/test_20170101_001.hdr
/net/rserv2/data/atm/clp/test_20170101_001.dcd
The call would be:
 dir  ='/net/rserv2/data/atm/clp/'
 fbase='test_20170101_001'    ; note no trailing .
nspc=shsgetspc(dir,fbase,spcar,freq,hdr)

(See /pkg/rsi/local/libao/phil/atm/shsgetspc.pro)


SHSHDR_DAT - GET DATA HEADER FOR TABLE

[Previous Routine] [Next Routine] [List of Routines]
NAME:
shshdr_dat - get data header for table
SYNTAX: istat=shshdr_dat(lun,dhdr,ahdr=ahdr)
ARGS:
   lun: int        lun assigned to file vis shsopen. desc.lun
RETURNS:
  istat: int   1 - got header
               0 - i/o error or eof
              -1 - never saw start of header "HEADER:"
              -2 - did not find end of header "]"
   dhdr: {}    strucuture holding primary header
 adhr[]: string array holding ascii lines input

DESCRIPTION:
   Read in the primary header from the file pointed to by desc.lun. The
file will be rewound before reading is started. The file will be 
left positioned after the start of the primary header.

(See /pkg/rsi/local/libao/phil/atm/shshdr_dat.pro)


SHSHDR_PRI - GET PRIMARY HEADER OF FILE

[Previous Routine] [Next Routine] [List of Routines]
NAME:
shshdr_pri - get primary header of file
SYNTAX: istat=shshdr_pri(lun,phdr,ahdr=ahdr)
ARGS:
   lun: int        file descriptor pointing to data file
RETURNS:
   phdr: {}    strucuture holding primary header
 adhr[]: string array holding ascii lines input

DESCRIPTION:
   Read in the primary header from the file pointed to by lun. The
file will be rewound before reading is started. The file will be 
left positioned after the start of the primary header.

(See /pkg/rsi/local/libao/phil/atm/shshdr_pri.pro)


SHSMERGEIMG - MERGE TWO IMAGES AVERGING OVERLAP

[Previous Routine] [Next Routine] [List of Routines]
NAME:
shsmergeimg - merge two images averging overlap
SYNTAX: istat=shsmergeimg(img1,img2,cfrAr,bw,imgMerged,imgI,nedgslop=nedgeslop)
ARGS:
img1[n,m]: float  one img to merge
img2[n,m]: float  2nd img to merge
cfrar[2]: double  freq, Mhz center each band.
                  if 4096 chan, the freq for chan[2048] cnt from 0
bw      : double  bw in mhz for each image
KEYWORDS:
edgslop: long      number of channels to ignore from each edge of each
                   img. def is 34. this  area has no data.
RETURNS:
istat          :  0 ok
                  -1 error
imgMerged[nn,m]: float  merged image
imgI     : {}     holds info about the new img
                  - imgI.nchan
                  - imgI.f0 first freq
                  - imgI.f1 last freq chan
                  - imgI.df  channel freq spacing
DESCRIPION:
	merge two images together. It will discard edgeslop channels
from the edges of each input image (def:34).
It will then averge the overlap region and return the final image.
	The routine does not reinterpolate the data. If the frequency
step does not divide into the frequency separation of the two bands
then there will be a freq error in the overlap region. this will be a
fraction of the channel width.
	The freq returned are: 
    imgI.f0 - is the first frequency kept from the first image
    imgI.f1 - is the last freq kept from the 2nd image
    imgI.df - is the original freq freq  step

(See /pkg/rsi/local/libao/phil/atm/shsmergeimg.pro)


SHSOPEN - OPEN AN ATM SHS FILE

[Previous Routine] [Next Routine] [List of Routines]
NAME:
shsopen - open an atm shs file
SYNTAX: istat=shsopen(filename,desc)
ARGS:
filename:  string filename of file to open
RETURNS:
  istat: int   1 open ok
               0 couldn't open file
   desc: {}    descriptor holding file info. pass this to the shs io routines.


DESCRIPTION:
   Open an atm shs file. Return a file descriptor that you will pass
to the shsxxx i/o routines. The file is left positioned at the start hdr
of the first table.

(See /pkg/rsi/local/libao/phil/atm/shsopen.pro)


SHSPOS - POSITION TO A RECORD IN THE SHS FILE

[Previous Routine] [Next Routine] [List of Routines]
NAME:
shspos - position to a record in the shs file
SYNTAX: istat=shspos(desc,rec,currec=currec,nextrec=nextrec)
ARGS:
   desc:{}     structure returned by shsopen().
    rec: long  record to position to (count from 0)
KEYWORDS:
   currec:     if set then reposition to start of current rec
   nextrec:    if set then position to next record.
RETURNS:
   istat:  1   - positioned ok.
           0   - beyond end of file
          -1   - error positioning

DESCRIPTION:
   Position to a record in an shs file. This uses the record length
from the first record of the file.

(See /pkg/rsi/local/libao/phil/atm/shspos.pro)


SHSSCANDIR - SCAN ALL FILES IN AN SHS DIRECTORY

[Previous Routine] [List of Routines]
NAME:
shsscandir - scan all files in an shs directory
SYNTAX: n=shsscandir(path,fI)
ARGS:
 path: string  directory path, filename (with wildcards) to search
               this string is passed to file_search()
RETURNS:
 n   : long    number of files found
fI[n]: {}      holds info for each file

 The fI struct contains:
IDL> help,fi,/st
** Structure <8c5cd8>, 5 tags, length=48, data length=44, refs=1:
   YYYYMMDD        LONG          20150619
   FNAME           STRING    '/net/daeron/data/t1193_20150619b/t1193'...
   LTIME           STRING    '23:51:24'
   SECMIDST        LONG             85884
   NRECS           LONG               109

(See /pkg/rsi/local/libao/phil/atm/shsscandir.pro)