Stereogramma¶

Questo quaderno mostra come realizzare uno stereogramma, ovvero uno scatter plot rot vs crad, dove ogni punto rappresenta la Pulse Height media di un qualche rivelatore (Calorimetro, APC...) per ciascuna posizione (rot, crad) del goniometro.

  • ƈ sufficiente fornire i numeri di run da usare e la corrispondente modalitĆ  di scansione
  • Per punti singoli, ĆØ indifferente se mettere rot o crad, ma deve comunque essere specificato
  • Questo quaderno ĆØ predisposto per costruire due stereogrammi usando le PH di due diversi rivelatori. Inoltre, verrĆ  effettuata la media sopra una certa soglia sogliola, che deve essere fornita
  • TODO: allo stato attuale delle cose, non supporta scan diagonali o meshgrid (ma neanche la DAQ...)

Questo quaderno ĆØ stato realizzato in collaborazone con Giulia

InĀ [1]:
import numpy as np
from matplotlib import pyplot as plt
import matplotlib as mpl

import h5py
import json

import os

from matplotlib.patches import Circle, Ellipse

Definisco il percorso dei file¶

InĀ [2]:
filePath = "/eos/project-i/insulab-como/testBeam/TB_T9_2022/HDF5"

Definisco e visualizzo il file JSON con le varie run e scan type¶

In realtà, sarebbe sufficiente avere o un file json esterno, o scriversi il dizionario qui dentro. Diciamo che è facilmente adattabile ad altre necessità, soprattutto se diventasse necessario passare più argomenti per ciascuna run.

InĀ [3]:
dizi = {
    '550299' : 'rot',
    '550300' : 'crad',
    '550303' : 'rot',
    '550304' : 'crad'
}

JSONfile = r"./stereogramma.json"

with open(JSONfile, "w") as f:
    json.dump(dizi, f, indent=4)
InĀ [4]:
with open(JSONfile, "r") as f:
    dizi = json.load(f)

print(dizi.keys())
dict_keys(['550299', '550300', '550303', '550304'])

Scelta dei rivelatori da usare¶

Definisco:

  • Gli indici nella matrice delle pulse height
  • Le soglie da usare
  • Le label che compariranno
InĀ [5]:
# Indici digitizer: 1 -> LG, 4 -> APC2

indici = [1, 4]
sogliola0 = 100
sogliola1 = 100
label0 = 'LG'
label1 = 'APC2'

Itero su ciascuna run¶

Calcolo la PH media per ogni step, la appendo alla lista generale, e visualizzo gli istogrammi

InĀ [6]:
# Preparo le liste per i dati che voglio tirarmi fuori
mean0_lst = []
mean1_lst = []
rot_lst = []
crad_lst = []

# Ciclo sui run
for k in dizi.keys():

    # Percorso completo del file da caricare
    fileName = os.path.join(filePath, f"run{k}.h5")
    
    # Importo i dati
    with h5py.File(fileName,'r', libver='latest', swmr=True) as hf:
        xpos = np.array(hf['xpos'])
        digi_ph = np.array(hf['digi_ph'])
        xinfo = np.array(hf['xinfo'])
        info_plus = np.array(hf['info_plus'])

    # Tolgo gli eventi problematici
    # Tengo solo gli eventi validi, ed estraggo le sotto componenti utili per il resto dell'analisi
    logico = (xpos > 0) & (xpos < 10)
    logico2 = logico.all(axis = 1)

    # PH dei due rivelatori da usare
    ph0 = digi_ph[logico2][:, indici[0]]
    ph1 = digi_ph[logico2][:, indici[1]]

    # Rot e Crad del goniometro
    gonio = [xinfo[logico2][:,0], xinfo[logico2][:,1]]
    
    # Numero di step, e valori unici
    step = info_plus[logico2][:, 1]
    unique_step = np.unique(step)

    # Valori di rot e crad ad ogni step
    rot_step  = [gonio[0][step == i][0] for i in unique_step]
    crad_step = [gonio[1][step == i][0] for i in unique_step]

    # Guardo che tipo di scan ĆØ (rot o crad) => DA SISTEMARE
    scan_type = dizi[k]
    if scan_type == 'rot':
        scan_step = rot_step
    elif scan_type == 'crad':
        scan_step = crad_step
    else:
        print("MEGA ERRORE") 

    # PH per ogni step
    phxstep0 = [ph0[step == i] for i in unique_step]
    phxstep1 = [ph1[step == i] for i in unique_step]

    # Media delle PH per ogni step
    mean0 = [np.mean(phxstep0[i][phxstep0[i]>sogliola0]) for i in unique_step]
    mean1 = [np.mean(phxstep1[i][phxstep1[i]>sogliola1]) for i in unique_step]

    ######################## Figura ##############################

    
    fig, ax = plt.subplots(2,2)
    fig.set_size_inches(12,12)
    ax = ax.flatten()
    
    
    fig.suptitle(f"nrun = {k} - scan {scan_type}")


    # Plotto gli istogrammi per ciascun step
    for i in unique_step:
        ax[0].hist(phxstep0[i], 100, label = f"{scan_step[i]:.2f} -> {mean0[i]:.2f}", histtype = 'step', lw = 3)
        ax[1].hist(phxstep1[i], 100, label = f"{scan_step[i]:.2f} -> {mean1[i]:.2f}", histtype = 'step', lw = 3)

    opts = {"ls" : "--", "c" : "k"}
    ax[0].axvline(x = sogliola0, **opts)
    ax[1].axvline(x = sogliola1, **opts)
    
    ax[0].set_title(label0)
    ax[1].set_title(label1)
    

    for i in [0, 1]:
        a = ax[i]
        a.set_yscale('log')
        a.set_xlabel('PH [ADC]')
        a.set_ylabel('Counts')
        a.legend()
    


    # Plotto le medie
    ax[2].plot(scan_step, mean0, '--')
    ax[3].plot(scan_step, mean1, '--')

    for i in [2, 3]:
        a = ax[i]
        a.set_xlabel(scan_type + ' [murad]')
        a.set_ylabel("PH mean [ADC]")
    
    
    plt.show()

    # Aggiungo le medie della run corrente alle liste generali

    mean0_lst += mean0
    mean1_lst += mean1
    rot_lst   += rot_step
    crad_lst  += crad_step


# Converto in array di numpy
mean0 = np.array(mean0_lst)
mean1 = np.array(mean1_lst)
rot = np.array(rot_lst)
crad = np.array(crad_lst)
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image

Stereogramma¶

Plotto lo stereogramma e cerchio il punto più alto

InĀ [7]:
# Opzioni per gli ellissi
opts = {"facecolor":'none', "lw":3, "edgecolor":"k"}

def plottaStereo(currMean, currLabel):

    fig, ax = plt.subplots()
    fig.set_size_inches(12, 10)
    
    # Plotto lo stereogramma
    gonioimg = ax.scatter(rot,crad,c=currMean, cmap="jet")
    
    
    # ax.set_title(currLabel)
    ax.set_xlabel(r"Rot [$\mu$rad]", fontsize = 14)
    ax.set_ylabel(r"Crad [$\mu$rad]", fontsize = 14)
    fig.colorbar(gonioimg, ax = ax)
    
    
    # Ottengo il massimo dello scan e lo cerchio
    myXcenter = rot[np.argmax(currMean)]
    myYcenter = crad[np.argmax(currMean)]
    myXmin, myXmax = ax.get_xlim()
    myYmin, myYmax = ax.get_ylim()
    myPercent = .4
    print(myXcenter, myYcenter)
    
    # Per avere il cerchio che ĆØ veramente rotondo, indipendentemente dall'aspect ratio della figura
    bbox = ax.get_window_extent().transformed(fig.dpi_scale_trans.inverted())
    width, height = bbox.width, bbox.height
    
    
    ax.add_patch(Ellipse(xy = (myXcenter, myYcenter), width = (myXmax - myXmin) * myPercent / width, height =  (myYmax - myYmin) * myPercent / height, angle=0,  **opts))
    
    ax.grid()
    fig.savefig(f"stereo-{currLabel}.pdf", format = "pdf",bbox_inches='tight', pad_inches=0)
    plt.show()
    


plottaStereo(mean0, label0)
plottaStereo(mean1, label1)
31142.121 -10425.97
No description has been provided for this image
32249.232000000004 -11305.403999999999
No description has been provided for this image

Bisognerebbe verificare che in questo modo sia davvero rotondo....

InĀ [8]:
# Opzioni per gli ellissi
opts = {"facecolor":'none', "lw":3, "edgecolor":"k"}


# ++++ PLOT 1 +++++
currMean = mean0
currLabel = label0

fig, ax = plt.subplots()
fig.set_size_inches(24, 6)

# Plotto lo stereogramma
gonioimg = ax.scatter(rot,crad,c=currMean, cmap="jet")


ax.set_title(currLabel)
ax.set_xlabel("Rot [murad]")
ax.set_ylabel("Crad [murad]")
fig.colorbar(gonioimg, ax = ax)


bbox = ax.get_window_extent().transformed(fig.dpi_scale_trans.inverted())
width, height = bbox.width, bbox.height



# Ottengo il massimo dello scan e lo cerchio
myXcenter = rot[np.argmax(currMean)]
myYcenter = crad[np.argmax(currMean)]
myXmin, myXmax = ax.get_xlim()
myYmin, myYmax = ax.get_ylim()
myPercent = 1
print(myXcenter, myYcenter)

ax.add_patch(Ellipse(xy = (myXcenter, myYcenter), width = (myXmax - myXmin) * myPercent/width, height =  (myYmax - myYmin) * myPercent/height, angle=0,  **opts))

ax.grid()

plt.show()
31142.121 -10425.97
No description has been provided for this image