FastJet 3.0beta1
|
00001 #ifndef __FASTJET_TOOLS_FILTER_HH__ 00002 #define __FASTJET_TOOLS_FILTER_HH__ 00003 00004 //STARTHEADER 00005 // $Id: Filter.hh 2494 2011-08-03 16:39:25Z salam $ 00006 // 00007 // Copyright (c) 2005-2011, Matteo Cacciari, Gavin Salam and Gregory Soyez 00008 // 00009 //---------------------------------------------------------------------- 00010 // This file is part of FastJet. 00011 // 00012 // FastJet is free software; you can redistribute it and/or modify 00013 // it under the terms of the GNU General Public License as published by 00014 // the Free Software Foundation; either version 2 of the License, or 00015 // (at your option) any later version. 00016 // 00017 // The algorithms that underlie FastJet have required considerable 00018 // development and are described in hep-ph/0512210. If you use 00019 // FastJet as part of work towards a scientific publication, please 00020 // include a citation to the FastJet paper. 00021 // 00022 // FastJet is distributed in the hope that it will be useful, 00023 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00024 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00025 // GNU General Public License for more details. 00026 // 00027 // You should have received a copy of the GNU General Public License 00028 // along with FastJet; if not, write to the Free Software 00029 // Foundation, Inc.: 00030 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00031 //---------------------------------------------------------------------- 00032 //ENDHEADER 00033 00034 #include <fastjet/ClusterSequence.hh> 00035 #include <fastjet/Selector.hh> 00036 #include <fastjet/CompositeJetStructure.hh> // to derive the FilterStructure from CompositeJetStructure 00037 #include <fastjet/tools/Transformer.hh> // to derive Filter from Transformer 00038 #include <iostream> 00039 #include <string> 00040 00041 FASTJET_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh 00042 00043 // fwd declarations 00044 class Filter; 00045 class FilterStructure; 00046 00047 //---------------------------------------------------------------------- 00048 /// @ingroup tools_generic 00049 /// \class Filter 00050 /// Class that helps perform filtering/trimming on jets, and optionally 00051 /// subtraction (if rho > 0). 00052 /// 00053 /// Though the original version was applied on Cambridge/Aachen jets, 00054 /// this one takes any jet (that has constituents) and reclusters it 00055 /// with a given algorithm. A user-provided Selector is applied to 00056 /// decide which of the subjets are kept to produce the filtered jet 00057 /// (others are discarded). 00058 /// 00059 /// 00060 /// \section desc Options 00061 /// 00062 /// The constructor has the following arguments: 00063 /// - The first argument is the jet definition to be used to 00064 /// recluster the constituents of the jet to be filtered. 00065 /// - The second argument is a Selector specifying the condition for 00066 /// a subjet to be kept. If the selector takes a reference, the jet 00067 /// being filtered is used. 00068 /// - As an optional 3rd argument, one can pass a value of rho (the 00069 /// estimated background per unit area) in which case, every subjet 00070 /// is subtracted before the selection condition is applied. 00071 /// 00072 /// 00073 /// \section input Input conditions 00074 /// 00075 /// - the original jet must have constituents 00076 /// - if rho>0, the jet must be the result of a Clustering with 00077 /// active area with explicit ghosts support or a merging of 00078 /// such pieces 00079 /// 00080 /// \section output Output/structure 00081 /// 00082 /// - a copy of the original jet is kept 00083 /// - kept pieces are stored under the form of a "CompositeJet" 00084 /// - rejected pieces are also stored in the structure 00085 /// 00086 /// \section usage Usage Examples 00087 /// 00088 /// Filtering as proposed in arXiv:0802.2470 for boosted object 00089 /// reconstruction (and used also in arXiv:0810.1304 for dijet 00090 /// reconstructions) involves two parameters, the filtering radius, 00091 /// Rfilt, and the number of subjets you wish to keep, nfilt. To get a 00092 /// filter of this kind define 00093 /// 00094 /// Filter filter(JetDefinition(cambridge_algorithm,Rfilt), 00095 /// SelectorNHardest(nfilt)); 00096 /// 00097 /// You apply it as follows 00098 /// 00099 /// PseudoJet filtered_jet = filter(jet); 00100 /// 00101 /// To get trimming defined with respect to a jet's pt, 00102 /// arXiv:0912.1342, you need an Rtrim to define subjets and a 00103 /// pt_fraction_min to decide which subjets to keep: 00104 /// 00105 /// Filter trimmer(JetDefinition(cambridge_algorithm,Rfilt), 00106 /// SelectorPtFractionMin(pt_fraction_min)); 00107 /// 00108 /// You then apply it as before 00109 /// 00110 /// PseudoJet trimmed_jet = trimmer(jet); 00111 /// 00112 /// You can then find out which pieces were filtered or trimmed jet is 00113 /// made of by calling 00114 /// 00115 /// trimmed_jet.pieces() 00116 /// 00117 /// Trimming defined with respect to an event's effective mass can 00118 /// be carried out with a SelectorPtMin(...) selector. 00119 /// 00120 /// More sophisticated filters/trimmers can easily be obtained by 00121 /// combining Selectors. 00122 /// 00123 /// [MORE INFO, E.G. ON PIECES REJECTED, SHOULD FOLLOW] 00124 /// 00125 /// 00126 /// \section impl Implementation 00127 /// 00128 /// If the jet was defined with the cambridge/aachen algorithm (or is 00129 /// made of pieces each of which comes from the C/A alg) and the 00130 /// filtering definition is C/A, then the filter does not rerun the 00131 /// C/A algorithm on the constituents, but instead makes use of the 00132 /// existent C/A cluster sequence in the original jet. 00133 /// 00134 /// See also \subpage Example11 for a usage example. 00135 class Filter : public Transformer{ 00136 public: 00137 /// trivial ctor 00138 /// Note: this is just for derived classes 00139 /// a Filter initialised through this constructor will not work! 00140 Filter() : _Rfiltfunc(0){}; 00141 00142 /// define a filter that decomposes a jet into subjets using a 00143 /// generic JetDefinition and then keeps only a subset of these 00144 /// subjets according to a Selector. Optionally, each subjet may be 00145 /// internally bakground-subtracted prior to selection. 00146 /// 00147 /// \param subjet_def the jet definition applied to obtain the subjets 00148 /// \param selector the Selector applied to compute the kept subjets 00149 /// \param rho if non-zero, backgruond-subtract each subjet befor selection 00150 /// 00151 /// Note: internal subtraction only applies on jets that are 00152 /// obtained with a cluster sequence with area support and explicit 00153 /// ghosts 00154 Filter(JetDefinition subjet_def, Selector selector, double rho = 0.0) : 00155 _subjet_def(subjet_def), _Rfiltfunc(0), _Rfilt(-1), _selector(selector), _rho(rho), _subtractor(0) {} 00156 00157 /// Same as the full constructor (see above) but just specifying the radius 00158 /// By default, Cambridge-Aachen is used 00159 /// If the jet (or all its pieces) is obtained with a non-default 00160 /// recombiner, that one will be used 00161 /// \param Rfilt the filtering radius 00162 Filter(double Rfilt, Selector selector, double rho = 0.0) : 00163 _Rfiltfunc(0), _Rfilt(Rfilt), _selector(selector), _rho(rho), _subtractor(0) { 00164 if (_Rfilt<0) 00165 throw Error("Attempt to create a Filter with a negative filtering radius"); 00166 } 00167 00168 /// Same as the full constructor (see above) but just specifying a 00169 /// filtering radius that will depend on the jet being filtered 00170 /// As for the previous case, Cambridge-Aachen is used 00171 /// If the jet (or all its pieces) is obtained with a non-default 00172 /// recombiner, that one will be used 00173 /// \param Rfilt_func the filtering radius function of a PseudoJet 00174 Filter(FunctionOfPseudoJet<double> *Rfilt_func, Selector selector, double rho = 0.0) : 00175 _Rfiltfunc(Rfilt_func), _Rfilt(-1), _selector(selector), _rho(rho), _subtractor(0) {} 00176 00177 /// default dtor 00178 virtual ~Filter(){}; 00179 00180 /// Set a subtractor that is applied to all individual subjets before 00181 /// deciding which ones to keep. It takes precedence over a non-zero rho. 00182 void set_subtractor(const Transformer * subtractor) {_subtractor = subtractor;} 00183 00184 /// runs the filtering and sets kept and rejected to be the jets of interest 00185 /// (with non-zero rho, they will have been subtracted). 00186 /// 00187 /// \param jet the jet that gets filtered 00188 /// \return the filtered jet 00189 virtual PseudoJet result(const PseudoJet & jet) const; 00190 00191 /// class description 00192 virtual std::string description() const; 00193 00194 typedef FilterStructure StructureType; 00195 00196 private: 00197 /// sets filtered_elements to be all the subjets on which filtering will work 00198 /// [NB: this routine is work in progress as part of a transition to a Filter 00199 /// that also works on jet collections] 00200 void _set_filtered_elements(const PseudoJet & jet, 00201 std::vector<PseudoJet> & filtered_elements, 00202 bool & discard_area) const; 00203 00204 /// set the filtered elements in the simple case of C/A+C/A 00205 void _set_filtered_elements_cafilt(const PseudoJet & jet, 00206 std::vector<PseudoJet> & filtered_elements, 00207 double Rfilt) const; 00208 00209 /// set the filtered elements in the generic re-clustering case 00210 void _set_filtered_elements_generic(const PseudoJet & jet, 00211 std::vector<PseudoJet> & filtered_elements) const; 00212 00213 /// gather the information about what is kept and rejected under the 00214 /// form of a PseudoJet with a special ClusterSequenceInfo 00215 PseudoJet _finalise(const PseudoJet & jet, 00216 std::vector<PseudoJet> & kept, 00217 std::vector<PseudoJet> & rejected, 00218 const bool discard_area) const; 00219 00220 // a series of checks 00221 //-------------------------------------------------------------------- 00222 /// get the pieces down to the fundamental pieces 00223 bool _get_all_pieces(const PseudoJet &jet, std::vector<PseudoJet> &all_pieces) const; 00224 00225 /// get the common recombiner to all pieces (NULL if none) 00226 const JetDefinition::Recombiner* _get_common_recombiner() const; 00227 00228 /// check if one can apply the simplified trick for C/A subjets 00229 bool _check_ca() const; 00230 00231 /// check if the jet (or all its pieces) have explicit ghosts 00232 /// (assuming the jet has area support 00233 /// 00234 /// Note that if the jet has an associated cluster sequence that is no 00235 /// longer valid, an error will be thrown 00236 bool _check_explicit_ghosts() const; 00237 00238 bool _uses_subtraction() const {return (_subtractor || _rho != 0);} 00239 00240 mutable JetDefinition _subjet_def; 00241 ///< the jet definition to use to extract the subjets 00242 FunctionOfPseudoJet<double> *_Rfiltfunc; 00243 ///< a dynamic filtering radius function of the jet being filtered 00244 double _Rfilt; ///< a constant specifying the subjet radius (with C/A) 00245 mutable Selector _selector; ///< the subjet selection criterium 00246 double _rho; ///< the background density (used for subtraction when possible) 00247 const Transformer * _subtractor; ///< for subtracting bkgd density from subjets 00248 00249 protected: 00250 // internal useful variables 00251 mutable std::vector<PseudoJet> all_pieces; 00252 }; 00253 00254 00255 00256 //---------------------------------------------------------------------- 00257 /// @ingroup tools_generic 00258 /// \class FilterStructure 00259 /// Class to contain structure information for a filtered jet. 00260 class FilterStructure : public CompositeJetStructure { 00261 public: 00262 /// constructor from an original ClusterSequenceInfo 00263 /// We just share the original ClusterSequenceWrapper and initialise 00264 /// the rest 00265 FilterStructure(const std::vector<PseudoJet> & pieces, 00266 const JetDefinition::Recombiner *rec = 0) 00267 : CompositeJetStructure(pieces, rec){} 00268 00269 /// virtual dtor to allow further overloading 00270 virtual ~FilterStructure(){} 00271 00272 /// description 00273 virtual std::string description() const { return "Filtered PseudoJet"; } 00274 00275 //------------------------------------------------------------------ 00276 /// @name The filter-specific information 00277 //------------------------------------------------------------------ 00278 00279 // /// returns the original jet (the first of the original jets 00280 // /// if you filtered a collection of jets) 00281 // const PseudoJet & original() const {return _original_jet;} 00282 00283 /// returns the subjets that were not kept during the filtering procedure 00284 /// (subtracted if the filter requests it, and valid in the original cs) 00285 const std::vector<PseudoJet> & rejected() const {return _rejected;} 00286 00287 friend class Filter; // allow the filter to change the protected/private members 00288 00289 protected: 00290 // PseudoJet _original_jet; ///< the original jet 00291 std::vector<PseudoJet> _rejected; ///< the subjets rejected by the filter 00292 }; 00293 00294 00295 FASTJET_END_NAMESPACE // defined in fastjet/internal/base.hh 00296 00297 #endif // __FASTJET_TOOLS_FILTER_HH__