pdev idl routines

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


List of Routines


Routine Descriptions

DEVTPRMS - COMPUTE RMS ON TOTAL POWER ARRAY

[Next Routine] [List of Routines]
NAME:
devtprms - compute rms on total power array
SYNTAX: pdevtprms,toAvg,tp,,rmsAr,allen=allen
ARGS:
 toAvg[n]: long    samples to average before computing rms.
                   If n, greater than 1 then the rms will be computed
                   on each dataset.
  tp[m,2]:float   total power data low band. 2nd index is pola,b
KEYWORDS:
   allen:          if set then return the allen deviation rather than
                   the standard deviation. 
                   it is y[i]=sqrt(.5*mean((tp[i]-tp[i+1])^2))
RETURNS:
  rmsAr[n,4]:float  return rms info for low band
DESCRIPTION:
   Compute the rms deviation of a set of total power noise samples. If the
keyword /allen is set then the sqrt of the allen variance is computed rather
than the standard deviation.
   toAvg determines the number of adjacent samples to average before
computing the deviation. If toavg is an array then the deviation will
be computed for each set of averages.
   The info is returned in rmsAr[n,4] where n is the number of entries in
toavg[n]. The 4 entries for each average contains:

   rmsAr[n,0] - rms for tp polA
   rmsAr[n,1] - rms for tp polB
   rmsAr[n,2] - pnts averaged before rms computed.
   rmsAr[n,3] - pnts available for rms after averaging

(See /pkg/rsi/local/libao/phil/pdev/pdevtprms.pro)


PDEVAVG - READ AND AVERAGE RECORDS

[Previous Routine] [Next Routine] [List of Routines]
NAME:
pdevavg -  read and average records
SYNTAX: istat=pdevavg(desc,nrecs,b,rec=rec,verb=verb,tp=tp)
ARGS:
    desc: {} returned by pdevopen
   nrecs: long recs avg
KEYWORDS: 
     rec: long record to position to before reading (cnt from 1)
RETURNS:
     istat: number of records averaged.
          : 0 returned no records
          : -1 returned some but not all of the recs
   tp[nrecs,npol]: float if supplied then return the total power at each sample
DESCRIPTIION:
   Read and average the requested number of records from file.

(See /pkg/rsi/local/libao/phil/pdev/pdevavg.pro)


PDEVAVGDIR - AVG ALL PDEV FILES IN AN ARRAY OF DIR.

[Previous Routine] [Next Routine] [List of Routines]
NAME:
pdevavgdir - Avg all pdev files in an array of dir.
SYNTAX: pdevavgdir,dirAr,skyCfr,lo2Off,savDir,verb=verb
ARGS:
   dirAr[]: strarr array of directory names to search. The names should
                   include the trailing /.
   skyCfr : float  Mhz. sky center frequency Mhz for all the files.
   lo2Off : float  Mhz. The lo2 offset for the two bands. Use a single
                        positive number.
   savDir : string Save file directory where the accumualated save files are
                   written.
RETURNS:
           A save file is written for each .pdev file found. It contains:
   freq[nchan] frequency array
   nrecsTot: number of records averaged
   b       : {} structure holding averaged data
   skycfr  :    sky center frequency
   descSav :    the descriptor returned from pdevopen(). This includes
                the initial file header.
DESCRIPTION:
 avgerage all the .pdev files in the requested directories.
 save the averages in the savDir directories.

(See /pkg/rsi/local/libao/phil/pdev/pdevavgdir.pro)


PDEVBITREVIND - RETURN INDEX ARRAY FOR FFT BITREVERSE

[Previous Routine] [Next Routine] [List of Routines]
NAME:
pdevbitrevind - return index array for fft bitreverse
SYNTAX: indAr=pevbitrevind(lengthfft)
ARGS:
   lengthfft: long length of fft for bitreverse
RETURNS:
   indAr[lenth]: long  index array for bit reverse.
 generate a bit reverse index array;
DESCRIPTION:
   The data from the pdev spectrometer is output in bit reversed
order. This routine will generate  an array of indices that can be used
to put the spectrum in proper frequency order:

EXAMPLE:
; let spcbr[8192] be the spectra in bit reversed order..
   indR=pdevbitrevind(8192)
   spc=spcbr[indR]         ; spc now in proper order

(See /pkg/rsi/local/libao/phil/pdev/pdevbitrevind.pro)


PDEVCLOSE - CLOSE A PDEV FILE FOR I/O

[Previous Routine] [Next Routine] [List of Routines]
NAME:
pdevclose - close a pdev file for i/o

SYNTAX: pdevclose,desc,all=all 

ARGS:
   desc: {pdevdescr} - descriptor to close (returned by pdevopen)
KEYWORDS:
    all:              if set then close all open descriptors.

DESCRIPTION:
   Files opened with pdevopen() need to be closed with pdevclose() so that
the resources are freed up.

EXAMPLE:
   filename='/share/pdata/pdev/phil/071106//testfits.20071107.b0s0.00000.fits'
   istat=pdevopen(filename,desc)
   .. process the data in the file
   pdevclose,desc   .. this closes the file when done with the processing.

(See /pkg/rsi/local/libao/phil/pdev/pdevclose.pro)


PDEVCMPSTATS - COMPUTE AVG, RMS FOR SET OF FILES

[Previous Routine] [Next Routine] [List of Routines]
NAME:
pdevcmpstats - compute avg, rms for set of files
SYNTAX: istat=pdevcmpstats(fnmIar,bavg,bavgN,bavgF,brms,brmsN,nrecsAr,descAr,$
                           fractFl=fractFl,maxrecs=maxrecs)
ARGS:
   fnmIar[n]: {}   hold files to process (returned from pdevfilelist())

KEYWORDS:
 fracFl: float fraction of bandpass to use for flattening average spectra.
                the default is .1 .
 maxrecs long  max number of records in file to use. Use this to limit the
               records that are read in for large files.
RETURNS:
 istat: long    number of files processed (n)
 bavg[n] : {}  averaged data. 
 bavgN[n]: {}  averaged data normalized to median of each bandpass.
 bavgF[n]: {}  averaged bandpassed flattend by taking fracFl of the
                   transformed bavg to create a bandpass correction.
 brms[n] : {}  rms by channel. Value is in average pdev counts.
 brmsN[n]: {}  rms by channel with each rms normalized by the
                   channel mean value.
nrecsAr[n]: lonarr number of records input for each file.
descAr[n]: {}  descriptor for pdevopen for each file. Use this to
                   generate the freq arrays.

DESCRIPTION:
   Compute the average and statistics for a number of files. 
This routine was written to check the statistics as you change
the level count at the digitizer.

NOTES: 
   The routine tries to read in the entire file so don't use in on
very large files (or use the maxrecs keyword to limit recs to something that
can be read into memory).
   The routine returns the info as an array. Each file should have the
same number of channels.
   This routine will have trouble with data taken in stokes mode since the
rms over the stokes channels may blowup..

(See /pkg/rsi/local/libao/phil/pdev/pdevcmpstats.pro)


PDEVFILEINFO - GET FILE INFO

[Previous Routine] [Next Routine] [List of Routines]
NAME:
pdevfileInfo - get file info
SYNTAX: istat=pdevfileInfo(filename,pdevfI) 
ARGS:
   filename: string    name of pdev file
RETURNS:
pdevfI: {}     file info structure;

(See /pkg/rsi/local/libao/phil/pdev/pdevfileinfo.pro)


PDEVFILELIST - GET LIST OF PDEV FILES

[Previous Routine] [Next Routine] [List of Routines]
NAME:
pdevfilelist - get list of pdev files 
SYNTAX: nfiles=pdevfilelist(nmAr,fnmIAr,recur=recur)
ARGS:
   nmAr[]: strarr   An array of names to search. Each name can be 
                    a pdev filename, or a directory name
KEYWORDS:
   recur:          if set then recurse down through any directories supplied.
RETURNS:
   ntot    : long  number of .pdev files found
fnmIArNtot[]:{}    an array of structures holding info on the
                   pdev files fou nd:w
DESCRIPTION:
   The returned structure contains:
 nmAr='/share/pdata/pdev/agc110443/x107.20070123.agc110443.b0a.00000.pdev'
 istat=pdevfilelist(nmAr,fnmI)
 help,fnmI,/st
* Structure PDEVFNMPARS, 8 tags, length=60, data length=60:
   DIR             STRING    '/share/pdata/pdev/agc110443/'
   FNAME           STRING    'x107.20070123.agc110443.b0a.00000.pdev'
   PROJ            STRING    'x107'
   DATE            LONG          20070123
   src             STRING    'agc110443'
   bm              INT           0
   BAND            INT           0
   grp             INT           0
   num             INT           0

(See /pkg/rsi/local/libao/phil/pdev/pdevfilelist.pro)


PDEVFREQ - RETURN FREQ ARRAY FOR A SPECTRA

[Previous Routine] [Next Routine] [List of Routines]
NAME:
pdevfreq - return freq array for a spectra
SYNTAX: freqAr=pdevfreq(desc,skycfr=skycfr,lo2offset=lo2offset,lenfft=lenfft,$
                        double=double,flipband=flipband)
ARGS:
    desc: {} returned by pdevopen
KEYWORDS: 
     skycfr: double sky cfr of band
  lo2Offset: double offset lo2 from center of band. default: bw/2.
   lenfft  : long   if timedomain data, then specify the len of the fft
  double   :        if true make sure double
 flipBand  :        is set then return the freq array flipped in freq.
                    Use if pdevgettmd(... /flipband)

RETURNS:
     freqAr[]:  frequency array in Mhz for the points in the spectra
Description:
  After aug11, program uses info from desc.hao ao header to determin
the freq. prior to that it has to guess (or you can enter the 
skycfr,lo2offset values).

(See /pkg/rsi/local/libao/phil/pdev/pdevfreq.pro)


PDEVGET - READ IN A PDEV RECORD

[Previous Routine] [Next Routine] [List of Routines]
NAME:
pdevget - read in a pdev record
SYNTAX: istat=pdevget(desc,d,rec=rec)
ARGS:
    desc: {} returned by pdevopen
KEYWORDS: 
     rec: long record to position to before reading.
RETURNS:
     istat: 1 got entire record
          : 0 hit eof this file
          : -1 some type of i/o error or bad data found.

(See /pkg/rsi/local/libao/phil/pdev/pdevget.pro)


PDEVGETHDR - READ A PDEV HEADER FROM FILE

[Previous Routine] [Next Routine] [List of Routines]
NAME:
pdevgethdr - read a pdev header from file
SYNTAX: istat=pdevgethdr(lun,hdrpdev,hdrsp1,hdrao,pdevver)
ARGS:
   lun: int            for file to read
RETURNS:
   istat: 0  got headers
          -1 could not read file
          -2 file does not contain a header
          -3 not an sp1 file header (maybe an rdev file?)
hdrpdev: {}   pdev main header
hdrsp1 : {}   sp1 header
hdrao  : {}   ao hdr
pdevver: int  version number 1,2, ...

DESCRIPTION:
	Read the pdev header from the pdevfile. The file has already
been open (with lun  the logical unit number for the open file).
	This routine is normally called only by pdevopen();

(See /pkg/rsi/local/libao/phil/pdev/pdevgethdr.pro)


PDEVGETM - READ MULTIPLE PDEV RECS

[Previous Routine] [Next Routine] [List of Routines]
NAME:
pdevgetm - read multiple pdev recs
SYNTAX: istat=pdevgetm(desc,nrecs,b,rec=rec,avg=avg,tp=tp)
ARGS:
    desc: {} returned by pdevopen
   nrecs: long recs to read
KEYWORDS: 
     rec: long record to position to before reading (cnt from 1)
     avg:      if keyword set then return the averaged data
nobitrev:      if set then don't do bit reversal on read
RETURNS:
  istat: 1 got all the requested records
       : 0 returned no records
       : -1 returned some but not all of the recs
   b[n]: {}   array of structs holding the data
 tp[n,2]: float array holding the total power for each spectra/sbc

(See /pkg/rsi/local/libao/phil/pdev/pdevgetm.pro)


PDEVGETTMD - READ PDEV TIMEDOMAIN DATA

[Previous Routine] [Next Routine] [List of Routines]
NAME:
pdevgettmd - read pdev timedomain data
SYNTAX: istat=pdevgettmd(desc,smpToRead,b,smpPos=smpPos,posInfo=posinfo,flipBand=flipBand)
ARGS:
    desc: {} returned by pdevopen
 smpToRead: long samples to read
KEYWORDS: 
   smpPos: long sample offset from start of file start read. def: current pos
               count from 1. <=0 --> current position
posInfo:{}     The user generates this structure by calling pdevpostmdinfo().
               This structure will let pdevgettmd() read across files in 
               multiple file sets. Without this struct, the routine
               will not read beyond the end of file of the current file.
flipBand:      if set then flip the frequency order of the band. This exchanges the 
               i,q samples.. It also updates the pdev.hao.bd
RETURNS:
     n: n  number of samples recovered
      : 0 hit eof this file
          if posInfo is supplied,it will read till the end of a multi file set.
      : -1 some type of i/o error or bad data found.
b     : complex return data here in struct
DESCRIPTION:
	Read pdev time domain data. It returns the number of samples read.
You can position in the file before reading using smpPos= keyword.
(Note that positioning will not yet allow you to move to the next file).
the posinfo= keyword will let you read across files of multiple file sets.
Warning: for the multi set read to not drop any datasamples, the files 
must be a multiple of the native datatype..This means that files with 16 bit
samples must have a file length that is even.).

(See /pkg/rsi/local/libao/phil/pdev/pdevgettmd.pro)


PDEVINPLPF - INPUT LOWPASS FILTER COEF FROM DISK

[Previous Routine] [Next Routine] [List of Routines]
NAME:
pdevinplpf - input lowpass filter coef from disk
SYNTAX: istat=pdevinplpf(filebase,filter)
ARGS:
filebase: string : basename for filter. Do not include the .0,.1,.2...
RETURNS:
istat  : int     : 0 ok, -1 error
filt[] : int     filter read in. It will be the symmetric about the center.
DESCRIPTION:
   Read in a hires low pass filter. Pass in the basename for the
filter (eg: 'dlpf.0032'). Don't include the .0,.1,.2,.3 .
Program will input the filter, symmeterize, and then return it.

(See /pkg/rsi/local/libao/phil/pdev/pdevinplpf.pro)


PDEVINPPFB - INPUT POLYPHASE FILTER BANK FILTER

[Previous Routine] [Next Routine] [List of Routines]
NAME:
pdevinppfb - input polyphase filter bank filter
SYNTAX: istat=pdevinplpf(filename,len,filter)
ARGS:
filename: string : name of file holding filter: pfb.8192.hamming
len:      int    : length of filter. eg 8192.
RETURNS:
istat  : int     : 0 ok, -1 error
filt[] : int     filter read in. It will be the symmetric about the center.
DESCRIPTION:
   Read in a polyphase filter. Pass in the filename (with directory if
needed). Also include the length of the pfb (eg. 8192).
Program will input and return the filter.

(See /pkg/rsi/local/libao/phil/pdev/pdevinppfb.pro)


PDEVKLPF - MAKE PDEV LOW PASS FILTER

[Previous Routine] [Next Routine] [List of Routines]
NAME:
pdevklpf - make pdev low pass filter
SYNTAX: istat=pdevmklpf(filterType,dec,filter,fbase=fbase)
ARGS:
filterType:string  filter type to use. values can be:
                   'rect'      
                   'hamming'   
                   'hanning'  
                   'blackman'  
                   'bartlett'  
                   'tri'       
 
dec: int			decimation 2..1024
KEYWORDS:
fbase: string		/dir/baseFilename to store the filter data
                   The program will add the .0,.1,.2.,3 for
                   the 4 files. If this keyword is not
                   supplied, then temp files:
                   /tmp/pdevmklpf.pid.dec.n will be created
                   and later deleted.
RETURNS:
istat	: it		= 0  ok
                   -1 illegal filterType
                   -2 illegal decimation
                   -3 trouble creating file
                   -4 trouble reading in file we created

filter[4*dec]: float  filter (in voltage).

(See /pkg/rsi/local/libao/phil/pdev/pdevmklpf.pro)


PDEVLEVELS - COMPUTE PDEV LEVELS DURING COMPUTATION

[Previous Routine] [Next Routine] [List of Routines]
NAME:
pdevlevels - compute pdev levels during computation
SYNTAX: istat=pdevlevels(hsp,tp,pdevlevels,b=b)
ARGS:
hsp {hsp}: struct   sp1 header (from desc.hsp).
tp[n]    : float    totPwr. each should come from hsp header.
KEYWORDS:
 b : {}    struct   data struct read via pdevget. Will compute the
                    power for polA,B in this struct (returning array of 2)
 RETURNS: 
 istat : int     0 ok, -1 error (time domain spectra).
 pdevlev[n]:{} : structure holding the levels at various steps.

DESCRIPTION:
   Given the total power value of a spectrum, and the sp1 header 
(desc.hsp) compute the levels at each step in the pdev computational chain 
(see http://www.naic.edu/~phil/hardware/pdev/pdevgain/settingPdevLvls.html). 
 The use can optionally pass in a single struct holding a spectral record
 read via pdevget().

The steps in the computation are:

 0. We use the average spectral value so divide by fftlen
 1. spcAvg= totalPwr/spcLen
 2. acc=spcAvg * ashiftScl
        40 bit accum was upshifted by ashift and then the upper pack
        bits were output.
 3. acc1D=acc/ndumps : get value for 1 accum. uses FCNT 
 4. acc1=acc1*dshiftScl. correct for DSHIFT. downshifts by  2^(DSHIFT_S0)
 5. fftOutpOut= sqrt(acc1/2.)/sqrt(2) : Converts to rms voltage. 
            Divide pwr by 2 since jeff computes V*V*2. 
            divide by sqrt(2) since pwr=(vI^2 + vR^2).  
            or sqrt(pwr)=sqrt(vI^2+VR^2)
            if vI same magnitude as vR then we get sqrt 2.
 6. fftInp: fftOut/pshiftScl
            pshiftscl is log2(sqrt(fftlen)-numshiftPshift)
            For unity scaling of noise in fft, need to divde by sqrt(fftlen)
 7  pfbInp: fftInp/pfbScl
            The fir portion of the pfb decreases noise rms by .75           
 8. If not hires mode, then the 12 bits of the A/D get put in the
    upper 12 bits of the 18 bit pfb reg. So there is a mult by 2^6=64
  
    to get Hi res to work:
       - There is no scaling when going dlpfOut to pfbInp ->
         upper most 16bits of dlpf -> lower 16 bits of pfbInp
       - The lpdf has a dc gain of .627 (i measured .61)
       -hr_shift (upshift) in the 26 bit accum should be set for unit
         gain for noise. With dec=0 this would be upshift of 10.
         if dec not zero then: hr_shift=10-alog2(sqrt(dec)) since the 
         noise grows as the sqrt of the number of adds.
       - the 12 bits of the a/d are put in the upper 12 bits of the
         dlpf 16 bit register (scale up by 2^4=16).

 9. A/D sigma: answer is sqrt(2) too low..probably in the 
    conversion from power to voltage. 

 PdevLev structure:
IDL> help,lev1,/st
* Structure <9ff2c34>, 28 tags, length=116, data length=106, refs=3:
   TP              FLOAT 4.99311e+09 total power input
   _FFTLEN         UINT  8192        fftlen
   SPCAVG          FLOAT 609510.     avg spectral value
   _PACK_B         INT   32          bits from accumulator returned
   _ASHIFT         UINT  0           upshift used in 40bit accum
   ACC             FLOAT 1.56035e+08 40 bit accum value 
   _FCNT           LONG  20752       number of spectra added
   ACC1D           FLOAT 7519.02     avgSpc value 1 spectra
   _DSHIFT         UINT   0          down shift each spc before sum
   ACC1            FLOAT  7519.02    acvSpc value before downshift
   FFTOUT          FLOAT  43.3561    output fft. rms
   _VSHFIT         UINT      0       upshift
   _PSHIFT         STRING '0x1ff5'   pshift. butter fly downshifts
   _SCLPSHIFT      FLOAT  0.0441942  scaling of fft
   _SCLPSHIFTMAX   FLOAT  0.707107   max scaling fft thru butterflys 
   _SCLPSHIFTMIN   FLOAT  0.0441942  min scaling fft thru butterflys
   FFTINP          FLOAT  981.03     rms input to fft.12bits in upper 18
   _PFBGAIN        FLOAT  0.750000   pfb noise gain
   PFBINP          FLOAT  1308.05    pfb inp
   DLPFOUT         FLOAT  20.4383    / by 64. 12 bits to upper 18.
   _DEC            INT    0          decimation dlpf
   _LPDFGAIN       FLOAT  0.627000   dlpf gain
   _HRSHIFT        UINT   9          hr_shift in dlpf
   _HRSHIFTEXP     FLOAT  0.0        expected shift
   _LPDFSCALE      FLOAT  1.00000    dlpf total scaling
   _DLPFINP       FLOAT  20.4383     dlpf input
   ATODSIGMA       FLOAT 20.4383     a/d sigma
   ATODSIGMACOR    FLOAT 28.9041     a/d sigma correct for sqrt(2)

(See /pkg/rsi/local/libao/phil/pdev/pdevlevels.pro)


PDEVOPEN - OPEN PDEV FILE FOR READING.

[Previous Routine] [Next Routine] [List of Routines]
NAME:
pdevopen - open pdev file for reading.
SYNTAX: istat=pdevopen(filename,desc,fnmI=fnmI,fnumhdr=fnumhdr)
ARGS:
   filename: string    filename to open (unless fnmI is specified)

KEYWORDS:
   fnmI    : {]        returned from pdevfilelist. if provided,
                       then ignore filename and use this as the
                       file to open.
   fnumhdr: string     If the file you are openning is not the first file
                       of a run of multiple files, then fnumhdr specifies
                       the file number for the first file of the set (which
                       contains the header). See below for how to use this.
RETURNS:
   istat: 0 ok
          -1 could not open file.
          -2 could not open header file in multi file set
          -3 error reading headerfile
          -4 header file didn not contain a header
          -5 header file didn not contain an sp1  header
          -6 unknown status from pdevgethdr()
   desc : {}  file descriptor to pass to the i/o routines.

DESCRIPTION:
	Open a .pdev file. The format for a pdev file is a 
1024 byte header followed by data. The data can be spectra or time domain
samples.
	If multiple files were written during 1 scan then only the first file 
has the 1024 byte header.  The first file of a scan always starts with a
number that is a multiple of 100.

	When you are done processing a file call pdevclose,desc to close the
file. You can use pdevclose,/all to close all open files. If you 
are reading a multifile scan sequentially then the next pdevopen() will 
close the previous file for you.

	If you have multiple files in a scan, pdevopen() trys to guess which 
file has the header. The algorithm it uses is:
   1. if you open files sequentially from the first header file,
      then pdevopen() stashes info in the desc. structure
   2. if you specify fnumhdr= then it uses that number as the file
      with the header.
   3. if the filenumber is not divisible by 100 then it will take the lowest
      number that is a multiple of 100 from the current file num and assume
      that is the header.
 	A problem can arrive in step 3. if there are > 100 files in the scan
and you don't specify fnumhdr=.. 
      eg: - scan starts at 1200
          - 150 scans in file
          - You want to open file 1305 without using fnumhdr=
          - pdevopen() will take int(1305/100)*100=1300 as the header
            instead of 1200. In this case you need to specify fnumdhr=1200

Examples:
1. To open the first file of a scan (which contains the header):

  file='/share/pdata1/pdev/moon.20080605.b0s1g0.01200.pdev'
  istat=pdevopen(file,desc)
   .. process the file
2. To open a file in the above scan that was not the first file:
   a. If you have already opened the first file:
  	   file='/share/pdata1/pdev/moon.20080605.b0s1g0.01203.pdev'
      istat=pdevopen(file,desc)
      - In this case don't bother to close the previous file, pdevopen()
        will do it for you.
   b. If you want to open the 3rd file of the set:
  	   file='/share/pdata1/pdev/moon.20080605.b0s1g0.01203.pdev'
      istat=pdevopen(file,desc)
      - pdevopen will try to figure out which file had the header.
   b. If you want to open the 3rd file of the set, and pdevopen() can't
      figure out which file was the header file:
  	   file='/share/pdata1/pdev/moon.20080605.b0s1g0.01203.pdev'
      istat=pdevopen(file,desc,fnumhdr=1200)

(See /pkg/rsi/local/libao/phil/pdev/pdevopen.pro)


PDEVPARSFNM - PARSE A PDEV FILE NAME

[Previous Routine] [Next Routine] [List of Routines]
NAME:
pdevparsfnm - parse a pdev file name
SYNTAX: istat=pdevparsfnm(filename,fnmI)
ARGS:
   filename: string  pdev filename to parse
RETURNS:
  istat: int  1 if valid pdev name, 0 if not a valid pdev name
  fnmI : {}     structure holding the parsed information.

 The format is:
 dir/proj.date.obs.brdId.seqnum.pdev
 where obs is optional

EXAMPLE:
 filename='/share/pdata/pdev/agc110443/x107.20070123.agc110443.b0a.00000.pdev'
 istat=pdevparsfnm(filename,fnmI)
IDL> help,fnmI,/st

* Structure PDEVFNMPARS, 8 tags, length=60, data length=60:
   DIR             STRING    '/share/pdata/pdev/agc110443/'
   FNAME           STRING    'x107.20070123.agc110443.b0a.00000.pdev'
   PROJ            STRING    'x107'
   DATE            LONG          20070123
   src             STRING    'agc110443'
   bm              INT           0
   BAND            INT           0
   grp             INT           0
   NUM             LONG          0

(See /pkg/rsi/local/libao/phil/pdev/pdevparsfnm.pro)


PDEVPLOT - PLOT PDEV SPECTRA

[Previous Routine] [Next Routine] [List of Routines]
NAME:
pdevplot - plot pdev spectra
SYNTAX: pdevplot,b,freq=freq ,over=over,brdlist=brdlist,norm=normRange

(See /pkg/rsi/local/libao/phil/pdev/pdevplot.pro)


PDEVPOSTMD - POSITION A TMD FILE

[Previous Routine] [Next Routine] [List of Routines]
NAME:
pdevpostmd - position a tmd file
SYNTAX: curPos=pdevpostmd(desc,smpPos)
ARGS:
    desc: {}   returned by pdevopen
 smpPos: long  sample to position to
               count from 1. if < 1 then return
               the current sample position
               count from 1. <=0 --> current position
RETURNS:
  curPos: long current sample postion (after positioning)
DESCRIPTION:
	Position timedomain file so the next read will read
sample number smpPos (counting from 1).
If the position is beyond the end of the file, position at the
end. If smpPos=0 then return the sample we are about to read
(count from 1).

(See /pkg/rsi/local/libao/phil/pdev/pdevpostmd.pro)


PDEVPOSTMDCMP - COMPUTE FILE,POSITION IN FILE FOR TIME OFFSET

[Previous Routine] [Next Routine] [List of Routines]
NAME:
pdevpostmdcmp - compute file,position in file for time offset
SYNTAX: istat=pdevpostmdcmp(posITmd,secs,retI,secs1970=secs1970,ymdhms=ymdhms)
ARGS:
 posITmd: {}   timedomain position info returned by pdevpostmdinfo();
   secs :long  second from start of file to position to
KEYWORDS:
secs1970:long  secs 1970 for position.
ymdhms[2]:long yymmdd, hhmmss fofor time to position to.
Note: all times are utc. Arecibo time is UTC-4HOURS

RETURNS:
  istat : int   0 ok, -1 error with errmsg printed
 retI   : {}    struct holding return position info
DESCRIPTION:
	Compute the position in a multi scan file for a given 
time offset from the beginning of the file. The user
inputs the integer seconds from start of file to move to.

	The keyword secs1970 lets you input the absolute secs from
1970 (utc) for the time of interest. 

   The keyword ymdhms[2] lets you input hour,minutes secs (utc).

	The routine returns in retI: the filename, byte offet in file, and the
samples left. 
 retI.filename
 retI.byteOffset
 retI.bytesLeftToRead .. in file from this position

 	No file opening or positioning  is done by this routine.

(See /pkg/rsi/local/libao/phil/pdev/pdevpostmdcmp.pro)


PDEVPOSTMDINFO - FIGURE OUT POSITION INFO FOR MULTI FILE RUN

[Previous Routine] [Next Routine] [List of Routines]
NAME:
pdevpostmdinfo - figure out position info for multi file run
SYNTAX: istat=pdevpostmdinfo(firstFile,nfiles,posI,fnmI=fnmI)
ARGS:
 firstFile: string name of first file of run
                   if fnmI supplied then ignore this
 nfiles:    long   number of files in scan (one beam)
KEYWORDS:
  fnmI: {}     fnmi struct from masfilelist. If supplied then
               name filename form here.
RETURNS:
istat: int     0 ok
              -1 : error .. message printed
 posI: {]      struct holding positioning info

DESCRIPTION:
	compute positioning info for multi file scans
This can then be used to figure out where in the
multi file scan to position to.

(See /pkg/rsi/local/libao/phil/pdev/pdevpostmdinfo.pro)


PDEVPWR - READ,COMPUTE TOTAL POWER

[Previous Routine] [Next Routine] [List of Routines]
NAME:
pdevpwr -  read,compute total power
SYNTAX: istat=pdevpwr(desc,nrecs,tp,rec=rec,ind=ind,bpc=bpc,hI=hI)
ARGS:
    desc: {} returned by pdevopen
   nrecs: long number of records to process
KEYWORDS: 
     rec: long record to position to before reading (cnt from 1)
  ind[n]: long if supplied then compute total power over the indices in
               this array (should b 0.. nchan-1)
bpc[nchn,nsbc]: long if supplied then divided each spectra by this bandpass
                     before computing total power.
                     nsbc should be 1 or 2. if stokes u,v are present they
                     should be ignored.
RETURNS:
     istat: number of records averaged.
          : 0 returned no records
          : -1 returned some but not all of the recs
   tp[nrecs,nsbc]: float if supplied then return the total power at each sample
                         nsbc will be 1 or 2. If stokes u,v present, they are ignored.
  hI[nrecs]: {}    record header from each record. Contains sequence number (mod
                   64k, calon,off and overflow info.
DESCRIPTIION:
   Read the requeseted number of records and compute the total power for each
sample.  If the file has stokes info, the last two spectra (u,v) are ignored.
   If the bpc keyword is supplied, then divide each spectra by the
band pass (1 bandpass for each pol) before computing the total power. 
   If the ind= keyword is supplied then compute the total power over the indices
provided in the ind array. The same indices are used for both pols. The indices
are over the returned channels (not the fftlen).

   The total power is returned in the array tp[nchan,sbc]. If the keyword
hi= is provided then the record header from each record is also returned.
 the structure contains:

IDL> help,hI,/st
** Structure PDEV_HDRDUMP, 10 tags, length=20, data length=20:
   SEQNUM          UINT             0
   FFTACCUM        UINT           191
   CALON           INT              0
   ADCOVERFLOW     INT              0
   PFBOVERFLOW     INT              0
   SATCNTVSHIFT    INT              0
   SATCNTACCS2S3   INT              0
   SATCNTACCS0S1   INT              0
   SATCNTASHFTS2S3 INT              0
   SATCNTASHFTS0S1 INT              0

(See /pkg/rsi/local/libao/phil/pdev/pdevpwr.pro)


PDEVRMS - COMPUTE RMS BY CHANNEL

[Previous Routine] [Next Routine] [List of Routines]
NAME:
pdevrms -  compute rms by channel
SYNTAX: brms=pdevrms(b,nodiv=nodiv,median=median)
ARGS:
    b[n]: {}  data from pdevget()
KEYWORDS: 
   median:    if set then don't normalize each channel to mean/median value
    nodiv:    if set then don't normalize each channel to mean/median value
  nocross:    if set then don't bother to process cross spectra
RETURNS:
    brms: {]  pdev data structure with rms instead of spectra
DESCRIPTIION:
   Compute standard deviation/mean by channel.

(See /pkg/rsi/local/libao/phil/pdev/pdevrms.pro)


PDEVRMSTMD - COMPUTE RMS,SPECTRA FOR TIMEDOMAIN FILE

[Previous Routine] [Next Routine] [List of Routines]
NAME:
pdevrmstmd - compute rms,spectra for timedomain file
SYNTAX: istat=pdevrmstmd(fname,retI,fnmI=fnmI,desc=desc,smpToRead=smpToRead,$
				fftlen=fftlen,verb=verb,var=var,cs=cs,font=font,tit=tit,$
               normspc=normspc)
ARGS:
    fname: string file to process 
KEYWORDS: 
   fnmI: {}    if supplied then use this for the file name
               (see masfilelist).
   desc: {}    if supplied then user has already openned the file
               read from the current position.
               Leave desc open at last read position on exit
 smpToRead:long number of samples to process. def=2^20l
 fftlen   : long length of xform to do, default=16384
            if fftlen=-1 then do not do xforms
 verb     :    if set then print mean,rms and plot avg spectra
 var[2]   : if supplied then vertical scale for plot
 normspc  : if set the normalize spectra to median value
RETURNS:
 istat: 0   ok
      : -1 trouble.. error message also printed
 retI : {} structure holding info
           retI.npol  = number of pols
           retI.fftlen= length of fft
           retI.freq[fftlen] freq for fft
           retI.spc[fftlen,npol] averaged spectra
           retI.mean[npol] mean (complex i,q)
           retI.rms[npol]  rms  (complex i,q)
           retI.histx[2^nbits]  x axis for histogram
		    reti.histy[2^nbits,npol] histogram

DESCRIPTION:
	Compute mean, rms, and average spectra for part of a
.pdev time domain file. 
	The specified file will be:
   -  openned.
      - if keyword desc provided then use desc passed in.
   - input the requested number of samples
   - compute mean,rms
   - compute average spectra of fftlen
     - if fftlen < 0 then skip this
     - if verb  is set then plot the average spectra
   - compute histogram of the bits
     for 16 bits, use 12bit hist (divide num / 16)
     if verb set then plot this
   - on exit, close the desc (if we opened it). 
     if the user supplied the desc, then leave it open.

(See /pkg/rsi/local/libao/phil/pdev/pdevrmstmd.pro)


PDEVSIM - SIMULATE PDEV COMPUATIONS.

[Previous Routine] [Next Routine] [List of Routines]
NAME:
pdevsim - simulate pdev compuations.
SYNTAX: pdevsim,lenfft,toavg,noiseRms,sineAmp,spcAvg,pshift=pshift,$
                   doplot=doplot,dohist=dohist,nopfb=nopfb
ARGS:
   lenfft: long    length of fft to use. needs to be a power of 2.
     toavg: long    number of spectra to average.
  noiseRms: float   rms in A/D counts for noise
  sineAmp:  float  amplitude of sine wave in a/d counts
KEYWORDS: 
   pshift: long    bit map telling when to do downshifts in butterfly.
  nopfb  :         if set then no polyphase filtering
RETURNS:
   spcAvg[lenfft] the averaged spectrum with dc in the center (shift(spcavg,lenfft/2))
DESCRIPTION:
   simulate the pdev spectrometer polyphase filter bank, fft, and power stages.
This routine differs from pdev in that it computes spectrum of PolA, not 2*spectrum of PolA
   Spc

(See /pkg/rsi/local/libao/phil/pdev/pdevsim.pro)


PDEVSIMTMD - SIMULATE TIME DOMAIN SAMPLING.

[Previous Routine] [Next Routine] [List of Routines]
NAME: 
pdevsimtmd - simulate time domain sampling.
SYNTAX: istat=pdevsimtmd(npnts,rmsInpV,dec,hr_shift,nbits,retI,$
                 ifsmp=ifsmp,linelossdb=linelossdb,filtertype=filtertype,$
				  presmo=presmo,ysmo=ysmo
ARGS:
 npnts: long    number of complex points to use
                power of 2 is quicker since fft for filtering
 rmsInpV: float rms input voltage. .787 is peak too peak max 
                - should be the measured input rms voltage.
                  (at scope before linelossdb).
    dec : int   decimation 1.. 1024
 hr_shift:int   upshift before taking nbits
 nbits    :int  bits to keep, 4,8 
filtertype: string filter type to use. Values are:
               rect,hamming,hanning,blackman,bartlett 
	 			The default type is hanning
KEYWORDS:
 ifsmp:  if true then then if sampling. only i dig.
         for power this just kicks things down by 2
 dlpffn: string  name of file holding lpf data (leave off the .1,.2..3,.4)
 lineLossDb: float  loss in line from rmsInpV measure to a/d
                 (in case you use the scope measurement in control room)
		           measured value about 1.2 db (cable and filter)
 presmo: long   presmooth the noise data by this amount (boxcar).
                this can HELP simulate IF sampling.
                eg: clock=160Mhz, IF BW=20Mhz. presmooth by 8.

RETURNS:
 istat: int      0 ok, -1 error
 retI: {}         struct holding info
 ysmo[fftlen]    return double smoothed data.
                 processing:
                   1. random numbers scaled 
                      to have 1sigma=rpsInpV
DESCRIPTION:
	Generate npnts gaussian random complex numbers. 
   (note npnts should be a large power of 2: 2&18 or more) 
 - scale so that rmsInpV is  1 sigma. 
 - scale this so .787 V is -2048 to +2047
 - round to integer
 - create filter time series, filter type.
 - 0 extend to npnts, fft,x, cener about npnts/2
 - xform data, shift by npnts/2
 - multily data , filter
 - shift back by npnts/2
 - transform back to time domain. this is ysmo
 - scale  by shift, nbit factors
 - clip to upper 4 bits
 - compute statistics, return

 Note: if you are only interested in ysmo, the values for hr_shift are
    not used (but should be reasonable)

 History
 06dec13 - remove filter from struct. so we can pt
           multiple runs of different decs into a single
          retiAr[]

(See /pkg/rsi/local/libao/phil/pdev/pdevsimtmd.pro)


PDEVTDSPC - COMPUTE SPECTRA FOR TIME DOMAIN DATA

[Previous Routine] [Next Routine] [List of Routines]
NAME:
pdevtdspc - compute spectra for time domain data
SYNTAX: n=pdevtdspc(desc,nchan,nspc,spc,posspc=posspc,toavg=toavg)
ARGS:
desc:{} from pdevopen()
nchan: long  number of freq chan in each spectra
nspc: long number of averaged spectra to return
KEYWORDS:
posspc: long	spectra to position to before starting.
               0--> no position. positioning uses 
               nchan length spc before averaging
toavg: long number of spectra toaverage. def=1

RETURNS:
   n: long number of averaged spectra

DESCRIPTION:
	Compute spectra from time domain data. It will
return nspc averaged spectra. Each averaged spc is nchan
long and has toavg spectra averaged. Data is returned
for both pols (if recorded).
	The spectra will be shifted to but dc in the center

	posspc= keyword can position you before reading. The position
unit is the length of a single spectra (before averaging).

The file will be left positioned after the last averaged
spectra input. If you hit eof before all spectra are input
it is left positioned at the end of the last full averaged
spectra input.

Notes:
   This routine will probably have trouble spanning
data sets in more than 1 file.

(See /pkg/rsi/local/libao/phil/pdev/pdevtdspc.pro)


PDEVTPFILE - COMPUTE TOTAL POWER FOR FILE.

[Previous Routine] [List of Routines]
NAME:
pdevtpfile - compute total power for file.
SYNTAX: istat=pdevtpfile(fname,tp,hdr=hdr,hI=hI,fnmI=fnmI,ind=ind,bavg=bavg)
ARGS:
 fname: string name of file to process (unless fnmI keyword is supplied)
KEYWORDS:
   fnmI:{} if supplied, then take filename from here. This structure is
           returned by bpdevfilelist().
   ind[]: long if supplied, then these are the indices in the data
               array to be used for the total power computation. The
               indices are relative to the channels stored in the 
               file (not the fftlen in case these two are different).
RETURNS:
   istat:   long   number of total power points returned (n)
                   0--> no points
                  -1    trouble opening file.
   tp[n,2]: float  total power. n = number of points. 2=pola,polb
   hdr    : {]     primary header. reg and sp.
                   hdr.h1 (general hdr0< hdr.h2 (sp header)
   hI[n]  : {}     record header for each record. contains sequence
                   number, calon/off and overflow info
     bavg : {pdevget} if this keyword is supplied then the program will
                   first compute the spectral average of the entire
                   file and then use this average to bandpass correct
                   every spectra before computing the total power.
                   the average spectra is then returned here.

(See /pkg/rsi/local/libao/phil/pdev/pdevtpfile.pro)