function secchi_rectify,a,scch,hdr=hdr, NOMODIFY=nomodify, NOROTATE=norotate,silent=silent ;+ ; NAME: SECCHI_RECTIFY ; PURPOSE: ; function procedure to rectify the CCD image, put solar north to the top of the image ; ; CATEGORY: ; CALLING SEQUENCE: x = SECCHI_RECTIFY (a,h) ; ; INPUTS: a = input image ; scch = structure header ; ; KEYWORDs: hdr = STRARR FITS header ; /NOMODIFY Leave input scch unchanged; default is to update ; /NOROTATE Do not apply rotation to image. (Set RECTROTA keyword only.) ; ; OUTPUTS: x = rectified image ; hdr = fits header will be modified to reflect the rectification ; ; OPTIONAL OUTPUT PARAMETERS: HDR ; COMMON BLOCKS: ; SIDE EFFECTS: Modify input header structure by default. ; RESTRICTIONS: ; PROCEDURE: ; Rotates an image so that ecliptic north is up and modifies coordinate ; keywords accordingly. ; ; ; Written :Lynn McNutt modified LASCO reduce_rectify.pro ; ; Modified : ; ; $Log: secchi_rectify.pro,v $ ; Revision 1.29 2023/08/14 17:50:07 secchia ; added Bills correction for post_conj dates ; ; Revision 1.28 2015/07/13 18:45:50 secchia ; correct EUVI rcols and rrows ; ; Revision 1.27 2015/07/01 18:49:06 mcnutt ; corrected EUVI crpix ; ; Revision 1.26 2015/06/24 17:13:08 hutting ; added missing endif ; ; Revision 1.25 2015/06/22 20:06:04 hutting ; added 180 deg to rotate if post_conjunction ; ; Revision 1.24 2014/12/10 18:07:39 hutting ; removed last versions changes 1.23 ; ; Revision 1.23 2013/10/28 17:05:41 nathan ; fix dstop logic for all telescopes ; ; Revision 1.22 2009/12/14 18:49:22 nathan ; no change in accidental commit ; ; Revision 1.21 2008/07/14 18:34:16 nathan ; added filename to message ; ; Revision 1.20 2007/11/27 15:58:06 mcnutt ; Bug 255 commented out lines to subtract 1 from dstop(12) ; ; Revision 1.19 2007/11/07 17:56:09 nathan ; corrected dstart/stop for binned images (Bug 255) ; ; Revision 1.18 2007/11/02 16:59:29 mcnutt ; corrected for keyword norotate and set rectify to F for norotate ; ; Revision 1.17 2007/11/02 15:16:16 mcnutt ; fills r[12]row and r[12]col with keyword norectify ; ; Revision 1.16 2007/05/21 18:39:43 colaninn ; added silent keyword ; ; Revision 1.15 2007/03/01 22:40:57 nathan ; fix DSTART/STOP and CRPIX errors ; ; Revision 1.14 2007/02/12 18:50:37 nathan ; implement DSTART and DSTOP ; ; Revision 1.13 2007/02/10 00:02:58 nathan ; update for RECTROTA, add /NOROTATE (Bug 93) ; ; Revision 1.12 2007/02/01 23:16:38 nathan ; add some comments ; ; Revision 1.11 2007/01/10 20:55:54 nathan ; swap rectification for COR1 between A and B (bug 24) ; ; Revision 1.10 2006/10/24 16:13:22 nathan ; Do NOT add 1 to rect crpix (is float) ; ; Revision 1.9 2006/10/19 15:37:13 nathan ; fix rect coord for COR1,2B ; ; Revision 1.8 2006/09/29 18:02:20 mcnutt ; corrected case error ; ; Revision 1.7 2006/09/25 17:58:45 nathan ; fix XYCEN per W.Thompson email ; ; Revision 1.6 2006/09/22 21:53:48 mcnutt ; changed for updated CCD orientations ; ; Revision 1.5 2006/09/20 21:09:57 nathan ; Add history; update input header structure unless /NOMODIFY; update CRPIX, ; SUMROW, SUMCOL; get X(Y)CEN ; ; Revision 1.4 2006/09/12 20:29:24 mcnutt ; removed common block to work outside of secchi_rduce ; ; Revision 1.3 2006/09/12 18:29:24 colaninn ; added hdr keyword to make it compatible w/ SECCHI_PREP ; ; Revision 1.2 2006/09/12 18:16:19 mcnutt ; corrected EUVI B ; ; Revision 1.1 2006/07/24 18:34:59 mcnutt ; modified LASCO reduce_rectify.pro ; ; ; ;common scc_reduce ; info="$Id: secchi_rectify.pro,v 1.29 2023/08/14 17:50:07 secchia Exp $" len=strlen(info) histinfo=strmid(info,1,len-2) IF scch.rectify EQ 'T' THEN BEGIN IF ~keyword_set(silent) THEN $ message,'RECTIFY=T -- Returning with no changes',/info return,a ENDIF if (scch.date_obs gt '2015-07-01T00:00:00') and (scch.date_obs lt '2023-08-12T00:00:00') $ then post_conj=1 else post_conj=0 stch=scch if ~keyword_set(NOROTATE) then begin stch.rectify = 'T' if (scch.OBSRVTRY eq 'STEREO_A' and post_conj eq 0) then begin case scch.detector of 'EUVI': begin b=rotate(a,6) stch.r1row=2176-scch.p2col+1 stch.r2row=2176-scch.p1col+1 stch.r1col=2176-scch.p2row+1 stch.r2col=2176-scch.p1row+1 stch.crpix1=scch.naxis2-scch.crpix2+1 stch.crpix2=scch.naxis1-scch.crpix1+1 stch.naxis1=scch.naxis2 & stch.naxis2=scch.naxis1 stch.sumrow=scch.sumcol stch.sumcol=scch.sumrow stch.rectrota=6 rotcmt='transpose and rotate 180 deg CCW' ;--indicate imaging area - rotate 6 ; naxis1 stch.dstart1 =(129-stch.r1col+1)>1 stch.dstop1 =stch.dstart1-1+((stch.r2col-stch.r1col+1)<2048) ; naxis2 stch.dstart2 =(79-stch.r1row+1)>1 stch.dstop2 =stch.dstart2-1+((stch.r2row-stch.r1row+1)<2048) end 'COR1': begin b=rotate(a,3) stch.r1row=2176-scch.p2col+1 stch.r2row=2176-scch.p1col+1 stch.r1col=scch.p1row stch.r2col=scch.p2row stch.crpix1=scch.crpix2 stch.crpix2=scch.naxis1-scch.crpix1+1 stch.naxis1=scch.naxis2 & stch.naxis2=scch.naxis1 stch.sumrow=scch.sumcol stch.sumcol=scch.sumrow stch.rectrota=3 rotcmt='rotate 270 deg CCW' ;--indicate imaging area - rotate 3 ; naxis1 stch.dstart1 =1 stch.dstop1 =stch.dstart1-1+((stch.r2col-stch.r1col+1)<2048) ; naxis2 stch.dstart2 =(79-stch.r1row+1)>1 stch.dstop2 =stch.dstart2-1+((stch.r2row-stch.r1row+1)<2048) end 'COR2': begin b=rotate(a,1) stch.r1row=scch.p1col stch.r2row=scch.p2col stch.r1col=2176-scch.p2row+1 stch.r2col=2176-scch.p1row+1 stch.crpix1=scch.naxis2-scch.crpix2+1 stch.crpix2=scch.crpix1 stch.naxis1=scch.naxis2 & stch.naxis2=scch.naxis1 stch.sumrow=scch.sumcol stch.sumcol=scch.sumrow stch.rectrota=1 rotcmt='rotate 90 deg CCW' ;--indicate imaging area - rotate 1 ; naxis1 stch.dstart1 =(129-stch.r1col+1)>1 stch.dstop1 =stch.dstart1-1+((stch.r2col-stch.r1col+1)<2048) ; naxis2 stch.dstart2 =(51-stch.r1row+1)>1 stch.dstop2 =stch.dstart2-1+((stch.r2row-stch.r1row+1)<2048) end 'HI1': begin b=a ; no change stch.r1row=scch.p1row stch.r2row=scch.p2row stch.r1col=scch.p1col stch.r2col=scch.p2col ;stch.naxis1=scch.naxis1 & stch.naxis2=scch.naxis2 stch.rectrota=0 rotcmt='no rotation necessary' end 'HI2': begin b=a ; no change stch.r1row=scch.p1row stch.r2row=scch.p2row stch.r1col=scch.p1col stch.r2col=scch.p2col ;stch.naxis1=scch.naxis1 & stch.naxis2=scch.naxis2 stch.rectrota=0 rotcmt='no rotation necessary' end endcase endif if (scch.OBSRVTRY eq 'STEREO_B') then begin case scch.detector of 'EUVI': begin b=rotate(a,3) stch.r1row=2176-scch.p2col+1 stch.r2row=2176-scch.p1col+1 stch.r1col=scch.p1row stch.r2col=scch.p2row stch.crpix1=scch.crpix2 stch.crpix2=scch.naxis1-scch.crpix1+1 stch.naxis1=scch.naxis2 & stch.naxis2=scch.naxis1 stch.sumrow=scch.sumcol stch.sumcol=scch.sumrow stch.rectrota=3 rotcmt='rotate 270 deg CCW' ;--indicate imaging area - rotate 3 ; naxis1 stch.dstart1 =1 stch.dstop1 =stch.dstart1-1+((stch.r2col-stch.r1col+1)<2048) ; naxis2 stch.dstart2 =(79-stch.r1row+1)>1 stch.dstop2 =stch.dstart2-1+((stch.r2row-stch.r1row+1)<2048) end 'COR1': begin b=rotate(a,1) ; 90 CCW =[x0,y0]=[y0,x1], [x1,y1]=[y1,x0] stch.r1row=scch.p1col stch.r2row=scch.p2col stch.r1col=2176-scch.p2row+1 stch.r2col=2176-scch.p1row+1 stch.crpix1=scch.naxis2-scch.crpix2+1 stch.crpix2=scch.crpix1 stch.naxis1=scch.naxis2 & stch.naxis2=scch.naxis1 stch.sumrow=scch.sumcol stch.sumcol=scch.sumrow stch.rectrota=1 rotcmt='rotate 90 deg CCW' ;--indicate imaging area - rotate 1 ; naxis1 stch.dstart1 =(129-stch.r1col+1)>1 stch.dstop1 =stch.dstart1-1+((stch.r2col-stch.r1col+1)<2048) ; naxis2 stch.dstart2 =(51-stch.r1row+1)>1 stch.dstop2 =stch.dstart2-1+((stch.r2row-stch.r1row+1)<2048) end 'COR2': begin b=rotate(a,3) stch.r1row=2176-scch.p2col+1 stch.r2row=2176-scch.p1col+1 stch.r1col=scch.p1row stch.r2col=scch.p2row stch.crpix1=scch.crpix2 stch.crpix2=scch.naxis1-scch.crpix1+1 stch.naxis1=scch.naxis2 & stch.naxis2=scch.naxis1 stch.sumrow=scch.sumcol stch.sumcol=scch.sumrow stch.rectrota=3 rotcmt='rotate 270 deg CCW' ;--indicate imaging area - rotate 3 ; naxis1 stch.dstart1 =1 stch.dstop1 =stch.dstart1-1+((stch.r2col-stch.r1col+1)<2048) ; naxis2 stch.dstart2 =(79-stch.r1row+1)>1 stch.dstop2 =stch.dstart2-1+((stch.r2row-stch.r1row+1)<2048) end 'HI1': begin b=rotate(a,2) stch.r1row=2176-scch.p2row+1 stch.r2row=2176-scch.p1row+1 stch.r1col=2176-scch.p2col+1 stch.r2col=2176-scch.p1col+1 stch.crpix1=scch.naxis1-scch.crpix1+1 stch.crpix2=scch.naxis2-scch.crpix2+1 stch.naxis1=scch.naxis1 & stch.naxis2=scch.naxis2 stch.rectrota=2 rotcmt='rotate 180 deg CCW' ;--indicate imaging area - rotate 2 ; naxis1 stch.dstart1 =(79-stch.r1col+1)>1 stch.dstop1 =stch.dstart1-1+((stch.r2col-stch.r1col+1)<2048) ; naxis2 stch.dstart2 =(129-stch.r1row+1)>1 stch.dstop2 =stch.dstart2-1+((stch.r2row-stch.r1row+1)<2048) end 'HI2': begin b=rotate(a,2) stch.r1row=2176-scch.p2row+1 stch.r2row=2176-scch.p1row+1 stch.r1col=2176-scch.p2col+1 stch.r2col=2176-scch.p1col+1 stch.crpix1=scch.naxis1-scch.crpix1+1 stch.crpix2=scch.naxis2-scch.crpix2+1 stch.naxis1=scch.naxis1 & stch.naxis2=scch.naxis2 stch.rectrota=2 rotcmt='rotate 180 deg CCW' ;--indicate imaging area - rotate 2 ; naxis1 stch.dstart1 =(79-stch.r1col+1)>1 stch.dstop1 =stch.dstart1-1+((stch.r2col-stch.r1col+1)<2048) ; naxis2 stch.dstart2 =(129-stch.r1row+1)>1 stch.dstop2 =stch.dstart2-1+((stch.r2row-stch.r1row+1)<2048) end endcase endif if (scch.OBSRVTRY eq 'STEREO_A' and post_conj eq 1) then begin case scch.detector of 'EUVI': begin b=rotate(a,4) stch.r1row=scch.p1col stch.r2row=scch.p2col stch.r1col=scch.p1row stch.r2col=scch.p2row stch.crpix1=scch.naxis1-scch.crpix2+1 stch.crpix2=scch.naxis2-scch.crpix1+1 stch.naxis1=scch.naxis2 & stch.naxis2=scch.naxis1 stch.sumrow=scch.sumcol stch.sumcol=scch.sumrow stch.rectrota=4 rotcmt='transpose' ;--indicate imaging area - rotate 4 ; naxis1 stch.dstart1 =(129-stch.r1col+1)>1 stch.dstop1 =stch.dstart1-1+((stch.r2col-stch.r1col+1)<2048) ; naxis2 stch.dstart2 =(79-stch.r1row+1)>1 stch.dstop2 =stch.dstart2-1+((stch.r2row-stch.r1row+1)<2048) end 'COR1': begin b=rotate(a,1) ; 90 CCW =[x0,y0]=[y0,x1], [x1,y1]=[y1,x0] stch.r1row=scch.p1col stch.r2row=scch.p2col stch.r1col=2176-scch.p2row+1 stch.r2col=2176-scch.p1row+1 stch.crpix1=scch.naxis2-scch.crpix2+1 stch.crpix2=scch.crpix1 stch.naxis1=scch.naxis2 & stch.naxis2=scch.naxis1 stch.sumrow=scch.sumcol stch.sumcol=scch.sumrow stch.rectrota=1 rotcmt='rotate 90 deg CCW' ;--indicate imaging area - rotate 1 ; naxis1 stch.dstart1 =(129-stch.r1col+1)>1 stch.dstop1 =stch.dstart1-1+((stch.r2col-stch.r1col+1)<2048) ; naxis2 stch.dstart2 =(51-stch.r1row+1)>1 stch.dstop2 =stch.dstart2-1+((stch.r2row-stch.r1row+1)<2048) end 'COR2': begin b=rotate(a,3) stch.r1row=2176-scch.p2col+1 stch.r2row=2176-scch.p1col+1 stch.r1col=scch.p1row stch.r2col=scch.p2row stch.crpix1=scch.crpix2 stch.crpix2=scch.naxis1-scch.crpix1+1 stch.naxis1=scch.naxis2 & stch.naxis2=scch.naxis1 stch.sumrow=scch.sumcol stch.sumcol=scch.sumrow stch.rectrota=3 rotcmt='rotate 270 deg CCW' ;--indicate imaging area - rotate 3 ; naxis1 stch.dstart1 =1 stch.dstop1 =stch.dstart1-1+((stch.r2col-stch.r1col+1)<2048) ; naxis2 stch.dstart2 =(79-stch.r1row+1)>1 stch.dstop2 =stch.dstart2-1+((stch.r2row-stch.r1row+1)<2048) end 'HI1': begin b=rotate(a,2) stch.r1row=2176-scch.p2row+1 stch.r2row=2176-scch.p1row+1 stch.r1col=2176-scch.p2col+1 stch.r2col=2176-scch.p1col+1 stch.crpix1=scch.naxis1-scch.crpix1+1 stch.crpix2=scch.naxis2-scch.crpix2+1 stch.naxis1=scch.naxis1 & stch.naxis2=scch.naxis2 stch.rectrota=2 rotcmt='rotate 180 deg CCW' ;--indicate imaging area - rotate 2 ; naxis1 stch.dstart1 =(79-stch.r1col+1)>1 stch.dstop1 =stch.dstart1-1+((stch.r2col-stch.r1col+1)<2048) ; naxis2 stch.dstart2 =(129-stch.r1row+1)>1 stch.dstop2 =stch.dstart2-1+((stch.r2row-stch.r1row+1)<2048) end 'HI2': begin b=rotate(a,2) stch.r1row=2176-scch.p2row+1 stch.r2row=2176-scch.p1row+1 stch.r1col=2176-scch.p2col+1 stch.r2col=2176-scch.p1col+1 stch.crpix1=scch.naxis1-scch.crpix1+1 stch.crpix2=scch.naxis2-scch.crpix2+1 stch.naxis1=scch.naxis1 & stch.naxis2=scch.naxis2 stch.rectrota=2 rotcmt='rotate 180 deg CCW' ;--indicate imaging area - rotate 2 ; naxis1 stch.dstart1 =(79-stch.r1col+1)>1 stch.dstop1 =stch.dstart1-1+((stch.r2col-stch.r1col+1)<2048) ; naxis2 stch.dstart2 =(129-stch.r1row+1)>1 stch.dstop2 =stch.dstart2-1+((stch.r2row-stch.r1row+1)<2048) end endcase endif endif else begin stch.rectify = 'F' b=a ; no change stch.r1row=scch.p1row stch.r2row=scch.p2row stch.r1col=scch.p1col stch.r2col=scch.p2col ;stch.naxis1=scch.naxis1 & stch.naxis2=scch.naxis2 stch.rectrota=0 rotcmt='no rotation' endelse ; For continuous readout only: if (stch.r1col lt 1) then begin stch.r2col = stch.r2col+abs(stch.r1col)+1 stch.r1col = 1 endif if (stch.r1row lt 1) then begin stch.r2row = stch.r2row+abs(stch.r1row)+1 stch.r1row = 1 endif ;stop xden=(2^(scch.ipsum+scch.sumcol-2)) yden=(2^(scch.ipsum+scch.sumrow-2)) stch.dstart1=fix(ceil(float(stch.dstart1)/xden))>1 stch.dstart2=fix(ceil(float(stch.dstart2)/yden))>1 stch.dstop1 =fix(float(stch.dstop1)/xden) stch.dstop2 =fix(float(stch.dstop2)/yden) ;IF xden GT 1 and stch.dstart1 GT 1 THEN stch.dstop1=stch.dstop1-1 ;IF yden GT 1 and stch.dstart2 GT 1 THEN stch.dstop2=stch.dstop2-1 if(stch.NAXIS1 gt 0 and stch.NAXIS2 gt 0)then begin WCS = FITSHEAD2WCS(stch) ; For RA/Dec, we need to specify system=A XYCEN = WCS_GET_COORD(WCS, [(stch.NAXIS1-1.)/2., (stch.NAXIS2-1.)/2.]) stch.XCEN=XYCEN[0] stch.YCEN=XYCEN[1] endif ; IF keyword_set(NOROTATE) THEN X(Y)CEN are irrelevant IF keyword_set(hdr) THEN BEGIN ; IF ~keyword_set(NOROTATE) THEN BEGIN fxaddpar,hdr,'NAXIS1', stch.naxis1 fxaddpar,hdr,'NAXIS2', stch.naxis2 fxaddpar,hdr,'R1COL', stch.r1col fxaddpar,hdr,'R2COL', stch.r2col fxaddpar,hdr,'R1ROW', stch.r1row fxaddpar,hdr,'R2ROW', stch.r2row fxaddpar,hdr,'SUMROW', stch.sumrow fxaddpar,hdr,'SUMCOL', stch.sumcol fxaddpar,hdr,'RECTIFY', stch.rectify fxaddpar,hdr,'CRPIX1', stch.crpix1 fxaddpar,hdr,'CRPIX2', stch.crpix2 fxaddpar,hdr,'XCEN', stch.xcen fxaddpar,hdr,'YCEN', stch.ycen fxaddpar,hdr,'CRPIX1A', stch.crpix1 fxaddpar,hdr,'CRPIX2A', stch.crpix2 fxaddpar,hdr,'DSTART1', stch.dstart1 fxaddpar,hdr,'DSTART2', stch.dstart2 fxaddpar,hdr,'DSTOP1', stch.dstop1 fxaddpar,hdr,'DSTOP2', stch.dstop2 ; ENDIF fxaddpar,hdr,'HISTORY', histinfo fxaddpar,hdr,'RECTROTA', stch.rectrota, rotcmt ENDIF ;IF ~keyword_set(NOMODIFY) THEN $ ; IF keyword_set(NOROTATE) THEN $ ; scch.rectrota=stch.rectrota ELSE scch=stch scch=stch IF keyword_set(NOROTATE) THEN BEGIN IF ~keyword_set(silent) THEN $ message,'NOROTATE set -- Image returned unchanged',/info return,a ENDIF ELSE BEGIN IF ~keyword_set(silent) THEN $ message,'Rectification applied to '+scch.filename+': '+rotcmt,/info return,b ENDELSE end ;rotate crpix1 crpix2 ;0 401 301 ;1 212=naxis2-crpix2+1. 401=crpix1 ;2 368=naxis1-crpix1+1. 212=naxis2-crpix2+1. ;3 301=crpix2 368=naxis1-crpix1+1. ;6 212=naxis2-crpix2+1. 368=naxis1-crpix1+1.