def compute_baseline_histogram(files, filename, max_events=None, pixel_id=None, event_types=None, disable_bar=False): if os.path.exists(filename) and len(files) == 0: baseline_histo = Histogram1D.load(filename) return baseline_histo else: if pixel_id is None: pixel_id = convert_pixel_args(None) n_pixels = len(pixel_id) events = calibration_event_stream(files, pixel_id=pixel_id, max_events=max_events, disable_bar=disable_bar) baseline_histo = Histogram1D( data_shape=(n_pixels, ), bin_edges=np.arange(0, 4096, 1 / 16), ) for event in events: if event_types and event.event_type not in event_types: continue baseline_histo.fill(event.data.digicam_baseline.reshape(-1, 1)) baseline_histo.save(filename) return baseline_histo
def compute_max_histo(files, histo_filename, pixel_id, max_events, integral_width, shift, baseline): n_pixels = len(pixel_id) if not os.path.exists(histo_filename): events = calibration_event_stream(files, pixel_id=pixel_id, max_events=max_events) # events = compute_baseline_with_min(events) events = fill_baseline(events, baseline) events = subtract_baseline(events) events = find_pulse_with_max(events) events = compute_charge(events, integral_width, shift) max_histo = Histogram1D( data_shape=(n_pixels, ), bin_edges=np.arange(-4095 * integral_width, 4095 * integral_width), ) for event in events: max_histo.fill(event.data.reconstructed_charge) max_histo.save(histo_filename) return max_histo else: max_histo = Histogram1D.load(histo_filename) return max_histo
def compute(files, pixel_id, max_events, pulse_indices, integral_width, shift, bin_width, output_path, charge_histo_filename='charge_histo.pk', amplitude_histo_filename='amplitude_histo.pk', save=True): amplitude_histo_path = os.path.join(output_path, amplitude_histo_filename) charge_histo_path = os.path.join(output_path, charge_histo_filename) if os.path.exists(charge_histo_path) and save: raise IOError('File {} already exists'.format(charge_histo_path)) if os.path.exists(amplitude_histo_path) and save: raise IOError('File {} already exists'.format(amplitude_histo_path)) n_pixels = len(pixel_id) events = calibration_event_stream(files, pixel_id=pixel_id, max_events=max_events) # events = compute_baseline_with_min(events) events = fill_digicam_baseline(events) events = subtract_baseline(events) # events = find_pulse_with_max(events) events = fill_pulse_indices(events, pulse_indices) events = compute_charge(events, integral_width, shift) events = compute_amplitude(events) charge_histo = Histogram1D(data_shape=(n_pixels, ), bin_edges=np.arange(-4095 * integral_width, 4096 * integral_width, bin_width), axis_name='reconstructed charge ' '[LSB $\cdot$ ns]') amplitude_histo = Histogram1D(data_shape=(n_pixels, ), bin_edges=np.arange(-4095, 4096, 1), axis_name='reconstructed amplitude ' '[LSB]') for event in events: charge_histo.fill(event.data.reconstructed_charge) amplitude_histo.fill(event.data.reconstructed_amplitude) if save: charge_histo.save(charge_histo_path) amplitude_histo.save(amplitude_histo_path) return amplitude_histo, charge_histo
def compute_spe(files, histo_filename, pixel_id, baseline, max_events, integral_width, shift, pulse_finder_threshold, debug=False): if not os.path.exists(histo_filename): n_pixels = len(pixel_id) events = calibration_event_stream(files, max_events=max_events, pixel_id=pixel_id) events = fill_baseline(events, baseline) events = subtract_baseline(events) # events = find_pulse_1(events, 0.5, 20) # events = find_pulse_2(events, widths=[5, 6], threshold_sigma=2) events = find_pulse_fast(events, threshold=pulse_finder_threshold) # events = find_pulse_fast_2(events, threshold=pulse_finder_threshold, # min_dist=3) # events = find_pulse_correlate(events, # threshold=pulse_finder_threshold) # events = find_pulse_gaussian_filter(events, # threshold=pulse_finder_threshold) # events = find_pulse_wavelets(events, widths=[4, 5, 6], # threshold_sigma=2) events = compute_charge(events, integral_width=integral_width, shift=shift) # events = compute_amplitude(events) # events = fit_template(events) # events = compute_full_waveform_charge(events) spe_histo = Histogram1D(data_shape=(n_pixels, ), bin_edges=np.arange(-4095 * 50, 4095 * 50)) for event in events: spe_histo.fill(event.data.reconstructed_charge) spe_histo.save(histo_filename) return spe_histo else: spe_histo = Histogram1D.load(histo_filename) return spe_histo
def main( input_file, output_file, max_events=None, pixel_id=[...], integral_width=7, shift=0, pulse_finder_threshold=3., use_digicam_baseline=False, ): baseline_span_ala_andrii = Histogram1D(data_shape=(1296, ), bin_edges=np.arange(0, 50, 1)) random_charge = Histogram1D(data_shape=(1296, ), bin_edges=np.arange(-50, 1000, 1)) if not use_digicam_baseline: events = calibration_event_stream(input_file, pixel_id=pixel_id, max_events=max_events) raw_histo = build_raw_data_histogram(events) save_container(raw_histo, output_file, 'histo', 'raw_lsb') events = calibration_event_stream(input_file, max_events=max_events, pixel_id=pixel_id) events = fill_histogram(events, 0, raw_histo) events = fill_electronic_baseline(events) events = subtract_baseline(events) else: events = calibration_event_stream(input_file, max_events=max_events, pixel_id=pixel_id) events = subtract_digicam_baseline(events) events = fill_baseline_span_ala_andrii(events, baseline_span_ala_andrii) events = fill_random_charge(events, random_charge, 5) for _ in events: pass save_container( CalibrationHistogramContainer().from_histogram( baseline_span_ala_andrii), output_file, 'histo', 'baseline_span_ala_andrii') save_container( CalibrationHistogramContainer().from_histogram(random_charge), output_file, 'histo', 'random_charge')
def compute(files, max_events, pixel_id, output_path, n_samples, filename='timing_histo.pk', save=True, time_method=compute_time_from_max): filename = os.path.join(output_path, filename) if os.path.exists(filename) and save: raise IOError('The file {} already exists \n'.format(filename)) n_pixels = len(pixel_id) events = calibration_event_stream(files, pixel_id=pixel_id, max_events=max_events) events = time_method(events) timing_histo = Histogram1D(data_shape=(n_pixels, ), bin_edges=np.arange(0, n_samples * 4, 1), axis_name='reconstructed time [ns]') for i, event in enumerate(events): timing_histo.fill(event.data.reconstructed_time) if save: timing_histo.save(filename) return timing_histo
def compute(files, max_events, pixel_id, n_samples, ac_levels, filename='timing_histo.pk', save=True, time_method=compute_time_from_max): if os.path.exists(filename) and save: raise IOError('The file {} already exists \n'.format(filename)) elif os.path.exists(filename): return Histogram1D.load(filename) n_pixels = len(pixel_id) n_ac_levels = len(ac_levels) n_files = len(files) if n_ac_levels != n_files: raise IOError('Number of files = {} does not match number of DAC level' ' {}'.format(n_files, n_ac_levels)) timing_histo = Histogram1D( data_shape=( n_ac_levels, n_pixels, ), bin_edges=np.arange(0, n_samples * 4, 1), ) for i, file in tqdm(enumerate(files), total=n_ac_levels, desc='DAC level'): events = calibration_event_stream(file, pixel_id=pixel_id, max_events=max_events) events = time_method(events) for event in events: timing_histo.fill(event.data.reconstructed_time, indices=(i, )) if save: timing_histo.save(filename) return timing_histo
def get_bad_pixels(calib_file=None, nsigma_gain=5, nsigma_elecnoise=5, dark_histo=None, nsigma_dark=8, plot="none", output=None): bad_pix = np.array([], dtype=int) if calib_file is not None: with open(calib_file) as file: calibration_parameters = yaml.load(file) gain = np.array(calibration_parameters['gain']) elecnoise = np.array(calibration_parameters['sigma_e']) nan_mask = np.logical_or(~np.isfinite(gain), ~np.isfinite(elecnoise)) sigclip_gain = SigmaClip(sigma=nsigma_gain, iters=10, cenfunc=np.nanmean, stdfunc=np.nanstd) sigclip_elecnoise = SigmaClip(sigma=nsigma_elecnoise, iters=10, cenfunc=np.nanmean, stdfunc=np.nanstd) gain_mask = sigclip_gain(gain).mask elecnoise_mask = sigclip_elecnoise(elecnoise).mask bad_mask = np.logical_or(nan_mask, np.logical_or(gain_mask, elecnoise_mask)) bad_pix = np.where(bad_mask)[0] if output is not None: calibration_parameters['bad_pixels'] = bad_pix with open(output, 'w') as file: yaml.dump(calibration_parameters, file) if plot is not None: fig, (ax_gain, ax_elecnoise) = plt.subplots(2, 1) gain_bins = np.linspace(np.nanmin(gain), np.nanmax(gain), 100) ax_gain.hist(gain[~bad_mask], gain_bins, color='b') ax_gain.hist(gain[bad_mask], gain_bins, color='r') ax_gain.set_xlabel('integral gain [LSB p.e.$^{-1}$]') elecnoise_bins = np.linspace(np.nanmin(elecnoise), np.nanmax(elecnoise), 100) ax_elecnoise.hist(elecnoise[~bad_mask], elecnoise_bins, color='b') ax_elecnoise.hist(elecnoise[bad_mask], elecnoise_bins, color='r') ax_elecnoise.set_xlabel('electronic noise [LSB]') plt.tight_layout() if plot != "show": plt.savefig(plot) else: plt.show() plt.close(fig) if dark_histo is not None: dark_histo = Histogram1D.load(dark_histo) baseline = dark_histo.mean(method='mid') sigclip_dark = SigmaClip(sigma=nsigma_dark, iters=10, cenfunc=np.nanmean, stdfunc=np.nanstd) dark_mask = sigclip_dark(baseline).mask bad_dark = np.where(dark_mask)[0] bad_pix = np.unique(np.concatenate((bad_pix, bad_dark))) return bad_pix
def compute(files, max_events, filename): if os.path.exists(filename) and len(files) == 0: dt_histo = Histogram1D.load(filename) return dt_histo else: events = calibration_event_stream(files, max_events=max_events) dt_histo = Histogram1D( data_shape=(9, ), bin_edges=np.logspace(2, 9, 140), # in ns # bin_edges=np.arange(150, 400, 4), # in ns ) previous_time = np.zeros(9) * np.nan for event in events: typ = event.event_type local_time = event.data.local_time # in ns dt = local_time - previous_time[typ] # in ns if np.isfinite(previous_time[typ]): dt_histo.fill(dt, indices=(event.event_type, )) previous_time[typ] = local_time dt_histo.save(filename) print(filename, 'saved') return dt_histo
def build_raw_data_histogram(events): for count, event in tqdm(enumerate(events)): if count == 0: n_pixels = len(event.pixel_id) adc_histo = Histogram1D(data_shape=(n_pixels, ), bin_edges=np.arange(0, 4095, 1), axis_name='[LSB]') adc_histo.fill(event.data.adc_samples) return CalibrationHistogramContainer().from_histogram(adc_histo)
def compute(files, filename, max_events=None, pixel_id=None, event_types=None, disable_bar=False, baseline_subtracted=False): if os.path.exists(filename) and len(files) == 0: raw_histo = Histogram1D.load(filename) return raw_histo else: if pixel_id is None: pixel_id = convert_pixel_args(None) n_pixels = len(pixel_id) events = calibration_event_stream(files, pixel_id=pixel_id, max_events=max_events, disable_bar=disable_bar) if baseline_subtracted: bin_edges = np.arange(-100, 4095, 1) else: bin_edges = np.arange(0, 4095, 1) raw_histo = Histogram1D( data_shape=(n_pixels, ), bin_edges=bin_edges, ) for event in events: if event_types and event.event_type not in event_types: continue samples = event.data.adc_samples if baseline_subtracted: samples = samples - event.data.digicam_baseline[:, None] raw_histo.fill(samples) raw_histo.save(filename) return raw_histo
def make_and_draw_charge_histo(data, bins, label): bin_edges = np.linspace(np.min(data), np.max(data) + 1, bins) histogram = Histogram1D(bin_edges=bin_edges) histogram.fill(data) # Histogram display fig, ax = plt.subplots() histogram.draw(axis=ax, label=label, legend=False) text = histogram._write_info(()) anchored_text = AnchoredText(text, loc=5) ax.add_artist(anchored_text) # Formatting to use in the digicampipe fitting single mpe method histogram.data = histogram.data.reshape((1, 1, -1)) histogram.overflow = histogram.overflow.reshape((1, -1)) histogram.underflow = histogram.underflow.reshape((1, -1)) return fig, ax, histogram
def entry(): args = docopt(__doc__) files = args['<INPUT>'] max_events = convert_int(args['--max_events']) output_path = args['--output'] if not os.path.exists(output_path): raise IOError('Path {} for output does not ' 'exists \n'.format(output_path)) pixel_id = convert_pixel_args(args['--pixel']) dc_levels = convert_list_int(args['--dc_levels']) n_pixels = len(pixel_id) n_dc_levels = len(dc_levels) results_filename = 'baseline_shift_results.npz' results_filename = os.path.join(output_path, results_filename) # fmpe_results_filename = args['--gain'] # crosstalk = args['--crosstalk'] # templates = args['--template'] histo = Histogram1D(data_shape=(n_dc_levels, n_pixels), bin_edges=np.arange(0, 4096)) if args['--compute']: if n_dc_levels != len(files): raise ValueError('n_dc levels = {} != ' 'n_files = {}'.format(n_dc_levels, len(files))) baseline_mean = np.zeros((n_dc_levels, n_pixels)) baseline_std = np.zeros((n_dc_levels, n_pixels)) for i, file in tqdm(enumerate(files), desc='DC level', total=len(files)): events = calibration_event_stream(file, pixel_id=pixel_id, max_events=max_events) for count, event in enumerate(events): baseline_mean[i] += event.data.digicam_baseline baseline_std[i] += event.data.digicam_baseline**2 histo.fill(event.data.adc_samples, indices=(i, )) count += 1 baseline_mean[i] = baseline_mean[i] / count baseline_std[i] = baseline_std[i] / count baseline_std[i] = baseline_std[i] - baseline_mean[i]**2 baseline_std[i] = np.sqrt(baseline_std[i]) histo.save(os.path.join(output_path, 'raw_histo.pk')) np.savez(results_filename, baseline_mean=baseline_mean, baseline_std=baseline_std, dc_levels=dc_levels) if args['--fit']: data = dict(np.load(results_filename)) baseline_mean = data['baseline_mean'] baseline_std = data['baseline_std'] dc_levels = data['dc_levels'] gain = 5 template_area = 18 crosstalk = 0.08 bias_resistance = 10 * 1E3 cell_capacitance = 50 * 1E-15 baseline_shift = baseline_mean - baseline_mean[0] nsb_rate = gain * template_area / (baseline_shift * (1 - crosstalk)) nsb_rate = nsb_rate - cell_capacitance * bias_resistance nsb_rate = 1 / nsb_rate np.savez(results_filename, baseline_mean=baseline_mean, baseline_std=baseline_std, dc_levels=dc_levels, nsb_rate=nsb_rate, baseline_shift=baseline_shift) if args['--save_figures']: pass if args['--display']: data = dict(np.load(results_filename)) histo = Histogram1D.load(os.path.join(output_path, 'raw_histo.pk')) baseline_mean = histo.mean() baseline_std = histo.std() nsb_rate = data['nsb_rate'] print(baseline_mean.shape) histo.draw((0, 1)) histo.draw((49, 1)) plt.figure() plt.plot(dc_levels, baseline_mean) plt.xlabel('DC DAC level') plt.ylabel('Baseline mean [LSB]') plt.figure() plt.plot(dc_levels, baseline_std) plt.xlabel('DC DAC level') plt.ylabel('Baseline std [LSB]') plt.figure() plt.plot(nsb_rate, baseline_std) plt.xlabel('$f_{NSB}$ [GHz]') plt.ylabel('Baseline std [LSB]') plt.figure() plt.plot(baseline_mean, baseline_std) plt.xlabel('Baseline mean [LSB]') plt.ylabel('Baseline std [LSB]') plt.figure() plt.semilogy(dc_levels, nsb_rate) plt.xlabel('DC DAC level') plt.ylabel('$f_{NSB}$ [GHz]') plt.show() pass return
def entry(): args = docopt(__doc__) files = args['INPUT'] debug = args['--debug'] max_events = convert_max_events_args(args['--max_events']) output_path = args['OUTPUT'] if not os.path.exists(output_path): raise IOError('Path for output does not exists \n') pixel_id = convert_pixel_args(args['--pixel']) integral_width = int(args['--integral_width']) shift = int(args['--shift']) bin_width = int(args['--bin_width']) n_samples = int(args['--n_samples']) # TODO access this in a better way ! ac_levels = convert_dac_level(args['--ac_levels']) n_pixels = len(pixel_id) n_ac_levels = len(ac_levels) if n_ac_levels != len(files): raise ValueError('n_ac levels = {} != ' 'n_files = {}'.format(n_ac_levels, len(files))) if args['--compute']: amplitude = np.zeros((n_pixels, n_ac_levels)) charge = np.zeros((n_pixels, n_ac_levels)) time = np.zeros((n_pixels, n_ac_levels)) for i, (file, ac_level) in tqdm(enumerate(zip(files, ac_levels)), total=n_ac_levels, desc='DAC level', leave=False): timing_histo_filename = 'timing_histo_ac_level_{}.pk' \ ''.format(ac_level) charge_histo_filename = 'charge_histo_ac_level_{}.pk' \ ''.format(ac_level) amplitude_histo_filename = 'amplitude_histo_ac_level_{}.pk' \ ''.format(ac_level) timing_histo = timing.compute(file, max_events, pixel_id, output_path, n_samples, filename=timing_histo_filename, save=False) time[:, i] = timing_histo.mean() pulse_indices = time[:, i] // 4 amplitude_histo, charge_histo = compute( file, pixel_id, max_events, pulse_indices, integral_width, shift, bin_width, output_path, charge_histo_filename=charge_histo_filename, amplitude_histo_filename=amplitude_histo_filename, save=False) amplitude[:, i] = amplitude_histo.mean() charge[:, i] = charge_histo.mean() plt.figure() plt.plot(amplitude[0], charge[0]) plt.show() np.savez(os.path.join(output_path, 'mpe_results'), amplitude=amplitude, charge=charge, time=time, pixel_id=pixel_id, ac_levels=ac_levels) if args['--fit']: pass if args['--save_figures']: pass if args['--display']: amplitude_histo_path = os.path.join(output_path, 'amplitude_histo.pk') charge_histo_path = os.path.join(output_path, 'charge_histo.pk') charge_histo = Histogram1D.load(charge_histo_path) charge_histo.draw(index=(0, ), log=False, legend=False) amplitude_histo = Histogram1D.load(amplitude_histo_path) amplitude_histo.draw(index=(0, ), log=False, legend=False) plt.show() pass return
def entry(): args = docopt(__doc__) input_dir = convert_text(args['--input_dir']) output_dir = convert_text(args['--output_dir']) channel = convert_int(args['--channel']) initial_values_dir = convert_text(args['--initial_values_dir']) debug = args['--debug'] if args['digicampipe']: file_list = read.give_list_of_file(input_dir) yaml_list = read.give_list_of_file(initial_values_dir) file_list.sort() yaml_list.sort() print(file_list) print(yaml_list) fit_parameters = {} for k, f in enumerate(file_list): level = 'LVL_{}'.format(k) bias_voltage = float(re.findall('\d+\.\d+', f)[0]) print('Fitting charge') f = input_dir + '/' + f i_val = initial_values_dir + '/' + yaml_list[k] print('charge file :', f) print('initialization file :', i_val) with open(i_val) as file: init_parameters = yaml.load(file, Loader=yaml.FullLoader) print('Initial Fitting parameters', init_parameters) # We need this new format to make work our fit function, it was built that way temp_dict = {} for key, value in init_parameters.items(): temp_dict[key] = np.array([[value]]) init_parameters = temp_dict del temp_dict data = fit_single_mpe(f, ac_levels=[0], pixel_ids=[0], init_params=init_parameters, debug=True) temp_data = {} for key, value in data.items(): if key is not 'pixel_ids': temp_data[key] = (value[0][0]).tolist() temp_data['bias_voltage'] = bias_voltage fit_parameters[level] = temp_data print('fit_parameter', fit_parameters) fit_parameters_file = '{}/fit_parameters.yml'.format(output_dir) with open(fit_parameters_file, 'w') as file: yaml.dump(fit_parameters, file) print('END of the digicampipe fitter') if args['multigauss']: file_list = read.give_list_of_file(input_dir) file_list.sort() print(file_list) # Creating the dictionary fit_parameters = {} for k, f in enumerate(file_list): f = os.path.join(input_dir, f) bias_voltage = float(re.findall('\d+\.\d+', f)[0]) charge_histogram = Histogram1D.load(f) y_data = charge_histogram.data x_data = charge_histogram.bin_centers if debug: pdf_debug_histo_to_plot = PdfPages(os.path.join(output_dir, 'ch{}_debug_histo_to_plot_V{}.pdf'.format(bias_voltage, channel))) fig, (ax1, ax2) = plt.subplots(2, 1) charge_histogram.draw(axis=ax1, legend=False, label='histogram data') ax1.plot(x_data, y_data, '|', label='plotting of data', mec='tab:orange', mfc='tab:orange', markersize=12) ax1.set_xlabel('[LSB]') ax1.legend() ax2.plot(y_data, label='plotting of data', marker='|', color='tab:blue', mfc='tab:orange', mec='tab:orange', markersize=12) ax2.set_ylabel('count') ax2.set_xlabel('Index') ax2.legend() pdf_debug_histo_to_plot.savefig(fig) pdf_debug_histo_to_plot.close() plt.close(fig) # Automatizing the initial values guess # Find peaks: Gain # First approx, it will set us to the separation of to peaks idx_peaks, _ = find_peaks(y_data, height=20) delta_idx_peak = np.diff(idx_peaks) idx_peak_bis, _ = find_peaks(y_data, distance=delta_idx_peak[0], height=40) print('idx of peaks found', idx_peak_bis) print('Peaks found : ', len(idx_peak_bis)) if debug: pdf_debug_peaks_found = PdfPages(os.path.join(output_dir, 'ch_{}_debug_peaks_found_V{}.pdf'.format(bias_voltage, channel))) fig, (ax1, ax2) = plt.subplots(2, 1) ax1.plot(y_data, color='tab:blue', label='Integral charge') ax1.plot(idx_peaks, y_data[idx_peaks], color='tab:green', label='Peaks found : 1st round', marker='v', linestyle='None') ax1.set_xlabel('Index') ax1.set_ylabel('count') ax1.legend() ax2.plot(y_data, color='tab:blue', label='Integral charge') ax2.plot(idx_peak_bis, y_data[idx_peak_bis], color='tab:red', label='Peaks found : 2st round', marker='v', linestyle='None') ax2.set_xlabel('Index') ax2.set_ylabel('count') ax2.legend() pdf_debug_peaks_found.savefig(fig) pdf_debug_peaks_found.close() plt.close(fig) initial_values = [] # We can do better : fitting the first peak with a gaussian to extract initial parameters # Defining the first peak (peak zeros) # safe_zone expansion safe_zone = 3 idx_valley = np.argmin(y_data[idx_peak_bis[0]: idx_peak_bis[1]]) idx_valley += idx_peak_bis[0] interval = [0, idx_valley] y_peak = y_data[interval[0]: interval[1] + safe_zone] x_peak = np.arange(len(y_peak)) pdf_fit_peak = PdfPages(os.path.join(output_dir, 'ch{}_fit_peak_V{}.pdf'.format(bias_voltage, channel))) popt, pcov, fig = fit_gaussian_peak(x_peak, y_peak) pdf_fit_peak.savefig(fig) plt.show() initial_values.append(popt) # Defining the second peak # idx_valley is key since new fit will be shift by the quantity idx_valley (important for plot) interval = [idx_valley, idx_valley + delta_idx_peak[0]] y_peak = y_data[interval[0]: interval[-1] + safe_zone] x_peak = np.arange(len(y_peak)) popt, pcov, fig = fit_gaussian_peak(x_peak, y_peak, display_offset=interval[0]) popt[1] += interval[0] pdf_fit_peak.savefig(fig) plt.show() initial_values.append(popt) # Defining the third peak # idx_valley is key since new fit will be shift by the quantity idx_valley (important for plot) interval = [interval[0] + delta_idx_peak[0], interval[0] + 2*delta_idx_peak[0]] y_peak = y_data[interval[0]: interval[-1] + safe_zone] x_peak = np.arange(len(y_peak)) popt, pcov, fig = fit_gaussian_peak(x_peak, y_peak, display_offset=interval[0]) popt[1] += interval[0] pdf_fit_peak.savefig(fig) plt.show() initial_values.append(popt) pdf_fit_peak.close() print('Initial values gotten') initial_values = np.array(initial_values) amplitude = initial_values.T[0] x_first_peak = initial_values.T[1][0] gain = np.diff(initial_values.T[1])[0] sigma_e = initial_values.T[2][0] sigma_s = np.sqrt(initial_values.T[2][1]**2 - sigma_e**2) # Fitting the multi-gauss function of 3 peaks x_data = np.arange(len(y_data)) popt, pcov = curve_fit(multi_gauss, x_data, y_data, p0=[amplitude[0], amplitude[1], amplitude[2], x_first_peak, gain, sigma_e, sigma_s]) var = popt var_err = np.sqrt(np.diagonal(pcov)) text = write_multi_gaus_info(var, var_err) x_fit = np.linspace(x_data[0], x_data[-1], 1000) fig = plt.figure() gs = gridspec.GridSpec(2, 1, height_ratios=[3, 1]) ax0 = fig.add_subplot(gs[0]) ax0.plot(x_data, y_data, 'b-', label='data') ax0.plot(x_fit, multi_gauss(x_fit, *popt), 'g--', label='fit') ax0.plot(x_data, multi_gauss(x_data, amplitude[0], amplitude[1], amplitude[2], x_first_peak, gain, sigma_e, sigma_s), 'r*', label='Initial values', ms=2) ax0.set_ylabel('count') ax0.legend(loc=9) text_formula = 'y = $ \\sum_{k=0}^{N=2} A_k\\frac{1}{\sigma_k \sqrt{2 \pi}} e^{-(\\frac{x-\mu_k}{\sigma_k})}$\n' \ ' $\sigma_k^2 = \sigma_e^2 + k\sigma_s^2$' anchored_text = AnchoredText(text, loc=1, frameon=False) anchored_formula = AnchoredText(text_formula, loc=4, frameon=False) ax0.add_artist(anchored_text) ax0.add_artist(anchored_formula) ax1 = fig.add_subplot(gs[1], sharex=ax0) ax1.plot(x_data, (y_data - multi_gauss(x_data, *popt)) / y_data, marker='o', ms=4, linestyle='None', color='black') ax1.axhline(0, color='gray', linestyle='dashed') ax1.set_ylabel('Residual') ax1.set_xlabel('Index') print('Multi-Gauss fitted') pdf_fit_multigauss = PdfPages(os.path.join(output_dir, 'ch{}_fit_multigauss_V{}.pdf'.format(bias_voltage, channel))) pdf_fit_multigauss.savefig(fig) pdf_fit_multigauss.close() plt.show() plt.close(fig) # Creating the sub-dictionary level = 'LVL_{}'.format(k) temp_dict = {} temp_dict['bias_voltage'] = bias_voltage temp_dict['amplitude'] = np.sum(var[0:2]) temp_dict['mu_peak'] = var[3] temp_dict['gain'] = var[4] temp_dict['sigma_e'] = var[5] temp_dict['sigma_s'] = var[6] temp_dict['error_amplitude'] = np.sqrt(np.sum(var_err[0:2]**2)) temp_dict['error_mu_peak'] = var_err[3] temp_dict['error_gain'] = var_err[4] temp_dict['error_sigma_e'] = var_err[5] temp_dict['error_sigma_s'] = var_err[6] fit_parameters[level] = temp_dict del temp_dict print('Multi-Gauss fitter for voltage {} V done '.format(bias_voltage)) if debug: print('fit_parameter', fit_parameters) fit_parameters_file = os.path.join(output_dir, 'fit_parameters.yml') with open(fit_parameters_file, 'w') as file: yaml.dump(fit_parameters, file) print('Fitted parameters saved at : {}'.format(fit_parameters_file)) print('END of the Multi-Gauss fitter')
def compute(files, pixel_id, max_events, pulse_indices, integral_width, shift, bin_width, charge_histo_filename='charge_histo.pk', amplitude_histo_filename='amplitude_histo.pk', save=True): if os.path.exists(charge_histo_filename) and save: raise IOError('File {} already exists'.format(charge_histo_filename)) elif os.path.exists(charge_histo_filename): charge_histo = Histogram1D.load(charge_histo_filename) if os.path.exists(amplitude_histo_filename) and save: raise IOError( 'File {} already exists'.format(amplitude_histo_filename)) elif os.path.exists(amplitude_histo_filename): amplitude_histo = Histogram1D.load(amplitude_histo_filename) if (not os.path.exists(amplitude_histo_filename)) or \ (not os.path.exists(charge_histo_filename)): n_pixels = len(pixel_id) events = calibration_event_stream(files, pixel_id=pixel_id, max_events=max_events) # events = compute_baseline_with_min(events) events = fill_digicam_baseline(events) events = subtract_baseline(events) # events = find_pulse_with_max(events) events = fill_pulse_indices(events, pulse_indices) events = compute_charge(events, integral_width, shift) events = compute_amplitude(events) charge_histo = Histogram1D(data_shape=(n_pixels, ), bin_edges=np.arange(-40 * integral_width, 4096 * integral_width, bin_width)) amplitude_histo = Histogram1D(data_shape=(n_pixels, ), bin_edges=np.arange(-40, 4096, 1)) for event in events: charge_histo.fill(event.data.reconstructed_charge) amplitude_histo.fill(event.data.reconstructed_amplitude) if save: charge_histo.save(charge_histo_filename) amplitude_histo.save(amplitude_histo_filename) return amplitude_histo, charge_histo
def entry(): args = docopt(__doc__) files = args['<INPUT>'] debug = args['--debug'] max_events = convert_int(args['--max_events']) raw_histo_filename = args['--raw_histo_filename'] charge_histo_filename = args['--charge_histo_filename'] max_histo_filename = args['--max_histo_filename'] results_filename = args['--output'] pixel_id = convert_pixel_args(args['--pixel']) n_pixels = len(pixel_id) integral_width = int(args['--integral_width']) shift = int(args['--shift']) pulse_finder_threshold = float(args['--pulse_finder_threshold']) n_samples = int(args['--n_samples']) # TODO access this in a better way ! estimated_gain = 20 ncall = int(args['--ncall']) if args['--compute']: raw_histo = raw.compute(files, max_events=max_events, pixel_id=pixel_id, filename=raw_histo_filename) baseline = raw_histo.mode() compute_max_histo(files, max_histo_filename, pixel_id, max_events, integral_width, shift, baseline) compute_spe(files, charge_histo_filename, pixel_id, baseline, max_events, integral_width, shift, pulse_finder_threshold, debug=debug) if args['--fit']: spe_histo = Histogram1D.load(charge_histo_filename) max_histo = Histogram1D.load(max_histo_filename) dark_count_rate = np.zeros(n_pixels) * np.nan electronic_noise = np.zeros(n_pixels) * np.nan crosstalk = np.zeros(n_pixels) * np.nan gain = np.zeros(n_pixels) * np.nan for i, pixel in tqdm(enumerate(pixel_id), total=n_pixels, desc='Pixel'): histo = max_histo[i] fitter = MaxHistoFitter(histo, estimated_gain, throw_nan=True) try: fitter.fit(ncall=100) fitter.fit(ncall=ncall) n_entries = histo.data.sum() number_of_zeros = fitter.parameters['a_0'] window_length = 4 * n_samples rate = compute_dark_rate(number_of_zeros, n_entries, window_length) electronic_noise[i] = fitter.parameters['sigma_e'] dark_count_rate[i] = rate if debug: fitter.draw() fitter.draw_init(x_label='[LSB]') fitter.draw_fit(x_label='[LSB]') plt.show() except Exception as e: print('Could not compute dark count rate' ' in pixel {}'.format(pixel)) print(e) np.savez(results_filename, dcr=dark_count_rate, sigma_e=electronic_noise, pixel_id=pixel_id) for i, pixel in tqdm(enumerate(pixel_id), total=n_pixels, desc='Pixel'): histo = spe_histo[i] fitter = SPEFitter(histo, estimated_gain, throw_nan=True) try: fitter.fit(ncall=100) fitter.fit(ncall=ncall) params = fitter.parameters n_entries = params['a_1'] n_entries += params['a_2'] n_entries += params['a_3'] n_entries += params['a_4'] crosstalk[i] = (n_entries - params['a_1']) / n_entries gain[i] = params['gain'] if debug: fitter.draw() fitter.draw_init(x_label='[LSB]') fitter.draw_fit(x_label='[LSB]') plt.show() except Exception as e: print('Could not compute gain and crosstalk' ' in pixel {}'.format(pixel)) print(e) data = dict(np.load(results_filename)) data['crosstalk'] = crosstalk data['gain'] = gain np.savez(results_filename, **data) save_figure = convert_text(args['--save_figures']) if save_figure is not None: output_path = save_figure spe_histo = Histogram1D.load(charge_histo_filename) spe_amplitude = Histogram1D.load(charge_histo_filename) raw_histo = Histogram1D.load(raw_histo_filename) max_histo = Histogram1D.load(max_histo_filename) figure_directory = output_path + 'figures/' if not os.path.exists(figure_directory): os.makedirs(figure_directory) histograms = [spe_histo, spe_amplitude, raw_histo, max_histo] names = [ 'histogram_charge/', 'histogram_amplitude/', 'histogram_raw/', 'histo_max/' ] for i, histo in enumerate(histograms): figure = plt.figure() histogram_figure_directory = figure_directory + names[i] if not os.path.exists(histogram_figure_directory): os.makedirs(histogram_figure_directory) for j, pixel in enumerate(pixel_id): axis = figure.add_subplot(111) figure_path = histogram_figure_directory + 'pixel_{}'. \ format(pixel) try: histo.draw(index=(j, ), axis=axis, log=True, legend=False) figure.savefig(figure_path) except Exception as e: print('Could not save pixel {} to : {} \n'.format( pixel, figure_path)) print(e) axis.remove() if args['--display']: spe_histo = Histogram1D.load(charge_histo_filename) raw_histo = Histogram1D.load( os.path.join(output_path, raw_histo_filename)) max_histo = Histogram1D.load(max_histo_filename) spe_histo.draw(index=(0, ), log=True, legend=False) raw_histo.draw(index=(0, ), log=True, legend=False) max_histo.draw(index=(0, ), log=True, legend=False) try: data = np.load(results_filename) dark_count_rate = data['dcr'] electronic_noise = data['sigma_e'] crosstalk = data['crosstalk'] gain = data['gain'] except IOError as e: print(e) print('Could not find the analysis files !') plt.figure() plt.hist(dark_count_rate[np.isfinite(dark_count_rate)], bins='auto') plt.xlabel('dark count rate [GHz]') plt.legend(loc='best') plt.figure() plt.hist(crosstalk[np.isfinite(crosstalk)], bins='auto') plt.xlabel('Crosstalk []') plt.legend(loc='best') plt.figure() plt.hist(gain[np.isfinite(gain)], bins='auto') plt.xlabel('Gain [LSB/p.e.]') plt.legend(loc='best') plt.figure() plt.hist(electronic_noise[np.isfinite(electronic_noise)], bins='auto') plt.xlabel('$\sigma_e$ [LSB]') plt.legend(loc='best') plt.show() return
def entry(): args = docopt(__doc__) files = args['<INPUT>'] max_events = convert_int(args['--max_events']) pixel_id = convert_pixel_args(args['--pixel']) n_samples = int(args['--n_samples']) timing_histo_filename = args['--timing_histo_filename'] ac_levels = convert_list_int(args['--ac_levels']) output_path = os.path.dirname(timing_histo_filename) results_filename = os.path.join(output_path, 'timing.npz') if not os.path.exists(output_path): raise IOError('Path for output does not exists \n') if args['--compute']: compute(files, max_events, pixel_id, n_samples, ac_levels, timing_histo_filename, save=True, time_method=compute_time_from_max) # or try to use compute_time_from_leading_edge) if args['--fit']: timing_histo = Histogram1D.load(timing_histo_filename) timing = timing_histo.mode() timing = mode(timing, axis=0)[0][0] np.savez(results_filename, time=timing) if args['--save_figures']: raw_histo = Histogram1D.load(timing_histo_filename) path = os.path.join(output_path, 'figures/', 'timing_histo/') if not os.path.exists(path): os.makedirs(path) figure = plt.figure() for i, pixel in tqdm(enumerate(pixel_id), total=len(pixel_id)): axis = figure.add_subplot(111) figure_path = path + 'pixel_{}.pdf' try: raw_histo.draw(index=(i, ), axis=axis, log=True, legend=False) figure.savefig(figure_path.format(pixel)) except Exception as e: print('Could not save pixel {} to : {} \n'.format( pixel, figure_path)) print(e) axis.remove() if args['--display']: timing_histo = Histogram1D.load(timing_histo_filename) timing_histo.draw(index=( len(ac_levels) - 1, 0, ), log=True, legend=False) pulse_time = timing_histo.mode() plt.figure() plt.plot(ac_levels, pulse_time) plt.xlabel('DAC level') plt.ylabel('Reconstructed pulse time [ns]') pulse_time = np.load(results_filename)['time'] plot_array_camera(pulse_time, label='time of pulse [ns]', allow_pick=True) plot_parameter(pulse_time, 'time of pulse', '[ns]', bins=20) plt.show() return
def entry(): args = docopt(__doc__) files = args['<INPUT>'] debug = args['--debug'] max_events = convert_int(args['--max_events']) results_filename = args['--fit_output'] dir_output = os.path.dirname(results_filename) if not os.path.exists(dir_output): raise IOError('Path {} for output ' 'does not exists \n'.format(dir_output)) pixel_ids = convert_pixel_args(args['--pixel']) integral_width = int(args['--integral_width']) shift = int(args['--shift']) bin_width = int(args['--bin_width']) ncall = int(args['--ncall']) ac_levels = convert_list_int(args['--ac_levels']) n_pixels = len(pixel_ids) n_ac_levels = len(ac_levels) adc_min = int(args['--adc_min']) adc_max = int(args['--adc_max']) timing_filename = args['--timing'] timing = np.load(timing_filename)['time'] charge_histo_filename = args['--compute_output'] fmpe_results_filename = args['--gain'] if args['--compute']: if n_ac_levels != len(files): raise ValueError('n_ac_levels = {} != ' 'n_files = {}'.format(n_ac_levels, len(files))) time = np.zeros((n_ac_levels, n_pixels)) charge_histo = Histogram1D(bin_edges=np.arange( adc_min * integral_width, adc_max * integral_width, bin_width), data_shape=( n_ac_levels, n_pixels, )) if os.path.exists(charge_histo_filename): raise IOError( 'File {} already exists'.format(charge_histo_filename)) for i, (file, ac_level) in tqdm(enumerate(zip(files, ac_levels)), total=n_ac_levels, desc='DAC level', leave=False): time[i] = timing[pixel_ids] pulse_indices = time[i] // 4 events = calibration_event_stream(file, pixel_id=pixel_ids, max_events=max_events) # events = compute_baseline_with_min(events) events = fill_digicam_baseline(events) events = subtract_baseline(events) # events = find_pulse_with_max(events) events = fill_pulse_indices(events, pulse_indices) events = compute_charge(events, integral_width, shift) events = compute_amplitude(events) for event in events: charge_histo.fill(event.data.reconstructed_charge, indices=i) charge_histo.save(charge_histo_filename, ) if args['--fit']: input_parameters = Table.read(fmpe_results_filename, format='fits') input_parameters = input_parameters.to_pandas() gain = np.zeros((n_ac_levels, n_pixels)) * np.nan sigma_e = np.zeros((n_ac_levels, n_pixels)) * np.nan sigma_s = np.zeros((n_ac_levels, n_pixels)) * np.nan baseline = np.zeros((n_ac_levels, n_pixels)) * np.nan mu = np.zeros((n_ac_levels, n_pixels)) * np.nan mu_xt = np.zeros((n_ac_levels, n_pixels)) * np.nan amplitude = np.zeros((n_ac_levels, n_pixels)) * np.nan gain_error = np.zeros((n_ac_levels, n_pixels)) * np.nan sigma_e_error = np.zeros((n_ac_levels, n_pixels)) * np.nan sigma_s_error = np.zeros((n_ac_levels, n_pixels)) * np.nan baseline_error = np.zeros((n_ac_levels, n_pixels)) * np.nan mu_error = np.zeros((n_ac_levels, n_pixels)) * np.nan mu_xt_error = np.zeros((n_ac_levels, n_pixels)) * np.nan amplitude_error = np.zeros((n_ac_levels, n_pixels)) * np.nan mean = np.zeros((n_ac_levels, n_pixels)) * np.nan std = np.zeros((n_ac_levels, n_pixels)) * np.nan chi_2 = np.zeros((n_ac_levels, n_pixels)) * np.nan ndf = np.zeros((n_ac_levels, n_pixels)) * np.nan ac_limit = [np.inf] * n_pixels charge_histo = Histogram1D.load(charge_histo_filename) for i, ac_level in tqdm(enumerate(ac_levels), total=n_ac_levels, desc='DAC level', leave=False): for j, pixel_id in tqdm(enumerate(pixel_ids), total=n_pixels, desc='Pixel', leave=False): histo = charge_histo[i, pixel_id] mean[i, j] = histo.mean() std[i, j] = histo.std() if histo.overflow > 0 or histo.data.sum() == 0: continue fit_params_names = describe(mpe_distribution_general) options = {'fix_n_peaks': True} fixed_params = {} for param in fit_params_names: if param in input_parameters.keys(): name = 'fix_' + param options[name] = True fixed_params[param] = input_parameters[param][pixel_id] if i > 0: if mu[i - 1, j] > 5: ac_limit[j] = min(i, ac_limit[j]) ac_limit[j] = int(ac_limit[j]) weights_fit = chi_2[:ac_limit[j], j] weights_fit = weights_fit / ndf[:ac_limit[j], j] options['fix_mu_xt'] = True temp = mu_xt[:ac_limit[j], j] * weights_fit temp = np.nansum(temp) temp = temp / np.nansum(weights_fit) fixed_params['mu_xt'] = temp try: fitter = MPEFitter(histogram=histo, cost='MLE', pedantic=0, print_level=0, throw_nan=True, fixed_params=fixed_params, **options) fitter.fit(ncall=ncall) if debug: x_label = '[LSB]' label = 'Pixel {}'.format(pixel_id) fitter.draw(legend=False, x_label=x_label, label=label) fitter.draw_init(legend=False, x_label=x_label, label=label) fitter.draw_fit(legend=False, x_label=x_label, label=label) plt.show() param = fitter.parameters param_err = fitter.errors gain[i, j] = param['gain'] sigma_e[i, j] = param['sigma_e'] sigma_s[i, j] = param['sigma_s'] baseline[i, j] = param['baseline'] mu[i, j] = param['mu'] mu_xt[i, j] = param['mu_xt'] amplitude[i, j] = param['amplitude'] gain_error[i, j] = param_err['gain'] sigma_e_error[i, j] = param_err['sigma_e'] sigma_s_error[i, j] = param_err['sigma_s'] baseline_error[i, j] = param_err['baseline'] mu_error[i, j] = param_err['mu'] mu_xt_error[i, j] = param_err['mu_xt'] amplitude_error[i, j] = param_err['amplitude'] chi_2[i, j] = fitter.fit_test() * fitter.ndf ndf[i, j] = fitter.ndf except Exception as e: print(e) print('Could not fit pixel {} for DAC level {}'.format( pixel_id, ac_level)) np.savez( results_filename, gain=gain, sigma_e=sigma_e, sigma_s=sigma_s, baseline=baseline, mu=mu, mu_xt=mu_xt, gain_error=gain_error, sigma_e_error=sigma_e_error, sigma_s_error=sigma_s_error, baseline_error=baseline_error, mu_error=mu_error, mu_xt_error=mu_xt_error, chi_2=chi_2, ndf=ndf, pixel_ids=pixel_ids, ac_levels=ac_levels, amplitude=amplitude, amplitude_error=amplitude_error, mean=mean, std=std, ) if args['--save_figures']: pass if args['--display']: charge_histo = Histogram1D.load(charge_histo_filename) charge_histo.draw(index=(0, 0), log=False, legend=False) pass return
import numpy as np import matplotlib.pyplot as plt import peakutils as peakutils from scipy.optimize import curve_fit from scipy.special import factorial from matplotlib.offsetbox import AnchoredText from matplotlib.backends.backend_pdf import PdfPages from docopt import docopt from digicampipe.utils.docopt import convert_int, convert_text from histogram.histogram import Histogram1D channel = 3 file = '/Users/lonewolf/Desktop/scifi/integral_charge/integral_charge_ch{}.fits'.format(channel) charge_histogram = Histogram1D.load(file) y_data = charge_histogram.data x_data = charge_histogram.bin_centers y = y_data[:1300].astype(float) x = np.arange(len(y)) # 1st stage : Find estimates of the peaks, high threshold indexes = peakutils.peak.indexes(y, thres=0.5, thres_abs=False) estimated_gain = np.average(np.diff(indexes), weights=y[indexes[:-1]]) # 2nd stage : Define a threshold for selecting peak (1/15 of the highest peak) idx_highest_peak = np.argmax(y) threshold = y[idx_highest_peak] / 15 # 3rd stage : Find all the true peak indexes = peakutils.peak.indexes(y, thres=threshold, min_dist=estimated_gain, thres_abs=True)
def data_quality( files, dark_filename, time_step, fits_filename, load_files, histo_filename, rate_plot_filename, baseline_plot_filename, nsb_plot_filename, parameters_filename, template_filename, aux_basepath, threshold_sample_pe=20., bias_resistance=1e4 * u.Ohm, cell_capacitance=5e-14 * u.Farad, disable_bar=False, aux_services=('DriveSystem',) ): input_dir = np.unique([os.path.dirname(file) for file in files]) if len(input_dir) > 1: raise AttributeError("input files must be from the same directories") input_dir = input_dir[0] if aux_basepath.lower() == "search": aux_basepath = input_dir.replace('/raw/', '/aux/') print("auxiliary files are expected in", aux_basepath) with open(parameters_filename) as file: calibration_parameters = yaml.load(file) pulse_template = NormalizedPulseTemplate.load(template_filename) pulse_area = pulse_template.integral() * u.ns gain_integral = np.array(calibration_parameters['gain']) charge_to_amplitude = pulse_template.compute_charge_amplitude_ratio(7, 4) gain_amplitude = gain_integral * charge_to_amplitude crosstalk = np.array(calibration_parameters['mu_xt']) pixel_id = np.arange(1296) n_pixels = len(pixel_id) dark_histo = Histogram1D.load(dark_filename) dark_baseline = dark_histo.mean() if not load_files: events = calibration_event_stream(files, disable_bar=disable_bar) events = add_slow_data_calibration( events, basepath=aux_basepath, aux_services=aux_services ) events = fill_digicam_baseline(events) events = fill_dark_baseline(events, dark_baseline) events = subtract_baseline(events) events = compute_baseline_shift(events) events = compute_nsb_rate( events, gain_amplitude, pulse_area, crosstalk, bias_resistance, cell_capacitance ) events = compute_gain_drop(events, bias_resistance, cell_capacitance) events = compute_sample_photo_electron(events, gain_amplitude) events = tag_burst_from_moving_average_baseline( events, n_previous_events=100, threshold_lsb=5 ) events = compute_3d_cleaning(events, geom=DigiCam.geometry, threshold_sample_pe=threshold_sample_pe) init_time = 0 baseline = 0 count = 0 shower_count = 0 az = 0 el = 0 container = DataQualityContainer() file = Serializer(fits_filename, mode='w', format='fits') baseline_histo = Histogram1D( data_shape=(n_pixels,), bin_edges=np.arange(4096) ) for i, event in enumerate(events): new_time = event.data.local_time if init_time == 0: init_time = new_time count += 1 baseline += np.mean(event.data.digicam_baseline) az += event.slow_data.DriveSystem.current_position_az el += event.slow_data.DriveSystem.current_position_el time_diff = new_time - init_time if event.data.shower: shower_count += 1 baseline_histo.fill(event.data.digicam_baseline.reshape(-1, 1)) if time_diff > time_step and i > 0: trigger_rate = count / time_diff shower_rate = shower_count / time_diff baseline = baseline / count az = az / count el = el / count container.trigger_rate = trigger_rate container.baseline = baseline container.time = (new_time + init_time) / 2 container.shower_rate = shower_rate container.burst = event.data.burst nsb_rate = event.data.nsb_rate container.nsb_rate = np.nanmean(nsb_rate).value container.current_position_az = az container.current_position_el = el baseline = 0 count = 0 init_time = 0 shower_count = 0 az = 0 el = 0 file.add_container(container) output_path = os.path.dirname(histo_filename) if not os.path.exists(output_path): os.makedirs(output_path) baseline_histo.save(histo_filename) print(histo_filename, 'created.') file.close() print(fits_filename, 'created.') data = Table.read(fits_filename, format='fits') data = data.to_pandas() data['time'] = pd.to_datetime(data['time'], utc=True) data = data.set_index('time') if rate_plot_filename is not None: fig1 = plt.figure() ax = plt.gca() plt.xticks(rotation=70) plt.plot(data['trigger_rate']*1E9, '.', label='trigger rate') plt.plot(data['shower_rate']*1E9, '.', label='shower_rate') plt.ylabel('rate [Hz]') plt.legend({'trigger rate', 'shower rate'}) xlim = plt.xlim() plt.xlim(xlim[0] - 1e-3, xlim[1] + 1e-3) # extra min on the sides if rate_plot_filename == "show": plt.show() else: output_path = os.path.dirname(rate_plot_filename) if not (output_path == '' or os.path.exists(output_path)): os.makedirs(output_path) plt.savefig(rate_plot_filename) plt.close(fig1) if baseline_plot_filename is not None: fig2 = plt.figure(figsize=(8, 6)) ax = plt.gca() data_burst = data[data['burst']] data_good = data[~data['burst']] plt.xticks(rotation=70) plt.plot(data_good['baseline'], '.', label='good', ms=2) plt.plot(data_burst['baseline'], '.', label='burst', ms=2) plt.ylabel('Baseline [LSB]') xlim = plt.xlim() plt.xlim(xlim[0] - 1e-3, xlim[1] + 1e-3) # extra min on the sides if rate_plot_filename == "show": plt.show() else: output_path = os.path.dirname(baseline_plot_filename) if not (output_path == '' or os.path.exists(output_path)): os.makedirs(output_path) plt.savefig(baseline_plot_filename) plt.close(fig2) if nsb_plot_filename is not None: fig3 = plt.figure() ax = fig3.add_subplot(111) data.plot(y='nsb_rate', ax=ax) ax.set_ylabel('$f_{NSB}$ [GHz]') if nsb_plot_filename == "show": plt.show() else: fig3.savefig(nsb_plot_filename) plt.close(fig3) return
def nsb_rate( baseline_histo_file, dark_histo_file, param_file, template_filename, plot="show", plot_nsb_range=None, norm="log", bias_resistance=1e4 * u.Ohm, cell_capacitance=5e-14 * u.Farad ): baseline_histo = Histogram1D.load(baseline_histo_file) dark_histo = Histogram1D.load(dark_histo_file) baseline_shift = baseline_histo.mean()-dark_histo.mean() n_pixel = len(DigiCam.geometry.neighbors) pixels = np.arange(n_pixel, dtype=int) with open(param_file) as file: pulse_template = NormalizedPulseTemplate.load(template_filename) pulse_area = pulse_template.integral() * u.ns charge_to_amplitude = pulse_template.compute_charge_amplitude_ratio(7, 4) calibration_parameters = yaml.load(file) gain_integral = np.array(calibration_parameters['gain']) gain_amplitude = gain_integral * charge_to_amplitude crosstalk = np.array(calibration_parameters['mu_xt']) rate = _compute_nsb_rate( baseline_shift=baseline_shift, gain=gain_amplitude, pulse_area=pulse_area, crosstalk=crosstalk, bias_resistance=bias_resistance, cell_capacitance=cell_capacitance ) bad_pixels = get_bad_pixels( calib_file=param_file, nsigma_gain=5, nsigma_elecnoise=5, dark_histo=dark_histo_file, nsigma_dark=8, plot=None, output=None ) bad_pixels = np.unique(np.hstack( ( bad_pixels, pixels[rate < 0], pixels[rate > 5 * u.GHz] ) )) avg_matrix = _get_average_matrix_bad_pixels(DigiCam.geometry, bad_pixels) good_pixels_mask = np.ones(n_pixel, dtype=bool) good_pixels_mask[bad_pixels] = False good_pixels = pixels[good_pixels_mask] rate[bad_pixels] = avg_matrix[bad_pixels, :].dot(rate[good_pixels]) if plot is None: return rate fig1, ax = plt.subplots(1, 1) display = CameraDisplay(DigiCam.geometry, ax=ax, norm=norm, title='NSB rate [GHz]') rate_ghz = rate.to(u.GHz).value display.image = rate_ghz if plot_nsb_range is None: plot_nsb_range = (np.min(rate_ghz), np.max(rate_ghz)) display.set_limits_minmax(*plot_nsb_range) display.add_colorbar(ax=ax) display.highlight_pixels(bad_pixels, color='r', linewidth=2) plt.tight_layout() output_path = os.path.dirname(plot) if plot == "show" or \ (output_path != "" and not os.path.isdir(output_path)): if not plot == "show": print('WARNING: Path ' + output_path + ' for output trigger ' + 'uniformity does not exist, displaying the plot instead.\n') plt.show() else: plt.savefig(plot) print(plot, 'created') plt.close(fig1) return rate
def entry(): args = docopt(__doc__) files = args['INPUT'] debug = args['--debug'] max_events = convert_max_events_args(args['--max_events']) output_path = args['OUTPUT'] if not os.path.exists(output_path): raise IOError('Path for output does not exists \n') pixel_id = convert_pixel_args(args['--pixel']) integral_width = int(args['--integral_width']) shift = int(args['--shift']) bin_width = int(args['--bin_width']) n_samples = int(args['--n_samples']) # TODO access this in a better way n_pixels = len(pixel_id) charge_histo_filename = 'charge_histo_fmpe.pk' amplitude_histo_filename = 'amplitude_histo_fmpe.pk' timing_histo_filename = 'timing_histo_fmpe.pk' if args['--compute']: timing_histo = Histogram1D.load(os.path.join(output_path, timing_histo_filename)) pulse_indices = timing_histo.mode() // 4 mpe.compute( files, pixel_id, max_events, pulse_indices, integral_width, shift, bin_width, output_path, charge_histo_filename=charge_histo_filename, amplitude_histo_filename=amplitude_histo_filename, save=True) if args['--fit']: charge_histo = Histogram1D.load( os.path.join(output_path, charge_histo_filename)) # charge_histo = Histogram1D.load( # os.path.join(output_path, amplitude_histo_filename)) gain = np.zeros(n_pixels) * np.nan sigma_e = np.zeros(n_pixels) * np.nan sigma_s = np.zeros(n_pixels) * np.nan baseline = np.zeros(n_pixels) * np.nan gain_error = np.zeros(n_pixels) * np.nan sigma_e_error = np.zeros(n_pixels) * np.nan sigma_s_error = np.zeros(n_pixels) * np.nan baseline_error = np.zeros(n_pixels) * np.nan chi_2 = np.zeros(n_pixels) * np.nan ndf = np.zeros(n_pixels) * np.nan n_pe_peaks = 10 estimated_gain = 20 min_dist = 5 # int(estimated_gain) results_filename = os.path.join(output_path, 'fmpe_results.npz') for i, pixel in tqdm(enumerate(pixel_id), total=n_pixels, desc='Pixel'): x = charge_histo._bin_centers() y = charge_histo.data[i] y_err = charge_histo.errors()[i] x, y, y_err = compute_data_bounds(x, y, y_err, estimated_gain, n_pe_peaks) try: params_init = compute_init_fmpe(x, y, y_err, snr=3, min_dist=min_dist, n_pe_peaks=n_pe_peaks, debug=debug) x, y, y_err = compute_data_bounds(x, y, y_err, estimated_gain, n_pe_peaks, params=params_init) params_limit = compute_limit_fmpe(params_init) m = fit_fmpe(x, y, y_err, params_init, params_limit) gain[i] = m.values['gain'] gain_error[i] = m.errors['gain'] sigma_e[i] = m.values['sigma_e'] sigma_e_error[i] = m.errors['sigma_e'] sigma_s[i] = m.values['sigma_s'] sigma_s_error[i] = m.errors['sigma_s'] baseline[i] = m.values['baseline'] baseline_error[i] = m.errors['baseline'] chi_2[i] = m.fval ndf[i] = len(x) - len(m.list_of_vary_param()) fig = plot_fmpe_fit(x, y, y_err, m, pixel) # fig.savefig(os.path.join(output_path, 'figures/') + # 'fmpe_pixel_{}'.format(pixel)) if debug: plt.show() plt.close() except Exception as exception: print('Could not fit FMPE in pixel {}'.format(pixel)) print(exception) np.savez(results_filename, gain=gain, sigma_e=sigma_e, sigma_s=sigma_s, baseline=baseline, gain_error=gain_error, sigma_e_error=sigma_e_error, sigma_s_error=sigma_s_error, baseline_error=baseline_error, chi_2=chi_2, ndf=ndf, pixel_id=pixel_id, ) if args['--save_figures']: amplitude_histo_path = os.path.join(output_path, 'amplitude_histo_fmpe.pk') charge_histo_path = os.path.join(output_path, 'charge_histo_fmpe.pk') timing_histo_path = os.path.join(output_path, 'timing_histo_fmpe.pk') charge_histo = Histogram1D.load(charge_histo_path) amplitude_histo = Histogram1D.load(amplitude_histo_path) timing_histo = Histogram1D.load(timing_histo_path) figure_path = os.path.join(output_path, 'figures/') if not os.path.exists(figure_path): os.makedirs(figure_path) figure_1 = plt.figure() figure_2 = plt.figure() figure_3 = plt.figure() axis_1 = figure_1.add_subplot(111) axis_2 = figure_2.add_subplot(111) axis_3 = figure_3.add_subplot(111) for i, pixel in tqdm(enumerate(pixel_id), total=len(pixel_id)): try: charge_histo.draw(index=(i,), axis=axis_1, log=True, legend=False) amplitude_histo.draw(index=(i,), axis=axis_2, log=True, legend=False) timing_histo.draw(index=(i,), axis=axis_3, log=True, legend=False) figure_1.savefig(figure_path + 'charge_fmpe_pixel_{}'.format(pixel)) figure_2.savefig(figure_path + 'amplitude_fmpe_pixel_{}'.format(pixel)) figure_3.savefig(figure_path + 'timing_fmpe_pixel_{}'.format(pixel)) except Exception as e: print('Could not save pixel {} to : {} \n'. format(pixel, figure_path)) print(e) axis_1.clear() axis_2.clear() axis_3.clear() if args['--display']: amplitude_histo_path = os.path.join(output_path, 'amplitude_histo_fmpe.pk') charge_histo_path = os.path.join(output_path, 'charge_histo_fmpe.pk') timing_histo_path = os.path.join(output_path, 'timing_histo_fmpe.pk') charge_histo = Histogram1D.load(charge_histo_path) charge_histo.draw(index=(0,), log=False, legend=False) amplitude_histo = Histogram1D.load(amplitude_histo_path) amplitude_histo.draw(index=(0,), log=False, legend=False) timing_histo = Histogram1D.load(timing_histo_path) timing_histo.draw(index=(0,), log=False, legend=False) plt.show() pass return
def nsb_rate( files, aux_basepath, dark_histo_file, param_file, template_filename, output=None, plot="show", plot_nsb_range=None, norm="log", plot_baselines=False, disable_bar=False, max_events=None, n_skip=10, stars=True, bias_resistance=1e4 * u.Ohm, cell_capacitance=5e-14 * u.Farad ): files = np.atleast_1d(files) if len(files) == 1 and not files[0].endswith('.fz'): table = Table.read(files[0])[:max_events] data = dict(table) data['nsb_rate'] = np.array(data['nsb_rate']) * u.GHz else: dark_histo = Histogram1D.load(dark_histo_file) n_pixel = len(DigiCam.geometry.neighbors) pixels = np.arange(n_pixel, dtype=int) with open(param_file) as file: pulse_template = NormalizedPulseTemplate.load(template_filename) pulse_area = pulse_template.integral() * u.ns charge_to_amplitude = pulse_template.compute_charge_amplitude_ratio(7, 4) calibration_parameters = yaml.load(file) gain_integral = np.array(calibration_parameters['gain']) gain_amplitude = gain_integral * charge_to_amplitude crosstalk = np.array(calibration_parameters['mu_xt']) events = calibration_event_stream(files, max_events=max_events, disable_bar=disable_bar) events = add_slow_data_calibration( events, basepath=aux_basepath, aux_services=('DriveSystem', ) ) data = { "baseline": [], "nsb_rate": [], "good_pixels_mask": [], "timestamp": [], "event_id": [], "az": [], "el": [], } bad_pixels = get_bad_pixels( calib_file=param_file, nsigma_gain=5, nsigma_elecnoise=5, dark_histo=dark_histo_file, nsigma_dark=8, plot=None, output=None ) events_skipped = 0 for event in events: if event.event_type.INTERNAL not in event.event_type: continue events_skipped += 1 if events_skipped < n_skip: continue events_skipped = 0 data['baseline'].append(event.data.digicam_baseline) baseline_shift = event.data.digicam_baseline - dark_histo.mean() rate = _compute_nsb_rate( baseline_shift=baseline_shift, gain=gain_amplitude, pulse_area=pulse_area, crosstalk=crosstalk, bias_resistance=bias_resistance, cell_capacitance=cell_capacitance ) bad_pixels_event = np.unique(np.hstack( ( bad_pixels, pixels[rate < 0], pixels[rate > 5 * u.GHz] ) )) avg_matrix = _get_average_matrix_bad_pixels( DigiCam.geometry, bad_pixels_event ) good_pixels_mask = np.ones(n_pixel, dtype=bool) good_pixels_mask[bad_pixels_event] = False good_pixels = pixels[good_pixels_mask] rate[bad_pixels_event] = avg_matrix[bad_pixels_event, :].dot( rate[good_pixels] ) data['good_pixels_mask'].append(good_pixels_mask) data['timestamp'].append(event.data.local_time) data['event_id'].append(event.event_id) data['nsb_rate'].append(rate) data['az'].append(event.slow_data.DriveSystem.current_position_az) data['el'].append(event.slow_data.DriveSystem.current_position_el) data['nsb_rate'] = np.array(data['nsb_rate']) * u.GHz if output is not None: table = Table(data) if os.path.isfile(output): os.remove(output) table.write(output, format='fits') time_obs = Time( np.array(data['timestamp'], dtype=np.float64) * 1e-9, format='unix' ) if plot_baselines: fig2, (ax1, ax2) = plt.subplots(2, 1, figsize=(16, 8), dpi=50) baseline_std = np.std(data['baseline'], axis=0) ax1.hist(baseline_std, 100) ax1.set_xlabel('std(baseline) [LSB]') # pixels_shown = np.arange(len(baseline_std))[baseline_std > 10] pixels_shown = [834,] ax2.plot_date( time_obs.to_datetime(), data['baseline'][:, pixels_shown], '-' ) ax2.set_xlabel('time') ax2.set_ylabel('baseline [LSB]') plt.tight_layout() plt.show() plt.close(fig2) az_obs = np.array(data['az']) * u.deg el_obs = np.array(data['el']) * u.deg n_event = len(data['timestamp']) fig1, ax = plt.subplots(1, 1, figsize=(16, 12), dpi=50) date = datetime.fromtimestamp(data['timestamp'][0]*1e-9) date_str = date.strftime("%H:%M:%S") display = CameraDisplay( DigiCam.geometry, ax=ax, norm=norm, title='NSB rate [GHz], t=' + date_str ) rate_ghz = np.array(data['nsb_rate'][0].to(u.GHz).value) display.image = rate_ghz if plot_nsb_range is None: min_range_rate = np.max([np.min(rate_ghz), 50e-3]) plot_nsb_range = (min_range_rate, np.max(rate_ghz)) display.set_limits_minmax(*plot_nsb_range) display.add_colorbar(ax=ax) bad_pixels = np.arange( len(data['good_pixels_mask'][0]) )[~data['good_pixels_mask'][0]] display.highlight_pixels(bad_pixels, color='r', linewidth=2) display.axes.set_xlim([-500., 500.]) display.axes.set_ylim([-500., 500.]) plt.tight_layout() if stars is True: stars_az, stars_alt, stars_pmag = get_stars_in_fov( az_obs[0], el_obs[0], time_obs ) stars_x, stars_y = transform_azel_to_xy( stars_az, stars_alt, az_obs, el_obs ) point_stars = [] for index_star in range(len(stars_pmag)): point_star, = ax.plot( stars_x[index_star, 0], stars_y[index_star, 0], 'ok', ms=20-2*stars_pmag[index_star], mew=3, mfc='None' ) point_stars.append(point_star) def update(i, display): print('frame', i, '/', len(data['timestamp'])) display.image = data['nsb_rate'][i].to(u.GHz).value date = datetime.fromtimestamp(data['timestamp'][i] * 1e-9) date_str = date.strftime("%H:%M:%S") display.axes.set_title('NSB rate [GHz], t=' + date_str) bad_pixels = np.arange( len(data['good_pixels_mask'][i]) )[~data['good_pixels_mask'][i]] display.highlight_pixels( bad_pixels, color='r', linewidth=2 ) if stars is True: for index_star in range(len(stars_pmag)): point_stars[index_star].set_xdata( stars_x[index_star, i] ) point_stars[index_star].set_ydata( stars_y[index_star, i] ) anim = FuncAnimation( fig1, update, frames=len(data['timestamp']), interval=20, fargs=(display, ) ) Writer = animation.writers['ffmpeg'] writer = Writer(fps=50, metadata=dict(artist='Y. Renier'), bitrate=4000, codec='h263p') output_path = os.path.dirname(plot) if plot == "show" or \ (output_path != "" and not os.path.isdir(output_path)): if not plot == "show": print('WARNING: Path ' + output_path + ' for output trigger ' + 'uniformity does not exist, displaying the plot instead.\n') display.enable_pixel_picker() plt.show() else: anim.save(plot, writer=writer) print(plot, 'created') plt.close(fig1)
def entry(): args = docopt(__doc__) files = args['INPUT'] debug = args['--debug'] max_events = convert_max_events_args(args['--max_events']) pixel_id = convert_pixel_args(args['--pixel']) n_samples = int(args['--n_samples']) output_path = args['OUTPUT'] timing_histo_filename = 'timing_histo.pk' if not os.path.exists(output_path): raise IOError('Path for output does not exists \n') if args['--compute']: compute(files, max_events, pixel_id, output_path, n_samples, timing_histo_filename, save=True, time_method=compute_time_from_leading_edge) if args['--save_figures']: histo_path = os.path.join(output_path, timing_histo_filename) raw_histo = Histogram1D.load(histo_path) path = os.path.join(output_path, 'figures/', 'timing_histo/') if not os.path.exists(path): os.makedirs(path) figure = plt.figure() for i, pixel in tqdm(enumerate(pixel_id), total=len(pixel_id)): axis = figure.add_subplot(111) figure_path = path + 'pixel_{}.pdf' try: raw_histo.draw(index=(i, ), axis=axis, log=True, legend=False) figure.savefig(figure_path.format(pixel)) except Exception as e: print('Could not save pixel {} to : {} \n'.format( pixel, figure_path)) print(e) axis.remove() if args['--display']: path = os.path.join(output_path, timing_histo_filename) raw_histo = Histogram1D.load(path) raw_histo.draw(index=(0, ), log=True, legend=False) plt.show() return
def entry(): args = docopt(__doc__) files = args['INPUT'] debug = args['--debug'] max_events = convert_max_events_args(args['--max_events']) output_path = args['OUTPUT'] if not os.path.exists(output_path): raise IOError('Path for output does not exists \n') pixel_id = convert_pixel_args(args['--pixel']) n_pixels = len(pixel_id) raw_histo_filename = 'raw_histo.pk' amplitude_histo_filename = output_path + 'amplitude_histo.pk' charge_histo_filename = output_path + 'charge_histo.pk' max_histo_filename = output_path + 'max_histo.pk' results_filename = output_path + 'fit_results.h5' dark_count_rate_filename = output_path + 'dark_count_rate.npz' crosstalk_filename = output_path + 'crosstalk.npz' electronic_noise_filename = output_path + 'electronic_noise.npz' integral_width = int(args['--integral_width']) shift = int(args['--shift']) pulse_finder_threshold = float(args['--pulse_finder_threshold']) n_samples = int(args['--n_samples']) # TODO access this in a better way ! if args['--compute']: raw_histo = raw.compute(files, max_events=max_events, pixel_id=pixel_id, output_path=output_path, filename=raw_histo_filename) baseline = raw_histo.mode() events = calibration_event_stream(files, pixel_id=pixel_id, max_events=max_events) # events = compute_baseline_with_min(events) events = fill_baseline(events, baseline) events = subtract_baseline(events) events = find_pulse_with_max(events) events = compute_charge(events, integral_width, shift) max_histo = Histogram1D(data_shape=(n_pixels, ), bin_edges=np.arange(-4095 * integral_width, 4095 * integral_width), axis_name='[LSB]') for event in events: max_histo.fill(event.data.reconstructed_charge) max_histo.save(max_histo_filename) events = calibration_event_stream(files, max_events=max_events, pixel_id=pixel_id) events = fill_baseline(events, baseline) events = subtract_baseline(events) # events = find_pulse_1(events, 0.5, 20) # events = find_pulse_2(events, widths=[5, 6], threshold_sigma=2) # events = find_pulse_fast(events, threshold=pulse_finder_threshold) # events = find_pulse_correlate(events, # threshold=pulse_finder_threshold) # events = find_pulse_gaussian_filter(events, # threshold=pulse_finder_threshold) events = find_pulse_wavelets(events, widths=[4, 5, 6], threshold_sigma=2) events = compute_charge(events, integral_width=integral_width, shift=shift) events = compute_amplitude(events) # events = fit_template(events) if debug: events = plot_event(events, 0) spe_charge = Histogram1D(data_shape=(n_pixels, ), bin_edges=np.arange(-4095 * integral_width, 4095 * integral_width)) spe_amplitude = Histogram1D(data_shape=(n_pixels, ), bin_edges=np.arange(-4095, 4095, 1)) for event in events: spe_charge.fill(event.data.reconstructed_charge) spe_amplitude.fill(event.data.reconstructed_amplitude) spe_charge.save(charge_histo_filename) spe_amplitude.save(amplitude_histo_filename) if args['--fit']: spe_charge = Histogram1D.load(charge_histo_filename) spe_amplitude = Histogram1D.load(amplitude_histo_filename) max_histo = Histogram1D.load(max_histo_filename) dark_count_rate = np.zeros(n_pixels) * np.nan electronic_noise = np.zeros(n_pixels) * np.nan for i, pixel in tqdm(enumerate(pixel_id), total=n_pixels, desc='Pixel'): x = max_histo._bin_centers() y = max_histo.data[i] n_entries = np.sum(y) mask = (y > 0) x = x[mask] y = y[mask] try: val, err = compute_gaussian_parameters_first_peak( x, y, snr=3, ) number_of_zeros = val['amplitude'] window_length = 4 * n_samples rate = compute_dark_rate(number_of_zeros, n_entries, window_length) dark_count_rate[pixel] = rate electronic_noise[pixel] = val['sigma'] except Exception as e: print('Could not compute dark count rate in pixel {}'.format( pixel)) print(e) np.savez(dark_count_rate_filename, dcr=dark_count_rate) np.savez(electronic_noise_filename, electronic_noise) spe = spe_charge name = 'charge' crosstalk = np.zeros(n_pixels) * np.nan results = SPEResultContainer() table_name = 'analysis_' + name with HDF5TableWriter(results_filename, table_name, mode='w') as h5: for i, pixel in tqdm(enumerate(pixel_id), total=n_pixels, desc='Pixel'): try: x = spe._bin_centers() y = spe.data[i] y_err = spe.errors(index=i) sigma_e = electronic_noise[i] sigma_e = sigma_e if not np.isnan(sigma_e) else None params, params_err, params_init, params_bound = \ fit_spe(x, y, y_err, sigma_e=sigma_e, snr=3, debug=debug) for key, val in params.items(): setattr(results.init, key, params_init[key]) setattr(results.param, key, params[key]) setattr(results.param_errors, key, params_err[key]) for key, val in results.items(): results[key]['pixel_id'] = pixel for key, val in results.items(): h5.write('spe_' + key, val) n_entries = params['a_1'] n_entries += params['a_2'] n_entries += params['a_3'] n_entries += params['a_4'] crosstalk[pixel] = (n_entries - params['a_1']) / n_entries except Exception as e: print('Could not fit for pixel_id : {}'.format(pixel)) print(e) np.savez(crosstalk_filename, crosstalk) if args['--save_figures']: spe_charge = Histogram1D.load(charge_histo_filename) spe_amplitude = Histogram1D.load(amplitude_histo_filename) raw_histo = Histogram1D.load( os.path.join(output_path, raw_histo_filename)) max_histo = Histogram1D.load(max_histo_filename) figure_directory = output_path + 'figures/' if not os.path.exists(figure_directory): os.makedirs(figure_directory) histograms = [spe_charge, spe_amplitude, raw_histo, max_histo] names = [ 'histogram_charge/', 'histogram_amplitude/', 'histogram_raw/', 'histo_max/' ] for i, histo in enumerate(histograms): figure = plt.figure() histogram_figure_directory = figure_directory + names[i] if not os.path.exists(histogram_figure_directory): os.makedirs(histogram_figure_directory) for j, pixel in enumerate(pixel_id): axis = figure.add_subplot(111) figure_path = histogram_figure_directory + 'pixel_{}'. \ format(pixel) try: histo.draw(index=(j, ), axis=axis, log=True, legend=False) figure.savefig(figure_path) except Exception as e: print('Could not save pixel {} to : {} \n'.format( pixel, figure_path)) print(e) axis.remove() if args['--display']: spe_charge = Histogram1D.load(charge_histo_filename) spe_amplitude = Histogram1D.load(amplitude_histo_filename) raw_histo = Histogram1D.load( os.path.join(output_path, raw_histo_filename)) max_histo = Histogram1D.load(max_histo_filename) spe_charge.draw(index=(0, ), log=True, legend=False) spe_amplitude.draw(index=(0, ), log=True, legend=False) raw_histo.draw(index=(0, ), log=True, legend=False) max_histo.draw(index=(0, ), log=True, legend=False) try: df = pd.HDFStore(results_filename, mode='r') parameters = df['analysis_charge/spe_param'] parameters_error = df['analysis_charge/spe_param_errors'] dark_count_rate = np.load(dark_count_rate_filename)['dcr'] crosstalk = np.load(crosstalk_filename)['arr_0'] except IOError as e: print(e) print('Could not find the analysis files !') plt.show() exit() label = 'mean : {:2f} \n std : {:2f}' for key, val in parameters.items(): fig = plt.figure() axes = fig.add_subplot(111) axes.hist(val, bins='auto', label=label.format(np.mean(val), np.std(val))) axes.set_xlabel(key + ' []') axes.set_ylabel('count []') axes.legend(loc='best') # fig = plt.figure() # axes = fig.add_subplot(111) # axes.hist(parameters_error[key]) # axes.set_xlabel(key + '_error' + ' []') # axes.set_ylabel('count []') crosstalk = crosstalk[np.isfinite(crosstalk)] dark_count_rate = dark_count_rate[np.isfinite(dark_count_rate)] plt.figure() plt.hist(crosstalk, bins='auto', label=label.format(np.mean(crosstalk), np.std(crosstalk))) plt.xlabel('XT []') plt.legend(loc='best') plt.figure() plt.hist(dark_count_rate[np.isfinite(dark_count_rate)], bins='auto', label=label.format(np.mean(dark_count_rate), np.std(dark_count_rate))) plt.xlabel('dark count rate [GHz]') plt.legend(loc='best') plt.show() return
def main_pipeline(files, aux_basepath, max_events, dark_filename, integral_width, debug, hillas_filename, parameters_filename, picture_threshold, boundary_threshold, template_filename, saturation_threshold, threshold_pulse, bad_pixels=None, disable_bar=False): # get configuration with open(parameters_filename) as file: calibration_parameters = yaml.load(file) if bad_pixels is None: bad_pixels = get_bad_pixels(calib_file=parameters_filename, dark_histo=dark_filename, plot=None) pulse_template = NormalizedPulseTemplate.load(template_filename) pulse_area = pulse_template.integral() * u.ns ratio = pulse_template.compute_charge_amplitude_ratio( integral_width=integral_width, dt_sampling=4) # ~ 0.24 gain = np.array(calibration_parameters['gain']) # ~ 20 LSB / p.e. gain_amplitude = gain * ratio crosstalk = np.array(calibration_parameters['mu_xt']) bias_resistance = 10 * 1E3 * u.Ohm # 10 kOhm cell_capacitance = 50 * 1E-15 * u.Farad # 50 fF geom = DigiCam.geometry dark_histo = Histogram1D.load(dark_filename) dark_baseline = dark_histo.mean() # define pipeline events = calibration_event_stream(files, max_events=max_events, disable_bar=disable_bar) events = add_slow_data_calibration( events, basepath=aux_basepath, aux_services=('DriveSystem', 'DigicamSlowControl', 'MasterSST1M', 'SafetyPLC', 'PDPSlowControl')) events = baseline.fill_dark_baseline(events, dark_baseline) events = baseline.fill_digicam_baseline(events) events = tagging.tag_burst_from_moving_average_baseline(events) events = baseline.compute_baseline_shift(events) events = baseline.subtract_baseline(events) events = filters.filter_clocked_trigger(events) events = baseline.compute_nsb_rate(events, gain_amplitude, pulse_area, crosstalk, bias_resistance, cell_capacitance) events = baseline.compute_gain_drop(events, bias_resistance, cell_capacitance) events = peak.find_pulse_with_max(events) events = charge.compute_dynamic_charge( events, integral_width=integral_width, saturation_threshold=saturation_threshold, threshold_pulse=threshold_pulse, debug=debug, pulse_tail=False, ) events = charge.compute_photo_electron(events, gains=gain) events = charge.interpolate_bad_pixels(events, geom, bad_pixels) events = cleaning.compute_tailcuts_clean( events, geom=geom, overwrite=True, picture_thresh=picture_threshold, boundary_thresh=boundary_threshold, keep_isolated_pixels=False) events = cleaning.compute_boarder_cleaning(events, geom, boundary_threshold) events = cleaning.compute_dilate(events, geom) events = image.compute_hillas_parameters(events, geom) events = charge.compute_sample_photo_electron(events, gain_amplitude) events = cleaning.compute_3d_cleaning(events, geom, n_sample=50, threshold_sample_pe=20, threshold_time=2.1 * u.ns, threshold_size=0.005 * u.mm) # create pipeline output file output_file = Serializer(hillas_filename, mode='w', format='fits') data_to_store = PipelineOutputContainer() for event in events: if debug: print(event.hillas) print(event.data.nsb_rate) print(event.data.gain_drop) print(event.data.baseline_shift) print(event.data.border) plot_array_camera(np.max(event.data.adc_samples, axis=-1)) plot_array_camera( np.nanmax(event.data.reconstructed_charge, axis=-1)) plot_array_camera(event.data.cleaning_mask.astype(float)) plot_array_camera(event.data.reconstructed_number_of_pe) plt.show() # fill container data_to_store.local_time = event.data.local_time data_to_store.event_type = event.event_type data_to_store.event_id = event.event_id data_to_store.az = event.slow_data.DriveSystem.current_position_az data_to_store.el = event.slow_data.DriveSystem.current_position_el r = event.hillas.r phi = event.hillas.phi psi = event.hillas.psi alpha = compute_alpha(phi.value, psi.value) * psi.unit data_to_store.alpha = alpha data_to_store.miss = compute_miss(r=r.value, alpha=alpha.value) data_to_store.miss = data_to_store.miss * r.unit data_to_store.baseline = np.mean(event.data.digicam_baseline) data_to_store.nsb_rate = np.mean(event.data.nsb_rate) temp_crate1 = event.slow_data.DigicamSlowControl.Crate1_T temp_crate2 = event.slow_data.DigicamSlowControl.Crate2_T temp_crate3 = event.slow_data.DigicamSlowControl.Crate3_T temp_digicam = np.array( np.hstack([temp_crate1, temp_crate2, temp_crate3])) temp_digicam_mean = np.mean(temp_digicam[np.logical_and( temp_digicam > 0, temp_digicam < 60)]) data_to_store.digicam_temperature = temp_digicam_mean temp_sector1 = event.slow_data.PDPSlowControl.Sector1_T temp_sector2 = event.slow_data.PDPSlowControl.Sector2_T temp_sector3 = event.slow_data.PDPSlowControl.Sector3_T temp_pdp = np.array( np.hstack([temp_sector1, temp_sector2, temp_sector3])) temp_pdp_mean = np.mean(temp_pdp[np.logical_and( temp_pdp > 0, temp_pdp < 60)]) data_to_store.pdp_temperature = temp_pdp_mean target_radec = event.slow_data.MasterSST1M.target_radec data_to_store.target_ra = target_radec[0] data_to_store.target_dec = target_radec[1] status_leds = event.slow_data.SafetyPLC.SPLC_CAM_Status # bit 8 of status_LEDs is about on/off, bit 9 about blinking data_to_store.pointing_leds_on = bool((status_leds & 1 << 8) >> 8) data_to_store.pointing_leds_blink = bool((status_leds & 1 << 9) >> 9) hv_sector1 = event.slow_data.PDPSlowControl.Sector1_HV hv_sector2 = event.slow_data.PDPSlowControl.Sector2_HV hv_sector3 = event.slow_data.PDPSlowControl.Sector3_HV hv_pdp = np.array(np.hstack([hv_sector1, hv_sector2, hv_sector3]), dtype=bool) data_to_store.all_hv_on = np.all(hv_pdp) ghv_sector1 = event.slow_data.PDPSlowControl.Sector1_GHV ghv_sector2 = event.slow_data.PDPSlowControl.Sector2_GHV ghv_sector3 = event.slow_data.PDPSlowControl.Sector3_GHV ghv_pdp = np.array(np.hstack([ghv_sector1, ghv_sector2, ghv_sector3]), dtype=bool) data_to_store.all_ghv_on = np.all(ghv_pdp) is_on_source = bool(event.slow_data.DriveSystem.is_on_source) data_to_store.is_on_source = is_on_source is_tracking = bool(event.slow_data.DriveSystem.is_tracking) data_to_store.is_tracking = is_tracking data_to_store.shower = bool(event.data.shower) data_to_store.border = bool(event.data.border) data_to_store.burst = bool(event.data.burst) data_to_store.saturated = bool(event.data.saturated) for key, val in event.hillas.items(): data_to_store[key] = val output_file.add_container(data_to_store) try: output_file.close() print(hillas_filename, 'created.') except ValueError: print('WARNING: no data to save,', hillas_filename, 'not created.')
def entry(): args = docopt(__doc__) files = args['<INPUT>'] debug = args['--debug'] max_events = convert_int(args['--max_events']) output_path = args['--output'] if not os.path.exists(output_path): raise IOError('Path for output does not exists \n') pixel_id = convert_pixel_args(args['--pixel']) integral_width = int(args['--integral_width']) shift = int(args['--shift']) bin_width = int(args['--bin_width']) n_pixels = len(pixel_id) charge_histo_filename = os.path.join(output_path, 'charge_histo_fmpe.pk') amplitude_histo_filename = os.path.join(output_path, 'amplitude_histo_fmpe.pk') results_filename = os.path.join(output_path, 'fmpe_fit_results.fits') timing_filename = args['--timing'] n_samples = int(args['--n_samples']) ncall = int(args['--ncall']) estimated_gain = float(args['--estimated_gain']) if args['--compute']: compute(files, max_events=max_events, pixel_id=pixel_id, n_samples=n_samples, timing_filename=timing_filename, charge_histo_filename=charge_histo_filename, amplitude_histo_filename=amplitude_histo_filename, save=True, integral_width=integral_width, shift=shift, bin_width=bin_width) if args['--fit']: charge_histo = Histogram1D.load(charge_histo_filename) param_names = describe(FMPEFitter.pdf)[2:] param_error_names = [key + '_error' for key in param_names] columns = param_names + param_error_names columns = columns + ['chi_2', 'ndf'] data = np.zeros((n_pixels, len(columns))) * np.nan results = pd.DataFrame(data=data, columns=columns) for i, pixel in tqdm(enumerate(pixel_id), total=n_pixels, desc='Pixel'): histo = charge_histo[i] try: fitter = FMPEFitter(histo, estimated_gain=estimated_gain, throw_nan=True) fitter.fit(ncall=ncall) fitter = FMPEFitter(histo, estimated_gain=estimated_gain, initial_parameters=fitter.parameters, throw_nan=True) fitter.fit(ncall=ncall) param = dict(fitter.parameters) param_error = dict(fitter.errors) param_error = { key + '_error': val for key, val in param_error.items() } param.update(param_error) param['chi_2'] = fitter.fit_test() * fitter.ndf param['ndf'] = fitter.ndf results.iloc[pixel] = param if debug: x_label = 'Charge [LSB]' label = 'Pixel {}'.format(pixel) fitter.draw(x_label=x_label, label=label, legend=False) fitter.draw_fit(x_label=x_label, label=label, legend=False) fitter.draw_init(x_label=x_label, label=label, legend=False) print(results.iloc[pixel]) plt.show() except Exception as exception: print('Could not fit FMPE in pixel {}'.format(pixel)) print(exception) if not debug: with fitsio.FITS(results_filename, 'rw') as f: f.write(results.to_records(index=False)) if args['--save_figures']: charge_histo = Histogram1D.load(charge_histo_filename) figure_path = os.path.join(output_path, 'figures/') if not os.path.exists(figure_path): os.makedirs(figure_path) plot_results(results_filename, figure_path) for i, pixel in tqdm(enumerate(pixel_id), total=len(pixel_id)): try: plot_fit(charge_histo, results_filename, i, figure_path) plt.close() except Exception as e: print('Could not save pixel {} to : {} \n'.format( pixel, figure_path)) print(e) if args['--display']: pixel = 0 charge_histo = Histogram1D.load(charge_histo_filename) plot_results(results_filename) plot_fit(charge_histo, results_filename, pixel=pixel) plt.show() pass return
def entry(): args = docopt(__doc__) input_dir = convert_text(args['--input_dir']) output_dir = convert_text(args['--output_dir']) channel = convert_int(args['--channel']) polarization = convert_int(args['--polarization']) initial_values_dir = convert_text(args['--initial_values_dir']) debug = args['--debug'] if args['compute']: file_list = read.give_list_of_file(input_dir) pdf_charge_draw = PdfPages('{}/plots/charge_ch{}.pdf'.format( output_dir, channel)) for f in file_list: bias_voltage = float(re.findall('\d+\.\d+', f)[0]) f = input_dir + '/' + f print(f) baseline, peak_index = read.average_baseline( file=f, polarization=polarization) waveforms = read.read_data(file=f, polarization=polarization) integral_charge, left_int_bound, right_int_bound = get_integral_charge( waveform_iter=waveforms, peak_index=peak_index, baseline=baseline, integration_bounds=[10, 15]) waveforms = read.read_data(file=f, polarization=polarization) amplitude_charge, left_window_bound, right_window_bound = get_amplitude_charge( waveform_iter=waveforms, peak_index=peak_index, baseline=baseline, window_bound=[50, 100]) if debug: print('Charge debugging waveform') waveforms = read.read_data(file=f, polarization=polarization) cnt = 0 pdf_charge_debug = PdfPages( '{}/plots/debug_charge_ch{}_V{}.pdf'.format( output_dir, channel, bias_voltage)) for time, waveform in waveforms: if cnt % 1000 == 0: fig, ax = read.draw_waveform( time, waveform, baseline=baseline, label='waveform {}'.format(cnt)) time = time / 1e-6 waveform = waveform * 1e3 ax.plot(time[left_int_bound:right_int_bound], waveform[left_int_bound:right_int_bound], label='Integration samples', color='tab:red') ax.legend() pdf_charge_debug.savefig(fig) plt.close(fig) cnt += 1 pdf_charge_debug.close() print('End of charge debugging waveform') histo_data = [integral_charge, amplitude_charge] histo_label = ['integral charge', 'amplitude charge'] for i, data in enumerate(histo_data): # Histogram creation bins = 100 bin_edges = np.linspace(np.min(data), np.max(data) + 1, bins) histogram = Histogram1D(bin_edges=bin_edges) histogram.fill(data) # Histogram display fig, ax = plt.subplots() histogram.draw(axis=ax, label='{} : V = {} V'.format( histo_label[i], bias_voltage), legend=False) text = histogram._write_info(()) anchored_text = AnchoredText(text, loc=5) ax.add_artist(anchored_text) pdf_charge_draw.savefig(fig) print('{} at {} V figure saved'.format(histo_label[i], bias_voltage)) #plt.show() plt.close(fig) # Formatting to use in the digicampipe fitting single mpe method histogram.data = histogram.data.reshape((1, 1, -1)) histogram.overflow = histogram.overflow.reshape((1, -1)) histogram.underflow = histogram.underflow.reshape((1, -1)) histogram.save('{}/charge/{}/ch{}_V_{}.fits'.format( output_dir, histo_label[i].replace(" ", "_"), channel, bias_voltage)) pdf_charge_draw.close() if args['fit']: file_list = read.give_list_of_file(input_dir) yaml_list = read.give_list_of_file(initial_values_dir) file_list.sort() yaml_list.sort() print(file_list) print(yaml_list) fit_parameters = {} for k, f in enumerate(file_list): level = 'LVL_{}'.format(k) bias_voltage = float(re.findall('\d+\.\d+', f)[0]) print('Fitting charge') f = input_dir + '/' + f i_val = initial_values_dir + '/' + yaml_list[k] print('charge file :', f) print('initialization file :', i_val) with open(i_val) as file: init_parameters = yaml.load(file, Loader=yaml.FullLoader) print('Initial Fitting parameters', init_parameters) # We need this new format to make work our fit function, it was built that way temp_dict = {} for key, value in init_parameters.items(): temp_dict[key] = np.array([[value]]) init_parameters = temp_dict del temp_dict data = fit_single_mpe(f, ac_levels=[0], pixel_ids=[0], init_params=init_parameters, debug=True) temp_data = {} for key, value in data.items(): if key is not 'pixel_ids': temp_data[key] = (value[0][0]).tolist() temp_data['bias_voltage'] = bias_voltage fit_parameters[level] = temp_data print('fit_parameter', fit_parameters) fit_parameters_file = '{}/fit_parameters.yml'.format(output_dir) with open(fit_parameters_file, 'w') as file: yaml.dump(fit_parameters, file) if args['save_figure']: print('save_figure') file_list = read.give_list_of_file(input_dir) fig, ax = plt.subplots() for f in file_list: bias_voltage = float(re.findall('\d+\.\d+', f)[0]) f = os.path.join(input_dir, f) print('File : ', f) histogram = Histogram1D.load(f) histogram.draw(axis=ax, legend=False, label='Bias voltage : {}'.format(bias_voltage)) pdf_superposition_charge = PdfPages( os.path.join(output_dir, 'charge_in_bias_voltage_ch{}.pdf'.format(channel))) pdf_superposition_charge.savefig(fig) pdf_superposition_charge.close() #plt.show() plt.close(fig)
def entry(): args = docopt(__doc__) files = args['<INPUT>'] max_events = convert_int(args['--max_events']) pixel_id = convert_pixel_args(args['--pixel']) base_sub = args['--baseline_subtracted'] raw_histo_filename = args['--output'] event_types = convert_list_int(args['--event_types']) baseline_filename = args['--baseline_filename'] disable_bar = args['--disable_bar'] if baseline_filename.lower() == 'none': baseline_filename = None output_path = os.path.dirname(raw_histo_filename) if not os.path.exists(output_path) and output_path != "": raise IOError('Path {} for output ' 'does not exists \n'.format(output_path)) if args['--compute']: compute(files=files, filename=raw_histo_filename, max_events=max_events, pixel_id=pixel_id, event_types=event_types, disable_bar=disable_bar, baseline_subtracted=base_sub) if baseline_filename: compute_baseline_histogram(files=files, filename=baseline_filename, max_events=max_events, pixel_id=pixel_id, disable_bar=disable_bar) if args['--save_figures']: raw_histo = Histogram1D.load(raw_histo_filename) path = os.path.join(output_path, 'figures/', 'raw_histo/') if not os.path.exists(path): os.makedirs(path) figure = plt.figure() for i, pixel in tqdm(enumerate(pixel_id), total=len(pixel_id)): axis = figure.add_subplot(111) figure_path = os.path.join(path, 'pixel_{}.pdf') try: raw_histo.draw(index=(i, ), axis=axis, log=True, legend=False) figure.savefig(figure_path.format(pixel)) except Exception as e: print('Could not save pixel {} to : {} \n'.format( pixel, figure_path)) print(e) axis.remove() if args['--display']: raw_histo = Histogram1D.load(raw_histo_filename) pixel = 0 raw_histo.draw(index=(pixel, ), log=True, legend=False, label='Histogram {}'.format(pixel), x_label='[LSB]') mean_value = raw_histo.mean() plot_histo(mean_value, bins='auto', x_label='Mean value [LSB]') plot_array_camera(mean_value, label='Mean value [LSB]') if baseline_filename: baseline_histo = Histogram1D.load(baseline_filename) baseline_histo.draw(index=(pixel, ), log=True, legend=False, label='Histogram {}'.format(pixel), x_label='DigiCam baseline [LSB]') mean_baseline = baseline_histo.mean() plot_histo(mean_baseline, bins='auto', x_label='Mean DigiCam baseline [LSB]') plot_array_camera(mean_baseline, label='Mean DigiCam baseline [LSB]') plot_array_camera(mean_baseline - mean_value, label='Diff [LSB]') plot_histo(mean_baseline - mean_value, bins='auto', x_label='Diff [LSB]') plt.show()