Viewing contents of file '../idllib/iuedac/iuelib/pro/expofin.pro'
;*****************************************************************************
;+
;*NAME:
;
;      EXPOFIN
;
;*CALLING SEQUENCE:
;      
;      EXPOFIN,LABEL,MIDT,EXP,rr
;
;*PURPOSE:
;
;      This procedure will extract the midtime and duration of an exposure
;      from the science image header.
;
;*PARAMETERS:
;
;      LABEL  (REQ) (I) (0) (S/I)
;             Either the imaget (filename without extension) in which the
;             science image header or label resides, or a unit number for
;             for the header file.  In the latter case, the procedure will
;             assume the file has been already been opened by a calling
;             procedure.
;
;       MIDT  (REQ) (O) (1) (D)
;             Julian date of the calculated midtime of exposure.
;
;        EXP  (REQ) (O) (0) (F)
;             Exposure time in seconds.
;
;         RR  (OPT) (I) (0) (I)
;             Round-robin flag - get the exp. time from the round robin
;             regardless of whether it can be determined by other means.
;             This is a logical - nonzero values equal 'true'.
;
;*SYSTEM VARIABLES USED:
;
;
;*PROCEDURE:
;
;      If a filename is passed to expofin, that file will be opened.  
;      The camera and image sequence numbers will be extracted from line 1.
;      The scheme name will be located in the image processing portion of the
;      header, and the aperture designation extracted from it.  If the image
;      was neither trailed nor double aperture, then the exposure time will
;      be extracted from line 2.  Then, the image processing portion of the
;      header will be searched for the midtime of the exposure.  If found,
;      and if the round-robin flag was not set, then the program will return. 
;      Otherwise, lines 11 through 32 (the event round robin) will be read
;      into an array, and this array will be sorted by time.  The sections of
;      the round robin between the two READ or READPREP commands for the
;      given camera will be kept; the rest discarded.  For double aperture
;      exposures, the label will be searched for the *DATA FROM ... APERTURE
;      line, and times from all EXPOBC commands and MODTIME commands for that
;      camera BETWEEN the 'target in ... ' and 'target from ... ' commands.
;      The user is given a chance to set the aperture, which is helpful if
;      the image was serendipitous.
;      Otherwise, all EXPOBC and MODTIME commands are taken into account.
;      Once an exposure time and mid-time are determined, a year and day must
;      be associated with them.  This is done by comparing the mid-time to
;      the read time in line 10. If the read time is later than the mid-time,
;      the day and year of read will be considered the day and read of mid-
;      time.  Otherwise, the previous day is used, the year remaining the 
;      same unless the read day is 1 January and the mid-time was on 31 Dec.
;      
;
;*SUBROUTINES CALLED:
;
;      decompose
;      PARCHECK
;      EBCDIC
;
;*FILES USED:
;
;      label (I)
;             label file designated by first input parameter
;
;*NOTES:
;
;      The user may enter a different aperture than the one the data pertains
;      to, allowing the program to extract the correct commands for images
;      that are serendipitous or otherwise simultaneous.
;
;      tested with IDL version 2.1.0 (sunos sparc)	11 Jul 1991
;      tested with IDL version 2.1.0 (ultrix mipsel)	N/A
;      tested with IDL version 2.1.0 (vms vax)        	28 Jun 1991
;
;*MODIFICATION HISTORY:
;
;      20 Dec 1990 - Written by LLT.
;     January 1991 - Modifications - MODTIME, etc.  
;     7 March 1991 - Converted to sun by LLT
;      10 May 1991 - PJL corrected prolog format
;     28 June 1991 - LLT add parcheck, cleaned up; tested on VAX; updated prolog
;     11 July 1991 - PJL tested on SUN; updated prolog
;     19 Sept 1991 - LLT revised treatment of blank lines in round robin.
;     20 Sept 1991 - LLT revise treatment of target aperture.
;     26 Sept 1991 - LLT add decompose.
;-
;******************************************************************************
 pro expofin,label,midt,exp,rr
;
 npar=n_params(0)
 if npar eq 0 then begin
    print,'EXPOFIN,LABEL,MIDT,EXP,rr'
    retall
 endif else if npar eq 3 then rr=0    ; npar eq 0 block
 parcheck,npar,3,'EXPOFIN'
;
; For IDL Version 1 - labtype=1 is a string.  For IDL Version 2, labtype
; should be 7.  We need to find out if input parameter #1 ('label') is a
; string or a unit number.
;
 lab=size(label)
 labtype=lab(n_elements(lab)-2)
 if labtype eq 7 then begin       ; Label is a string => imaget was given.
    get_lun,u
;    if strpos(label,';') gt 0 then begin   ; Check for version number
;       sc=strpos(label,';')
;       v=strmid(label,sc,strlen(label)-sc) ; Version number
;       label=strmid(label,0,sc)            ; Imaget
;    endif else v=''                        ; end of version number block
    decompose,label,disk,uic,name,extn,v   ;
    openr,u,disk+uic+name+'.lab'+v         ; Open label file
 endif else u=label                        ; Label is a unit number
;                                          ; end of labtype eq 7 block
 rec=assoc(u,bytarr(74))                   ; one line of label file
; 
; Get preliminary information - camera, image sequence number, scheme name
; Set up output arrays and variables.
;
 midt=fltarr(4)                   ; Midpoint of exposure time
 exp=0.0                          ; Exposure time
 ap=''
 rexp=-1                          ; Round robin hasn't been checked
;
 line=rec(1) & ebcdic,line & line=string(line)
 cam=strmid(line,50,1)                   ; camera number
 isn=strtrim(strmid(line,52,5),2)        ; image sequence number
 print,cam,' ',isn
 i=101
 while strmid(line,72,1) ne 'L' do begin           ; Get scheme name - extract
    line=rec(i) & ebcdic,line & line=string(line)  ; aperture designation
    if strpos(line,'SCHEME') gt 0 then goto,foundscheme
    i=i+1
 endwhile                  ; end of while loop to look for scheme name
 goto,notfound
;
; The scheme name contains information about which aperture was processed.
; If both apertures were processed, the camera-on time in line 2 (which we
; can consider to be the exposure time in many cases) will be the cumulative
; exposure time for both apertures.  In this case, the round robin should
; be checked.  Otherwise, we can check the image processing portion of the
; label for the line that gives the observation date (not found in older
; images).  This date is actually equal to the end-of-exposure time minus
; half of the camera-on time found in line 2.
;
 foundscheme:
 scheme=strmid(line,21,6)                ; Scheme name
 ap=strmid(scheme,3,1)+'A'                   ; Aperture
 if (ap eq 'EA') or (ap eq 'TA') then ap='LA'  ; Large ap. extended or trailed
 print,'Scheme name: ',scheme,'    Aperture: ',ap
 if cam eq '' then cam=strmid(scheme,1,1) ;camera
 if (ap ne 'BA') and (ap ne 'XA') and (ap ne 'YA') then begin  ; B,X,Y - both
    i=100                                              ; apertures or trailed.
    while strmid(line,72,1) ne 'L' do begin            ; If one aperture and
       i=i+1                                           ; not trailed, it may
       line=rec(i)                                     ; be safe to use given
       ebcdic,line & line=string(line)                 ; values.
       if strpos(line,'OBSERVATION DATE(GMT):') ge 0 then goto,found
    endwhile      ;End of while loop to look for observation date
    print,'Observation date not found in label.'
    goto,notfound                           ; Didn't find midtime of obs.
    found:
    oy=strpos(line,'YR=')+3                     ; String pos of obs. year
    od=strpos(line,'DAY=')+4                    ; String pos of obs. day
    oh=strpos(line,'HR=')+3                     ; String pos of obs. hour
    om=strpos(line,'MIN=')+4                    ; String pos of obs. minute
    midt(0)=float(strmid(line,oy,2))            ; Year of midtime of observation
    midt(1)=float(strtrim(strmid(line,od,3),2)) ; Day number "    "
    midt(2)=float(strtrim(strmid(line,oh,2),2)) ; Hour of midtime of observation
    midt(3)=float(strtrim(strmid(line,om,2),2)) ; Minute of midtime of "    "
    print,'The following were assumed by IUESIPS to be correct:'
    print,'Mid-time of observation: ',midt
    line=rec(2) & ebcdic,line & line=string(line) ; Exp. time (avoiding commas)
    time=byte(strmid(line,30,6)) & exp=float(string(time(where(time ne 44))))
    print,'Exposure time: ',exp
    ap=''
    if rr then begin                         ; Round-robin flag, the user would
       print,"About to check the round robin." ; like to check it regardless.
       goto,notfound
    endif else goto,choose             ; Ask the user if they want to use these
 endif else ap=''                      ; values, or enter new ones
    ; End of block to be executed if image was not double aperture or trailed.
;
; If both apertures were processed, or if the scheme name could not be 
; located, or (for single aperture exposures) if the observation date 
; was not found, we come down here to NOTFOUND.  If necessary, we make
; another effort to determine which aperture was processed; the user
; will be asked if all else fails.  For double aperture exposures, it
; is important to determine which aperture the target was in (LWLA,
; LWSA, SWLA, or SWSA).
;
 notfound:        ; Need to look at round robin to get information
   if ap eq '' then begin
    i=0 
    repeat begin                  ; Find the line telling us which aperture
       line=rec(101+i)            ; this data is from
       ebcdic,line & line=string(line) ;and convert it to ascii
       if strpos(line,'********  DATA FROM') ge 0 then print,line
       if strpos(line,'********  DATA FROM') ge 0 then goto,foundap
       i=i+1
    endrep until strmid(line,72,1) eq 'L'   ; End loop looking for aperture
    print,"Can't find aperture information in the label.  Unless you can"
    print,"say which aperture was used, total time for all open apertures"
    print,'will be included.  (Give the aperture the TARGET was in!)'
    read,'What aperture was used (e.g., LWLA)',ap
    ap=strtrim(strupcase(ap),2)
   endif else begin    ;end - unknown aperture, start - known aperture

 foundap:
    if strpos(line,'LARGE') ge 0 then ap='LA' else $
       if strpos(line,'SMALL') ge 0 then ap='SA'
;
; Here's where we branch to if a user, having found the observation date
; in the label, decides to check the round robin after all...
;
 robin:
    c=' '
    case cam of 
       '1': c='LW'               ; LWP or LWR -
       '2': c='LW'               ; one of the long wavelength cameras
       '3': c='SW'               ; SWP or (theoretically) SWR -
       '4': c='SW'               ; one of the short wavelength cameras
       else: read,'What camera was used (lwp, swp, or lwr)',c
    endcase                      ; finish camera part of aperture designation
    c=strupcase(strmid(c,0,2))
    if ap ne '' then begin
      ap=c+ap
       print,'Exposure times for this camera will be included when the TARGET'
       print,'is in the '+ap+'.  If this is NOT the aperture the target was in,'
       print,'enter the correct aperture.  Otherwise, hit return.'
       newap=''
       read,newap
       if newap ne '' then ap=strtrim(strupcase(newap),2)
       print,'Target was in the '+ap
    endif    ;end determining the aperture from info in the label
   endelse   ;end determining the aperture
;
; The round robin exists in lines 10 through 32 of the science image header.
; It is in two columns.  These commands must be extracted and sorted.
; The oldest commands start after a pair of double blank lines, and
; continue until the latest commands immediately before the same double
; blank lines.  The commands must be rotated until the oldest commands
; are the first commands in the array.  Very old images may not follow
; this format; those will not be sorted.
;
    command=strarr(45)                 ; Array for commands
    for i=0,21 do begin
       line=rec(11+i)                     ; First line of round robin
       ebcdic,line & line=string(line)    ; Convert to ascii string
       command(i)=strmid(line,1,32)     
       command(23+i)=strmid(line,34,32)
    endfor                              ; end of loop to read round robin
    line=rec(10)                        ; Line 10 contains read time AND
    ebcdic,line & line=string(line)     ; a command from the round robin
    command(22)=strmid(line,34,32)
;
;    for i=0,44 do if strtrim(strmid(command(i),6,26),2) eq '' then ci(i)=1
    ci=strtrim(strmid(command,6,26),2) eq ''
    nci=where(ci eq 1)    ;Blank lines
    nci0=where(ci eq 0)   ;Non-blank lines

; The following lines will determine whether the blank lines are consecutive
; AND whether the commands are consecutive.  If NEITHER are consecutive, then
; it must be assumed that the commands and blank lines are scattered randomly.

    bconsec=total(nci eq (indgen(n_elements(nci))+nci(0))) eq n_elements(nci)
    cconsec=total(nci0 eq (indgen(n_elements(nci0))+nci0(0))) eq n_elements(nci0)
    if total(ci) gt 2 then begin
       print,'Warning: the round robin has more than two blank lines.'
       if (cconsec or bconsec) then print,'However, the lines are consecutive.'
    endif
    if not cconsec then begin               ;If commands are not consecutive
       if bconsec then begin                ;If blanks are consecutive
          tempcommand=command               ;
          snci=nci(n_elements(nci)-1)+1     ;Index of oldest line
          command(0)=tempcommand(snci:44)   ; Oldest commands
          tc=n_elements(tempcommand(snci:44))
          command(tc)=tempcommand(0:snci-1)
          cconsec=1                         ;Commands should now be consecutive
       endif else begin  ; Blank lines aren't consecutive
          print,'The blank lines are interspersed with commands.'
          print,'Commands will be sorted - you may wish to check the results!'
          command=command(where(ci eq 0))   ; Discard blank lines
          command=command(sort(command))    ; Sort entries
       endelse                              ; end of dealing with blank lines 
    endif                                   ; commands not consecutive

; The only part of the round robin that interests us is the portion dealing
; with the current image.  We know that the last READ or READPREP command
; is the read command for our image.  We therefore need to search backwards
; to find the READ(PREP) command for the previous image FOR THAT CAMERA.
; Then we can discard the rest of the commands.
;
;    if cconsec eq 1 then begin      ; Don't do for images with excessive blanks
;       i=45                        ; in the round robin that aren't consecutive
;       s=45
;       repeat begin
;          i=i-1
;          if strpos(command(i),'READPREP '+cam+' IMAGE '+isn) ge 0 then s=i $
;             else if ((strpos(command(i),'PREP '+cam) ge 0) or $
;                (strpos(command(i),'READ '+cam) ge 0)) then $
;                if s eq 45 then s=i else goto,limits
;       endrep until i eq 0         ; Loop to find read command
;       limits:
;       if s eq 45 then s=44
;       if i eq 0 then begin 
;          print,'Warning: no read command was found for the previous image'
;          print,'for this camera.  There may be missing pertinent commands.'
;       endif
;       command=command(i:s)

;**************************************************************
;Version 2 method:
   
        rdprep=where((strpos(command,'READPREP '+cam+' IMAGE '+isn,0) ge 0) or $
                     (strpos(command,'PREP '+cam,0) ge 0) or $
                     (strpos(command,'READ '+cam,0) ge 0))

        nrdprep=rdprep(n_elements(rdprep)-1)
        if n_elements(rdprep) eq 1 then begin
           nprd=0 
           print,'Warning: no read command was found for the previous image'
           print,'for this camera.  There may be missing pertinent commands.'
        endif else nprd=rdprep(n_elements(rdprep)-2)
        command=command(nprd:nrdprep)
;    endif                          ; End of block to sort the round robin and
                                   ; discard lines not pertinent to image.
;
; Now, we need to prepare the variables we'll need to search the round robin.
; If this is a double aperture exposure, we'll need to identify the commands
; which bracket the commands dealing with the aperture pertaining to this
; image file.  These are the 'TARGET IN ...' and TARGET FROM ...' commands.
;
    expobc=where(((strpos(command,'EXPOBC',0) ge 0) and $
                (strtrim(strmid(command,14,2),2) eq cam)) or $
                (strpos(command,'MODTIME '+cam,0) ge 0))
    sexpobc=size(expobc)

;For each command, which aperture was the target in?

    targetap=strarr(4,n_elements(command)-1)
    ta=''
    if ap ne '' then $
      for it=0,n_elements(command)-1 do begin
        if strpos(command(it),'TARGET IN ',0) ge 0 then begin
           targetap(it)=strtrim(strmid(command(it),16,6),2) 
           ta=targetap(it)
        endif else if strpos(command(it),'TARGET FROM ',0) ge 0 then begin
           targetap(it)=strtrim(strmid(command(it),18,6),2) 
           if ta eq '' then targetap(0:it-1)=targetap(it)
        endif else targetap(it)=ta   
      endfor else for it=0,n_elements(command)-1 do targetap(it)=''       
          
    
    min=0 & sec=0
    time1=25.
    rexp=0.0
    rmidt=replicate(0.0,4)
;
; Now, locate all the EXPOBC and MODTIME commands for this camera, image
; number, and aperture, and extract all commanded exposure times, and also
; the start and end of exposure times.
; 
     if sexpobc(0) ne 0 then for j=0,n_elements(expobc)-1 do $
        if targetap(expobc(j)) eq ap then $
           if strpos(command(expobc(j)),'EXPOBC',0) ge 0 then begin
             temp=strtrim(strmid(command(expobc(j)),16,7),2)
             print,command(expobc(j))
             time=strmid(command(expobc(j)),0,6)
             temp=strtrim(temp,2)
             space=strpos(temp,' ')
             min=fix(strmid(temp,0,space))
             sec=fix(strmid(temp,space+1,strlen(temp)-space-1))
             rexp=rexp+sec+min*60.0                ; Total exposure time so far
             ts=fix(strmid(time,4,2))              ; Current seconds
             tm=fix(strmid(time,2,2))+ts/60.0      ; Current minutes
             th=fix(strmid(time,0,2))+tm/60.0      ; Current hours
             if time1 eq 25. then time1=th         ; Start time of exposure
             th=th+(min+(sec/60.0))/60.0           ; End of current segment
           endif else if strpos(command(expobc(j)),'MODTIME '+cam) ge 0 then begin
             print,command(expobc(j))
             th=th-(min+(sec/60.0))/60.0           ; Modify end time 
             rexp=rexp-sec-min*60.                 ; Subract last segment
             temp=strtrim(strmid(command(expobc(j)),17,18),2) 
             space=strpos(temp,' ')
             min=fix(strmid(temp,0,space))
             sec=fix(strmid(temp,space+1,strlen(temp)-space-1))
             rexp=rexp+sec+min*60.                ; Revised total exposure time
             th=th+(min+(sec/60.0))/60.0          ; Revised end time
          endif                                   ; Block to extract exp. time
;
; Now, calculate the midtime of exposure and then assign a year and day number
; to it.
;
 if rexp eq 0.0 then begin
    print,"Couldn't find EXPOBC/MODTIME command for camera ",cam
 endif else begin
    mt=time1+(th-time1)/2.0       ; Midtime in decimal hours
    line=rec(10) & ebcdic,line & line=string(line)
    rdy=strmid(line,1,2)    ; Read time year
    rdd=strmid(line,3,3)    ; Read time day number
    rdh=strmid(line,6,2)    ; Read time hour
    rdm=strmid(line,8,2)    ; Read time minute
    rds=strmid(line,10,2)   ; Read time second
    rdtime=float(rdh+(rdm+rds/60.0)/60.0)
    print,line
    rdhour=rdh+(rdm+(rds/60.0))/60.0
    rmidt(0)=rdy                        ; Year of read and observation, we hope
    rmidt(1)=rdd                        ; Day of read and observation, we hope
    if rdhour-mt lt 0 then begin        ; What if readtime hour < midtime hour
;
       rmidt(1)=rmidt(1)-1
       if rmidt(1) le 0 then begin   ; Check for exposures crossing 31 Dec/1 Jan
          rmidt(0)=rdy-1
          if rmidt(0)/4. eq fix(rmidt(0)/4.) then rmidt(1)=366 else rmidt(1)=365
       endif                            ; End - check for 31 Dec/1 Jan
    endif                               ; End - readtime hour < midtime hour
    rmidt(2)=fix(mt)                    ; Hour of midtime exposure
    rmidt(3)=(60.*(mt-rmidt(2)))        ; Minute of midtime exposure (decimal)
;
    print,'The following were found in the round robin:'
    print,'Mid-time of observation: ',rmidt
    print,'Exposure time [seconds]: ',rexp
 endelse                              ; End - exposure time found in round robin
;
; Give the user the choice of what to do
;
 choose:
 ncm=n_elements(command)/2-1
 repeat begin
    print,' '
    print,'Please enter: '
    if exp ne 0 then begin 
       print,' 0 to use the IUESIPS values:',exp,' seconds'
       print,'    Midtime: ',midt 
    endif                           ; Program found values generated by IUESIPS
    if rexp gt 0 then begin
    print,' 1 to use the values read from the round robin:',fix(rexp),' seconds'
       print,'    Midtime: ',rmidt  
    endif                             ; Program found values in the round robin
    print," 2 to see the telescope operator's comments,"
 if rexp ne -1 then print,' 3 to see the relevant round robin commands,' $
    else print,' 3 to check the round robin'
;
    print,' 4 to enter a new midtime of observation and new exposure time.'
    print,' 5 for help.'
    print,' 6 to quit.'
;
    choice=1 
    read,' ',choice
;
    case choice of
       0: print,'Using the IUESIPS values.'
       1: if rexp ne -1 then begin & print,'Using values from the round robin.' 
             exp=rexp & midt=rmidt 
          endif else begin
             print,'The round robin has not been searched.' & choice=-1 
          endelse
       2: for ii=0,10 do begin & line=rec(ii) & ebcdic,line & line=string(line)
              print,line
          endfor
       3: if rexp ne -1 then print,command else goto,robin
       4: begin & read,'What is the correct exposure time (seconds)?',exp 
             print,'Enter the correct midtime of exposure:'
             read,'[year-1900,day number,hour,decimal minutes]',midt 
          end
       5: begin & print,'When available, the value for the mid-time found in' 
             print,'the label and scale factor record was calculated by'
             print,'IUESIPS by subtracting half of the total camera-on'
             print,'time from the end-of-exposure time.'
             a=' '
             print,'Hit return when ready for more...'
             read,a
             print,' '
             print,'The round robin is a description of the events that'
             print,'took place around the time of observation.  This'
             print,"program searches for exposure ('EXPOBC') commands and"
             print,'MODTIME commands for that camera, image, and aperture,'
             print,'adds up the exposure times, and subtracts the start time'
             print,'of the first segment from the end time of the final'
             print,'segment and adds half of that to the start time to get'
             print,'the mid-time.  A year and day number are acquired by'
             print,'comparing the mid-time to the read time in line 10 of'
             print,'the science image header (label).'
             print,' '
          end
          6: begin & if labtype eq 7 then free_lun,u & retall & end
       else: print,' '
    endcase        ; Deal with user's choice
 endrep until (choice eq 0) or (choice eq 1) or (choice eq 4)
    ; End of choice loop
;
 if labtype eq 7 then free_lun,u
 return
 end  ; expofin