FUNCTION GET_SUN_CENTER, hdr, source, STAR=star, MEDIAN=median, AVG=avg, FULL=full, $ RAW=raw, NOCHECK=nocheck,DOCHECK=docheck, DEGREES=degrees, ROLL=roll, $ NO_OCCULTER=no_occulter, _EXTRA=_extra, SILENT=silent ;+ ; $Id: get_sun_center.pro,v 1.25 2012/02/01 16:26:51 nathan Exp $ ; NAME: ; GET_SUN_CENTER ; ; PURPOSE: ; This function returns a 2 element array of the column and row ; numbers as the sun center, and optionally roll in a keyword. ; ; This routine returns value in IDL coords (starts at 0). ; ; The value of sun center and roll is computed for each LASCO image using ; corrected EIT-corrected time values and star locations. Then a median filter is applied to ; to give the value which is returned by get_roll_or_xy.pro. If the particular image ; is not found but lies between images, a linear interpolation is done to approximate. ; If the star-location procedure has not been done yet, then an approximate value is returned ; based on recent trends. ; ; ; CATEGORY: ; LASCO_ANALYSIS ; ; CALLING SEQUENCE: ; Result = GET_SUN_CENTER (Hdr) ; ; INPUTS: ; Hdr: A LASCO, EIT or SECCHI header structure for the image that the center is desired ; (Should be compatable, but not tested with other instruments.) ; ; OPTIONAL INPUTS: ; /Star, /MEDIAN, /AVG: obsolete ; FULL=FULL: Assuming in subfield is placed in a FFV square array, this is the size of the ; FFV which corresponds to the original header. Ex: ; Original image was not binned: ; Result = GET_SUN_CENTER (Hdr, FULL=1024) ; Original image was binned: ; Result = GET_SUN_CENTER (Hdr, FULL=512) ; RAW: If set, no corrections are applied ; DOCHECK: If set, corrected header is read in ; NOCHECK: If set, input header is used ; DEGREES: Value returned in ROLL keyword is in degrees, else is radians. ; /NO_OCCULTER: If no star center found, return 0 ; /SILENT Less messages ; ; OUTPUTS: ; This function returns the sun center for UNRECTIFIED image ; as a two element array in which ; the first element is the column center and the second element is the ; row center starting at 0 (IDL coords). ; ; OPTIONAL OUTPUT: ; ROLL=named_var Named_var will contain CW roll value ; ; OPTIONAL IO: ; source: On output, returns one of the following sources used to ; get the sun center: STAR, AVG, MEDIAN, OCC. ; ; ; CALLED PROGRAMS: ; GET_ROLL_OR_XY ; ; RESTRICTIONS: ; Returns the center for the readout port "C" ; ; PROCEDURE: ; Returns values that have been determined by other means and put ; into a table here. ; ; MODIFICATION HISTORY: ; Written by: S.E. Paswaters, 30 August 1996 ; $Log: get_sun_center.pro,v $ ; Revision 1.25 2012/02/01 16:26:51 nathan ; check for cdelt1 in shdr ; ; Revision 1.24 2012/01/27 16:31:01 savani ; nr - fix case where cdelt1 eq 0 ; ; Revision 1.23 2012-01-19 18:58:47 nathan ; undid previous change because giving incorrect result for rectified images ; ; Revision 1.22 2011/09/16 13:29:08 dennison ; Bug fix for lasco level-1 images ; ; Revision 1.21 2011-05-13 20:18:58 nathan ; skip docheck because it does nothing ; ; Revision 1.20 2011/04/25 21:37:50 nathan ; add /silent ; ; Revision 1.19 2011/01/05 17:33:12 nathan ; blank time_obs if already in date_obs ; ; Revision 1.18 2010/12/23 16:01:56 nathan ; add /silent to fitshead2struct call to get around more bug ; ; Revision 1.17 2010/12/22 23:39:18 nathan ; handle SECCHI headers; make sure values in hdr are not already correct ; ; Revision 1.16 2010/11/17 23:44:26 nathan ; check for sector in eit header ; ; Revision 1.15 2010/11/09 15:29:22 nathan ; update source output ; ; Revision 1.14 2010/11/01 21:05:16 nathan ; added /SILENT ; ; Revision 1.13 2010/11/01 21:03:56 nathan ; added more /SILENT tests; fix doc; add _EXTRA ; ; Revision 1.12 2010/10/04 16:13:59 nathan ; fix in_timerange check for c1 ; ; Revision 1.11 2010/09/15 21:56:06 nathan ; use estimated values instead of occulter center; use eit_point; allow vector input ; ; Revision 1.10 2010/09/13 18:10:11 nathan ; use cvs for version ; ; Revision 1.9 2010/08/20 13:15:09 mcnutt ; change reduce_history common block to match reduce_level_1 ; ; Revision 1.8 2010/08/17 15:50:21 nathan ; use FULL= to define nxfac; add /NO_OCCULTER ; ; Revision 1.7 2010/03/23 21:11:11 nathan ; do not try to get header if filename not found in /docheck case ; ; Revision 1.6 2010/03/16 18:26:52 mcnutt ; removed last revision ; ; Revision 1.4 2010/02/11 20:59:41 nathan ; fix bug when input is strarr ; ; Revision 1.3 2010/02/08 22:25:24 nathan ; Recomputed occulter center for C1 Fe XIV using find_chord_ctr.pro ; ; Revision 1.2 2010/02/01 22:37:37 nathan ; properly account for binning if occltr_cntr is used; fix how FULL keyword works ; ; Revision 1.1 2008/04/14 16:38:38 nathan ; moved from lasco/idl/data_anal ; ; Updated: ; 96/10/04 SEP Changed FULL to allow different sizes. ; ; 97/01/08 SHH Added correction for cropped images. ; 97/02/11 RAH Added keyword to return raw center ; 97/12/16 SEP updated check for EIT date_obs ; 98/08/24 RAH added capability to handle MLO/MK3 images ; 98/08/26 DW fixed problem ; 98/10/06 AEE Added code to use time files for getting ; the sun center, first. A returned center ; of {0.0,0.0} from get_roll_or_xy means ; center info for the image was not in a ; time file and, so, occ_cen_arr is used, ; as before. ; 98/10/26 AEE Added AVG keyword and made it default. ; It still uses occ_cen_arr if zero is ; returned by get_roll_or_xy. ; 98/11/05 AEE Corrected nocheck and added docheck ; 98/11/12 RAH Changed MLO/MK3 cam to be MK3 ; 98/11/13 AEE Corrected docheck. Assign all of complete ; hdr to shdr. ; 98/12/01 AEE changed call to read_occ_dat to ; occltr_cntr. ; 98/12/11 AEE now returns the source used for sun ; center (STAR,MEDIAN,AVG,OCC) as an ; optional parameter. ; 99/05/14 NBR Change name of sun_cen stucture for MK3 ; 99/06/22 NBR Make factor floating point for /FULL ; 00/01/14 DAB Added MK4 telescope ; 01/01/08 NBR Do not correct for subfield if keyword FULL is set ; 04.04.01, nbr - add COMMON reduce_history ; 06.04.25, nbr - Add ROLL and DEGREES keywords ; 09/16/11, Hillary/Karl Removed If statement for LASCO level-1 images ; version= '$Id: get_sun_center.pro,v 1.25 2012/02/01 16:26:51 nathan Exp $' ; SECCHI IDL LIBRARY ; ; ;- COMMON GET_SUN_CENTER_COMMON, occ_cen_arr COMMON reduce_history, cmnver, prev_a, prev_hdr, zblocks0 len=strlen(version) cmnver = strmid(version,1,len-2) IF (DATATYPE(hdr) NE 'STC') THEN BEGIN tel = STRUPCASE(STRTRIM(FXPAR(hdr,'TELESCOP'),2)) IF (tel EQ 'MK3') OR (tel EQ 'MK4') THEN shdr=MLO_FITSHDR2STRUCT(hdr) ELSE shdr=fitshead2struct(hdr,/dash2underscore,/silent) ENDIF ELSE shdr = hdr ;--Handle SECCHI header or Level-1+ LASCO/EIT header IF (tag_exist(shdr,'cdelt1')) THEN IF shdr.INSTRUME EQ 'SECCHI' or $ (fix(strmid(shdr.filename,1,1)) GT 3 and shdr.cdelt1 GT 0) THEN BEGIN sun_cen=scc_sun_center(shdr,FULL=full) IF tag_exist(shdr,'CROTA1') THEN roll=shdr.crota1 ELSE roll=shdr.crota IF not keyword_set(DEGREES) THEN roll=roll*!pi/180. return,sun_cen ENDIF ;--Fix date_obs, time_obs IF strlen(shdr[0].date_obs) GT 12 THEN shdr.time_obs='' IF keyword_set(FULL) THEN BEGIN nxfac=1024/full nyfac=nxfac ENDIF ELSE BEGIN sumrow = shdr.SUMROW > 1 sumcol = shdr.SUMCOL > 1 lebxsum = shdr.LEBXSUM > 1 lebysum = shdr.LEBYSUM > 1 nxfac = 2^(sumcol+lebxsum-2) ; If image is binned, nxsum = 2 nyfac = 2^(sumrow+lebysum-2) ; If image is summed, assume size is halved. ENDELSE nh=n_elements(shdr) sun_cen = make_array(nh,value={sun_center,xcen:0.,ycen:0.}) ; cam = ['C1','C2','C3','EIT','MK3','MK4'] ismk = WHERE(strmid(shdr.detector,0,2) EQ 'MK',nmk,COMPLEMENT=notmk, NCOMPLEMENT=nnotmk) ;tele = tele(0) IF (nmk GT 0) THEN BEGIN ; MLO sun_cen[ismk].xcen = shdr[ismk].crpix1-1 sun_cen[ismk].ycen = shdr[ismk].crpix2-1 ;RETURN,sun_cen ENDIF IF nnotmk GT 0 THEN sun_cen[notmk]= get_roll_or_xy(shdr[notmk],'CENTER',source, ROLL=roll,DEGREES=degrees, SILENT=silent, _EXTRA=_extra) ; ## /STAR,/MEDIAN,/AVG are obsolete -- nbr,06.04.25 ; IF(KEYWORD_SET(STAR)) THEN BEGIN ; sun_cen= get_roll_or_xy(hdr,'CENTER',source,/STAR) ; ENDIF ELSE BEGIN ; IF(KEYWORD_SET(MEDIAN)) THEN $ ; sun_cen= get_roll_or_xy(hdr,'CENTER',source,/MEDIAN) $ ; ELSE $ ; sun_cen= get_roll_or_xy(hdr,'CENTER',source,/AVG) ; ENDELSE ; ; Check to see if valid sun_center was returned and if not then ; force to be calculated from offset from the occulter center ; isc1z = WHERE(shdr.detector EQ 'C1',nc1) isc2z = WHERE(shdr.detector EQ 'C2' and (sun_cen.xcen eq 0.0 AND sun_cen.ycen eq 0.0),nc2) isc3z = WHERE(shdr.detector EQ 'C3' and (sun_cen.xcen eq 0.0 AND sun_cen.ycen eq 0.0),nc3) iseiz = WHERE(shdr.detector EQ 'EIT' and (sun_cen.xcen eq 0.0 AND sun_cen.ycen eq 0.0),nei) IF keyword_set(NO_OCCULTER) THEN return,sun_cen ; CRPIX values in C1 headers are mostly incorrect IF nc1 GT 0 THEN BEGIN ;-- 2/5/10, nr - Recomputed occulter center for C1 Fe XIV using find_chord_ctr.pro sun_cen[isc1z].xcen = 510.0 ; instead of 510.4 sun_cen[isc1z].ycen = 492.9 ; instead of 495.5 altc1=where(ssw_in_timerange(shdr[isc1z].date_obs+' '+shdr[isc1z].time_obs,'1996/08/08 04:30','1996/08/09 11:10'),nalt) IF nalt gt 1 then begin sun_cen[ISC1Z[ALTC1]].xcen = 510.8 sun_cen[ISC1Z[ALTC1]].ycen = 492.2 ENDIF source=source+' and suncenter estimate' ENDIF IF nc2 GT 0 THEN BEGIN source=source+' and suncenter estimate' IF ~keyword_set(SILENT) THEN print,'Estimating C2 center based on history after 2005.' sun_cen[isc2z].xcen=510.2 ; occulter is 512.63 sun_cen[isc2z].ycen=506.5 ; occulter is 505.29 ENDIF IF nc3 GT 0 THEN BEGIN source=source+' and suncenter estimate' IF ~keyword_set(SILENT) THEN print,'Estimating C3 center based on history after July 2009.' sun_cen[isc3z].xcen=518.2 ; occltr_cntr is 516.46 sun_cen[isc3z].ycen=532.5 ; occltr_cntr is 531.13 ENDIF ;;** We know that for C3 Sun Center is 1.5 pixels west and 1.5 pixels north ;; of occulter center ;IF (tele EQ 2) THEN BEGIN ; sun_cen.xcen = sun_cen.xcen + 1.5 ; sun_cen.ycen = sun_cen.ycen + 1.5 ;ENDIF IF nei GT 0 THEN BEGIN eitimes=shdr[iseiz].date_obs + ' ' + shdr[iseiz].time_obs otai = UTC2TAI(STR2UTC('1996/04/16 23:13')) IF tag_exist(shdr[0],'sector') THEN sectors=shdr.sector ELSE sectors=shdr.wavelnth FOR i=0,nei-1 DO BEGIN cen=eit_point(eitimes[i],sectors[iseiz[i]]) sun_cen[iseiz[i]].xcen=cen[0] sun_cen[iseiz[i]].ycen=cen[1] tai = UTC2TAI(STR2UTC(eitimes[i])) ;** check if image was prior to S/C 3.3 arcmin offset repointing IF (tai LT otai) THEN sun_cen[iseiz[i]].ycen = 588.7 ENDFOR source=source+' and eit_point.pro' ENDIF ; sun_cen is now for ffv 1024x1024 IF KEYWORD_SET(RAW) THEN RETURN,sun_cen goto, skipcheck IF KEYWORD_SET(DOCHECK) THEN FOR i=0,nh-1 DO BEGIN ;** get complete header for file date=shdr[i].date_obs year=FIX(strmid(date,2,2)) mon=FIX(strmid(date,5,2)) day=FIX(strmid(date,8,2)) IF (STRMID(shdr.filename,1,1) eq '2') THEN dir=LZ_GETLASCODIR(mon,day,year,STRLOWCASE(shdr[i].detector)) $ ELSE dir=QL_GETLASCODIR(mon,day,year,STRLOWCASE(shdr[i].detector)) filename=STRCOMPRESS(dir+shdr[i].filename,/REMOVE_ALL) ; Check to make sure file is not a QL image that is not there any more OPENR, LU, filename, /GET_LUN, ERR=err filename0=filename IF (ERR NE 0) THEN BEGIN ; QL image is not there IF ~keyword_set(SILENT) THEN MESSAGE, 'Using corresponding lz image.', /INFORMATIONAL filename = LZ_FROM_QL(HDR = shdr) ; this returns 'none' if not found filename = path + filename filename = filename(0) ENDIF CLOSE, LU FREE_LUN, LU help,filename IF filename NE 'none' THEN BEGIN complete_hdr=headfits(filename) shdr[i]=LASCO_FITSHDR2STRUCT(complete_hdr) ENDIF ELSE $ IF ~keyword_set(SILENT) THEN message,'WARNING: No matching image found for '+filename0+'; header unchanged',/info ; shdr.r1col = fxpar(complete_hdr,'R1COL') ; shdr.r1row = fxpar(complete_hdr,'R1ROW') ENDFOR skipcheck: IF KEYWORD_SET(FULL) THEN BEGIN ;** subfield has been placed in FFV and rebind to FULLxFULL ; factor = (1024/float(full)) ; factor = 1 or 2 or 4 sun_cen.xcen = sun_cen.xcen/factor sun_cen.ycen = sun_cen.ycen/factor RETURN, sun_cen ENDIF ELSE BEGIN ;** apply correction for read out coordinates / cropping of image sun_cen.xcen = sun_cen.xcen - (shdr.r1col - 20) sun_cen.ycen = sun_cen.ycen - (shdr.r1row - 1) ENDELSE ;** apply correction for on chip summing ;** and LEB summing sun_cen.xcen = sun_cen.xcen / nxfac sun_cen.ycen = sun_cen.ycen / nyfac RETURN, sun_cen END