00001 #include <sstream>
00002 #include <algorithm>
00003 #include "fastjet/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
00066
00067 class SW_Identity : public SelectorWorker {
00068 public:
00069
00070 SW_Identity(){}
00071
00072
00073 virtual bool pass(const PseudoJet & jet) const {
00074 return true;
00075 }
00076
00077
00078
00079 virtual void terminator(vector<const PseudoJet *> & jets) const {
00080
00081 return;
00082 }
00083
00084
00085 virtual string description() const { return "Identity";}
00086 };
00087
00088
00089
00090 Selector SelectorIdentity() {
00091 return Selector(new SW_Identity);
00092 }
00093
00094
00095
00096
00097
00098
00099
00100
00101 class SW_Not : public SelectorWorker {
00102 public:
00103
00104 SW_Not(const Selector & s) : _s(s) {}
00105
00106
00107 virtual SelectorWorker* copy(){ return new SW_Not(*this);}
00108
00109
00110
00111 virtual bool pass(const PseudoJet & jet) const {
00112
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
00120 virtual bool applies_jet_by_jet() const {return _s.applies_jet_by_jet();}
00121
00122
00123 virtual void terminator(vector<const PseudoJet *> & jets) const {
00124
00125
00126 if (applies_jet_by_jet()){
00127 SelectorWorker::terminator(jets);
00128 return;
00129 }
00130
00131
00132 vector<const PseudoJet *> s_jets = jets;
00133 _s.worker()->terminator(s_jets);
00134
00135
00136
00137 for (unsigned int i=0; i<s_jets.size(); i++){
00138 if (s_jets[i]) jets[i] = NULL;
00139 }
00140 }
00141
00142
00143 virtual string description() const {
00144 ostringstream ostr;
00145 ostr << "!(" << _s.description() << ")";
00146 return ostr.str();
00147 }
00148
00149
00150 virtual bool takes_reference() const { return _s.takes_reference();}
00151
00152 protected:
00153 Selector _s;
00154 };
00155
00156
00157
00158 Selector operator!(const Selector & s) {
00159 return Selector(new SW_Not(s));
00160 }
00161
00162
00163
00164
00165 class SW_BinaryOperator: public SelectorWorker {
00166 public:
00167
00168 SW_BinaryOperator(const Selector & s1, const Selector & s2) : _s1(s1), _s2(s2) {
00169
00170
00171
00172 _applies_jet_by_jet = _s1.applies_jet_by_jet() && _s2.applies_jet_by_jet();
00173
00174
00175 _takes_reference = _s1.takes_reference() || _s2.takes_reference();
00176
00177
00178 _has_area = _s1.has_area() && _s2.has_area();
00179 }
00180
00181
00182 virtual bool applies_jet_by_jet() const {return _applies_jet_by_jet;}
00183
00184
00185 virtual bool takes_reference() const{
00186 return _takes_reference;
00187 }
00188
00189
00190 virtual void set_reference(const PseudoJet ¢re){
00191 _s1.set_reference(centre);
00192 _s2.set_reference(centre);
00193 }
00194
00195
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
00209 class SW_And: public SW_BinaryOperator {
00210 public:
00211
00212 SW_And(const Selector & s1, const Selector & s2) : SW_BinaryOperator(s1,s2){}
00213
00214
00215 virtual SelectorWorker* copy(){ return new SW_And(*this);}
00216
00217
00218
00219 virtual bool pass(const PseudoJet & jet) const {
00220
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
00228 virtual void terminator(vector<const PseudoJet *> & jets) const {
00229
00230
00231 if (applies_jet_by_jet()){
00232 SelectorWorker::terminator(jets);
00233 return;
00234 }
00235
00236
00237 vector<const PseudoJet *> s1_jets = jets;
00238 _s1.worker()->terminator(s1_jets);
00239
00240
00241 _s2.worker()->terminator(jets);
00242
00243
00244 for (unsigned int i=0; i<jets.size(); i++){
00245 if (! s1_jets[i]) jets[i] = NULL;
00246 }
00247 }
00248
00249
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
00259 virtual string description() const {
00260 ostringstream ostr;
00261 ostr << "(" << _s1.description() << " && " << _s2.description() << ")";
00262 return ostr.str();
00263 }
00264 };
00265
00266
00267
00268 Selector operator&&(const Selector & s1, const Selector & s2) {
00269 return Selector(new SW_And(s1,s2));
00270 }
00271
00272
00273
00274
00275
00276 class SW_Or: public SW_BinaryOperator {
00277 public:
00278
00279 SW_Or(const Selector & s1, const Selector & s2) : SW_BinaryOperator(s1,s2) {}
00280
00281
00282 virtual SelectorWorker* copy(){ return new SW_Or(*this);}
00283
00284
00285
00286 virtual bool pass(const PseudoJet & jet) const {
00287
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
00295 virtual bool applies_jet_by_jet() const {
00296
00297
00298
00299 return _s1.applies_jet_by_jet() && _s2.applies_jet_by_jet();
00300 }
00301
00302
00303 virtual void terminator(vector<const PseudoJet *> & jets) const {
00304
00305
00306 if (applies_jet_by_jet()){
00307 SelectorWorker::terminator(jets);
00308 return;
00309 }
00310
00311
00312 vector<const PseudoJet *> s1_jets = jets;
00313 _s1.worker()->terminator(s1_jets);
00314
00315
00316 _s2.worker()->terminator(jets);
00317
00318
00319
00320 for (unsigned int i=0; i<jets.size(); i++){
00321 if (s1_jets[i]) jets[i] = s1_jets[i];
00322 }
00323 }
00324
00325
00326 virtual string description() const {
00327 ostringstream ostr;
00328 ostr << "(" << _s1.description() << " || " << _s2.description() << ")";
00329 return ostr.str();
00330 }
00331
00332
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
00344 Selector operator ||(const Selector & s1, const Selector & s2) {
00345 return Selector(new SW_Or(s1,s2));
00346 }
00347
00348
00349
00350 class SW_Mult: public SW_And {
00351 public:
00352
00353 SW_Mult(const Selector & s1, const Selector & s2) : SW_And(s1,s2) {}
00354
00355
00356 virtual SelectorWorker* copy(){ return new SW_Mult(*this);}
00357
00358
00359 virtual void terminator(vector<const PseudoJet *> & jets) const {
00360
00361
00362 if (applies_jet_by_jet()){
00363 SelectorWorker::terminator(jets);
00364 return;
00365 }
00366
00367
00368 _s2.worker()->terminator(jets);
00369
00370
00371 _s1.worker()->terminator(jets);
00372 }
00373
00374
00375 virtual string description() const {
00376 ostringstream ostr;
00377 ostr << "(" << _s1.description() << " * " << _s2.description() << ")";
00378 return ostr.str();
00379 }
00380 };
00381
00382
00383
00384 Selector operator*(const Selector & s1, const Selector & s2) {
00385 return Selector(new SW_Mult(s1,s2));
00386 }
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
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
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
00419 template<typename QuantityType>
00420 class SW_QuantityMin : public SelectorWorker{
00421 public:
00422
00423 SW_QuantityMin(double qmin) : _qmin(qmin) {}
00424
00425
00426 virtual bool pass(const PseudoJet & jet) const {return _qmin(jet) >= _qmin.comparison_value();}
00427
00428
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;
00437 };
00438
00439
00440
00441 template<typename QuantityType>
00442 class SW_QuantityMax : public SelectorWorker {
00443 public:
00444
00445 SW_QuantityMax(double qmax) : _qmax(qmax) {}
00446
00447
00448 virtual bool pass(const PseudoJet & jet) const {return _qmax(jet) <= _qmax.comparison_value();}
00449
00450
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;
00459 };
00460
00461
00462
00463 template<typename QuantityType>
00464 class SW_QuantityRange : public SelectorWorker {
00465 public:
00466
00467 SW_QuantityRange(double qmin, double qmax) : _qmin(qmin), _qmax(qmax) {}
00468
00469
00470 virtual bool pass(const PseudoJet & jet) const {
00471 double q = _qmin(jet);
00472 return (q >= _qmin.comparison_value()) && (q <= _qmax.comparison_value());
00473 }
00474
00475
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;
00484 QuantityType _qmax;
00485 };
00486
00487
00488
00489
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
00498 Selector SelectorPtMin(double ptmin) {
00499 return Selector(new SW_QuantityMin<QuantityPt2>(ptmin));
00500 }
00501
00502
00503 Selector SelectorPtMax(double ptmax) {
00504 return Selector(new SW_QuantityMax<QuantityPt2>(ptmax));
00505 }
00506
00507
00508 Selector SelectorPtRange(double ptmin, double ptmax) {
00509 return Selector(new SW_QuantityRange<QuantityPt2>(ptmin, ptmax));
00510 }
00511
00512
00513
00514
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
00523 Selector SelectorEtMin(double Etmin) {
00524 return Selector(new SW_QuantityMin<QuantityEt2>(Etmin*Etmin));
00525 }
00526
00527
00528 Selector SelectorEtMax(double Etmax) {
00529 return Selector(new SW_QuantityMax<QuantityEt2>(Etmax*Etmax));
00530 }
00531
00532
00533 Selector SelectorEtRange(double Etmin, double Etmax) {
00534 return Selector(new SW_QuantityRange<QuantityEt2>(Etmin*Etmin, Etmax*Etmax));
00535 }
00536
00537
00538
00539
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
00548 Selector SelectorEMin(double Emin) {
00549 return Selector(new SW_QuantityMin<QuantityE>(Emin));
00550 }
00551
00552
00553 Selector SelectorEMax(double Emax) {
00554 return Selector(new SW_QuantityMax<QuantityE>(Emax));
00555 }
00556
00557
00558 Selector SelectorERange(double Emin, double Emax) {
00559 return Selector(new SW_QuantityRange<QuantityE>(Emin, Emax));
00560 }
00561
00562
00563
00564
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
00573 Selector SelectorMMin(double mmin) {
00574 return Selector(new SW_QuantityMin<QuantityM2>(mmin*mmin));
00575 }
00576
00577
00578 Selector SelectorMMax(double mmax) {
00579 return Selector(new SW_QuantityMax<QuantityM2>(mmax*mmax));
00580 }
00581
00582
00583 Selector SelectorMRange(double mmin, double mmax) {
00584 return Selector(new SW_QuantityRange<QuantityM2>(mmin*mmin, mmax*mmax));
00585 }
00586
00587
00588
00589
00590
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
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
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
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;}
00630 virtual bool has_known_area() const { return true;}
00631 virtual double known_area() const {
00632 return twopi * (_qmax.comparison_value()-_qmin.comparison_value());
00633 }
00634 };
00635
00636
00637 Selector SelectorRapMin(double rapmin) {
00638 return Selector(new SW_RapMin(rapmin));
00639 }
00640
00641
00642 Selector SelectorRapMax(double rapmax) {
00643 return Selector(new SW_RapMax(rapmax));
00644 }
00645
00646
00647 Selector SelectorRapRange(double rapmin, double rapmax) {
00648 return Selector(new SW_RapRange(rapmin, rapmax));
00649 }
00650
00651
00652
00653
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
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;}
00671 virtual bool has_known_area() const { return true;}
00672 virtual double known_area() const {
00673 return twopi * 2 * _qmax.comparison_value();
00674 }
00675 };
00676
00677
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;}
00686 virtual bool has_known_area() const { return true;}
00687 virtual double known_area() const {
00688 return twopi * 2 * (_qmax.comparison_value()-max(_qmin.comparison_value(),0.0));
00689 }
00690 };
00691
00692
00693 Selector SelectorAbsRapMin(double absrapmin) {
00694 return Selector(new SW_QuantityMin<QuantityAbsRap>(absrapmin));
00695 }
00696
00697
00698 Selector SelectorAbsRapMax(double absrapmax) {
00699 return Selector(new SW_AbsRapMax(absrapmax));
00700 }
00701
00702
00703 Selector SelectorAbsRapRange(double rapmin, double rapmax) {
00704 return Selector(new SW_AbsRapRange(rapmin, rapmax));
00705 }
00706
00707
00708
00709
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
00718 Selector SelectorEtaMin(double etamin) {
00719 return Selector(new SW_QuantityMin<QuantityEta>(etamin));
00720 }
00721
00722
00723 Selector SelectorEtaMax(double etamax) {
00724 return Selector(new SW_QuantityMax<QuantityEta>(etamax));
00725 }
00726
00727
00728 Selector SelectorEtaRange(double etamin, double etamax) {
00729 return Selector(new SW_QuantityRange<QuantityEta>(etamin, etamax));
00730 }
00731
00732
00733
00734
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
00743 Selector SelectorAbsEtaMin(double absetamin) {
00744 return Selector(new SW_QuantityMin<QuantityAbsEta>(absetamin));
00745 }
00746
00747
00748 Selector SelectorAbsEtaMax(double absetamax) {
00749 return Selector(new SW_QuantityMax<QuantityAbsEta>(absetamax));
00750 }
00751
00752
00753 Selector SelectorAbsEtaRange(double absetamin, double absetamax) {
00754 return Selector(new SW_QuantityRange<QuantityAbsEta>(absetamin, absetamax));
00755 }
00756
00757
00758
00759
00760
00761
00762
00763
00764 class SW_PhiRange : public SelectorWorker {
00765 public:
00766
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
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
00784 virtual string description() const {
00785 ostringstream ostr;
00786 ostr << _phimin << " <= phi <= " << _phimax;
00787 return ostr.str();
00788 }
00789
00790 protected:
00791 double _phimin;
00792 double _phimax;
00793 double _phispan;
00794 };
00795
00796
00797
00798 Selector SelectorPhiRange(double phimin, double phimax) {
00799 return Selector(new SW_PhiRange(phimin, phimax));
00800 }
00801
00802
00803
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
00812 virtual bool has_area() const { return true;}
00813
00814
00815 virtual bool has_known_area() const { return true;}
00816
00817
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
00833 class SW_NHardest : public SelectorWorker {
00834 public:
00835
00836 SW_NHardest(unsigned int n) : _n(n) {};
00837
00838
00839
00840
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
00848
00849 virtual void terminator(vector<const PseudoJet *> & jets) const {
00850
00851 if (jets.size() < _n) return;
00852
00853
00854
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
00863
00864
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
00877 virtual bool applies_jet_by_jet() const {return false;}
00878
00879
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
00892 Selector SelectorNHardest(unsigned int n) {
00893 return Selector(new SW_NHardest(n));
00894 }
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904 class SW_WithReference : public SelectorWorker{
00905 public:
00906
00907 SW_WithReference() : _is_initialised(false){};
00908
00909
00910 virtual bool takes_reference() const { return true;}
00911
00912
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
00925 class SW_Circle : public SW_WithReference {
00926 public:
00927 SW_Circle(const double &radius) : _radius2(radius*radius) {}
00928
00929
00930 virtual SelectorWorker* copy(){ return new SW_Circle(*this);}
00931
00932
00933
00934 virtual bool pass(const PseudoJet & jet) const {
00935
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
00943 virtual string description() const {
00944 ostringstream ostr;
00945 ostr << "distance from the centre <= " << sqrt(_radius2);
00946 return ostr.str();
00947 }
00948
00949
00950 virtual void get_rapidity_extent(double & rapmin, double & rapmax) const{
00951
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;}
00960 virtual bool has_known_area() const { return true;}
00961 virtual double known_area() const {
00962 return pi * _radius2;
00963 }
00964
00965 protected:
00966 double _radius2;
00967 };
00968
00969
00970
00971 Selector SelectorCircle(const double & radius) {
00972 return Selector(new SW_Circle(radius));
00973 }
00974
00975
00976
00977
00978
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
00985 virtual SelectorWorker* copy(){ return new SW_Doughnut(*this);}
00986
00987
00988
00989 virtual bool pass(const PseudoJet & jet) const {
00990
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
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
01007 virtual void get_rapidity_extent(double & rapmin, double & rapmax) const{
01008
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;}
01017 virtual bool has_known_area() const { return true;}
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
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
01036 class SW_Strip : public SW_WithReference {
01037 public:
01038 SW_Strip(const double &delta) : _delta(delta) {}
01039
01040
01041 virtual SelectorWorker* copy(){ return new SW_Strip(*this);}
01042
01043
01044
01045 virtual bool pass(const PseudoJet & jet) const {
01046
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
01054 virtual string description() const {
01055 ostringstream ostr;
01056 ostr << "|rap - rap_reference| <= " << _delta;
01057 return ostr.str();
01058 }
01059
01060
01061 virtual void get_rapidity_extent(double & rapmin, double & rapmax) const{
01062
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;}
01071 virtual bool has_known_area() const { return true;}
01072 virtual double known_area() const {
01073 return twopi * 2 * _delta;
01074 }
01075
01076 protected:
01077 double _delta;
01078 };
01079
01080
01081
01082 Selector SelectorStrip(const double & half_width) {
01083 return Selector(new SW_Strip(half_width));
01084 }
01085
01086
01087
01088
01089
01090
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
01097 virtual SelectorWorker* copy(){ return new SW_Rectangle(*this);}
01098
01099
01100
01101 virtual bool pass(const PseudoJet & jet) const {
01102
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
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
01117 virtual void get_rapidity_extent(double & rapmin, double & rapmax) const{
01118
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;}
01127 virtual bool has_known_area() const { return true;}
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
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
01147
01148
01149
01150
01151 class SW_IsPureGhost : public SelectorWorker {
01152 public:
01153
01154 SW_IsPureGhost(){}
01155
01156
01157 virtual bool pass(const PseudoJet & jet) const {
01158
01159 if (!jet.has_area()) return false;
01160
01161
01162 return jet.is_pure_ghost();
01163 }
01164
01165
01166 virtual string description() const { return "pure ghost";}
01167 };
01168
01169
01170
01171 Selector SelectorIsPureGhost(){
01172 return Selector(new SW_IsPureGhost());
01173 }
01174
01175
01176
01177
01178
01179 class SW_PtFractionMin : public SW_WithReference {
01180 public:
01181
01182 SW_PtFractionMin(double fraction) : _fraction2(fraction*fraction){}
01183
01184
01185 virtual SelectorWorker* copy(){ return new SW_PtFractionMin(*this);}
01186
01187
01188
01189 virtual bool pass(const PseudoJet & jet) const {
01190
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
01195 return (jet.perp2() >= _fraction2*_reference.perp2());
01196 }
01197
01198
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
01211
01212 Selector SelectorPtFractionMin(double fraction){
01213 return Selector(new SW_PtFractionMin(fraction));
01214 }
01215
01216 FASTJET_END_NAMESPACE