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