NightOperations/Commissioning/pFPA: CalculateHPFfiberpositions.py

File CalculateHPFfiberpositions.py, 22.6 KB (added by stevenj, 7 months ago)

updated CalculateHPFfiberpositions.py

Line 
1#!/usr/bin/env python
2""" This script is to calculate the HPFs fiber and CFB positions on HET telescope.
3If something is not clear, feel free to drop me an email - Joe Ninan, indiajoe@gmail.com """
4
5from __future__ import division
6import sys
7import argparse
8import numpy as np
9from scipy.optimize import leastsq
10import matplotlib.pyplot as plt
11from collections import OrderedDict
12##########################################################################
13# Library of functions we will use later in this calculation.
14######################################################
15### Calculation of general purpose transformation matrix
16#### These are constrained transformation matrix where scaling in x and y is same.
17
18def ScaleMatrix(Scale):
19    ScaleMatrix = np.matrix([[Scale,0,0],
20                             [0,Scale,0],
21                             [0,0,1]])
22    return ScaleMatrix
23
24def TranslateMatrix(TranX,TranY):
25    TranslateMatrix = np.matrix([[1,0,TranX],
26                                 [0,1,TranY],
27                                 [0,0,1]])
28    return TranslateMatrix
29
30def RotMatrix(theta):
31    RotMatrix = np.matrix([[np.cos(theta),-np.sin(theta),0],
32                           [np.sin(theta),np.cos(theta),0],
33                           [0,0,1]])
34    return RotMatrix
35
36def ReflectYMatrix():
37    ReflectYMatrix = np.matrix([[1,0,0],
38                                [0,-1,0],
39                                [0,0,1]])
40    return ReflectYMatrix
41
42def ReflectXMatrix():
43    ReflectXMatrix = np.matrix([[-1,0,0],
44                                [0,1,0],
45                                [0,0,1]])
46    return ReflectXMatrix
47
48###################################
49# Error functions to fit the pramaeters of transformation matrix
50
51# Function to fit the Translate*Rotate*Scale transformation
52def error_funcTRS(p,OldCoords,NewCoords):
53    """ Error function to fit the coordinate where parameters are p=[Scale,theta,TranX,TranY]
54    which will transform OldCoords to NewCoords
55    Fitted transformation is TRS: Translate*Rotate*Scale """
56    RS = np.matmul(RotMatrix(p[1]),ScaleMatrix(p[0]))
57    TRS = np.matmul(TranslateMatrix(p[2],p[3]),RS)
58    TransformCoords = np.matmul(TRS,OldCoords)
59    return np.array(TransformCoords.flatten() - NewCoords.flatten())[0]
60
61# Function to fit the Translate*Rotate*Scale*ParityFlipY transformation
62# Not used for naything now. Just here for completeness
63def error_funcTRSP(p,OldCoords,NewCoords):
64    """ Error function to fit the coordinate where parameters are p=[Scale,theta,TranX,TranY]
65    which will transform OldCoords to NewCoords
66    Fitted transformation is TRSP: Translate*Rotate*Scale*ParityFlipY"""
67    SP = np.matmul(ScaleMatrix(p[0]),ReflectYMatrix())
68    RSP = np.matmul(RotMatrix(p[1]),SP)
69    TRSP = np.matmul(TranslateMatrix(p[2],p[3]),RSP)
70    TransformCoords = np.matmul(TRSP,OldCoords)
71    return np.array(TransformCoords.flatten() - NewCoords.flatten())[0]
72
73#############################################################################
74
75
76# There are three Scenarios of calculation
77
78#HPF fiber head fiber positions in telecentric lens images measured at PSU lab.
79CentroidCoords = OrderedDict()
80CentroidCoords['cCFB'] = (641.7590850208674, 378.2411130588114)
81CentroidCoords['sCFB'] = (373.99530838383396, 644.5011001356886)
82CentroidCoords['oct1'] = (241.7727067933783, 715.9757709056951)
83CentroidCoords['oct2'] = (298.5672272093679, 773.1045874545131)
84CentroidCoords['oct3'] = (717.8617085355628, 248.97764755048598)
85CentroidCoords['oct4'] = (774.8631863343908, 305.7149638147935)
86CentroidCoords['cir1'] = (222.25408901265263, 333.5099840115954)
87CentroidCoords['cir2'] = (273.45298734501097, 270.7847529387491)
88CentroidCoords['cir3'] = (336.04330942778, 222.2177477751225)
89CentroidCoords['cir4'] = (680.1842052725259, 800.6668579582121)
90CentroidCoords['cir5'] = (744.1546788398894, 752.2047326301424)
91CentroidCoords['cir6'] = (793.7851982362772, 688.9766017329656)
92
93def Calculate_all_coordinates_from_scratch(DictOfCoords,MakePlot=False):
94    """
95    Scenrio 1
96    Calculates all the coordinates from scratch using new measured positions
97    ## Scenario 1: Everything from scratch ############################################
98   
99    # 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..
100   
101    # Things to do:
102    # 1. Measure the cCFB and sCFB positions in in ACAM
103    # 2. Calculate all of the HPF fiber positions in the fplane.txt file
104    # 3. Calculate the offsets in X & Y coordinates for moving from cCFB to science fibers.
105    # 4. Calculate the ACAM pixel coordinates for all the fibers.
106   
107    ### Step 1: Measure the cCFB and sCFB positions in ACAM
108   
109    # 1. Use the previous estimate of the ACAM coordaintes to bring the star inside cCFB
110    # 2. Guide the telescope using a guide probe and offset it to bring the star to the center of cCFB. (You cannot guide on cCFB unless the orientation is constrained later)
111    # 3. Once the star is at the center of cCFB of HPF_ACQM, and guiding smoothly on the guide probe. Insert the ACAM and wait for it to stabilise before taking exposure.
112    # 4. Take a few exposures, and then retract the ACAM. Make sure star is still at the center of cCFB
113    # 5. Repeate the procedure of inserting the ACAM, taking images, retreive,reinsert..
114    # 6. Average the centriods to get a good accurate ACAM pixel position of cCFB.
115    # 7. Do the same for sCFB and get its pixel coordinates on ACAM.
116   
117    ### Step 2: Calculate all of the HPF fiber positions in the fplane.txt file
118    # 1. Get the latest ACAM pixel positions of BIB, LRS2R, and LRS2B from https://het.as.utexas.edu:8001/trac/WFUCommissioning/wiki/NightOperations/Commissioning/Results
119    # 2. Get the fplane.tx coordinates of BIB, LRS2R, and LRS2B from fplane.txt file
120    # 3. Fits a linear transformation matrix to transform ACAM pixel coordinates to fplane.txt coordinates
121   
122    """
123    try: 
124        coordsOfACAMcCFB = DictOfCoords['ACAMcCFB']
125        coordsOfACAMsCFB = DictOfCoords['ACAMsCFB']
126        coordsOfBIB = DictOfCoords['BIB']
127        coordsOfLRS2R = DictOfCoords['LRS2R']
128        coordsOfLRS2B = DictOfCoords['LRS2B']
129        fplaneBIB = DictOfCoords['fplaneBIB']
130        fplaneLRS2R = DictOfCoords['fplaneLRS2R']
131        fplaneLRS2B = DictOfCoords['fplaneLRS2B']
132    except KeyError as e:
133        print('ERROR: Missing coordinate in input')
134        print(e)
135        raise
136
137
138    ##### First doing the calculation for ACAM coordinates
139   
140    # Telcentric lens image pixel coordinates of central CFB and side CFB as a matrix for transformation
141    PixelCoords = np.matrix([[CentroidCoords['cCFB'][0],CentroidCoords['sCFB'][0]],
142                             [CentroidCoords['cCFB'][1],CentroidCoords['sCFB'][1]],
143                             [1,1]])
144
145    #New ACAM image coordinate measurements of (Central CFB & Side CFB)
146    # All other coordinates on ACAM is going to depend on this. So make sure you have best measurment possible.
147    ACAMcoords = np.matrix([[coordsOfACAMcCFB[0],coordsOfACAMsCFB[0]],
148                            [coordsOfACAMcCFB[1],coordsOfACAMsCFB[1]],
149                            [1,1]])
150
151    # Do a least square solution of the TRS transformation from Telecentric image pixel coordinates to ACAM coordinates
152    p0 = [0.1,1,1,1]
153    pTRS,iter = leastsq(error_funcTRS,p0,args=(PixelCoords,ACAMcoords))
154    print('TRS transformation solution from Telecentric pixels to ACAM')
155    print('Scale = {0},theta ={1},TranX ={2},TranY={3}'.format(*pTRS))
156
157    RS = np.matmul(RotMatrix(pTRS[1]),ScaleMatrix(pTRS[0]))
158    TRS = np.matmul(TranslateMatrix(pTRS[2],pTRS[3]),RS)
159    print('Matrix of transformation : {0}'.format(TRS))
160
161    # We chose TRS instead of TRSP since TRS matches the BIB and IMHP orientaiton
162    print('*'*20)
163    print('New ACAM positions of two CFBs and all HPF fibers')
164    print('*'*20)
165
166    ACAMCoordTRS = OrderedDict()
167    for fiber in CentroidCoords:
168        ACAMCoordTRS[fiber] = np.matmul(TRS,np.matrix([[CentroidCoords[fiber][0]],[CentroidCoords[fiber][1]],[1]]))
169        print('{0} : {1:.1f} {2:.1f}'.format(fiber,ACAMCoordTRS[fiber][0,0],ACAMCoordTRS[fiber][1,0]))
170        if MakePlot:
171            plt.plot(ACAMCoordTRS[fiber][0,0],ACAMCoordTRS[fiber][1,0],'o')
172            plt.text(ACAMCoordTRS[fiber][0,0],ACAMCoordTRS[fiber][1,0],fiber+ ' ({0:.1f},{1:.1f})'.format(ACAMCoordTRS[fiber][0,0],ACAMCoordTRS[fiber][1,0]))
173    print('*'*20)
174    if MakePlot:
175        plt.xlabel('X (pixel)')
176        plt.ylabel('Y (pixel)')
177        plt.title('ACAM pixels')
178        plt.show()
179
180
181
182    ### ACAM to fplane.txt transformation
183    # We shall use BIB, LRS2R, LRS2B to fit the transform.
184
185    # New ACAM measurement of BIB, LRS2R, LRS2B
186    ACAMbilrlbCoords = np.matrix([[coordsOfBIB[0],coordsOfLRS2R[0],coordsOfLRS2B[0]],
187                                  [coordsOfBIB[1],coordsOfLRS2R[1],coordsOfLRS2B[1]],
188                                  [1,1,1]])
189
190    # Latest fplane.txt coordinates of BIB, LRS2R, LRS2B
191    SkybilrlbCoords = np.matrix([[fplaneBIB[0],fplaneLRS2R[0],fplaneLRS2B[0]],
192                                 [fplaneBIB[1],fplaneLRS2R[1],fplaneLRS2B[1]],
193                                 [1,1,1]])
194
195    # Do a least square solution of the TRS transformation from ACAM coordinates to fplane coordinates
196    p0 = [0.1,1,1,1]
197    pTRS,iter = leastsq(error_funcTRS,p0,args=(ACAMbilrlbCoords,SkybilrlbCoords))
198    print('TRS transformation solution from ACAM coordinates to fplane coordinates')
199    print('Scale = {0},theta ={1},TranX ={2},TranY={3}'.format(*pTRS))
200
201    RS = np.matmul(RotMatrix(pTRS[1]),ScaleMatrix(pTRS[0]))
202    TRS = np.matmul(TranslateMatrix(pTRS[2],pTRS[3]),RS)
203    print('Matrix of transformation : {0}'.format(TRS))
204
205    #  Transformation of all the coordinates to fplane.txt Sky coords from ACAM pixels 
206    print('Sanity Check of calculating the BIB, LRS2R, LRS2B coorindates in fplane')
207    print('TRS: BIB, LRS2R, LRS2B in fplane:', np.matmul(TRS, ACAMbilrlbCoords))
208    print('Sanity Check of calculating the cCFB, sCFB coorindates in fplane')
209    print('TRS: cCFB, sCFB in fplane:', np.matmul(TRS, ACAMcoords))
210    ###############################################
211    #  Transformation of all the fiber coordinates
212    print('*'*20)
213    print('New fplane.txt positions of two CFBs and all HPF fibers')
214    print('*'*20)
215    SkyCoordTRS = OrderedDict()
216    for fiber in ACAMCoordTRS:
217        SkyCoordTRS[fiber] = np.matmul(TRS,np.matrix([[ACAMCoordTRS[fiber][0,0]],[ACAMCoordTRS[fiber][1,0]],[1]]))
218        print('{0} : {1:.1f} {2:.1f}'.format(fiber,SkyCoordTRS[fiber][0,0],SkyCoordTRS[fiber][1,0]))
219        if MakePlot:
220            plt.plot(SkyCoordTRS[fiber][0,0],SkyCoordTRS[fiber][1,0],'o')
221            plt.text(SkyCoordTRS[fiber][0,0],SkyCoordTRS[fiber][1,0],fiber+ ' ({0:.1f},{1:.1f})'.format(SkyCoordTRS[fiber][0,0],SkyCoordTRS[fiber][1,0]))
222    print('*'*20)
223    if MakePlot:
224        plt.title('fplane.txt')
225        plt.xlabel('X (arcsec)')
226        plt.ylabel('Y (arcsec)')
227        plt.show()
228    print('New guider fiducial offset command to go from cCFB to HR Sci fiber is')
229    print("""syscmd -T 'Guider1_offset_fiducial(dx_asec={0:.1f},dy_asec={1:.1f},compensate="true")'""".format(SkyCoordTRS['cCFB'][0,0]-SkyCoordTRS['oct3'][0,0],
230                                                                                                              SkyCoordTRS['cCFB'][1,0]-SkyCoordTRS['oct3'][1,0]))
231
232    return ACAMCoordTRS, SkyCoordTRS
233
234
235
236### Second Scenario is when there is only an over all shift of the entire focal plane array on ACAM.
237# No shifts of the HPF fiber itself with respect to LRS2 or BIB.
238
239def Calculate_new_ACAMcoordinates_from_old(DictOfOldAndNew,DictOfOldPositions,MakePlot=False):
240    """
241    ## Scenario 2: Update the ACAM coordinates after an IHMP take down and IFU install
242    # When: This is when there is only an overall shift to correct after IHMP take down and IFU re-install
243   
244    # Things to do:
245    # 1. Get the old ACAM pixels positions of BIB, LRS2R, and LRS2B
246    # 2. Get the latest ACAM pixel positions of BIB, LRS2R, and LRS2B from https://het.as.utexas.edu:8001/trac/WFUCommissioning/wiki/NightOperations/Commissioning/Results
247    # 3. Fit a linear transformation from the old pixel coordinates to new pixel coordinates
248    # 4. Apply the transformation to old HPF acam pixel positions to obtain new pixel coordinates
249   
250    """
251    try:
252        oldBIB = DictOfOldAndNew['oldBIB']
253        oldLRS2R = DictOfOldAndNew['oldLRS2R']
254        oldLRS2B = DictOfOldAndNew['oldLRS2B']
255        newBIB = DictOfOldAndNew['newBIB']
256        newLRS2R = DictOfOldAndNew['newLRS2R']
257        newLRS2B = DictOfOldAndNew['newLRS2B']
258    except KeyError as e:
259        print('ERROR: Missing coordinate in input')
260        print(e)
261        raise
262
263
264    # Step 1:
265    # Old BIB, LRS2R, LRS2B pixel coordinates in ACAM 
266    OldACAM_b_lr_lb_Coords = np.matrix([[oldBIB[0], oldLRS2R[0], oldLRS2B[0]],
267                                        [oldBIB[1], oldLRS2R[1], oldLRS2B[1]],
268                                        [1,     1,     1]])
269
270
271    # Step 2:
272    # New BIB, LRS2R, LRS2B pixel coordinates in ACAM 
273    NewACAM_b_lr_lb_Coords = np.matrix([[newBIB[0], newLRS2R[0], newLRS2B[0]],
274                                        [newBIB[1], newLRS2R[1], newLRS2B[1]],
275                                        [1,     1,     1]])
276
277
278    # Step 3:
279    # Fit TRS linear transformtion
280    p0 = [1,0,0,0]
281    pTRS,iter = leastsq(error_funcTRS,p0,args=(OldACAM_b_lr_lb_Coords,NewACAM_b_lr_lb_Coords))
282    print('Scale = {0},theta ={1},TranX ={2},TranY={3}'.format(*pTRS))
283
284    print('Transformation matrix')
285    RS = np.matmul(RotMatrix(pTRS[1]),ScaleMatrix(pTRS[0]))
286    TRS = np.matmul(TranslateMatrix(pTRS[2],pTRS[3]),RS)
287    print(TRS)
288    print('Residue/Error in the fitted transform (PredictedNewCoords - NewCoords). This is a consistence and sanity check')
289    print(np.matmul(TRS,OldACAM_b_lr_lb_Coords)-NewACAM_b_lr_lb_Coords)
290
291    # Step 4
292    # Apply the transformation to old coordinates to obtain new ACAM coordinates
293    print('*'*20)
294    print('New ACAM positions of old ACAM coordinates')
295    print('*'*20)
296    NewACAMCoordTRS = OrderedDict()
297    for fiber in DictOfOldPositions:
298        NewACAMCoordTRS[fiber] = np.matmul(TRS,np.matrix([[DictOfOldPositions[fiber][0]],[DictOfOldPositions[fiber][1]],[1]]))
299        print('{0} : {1:.1f} {2:.1f}'.format(fiber,NewACAMCoordTRS[fiber][0,0],NewACAMCoordTRS[fiber][1,0]))
300        if MakePlot:
301            plt.plot(NewACAMCoordTRS[fiber][0,0],NewACAMCoordTRS[fiber][1,0],'o')
302            plt.text(NewACAMCoordTRS[fiber][0,0],NewACAMCoordTRS[fiber][1,0],fiber+ ' ({0:.1f},{1:.1f})'.format(NewACAMCoordTRS[fiber][0,0],NewACAMCoordTRS[fiber][1,0]))
303    print('*'*20)
304    if MakePlot:
305        plt.title('New ACAM coords')
306        plt.xlabel('X (pixels)')
307        plt.ylabel('Y (pixels)')
308        plt.show()
309
310    return NewACAMCoordTRS
311
312#################### Third Scenrario
313# fplane positions of the Central CFB and Side CFB are calculated using simultanious measurments with VIRUS
314# We need to transform HPF fibers also to the fplane coordinates using the Lab measurment
315
316def Calculate_all_fplanecoordinates_from_CFBs(DictOfCFBCoords,MakePlot=False):
317    """
318    Scenrio 3
319    Calculates all the coordinates from scratch using new measured positions of central and side CFBs
320    ## Scenario 3: Fibers based on cCFB and sCFB positions ############################################
321   
322    # When: This is when you have new measurmenets of the HPF's cetranl as sied CFBs in the HET's focal plane or ACAM
323   
324    # Things to do:
325    # 1. Measure the cCFB and sCFB positions in fplane positions using VIRUS unit or in ACAM
326    # 2. Calculate all of the HPF fiber positions in the fplane.txt file
327    # 3. Calculate the offsets in X & Y coordinates for moving from cCFB to science fibers.
328   
329    ### Step 1: Measure the cCFB and sCFB positions in fplane
330    ### Step 2: Calculate all of the HPF fiber positions in the fplane.txt file
331    #  Fits a linear transformation matrix to transform PSU lab measurments coordinates to fplane.txt coordinates
332   
333    """
334    try: 
335        coordsOfcCFB = DictOfCFBCoords['cCFB']
336        coordsOfsCFB = DictOfCFBCoords['sCFB']
337    except KeyError as e:
338        print('ERROR: Missing coordinate in input')
339        print(e)
340        raise
341
342
343    ##### First doing the calculation for fplane coordinates
344   
345    # PSU Telcentric lens image pixel coordinates of central CFB and side CFB as a matrix for transformation
346    PixelCoords = np.matrix([[CentroidCoords['cCFB'][0],CentroidCoords['sCFB'][0]],
347                             [CentroidCoords['cCFB'][1],CentroidCoords['sCFB'][1]],
348                             [1,1]])
349
350    # New fplane/ACAM coordinate measurements of (Central CFB & Side CFB)
351    # All other coordinates on ACAM is going to depend on this. So make sure you have best measurment possible.
352    fplanecoords = np.matrix([[coordsOfcCFB[0],coordsOfsCFB[0]],
353                              [coordsOfcCFB[1],coordsOfsCFB[1]],
354                              [1,1]])
355
356    # Do a least square solution of the TRS transformation from Telecentric image pixel coordinates to fplane/ACAM coordinates
357    p0 = [0.1,1,1,1]
358    pTRS,iter = leastsq(error_funcTRS,p0,args=(PixelCoords,fplanecoords))
359    print('TRS transformation solution from Telecentric pixels to fplane')
360    print('Scale = {0},theta ={1},TranX ={2},TranY={3}'.format(*pTRS))
361
362    RS = np.matmul(RotMatrix(pTRS[1]),ScaleMatrix(pTRS[0]))
363    TRS = np.matmul(TranslateMatrix(pTRS[2],pTRS[3]),RS)
364    print('Matrix of transformation : {0}'.format(TRS))
365
366    # We chose TRS instead of TRSP since TRS matches the fplane orientaiton to PSU telecentric coordinates
367    print('*'*20)
368    print('New fplane positions of two CFBs and all HPF fibers')
369    print('*'*20)
370
371    fplaneCoordTRS = OrderedDict()
372    for fiber in CentroidCoords:
373        fplaneCoordTRS[fiber] = np.matmul(TRS,np.matrix([[CentroidCoords[fiber][0]],[CentroidCoords[fiber][1]],[1]]))
374        print('{0} : {1:.1f} {2:.1f}'.format(fiber,fplaneCoordTRS[fiber][0,0],fplaneCoordTRS[fiber][1,0]))
375        if MakePlot:
376            plt.plot(fplaneCoordTRS[fiber][0,0],fplaneCoordTRS[fiber][1,0],'o')
377            plt.text(fplaneCoordTRS[fiber][0,0],fplaneCoordTRS[fiber][1,0],fiber+ ' ({0:.1f},{1:.1f})'.format(fplaneCoordTRS[fiber][0,0],fplaneCoordTRS[fiber][1,0]))
378    print('*'*20)
379    if MakePlot:
380        plt.title('fplane.txt')
381        plt.xlabel('X (arcsec)')
382        plt.ylabel('Y (arcsec)')
383        plt.show()
384
385
386    print('New guider fiducial offset command to go from cCFB to HR Sci fiber is')
387    print("""syscmd -T 'Guider1_offset_fiducial(dx_asec={0:.1f},dy_asec={1:.1f},compensate="true")'""".format(fplaneCoordTRS['cCFB'][0,0]-fplaneCoordTRS['oct3'][0,0],
388                                                                                                              fplaneCoordTRS['cCFB'][1,0]-fplaneCoordTRS['oct3'][1,0]))
389
390    return fplaneCoordTRS
391
392
393
394#####################################################################################################
395def LoadInputCoordsFile(inpfilename):
396    """ Loads and returns the coordinates in the input file as a dictionary.
397    All blank lines and comments starting with # are ignored.
398    Inlines comments startting with # are ignored.
399    Valid line format is as follows
400    FiberName = Xcoord , Ycoords  # Any optional inline comment which will be ignored
401    """
402    CoordsDic = OrderedDict()
403    with open(inpfilename,'r') as inpfile:
404        for line in inpfile:
405            line = line.rstrip()
406            if (len(line) < 1) or (line[0] =='#'):  # Ignore blank lines and comment lines starting with #
407                continue
408            line = line.split('#')[0]  # Ignore inline comments after #
409            name = line.split('=')[0].strip()
410            value = tuple(float(c.strip()) for c in line.split('=')[1].strip().split(','))
411            CoordsDic[name]=value
412    return CoordsDic
413           
414def parse_args():
415    """ Parses the command line input arguments"""
416    parser = argparse.ArgumentParser(description="Script to calculate the HPFs fiber and CFB positions on HET telescope.")
417    parser.add_argument('--ShowPlots', action='store_true', help='Show Plots')
418    subparsers = parser.add_subparsers(help='Choose one of the subcommands below and add -h flag for more help')
419
420    parser_a = subparsers.add_parser('fromscratch', help='Calculate both ACAM positions as well as fplane positions using cCFB and sCFB')
421    parser_a.add_argument('MeasuredCoordsFile', type=str,
422                        help="Input Coords file containing the New ACAM image coordinate measurements of (Central CFB & Side CFB), BIB, LRS2R, LRS2B, and Latest fplane.txt coordinates of BIB, LRS2R, LRS2B. See the example file for the keywords and format to use.")
423    parser_a.set_defaults(command='fromscratch')
424
425    parser_b = subparsers.add_parser('old2newacam', help='Calculate new ACAM positions based on old ACAM positions')
426    parser_b.add_argument('OldAndNewCoordsFile', type=str,
427                        help="Input Coords file containing the Old BIB, LRS2R, LRS2B pixel coordinates in ACAM as well as new BIB, LRS2R, LRS2B pixel coordinates in ACAM.  See the example file for the keywords and format to use.")
428    parser_b.add_argument('OldCoordsToRecalculate', type=str,
429                        help="Input Coords file containing the Old pixel coordinates of HPF fibers in ACAM which needs to be recalculated. See the example file for the format to use.")
430    parser_b.set_defaults(command='old2newacam')
431
432    parser_c = subparsers.add_parser('newfplane', help='Calculate new fplane positions based on new fplane position measurement of cCFB and sCFB')
433    parser_c.add_argument('MeasuredCFBfplaneCoordsFile', type=str,
434                          help="Input Coords file containing the new fplane coordinate measurements of Central CFB  (cCFB) & Side CFB (cCFB).  See the example file for the keywords and format to use.")
435    parser_c.set_defaults(command='newfplane')
436
437    args = parser.parse_args()
438    return args
439   
440
441def main():
442    """ Standalone Script to calculate new HPF fiber positions on HET focal plan or ACAM"""
443    # Parse input arguments
444    args = parse_args()
445    if args.command == 'fromscratch':
446        DictOfCoords = LoadInputCoordsFile(args.MeasuredCoordsFile)
447        _ = Calculate_all_coordinates_from_scratch(DictOfCoords,MakePlot=args.ShowPlots)
448       
449    elif args.command == 'old2newacam':
450        DictOfOldAndNew = LoadInputCoordsFile(args.OldAndNewCoordsFile)
451        DictOfOldPositions = LoadInputCoordsFile(args.OldCoordsToRecalculate)
452        _ = Calculate_new_ACAMcoordinates_from_old(DictOfOldAndNew,DictOfOldPositions,MakePlot=args.ShowPlots)
453
454    elif args.command == 'newfplane':
455        DictOfCFBCoords = LoadInputCoordsFile(args.MeasuredCFBfplaneCoordsFile)
456        _ = Calculate_all_fplanecoordinates_from_CFBs(DictOfCFBCoords,MakePlot=args.ShowPlots)
457       
458    print('-'*20)
459   
460
461if __name__ == '__main__':
462    main()