StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StFcsDbPulse.cxx
1 #include "StFcsDbPulse.h"
2 
3 ClassImp(StFcsDbPulse);
4 
5 StFcsDbPulse::StFcsDbPulse(const char* name) : TDataSet(name)
6 {
7  mTail = 0;
8  mTBPerRC = 8;
9 
10  mGSigma = 0;
11  mA1 = 0;
12  mA2 = 0;
13  mXoff1 = 0;
14  mXoff2 = 0;
15  mTau1 = 0;
16  mTau2 = 0;
17  mP1 = 0;
18  mP2 = 0;
19 }
20 
22 
24 {
25 
26  mGSigma = 24.5; // signal nominal sigma
27  //GSigmaSigma = 0; // distibution of signal sigma
28  mA1 = 1.0/sqrtpi()/0.155/129;
29  mA2 = 0.2/sqrtpi()/0.155/129;
30  mXoff1 = 70 - 129;
31  mXoff2 = 220 - 129;
32  mTau1 = 200.0;
33  mTau2 = 40.0;
34  mP1 = 1.0;
35  mP2 = 1.0;
36 
37  return 0;
38 }
39 
40 void StFcsDbPulse::setTail(int tail)
41 {
42  mTail = tail;
43  if( tail == 0 ){return;}
44  if( tail == 1 )
45  {
46  //Data from Gerard 2020 summer
47  mGSigma = 24.5/nsecPerTB();
48  mA1 = 1.0/0.154/mGSigma;
49  mA2 = 0.2/0.154/mGSigma;
50  mXoff1 = (70 - 129)/nsecPerTB();
51  mXoff2 = (220 - 129)/nsecPerTB();
52  mTau1 = 200.0/nsecPerTB();
53  mTau2 = 40.0/nsecPerTB();
54  mP1 = 1.0;
55  mP2 = 1.0;
56  }
57  else if( tail == 2 )
58  {
59  //Data from WAH with real detector/LED system 2021 Jan
60  mGSigma = 2.347;
61  mA1 = 2543.0/854.0/mGSigma;
62  mA2 = 0.0;
63  mXoff1 = 211.3-215.7;
64  mXoff2 = 0.0;
65  mTau1 = 4.375;
66  mTau2 = 0.0;
67  mP1 = 1.0;
68  mP2 = 0.0;
69  }
70  else{ LOG_WARN << "StFcsDbPulse::setTail - Invalid Tail value " << tail << endm; }
71 }
72 
73 void StFcsDbPulse::setTGraphAsymmErrors(TGraphAsymmErrors* gae, const int &i, const double &adc, double Yerr, double YerrSat){
74  if( gae == 0 ){LOG_ERROR << "StFcsDbPulse::setTGraphAsymmErrors - Graph object cannot be zero" << endm; return;}
75  double HighY = 0;
76  if(adc<mAdcSaturation) { HighY=Yerr; }
77  else { HighY=YerrSat; }
78  gae->SetPointError(i,0,0,Yerr,HighY);
79 }
80 
81 //this one is just shower shape function
82 double StFcsDbPulse::pulseShape(double* x, double* p) {
83  double ret = p[0]*exp(-0.5*pow((x[0]-p[1])/p[2],2));
84  if(mTail>0){
85  double x1 = x[0] - p[1] - mXoff1;
86  if(x1>0){
87  double a0 = p[0] * p[2];
88  ret += a0*mA1/mTau1/mTau1*pow(x1,mP1)*exp(-x1/mTau1);
89  if(mA2>0){
90  double x2 = x[0] - p[1] - mXoff2;
91  if(x2>0){
92  ret += a0*mA2/mTau2/mTau2*pow(x2,mP2)*exp(-x2/mTau2);
93  }
94  }
95  }
96  }
97  return ret;
98 }
99 
100 double StFcsDbPulse::multiPulseShape(double* x, double* p) {
101  int npulse = p[0];
102  double ret = p[1];
103  for(int i=0; i<npulse; i++){
104  ret += pulseShape(x, &p[2+i*3]);
105  }
106  return ret;
107 }
108 
109 TF1* StFcsDbPulse::createPulse(double xlow, double xhigh, int npars)
110 {
111  if( npars<5 ){LOG_WARN << "StFcsDbPulse::createPulse - npars must be greater than or equal to 5 paramaters" <<endm; return 0;}
112  else if( xlow>=xhigh ){LOG_ERROR << "StFcsDbPulse::createPulse - Invalid range" <<endm; return 0;}
113  else{return new TF1("F1_fcsDbPulse",this,&StFcsDbPulse::multiPulseShape,xlow,xhigh,npars);}//More unique name in future??
114 }
115 
116 int StFcsDbPulse::GenericPadPos(int value, int Nvals, int PadNums )
117 {
118  if( value<=0 ){return ceil( static_cast<double>(value+(Nvals*PadNums))/static_cast<double>(Nvals) );}
119  else{ return GenericPadPos(value-(Nvals*PadNums), Nvals, PadNums); }
120 }
121 
122 int StFcsDbPulse::PadNum4x4(int det, int col, int row)
123 {
124  int ncol = 0;
125  int nrow = 0;
126  if( det<=1 )
127  {
128  ncol = 2;
129  nrow = 3;
130  }
131  else if( det<=3 )
132  {
133  ncol = 2;
134  nrow = 2;
135  }
136  else{ LOG_ERROR << "This only works for Ecal and Hcal" << endm; return 0;}
137  int padcol = GenericPadPos(col,ncol,4);
138  int padrow = GenericPadPos(row,nrow,4);
139  return 4*(padrow-1)+padcol;
140 }
141 
142 Int_t StFcsDbPulse::getYMinMax(TGraphAsymmErrors* gae, Double_t &Ymin, Double_t &Ymax, Double_t xmin, Double_t xmax)
143 {
144  if( gae==0 ){ return -1; }
145  Int_t index = -1;
146  //Start with invalid values
147  Double_t MinY = Ymax;
148  Double_t MaxY = Ymin;
149  for( int i=0; i<gae->GetN(); ++i )
150  {
151  Double_t X; Double_t Y;
152  gae->GetPoint(i,X,Y);
153  if( X<xmin || X>xmax ){continue;}
154  if( Y>MaxY ){ MaxY=Y; index=i;}
155  if( Y<MinY ){ MinY=Y; }
156  }
157  if( index<0 ){std::cout << "Unable to find a maximum ADC value" << std::endl; return index;}
158  Ymin=MinY;
159  Ymax=MaxY;
160  return index;
161 }
162 
163 void StFcsDbPulse::Print(Option_t* opt) const
164 {
165  std::cout << "Constants"
166  << "|sqrtpi:" << sqrtpi()
167  << "|sqrt2pi:" << sqrt2pi()
168  << std::endl;
169  std::cout << "TimebinInfo"
170  << "|TBPerRC:" << TBPerRC()
171  << "|nsecPerTB:"<< nsecPerTB()
172  << "|BeamLengthSig:"<< BeamLengthSig()
173  << std::endl;
174  std::cout << "PulseInfo"
175  << "|GSigma:" << GSigma()
176  << "|A1:" << A1()
177  << "|A2:" << A2()
178  << "|Xoff1:" << Xoff1()
179  << "|Xoff2:" << Xoff2()
180  << "|Tau1:" << Tau1()
181  << "|Tau2:" << Tau2()
182  << "|P1:" << P1()
183  << "|P2:" << P2()
184  << std::endl;
185 }
186 
static double sqrtpi()
sqrt(TMath::Pi)
Definition: StFcsDbPulse.h:36
double mXoff1
pulse shape tail: x offset of first xexp function
Definition: StFcsDbPulse.h:159
double A1() const
Definition: StFcsDbPulse.h:67
StFcsDbPulse(const char *name="fcsPulse")
Constructor.
Definition: StFcsDbPulse.cxx:5
double P1() const
Definition: StFcsDbPulse.h:73
double nsecPerTB() const
nanoseconds per timebin
Definition: StFcsDbPulse.h:42
static Int_t getYMinMax(TGraphAsymmErrors *gae, Double_t &Ymin, Double_t &Ymax, Double_t xmin=-5, Double_t xmax=2000)
Finds minimum and maximum y-values in a TGraph and returns index for max y.
TF1 * createPulse(double xlow=0, double xhigh=1, int npars=5)
Function to create pulse shape for FCS, 5 parameters is minimum.
double BeamLengthSig() const
beam length sigma
Definition: StFcsDbPulse.h:43
double mP1
pulse shape tail: power of first xexp function
Definition: StFcsDbPulse.h:163
double Xoff2() const
Definition: StFcsDbPulse.h:70
int Init()
Initialize object.
double A2() const
Definition: StFcsDbPulse.h:68
static double sqrt2pi()
sqrt(2*TMath::Pi)
Definition: StFcsDbPulse.h:37
double mXoff2
pulse shape tail: x offset of second xexp function
Definition: StFcsDbPulse.h:160
double mGSigma
pulse shape nominal sigma of Gaussian part
Definition: StFcsDbPulse.h:155
static void setTGraphAsymmErrors(TGraphAsymmErrors *gae, const int &i, const double &adc, double Yerr, double YerrSat)
Figure out and set the errors on FCS pulse data stored in a TGraphAsymmErrors object.
double P2() const
Definition: StFcsDbPulse.h:74
static int GenericPadPos(int value, int Nvals, int PadNums)
Function to tell you pad number when drawing multiple objects on the same pad.
double Tau1() const
Definition: StFcsDbPulse.h:71
double mTau2
pulse shape tail: scale of second xexp function
Definition: StFcsDbPulse.h:162
double Tau2() const
Definition: StFcsDbPulse.h:72
virtual ~StFcsDbPulse()
Destructor.
static int PadNum4x4(int det, int col, int row)
Function that gives pad number when drawing a specific detector id.
double mA1
pulse shape tail: height of first xexp function
Definition: StFcsDbPulse.h:157
double mA2
pulse shape tail: height of second xexp function
Definition: StFcsDbPulse.h:158
double multiPulseShape(double *x, double *p)
Multi-pulse shape function constant+gaus+xexp+xexp for many pulses.
double TBPerRC() const
Definition: StFcsDbPulse.h:41
double mTau1
pulse shape tail: scale of first xexp function
Definition: StFcsDbPulse.h:161
double pulseShape(double *x, double *p)
Single pulse shape gaus+xexp+xexp.
double mTBPerRC
number of timebins in one RHIC crossing
Definition: StFcsDbPulse.h:154
double mP2
pulse shape tail: power of second xexp function
Definition: StFcsDbPulse.h:164
double Xoff1() const
Definition: StFcsDbPulse.h:69
double GSigma() const
Definition: StFcsDbPulse.h:66
void setTail(int tail)
Sets the variables needed by the sum of xexp functions that describe the tail of the pulse shape...
virtual void Print(Option_t *opt="") const
Print all the constants associated with this class.