|
fastjet 3.0alpha2
|
00001 #include <sstream> 00002 #include <algorithm> 00003 #include "fastjet/Selector.hh" 00004 00005 using namespace std; 00006 00007 FASTJET_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh 00008 00009 //---------------------------------------------------------------------- 00010 // implementations of some of the more complex bits of Selector 00011 //---------------------------------------------------------------------- 00012 00013 // implementation of the operator() acting on a vector of jets 00014 std::vector<PseudoJet> Selector::operator()(const std::vector<PseudoJet> & jets) const { 00015 std::vector<PseudoJet> result; 00016 if (validated_worker()->applies_jet_by_jet()) { 00017 //if (false) { 00018 // for workers that apply jet by jet, this is more efficient 00019 for (std::vector<PseudoJet>::const_iterator jet = jets.begin(); 00020 jet != jets.end(); jet++) { 00021 if (_worker->pass(*jet)) result.push_back(*jet); 00022 } 00023 } else { 00024 // for workers that can only be applied to entire vectors, 00025 // go through the following 00026 std::vector<const PseudoJet *> jetptrs(jets.size()); 00027 for (unsigned i = 0; i < jets.size(); i++) { 00028 jetptrs[i] = & jets[i]; 00029 } 00030 _worker->terminator(jetptrs); 00031 for (unsigned i = 0; i < jetptrs.size(); i++) { 00032 if (jetptrs[i]) result.push_back(jets[i]); 00033 } 00034 } 00035 return result; 00036 } 00037 00038 00039 // implementation of the Selector's area function 00040 double Selector::area(double cell_area) const{ 00041 if (! has_area()) throw InvalidArea(); 00042 00043 // has area will already check we've got a valid worker 00044 if (_worker->has_known_area()) return _worker->known_area(); 00045 00046 // generate a set of "ghosts" 00047 double rapmin, rapmax; 00048 get_rapidity_extent(rapmin, rapmax); 00049 GhostedAreaSpec ghost_spec(rapmin, rapmax, 1, cell_area); 00050 std::vector<PseudoJet> ghosts; 00051 ghost_spec.add_ghosts(ghosts); 00052 00053 // check what passes the selection 00054 // unsigned int npass= 0; 00055 // for (std::vector<PseudoJet>::const_iterator jet = ghosts.begin(); jet != ghosts.end(); jet++) 00056 // if (_worker->geometric_pass(*jet)) npass++; 00057 return ghost_spec.ghost_area() * ((*this)(ghosts)).size(); 00058 } 00059 00060 00061 //---------------------------------------------------------------------- 00062 // very basic set of selectors (at the moment just the identity!) 00063 //---------------------------------------------------------------------- 00064 00065 //---------------------------------------------------------------------- 00066 /// helper for selecting the n hardest jets 00067 class SW_Identity : public SelectorWorker { 00068 public: 00069 /// ctor with specification of the number of objects to keep 00070 SW_Identity(){} 00071 00072 /// just let everything pass 00073 virtual bool pass(const PseudoJet & jet) const { 00074 return true; 00075 } 00076 00077 /// For each jet that does not pass the cuts, this routine sets the 00078 /// pointer to 0. 00079 virtual void terminator(vector<const PseudoJet *> & jets) const { 00080 // everyything passes, hence nothing to nullify 00081 return; 00082 } 00083 00084 /// returns a description of the worker 00085 virtual string description() const { return "Identity";} 00086 }; 00087 00088 00089 // returns an "identity" selector that lets everything pass 00090 Selector SelectorIdentity() { 00091 return Selector(new SW_Identity); 00092 } 00093 00094 00095 //---------------------------------------------------------------------- 00096 // selector and workers for operators 00097 //---------------------------------------------------------------------- 00098 00099 //---------------------------------------------------------------------- 00100 /// helper for combining selectors with a logical not 00101 class SW_Not : public SelectorWorker { 00102 public: 00103 /// ctor 00104 SW_Not(const Selector & s) : _s(s) {} 00105 00106 /// return a copy of the current object 00107 virtual SelectorWorker* copy(){ return new SW_Not(*this);} 00108 00109 /// returns true if a given object passes the selection criterium 00110 /// this has to be overloaded by derived workers 00111 virtual bool pass(const PseudoJet & jet) const { 00112 // make sure that the "pass" can be applied on both selectors 00113 if (!applies_jet_by_jet()) 00114 throw Error("Cannot apply this selector worker to an individual jet"); 00115 00116 return ! _s.pass(jet); 00117 } 00118 00119 /// returns true if this can be applied jet by jet 00120 virtual bool applies_jet_by_jet() const {return _s.applies_jet_by_jet();} 00121 00122 /// select the jets in the list that pass both selectors 00123 virtual void terminator(vector<const PseudoJet *> & jets) const { 00124 // if we can apply the selector jet-by-jet, call the base selector 00125 // that does exactly that 00126 if (applies_jet_by_jet()){ 00127 SelectorWorker::terminator(jets); 00128 return; 00129 } 00130 00131 // check the effect of the selector we want to negate 00132 vector<const PseudoJet *> s_jets = jets; 00133 _s.worker()->terminator(s_jets); 00134 00135 // now apply the negation: all the jets that pass the base 00136 // selector (i.e. are not NULL) have to be set to NULL 00137 for (unsigned int i=0; i<s_jets.size(); i++){ 00138 if (s_jets[i]) jets[i] = NULL; 00139 } 00140 } 00141 00142 /// returns a description of the worker 00143 virtual string description() const { 00144 ostringstream ostr; 00145 ostr << "!(" << _s.description() << ")"; 00146 return ostr.str(); 00147 } 00148 00149 /// returns true is the worker can be set_referenced 00150 virtual bool takes_reference() const { return _s.takes_reference();} 00151 00152 protected: 00153 Selector _s; 00154 }; 00155 00156 00157 // logical not applied on a selector 00158 Selector operator!(const Selector & s) { 00159 return Selector(new SW_Not(s)); 00160 } 00161 00162 00163 //---------------------------------------------------------------------- 00164 /// Base class for binary operators 00165 class SW_BinaryOperator: public SelectorWorker { 00166 public: 00167 /// ctor 00168 SW_BinaryOperator(const Selector & s1, const Selector & s2) : _s1(s1), _s2(s2) { 00169 // stores info for more efficient access to the selector's properties 00170 00171 // we can apply jet by jet only if this is the case for both sub-selectors 00172 _applies_jet_by_jet = _s1.applies_jet_by_jet() && _s2.applies_jet_by_jet(); 00173 00174 // the selector takes a reference if either of the sub-selectors does 00175 _takes_reference = _s1.takes_reference() || _s2.takes_reference(); 00176 00177 // we have a well-defined area provided the two objects have one 00178 _has_area = _s1.has_area() && _s2.has_area(); 00179 } 00180 00181 /// returns true if this can be applied jet by jet 00182 virtual bool applies_jet_by_jet() const {return _applies_jet_by_jet;} 00183 00184 /// returns true if this takes a reference jet 00185 virtual bool takes_reference() const{ 00186 return _takes_reference; 00187 } 00188 00189 /// sets the reference jet 00190 virtual void set_reference(const PseudoJet ¢re){ 00191 _s1.set_reference(centre); 00192 _s2.set_reference(centre); 00193 } 00194 00195 /// check if it has a finite area 00196 virtual bool has_area() const { return _has_area;} 00197 00198 protected: 00199 Selector _s1, _s2; 00200 bool _applies_jet_by_jet; 00201 bool _takes_reference; 00202 bool _has_area; 00203 }; 00204 00205 00206 00207 //---------------------------------------------------------------------- 00208 /// helper for combining selectors with a logical and 00209 class SW_And: public SW_BinaryOperator { 00210 public: 00211 /// ctor 00212 SW_And(const Selector & s1, const Selector & s2) : SW_BinaryOperator(s1,s2){} 00213 00214 /// return a copy of this 00215 virtual SelectorWorker* copy(){ return new SW_And(*this);} 00216 00217 /// returns true if a given object passes the selection criterium 00218 /// this has to be overloaded by derived workers 00219 virtual bool pass(const PseudoJet & jet) const { 00220 // make sure that the "pass" can be applied on both selectors 00221 if (!applies_jet_by_jet()) 00222 throw Error("Cannot apply this selector worker to an individual jet"); 00223 00224 return _s1.pass(jet) && _s2.pass(jet); 00225 } 00226 00227 /// select the jets in the list that pass both selectors 00228 virtual void terminator(vector<const PseudoJet *> & jets) const { 00229 // if we can apply the selector jet-by-jet, call the base selector 00230 // that does exactly that 00231 if (applies_jet_by_jet()){ 00232 SelectorWorker::terminator(jets); 00233 return; 00234 } 00235 00236 // check the effect of the first selector 00237 vector<const PseudoJet *> s1_jets = jets; 00238 _s1.worker()->terminator(s1_jets); 00239 00240 // apply the second 00241 _s2.worker()->terminator(jets); 00242 00243 // terminate the jets that wiuld be terminated by _s1 00244 for (unsigned int i=0; i<jets.size(); i++){ 00245 if (! s1_jets[i]) jets[i] = NULL; 00246 } 00247 } 00248 00249 /// returns the rapidity range for which it may return "true" 00250 virtual void get_rapidity_extent(double & rapmin, double & rapmax) const { 00251 double s1min, s1max, s2min, s2max; 00252 _s1.get_rapidity_extent(s1min, s1max); 00253 _s2.get_rapidity_extent(s2min, s2max); 00254 rapmax = min(s1max, s2max); 00255 rapmin = max(s1min, s2min); 00256 } 00257 00258 /// returns a description of the worker 00259 virtual string description() const { 00260 ostringstream ostr; 00261 ostr << "(" << _s1.description() << " && " << _s2.description() << ")"; 00262 return ostr.str(); 00263 } 00264 }; 00265 00266 00267 // logical and between two selectors 00268 Selector operator&&(const Selector & s1, const Selector & s2) { 00269 return Selector(new SW_And(s1,s2)); 00270 } 00271 00272 00273 00274 //---------------------------------------------------------------------- 00275 /// helper for combining selectors with a logical or 00276 class SW_Or: public SW_BinaryOperator { 00277 public: 00278 /// ctor 00279 SW_Or(const Selector & s1, const Selector & s2) : SW_BinaryOperator(s1,s2) {} 00280 00281 /// return a copy of this 00282 virtual SelectorWorker* copy(){ return new SW_Or(*this);} 00283 00284 /// returns true if a given object passes the selection criterium 00285 /// this has to be overloaded by derived workers 00286 virtual bool pass(const PseudoJet & jet) const { 00287 // make sure that the "pass" can be applied on both selectors 00288 if (!applies_jet_by_jet()) 00289 throw Error("Cannot apply this selector worker to an individual jet"); 00290 00291 return _s1.pass(jet) || _s2.pass(jet); 00292 } 00293 00294 /// returns true if this can be applied jet by jet 00295 virtual bool applies_jet_by_jet() const { 00296 // watch out, even though it's the "OR" selector, to be applied jet 00297 // by jet, both the base selectors need to be jet-by-jet-applicable, 00298 // so the use of a && in the line below 00299 return _s1.applies_jet_by_jet() && _s2.applies_jet_by_jet(); 00300 } 00301 00302 /// select the jets in the list that pass both selectors 00303 virtual void terminator(vector<const PseudoJet *> & jets) const { 00304 // if we can apply the selector jet-by-jet, call the base selector 00305 // that does exactly that 00306 if (applies_jet_by_jet()){ 00307 SelectorWorker::terminator(jets); 00308 return; 00309 } 00310 00311 // check the effect of the first selector 00312 vector<const PseudoJet *> s1_jets = jets; 00313 _s1.worker()->terminator(s1_jets); 00314 00315 // apply the second 00316 _s2.worker()->terminator(jets); 00317 00318 // resurrect any jet that has been terminated by the second one 00319 // and not by the first one 00320 for (unsigned int i=0; i<jets.size(); i++){ 00321 if (s1_jets[i]) jets[i] = s1_jets[i]; 00322 } 00323 } 00324 00325 /// returns a description of the worker 00326 virtual string description() const { 00327 ostringstream ostr; 00328 ostr << "(" << _s1.description() << " || " << _s2.description() << ")"; 00329 return ostr.str(); 00330 } 00331 00332 /// returns the rapidity range for which it may return "true" 00333 virtual void get_rapidity_extent(double & rapmin, double & rapmax) const { 00334 double s1min, s1max, s2min, s2max; 00335 _s1.get_rapidity_extent(s1min, s1max); 00336 _s2.get_rapidity_extent(s2min, s2max); 00337 rapmax = max(s1max, s2max); 00338 rapmin = min(s1min, s2min); 00339 } 00340 }; 00341 00342 00343 // logical or between two selectors 00344 Selector operator ||(const Selector & s1, const Selector & s2) { 00345 return Selector(new SW_Or(s1,s2)); 00346 } 00347 00348 //---------------------------------------------------------------------- 00349 /// helper for multiplying two selectors (in an operator-like way) 00350 class SW_Mult: public SW_And { 00351 public: 00352 /// ctor 00353 SW_Mult(const Selector & s1, const Selector & s2) : SW_And(s1,s2) {} 00354 00355 /// return a copy of this 00356 virtual SelectorWorker* copy(){ return new SW_Mult(*this);} 00357 00358 /// select the jets in the list that pass both selectors 00359 virtual void terminator(vector<const PseudoJet *> & jets) const { 00360 // if we can apply the selector jet-by-jet, call the base selector 00361 // that does exactly that 00362 if (applies_jet_by_jet()){ 00363 SelectorWorker::terminator(jets); 00364 return; 00365 } 00366 00367 // first apply _s2 00368 _s2.worker()->terminator(jets); 00369 00370 // then apply _s1 00371 _s1.worker()->terminator(jets); 00372 } 00373 00374 /// returns a description of the worker 00375 virtual string description() const { 00376 ostringstream ostr; 00377 ostr << "(" << _s1.description() << " * " << _s2.description() << ")"; 00378 return ostr.str(); 00379 } 00380 }; 00381 00382 00383 // logical and between two selectors 00384 Selector operator*(const Selector & s1, const Selector & s2) { 00385 return Selector(new SW_Mult(s1,s2)); 00386 } 00387 00388 00389 //---------------------------------------------------------------------- 00390 // selector and workers for kinematic cuts 00391 //---------------------------------------------------------------------- 00392 00393 //---------------------------------------------------------------------- 00394 // a series of basic classes that allow easy implementations of 00395 // min, max and ranges on a quantity-to-be-defined 00396 00397 // generic holder for a quantity 00398 class QuantityBase{ 00399 public: 00400 QuantityBase(double q) : _q(q){} 00401 virtual double operator()(const PseudoJet & jet ) const =0; 00402 virtual string description() const =0; 00403 virtual double comparison_value() const {return _q;} 00404 virtual double description_value() const {return comparison_value();} 00405 protected: 00406 double _q; 00407 }; 00408 00409 // generic holder for a squared quantity 00410 class QuantitySquareBase : public QuantityBase{ 00411 public: 00412 QuantitySquareBase(double sqrtq) : QuantityBase(sqrtq*sqrtq), _sqrtq(sqrtq){} 00413 virtual double description_value() const {return _sqrtq;} 00414 protected: 00415 double _sqrtq; 00416 }; 00417 00418 // generic_quantity >= minimum 00419 template<typename QuantityType> 00420 class SW_QuantityMin : public SelectorWorker{ 00421 public: 00422 /// detfault ctor (initialises the pt cut) 00423 SW_QuantityMin(double qmin) : _qmin(qmin) {} 00424 00425 /// returns true is the given object passes the selection pt cut 00426 virtual bool pass(const PseudoJet & jet) const {return _qmin(jet) >= _qmin.comparison_value();} 00427 00428 /// returns a description of the worker 00429 virtual string description() const { 00430 ostringstream ostr; 00431 ostr << _qmin.description() << " >= " << _qmin.description_value(); 00432 return ostr.str(); 00433 } 00434 00435 protected: 00436 QuantityType _qmin; ///< the cut 00437 }; 00438 00439 00440 // generic_quantity <= maximum 00441 template<typename QuantityType> 00442 class SW_QuantityMax : public SelectorWorker { 00443 public: 00444 /// detfault ctor (initialises the pt cut) 00445 SW_QuantityMax(double qmax) : _qmax(qmax) {} 00446 00447 /// returns true is the given object passes the selection pt cut 00448 virtual bool pass(const PseudoJet & jet) const {return _qmax(jet) <= _qmax.comparison_value();} 00449 00450 /// returns a description of the worker 00451 virtual string description() const { 00452 ostringstream ostr; 00453 ostr << _qmax.description() << " <= " << _qmax.description_value(); 00454 return ostr.str(); 00455 } 00456 00457 protected: 00458 QuantityType _qmax; ///< the cut 00459 }; 00460 00461 00462 // generic quantity in [minimum:maximum] 00463 template<typename QuantityType> 00464 class SW_QuantityRange : public SelectorWorker { 00465 public: 00466 /// detfault ctor (initialises the pt cut) 00467 SW_QuantityRange(double qmin, double qmax) : _qmin(qmin), _qmax(qmax) {} 00468 00469 /// returns true is the given object passes the selection pt cut 00470 virtual bool pass(const PseudoJet & jet) const { 00471 double q = _qmin(jet); // we could identically use _qmax 00472 return (q >= _qmin.comparison_value()) && (q <= _qmax.comparison_value()); 00473 } 00474 00475 /// returns a description of the worker 00476 virtual string description() const { 00477 ostringstream ostr; 00478 ostr << _qmin.description_value() << " <= " << _qmin.description() << " <= " << _qmax.description_value(); 00479 return ostr.str(); 00480 } 00481 00482 protected: 00483 QuantityType _qmin; // the lower cut 00484 QuantityType _qmax; // the upper cut 00485 }; 00486 00487 00488 //---------------------------------------------------------------------- 00489 /// helper class for selecting on pt 00490 class QuantityPt2 : public QuantitySquareBase{ 00491 public: 00492 QuantityPt2(double pt) : QuantitySquareBase(pt){} 00493 virtual double operator()(const PseudoJet & jet ) const { return jet.perp2();} 00494 virtual string description() const {return "pt";} 00495 }; 00496 00497 // returns a selector for a minimum pt 00498 Selector SelectorPtMin(double ptmin) { 00499 return Selector(new SW_QuantityMin<QuantityPt2>(ptmin)); 00500 } 00501 00502 // returns a selector for a maximum pt 00503 Selector SelectorPtMax(double ptmax) { 00504 return Selector(new SW_QuantityMax<QuantityPt2>(ptmax)); 00505 } 00506 00507 // returns a selector for a pt range 00508 Selector SelectorPtRange(double ptmin, double ptmax) { 00509 return Selector(new SW_QuantityRange<QuantityPt2>(ptmin, ptmax)); 00510 } 00511 00512 00513 //---------------------------------------------------------------------- 00514 /// helper class for selecting on transverse energy 00515 class QuantityEt2 : public QuantitySquareBase{ 00516 public: 00517 QuantityEt2(double Et) : QuantitySquareBase(Et){} 00518 virtual double operator()(const PseudoJet & jet ) const { return jet.Et2();} 00519 virtual string description() const {return "Et";} 00520 }; 00521 00522 // returns a selector for a minimum Et 00523 Selector SelectorEtMin(double Etmin) { 00524 return Selector(new SW_QuantityMin<QuantityEt2>(Etmin*Etmin)); 00525 } 00526 00527 // returns a selector for a maximum Et 00528 Selector SelectorEtMax(double Etmax) { 00529 return Selector(new SW_QuantityMax<QuantityEt2>(Etmax*Etmax)); 00530 } 00531 00532 // returns a selector for a Et range 00533 Selector SelectorEtRange(double Etmin, double Etmax) { 00534 return Selector(new SW_QuantityRange<QuantityEt2>(Etmin*Etmin, Etmax*Etmax)); 00535 } 00536 00537 00538 //---------------------------------------------------------------------- 00539 /// helper class for selecting on energy 00540 class QuantityE : public QuantityBase{ 00541 public: 00542 QuantityE(double E) : QuantityBase(E){} 00543 virtual double operator()(const PseudoJet & jet ) const { return jet.E();} 00544 virtual string description() const {return "E";} 00545 }; 00546 00547 // returns a selector for a minimum E 00548 Selector SelectorEMin(double Emin) { 00549 return Selector(new SW_QuantityMin<QuantityE>(Emin)); 00550 } 00551 00552 // returns a selector for a maximum E 00553 Selector SelectorEMax(double Emax) { 00554 return Selector(new SW_QuantityMax<QuantityE>(Emax)); 00555 } 00556 00557 // returns a selector for a E range 00558 Selector SelectorERange(double Emin, double Emax) { 00559 return Selector(new SW_QuantityRange<QuantityE>(Emin, Emax)); 00560 } 00561 00562 00563 //---------------------------------------------------------------------- 00564 /// helper class for selecting on mass 00565 class QuantityM2 : public QuantitySquareBase{ 00566 public: 00567 QuantityM2(double m) : QuantitySquareBase(m){} 00568 virtual double operator()(const PseudoJet & jet ) const { return jet.m2();} 00569 virtual string description() const {return "m";} 00570 }; 00571 00572 // returns a selector for a minimum m 00573 Selector SelectorMMin(double mmin) { 00574 return Selector(new SW_QuantityMin<QuantityM2>(mmin*mmin)); 00575 } 00576 00577 // returns a selector for a maximum m 00578 Selector SelectorMMax(double mmax) { 00579 return Selector(new SW_QuantityMax<QuantityM2>(mmax*mmax)); 00580 } 00581 00582 // returns a selector for a m range 00583 Selector SelectorMRange(double mmin, double mmax) { 00584 return Selector(new SW_QuantityRange<QuantityM2>(mmin*mmin, mmax*mmax)); 00585 } 00586 00587 00588 00589 //---------------------------------------------------------------------- 00590 /// helper for selecting on rapidities: quantity 00591 class QuantityRap : public QuantityBase{ 00592 public: 00593 QuantityRap(double rap) : QuantityBase(rap){} 00594 virtual double operator()(const PseudoJet & jet ) const { return jet.rap();} 00595 virtual string description() const {return "rap";} 00596 }; 00597 00598 00599 /// helper for selecting on rapidities: min 00600 class SW_RapMin : public SW_QuantityMin<QuantityRap>{ 00601 public: 00602 SW_RapMin(double rapmin) : SW_QuantityMin<QuantityRap>(rapmin){} 00603 virtual void get_rapidity_extent(double &rapmin, double & rapmax) const{ 00604 rapmax = std::numeric_limits<double>::max(); 00605 rapmin = _qmin.comparison_value(); 00606 } 00607 }; 00608 00609 /// helper for selecting on rapidities: max 00610 class SW_RapMax : public SW_QuantityMax<QuantityRap>{ 00611 public: 00612 SW_RapMax(double rapmax) : SW_QuantityMax<QuantityRap>(rapmax){} 00613 virtual void get_rapidity_extent(double &rapmin, double & rapmax) const{ 00614 rapmax = _qmax.comparison_value(); 00615 rapmin = -std::numeric_limits<double>::max(); 00616 } 00617 }; 00618 00619 /// helper for selecting on rapidities: range 00620 class SW_RapRange : public SW_QuantityRange<QuantityRap>{ 00621 public: 00622 SW_RapRange(double rapmin, double rapmax) : SW_QuantityRange<QuantityRap>(rapmin, rapmax){ 00623 assert(rapmin<=rapmax); 00624 } 00625 virtual void get_rapidity_extent(double &rapmin, double & rapmax) const{ 00626 rapmax = _qmax.comparison_value(); 00627 rapmin = _qmin.comparison_value(); 00628 } 00629 virtual bool has_area() const { return true;} ///< it has a finite area 00630 virtual bool has_known_area() const { return true;} ///< the area is analytically known 00631 virtual double known_area() const { 00632 return twopi * (_qmax.comparison_value()-_qmin.comparison_value()); 00633 } 00634 }; 00635 00636 // returns a selector for a minimum rapidity 00637 Selector SelectorRapMin(double rapmin) { 00638 return Selector(new SW_RapMin(rapmin)); 00639 } 00640 00641 // returns a selector for a maximum rapidity 00642 Selector SelectorRapMax(double rapmax) { 00643 return Selector(new SW_RapMax(rapmax)); 00644 } 00645 00646 // returns a selector for a rapidity range 00647 Selector SelectorRapRange(double rapmin, double rapmax) { 00648 return Selector(new SW_RapRange(rapmin, rapmax)); 00649 } 00650 00651 00652 //---------------------------------------------------------------------- 00653 /// helper for selecting on |rapidities| 00654 class QuantityAbsRap : public QuantityBase{ 00655 public: 00656 QuantityAbsRap(double absrap) : QuantityBase(absrap){} 00657 virtual double operator()(const PseudoJet & jet ) const { return abs(jet.rap());} 00658 virtual string description() const {return "|rap|";} 00659 }; 00660 00661 00662 /// helper for selecting on |rapidities|: max 00663 class SW_AbsRapMax : public SW_QuantityMax<QuantityAbsRap>{ 00664 public: 00665 SW_AbsRapMax(double absrapmax) : SW_QuantityMax<QuantityAbsRap>(absrapmax){} 00666 virtual void get_rapidity_extent(double &rapmin, double & rapmax) const{ 00667 rapmax = _qmax.comparison_value(); 00668 rapmin = -_qmax.comparison_value(); 00669 } 00670 virtual bool has_area() const { return true;} ///< it has a finite area 00671 virtual bool has_known_area() const { return true;} ///< the area is analytically known 00672 virtual double known_area() const { 00673 return twopi * 2 * _qmax.comparison_value(); 00674 } 00675 }; 00676 00677 /// helper for selecting on |rapidities|: max 00678 class SW_AbsRapRange : public SW_QuantityRange<QuantityAbsRap>{ 00679 public: 00680 SW_AbsRapRange(double absrapmin, double absrapmax) : SW_QuantityRange<QuantityAbsRap>(absrapmin, absrapmax){} 00681 virtual void get_rapidity_extent(double &rapmin, double & rapmax) const{ 00682 rapmax = _qmax.comparison_value(); 00683 rapmin = -_qmax.comparison_value(); 00684 } 00685 virtual bool has_area() const { return true;} ///< it has a finite area 00686 virtual bool has_known_area() const { return true;} ///< the area is analytically known 00687 virtual double known_area() const { 00688 return twopi * 2 * (_qmax.comparison_value()-max(_qmin.comparison_value(),0.0)); // this shold handle properly absrapmin<0 00689 } 00690 }; 00691 00692 // returns a selector for a minimum |rapidity| 00693 Selector SelectorAbsRapMin(double absrapmin) { 00694 return Selector(new SW_QuantityMin<QuantityAbsRap>(absrapmin)); 00695 } 00696 00697 // returns a selector for a maximum |rapidity| 00698 Selector SelectorAbsRapMax(double absrapmax) { 00699 return Selector(new SW_AbsRapMax(absrapmax)); 00700 } 00701 00702 // returns a selector for a |rapidity| range 00703 Selector SelectorAbsRapRange(double rapmin, double rapmax) { 00704 return Selector(new SW_AbsRapRange(rapmin, rapmax)); 00705 } 00706 00707 00708 //---------------------------------------------------------------------- 00709 /// helper for selecting on pseudo-rapidities 00710 class QuantityEta : public QuantityBase{ 00711 public: 00712 QuantityEta(double eta) : QuantityBase(eta){} 00713 virtual double operator()(const PseudoJet & jet ) const { return jet.eta();} 00714 virtual string description() const {return "eta";} 00715 }; 00716 00717 // returns a selector for a pseudo-minimum rapidity 00718 Selector SelectorEtaMin(double etamin) { 00719 return Selector(new SW_QuantityMin<QuantityEta>(etamin)); 00720 } 00721 00722 // returns a selector for a pseudo-maximum rapidity 00723 Selector SelectorEtaMax(double etamax) { 00724 return Selector(new SW_QuantityMax<QuantityEta>(etamax)); 00725 } 00726 00727 // returns a selector for a pseudo-rapidity range 00728 Selector SelectorEtaRange(double etamin, double etamax) { 00729 return Selector(new SW_QuantityRange<QuantityEta>(etamin, etamax)); 00730 } 00731 00732 00733 //---------------------------------------------------------------------- 00734 /// helper for selecting on |pseudo-rapidities| 00735 class QuantityAbsEta : public QuantityBase{ 00736 public: 00737 QuantityAbsEta(double abseta) : QuantityBase(abseta){} 00738 virtual double operator()(const PseudoJet & jet ) const { return abs(jet.eta());} 00739 virtual string description() const {return "|eta|";} 00740 }; 00741 00742 // returns a selector for a minimum |pseudo-rapidity| 00743 Selector SelectorAbsEtaMin(double absetamin) { 00744 return Selector(new SW_QuantityMin<QuantityAbsEta>(absetamin)); 00745 } 00746 00747 // returns a selector for a maximum |pseudo-rapidity| 00748 Selector SelectorAbsEtaMax(double absetamax) { 00749 return Selector(new SW_QuantityMax<QuantityAbsEta>(absetamax)); 00750 } 00751 00752 // returns a selector for a |pseudo-rapidity| range 00753 Selector SelectorAbsEtaRange(double absetamin, double absetamax) { 00754 return Selector(new SW_QuantityRange<QuantityAbsEta>(absetamin, absetamax)); 00755 } 00756 00757 00758 //---------------------------------------------------------------------- 00759 /// helper for selecting on azimuthal angle 00760 /// 00761 /// Note that the bounds have to be specified as min<max 00762 /// phimin has to be > -2pi 00763 /// phimax has to be < 4pi 00764 class SW_PhiRange : public SelectorWorker { 00765 public: 00766 /// detfault ctor (initialises the pt cut) 00767 SW_PhiRange(double phimin, double phimax) : _phimin(phimin), _phimax(phimax){ 00768 assert(_phimin<_phimax); 00769 assert(_phimin>-twopi); 00770 assert(_phimax<2*twopi); 00771 00772 _phispan = _phimax - _phimin; 00773 } 00774 00775 /// returns true is the given object passes the selection pt cut 00776 virtual bool pass(const PseudoJet & jet) const { 00777 double dphi=jet.phi()-_phimin; 00778 if (dphi >= twopi) dphi -= twopi; 00779 if (dphi < 0) dphi += twopi; 00780 return (dphi <= _phispan); 00781 } 00782 00783 /// returns a description of the worker 00784 virtual string description() const { 00785 ostringstream ostr; 00786 ostr << _phimin << " <= phi <= " << _phimax; 00787 return ostr.str(); 00788 } 00789 00790 protected: 00791 double _phimin; // the lower cut 00792 double _phimax; // the upper cut 00793 double _phispan; // the span of the range 00794 }; 00795 00796 00797 // returns a selector for a phi range 00798 Selector SelectorPhiRange(double phimin, double phimax) { 00799 return Selector(new SW_PhiRange(phimin, phimax)); 00800 } 00801 00802 //---------------------------------------------------------------------- 00803 /// helper for selecting on both rapidity and azimuthal angle 00804 class SW_RapPhiRange : public SW_And{ 00805 public: 00806 SW_RapPhiRange(double rapmin, double rapmax, double phimin, double phimax) 00807 : SW_And(SelectorRapRange(rapmin, rapmax), SelectorPhiRange(phimin, phimax)){ 00808 _known_area = ((phimax-phimin > twopi) ? twopi : phimax-phimin) * (rapmax-rapmin); 00809 } 00810 00811 /// check if it has a finite area 00812 virtual bool has_area() const { return true;} 00813 00814 /// check if it has an analytically computable area 00815 virtual bool has_known_area() const { return true;} 00816 00817 /// if it has a computable area, return it 00818 virtual double known_area() const{ 00819 return _known_area; 00820 } 00821 00822 protected: 00823 double _known_area; 00824 }; 00825 00826 Selector SelectorRapPhiRange(double rapmin, double rapmax, double phimin, double phimax) { 00827 return Selector(new SW_RapPhiRange(rapmin, rapmax, phimin, phimax)); 00828 } 00829 00830 00831 //---------------------------------------------------------------------- 00832 /// helper for selecting the n hardest jets 00833 class SW_NHardest : public SelectorWorker { 00834 public: 00835 /// ctor with specification of the number of objects to keep 00836 SW_NHardest(unsigned int n) : _n(n) {}; 00837 00838 /// pass makes no sense here normally the parent selector will throw 00839 /// an error but for internal use in the SW, we'll throw one from 00840 /// here by security 00841 virtual bool pass(const PseudoJet & jet) const { 00842 if (!applies_jet_by_jet()) 00843 throw Error("Cannot apply this selector worker to an individual jet"); 00844 return false; 00845 } 00846 00847 /// For each jet that does not pass the cuts, this routine sets the 00848 /// pointer to 0. 00849 virtual void terminator(vector<const PseudoJet *> & jets) const { 00850 // nothing to do if the size is too small 00851 if (jets.size() < _n) return; 00852 00853 // do we want to first chech if things are already ordered before 00854 // going through the ordering process? 00855 00856 vector<double> minus_pt2(jets.size()); 00857 vector<unsigned int> indices(jets.size()); 00858 00859 for (unsigned int i=0; i<jets.size(); i++){ 00860 indices[i] = i; 00861 00862 // we need to make sure that the object has not already been 00863 // nullified. Note that if we have less than _n jets, this 00864 // whole n-hardest selection will not have any effect. 00865 minus_pt2[i] = jets[i] ? -jets[i]->perp2() : 0.0; 00866 } 00867 00868 IndexedSortHelper sort_helper(& minus_pt2); 00869 00870 partial_sort(indices.begin(), indices.begin()+_n, indices.end(), sort_helper); 00871 00872 for (unsigned int i=_n; i<jets.size(); i++) 00873 jets[indices[i]] = NULL; 00874 } 00875 00876 /// returns true if this can be applied jet by jet 00877 virtual bool applies_jet_by_jet() const {return false;} 00878 00879 /// returns a description of the worker 00880 virtual string description() const { 00881 ostringstream ostr; 00882 ostr << _n << " hardest"; 00883 return ostr.str(); 00884 } 00885 00886 protected: 00887 unsigned int _n; 00888 }; 00889 00890 00891 // returns a selector for the n hardest jets 00892 Selector SelectorNHardest(unsigned int n) { 00893 return Selector(new SW_NHardest(n)); 00894 } 00895 00896 00897 00898 //---------------------------------------------------------------------- 00899 // selector and workers for geometric ranges 00900 //---------------------------------------------------------------------- 00901 00902 //---------------------------------------------------------------------- 00903 /// a generic class for objects that contain a position 00904 class SW_WithReference : public SelectorWorker{ 00905 public: 00906 /// ctor 00907 SW_WithReference() : _is_initialised(false){}; 00908 00909 /// returns true if the worker takes a reference jet 00910 virtual bool takes_reference() const { return true;} 00911 00912 /// sets the reference jet 00913 virtual void set_reference(const PseudoJet ¢re){ 00914 _is_initialised = true; 00915 _reference = centre; 00916 } 00917 00918 protected: 00919 PseudoJet _reference; 00920 bool _is_initialised; 00921 }; 00922 00923 //---------------------------------------------------------------------- 00924 /// helper for selecting on objects within a distance 'radius' of a reference 00925 class SW_Circle : public SW_WithReference { 00926 public: 00927 SW_Circle(const double &radius) : _radius2(radius*radius) {} 00928 00929 /// return a copy of the current object 00930 virtual SelectorWorker* copy(){ return new SW_Circle(*this);} 00931 00932 /// returns true if a given object passes the selection criterium 00933 /// this has to be overloaded by derived workers 00934 virtual bool pass(const PseudoJet & jet) const { 00935 // make sure the centre is initialised 00936 if (! _is_initialised) 00937 throw Error("To use a SelectorCircle (or any selector that requires a reference), you first have to call set_reference(...)"); 00938 00939 return jet.squared_distance(_reference) <= _radius2; 00940 } 00941 00942 /// returns a description of the worker 00943 virtual string description() const { 00944 ostringstream ostr; 00945 ostr << "distance from the centre <= " << sqrt(_radius2); 00946 return ostr.str(); 00947 } 00948 00949 /// returns the rapidity range for which it may return "true" 00950 virtual void get_rapidity_extent(double & rapmin, double & rapmax) const{ 00951 // make sure the centre is initialised 00952 if (! _is_initialised) 00953 throw Error("To use a SelectorCircle (or any selector that requires a reference), you first have to call set_reference(...)"); 00954 00955 rapmax = _reference.rap()+sqrt(_radius2); 00956 rapmin = _reference.rap()-sqrt(_radius2); 00957 } 00958 00959 virtual bool has_area() const { return true;} ///< it has a finite area 00960 virtual bool has_known_area() const { return true;} ///< the area is analytically known 00961 virtual double known_area() const { 00962 return pi * _radius2; 00963 } 00964 00965 protected: 00966 double _radius2; 00967 }; 00968 00969 00970 // select on objets within a distance 'radius' of a variable location 00971 Selector SelectorCircle(const double & radius) { 00972 return Selector(new SW_Circle(radius)); 00973 } 00974 00975 00976 //---------------------------------------------------------------------- 00977 /// helper for selecting on objects with a distance to a reference 00978 /// betwene 'radius_in' and 'radius_out' 00979 class SW_Doughnut : public SW_WithReference { 00980 public: 00981 SW_Doughnut(const double &radius_in, const double &radius_out) 00982 : _radius_in2(radius_in*radius_in), _radius_out2(radius_out*radius_out) {} 00983 00984 /// return a copy of the current object 00985 virtual SelectorWorker* copy(){ return new SW_Doughnut(*this);} 00986 00987 /// returns true if a given object passes the selection criterium 00988 /// this has to be overloaded by derived workers 00989 virtual bool pass(const PseudoJet & jet) const { 00990 // make sure the centre is initialised 00991 if (! _is_initialised) 00992 throw Error("To use a SelectorDoughnut (or any selector that requires a reference), you first have to call set_reference(...)"); 00993 00994 double distance2 = jet.squared_distance(_reference); 00995 00996 return (distance2 <= _radius_out2) && (distance2 >= _radius_in2); 00997 } 00998 00999 /// returns a description of the worker 01000 virtual string description() const { 01001 ostringstream ostr; 01002 ostr << sqrt(_radius_in2) << " <= distance from the centre <= " << sqrt(_radius_out2); 01003 return ostr.str(); 01004 } 01005 01006 /// returns the rapidity range for which it may return "true" 01007 virtual void get_rapidity_extent(double & rapmin, double & rapmax) const{ 01008 // make sure the centre is initialised 01009 if (! _is_initialised) 01010 throw Error("To use a SelectorDoughnut (or any selector that requires a reference), you first have to call set_reference(...)"); 01011 01012 rapmax = _reference.rap()+sqrt(_radius_out2); 01013 rapmin = _reference.rap()-sqrt(_radius_out2); 01014 } 01015 01016 virtual bool has_area() const { return true;} ///< it has a finite area 01017 virtual bool has_known_area() const { return true;} ///< the area is analytically known 01018 virtual double known_area() const { 01019 return pi * (_radius_out2-_radius_in2); 01020 } 01021 01022 protected: 01023 double _radius_in2, _radius_out2; 01024 }; 01025 01026 01027 01028 // select on objets with distance from the centre is between 'radius_in' and 'radius_out' 01029 Selector SelectorDoughnut(const double & radius_in, const double & radius_out) { 01030 return Selector(new SW_Doughnut(radius_in, radius_out)); 01031 } 01032 01033 01034 //---------------------------------------------------------------------- 01035 /// helper for selecting on objects with rapidity within a distance 'delta' of a reference 01036 class SW_Strip : public SW_WithReference { 01037 public: 01038 SW_Strip(const double &delta) : _delta(delta) {} 01039 01040 /// return a copy of the current object 01041 virtual SelectorWorker* copy(){ return new SW_Strip(*this);} 01042 01043 /// returns true if a given object passes the selection criterium 01044 /// this has to be overloaded by derived workers 01045 virtual bool pass(const PseudoJet & jet) const { 01046 // make sure the centre is initialised 01047 if (! _is_initialised) 01048 throw Error("To use a SelectorStrip (or any selector that requires a reference), you first have to call set_reference(...)"); 01049 01050 return abs(jet.rap()-_reference.rap()) <= _delta; 01051 } 01052 01053 /// returns a description of the worker 01054 virtual string description() const { 01055 ostringstream ostr; 01056 ostr << "|rap - rap_reference| <= " << _delta; 01057 return ostr.str(); 01058 } 01059 01060 /// returns the rapidity range for which it may return "true" 01061 virtual void get_rapidity_extent(double & rapmin, double & rapmax) const{ 01062 // make sure the centre is initialised 01063 if (! _is_initialised) 01064 throw Error("To use a SelectorStrip (or any selector that requires a reference), you first have to call set_reference(...)"); 01065 01066 rapmax = _reference.rap()+_delta; 01067 rapmin = _reference.rap()-_delta; 01068 } 01069 01070 virtual bool has_area() const { return true;} ///< it has a finite area 01071 virtual bool has_known_area() const { return true;} ///< the area is analytically known 01072 virtual double known_area() const { 01073 return twopi * 2 * _delta; 01074 } 01075 01076 protected: 01077 double _delta; 01078 }; 01079 01080 01081 // select on objets within a distance 'radius' of a variable location 01082 Selector SelectorStrip(const double & half_width) { 01083 return Selector(new SW_Strip(half_width)); 01084 } 01085 01086 01087 //---------------------------------------------------------------------- 01088 /// helper for selecting on objects with rapidity within a distance 01089 /// 'delta_rap' of a reference and phi within a distanve delta_phi of 01090 /// a reference 01091 class SW_Rectangle : public SW_WithReference { 01092 public: 01093 SW_Rectangle(const double &delta_rap, const double &delta_phi) 01094 : _delta_rap(delta_rap), _delta_phi(delta_phi) {} 01095 01096 /// return a copy of the current object 01097 virtual SelectorWorker* copy(){ return new SW_Rectangle(*this);} 01098 01099 /// returns true if a given object passes the selection criterium 01100 /// this has to be overloaded by derived workers 01101 virtual bool pass(const PseudoJet & jet) const { 01102 // make sure the centre is initialised 01103 if (! _is_initialised) 01104 throw Error("To use a SelectorRectangle (or any selector that requires a reference), you first have to call set_reference(...)"); 01105 01106 return (abs(jet.rap()-_reference.rap()) <= _delta_rap) && (abs(jet.delta_phi_to(_reference)) <= _delta_phi); 01107 } 01108 01109 /// returns a description of the worker 01110 virtual string description() const { 01111 ostringstream ostr; 01112 ostr << "|rap - rap_reference| <= " << _delta_rap << " && |phi - phi_reference| <= " << _delta_phi ; 01113 return ostr.str(); 01114 } 01115 01116 /// returns the rapidity range for which it may return "true" 01117 virtual void get_rapidity_extent(double & rapmin, double & rapmax) const{ 01118 // make sure the centre is initialised 01119 if (! _is_initialised) 01120 throw Error("To use a SelectorRectangle (or any selector that requires a reference), you first have to call set_reference(...)"); 01121 01122 rapmax = _reference.rap()+_delta_rap; 01123 rapmin = _reference.rap()-_delta_rap; 01124 } 01125 01126 virtual bool has_area() const { return true;} ///< it has a finite area 01127 virtual bool has_known_area() const { return true;} ///< the area is analytically known 01128 virtual double known_area() const { 01129 return 4 * _delta_rap * _delta_phi; 01130 } 01131 01132 protected: 01133 double _delta_rap, _delta_phi; 01134 }; 01135 01136 01137 // select on objets within a distance 'radius' of a variable location 01138 Selector SelectorRectangle(const double & half_rap_width, const double & half_phi_width) { 01139 return Selector(new SW_Rectangle(half_rap_width, half_phi_width)); 01140 } 01141 01142 01143 01144 01145 //---------------------------------------------------------------------- 01146 // additional (mostly helper) selectors 01147 //---------------------------------------------------------------------- 01148 01149 //---------------------------------------------------------------------- 01150 /// helper for selecting the pure ghost 01151 class SW_IsPureGhost : public SelectorWorker { 01152 public: 01153 /// ctor with specification of the number of objects to keep 01154 SW_IsPureGhost(){} 01155 01156 /// return true if the jet is a pure-ghost jet 01157 virtual bool pass(const PseudoJet & jet) const { 01158 // if the jet has no area support then it's certainly not a ghost 01159 if (!jet.has_area()) return false; 01160 01161 // otherwise, just call that method on the jet 01162 return jet.is_pure_ghost(); 01163 } 01164 01165 /// returns a description of the worker 01166 virtual string description() const { return "pure ghost";} 01167 }; 01168 01169 01170 // select objects that are (or are only made of) ghosts 01171 Selector SelectorIsPureGhost(){ 01172 return Selector(new SW_IsPureGhost()); 01173 } 01174 01175 01176 //---------------------------------------------------------------------- 01177 /// helper for selecting the jets that carry at least a given fraction 01178 /// of the reference jet 01179 class SW_PtFractionMin : public SW_WithReference { 01180 public: 01181 /// ctor with specification of the number of objects to keep 01182 SW_PtFractionMin(double fraction) : _fraction2(fraction*fraction){} 01183 01184 /// return a copy of the current object 01185 virtual SelectorWorker* copy(){ return new SW_PtFractionMin(*this);} 01186 01187 /// return true if the jet carries a large enough fraction of the reference. 01188 /// Throw an error if the reference is not initialised. 01189 virtual bool pass(const PseudoJet & jet) const { 01190 // make sure the centre is initialised 01191 if (! _is_initialised) 01192 throw Error("To use a SelectorPtFractionMin (or any selector that requires a reference), you first have to call set_reference(...)"); 01193 01194 // otherwise, just call that method on the jet 01195 return (jet.perp2() >= _fraction2*_reference.perp2()); 01196 } 01197 01198 /// returns a description of the worker 01199 virtual string description() const { 01200 ostringstream ostr; 01201 ostr << "pt >= " << sqrt(_fraction2) << "* pt_ref"; 01202 return ostr.str(); 01203 } 01204 01205 protected: 01206 double _fraction2; 01207 }; 01208 01209 01210 // select objects that carry at least a fraction "fraction" of the reference jet 01211 // (Note that this selectir takes a reference) 01212 Selector SelectorPtFractionMin(double fraction){ 01213 return Selector(new SW_PtFractionMin(fraction)); 01214 } 01215 01216 FASTJET_END_NAMESPACE // defined in fastjet/internal/base.hh
1.7.3