FairRoot/PandaRoot
PndSdsChargeWeightingAlgorithms.cxx
Go to the documentation of this file.
1 #include <iostream>
2 #include <map>
3 #include <vector>
4 #include <fstream>
5 
6 
7 //#include "runinfo.h"
9 #include "PndSdsDigi.h"
10 #include "PndSdsCluster.h"
11 #include "PndSdsCalcStrip.h"
12 
13 #include "TArray.h"
14 //using namespace std;
16 
18 : TObject(),
19  fDigiArray(arr),
20  fCalcStrip(NULL),
21  fChargeConverter(NULL),
22  fVerbose(0)
23 {
24 }
26 {
27 }
28 
29 /*
30 returns the (modified) error function
31 this is a local (private) function
32 */
34 {
35  return ((TMath::Erf(p0*(x-p1)))*p2+p3);
36 }
37 
38 std::pair<Double_t,Double_t> PndSdsChargeWeightingAlgorithms::CenterOfGravity(const PndSdsCluster* Cluster)
39 {
40  Int_t nrHits = Cluster->GetClusterSize();
41  if(nrHits<2) return Binary(Cluster);
42  std::pair<Double_t,Double_t> result;
43  Double_t x_g=0., chargesum=0, charge=0, stripno=0;
44  Double_t xerror=0.,xtmp=0.,err=0.;
47  Double_t Tthr=threshold/noise;
48 
49  for(Int_t l=0;l<nrHits;++l) // loop over all hits
50  { // ( q_i*chan_i )
51  // x_g= SUM ( ------------ )
52  // ( Q_sum )
53  charge = DigiCharge(Cluster->GetDigiIndex(l));
54  stripno = DigiStripno(Cluster->GetDigiIndex(l));
55  chargesum+=charge;
56  x_g += charge * stripno ;
57  if(fVerbose>2) Info("CenterOfGravity","Adding digi values (stripno,charge) = (%f,%f)",stripno,charge);
58  }
59  x_g = x_g/chargesum;
60  result.first=x_g;
61 
62  Double_t chanmax=DigiStripno(Cluster->GetDigiIndex(nrHits-1));
63  Double_t chanmin=DigiStripno(Cluster->GetDigiIndex(0));
64  for(Int_t l=0;l<nrHits;++l) // loop over all hits
65  {
66  stripno = DigiStripno(Cluster->GetDigiIndex(l));
67  if(stripno>chanmax) chanmax=stripno;
68  if(stripno<chanmin) chanmin=stripno;
69  xtmp = stripno - x_g;
70  xtmp*=xtmp;
71  xerror+=xtmp;
72  }
73  chanmax++;
74  chanmax-=x_g;
75  chanmax*=chanmax;
76  chanmin--;
77  chanmin-=x_g;
78  chanmin*=chanmin;
79  xtmp=chanmax;
80  xtmp+=chanmin;
81  xtmp*=Tthr;
82  xtmp*=Tthr;
83  xtmp/=12.;//Thr is uniform distr.
84  err=xerror;
85  err+=xtmp;
86  err=sqrt(err);
87  err*=noise;
88  err/=chargesum;
89 
90  if (err < 1e-15) Warning("CenterOfGravity","Got bad error value: Cluster with %i digis. Position %f +-%f chn.",nrHits,x_g,xerror);
91  result.second = err;
92 
93  if(fVerbose>1) Info("CenterOfGravity","Got a cluster with %i digis. Position %f +- %f chn.",nrHits,result.first,result.second);
94  return result;
95 }
96 
97 
98 std::pair<Double_t,Double_t> PndSdsChargeWeightingAlgorithms::HeadTail(const PndSdsCluster* Cluster)
99 {
100  Int_t nrHits = Cluster->GetClusterSize();
101  if(nrHits<2) return Binary(Cluster);
102  if(nrHits==2) return CenterOfGravity(Cluster);
103 
104  // We assume that the digis in each cluster are sorted.
105  std::pair<Double_t,Double_t> result;
107 
108  Double_t x_h=DigiStripno(Cluster->GetDigiIndex(0));
109  Double_t x_t=DigiStripno(Cluster->GetDigiIndex(nrHits-1));
110 
111  Double_t Q=0.,q_inner=0., charge=0.,stripno=-1.,err=0.;
112  Int_t k_h=0, k_t=nrHits-1;
113  for (Int_t kk=0;kk<nrHits;kk++)
114  {
115  charge = DigiCharge(Cluster->GetDigiIndex(kk));
116  stripno = DigiStripno(Cluster->GetDigiIndex(kk));
117  Q+=charge;
118  if(x_h>stripno){k_h=kk;x_h=stripno;}
119  if(x_t<stripno){k_t=kk;x_t=stripno;}
120  }
121  Double_t x_ht=x_h+0.5*nrHits;
122  Double_t q_h=DigiCharge(Cluster->GetDigiIndex(k_h));
123  Double_t q_t=DigiCharge(Cluster->GetDigiIndex(k_t));
124  q_inner=Q-q_h-q_t;
125  q_inner /= (nrHits-2.); // this number is just a good estiamte for the charge being lost of such a particle in one strip
126  Double_t w=(q_t-q_h)/(2.*q_inner);
127  x_ht+=w;
128  err=sqrt(2.)*noise/q_inner;
129 
130  result.first=x_ht;
131  result.second=err;
132 
133  return result;
134 }
135 
136 
137 std::pair<Double_t,Double_t> PndSdsChargeWeightingAlgorithms::Median(const PndSdsCluster* Cluster)
138 {
139  Int_t nrHits = Cluster->GetClusterSize();
140  std::pair<Double_t,Double_t> result;
141  Double_t channel=Cluster->GetDigiIndex(0); // assume sorted digis in cluster from k to k+n
142  channel+=0.5*nrHits;
143  result.first=channel;
144  result.second=1./sqrt(12.);
145  if(fVerbose>1) Info("Median","Got a cluster with %i digis. Position %f +- %f chn.",nrHits,result.first,result.second);
146  return result;
147 }
148 
149 
150 
151 std::pair<Double_t,Double_t> PndSdsChargeWeightingAlgorithms::Binary(const PndSdsCluster* Cluster)
152 {
153  Int_t nrHits = Cluster->GetClusterSize();
154  std::pair<Double_t,Double_t> result;
155  Double_t charge=0.,chargemax=0;
156  Double_t channel=0;
157  for(Int_t i=0;i<nrHits;++i)
158  {
159  charge=DigiCharge(Cluster->GetDigiIndex(i));
160  if( charge > chargemax)
161  { // choose highest signal
162  chargemax=charge;
163  channel=DigiStripno(Cluster->GetDigiIndex(i));
164  }
165  }
166  result.first=channel;
167  result.second=1./sqrt(12.);
168  if(fVerbose>1) Info("Binary","Got a cluster with %i digis. Position %f +- %f chn.",nrHits,result.first,result.second);
169  return result;
170 }
171 
172 //std::pair<Double_t,Double_t> PndSdsChargeWeightingAlgorithms::Eta(const PndSdsCluster* Cluster)
173 //{
174 // //TODO: Make a good MVD eta-par file. Eta Algo needed at all?
175 // std::pair<Double_t,Double_t> result; // first calc eta!
176 // Int_t nrHits = Cluster->GetClusterSize();
177 // if(nrHits>1)
178 // {
179 // Double_t ql=DigiCharge(Cluster->GetDigiIndex(0));
180 // Double_t qr=DigiCharge(Cluster->GetDigiIndex(nrHits-1));
181 //
182 // Int_t f=1, o=nrHits-2;
183 // Double_t xl=DigiStripno(Cluster->GetDigiIndex(0))*1.;
184 //
185 // Double_t p0,pe0,p1,pe1,p2,pe2,p3,pe3; // f(eta) parameters calc before
186 // std::ifstream InPar("/home/student/Desktop/repository/calibPar/Eta_para.par");
187 // InPar >> p0>>pe0>>p1>>pe1>>p2>>pe2>>p3>>pe3;
188 // InPar.close();
189 // while(f<o) // build groups nearly same charge value
190 // {
191 // if(ql<=qr) // who is smaller
192 // {
193 // ql=ql+DigiCharge(Cluster->GetDigiIndex(f));
194 // ++f;
195 // }
196 // if(qr<ql)
197 // {
198 // qr=qr+DigiCharge(Cluster->GetDigiIndex(o));
199 // // xl=xl+Erfmod(sube, p0, p1, p2, p3);
200 // --o;
201 // }
202 // }
203 //
204 // Double_t e = qr/(qr+ql); // total eta
205 //
206 // result.first=xl+f-1+Erfmod(e, p0, p1, p2, p3); // reconstruct
207 // }else{
208 // return Binary(Cluster);
209 // }
210 // result.second=0.;
211 // return result;
212 //}
213 
214 std::pair<Double_t,Double_t> PndSdsChargeWeightingAlgorithms::Eta(const PndSdsCluster* Cluster, const TH2F* PosVsEta)//, const TH1F* pitch3)
215 {
216  Int_t nrHits = Cluster->GetClusterSize();
217 
218  if(nrHits < 2.){return Binary(Cluster);}
219  if(nrHits > 2.){return CenterOfGravity(Cluster);}
220 
221  std::pair<Double_t,Double_t> result;
222  //if(nrHits == 2. && DigiStripno(Cluster->GetDigiIndex(1))-DigiStripno(Cluster->GetDigiIndex(0))==1.)
223 
224  std::pair<Double_t,Double_t> eta_value;
225  Double_t stripno=0.;
226  Int_t NmbOfStrips=0;
227 
228  eta_value = EtaValue(Cluster, stripno, NmbOfStrips);
229 
230  Int_t Clustercharge=(Int_t)ceil((DigiCharge(Cluster->GetDigiIndex(0)) + DigiCharge(Cluster->GetDigiIndex(1)))/2500);
231  if(Clustercharge>21)Clustercharge=21;
232 
233  result.first=stripno + PosVsEta->GetBinContent((Int_t)ceil(eta_value.first * 500.), Clustercharge); //etadist histogram contains 200 bins.
234 
235  result.second=(PosVsEta->GetBinContent((Int_t)ceil((eta_value.first+eta_value.second) * 500.), Clustercharge)
236  - PosVsEta->GetBinContent((Int_t)ceil((eta_value.first-eta_value.second) * 500.), Clustercharge))/2.;
237 
238  return result;
239 }
240 
241 std::pair<Double_t,Double_t> PndSdsChargeWeightingAlgorithms::EtaValue(const PndSdsCluster* Cluster, Double_t &stripno, Int_t &NmbOfStrips)
242 {
243 
244  Int_t nrHits = Cluster->GetClusterSize();
245  std::pair<Double_t,Double_t> result;
246 
247  if(nrHits==2. && DigiStripno(Cluster->GetDigiIndex(1)) - DigiStripno(Cluster->GetDigiIndex(0))==1.) // 2 strips fired
248  {
249  NmbOfStrips=2;
250  Double_t ql=0., qr=0., noise=0., cherrl=0., cherrr=0.;
252 
253  ql = DigiCharge(Cluster->GetDigiIndex(0));
254  qr = DigiCharge(Cluster->GetDigiIndex(1));
255  cherrr = DigiChargeError(Cluster->GetDigiIndex(1));
256  cherrr = sqrt(noise*noise+cherrr*cherrr);
257 
258  cherrl = DigiChargeError(Cluster->GetDigiIndex(0));
259  cherrl = sqrt(noise*noise+cherrl*cherrl);
260 
261  stripno = DigiStripno(Cluster->GetDigiIndex(0));
262 
263  result.first=qr/(qr+ql);
264 
265  //unused??
266  //PndSdsDigiStrip* digil = (PndSdsDigiStrip*)(fDigiArray->At(Cluster->GetDigiIndex(0)));
267  //PndSdsDigiStrip* digir = (PndSdsDigiStrip*)(fDigiArray->At(Cluster->GetDigiIndex(1)));
268 
269  result.second=sqrt(((ql/(qr+ql))*(1./(qr+ql))*(ql/(qr+ql))*(1./(qr+ql))*cherrr*cherrr)+((qr/(qr+ql))*(1./(qr+ql))*(qr/(qr+ql))*(1./(qr+ql))*cherrl*cherrl));
270  return result;
271  }
272 
273  if(nrHits==3 || (DigiStripno(Cluster->GetDigiIndex(1)) - DigiStripno(Cluster->GetDigiIndex(0))==2. && nrHits==2)) // 3 strips fired, sometimes middle strip is empty
274  {
275 
276  Double_t ql=0., qr=0., qm=0., noise=0., cherrl=0., cherrr=0.;
278  NmbOfStrips=3;
279 
280  if(nrHits==3){
281  ql = DigiCharge(Cluster->GetDigiIndex(0));
282  qm = DigiCharge(Cluster->GetDigiIndex(1));
283  qr = DigiCharge(Cluster->GetDigiIndex(2));
284  cherrr = sqrt(TMath::Power(DigiChargeError(Cluster->GetDigiIndex(2)),2.)+TMath::Power((DigiChargeError(Cluster->GetDigiIndex(1))/2.),2.));
285  cherrl = sqrt(TMath::Power(DigiChargeError(Cluster->GetDigiIndex(0)),2.)+TMath::Power((DigiChargeError(Cluster->GetDigiIndex(1))/2.),2.));
286 
287  }else{
288  ql = DigiCharge(Cluster->GetDigiIndex(0));
289  qr = DigiCharge(Cluster->GetDigiIndex(1));
290  qm=3000.;
291  cherrr = sqrt(TMath::Power(DigiChargeError(Cluster->GetDigiIndex(1)),2.)+TMath::Power((noise/2.),2.));
292  cherrl = sqrt(TMath::Power(DigiChargeError(Cluster->GetDigiIndex(0)),2.)+TMath::Power((noise/2.),2.));
293  PndSdsDigiStrip* digil = (PndSdsDigiStrip*)(fDigiArray->At(Cluster->GetDigiIndex(0)));
294  PndSdsDigiStrip* digir = (PndSdsDigiStrip*)(fDigiArray->At(Cluster->GetDigiIndex(1)));
295  std::cout<<"strip no charge: UNBL: "<<DigiStripno(Cluster->GetDigiIndex(0))<<" "<<digil->GetCharge()<<" "<<DigiStripno(Cluster->GetDigiIndex(1))<<" "<<digir->GetCharge()<<std::endl;
296 
297  }
298 
299  ql+=qm/2.;
300  qr+=qm/2.;
301 
302  cherrr = sqrt(noise*noise+cherrr*cherrr);
303  cherrl = sqrt(noise*noise+cherrr*cherrr);
304  stripno = DigiStripno(Cluster->GetDigiIndex(0));
305  result.first=qr/(qr+ql);
306  result.second=sqrt(((ql/(qr+ql))*(1./(qr+ql))*(ql/(qr+ql))*(1./(qr+ql))*cherrr*cherrr)+((qr/(qr+ql))*(1./(qr+ql))*(qr/(qr+ql))*(1./(qr+ql))*cherrl*cherrl));
307  return result;
308  }
309 
310  result.first=-1.;
311  result.second=-1.;
312  return result;
313 }
314 
315 
316 std::pair<Double_t,Double_t> PndSdsChargeWeightingAlgorithms::AutoSelect(const PndSdsCluster* Cluster)
317 {
318  Warning("auto_select", "Do not use, this selection is still wrong!");
319  switch(Cluster->GetClusterSize())
320  {
321  case 1:
322  return Binary(Cluster);
323  break;
324  case 2:
325  //return eta(Cluster); // switched off (no par file)
326  return CenterOfGravity(Cluster);
327  break;
328  case 3:
329  return CenterOfGravity(Cluster);
330  break;
331  case 4:
332  return CenterOfGravity(Cluster);
333  break;
334  default:
335  return HeadTail(Cluster);
336  break;
337  }
338  return HeadTail(Cluster);
339 }
340 /*
341 void PndSdsChargeWeightingAlgorithms::MakedNdEta(const std::vector<PndSdsCluster>& Cluster, RunInfo& info)
342 {
343 for(Int_t cID=0;cID<Cluster->size();cID++)
344 {
345 Int_t nrHits = Cluster[cID].GetClusterSize();
346 if(nrHits>1)
347 {
348 Double_t ql=Cluster[cID].GetHit(0).GetCharge()*1.;
349 Double_t qr=Cluster[cID].GetHit(nrHits-1).GetCharge()*1.;
350 
351 Int_t f=1, o=nrHits-2;
352 Double_t xl=Cluster[cID].GetHit(0).GetChannel()*1.;
353 while(f<o) // build groups nearly same charge value
354 {
355 if(ql<=qr) // who is smaller
356 {
357 ql=ql+Cluster[cID].GetHit(f).GetCharge()*1.;
358 ++f;
359 }
360 if(qr<ql)
361 {
362 qr=qr+Cluster[cID].GetHit(o).GetCharge()*1.;
363 // xl=xl+Erfmod(sube, p0, p1, p2, p3);
364 --o;
365 }
366 }
367 Double_t e = qr/(qr+ql); // total eta
368 info.FilldNdEta(e);
369 }
370 }
371 return;
372 }
373 */
374 
376 {
377  PndSdsDigiStrip* digi = (PndSdsDigiStrip*)(fDigiArray->At(digiIndex));
379  //Info("DigiCharge","digi=%p chargedigi=%f charge=%f",digi,digi->GetCharge(), charge);
380  //digi->Print();
381  return charge;
382 }
383 
385 {
386  Double_t cherr = DigiCharge(digiIndex);
387  cherr *= fChargeConverter->GetRelativeError(cherr);
388  return cherr;
389 }
390 
391 
393 {
394  Int_t strip;
395  SensorSide side;
396  PndSdsDigiStrip* myDigi = (PndSdsDigiStrip*)fDigiArray->At(digiIndex);
397  fCalcStrip->CalcFeChToStrip(myDigi->GetFE(), myDigi->GetChannel(), strip, side);
398  return strip;
399 }
400 
401 
402 
403 
404 
std::pair< Double_t, Double_t > HeadTail(const PndSdsCluster *Cluster)
int fVerbose
Definition: poormantracks.C:24
TClonesArray * digi
std::pair< Double_t, Double_t > Median(const PndSdsCluster *Cluster)
Int_t GetClusterSize() const
Definition: PndSdsCluster.h:39
Int_t i
Definition: run_full.C:25
Class to store the Digis which belong to one cluster This class holds the information which Digi belo...
Definition: PndSdsCluster.h:19
friend F32vec4 sqrt(const F32vec4 &a)
Definition: P4_F32vec4.h:29
Class for digitised strip hits.
Double_t GetCharge() const
Definition: PndSdsDigi.h:60
virtual Double_t GetRelativeError(Double_t Charge)=0
Int_t GetFE() const
Definition: PndSdsDigi.h:57
virtual Double_t DigiValueToCharge(Double_t digi)=0
Converts a given digitized charge into charge in electrons.
Int_t GetDigiIndex(Int_t i) const
Definition: PndSdsCluster.h:40
int strip
Definition: anaMvdDigi.C:135
Double_t
SensorSide
std::pair< Double_t, Double_t > CenterOfGravity(const PndSdsCluster *Cluster)
double threshold
TPad * p2
Definition: hist-t7.C:117
std::pair< Double_t, Double_t > EtaValue(const PndSdsCluster *Cluster, Double_t &stripno, Int_t &NmbOfStrips)
void CalcFeChToStrip(Int_t fe, Int_t channel, Int_t &strip, enum SensorSide &side) const
Double_t x
std::pair< Double_t, Double_t > Eta(const PndSdsCluster *Cluster, const TH2F *PosVsEta)
std::pair< Double_t, Double_t > Binary(const PndSdsCluster *Cluster)
Double_t GetThreshold() const
ClassImp(PndAnaContFact)
TPad * p1
Definition: hist-t7.C:116
Double_t Erfmod(Double_t x, Double_t p0, Double_t p1, Double_t p2, Double_t p3)
std::pair< Double_t, Double_t > AutoSelect(const PndSdsCluster *Cluster)
Int_t GetChannel() const
double noise
Double_t GetNoise() const