BES3 Data Reading
Read ROOT files (rtraw, dst, rec)
To enable uproot to read BES3 ROOT files, import pybes3 before opening any file:
>>> import pybes3
>>> import uproot
Then, open file using uproot:
>>> f = uproot.open("test.rtraw")
>>> evt = f["Event"]
Print information about this event tree:
>>> evt.show(name_width=30)
name | typename | interpretation
-------------------------------+--------------------------+-------------------------------
TEvtHeader | TEvtHeader | AsGroup(<TBranchElement 'TE...
TEvtHeader/TObject | unknown | <UnknownInterpretation 'non...
TEvtHeader/m_eventId | int32_t | AsDtype('>i4')
TEvtHeader/m_runId | int32_t | AsDtype('>i4')
...
TMcEvent | TMcEvent | AsGroup(<TBranchElement 'TM...
TMcEvent/TObject | unknown | <UnknownInterpretation 'non...
TMcEvent/m_mdcMcHitCol | TMdcMc | AsBes3(TObjArray[TMdcMc])
TMcEvent/m_emcMcHitCol | TEmcMc | AsBes3(TObjArray[TEmcMc])
TMcEvent/m_tofMcHitCol | TTofMc | AsBes3(TObjArray[TTofMc])
TMcEvent/m_mucMcHitCol | TMucMc | AsBes3(TObjArray[TMucMc])
TMcEvent/m_mcParticleCol | TMcParticle | AsBes3(TObjArray[TMcParticle])
TDigiEvent | TDigiEvent | AsGroup(<TBranchElement 'TD...
TDigiEvent/TObject | unknown | <UnknownInterpretation 'non...
TDigiEvent/m_fromMc | bool | AsDtype('bool')
TDigiEvent/m_mdcDigiCol | TMdcDigi | AsBes3(TObjArray[TMdcDigi])
...
Reading sub-trees
To read TMcEvent (note: use arrays() instead of array() here):
>>> mc_evt = evt["TMcEvent"].arrays()
>>> mc_evt.fields
['m_mdcMcHitCol', 'm_emcMcHitCol', 'm_tofMcHitCol', 'm_mucMcHitCol', 'm_mcParticleCol']
Now go to event 0:
>>> evt0 = mc_evt[0]
>>> evt0.m_mcParticleCol.m_particleID
<Array [23, 4, -4, 91, 443, 11, ..., 111, 211, -211, 22, 22] type='12 * int32'>
>>> mc_evt[0].m_mcParticleCol.m_eInitialMomentum
<Array [3.1, 1.55, 1.55, 3.1, ..., 1.23, 0.178, 1.28] type='12 * float64'>
This indicates that event 0 contains 12 MC particles. Their PDGIDs are 23, 4, -3, ... and initial energies are 3.1, 1.55, 1.55, ... (GeV).
Reading specific branches
Tip
It is recommended to read only the branches you need for better performance.
To read a specific branch (note: use array() instead of arrays() here):
>>> pdgid_arr = evt["TMcEvent/m_mcParticleCol/m_particleID"].array()
>>> e_init_arr = evt["TMcEvent/m_mcParticleCol/m_eInitialMomentum"].array()
or retrieve branches from mc_evt:
>>> pdgid_arr = mc_evt["m_mcParticleCol/m_particleID"].array()
>>> e_init_arr = mc_evt["m_mcParticleCol/m_eInitialMomentum"].array()
Read raw data files
Read a single file
To read a raw data file, use pybes3.open_raw:
>>> import pybes3 as p3
>>> file_path = "/besfs8/offline/data/merge/raw/round19/250912/run_0087397_All_merge0_file001_SFO-1.raw"
>>> raw_file = p3.open_raw(file_path)
>>> raw_file
<RawData filename='run_0087397_All_merge0_file001_SFO-1.raw' Entries=180322 Size='2368 MB'>
Get meta information:
>>> raw_file.entries # Number of events
180322
>>> raw_file.run_number
87397
>>> raw_file.path
'/besfs8/offline/data/merge/raw/round19/250912/run_0087397_All_merge0_file001_SFO-1.raw'
>>> raw_file.size
2483177188 # Size in bytes
To read all data:
>>> raw_data = raw_file.arrays()
>>> raw_data
<Array [{evt_header: {...}, ...}, ..., {...}] type='180322 * {evt_header: {...'>
>>> raw_data.fields
['evt_header', 'cgem', 'mdc', 'tof', 'emc', 'muc', 'trigGTD']
>>> raw_data.cgem.fields
['id', 'adc', 'tdc', 'time', 'charge']
To read a portion of the file:
>>> some_digi = raw_file.arrays(entry_start=50, entry_stop=100)
>>> some_digi
<Array [{evt_header: {...}, ...}, ..., {...}] type='50 * {evt_header: {evt_...'>
Warning
Explicitly specifying entry_start and entry_stop will slow down the reading speed (\(\sim 0.33 \times\)), as the reader needs to skip entries one by one until it reaches entry_stop.
To read only specific fields:
>>> cgem_mdc_digi = raw_file.arrays(filter_name=['cgem', 'mdc'])
>>> cgem_mdc_digi.fields
['evt_header', 'cgem', 'mdc']
Info
Available fields are: cgem, mdc, tof, emc, muc, trigGTD.
evt_header is always read and cannot be filtered out.
Close the file when done:
>>> raw_file.close()
Warning
Always close the file after reading to free up system resources.
Open the file using a context manager to automatically close it after reading:
>>> with p3.open_raw(file_path) as f:
... raw_data = f.arrays()
Concatenate multiple files
To read multiple files and concatenate them into a single array, use pybes3.concatenate_raw:
>>> files = [
file_path,
"/besfs8/offline/data/merge/raw/round19/250912/run_0087397_All_merge0_file002_SFO-1.raw",
>>> ]
>>> raw_data = p3.concatenate_raw(files)
>>> raw_data
<Array [{evt_header: {...}, ...}, ..., {...}] type='363492 * {evt_header: {...'>
Set verbose=True to print progress:
>>> raw_data = p3.concatenate_raw(files, verbose=True)
Reading file /mnt/f/pybes3/run_0087397_All_merge0_file001_SFO-1.raw: 0 -> 180322 entries ...
Reading file /mnt/f/pybes3/run_0087397_All_merge0_file001_SFO-1.raw: 180322 -> 363492 entries ...
entry_start, entry_stop and filter_name can also be used in concatenate_raw to read only a portion of the files or specific fields:
>>> raw_data = p3.concatenate_raw(files, entry_start=100, entry_stop=200, filter_name=['cgem', 'mdc'])
>>> raw_data
<Array [{evt_header: {...}, ...}, ..., {...}] type='100 * {evt_header: {evt...'>