def plot(self):
        h5_filename = self.output_filename + '.h5'

        self.logger.info('Starting plotting...')
        with tb.open_file(h5_filename, 'r') as h5_file:

            # Q: Maybe Plotting should not know about the file?
            with plotting.Plotting(h5_filename) as p:

                Vthreshold_start = p.run_config['Vthreshold_start']
                Vthreshold_stop = p.run_config['Vthreshold_stop']

                p.plot_parameter_page()

                mask = h5_file.root.configuration.mask_matrix[:]

                thr_matrix = h5_file.root.configuration.thr_matrix[:],
                p.plot_distribution(thr_matrix, plot_range=np.arange(-0.5, 16.5, 1), title='TDAC distribution', x_axis_title='TDAC', y_axis_title='# of hits', suffix='tdac_distribution')

                vth_hist = h5_file.root.interpreted.HitDistribution[:].T
                p.plot_scurves(vth_hist, range(Vthreshold_start, Vthreshold_stop), scan_parameter_name="Vthreshold")

                vths = h5_file.root.interpreted.PixelThresholdMap[:]
                p.plot_occupancy(vths, z_label='Threshold', title='Threshold', show_sum=False, suffix='threshold_map', z_min=Vthreshold_start, z_max=Vthreshold_stop)
                p.plot_distribution(vths, plot_range=np.arange(Vthreshold_start-0.5, Vthreshold_stop-0.5, 1), x_axis_title='Vthreshold', title='Threshold distribution', suffix='threshold_distribution')
예제 #2
0
    def plot(self, status = None, plot_queue = None, **kwargs):
        '''
            Plot data and histograms of the scan
            If there is a status queue information about the status of the scan are put into it
        '''

        h5_filename = self.output_filename + '.h5'

        self.logger.info('Starting plotting...')
        if status != None:
            status.put("Create Plots")
        with tb.open_file(h5_filename, 'r+') as h5_file:

            with plotting.Plotting(h5_filename) as p:

                # Read needed configuration parameters
                Vthreshold_start = int(p.run_config[b'Vthreshold_start'])
                Vthreshold_stop = int(p.run_config[b'Vthreshold_stop'])
                n_injections = int(p.run_config[b'n_injections'])

                # Plot a page with all parameters
                p.plot_parameter_page()

                mask = h5_file.root.configuration.mask_matrix[:]

                # Plot the occupancy matrix
                occ_masked = np.ma.masked_array(h5_file.root.interpreted.HistOcc[:], mask)
                p.plot_occupancy(occ_masked, title='Integrated Occupancy', z_max='median', suffix='occupancy', plot_queue=plot_queue)

                # Plot the equalisation bits histograms
                thr_matrix = h5_file.root.configuration.thr_matrix[:],
                p.plot_distribution(thr_matrix, plot_range=np.arange(-0.5, 16.5, 1), title='TDAC distribution', x_axis_title='TDAC', y_axis_title='# of hits', suffix='tdac_distribution', plot_queue=plot_queue)

                # Plot the S-Curve histogram
                scurve_hist = h5_file.root.interpreted.HistSCurve[:].T
                max_occ = n_injections * 5
                p.plot_scurves(scurve_hist, list(range(Vthreshold_start, Vthreshold_stop)), scan_parameter_name="Vthreshold", max_occ=max_occ, plot_queue=plot_queue)

                # Do not plot pixels with converged  S-Curve fits
                chi2_sel = h5_file.root.interpreted.Chi2Map[:] > 0.  # Mask not converged fits (chi2 = 0)
                mask[~chi2_sel] = True

                # Plot the threshold distribution based on the S-Curve fits
                hist = np.ma.masked_array(h5_file.root.interpreted.ThresholdMap[:], mask)
                p.plot_distribution(hist, plot_range=np.arange(Vthreshold_start-0.5, Vthreshold_stop-0.5, 1), x_axis_title='Vthreshold', title='Threshold distribution', suffix='threshold_distribution', plot_queue=plot_queue)

                # Plot the occupancy
                p.plot_occupancy(hist, z_label='Threshold', title='Threshold', show_sum=False, suffix='threshold_map', z_min=Vthreshold_start, z_max=Vthreshold_stop, plot_queue=plot_queue)

                # Plot the noise map
                hist = np.ma.masked_array(h5_file.root.interpreted.NoiseMap[:], mask)
                p.plot_distribution(hist, plot_range=np.arange(0.1, 20, 0.1), title='Noise distribution', suffix='noise_distribution', plot_queue=plot_queue)
                p.plot_occupancy(hist, z_label='Noise', title='Noise', show_sum=False, suffix='noise_map', z_min=0.1, z_max=20.0, plot_queue=plot_queue)
예제 #3
0
    def plot(self):
        h5_filename = self.output_filename + '.h5'

        self.logger.info('Starting plotting...')
        with tb.open_file(h5_filename, 'r') as h5_file:

            # Q: Maybe Plotting should not know about the file?
            with plotting.Plotting(h5_filename) as p:

                VTP_fine_start = p.run_config['VTP_fine_start']
                VTP_fine_stop = p.run_config['VTP_fine_stop']
                n_injections = p.run_config['n_injections']

                p.plot_parameter_page()

                mask = h5_file.root.configuration.mask_matrix[:]

                occ_masked = np.ma.masked_array(h5_file.root.interpreted.HistOcc[:], mask)
                p.plot_occupancy(occ_masked, title='Integrated Occupancy', z_max='median', suffix='occupancy')

                thr_matrix = h5_file.root.configuration.thr_matrix[:],
                p.plot_distribution(thr_matrix, plot_range=np.arange(-0.5, 16.5, 1), title='TDAC distribution', x_axis_title='TDAC', y_axis_title='# of hits', suffix='tdac_distribution')

                scurve_hist = h5_file.root.interpreted.HistSCurve[:].T
                max_occ = n_injections + 10
                p.plot_scurves(scurve_hist, range(VTP_fine_start, VTP_fine_stop), scan_parameter_name="VTP_fine", max_occ=max_occ)

                chi2_sel = h5_file.root.interpreted.Chi2Map[:] > 0.  # Mask not converged fits (chi2 = 0)
                mask[~chi2_sel] = True

                hist = np.ma.masked_array(h5_file.root.interpreted.ThresholdMap[:], mask)
                p.plot_distribution(hist, plot_range=np.arange((VTP_fine_start-0.5, VTP_fine_stop-0.5, 1), x_axis_title='VTP_fine', title='Threshold distribution', suffix='threshold_distribution')

                p.plot_occupancy(hist, z_label='Threshold', title='Threshold', show_sum=False, suffix='threshold_map', z_min=VTP_fine_start, z_max=VTP_fine_stop)

                hist = np.ma.masked_array(h5_file.root.interpreted.NoiseMap[:], mask)
                p.plot_distribution(hist, plot_range=np.arange(0.1, 4, 0.1), title='Noise distribution', suffix='noise_distribution')
                p.plot_occupancy(hist, z_label='Noise', title='Noise', show_sum=False, suffix='noise_map', z_min=0.1, z_max=4.0)


if __name__ == "__main__":
    scan = TestpulseScan()
    scan.start(**local_configuration)
    scan.analyze()
    scan.plot()
예제 #4
0
    def plot(self, status=None, plot_queue=None, **kwargs):
        '''
            Plot data and histograms of the scan
            If there is a status queue information about the status of the scan are put into it
        '''

        h5_filename = self.output_filename + '.h5'

        self.logger.info('Starting plotting...')
        if status != None:
            status.put("Create Plots")
        with tb.open_file(h5_filename, 'r+') as h5_file:

            with plotting.Plotting(h5_filename) as p:

                # Read needed configuration parameters
                Vthreshold_start = int(p.run_config[b'Vthreshold_start'])
                Vthreshold_stop = int(p.run_config[b'Vthreshold_stop'])

                # Plot a page with all parameters
                p.plot_parameter_page()

                mask = h5_file.root.configuration.mask_matrix[:]

                # Plot the equalisation bits histograms
                thr_matrix = h5_file.root.configuration.thr_matrix[:],
                p.plot_distribution(thr_matrix,
                                    plot_range=np.arange(-0.5, 16.5, 1),
                                    title='TDAC distribution',
                                    x_axis_title='TDAC',
                                    y_axis_title='# of hits',
                                    suffix='tdac_distribution',
                                    plot_queue=plot_queue)

                # Plot the noise pixels histogram
                noise_curve = h5_file.root.interpreted.NoiseCurve[:]
                p._plot_1d_hist(hist=noise_curve,
                                plot_range=list(
                                    range(Vthreshold_start, Vthreshold_stop)),
                                x_axis_title='Threshold',
                                y_axis_title='Number of active pixels',
                                plot_queue=plot_queue)
예제 #5
0
    def plot(self, status=None, plot_queue=None, **kwargs):
        '''
            Plot data and histograms of the scan
            If there is a status queue information about the status of the scan are put into it
        '''

        h5_filename = self.output_filename + '.h5'

        self.logger.info('Starting plotting...')
        if status != None:
            status.put("Create Plots")
        with tb.open_file(h5_filename, 'r+') as h5_file:
            with plotting.Plotting(h5_filename) as p:

                # Read needed configuration parameters
                VTP_fine_start = int(p.run_config[b'VTP_fine_start'])
                VTP_fine_stop = int(p.run_config[b'VTP_fine_stop'])
                VTP_coarse = int(p.dacs[b'VTP_coarse'])

                # Plot a page with all parameters
                p.plot_parameter_page()

                mask = h5_file.root.configuration.mask_matrix[:]

                # Plot the equalisation bits histograms
                thr_matrix = h5_file.root.configuration.thr_matrix[:],
                p.plot_distribution(thr_matrix,
                                    plot_range=np.arange(-0.5, 16.5, 1),
                                    title='TDAC distribution',
                                    x_axis_title='TDAC',
                                    y_axis_title='# of hits',
                                    suffix='tdac_distribution',
                                    plot_queue=plot_queue)

                # Plot the ToT-Curve histogram
                ToT_hist = h5_file.root.interpreted.HistToTCurve[:].T
                p.plot_scurves(ToT_hist.astype(int),
                               list(range(VTP_fine_start, VTP_fine_stop)),
                               electron_axis=False,
                               scan_parameter_name="VTP_fine",
                               max_occ=250,
                               ylabel='ToT Clock Cycles',
                               title='ToT curves',
                               plot_queue=plot_queue)

                # Plot the mean ToT-Curve with fit
                mean = h5_file.root.interpreted.mean_curve[:]

                fit_params = h5_file.root.interpreted.fit_params[:]
                a = [
                    float(item["value"]) for item in fit_params
                    if item[0] == b'a'
                ][0]
                ac = [
                    float(item["stddev"]) for item in fit_params
                    if item[0] == b'a'
                ][0]
                b = [
                    float(item["value"]) for item in fit_params
                    if item[0] == b'b'
                ][0]
                bc = [
                    float(item["stddev"]) for item in fit_params
                    if item[0] == b'b'
                ][0]
                c = [
                    float(item["value"]) for item in fit_params
                    if item[0] == b'c'
                ][0]
                cc = [
                    float(item["stddev"]) for item in fit_params
                    if item[0] == b'c'
                ][0]
                t = [
                    float(item["value"]) for item in fit_params
                    if item[0] == b't'
                ][0]
                tc = [
                    float(item["stddev"]) for item in fit_params
                    if item[0] == b't'
                ][0]

                mean['tot']
                mean['tot_error']
                points = np.linspace(t * 1.001, len(mean['tot']), 500)
                fit = analysis.totcurve(points, a, b, c, t)

                p.plot_two_functions(
                    range(len(mean['tot'])),
                    mean['tot'],
                    range(len(mean['tot'])),
                    mean['tot_error'],
                    points,
                    fit,
                    y_plot_range=[0, np.amax(fit[1])],
                    label_1='mean ToT',
                    label_2=
                    'fit with \na=(%.2f+/-%.2f), \nb=(%.2f+/-%.2f), \nc=(%.2f+/-%.2f), \nt=(%.2f+/-%.2f)'
                    % (a, ac, b, bc, c, cc, t, tc),
                    x_axis_title='VTP [2.5 mV]',
                    y_axis_title='ToT Clock Cycles [25 ns]',
                    title='ToT fit',
                    suffix='ToT fit',
                    plot_queue=plot_queue)
예제 #6
0
    def plot(self, file_name, args):

        self.logger.info('Starting plotting...')

        new_file = args_dict["new_file"]
        if new_file:
            file_name = file_name.replace("data_take", "analysis")

        with tb.open_file(file_name, 'r+') as h5_file:
            with plotting.Plotting(file_name) as p:
                p.plot_parameter_page()

                hit_data_x = np.empty(0, dtype=np.uint32)
                hit_data_y = np.empty(0, dtype=np.uint32)
                tot = np.empty(0, dtype=np.uint32)
                toa = np.empty(0, dtype=np.uint32)
                toa_comb = np.empty(0, dtype=np.uint64)

                # iterate over all hit_data groups in the hdf5 file and build arrays for the histograms
                for group in h5_file.root.interpreted:
                    hit_data = group[:]
                    hit_data_x = np.concatenate((hit_data_x, hit_data['x']),
                                                axis=None)
                    hit_data_y = np.concatenate((hit_data_y, hit_data['y']),
                                                axis=None)
                    tot = np.concatenate((tot, hit_data['TOT']), axis=None)
                    toa = np.concatenate((toa, hit_data['TOA']), axis=None)
                    toa_comb = np.concatenate(
                        (toa_comb, hit_data['TOA_Combined']), axis=None)

                # Plot general hit properties

                # Plot the occupancy matrix
                pix_occ = np.bincount(hit_data_x * 256 + hit_data_y,
                                      minlength=256 * 256).astype(np.uint32)
                hist_occ = np.reshape(pix_occ, (256, 256)).T
                p.plot_occupancy(hist_occ,
                                 title='Integrated Occupancy',
                                 z_max='maximum',
                                 suffix='occupancy')

                # Plot the ToT-Curve histogram
                p.plot_distribution(tot,
                                    plot_range=np.arange(
                                        np.amin(tot) - 0.5,
                                        np.median(tot) * 7, 5),
                                    x_axis_title='ToT',
                                    title='ToT distribution',
                                    suffix='ToT_distribution',
                                    fit=False)

                # Plot the ToA-Curve histogram
                p.plot_distribution(toa,
                                    plot_range=np.arange(
                                        np.amin(toa) - 0.5, np.amax(toa), 100),
                                    x_axis_title='ToA',
                                    title='ToA distribution',
                                    suffix='ToA_distribution',
                                    fit=False)

                # Plot the ToA_Combined-Curve histogram
                p.plot_distribution(
                    toa_comb,
                    plot_range=np.arange(
                        np.amin(toa_comb), np.amax(toa_comb),
                        (np.amax(toa_comb) - np.amin(toa_comb)) // 100),
                    x_axis_title='ToA_Combined',
                    title='ToA_Combined distribution',
                    suffix='ToA_Combined_distribution',
                    fit=False)

                hist_size = np.empty(0, dtype=np.uint32)
                hist_sum = np.empty(0, dtype=np.uint32)
                first = True

                # iterate over all run_* groups in the hdf5 file and build arrays for the histograms
                for group in h5_file.root.reconstruction:
                    hist_size = np.concatenate((hist_size, group.hits[:]),
                                               axis=None)
                    hist_sum = np.concatenate((hist_sum, group.sumTOT[:]),
                                              axis=None)
                    if first == False:
                        histcha = np.concatenate((histcha, group.TOT[:]),
                                                 axis=0)
                        histtoa = np.concatenate((histtoa, group.TOA[:]),
                                                 axis=0)
                        histindex = np.concatenate(
                            (histindex, group.hit_index[:]), axis=0)
                    else:
                        histcha = np.array(group.TOT[:], dtype=object)
                        histtoa = np.array(group.TOA[:], dtype=object)
                        histindex = np.array(group.hit_index[:], dtype=object)
                        first = False
                """histindex = histindex.flatten()
                u, c = np.unique(histindex, return_counts=True)
                dup = u[c > 1]
                print(dup)"""

                # Plot cluster properties

                num_cluster = len(hist_size)

                # Plot the Cluster Size
                p.plot_distribution(hist_size,
                                    plot_range=np.arange(
                                        -0.5,
                                        np.median(hist_size) * 7 + 0.5, 1),
                                    x_axis_title='Cluster Size',
                                    y_axis_title='# of clusters',
                                    title='Size distribution' +
                                    r' ($\Sigma$ = {0})'.format(num_cluster),
                                    suffix='Size_distribution',
                                    fit=False)

                # Plot the Cluster ToT
                p.plot_distribution(hist_sum,
                                    plot_range=np.arange(
                                        np.amin(hist_sum) - 0.5,
                                        np.median(hist_sum) * 7, 5),
                                    x_axis_title='Cluster ToT',
                                    y_axis_title='# of clusters',
                                    title='Cluster ToT distribution',
                                    suffix='Cluster_toT_distribution',
                                    fit=False)

                # Plot the Cluster ToT for all clusters with more than one pixel
                histm1 = hist_sum[hist_size != 1]
                p.plot_distribution(
                    histm1,
                    plot_range=np.arange(
                        np.amin(hist_sum) - 0.5,
                        np.median(hist_sum) * 7, 5),
                    x_axis_title=
                    'Cluster ToT for clusters with more than one pixel',
                    y_axis_title='# of clusters',
                    title=
                    'Cluster ToT distribution for clusters with more than one pixel',
                    suffix='Cluster_toT_distribution',
                    fit=False)

                # Plot the Cluster ToT for all clusters with one pixel
                histe1 = hist_sum[hist_size == 1]
                p.plot_distribution(
                    histe1,
                    plot_range=np.arange(
                        np.amin(hist_sum) - 0.5,
                        np.median(hist_sum) * 7, 5),
                    x_axis_title='Cluster ToT for clusters with one pixel',
                    y_axis_title='# of clusters',
                    title=
                    'Cluster ToT distribution for clusters with one pixel',
                    suffix=
                    'Cluster_toT_distribution for clusters with one pixel',
                    fit=False)

                # K7
                #a = 10.17
                #b = -4307.6
                #c = -52649.2
                #t = 268.85
                # I7 THR=800
                #a = 8.8
                #b = -3910.2
                #c = -66090.6
                #t = 258.61
                # I7 THR=1000
                a = 8.0
                b = -2964.3
                c = -46339.0
                t = 206.31
                # I7 THR=1100
                #a = 7.4
                #b = -2288.9
                #c = -7204.0
                #t = 236.44
                histch = np.zeros(len(histcha))
                for i, el in enumerate(histcha):
                    for value in el:
                        histch[i] += 3 * np.abs(
                            100 * 0.005 -
                            (-(b - value * 25 - t * a) / (2 * a) + np.sqrt(
                                ((b - value * 25 - t * a) / (2 * a))**2 -
                                (value * 25 * t - b * t - c) / a)) * 2 / 2.5 *
                            0.0025) / 1.602 * 10**4

                #p.plot_distribution(histch, plot_range = np.arange(np.amin(histch)-0.5, np.median(histch) *7, 500), x_axis_title='Number of electrons per cluster', y_axis_title='# of clusters', title='Number of electrons per cluster', suffix='Number of electrons per cluster', fit=False)

                p.plot_distribution(
                    histch,
                    plot_range=np.arange(0, 48000, 500),
                    x_axis_title='Number of electrons per cluster',
                    y_axis_title='# of clusters',
                    title='Number of electrons per cluster',
                    suffix='Number of electrons per cluster',
                    fit=False)

                histchm1 = histch[hist_size != 1]
                p.plot_distribution(
                    histchm1,
                    plot_range=np.arange(
                        np.amin(histch) - 0.5,
                        np.median(histch) * 7, 500),
                    x_axis_title=
                    'Number of electrons per cluster for clusters with more than one pixel',
                    y_axis_title='# of clusters',
                    title=
                    'Number of electrons per cluster for clusters with more than one pixel',
                    suffix=
                    'Number of electrons per cluster for clusters with more than one pixel',
                    fit=False)

                histche1 = histch[hist_size == 1]
                p.plot_distribution(
                    histche1,
                    plot_range=np.arange(
                        np.amin(histch) - 0.5,
                        np.median(histch) * 7, 500),
                    x_axis_title=
                    'Number of electrons per cluster for clusters with only one pixel',
                    y_axis_title='# of clusters',
                    title=
                    'Number of electrons per cluster for clusters with only one pixel',
                    suffix=
                    'Number of electrons per cluster for clusters with only one pixel',
                    fit=False)

                histche2 = histch[hist_size == 2]
                p.plot_distribution(
                    histche2,
                    plot_range=np.arange(
                        np.amin(histch) - 0.5,
                        np.median(histch) * 7, 500),
                    x_axis_title=
                    'Number of electrons per cluster for clusters with two pixel',
                    y_axis_title='# of clusters',
                    title=
                    'Number of electrons per cluster for clusters with two pixel',
                    suffix=
                    'Number of electrons per cluster for clusters with only one pixel',
                    fit=False)

                histche3 = histch[hist_size == 3]
                p.plot_distribution(
                    histche3,
                    plot_range=np.arange(
                        np.amin(histch) - 0.5,
                        np.median(histch) * 7, 500),
                    x_axis_title=
                    'Number of electrons per cluster for clusters with three pixel',
                    y_axis_title='# of clusters',
                    title=
                    'Number of electrons per cluster for clusters with three pixel',
                    suffix=
                    'Number of electrons per cluster for clusters with only one pixel',
                    fit=False)

                histche4 = histch[hist_size == 4]
                p.plot_distribution(
                    histche4,
                    plot_range=np.arange(
                        np.amin(histch) - 0.5,
                        np.median(histch) * 7, 500),
                    x_axis_title=
                    'Number of electrons per cluster for clusters with four pixel',
                    y_axis_title='# of clusters',
                    title=
                    'Number of electrons per cluster for clusters with four pixel',
                    suffix=
                    'Number of electrons per cluster for clusters with only one pixel',
                    fit=False)

                # Plot the charge for all pixels
                hist = np.empty(len(tot))
                for i, value in enumerate(tot):
                    hist[i] = 3 * np.abs(
                        100 * 0.005 -
                        (-(b - value * 25 - t * a) /
                         (2 * a) + np.sqrt(((b - value * 25 - t * a) /
                                            (2 * a))**2 -
                                           (value * 25 * t - b * t - c) / a)) *
                        2 / 2.5 * 0.0025) / 1.602 * 10**4
                p.plot_distribution(
                    hist,
                    plot_range=np.arange(0 - 0.5,
                                         np.median(hist) * 7, 500),
                    x_axis_title='Number of electrons per pixel',
                    y_axis_title='# of pixels',
                    title='Number of electrons per pixel',
                    suffix='Number of electrons per pixel',
                    fit=False)

                # plot the ToA spread in the clusters
                hist_spread = np.empty(len(tot))
                ind = 0
                for i, el in enumerate(histtoa):
                    if not len(el) == 1:
                        m = np.mean(el)
                        for value in el:
                            hist_spread[ind] = value - m
                            ind += 1
                p.plot_distribution(
                    hist_spread,
                    plot_range=np.arange(-10.125, 10.125, 0.25),
                    x_axis_title='Deviation from mean ToA of cluster',
                    y_axis_title='# of pixels',
                    title='Deviation from mean ToA of cluster',
                    suffix='Deviation from mean ToA of cluster',
                    fit=True)
예제 #7
0
    def plot(self, status = None, plot_queue = None, **kwargs):
        '''
            Plot data and histograms of the scan
            If there is a status queue information about the status of the scan are put into it
        '''

        h5_filename = self.output_filename + '.h5'

        self.logger.info('Starting plotting...')
        if status != None:
            status.put("Create Plots")
        with tb.open_file(h5_filename, 'r+') as h5_file:
            with plotting.Plotting(h5_filename, iteration = 0) as p:

                # Read needed configuration parameters
                iterations = int(p.run_config[b'n_pulse_heights'])
                Vthreshold_start = int(p.run_config[b'Vthreshold_start'])
                Vthreshold_stop = int(p.run_config[b'Vthreshold_stop'])
                n_injections = int(p.run_config[b'n_injections'])

                # Plot a page with all parameters
                p.plot_parameter_page()

                # Plot the equalisation bits histograms
                thr_matrix = h5_file.root.configuration.thr_matrix_0[:],
                p.plot_distribution(thr_matrix, plot_range=np.arange(-0.5, 16.5, 1), title='TDAC distribution', x_axis_title='TDAC', y_axis_title='# of hits', suffix='tdac_distribution', plot_queue=plot_queue)

                mask = h5_file.root.configuration.mask_matrix_0[:]

                # remove the calibration node if it already exists
                try:
                    h5_file.remove_node(h5_file.root.calibration, recursive=True)
                except:
                    pass
                
                # create a group for the calibration results
                h5_file.create_group(h5_file.root, 'calibration', 'Threshold calibration results')

                # create a table for the calibration results
                data_type = {'names': ['pulse_height', 'threshold', 'threshold_error'],
                             'formats': ['double', 'double', 'double']}
                calib_results = np.recarray(iterations, dtype=data_type)

                # create arrays for the calibration data points
                pulse_heights = np.zeros(iterations, dtype=float)
                thresholds = np.zeros(iterations, dtype=float)
                errors = np.zeros(iterations, dtype=float)

                # iterate though the iteration to plot the iteration specific results
                for iteration in range(iterations):

                    HistSCurve_call = ('h5_file.root.interpreted_' + str(iteration) + '.HistSCurve' + '[:]')
                    Chi2Map_call = ('h5_file.root.interpreted_' + str(iteration) + '.Chi2Map' + '[:]')
                    ThresholdMap_call = ('h5_file.root.interpreted_' + str(iteration) + '.ThresholdMap' + '[:]')

                    # Plot the S-Curve histogram
                    scurve_hist = eval(HistSCurve_call).T
                    max_occ = n_injections * 5
                    p.plot_scurves(scurve_hist, list(range(Vthreshold_start, Vthreshold_stop)), scan_parameter_name="Vthreshold", max_occ=max_occ, plot_queue=plot_queue)

                    # Do not plot pixels with converged  S-Curve fits
                    chi2_sel = eval(Chi2Map_call) > 0. # Mask not converged fits (chi2 = 0)
                    mask[~chi2_sel] = True

                    # Plot the threshold distribution based on the S-Curve fits
                    hist = np.ma.masked_array(eval(ThresholdMap_call), mask)
                    it_parameters, it_errors = p.plot_distribution(hist, plot_range=np.arange(Vthreshold_start-0.5, Vthreshold_stop-0.5, 1), x_axis_title='Vthreshold', title='Threshold distribution', suffix='threshold_distribution', plot_queue=plot_queue)

                    # Fill the iteration results in the calibration parameter arrays
                    pulse_heights[iteration] = ((211 + (100 // iterations) * iteration) - 200) * 46.75
                    thresholds[iteration] = it_parameters[1]
                    errors[iteration] = it_parameters[2]

                # Fill the table with the calibration results
                calib_results['pulse_height'] = pulse_heights
                calib_results['threshold'] = thresholds
                calib_results['threshold_error'] = errors

                # Save the table to the HDF5 file
                h5_file.create_table(h5_file.root.calibration, 'calibration_results', calib_results)

                # Create the calibration plot
                p.plot_datapoints(pulse_heights, thresholds, x_plot_range=np.arange(0, 5500, 1), y_plot_range=np.arange(0, 3000, 1), y_err = errors, x_axis_title = 'Charge in electrons', y_axis_title = 'Threshold', title='Threshold calibration', suffix='threshold_calibration', plot_queue=plot_queue)