function cor1_calibrate, im, hdr, calfac_off=calfac_off, bias_off=bias_off, $
                         exptime_off=exptime_off, calimg_off=calimg_off, $
                         sebip_off=sebip_off, nan_off=nan_off, $
                         bkgimg_off=bkgimg_off, silent=silent,$
                         discri_pobj_on=discri_pobj_on, _EXTRA=ex
;+
; $Id: cor1_calibrate.pro,v 1.12 2008/05/16 20:27:33 thompson Exp $
;
; Project   : STEREO SECCHI
;                   
; Name      : cor1_calibrate
;               
; Purpose   : This function returns calibrated images.
;               
; Explanation: The default calibration procedure involves; subtracting
;        the CCD bias, multiplying by the calibration factor and vignetting
;        function, and dividing by the exposure time. Any of these operations
;        can turned off using the keywords. 
;               
; Use       : IDL> cal_image = cor1_calibrate(image,hdr)
;    
; Inputs    : image - level 0.5 image in DN (long)
;             hdr -image header, either fits or SECCHI structure
;
; Outputs   :  cal_image - image convert from  DN (long) to physical
;                          units (float)
;
; Keywords  :calfac_off - set to return image without calibration
;                         factor applied
;            bias_off - set to return image without bias subtraction applied
;            exptime_off - set to return image without exposure time normalized
;            bkgimg_off - set to return image without background subtraction
;            calimg_off - set to return image without vignetting
;                        (flat-field) correction 
;            sebip_off - set to return image without SEB IP correction
;                        applied
;            nan_off   - Turn off setting missing pixels to NaN.
;            discri_pobj_on - use discri_pobj.pro to remove the cosmics
;
; Common    : None.
;
; Calls     : SCC_FITSHDR2STRUCT, SCC_SEBIP, GET_EXPTIME,
;             GET_BIASMEAN, GET_CALFAC, GET_CALIMG, RATIO, SCC_UPDATE_HISTORY
;               
; Category    : Calibration
;               
; Prev. Hist. : Based on COR_CALIBRATE, version 1.7
;                       by Robin C Colaninno NRL/GMU July 2006
;
; Written     : 12-Mar-2007, William Thompson, GSFC
;                       Flag missing pixels as NaN.
;               09-Oct-2007, WTT, added background subtract, BKGIMG_OFF
;               16-May-2008, WTT, check CCDSUM for image vs. background
;-     
;
IF datatype(ex) EQ 'UND' THEN ex = create_struct('blank',-1)
IF keyword_set(silent) THEN ex = CREATE_STRUCT('silent',1,ex)
info="$Id: cor1_calibrate.pro,v 1.12 2008/05/16 20:27:33 thompson Exp $"
len=strlen(info)
version='Applied '+strmid(info,5,len-10)
IF ~keyword_set(silent) THEN  message,version,/inform



;--Check Header-------------------------------------------------------
 IF(DATATYPE(hdr) NE 'STC') THEN hdr=SCC_FITSHDR2STRUCT(hdr)

IF (tag_names(hdr, /STRUCTURE_NAME) NE 'SECCHI_HDR_STRUCT') THEN $
 message,'ONLY SECCHI HEADER STRUCTURE ALLOWED'

IF (hdr[0].DETECTOR NE 'COR1') THEN $
  message,'Calibration for COR1 DETECTOR only'
;----------------------------------------------------------------------

;  Keep track of missing pixels (pixels set to zero).

wmissing = where(im eq hdr[0].blank, nmissing)

;--Add file version to header history
hdr = scc_update_history(hdr,version)

;------------------------------------------------------------------------
;--Correct for SEB IP(ON)
IF ~keyword_set(sebip_off) THEN im = SCC_SEBIP(im,hdr,ip_flag, _extra=ex)
; hdr modified in sebip

;--Convert to DN/S (ON)
IF keyword_set(exptime_off) THEN exptime = 1.0 ELSE BEGIN
  exptime = GET_EXPTIME(hdr,_EXTRA=ex)
  IF exptime NE 1.0 THEN BEGIN
    hdr = SCC_UPDATE_HISTORY(hdr,'Exposure Normalized to 1 Second',value=exptime)
    IF ~keyword_set(SILENT) THEN message,'Exposure Normalized to 1 Second',/info
  ENDIF
ENDELSE

;-- Bias Subtraction(ON)
IF keyword_set(bias_off) THEN biasmean = 0.0 ELSE BEGIN
  biasmean =GET_BIASMEAN(hdr,_extra=ex)
  IF biasmean NE 0.0 THEN BEGIN
    hdr = SCC_UPDATE_HISTORY(hdr,'Bias Subtracted',value=biasmean)
    hdr.OFFSETCR=biasmean
    IF ~keyword_set(SILENT) THEN message,'Bias Subtracted',/info
  ENDIF
ENDELSE

;--Correction for flat field and vignetting (ON)
If keyword_set(calimg_off) THEN calimg = 1.0 ELSE BEGIN
  calimg = GET_CALIMG(hdr,fn,_EXTRA=ex)
  IF (size(calimg))(0) GT 1 THEN BEGIN
    hdr = SCC_UPDATE_HISTORY(hdr,'Applied Vignetting '+fn)
  ENDIF
ENDELSE

;--Background subtraction (ON)
if keyword_set(bkgimg_off) then bkgimg=0 else begin
    bkgimg = scc_getbkgimg(hdr, outhdr=bkghdr, match=0, _extra=ex)
    if n_elements(bkghdr) eq 1 then begin
        if hdr.ccdsum ne bkghdr.ccdsum then begin
            if ~keyword_set(SILENT) then message, /info, $
              "CCDSUM values don't agree - not subtracting background"
            bkgimg = 0
        endif
    endif
    if n_elements(bkgimg) gt 1 then begin
        sumdif=hdr.ipsum - bkghdr.ipsum
        IF sumdif NE 0 THEN bkgimg=temporary(bkgimg)*4^(sumdif)
        if keyword_set(exptime_off) then bkgimg = $
          temporary(bkgimg) * get_exptime(hdr, _extra=ex)
        hdr = scc_update_history(hdr, 'Background subtracted')
    endif
endelse



;--Apply Photometric Calibration - DN to MSB
IF keyword_set(calfac_off) THEN calfac=1.0 ELSE BEGIN
  calfac = GET_CALFAC(hdr,_EXTRA=ex)
  IF calfac NE 1.0 THEN BEGIN
    hdr = SCC_UPDATE_HISTORY(hdr,'Applied Calibration Factor',value=calfac)
    IF ~keyword_set(SILENT) THEN message,'Applied Calibration Factor '+trim(calfac),/info
  ENDIF
ENDELSE 

;----------------------------------------------------------------------
;--Apply Calibration
biasmean = biasmean[0]
if biasmean ne 0 then im = temporary(im) - biasmean
exptime = exptime[0]
if exptime ne 1 then im = temporary(im) / exptime
if n_elements(bkgimg) gt 1 then im = temporary(im) - bkgimg
if n_elements(calimg) gt 1 then im = temporary(im) / calimg

;--Apply cosmic correction after background subtraction
if keyword_set(discri_pobj_on) then begin
    if n_elements(discri_pobj_on) eq 2 then $
        im=discri_pobj(im,thres=discri_pobj_on[0],bias=discri_pobj_on[1]) else $
	im=discri_pobj(im,thres=0.1,bias=800.)
endif


calfac = calfac[0]
if calfac ne 1 then im = temporary(im) * calfac

;----------------------------------------------------------------------

;  Flag missing pixels

if (nmissing gt 0) and (not keyword_set(nan_off)) then $
  flag_missing, im, wmissing

RETURN,im
END

