Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
JetAnalyzer.cxx
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file JetAnalyzer.cxx
1 
10 #include "JetAnalyzer.hh"
11 
12 // ------------
13 // Constructors
14 // ------------
15 
16 // ------------------------------------------------------------------------
17 // Standard ctor
18 JetAnalyzer::JetAnalyzer( std::vector<fastjet::PseudoJet>& InOrigParticles, fastjet::JetDefinition& JetDef,
19  fastjet::AreaDefinition& AreaDef, fastjet::Selector selector_bkgd )
20  : fastjet::ClusterSequenceArea ( InOrigParticles, JetDef, AreaDef ), OrigParticles ( InOrigParticles ),
21  selector_bkgd (selector_bkgd)
22 {
23 
24  CanDoBackground=true;
25 
26  // this should not be necessary :-/
28  jet_def_bkgd = 0;
29  bkgd_estimator = 0;
30  bkgd_subtractor = 0;
31  area_def_bkgd = new fastjet::AreaDefinition( AreaDef );
32  // DEBUG
33  // area_def_bkgd = new fastjet::AreaDefinition( fastjet::VoronoiAreaSpec( 1.0 ) );
34 
35  // // std::cout << "Area Spec " << area_spec.description() << std::endl;
36  // std::cout << "Area Def given: " << std::endl << AreaDef.description() << std::endl;
37  // std::cout << "Area Def Bkgd: " << std::endl << area_def_bkgd->description() << std::endl;
38  // std::cout << "This: " << std::endl << this->area_def().description() << std::endl;
39 
40 }
41 // ------------------------------------------------------------------------
42 
43 // ------------------------------------------------------------------------
44 // Standard ctor for use as ClusterSequence
45 JetAnalyzer::JetAnalyzer( std::vector<fastjet::PseudoJet>& InOrigParticles, fastjet::JetDefinition& JetDef )
46  : fastjet::ClusterSequenceArea ( InOrigParticles, JetDef, 0 ), OrigParticles ( InOrigParticles )
47 {
48  CanDoBackground=false;
49 
50  // this should not be necessary :-/
52  area_def_bkgd=0;
53  jet_def_bkgd = 0;
54  bkgd_estimator = 0;
55  bkgd_subtractor = 0;
56 
57 }
58 // ------------------------------------------------------------------------
59 
60 
61 
62 // ------------
63 // Methods
64 // ------------
65 
66 // ------------------------------------------------------------------------
67 // Background functionality
68 fastjet::Subtractor* JetAnalyzer::GetBackgroundSubtractor(){
69  if ( !CanDoBackground ) {
70  // throw std::string("Should not be called unless we can actually do background subtraction.");
71  return 0;
72  }
73 
74  // // Area
75  // // ----
76  // // Construct from jet definition and radius
77  // double ymin, ymax;
78  // selector_bkgd.get_rapidity_extent (ymin, ymax);
79  // assert ( !std::isinf(ymin) && !std::isinf(ymax) && "Can't handle unrestricted area." );
80  // assert ( ymin == -ymax && "Can't construct ghosted area for asymmetric rapidity cuts.");
81 
82  // double ghost_maxrap = ymax + 2.0*jet_def().R();
83  // area_def_bkgd = new fastjet::AreaDefinition (fastjet::active_area_explicit_ghosts,
84  // fastjet::GhostedAreaSpec( ghost_maxrap ));
85 
86  // Background jet definition
87  // -------------------------
88  jet_def_bkgd = new fastjet::JetDefinition (fastjet::kt_algorithm, jet_def().R());
89 
90  // Estimator and subtractor
91  // ------------------------
92  // std::cout << area_def_bkgd->description() << std::endl;
93  // std::cout << selector_bkgd.description() << std::endl;
94  // std::cout << "selector.has_finite_area() = "<< selector_bkgd.has_finite_area() << std::endl;
95  bkgd_estimator = new fastjet::JetMedianBackgroundEstimator(selector_bkgd, *jet_def_bkgd, *area_def_bkgd);
96  bkgd_subtractor = new fastjet::Subtractor(bkgd_estimator);
97 
98  // since FastJet 3.1.0, rho_m is supported natively in background
99  // estimation (both JetMedianBackgroundEstimator and
100  // GridMedianBackgroundEstimator).
101  //
102  // For backward-compatibility reasons its use is by default switched off
103  // (as is the enforcement of m>0 for the subtracted jets). The
104  // following 2 lines of code switch these on. They are strongly
105  // recommended and should become the default in future versions of
106  // FastJet.
107 #if FASTJET_VERSION_NUMBER >= 30100
108  bkgd_subtractor->set_use_rho_m(true);
109  bkgd_subtractor->set_safe_mass(true);
110 #endif
111 
112  bkgd_estimator->set_particles( OrigParticles );
113 
114  // std::cout << OrigParticles.size() << std::endl;
115  // std::cout << " rho = " << bkgd_estimator->rho() << std::endl;
116  // std::cout << " sigma = " << bkgd_estimator->sigma() << std::endl;
117 
118  return bkgd_subtractor;
119 }
120 // ------------------------------------------------------------------------
121 // ----------------
122 // Analysis methods
123 // ----------------
124 // Dijet finding as a Selector
125 void SelectorDijetWorker::terminator(std::vector<const fastjet::PseudoJet *> & jets) const{
126  // For each jet that does not pass the cuts, this routine sets the
127  // pointer to 0.
128 
129  // Save these ones from being zeroed
130  int i0 = -1;
131  int i1 = -1;
132 
133  // For dPhi<0 or too few jets, we don't even need to try
134  if ( dPhi>=0 && jets.size() >= 2 ) {
135  // need to allow unsorted input
136  // So find the two largest pT jets. Sigh.
137 
138  // Pair negative pT^2 with the index
139  // That takes care of pT sign and of stl::sorting order
140  std::vector< std::pair<int,double> > IndexPt;
141  for (unsigned int i=0; i<jets.size(); ++i ){
142  // Note that jets.at(i) might be NULL
143  IndexPt.push_back( std::pair<int,double>( i, jets.at(i) ? -jets.at(i)->perp2() : 0.0) );
144  }
145 
146  // and sort
147  std::sort(IndexPt.begin(), IndexPt.end(), sort_IntDoubleByDouble());
148 
149  // We only accept top two jets
150  // Now Index 0 and 1 should point to the largest ones
151  // Tentatively set them to be keepers
152  i0 = IndexPt.at(0).first;
153  i1 = IndexPt.at(1).first;
154 
155  // clarified for readability
156  double phi0 = jets.at(i0)->phi();
157  double phi1 = jets.at(i1)->phi();
158 
159  if ( ! (fabs ( JetAnalyzer::phimod2pi( phi0 - phi1 - JetAnalyzer::pi) ) < dPhi) ) {
160  // Nope, don't save them after all
161  i0=i1=-1;
162  }
163  } else {
164  // std::cout << " -------------------- dPhi<0 or Not enough jets" << std::endl;
165  }
166 
167  // Zero out everything else
168  for ( int i=0; i< int( jets.size() ) ; ++i ){
169  if ( i==i0 ) continue;
170  if ( i==i1 ) continue;
171  jets.at(i)= NULL;
172  }
173 
174  return;
175 }
176 fastjet::Selector SelectorDijets( const double dPhi ){
177  return fastjet::Selector(new SelectorDijetWorker( dPhi ) );
178 }
179 
180 // ------------------------------------------------------------------------
181 
182 // -------
183 // Helpers
184 // -------
185 double JetAnalyzer::phimod2pi ( double phi ){
186  while ( phi <-pi ) phi += 2.0*pi;
187  while ( phi > pi ) phi -= 2.0*pi;
188  return phi;
189 }
190 
191 // ------------------------------------------------------------------------
192 
193 // -------------------
194 // Getters and Setters
195 // -------------------
196 
197 // ------------------------------------------------------------------------
198 
199 
200 // --------------
201 // Other funtions
202 // --------------
203 // ------------------------------------------------------------------------
204 bool IsMatched ( const std::vector<fastjet::PseudoJet>& jetset1, const std::vector<fastjet::PseudoJet>& jetset2, const double Rmax )
205 {
206  // could also return lists of matches or so
207  // As it is, I'm using a primitive 1-to-1 matching
208  // Enforcing 1 to 1 to avoid stupid pathologies
209  // For dijet A_J, the following is already overkill, but I want to
210  // lay the groundwork for more complex tasks
211  if ( jetset1.size() != jetset2.size() ) return false;
212 
213  std::vector<fastjet::PseudoJet> j2copy = jetset2; // cause we're going to destroy it
214  for ( int j1 = 0; j1 < int( jetset1.size() ) ; ++j1 ){
215  bool j1matched=false;
216  for ( std::vector<fastjet::PseudoJet>::iterator pj2=j2copy.begin() ; pj2!=j2copy.end(); ++pj2 ){
217  if ( jetset1.at(j1).delta_R( *pj2 ) < Rmax ){
218  j1matched=true;
219 
220  // std::cout << jetset1.at(j1).delta_R( *pj2 ) << std::endl; // DEBUG
221  // could pop it into a result list, like so:
222  // result.push_back (*pj2);
223 
224  // remove from jetset2
225  j2copy.erase( pj2 );
226 
227  // done with this one
228  break;
229  } // if (R<max)
230  } // for jet2
231  // not matched? bad
232  if ( !j1matched ) return false;
233  } // for jet1
234 
235  // Now we should have cleanly removed all jets from set 2;
236  if ( j2copy.size() >0 ) return false;
237 
238  return true;
239 }
240 // ------------------------------------------------------------------------
241 bool IsMatched ( const std::vector<fastjet::PseudoJet>& jetset1, const fastjet::PseudoJet& reference, const double Rmax )
242 {
243  for ( int j1 = 0; j1 < int (jetset1.size()) ; ++ j1 ){
244  if ( jetset1.at(j1).delta_R( reference ) < Rmax ){
245  return true;
246  } // if (R<max)
247  } // for jet1
248 
249  return false;
250 }
251 
252 // ------------------------------------------------------------------------
253 bool IsMatched ( const fastjet::PseudoJet& jet1, const fastjet::PseudoJet& jet2, const double Rmax )
254 {
255  return jet1.delta_R( jet2 ) < Rmax;
256 }
257 
258 // ------------------------------------------------------------------------
259 TLorentzVector MakeTLorentzVector ( const fastjet::PseudoJet& pj ){
260  return TLorentzVector( pj.px(), pj.py(), pj.pz(), pj.E() );
261  // Below could be slightly faster but circumvents encapsulation.
262  // four_mom() is a valarray<double> which is NOT guaranteed to be contiguous
263  // return TLorentzVector( (Double_t*) &pj.four_mom()[0] );
264 }
265 // ------------------------------------------------------------------------
266 
267 // ------------------------------------------------------------------------
268 fastjet::PseudoJet MakePseudoJet ( const TLorentzVector* const lv ){
269  return fastjet::PseudoJet ( *lv );
270 }
271 
272 
273 // ------------------------------------------------------------------------
274 // the function that allows to write simply
275 // Selector sel = SelectorChargeRange( cmin, cmax );
276 fastjet::Selector SelectorChargeRange( const int cmin, const int cmax){
277  return fastjet::Selector(new SelectorChargeWorker(cmin, cmax));
278 };
279 // ------------------------------------------------------------------------
280 // Helper to get an enum from a string
282  std::transform(s.begin(), s.end(), s.begin(), ::tolower);
283 
284  if ( s.substr(0,2) == "kt" ) return fastjet::kt_algorithm;
285  if ( s.substr(0,6) == "antikt" ) return fastjet::antikt_algorithm;
286  if ( s.substr(0,6) == "cambri" ) return fastjet::cambridge_algorithm;
287 
289 
290 }
291 // ------------------------------------------------------------------------
292 const double JetAnalyzer::pi = 3.141592653589793238462643383279502884;