00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "fastjet/tools/Filter.hh"
00032 #include <fastjet/ClusterSequenceActiveAreaExplicitGhosts.hh>
00033 #include <cassert>
00034 #include <algorithm>
00035 #include <sstream>
00036
00037 using namespace std;
00038
00039
00040 FASTJET_BEGIN_NAMESPACE
00041
00042
00043
00044
00045
00046
00047
00048 string Filter::description() const {
00049 ostringstream ostr;
00050 ostr << "Filter with subjet_def = ";
00051 ostr << _subjet_def.description();
00052 ostr<< ", and selection " << _selector.description();
00053 return ostr.str();
00054 }
00055
00056
00057
00058 PseudoJet Filter::operator()(const PseudoJet &jet) const {
00059 ClusterSequence *internal_cs;
00060
00061
00062
00063
00064 vector<PseudoJet> subjets;
00065 _set_filtered_elements(jet, subjets, internal_cs);
00066
00067
00068
00069 vector<const PseudoJet*> subjet_pointers;
00070 for (unsigned int i=0;i<subjets.size(); i++)
00071 subjet_pointers.push_back(&(subjets[i]));
00072
00073
00074 if (_selector.takes_reference()) _selector.set_reference(jet);
00075 _selector.nullify_non_selected(subjet_pointers);
00076
00077
00078 vector<PseudoJet> kept, rejected;
00079 for (unsigned int i=0;i<subjets.size(); i++){
00080 if (subjet_pointers[i]==0)
00081 rejected.push_back(subjets[i]);
00082 else
00083 kept.push_back(subjets[i]);
00084 }
00085
00086
00087 return _finalise(jet, kept, rejected, internal_cs);
00088 }
00089
00090
00091
00092 void Filter::_set_filtered_elements(const PseudoJet & jet,
00093 vector<PseudoJet> & filtered_elements,
00094 ClusterSequence * &internal_cs) const {
00095
00096
00097
00098 if (! jet.has_constituents())
00099 throw Error("Filter can only be applied on jets having constituents");
00100
00101
00102
00103 if (_rho != 0.0){
00104 if (!jet.has_area())
00105 throw Error("Attempt to filter and subtract (non-zero rho) without area info for the original jet");
00106
00107 if (!jet.has_associated_cluster_sequence())
00108 throw Error("Attempt to filter and subtract (non-zero rho) without a cluster sequence associated with the jet");
00109
00110
00111
00112
00113 if (!jet.validated_csab()->has_explicit_ghosts())
00114 throw Error("Attempt to filter and subtract (non-zero rho) without explicit ghosts");
00115 }
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125 bool simple_cafilt = (_subjet_def.jet_algorithm() == cambridge_algorithm) && (_recursively_check_ca(jet));
00126
00127
00128
00129 if (simple_cafilt){
00130 _set_filtered_elements_cafilt(jet, filtered_elements, _subjet_def.R());
00131 internal_cs = NULL;
00132 } else {
00133 if (_rho != 0.0){
00134 internal_cs = _set_filtered_elements_generic_subtracted(jet, filtered_elements);
00135 } else {
00136 internal_cs = _set_filtered_elements_generic_unsubtracted(jet, filtered_elements);
00137 }
00138 }
00139
00140
00141 filtered_elements = sorted_by_pt(filtered_elements);
00142 }
00143
00144
00145
00146
00147 PseudoJet Filter::_finalise(const PseudoJet & jet, vector<PseudoJet> & kept, vector<PseudoJet> & rejected, ClusterSequence * &internal_cs) const {
00148 PseudoJet filtered_jet(0.0,0.0,0.0,0.0);
00149
00150
00151 FilteredJetStructure *fi = new FilteredJetStructure();
00152
00153 fi->_original_jet = jet;
00154 fi->_pieces = kept;
00155 fi->_rejected = rejected;
00156
00157 if (internal_cs)
00158 fi->_internal_cs.reset(internal_cs);
00159
00160
00161 const JetDefinition::Recombiner &rec = *(_subjet_def.recombiner());
00162 for (unsigned i = 0; i < kept.size(); i++)
00163 rec.plus_equal(filtered_jet, kept[i]);
00164
00165
00166
00167
00168
00169 filtered_jet.set_cluster_hist_index(jet.cluster_hist_index());
00170 filtered_jet.set_user_index(jet.user_index());
00171
00172
00173 filtered_jet.set_structure_shared_ptr(SharedPtr<PseudoJetStructureBase>(fi));
00174
00175 return filtered_jet;
00176 }
00177
00178
00179
00180 bool Filter::_recursively_check_ca(const PseudoJet & jet) const{
00181 if (jet.has_associated_cluster_sequence())
00182 return jet.associated_cluster_sequence()->jet_def().jet_algorithm() == cambridge_algorithm;
00183
00184 if (jet.has_pieces()){
00185 const vector<PseudoJet> pieces = jet.pieces();
00186 for (vector<PseudoJet>::const_iterator it=pieces.begin(); it!=pieces.end(); it++)
00187 if (!_recursively_check_ca(*it)) return false;
00188 return true;
00189 }
00190
00191 return false;
00192 }
00193
00194
00195
00196
00197
00198
00199
00200 void Filter::_set_filtered_elements_cafilt(const PseudoJet & jet, vector<PseudoJet> & filtered_elements, double Rfilt) const{
00201
00202 if (jet.has_associated_cluster_sequence()){
00203
00204 const ClusterSequence *cs = jet.associated_cluster_sequence();
00205 vector<PseudoJet> local_fe;
00206
00207 double dcut = Rfilt / cs->jet_def().R();
00208 if (dcut>=1.0){
00209 local_fe.push_back(jet);
00210 } else {
00211 dcut *= dcut;
00212 local_fe = jet.exclusive_subjets(dcut);
00213 }
00214
00215
00216
00217
00218 if (_rho != 0.0){
00219 const ClusterSequenceAreaBase * csab = jet.validated_csab();
00220 for (unsigned int i=0;i<local_fe.size();i++)
00221 local_fe[i] = csab->subtracted_jet(local_fe[i], _rho);
00222 }
00223
00224 copy(local_fe.begin(), local_fe.end(), back_inserter(filtered_elements));
00225 return;
00226 }
00227
00228
00229 const vector<PseudoJet> & pieces = jet.pieces();
00230 for (vector<PseudoJet>::const_iterator it = pieces.begin(); it!=pieces.end(); it++)
00231 _set_filtered_elements_cafilt(*it, filtered_elements, Rfilt);
00232 }
00233
00234
00235
00236 ClusterSequence * Filter::_set_filtered_elements_generic_unsubtracted(const PseudoJet & jet,
00237 vector<PseudoJet> & filtered_elements) const{
00238
00239
00240
00241 ClusterSequence * cs = new ClusterSequence(jet.constituents(), _subjet_def);
00242 filtered_elements = cs->inclusive_jets();
00243
00244 return cs;
00245 }
00246
00247
00248 ClusterSequence * Filter::_set_filtered_elements_generic_subtracted(const PseudoJet & jet,
00249 vector<PseudoJet> & filtered_elements) const{
00250
00251
00252
00253
00254
00255 vector<PseudoJet> all_constituents = jet.constituents();
00256 vector<PseudoJet> regular_constituents, ghosts;
00257
00258 for (vector<PseudoJet>::iterator it = all_constituents.begin();
00259 it != all_constituents.end(); it++){
00260 if (it->is_pure_ghost())
00261 ghosts.push_back(*it);
00262 else
00263 regular_constituents.push_back(*it);
00264 }
00265
00266
00267
00268
00269 double ghost_area = (ghosts.size()) ? ghosts[0].area() : 0.01;
00270 ClusterSequenceActiveAreaExplicitGhosts * csa
00271 = new ClusterSequenceActiveAreaExplicitGhosts(regular_constituents, _subjet_def,
00272 ghosts, ghost_area);
00273
00274
00275 filtered_elements = csa->subtracted_jets(_rho);
00276
00277 return csa;
00278 }
00279
00280
00281
00282
00283
00284
00285
00286
00287 FASTJET_END_NAMESPACE