Tutorial plot waveform e persistenza¶

Esempio di visualizzazione di waveform per i dati di Techno-CLS, T9, agosto 2023.
Questi dati non sono disponibili, ho convertito ad hoc alcuni hbook in root

In [1]:
import numpy as np
import sys, os, re, glob
import uproot
from matplotlib import pyplot as plt
import matplotlib as mpl

Definisco il percorso e la run da usare

In [2]:
path = "/eos/project/i/insulab-como/testBeam/TB_T9_2023_08_OREO/miscROOT"
numRun = 680233

nameFile = f"run{numRun}_00001.root"
nameFile = f"run{numRun}.root"

fileToLoad = os.path.join(path, nameFile)

Carico il file e ispeziono il contenuto e la struttura¶

In [3]:
with uproot.open(fileToLoad) as f:
    for k in f:
        print(k)
        try:
            for kk in f[k]:
                print(kk)
        except:
            pass
h1;1
<TBranch 'Ievent' at 0x7ff7cb7e72e0>
<TBranch 'Itime' at 0x7ff7cb7e7b20>
<TBranch 'Iatime' at 0x7ff7cb717310>
<TBranch 'N1' at 0x7ff7cb717ac0>
<TBranch 'N2' at 0x7ff7cb71d2b0>
<TBranch 'N3' at 0x7ff7cb71da60>
<TBranch 'N4' at 0x7ff7cb724250>
<TBranch 'N5' at 0x7ff7cb724a00>
<TBranch 'N6' at 0x7ff7cb7281f0>
<TBranch 'N7' at 0x7ff7cb7289a0>
<TBranch 'N8' at 0x7ff7cb72e190>
<TBranch 'N9' at 0x7ff7cb72e940>
<TBranch 'N10' at 0x7ff7cb733130>
<TBranch 'N11' at 0x7ff7cb7338e0>
<TBranch 'Ivfas_strip1' at 0x7ff7cb739100>
<TBranch 'Ivfas_strip2' at 0x7ff7cb7398b0>
<TBranch 'Ivfas_strip3' at 0x7ff7cb739fd0>
<TBranch 'Ivfas_strip4' at 0x7ff7cb73f850>
<TBranch 'Ivfas_strip5' at 0x7ff7cb73ff70>
<TBranch 'Ivfas_strip6' at 0x7ff7cb7457f0>
<TBranch 'Ivfas_strip7' at 0x7ff7cb745fa0>
<TBranch 'Ivfas_strip8' at 0x7ff7cb74a790>
<TBranch 'Ivfas_strip9' at 0x7ff7cb74af40>
<TBranch 'Ivfas_strip10' at 0x7ff7cb6d0730>
<TBranch 'Ivfas_data1' at 0x7ff7cb6d0ee0>
<TBranch 'Ivfas_data2' at 0x7ff7cb6d46d0>
<TBranch 'Ivfas_data3' at 0x7ff7cb6d4e80>
<TBranch 'Ivfas_data4' at 0x7ff7cb6db670>
<TBranch 'Ivfas_data5' at 0x7ff7cb6dbe20>
<TBranch 'Ivfas_data6' at 0x7ff7cb6e1610>
<TBranch 'Ivfas_data7' at 0x7ff7cb6e1dc0>
<TBranch 'Ivfas_data8' at 0x7ff7cb6e65b0>
<TBranch 'Ivfas_data9' at 0x7ff7cb6e6d60>
<TBranch 'Ivfas_data10' at 0x7ff7cb6ed550>
<TBranch 'Ivfas_data11' at 0x7ff7cb6edd00>
<TBranch 'Xinfo' at 0x7ff7cb6f24f0>
<TBranch 'Info_plus' at 0x7ff7cb6f2ca0>
<TBranch 'Info_digi' at 0x7ff7cb6f8490>
<TBranch 'Icrys' at 0x7ff7cb6f8c40>
h2;1
<TBranch 'Idigi2' at 0x7ff7cb6fd970>
<TBranch 'Idtime2' at 0x7ff7cb7012b0>
<TBranch 'Idatime2' at 0x7ff7cb701a60>
<TBranch 'Nwdigi_730' at 0x7ff7cb709250>
<TBranch 'Idigi_730' at 0x7ff7cb709a00>
h100;1
h200;1
h101;1
h201;1
h102;1
h202;1
h103;1
h203;1
h104;1
h204;1
h105;1
h205;1
h106;1
h206;1
h107;1
h207;1
h108;1
h208;1
h109;1
h209;1
h110;1
h210;1
h111;1
h211;1
h112;1
h212;1
h113;1
h213;1
h114;1
h214;1
h115;1
h215;1
h116;1
h216;1
h117;1
h217;1
h1000;1
h1001;1
h1002;1
h1003;1
h1004;1
h1005;1
h1006;1
h1007;1
h1008;1
h1009;1

Carico le info di interesse¶

Le informazioni del digitizer x730 sono contenute nel secondo oggetto h2.

  • Nwdigi_730 Contiene il numero di parole nel dato evento. Questo valore deve essere $(5+512+2)*8=4152$
  • Idigi_730 Contiene le varie parole. Sono 5+512+2 (header + wf + trailer) per 8 canali
In [4]:
with uproot.open(fileToLoad)["h2"] as f:
    f.show()
    for k in f:
        print(k)
    Nwdigi = f["Nwdigi_730"].arrays(library = "np")["Nwdigi_730"]
    Idigi = f["Idigi_730"].arrays(library = "np")["Idigi_730"]
    
    print(Nwdigi.shape, Idigi.shape)
    
# Condizione da soddisfare, (direi che è sempre vera)
conda = (Nwdigi == 4152)#32992)
print(f"Good events: {conda.sum()}\nTotal: {conda.shape}")

#Nwdigi_742a = Nwdigi_742a[conda]
Idigi = Idigi[conda]
name                 | typename                 | interpretation                
---------------------+--------------------------+-------------------------------
Idigi2               | int32_t                  | AsDtype('>i4')
Idtime2              | int32_t                  | AsDtype('>i4')
Idatime2             | int32_t                  | AsDtype('>i4')
Nwdigi_730           | uint16_t[1]              | AsDtype("('>u2', (1,))")
Idigi_730            | uint16_t[1][4152]        | AsDtype("('>u2', (1, 4152))")
<TBranch 'Idigi2' at 0x7ff7cb5bdbe0>
<TBranch 'Idtime2' at 0x7ff7cb5c5460>
<TBranch 'Idatime2' at 0x7ff7cb5c5c10>
<TBranch 'Nwdigi_730' at 0x7ff7cb5c9400>
<TBranch 'Idigi_730' at 0x7ff7cb5c9bb0>
(6935, 1) (6935, 1, 4152)
Good events: 6935
Total: (6935, 1)

Un esempio di funzione per ottenere una waveform di un canale¶

In [5]:
# Parametri caratteristici che ho appena descritto sopra

nPtsDigi = 512
nWordSingleChannel = 5+nPtsDigi+2
nChannels = 8 # 32


def getWaveform(matrice, canale, evento):
    """
    matrice: matrice dei dati
    canale: numero di canale, contando da 0
    evento: numero di evento (riga), contando da 0
    """
    i = evento
    j = canale
    return matrice[i, (5 + nWordSingleChannel*j) : (5 + nWordSingleChannel*j + nPtsDigi)]
In [6]:
xVect = np.arange(0, nPtsDigi) * 2 #ns, sampling 500 MHz

chanToPlot = 2

for i in range(10):
    fig, ax = plt.subplots()
    fig.set_size_inches(12, 5)
    wf = getWaveform(Idigi, chanToPlot, i)
    
    ax.plot(xVect, wf, ls = ":", c = "tab:green")
    
    ax.grid()
    ax.set_xlabel("Time [ns]", fontsize = 14)
    ax.set_ylabel("[ADC]", fontsize = 14)
    
    ax.set_title(f"Chan. {chanToPlot} -- Ev. {i}", fontsize = 16)
    
    plt.show()

Integrale con persistenza delle sei matrici¶

Inizio con impacchettare il tutto in una matrice 3D (evento, canale, punto della wf)

In [7]:
Idigipack = Idigi.reshape(Idigi.shape[0], nChannels, nWordSingleChannel)[:,:,5:5+nPtsDigi ]
In [8]:
iChan = 2

fig, ax = plt.subplots(2,3)
fig.set_size_inches(60, 40)
ax = ax.flatten()

for i in range(6):
    iChan = i+2

    # Ripeto 0..512 per il numero di eventi (Idigipack.shape[0])
    hh = ax[i].hist2d(np.tile(np.arange(nPtsDigi),Idigipack.shape[0]), 
                      Idigipack[:,iChan,:].flatten(), 
                      bins=(nPtsDigi,50), norm=mpl.colors.LogNorm(), cmap = "jet")
    ax[i].set_title(f"Chan {iChan}", fontsize = 40)
    fig.colorbar(hh[3], ax = ax[i])
plt.show()
In [ ]:
 
In [ ]: