; NAME:
;   darkcurrent_test_vsub.pro (v1.0)
;
; PURPOSE:
;   This program obtains data for measuring dark current as a function
;   of temperature.  WARNING:  THIS IS A MODIFIED DARK CURRENT EXPERIMENT THAT
;   MODIFIES THE VALUE OF VSUB AS DATA ARE OBTAINED.  IT SHOULD ONLY BE USED
;   WITH A SIPIN DETECTOR ON AN H1RG MUX.
;
; CALLING SEQUENCE:
;   darkcurrent_test_vsub, [paramfile=paramfile]
;
; INPUTS:
;   none
;
; KEYWORD PARAMETERS:
;   paramfile:  The complete file path of the parameter file to use for this
;               experiment.  The default value is 
;               '/opt/idl/params/dktest.param'.
;
; EXAMPLE
;   Execute a dark current test using default parameter file
;   IDL> darkcurrent_test_vsub
;
;
; REFERENCE:
;   none
;
; MODIFICATION HISTORY:
;   Written by:  
;       Ernie Morse, IDTL, June 24, 2004
;           Modified darkcurrent_test to alter VSUB while data are being 
;           obtained.
;
pro darkcurrent_test_vsub, paramfile=paramfile

    if not keyword_set(paramfile) then begin
        parfile='/opt/idl/params/dktest.param'
    endif else begin
        parfile=strtrim(paramfile)
    endelse

    print, parfile

    ; Open the parameters file
    openr, U, parfile, /GET_LUN

    ; Call parseline to read the temps for the experiment
    parseline, U, temps, num_temps
    print, 'Will run test at: '
    print, temps

    ; read from the param file the number of exposures per temperature for dark
    ; measurement
    parseline, U, exposures_per_temperature
    exposures_per_temperature = fix(exposures_per_temperature[0])

    ; read from the param file the exposure time to use for darks
    parseline, U, exposure_time
    exposure_time = exposure_time[0]

    ; read from the param file the readmode to use for darks
    parseline, U, rd_mode
    rd_mode = rd_mode[0]
    mode_params = strsplit(rd_mode, ',', /extract)
    mode_params = strtrim(mode_params, 2)

    ; read from the param file the number of times to repeat the test
    parseline, U, loop_times
    loop_times = fix(loop_times[0])

    ; read from the param file the time to take darks at the beginning of the
    ; experiment (in hours)
    parseline, U, initial_dark_hours
    initial_dark_hours = float(initial_dark_hours[0])

    ; read whether or not to use autoflush
    parseline, U, autoflush
    autoflush = autoflush[0]

    ; Print status information
    print
    print, 'Running darkcurrent_test.pro'
    print, 'Exposures per temperature = ', exposures_per_temperature
    print, 'Exposure time (s) = ', exposure_time
    print, 'Number of times to repeat the whole test', loop_times
    print, 'Initial number of hours of darks to start with', initial_dark_hours

    ; make an array to keep track of multiple instances of the same
    ; temperature
    tempcount = intarr(n_elements(temps))

    ; examine each temperature, fill tempcount array with sequence number of 
    ; the temperature
    unique_temps = temps[uniq(temps, sort(temps))]
    for ucount = 0, n_elements(unique_temps) - 1 do begin
        eqtemps = where(temps eq unique_temps[ucount])
        tempcount[eqtemps] = indgen(n_elements(eqtemps))
    endfor

    tempcount = tempcount * exposures_per_temperature

    ; use several different values of VSUB
    vsub_vals = findgen(6) * 2.0

    ; convert to hex
    vsub_scaled = 4095 * (vsub_vals + 10.0) / 20.0
    vsub_hex = strarr(n_elements(vsub_vals))
    for vs = 0, n_elements(vsub_vals) - 1 do begin
        vsub_hex[vs] = strtrim(string(vsub_scaled[vs], format = '(3z)'), 2)
    endfor

    ; call setupexperiment to start Voodoo and create output directory
    setupexperiment,'darkcurrent_test', outdir, paramfile=parfile

    ; Call lakeshore_setup, which does a range of setup tasks including setting
    ; the PID values and turning on power.
    print, 'Setting up Lakeshore temperature controller'
    lakeshore_setup

    ; set filter wheels to closed positions.  Tryfilt is a procedure to attempt
    ; filter wheel commands multiple times until successful.  If there are 10
    ; failures, it will abort the experiment.
    tryfilt, 'Closed', 'Closed'

    ; turn off power to motors with a direct command to each filter wheel motor
    ; controller
    a = idtl('par 1ST1')
    a = idtl('par 2ST1')

    ; turn off autoflush if requested
    if (strupcase(autoflush) eq 'N') then begin
        print, 'Turning off autoflush'
        a = idtl('mandsp SAF,0')
    endif

    wait,5

    ; Set up for initial darks if they were requested.
    ; We want to take UTR-8,1 exposures for the initial/non-glow darks.
    ; The exposure time should be matched to that for the dark ramps.  However,
    ; if the exposure time is 'min', we need to calculate the actual exposure
    ; time from the minimum CDS exposuretime.

    if (initial_dark_hours gt 0.0) then begin
        if (strtrim(exposure_time, 2) eq 'min') then begin

            ; First, take a min-time CDS exposure and read the header to find
            ; its exposure time.
	    a = idtl('readmode normal')
	    wait, 10
	    a = idtl('readmode cds')
	    wait,10
	    a = idtl('setimagename mintimeCDS.fits')
	    wait,3
	    a = idtl('expose')
	    wait,3
	    fits_read, outdir+'/mintimeCDS.fits', 0, minCDShdr, /header_only
	    minCDStime = sxpar(minCDShdr, 'exp_time')

	    ; Number of reads in dark images is element 1 of mode_params array.
	    ; use it to calculate the initial exposuretime (which should be the
            ; same as the exposure time for the dark ramps).
	    ; add 10 microseconds if the number of reads in the dark ramps is
            ; equal to the number in the initial ramps (8).  Otherwise, the
            ; exposure will fail because Voodoo requires the exposure time to be
            ; at least 10 microseconds greater than minimum in this case.

	    if (mode_params[1] eq '8') then begin
	        init_exptime = strtrim(string((fix(mode_params[1])-1) * $
                    minCDStime + 1e-5, format='(F12.6)'),2)
	    endif else begin
	        init_exptime = strtrim(string((fix(mode_params[1])-1) * $
                    minCDStime, format='(F12.6)'),2)
	    endelse
        endif else begin
            init_exptime = strtrim(exposure_time,2)
        endelse

        ; now set the parameters for the initial darks.  These are UTR-8
        ; exposures with the same exposure time as the dark ramps.
        a = idtl('readmode normal')
        wait,10
        a = idtl('readmode utr,8,1')
        wait,10

        ; Set exposure time for the initial darks
        print, 'Setting exposure time = ' + init_exptime + ' seconds'
        cmd = 'setexposuretime ' + init_exptime		
        a = idtl(cmd)                     		
        wait,5

        ; change temp to initial temp
        set_temperature, temps[0], flag

        ; determine range of time over which initial darks should be taken.
        ; the 0th element of idk_endpoints is the current time, while the 1st
        ; element is the end time of the initial dark period.
        idk_endpts = timegen(2, units = 'hours', $
            step_size = initial_dark_hours, start = systime(/julian))
        current_time = idk_endpts[0]

        ; take initial darks until the end time is reached.
        idk_count = 0
        while(current_time lt idk_endpts[1]) do begin
            idk_count = idk_count + 1
            a = idtl('setimagename initial_dark_'+ $
                strtrim(string(idk_count), 2) + '.fits')
            wait,5
            a = idtl('expose')
            current_time = systime(/julian)
        endwhile
    endif

    ; reset readmode for the dark ramps
    a = idtl('readmode normal')
    wait,10
    a = idtl('readmode ' + rd_mode)

    ; Set exposure time for the dark ramps
    print, 'Setting exposure time ='+strtrim(string(exposure_time),2)+ $
        ' seconds'
    cmd = 'setexposuretime '+strtrim(string(exposure_time),2) 
    a=idtl(cmd)                     
    wait,10

    ; Entire experiment will be repeated k times.
    for k=1,loop_times do begin

        ; Now loop through all the temperatures
        for i=0,n_elements(temps)-1 do begin
            set_temperature, temps[i], flag
            print, 'Detector temperature stable at T = ', temps[i]

            ; loop through and set VSUB values
            for vsub = 0, n_elements(vsub_hex) - 1 do begin
                cmd = 'mandsp SBN,2,23,CLK,' + vsub_hex[vsub]
                a = idtl(cmd)

                ; Obtain a number of images for each detector temperature
                for j = 1, exposures_per_temperature do begin

                    ; make a string representation of the exposure number, adding a
                    ; leading 0 if necessary.
                    exp_num = tempcount[i] + j
                    if (exp_num lt 10) then begin
                        exp_num = '0' + strtrim(string(exp_num), 2)
                    endif else begin
                        exp_num = strtrim(string(exp_num), 2)
                    endelse

                    ; create the file name for the dark ramp
		    darkname = 'dark_'+strtrim(string(temps[i]),2)+'K_'+ $
                            mode_params[1] + '_' + strtrim(exposure_time) + '_' + $
                            strtrim(string(k),2)+ '_' $
                            + strtrim(string(vsub_vals[vsub], format = '(F5.1)'), 2) $
                            + '_' + exp_num + '.fits'

                    ; perform the exposure
                    cmd = 'setimagename ' + darkname 
                    a = idtl(cmd)       
		    wait,5
                    print,'Starting exposure # '+strtrim(string(j),2)
                    a = idtl('expose')
		    wait,5
                endfor  ; exposures
            endfor      ; vsub
        endfor          ; temps
    endfor              ; repeats

    ; restore current to filter wheel motors
    a = idtl('par 1ST0')
    a = idtl('par 2ST0')

    ; turn autoflush back on
    if (strupcase(autoflush) eq 'N') then begin
        a = idtl('mandsp SAF,AFL')
    endif

    cleanupexperiment,'darkcurrent_test',outdir
    FREE_LUN, U

    ; Make lists of images and create directories to hold reduced data
    ; First change to the directory with the resulting data files
    cd, outdir

    ; Create ordered lists of files for the reduction script
    spawn, '/usr/ucb/ls -t initial_dark*.fits | /usr/ucb/tail -r > initial.lst'
    spawn, '/usr/ucb/ls -t dark*.fits | /usr/ucb/tail -r > dark.lst'

    ; Create the Results directory, unless it already exists
    dirlist = findfile('Results', count = direxist)
    if (direxist eq 0) then begin
        spawn, '/usr/bin/mkdir Results'
        spawn, '/usr/bin/chmod 775 Results
    endif

    dirlist = findfile('SlopePlots', count = direxist)
    if (direxist eq 0) then begin
        spawn, '/usr/bin/mkdir SlopePlots'
        spawn, '/usr/bin/chmod 775 SlopePlots'
    endif

    dirlist = findfile('ReadNoise_Results', count = direxist)
    if (direxist eq 0) then begin
        spawn, '/usr/bin/mkdir ReadNoise_Results'
        spawn, '/usr/bin/chmod 775 ReadNoise_Results'
    endif

end
