C+ C NAME: C smei_frm_read C PURPOSE: C Read SMEI frame C CATEGORY: C I/O C CALLING SEQUENCE: logical function smei_frm_read(iAct0,cFile,N,nX,nY,nB,Img,hdr,headroom) C INPUTS: C iAct0 integer open code passed to href=bOpenFile= C Usually set to zero. If cFile is known C to exist (e.g. a return value from C href=iSearch=) then file access can be C made more efficient by using the value C OPN__REOPEN (defined in openfile.h). C cFile character*(*) file name. If no explicit directory C is specified then the SMEI databases C are tried, first SMEIDC, then SMEIDB. C N integer size of Img C OUTPUTS: C smei_frm_read logical .TRUE. : success C .FALSE.: failure C nX integer horizontal size of image C nY integer vertical size of image C nB integer # bytes per number on input file C 2 for integer*2 C 4 for integer*4 C -4 for real*4 C Img(nX*nY) real image data C (the image read from file divided by the C the headroom) C hdr(*) double precision C array with frame header entries C headroom real headroom (1.0 or 0.75) C CALLS: C bReadNic, NicHdr, iSetFileSpec, iGetFileSpec, say_fts C smei_frm_path, iGetLun, iFreeLun, ArrR4TimesConstant C FTNOPN, FTCLOS, FTGPVE, FTGKYJ, FTGISZ, FTGKYS, FTGKYD, FTGKND C smei_Time2Split, Time2Str, ArrR8Zero, Say, smei_hdr_time C smei_frm_c3mask_active C SEE ALSO: C bWriteNic, bWriteFrm C RESTRICTIONS: C Reading of *.gz files depends on availability of gzip C (windows) or gunzip (Linux). C INCLUDE: include 'filparts.h' include 'smei_frm_layout.h' include 'smei_frm_hdr.h' include 'ftspar.h' C PROCEDURE: C See bReadNic C MODIFICATION HISTORY: C JUN-2004, Paul Hick (UCSD/CASS) C JUN-2005, Paul Hick (UCSD/CASS) C Added check for presence of VERSION keyword in header. In C early Fits files produced by IDL this keyword was not present. C AUG-2005, Paul Hick (UCSD/CASS) C Fixed bug that affected the factor two compensation applied to C correct for the onboard gain change in Feb 2005 for cam 2, mode 1. C The frame time was not picked up correctly from the header. C APR-2006, Paul Hick (UCSD/CASS) C If no directory is specifed in cFile, first SMEIDC, then SMEIDB C is tried (only SMEIDB was checked before). C JUN-2007, Paul Hick (UCSD/CASS; pphick@ucsd.edu) C Bug fixes. For time periods with a "bad pixel" mask onboard C (smei_frm_c3mask_active(0,ctime,-1,cmask)=1) C two errors were made: C - For camera 3, mode 1, the gain change of a factor two was C not applied to frames with the flat_enabled flag off (zero) C In smei_base this would have failed all frames. C In smei_cal this would have had no effect (the mask setting C is not used when mode=0 and flat_enabled=0 as is the case C for the weekly calibration data). C In smei_orb the orbital pattern would have been wrong when C flat_enabled=0. This occurs the first time after 2007_133, C but this has not yet been run through smei_orb at this time. C In smei_skyd the skyamp would have been wrong also if C flat_enabled=0, i.e after 2007_133, but these data have not C been run yet. C - For cameras 1 and 2 the headroom 0.75 was not corrected for C if flat_enabled=1. C In smei_base this would have resulted in a pedestal and C and dark current of 0.75 the correct value. C In smei_base this would have had no effect (since always C flat_enabled=0 for the weekly calibration data) C smei_orb is never run for cameras 1 and 2. C In smei_skyd the resulting skymap would be too low by C about 0.75 if the same error was made in smei_base. However, C if the pedestal and dark current were calculate with C a smei_base version < 4.00, then the error would not be C a simple scaling. C- integer iAct0 character cFile*(*) integer N integer nX integer nY integer nB real Img(*) double precision hdr(*) real headroom character cSay*8 /'frm_read'/ character cSeverity /'E'/ character cTrailer *512 character cStr *(FIL__LENGTH) character cFileOne *(FIL__LENGTH) character cFileTwo *(FIL__LENGTH) character cType *7 character cTypeDef *7 /'.fts.gz'/ integer smei_frm_path integer Time2Str integer smei_frm_c3mask_active logical bReadNic logical smei_frm_read_set_sdark logical smei_frm_read_get_sdark real PixFix(0:2) /0.0,2.0,1.333/ logical anyf integer nAxes(2) integer tt(2) integer flat_enabled integer camera character ctime*(SMEI__UT_FORMAT_LEN) character cmask*(SMEI__UT_FORMAT_LEN) integer idark ! Input : smei_frm_read_set_sdark ! Output: smei_frm_read_get_sdark integer sdark /-1/ save sdark ! Store input file name cFile k = iSetFileSpec(cFile) ! Check for presence of directory specification ! Store directory in cFileOne i = iGetFileSpec(0,FIL__DIRECTORY,cFileOne) j = iGetFileSpec(0,FIL__DIRECTORY,cFileTwo) if (i*j .eq. 0) then ! No directory, use SMEIDC or SMEIDB ! No directory specified ! Set up two directories: one for SMEIDC, the other for SMEIDB i = smei_frm_path(.TRUE., cFile, tt, icam, 'SMEIDC?', cFileOne) j = smei_frm_path(.TRUE., cFile, tt, icam, 'SMEIDB?', cFileTwo) end if ! Append the file name to directory specification k = iSetFileSpec(cFile) ! This is NOT redundant !!! i = i+iGetFileSpec(FIL__NAME,0,cFileOne(i+1:)) j = j+iGetFileSpec(FIL__NAME,0,cFileTwo(j+1:)) ! Append default file type if necessary k = iGetFileSpec(FIL__TYPE,FIL__TYPE,cType) if (k .eq. 1) then ! Only a dot cType = cTypeDef cFileOne(i:) = cTypeDef cFileTwo(i:) = cTypeDef end if if (cType(:4) .eq. '.nic') then smei_frm_read = bReadNic(iAct0, cFileOne, N, nX, nY, nB, Img, cTrailer) if (smei_frm_read) then call NicHdr(1,hdr,cTrailer(4:)) ! Skip leading 'buf' if (nint(hdr(SMEI__HDR_FULL_FRAME)) .eq. 0 .or. & nint(hdr(SMEI__HDR_NAXES )) .eq. 0 .or. & nint(hdr(SMEI__HDR_NAXES+1 )) .eq. 0) then i = iSetFileSpec(cFileOne) i = iGetFileSpec(FIL__NAME,FIL__NAME,cStr) call Say(cSay,'W',cStr,'fixed frame size entries') hdr(SMEI__HDR_FULL_FRAME) = 1d0 hdr(SMEI__HDR_NAXES ) = dble(nX) hdr(SMEI__HDR_NAXES+1 ) = dble(nY) hdr(SMEI__HDR_N_DATA ) = dble(nX*nY) end if cFile = cFileOne end if else call ArrR8Zero(SMEI__HDR_N,hdr) ! Should be unnecessary istat = 0 ! First try cFileOne. This is either the file name specified ! in input argument cFile (if it contained a directory), ! or a file name pointing to SMEIDC (if cFile did not contain ! a directory. iU = iGetLun(cFileOne) call FTNOPN(iU, cFileOne, FTS__READONLY, istat) if (istat .ne. 0) then ! If cFileOne = cFileTwo then the input cFile contained ! a directory. If open failed, stop. if (cFileOne .eq. cFileTwo) call say_fts(cSay,cSeverity,istat) istat = 0 ! Reinitialize ! cFileTwo is the same file name, but now in SMEIDB ! Try to open it. If this fails too, stop. iU = iGetLun(cFileTwo) call FTNOPN(iU, cFileTwo, FTS__READONLY, istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) cFileOne = cFileTwo ! Successfully opened file on SMEIDB end if call FTGKYJ(iU, 'BITPIX' , i, cStr,istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) hdr(SMEI__HDR_BITPIX) = dble(i) nB = i/8 call FTGISZ(iU, 2, nAxes, istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) hdr(SMEI__HDR_NAXES ) = dble(nAxes(1)) hdr(SMEI__HDR_NAXES+1) = dble(nAxes(2)) call FTGKYJ(iU, 'BZERO', izero, cStr, istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) call FTGKYJ(iU, 'FRAME_NR', i, cStr,istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) hdr(SMEI__HDR_FRAME_NR) = dble(i) call FTGKYJ(iU, 'CAMERA' , i, cStr,istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) hdr(SMEI__HDR_CAMERA) = dble(i) call FTGKYJ(iU, 'ROI_MAP' , i, cStr,istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) hdr(SMEI__HDR_ROI_MAP) = dble(i) call FTGKYJ(iU, 'MODE' , i, cStr,istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) hdr(SMEI__HDR_MODE) = dble(i) call FTGKYJ(iU, 'N_DATA' , i, cStr,istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) hdr(SMEI__HDR_N_DATA) = dble(i) call FTGKYS(iU, 'TIME', cTrailer, cStr,istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) call smei_Time2Split(2,cTrailer,tt) hdr(SMEI__HDR_TIME ) = dble(tt(1)) hdr(SMEI__HDR_TIME+1) = dble(tt(2)) call FTGKYJ(iU, 'EXPOSURE', i, cStr,istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) hdr(SMEI__HDR_EXPOSURE) = dble(i) call FTGKYD(iU, 'RA' , hdr(SMEI__HDR_RA ), cStr,istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) call FTGKYD(iU, 'DEC' , hdr(SMEI__HDR_DEC ), cStr,istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) call FTGKYD(iU, 'ANGLE', hdr(SMEI__HDR_ANGLE), cStr,istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) call FTGKND(iU, 'QUAT' , 1, 4, hdr(SMEI__HDR_QUAT ), i, istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) call FTGKND(iU, 'RQUAT', 1, 4, hdr(SMEI__HDR_RQUAT), i, istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) call FTGKND(iU, 'SUN' , 1, 3, hdr(SMEI__HDR_SUN), i, istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) call FTGKND(iU, 'MOON' , 1, 3, hdr(SMEI__HDR_MOON), i, istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) call FTGKND(iU, 'VENUS', 1, 3, hdr(SMEI__HDR_VENUS), i, istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) call FTGKYJ(iU, 'OBS_FRAM', i, cStr,istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) hdr(SMEI__HDR_OBS_FRAME) = dble(i) call FTGKYJ(iU, 'BOS_CHAN', i, cStr,istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) hdr(SMEI__HDR_BOS_CHANGE) = dble(i) call FTGKYJ(iU, 'FIXED_BI', i, cStr,istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) hdr(SMEI__HDR_FIXED_BITS) = dble(i) call FTGKYJ(iU, 'CORRUPT_', i, cStr,istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) hdr(SMEI__HDR_CORRUPT_PIX) = dble(i) call FTGKYJ(iU, 'CR_HITS', i, cStr,istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) hdr(SMEI__HDR_CR_HITS) = dble(i) call FTGKYD(iU, 'ATTITUDE', hdr(SMEI__HDR_ATTITUDE_DT), cStr,istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) call FTGKYD(iU, 'CCD_TEMP', hdr(SMEI__HDR_CCD_TEMP), cStr,istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) call FTGKYD(iU, 'BAD_DATA', hdr(SMEI__HDR_BAD_DATA), cStr,istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) call FTGKYJ(iU, 'FLAGS', i, cStr,istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) call smei_hdr_flag(0,i,hdr) ! Fill all flags in hdr call FTGKYD(iU, 'PEDESTAL', hdr(SMEI__HDR_PEDESTAL), cStr,istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) if (sdark .eq. -1) then call FTGKYD(iU, 'DARK_CUR', hdr(SMEI__HDR_DARK_MEDIAN), cStr,istat) else write (cStr(:3),'(I3.3)') sdark call FTGKYD(iU, 'SDARK'//cStr(:3), hdr(SMEI__HDR_DARK_MEDIAN), cStr,istat) end if if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) call FTGKYD(iU, 'DARK_AVE', hdr(SMEI__HDR_DARK_MEAN), cStr,istat) if (istat .ne. 0) then hdr(SMEI__HDR_DARK_MEAN) = hdr(SMEI__HDR_BAD_DATA) istat = 0 end if call FTGKYD(iU, 'PED_SIGM', hdr(SMEI__HDR_PED_SIGMA), cStr,istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) call FTGKYD(iU, 'DARK_SIG', hdr(SMEI__HDR_DARK_SIGMA), cStr,istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) call FTGKYD(iU, 'SQUARE' , hdr(SMEI__HDR_SQUARE), cStr,istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) call FTGKYD(iU, 'CENTER' , hdr(SMEI__HDR_CENTER), cStr,istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) call FTGKYJ(iU, 'N_PEDEST', i, cStr,istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) hdr(SMEI__HDR_N_PEDESTAL) = dble(i) call FTGKYJ(iU, 'N_DARK_C', i, cStr,istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) hdr(SMEI__HDR_N_DARK_CURRENT) = dble(i) call FTGKYJ(iU, 'N_SATURA', i, cStr,istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) hdr(SMEI__HDR_N_SATURATED) = dble(i) call FTGKYJ(iU, 'N_POS_ME', i, cStr,istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) hdr(SMEI__HDR_N_POS_MEASLES) = dble(i) call FTGKYJ(iU, 'N_BIG_ME', i, cStr,istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) hdr(SMEI__HDR_N_BIG_MEASLES) = dble(i) call FTGKYJ(iU, 'N_PIXSUM', i, cStr,istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) hdr(SMEI__HDR_N_PIXSUM) = dble(i) call FTGKYJ(iU, 'N_PIXDIF', i, cStr,istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) hdr(SMEI__HDR_N_PIXDIF) = dble(i) call FTGKYD(iU, 'PIXSUM', hdr(SMEI__HDR_PIXSUM), cStr,istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) call FTGKYD(iU, 'PIXDIF', hdr(SMEI__HDR_PIXDIF), cStr,istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) call FTGKYS(iU, 'CAL_PATT', cTrailer, cStr, istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) call smei_hdr_str(-SMEI__HDR_CAL_PATTERN, hdr, cTrailer) call FTGKYS(iU, 'ORB_PATT', cTrailer, cStr, istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) call smei_hdr_str(-SMEI__HDR_ORB_PATTERN, hdr, cTrailer) call FTGKYD(iU, 'VERSION', hdr(SMEI__HDR_VERSION), cStr,istat) if (istat .eq. 202) then ! Version was not present initially hdr(SMEI__HDR_VERSION) = -1d0 istat = 0 end if if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) call FTGKYS(iU, 'TLM_FILE', cTrailer, cStr, istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) call smei_hdr_str(-SMEI__HDR_TLM_FILE, hdr, cTrailer) call FTGKYS(iU, 'L1A_FILE', cTrailer, cStr, istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) call smei_hdr_str(-SMEI__HDR_L1A_FILE, hdr, cTrailer) call FTGKYJ(iU, 'L1A_PNTR', i, cStr,istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) hdr(SMEI__HDR_L1A_PNTR) = dble(i) anyf = .FALSE. call FTGPVE(iU, 1, 1, nAxes(1)*nAxes(2), 0, Img, anyf, istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) call FTCLOS(iU, istat) if (istat .ne. 0) call say_fts(cSay,cSeverity,istat) iU = iFreeLun(iU) nX = nAxes(1) nY = nAxes(2) smei_frm_read = .TRUE. end if if (smei_frm_read) then call smei_hdr_time(hdr,tt) i = Time2Str(SMEI__UT_FORMAT,tt,ctime) flat_enabled = nint(hdr(SMEI__HDR_FLAT_ENABLED)) camera = nint(hdr(SMEI__HDR_CAMERA )) mode = nint(hdr(SMEI__HDR_MODE )) ! "Bad-pixel" mask is used ONLY for camera 3 if (camera .eq. 3) then MaskActive = smei_frm_c3mask_active(0,ctime,flat_enabled,cmask,fudge) else MaskActive = 0 end if ! Make various adjustments to CCD readout. headroom = 1.0 if (flat_enabled .eq. 1) then nbin = 2**mode jleft = (SMEI__FRM_LEFT -1)/nbin+1 jright = SMEI__FRM_RIGHT /nbin fix = PixFix(mode) do i=1,nY do j=jleft,jright,jright-jleft k = (i-1)*nX+j Img(k) = fix*Img(k) end do end do ! If the onboard flat field is enabled then the frame is ! multiplied by 0.75 onboard, BUT ... ! the factor 0.75 is NOT applied when a c3 "bad pixel" ! mask is active. ! (Note that for cameras 1 and 2 always MaskActive=0) if (MaskActive .eq. 0) then ! "Bad pixel" mask NOT active headroom = SMEI__HEADROOM do k=1,nX*nY Img(k) = Img(k)/headroom end do else if (camera .eq. 3 .and. mode .eq. 0) then call ArrR4TimesConstant(nX*nY,Img,2.0,Img) end if end if else ! flat_enabled = 0 ! During this time the cameras were in science mode ! For one orbit the flat field was off for camera 1 and 2 ! and on for camera 3. if ('2003_353_140000' .lt. ctime .and. ctime .lt. '2003_353_170000') then call Say(cSay,'W',ctime,'anomalous headroom application?') headroom = SMEI__HEADROOM do k=1,nX*nY Img(k) = Img(k)/headroom end do end if end if ! For camera 3 in mode 1 the gain increases by a factor 2 after ! 24 Feb 2005, 17:30 UT. ! Multiply by 0.5 here to compensate for this, BUT ... ! ... NOT when the c3 "bad pixel" mask is active. if (camera .eq. 3 .and. mode .eq. 1) then if (MaskActive .eq. 0) then if (ctime .gt. SMEI__UT_C3_GAIN_CHANGE) call ArrR4TimesConstant(nX*nY,Img,0.5,Img) end if end if end if return C+ C NAME: C smei_frm_read_set_dark C CALLING SEQUENCE: entry smei_frm_read_set_sdark(idark) C- sdark = idark if (sdark .ne. -1) then write (cStr(:3),'(I3.3)') sdark call Say(cSay//'_set_sdark','W','SDARK'//cStr(:3),'dark current keyword') end if smei_frm_read_set_sdark = sdark .eq. -1 .or. sdark .eq. 3 .or. sdark .eq. 10 return C+ C NAME: C smei_frm_read_get_sdark C CALLING SEQUENCE: entry smei_frm_read_get_sdark(idark) C- idark = sdark smei_frm_read_get_sdark = sdark .eq. -1 .or. sdark .eq. 3 .or. sdark .eq. 10 return end