import argparse import os import subprocess import glob import csv from ROOT import * from array import array #folders containing output will be created in the cwd pwd = os.getcwd() dir_rootFiles = pwd + '/' + 'rootFiles_SiPMs_all' path_DACFiles = pwd + '/update_allDAC/' #path to folder containing proddb executable AND cookies.txt #proddb="/home/gueth/work/detector/SciFi/database/proddb-0.2/" proddb=os.getenv('PRODDBDIR') os.chdir(proddb) dacAmplitude = 4.2 #get SiPM database ID from SiPM serial number def get_DBid_SiPM(SN_SiPM): ID_SiPM = subprocess.check_output(["./proddb", "TABLE", "260", "id", "1140="+SN_SiPM]).strip() return ID_SiPM #get SiPM serial number from SiPM database ID def get_SN_SiPM(ID_SiPM): SN_SiPM = subprocess.check_output(["./proddb", "TABLE", "260", "1140", "id="+ID_SiPM]).strip() return SN_SiPM def get_BTC_from_FAMandSide(FAM,side): if not side in ['A','B','a','b']: print 'Side of the FAM not specified correctly, choose A or B, aborting' exit() FAMnum = FAM.zfill(5) FAMbc = 'FAM' + FAMnum FAMid = subprocess.check_output(["./proddb", "BC2ID", FAMbc]).strip() if side in ['A','a']: BTCid = subprocess.check_output(["./proddb", "TABLE", "292", "1488", "id="+FAMid]).strip() else: BTCid = subprocess.check_output(["./proddb", "TABLE", "292", "1489", "id="+FAMid]).strip() return BTCid def get_BC_from_DBid(DBid): BC = subprocess.check_output(["./proddb", "ID2BC", DBid]) return BC def get_SiPMlist_from_BTC(BTCid): BSCid = subprocess.check_output(["./proddb", "TABLE", "195", "1287", "id="+BTCid]).strip() if BSCid == '': BTC_BC = get_BC_from_DBid(BTCid) print 'No BSC found in DB for ', BTC_BC[-8:] return [''] list_SiPMs = subprocess.check_output(["./proddb", "TABLE", "261", "1198", "1199", "1200", "1201", "1202", "1203", "1204", "1205", "1206", "1207", "1208", "1209", "1210", "1211", "1212", "1213", "id=" + BSCid]).strip().split(';') print list_SiPMs return list_SiPMs #download SiPM root file via DBid def download_rootFile_SiPM(DBids_SiPM): download_all = True if not os.path.isdir(dir_rootFiles): try: os.makedirs(dir_rootFiles) except: print 'Could not create directory ' + dir_rootFiles for DBid in DBids_SiPM: #print "Downloading SiPM root file from DB for SiPM DBid " + str(DBid) filename = 'SiPM_' + DBid + '.root' if os.path.isfile(dir_rootFiles + '/' + filename): #print 'root file ' + filename + ' already exists in ' + dir_rootFiles + ' , skipping ...' continue with open(dir_rootFiles + '/' + 'SiPM_' + DBid + '.root','w+') as outfile: root_download = subprocess.call(["./proddb", "DOWNLOAD", str(DBid), "1151"], stdout=outfile) #if not os.path.isfile(outfile): # print "Failed to download root file for SiPM DBid " + str(DBid) # download_all = False return download_all def read_root_get_Vbd(path_rootFile, SiPM_SN, list_Vbd): #print path_rootFile input_file = TFile.Open(path_rootFile, "READONLY") input_tree = input_file.Get('Data_'+str(SiPM_SN)) for channel, candidate in enumerate(input_tree): #4.2 Volts added by SPIROC wrt. 'bare' Vbd numbers from EPFL in the DB V_bd = candidate.Breakdown list_Vbd.append(V_bd) def get_physical_channel_address(block, logical_subchannel): subaddress = 32*block + logical_subchannel physical_channel = ( ((subaddress^32^1) << 1)^1 if subaddress<128 else ((subaddress^127^32^1) << 1) & 255 )^128 return physical_channel def get_logical_channel_address(physical_channel): logical_channel = -10 for subaddress in range(0,256): test = ( ((subaddress^32^1) << 1)^1 if subaddress<128 else ((subaddress^127^32^1) << 1) & 255 )^128 #print 'test:', test, 'physical channel:', physical_channel if test == physical_channel: logical_channel = subaddress break #print 'Logical channel:', logical_channel block = logical_channel/32 channel_id = logical_channel%32 return block, channel_id def calc_write_DacFile(BTC, Vbds, factor, name, boardID): path_dir = path_DACFiles + BTC + '/' if not os.path.isdir(path_dir): try: os.makedirs(path_dir) except: print 'Could not create directory ' + path_dir path_file = path_dir + 'DACFile_' + BTC + '_' + boardID + '.txt' if os.path.exists(path_file): print "DACFile already exists under:" print path_file return 0 print "Do you want to delete it? [yes/no]" choice = raw_input().lower() if choice == 'yes': os.remove(path_file) print("Old DACFile deleted.") else: print("DACFile.txt already exists, but you do not want to delete it. Exiting ...") exit() #else: #print("No DACFile.txt found. Continuing.") DACfile = open(path_file,'a') list_DACs = [] desiredBreakdown = 54.5 #loop over all channels for channel in range(0,2048): add = channel/256 UL = 10 + add if boardID == 'board36': UL = 20 + add block = (channel-add*256)/32 channel_ID = (channel-add*256)%32 #important! Vbd arrays are ordered in physical channel order for plotting. Need logical ordering for DAC File #Loop here over logical channel numbers channel_phys = add*256 + get_physical_channel_address(block, channel_ID) DAC = factor * (Vbds[channel_phys] + dacAmplitude - desiredBreakdown) / (dacAmplitude/256.) list_DACs.append(DAC) #set DAC to zero if desiredBreakdown > V_bd if DAC < 0: DAC = 0 if DAC == 0: print 'Warning: Negative DAC value detected for BTC ', BTC, ' Vdb values from ', name print 'Corresponding Vbds is: ', Vbds[channel_phys], 'V' if DAC > 255: print 'Warning: DAC value >255 detected for BTC ', BTC, ' Vdb values from ', name DAC = str(int(round(DAC))).zfill(3) DACfile.write(str(UL) + ' ' + str(block) + ' ' + str(channel_ID) + ' ' + str(DAC) + '\n') return list_DACs def plot_Vbd(BTC, Vbds): #path_Vbd_plots = '/home/gueth/work/detector/SciFi/database/rootfilesVbd/' path_Vbd_plots = pwd+'/rootfilesVbd/' # channels = array("d", [ch for ch in range(0,2048)]) # Vbds = array("d", Vbds) # gROOT.SetBatch(True) # c1 = TCanvas(BTC,"",800,800) # c1.cd() # gr_Vbd_DB = TGraph( 2048, channels, Vbds ) # gr_Vbd_DB.SetTitle('') # gr_Vbd_DB.SetMarkerSize(0.7) # gr_Vbd_DB.SetMarkerStyle(20) # gr_Vbd_DB.GetYaxis().SetRangeUser(48.001,55.) # gr_Vbd_DB.GetXaxis().SetRangeUser(0.,2048.) # gr_Vbd_DB.GetYaxis().SetTitle('V_{bd} [V]') # gr_Vbd_DB.GetXaxis().SetTitle('channel') # gr_Vbd_DB.Draw('Ap') nChan = 2048 h1_Vbd_DB = TH1F('Vbd_from_DB','Vbd_from_DB',nChan, -0.5, nChan-0.5) h1_Vbd_DB.SetMarkerSize(0.7) h1_Vbd_DB.SetMarkerStyle(20) h1_Vbd_DB.GetYaxis().SetRangeUser(48.001,55.) h1_Vbd_DB.GetYaxis().SetTitle('V_{bd} [V]') h1_Vbd_DB.GetXaxis().SetTitle('channel') for ibin, Vbd in enumerate(Vbds): h1_Vbd_DB.SetBinContent(ibin+1, Vbd) #writing output path_dir = path_Vbd_plots + BTC + '/' if not os.path.isdir(path_dir): try: os.makedirs(path_dir) except: print 'Could not create directory ' + path_dir output_file = TFile.Open(path_dir + "Vbd.root", "RECREATE") output_file.cd() #c1.Write() h1_Vbd_DB.Write() output_file.Close() #c1.Delete() def main(): #loop over BTCs list_BTCs = subprocess.check_output(["./proddb", "TABLE", "195", "id"]).split('\n') for BTC in list_BTCs: if BTC == '': continue BTC_tot = get_BC_from_DBid(BTC) BTC_BC = BTC_tot[-8:] print '' print 'BTC: ', BTC_BC b_download = True list_SiPMs = get_SiPMlist_from_BTC(BTC) if '' in list_SiPMs: print 'SiPM assembly for ', BTC_BC, ' is incomplete. No root files will be downloaded ...' continue #download the corresponding SiPM root files from the SciFi DB and check that output is complete if b_download: test_download = download_rootFile_SiPM(list_SiPMs) if not test_download: print 'Download of all root files for SiPMs in assembly failed, exiting ...' else: print 'No download of SiPM root files from DB requested, trying to access them from local directory ...' #list of all Vbds, ordered by SciFi channel number, to be plotted all_Vbds_DB = [] for SiPM in list_SiPMs: rootfile_SiPM = dir_rootFiles + '/' + 'SiPM_' + str(SiPM) + '.root' SiPM_serial = get_SN_SiPM(SiPM).zfill(4) read_root_get_Vbd(rootfile_SiPM, SiPM_serial, all_Vbds_DB) #factor in calculation of DAC values mult = 1.0 calc_write_DacFile(BTC_BC, all_Vbds_DB, mult, 'Vbds_DB', 'board37') calc_write_DacFile(BTC_BC, all_Vbds_DB, mult, 'Vbds_DB', 'board36') plot_Vbd(BTC_BC,all_Vbds_DB) if __name__== "__main__": main()