def main():
    parser = argparse.ArgumentParser(
        description="Generate Camera configuration files")
    parser.add_argument('-o', dest='output', help='Output directory')
    args = parser.parse_args()
    output_dir = args.output

    create_directory(output_dir)

    n_samples = 96
    spe = SiPMPrompt(opct=0.1, normalise_charge=False)
    camera_kwargs = dict(
        mapping=SSTCameraMapping(),
        photoelectron_spectrum=spe,
        n_waveform_samples=n_samples,
        continuous_readout_duration=n_samples,
        readout_noise=GaussianNoise(stddev=2),
        digitisation_noise=GaussianNoise(stddev=1),
    )

    for mv_per_pe in [0.5, 0.8, 1.1, 1.375, 2.25, 3.125, 4]:
        for width in [2, 4, 6, 8, 10, 14, 20]:
            sigma = width / 2.355
            pulse = GaussianPulse(30, sigma, 60, mv_per_pe=mv_per_pe)
            coupling = ACOffsetCoupling(pulse_area=pulse.area,
                                        spectrum_average=spe.average)
            camera = Camera(**camera_kwargs,
                            photoelectron_pulse=pulse,
                            coupling=coupling)

            name = f"width_{width:.2f}_height_{mv_per_pe:.2f}.pkl"
            camera.save(join(output_dir, name))
def main():
    parser = argparse.ArgumentParser(
        description="Generate Camera configuration files")
    parser.add_argument('-o', dest='output', help='Output directory')
    args = parser.parse_args()
    output_dir = args.output

    create_directory(output_dir)

    n_samples = 128
    width = 14
    sigma = width / 2.355

    for opct in np.linspace(0, 0.5, 6):
        for mv_per_pe in np.linspace(0.4, 4, 5):
            for nsb in np.linspace(0, 50, 5):
                pulse = GaussianPulse(20, sigma, 40, mv_per_pe=mv_per_pe)
                spe = SiPMPrompt(opct=opct, normalise_charge=False)
                coupling = ACOffsetCoupling(pulse_area=pulse.area,
                                            spectrum_average=spe.average)
                camera = Camera(
                    mapping=SSTCameraMapping(),
                    photoelectron_spectrum=spe,
                    photoelectron_pulse=pulse,
                    coupling=coupling,
                    n_waveform_samples=n_samples,
                    continuous_readout_duration=n_samples,
                    readout_noise=GaussianNoise(stddev=0.5),
                    digitisation_noise=GaussianNoise(stddev=1),
                )
                camera.attach_metadata("nsb", nsb)
                name = f"camera_{opct:.2f}_{mv_per_pe:.2f}_{nsb:.2f}.pkl"
                camera.save(join(output_dir, name))
示例#3
0
def get_camera_and_readout(pulse_width, mv_per_pe, spectrum, nsb_rate):
    camera = Camera(continuous_readout_duration=int(2e5),
                    n_waveform_samples=int(2e5),
                    mapping=SSTCameraMapping(n_pixels=1),
                    photoelectron_pulse=GaussianPulse(sigma=pulse_width,
                                                      mv_per_pe=mv_per_pe),
                    photoelectron_spectrum=spectrum)
    source = PhotoelectronSource(camera=camera, seed=1)
    acquisition = EventAcquisition(camera=camera, seed=1)
    pe = source.get_nsb(nsb_rate)
    return camera, acquisition.get_continuous_readout(pe)
示例#4
0
def test_neighbour():
    mapping = SSTCameraMapping(n_pixels=16)
    n_photoelectrons = 1000000
    photoelectrons = Photoelectrons(
        pixel=np.zeros(n_photoelectrons, dtype=int),
        time=np.full(n_photoelectrons, 10.),
        charge=np.ones(n_photoelectrons),
    )

    rng = np.random.RandomState(seed=1)

    spectrum_template = SiPMReflectedOCT(mapping=mapping, reflected_scale=5)
    result = spectrum_template.apply(photoelectrons, rng)
    charge = result.get_charge_per_pixel(mapping.n_pixels)
    assert (charge > 0).all()
示例#5
0
def main():
    normalise_charge = True
    spectra = {
        "No OCT":
        SiPMPrompt(opct=0, normalise_charge=normalise_charge),
        "Prompt OCT (20%)":
        SiPMPrompt(opct=0.2, normalise_charge=normalise_charge),
        "Delayed OCT (20%, τ=24ns)":
        SiPMDelayed(opct=0.2,
                    time_constant=24,
                    normalise_charge=normalise_charge),
        "Delayed OCT (55%, τ=24ns)":
        SiPMDelayed(opct=0.55,
                    time_constant=24,
                    normalise_charge=normalise_charge),
    }

    path = "/Users/Jason/Software/TargetCalib/source/dev/reference_pulse_checs_V1-1-0.cfg"
    ref_x, ref_y = np.loadtxt(path, unpack=True)
    pulse = GenericPulse(ref_x * 1e9, ref_y, mv_per_pe=4)

    p_waveform = WaveformPlot(talk=True)

    for name, spectrum in spectra.items():
        camera = Camera(
            continuous_readout_duration=128,
            n_waveform_samples=128,
            mapping=SSTCameraMapping(n_pixels=1),
            photoelectron_spectrum=spectrum,
            photoelectron_pulse=pulse,
        )
        source = PhotoelectronSource(camera=camera)
        acquisition = EventAcquisition(camera=camera)
        n_events = 100
        waveform = np.zeros((n_events, 128))
        for iev in trange(n_events):
            pe = source.get_uniform_illumination(30, 50)
            readout = acquisition.get_continuous_readout(pe)
            waveform[iev] = acquisition.get_sampled_waveform(readout)[0]
        waveform_avg = np.mean(waveform, 0)

        p_waveform.ax.plot(waveform_avg, label=name)

    p_waveform.add_legend('best')
    p_waveform.ax.set_xlabel("Time (ns)")
    p_waveform.ax.set_ylabel("Amplitude (mV)")
    p_waveform.ax.set_title("Average Pulse (50 p.e.)")
    p_waveform.save("pulse.pdf")
示例#6
0
def main():
    parser = argparse.ArgumentParser(
        description="Generate Camera configuration files")
    parser.add_argument('-o', dest='output', help='Output directory')
    args = parser.parse_args()
    output_dir = args.output

    create_directory(output_dir)

    # Define camera
    n_samples = 128
    width = 8  # ns
    sigma = width / (2 * np.sqrt(2 * np.log(2)))
    pulse = GaussianPulse(mean=15, sigma=sigma, duration=30, mv_per_pe=4)
    mapping = SSTCameraMapping()
    camera_kwargs = dict(
        mapping=mapping,
        photoelectron_pulse=pulse,
        n_waveform_samples=n_samples,
        continuous_readout_duration=n_samples,
        digitisation_noise=GaussianNoise(stddev=1),
    )

    self_opct_l = [0.08, 0.15, 0.3]
    reflected_opct_l = [0, 0.08, 0.15, 0.3]
    reflected_scale_l = [0.6, 1.0, 1.5, 2.3, 5]
    for self_opct in self_opct_l:
        for reflected_opct in reflected_opct_l:
            for reflected_scale in reflected_scale_l:
                spe = SiPMReflectedOCT(
                    opct=self_opct,
                    reflected_opct=reflected_opct,
                    reflected_scale=reflected_scale,
                    normalise_charge=False,
                    mapping=mapping,
                )
                coupling = ACOffsetCoupling(pulse_area=pulse.area,
                                            spectrum_average=spe.average)
                camera = Camera(**camera_kwargs,
                                photoelectron_spectrum=spe,
                                coupling=coupling)
                name = f"refl_opct_{self_opct:.2f}_{reflected_opct:.2f}_{reflected_scale:.2f}.pkl"
                camera.save(join(output_dir, name))
示例#7
0
def main():
    spectrum = SiPMGentileSPE(opct=0.2, normalise_x=False)
    camera = Camera(photoelectron_spectrum=spectrum,
                    mapping=SSTCameraMapping(n_pixels=1))
    n_events = 200000

    source = PhotoelectronSource(camera=camera)
    pe1 = []
    pe50 = []
    for iev in trange(n_events):
        pe1.append(source.get_uniform_illumination(20, 1).charge.sum())
        pe50.append(source.get_uniform_illumination(20, 20).charge.sum())
    pe1 = np.array(pe1)
    pe50 = np.array(pe50)

    # embed()

    plot = SpectrumPlot(sidebyside=True)
    plot.ax.hist(
        pe1,
        bins=70,
        histtype='step',
        label=f"λ = 1, Average Charge Per Event = {pe1.mean():.2f} f.c.")
    plot.ax.hist(
        pe50,
        bins=70,
        histtype='step',
        label=f"λ = 20, Average Charge Per Event = {pe50.mean():.2f} f.c.")
    # plot.ax.set_yscale('log')
    plot.ax.set_xlabel("Charge Per Event (f.c.)")
    plot.ax.set_ylabel("Number of Events")
    plot.add_legend('best')
    plot.save(get_plot("d201029_sipm_calib_doc/charge_mc.pdf"))

    spectrum = SiPMGentileSPE(opct=0.2, normalise_x=True)
    camera = Camera(photoelectron_spectrum=spectrum,
                    mapping=SSTCameraMapping(n_pixels=1))
    n_events = 200000

    source = PhotoelectronSource(camera=camera)
    pe1 = []
    pe50 = []
    for iev in trange(n_events):
        pe1.append(source.get_uniform_illumination(20, 1).charge.sum())
        pe50.append(source.get_uniform_illumination(20, 20).charge.sum())
    pe1 = np.array(pe1)
    pe50 = np.array(pe50)

    # embed()

    plot = SpectrumPlot(sidebyside=True)
    plot.ax.hist(
        pe1,
        bins=70,
        histtype='step',
        label=f"λ = 1, Average Charge Per Event = {pe1.mean():.2f} p.e.")
    plot.ax.hist(
        pe50,
        bins=70,
        histtype='step',
        label=f"λ = 20, Average Charge Per Event = {pe50.mean():.2f} p.e.")
    # plot.ax.set_yscale('log')
    plot.ax.set_xlabel("Charge Per Event (p.e.)")
    plot.ax.set_ylabel("Number of Events")
    plot.add_legend('best')
    plot.save(get_plot("d201029_sipm_calib_doc/charge_pe.pdf"))
def main():
    camera = Camera(
        continuous_readout_duration=10000,
        mapping=SSTCameraMapping(n_pixels=1),
        photoelectron_spectrum=SiPMDelayed(opct=0.2, time_constant=24),
        # photoelectron_spectrum=PerfectPhotosensor(),
    )
    source = PhotoelectronSource(camera=camera)
    nsb_rate = 2.3
    n_events = 100000
    dt = []
    rng = np.random.RandomState(None)
    for iev in trange(n_events):
        pe = source.get_nsb(rate=nsb_rate)
        # pe = Photoelectrons(
        #     pixel=np.zeros(1),
        #     time=np.full(1, 20.),
        #     charge=np.ones(1),
        # )
        # pe = camera.photoelectron_spectrum.apply(pe, rng)
        time = np.sort(pe.time)
        # time = pe.time
        if time.size > 1:
            # embed()
            dt.append(time[1] - time[0])
            # dt.append(time[1:] - time[0])
            # if (np.diff(time) < 100).any():
            #     embed()
            # dt.append(np.diff(time))
    # dt = dt[dt < 1000]
    # dt = (time - time[:, None]).ravel()
    # dt = dt[dt > 8]
    # embed()
    dt = np.array(dt)
    # dt = np.concatenate(dt)
    dt = dt[(dt > 0) & (dt < 1000)]
    hist, edges = np.histogram(dt, bins=200)
    between = (edges[1:] + edges[:-1]) / 2

    def func(t, a0, tc0, a1, tc1):
        return a0 * 1 / tc0 * np.exp(t / -tc0) + a1 * 1 / tc1 * np.exp(
            t / -tc1)

    def cost_binned_nll(a0, tc0, a1, tc1):
        f_y = func(between, a0, tc0, a1, tc1)
        scale = np.sum(hist) / np.sum(f_y)
        return np.sum(_bin_nll(f_y * scale, hist))

    def cost_ls(a0, tc0, a1, tc1):
        f_y = func(between, a0, tc0, a1, tc1)
        gt5 = hist > 5
        return np.sum((hist[gt5] - f_y[gt5])**2 / hist[gt5])

    def cost_unbinned_nll(a0, tc0, a1, tc1):
        if np.isnan(np.array([a0, tc0, a1, tc1])).any():
            return np.inf
        f_y = func(dt, a0, tc0, a1, tc1)
        return -_sum_log_x(f_y)

    initial = dict(a0=1, tc0=30, a1=1, tc1=1e3 / nsb_rate)
    limits = dict(limit_a0=(0, None),
                  limit_tc0=(1, None),
                  limit_a1=(0, None),
                  limit_tc1=(1, None))
    fixed = dict(
        # fix_a0=True,
        # fix_tc0=True,
        # fix_a1=True,
        # fix_tc1=True
    )

    m0 = iminuit.Minuit(
        cost_binned_nll,
        **initial,
        **limits,
        **fixed,
        errordef=0.5,
        print_level=0,
        pedantic=False,
        throw_nan=True,
    )
    m0.migrad()
    m0.hesse()

    # # Attempt to run HESSE to compute parabolic errors.
    # with warnings.catch_warnings():
    #     warnings.simplefilter("ignore", iminuit.util.HesseFailedWarning)
    #     m0.hesse()

    # embed()
    print(m0.values)
    print(m0.errors)

    # popt, pcov = curve_fit(func, between, hist)
    # embed()
    p_timesep = TimeSeperationPlot(talk=True)
    # p_timesep.ax.hist(dt, bins=100)#, density=True)
    # p_timesep.ax.plot(between, hist, '.')
    (_, caps, _) = p_timesep.ax.errorbar(between,
                                         hist,
                                         yerr=np.sqrt(hist),
                                         mew=1,
                                         capsize=1,
                                         elinewidth=0.5,
                                         markersize=2,
                                         linewidth=0.5,
                                         fmt='.',
                                         zorder=1)
    # p_timesep.ax.errorbar(between, hist, yerr=np.sqrt(hist))
    f_y = func(between, *m0.values.values())
    scale = np.sum(hist) / np.sum(f_y)
    p_timesep.ax.plot(between, f_y * scale)
    p_timesep.ax.text(0.1,
                      0.8,
                      fr"$τ_S$={m0.values['tc0']:.2f}",
                      transform=p_timesep.ax.transAxes)
    p_timesep.ax.text(0.7,
                      0.4,
                      fr"$τ_L$={m0.values['tc1']:.2f}",
                      transform=p_timesep.ax.transAxes)
    p_timesep.ax.set_yscale("log")
    p_timesep.ax.set_xlabel("Δt (ns)")
    p_timesep.save("timesep.pdf")