def __init__(self, **kwargs): """Waveform peak finder wrapper. - wf digitizer channels (0,1,2,3,4) should be ordered for u1,u2,v1,v2[,w1,w2],mcp, respectively """ logger.debug(gu.str_kwargs(kwargs, title='WFPeaks input parameters:')) self.set_wf_peak_finder_parameters(**kwargs) self._wfs_old = None
def calib_on_data(**kwargs): OSQRT3 = 1. / sqrt(3.) CTYPE_HEX_CONFIG = 'hex_config' CTYPE_HEX_TABLE = 'hex_table' print(usage()) #SRCCHS #DSNAME = kwargs.get('dsname', '/reg/g/psdm/detector/data2_test/xtc/data-amox27716-r0100-acqiris-e000100.xtc2') COMMAND = kwargs.get('command', 0) IFNAME = kwargs.get( 'ifname', '/reg/g/psdm/detector/data_test/hdf5/amox27716-r0100-e060000-single-node.h5' ) DETNAME = kwargs.get('detname', 'tmo_hexanode') EVSKIP = kwargs.get('evskip', 0) EVENTS = kwargs.get('events', 1000000) + EVSKIP OFPREFIX = kwargs.get('ofprefix', './figs-hexanode/plot') NUM_CHANNELS = kwargs.get('numchs', 5) NUM_HITS = kwargs.get('numhits', 16) calibtab = kwargs.get('calibtab', None) calibcfg = kwargs.get('calibcfg', None) PLOT_HIS = kwargs.get('plot_his', True) SAVE_HIS = kwargs.get('save_his', False) VERBOSE = kwargs.get('verbose', False) print(gu.str_kwargs(kwargs, title='input parameters:')) sp.set_parameters(**kwargs) # save parameters in store for graphics #===================== file = open_input_h5file(IFNAME) #===================== CALIBTAB = calibtab #if calibtab is not None else file.find_calib_file(type=CTYPE_HEX_TABLE) CALIBCFG = calibcfg #if calibcfg is not None else file.find_calib_file(type=CTYPE_HEX_CONFIG) #===================== print('events in file : %s' % file.h5ds_nevents) print('start time : %s' % file.start_time()) print('stop time : %s' % file.stop_time()) print('tdc_resolution : %s' % file.tdc_resolution()) print('CALIBTAB : %s' % CALIBTAB) print('CALIBCFG : %s' % CALIBCFG) #print('file calib_dir : %s' % file.calib_dir()) #print('file calib_src : %s' % file.calib_src()) #print('file calib_group : %s' % file.calib_group()) #print('file ctype_dir : %s' % file.calibtype_dir()) # // The "command"-value is set in the first line of "sorter.txt" # // 0 = only convert to new file format # // 1 = sort and write new file # // 2 = calibrate fv, fw, w_offset # // 3 = create calibration table files # // create the sorter: sorter = hexanode.py_sort_class() status, command_cfg, offset_sum_u, offset_sum_v, offset_sum_w, w_offset, pos_offset_x, pos_offset_y=\ hexanode.py_read_config_file(CALIBCFG.encode(), sorter) #command = COMMAND # command_cfg command = command_cfg print('read_config_file status, COMMAND, offset_sum_u, offset_sum_v, offset_sum_w, w_offset, pos_offset_x, pos_offset_y=',\ status, command, offset_sum_u, offset_sum_v, offset_sum_w, w_offset, pos_offset_x, pos_offset_y) if not status: print("WARNING: can't read config file %s" % fname_cfg) del sorter sys.exit(0) print('use_sum_correction', sorter.use_sum_correction) print('use_pos_correction HEX ONLY', sorter.use_pos_correction) if sorter is not None: if sorter.use_sum_correction or sorter.use_pos_correction: status = hexanode.py_read_calibration_tables( CALIBTAB.encode(), sorter) if command == -1: print("no config file was read. Nothing to do.") if sorter is not None: del sorter sys.exit(0) Cu1 = sorter.cu1 Cu2 = sorter.cu2 Cv1 = sorter.cv1 Cv2 = sorter.cv2 Cw1 = sorter.cw1 Cw2 = sorter.cw2 Cmcp = sorter.cmcp print("Numeration of channels - u1:%i u2:%i v1:%i v2:%i w1:%i w2:%i mcp:%i"%\ (Cu1, Cu2, Cv1, Cv2, Cw1, Cw2, Cmcp)) #inds_of_channels = (Cu1, Cu2, Cv1, Cv2, Cw1, Cw2) #incr_of_consistence = ( 1, 2, 4, 8, 16, 32) inds_of_channels = (Cu1, Cu2, Cv1, Cv2, Cmcp) incr_of_consistence = (1, 2, 4, 8, 16) inds_incr = list(zip(inds_of_channels, incr_of_consistence)) #print("chanel increments:", inds_incr) #===================== #===================== #===================== print("init sorter... ") tdc_ns = np.zeros((NUM_CHANNELS, NUM_HITS), dtype=np.float64) number_of_hits = np.zeros((NUM_CHANNELS, ), dtype=np.int32) sorter.set_tdc_resolution_ns(file.tdc_resolution()) sorter.set_tdc_array_row_length(NUM_HITS) sorter.set_count(number_of_hits) sorter.set_tdc_pointer(tdc_ns) #sorter.set_use_reflection_filter_on_u1(False) # Achim recommended False #sorter.set_use_reflection_filter_on_u2(False) if command >= 2: sorter.create_scalefactors_calibrator(True,\ sorter.runtime_u,\ sorter.runtime_v,\ sorter.runtime_w, 0.78,\ sorter.fu, sorter.fv, sorter.fw) error_code = sorter.init_after_setting_parameters() if error_code: print("sorter could not be initialized\n") error_text = sorter.get_error_text(error_code, 512) print('Error %d: %s' % (error_code, error_text)) sys.exit(0) print("Calibration factors:\n f_U (mm/ns) =%f\n f_V (mm/ns) =%f\n f_W (mm/ns) =%f\n Offset on layer W (ns) =%f\n"%\ (2*sorter.fu, 2*sorter.fv, 2*sorter.fw, w_offset)) print("ok for sorter initialization\n") create_output_directory(OFPREFIX) print("reading event data... \n") evnum = 0 t_sec = time() t1_sec = time() while file.next_event(): evnum = file.event_number() if evnum < EVSKIP: continue if evnum > EVENTS: break if gu.do_print(evnum): t1 = time() print('Event: %06d, dt(sec): %.3f' % (evnum, t1 - t1_sec)) t1_sec = t1 # //if (event_counter%10000 == 0) {if (my_kbhit()) break;} # //================================== # // TODO by end user: # // Here you must read in a data block from your data file # // and fill the array tdc_ns[][] and number_of_hits[] #nhits = np.zeros((NUMBER_OF_CHANNELS,), dtype=np.int32) file.get_number_of_hits_array(number_of_hits, maxvalue=NUM_HITS) if file.error_flag(): error_text = file.get_error_text(file.error_flag()) print("file Error %d: %s" % (file.error_flag(), error_text)) sys.exit(0) if VERBOSE: print('====raw number_of_hits_array', number_of_hits[:]) #number_of_hits = np.array([n if n<NUM_HITS else NUM_HITS for n in number_of_hits]) #if VERBOSE : print(' number_of_hits_array constrained ', number_of_hits[:8]) file.get_tdc_data_array(tdc_ns, maxsize=NUM_HITS) if file.error_flag(): error_text = file.get_error_text(file.error_flag()) print("file Error %d: %s" % (file.error_flag(), error_text)) sys.exit(0) conds = number_of_hits[:5] == 0 if conds.any(): continue # // apply conversion to ns # if False : # file returns tdc_ns already in [ns] # tdc_ns *= file.tdc_resolution() # //================================== if sp.PLOT_NHITS: sp.lst_nhits_u1.append(number_of_hits[Cu1]) sp.lst_nhits_u2.append(number_of_hits[Cu2]) sp.lst_nhits_v1.append(number_of_hits[Cv1]) sp.lst_nhits_v2.append(number_of_hits[Cv2]) #sp.lst_nhits_w1 .append(number_of_hits[Cw1]) #sp.lst_nhits_w2 .append(number_of_hits[Cw2]) sp.lst_nhits_mcp.append(number_of_hits[Cmcp]) if sp.PLOT_TIME_CH: sp.lst_u1.append(tdc_ns[Cu1, 0]) sp.lst_u2.append(tdc_ns[Cu2, 0]) sp.lst_v1.append(tdc_ns[Cv1, 0]) sp.lst_v2.append(tdc_ns[Cv2, 0]) #sp.lst_w1 .append(tdc_ns[Cw1,0]) #sp.lst_w2 .append(tdc_ns[Cw2,0]) sp.lst_mcp.append(tdc_ns[Cmcp, 0]) if sp.PLOT_REFLECTIONS: if number_of_hits[Cu2] > 1: sp.lst_refl_u1.append(tdc_ns[Cu2, 1] - tdc_ns[Cu1, 0]) if number_of_hits[Cu1] > 1: sp.lst_refl_u2.append(tdc_ns[Cu1, 1] - tdc_ns[Cu2, 0]) if number_of_hits[Cv2] > 1: sp.lst_refl_v1.append(tdc_ns[Cv2, 1] - tdc_ns[Cv1, 0]) if number_of_hits[Cv1] > 1: sp.lst_refl_v2.append(tdc_ns[Cv1, 1] - tdc_ns[Cv2, 0]) #if number_of_hits[Cw2]>1 : sp.lst_refl_w1.append(tdc_ns[Cw2,1] - tdc_ns[Cw1,0]) #if number_of_hits[Cw1]>1 : sp.lst_refl_w2.append(tdc_ns[Cw1,1] - tdc_ns[Cw2,0]) #--------- preserve RAW time sums #time_sum_u = deepcopy(tdc_ns[Cu1,0] + tdc_ns[Cu2,0] - 2*tdc_ns[Cmcp,0]) #deepcopy(...) #time_sum_v = deepcopy(tdc_ns[Cv1,0] + tdc_ns[Cv2,0] - 2*tdc_ns[Cmcp,0]) time_sum_u = tdc_ns[Cu1, 0] + tdc_ns[Cu2, 0] - 2 * tdc_ns[Cmcp, 0] time_sum_v = tdc_ns[Cv1, 0] + tdc_ns[Cv2, 0] - 2 * tdc_ns[Cmcp, 0] time_sum_w = 0 #tdc_ns[Cw1,0] + tdc_ns[Cw2,0] - 2*tdc_ns[Cmcp,0] #print("RAW time_sum_u, time_sum_v:", time_sum_u, time_sum_v) #--------- if VERBOSE: print_tdc_ns(tdc_ns, cmt=' TDC raw data ') if sorter.use_hex: # shift the time sums to zero: sorter.shift_sums(+1, offset_sum_u, offset_sum_v, offset_sum_w) #shift layer w so that the middle lines of all layers intersect in one point: sorter.shift_layer_w(+1, w_offset) else: # shift the time sums to zero: sorter.shift_sums(+1, offset_sum_u, offset_sum_v) if VERBOSE: print_tdc_ns(tdc_ns, cmt=' TDC after shift_sums ') # shift all signals from the anode so that the center of the detector is at x=y=0: sorter.shift_position_origin(+1, pos_offset_x, pos_offset_y) sorter.feed_calibration_data( True, w_offset ) # for calibration of fv, fw, w_offset and correction tables if VERBOSE: print_tdc_ns(tdc_ns, cmt=' TDC after feed_calibration_data ') #print('map_is_full_enough', hexanode.py_sorter_scalefactors_calibration_map_is_full_enough(sorter)) # NOT VALID FOR QUAD #sfco = hexanode.py_scalefactors_calibration_class(sorter) # NOT FOR QUAD # break loop if statistics is enough #if sfco : # if sfco.map_is_full_enough() : # print('sfo.map_is_full_enough(): %s event number: %06d' % (sfco.map_is_full_enough(), evnum)) # break #if sp.PLOT_XY_RESOLUTION : # #print(" binx: %d biny: %d resolution(FWHM): %.6f" % (sfco.binx, sfco.biny, sfco.detector_map_resol_FWHM_fill)) # if sfco.binx>=0 and sfco.biny>=0 : # sp.lst_binx.append(sfco.binx) # sp.lst_biny.append(sfco.biny) # sp.lst_resol_fwhm.append(sfco.detector_map_resol_FWHM_fill) # Sort the TDC-Data and reconstruct missing signals and apply the time-sum- and NL-correction. # number_of_particles is the number of reconstructed particles number_of_particles = sorter.sort() if command == 1 else\ sorter.run_without_sorting() #file.get_tdc_data_array(tdc_ns, NUM_HITS) if VERBOSE: print(' (un/)sorted number_of_hits_array', number_of_hits[:8]) if VERBOSE: print_tdc_ns(tdc_ns, cmt=' TDC sorted data ') if VERBOSE: print(" Event %5i number_of_particles: %i" % (evnum, number_of_particles)) for i in range(number_of_particles): #### IT DID NOT WORK ON LCLS2 because pointer was deleted in py_hit_class.__dealloc__ hco = hexanode.py_hit_class(sorter, i) print(" p:%2i x:%7.3f y:%7.3f t:%7.3f met:%d" % (i, hco.x, hco.y, hco.time, hco.method)) #print_tdc_ns(tdc_ns, cmt=' TDC sorted data ') #print(' XXX sorter.time_list', sorter.t_list()) if sp.PLOT_NHITS: sp.lst_nparts.append(number_of_particles) # Discards most of events in command>1 #===================== if number_of_particles < 1: continue #===================== # // TODO by end user..." #--------- u_ns = tdc_ns[Cu1, 0] - tdc_ns[Cu2, 0] v_ns = tdc_ns[Cv1, 0] - tdc_ns[Cv2, 0] w_ns = 0 #tdc_ns[Cw1,0] - tdc_ns[Cw2,0] u = u_ns * sorter.fu v = v_ns * sorter.fv w = 0 #(w_ns + w_offset) * sorter.fw Xuv = u Xuw = 0 #u Xvw = 0 #v + w Yuv = v #(u - 2*v)*OSQRT3 Yuw = 0 #(2*w - u)*OSQRT3 Yvw = 0 # (w - v)*OSQRT3 dX = 0 # Xuv - Xvw dY = 0 # Yuv - Yvw dR = sqrt(dX * dX + dY * dY) time_sum_u_corr = tdc_ns[Cu1, 0] + tdc_ns[Cu2, 0] - 2 * tdc_ns[Cmcp, 0] time_sum_v_corr = tdc_ns[Cv1, 0] + tdc_ns[Cv2, 0] - 2 * tdc_ns[Cmcp, 0] time_sum_w_corr = 0 #tdc_ns[Cw1,0] + tdc_ns[Cw2,0] - 2*tdc_ns[Cmcp,0] #--------- if sp.PLOT_UVW or sp.PLOT_CORRELATIONS: sp.lst_u_ns.append(u_ns) sp.lst_v_ns.append(v_ns) sp.lst_w_ns.append(w_ns) sp.lst_u.append(u) sp.lst_v.append(v) sp.lst_w.append(w) if sp.PLOT_TIME_SUMS or sp.PLOT_CORRELATIONS: sp.lst_time_sum_u.append(time_sum_u) sp.lst_time_sum_v.append(time_sum_v) sp.lst_time_sum_w.append(time_sum_w) sp.lst_time_sum_u_corr.append(time_sum_u_corr) sp.lst_time_sum_v_corr.append(time_sum_v_corr) sp.lst_time_sum_w_corr.append(time_sum_w_corr) if sp.PLOT_XY_COMPONENTS: sp.lst_Xuv.append(Xuv) sp.lst_Xuw.append(Xuw) sp.lst_Xvw.append(Xvw) sp.lst_Yuv.append(Yuv) sp.lst_Yuw.append(Yuw) sp.lst_Yvw.append(Yvw) hco = hexanode.py_hit_class(sorter, 0) if sp.PLOT_MISC: sp.list_dr.append(dR) # fill Consistence Indicator consistenceIndicator = 0 for (ind, incr) in inds_incr: if number_of_hits[ind] > 0: consistenceIndicator += incr sp.lst_consist_indicator.append(consistenceIndicator) sp.lst_rec_method.append(hco.method) #print('reconstruction method %d' % hco.method) if sp.PLOT_XY_2D: # fill 2-d images x1, y1 = hco.x, hco.y x2, y2 = (-10, -10) if number_of_particles > 1: hco2 = hexanode.py_hit_class(sorter, 1) x2, y2 = hco2.x, hco2.y ix1, ix2, ixuv, ixuw, ixvw = sp.img_x_bins.bin_indexes( (x1, x2, Xuv, Xuw, Xvw)) iy1, iy2, iyuv, iyuw, iyvw = sp.img_y_bins.bin_indexes( (y1, y2, Yuv, Yuw, Yvw)) sp.img_xy_1[iy1, ix1] += 1 sp.img_xy_2[iy2, ix2] += 1 sp.img_xy_uv[iyuv, ixuv] += 1 sp.img_xy_uw[iyuw, ixuw] += 1 sp.img_xy_vw[iyvw, ixvw] += 1 if sp.PLOT_PHYSICS: if number_of_hits[Cmcp] > 1: #t0, t1 = tdc_ns[Cmcp,:2] #it0, it1 = sp.t_ns_bins.bin_indexes((t0, t1)) #sp.t1_vs_t0[it1, it0] += 1 #ix, iy = sp.x_mm_bins.bin_indexes((Xuv,Yuv)) #sp.x_vs_t0[ix, it0] += 1 #sp.y_vs_t0[iy, it0] += 1 #print(" Event %5i number_of_particles: %i" % (evnum, number_of_particles)) #for i in range(number_of_particles) : # hco = hexanode.py_hit_class(sorter, i) # #print(" p:%2i x:%7.3f y:%7.3f t:%7.3f met:%d" % (i, hco.x, hco.y, hco.time, hco.method)) # x,y,t = hco.x, hco.y, hco.time # r = sqrt(x*x+y*y) # if x<0 : r=-r # ir = sp.r_mm_bins.bin_indexes((r,)) # it = sp.t_ns_bins.bin_indexes((t,)) # sp.r_vs_t[ir, it] += 1 for x, y, r, t in sorter.xyrt_list(): irx, iry = sp.r_mm_bins.bin_indexes( (r if x > 0 else -r, r if y > 0 else -r)) it = sp.t_ns_bins.bin_indexes((t, )) sp.rsx_vs_t[irx, it] += 1 sp.rsy_vs_t[iry, it] += 1 times = sorter.t_list() tinds = sp.t_ns_bins.bin_indexes( times) # INDEXES SHOULD BE np.array #print_ndarr(times, '\n XXX times') #print_ndarr(tinds, '\n XXX tinds') # accumulate times in the list for t in times: sp.lst_t_all.append(t) # accumulate times directly in histogram to evaluate average sp.t_all[tinds] += 1 # accumulate times in correlation matrix for i in tinds: sp.ti_vs_tj[i, tinds] += 1 # // write the results into a new data file. # // the variable "number_of_particles" contains the number of reconstructed particles. # // the x and y (in mm) and TOF (in ns) is stored in the array sorter->output_hit_array: # // for the i-th particle (i starts from 0): # // hco= hexanode.py_hit_class(sorter, i) # // hco.x, hco.y, hco.time # // for each particle you can also retrieve the information about how the particle # // was reconstructed (tog et some measure of the confidence): # // hco.method # end of the while loop print("end of the while loop... \n") if command == 2: print("sorter.do_calibration()... for command=2") sorter.do_calibration() print("ok - after do_calibration") # QUAD SHOULD NOT USE: scalefactors_calibration_class #sfco = hexanode.py_scalefactors_calibration_class(sorter) #if sfco : # print("Good calibration factors are:\n f_U =%f\n f_V =%f\n f_W =%f\n Offset on layer W=%f\n"%\ # (2*sorter.fu, 2*sfco.best_fv, 2*sfco.best_fw, sfco.best_w_offset)) # # print('CALIBRATION: These parameters and time sum offsets from histograms should be set in the file\n %s' % CALIBCFG) if command == 3: # generate and print(correction tables for sum- and position-correction CALIBTAB = calibtab if calibtab is not None else\ file.make_calib_file_path(type=CTYPE_HEX_TABLE) print("creating calibration table in file: %s" % CALIBTAB) status = hexanode.py_create_calibration_tables(CALIBTAB.encode(), sorter) print("CALIBRATION: finished creating calibration tables: status %s" % status) #===================== #sys.exit('TEST EXIT in QuadCalib') #===================== print("consumed time (sec) = %.6f\n" % (time() - t_sec)) if sorter is not None: del sorter if PLOT_HIS: plot_histograms(prefix=OFPREFIX, do_save=SAVE_HIS, hwin_x0y0=(0, 0)) show()