T. Metcalf 2001-Oct-17 (last update: 2003-Sep-26)

While analyzing the TRACE WL data from a flare, I had the need to get very accurate TRACE pointing information for the co-alignment with HXT data as well as other data sets. Doing a blind co-alignment showed that the TRACE pointing was off by something like 10 arc seconds. One of the science questions I wanted to address was the spatial correspondence between the TRACE flare kernels and the HXR flare kernels, so I needed a much better co-alignment than I could get with the pointing information in the TRACE header.

To correct the TRACE pointing, I use an MDI WL image nearby in time (get MDI data from here: you probably want the fd_Ic data). The problem was how to do the alignment between MDI and TRACE very accurately. To solve this problem, I wrote two IDL routines. The goal of the programs are simply to update the pointing information in the TRACE header to match the pointing in the MDI header under the assumption that the MDI pointing is known to a higher accuracy than the TRACE pointing. The TRACE data are not altered in any way.

In the end, the alignment with the HXT data is much improved, so I believe these programs are worthwhile. The code accounts for the parallax between the SoHO and Earth views using the pointing information in the SoHO header. It also works with EUV images from SoHO/EIT, though these images change rapidly so you need TRACE/EIT images very close in time for the process to work. Only use EIT as a last resort: white light images give a better alignment.

The two Solar Soft routines are:


This routine does a cross correlation alignment between a TRACE WL or EUV image and an MDI WL or EIT EUV image. It is quite slow since it includes a very general warping of the images which will account for foreshortening, evolution, etc. Specify the /eit keyword if you are using an EIT image for the alignment. The output is a new TRACE index with the .xcen and .ycen fields corrected from the SoHO pointing which is assumed to be correct. The user first gives an initial guess for the transformation between TRACE and SoHO using setpts_roi and then the guess is refined using auto_align_images. The transformation is then used to set the pointing of TRACE. Obviously, the TRACE and SoHO images should be close in time to avoid AR evolution, but solar rotation and foreshortening are accounted for as is the parallax between the Earth and SoHO views. EUV images change very rapidly, so the time constraint is much more severe for EUV images than WL images In my case, the TRACE and MDI images were about an hour apart and the alignment was quite good. I presume one would not want to try a separation in time of the TRACE and MDI images much greater than a few hours due to the evolution of the active regions. I would not try an EUV alignment with images more than a few minutes apart. If using EUV images, you obviously want to make sure the TRACE and EIT images are from the same channel (e.g. 195).


This routine fixes the pointing within a TRACE dataset by aligning each image to some reference image in the data cube. The pointing of the reference image is assumed to be correct. The output is a new array of TRACE indices which have the .xcen and .ycen values corrected to be consistent with the reference image after accounting for solar rotation. The images themselves are not modified. This routine is kind of like align_cube_correl but more general (and much slower). If you are correcting EUV images, the routine will fail if the reference is too far away in time, so it might be necessary to bootstrap.

I also wrote a third program which does modify the TRACE data. It uses the corected pointing to make a new data cube and index with jitter, pointing changes, etc. removed.


This routine takes a TRACE data cube (presumably with corrected pointing from trace_mdi_align and trace_cube_pointing) and returns a new data cube with shifted images so that the images are all aligned/dejittered. Optionally, it will correct for solar rotation as well.

To correct the pointing in a TRACE data set using these routines, you first call trace_mdi_align on the white light or EUV image in the TRACE data set which is closest in time to the SoHO white light or EUV image. This corrects the pointing for that image which you then use as the reference image in a call to trace_cube_pointing. During this process, the TRACE images are not modified in any way. The only change is that the .xcen and .ycen fields in the TRACE index are updated. The whole process seems to be accurate to something around 0.25 arc second (half TRACE pixel), at least for the data I was working with (for which the TRACE and MDI images were an hour apart). This is based on a test of how the pointing varies as I pick different images in the TRACE data cube to be the reference image. Your mileage may vary. Of course, any error in the MDI pointing propagates into the new TRACE pointing.

With the TRACE pointing corrected, it is a simple matter to correct other TRACE wavelengths under the assumption that the trace pointing does not vary much. There is a well known shift between the EUV and WL TRACE images which is accounted for by calling trace_wave2point or by using the /wave2point keyword in trace_prep.

trace_mdi_align and trace_cube_pointing are very slow. For my purposes, I wanted the most accurate pointing I could come up with. The fact that it takes several hours to do the alignments on 13 TRACE images plus one MDI image is unimportant. This will obviously reduce the utility of these routines for some applications though. The reason for the lengthy computation is that these routines are using very general warpings from one image to the next. This allows corrections for foreshortening, solar rotation, parallax, and some AR evolution.

Here is an example of the alignment process for WL images with a few comments indicating how the example might change for EUV images:

; The TRACE data are in dtrace with the index structures in itrace.
; The MDI image is dmdi with the MDI header structure in imdi.

; Which TRACE image is closest to the MDI image?

junk = min(abs(int2secarr(anytim(itrace.date_obs,/yoh), $

; itref is now the index of the reference TRACE image.  Correct the
; .xcen and .ycen field in this TRACE index using the MDI image.

; Mask out points off the limb (don't do this for EUV images)
trace_mask = where(dtrace[*,*,itref] LT 50.)  
mdi_mask = where(dmdi LT 1000.)

; Now do the alignment.  This will take awhile.
; For EUV images, set the /eit keyword in trace_mdi_align
; Select the smallest possible region with covers the sunspots etc
; you want to use for the alignment.  Smaller is faster and more robust.
inew = trace_mdi_align(itrace[itref],dtrace[*,*,itref],imdi,dmdi, $

itrace[itref].xcen = inew.xcen  ; Update the pointing of the reference image
itrace[itref].ycen = inew.ycen

; Align the rest of the TRACE WL images with the reference TRACE image.  One
; could pass a mask here if there are points in the TRACE images which are
; off the limb, saturated, or whatever.  Since the EUV changes rapidly, you 
; will want to do this alignment only for images very close in time if you
; are using EIT.  Select the smallest possible region with covers the 
; sunspots etc you want to use for the alignment.  Smaller is faster and 
; more robust.

itrace = trace_cube_pointing(itrace,dtrace,itref)

; Done.  The .xcen and .ycen field in itrace have been updated.  dtrace
; has not changed at all.

; Optionally check the result by overlaying the MDI data on the TRACE data:

index2map,itrace[itref],dtrace[*,*,itref],tmap  ; TRACE map
mmap = mk_soho_map_earth(imdi,dmdi,/use_warp_tri) ; MDI map warped to Earth view

; Optionally make a dejittered/aligned data cube


; A movie of index/data should appear rock solid.

Here is an example of correcting the pointing of other trace wavelengths once the pointing of the WL is known. This assumes that the TRACE pointing is not changing between WL images. Obviously you should do a sanity check to make sure the the pointing of the WL images is not varying rapidly. The process of correcting the pointing in channels other than WL is made much easier by the convention that the pointing of the other wavelengths is supposed to reflect the pointing of the WL images. The offset between WL and the other wavelengths is applied later (in trace_prep for example if the /wave2point flag is set or with the trace_wave2point routine as below). This example uses 195 and assumes that the index for the 195 channel is in itrace195 and the index for the WL data is in itracewl.

tracedate0 = anytim(itrace195[0],/yoh)   ; 195
tracedate_wl = anytim(itracewl,/yoh) ; WL

for i=0,ntrace-1 do begin  ; correct the pointing using WL
   ; Figure out which WL image is closest in time to this
   ; 195 image
   tracedate = anytim(itrace195[i].date_obs,/yoh)
   tdiff = min(abs(int2secarr(tracedate_wl,tracedate)),wl)
   ; Replace the pointing with the best WL pointing
   itrace195[i].xcen = itracewl[wl].xcen
   itrace195[i].ycen = itracewl[wl].ycen
   ; sanity check:  make sure there are no large pointing jumps
; Correct for the WL->195 offset (don't do this for EUV alignments
; or if you plan to use the /wave2point flag in trace_prep)
itrace195 = trace_wave2point(itrace195)

Here's an example of aligning a single TRACE 195 image with a single EIT 195 image:

eitfile = 'efr20020421.011334.fits'
tracefile = 'trf20020421_011323.fits'

deit = rfits(eitfile,header=ieit) & ieit = fitshead2struct(ieit)
dtrace = rfits(tracefile,header=itrace) & itrace = fitshead2struct(itrace)

inew = trace_mdi_align(itrace,dtrace,ieit,deit,/eit)

emap = mk_soho_map_earth(ieit,deit,/use_warp_tri)

xrange = [ 800, 1000 ]
yrange = [ -350, -150 ]
eit_colors, 195