FairRoot/PandaRoot
PndEmcMultiWaveformToCalibratedDigi.cxx
Go to the documentation of this file.
1 //----------------------------------------------------------------------
2 // File and Version Information:
3 // $Id: //
4 // Description:
5 // Class PndEmcMultiWaveformToCalibratedDigi. Module to take the ADC waveforms and produces digi.
6 //
7 // Software developed for the BaBar Detector at the SLAC B-Factory.
8 // Adapted for the PANDA experiment at GSI
9 //
10 // Author List:
11 // Phil Strother Original Author
12 // Dima Melnichuk - adaption for PANDA
13 // Copyright Information:
14 // Copyright (C) 1996 Imperial College
15 //
16 //----------------------------------------------------------------------
17 
19 
20 #include "PndEmcMultiWaveform.h"
21 #include "PndEmcWaveform.h"
22 #include "PndEmcDigi.h"
23 #include "PndEmcDigiPar.h"
24 #include "PndEmcRecoPar.h"
25 #include "PndEmcAsicPulseshape.h"
26 #include "PndEmcPSAParabolic.h"
29 
30 #include "FairRootManager.h"
31 #include "FairRunAna.h"
32 #include "FairRuntimeDb.h"
33 
34 #include "TClonesArray.h"
35 #include "TStopwatch.h"
36 
37 #include <iostream>
38 #include <fstream>
39 //#include <map>
40 
41 using std::cout;
42 using std::endl;
43 using std::fstream;
44 
46 {
48  fDigiPosMethod="depth";// "surface" or "depth"
50  SetPersistency(storedigis);
52  //fPndEmcDigiPositionDepth=6.2;
53 }
54 
55 //--------------
56 // Destructor --
57 //--------------
58 
60 {
61 }
62 
63 
65 {
66  // Get RootManager
67  FairRootManager* ioman = FairRootManager::Instance();
68  if ( ! ioman )
69  {
70  cout << "-E- PndEmcMultiWaveformToCalibratedDigi::Init: "
71  << "RootManager not instantiated!" << endl;
72  return kFATAL;
73  }
74 
75  // Get input array
76  fWaveformArray = (TClonesArray*) ioman->GetObject("EmcMultiWaveform");
77  if ( ! fWaveformArray ) {
78  cout << "-W- PndEmcMultiWaveformToCalibratedDigi::Init: "
79  << "No PndEmcMultiWaveform array!" << endl;
80  return kERROR;
81  }
82 
83  // Create and register output array
84  fDigiArray = new TClonesArray("PndEmcDigi");
85 
86  ioman->Register("EmcDigi","Emc",fDigiArray,GetPersistency());
99 
100  cout<<"fEmcDigiPositionDepthPWO: "<<fEmcDigiPositionDepthPWO<<endl;
101  cout<<"fEmcDigiPositionDepthShashlyk: "<<fEmcDigiPositionDepthShashlyk<<endl;
102 
103  if (!fDigiPosMethod.CompareTo("surface"))
104  {
106  }
107  else if (!fDigiPosMethod.CompareTo("depth"))
108  {
111  }
112  else
113  {
114  cout << "-W- PndEmcMultiWaveformToCalibratedDigi::Init: "
115  << "Unknown digi position method!" << endl;
116  return kERROR;
117  }
118 
121 
122 
123  if(fpsaAlgorithm == NULL){
124  // Matched digital filter
125  // Parameters of the filter are hardcoded at the moment
126  // For different pulseshape in barrel and endcaps different filters should be implemented
127  std::vector<Double_t> params;
128  params.push_back(30); // width
129  params.push_back(fSampleRate); // Sample rate
131  }
132 
133  if(fpsaAlgorithm_pmt == NULL){
134  // Pulse shape analysis algorithm.
135  // Simple parabolic fit.
137  }
138 
139  // Determine normalisation constant for PndEmcMultiWaveform
140  PndEmcWaveform *tmpwaveform=new PndEmcWaveform(0,101010001, fNumber_of_samples_in_waveform);
141  PndEmcWaveform *tmpwaveform2=new PndEmcWaveform(0,101010001, fNumber_of_samples_in_waveform_pmt);
142 
143  PndEmcHit *gevHit=new PndEmcHit();
144  gevHit->SetEnergy(1.0);
145  gevHit->SetTime(0.);
146  tmpwaveform->UpdateWaveform(gevHit, 0, false, 1., 0., fSampleRate, fPulseshape);
147  tmpwaveform2->UpdateWaveform(gevHit, 0, false, 1., 0., fSampleRate_PMT, fPulseshape_pmt);
148  Double_t tmpPeakPosition;
149  Double_t tmpPeakPosition2;
150  fpsaAlgorithm->Process(tmpwaveform,fWfNormalisation,tmpPeakPosition);
151  fpsaAlgorithm_pmt->Process(tmpwaveform2,fWfNormalisation_pmt,tmpPeakPosition2);
152 
154 
155  if(fCalibrationFileName !="")
157 
158  cout << "-I- PndEmcMultiWaveformToCalibratedDigi: Read "<< fCalibrationMap.size() << " Calibration Entries" << endl;
159 
160  cout << "-I- PndEmcMultiWaveformToCalibratedDigi: Intialization successfull" << endl;
161 
162  return kSUCCESS;
163 }
164 
166 {
167  TStopwatch timer;
168  if (fVerbose>2){
169  timer.Start();
170  }
171 // Reset output array
172  if ( ! fDigiArray ) Fatal("Exec", "No Digi Array");
173  fDigiArray->Delete();
174  Double_t peakPosition;
176  Double_t digi_time;
177  Int_t i_digi=0; //index of digi in TClonesArray
178  Int_t hitIndex;
179  Int_t detId;
180  Int_t trackId;
181  Int_t module;
182  Int_t nWaveforms = fWaveformArray->GetEntriesFast();
183  Int_t nSignal;
184  Bool_t highgain;
185  PndEmcAbsPSA *thePSA;
186  Double_t theEnergyNorm;
187  Double_t theSampleRate;
188  Int_t nHits[4];
189  Double_t hittimes[4][32];
190  Double_t hitenergies[4][32];
191  std::map<Int_t,Double_t>::iterator it;
192  //cout<<"PndEmcMultiWaveformToCalibratedDigi: "<<nWaveforms<<" waveforms to convert"<<endl;
193  for (Int_t iWaveform=0; iWaveform<nWaveforms; iWaveform++) {
194  PndEmcMultiWaveform* theWaveform = (PndEmcMultiWaveform*) fWaveformArray->At(iWaveform);
195  hitIndex=theWaveform->GetHitIndex();
196  detId=theWaveform->GetDetectorId();
197  trackId=theWaveform->GetTrackId();
198  module=theWaveform->GetModule();
199  nSignal=theWaveform->GetNumberOfWaveforms();
200  if(module == 5){
201  thePSA = fpsaAlgorithm_pmt;
202  theEnergyNorm = fWfNormalisation_pmt;
203  theSampleRate = fSampleRate_PMT;
204  } else {
205  thePSA = fpsaAlgorithm;
206  theEnergyNorm = fWfNormalisation_proto192;;
207  theSampleRate = fSampleRate;
208  }
209  for(Int_t iSignal=0; iSignal < nSignal; iSignal++){
210  theWaveform->SetActiveWaveform(iSignal);
211  nHits[iSignal] = thePSA->Process(theWaveform);
212 // std::cout << "Signal " << iSignal << ": " << nHits[iSignal] << " Hits" << std::endl;
213  for(Int_t iHit = 0; iHit < nHits[iSignal]; iHit ++){
214  thePSA->GetHit(iHit,hitenergies[iSignal][iHit],hittimes[iSignal][iHit]);
215 // std::cout << "Signal " << iSignal << ", Hit " << iHit << ": Energy " << hitenergies[iSignal][iHit] <<std::endl;
216  }
217  }
218 // std::cout << "found "<<nHits[0] << " hits for detid " << detId << std::endl;
219  for(Int_t iHit = 0; iHit < nHits[0]; iHit++){
220  highgain = kTRUE;
221  peakPosition = hittimes[0][iHit];
222  energy = hitenergies[0][iHit];
223  if(nSignal > 1 && energy > 1500.){ //todo make highgain limit a config option
224  //look for hit in lowgain
225 // std::cout << "Hit " << iHit << " is too high (" << energy << ") checking lowgain." << std::endl;
226 // std::cout << "highgain time: " << hittimes[0][iHit] << std::endl;
227  for(Int_t iHit1 = 0; iHit1<nHits[1]; iHit1++){
228 // std::cout << "lowgain hit time: " << hittimes[1][iHit] << std::endl;
229  if(TMath::Abs(peakPosition - hittimes[1][iHit1]) < 10.){ //todo make timediff a config option
230 // std::cout << "Found matching highgain hit " << iHit1 << std::endl;
231  energy = hitenergies[1][iHit1];
232  peakPosition = hittimes[0][iHit];
233  highgain = kFALSE;
234  break;
235  }
236  }
237  }
238 
239 
240  energy/=theEnergyNorm;
241  digi_time = peakPosition/theSampleRate;
242 // std::cout << "looking for calibration of detid " << detId << std::endl;
243  it = fCalibrationMap.find(detId);
244  if(it!=fCalibrationMap.end()){
245 // if(hitIndex == 45) std::cout << "found calibration value of " << it->second << " for hitIndex " << hitIndex << std::endl;
246  energy*=it->second;
247  }else{
248 // if(hitIndex == 45) std::cout << "no calibration value for hitIndex " << hitIndex << std::endl;
249  }
250  if(!highgain){
251 // if(hitIndex == 45) std::cout << "highgain" << std::endl;
252  it=fGainMap.find(detId);
253  if(it!=fGainMap.end()){
254  if(hitIndex == 45) std::cout << "found highgain value of " << it->second << " for hitIndex " << hitIndex << std::endl;
255  energy*=it->second;
256  }
257  }
258  // if(energy>1000){
259  // if(hitIndex == 45) std::cout << "energy: " << energy << " threshold: "<< fEnergyDigiThreshold << endl;
260  // if(hitIndex == 45) std::cout << "creating digi for detid: " << detId << "hitIndex: " << hitIndex <<std::endl;
261  // }
262  if (energy>fEnergyDigiThreshold)
263  {
264 // if(hitIndex == 45) std::cout << "energy: " << energy << endl;
265  PndEmcDigi* myDigi = new((*fDigiArray)[i_digi]) PndEmcDigi(trackId,detId, energy, digi_time, hitIndex);
266  myDigi->AddLink(FairLink("EmcMultiWaveform", iWaveform));
267  i_digi++;
268 
269  }
270  }
271  }
272  if (fVerbose>2){
273  timer.Stop();
274  Double_t rtime = timer.RealTime();
275  Double_t ctime = timer.CpuTime();
276  cout << "PndEmcMultiWaveformToCalibratedDigi, Real time " << rtime << " s, CPU time " << ctime << " s" << endl;
277  }
278 
279 }
280 
282 
283  // Get run and runtime database
284  FairRun* run = FairRun::Instance();
285  if ( ! run ) Fatal("SetParContainers", "No analysis run");
286 
287  FairRuntimeDb* db = run->GetRuntimeDb();
288  if ( ! db ) Fatal("SetParContainers", "No runtime database");
289 
290  // Get Emc digitisation parameter container
291  fDigiPar = (PndEmcDigiPar*) db->getContainer("PndEmcDigiPar");
292 
293  // Get Emc reconstruction parameter container
294  fRecoPar = (PndEmcRecoPar*) db->getContainer("PndEmcRecoPar");
295 
296 }
297 
299 {
300  SetPersistency(val);
301  return;
302 }
303 
305  std::ifstream in(fCalibrationFileName,std::ifstream::in);
306 // in.open(fCalibrationFileName);
307  if (!in.good()) {
308  std::cerr << "Cannot open calibration file!" << endl;
309  return;
310  }
311 
312  char buf[255];
313  while (in.getline(buf, 255)) {
314  TString tmp = buf;
315  TObjArray *tokens = tmp.Tokenize(" \t;");
316  if(tokens->GetEntries()<2){
317  continue;
318  }
319  tmp=tokens->UncheckedAt(0)->GetName();
320  TString tmp2 = tokens->UncheckedAt(1)->GetName();
321  if(tmp.IsDigit() && tmp2.IsFloat()){
322  fCalibrationMap.insert(std::pair<Int_t,Double_t>(tmp.Atoi(),tmp2.Atof()));
323 
324  }
325  if(tokens->GetEntries()<3){
326  continue;
327  }
328  tmp2 = tokens->UncheckedAt(2)->GetName();
329  if(tmp.IsDigit() && tmp2.IsFloat()){
330  fGainMap.insert(std::pair<Int_t,Double_t>(tmp.Atoi(),tmp2.Atof()));
331 
332  }
333  delete tokens;
334 
335 
336  }
337  if(fVerbose >1){
338  std::cout << "calibration values:" << std::endl;
339  std::map<Int_t,Double_t>::iterator it;
340  std::map<Int_t,Double_t>::iterator it2;
341  Int_t detid;
342  for ( it=fCalibrationMap.begin() ; it != fCalibrationMap.end(); it++ ){
343  detid = (*it).first;
344  std::cout << detid << "\t" << (*it).second << "\t";
345  it2=fGainMap.find(detid);
346  if(it2!=fGainMap.end()){
347  std::cout << (*it2).second;
348  }
349  std::cout << endl;
350  }
351  }
352 }
353 
354 
Int_t GetNumberOfWaveforms() const
Double_t GetEmcDigiPositionDepthShashlyk()
Definition: PndEmcRecoPar.h:25
Double_t GetSampleRate()
Definition: PndEmcDigiPar.h:39
Double_t GetPMT_Shaping_diff_time()
Definition: PndEmcDigiPar.h:33
static void selectDigiPositionMethod(PositionMethod, double positionDepthPWO=0., double positionDepthShahslyk=0., double rescaleFactor=1.)
Definition: PndEmcDigi.cxx:153
Int_t run
Definition: autocutx.C:47
Int_t GetNumber_of_samples_in_waveform()
Definition: PndEmcDigiPar.h:44
Pulseshape analysis for ADC waveforms.
represents the reconstructed hit of one emc crystal
Definition: PndEmcDigi.h:40
Double_t val[nBoxes][nFEBox]
Definition: createCalib.C:11
Module to take the hit list for the calorimeter and make ADC waveforms from them. ...
#define verbose
virtual Int_t Process(const PndEmcWaveform *waveform)=0
Find Hits in Waveform.
Double_t GetCrystal_time_constant()
Definition: PndEmcDigiPar.h:36
Int_t GetHitIndex() const
void SetPersistency(Bool_t val=kTRUE)
Pulseshape analysis for ADC waveforms.
virtual void GetHit(Int_t i, Double_t &energy, Double_t &time)=0
Get energy and time of hit.
Double_t GetASIC_Shaping_int_time()
Definition: PndEmcDigiPar.h:31
Pulseshape from an CRRC-Shaper.
Double_t GetEnergyDigiThreshold()
Definition: PndEmcDigiPar.h:42
static T Abs(const T &x)
Definition: PndCAMath.h:39
int nHits
Definition: RiemannTest.C:16
Pulseshape from an APFEL ASIC preamplifier shaper.
Double_t
int GetTrackId() const
TStopwatch timer
Definition: hit_dirc.C:51
parameter set of Emc digitisation
Definition: PndEmcDigiPar.h:12
void UpdateWaveform(PndEmcHit *hit, Double_t pePerMeV, Bool_t usePhotonStatistic, Double_t excessNoiseFactor, Double_t firstADCBinTime, Double_t sampleRate, PndEmcAbsPulseshape *pulseshape, Double_t=0)
virtual void SetEnergy(Double32_t energy)
Definition: PndEmcHit.h:50
long GetDetectorId() const
represents a simulated waveform in an emc crystal
Class to hold multiple waveforms from one Emc Hit / ADC readout.
Double_t ctime
Definition: hit_dirc.C:114
Baseclass for pulseshapeanalysis ( featureextraction )
Definition: PndEmcAbsPSA.h:21
represents the deposited energy of one emc crystal from simulation
Definition: PndEmcHit.h:26
ClassImp(PndAnaContFact)
Short_t GetModule() const
void SetActiveWaveform(Int_t active=1)
PndEmcMultiWaveformToCalibratedDigi(Int_t verbose=0, Bool_t storedigis=kTRUE)
Double_t GetSampleRate_PMT()
Definition: PndEmcDigiPar.h:40
Double_t rtime
Definition: hit_dirc.C:113
virtual void SetTime(Double32_t time)
Definition: PndEmcHit.h:51
Double_t GetShashlyk_time_constant()
Definition: PndEmcDigiPar.h:37
Int_t GetNumber_of_samples_in_waveform_pmt()
Definition: PndEmcDigiPar.h:45
Double_t GetPMT_Shaping_int_time()
Definition: PndEmcDigiPar.h:32
Parameter set for Emc Reco.
Definition: PndEmcRecoPar.h:12
Double_t energy
Definition: plot_dirc.C:15
Double_t GetEmcDigiPositionDepthPWO()
Definition: PndEmcRecoPar.h:24