00001 #include <sstream>
00002 #include <algorithm>
00003 #include "fastjet/tools/Selector.hh"
00004
00005 using namespace std;
00006
00007 FASTJET_BEGIN_NAMESPACE
00008
00009
00010
00011
00012
00013
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
00018
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
00025
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
00040 double Selector::area(double cell_area) const{
00041 if (! has_area()) throw InvalidArea();
00042
00043
00044 if (_worker->has_known_area()) return _worker->known_area();
00045
00046
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
00054
00055
00056
00057 return ghost_spec.ghost_area() * ((*this)(ghosts)).size();
00058 }
00059
00060
00061
00062
00063
00064
00065
00067 class SW_Not : public SelectorWorker {
00068 public:
00070 SW_Not(const Selector & s) : _s(s) {}
00071
00073 virtual SelectorWorker* copy(){ return new SW_Not(*this);}
00074
00077 virtual bool pass(const PseudoJet & jet) const {
00078
00079 if (!applies_jet_by_jet())
00080 throw Error("Cannot apply this selector worker to an individual jet");
00081
00082 return ! _s.pass(jet);
00083 }
00084
00086 virtual bool applies_jet_by_jet() const {return _s.applies_jet_by_jet();}
00087
00089 virtual void terminator(vector<const PseudoJet *> & jets) const {
00090
00091
00092 if (applies_jet_by_jet()){
00093 SelectorWorker::terminator(jets);
00094 return;
00095 }
00096
00097
00098 vector<const PseudoJet *> s_jets = jets;
00099 _s.worker()->terminator(s_jets);
00100
00101
00102
00103 for (unsigned int i=0; i<s_jets.size(); i++){
00104 if (s_jets[i]) jets[i] = NULL;
00105 }
00106 }
00107
00109 virtual string description() const {
00110 ostringstream ostr;
00111 ostr << "!(" << _s.description() << ")";
00112 return ostr.str();
00113 }
00114
00116 virtual bool is_relocatable() const { return _s.is_relocatable();}
00117
00118 protected:
00119 Selector _s;
00120 };
00121
00122
00123
00124 Selector operator!(const Selector & s) {
00125 return Selector(new SW_Not(s));
00126 }
00127
00128
00129
00131 class SW_BinaryOperator: public SelectorWorker {
00132 public:
00134 SW_BinaryOperator(const Selector & s1, const Selector & s2) : _s1(s1), _s2(s2) {
00135
00136
00137
00138 _applies_jet_by_jet = _s1.applies_jet_by_jet() && _s2.applies_jet_by_jet();
00139
00140
00141 _is_relocatable = _s1.is_relocatable() || _s2.is_relocatable();
00142
00143
00144 _has_area = _s1.has_area() && _s2.has_area();
00145 }
00146
00148 virtual bool applies_jet_by_jet() const {return _applies_jet_by_jet;}
00149
00151 virtual bool is_relocatable() const{
00152 return _is_relocatable;
00153 }
00154
00156 virtual void relocate(const PseudoJet ¢re){
00157 _s1.relocate(centre);
00158 _s2.relocate(centre);
00159 }
00160
00162 virtual bool has_area() const { return _has_area;}
00163
00164 protected:
00165 Selector _s1, _s2;
00166 bool _applies_jet_by_jet;
00167 bool _is_relocatable;
00168 bool _has_area;
00169 };
00170
00171
00172
00173
00175 class SW_And: public SW_BinaryOperator {
00176 public:
00178 SW_And(const Selector & s1, const Selector & s2) : SW_BinaryOperator(s1,s2){}
00179
00181 virtual SelectorWorker* copy(){ return new SW_And(*this);}
00182
00185 virtual bool pass(const PseudoJet & jet) const {
00186
00187 if (!applies_jet_by_jet())
00188 throw Error("Cannot apply this selector worker to an individual jet");
00189
00190 return _s1.pass(jet) && _s2.pass(jet);
00191 }
00192
00194 virtual void terminator(vector<const PseudoJet *> & jets) const {
00195
00196
00197 if (applies_jet_by_jet()){
00198 SelectorWorker::terminator(jets);
00199 return;
00200 }
00201
00202
00203 vector<const PseudoJet *> s1_jets = jets;
00204 _s1.worker()->terminator(s1_jets);
00205
00206
00207 _s2.worker()->terminator(jets);
00208
00209
00210 for (unsigned int i=0; i<jets.size(); i++){
00211 if (! s1_jets[i]) jets[i] = NULL;
00212 }
00213 }
00214
00216 virtual void get_rapidity_extent(double & rapmin, double & rapmax) const {
00217 double s1min, s1max, s2min, s2max;
00218 _s1.get_rapidity_extent(s1min, s1max);
00219 _s2.get_rapidity_extent(s2min, s2max);
00220 rapmax = min(s1max, s2max);
00221 rapmin = max(s1min, s2min);
00222 }
00223
00225 virtual string description() const {
00226 ostringstream ostr;
00227 ostr << "(" << _s1.description() << " && " << _s2.description() << ")";
00228 return ostr.str();
00229 }
00230 };
00231
00232
00233
00234 Selector operator&&(const Selector & s1, const Selector & s2) {
00235 return Selector(new SW_And(s1,s2));
00236 }
00237
00238
00239
00240
00242 class SW_Or: public SW_BinaryOperator {
00243 public:
00245 SW_Or(const Selector & s1, const Selector & s2) : SW_BinaryOperator(s1,s2) {}
00246
00248 virtual SelectorWorker* copy(){ return new SW_Or(*this);}
00249
00252 virtual bool pass(const PseudoJet & jet) const {
00253
00254 if (!applies_jet_by_jet())
00255 throw Error("Cannot apply this selector worker to an individual jet");
00256
00257 return _s1.pass(jet) || _s2.pass(jet);
00258 }
00259
00261 virtual bool applies_jet_by_jet() const {
00262
00263
00264
00265 return _s1.applies_jet_by_jet() && _s2.applies_jet_by_jet();
00266 }
00267
00269 virtual void terminator(vector<const PseudoJet *> & jets) const {
00270
00271
00272 if (applies_jet_by_jet()){
00273 SelectorWorker::terminator(jets);
00274 return;
00275 }
00276
00277
00278 vector<const PseudoJet *> s1_jets = jets;
00279 _s1.worker()->terminator(s1_jets);
00280
00281
00282 _s2.worker()->terminator(jets);
00283
00284
00285
00286 for (unsigned int i=0; i<jets.size(); i++){
00287 if (s1_jets[i]) jets[i] = s1_jets[i];
00288 }
00289 }
00290
00292 virtual string description() const {
00293 ostringstream ostr;
00294 ostr << "(" << _s1.description() << " || " << _s2.description() << ")";
00295 return ostr.str();
00296 }
00297
00299 virtual void get_rapidity_extent(double & rapmin, double & rapmax) const {
00300 double s1min, s1max, s2min, s2max;
00301 _s1.get_rapidity_extent(s1min, s1max);
00302 _s2.get_rapidity_extent(s2min, s2max);
00303 rapmax = max(s1max, s2max);
00304 rapmin = min(s1min, s2min);
00305 }
00306 };
00307
00308
00309
00310 Selector operator ||(const Selector & s1, const Selector & s2) {
00311 return Selector(new SW_Or(s1,s2));
00312 }
00313
00314
00316 class SW_Mult: public SW_And {
00317 public:
00319 SW_Mult(const Selector & s1, const Selector & s2) : SW_And(s1,s2) {}
00320
00322 virtual SelectorWorker* copy(){ return new SW_Mult(*this);}
00323
00325 virtual void terminator(vector<const PseudoJet *> & jets) const {
00326
00327
00328 if (applies_jet_by_jet()){
00329 SelectorWorker::terminator(jets);
00330 return;
00331 }
00332
00333
00334 _s2.worker()->terminator(jets);
00335
00336
00337 _s1.worker()->terminator(jets);
00338 }
00339
00341 virtual string description() const {
00342 ostringstream ostr;
00343 ostr << "(" << _s1.description() << " * " << _s2.description() << ")";
00344 return ostr.str();
00345 }
00346 };
00347
00348
00349
00350 Selector operator*(const Selector & s1, const Selector & s2) {
00351 return Selector(new SW_Mult(s1,s2));
00352 }
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364 class QuantityBase{
00365 public:
00366 QuantityBase(double q) : _q(q){}
00367 virtual double operator()(const PseudoJet & jet ) const =0;
00368 virtual string description() const =0;
00369 virtual double comparison_value() const {return _q;}
00370 virtual double description_value() const {return comparison_value();}
00371 protected:
00372 double _q;
00373 };
00374
00375
00376 class QuantitySquareBase : public QuantityBase{
00377 public:
00378 QuantitySquareBase(double sqrtq) : QuantityBase(sqrtq*sqrtq), _sqrtq(sqrtq){}
00379 virtual double description_value() const {return _sqrtq;}
00380 protected:
00381 double _sqrtq;
00382 };
00383
00384
00385 template<typename QuantityType>
00386 class SW_QuantityMin : public SelectorWorker{
00387 public:
00389 SW_QuantityMin(double qmin) : _qmin(qmin) {}
00390
00392 virtual bool pass(const PseudoJet & jet) const {return _qmin(jet) >= _qmin.comparison_value();}
00393
00395 virtual string description() const {
00396 ostringstream ostr;
00397 ostr << _qmin.description() << " >= " << _qmin.description_value();
00398 return ostr.str();
00399 }
00400
00401 protected:
00402 QuantityType _qmin;
00403 };
00404
00405
00406
00407 template<typename QuantityType>
00408 class SW_QuantityMax : public SelectorWorker {
00409 public:
00411 SW_QuantityMax(double qmax) : _qmax(qmax) {}
00412
00414 virtual bool pass(const PseudoJet & jet) const {return _qmax(jet) <= _qmax.comparison_value();}
00415
00417 virtual string description() const {
00418 ostringstream ostr;
00419 ostr << _qmax.description() << " <= " << _qmax.description_value();
00420 return ostr.str();
00421 }
00422
00423 protected:
00424 QuantityType _qmax;
00425 };
00426
00427
00428
00429 template<typename QuantityType>
00430 class SW_QuantityRange : public SelectorWorker {
00431 public:
00433 SW_QuantityRange(double qmin, double qmax) : _qmin(qmin), _qmax(qmax) {}
00434
00436 virtual bool pass(const PseudoJet & jet) const {
00437 double q = _qmin(jet);
00438 return (q >= _qmin.comparison_value()) && (q <= _qmax.comparison_value());
00439 }
00440
00442 virtual string description() const {
00443 ostringstream ostr;
00444 ostr << _qmin.description_value() << " <= " << _qmin.description() << " <= " << _qmax.description_value();
00445 return ostr.str();
00446 }
00447
00448 protected:
00449 QuantityType _qmin;
00450 QuantityType _qmax;
00451 };
00452
00453
00454
00456 class QuantityPt2 : public QuantitySquareBase{
00457 public:
00458 QuantityPt2(double pt) : QuantitySquareBase(pt){}
00459 virtual double operator()(const PseudoJet & jet ) const { return jet.perp2();}
00460 virtual string description() const {return "pt";}
00461 };
00462
00463
00464 Selector SelectorPtMin(double ptmin) {
00465 return Selector(new SW_QuantityMin<QuantityPt2>(ptmin));
00466 }
00467
00468
00469 Selector SelectorPtMax(double ptmax) {
00470 return Selector(new SW_QuantityMax<QuantityPt2>(ptmax));
00471 }
00472
00473
00474 Selector SelectorPtRange(double ptmin, double ptmax) {
00475 return Selector(new SW_QuantityRange<QuantityPt2>(ptmin, ptmax));
00476 }
00477
00478
00479
00481 class QuantityEt2 : public QuantitySquareBase{
00482 public:
00483 QuantityEt2(double Et) : QuantitySquareBase(Et){}
00484 virtual double operator()(const PseudoJet & jet ) const { return jet.Et2();}
00485 virtual string description() const {return "Et";}
00486 };
00487
00488
00489 Selector SelectorEtMin(double Etmin) {
00490 return Selector(new SW_QuantityMin<QuantityEt2>(Etmin*Etmin));
00491 }
00492
00493
00494 Selector SelectorEtMax(double Etmax) {
00495 return Selector(new SW_QuantityMax<QuantityEt2>(Etmax*Etmax));
00496 }
00497
00498
00499 Selector SelectorEtRange(double Etmin, double Etmax) {
00500 return Selector(new SW_QuantityRange<QuantityEt2>(Etmin*Etmin, Etmax*Etmax));
00501 }
00502
00503
00504
00506 class QuantityE : public QuantityBase{
00507 public:
00508 QuantityE(double E) : QuantityBase(E){}
00509 virtual double operator()(const PseudoJet & jet ) const { return jet.E();}
00510 virtual string description() const {return "E";}
00511 };
00512
00513
00514 Selector SelectorEMin(double Emin) {
00515 return Selector(new SW_QuantityMin<QuantityE>(Emin));
00516 }
00517
00518
00519 Selector SelectorEMax(double Emax) {
00520 return Selector(new SW_QuantityMax<QuantityE>(Emax));
00521 }
00522
00523
00524 Selector SelectorERange(double Emin, double Emax) {
00525 return Selector(new SW_QuantityRange<QuantityE>(Emin, Emax));
00526 }
00527
00528
00529
00531 class QuantityM2 : public QuantitySquareBase{
00532 public:
00533 QuantityM2(double m) : QuantitySquareBase(m){}
00534 virtual double operator()(const PseudoJet & jet ) const { return jet.m2();}
00535 virtual string description() const {return "m";}
00536 };
00537
00538
00539 Selector SelectorMMin(double mmin) {
00540 return Selector(new SW_QuantityMin<QuantityM2>(mmin*mmin));
00541 }
00542
00543
00544 Selector SelectorMMax(double mmax) {
00545 return Selector(new SW_QuantityMax<QuantityM2>(mmax*mmax));
00546 }
00547
00548
00549 Selector SelectorMRange(double mmin, double mmax) {
00550 return Selector(new SW_QuantityRange<QuantityM2>(mmin*mmin, mmax*mmax));
00551 }
00552
00553
00554
00555
00557 class QuantityRap : public QuantityBase{
00558 public:
00559 QuantityRap(double rap) : QuantityBase(rap){}
00560 virtual double operator()(const PseudoJet & jet ) const { return jet.rap();}
00561 virtual string description() const {return "rap";}
00562 };
00563
00564
00566 class SW_RapMin : public SW_QuantityMin<QuantityRap>{
00567 public:
00568 SW_RapMin(double rapmin) : SW_QuantityMin<QuantityRap>(rapmin){}
00569 virtual void get_rapidity_extent(double &rapmin, double & rapmax) const{
00570 rapmax = std::numeric_limits<double>::max();
00571 rapmin = _qmin.comparison_value();
00572 }
00573 };
00574
00576 class SW_RapMax : public SW_QuantityMax<QuantityRap>{
00577 public:
00578 SW_RapMax(double rapmax) : SW_QuantityMax<QuantityRap>(rapmax){}
00579 virtual void get_rapidity_extent(double &rapmin, double & rapmax) const{
00580 rapmax = _qmax.comparison_value();
00581 rapmin = -std::numeric_limits<double>::max();
00582 }
00583 };
00584
00586 class SW_RapRange : public SW_QuantityRange<QuantityRap>{
00587 public:
00588 SW_RapRange(double rapmin, double rapmax) : SW_QuantityRange<QuantityRap>(rapmin, rapmax){
00589 assert(rapmin<=rapmax);
00590 }
00591 virtual void get_rapidity_extent(double &rapmin, double & rapmax) const{
00592 rapmax = _qmax.comparison_value();
00593 rapmin = _qmin.comparison_value();
00594 }
00595 virtual bool has_area() const { return true;}
00596 virtual bool has_known_area() const { return true;}
00597 virtual double known_area() const {
00598 return twopi * (_qmax.comparison_value()-_qmin.comparison_value());
00599 }
00600 };
00601
00602
00603 Selector SelectorRapMin(double rapmin) {
00604 return Selector(new SW_RapMin(rapmin));
00605 }
00606
00607
00608 Selector SelectorRapMax(double rapmax) {
00609 return Selector(new SW_RapMax(rapmax));
00610 }
00611
00612
00613 Selector SelectorRapRange(double rapmin, double rapmax) {
00614 return Selector(new SW_RapRange(rapmin, rapmax));
00615 }
00616
00617
00618
00620 class QuantityAbsRap : public QuantityBase{
00621 public:
00622 QuantityAbsRap(double absrap) : QuantityBase(absrap){}
00623 virtual double operator()(const PseudoJet & jet ) const { return abs(jet.rap());}
00624 virtual string description() const {return "|rap|";}
00625 };
00626
00627
00629 class SW_AbsRapMax : public SW_QuantityMax<QuantityAbsRap>{
00630 public:
00631 SW_AbsRapMax(double absrapmax) : SW_QuantityMax<QuantityAbsRap>(absrapmax){}
00632 virtual void get_rapidity_extent(double &rapmin, double & rapmax) const{
00633 rapmax = _qmax.comparison_value();
00634 rapmin = -_qmax.comparison_value();
00635 }
00636 virtual bool has_area() const { return true;}
00637 virtual bool has_known_area() const { return true;}
00638 virtual double known_area() const {
00639 return twopi * 2 * _qmax.comparison_value();
00640 }
00641 };
00642
00644 class SW_AbsRapRange : public SW_QuantityRange<QuantityAbsRap>{
00645 public:
00646 SW_AbsRapRange(double absrapmin, double absrapmax) : SW_QuantityRange<QuantityAbsRap>(absrapmin, absrapmax){}
00647 virtual void get_rapidity_extent(double &rapmin, double & rapmax) const{
00648 rapmax = _qmax.comparison_value();
00649 rapmin = -_qmax.comparison_value();
00650 }
00651 virtual bool has_area() const { return true;}
00652 virtual bool has_known_area() const { return true;}
00653 virtual double known_area() const {
00654 return twopi * 2 * (_qmax.comparison_value()-max(_qmin.comparison_value(),0.0));
00655 }
00656 };
00657
00658
00659 Selector SelectorAbsRapMin(double absrapmin) {
00660 return Selector(new SW_QuantityMin<QuantityAbsRap>(absrapmin));
00661 }
00662
00663
00664 Selector SelectorAbsRapMax(double absrapmax) {
00665 return Selector(new SW_AbsRapMax(absrapmax));
00666 }
00667
00668
00669 Selector SelectorAbsRapRange(double rapmin, double rapmax) {
00670 return Selector(new SW_AbsRapRange(rapmin, rapmax));
00671 }
00672
00673
00674
00676 class QuantityEta : public QuantityBase{
00677 public:
00678 QuantityEta(double eta) : QuantityBase(eta){}
00679 virtual double operator()(const PseudoJet & jet ) const { return jet.eta();}
00680 virtual string description() const {return "eta";}
00681 };
00682
00683
00684 Selector SelectorEtaMin(double etamin) {
00685 return Selector(new SW_QuantityMin<QuantityEta>(etamin));
00686 }
00687
00688
00689 Selector SelectorEtaMax(double etamax) {
00690 return Selector(new SW_QuantityMax<QuantityEta>(etamax));
00691 }
00692
00693
00694 Selector SelectorEtaRange(double etamin, double etamax) {
00695 return Selector(new SW_QuantityRange<QuantityEta>(etamin, etamax));
00696 }
00697
00698
00699
00701 class QuantityAbsEta : public QuantityBase{
00702 public:
00703 QuantityAbsEta(double abseta) : QuantityBase(abseta){}
00704 virtual double operator()(const PseudoJet & jet ) const { return abs(jet.eta());}
00705 virtual string description() const {return "|eta|";}
00706 };
00707
00708
00709 Selector SelectorAbsEtaMin(double absetamin) {
00710 return Selector(new SW_QuantityMin<QuantityAbsEta>(absetamin));
00711 }
00712
00713
00714 Selector SelectorAbsEtaMax(double absetamax) {
00715 return Selector(new SW_QuantityMax<QuantityAbsEta>(absetamax));
00716 }
00717
00718
00719 Selector SelectorAbsEtaRange(double absetamin, double absetamax) {
00720 return Selector(new SW_QuantityRange<QuantityAbsEta>(absetamin, absetamax));
00721 }
00722
00723
00724
00730 class SW_PhiRange : public SelectorWorker {
00731 public:
00733 SW_PhiRange(double phimin, double phimax) : _phimin(phimin), _phimax(phimax){
00734 assert(_phimin<_phimax);
00735 assert(_phimin>-twopi);
00736 assert(_phimax<2*twopi);
00737
00738 _phispan = _phimax - _phimin;
00739 }
00740
00742 virtual bool pass(const PseudoJet & jet) const {
00743 double dphi=jet.phi()-_phimin;
00744 if (dphi >= twopi) dphi -= twopi;
00745 if (dphi < 0) dphi += twopi;
00746 return (dphi <= _phispan);
00747 }
00748
00750 virtual string description() const {
00751 ostringstream ostr;
00752 ostr << _phimin << " <= phi <= " << _phimax;
00753 return ostr.str();
00754 }
00755
00756 protected:
00757 double _phimin;
00758 double _phimax;
00759 double _phispan;
00760 };
00761
00762
00763
00764 Selector SelectorPhiRange(double phimin, double phimax) {
00765 return Selector(new SW_PhiRange(phimin, phimax));
00766 }
00767
00768
00770 class SW_RapPhiRange : public SW_And{
00771 public:
00772 SW_RapPhiRange(double rapmin, double rapmax, double phimin, double phimax)
00773 : SW_And(SelectorRapRange(rapmin, rapmax), SelectorPhiRange(phimin, phimax)){
00774 _known_area = ((phimax-phimin > twopi) ? twopi : phimax-phimin) * (rapmax-rapmin);
00775 }
00776
00778 virtual bool has_area() const { return true;}
00779
00781 virtual bool has_known_area() const { return true;}
00782
00784 virtual double known_area() const{
00785 return _known_area;
00786 }
00787
00788 protected:
00789 double _known_area;
00790 };
00791
00792 Selector SelectorRapPhiRange(double rapmin, double rapmax, double phimin, double phimax) {
00793 return Selector(new SW_RapPhiRange(rapmin, rapmax, phimin, phimax));
00794 }
00795
00796
00797
00799 class SW_NHardest : public SelectorWorker {
00800 public:
00802 SW_NHardest(unsigned int n) : _n(n) {};
00803
00807 virtual bool pass(const PseudoJet & jet) const {
00808 if (!applies_jet_by_jet())
00809 throw Error("Cannot apply this selector worker to an individual jet");
00810 return false;
00811 }
00812
00815 virtual void terminator(vector<const PseudoJet *> & jets) const {
00816
00817
00818
00819 vector<double> minus_pt2(jets.size());
00820 vector<unsigned int> indices(jets.size());
00821
00822 for (unsigned int i=0; i<jets.size(); i++){
00823 indices[i] = i;
00824
00825
00826
00827
00828 minus_pt2[i] = jets[i] ? -jets[i]->perp2() : 0.0;
00829 }
00830
00831 IndexedSortHelper sort_helper(& minus_pt2);
00832
00833 partial_sort(indices.begin(), indices.begin()+_n, indices.end(), sort_helper);
00834
00835 for (unsigned int i=_n; i<jets.size(); i++)
00836 jets[indices[i]] = NULL;
00837 }
00838
00840 virtual bool applies_jet_by_jet() const {return false;}
00841
00843 virtual string description() const {
00844 ostringstream ostr;
00845 ostr << _n << " hardest";
00846 return ostr.str();
00847 }
00848
00849 protected:
00850 unsigned int _n;
00851 };
00852
00853
00854
00855 Selector SelectorNHardest(unsigned int n) {
00856 return Selector(new SW_NHardest(n));
00857 }
00858
00859
00860
00861
00862
00863
00864
00865
00867 class SW_Relocatable : public SelectorWorker{
00868 public:
00870 SW_Relocatable() : _is_initialised(false){};
00871
00873 virtual bool is_relocatable() const { return true;}
00874
00876 virtual void relocate(const PseudoJet ¢re){
00877 _is_initialised = true;
00878 _centre = centre;
00879 }
00880
00881 protected:
00882 PseudoJet _centre;
00883 bool _is_initialised;
00884 };
00885
00886
00888 class SW_Circle : public SW_Relocatable {
00889 public:
00890 SW_Circle(const double &radius) : _radius2(radius*radius) {}
00891
00893 virtual SelectorWorker* copy(){ return new SW_Circle(*this);}
00894
00897 virtual bool pass(const PseudoJet & jet) const {
00898
00899 if (! _is_initialised)
00900 throw Error("To use a SelectorCircle (or any relocatable selector), you first have to call relocate()");
00901
00902 return jet.squared_distance(_centre) <= _radius2;
00903 }
00904
00906 virtual string description() const {
00907 ostringstream ostr;
00908 ostr << "distance from the centre <= " << sqrt(_radius2);
00909 return ostr.str();
00910 }
00911
00913 virtual void get_rapidity_extent(double & rapmin, double & rapmax) const{
00914
00915 if (! _is_initialised)
00916 throw Error("To use a SelectorCircle (or any relocatable selector), you first have to call relocate()");
00917
00918 rapmax = _centre.rap()+sqrt(_radius2);
00919 rapmin = _centre.rap()-sqrt(_radius2);
00920 }
00921
00922 virtual bool has_area() const { return true;}
00923 virtual bool has_known_area() const { return true;}
00924 virtual double known_area() const {
00925 return pi * _radius2;
00926 }
00927
00928 protected:
00929 double _radius2;
00930 };
00931
00932
00933
00934 Selector SelectorCircle(const double & radius) {
00935 return Selector(new SW_Circle(radius));
00936 }
00937
00938
00939
00942 class SW_Doughnut : public SW_Relocatable {
00943 public:
00944 SW_Doughnut(const double &radius_in, const double &radius_out)
00945 : _radius_in2(radius_in*radius_in), _radius_out2(radius_out*radius_out) {}
00946
00948 virtual SelectorWorker* copy(){ return new SW_Doughnut(*this);}
00949
00952 virtual bool pass(const PseudoJet & jet) const {
00953
00954 if (! _is_initialised)
00955 throw Error("To use a SelectorDoughnut (or any relocatable selector), you first have to call relocate()");
00956
00957 double distance2 = jet.squared_distance(_centre);
00958
00959 return (distance2 <= _radius_out2) && (distance2 >= _radius_in2);
00960 }
00961
00963 virtual string description() const {
00964 ostringstream ostr;
00965 ostr << sqrt(_radius_in2) << " <= distance from the centre <= " << sqrt(_radius_out2);
00966 return ostr.str();
00967 }
00968
00970 virtual void get_rapidity_extent(double & rapmin, double & rapmax) const{
00971
00972 if (! _is_initialised)
00973 throw Error("To use a SelectorDoughnut (or any relocatable selector), you first have to call relocate()");
00974
00975 rapmax = _centre.rap()+sqrt(_radius_out2);
00976 rapmin = _centre.rap()-sqrt(_radius_out2);
00977 }
00978
00979 virtual bool has_area() const { return true;}
00980 virtual bool has_known_area() const { return true;}
00981 virtual double known_area() const {
00982 return pi * (_radius_out2-_radius_in2);
00983 }
00984
00985 protected:
00986 double _radius_in2, _radius_out2;
00987 };
00988
00989
00990
00991
00992 Selector SelectorDoughnut(const double & radius_in, const double & radius_out) {
00993 return Selector(new SW_Doughnut(radius_in, radius_out));
00994 }
00995
00996
00997
00999 class SW_Strip : public SW_Relocatable {
01000 public:
01001 SW_Strip(const double &delta) : _delta(delta) {}
01002
01004 virtual SelectorWorker* copy(){ return new SW_Strip(*this);}
01005
01008 virtual bool pass(const PseudoJet & jet) const {
01009
01010 if (! _is_initialised)
01011 throw Error("To use a SelectorStrip (or any relocatable selector), you first have to call relocate()");
01012
01013 return abs(jet.rap()-_centre.rap()) <= _delta;
01014 }
01015
01017 virtual string description() const {
01018 ostringstream ostr;
01019 ostr << "|rap - rap_centre| <= " << _delta;
01020 return ostr.str();
01021 }
01022
01024 virtual void get_rapidity_extent(double & rapmin, double & rapmax) const{
01025
01026 if (! _is_initialised)
01027 throw Error("To use a SelectorStrip (or any relocatable selector), you first have to call relocate()");
01028
01029 rapmax = _centre.rap()+_delta;
01030 rapmin = _centre.rap()-_delta;
01031 }
01032
01033 virtual bool has_area() const { return true;}
01034 virtual bool has_known_area() const { return true;}
01035 virtual double known_area() const {
01036 return twopi * 2 * _delta;
01037 }
01038
01039 protected:
01040 double _delta;
01041 };
01042
01043
01044
01045 Selector SelectorStrip(const double & half_width) {
01046 return Selector(new SW_Strip(half_width));
01047 }
01048
01049
01050
01054 class SW_Rectangle : public SW_Relocatable {
01055 public:
01056 SW_Rectangle(const double &delta_rap, const double &delta_phi)
01057 : _delta_rap(delta_rap), _delta_phi(delta_phi) {}
01058
01060 virtual SelectorWorker* copy(){ return new SW_Rectangle(*this);}
01061
01064 virtual bool pass(const PseudoJet & jet) const {
01065
01066 if (! _is_initialised)
01067 throw Error("To use a SelectorRectangle (or any relocatable selector), you first have to call relocate()");
01068
01069 return (abs(jet.rap()-_centre.rap()) <= _delta_rap) && (abs(jet.delta_phi_to(_centre)) <= _delta_phi);
01070 }
01071
01073 virtual string description() const {
01074 ostringstream ostr;
01075 ostr << "|rap - rap_centre| <= " << _delta_rap << " && |phi - phi_centre| <= " << _delta_phi ;
01076 return ostr.str();
01077 }
01078
01080 virtual void get_rapidity_extent(double & rapmin, double & rapmax) const{
01081
01082 if (! _is_initialised)
01083 throw Error("To use a SelectorRectangle (or any relocatable selector), you first have to call relocate()");
01084
01085 rapmax = _centre.rap()+_delta_rap;
01086 rapmin = _centre.rap()-_delta_rap;
01087 }
01088
01089 virtual bool has_area() const { return true;}
01090 virtual bool has_known_area() const { return true;}
01091 virtual double known_area() const {
01092 return 4 * _delta_rap * _delta_phi;
01093 }
01094
01095 protected:
01096 double _delta_rap, _delta_phi;
01097 };
01098
01099
01100
01101 Selector SelectorRectangle(const double & half_rap_width, const double & half_phi_width) {
01102 return Selector(new SW_Rectangle(half_rap_width, half_phi_width));
01103 }
01104
01105
01106
01107 FASTJET_END_NAMESPACE