-Incase of any doubt, drop me an email (Joe Ninan)
# Library of functions we will use later in this calculation. # Execute this cell in the beginning, by pressing Shift+Enter import numpy as np from scipy.optimize import leastsq ###################################################### ### Calculation of transformation matrix #### Constrained transformation matrix where scaling in x and y is same. def ScaleMatrix(Scale): ScaleMatrix = np.matrix([[Scale,0,0], [0,Scale,0], [0,0,1]]) return ScaleMatrix def TranslateMatrix(TranX,TranY): TranslateMatrix = np.matrix([[1,0,TranX], [0,1,TranY], [0,0,1]]) return TranslateMatrix def RotMatrix(theta): RotMatrix = np.matrix([[np.cos(theta),-np.sin(theta),0], [np.sin(theta),np.cos(theta),0], [0,0,1]]) return RotMatrix def ReflectYMatrix(): ReflectYMatrix = np.matrix([[1,0,0], [0,-1,0], [0,0,1]]) return ReflectYMatrix def ReflectXMatrix(): ReflectXMatrix = np.matrix([[-1,0,0], [0,1,0], [0,0,1]]) return ReflectXMatrix ################################### # Error functions to fit the pramaeters of transformation matrix # Function to fit the Translate*Rotate*Scale transformation def error_funcTRS(p,OldCoords,NewCoords): """ Error function to fit the coordinate where parameters are p=[Scale,theta,TranX,TranY] which will transform OldCoords to NewCoords Fitted transformation is TRS: Translate*Rotate*Scale """ RS = np.matmul(RotMatrix(p[1]),ScaleMatrix(p[0])) TRS = np.matmul(TranslateMatrix(p[2],p[3]),RS) TransformCoords = np.matmul(TRS,OldCoords) return np.array(TransformCoords.flatten() - NewCoords.flatten())[0] # Function to fit the Translate*Rotate*Scale*ParityFlipY transformation def error_funcTRSP(p,OldCoords,NewCoords): """ Error function to fit the coordinate where parameters are p=[Scale,theta,TranX,TranY] which will transform OldCoords to NewCoords Fitted transformation is TRSP: Translate*Rotate*Scale*ParityFlipY""" SP = np.matmul(ScaleMatrix(p[0]),ReflectYMatrix()) RSP = np.matmul(RotMatrix(p[1]),SP) TRSP = np.matmul(TranslateMatrix(p[2],p[3]),RSP) TransformCoords = np.matmul(TRSP,OldCoords) return np.array(TransformCoords.flatten() - NewCoords.flatten())[0]
When: This is when you suspect the HPF's fiber puck inserted in the HET's focal plane has moved with respect to BIB, LRS2 etc..
Things to do:
import matplotlib.pyplot as plt #HPF fiber head fiber positions in telecentric lens images CentroidCoords = {'cir2': (273.45298734501097, 270.7847529387491), 'cir3': (336.04330942778, 222.2177477751225), 'cir1': (222.25408901265263, 333.5099840115954), 'cir6': (793.7851982362772, 688.9766017329656), 'cir4': (680.1842052725259, 800.6668579582121), 'cir5': (744.1546788398894, 752.2047326301424), 'oct4': (774.8631863343908, 305.7149638147935), 'oct2': (298.5672272093679, 773.1045874545131), 'oct3': (717.8617085355628, 248.97764755048598), 'cCFB': (641.7590850208674, 378.2411130588114), 'oct1': (241.7727067933783, 715.9757709056951), 'sCFB': (373.99530838383396, 644.5011001356886)} ##### Now do the calculation for ACAM coordinates PixelCoords = np.matrix([[CentroidCoords['cCFB'][0],CentroidCoords['sCFB'][0]], [CentroidCoords['cCFB'][1],CentroidCoords['sCFB'][1]], [1,1]]) # Febrary 2018 calculation #ACAMcoords = np.matrix([[148.0,219.0], # [254.8,179.5], # [1,1]]) #New measurements from September 29th (Central CFB) and October 1st (Side CFB) #ACAMcoords = np.matrix([[145.7,217.9], # [254.2,182.2], # [1,1]]) #New measurements from October 2nd (Central CFB & Side CFB) #ACAMcoords = np.matrix([[145.8,217.8], # [256.4,182.5], # [1,1]]) #New measurements from 2019 July 10th (Central CFB & Side CFB) ACAMcoords = np.matrix([[148.7,217.8], [256.4,182.5], [1,1]]) p0 = [0.1,1,1,1] pTRS,iter = leastsq(error_funcTRS,p0,args=(PixelCoords,ACAMcoords)) print(pTRS) RS = np.matmul(RotMatrix(pTRS[1]),ScaleMatrix(pTRS[0])) TRS = np.matmul(TranslateMatrix(pTRS[2],pTRS[3]),RS) print(TRS) # We chose TRS instead of TRSP since TRS matches the BIB and IMHP orientaiton ACAMCoordTRS = {} for fiber in CentroidCoords: ACAMCoordTRS[fiber] = np.matmul(TRS,np.matrix([[CentroidCoords[fiber][0]],[CentroidCoords[fiber][1]],[1]])) print('{0} : {1:.1f} {2:.1f}'.format(fiber,ACAMCoordTRS[fiber][0,0],ACAMCoordTRS[fiber][1,0])) plt.plot(ACAMCoordTRS[fiber][0,0],ACAMCoordTRS[fiber][1,0],'o') plt.text(ACAMCoordTRS[fiber][0,0],ACAMCoordTRS[fiber][1,0],fiber+ ' ({0:.1f},{1:.1f})'.format(ACAMCoordTRS[fiber][0,0],ACAMCoordTRS[fiber][1,0])) plt.xlabel('X (pixel)') plt.ylabel('Y (pixel)') plt.title('ACAM pixels') plt.show() ### ACAM to fplane.txt transformation # We shall use BIB, LRS2R, LRS2B to fit the transform. # Calculation from Febrary 2018 #ACAMbilrlbCoords = np.matrix([[461.16,744.5,741.8], # [404.63,581.5,213.3], # [1,1,1]]) # New measurement from 2018 October 1st ACAMbilrlbCoords = np.matrix([[453.0,737.9,735.5], [401.5,581.7,212.6], [1,1,1]]) # Pre-September 2018 fplane.txt coordinates #SkybilrlbCoords = np.matrix([[3.3,49.8,-49.8], # [-73.2,-151.3,-148.7], # [1,1,1]]) # New fplane.txt form Matthew on 8th Oct 2018 SkybilrlbCoords = np.matrix([[0.7,50,-50], [-73.13,-150.0,-150.0], [1,1,1]]) p0 = [0.1,1,1,1] pTRS,iter = leastsq(error_funcTRS,p0,args=(ACAMbilrlbCoords,SkybilrlbCoords)) print(pTRS) RS = np.matmul(RotMatrix(pTRS[1]),ScaleMatrix(pTRS[0])) TRS = np.matmul(TranslateMatrix(pTRS[2],pTRS[3]),RS) print(TRS) # Transformation of all the coordinates to fplane.txt Sky coords from ACAM pixels print ('TRS: BIB, LRS2R, LRS2B in fplane:', np.matmul(TRS, ACAMbilrlbCoords)) # TRS was found to match correctly print ('TRS: cCFB, sCFB in fplane:', np.matmul(TRS, ACAMcoords)) ############################################### # Transformation of all the coordinates # TRS matches the BIB and IMHP orientaiton for fiber in ACAMCoordTRS: SkyCoordTRS = np.matmul(TRS,np.matrix([[ACAMCoordTRS[fiber][0,0]],[ACAMCoordTRS[fiber][1,0]],[1]])) print('{0} : {1:.1f} {2:.1f}'.format(fiber,SkyCoordTRS[0,0],SkyCoordTRS[1,0])) plt.plot(SkyCoordTRS[0,0],SkyCoordTRS[1,0],'o') plt.text(SkyCoordTRS[0,0],SkyCoordTRS[1,0],fiber+ ' ({0:.1f},{1:.1f})'.format(SkyCoordTRS[0,0],SkyCoordTRS[1,0])) plt.title('fplane.txt') plt.xlabel('X (arcsec)') plt.ylabel('Y (arcsec)') plt.show()
# Output from above cell on October 2018 [ -2.73230898e-01 -1.58378347e-02 3.22763146e+02 3.56957175e+02] [[ -2.73196630e-01 -4.32720489e-03 3.22763146e+02] [ 4.32720489e-03 -2.73196630e-01 3.56957175e+02] [ 0.00000000e+00 0.00000000e+00 1.00000000e+00]] cir4 : 133.5 141.2 cir2 : 246.9 284.2 oct1 : 253.6 162.4 cir1 : 260.6 266.8 oct2 : 237.9 147.0 cCFB : 145.8 256.4 cir6 : 102.9 172.2 cir3 : 230.0 297.7 oct4 : 109.8 276.8 oct3 : 125.6 292.0 cir5 : 116.2 154.7 sCFB : 217.8 182.5 [ -0.27092843 1.57717676 -108.86655128 48.90293818] [[ 1.72862813e-03 2.70922917e-01 -1.08866551e+02] [ -2.70922917e-01 1.72862813e-03 4.89029382e+01] [ 0.00000000e+00 0.00000000e+00 1.00000000e+00]] TRS: BIB, LRS2R, LRS2B in fplane: [[ 0.69206859 50.00486446 -49.99693305] [ -73.1310992 -150.00553958 -149.99336122] [ 1. 1. 1. ]] TRS: cCFB, sCFB in fplane: [[-39.14988128 -59.04662365] [ 9.84559708 -9.78859859] [ 1. 1. ]] cir4 : -70.4 13.0 cir2 : -31.5 -17.5 oct1 : -64.4 -19.5 cir1 : -36.1 -21.2 oct2 : -68.6 -15.3 cCFB : -39.1 9.8 cir6 : -62.0 21.3 cir3 : -27.8 -12.9 oct4 : -33.7 19.6 oct3 : -29.5 15.4 cir5 : -66.8 17.7 sCFB : -59.0 -9.8
[ -2.74075066e-01 -3.21991544e-02 3.27136387e+02 3.52750187e+02] [[ -2.73932999e-01 -8.82346050e-03 3.27136387e+02] [ 8.82346050e-03 -2.73932999e-01 3.52750187e+02] [ 0.00000000e+00 0.00000000e+00 1.00000000e+00]] oct4 : 112.2 275.8 cir6 : 103.6 171.0 cir3 : 233.1 294.8 cCFB : 148.0 254.8 oct3 : 128.3 290.9 cir5 : 116.7 153.3 cir4 : 133.7 139.4 oct2 : 238.5 143.6 oct1 : 254.6 158.8 sCFB : 219.0 179.5 cir2 : 249.8 281.0 cir1 : 263.3 263.4 [ -0.27143363 1.5526728 -104.21083054 53.73980234] [[ -4.91906601e-03 2.71389056e-01 -1.04210831e+02] [ -2.71389056e-01 -4.91906601e-03 5.37398023e+01] [ 0.00000000e+00 0.00000000e+00 1.00000000e+00]] TRS: BIB, LRS2R, LRS2B in fplane: [[ 3.33284685 49.93966109 -49.97250798] [ -73.40437657 -151.16978701 -148.62583645] [ 1. 1. 1. ]] TRS: cCFB, sCFB in fplane: [[-35.78892075 -56.57377038] [ 12.32084398 -6.57737335] [ 1. 1. ]] cir4 : -67.0 16.8 cir6 : -58.3 24.8 oct4 : -29.9 21.9 cCFB : -35.8 12.3 oct3 : -25.9 17.5 cir5 : -63.2 21.3 oct2 : -66.4 -11.7 cir3 : -25.3 -11.0 oct1 : -62.4 -16.1 sCFB : -56.6 -6.6 cir2 : -29.2 -15.4 cir1 : -34.0 -19.0
When: This is when there is only an overall shift to correct after IHMP take down and IFU re-install
Things to do:
# Step 1: # Old BIB, LRS2R, LRS2B pixel coordinates in ACAM (Date: October 2017) # This was old and wrong BIB OldACAM_b_lr_lb_Coords = np.matrix([[452.6, 744.5, 741.8], [402.6, 581.5, 213.3], [1, 1, 1]]) #OldACAM_b_lr_lb_Coords = np.matrix([[461.16, 744.5, 741.8], # [404.63, 581.5, 213.3], # [1, 1, 1]]) # Step 2: # New BIB, LRS2R, LRS2B pixel coordinates in ACAM (Date: 27th January 2018) # #NewACAM_b_lr_lb_Coords = np.matrix([[458.41, 742.79, 740.75], # [398.65, 578.99, 210.23], # [1, 1, 1]]) # New BIB, LRS2R, LRS2B pixel coordinates in ACAM (Date: 29th September 2018) #NewACAM_b_lr_lb_Coords = np.matrix([[454.8, 738.2, 735.9], # [402.3, 581.8, 212.2], # [1, 1, 1]]) # New BIB, LRS2R, LRS2B pixel coordinates in ACAM (Date: 1st October 2018) NewACAM_b_lr_lb_Coords = np.matrix([[453.0, 737.9, 735.5], [401.5, 581.7, 212.6], [1, 1, 1]]) # Step 3: # Fit TRS linear transformtion p0 = [1,0,0,0] pTRS,iter = leastsq(error_funcTRS,p0,args=(OldACAM_b_lr_lb_Coords,NewACAM_b_lr_lb_Coords)) print('Scale = {0},theta ={1},TranX ={2},TranY={3}'.format(*pTRS)) print('Transformation matrix') RS = np.matmul(RotMatrix(pTRS[1]),ScaleMatrix(pTRS[0])) TRS = np.matmul(TranslateMatrix(pTRS[2],pTRS[3]),RS) print(TRS) print('Residue/Error in the fitted transform (PredictedNewCoords - NewCoords). This is a consistence check') print(np.matmul(TRS,OldACAM_b_lr_lb_Coords)-NewACAM_b_lr_lb_Coords) # Step 4 # Apply the transformation to old coordinates to obtain new ACAM coordinates #(Date: October 2017) OldACAM_cCFB_sCFB_HRsci_HEsci = np.matrix([[148.0,219.0,128.3,112.2], [254.8,179.5,290.9,275.8], [1, 1, 1, 1]]) print('New Corrdinates of Central CFB, Side CFB, HR and HE science fibers') print(np.matmul(TRS,OldACAM_cCFB_sCFB_HRsci_HEsci))
Scale = 1.002868101230477,theta =0.006012141442238229,TranX =-1.2761448921104395,TranY=-8.906754443102646
Transformation matrix
[[ 1.00284998e+00 -6.02934855e-03 -1.27614489e+00]
[ 6.02934855e-03 1.00284998e+00 -8.90675444e+00]
[ 0.00000000e+00 0.00000000e+00 1.00000000e+00]]
Residue/Error in the fitted transform (PredictedNewCoords - NewCoords). This is a consistence check
[[ 0.34849498 -0.95040355 0.60190765]
[ 1.00692594 -0.2506431 -0.7562837 ]
[ 0. 0. 0. ]]
New Corrdinates of Central CFB, Side CFB, HR and HE science fibers
[[ 145.60937362 217.2657319 125.6355696 109.58072814]
[ 247.51176316 172.42524368 283.59586915 268.35576199]
[ 1. 1. 1. 1. ]]