;+ ; NAME: ; ZGRID ; PURPOSE: ; Draw an angle/radius grid appropriate to an existing solar image on ; the current output device. Useful for coalignments. ; CALLING SEQUENCE: ; ZGRID,hdr,[nr=n1,na=n2,/label,/nolabel] ; INPUTS: ; hdr: The fits header of the image to grid for. ; OPTIONAL INPUT PARAMETERS: ; (none) ; KEYWORD PARAMETERS: ; nr: the number of angular circles to draw per solar radius (default 10) ; na: the number of radial lines to draw per full circle (default 36) ; label: (default): draws textual labels near each grid intersection ; nolabel: doesn't. ; OUTPUTS: ; none ; RESTRICTIONS: ; The image must have the MSSTA alignment tags in the image header. ; MODIFICATION HISTORY: ; Created by Craig DeForest, 1/30/1995 ; Fixed-up to do the right thing with reflected images, 3/2/1995 ; Added cliprect and offset capability, 5/24/1995 CED ; Modified for proper CRPIXn usage, 13-Mar-98 CED ;- PRO zgrid,hdr1,nr=nr,na=na,nla=nla,nlr=nlr,label=kl,rmin=rmin,rmax=rmax,$ black=black,pretty=pretty,psheight=psheight,pswidth=pswidth,$ xoffset=xoffset,yoffset=yoffset hdr = hdr1 hdr.CRPIX1 = hdr.CRPIX1 - (hdr.CRVAL1)/(hdr.CDELT1) hdr.CRPIX2 = hdr.CRPIX2 - (hdr.CRVAL2)/(hdr.CDELT2) hdr.CRVAL1 = 0 hdr.CRVAL2 = 0 ;fug is a quick-hack scale parameter to make everything match up right. ;tvscl does the "right thing" on different output devices, scaling ;its output so that it's still 75 dpi on the laserjet. Idl does no ;such thing, bummer. So we apply a scale factor based on the resolution ;that we suppose tvscl to have used. ; fugx = 1 fugy = 1 ; ; Figure out if we're using a postscript device, and scale accordingly. ; Postscript output has 1,000 pixels per cm (go figure), so we have to ; scale to match the image pixel coordinates. ; if(!D.NAME eq 'PS') then begin if(not(keyword_set(psheight) and keyword_set(pswidth))) then begin print,"Warning -- postscript device and psheight & pswidth not set." print,"Using fugx=1 and fugy = 1" endif else begin fugx = 1000 * 2.54 * pswidth / hdr.NAXIS1 fugy = 1000 * 2.54 * psheight/ hdr.NAXIS2 endelse endif else if(!D.NAME ne 'X') then begin print,"Warning -- unknown device. Using fugx=1 & fugy = 1..." endif ; ; Set defaults for a bunch of our keywords ; label = keyword_set(kl) if(not(keyword_set(nr))) then nr = 10 if(not(keyword_set(na))) then na = 360 if(not(keyword_set(nla))) then nla = 30 else label = 1 if(not(keyword_set(nlr))) then nlr = 2 else label = 1 ; ; px0 and py0 are the output plane coordinates of the origin of ; the image being gridded, ie add px0 and py0 to all output ; coordinates fed to plots. ; ; We assume we're using the postscript device, if there's ; an offset. This is broken and should one day be fixed. ; --CED ; if(not(isvalid(xoffset))) then xoffset = 0 if(not(isvalid(yoffset))) then yoffset = 0 px0 = 1000*2.54*xoffset py0 = 1000*2.54*yoffset ; ;x0,y0 contains the center of the sun in image coords ;scale contains the number of solar radii per pixel ;This is in pixel coords, ie should be multiplied by fug[xy] before ;feeding into plots. ; x0 = hdr.CRPIX1-1 y0 = hdr.CRPIX2-1 hd2 = hdr zhdrunit,hd2,'solar-radii' scale=hd2.CDELT1 angle=hdr.CROTA * 3.1415926 / 180 refl= 1 - 2*safetag(hdr,'REFLECT') if(refl lt 0) then print,'Image is reflected...' xmax = long(hdr.NAXIS1)-1 ymax = long(hdr.NAXIS2)-1 print,'xmax=',xmax,', ymax=',ymax,', scale=',scale,'radii per pixel (',1.0/scale,'pix per radius)' ;calculate rmax. This is always the distance to one of the four corners. if(not(keyword_set(rmax))) then $ rmax = max([ zdist(x0,y0,0,0), zdist(x0,y0,xmax,0), $ zdist(x0,y0,0,ymax), zdist(x0,y0,xmax,ymax) ] ) * scale rmin = 0 ; ; Calculate the clip-rect. If we're working within a specified ; width (pswidth and psheight specified, then we clip to the ; specified size. Otherwise, we clip to the image itself, as ; measured in its header. ; cliprect = [ $ long(px0), long(py0), $ long(px0+fugx*hdr.NAXIS1), long(py0+fugy*hdr.NAXIS2), $ long(0), long(0)] oldbangp = !P oldbangx = !X oldbangy = !Y oldbangz = !Z ; ;------------------- ; Ready to start drawing concentric rings. We generate a single circular ; array, and scale it for each ring we plot. ; Generate the array. We guess at a big number of edges for a big polygon ; to approximate a circle. numsteps = (rmax / scale) foo= lindgen(numsteps + 1) cxs = lonarr(numsteps + 1) cys = lonarr(numsteps + 1) xs = lonarr(numsteps + 1) ys = lonarr(numsteps + 1) foo = foo * 2 * 3.1415926 / numsteps cxs = sin(foo) cys = cos(foo) imin = long(rmin * nr) imax = long(rmax * nr) ; ; for i=imin,imax do begin xs = (cxs * (i / (nr * scale))) + x0 ys = (cys * (i / (nr * scale))) + y0 plots,color=255*(not keyword_set(black)), $ /device, clip=cliprect, noclip=0, $ linestyle=( 1 - keyword_set(pretty)* $ ((i ne nr) and ((i/float(nlr)) eq long(i/nlr)))), $ px0+xs*fugx,py0+ys*fugy endfor for i=0,na-1 do begin dx = - sin(angle + refl * i * 2 * 3.1415926 / na) / scale dy = cos(angle + refl * i * 2 * 3.1415926 / na) / scale plots, $ color=255*(not keyword_set(black)), $ /device, clip=cliprect, noclip=0, $ linestyle=(1- keyword_set(pretty)*((i/float(nla)) eq long(i/nla))),$ px0+ [x0+dx*rmin, x0+dx*rmax] * fugx,$ py0+ [y0+dy*rmin, y0+dy*rmax] * fugy endfor ; ; Draw the labels. We skip any label at r=1.0, to avoid scribbling all over ; the limb... ; if(label) then $ for i=imin,imax do $ for j=0,na-1 do $ if( (((i mod nlr) eq 0) and ((j mod nla) eq 0)) and $ (i gt 0) and $ ( fix(10.0 * i/nr + 0.5) ne 10 ) ) then $ xyouts, $ px0 + (x0 - sin(refl*(j*2*3.1415926/na)+angle)*i/nr/scale + 2)*fugx,$ py0 + (y0 + cos(refl*(j*2*3.1415926/na)+angle)*i/nr/scale + 2)*fugy,$ alignment=0.0,charsize=0.5, $ /device, clip=cliprect, noclip=0, $ color=255*(not keyword_set(black)), $ string(format="(F4.2,A,I3)",i/float(nr),',',(j*360.0/na+720) mod 360) !P = oldbangp !X = oldbangx !Y = oldbangy !Z = oldbangz end