xy_tranrot_

Here we consider a family of OTW codes that deal with one fairly simple task: linear XY coordinate transformation. By this I mean we apply a rotation, translation, and/or scale adjustment using two linearly indpendent trasformation equations of the form:

 
 The set2 coordinates are transformed to the set1 system via the relations:
    Xset1 = avals(1) + avals(2)*Xset2 + avals(3)*Yset2
    Yset1 = avals(4) + avals(5)*Xset2 + avals(6)*Yset2
 




Special Note:
As of Sep2016 I have begun to build online help files for the xy_tranrot_ routines. You can get a fairly detailed description of, for example, xy_tranrot_res.sh, by using:
 
% xy_tranrot_res.sh --help 
Help Information for:  xy_tranrot_res.sh

Usage: xy_tranrot_res.sh xy.1 xy.2 Y
arg1 - name of input XY file 1 
arg2 - name of input XY file 2 
arg3 - Do files have "# data" headers?  (Y or N) 

I will show: /home/sco/sco/codes/bash/HELP_FILES/xy_tranrot_res.sh.help

Enter any key to roceed with the view of help: Return
xy_tranrot_res.sh
   Compare two files of XY values by computing X,Y residusals. 

  Each file must have X (in column 1) and Y (in column 2). The 
  files may or may not have "# data" headers. The third argument
  on the command line identifies this header state. It is true 
  that the files must be the same in this regard: eith they both
  have headers, or they both do not. 
 



This collection of routines were built to handle simple files of X,Y lists. The files have no headers, and are usually generated on the fly by other scripts. The scripts (shown below) allow you to derive a linear XY transormation (xy_tranrot_fit.sh), then you can apply this transormation to a set of XY coordiantes (xy_tranrot_apply.sh). Finally, to acess how well the transofmation works, there is a module that computed residuals between the original and predicted XY sets (xy_tranrot_res.sh). Here are some more verbose descriptions of each routine:

 
 xy_tranrot_fit.sh  == derive the 6 transformation coefficents (i.e. fill 
                       the avals(i=1,6) array.
 
 xy_tranrot_apply.sh == Convert a file of X,Y value using the expressions 
                        derived with xy_tranrot_fit.sh

 xy_tranrot_res.sh   == compute residuals and mean statistics for two 
                        sets of (X,Y). We can use this to evaluate the    
                        "goodness of fit" from xy_tranrot_fit.sh.
 
 xy_tranrot_image.sh == Very much like xy_tranrot_apply.sh, except the 
                        transformations are applied to pixel position 
                        in Image_1 to predict positions in Image_2. In 
                        this way we can replace pixels in Image_1 with the 
                        Image_2 and hence computed a spatially transformed 
                        image. This is commonly used for image registration 
                        and stacking procedures. 

Below I present usage messages for these routines.
 
 
% xy_tranrot_fit.sh list1.xy_define list2.xy_to_transform
Usage: xy_tranrot_fit.sh list1.xy_define list2.xy_to_transform
arg1 - name of input XY_1 file (XY defining system to be transformed to, set1)
arg2 - name of input XY_2 file (XY to be transformed, set2)
NOTE: THis creates the coefficients file called xy_tranrot_fit.out_explain

% xy_tranrot_apply.sh list.xy xy_tranrot_fit.out_explain 
Usage: xy_tranrot_apply.sh list.xy xy_tranrot_fit.out_explain 
arg1 - name of input XY file 
arg2 - name of solution file (from xy_tranrot_fit.sh)

% xy_tranrot_res.sh xy.1 xy.2 Y 
Usage: xy_tranrot_res.sh xy.1 xy.2 Y
arg1 - name of input XY file 1 
arg2 - name of input XY file 2 
arg3 - Do files have "# data" headers?  (Y or N) 

% xy_tranrot_image.sh acam_empty.fits dss.fits xy_tranrot_fit.out_explain acam_dss.fits
Usage: xy_tranrot_image.sh acam_empty.fits dss.fits xy_tranrot_fit.out_explain acam_dss.fits
arg1 - input FITS image to be filled
arg2 - FITS image contributing pixel values
arg3 - XY transform to go from arg1 to arg2
arg4 - output image name


Below I show some practical runs with the data files and script (FIT) thate does everything. One point that is not too clear above is that I wriote this stuff to use simple X,Y data files, just pasted columns with no "# data" headers or anything. The second set of corrdinates (set2 or list2 above) are the ones TO BE TRANSFORMED to the system defined by the set1 coordinates. Below is a script that might make this clear. I also show some out put and data files.

 

The script (FIT): 

#!/bin/bash

# Check command line arguments
if [ -z "$1" ]
then
 printf "Usage: FIT R\n"
 printf "arg1 - Fit R or B data (for files Table.R or Table.B)  \n"
 exit
fi

chan="$1"
fdat="Table.$chan"
printf "\nLRS2-$chan Transformations \n"
printf "Processing file = $fdat\n"

# Build the column files 
colget.py $fdat  9 Xacam N
colget.py $fdat 10 Yacam N
colget.py $fdat 11 Xlrs2 N
colget.py $fdat 12 Ylrs2 N

# paste together the XY sets 
paste Xacam Yacam > XY.acam 
paste Xlrs2 Ylrs2 > XY.lrs2 

#==================================================================================
# Fit the ACAM to LRS2 transform 
xy_tranrot_fit.sh XY.lrs2 XY.acam > junk.1  
mv xy_tranrot_fit.out_explain coefs.ACAM_to_LRS2 

# Use the fit to convert acam XY to the lrs2 XY
xy_tranrot_apply.sh XY.acam coefs.ACAM_to_LRS2 > XY.lrs2_predicted
mv coefs.ACAM_to_LRS2 coefs.ACAM_to_LRS2_$chan

# Now compare the two sets of lrs2 coordinates 
xy_tranrot_res.sh XY.lrs2 XY.lrs2_predicted > stats
read sigx sigy np < stats

printf "\nFor the XY_acam to XY_lrs2 transformations: \n"
printf "X sigma in LRS2 coordinates = $sigx  (arcseconds) \n"
printf "Y sigma in LRS2 coordinates = $sigy  (arcseconds) \n"
printf "Number of points in fit     = $np  \n"
#==================================================================================

#==================================================================================
# Fit the LRS2 to ACAM transform 
xy_tranrot_fit.sh XY.acam XY.lrs2 > junk.1  
mv xy_tranrot_fit.out_explain coefs.LRS2_to_ACAM

# Use the fit to convert lrs2 XY to the  acam XY
xy_tranrot_apply.sh XY.lrs2 coefs.LRS2_to_ACAM > XY.acam_predicted
mv coefs.LRS2_to_ACAM coefs.LRS2_to_ACAM_$chan 

# Now compare the two sets of acam coordinates 
xy_tranrot_res.sh XY.acam XY.acam_predicted > stats
read sigx sigy np < stats

printf "\nFor the XY_lrs2 to XY_acam transformations: \n"
printf "X sigma in ACAM coordinates = $sigx  (pixel) \n"
printf "Y sigma in ACAM coordinates = $sigy  (pixels) \n"
printf "Number of points in fit     = $np  \n"
#==================================================================================

# clean up 
\rm -f coefs.acam_to_lrs2 head.lines junk.1 pars.in stats Xacam Xlrs2 XY.acam XY.acam_predicted XY.lrs2 XY.lrs2_predicted Yacam Ylrs2
 

Here is the initial file: 
% cat Table.B
p#  chan  obs  exp   Date    dx_ang dy_ang  Associated ACAM image            Xacam Yacam     Xlrs2   Ylrs2
# data 
10   B    009   01  20160816   0.0   0.0    20160816T041516.4_acm_sci.fits  710.69 185.59   +0.395  -0.217
11   B    009   02  20160816  +3.0  +2.0    20160816T042017.0_acm_sci.fits  716.97 174.16   +3.448  -2.255
12   B    009   03  20160816  -3.0  -2.0    20160816T043321.8_acm_sci.fits  710.74 184.59   +0.643  -0.326
13   B    009   04  20160816  +4.0  +2.0    20160816T044347.1_acm_sci.fits  715.33 169.19   +4.630  -2.038
14   B    009   05  20160816  -4.0  -2.0    20160816T045108.1_acm_sci.fits  709.05 184.86   +0.450  -0.054
15   B    009   06  20160816  -3.0  -1.0    20160816T045727.2_acm_sci.fits  704.45 194.34   -2.492  +1.060
16   B    009   07  20160816  +3.0  +1.0    20160816T050508.3_acm_sci.fits  708.69 184.94   +0.450  +0.163
17   B    009   08  20160816  +3.0  +2.0    20160816T051740.8_acm_sci.fits  711.96 170.56   +4.190  -1.223

For the initial files the script builds: 
% cat XY.acam
710.69	185.59
716.97	174.16
710.74	184.59
715.33	169.19
709.05	184.86
704.45	194.34
708.69	184.94
711.96	170.56

% cat XY.lrs2
+0.395	-0.217
+3.448	-2.255
+0.643	-0.326
+4.630	-2.038
+0.450	-0.054
-2.492	+1.060
+0.450	+0.163
+4.190	-1.223

When I make the run I get fit info: 
% FIT B 
LRS2-B Transformations 
Processing file = Table.B

For the XY_acam to XY_lrs2 transformations: 
X sigma in LRS2 coordinates = 0.117  (arcseconds) 
Y sigma in LRS2 coordinates = 0.129  (arcseconds) 
Number of points in fit     = 8  

For the XY_lrs2 to XY_acam transformations: 
X sigma in ACAM coordinates = 0.674  (pixel) 
Y sigma in ACAM coordinates = 0.571  (pixels) 
Number of points in fit     = 8  

The files that are important (that can be used to do tranformations 
with the xy_tranrot_apply.sh code) are then:
coefs.LRS2_to_ACAM_B
coefs.ACAM_to_LRS2_B


Later I added to the FIT script and had it save the XY data files. If I was running B data, then I would create the files XY.acam_B and XY.lrs2_B. In addition, I modified the xy_tranrot_res.sh code so that a detailed list of residuals is created. Here is the list from my processing of the B data (i.e.the Table.B data):
 

% cat xy_tranrot_res.resids_list
# List of XY residuals from xy_tranrot_res.sh
  line       X1        Y1           X2        Y2           dX        dY          Res       Res_norm
    1       0.297    -0.363        0.395    -0.217       -0.098    -0.146        0.176      1.0055
    2       3.554    -2.119        3.448    -2.255        0.106     0.136        0.172      0.9839
    3       0.552    -0.414        0.643    -0.326       -0.091    -0.088        0.127      0.7254
    4       4.708    -1.989        4.630    -2.038        0.078     0.049        0.092      0.5284
    5       0.383    -0.057        0.450    -0.054       -0.067    -0.003        0.067      0.3849
    6      -2.282     1.275       -2.492     1.060        0.210     0.215        0.301      1.7224
    7       0.341     0.020        0.450     0.163       -0.109    -0.143        0.180      1.0299
    8       4.161    -1.242        4.190    -1.223       -0.029    -0.019        0.035      0.1998

We can use this listing to find bad points that should be rejected in a subsequent refit of the data. The column labeled "Res" is the combined (dX,dY) residual. The column labeled "Res_norm" is the value of Res divided by the combined mean X,Y standard deviations. In the table above, the large values of Res and Res_norm for point 6 might lead me to reject it. In this case I did not since point 6 has a large residual beecause it is the only point at large negative X.




Back to SCO CODES page