Coverage for /wheeldirectory/casa-6.7.0-12-py3.10.el8/lib/py/lib/python3.10/site-packages/casatasks/private/correct_ant_posns.py: 86%

44 statements  

« prev     ^ index     » next       coverage.py v7.6.4, created at 2024-11-01 07:19 +0000

1import json 

2 

3from casatools import table 

4from casatasks import casalog 

5 

6from .correct_ant_posns_evla import correct_ant_posns_evla as _correct_ant_posns_evla 

7 

8_tb = table( ) 

9 

10def correct_ant_posns(vis_name, print_offsets=False, time_limit=0): 

11 """ 

12 Given an input visibility MS name (vis_name), find the antenna 

13 position offsets that should be applied. This application should 

14 be via the gencal task, using caltype='antpos'. 

15 

16 If the print_offsets parameter is True, will print out each of 

17 the found offsets (or indicate that none were found), otherwise 

18 runs silently. 

19 

20 A list is returned where the first element is the returned error 

21 code, the second element is a string of the antennas, and the 

22 third element is a list of antenna Bx,By,Bz offsets. An example 

23 return list might look like: 

24 [ 0, 'ea01,ea19', [0.0184, -0.0065, 0.005, 0.0365, -0.0435, 0.0543] ] 

25 

26 The second and third elements of the list returned are in the format 

27 expected by the calibrater tool method cb.specifycal() for the 

28 parameters antenna and parameter, respectively. 

29 

30 Usage examples: 

31 

32 CASA <1>: antenna_offsets = correct_ant_posns('test.ms') 

33 CASA <2>: if (antenna_offsets[0] == 0): 

34 CASA <3>: gencal(vis='test.ms', caltable='cal.G', \ 

35 caltype='antpos', antenna=antenna_offsets[1], \ 

36 parameter=antenna_offsets[2]) 

37 

38 For specific details for the EVLA see correct_ant_posns_evla. 

39 """ 

40 _tb.open(vis_name+'/OBSERVATION') 

41 # specific code for different telescopes 

42 tel_name = _tb.getcol('TELESCOPE_NAME') 

43 _tb.close() 

44 if tel_name == 'EVLA' or tel_name == 'VLA': 

45 return _correct_ant_posns_evla(vis_name, print_offsets, time_limit) 

46 else: 

47 msg = 'Currently only work for EVLA observations' 

48 if (print_offsets): 

49 print(msg) 

50 else: 

51 # send to casalogger 

52 casalog.post(msg, "WARN") 

53 return [1, '', []] 

54 

55def correct_ant_posns_alma_json(vis_name, json_file): 

56 """ 

57 This function computes the differences of the ALMA antenna 

58 positions given the corrected positions in a JSON file (presumably 

59 created by the getantposalma task). 

60 

61 For each antenna found in the JSON file which is also present in the 

62 ANTENNA subtable, the difference between the corrected position in 

63 the JSON file and the nominal position in the MS is computed. 

64 

65 If the MS does not belong to an ALMA observation an exception is 

66 thrown. 

67 

68 Likewise, if the JSON file has not been created by the getantposalma an 

69 exception is thrown. 

70 

71 It returns a tuple with the antenna names as a string with the antenna 

72 names separated by commma and the differential possitions as a long 

73 vector with a list of antenna Bx,By,Bz offsets. An example return 

74 might look like: 

75 ['DA42,DA43', [-0.001, 0.001, 0.001, 0.002, -0.002, 0.002] ] 

76 

77 These two elements of the list returned are in the format 

78 expected by the calibrater tool method cb.specifycal() for the 

79 parameters antenna and parameter, respectively. 

80 """ 

81 

82 # get the telescope name 

83 _tb.open(vis_name+'/OBSERVATION') 

84 tel_name = _tb.getcol('TELESCOPE_NAME') 

85 _tb.close() 

86 with open(json_file, "r") as f: 

87 corrected_antenna_abspos_map = json.load(f) 

88 

89 # throw if the MS wasn't observed with ALMA 

90 if tel_name[0] != 'ALMA' : 

91 raise ValueError('Antenna positions are from ALMA but MS is from '+tel_name[0]+' telescope') 

92 

93 # throw if the JSON file wasn't generated using the ALMA web service 

94 if(corrected_antenna_abspos_map['metadata']['product_code'] != 'antposalma') : 

95 raise ValueError('JSON file with antenna positions is not from ALMA. This is currently not supported') 

96 

97 # compute the differences in antenna positions between the corrected ones in the 

98 # JSON file and the nominal ones in the MS. 

99 _tb.open(vis_name+'/ANTENNA') 

100 nominal_antenna_names = list(_tb.getcol('NAME')) 

101 nominal_abspos = _tb.getcol('POSITION') 

102 antennas_to_correct = "" 

103 differential_pos = [] 

104 for corrected_antenna_name, corrected_abspos in corrected_antenna_abspos_map['data'].items() : 

105 if corrected_antenna_name in nominal_antenna_names : 

106 tb_idx = nominal_antenna_names.index(corrected_antenna_name) 

107 if len(antennas_to_correct) != 0 : 

108 antennas_to_correct += "," 

109 antennas_to_correct += corrected_antenna_name 

110 differential_pos.append(corrected_abspos[0] - nominal_abspos[0][tb_idx]) 

111 differential_pos.append(corrected_abspos[1] - nominal_abspos[1][tb_idx]) 

112 differential_pos.append(corrected_abspos[2] - nominal_abspos[2][tb_idx]) 

113 else: 

114 raise ValueError("Antenna {} could not be found in input MS".format(corrected_antenna_name)) 

115 if (len(differential_pos) == 0) : 

116 raise ValueError("The list of antenna positions in JSON file is empty") 

117 

118 

119 return antennas_to_correct, differential_pos 

120