;+ ; Project : STEREO - SECCHI ; ; Name : COR1_QUICKPOL ; ; Purpose : Return COR1 total and polarized brightness, mu angle ; ; Category : STEREO, SECCHI, COR1, Analysis ; ; Explanation : This routine performs the same function as COR_POLARIZ, but can ; be up to 20 times faster. It returns the total brightness, ; polarized brightness, and angle of polarization (MU). It can ; also handle multiple sequences. ; ; Syntax : COR1_QUICKPOL, IMAGE, TOTB [, PB [, MU ]] ; ; Examples : CAT = COR1_PBSERIES('1-Apr-2007', 'Ahead') ; SECCHI_PREP, CAT.FILENAME, HEADER, IMAGE ; COR1_QUICKPOL, IMAGE, TOTB, PB, MU ; ; Inputs : IMAGE = Array containing the pB images to process, with ; polarizer angles of 0,120,240. This must have either ; the dimensions (Nx,Ny,3*Ns) or (Nx,Ny,3,Ns), where Ns ; is the number of sequences. ; ; Opt. Inputs : None. ; ; Outputs : TOTB = The total brightness image(s) ; ; Opt. Outputs: PB = The polarized brightness image(s) ; MU = The polarization angle image(s) ; ; Keywords : DOUBLE = If set, then the output images are returned as double ; precision. The calculation is performed in double ; precision, but returned as floating point unless ; IMAGE is double precision or /DOUBLE is passed. ; ; HEADER = Array containing the image header structures. ; Passing in the headers allows the MU values to be ; corrected for the use of other polarization ; sequences, such as [10,130,250]. ; ; TANGENTIAL = If set, then return only the tangential ; component of pB. Ignored if HEADER not passed. ; The pB values are multiplied by the cosine of the ; angle to the tangential direction. This tends to ; sppress noisy regions, while not significantly ; effecting other regions. ; ; RADIAL = If set, then return only the radial component of pB. ; The solar corona should not be polarized radially, ; but comet tails can be polarized radially or ; tangentially, depending on the phase angle. ; ; ERRMSG = If defined and passed, then any error messages will ; be returned to the user in this parameter rather than ; depending on the MESSAGE routine in IDL. If no ; errors are encountered, then the input string is ; returned unchanged. In order to use this feature, ; ERRMSG must be defined first, e.g. ; ; ERRMSG = '' ; COR1_QUICKPOL, ERRMSG=ERRMSG, ... ; IF ERRMSG NE '' THEN ... ; ; Calls : None. ; ; Common : None. ; ; Restrictions: The calculation assumes that the images are presented with ; polarizer angles of 0,120,240. The calculations of TOTB and ; PB will be correct so long as the three polarizer angles are ; separated by either 60 or 120 degrees. For cases other than ; [0,120,240], the correct MU will be returned when the optional ; HEADER keyword is passed. ; ; Side effects: None. ; ; Prev. Hist. : None. ; ; History : Version 1, 6-Apr-2007, William Thompson, GSFC ; Version 2, 2-Jul-2007, WTT, make more memory friendly ; Version 3, 25-Sep-2007, WTT, fix double precision bug ; Version 4, 15-Feb-2008, WTT, added /TANGENTIAL keyword ; ; Contact : WTHOMPSON ;- ; pro cor1_quickpol, image, totb, pb, mu, double=k_double, header=header, $ tangential=k_tangential, radial=k_radial, errmsg=errmsg on_error, 2 ; ; Check the number of input parameters. ; if n_params() lt 2 then begin message = 'Syntax: COR1_QUICKPOL, IMAGE, TOTB [, PB [, MU ]]' goto, handle_error endif ; tangential = keyword_set(k_tangential) and (n_elements(header) gt 0) radial = keyword_set(k_radial) and (n_elements(header) gt 0) ; ; Make sure that IMAGE has the right dimensions. ; sz = size(image) case sz[0] of 3: begin if (sz[3] mod 3) ne 0 then begin message = 'Number of images must be divisible by 3' goto, handle_error endif save_dim = sz[1:3] nseq = sz[3]/3 image = reform(image, sz[1], sz[2], 3, nseq, /overwrite) end 4: begin if sz[3] ne 3 then begin message = 'Third IMAGE dimension must be 3' goto, handle_error endif nseq = sz[4] save_dim = sz[1:4] end else: begin message = 'IMAGE must have dimensions (Nx,Ny,3*Ns) or (Nx,Ny,3,Ns)' goto, handle_error end endcase ; ; If IMAGE is not double precision, then save the original image and make a ; double precision version for processing. ; test_dbl = datatype(image) eq 'DOU' if test_dbl then begin delvarx, save_image a = temporary(image) end else begin save_image = temporary(image) a = double(save_image) endelse ; ; Calculate the total brightness. The 2/3 factor will be applied later. ; totb = total(a,3) ; ; If requested, calculate the polarized brightness. ; if n_params() ge 3 then begin pb = totb for iseq = 0,nseq-1 do pb[*,*,iseq] = totb[*,*,iseq]^2 - $ 3.d0*reform(a[*,*,0,iseq]*a[*,*,1,iseq] + $ a[*,*,0,iseq]*a[*,*,2,iseq] + $ a[*,*,1,iseq]*a[*,*,2,iseq]) pb = (4.d0/3.d0) * sqrt(0 > temporary(pb)) end else pb = 0 ;Place-holder ; ; Apply the 2/3 factor to total brightness. ; totb = (2.d0/3.d0) * temporary(totb) ; ; If requested, calculate the angle of polarization. ; if (n_params() eq 4) or tangential or radial then begin w = where(pb gt 0, n0) if n0 eq 0 then mu = pb else begin pmin = min(pb[w]) mu = pb for iseq = 0,nseq-1 do begin mu0 = acos(sqrt(0 > ((reform(a[*,*,0,iseq]) - $ 0.5d0*(totb[*,*,iseq]-pb[*,*,iseq])) / $ (pb[*,*,iseq]>pmin))) < 1) w = where(a[*,*,2,iseq] lt a[*,*,1,iseq], count) if count gt 0 then mu0[w] = -mu0[w] mu[*,*,iseq] = mu0 endfor endelse ; ; If the header was passed, then modify MU based on the polarizer angles in ; the header. ; if n_elements(header) gt 0 then begin mu0 = header[0].polar * !dpi / 180.d0 halfpi = !dpi / 2.d0 mu = temporary(mu) + mu0 w = where(mu gt halfpi, count) if count gt 0 then mu[w] = mu[w] - !dpi w = where(mu lt -halfpi, count) if count gt 0 then mu[w] = mu[w] + !dpi dpolar = header[1].polar - header[0].polar if (dpolar eq 60) or (dpolar eq 240) or (dpolar eq -120) then $ mu = -temporary(mu) endif end else mu = 0 ;Place-holder ; ; Apply the /tangential or /radial keyword. ; if tangential or radial then begin wcs = fitshead2wcs(header[0]) cen = wcs_get_pixel(wcs, [0,0]) x = dindgen(sz[1]) - cen[0] y = dindgen(sz[2]) - cen[1] x = rebin(reform(x,sz[1],1), sz[1],sz[2]) y = rebin(reform(y,1,sz[2]), sz[1],sz[2]) theta = atan(y,x) for iseq = 0,nseq-1 do begin dmu = mu[*,*,iseq] - theta corr = abs(cos(dmu)) if radial then corr = abs(sin(dmu)) pb[*,*,iseq] = pb[*,*,iseq] * corr endfor endif ; ; Restore the original IMAGE array. ; if n_elements(save_image) gt 0 then image = temporary(save_image) else $ image = temporary(a) image = reform(image, save_dim, /overwrite) ; ; If the original IMAGE was not double precision, then convert the output to ; floating point. ; if (not test_dbl) and (not keyword_set(k_double)) then begin totb = float(temporary(totb)) pb = float(temporary(pb)) mu = float(temporary(mu)) endif return ; ; Error handling point. ; handle_error: if n_elements(errmsg) eq 0 then message, message else errmsg=message return end