Dear Rooters,
I have got a problem in saving (generated) detector signals into a TTree. The signals are copied to 2d-vectors of type std::vector< vector> (each channel == one 1d vector), but should be saved as 1d vectors of type std::vector.
The signal generator works fine, the signals are passed properly to the method, which will fill the vectors into the TTree, but their content is not saved. Saving std::vector directly into the Tree works fine (see the pGlTime vector of the attached code).
I attached a minimal (not) working example. Don’t be confused by creating the signals as local pointers and passing them to global variables. The code was extracted from a more complex QtRoot application.
Thanks in advance for your suggestions.
[code]//macro to save vector in TTree
//std. c includes
#include <stdlib.h>
#include <stdio.h>
#include
//root includes
#include “TTree.h”
#include “TFile.h”
#include “TBranch.h”
#include “TSystem.h”
//global Variable definition
std::vector *pGlTime;
std::vector <vector > *pGlSignalVector;
TTree *pGlSignalTree;
TFile *pGlFile;
using namespace std;
//______________________________________________________________________________
void FillTTreeAcq()
{ //main method
//define signal characteristics
unsigned int NumEvents = 10000,
NumChannels = 1,
NumSamples = 1000,
BaseLine = 100,
Width = 300;
double Offset[] = {0.4,0.3,0.2,0.1};
//init global signal vectors
pGlTime = new vector<float>();
pGlSignalVector = new vector <vector <float> >();
pGlSignalVector->resize(4);
//define and init local signal vector
vector <float> *pTime = new vector <float>();
vector <float> *pSignal = new vector <float>();
vector <vector <float> > *pSignalVector = new vector <vector <float> >();
//initializise the TFile and the TTree
init_TTree(NumChannels, NumSamples);
//fill the time vector
for (unsigned int i_sa=0; i_sa<NumSamples; i_sa++)
pTime->push_back(i_sa);
//define loop variables
unsigned int Event, i_ch;
//event loop
for (Event=0; Event<NumEvents; Event++)
{ //loop over channels
for (i_ch=0; i_ch<NumChannels; i_ch++)
{ //generate signal and fill it to pSignal
GenerateSignal( pSignal, NumSamples, BaseLine, Width, Offset[i_ch]);
pSignalVector->push_back(*pSignal);
}
//record the signals
RecordSignals(*pTime, *pSignalVector);
gSystem->ProcessEvents();
//clear the signal vector
pSignalVector->clear();
}
//write the TTree to TFile, close the TFile
pGlSignalTree->Write();
pGlFile->Close();
}
//______________________________________________________________________________
double init_TTree(unsigned int NumChannels, unsigned int NumSamples)
{ //method to init the TTree
char tree_name[100] = “”;
char tree_description[100] = “”;
char branch_name[100] = “”;
//(re-)create TFile
pGlFile = new TFile("Data.root", "RECREATE");
//set name and description of the TTree
sprintf(tree_name, "Signals");
sprintf(tree_description, "Tree containing signals from a generator");
//create the TTree
pGlSignalTree = new TTree(tree_name, tree_description);
pGlSignalTree->Branch("time", &pGlTime, NumSamples, 0);
for (int i_ch=0; i_ch<NumChannels; i_ch++)
{ sprintf(branch_name, "channel%i",i_ch+1);
pGlSignalTree->Branch(branch_name, &pGlSignalVector->at(i_ch),
NumSamples,0);
}
return 0;
}
//______________________________________________________________________________
void RecordSignals(vector pTime, vector< vector > pSignalVector)
{ //method to copy the produced signals into global variables and filling of
//the tree with them
//copy local to global vectors
pGlTime = &pTime;
pGlSignalVector = &pSignalVector;
//ouput
// for (int i_ch=0; i_ch<1; i_ch++)
// for (int i_sa=0; i_saat(i_ch).size(); i_sa++)
// cout << "Channel: " << i_ch << “\t”
// << pGlSignalVector->at(i_ch).at(i_sa) << endl;
//Fill the TTree
pGlSignalTree->Fill();
//clear the global vectors
pGlTime->clear();
pGlSignalVector->clear();
}
//______________________________________________________________________________
void GenerateSignal(vector *pSignal, int Length, int BaseLine,
int Width, double Offset)
{ // method to create a logic signal with noise
////////////////////////////////////////////////////////////////////////////////
// <------------------------Length--------------------------------->
// <—BaseLine---->
// Offset ________________ _____________________________________
// H | |
// e | |
// i | |
// g | |
// h | |
// t -------------
// <–Width–>
////////////////////////////////////////////////////////////////////////////////
// double Height = gRandom->Uniform(0,-0.8);
double Height = gRandom->Gaus(-0.4, 0.1);
double noise;
//clear vector
pSignal->clear();
for (int sample=0; sample<Length; sample++)
{ //Baseline
if (sample<BaseLine)
{ noise = gRandom->Gaus(Offset, fabs(0.01*Height));
pSignal->push_back(noise);
}
//signal
else if (sample<BaseLine+Width)
{ noise = gRandom->Gaus(Offset+Height, fabs(0.01*Height));
pSignal->push_back(noise);
}
//rest
else
{ noise = gRandom->Gaus(Offset, fabs(0.01*Height));
pSignal->push_back(noise);
}
}
return;
}[/code]
FillTTreeAcq.cpp (5.89 KB)