HYDRA_development_version
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
hmdcdedx2.cc
Go to the documentation of this file.
1 //_HADES_CLASS_DESCRIPTION
2 ////////////////////////////////////////////////////////////////////////////
3 //*-- AUTHOR : J. Markert
4 ////////////////////////////////////////////////////////////////////////////
5 // HMdcDeDx
6 //
7 // This transformation class calculates the "pseudo dEdx" from t2-t1 (time above threshold)
8 // of all fired drift cells included in one HMdcSeg. The transformation is performed doing a
9 // normalization of the measured t2-t1 with impact angle and minimum distance to wire
10 // (MDCCAL2 parametrization) and the algorithm to normalize the single measurements and
11 // average over all cells included in the segment.
12 //-------------------------------------------------------------------------
13 // Calculation of dEdx:
14 // Float_t calcDeDx(HMdcSeg*,Float_t*,Float_t*,UChar_t*,Float_t*,UChar_t*,
15 // Int_t vers=2,Int_t mod=2, Bool_t useTruncMean=kTRUE, Float_t truncMeanWindow=-99.,Int_t inputselect)
16 // calculates dedx of a MDC (or 2) segment by doing normalization for
17 // impact angle and distance from wire for the fired cells of
18 // the segment. The measurements are sorted in decreasing order,
19 // the mean and sigma is calculated. Afterwards the truncated mean
20 // is calculated and returned as dedx. Mean,sigma,number of wires before
21 // truncating,truncated mean,truncated mean sigma and number of wires
22 // after truncating can be obtained by the returned pointers.
23 // Different methods can be selected:
24 // vers==0 : Input filling from inner HMdcSeg
25 // vers==1 : Input filling from outer HMdcSeg
26 // vers==2 : Input filling from inner+outer HMdcSeg (default)
27 // mod==0 : calc dedx from 1st module in segment
28 // mod==1 : calc dedx from 2nd module in segment
29 // mod==2 : calc dedx from whole segment (default)
30 // useTruncMean: kTRUE (default) apply truncated Mean
31 // truncMeanWindow (unit: SIGMA RMS of mean TOT): -99 (default) use standard window
32 // inputselect==0 : fill from segment (default,wires rejected by fit are missing)
33 // inputselect==1 : fill from cluster
34 // returns -99 if nothing was calculated
35 //-------------------------------------------------------------------------
36 // Settings of the truncated Mean method:
37 // The truncated mean is calculated according to the set window (in sigma units)
38 // (setWindow(Float_t window)) arround the mean. For the calculation of the truncated
39 // mean only drift cells with a dEdx inside the window arround the mean (calculated from
40 // all drift cells of the segment) will be taken into account.
41 // With setMinimumWires(Int_t minwires) the algorithm can be forced to keep
42 // a minimum number of wires. The method will stop removing drift cells from the active
43 // sample if the minimum number is reached.
44 ////////////////////////////////////////////////////////////////////////////
45 #include "hmdcdedx2.h"
46 #include "hmessagemgr.h"
47 #include "hparamlist.h"
48 #include "hmatrixcategory.h"
49 #include "hlinearcategory.h"
50 #include "hrecevent.h"
51 #include "hmdcdef.h"
52 #include "hmdctrackddef.h"
53 #include "hmdccal1.h"
54 #include "hmdcseg.h"
55 #include "hmdchit.h"
56 #include "hmdcclusinf.h"
57 #include "hmdcclusfit.h"
58 #include "hmdcclus.h"
59 #include "hmdcwirefit.h"
60 #include "hmdcsizescells.h"
61 #include "hphysicsconstants.h"
62 #include "hgeantkine.h"
63 
64 #include "TStyle.h"
65 #include "TMath.h"
66 #include "TRandom.h"
67 #include "TH1.h"
68 #include <stdlib.h>
69 
71 
72 Float_t HMdcDeDx2::MaxMdcMinDist[4] = {4.,4.,8.,9.};
73 Bool_t HMdcDeDx2::debug=kFALSE;
74 
75 
76 HMdcDeDx2::HMdcDeDx2(const Char_t* name,const Char_t* title,
77  const Char_t* context)
78  : HParCond(name,title,context)
79 {
80  //
81  clear();
82  loccal.set(4,0,0,0,0);
83  minimumWires = 5;
84  isInitialized = kFALSE;
85  setWindow(1.);
87  measurements.Reset(-99);
88  module = 2;
89  method = 2;
90  useCalibration = kTRUE;
91  for(Int_t i = 0; i < 4; i ++){
92  MinDistStep[i] = MaxMdcMinDist[i] / (Float_t) N_DIST;
94  }
95  AngleStep = 5.;
96 
97  memset(&parMax[0][0][0][0],0,sizeof(Double_t) * 6 * 4 * N_ANGLE * N_DIST);
98  memset(&pargaincorr[0][0][0][0],0,sizeof(Double_t) * 6 * 4 * 6 * 220);
99 }
101 {
102  // destructor
103 }
105 {
106  hefr = 0;
107  status = kFALSE;
109  changed = kFALSE;
110 }
111 void HMdcDeDx2::printParam(TString opt)
112 {
113  // prints the parameters of HMdcDeDx2 to the screen.
114 
115  cout<<"HMdcDeDx2:"<<endl;
116  if(opt.CompareTo("par") == 0 || opt.CompareTo("all") == 0)
117  {
118  cout<<"par:"<<endl;
119 
120  for(Int_t s = 0; s < 6; s ++){
121  for(Int_t m = 0; m < 4; m ++){
122  for(Int_t a = 0; a < N_ANGLE; a ++){
123  for(Int_t d = 0; d < N_DIST; d ++){
124  printf("s %i m %i angle %2i dist %2i %1.15e %1.15e %1.15e %1.15e\n",
125  s,m,a,d,
126  par[s][m][a][d][0],par[s][m][a][d][1],par[s][m][a][d][2],par[s][m][a][d][3]);
127  }
128  }
129  }
130  }
131  }
132  if(opt.CompareTo("parMax") == 0 || opt.CompareTo("all") == 0)
133  {
134  cout<<"parMax:"<<endl;
135 
136  for(Int_t s = 0; s < 6; s ++){
137  for(Int_t m = 0; m < 4; m ++){
138  for(Int_t a = 0; a < N_ANGLE; a ++){
139  for(Int_t d = 0; d < N_DIST; d ++){
140  printf("s %i m %i angle %2i dist %2i %7.3f\n",
141  s,m,a,d,
142  parMax[s][m][a][d]);
143  }
144  }
145  }
146  }
147  }
148  if(opt.CompareTo("shiftpar") == 0 || opt.CompareTo("all") == 0)
149  {
150  cout<<"shift par:"<<endl;
151  for(Int_t s = 0; s < 6; s ++){
152  for(Int_t m = 0; m < 4; m ++){
153  for(Int_t a = 0; a < N_ANGLE; a ++){
154  for(Int_t d = 0; d < N_DIST; d ++){
155  printf("s %i m %i angle %2i dist %2i %1.15e %1.15e\n",
156  s,m,a,d,
157  shiftpar[s][m][a][d][0],shiftpar[s][m][a][d][1]);
158  }
159  }
160  }
161  }
162  }
163 
164  if(opt.CompareTo("pargaincorr") == 0 || opt.CompareTo("all") == 0)
165  {
166  cout<<"pargaincorr:"<<endl;
167 
168  for(Int_t s = 0; s < 6; s ++){
169  for(Int_t m = 0; m < 4; m ++){
170  for(Int_t l = 0; l < 6; l ++){
171  for(Int_t c = 0; c < 220; c ++){
172  printf("s %i m %i l %i c %i %7.3f\n",
173  s,m,l,c,
174  pargaincorr[s][m][l][c]);
175  }
176  }
177  }
178  }
179  }
180 
181  if(opt.CompareTo("parmindistcut") == 0 || opt.CompareTo("all") == 0)
182  {
183  cout<<"parmindistcut:"<<endl;
184 
185  for(Int_t m = 0; m < 4; m ++){
186  printf("m %i %7.3f\n",
187  m,
188  parmindistcut[m]);
189  }
190  }
191 
192  cout<<"window:"<<endl;
193  printf("window %7.3f \n",window);
194  cout<<"hefr:"<<endl;
195  printf("hefr %7.3f \n",hefr);
196 
197 }
198 Bool_t HMdcDeDx2::createMaxPar(Bool_t print)
199 {
200  // create the maximum allowed value of ToT to keep
201  // the numerical calulations inside the range of double.
202  // The procedure loops over all s,m,abin,dbin to set
203  // the boundary automatically. This function needs
204  // the parameter array for the fit functions to be initialized
205  // before. The boundary value are stored inside the container.
206  Double_t dEdX;
207  Double_t ToT;
208  for(Int_t s = 0; s < 6; s ++){
209  for(Int_t m = 0; m < 4; m ++){
210  for(Int_t a = 0; a < N_ANGLE; a ++){
211  for(Int_t d = 0; d <N_DIST; d ++){
212  Double_t* p = &par[s][m][a][d][0];
213 
214  ToT = 1.;
215  dEdX = TMath::Power(10.,(TMath::Power((ToT - p[0]) / p[1],(1. / p[2])))) - p[3];
216  while(TMath::Finite(dEdX))
217  {
218  ToT += 1.;
219  dEdX = TMath::Power(10.,(TMath::Power((ToT - p[0]) / p[1],(1. / p[2])))) - p[3];
220  if(!TMath::Finite(dEdX)) {
221  parMax[s][m][a][d] = ToT - 1;
222  break;
223  }
224  }
225  if(print)
226  {
227  cout<<"s " <<s
228  <<" m "<<m
229  <<" a "<<a
230  <<" d "<<d
231  <<" ToTmax " <<parMax[s][m][a][d]
232  <<endl;
233  }
234  }
235  }
236  }
237  }
238 
239  return kTRUE;
240 }
242 {
243  if(!isInitialized)
244  {
245 
246  catcal = (HCategory*)((HRecEvent*)(gHades->getCurrentEvent()))->getCategory(catMdcCal1);
247  if(!catcal) { Error("initContainer()","HMdcCal1 Category not found in current Event!");}
248 
249  cathit = (HCategory*)((HRecEvent*)(gHades->getCurrentEvent()))->getCategory(catMdcHit);
250  if(!cathit) { Error("initContainer()","HMdcHit Category not found in current Event!");}
251 
252  catclusinf = (HCategory*)((HRecEvent*)(gHades->getCurrentEvent()))->getCategory(catMdcClusInf);
253  if(!catclusinf) { Error("initContainer()","HMdcClusInf Category not found in current Event!");}
254 
255  catclus = (HCategory*)((HRecEvent*)(gHades->getCurrentEvent()))->getCategory(catMdcClus);
256  if(!catclus) { Error("initContainer()","HMdcClus Category not found in current Event!");}
257 
259  if(!sizescells)
260  {
261  Error("init()","NO HMDCSIZESCELLS CONTAINER IN INPUT!");
262  return kFALSE;
263  }
264  //if(!sizescells->hasChanged()) sizescells->initContainer();
265  isInitialized = kTRUE;
266  }
267  return kTRUE;
268 }
270 {
271  // Puts all params of HMdcDeDx2 to the parameter list of
272  // HParamList (which ist used by the io);
273  if (!l) return;
274  l->add("par" ,&par [0][0][0][0][0],6 * 4 * N_ANGLE * N_DIST * N_PARAM );
275  l->add("parMax" ,&parMax [0][0][0][0] ,6 * 4 * N_ANGLE * N_DIST );
276  l->add("shiftpar" ,&shiftpar[0][0][0][0][0],6 * 4 * N_ANGLE * N_DIST * N_SHIFT_PARAM);
277 
278  l->add("pargaincorr",&pargaincorr[0][0][0][0],6 * 4 * 6 * 220);
279  l->add("parmindistcut",&parmindistcut[0],4);
280 
281  l->add("window" ,window);
282  l->add("hefr" ,hefr);
283 
284 
285 }
287 {
288  if (!l) return kFALSE;
289  if (!( l->fill("par" ,&par [0][0][0][0][0],6 * 4 * N_ANGLE * N_DIST * N_PARAM ))) return kFALSE;
290  if (!( l->fill("parMax" ,&parMax [0][0][0][0] ,6 * 4 * N_ANGLE * N_DIST ))) return kFALSE;
291  if (!( l->fill("shiftpar" ,&shiftpar[0][0][0][0][0],6 * 4 * N_ANGLE * N_DIST * N_SHIFT_PARAM))) return kFALSE;
292 
293  if (!( l->fill("pargaincorr" ,&pargaincorr[0][0][0][0],6 * 4 * 6 * 220 ))) return kFALSE;
294  if (!( l->fill("parmindistcut",&parmindistcut[0] ,4 ))) return kFALSE;
295 
296  if (!( l->fill("window" ,&window ))) return kFALSE;
297  if (!( l->fill("hefr" ,&hefr ))) return kFALSE;
298 
299  return kTRUE;
300 }
301 
302 void HMdcDeDx2::sort(Int_t nHits)
303 {
304  // Puts the measurement values into decreasing order.
305 
306  Int_t nhit=nHits;
307  if(nHits>MAX_WIRES) nhit=MAX_WIRES;
308 
309  register Int_t a,b,c;
310  Int_t exchange;
311  Double_t val;
312 
313  for(a = 0; a < nhit - 1; ++ a)
314  {
315  exchange = 0;
316  c = a;
317  val = measurements[a];
318 
319  for(b = a + 1; b < nhit; ++ b)
320  {
321  if(measurements[b] > val) // : < increasing :> decreasing
322  {
323  c = b;
324  val = measurements[b];
325  exchange = 1;
326  }
327  }
328  if(exchange)
329  {
330  measurements[c] = measurements[a];
331  measurements[a] = val;
332  }
333  }
334 }
335 Float_t HMdcDeDx2::calcDeDx(HMdcSeg* seg[2],
336  Float_t* meanold,Float_t* sigmaold,UChar_t* nwire,
337  Float_t* sigmanew,UChar_t* nwiretrunc,
338  Int_t vers,Int_t mod,
339  Bool_t useTruncMean,
340  Float_t truncMeanWindow,
341  Int_t inputselect)
342 {
343  // calculates dedx of a MDC segment by doing normalization for
344  // impact angle and distance from wire for the fired cells of
345  // the segment. The measurements are sorted in decreasing order,
346  // the mean and sigma is calculated. Afterwards the truncated mean
347  // according to the set window (in sigma units) arround the mean
348  // is calculated and returned as dedx. Mean,sigma,number of wires before
349  // truncating,truncated mean,truncated mean sigma and number of wires
350  // after truncating can be obtained by the returned pointers.
351  // Different methods can be selected:
352  // vers==0 : Input filling from inner HMdcSeg
353  // vers==1 : Input filling from outer HMdcSeg
354  // vers==2 : Input filling from inner+outer HMdcSeg (default)
355  // mod==0 : calc dedx from 1st module in segment
356  // mod==1 : calc dedx from 2nd module in segment
357  // mod==2 : calc dedx from whole segment (default)
358  // useTruncMean: kTRUE (default) apply truncated Mean
359  // truncMeanWindow (unit: SIGMA RMS of mean TOT): -99 (default) use standard window
360  // inputselect==0 : fill from segment (default, wires rejected by fit are missing)
361  // inputselect==1 : fill from cluster
362  // returns -99 if nothing was calculated
363 
364  //to be sure initialized values are returned
365  *meanold = -1.;
366  *sigmaold = -1.;
367  *nwire = 0;
368  *sigmanew = -1.;
369  *nwiretrunc= 0;
370  Float_t dedx = -99.;
371  Float_t mean = -99.;
372  Float_t sigma = -99.;
373  UChar_t nWire = 0;
374  UChar_t nWireTrunc = 0;
375 
376  if(!catcal ) return mean; // no cal1 data in input !
377 
378  if(!isInitialized) {
379  Error("HMdcDeDx2::calcDeDx()","Container HMdcDeDx2 has not been initialized!");
380  return mean;
381 
382  }
383  if(vers >= 0 && vers <= 2) method = vers;
384 
385  if(seg[0] == 0 && (method == 0 || method == 2))
386  {
387  Error("HMdcDeDx2::calcDeDx()","ZERO POINTER FOR inner HMdcSeg RECEIVED!");
388  return mean;
389  }
390  if(seg[1] == 0 && (method == 1))
391  {
392  return mean;
393  }
394 
395  if(mod >= 0 && mod < 3)
396  {
397  module = mod;
398  }
399  else
400  {
401  Warning("calcDeDx()","Unknown module type! Will use both modules of Segment!");
402  module = 2;
403  }
404 
405  //---------------------------------------------------
406  // getting input
407  measurements.Reset(-99);
408 
409  nWire = fillingInput(seg,inputselect);
410  if(debug) {
411  cout<<"calcDeDx() from fillingInput(): "
412  <<"nw " <<((Int_t)nWire)
413  <<" methode "<<method
414  <<" module " <<module
415  <<endl;
416  }
417  if(nWire == 0) return mean;
418 
419  *nwire = nWire;
420 
421  if(nWire > 0) mean = TMath::Mean(nWire,measurements.GetArray(), NULL);
422  *meanold = mean;
423  //---------------------------------------------------
424  // calculating sigma
425  if(nWire >= 1)
426  {
427  sigma = TMath::RMS(nWire,measurements.GetArray());
428  *sigmaold = sigma;
429  //--------------------truncating measurements outside +- x*sigma
430  if (useTruncMean) {
431  nWireTrunc = select(mean,sigma,nWire,truncMeanWindow);
432  } else {
433  sort(nWire);
434  nWireTrunc=nWire;
435  }
436  *nwiretrunc = nWireTrunc;
437  //--------------------calculating truncated mean
438  dedx = TMath::Mean(nWireTrunc,measurements.GetArray(), NULL);
439  //--------------------calculating new sigma
440  sigma = TMath::RMS(nWireTrunc,measurements.GetArray());
441  *sigmanew = sigma;
442 
443  }else{
444  Warning("calcDeDx()","nWire <=1 : skipped %i and %i with t2<=-998 !",
446  }
447 
448  //---------------------------------------------------
449  // now calibrate mean value of ToT to dEdX
450  Int_t s = 0;
451  if(seg[0]){
452  s = seg[0]->getSec();
453  }
454  dedx = toTTodEdX(s,ref_MOD,-1,-1,ref_ANGLE,ref_DIST,dedx);
455  if(dedx > 100000) {
456  if(debug){cout<<"calcDeDx() : dEdX>1000 -->"<<dedx<<endl;}
457  dedx = 100000.;
458  }
459  //---------------------------------------------------
460 
461  return dedx;
462 }
463 UChar_t HMdcDeDx2::fillingInput(HMdcSeg* seg[2],Int_t inputselect)
464 {
465  // Fills array of measurements from HMdcSeg and returns the number of fired wires in Segment
466  // The single measurements are normalized by impact angle and distance from wire. Only the first
467  // wires < MAX_WIRES are accepted.
468  // inputselect==0 : fill from segment (default,wires rejected by fit are missing)
469  // inputselect==1 : fill from cluster
470 
471  ctskipmod0 = 0;
472  ctskipmod1 = 0;
473 
474  Float_t t1,t2;
475  Double_t alpha,mindist;
476  Double_t x1,y1,z1,x2,y2,z2;
477 
478  UChar_t nWire = 0;
479 
480  if(!catcal ) return nWire; // no cal1 data in input !
481 
482  if(inputselect == 1 &&
483  (!cathit || !catclusinf || !catclus)
484  ) return nWire; // no cluster data in input !
485 
486  HMdcClus* clus[2] = {0};
487  //----------------------------------------getting input--------------------------------------------------
488  Int_t low = 0;
489  Int_t up = 2;
490 
491  if (method == 0) {low = 0;up = 1;} // inner seg
492  else if(method == 1) {low = 1;up = 2;} // outer seg
493  else if(method == 2) {low = 0;up = 2;} // both seg
494 
495  for(Int_t io = low; io < up; io ++)
496  {
497  if(seg[io] == 0) continue;
498 
499  //---------------------------------------------------------------------------
500  if(inputselect == 1)
501  {
502  // we have to get the cluster for looping
503  // the drift cells
504  for(Int_t ihit = 0; ihit < 2; ihit ++)
505  {
506  Int_t hitind = seg[io]->getHitInd(ihit);
507  if(hitind != -1)
508  { // hit and clusinf have the same index!
509  HMdcClusInf* clusinf = (HMdcClusInf*) catclusinf->getObject(hitind);
510  if(clusinf)
511  {
512  clus[io] = (HMdcClus*) catclus->getObject(clusinf->getClusIndex());
513  if(clus[io] == 0){
514  Error("fillingInput()","Zero pointer for HMdcClus object retrieved!");
515  return nWire;
516  }
517  }
518  else Error("fillingInput()","Zero pointer for HMdcClusInd object retrieved!");
519 
520  break; // found cluster -> exit the loop
521  }
522 
523  }
524  }
525  //---------------------------------------------------------------------------
526 
527 
528  for(Int_t l = 0; l < 12; l ++)
529  {
530  if(module == 0 && l > 5) continue; // fill for 1st module only
531  if(module == 1 && l < 6) continue; // fill for 2st module only
532 
533  Int_t nCell = 0;
534  // input selection
535  if(inputselect == 1){nCell = clus[io]->getNCells(l);}
536  else {nCell = seg [io]->getNCells(l);}
537 
538  loccal[0] = seg[io]->getSec();
539  Int_t ioseg = seg[io]->getIOSeg();
540 
541  for(Int_t i = 0; i < nCell; i ++)
542  {
543  if(ioseg == 0){
544  (l < 6)? loccal[1] = 0 : loccal[1] = 1;
545  }else if(ioseg == 1){
546  (l < 6)? loccal[1] = 2 : loccal[1] = 3;
547  }
548  (l < 6)? loccal[2] = l : loccal[2] = l - 6;
549 
550  // input selection
551  if(inputselect == 1){loccal[3] = clus[io]->getCell(l,i);}
552  else {loccal[3] = seg [io]->getCell(l,i);}
553 
554  calcSegPoints(seg[io],x1,y1,z1,x2,y2,z2);
555  (*sizescells)[loccal[0]][loccal[1]][loccal[2]].getImpact(x1,y1,z1,x2,y2,z2,loccal[3],alpha,mindist);
556 
557  HMdcCal1* cal1 = (HMdcCal1*)catcal->getObject(loccal);
558  if(cal1 != 0)
559  {
560  t1 = cal1->getTime1();
561  t2 = cal1->getTime2();
562 
563  if(t2 != -998 && t2 != -999 &&
564  t1 != -998 && t1 != -999 &&
565  TMath::Finite(t1) &&
566  TMath::Finite(t2) &&
567 
568  mindist<=parmindistcut[loccal[1]]
569  )
570  { // some times t1 or t2 can be missing (-999,-998)
571  // calculating mean value
572 
573  if(nWire < MAX_WIRES - 1)
574  {
575  if(useCalibration)measurements[nWire] = normalize(loccal[0],loccal[1],loccal[2],loccal[3],alpha,mindist,t2-t1);
576  else measurements[nWire] = t2-t1;
577  nWire ++;
578  }else{
579  if(debug) Warning("fillingInput()","Number of wires in Segment=%i > MAX_WIRES = %i! Skipped!",nWire,MAX_WIRES);
580  }
581  } else {
582  if(loccal[1] == 0 || loccal[1] == 2) ctskipmod0 ++;
583  if(loccal[1] == 1 || loccal[1] == 3) ctskipmod1 ++;}
584  }else{
585  Warning("calcDeDx()","ZERO pointer recieved for cal1 object!");
586  }
587  }
588  }
589  }
590  return nWire;
591 }
592 
593 UChar_t HMdcDeDx2::select(Float_t mean,Float_t sigma,UChar_t nWire,Float_t wind)
594 {
595  // loops over the measurement array with nWire values and puts values to
596  // -99 if the measurements are outside the wanted window arround the mean value mean
597  // (set with setWindow() (sigma units)).
598  // The procedure keeps at least a number of minimum wires set with setMinimumWires().
599 
600  UChar_t nWTrunc = nWire;
601  UChar_t count = 0;
602  UChar_t minW = (UChar_t)getMinimumWires();
603 
604  if(nWTrunc < minW)
605  {
606  if(debug){cout<<"select : skipp because nWT<minW "<<endl;}
607  return nWTrunc;
608  }
609 
610  //---------------------------------------------------
611  // decide about the window for truncated Mean method
612  Float_t tempWindow = getWindow();
613  if(wind > 0) tempWindow = wind;
614  //---------------------------------------------------
615 
616  //--------------------sorting measurements in decreasing order
617  sort(nWire);
618  if(debug){
619  cout<<"---------------------------------------------------"<<endl;
620  cout<<"measurements before truncation :"<<endl;
621  for(Int_t i = 0; i < nWire; i ++){
622  cout<<i<<" "<<measurements[i]<<endl;
623  }
624  }
625 
626  Bool_t fail_high = kFALSE;
627  Bool_t fail_low = kFALSE;
628 
629  while(nWTrunc > minW &&
630  count < nWire )
631  {
632  //------------------------------------------------------------
633  // starting from highest val
634  if(!fail_high && fabs(measurements[count] - mean) > (tempWindow * sigma))
635  { // if measurement outside the window
636  measurements[count] = -99;
637  nWTrunc --;
638  } else fail_high = kTRUE;
639  //------------------------------------------------------------
640 
641  //------------------------------------------------------------
642  // taking lowest val next
643  if(nWTrunc > minW)
644  {
645  if(!fail_low && fabs(measurements[nWire - 1 - count] - mean) > (tempWindow * sigma))
646  { // if measurement outside the window
647  measurements[nWire - 1 - count] = -99;
648  nWTrunc --;
649  }
650  else fail_low = kTRUE;
651  } else fail_low = kTRUE;
652  //------------------------------------------------------------
653  count ++;
654  if(fail_low && fail_high) break;
655  }
656  sort(nWire);
657 
658  if(debug){
659  cout<<"---------------------------------------------------"<<endl;
660  cout<<"measurements after truncation :"<<endl;
661  for(Int_t i = 0; i < nWTrunc; i ++){
662  cout<<i<<" "<<measurements[i]<<endl;
663  }
664  cout<<"method " <<method
665  <<" window " <<tempWindow
666  <<" mean " <<mean
667  <<" meanN " <<TMath::Mean(nWTrunc,measurements.GetArray())
668  <<" sig " <<sigma
669  <<" sigN " <<TMath::RMS(nWTrunc,measurements.GetArray())
670  <<" w " <<((Int_t)nWire)
671  <<" trunc w "<<((Int_t)nWTrunc)
672  <<endl;
673  }
674 
675  return nWTrunc;
676 
677 }
678 void HMdcDeDx2::setFuncPar(Int_t s,Int_t m,Int_t abin,Int_t dbin,Double_t* p,Int_t size)
679 {
680  // set the values for the dedx functions by s, m, angle bin, dist bin. Needs pointer
681  // to parameter array[N_PARAM]
682  if(size == N_PARAM &&
683  abin >= 0 && abin < N_ANGLE &&
684  dbin >= 0 && dbin < N_DIST &&
685  s >= 0 && s < 6 &&
686  m >= 0 && m < 4){
687  for(Int_t i = 0; i < size; i ++) par[s][m][abin][dbin][i] = p[i];
688  } else Error("SetFuncPar(...)","array indices out of range!");
689 }
690 void HMdcDeDx2::setFuncPar(Double_t* p)
691 {
692  // set all values for the dedx functions. Needs pointer
693  // to parameter array[6][4][N_ANGLE][N_DIST][N_PARAM]
694  for(Int_t s = 0; s < 6;s ++) {
695  for(Int_t m = 0; m < 4; m ++) {
696  for(Int_t a = 0; a < N_ANGLE; a ++) {
697  for(Int_t d = 0; d < N_DIST; d ++) {
698  for(Int_t i = 0; i < N_PARAM; i ++) {
699 
700  Int_t maxS = 4 * N_ANGLE * N_DIST * N_PARAM;
701  Int_t maxM = N_ANGLE * N_DIST * N_PARAM;
702  Int_t maxA = N_DIST * N_PARAM;
703 
704  par[s][m][a][d][i] = p[s * maxS + m * maxM + a * maxA + d * N_PARAM + i];
705  }
706  }
707  }
708  }
709  }
710 }
711 void HMdcDeDx2::getFuncPar(Double_t* p)
712 {
713  // set all values for the dedx functions. Needs pointer
714  // to parameter array[6][4][N_ANGLE][N_DIST][N_PARAM]
715  for(Int_t s = 0;s < 6; s ++) {
716  for(Int_t m = 0; m < 4; m ++) {
717  for(Int_t a = 0; a < N_ANGLE; a ++) {
718  for(Int_t d = 0; d < N_DIST; d ++) {
719  for(Int_t i = 0; i < N_PARAM; i ++) {
720 
721  Int_t maxS = 4 * N_ANGLE * N_DIST * N_PARAM;
722  Int_t maxM = N_ANGLE * N_DIST * N_PARAM;
723  Int_t maxA = N_DIST * N_PARAM;
724 
725  p[s * maxS + m * maxM + a * maxA + d * N_PARAM + i] = par[s][m][a][d][i];
726  }
727  }
728  }
729  }
730  }
731 }
732 void HMdcDeDx2::setFuncMaxPar(Int_t s,Int_t m,Int_t abin,Int_t dbin,Double_t p)
733 {
734  // set the values for the dedx functions by s, m, angle bin, dist bin.
735  if(abin >= 0 && abin < N_ANGLE &&
736  dbin >= 0 && dbin < N_DIST &&
737  s >= 0 && s < 6 &&
738  m >= 0 && m < 4){
739  parMax[s][m][abin][dbin] = p;
740  } else Error("SetFuncPar(...)","array indices out of range!");
741 }
742 void HMdcDeDx2::setFuncMaxPar(Double_t* p)
743 {
744  // set all values for the dedx functions. Needs pointer
745  // to parameter array[6][4][N_ANGLE][N_DIST]
746  for(Int_t s = 0; s < 6; s ++) {
747  for(Int_t m = 0; m < 4; m ++) {
748  for(Int_t a = 0; a < N_ANGLE; a ++) {
749  for(Int_t d = 0; d < N_DIST;d ++) {
750  Int_t maxS = 4 * N_ANGLE * N_DIST;
751  Int_t maxM = N_ANGLE * N_DIST;
752  Int_t maxA = N_DIST;
753 
754  parMax[s][m][a][d] = p[s * maxS + m * maxM + a * maxA + d];
755  }
756  }
757  }
758  }
759 }
760 void HMdcDeDx2::getFuncMaxPar(Double_t* p)
761 {
762  // set all values for the dedx functions. Needs pointer
763  // to parameter array[6][4][N_ANGLE][N_DIST]
764  for(Int_t s = 0; s < 6; s ++) {
765  for(Int_t m = 0; m < 4; m ++) {
766  for(Int_t a = 0; a < N_ANGLE; a ++) {
767  for(Int_t d = 0; d <N_DIST; d ++) {
768  Int_t maxS = 4 * N_ANGLE * N_DIST;
769  Int_t maxM = N_ANGLE * N_DIST;
770  Int_t maxA = N_DIST;
771 
772  p[s * maxS + m * maxM + a * maxA + d] = parMax[s][m][a][d];
773  }
774  }
775  }
776  }
777 }
778 
779 void HMdcDeDx2::setFuncWidthPar(Int_t s,Int_t m,Int_t abin,Int_t dbin,Double_t* p,Int_t size)
780 {
781  // set the values fpr the dedx width functions by s, m, angle bin, dist bin. Needs pointer
782  // to parameter array[N_SHIFT_PARAM]
783 
784  if(size == N_SHIFT_PARAM &&
785  abin >= 0 && abin < N_ANGLE&&
786  dbin >= 0 && dbin < N_DIST &&
787  s >= 0 && s < 6 &&
788  m >= 0 && m < 4){
789  for(Int_t i = 0; i < size; i ++) shiftpar[s][m][abin][dbin][i] = p[i];
790  } else Error("SetFuncPar(...)","array indices out of range!");
791 }
792 void HMdcDeDx2::setFuncWidthPar(Double_t* p)
793 {
794  // set all values for the dedx width functions. Needs pointer
795  // to parameter array[6][4][N_ANGLE][N_DIST][N_SHIFT_PARAM]
796  for(Int_t s = 0;s < 6; s ++) {
797  for(Int_t m = 0; m < 4; m ++) {
798  for(Int_t a = 0; a < N_ANGLE; a ++) {
799  for(Int_t d = 0; d < N_DIST; d ++) {
800  for(Int_t i = 0; i < N_SHIFT_PARAM; i ++) {
801 
802  Int_t maxS = 4 * N_ANGLE * N_DIST * N_SHIFT_PARAM;
803  Int_t maxM = N_ANGLE * N_DIST * N_SHIFT_PARAM;
804  Int_t maxA = N_DIST * N_SHIFT_PARAM;
805 
806  shiftpar[s][m][a][d][i] = p[s * maxS + m * maxM + a * maxA + d * N_SHIFT_PARAM + i];
807  }
808  }
809  }
810  }
811  }
812 }
813 void HMdcDeDx2::getFuncWidthPar(Double_t* p)
814 {
815  // set all values for the dedx width functions. Needs pointer
816  // to parameter array[6][4][N_ANGLE][N_DIST][N_SHIFT_PARAM]
817  for(Int_t s = 0; s < 6; s ++) {
818  for(Int_t m = 0; m < 4; m ++) {
819  for(Int_t a = 0; a < N_ANGLE; a ++) {
820  for(Int_t d = 0; d < N_DIST; d ++) {
821  for(Int_t i = 0; i < N_SHIFT_PARAM; i ++) {
822 
823  Int_t maxS = 4 * N_ANGLE * N_DIST * N_SHIFT_PARAM;
824  Int_t maxM = N_ANGLE * N_DIST * N_SHIFT_PARAM;
825  Int_t maxA = N_DIST * N_SHIFT_PARAM;
826 
827  p[s * maxS + m * maxM + a * maxA + d * N_SHIFT_PARAM + i] = shiftpar[s][m][a][d][i];
828  }
829  }
830  }
831  }
832  }
833 }
834 
835 void HMdcDeDx2::setFuncGainPar(Int_t s,Int_t m,Int_t l,Int_t c,Double_t p)
836 {
837  // set the values for the gain corrections by s, m, l, c.
838  if(c >= 0 && c < 220 &&
839  l >= 0 && l < 6 &&
840  s >= 0 && s < 6 &&
841  m >= 0 && m < 4){
842  pargaincorr[s][m][l][c] = p;
843  } else Error("SetGainPar(...)","array indices out of range!");
844 }
845 void HMdcDeDx2::setFuncGainPar(Double_t* p)
846 {
847  // set all values for the gain correction. Needs pointer
848  // to parameter array[6][4][6][220]
849  for(Int_t s = 0; s < 6; s ++) {
850  for(Int_t m = 0; m < 4; m ++) {
851  for(Int_t l = 0; l < 6; l ++) {
852  for(Int_t c = 0; c < 220;c ++) {
853  Int_t maxS = 4 * 6 * 220;
854  Int_t maxM = 6 * 220;
855  Int_t maxL = 220;
856 
857  pargaincorr[s][m][l][c] = p[s * maxS + m * maxM + l * maxL + c];
858  }
859  }
860  }
861  }
862 }
863 void HMdcDeDx2::getFuncGainPar(Double_t* p)
864 {
865  // set all values for the gain correction. Needs pointer
866  // to parameter array[6][4][6][220]
867  for(Int_t s = 0; s < 6; s ++) {
868  for(Int_t m = 0; m < 4; m ++) {
869  for(Int_t l = 0; l < 6; l ++) {
870  for(Int_t c = 0; c < 220;c ++) {
871  Int_t maxS = 4 * 6 * 220;
872  Int_t maxM = 6 * 220;
873  Int_t maxL = 220;
874 
875  p[s * maxS + m * maxM + l * maxL + c] = pargaincorr[s][m][l][c];
876  }
877  }
878  }
879  }
880 }
881 
882 void HMdcDeDx2::setMinDistCutPar(Int_t m,Double_t p)
883 {
884  // set the values for the cut on minDist by m.
885  if(m >= 0 && m < 4){
886  parmindistcut[m] = p;
887  } else Error("SetMinDistCutPar(...)","array indices out of range!");
888 }
890 {
891  // set all values for the minDistcut. Needs pointer
892  // to parameter array[4]
893  for(Int_t m = 0; m < 4; m ++) {
894 
895  parmindistcut[m] = p[m];
896  }
897 }
899 {
900  // set all values for the minDistcut. Needs pointer
901  // to parameter array[4]
902  for(Int_t m = 0; m < 4; m ++) {
903 
904  p[m] = parmindistcut[m];
905  }
906 }
907 
908 Double_t HMdcDeDx2::calcLength(Int_t m,Double_t angle,Double_t dist)
909 {
910  // calc max length of track in cell for given module
911  // m (0-3), impact angle "angle" [Deg] and distance
912  // from wire "dist" [mm]
913 
914  Double_t maxLength;
915  Double_t yU,xU,yL,xL;
916  Double_t alphaRad,tanAlpha,b;
917  Double_t cellX[4];
918  Double_t cellY[4];
919 
920  Double_t cX[4] = {2.5,3.0,6.0,7.0};
921  Double_t cY[4] = {2.5,2.5,4.0,5.0};
922  for(Int_t i=0;i<4;i++){
923  cellX[i] = cX[i];
924  cellY[i] = cY[i];
925  }
926 
927  alphaRad = angle * TMath::DegToRad();// angle of Curve
928  b = dist / cos(alphaRad);
929  tanAlpha = tan(alphaRad);
930  if(angle > 0) {
931  xU = (cellY[m] - b) / tanAlpha;
932  if(xU <= cellX[m]) {
933  yU = cellY[m];
934  } else {
935  yU = tanAlpha * cellX[m] + b;
936  xU = cellX[m];
937  }
938 
939  xL = (-cellY[m] - b) / tanAlpha;
940  if(xL >= -cellX[m]) {
941  yL = -cellY[m];
942  } else {
943  yL = tanAlpha * -cellX[m] + b;
944  xL = -cellX[m];
945  }
946 
947  maxLength = sqrt( (xU - xL) * (xU - xL) + (yU - yL) * (yU - yL) );
948  } else {
949  yU = 0;
950  xU = 0;
951  yL = 0;
952  xL = 0;
953  maxLength = 2 * cellX[m];
954  }
955 
956  return maxLength ;
957 }
958 
959 
960 void HMdcDeDx2::calcSegPoints(HMdcSeg * seg,Double_t& x1, Double_t& y1, Double_t& z1, Double_t& x2, Double_t& y2, Double_t& z2)
961 {
962  // calculates 2 coordinate points from segment
963 
964  Double_t teta = seg->getTheta();
965  Double_t phi = seg->getPhi();
966  Double_t z = seg->getZ();
967  Double_t r = seg->getR();
968  Double_t pi2 = acos(-1.)/2.;
969 
970  Double_t X = r * cos(phi + pi2);
971  Double_t Y = r * sin(phi + pi2);
972  Double_t Z = z;
973 
974  x1 = X;
975  y1 = Y;
976  z1 = Z;
977  x2 = X + cos(phi) * sin(teta);
978  y2 = Y + sin(phi) * sin(teta);
979  z2 = Z + cos(teta);
980 
981 }
982 
983 void HMdcDeDx2::findBin(Int_t m,Double_t* angle,Double_t* mindist,Int_t* abin,Int_t* dbin)
984 {
985  Double_t a =* angle;
986  Double_t d =* mindist;
987 
988  if(d>MaxMdcMinDist[m]) d = MaxMdcMinDist[m];
989  if(a > 90) a = 90.;
990  if(a < 0) a = 0.;
991 
992  (*abin) = (Int_t)((90. - a) / AngleStep);
993  (*dbin) = (Int_t)(d / MinDistStep[m]);
994 
995  if((*abin) == 18) (*abin) = 17;
996  if((*dbin) == N_DIST) (*dbin) = N_DIST - 1;
997 
998 }
999 
1000 Double_t HMdcDeDx2::toTSigma(Int_t s,Int_t m,Double_t angle,Double_t mindist,Int_t shift)
1001 {
1002  // returns asymmetric width of ToT for single drift cell
1003  // shift == 0 (default) : returns 0
1004  // ==-1 : low bound width of ToT distribution (sigma)
1005  // == 1 : upper bound width of ToT distribution (sigma)
1006 
1007  Int_t abin = 0;
1008  Int_t dbin = 0;
1009 
1010  findBin(m,&angle,&mindist,&abin,&dbin);
1011 
1012  // shift is half FWHM = 2.355/2=1.1775 sigma
1013  // we have to recalulate sigma here
1014 
1015  if (shift < 0) return (shiftpar[s][m][abin][dbin][0] / 1.1775);
1016  else if (shift > 0) return (shiftpar[s][m][abin][dbin][1] / 1.1775);
1017  else return 0.;
1018 }
1019 
1020 Double_t HMdcDeDx2::toTTodEdX(Int_t s,Int_t m,Int_t l,Int_t c,Double_t angle,Double_t mindist,Double_t ToT)
1021 {
1022  // calculation of ToT -> dEdX for single drift cell
1023 
1024  Int_t abin = 0;
1025  Int_t dbin = 0;
1026 
1027  findBin(m,&angle,&mindist,&abin,&dbin);
1028 
1029  Double_t* p= &par[s][m][abin][dbin][0];
1030 
1031  //-----------------------------------------------------
1032  Double_t ToTgaincorr = ToT;
1033  Double_t ToTcorr = ToT;
1034 
1035  if(l > -1 && c > -1){
1036 
1037  ToTgaincorr = ToT + pargaincorr[s][m][l][c];
1038  ToTcorr = ToTgaincorr/calcLength(m,angle,mindist);
1039  }
1040 
1041  if(ToTcorr > parMax[s][m][abin][dbin]) ToTcorr = parMax[s][m][abin][dbin];
1042 
1043  Double_t dEdX = TMath::Power(10.,(TMath::Power((ToTcorr - p[0]) / p[1],(1. / p[2])))) - p[3];
1044  if(!TMath::Finite(dEdX)){
1045  Warning("totTodEdX()","dEdX out of range: s %i m %i abin %i dbin %i ToT %1.15e dEdX %1.15e !",s,m,abin,dbin,ToTcorr,dEdX);
1046  dEdX = -1;
1047  }
1048  return dEdX;
1049 }
1050 Double_t HMdcDeDx2::dEdXToToT(Int_t s,Int_t m,Int_t l,Int_t c,Double_t angle,Double_t mindist,Double_t dEdX)
1051 {
1052  // calculation of dEdX -> ToT for single drift cell
1053 
1054  Int_t abin = 0;
1055  Int_t dbin = 0;
1056 
1057  findBin(m,&angle,&mindist,&abin,&dbin);
1058 
1059  Double_t* p = &par[s][m][abin][dbin][0];
1060 
1061  Double_t ToT = p[0] + p[1] * TMath::Power((TMath::Log10(dEdX + p[3])),p[2]);
1062  Double_t ToTcorr = ToT;
1063 
1064  if(l > -1 && c > -1){
1065  ToTcorr = ToT*calcLength(m,angle,mindist);
1066  ToTcorr = ToTcorr - pargaincorr[s][m][l][c];
1067  }
1068 
1069  if(!TMath::Finite(ToTcorr)){
1070  Warning("dEdXToToT()","ToT out of range: s %i m %i abin %i dbin %i ToT %1.15e dEdX %1.15e !",s,m,abin,dbin,ToTcorr,dEdX);
1071  ToTcorr = -1;
1072  }
1073 
1074  return ToTcorr;
1075 }
1076 Double_t HMdcDeDx2::normalize(Int_t s,Int_t m,Int_t l,Int_t c,Double_t angle,Double_t mindist,Double_t ToT)
1077 {
1078  // calibrate ToT :
1079  // dEdX=TotTodEdX(t2-t1) ----> dEdXToToT(dEdX) for reference module,angle,distbin
1080  if(ToT < 0) return ToT;
1081  Double_t dEdX = toTTodEdX(s,m,l,c,angle,mindist,ToT);
1082  if(dEdX >= 0) ToT = dEdXToToT(s,ref_MOD,-1,-1,ref_ANGLE,ref_DIST,dEdX);
1083 
1084  return ToT;
1085 }
1086 
1087 
1088 
1089 //----------------------dEdx-----------------------------------------------
1090 Double_t HMdcDeDx2::beta(Int_t id,Double_t p)
1091 {
1092  Double_t mass = HPhysicsConstants::mass(id);
1093  if(mass == 0) return -1;
1094  return sqrt(1. / (((mass*mass)/(p*p)) + 1.));
1095 }
1096 TGraph* HMdcDeDx2::betaGraph(Int_t id,Int_t opt,Int_t markerstyle,Int_t markercolor,Float_t markersize)
1097 {
1098  // creates a TGraph for particle with GEANT ID id and
1099  // momentum p
1100  // opt = 1 : no exchange x-axis and y-axis
1101  // -1 : take -p
1102  // 2 : exchange axis
1103  // -2 : -p + exchange axis
1104 
1105  if(opt<-2||opt>2||opt==0){
1106  ::Error("betaGraph()","Unknown Option opt=%i!. Use default opt=1",opt);
1107  opt=1;
1108  }
1109 
1110  Double_t pmin = 50;
1111  Double_t pmax = 100000.;
1112  Int_t np = 100;
1113 
1114  Double_t ptot = 0;
1115  Double_t xarray[np];
1116  Double_t yarray[np];
1117 
1118 
1119  for(Int_t i = 1; i <= np; i ++)
1120  {
1121  ptot = pmin * pow((pmax / pmin),(i - 1) / (Double_t)(np - 1.));
1122  xarray[i - 1] = (opt == -1 || opt == -2)? -ptot : ptot;
1123  yarray[i - 1] = HMdcDeDx2::beta(id,ptot);
1124  }
1125  Char_t name[300];
1126  sprintf(name,"beta_%s",HPhysicsConstants::pid(id));
1127  TGraph* g = 0;
1128  if(opt==1||opt==-1)g = new TGraph(np,xarray,yarray);
1129  else g = new TGraph(np,yarray,xarray);
1130  g->SetName(name);
1131  g->SetMarkerStyle(markerstyle);
1132  g->SetMarkerSize (markersize);
1133  g->SetMarkerColor(markercolor);
1134 
1135  return g;
1136 }
1137 
1138 Double_t HMdcDeDx2::gamma(Int_t id,Double_t p)
1139 {
1140  Double_t mass = HPhysicsConstants::mass(id);
1141  if(mass == 0) return -1;
1142  Double_t beta2 = 1. / (((mass*mass)/(p*p)) + 1.);
1143  return sqrt(1./ (1 - beta2));
1144 }
1145 
1146 Double_t HMdcDeDx2::energyLoss(Int_t id,Double_t p,Double_t hefr)
1147 {
1148  // Calculates the dEdx (MeV 1/g cm2) of an particle with GEANT ID id
1149  // and momentum p (MeV) for He/i-butan gas mixture with He fraction hefr
1150  // (He (hefr) / i-butan (1-hefr)). The fomular is taken from PDG and doesn't
1151  // include the density correction term. The values for the mean excitation
1152  // energy are taken from Sauli.
1153 
1154  if(p == 0) return -1;
1155  if(hefr < 0. || hefr > 1.) return -1;
1156  Double_t mass = HPhysicsConstants::mass(id);
1157  if(mass == 0) return -1;
1158 
1159  // keep function value inside boundary
1160  if (mass < 150 && p < 5 ) p = 5 ;
1161  else if (mass >= 150 && mass < 1000 && p < 20) p = 20;
1162  else if (mass >= 1000 && mass < 2000 && p < 35) p = 35;
1163  else if (mass >= 2000 && p < 55) p = 55;
1164 
1165  // Z and A
1166  Double_t Z_gas = 2. * hefr + (1. - hefr) * 34.;
1167  Double_t A_gas = 4. * hefr + (1. - hefr) * 58.;
1168  // I_0 and I
1169  Double_t I_0_gas = 24.6 * hefr + (1. - hefr) * 10.8;
1170  Double_t I2 = pow(I_0_gas * Z_gas * (1.e-6),2); // sauli
1171  //Double_t I2 =pow(16. * pow(Z_gas,0.9),2); //C.Lippmann thesis
1172 
1173 
1174  Double_t K = 0.307075; // MeV cm2 PDG, 4 * pi * N_{A} * r_{e}2 * m_{e}2 * c2
1175  Double_t mass2 = pow(mass,2);
1176  Double_t m_ec2 = HPhysicsConstants::mass(3);
1177  Double_t z2 = pow((Float_t)HPhysicsConstants::charge(id),2);
1178  Double_t p2 = pow(p,2);
1179  Double_t beta2 = 1. / ((mass2/p2) + 1.);
1180  Double_t gamma2 = 1./ (1 - beta2);
1181  Double_t gamma = sqrt(gamma2);
1182 
1183  Double_t Tmax = (2. * m_ec2 * beta2 * gamma2) / (1. + 2.* gamma * (m_ec2 / mass) + pow((m_ec2 / mass),2));
1184  Double_t term1 = K * z2 * (Z_gas / A_gas) * (1. / beta2);
1185  Double_t term2 = ((2. * m_ec2 * beta2 * gamma2 * Tmax) / I2);
1186  Double_t dedx = term1 * (0.5 * log(term2) - beta2);
1187 
1188  return dedx;
1189 }
1190 TGraph* HMdcDeDx2::energyLossGraph(Int_t id,Double_t hefr,TString opt,Bool_t exchange,Int_t markerstyle,Int_t markercolor,Float_t markersize)
1191 {
1192  // creates a TGraph for particle with GEANT ID id and
1193  // and He/i-butan gas mixture with He fraction hefr
1194  // (He (hefr) / i-butan (1-hefr) dEdx vs p,beta,1/beta2 or betagamma
1195  // depending on opt (p,beta,1/beta2,betagamma). exchange=kTRUE
1196  // will exchange x-axis and y-axis.
1197 
1198 
1199  Double_t pmin = 50;
1200  Double_t pmax = 100000.;
1201  Int_t np = 100;
1202 
1203  Double_t ptot = 0;
1204  Double_t xarray[np];
1205  Double_t yarray[np];
1206 
1207  Int_t vers = 0;
1208  Double_t mass = HPhysicsConstants::mass(id);
1209 
1210 
1211  if(opt.CompareTo("p" ) == 0) vers = 0;
1212  else if(opt.CompareTo("beta" ) == 0) vers = 1;
1213  else if(opt.CompareTo("1/beta2" ) == 0) vers = 2;
1214  else if(opt.CompareTo("betagamma") == 0) vers = 3;
1215  else {cout<<"HMdcDedx::calcDeDxGraph():unknow option!"<<endl;}
1216 
1217  for(Int_t i = 1; i <= np; i ++)
1218  {
1219  ptot = pmin * pow((pmax / pmin),(i - 1) / (Double_t)(np - 1.));
1220  if(vers == 0){xarray[i - 1] = ptot;}
1221  if(vers == 1){xarray[i - 1] = sqrt(1. / ((pow(mass,2) / pow(ptot,2)) + 1.));}
1222  if(vers == 2){xarray[i-1] = ((pow(mass,2) / pow(ptot,2)) + 1.);}
1223  if(vers == 3){xarray[i-1] = (ptot / mass);}
1224  yarray[i - 1] = HMdcDeDx2::energyLoss(id,ptot,hefr);
1225  }
1226  Char_t name[300];
1227  sprintf(name,"dedx_%s_He_%5.1f_ibutane_%5.1f",HPhysicsConstants::pid(id),hefr * 100,(1 - hefr) * 100);
1228  TGraph* g = 0;
1229  if(!exchange)g = new TGraph(np,xarray,yarray);
1230  else g = new TGraph(np,yarray,xarray);
1231  g->SetName(name);
1232  g->SetMarkerStyle(markerstyle);
1233  g->SetMarkerSize (markersize);
1234  g->SetMarkerColor(markercolor);
1235 
1236  return g;
1237 }
1239  Double_t p,
1240  Float_t t1, Float_t t2, Float_t* t2err,
1241  Int_t s,Int_t m,Int_t l,Int_t c,
1242  Double_t alpha,Double_t mindist)
1243 {
1244  // calculated the t2 of drift cell measurent
1245  // from dedx of a given particle with momentum p.
1246  // The assumption is that all drift cell measurements
1247  // belonging to one track can be treated independent.
1248  // return t2 and smeared error to pointer t2err for an
1249  // single measurement. If the result t2-t1 would
1250  // be < 0 a random value for t2 0-20 ns larger than
1251  // t1(already including error) will be created.
1252  // The smeared error will be returned to the pointer t2err.
1253 
1254 
1255  //------------------------------------------------
1256  // check input
1257  if(!kine) {
1258  Error("caledTimeAboveThreshold()","retrieved ZERO pointer for kine object!");
1259  return -99;
1260  }
1261  if(p < 0) {
1262  Error("caledTimeAboveThreshold()","momentum = %5.3f is wrong!",p);
1263  return -99;
1264  }
1265  if(t1 < -997) {
1266  Error("caledTimeAboveThreshold()","t1 = %5.3f is wrong!",t1);
1267  return -99;
1268  }
1269  if(t2 < -997) {
1270  Error("caledTimeAboveThreshold()","t2 = %5.3f is wrong!",t1);
1271  return -99;
1272  }
1273  //------------------------------------------------
1274 
1275  //------------------------------------------------
1276  // get particle ID from kine object
1277  Int_t pTr = -1,pID = 0;
1278  kine->getParticle(pTr,pID);
1279  //------------------------------------------------
1280 
1281 
1282  //------------------------------------------------
1283  // get mass and charge of particle for dedx
1284  // calculation
1285  Double_t mass = HPhysicsConstants::mass (pID);
1286  Int_t charge = HPhysicsConstants::charge(pID);
1287 
1288 
1289  if(charge == 0 || mass == 0)
1290  {
1291  Warning("HMdcDeDx2::scaledEnergyLoss()","id %i %s mass %7.5f charge %i p %7.5f skipped!"
1292  ,pID,HPhysicsConstants::pid(pID),mass,charge,p);
1293  return t2;
1294  }
1295  //------------------------------------------------
1296 
1297  //------------------------------------------------
1298  // calulate analytical dedx of particle
1299 
1300  Double_t dedx = energyLoss(pID,p,getHeFraction());
1301 
1302  if(!TMath::Finite(dedx)){
1303  Error("scaledTimeAboveThreshold()","dedx either NaN or Inf!");
1304  return t2;
1305  }
1306  //------------------------------------------------
1307 
1308  //------------------------------------------------
1309  // recalculate dedx to mean value of Time over
1310  // threshold for the given drift chamber
1311  Double_t ToTmean = dEdXToToT(s,m,l,c,alpha,mindist,dedx);
1312 
1313  if(!TMath::Finite(ToTmean) || dedx < 0){
1314  Error("caledTimeAboveThreshold()","ToT either NaN or Inf!");
1315  cout<<"s " <<s
1316  <<" m " <<m
1317  <<" angle " <<alpha
1318  <<" dist " <<mindist
1319  <<" dedx " <<dedx
1320  <<" pid " <<pID
1321  <<" mass " <<mass
1322  <<" charge "<<charge
1323  <<" mom " <<p
1324  <<" t1 " <<t1
1325  <<" t2 " <<t2
1326  <<endl;
1327 
1328  return t2;
1329  }
1330  //------------------------------------------------
1331 
1332  //------------------------------------------------
1333  // generate some realistic smearing arround
1334  // the ToT mean value for single measurement
1335  // The distribution of ToT is asymmetric.
1336  // the smearing has to be done for left and right half
1337  // different.
1338 
1339  Double_t length = calcLength(m,alpha,mindist);
1340  Double_t sigL = toTSigma (s,m,alpha,mindist,-1)*length;
1341  Double_t sigR = toTSigma (s,m,alpha,mindist, 1)*length;
1342 
1343  Double_t smear;
1344  if(gRandom->Rndm() > 0.5){
1345  smear = TMath::Abs(gRandom->Gaus(0., sigR));
1346  } else{
1347  smear = -TMath::Abs(gRandom->Gaus(0., sigL));
1348  }
1349  if(t2err) * t2err = smear;
1350  //------------------------------------------------
1351 
1352 
1353  //------------------------------------------------
1354  // return t2 mean of an single measurement. If the
1355  // result t2-t1 would be < 0 a random value for
1356  // t2 0-20 ns larger than t1 will be created.
1357  t2 = ToTmean + t1;
1358  if(t2 <= t1){
1359  t2 = t1 + gRandom->Rndm() * 20.;
1360  }
1361  if(debug){
1362  cout<<"scaledEnergyLoss() "
1363  <<" s " <<s
1364  <<" m " <<m
1365  <<" a " <<alpha
1366  <<" d " <<mindist
1367  <<" id " <<pID
1368  <<" mass " <<mass
1369  <<" charge "<<charge
1370  <<" mom " <<p
1371  <<" dedx " <<dedx
1372  <<" t1 " <<t1
1373  <<" t2 " <<t2
1374  <<" t2err " <<smear
1375  <<" tot " <<ToTmean
1376  <<" sigL " <<sigL
1377  <<" sigR " <<sigR
1378  <<endl;
1379  }
1380 
1381  return t2;
1382 }
1383 
void sort(Int_t)
kTRUE print infos of trun mean
Definition: hmdcdedx2.cc:302
Float_t window
Definition: hmdcdedx2.h:44
Int_t getNCells(Int_t lay, Int_t layEnd=-1) const
Int_t method
flag after init
Definition: hmdcdedx2.h:54
static Int_t charge(const Int_t id)
Double_t calcLength(Int_t m, Double_t angle, Double_t dist)
Definition: hmdcdedx2.cc:908
Int_t getIOSeg(void) const
Definition: hmdcseg.h:139
Double_t getFuncMaxPar(Int_t s, Int_t m, Int_t abin, Int_t dbin)
Definition: hmdcdedx2.h:98
Double_t par[6][4][N_ANGLE][N_DIST][N_PARAM]
Definition: hmdcdedx2.h:31
Bool_t isInitialized
location object of cal1
Definition: hmdcdedx2.h:53
static TGraph * energyLossGraph(Int_t id, Double_t hefr=0.6, TString opt="p", Bool_t exchange=kFALSE, Int_t markerstyle=8, Int_t markercolor=2, Float_t markersize=0.7)
Definition: hmdcdedx2.cc:1190
#define ref_DIST
Definition: hmdcdedx2.h:26
HCategory * catclusinf
pointer to mdc hit
Definition: hmdcdedx2.h:49
static Double_t energyLoss(Int_t id, Double_t p, Double_t hefr=0.6)
Definition: hmdcdedx2.cc:1146
const Cat_t catMdcCal1
Definition: hmdcdef.h:7
Double_t parmindistcut[4]
Definition: hmdcdedx2.h:36
void setMinDistCutPar(Int_t m, Double_t p)
Definition: hmdcdedx2.cc:882
Double_t getMinDistCutPar(Int_t m, Double_t p)
Definition: hmdcdedx2.h:105
Double_t hefr
Definition: hmdcdedx2.h:42
Float_t getTime2(void) const
Definition: hmdccal1.h:50
void calcSegPoints(HMdcSeg *, Double_t &, Double_t &, Double_t &, Double_t &, Double_t &, Double_t &)
Definition: hmdcdedx2.cc:960
HEvent *& getCurrentEvent(void)
Definition: hades.cc:422
static Double_t gamma(Int_t id, Double_t p)
Definition: hmdcdedx2.cc:1138
TGraph p2(xdim, pgrid, respme)
HMdcDeDx2(const Char_t *name="MdcDeDx2", const Char_t *title="Mdc lookup for MDC dEdX calculation", const Char_t *context="MdcDeDx2Production")
Definition: hmdcdedx2.cc:76
Bool_t initContainer()
Definition: hmdcdedx2.cc:241
#define ref_ANGLE
Definition: hmdcdedx2.h:25
Double_t parMax[6][4][N_ANGLE][N_DIST]
Definition: hmdcdedx2.h:33
Float_t getTheta(void) const
Definition: hmdcseg.h:103
Double_t pargaincorr[6][4][6][220]
Definition: hmdcdedx2.h:35
static HMdcSizesCells * getExObject(void)
void putParams(HParamList *)
Definition: hmdcdedx2.cc:269
Int_t getHitInd(Int_t i) const
Definition: hmdcseg.h:166
Float_t getWindow()
Definition: hmdcdedx2.h:114
const Cat_t catMdcClus
Definition: hmdctrackddef.h:6
void getParticle(Int_t &aTrack, Int_t &aID)
Definition: hgeantkine.cc:197
void setFuncPar(Int_t s, Int_t m, Int_t abin, Int_t dbin, Double_t *p, Int_t size)
Definition: hmdcdedx2.cc:678
const Cat_t catMdcHit
Definition: hmdcdef.h:6
void resetInputVersions()
Definition: hparset.cc:144
void add(HParamObj &)
Definition: hparamlist.cc:415
ClassImp(HMdcDeDx2) Float_t HMdcDeDx2
Definition: hmdcdedx2.cc:70
const Cat_t catMdcClusInf
Definition: hmdctrackddef.h:9
Bool_t getParams(HParamList *)
Definition: hmdcdedx2.cc:286
UChar_t select(Float_t, Float_t, UChar_t, Float_t wind=-99.)
Definition: hmdcdedx2.cc:593
TArrayD measurements
method switch for filling input for module 1/2 of segment
Definition: hmdcdedx2.h:57
Float_t getPhi(void) const
Definition: hmdcseg.h:104
static TGraph * betaGraph(Int_t id, Int_t opt=1, Int_t markerstyle=8, Int_t markercolor=2, Float_t markersize=0.7)
Definition: hmdcdedx2.cc:1096
Int_t ctskipmod1
counter for wires skipped with t2<=-998 in mod0 of seg
Definition: hmdcdedx2.h:60
Bool_t useCalibration
array of measurements
Definition: hmdcdedx2.h:58
#define N_DIST
Definition: hmdcdedx2.h:20
Bool_t changed
static flag
Definition: hparset.h:14
Double_t getFuncGainPar(Int_t s, Int_t m, Int_t l, Int_t c)
Definition: hmdcdedx2.h:103
#define N_PARAM
Definition: hmdcdedx2.h:21
static Float_t mass(const Int_t id)
Double_t toTSigma(Int_t s, Int_t m, Double_t angle, Double_t mindist, Int_t shift=0)
Definition: hmdcdedx2.cc:1000
Int_t getCell(Int_t layer, Int_t idx)
#define N_SHIFT_PARAM
Definition: hmdcdedx2.h:22
Double_t * getFuncWidthPar(Int_t s, Int_t m, Int_t abin, Int_t dbin)
Definition: hmdcdedx2.h:100
Double_t getHeFraction()
Definition: hmdcdedx2.h:132
void setFuncMaxPar(Int_t s, Int_t m, Int_t abin, Int_t dbin, Double_t val)
Definition: hmdcdedx2.cc:732
void clear()
Definition: hmdcdedx2.cc:104
#define MAX_WIRES
Definition: hmdcdedx2.h:18
Hades * gHades
Definition: hades.cc:1213
Float_t getZ(void) const
Definition: hmdcseg.h:101
Double_t normalize(Int_t s, Int_t m, Int_t l, Int_t c, Double_t angle, Double_t mindist, Double_t ToT)
Definition: hmdcdedx2.cc:1076
UChar_t fillingInput(HMdcSeg *seg[2], Int_t inputselect=0)
Definition: hmdcdedx2.cc:463
Int_t getCell(Int_t lay, Int_t idx) const
Float_t AngleStep
Definition: hmdcdedx2.h:41
static Double_t beta(Int_t id, Double_t p)
Definition: hmdcdedx2.cc:1090
HLocation loccal
pointer to mdc clusinf
Definition: hmdcdedx2.h:51
HCategory * cathit
pointer to mdc cal1
Definition: hmdcdedx2.h:48
Bool_t status
versions of container in the 2 possible inputs
Definition: hparset.h:13
HMdcSizesCells * sizescells
Definition: hmdcdedx2.h:46
Bool_t createMaxPar(Bool_t print=kFALSE)
Definition: hmdcdedx2.cc:198
Double_t scaledTimeAboveThreshold(HGeantKine *kine=0, Double_t p=-1, Float_t t1=-999, Float_t t2=-999, Float_t *t2err=0, Int_t s=0, Int_t m=0, Int_t l=0, Int_t c=0, Double_t alpha=0, Double_t mindist=0)
Definition: hmdcdedx2.cc:1238
Double_t shiftpar[6][4][N_ANGLE][N_DIST][N_SHIFT_PARAM]
Definition: hmdcdedx2.h:32
#define N_ANGLE
Definition: hmdcdedx2.h:19
void setFuncWidthPar(Int_t s, Int_t m, Int_t abin, Int_t dbin, Double_t *p, Int_t size)
Definition: hmdcdedx2.cc:779
Int_t getSec(void) const
Definition: hmdcseg.h:138
Double_t dEdXToToT(Int_t s, Int_t m, Int_t l, Int_t c, Double_t angle, Double_t mindist, Double_t dEdX)
Definition: hmdcdedx2.cc:1050
Float_t MinDistStep[4]
Definition: hmdcdedx2.h:40
static Bool_t debug
counter for wires skipped with t2<=-998 in mod1 of seg
Definition: hmdcdedx2.h:61
void printParam(TString opt="all")
Definition: hmdcdedx2.cc:111
Double_t * getFuncPar(Int_t s, Int_t m, Int_t abin, Int_t dbin)
Definition: hmdcdedx2.h:96
Short_t getClusIndex(void)
Definition: hmdcclusinf.h:89
Int_t getNCells(Int_t layer)
Float_t phi
Definition: drawAccCuts.C:15
void setWindow(Float_t win)
Definition: hmdcdedx2.h:115
Float_t getR(void) const
Definition: hmdcseg.h:102
Float_t calcDeDx(HMdcSeg *seg[2], Float_t *, Float_t *, UChar_t *, Float_t *, UChar_t *, Int_t vers=2, Int_t mod=2, Bool_t useTruncMean=kTRUE, Float_t truncMeanWindow=-99., Int_t inputselect=0)
Definition: hmdcdedx2.cc:335
Int_t module
method switch for filling input
Definition: hmdcdedx2.h:55
Double_t ptot
static Int_t pid(const Char_t *pidName)
Bool_t fill(const Text_t *, Text_t *, const Int_t)
Definition: hparamlist.cc:561
void setFuncGainPar(Int_t s, Int_t m, Int_t l, Int_t c, Double_t p)
Definition: hmdcdedx2.cc:835
Double_t toTTodEdX(Int_t s, Int_t m, Int_t l, Int_t c, Double_t angle, Double_t mindist, Double_t ToT)
Definition: hmdcdedx2.cc:1020
static Float_t MaxMdcMinDist[4]
Definition: hmdcdedx2.h:38
Int_t ctskipmod0
use/don't use normalization table
Definition: hmdcdedx2.h:59
void findBin(Int_t m, Double_t *angle, Double_t *mindist, Int_t *abin, Int_t *dbin)
Definition: hmdcdedx2.cc:983
HCategory * catcal
pointer to HMdcSizesCells container
Definition: hmdcdedx2.h:47
HCategory * catclus
pointer to mdc clusinf
Definition: hmdcdedx2.h:50
Float_t getTime1(void) const
Definition: hmdccal1.h:49
#define ref_MOD
Definition: hmdcdedx2.h:24
Int_t getMinimumWires()
Definition: hmdcdedx2.h:116
Int_t minimumWires
Definition: hmdcdedx2.h:43