FairRoot/PandaRoot
PndSdsStripCorrelator.cxx
Go to the documentation of this file.
1 //------------------------------------------------------------------------------------
2 //---------------- PndSdsStripCorrelator.cxx -----------------------
3 // Class to correlate top and bottom clusters on double sided strip sensors
4 //
5 // Authors: R. Kliemt (Uni Bonn)
6 // H.G. Zaunick (Uni Bonn)
7 // Date: June 2012
8 //
9 //------------------------------------------------------------------------------------
10 
11 #define CLUSTER_MULT_CUTOFF 5 //7
12  //This is a hard cut on the allowed number of clusters per sensor side
13  //Combinatorics take a large toll already at 6 clusters present!
14 
15 #include "PndSdsStripCorrelator.h"
16 #include <cmath>
17 
18 //------------------------------------------------------------------------------------
20  fClusterList(),
21  fCorrelationList(),
22  fCorrelationProbList(),
23  fSecondProbList(),
24  fMultProbList(),
25  fCut(cut),
26  fNoise(noise),
27  fThreshold(threshold),
28  fMode(mode),
29  fCalculated(false)
30 {}
31 
32 //------------------------------------------------------------------------------------
34 
35 //------------------------------------------------------------------------------------
36 void PndSdsStripCorrelator::AddCluster(int moduleId, int side, int clusterIndex, double charge)
37 {
38  fClusterList[moduleId][side].push_back(make_pair(clusterIndex,charge));
39 }
40 
41 //------------------------------------------------------------------------------------
43 {
44  fClusterList.clear();
45  fCorrelationList.clear();
46  fCorrelationProbList.clear();
47  fSecondProbList.clear();
48  fMultProbList.clear();
49  fCalculated=false;
50 }
51 
52 //------------------------------------------------------------------------------------
53 void PndSdsStripCorrelator::Setup(int mode, double cut, double noise, double threshold)
54 {
55  fMode=mode;
56  fCut=cut;
57  fNoise=noise;
59  fCalculated=false;
60 }
61 
62 //------------------------------------------------------------------------------------
64 {
65  if(!fCalculated)
66  {
67  switch (fMode) {
68  case 0:
70  break;
71  case 1:
73  break;
74  default:
75  CalcAll();
76  break;
77  }
78  fCalculated=true;
79  }
80  return fCorrelationList;
81 }
82 
83 //------------------------------------------------------------------------------------
85 {
86  if(!fCalculated){
87  fCorrelationProbList.clear(); // empty on invalid state, just in case
88  fSecondProbList.clear(); // empty on invalid state, just in case
89  fMultProbList.clear(); // empty on invalid state, just in case
90  }
91  return fCorrelationProbList;
92 }
93 
94 //------------------------------------------------------------------------------------
96 {
97  if(!fCalculated){
98  fCorrelationProbList.clear(); // empty on invalid state, just in case
99  fSecondProbList.clear(); // empty on invalid state, just in case
100  fMultProbList.clear(); // empty on invalid state, just in case
101  }
102  return fSecondProbList;
103 }
104 
105 //------------------------------------------------------------------------------------
107 {
108  if(!fCalculated){
109  fCorrelationProbList.clear(); // empty on invalid state, just in case
110  fSecondProbList.clear(); // empty on invalid state, just in case
111  fMultProbList.clear(); // empty on invalid state, just in case
112  }
113  return fMultProbList;
114 }
115 
116 //------------------------------------------------------------------------------------
118 {
119  double oldcut = fCut;
120  fCut=0.;
122  fCut=oldcut;
123 }
124 
125 //------------------------------------------------------------------------------------
127 {
128  double dq=0;
129  fCorrelationList.clear();
130  for (map<int,map<int,vector<pair<int,double> > > >::iterator modIt=fClusterList.begin(); modIt!=fClusterList.end(); ++modIt)
131  {
132  for (vector<pair<int,double> >::iterator topIt = modIt->second[0].begin(); topIt != modIt->second[0].end(); ++topIt)
133  {
134  for (vector<pair<int,double> >::iterator botIt = modIt->second[1].begin(); botIt != modIt->second[1].end(); ++botIt)
135  {
136  dq=fabs((*topIt).second - (*botIt).second);
137  if (dq<fCut)
138  {
139  fCorrelationList.push_back(make_pair((*topIt).first,(*botIt).first));
140  fCorrelationProbList.push_back( (dq>5e4) ? 0 : (1 - 2e-5*dq) );
141  fSecondProbList.push_back( -1 );
142  }
143  }
144  }
145  }
146 }
147 
148 //------------------------------------------------------------------------------------
150 {
151  //per sensor module fill a combinations matrix, calculate likelihoods, assign b
152 
153  fCorrelationList.clear();
154  for (map<int,map<int,vector<pair<int,double> > > >::iterator modIt=fClusterList.begin(); modIt!=fClusterList.end(); ++modIt)
155  {
156  if (modIt->second[0].size()>CLUSTER_MULT_CUTOFF) continue; // skip modules with too busy events
157  if (modIt->second[1].size()>CLUSTER_MULT_CUTOFF) continue; // skip modules with too busy events
158  //fill matrix
159  std::map<int,std::map<int,PndSdsStripCorrelatorCand> > matrix;
160  double top_total=0.,wert=0.;
161  int nTop=0, nBot=0, iBot=0; //,iTop=-1,iBot=-1;
162  for (vector<pair<int,double> >::iterator topIt = modIt->second[0].begin(); topIt != modIt->second[0].end(); ++topIt)
163  {
164  for (vector<pair<int,double> >::iterator botIt = modIt->second[1].begin(); botIt != modIt->second[1].end(); ++botIt)
165  {
166  wert = (*topIt).second - (*botIt).second;
167  // wert *= wert;
168  // top_total += wert;
169  top_total += wert*wert;
170  wert = erfc(fabs(wert)/(2.*fThreshold)/sqrt(2.)); // [R.K.31.7.'12]
171  //wert = erfc(fabs(wert)/(6.*fNoise)/sqrt(2.)); // original
172  matrix[nTop][iBot]=PndSdsStripCorrelatorCand((*topIt).first,(*botIt).first,(*topIt).second,(*botIt).second,wert);
173  //printf("add to matrix: t=%i, b=%i, qt=%f, qb=%f, p=%f \n",(*topIt).first,(*botIt).first,(*topIt).second,(*botIt).second,wert);
174  iBot++;
175  }
176  if(iBot>nBot)nBot=iBot;
177  iBot=0;
178  nTop++;
179  }
180 
181  // Calculate combinations
182  std::vector<PndSdsStripCorrelatorCombi> combinations = getCombinations(matrix,nTop,nBot);
183 
184  if(combinations.size()==0) continue; //next module
185 
186  //select the lowest probability
187  double klein=-1.,ganzklein=-1.;
188  int who=-1, whoelse=-1;
189 
190  for(int like=0;like<(int)combinations.size();like++)
191  {
192  if(combinations[like].prob>klein)
193  {
194  if(combinations[like].prob>ganzklein)
195  {
196  klein=ganzklein;
197  whoelse=who;
198  ganzklein=combinations[like].prob;
199  who=like;
200  }
201  else
202  {
203  klein=combinations[like].prob;
204  whoelse=like;
205  }
206  }
207  }
208  // if(combinations[who].prob>fCut)
209  // { // index pairs for the output
210  for (int kk=0; kk<(int)combinations[who].pairlist.size(); ++kk)
211  {
212  fCorrelationList.push_back(make_pair(combinations[who].pairlist[kk].top,combinations[who].pairlist[kk].bot));
213  //printf("add correlation [%i|%i] p=%f \n",combinations[who].pairlist[kk].top,combinations[who].pairlist[kk].bot,combinations[who].prob);
214  fCorrelationProbList.push_back(combinations[who].prob);
215  if(whoelse>=0) fSecondProbList.push_back(combinations[whoelse].prob);
216  else fSecondProbList.push_back(-1.);
217  fMultProbList.push_back(combinations.size());
218  }
219  // }
220  }
221 }
222 
223 
224 //------------------------------------------------------------------------------------
225 
226 std::vector<PndSdsStripCorrelatorCombi> PndSdsStripCorrelator::getCombinations(std::map<int,std::map<int,PndSdsStripCorrelatorCand> > matrix, int cols, int rows)
227 {
228  //printf("getCombinations: Matrix(%i,%i) \n",cols,rows);
229  std::vector<PndSdsStripCorrelatorCombi> combinations;
230  if (cols==1 && rows==1) {
232  combi.pairlist.push_back(PndSdsStripCorrelatorCand(matrix[0][0]));
233  combi.prob=matrix[0][0].prob;
234  combinations.push_back(combi);
235  return combinations;
236  }
237  if (cols==1) {
239  double q_t[rows];
240  double bsum=0.;
241  for (int i=0; i< rows; i++) bsum+=matrix[0][i].q_bot;
242  for (int i=0; i< rows; i++) q_t[i]=matrix[0][0].q_top - bsum + matrix[0][i].q_bot;
243  //double tot=0.; //unused?
244  //double diag=0.; //unused?
245  for (int i=0; i< rows; i++)
246  {
247  combi.pairlist.push_back(PndSdsStripCorrelatorCand(matrix[0][i].top,matrix[0][i].bot,q_t[i],matrix[0][i].q_bot,matrix[0][i].prob));
248  combi.prob*=erfc(fabs(q_t[i]-matrix[0][i].q_bot)/(2.*fThreshold*sqrt(2.)));// [R.K.31.7.'12]
249  //combi.prob*=erfc(fabs(q_t[i]-matrix[0][i].q_bot)/(6.*fNoise*sqrt(2.)));//original
250  }
251  double prob_full=combi.prob;
252  combinations.push_back(combi);
253  //double _maxprob = combi.prob; //unused?
254  //int _maxcombi = 0; //unused?
255  for (int i=0; i<rows; ++i)
256  { // Recursive call
257  std::vector<PndSdsStripCorrelatorCombi> combilist_reduced=getCombinations(getSubMatrix(matrix,1,rows,-1,i),1,rows-1);
258  for (int ii=0; ii<(int)combilist_reduced.size(); ii++)
259  {
260  combilist_reduced[ii].prob*=(1.-prob_full);
261  }
262  combinations.insert(combinations.end(),combilist_reduced.begin(),combilist_reduced.end());
263  }
264  return combinations;
265  }
266  if (rows==1) {
268  double q_b[cols];
269  double tsum=0.;
270  for (int i=0; i< cols; i++) tsum+=matrix[i][0].q_top;
271  for (int i=0; i< cols; i++) q_b[i]=matrix[0][0].q_bot - tsum + matrix[i][0].q_top;
272  //double tot=0.; //unused?
273  //double diag=0.; //unused?
274  for (int i=0; i< cols; i++)
275  {
276  combi.pairlist.push_back(PndSdsStripCorrelatorCand(matrix[i][0].top,matrix[i][0].bot,matrix[i][0].q_top,q_b[i],matrix[i][0].prob));
277  combi.prob*=erfc(fabs(matrix[i][0].q_top-q_b[i])/(2.*fThreshold*sqrt(2.)));// [R.K.31.7.'12]
278  //combi.prob*=erfc(fabs(matrix[i][0].q_top-q_b[i])/(6.*fNoise*sqrt(2.)));//original
279  }
280  double prob_full=combi.prob;
281  combinations.push_back(combi);
282  //double _maxprob = combi.prob; //unused?
283  //int _maxcombi = 0; //unused?
284  for (int i=0; i<cols; ++i)
285  { // Recursive call
286  std::vector<PndSdsStripCorrelatorCombi> combilist_reduced=getCombinations(getSubMatrix(matrix,cols,1,i,-1),cols-1,1);
287  for (int ii=0; ii<(int)combilist_reduced.size(); ii++)
288  {
289  combilist_reduced[ii].prob*=(1.-prob_full);
290  }
291  combinations.insert(combinations.end(),combilist_reduced.begin(),combilist_reduced.end());
292  }
293  return combinations;
294  }
295  // treat 2x2 matrix as separate case since the nr. of independent combinations is just half of the nr. of possible combinations
296  if (rows==2 && cols==2) {
299  combi1.prob=1.;
300  combi2.prob=1.;
301  combi1.pairlist.push_back(PndSdsStripCorrelatorCand(matrix[0][0]));
302  combi1.prob*=matrix[0][0].prob;
303  combi1.pairlist.push_back(PndSdsStripCorrelatorCand(matrix[1][1]));
304  combi1.prob*=matrix[1][1].prob;
305  combi2.pairlist.push_back(PndSdsStripCorrelatorCand(matrix[1][0]));
306  combi2.prob*=matrix[1][0].prob;
307  combi2.pairlist.push_back(PndSdsStripCorrelatorCand(matrix[0][1]));
308  combi2.prob*=matrix[0][1].prob;
309  combinations.push_back(combi1);
310  combinations.push_back(combi2);
311  return combinations;
312  }
313  for (int i=0; i<cols; i++) {
314  for (int j=0; j<rows; j++)
315  { // Recursive call
316  std::vector<PndSdsStripCorrelatorCombi> combilist=getCombinations(getSubMatrix(matrix,cols,rows,i,j),cols-1,rows-1);
317  for (int k=0; k<(int)combilist.size(); k++) {
318  combilist[k].pairlist.push_back(PndSdsStripCorrelatorCand(matrix[i][j]));
319  combilist[k].prob*=matrix[i][j].prob;
320  combinations.push_back(PndSdsStripCorrelatorCombi(combilist[k].pairlist,combilist[k].prob));
321  }
322  }
323  }
324  return combinations;
325 }
326 
327 //------------------------------------------------------------------------------------
328 
329 std::map<int,std::map<int,PndSdsStripCorrelatorCand> > PndSdsStripCorrelator::getSubMatrix(std::map<int,std::map<int,PndSdsStripCorrelatorCand> > matrix, int cols, int rows, int pivotCol, int pivotRow)
330 {
331  std::map<int,std::map<int,PndSdsStripCorrelatorCand> > result;
332  int ii=0;
333  for (int i=0; i<cols;i++)
334  {
335  if (i==pivotCol) continue;
336  int jj=0;
337  for (int j=0; j<rows; j++)
338  {
339  result[ii][jj]=matrix[i][j];
340  if (j==pivotRow) continue;
341  jj++;
342  }
343  ii++;
344  }
345  return result;
346 }
347 
348 
349 //------------------------------------------------------------------------------------
350 
351 //#define CLUSTER_MULT_CUTOFF 7
352 //
353 //std::vector<RecoHitPair> StripHitReco::GetHitPoints(double sigmaNoise, double minProbability)
354 //{
355 // std::vector<RecoHitPair> result;
356 // if(!fTopClusterList.size() || !fBottomClusterList.size()) return result;
357 // if (
358 // (fTopClusterList.size()>=CLUSTER_MULT_CUTOFF || fBottomClusterList.size()>=CLUSTER_MULT_CUTOFF))
359 // {
360 // if (fVerbose) cout<<"-W- too many clusters ("<<fTopClusterList.size()<<","<<fBottomClusterList.size()<<"). skipping event "<<endl;
361 // return result;
362 // }
363 //
364 // if (fVerbose>2) cout<<"-I- *** clusters (t/b): ("<<fTopClusterList.size()<<"/"<<fBottomClusterList.size()<<")"<<endl;
365 //
366 // std::map<int,std::map<int,PndSdsStripCorrelatorCand> > matrix;
367 // double top_total=0.;
368 // //fill matrix
369 // for(int first=0;first<fTopClusterList.size();++first)
370 // {
371 // for(int second=0;second<fBottomClusterList.size();++second)
372 // {
373 // double wert=fTopClusterList[first].GetChargeSum()-fBottomClusterList[second].GetChargeSum();
374 // wert*=wert;
375 // top_total+=wert;
376 // matrix[first][second]=PndSdsStripCorrelatorCand(first,second,fTopClusterList[first].GetChargeSum(),fBottomClusterList[second].GetChargeSum(),wert);
377 // }
378 // }
379 // if (fVerbose>2) if (fTopClusterList.size()>=1 || fBottomClusterList.size()>=1) cout<<"-I- total sum of charge differences="<<sqrt(top_total)<<endl;
380 //
381 //
382 // if (fVerbose>1) if (fTopClusterList.size()>=1 || fBottomClusterList.size()>=1) cout<<"-I- matrix of charge differences:"<<endl;
383 // if (fTopClusterList.size()>1 || fBottomClusterList.size()>1)
384 // {
385 // for(int second=0;second<fBottomClusterList.size();++second)
386 // {
387 // for(int first=0;first<fTopClusterList.size();++first)
388 // {
389 // double _diff=sqrt(matrix[first][second].prob);
390 // if (fVerbose>1) if (fTopClusterList.size()>1 || fBottomClusterList.size()>1) cout<<" "<<_diff;
391 // // combinatorial probability
392 // matrix[first][second].prob=1.;
393 // // probability due to charge difference
394 // matrix[first][second].prob*=erfc(fabs(_diff)/(6.*fNoise)/sqrt(2.));
395 // }
396 // if (fVerbose>1) if (fTopClusterList.size()>1 || fBottomClusterList.size()>1) cout<<endl;
397 // }
398 // } else if (fTopClusterList.size()==1 && fBottomClusterList.size()==1) {
399 // double _diff=sqrt(matrix[0][0].prob);
400 // if (fVerbose>1) cout<<_diff<<endl;
401 // matrix[0][0].prob=erfc(fabs(_diff)/(6.*fNoise)/sqrt(2.));
402 // }
403 //
404 // std::vector<PndSdsStripCorrelatorCombi> combinations=getCombinations(matrix,fTopClusterList.size(),fBottomClusterList.size());
405 //
406 // if (fVerbose) if (fTopClusterList.size()>1 || fBottomClusterList.size()>1) cout<<"-I- nr of combinations="<<combinations.size()<<endl;
407 //
408 //
409 // if (fVerbose>2)
410 // if (combinations.size()>1)
411 // for (int i=0; i<combinations.size(); i++)
412 // {
413 // cout<<"-I- "<<i<<": prob="<<combinations[i].prob<<" ";
414 // for (int j=0; j<combinations[i].pairlist.size(); j++)
415 // cout<<"("<<combinations[i].pairlist[j].top<<","<<combinations[i].pairlist[j].bot<<") ";
416 // cout<<endl;
417 // }
418 //
419 // double klein=-1.;
420 // int who=-1;
421 // for(int like=0;like<combinations.size();like++)
422 // {
423 // if(combinations[like].prob>klein)
424 // {
425 // klein=combinations[like].prob;
426 // who=like;
427 // }
428 // }
429 //
430 // if (fVerbose)
431 // if (fTopClusterList.size()>=1 || fBottomClusterList.size()>=1) {
432 // cout<<"-I- most probable combination (prob="<<combinations[who].prob<<"): ";
433 // for (int j=0; j<combinations[who].pairlist.size(); j++)
434 // cout<<"("<<combinations[who].pairlist[j].top<<","<<combinations[who].pairlist[j].bot<<") ";
435 // cout<<endl;
436 // cout<<"-I- charges: ";
437 // for (int j=0; j<combinations[who].pairlist.size(); j++)
438 // cout<<"("<<combinations[who].pairlist[j].q_top<<","<<combinations[who].pairlist[j].q_bot<<") ";
439 // cout<<endl;
440 // }
441 //
442 //
443 // if(combinations.size()!=0 && combinations[who].prob>minProbability)
444 // {
445 // for(int i=0;i<combinations[who].pairlist.size();++i)
446 // {
447 // double top=calcCoordinate(fTopClusterList[combinations[who].pairlist[i].top]);
448 // double toperror=falgorith.GetError();
449 // double bottom=calcCoordinate(fBottomClusterList[combinations[who].pairlist[i].bot]);
450 // double bottomerror=falgorith.GetError();
451 //
452 // RecoHitPair Punkt(fTopClusterList[combinations[who].pairlist[i].top].GetEventID(),
453 // fTopClusterList[combinations[who].pairlist[i].top].GetTimestamp(),
454 // fTopClusterList[combinations[who].pairlist[i].top].GetModuleID(),
455 // combinations[who].pairlist[i].q_top,
456 // combinations[who].pairlist[i].q_bot,
457 // top,
458 // bottom,
459 // fTopClusterList[combinations[who].pairlist[i].top].NrHits(),
460 // fBottomClusterList[combinations[who].pairlist[i].bot].NrHits(),
461 // combinations[who].prob,
462 // toperror,
463 // bottomerror);
464 //
465 // result.push_back(Punkt);
466 // }
467 // }
468 // return result;
469 //}
470 
471 
472 
Int_t i
Definition: run_full.C:25
PndTransMap * map
Definition: sim_emc_apd.C:99
friend F32vec4 sqrt(const F32vec4 &a)
Definition: P4_F32vec4.h:29
vector< pair< int, int > > GetCorrelationList()
vector< double > fSecondProbList
vector< double > GetProbList()
map< int, map< int, vector< pair< int, double > > > > fClusterList
TGeoVolume * top
vector< double > fCorrelationProbList
double cut[MAX]
Definition: autocutx.C:36
Int_t mode
Definition: autocutx.C:47
void Setup(int mode=0, double cut=0., double noise=0., double threshold=0.)
std::map< int, std::map< int, PndSdsStripCorrelatorCand > > getSubMatrix(std::map< int, std::map< int, PndSdsStripCorrelatorCand > > matrix, int cols, int rows, int pivotCol, int pivotRow)
void AddCluster(int moduleId, int side, int clusterIndex, double charge)
int cols[10]
Definition: evaltrig.C:69
vector< pair< int, int > > fCorrelationList
PndSdsStripCorrelator(int mode=0, double cut=0., double noise=0., double threshold=0.)
TGeoCombiTrans * combi
friend F32vec4 fabs(const F32vec4 &a)
Definition: P4_F32vec4.h:47
double threshold
vector< double > GetSecondProbList()
#define CLUSTER_MULT_CUTOFF
std::vector< PndSdsStripCorrelatorCand > pairlist
double noise
std::vector< PndSdsStripCorrelatorCombi > getCombinations(std::map< int, std::map< int, PndSdsStripCorrelatorCand > > matrix, int cols, int rows)