CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/RecoJets/JetAlgorithms/src/PrunedRecombPlugin.cc

Go to the documentation of this file.
00001 
00002 
00003 // PrunedRecombPlugin.cc
00004 // Last update: 5/28/09 CKV
00005 // PrunedRecomb version: 0.2.0
00006 // Author: Christopher Vermilion <verm@u.washington.edu>
00007 //
00008 // Implements the PrunedRecombPlugin class.  See PrunedRecombPlugin.h for a 
00009 //   description.
00010 //
00012 
00013 #include "PrunedRecombPlugin.h"
00014 
00015 #include <sstream>
00016 #include <cmath>
00017 using namespace std;
00018 
00019 FASTJET_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
00020 
00021 string PrunedRecombPlugin::description () const {
00022         ostringstream desc;
00023   
00024         desc << "Pruned jet algorithm \n"
00025              << "----------------------- \n"
00026              << "Jet finder: " << _find_definition.description()
00027              << "\n----------------------- \n"
00028              << "Prune jets with: " << _prune_definition.description()
00029              << "\n----------------------- \n"
00030                   << "Pruning parameters: "
00031              << "zcut = " << _zcut << ", "
00032              << "Rcut_factor = " << _Rcut_factor << "\n"
00033                   << "----------------------- \n" ;
00034 
00035   return desc.str();
00036 }
00037 
00038 // Meat of the plugin.  This function takes the input particles from input_seq
00039 //   and calls plugin_record_{ij, iB}_recombination repeatedly such that
00040 //   input_seq holds a cluster sequence corresponding to pruned jets
00041 // This function first creates unpruned jets using _find_definition, then uses
00042 //   the prune_definition, along with the PrunedRecombiner, on each jet to
00043 //   produce a pruned jet.  For each of these jets, output_mergings() is called,
00044 //   which reads the history of the pruned sequence and calls the
00045 //   plugin_record functions of input_seq to match this history.
00046 // Branches that are pruned appear in the history as PseudoJets with no
00047 //   children.  For this reason, only inclusive_jets() is sensible to use with
00048 //   the final ClusterSequence.  The substructure, e.g., constituents() of a
00049 //   pruned jet will not include the pruned away branchings.
00050 void PrunedRecombPlugin::run_clustering(ClusterSequence & input_seq) const {
00051                 
00052         vector<PseudoJet> inputs = input_seq.jets();
00053         // Record user_index's so we can match PJ's in pruned jets to PJ's in 
00054         //   input_seq.
00055         // Use i+1 to distinguish from the default, which in some places appears to
00056         //   be 0.
00057         for (unsigned int i = 0; i < inputs.size(); i++)
00058                 inputs[i].set_user_index(i+1);
00059                 
00060         // ClusterSequence for initial (unpruned) jet finding
00061         ClusterSequence unpruned_seq(inputs, _find_definition);
00062         
00063         // now, for each jet, construct a pruned version:
00064         vector<PseudoJet> unpruned_jets
00065                             = sorted_by_pt(unpruned_seq.inclusive_jets(0.0));
00066         for (unsigned int i = 0; i < unpruned_jets.size(); i++) {
00067                 double angle = _characteristic_angle(unpruned_jets[i], unpruned_seq);
00068                 // PrunedRecombiner is just DefaultRecombiner but vetoes on recombinations
00069                 //   that fail a pruning test.  Note that Rcut is proportional to the
00070                 //   characteristic angle of the jet.
00071                 JetDefinition::Recombiner *pruned_recombiner = 
00072                                           new PrunedRecombiner(_zcut, _Rcut_factor*angle);
00073                 _prune_definition.set_recombiner(pruned_recombiner);
00074                 ClusterSequence pruned_seq
00075                                        (unpruned_seq.constituents(unpruned_jets[i]), 
00076                                         _prune_definition);
00077                 delete pruned_recombiner;
00078                 
00079                 // Cluster all the particles in this jet into 1 pruned jet.
00080                 // It is possible, though rare, to have a particle or two not clustered 
00081                 //   into the jet even with R = pi/2.  It doesn't have to be the first 
00082                 //  element of pruned_jets!  Sorting by pT and taking [0] should work...
00083                 vector<PseudoJet> pruned_jets = pruned_seq.inclusive_jets(0.0);
00084                 PseudoJet pruned_jet = sorted_by_pt(pruned_jets)[0];
00085 
00086                 _output_mergings(pruned_seq, input_seq);
00087         }
00088 }
00089 
00090 
00091 // Takes the merging structure of "in_seq" and feeds this into "out_seq" using 
00092 //   _plugin_record_{ij,iB}_recombination().
00093 // PJ's in the input CS should have user_index's that are their (index+1) in 
00094 //        _jets() in the output CS (the output CS should be the input CS to
00095 //        run_clustering()).
00096 // This allows us to build up the same jet in out_seq as already exists in
00097 //   in_seq.                                                                                                                                                                             
00098 void PrunedRecombPlugin::_output_mergings(ClusterSequence & in_seq,
00099                                                ClusterSequence & out_seq) const
00100 {
00101         vector<PseudoJet> p = in_seq.jets();
00102 
00103         // get the history from in_seq
00104         const vector<ClusterSequence::history_element> & hist = in_seq.history();
00105         vector<ClusterSequence::history_element>::const_iterator
00106                 iter = hist.begin();
00107         
00108         // skip particle input elements
00109         while (iter->parent1 == ClusterSequence::InexistentParent)
00110                 iter++;
00111         
00112         // Walk through history.  PseudoJets in in_seq should have a user_index
00113         //   corresponding to their index in out_seq.  Note that when we create a 
00114         //   new PJ via record_ij we need to set the user_index of our local copy.
00115         for (; iter != hist.end(); iter++) {
00116                 int new_jet_index = -1;
00117                 int i1 = p[hist[iter->parent1].jetp_index].user_index() - 1;
00118                 if (iter->parent2 == ClusterSequence::BeamJet) {
00119                         out_seq.plugin_record_iB_recombination(i1, iter->dij);
00120                 } else {
00121                         int i2 = p[hist[iter->parent2].jetp_index].user_index() - 1;
00122                         
00123                         // Check if either parent is equal to the child, indicating pruning.
00124                         //  There is probably a smarter way to keep track of this.
00125                         if (p[iter->jetp_index].e() - p[hist[iter->parent1].jetp_index].e() == 0)
00126                                 // pruned away parent2 -- just give child parent1's index
00127                                 p[iter->jetp_index].set_user_index(p[hist[iter->parent1].jetp_index].user_index());
00128                         else if (p[iter->jetp_index].e() - p[hist[iter->parent2].jetp_index].e() == 0)
00129                                 // pruned away parent1 -- just give child parent2's index
00130                                 p[iter->jetp_index].set_user_index(p[hist[iter->parent2].jetp_index].user_index());
00131                         else {
00132                                 // no pruning -- record combination and index for child
00133                                 out_seq.plugin_record_ij_recombination(i1, i2, iter->dij,
00134                                                                new_jet_index);
00135                                 p[iter->jetp_index].set_user_index(new_jet_index + 1);
00136                         }
00137                 }
00138         }
00139 }
00140 
00141 
00142 
00143 // Helper function to find the characteristic angle of a given jet.
00144 // There are a few reasonable choices for this; we use 2*m/pT.
00145 //   If no parents, return -1.0.
00146 double PrunedRecombPlugin::_characteristic_angle (const PseudoJet & jet, 
00147                                            const ClusterSequence & seq) const
00148 {
00149         PseudoJet p1, p2;
00150         if (! seq.has_parents(jet, p1, p2))
00151                 return -1.0;
00152         else
00153                 //return sqrt(p1.squared_distance(p2));  // DeltaR
00154                 return 2.0*jet.m()/jet.perp();
00155 }
00156 
00157 
00158 FASTJET_END_NAMESPACE      // defined in fastjet/internal/base.hh