The management of data for a given experiment or experimental campaign is handled by a KVDataSet object, which brings together:
- the description of the experimental setup with a KVMultiDetArray or KVExpSetUp object;
- a database containing a description of each studied reaction (projectile, energy, target characteristics, DAQ trigger, etc.), detector/array settings, calibration parameters, etc. (KVExpDB, KVExpSetUpDB)
Many different experiments or experimental campaigns can be grouped together and handled by a KVDataSetManager instance: such an object can be used to consult which datasets are available and change from one to another.
Accessing the data files for different experiments is handled by an object of KVDataRepository type: data may be accessed either locally on the host PC or remotely using e.g. IRODS or xrootd backends. Each KVDataRepository has an associated KVDataSetManager, which describes the list of experiments (KVDataSet objects) whose data is available from that source.
Several different KVDataRepository data sources may be handled by an instance of the KVDataRepositoryManager class.
In this chapter we will see how to use these objects to access the relevant information.
Consulting the catalogue - Dataset Manager
The list of datasets (experiments) known to a given installation of KaliVeda depends on which - if any - datasets were configured to be downloaded and used at build time (see the WITH_*_DATASETS CMake options in Appendix: KaliVeda build system). In order to consult the list of known datasets requires simply to initialise a KVDataSetManager object:
dsm.Print()
Dataset
name=INDRA_camp1 (1st INDRA campaign (1993)) [ AVAILABLE: raw dst recon root]
Dataset
name=INDRA_camp2 (2nd INDRA campaign (1994)) [ AVAILABLE: raw dst recon root]
...
Manage all datasets contained in a given data repository.
Bool_t Init(KVDataSetRepository *=0)
What you see in this list (if anything) will therefore depend on your specific installation, but in general for each dataset there is a line with its name, title, and a list of available data types (see below).
Note that the call to KVDataSetManager::Init() initialises a global pointer, gDataSetManager, with the address of the dataset manager object.
Consulting a specific dataset
Each dataset can be accessed from the manager using its name,
auto indra_camp1 = gDataSetManager->
GetDataSet(
"INDRA_camp1")
KVDataSet * GetDataSet(Int_t) const
Return pointer to DataSet using index in list of all datasets, index>=0.
but usually, in order to obtain useful information on a given dataset, it is necessary to make it the 'currently active dataset' by calling the method KVDataSet::cd() for the dataset in question, which can be done directly like so:
If the database of systems, runs, calibration parameters, etc. for the chosen dataset is out of date, this will automatically trigger an update of the database using the installed versions of the dataset files:
Info in <KVDataSet::OpenDataBase>: Updating database
file
Info in <KVINDRADB1::OpenRLFile>: Opened
file .../share/
kaliveda/INDRA_camp1/Runlist.csv
for reading
New System : 129Xe + natSn 25
MeV/A
Zproj = 54 Ztarg = 50 targ_thick = 0.35 Ebeam = 24.981
Target natSn, Target for experiment
Collection
name=
'KVSeqCollection_720', embedded list
class=
'TList',
size=1
Area density 0.00035
g/
cm**2
-----------------------------------------------
Z = 50 atomic mass = 118.71
[...]
size_t size(const MatrixT &matrix)
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t g
virtual void ReadSystemList()
Description of physical materials used to construct detectors & targets; interface to range tables.
const long double MeV
energies
etc. etc.
Note that the call to KVDataSet::cd() initialises 2 global pointers:
gDataSet, with the address of the 'currently active dataset';
gExpDB, with the address of the database for the dataset
Systems, runs, calibrations - consulting the database
The experimental database (object of a class derived from KVExpDB) associated with the any dataset can be accessed in 3 ways:
void Print(Option_t *option="") const override
KVExpDB * GetDataBase(const TString &opt="") const
KVExpDB::Print() will show the structure of the database, in terms of 'tables':
_______________________________________________________
Available Tables :
Runs
Systems
INDRA.OoO Detectors
INDRA.Calibrations
FAZIA.OoO Detectors
FAZIA.Absent Detectors
FAZIA.Calibrations
_______________________________________________________
Calibration database for experiments using coupled detector arrays.
Each table can be accessed using the given name, and its contents reviewed:
KVDBTable : Runs <---> List of available runs [3632 records]
OBJ:
KVDBRun Run 1000 12
C + 197Au[660] 13.75
MeV/A (q=4+ f=13.45MHz CSS1) : 0 at: 0x5af6847d6cd0
OBJ:
KVDBRun Run 1001 12
C + 197Au[660] 13.75
MeV/A (
q=4+
f=13.45MHz CSS1) : 0 at: 0x5af684dccfa0
OBJ:
KVDBRun Run 1002 12
C + 197Au[660] 13.75
MeV/A (
q=4+
f=13.45MHz CSS1) : 0 at: 0x5af6844b5630
OBJ:
KVDBRun Run 1003 12
C + 197Au[660] 13.75
MeV/A (
q=4+
f=13.45MHz CSS1) : 0 at: 0x5af684cc1870
[...]
gExpDB->GetTable("Systems")->GetRecords()->ls()
KVDBSystem : Poubelle Runs : 5002 10000 19000-19002 20000 21000-21005 22000-22003 23000-23006 39000 40000 41000 43006-43015 81000 82000 85000 86000 94000 121000-121009
KVDBSystem : 12
C + 197Au[660] 13.75
MeV/A (
q=4+
f=13.45MHz CSS1) Runs : 1000-1013
KVDBSystem : 12
C + 197Au[980] 13.75
MeV/A (
q=4+
f=13.45MHz CSS1) Runs : 2000-2017 3000-3019 4000-4029 5000-5001 6000
[...]
Description of an experimental run in database ,,.
Database class used to store information on different colliding systems studied during an experiment....
void ls(Option_t *option="*") const override
virtual KVSeqCollection * GetRecords() const
virtual KVDBTable * GetTable(const Char_t *table) const
Extended version of ROOT THashList.
void ls(Option_t *option="") const override
RooCmdArg Extended(bool flag=true)
Note that each run is described by a KVDBRun object, each system by a KVDBSystem object. For these two cases, more direct access is provided by other methods of KVExpDB:
OBJ:
KVDBRun Run 1000 12
C + 197Au[660] 13.75
MeV/A (q=4+ f=13.45MHz CSS1) : 0 at: 0x5af6847d6cd0
OBJ:
KVDBRun Run 1001 12
C + 197Au[660] 13.75
MeV/A (
q=4+
f=13.45MHz CSS1) : 0 at: 0x5af684dccfa0
OBJ:
KVDBRun Run 1002 12
C + 197Au[660] 13.75
MeV/A (
q=4+
f=13.45MHz CSS1) : 0 at: 0x5af6844b5630
OBJ:
KVDBRun Run 1003 12
C + 197Au[660] 13.75
MeV/A (
q=4+
f=13.45MHz CSS1) : 0 at: 0x5af684cc1870
[...]
gExpDB->GetRunList()
gExpDB->GetDBRun(1001)->
Print()
___________________________________________________
Run 1001 (12
C + 197Au[660] 13.75
MeV/A (
q=4+
f=13.45MHz CSS1))
System : 12
C + 197Au[660] 13.75
MeV/A (
q=4+
f=13.45MHz CSS1)
Target : 197Au
___________________________________________________
<Start Date=2022-04-02 14:42:26>
<
End Date=2022-04-02 14:46:13>
___________________________________________________
___________________________________________________
<Events_hi=0>
<Events_lo=218014>
___________________________________________________
gExpDB->GetSystems()->ls()
KVDBSystem : Poubelle Runs : 5002 10000 19000-19002 20000 21000-21005 22000-22003 23000-23006 39000 40000 41000 43006-43015 81000 82000 85000 86000 94000 121000-121009
KVDBSystem : 12
C + 197Au[660] 13.75
MeV/A (
q=4+
f=13.45MHz CSS1) Runs : 1000-1013
KVDBSystem : 12
C + 197Au[980] 13.75
MeV/A (
q=4+
f=13.45MHz CSS1) Runs : 2000-2017 3000-3019 4000-4029 5000-5001 6000
[...]
gExpDB->GetSystem(
"12C + 197Au[660] 13.75 MeV/A (q=4+ f=13.45MHz CSS1)")->
Print()
________________________________________________________
System : 12
C + 197Au[660] 13.75
MeV/A (
q=4+
f=13.45MHz CSS1)
Runs : 1000-1013
Zbeam : 6
Abeam : 12
Ztarget : 79
Atarget : 197
Target Thickness : 0.66
mg/cm2
________________________________________________________
virtual KVSeqCollection * GetRuns() const
Handles lists of named parameters with different types, a list of KVNamedParameter objects.
void Print(std::ostream &os, const OptionType &opt)
Note that for each database system corresponding to a reaction between a projectile and a target the corresponding kinematics object KV2Body can be retrieved simply with the method KVDBSystem::GetKinematics(), e.g.
***** REACTION 58Ni + 58Ni ---> 58Ni + 58Ni ******
E.LAB = 1854.65 MEV QGG = 0 MEV
E.EXC = 0 MEV ==> Q-REACTION = 0 MEV
AVAILABLE ENERGY IN
C.M. : ECM = 923.373 MEV (7.96012 MEV/A)
PROJECTILE VELOCITY IN LAB 7.66451 CM/NS ( 0.255661 * C )
VELOCITY OF
C.M. 3.89701 CM/NS
ENERGY - VELOCITY OF NUCLEUS 1 IN CM : 461.687 MEV 3.89701 CM/NS (K=1)
ENERGY - VELOCITY OF NUCLEUS 2 IN CM : 461.687 MEV 3.89701 CM/NS (K=1)
ENERGY - VELOCITY OF NUCLEUS 3 IN CM : 461.687 MEV 3.89701 CM/NS (K=1)
ENERGY - VELOCITY OF NUCLEUS 4 IN CM : 461.687 MEV 3.89701 CM/NS (K=1)
MAXIMUM SCATTERING ANGLE IN LABORATORY
THETA #3# 90 DEG.
THETA #4# 90 DEG.
GRAZING ANGLE IN LABORATORY : PROJECTILE 3.21146 DEG.
GRAZING ANGLE IN LABORATORY : TARGET 86.7885 DEG.
void Print(Option_t *opt="") const override
KV2Body * GetKinematics()
virtual KVDBSystem * GetSystem(const Char_t *system) const
Experimental setup/detector geometry for dataset - the KVMultiDetArray
The experimental setup used during a particular experiment is described by a dedicated object derived from the KVMultiDetArray class (see Detector Array Geometries). This object can be built for a particular dataset using
static KVMultiDetArray * MakeMultiDetector(const Char_t *dataset_name, Int_t run=-1, TString classname="KVMultiDetArray", KVExpDB *db=nullptr)
This method initialises a global pointer, gMultiDetArray, with the address of the detector geometry object.
Since v1.15/06 this method will initialise the default dataset manager if none exists, the associated dataset will be automatically made the 'currently active dataset'.
The second, optional, argument is the number of a run from the dataset: if given, it will set any parameters of the array defined in the database to their values for that run (ionization chamber gas pressures, calibration parameters, identification grids, etc. etc.). It is equivalent to doing:
virtual void SetParameters(UInt_t n, Bool_t physics_parameters_only=kFALSE)
Accessing the data
To access the data for a given dataset, you need to initialise a data repository manager like so (in this case we will assume that somebody has put in place the necessary configuration in your working environment - if you need to do it yourself, see KVDataRepository documentation):
Manages access to one or more data repositories.
which will automatically initialise the default data repository and associated data set manager which you can use like this:
Info in <KVDataSetRepository::Print>: configuration of repository is
as follows -
RootDir = /home/uindra/uindraX
AccessProtocol = local
AccessRootDir = /home/uindra/uindraX
[...]
gDataSetManager->
Print(
"available")
1. E881 - Hoyle state radius from inelastic scattering
2. E884 - QP splitting entrance channel dependence
3. T26_01 - Precise measurement of
gamma decay probability of 3- state of 12
C
void Print(Option_t *opt="") const override
Print info on repository.
void Print(Option_t *opt="") const
TMatrixT< Double_t > as(SEXP)
Note that the latter command only prints the dataset for which some data files are present in the repository. To see which types of data are available for a given dataset, you can do:
Dataset
name=INDRAFAZIA.E884 (E884 - QP splitting entrance channel dependence) [ AVAILABLE: raw recon]
const Char_t * GetAvailableDataTypes() const
void Print(Option_t *opt="") const override
Opening and reading runfiles
To open a file containing data of any type for the currently active dataset, you use the method
FileType * OpenRunfile(const KVString &type, const run_index_t &run)
which requires two arguments: the type of data, and the run number and index of the runfile.
Reading raw data files
Before reading a raw data file, it is most useful to first initialize the description of the experimental setup for the dataset (see Experimental setup/detector geometry for dataset - the KVMultiDetArray above) because, when reading raw data, the detector signals associated to the different acquisition parameters etc. in the data will be set for each event read in - only if they exist! It is also usually best to initialise the setup for the run corresponding to the runfile you will read (in case calibration, identification, etc. parameters vary with run number).
Then, to open a particular runfile of the dataset, let's say runfile 26.14 of the E884 dataset, you just need to do:
Abstract base class for reading raw (DAQ) data.
The simple cast to KVRawDataReader is safe because all classes for reading raw data files inherit from this same base class.
Once you have opened the file, you can retrieve any informations on the runfile that may have been read in in a KVNameValueList, by calling KVRawDataReader::GetRunInfos():
<ExperimentName=e884>
<FileName=run_0026.dat.02-06-25_17h51m41s>
<FileCreationTime=02-06-25_20h54m57s>
<RunNumber=26>
<RunIndex=0>
<RunStartTime=02-06-25_17h51m41s>
Before reading any data, you need to first need to perform any necessary initialisations of the KVMultiDetArray/KVExpSetUp in order to read the data:
virtual void InitialiseRawDataReading(KVRawDataReader *)
Then, to read an event from the file call the KVRawDataReader::GetNextEvent() method:
The method returns true as long as an event is successfully read from the file, false when the end of the file is reached.
In order to decode the data, do the following:
(bool) true
virtual Bool_t HandleRawDataEvent(KVRawDataReader *)
The method returns true if there was some data in the event that corresponds to this experimental setup. If you don't test directly the value returned by the method, you can subsequently test with
(bool) true
Bool_t HandledRawData() const
If the experimental setup consists of a combination of 2 or more arrays, you can also test which of the arrays handled some data in the event:
(bool) true
(bool) false
virtual KVMultiDetArray * GetArray(const Char_t *) const
To know which detectors and/or signals 'fired' in the event, there are 2 methods which return the corresponding lists:
OBJ:
KVCsI CSI_1103 CSI : 0 at: 0x614014550540
CsI(Tl) scintillation detectors of the INDRA multidetector array.
Base class for output signal data produced by a detector.
const KVSeqCollection * GetFiredSignals() const
const KVSeqCollection * GetFiredDetectors() const
Looking at the second event, we see:
(bool) true
(bool) true
(bool) false
(bool) true
Base class for FAZIA detectors.
Reading reconstructed data files
Before reading a reconstructed data file, it can be very useful to first initialize the description of the experimental setup for the dataset (see Experimental setup/detector geometry for dataset - the KVMultiDetArray above) because reconstructed nuclei are intimately linked to the detectors in which they were detected and identified, while the detector signals associated to the different acquisition parameters etc. in the raw data will also be set for each event read in in this case. It is also usually best to initialise the setup for the run corresponding to the runfile you will read (in case calibration, identification, etc. parameters vary with run number).
So, as we have decided to open a particular runfile of reconstructed data for the E884 dataset, let's say 26.14, we begin by
Then we can do (see run_index_t for the syntax of the argument designating the runfile by its run number and index):
TFile** /some/path/INDRAFAZIA/E884/recon/run26.recon.root.2026-07-24_11:58:00.14
TFile* /some/path/INDRAFAZIA/E884/recon/run26.recon.root.2026-07-24_11:58:00.14
KEY:
TTree ReconEvents;46 INDRA-FAZIA : 70Zn + 209Bi 34.6
MeV/A : run_26.14 [current cycle]
KEY:
TTree ReconEvents;45 INDRA-FAZIA : 70Zn + 209Bi 34.6
MeV/A : run_26.14 [backup cycle]
and if we inspect the TTree in the file:
******************************************************************************
*Tree :ReconEvents: INDRA-FAZIA : 70Zn + 209Bi 34.6
MeV/A : run_26.14 *
*Entries : 1688446 : Total = 7694317216
bytes File
Size = 1303339627 *
* : : Tree compression factor = 5.90 *
******************************************************************************
*Entries :1688446 : Total
Size= 7694215618
bytes File
Size = 1303314702 *
*Baskets : 336 : Basket
Size= 25600000
bytes Compression= 5.90 *
*............................................................................*
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t bytes
Event containing KVReconstructedNucleus nuclei reconstructed from hits in detectors.
void Print(Option_t *option="") const override
We can see that the TTree contains 1.7 million events contained in its single branch. To read back the data (by hand, only for debugging purposes! To analyse data, see Data Analysis), we can use a TTreeReader:
then to read back each event in sequence and see what the event contains (KVReconstructedEvent::ls()):
reader.Next()
(bool) true
recev->ls()
KVNameValueList::EventParameters :
Parameters associated with an
event (0x58de6060c828)
<INDRA.TS_hi=22600>
<INDRA.TS_lo=-2135809998>
<Free_Trigger_hi=0>
<Free_Trigger_lo=678592125>
<Exp_Trigger_hi=0>
<Exp_Trigger_lo=645118286>
<RUTHMON1_hi=0>
<RUTHMON1_lo=138613>
<RUTHMON2_hi=0>
<RUTHMON2_lo=165097>
<RUTHMON3_hi=0>
<RUTHMON3_lo=200591>
<RUTHMON4_hi=0>
<RUTHMON4_lo=239862>
<FAZIA_Trigger_hi=0>
<FAZIA_Trigger_lo=134743776>
<INDRA.MESYTEC=true>
<ACQPAR.INDRA.CSI_1103.T=491.748>
<ACQPAR.INDRA.CSI_1103.TotLight=148>
<ACQPAR.INDRA.CSI_1103.R=40>
1 A: INDRA D: CSI_1103 IDCODE=14
RooCmdArg Parameters(const RooArgSet ¶ms)
Here we see first of all a list of parameters associated with the event (accessed through KVReconstructedEvent::GetParameters()), and then the (very short) list of reconstructed nuclei: in this case, just a single unidentified nucleus stopped in detector CSI_1103.
Looking at the second event we see:
reader.Next()
(bool) true
recev->ls()
KVNameValueList::EventParameters :
Parameters associated with an
event (0x58de6060c828)
<FAZIA.TS_hi=22600>
<FAZIA.TS_lo=-2135765055>
<FAZIA.TRIGPAT=0>
<FAZIA.EC_hi=0>
<FAZIA.EC_lo=6959>
<FAZIA.TRIGRATE.DT=2.88718e+07>
1 A: FAZIA D: SI2-141 IDCODE=12 ID: ID_SI1_SI2_141 Z=30 :
E=2420.97
MeV
In this case, a particle stopped in detector SI2-141 has been successfully reconstructed as a \(Z=30\) (zinc) nucleus with an incident energy of nearly 35 MeV/nucleon. For more information we can use KVReconstructedEvent::Print():
recev->Print()
***
MULTIPLICITY = 1
RECONSTRUCTED PARTICLE #1
SI1-141 -- DetTag=0 | GTTag=0 | QH1.Amplitude=0 | QH1.RawAmplitude=0 | QH1.FPGAEnergy=3167.01 | QH1.RiseTime=0 | QH1.BaseLine=-7475.5 | QH1.SigmaBaseLine=0 | I1.Amplitude=7270.87 | I1.RawAmplitude=8477 | I1.BaseLine=-5153.03 | I1.SigmaBaseLine=5.78206 | QL1.Amplitude=14148.2 | QL1.RawAmplitude=14174 | QL1.RiseTime=3.71914 | QL1.BaseLine=-5957.22 | QL1.SigmaBaseLine=9.90614 | Energy=890.91 |
SI2-141 -- DetTag=0 | GTTag=0 | Q2.Amplitude=0 | Q2.RawAmplitude=0 | Q2.FPGAEnergy=5708.24 | Q2.RiseTime=0 | Q2.BaseLine=-7628.75 | Q2.SigmaBaseLine=0 | I2.Amplitude=0 | I2.RawAmplitude=0 | I2.BaseLine=0 | I2.SigmaBaseLine=0 | Energy=1529.2 |
Identification #1 -
Type:Si-Si => SUCCESS
Grid used: QH1.FPGAEnergy_Q2.FPGAEnergy
ID code = 12 Quality code = 0 (ok)
Z identified = 30 A returned = 65 PID = 30.036212
Identification #2 -
Type:SiPSA => SUCCESS
Grid used: QH1.FPGAEnergy_I1.Amplitude
ID code = 11 Quality code = 0 (ok)
Z identified = 21 A returned = 43 PID = 21.407778
QH1.FPGAEnergy_I1.Amplitude : MassID
STOPPED IN : SI2-141
IDENTIFIED IN : ID_SI1_SI2_141
=======> Z=30 A=65 Zreal=30.0362 Total Energy = 2420.97
MeV, Theta=2.52855 Phi=64.965
Target energy loss correction : 0.860176
MeV
RECONSTRUCTION STATUS :
Particle alone in
group, or identification independently of other particles in
group is directly possible.
GDNTraj_583_SI2-141 : SI2-141/SI1-141/
Identifications [2/2] :
ID_SI1_SI2_141 (1)
ID_SI1_141 (1)
<ARRAY=FAZIA>
<DetTag=23836>
<GTTag=23903>
<SI2-141.Q2.FPGAEnergy=5708.24>
<SI2-141.Q2.BaseLine=-7628.75>
<SI1-141.QH1.FPGAEnergy=3167.01>
<SI1-141.QH1.BaseLine=-7475.5>
<SI1-141.I1.Amplitude=7270.87>
<SI1-141.I1.RawAmplitude=8477>
<SI1-141.I1.BaseLine=-5153.03>
<SI1-141.I1.SigmaBaseLine=5.78206>
<SI1-141.QL1.Amplitude=14148.2>
<SI1-141.QL1.RawAmplitude=14174>
<SI1-141.QL1.RiseTime=3.71914>
<SI1-141.QL1.BaseLine=-5957.22>
<SI1-141.QL1.SigmaBaseLine=9.90614>
<IDCODE=12>
<si1_pileup=false>
<si2_pileup=false>
<ECODE=1>
<FAZIA.ESI1=890.91>
<FAZIA.ESI2=1529.2>
<FAZIA.avatar.ESI1=836.683>
<FAZIA.avatar.ESI2=1584.29>
For more explanations of what is shown here, see Debugging identifications for reconstructed data.