00001 #ifndef __FASTJET_TOOLS_FILTER_HH__ 00002 #define __FASTJET_TOOLS_FILTER_HH__ 00003 00004 //STARTHEADER 00005 // $Id$ 00006 // 00007 // Copyright (c) 2009-2010, 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 FilteredJet structure from CompositeJetStructure 00037 #include "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 FilteredJetStructure; 00046 00047 //---------------------------------------------------------------------- 00048 /// @ingroup tools 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/interface 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, arXiv:0912.1342, you need an Rtrim to define 00102 /// subjets and a pt_fraction_min to decide which subjets to keep: 00103 /// 00104 /// Filter trimmer(JetDefinition(cambridge_algorithm,Rfilt), 00105 /// SelectorPtFractionMin(pt_fraction_min)); 00106 /// 00107 /// You then apply it as before 00108 /// 00109 /// PseudoJet trimmed_jet = trimmer(jet); 00110 /// 00111 /// You can then find out which pieces were filtered or trimmed jet is 00112 /// made of by calling 00113 /// 00114 /// trimmed_jet.pieces() 00115 /// 00116 /// More sophisticated filters/trimmers can easily be obtained by 00117 /// combining Selectors. 00118 /// 00119 /// [MORE INFO, E.G. ON PIECES REJECTED, SHOULD FOLLOW] 00120 /// 00121 /// 00122 /// \section impl Implementation 00123 /// 00124 /// If the jet was defined with the cambridge/aachen algorithm (or is 00125 /// made of pieces each of which comes from the C/A alg) and the 00126 /// filtering definition is C/A, then the filter does not rerun the 00127 /// C/A algorithm on the constituents, but instead makes use of the 00128 /// existent C/A cluster sequence in the original jet. 00129 /// 00130 /// See also \subpage Example12 for a usage example. 00131 class Filter : public Transformer{ 00132 public: 00133 /// trivial ctor 00134 /// Note: this is just for derived classes 00135 /// a Filter initialised through this constructor will not work! 00136 Filter(){}; 00137 00138 /// define a filter that decomposes a jet into subjets using a 00139 /// generic JetDefinition and then keeps only a subset of these 00140 /// subjets according to a Selector. Optionally, each subjet may be 00141 /// internally bakground-subtracted prior to selection. 00142 /// 00143 /// \param subjet_def the jet definition applied to obtain the subjets 00144 /// \param selector the Selector applied to compute the kept subjets 00145 /// \param rho if non-zero, backgruond-subtract each subjet befor selection 00146 /// 00147 /// Note: internal subtraction only applies on jets that are 00148 /// obtained with a cluster sequence with area support and explicit 00149 /// ghosts 00150 Filter(JetDefinition subjet_def, Selector selector, double rho = 0.0) : 00151 _subjet_def(subjet_def), _selector(selector), _rho(rho) {} 00152 00153 /// default dtor 00154 virtual ~Filter(){}; 00155 00156 /// runs the filtering and sets kept and rejected to be the jets of interest 00157 /// (with non-zero rho, they will have been subtracted). 00158 /// 00159 /// \param jet the jet that gets filtered 00160 /// \return the filtered jet 00161 virtual PseudoJet operator()(const PseudoJet & jet) const; 00162 00163 /// action of the transformer on each jet from the vector 00164 /// this has to be repeated because it shares the same name as the operator()(PseudoJet) 00165 virtual std::vector<PseudoJet> operator()(const std::vector<PseudoJet> & originals) const{ 00166 return Transformer::operator()(originals); 00167 } 00168 00169 /// class description 00170 std::string description() const; 00171 00172 typedef FilteredJetStructure StructureType; 00173 00174 protected: 00175 /// sets filtered_elements to be all the subjets on which filtering will work 00176 /// [NB: this routine is work in progress as part of a transition to a Filter 00177 /// that also works on jet collections] 00178 void _set_filtered_elements(const PseudoJet & jet, 00179 std::vector<PseudoJet> & filtered_elements, 00180 ClusterSequence * &internal_cs) const; 00181 00182 /// gather the information about what is kept and rejected under the 00183 /// form of a PseudoJet with a special ClusterSequenceInfo 00184 PseudoJet _finalise(const PseudoJet & jet, 00185 std::vector<PseudoJet> & kept, 00186 std::vector<PseudoJet> & rejected, 00187 ClusterSequence * &internal_cs) const; 00188 00189 /// check if the jet is obtained from C/A or a superposition of C/A pieces 00190 bool _recursively_check_ca(const PseudoJet & jet) const; 00191 00192 /// set the filtered elements in the simple case of C/A+C/A 00193 void _set_filtered_elements_cafilt( 00194 const PseudoJet & jet, 00195 std::vector<PseudoJet> & filtered_elements, 00196 double Rfilt) const; 00197 00198 /// set the filtered elements in the generic re-clustering case (wo subtraction) 00199 ClusterSequence* _set_filtered_elements_generic_unsubtracted( 00200 const PseudoJet & jet, 00201 std::vector<PseudoJet> & filtered_elements) const; 00202 00203 /// set the filtered elements in the generic re-clustering case (with subtraction) 00204 ClusterSequence* _set_filtered_elements_generic_subtracted( 00205 const PseudoJet & jet, 00206 std::vector<PseudoJet> & filtered_elements) const; 00207 00208 JetDefinition _subjet_def; ///< the jet definition to use to extract the subjets 00209 mutable Selector _selector; ///< the subjet selection criterium 00210 double _rho; ///< the background density (used for subtraction when possible) 00211 }; 00212 00213 00214 00215 //---------------------------------------------------------------------- 00216 /// @ingroup tools 00217 /// \class FilteredJetStructure 00218 /// Class to contain structure information for a filtered jet. 00219 class FilteredJetStructure : public CompositeJetStructure { 00220 public: 00221 /// constructor from an original ClusterSequenceInfo 00222 /// We just share the original ClusterSequenceWrapper and initialise 00223 /// the rest 00224 FilteredJetStructure(){} 00225 00226 /// virtual dtor to allow further overloading 00227 virtual ~FilteredJetStructure(){} 00228 00229 /// description 00230 virtual std::string description() const { return "Filtered PseudoJet"; } 00231 00232 //------------------------------------------------------------------ 00233 /// @name The filter-specific information 00234 //------------------------------------------------------------------ 00235 00236 /// returns the original jet (the first of the original jets 00237 /// if you filtered a collection of jets) 00238 const PseudoJet & original() const {return _original_jet;} 00239 00240 /// returns the subjets that were not kept during the filtering procedure 00241 /// (subtracted if the filter requests it, and valid in the original cs) 00242 const std::vector<PseudoJet> & rejected() const {return _rejected;} 00243 00244 friend class Filter; // allow the filter to change the protected/private members 00245 00246 protected: 00247 PseudoJet _original_jet; 00248 std::vector<PseudoJet> _rejected; 00249 00250 SharedPtr<ClusterSequence> _internal_cs; //< for a generic filter (we use a shared-ptr to avoid worrying about memory management) 00251 }; 00252 00253 00254 FASTJET_END_NAMESPACE // defined in fastjet/internal/base.hh 00255 00256 #endif // __FASTJET_TOOLS_FILTER_HH__