Coverage for hiperta_stream/scripts/create_base_config_structure.py: 0%

99 statements  

« prev     ^ index     » next       coverage.py v7.4.3, created at 2024-07-16 10:16 +0000

1#!/usr/bin/env python 

2# P. Aubert & E. Garcia - Nov 2020, lock down Chap. II 

3 

4import tables 

5import argparse 

6import numpy as np 

7from pkg_resources import resource_filename 

8 

9 

10class TelescopeInformation(tables.IsDescription): 

11 """ 

12 Class to create telescope information within r0/monitoring/telescope/information 

13 """ 

14 nb_pixel = tables.UInt64Col() 

15 nb_gain = tables.UInt64Col() 

16 nb_slice = tables.UInt64Col() 

17 tel_index = tables.UInt64Col() 

18 tel_id = tables.UInt64Col() 

19 tel_type = tables.UInt64Col() 

20 

21 

22class CameraGeometry(tables.IsDescription): 

23 """ 

24 Camera geometry 

25 """ 

26 pix_id = tables.UInt64Col() 

27 pix_x = tables.Float32Col() 

28 pix_y = tables.Float32Col() 

29 pix_area = tables.Float32Col() 

30 

31 

32def update_calibration_data(hfile_out, gain_and_pedestal, sample_offset): 

33 """ 

34 Reads and copies to the output file the gain, the pedestal and the unused pixels. 

35 

36 It **MUST** be the same calibration file as the file to be processed by the stream. 

37 

38 f.eg: 

39 - /fefs/aswg/data/real/calibration/20201008/v05/calibration.Run2833.0000.hdf5 

40 - LST-1.1.Run2833.0000.fits.fz 

41 

42 param hfile_out : obj 

43 hdf5 output file to be created 

44 gain_and_pedestal : str 

45 Path to the calibration file to be read and copied 

46 sample_offset : float 

47 Offset of the pedestal we have to use for some nonsense reason 

48 """ 

49 hfile_gain_ped = tables.open_file(gain_and_pedestal, 'r') 

50 

51 # We take the np.arrays to copy (Table with a single column not named !) 

52 dc_pe = np.asarray(hfile_gain_ped.root.tel_1.calibration.col('dc_to_pe'), dtype=np.float32)[0] 

53 ped = np.asarray(hfile_gain_ped.root.tel_1.calibration.col('pedestal_per_sample'), dtype=np.float32)[0] 

54 unusable_pix = np.asarray(hfile_gain_ped.root.tel_1.calibration.col('unusable_pixels'), dtype=np.float32)[0] 

55 

56 ped += sample_offset 

57 

58 # Create groups in output file 

59 dc_pe_group = hfile_out.create_group('/r0/monitoring/telescope', 'gain', createparents=True) 

60 nonused_pix_group = hfile_out.create_group('/r0/monitoring/telescope', 'unusable_pixels', createparents=True) 

61 

62 # Copy the np.arrays (array pyTable) into the output 

63 hfile_out.create_array(dc_pe_group, 'tel_001', dc_pe, 'Gain of the camera.') 

64 hfile_out.create_array(nonused_pix_group, 'tel_001', unusable_pix, 'Unused pixels.') 

65 

66 # Create telescope information table (we need to create a class before). Way 1. 

67 info_group = hfile_out.create_group('/r0/monitoring/telescope', 'information', createparents=True) 

68 table_info_group = hfile_out.create_table(info_group, 'tel_001', TelescopeInformation, 'Telescope Information') 

69 

70 # And then add row by row all the value. Do not forget the .append() !! 

71 row = table_info_group.row 

72 row['nb_pixel'] = ped.shape[1] 

73 row['nb_gain'] = ped.shape[0] 

74 row['nb_slice'] = 40 # TODO read configuration file whenever there would be more telescopes 

75 row['tel_index'] = 0 # TODO read configuration file whenever there would be more telescopes 

76 row['tel_id'] = 1 # TODO read configuration file whenever there would be more telescopes 

77 row['tel_type'] = 0 # TODO read configuration file whenever there would be more telescopes 

78 row.append() 

79 

80 # Create ped table. Way 2. 

81 ped_group = hfile_out.create_group('/r0/monitoring/telescope', 'pedestal', createparents=True) # same place as bef 

82 columns_dict_pedestal = { 

83 "first_event_id": tables.UInt64Col(), 

84 "last_event_id": tables.UInt64Col(), 

85 "pedestal": tables.Float32Col(shape=ped.shape) 

86 } 

87 

88 # magic to create a description from a dictionary 

89 description_pedestal = type('description columns_dict_pedestal', (tables.IsDescription,), columns_dict_pedestal) 

90 

91 table_pedestal = hfile_out.create_table(ped_group, 'tel_001', description_pedestal, 

92 "Table of the pedestal for high and low gain", expectedrows=1, chunkshape=1) 

93 

94 # and lastly, add the row as always 

95 tab_ped_for_entry = table_pedestal.row 

96 tab_ped_for_entry["first_event_id"] = np.uint64(0) 

97 tab_ped_for_entry["last_event_id"] = np.uint64(1) 

98 tab_ped_for_entry["pedestal"] = ped 

99 tab_ped_for_entry.append() 

100 

101 hfile_gain_ped.close() 

102 

103 

104def update_pixel_order(hfile_out, pix_order): 

105 """ 

106 Copies to the final h5 output file the order of pixels of the camera (injection tables; position [x] in array 

107 corresponds to pixel Y in the camera). 

108 

109 Once the modules is installed, this file will ALWAYS be at 

110 $PATH/hiperta_stream/config/LST-1.1.Run00442.0000_pixel_order_bin.npy 

111 

112 hfile_out : obj 

113 hdf5 output file to be created 

114 pix_order : str 

115 Path to file that contains the injection table 

116 

117 """ 

118 table_pix_order = np.fromfile(pix_order, dtype=np.uint16) 

119 

120 # update table, we kill it, then we ask 

121 pix_order_group = hfile_out.root.configuration.instrument.telescope.camera.pixel_order 

122 pix_order_table = pix_order_group.tel_001 

123 hfile_out.remove_node(pix_order_table) 

124 

125 # And add the new table at same place 

126 hfile_out.create_array(pix_order_group, 'tel_001', table_pix_order, 'Pixel order of the Camera.') 

127 

128 

129def update_camera_geometry(hfile_out): 

130 """ 

131 Update the camera geometry with the correct one taken from ctapipe_io_lst 

132 

133 :param hfile_out: obj 

134 hdf5 output file to be created 

135 """ 

136 try: 

137 from ctapipe_io_lst import load_camera_geometry 

138 geometry = load_camera_geometry() 

139 

140 tabX = geometry.pix_x.value 

141 tabY = geometry.pix_y.value 

142 tabId = geometry.pix_id.value 

143 tabArea = geometry.pix_area.value 

144 nbPixel = geometry.n_pixels 

145 except: 

146 from hiperta_stream.dataset import get 

147 

148 tabX = np.fromfile(get('lst_proto_cam_pix_x.bin'), dtype=np.float32) 

149 tabY = np.fromfile(get('lst_proto_cam_pix_y.bin'), dtype=np.float32) 

150 tabId = np.fromfile(get('lst_proto_cam_pix_id.bin'), dtype=np.uint16) 

151 tabArea = np.fromfile(get('lst_proto_cam_pix_area.bin'), dtype=np.float32) 

152 nbPixel = tabArea.size 

153 

154 lstcam_table = hfile_out.root.configuration.instrument.telescope.camera.geometry_LSTCam 

155 

156 hfile_out.remove_node(lstcam_table) 

157 # Remember to pass the parent group !! 

158 new_lstcam_table = hfile_out.create_table( 

159 hfile_out.root.configuration.instrument.telescope.camera, "geometry_LSTCam", CameraGeometry, 

160 "LST camera geometry", expectedrows=nbPixel 

161 ) 

162 

163 new_lstcam_row = new_lstcam_table.row 

164 for pix_area, pix_id, pix_x, pix_y in zip(tabArea, tabId, tabX, tabY): 

165 new_lstcam_row['pix_area'] = pix_area 

166 new_lstcam_row['pix_id'] = pix_id 

167 new_lstcam_row['pix_x'] = pix_x 

168 new_lstcam_row['pix_y'] = pix_y 

169 new_lstcam_row.append() 

170 

171 

172def main(): 

173 parser = argparse.ArgumentParser(description="Create hdf5 configuration files for hiperta_stream ") 

174 

175 parser.add_argument('--gain_pedestal', '-g', action='store', type=str, 

176 dest='gain_pedestal', 

177 help='Gain and pedestal hdf5 files. ', 

178 required=True 

179 ) 

180 

181 parser.add_argument('--pixel_order', '-p', action='store', type=str, 

182 dest='pixel_order', 

183 help='Path to the file that contains the pixel injection table ( created with ' 

184 '`rta_get_zfits_pix_order`).\n' 

185 'NOTE: In case of an URGENT/EMERGENCY value, an example file can be found at ' 

186 '$INSTALL_PATH/hiperta_stream/dataset/LST-1.1.Run00442.0000_pixel_order_bin.npy', 

187 required=True 

188 ) 

189 

190 parser.add_argument('--config_file', '-c', action='store', type=str, 

191 dest='config_file', 

192 help='Path to the file that contains the `/configuration` node (gain, pedestal, pix position,' 

193 'geometry ...) - stored in the config submodule of this project\n' 

194 'DEFAULT: $INSTALL_PATH/hiperta_stream/dataset/default_configuration.h5', 

195 default=None 

196 ) 

197 

198 parser.add_argument('--output_file', '-o', action='store', type=str, 

199 dest='output_file', 

200 help='Output filename.', 

201 default='./base_structure_hdf5.h5' 

202 ) 

203 

204 parser.add_argument('--offset', '-s', action='store', type=float, 

205 dest='sample_offset', 

206 help='Offset of the pedestal.', 

207 required=False, 

208 default=400 

209 ) 

210 

211 args = parser.parse_args() 

212 

213 hout = tables.open_file(args.output_file, 'w') 

214 if args.config_file is None: 

215 configuration_file = resource_filename('hiperta_stream', 'dataset/default_configuration.h5') 

216 else: 

217 configuration_file = args.config_file 

218 hin = tables.open_file(configuration_file, 'r') 

219 

220 # Copy the configuration node 

221 hout.copy_node(hin.root.configuration, newparent=hout.root, recursive=True) 

222 hin.close() 

223 

224 update_calibration_data(hout, args.gain_pedestal, args.sample_offset) 

225 

226 update_pixel_order(hout, args.pixel_order) 

227 update_camera_geometry(hout) 

228 

229 hout.close() 

230 

231 

232if __name__ == '__main__': 

233 main()