ATLAS Offline Software
Loading...
Searching...
No Matches
TilePulseShape.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
5
7
8#include "TMath.h"
9#include "TGraph.h"
10#include "TSpline.h"
11#include "TF1.h"
12
13#include <iostream>
14
15#include "GaudiKernel/IMessageSvc.h"
16#include "GaudiKernel/GaudiException.h"
17
18//_________________________________________________________________________
19TilePulseShape::TilePulseShape(IMessageSvc* msgSvc, const std::string& name)
20 : AthMessaging(msgSvc, name)
21{
22}
23
24//_________________________________________________________________________
25TilePulseShape::TilePulseShape(IMessageSvc* msgSvc, const std::string& name, const TString& fileName)
26 : AthMessaging(msgSvc, name)
27{
28 loadPulseShape(fileName);
29}
30
31//________________________________________________________________________
32TilePulseShape::TilePulseShape(IMessageSvc* msgSvc, const std::string& name, const std::vector<double>& shapevec)
33 : AthMessaging(msgSvc, name)
34{
35 setPulseShape(shapevec);
36}
37
38//_________________________________________________________________________
45
46//_________________________________________________________________________
47void TilePulseShape::loadPulseShape(const TString& fileName)
48{
50 if(m_pulseShape) delete m_pulseShape;
51 m_pulseShape = new TGraph(fileName.Data());
52 if(m_pulseShape->IsZombie()) {
53 throw GaudiException(std::string("could not load pulseshape from file: ") + fileName.Data(),
54 "TilePulseShape", StatusCode::FAILURE);
55 } else ATH_MSG_INFO("Loaded pulseshape from file: " << fileName);
57}
58
59//_________________________________________________________________________
60void TilePulseShape::setPulseShape(const std::vector<double>& shapevec)
61{
63 if(m_pulseShape) delete m_pulseShape;
64 m_pulseShape = new TGraph(shapevec.size());
65 for(std::vector<double>::size_type i = 0; i != shapevec.size(); i++) {
66 m_pulseShape->SetPoint(i, -75.5+i*0.5, shapevec.at(i));
67 }
69}
70
71
72//
73//_________________________________________________________________________
74// This function gives a pulse shaper for the 3-in-1 FEB
75double TilePulseShape::eval(double x, bool useSpline, bool useUndershoot)
76{
77
78 //=== make sure pulseshape is available
79 if(!m_deformedShape){
80 ATH_MSG_ERROR("No pulseshape loaded!");
81 return 0.;
82 }
83
84 //=== interpolate pulseShape value, TMath::BinarySearch returns
85 //=== index of value smaller or equal to the search value.
86 //=== -> Need to catch boundary values
87 double y(0.);
88 int n(m_deformedShape->GetN());
89 int idx = TMath::BinarySearch(n,m_deformedShape->GetX(),x);
90 if(idx<0){
91 //=== left out of bounds, return leftmost value
92// y = (_deformedShape->GetY())[0];
93 y = 0;
94 ATH_MSG_DEBUG("Left out of bounds. Replacing y = " << (m_deformedShape->GetY())[0] << " with y = 0. (idx = " << idx << ", x = " << x << ")");
95 }
96 else if(idx>=n-1){
97 //=== right out of bounds, return rightmost value
98// y = (_deformedShape->GetY())[n-1];
99 if(useUndershoot){
100 y = 0.00196 * (1 - exp(- x / 20664.59) ) - 0.00217;
101 }
102 else{
103 y = 0;
104 ATH_MSG_DEBUG("Right out of bounds. Replacing y = " << (m_deformedShape->GetY())[0] << " with y = 0. (idx = " << idx << ", x = " << x << ")");
105 }
106 }
107 else{
108 //=== linear interpolation
109 double xLo = (m_deformedShape->GetX())[idx ];
110 double xHi = (m_deformedShape->GetX())[idx+1];
111 double yLo = (m_deformedShape->GetY())[idx ];
112 double yHi = (m_deformedShape->GetY())[idx+1];
113 double yLinear = yLo + (yHi-yLo)/(xHi-xLo) * (x-xLo);
114 //=== spline interpolation
115 double ySpline = m_deformedSpline->Eval(x);
116
117 if(useSpline) y = ySpline;
118 else y = yLinear;
119 }
120
121 return y;
122}
123
124//
125//_______________________________________________________________________
127{
128 if(m_deformedShape==m_pulseShape) return;
129
130 delete m_deformedShape;
131 delete m_deformedSpline;
133 m_deformedSpline = new TSpline3("deformedSpline",m_deformedShape);
134}
135
136//
137//_______________________________________________________________________
138int TilePulseShape::scalePulse(double leftSF, double rightSF)
139{
140
142 if(!m_pulseShape) {
143 ATH_MSG_WARNING("Attempted pulse shape scaling before loading pulse shape");
144 return 1;
145 } else {
146 m_deformedShape = (TGraph*) m_pulseShape->Clone();
147
148 for(int i=0; i<m_deformedShape->GetN(); ++i){
149 double x,y;
150 m_deformedShape->GetPoint(i,x,y);
151 if(x<0.) x*= leftSF;
152 else if(x>0.) x*=rightSF;
153 m_deformedShape->SetPoint(i,x,y);
154 }
155
156 delete m_deformedSpline;
157 m_deformedSpline = new TSpline3("deformedSpline",m_deformedShape);
158 return 0;
159 }
160
161}
162
163//
164//_______________________________________________________________________
165TGraph* TilePulseShape::getGraph(double t0, double ped, double amp)
166{
167 TGraph* gr = (TGraph*) m_deformedShape->Clone();
168 for(int i=0; i<gr->GetN(); i++){
169 double x,y;
170 gr->GetPoint(i,x,y);
171 y*=amp;
172 y+=ped;
173 x+=t0;
174 gr->SetPoint(i,x,y);
175 }
176 return gr;
177}
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
#define gr
static Double_t t0
#define y
#define x
AthMessaging(IMessageSvc *msgSvc, const std::string &name)
Constructor.
double eval(double x, bool useSpline=true, bool useUndershoot=false)
void setPulseShape(const std::vector< double > &shapevec)
TGraph * getGraph(double t0=0., double ped=0., double amp=1.)
virtual ~TilePulseShape()
TGraph * m_pulseShape
TSpline * m_deformedSpline
int scalePulse(double leftSF=1., double rightSF=1.)
void loadPulseShape(const TString &fileName)
TGraph * m_deformedShape
TilePulseShape(IMessageSvc *msgSvc, const std::string &name)