FairRoot/PandaRoot
PndEvtFilterOnInvMassCounts.cxx
Go to the documentation of this file.
1 // -------------------------------------------------------------------------
2 // ----- PndEvtFilterOnInvMassCounts source file -----
3 // -------------------------------------------------------------------------
4 
6 #include "TParticlePDG.h"
7 #include <algorithm>
8 
9 
10 
11 // ----- Default constructor -------------------------------------------
12 PndEvtFilterOnInvMassCounts::PndEvtFilterOnInvMassCounts() : PndEvtFilter(), fInvMassRangeSet(0), fPgdCodesSet(0), fCountRangeSet(0)
13 
14 {
15  fInvMassSel = 0;
16 }
17 
18 
19 // ----- Constructor with name and title ------------------------------------
20 PndEvtFilterOnInvMassCounts::PndEvtFilterOnInvMassCounts(const char* name, const char* title) : PndEvtFilter(name, title), fInvMassRangeSet(0), fPgdCodesSet(0), fCountRangeSet(0)
21 {
22  fInvMassSel = 0;
23 }
24 
25 // ----- Destructor ----------------------------------------------------
27 
28 
30 {
31  if ( kTRUE == fCountRangeSet ){
32  std::cout << "\n\n\n -WARNING from PndEvtFilterOnInvMassCounts of " << this->GetTitle() << ": " << this->GetName() << ": \n";
33  std::cout << "You are trying to set min and max counts for the events more than once! \n";
34  std::cout << "I take the first setting of min = " << fCountsMinMax.first << " max = " << fCountsMinMax.second << " and ignore the later ones! \n\n\n";
35  std::cout << "Your current input of min = " << min << " max = " << max << " is ignored! \n\n\n";
36  return kFALSE;
37  }
38 
39  // check if filter can be applied (make sure that min and max make sense)
40  if ( min < 0 ){
41  std::cout << "\n\n\n -WARNING from PndEvtFilterOnInvMassCounts of " << this->GetTitle() << ": " << this->GetName() << ": Filter could not be added. You are trying to request that your events should have at least a number <= 0 of some particles. That makes no sense. \n\n\n";
42  return kFALSE;
43  }
44  if ( max < min ){
45  std::cout << "\n\n\n -WARNING from PndEvtFilterOnInvMassCounts of " << this->GetTitle() << ": " << this->GetName() << ": Filter could not be added. You are trying to request that your events should have at most a number of some particles which is less than the minimum number that you request. That makes no sense. \n\n\n";
46  return kFALSE;
47  }
48 
49  // set the minimum and maximum number of particle combinations
50  fCountsMinMax = std::pair<Int_t, Int_t> (min,max);
51 
52  // turn filter on
53  fCountRangeSet = kTRUE;
54 
55  return kTRUE;
56 }
57 
58 
60 {
61  if ( kTRUE == fInvMassRangeSet ){
62  std::cout << "\n\n\n -WARNING from PndEvtFilterOnInvMassCounts of " << this->GetTitle() << ": " << this->GetName() << ": \n";
63  std::cout << "You are trying to set the limits for the invariant mass selection set more than once! \n";
64  std::cout << "I take the first setting and ignore the later ones! \n\n\n";
65  return kFALSE;
66  }
67 
68  // check if filter can be applied (make sure that min and max make sense)
69  if ( min < 0. ){
70  std::cout << "\n\n\n -WARNING from PndEvtFilterOnInvMassCounts " << this->GetTitle() << ": " << this->GetName() << ": Filter could not be added. Min inv. mass too low. \n\n\n";
71  return kFALSE;
72  }
73  if ( max < min ){
74  std::cout << "\n\n\n -WARNING from PndEvtFilterOnInvMassCounts " << this->GetTitle() << ": " << this->GetName() << ": Filter could not be added. Max inv. mass lower than min inv. mass. \n\n\n";
75  return kFALSE;
76  }
77 
78  // set up the inv. mass selector
79  Double_t mu = (min + max)/2.0;
80  Double_t fullWidth = max - min;
81 
82  fInvMassSel = new RhoMassParticleSelector("invMassFilter", mu, fullWidth);
83 
84  // turn filter on
85  fInvMassRangeSet = kTRUE;
86 
87  return kTRUE;
88 }
89 
90 
92 {
93  if ( kTRUE == fInvMassRangeSet ){
94  std::cout << "\n\n\n -WARNING from PndEvtFilterOnInvMassCounts of " << this->GetTitle() << ": " << this->GetName() << ": \n";
95  std::cout << "You are trying to set the limits for the invariant mass selection set more than once! \n";
96  std::cout << "I take the first setting and ignore the later ones! \n\n\n";
97  return kFALSE;
98  }
99 
100  // check if filter can be applied (make sure that min and max make sense)
101  if ( cv <= 0. ){
102  std::cout << "\n\n\n -WARNING from PndEvtFilterOnInvMassCounts " << this->GetTitle() << ": " << this->GetName() << ": Filter could not be added. cv has to be positive. \n\n\n";
103  return kFALSE;
104  }
105  if ( w < 0. ){
106  std::cout << "\n\n\n -WARNING from PndEvtFilterOnInvMassCounts " << this->GetTitle() << ": " << this->GetName() << ": Filter could not be added. w has to be non-negative. \n\n\n";
107  return kFALSE;
108  }
109 
110  fInvMassSel = new RhoMassParticleSelector(name, cv, w, type);
111 
112  // turn filter on
113  fInvMassRangeSet = kTRUE;
114 
115  return kTRUE;
116 }
117 
118 
119 Bool_t PndEvtFilterOnInvMassCounts::SetPdgCodesToCombine( Int_t pdgCode1, Int_t pdgCode2, Int_t pdgCode3, Int_t pdgCode4, Int_t pdgCode5 ){
120  if ( kTRUE == fPgdCodesSet ){
121  std::cout << "\n\n\n -WARNING from PndEvtFilterOnInvMassCounts of " << this->GetTitle() << ": " << this->GetName() << ": \n";
122  std::cout << "You are trying to set the pdgCodes to combine into invariant mass combinations more than once! \n";
123  std::cout << "I take the first setting and ignore the later ones! \n\n\n";
124  return kFALSE;
125  }
126 
127 
128  // create temp. vector of all input pdg codes
129  std::vector< Int_t > pdgCodes, apdgCodes;
130  pdgCodes.push_back(pdgCode1);
131  pdgCodes.push_back(pdgCode2);
132  pdgCodes.push_back(pdgCode3);
133  pdgCodes.push_back(pdgCode4);
134  pdgCodes.push_back(pdgCode5);
135 
136 
137 // std::cout <<"[PndEvtFilterOnInvMassCounts]"<<pdgCode1<<" "<<pdgCode2<<" "<<pdgCode3<<" "<<pdgCode4<<" "<<pdgCode5<<std::endl;
138 
139  // Copy valid entries from pdgCodes to fPdgCodesCharges
140  for (UInt_t iPdgCodes = 0; iPdgCodes < pdgCodes.size(); ++iPdgCodes){
141  // skip kInvalidPdgCode entries in pdgCodes
142  if ( kInvalidPdgCode == pdgCodes[iPdgCodes] ) { continue; }
143  // If we have invalid pdg codes warn user
144  Double_t pdgCodeCharge = kNoChargeSpecified;
145  if ( kFALSE == GetCharge( pdgCodes[iPdgCodes], &pdgCodeCharge ) ) {
146  std::cout << "\n\n\nFATAL ERROR FROM PndEvtFilterOnInvMassCounts::SetPdgCodesToCombine of " << this->GetTitle() << ": " << this->GetName() << " Charge for pdg code " << pdgCodes[iPdgCodes] << " was not found. \n";
147  std::cout << "Filter was not set. \n\n\n”";
148  fPgdCodesSet = kFALSE;
149  return kFALSE;
150  }
151  // If we get to this point, we have successfully added a pdg code
152  fPdgCodesCharges.push_back(std::pair<Int_t, Double_t> (pdgCodes[iPdgCodes], pdgCodeCharge));
153  }
154 
155  // Check that we had at least two correctly set pdg codes
156  if ( 1 < fPdgCodesCharges.size() ){
157  fPgdCodesSet = kTRUE;
158  return kTRUE;
159  } else {
160  std::cout << "\n\n\nFATAL ERROR FROM PndEvtFilterOnInvMassCounts::SetPdgCodesToCombine of " << this->GetTitle() << ": " << this->GetName() << " You have to specify at least 2 valid pdg codes. \n";
161  std::cout << "Filter was not set. \n\n\n”";
162  fPgdCodesSet = kFALSE;
163  return kFALSE;
164  }
165 }
166 
167 
168 
170 {
171  if (fVerbose > 3){
172  std::cout << "\n\n";
173  std::cout << "Internal eventNr:" << evtNr << "\n";
174  std::cout << "Nr. of simulated particles:" << fParticleList->GetEntries()<<"\n";
176  std::cout << "PndEvtFilterOnInvMassCounts " << this->GetTitle() << ": " << this->GetName() << ": Beginning of EventMatches\n";
177  }
178 
179  // sanity checks
180  if (0==fParticleList){
181  std::cout << "\n\n\n PndEvtFilterOnInvMassCounts " << this->GetTitle() << ": " << this->GetName() << ": FATAL ERROR: No particle list! Discard this event.\n\n\n";
182  return kFALSE;
183  }
184 
185 
186  // do not accept events that do not have enough particles
187  if ( fParticleList->GetEntriesFast() < (int)fPdgCodesCharges.size() ){
188  if (0<fVerbose) std::cout << "\n\n\n PndEvtFilterOnInvMassCounts: Event contains less than " << fPdgCodesCharges.size() << " particles. " << this->GetTitle() << ": " << this->GetName() << " will not accept this event.\n\n\n";
189  return kFALSE;
190  }
191 
192  // get rho cand lists of particles and combine them
193  RhoCandList p0, p1, p2, p3, p4;
194  // also care about charged conjugate
195  RhoCandList ap0, ap1, ap2, ap3, ap4;
196 
197  std::vector<int> pdg, apdg;
198 
199  // make list with anti-pdg codes
200  for (UInt_t i=0;i<fPdgCodesCharges.size();++i)
201  {
202  int cpdg = fPdgCodesCharges[i].first;
203  pdg.push_back(cpdg);
204 
205  if (fdbPdg->GetParticle(cpdg)!=0x0 && fdbPdg->GetParticle(cpdg)->AntiParticle()!=0x0)
206  apdg.push_back(fdbPdg->GetParticle(cpdg)->AntiParticle()->PdgCode());
207  else
208  apdg.push_back(cpdg);
209  }
210 
211  // is the cc'd list the same as the original one (= a permutation)?
212  bool isperm = is_permutation(pdg.begin(), pdg.end(), apdg.begin());
213 
214 
215  FillList( p0, fPdgCodesCharges[0].first, fPdgCodesCharges[0].second );
216  FillList( p1, fPdgCodesCharges[1].first, fPdgCodesCharges[1].second );
217 
218  // fill anti-particle lists
219  if (!isperm)
220  {
221  FillList( ap0, apdg[0], -fPdgCodesCharges[0].second );
222  FillList( ap1, apdg[1], -fPdgCodesCharges[1].second );
223  }
224 
225  RhoCandList combinedList, combinedAntiList;
226 
227  switch( fPdgCodesCharges.size() ) {
228  case 2:
229  combinedList.Combine(p0, p1);
230  if (!isperm) combinedAntiList.Combine(ap0, ap1);
231  break;
232  case 3:
233  FillList( p2, fPdgCodesCharges[2].first, fPdgCodesCharges[2].second );
234  combinedList.Combine(p0, p1, p2);
235  if (!isperm)
236  {
237  FillList( ap2, apdg[2], -fPdgCodesCharges[2].second );
238  combinedAntiList.Combine(ap0, ap1, ap2);
239  }
240  break;
241  case 4:
242  FillList( p2, fPdgCodesCharges[2].first, fPdgCodesCharges[2].second );
243  FillList( p3, fPdgCodesCharges[3].first, fPdgCodesCharges[3].second );
244  combinedList.Combine(p0, p1, p2, p3);
245  if (!isperm)
246  {
247  FillList( ap2, apdg[2], -fPdgCodesCharges[2].second );
248  FillList( ap3, apdg[3], -fPdgCodesCharges[3].second );
249  combinedAntiList.Combine(ap0, ap1, ap2, ap3);
250  }
251  break;
252  case 5:
253  FillList( p2, fPdgCodesCharges[2].first, fPdgCodesCharges[2].second );
254  FillList( p3, fPdgCodesCharges[3].first, fPdgCodesCharges[3].second );
255  FillList( p4, fPdgCodesCharges[4].first, fPdgCodesCharges[4].second );
256  combinedList.Combine(p0, p1, p2, p3, p4);
257  if (!isperm)
258  {
259  FillList( p2, apdg[2], -fPdgCodesCharges[2].second );
260  FillList( p3, apdg[3], -fPdgCodesCharges[3].second );
261  FillList( p4, apdg[4], -fPdgCodesCharges[4].second );
262  combinedAntiList.Combine(ap0, ap1, ap2, ap3, ap4);
263  }
264  break;
265  default:
266  std::cout << "FATAL ERROR in PndEvtFilterOnInvMassCounts::EventMatches of " << this->GetTitle() << ": " << this->GetName() << ". The number of pdg codes is not supported. \n";
267  return kFALSE;
268  break;
269  }
270 
271 
272  if (fVerbose > 3){
273  std::cout << "Looking for inv. masses of " << fPdgCodesCharges.size() << " particles.\n";
274  std::cout << p0.GetLength() << " / " << p1.GetLength() << " / " << p2.GetLength() << " / " << p3.GetLength() << " / " << p4.GetLength();
275  std::cout << " particles in initial lists\n";
276  std::cout << combinedList.GetLength() << " particles in combined list before mass selection\n";
277  }
278 
279  // select acceptable invariant mass range
280  combinedList.Select(fInvMassSel);
281  if (!isperm) combinedAntiList.Select(fInvMassSel);
282 
283  int ncand = combinedList.GetLength() + combinedAntiList.GetLength();
284 
285  if (fVerbose > 3){
286  std::cout << combinedList.GetLength()<<" + "<< combinedAntiList.GetLength()<< " particles in combined list after mass selection\n";
287  }
288 
289  // check if number of acceptable combinations is within acceptable limits
290  if ( ncand < fCountsMinMax.first){
291  if (fVerbose >9){
292  std::cout << "Event is not accepted by " << this->GetTitle() << ": " << this->GetName() << " because there are too few matching inv. mass combinations in the event. \n";
293  }
294  return kFALSE;
295  }
296  if ( ncand > fCountsMinMax.second ){
297  if (fVerbose >9){
298  std::cout << "Event is not accepted by " << this->GetTitle() << ": " << this->GetName() << " because there are too many matching inv. mass combinations in the event. \n";
299  }
300  return kFALSE;
301  }
302 
303 
304  // for QA
305  fAcceptedEventNumbers.insert(evtNr);
306  if (fVerbose >5){
307  std::cout << "\n Event matches " << this->GetTitle() << ": " << this->GetName() << "\n\n";
308  }
309  return kTRUE;
310 }
311 
312 
Bool_t SetMinMaxCounts(Int_t min, Int_t max)
void PrintAllTParticleInEvent()
Int_t i
Definition: run_full.C:25
Bool_t FillList(RhoCandList &rhoOutList, Int_t inPdgCode, Double_t pdgCodeCharge=kNoChargeSpecified)
Bool_t GetCharge(Int_t inPdgCode, Double_t *pdgCodeCharge)
Int_t GetLength() const
Definition: RhoCandList.h:46
friend F32vec4 max(const F32vec4 &a, const F32vec4 &b)
Definition: P4_F32vec4.h:26
Bool_t SetMinMaxInvMass(Double_t min, Double_t max)
void Combine(RhoCandList &l1, RhoCandList &l2)
Double_t
RhoMassParticleSelector * fInvMassSel
std::set< Int_t > fAcceptedEventNumbers
TClonesArray * fParticleList
void Select(RhoParticleSelectorBase *pidmgr)
friend F32vec4 min(const F32vec4 &a, const F32vec4 &b)
Definition: P4_F32vec4.h:25
static const Double_t kNoChargeSpecified
TString name
TPad * p2
Definition: hist-t7.C:117
std::pair< Int_t, Int_t > fCountsMinMax
Bool_t SetPdgCodesToCombine(Int_t pdgCode1, Int_t pdgCode2, Int_t pdgCode3=kInvalidPdgCode, Int_t pdgCode4=kInvalidPdgCode, Int_t pdgCode5=kInvalidPdgCode)
ClassImp(PndAnaContFact)
TPad * p1
Definition: hist-t7.C:116
Bool_t SetRhoMassParticleSelector(const char *name, Double_t cv, Double_t w, const char *type)
std::vector< std::pair< Int_t, Double_t > > fPdgCodesCharges
TDatabasePDG * fdbPdg