Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:31:17

0001 //
0002 //
0003 
0004 /**
0005     @file RunHitFit.h
0006 
0007     @brief Template class of experiment-independent interface to HitFit.
0008 
0009     @author Haryo Sumowidagdo <Suharyo.Sumowidagdo@cern.ch>
0010 
0011     @par Creation date:
0012     May 2009.
0013 
0014     @par Modification History:
0015     Nov 2009: Haryo Sumowidagdo <Suharyo.Sumowidagdo@cern.ch>:
0016     Add doxygen tags for automatic generation of documentation.
0017  */
0018 
0019 #ifndef HITFIT_RUNHITFIT_H
0020 #define HITFIT_RUNHITFIT_H
0021 
0022 #include <algorithm>
0023 
0024 #include "TopQuarkAnalysis/TopHitFit/interface/Defaults_Text.h"
0025 #include "TopQuarkAnalysis/TopHitFit/interface/LeptonTranslatorBase.h"
0026 #include "TopQuarkAnalysis/TopHitFit/interface/JetTranslatorBase.h"
0027 #include "TopQuarkAnalysis/TopHitFit/interface/METTranslatorBase.h"
0028 #include "TopQuarkAnalysis/TopHitFit/interface/Fit_Result.h"
0029 #include "TopQuarkAnalysis/TopHitFit/interface/Lepjets_Event.h"
0030 #include "TopQuarkAnalysis/TopHitFit/interface/Top_Fit.h"
0031 
0032 // Explanation about the MIN/MAX definitions:
0033 //
0034 // For a given number of jets, there is a corresponding number of
0035 // permutations how to assign each jet in the event to the corresponding
0036 // parton-level jet.
0037 // The number of permutations up to 10 jets are given below for Tt and
0038 // TtH events.
0039 //
0040 // NJet         Npermutation (Tt)       Npermutation (TtH)
0041 // 4            24                      --
0042 // 5            120                     --
0043 // 6            360                     360
0044 // 7            840                     2520
0045 // 8            1680                    10080
0046 // 9            3024                    30240
0047 // 10           5040                    75600
0048 //
0049 // The formulas for the number of permutations for Tt and TtH events
0050 // given n jets in the event are
0051 //
0052 //         n!
0053 // Tt:  -------- ; n >= 4
0054 //      (n - 4)!
0055 //
0056 //          n!
0057 // TtH: ---------- ; n >= 6
0058 //      (n - 6)!2!
0059 //
0060 // The current MAX settings are chosen for a maximum number of 8 jets
0061 // Increasing this limit should be done with caution, as it will
0062 // increase the number of permutations rapidly.
0063 //
0064 
0065 namespace hitfit {
0066 
0067   /**
0068     @brief Template class of experiment-independent interface to HitFit.
0069     This class is intended to be used inside the programming environment of
0070     a specific experiment, where each type of physics objects has its
0071     own class/type.  For using HitFit with generic four-vector classes,
0072     user can't use this class and have to use the Top_Fit class directly.
0073     The reason is: this class is designed assuming electron and muon are
0074     represented by different object type, a situation which is guaranteed to
0075     happen in any experiments.
0076     The class contains some static integer constants to limit the maximum
0077     amount of jets in an event before fitting. See the description of those
0078     constants for details.  The numbers of permutations for \f$t\bar{t}\f$ and
0079     \f$t\bar{t}H\f$ as a function of the number of jets
0080     \f$N_{\mathrm{jet}}\f$ in the event for a few values of are
0081 
0082     <center>
0083     <table border="2">
0084 
0085     <tr>
0086     <th>\f$N_{\mathrm{jet}}\f$</th>
0087     <th>\f$N_{t\bar{t}}\f$</th>
0088     <th>\f$N_{t\bar{t}H}\f$</th>
0089     </tr>
0090 
0091     <tr>
0092     <td align="right">4</td>
0093     <td align="right">24</td>
0094     <td align="right">N/A</td>
0095     </tr>
0096 
0097     <tr>
0098     <td align="right">5</td>
0099     <td align="right">120</td>
0100     <td align="right">N/A</td>
0101     </tr>
0102 
0103     <tr>
0104     <td align="right">6</td>
0105     <td align="right">360</td>
0106     <td align="right">360</td>
0107     </tr>
0108 
0109     <tr>
0110     <td align="right">7</td>
0111     <td align="right">840</td>
0112     <td align="right">2520</td>
0113     </tr>
0114 
0115     <tr>
0116     <td align="right">8</td>
0117     <td align="right">1680</td>
0118     <td align="right">20160</td>
0119     </tr>
0120 
0121     </table>
0122     </center>
0123 
0124     If adjusting the limits defined by the static constants is desired, then
0125     please the following formulas.
0126 
0127     The number for possible
0128     permutations, \f$N_{t\bar{t}}\f$, as a function of number of jets,
0129     \f$n\f$, for \f$t\bar{t}\f$ event is given by:
0130     \f[
0131     N_{t\bar{t}}(n) = \frac{n!}{(n-4)!};~ n \ge 4
0132     \f]
0133     The number for possible permutations, \f$N_{t\bar{t}H}\f$, as a
0134     function of number of jets, \f$n\f$, for \f$t\bar{t}H\f$ is given by:
0135     \f[
0136     N_{t\bar{t}}(n) = \frac{n!}{(n-6)!2!};~ n \ge 6
0137     \f]
0138 
0139     @param AElectron The typename of the electron physics object class to
0140     be translated into HitFit's Lepjets_Event_Lep.
0141 
0142     @param AMuon The typename of the muon physics object class to
0143     be translated into HitFit's Lepjets_Event_Lep.
0144 
0145     @param AJet The typename of the jet physics object class to
0146     be translated into HitFit's Lepjets_Event_Jet.
0147 
0148     @param AMet The typename of the missing transverse energy physics
0149     object class be translated into HitFit's Fourvec.
0150 
0151  */
0152   template <class AElectron, class AMuon, class AJet, class AMet>
0153   class RunHitFit {
0154   private:
0155     /**
0156        The translator from AElectron to Lepjets_Event_Lep.
0157      */
0158     LeptonTranslatorBase<AElectron> _ElectronTranslator;
0159 
0160     /**
0161        The translator from AMuon to Lepjets_Event_Lep.
0162      */
0163     LeptonTranslatorBase<AMuon> _MuonTranslator;
0164 
0165     /**
0166        The translator from AJet to Lepjets_Event_Jet.
0167      */
0168     JetTranslatorBase<AJet> _JetTranslator;
0169 
0170     /**
0171        The translator from AMet to Fourvec.
0172      */
0173     METTranslatorBase<AMet> _METTranslator;
0174 
0175     /**
0176        The internal event.
0177        The internal event only contains lepton and missing
0178        transverse energy.
0179      */
0180     Lepjets_Event _event;
0181 
0182     /**
0183        The internal array of jets.
0184        Jets are kept in this array and not added into the internal
0185        event. The reason is: the jet energy correction applied to a jet
0186        is dependent on the assumed jet type (b or light) in the
0187        permutation.  Therefore the decision is to store
0188        jets in their original format/data type.
0189 
0190        Before a fit to a particular permutation is done,
0191        this class convert the jets in this array into
0192        Lepjets_Event_Jet format, taking into consideration
0193        the assumed jet type and applying the appropriate jet energy
0194        correction.
0195      */
0196     std::vector<AJet> _jets;
0197 
0198     /**
0199        Boolean flag which sets whether to use jet resolution
0200        read from file or jet resolution embedded in the physics objects.
0201 
0202        This flag is only set when the FIRST jet is added into the event.
0203 
0204        By default this flag is set to FALSE if user does not specify anything
0205        about which resolution to be used.
0206      */
0207     bool _jetObjRes;
0208 
0209     /**
0210        The interface between the event and the fitting algorithm.
0211      */
0212     Top_Fit _Top_Fit;
0213 
0214     /**
0215        The array of events with permutation information before fitting.
0216      */
0217     std::vector<Lepjets_Event> _Unfitted_Events;
0218 
0219     /**
0220        The results of the kinematic fit.
0221      */
0222     std::vector<Fit_Result> _Fit_Results;
0223 
0224   public:
0225     /**
0226        @brief Constructor.
0227 
0228        @param el The function object to translate from AElectron to
0229        Lepjets_Event_Lep.
0230 
0231        @param mu The function object to translate from AMuon to
0232        Lepjets_Event_Lep.
0233 
0234        @param jet The function object to translate from AJet to
0235        Lepjets_Event_Jet.
0236 
0237        @param met The function object to translate from AMet to
0238        Fourvec.
0239 
0240        @param default_file The path of ASCII text files which contains the
0241        parameter settings for this instance of RunHitFit.
0242 
0243        @param lepw_mass The mass to which the leptonic \f$ W- \f$ boson should be
0244        constrained to.  A value of zero means this constraint will be removed.
0245 
0246        @param hadw_mass The mass to which the hadronic \f$ W- \f$ boson should be
0247        constrained to.  A value of zero means this constraint will be removed.
0248 
0249        @param top_mass The mass to which the top quark should be constrained
0250        to.  A value of zero means this constraint will be removed.
0251      */
0252     RunHitFit(const LeptonTranslatorBase<AElectron>& el,
0253               const LeptonTranslatorBase<AMuon>& mu,
0254               const JetTranslatorBase<AJet>& jet,
0255               const METTranslatorBase<AMet>& met,
0256               const std::string default_file,
0257               double lepw_mass,
0258               double hadw_mass,
0259               double top_mass)
0260         : _ElectronTranslator(el),
0261           _MuonTranslator(mu),
0262           _JetTranslator(jet),
0263           _METTranslator(met),
0264           _event(0, 0),
0265           _jetObjRes(false),
0266           _Top_Fit(Top_Fit_Args(Defaults_Text(default_file)), lepw_mass, hadw_mass, top_mass) {}
0267 
0268     /**
0269        @brief Destructor.
0270      */
0271     ~RunHitFit() {}
0272 
0273     /**
0274        @brief Clear the internal event, fit results, and jets.
0275      */
0276     void clear() {
0277       _event = Lepjets_Event(0, 0);
0278       _jets.clear();
0279       _jetObjRes = false;
0280       _Unfitted_Events.clear();
0281       _Fit_Results.clear();
0282     }
0283 
0284     /**
0285        @brief Add one electron into the internal event.
0286 
0287        @param electron The electron to be added into the internal event.
0288 
0289        @param useObjRes Boolean parameter to indicate if the
0290        user would like to use the resolution embedded in the object,
0291        and not the resolution read when instantiating the class.
0292      */
0293     void AddLepton(const AElectron& electron, bool useObjRes = false) {
0294       _event.add_lep(_ElectronTranslator(electron, electron_label, useObjRes));
0295       return;
0296     }
0297 
0298     /**
0299        @brief Add one muon into the internal event.
0300 
0301        @param muon The muon to be added into the internal event.
0302 
0303        @param useObjRes Boolean parameter to indicate if the
0304        user would like to use the resolution embedded in the object,
0305        and not the resolution read when instantiating the class.
0306     */
0307     void AddLepton(const AMuon& muon, bool useObjRes = false) {
0308       _event.add_lep(_MuonTranslator(muon, muon_label, useObjRes));
0309       return;
0310     }
0311 
0312     /**
0313        @brief Add one jet into the internal event.  This function will
0314        do nothing if the internal event has already contained the maximally
0315        allowed number of jets.
0316 
0317        Explanation about this function: This function does not directly add
0318        the jet into the internal event.  Rather, this function store the
0319        jet in an internal array.
0320        The reason is: jet energy correction
0321        and resolution depends on the jet type in the permutation.
0322        Therefore RunHitFit will only add jet into the event after a specific
0323        jet permutation has been determined.
0324        This is done in the FitAllPermutation function().
0325 
0326        @param jet The jet to be added into the internal event.
0327 
0328        @param useObjRes Boolean parameter to indicate if the
0329        user would like to use the resolution embedded in the object,
0330        and not the resolution read when instantiating the class.
0331     */
0332     void AddJet(const AJet& jet, bool useObjRes = false) {
0333       // Only set flag when adding the first jet
0334       // the additional jets then WILL be treated in the
0335       // same way like the first jet.
0336       if (_jets.empty()) {
0337         _jetObjRes = useObjRes;
0338       }
0339 
0340       if (_jets.size() < MAX_HITFIT_JET) {
0341         _jets.push_back(jet);
0342       }
0343       return;
0344     }
0345 
0346     /**
0347        @brief Set the missing transverse energy of the internal event.
0348      */
0349     void SetMet(const AMet& met, bool useObjRes = false) {
0350       _event.met() = _METTranslator(met, useObjRes);
0351       _event.kt_res() = _METTranslator.KtResolution(met, useObjRes);
0352       return;
0353     }
0354 
0355     /**
0356        @brief Set the \f$k_{T}\f$ resolution of the internal event.
0357 
0358        @param res The resolution.
0359      */
0360     void SetKtResolution(const Resolution& res) {
0361       _event.kt_res() = res;
0362       return;
0363     }
0364 
0365     /**
0366        @brief Set the \f$E_{T}\!\!\!\!/\f$ resolution of the internal event.
0367 
0368        @param res The \f$E_{T}\!\!\!\!/\f$ resolution, same as \f$k_{T}\f$
0369        resolution.
0370      */
0371     void SetMETResolution(const Resolution& res) {
0372       SetKtResolution(res);
0373       return;
0374     }
0375 
0376     /**
0377        @brief Return a constant reference to the underlying Top_Fit object.
0378      */
0379     const Top_Fit& GetTopFit() const { return _Top_Fit; }
0380 
0381     /**
0382        @brief Fit all permutations of the internal event.  Returns the
0383        number of permutations.
0384      */
0385     std::vector<Fit_Result>::size_type FitAllPermutation() {
0386       if (_jets.size() < MIN_HITFIT_JET) {
0387         // For ttbar lepton+jets, a minimum of MIN_HITFIT_JETS jets
0388         // is required
0389         return 0;
0390       }
0391 
0392       if (_jets.size() > MAX_HITFIT_JET) {
0393         // Restrict the maximum number of jets in the fit
0394         // to prevent loop overflow
0395         return 0;
0396       }
0397 
0398       _Unfitted_Events.clear();
0399       _Fit_Results.clear();
0400 
0401       // Prepare the array of jet types for permutation
0402       std::vector<int> jet_types(_jets.size(), unknown_label);
0403       jet_types[0] = lepb_label;
0404       jet_types[1] = hadb_label;
0405       jet_types[2] = hadw1_label;
0406       jet_types[3] = hadw1_label;
0407 
0408       if (_Top_Fit.args().do_higgs_flag() && _jets.size() >= MIN_HITFIT_TTH) {
0409         jet_types[4] = higgs_label;
0410         jet_types[5] = higgs_label;
0411       }
0412 
0413       std::stable_sort(jet_types.begin(), jet_types.end());
0414 
0415       do {
0416         // begin loop over all jet permutation
0417         for (int nusol = 0; nusol != 2; nusol++) {
0418           // loop over two neutrino solution
0419           bool nuz = bool(nusol);
0420 
0421           // Copy the event
0422           Lepjets_Event fev = _event;
0423 
0424           // Add jets into the event, with the assumed type
0425           // in accord with the permutation.
0426           // The translator _JetTranslator will correctly
0427           // return object of Lepjets_Event_Jet with
0428           // jet energy correction applied in accord with
0429           // the assumed jet type (b or light).
0430           for (size_t j = 0; j != _jets.size(); j++) {
0431             fev.add_jet(_JetTranslator(_jets[j], jet_types[j], _jetObjRes));
0432           }
0433 
0434           // Clone fev (intended to be fitted event)
0435           // to ufev (intended to be unfitted event)
0436           Lepjets_Event ufev = fev;
0437 
0438           // Set jet types.
0439           fev.set_jet_types(jet_types);
0440           ufev.set_jet_types(jet_types);
0441 
0442           // Store the unfitted event
0443           _Unfitted_Events.push_back(ufev);
0444 
0445           // Prepare the placeholder for various kinematic quantities
0446           double umwhad;
0447           double utmass;
0448           double mt;
0449           double sigmt;
0450           Column_Vector pullx;
0451           Column_Vector pully;
0452 
0453           // Do the fit
0454           double chisq = _Top_Fit.fit_one_perm(fev, nuz, umwhad, utmass, mt, sigmt, pullx, pully);
0455           // Store output of the fit
0456           _Fit_Results.push_back(Fit_Result(chisq, fev, pullx, pully, umwhad, utmass, mt, sigmt));
0457 
0458         }  // end loop over two neutrino solution
0459 
0460       } while (std::next_permutation(jet_types.begin(), jet_types.end()));
0461       // end loop over all jet permutations
0462 
0463       return _Fit_Results.size();
0464     }
0465 
0466     /**
0467         @brief Return the unfitted events for all permutations.
0468      */
0469     std::vector<Lepjets_Event> GetUnfittedEvent() { return _Unfitted_Events; }
0470 
0471     /**
0472         @brief Return the results of fitting all permutations of the
0473         internal event.
0474      */
0475     std::vector<Fit_Result> GetFitAllPermutation() { return _Fit_Results; }
0476 
0477     /**
0478        Minimum number of jet as input to HitFit in Tt event
0479      */
0480     static const unsigned int MIN_HITFIT_JET = 4;
0481 
0482     /**
0483        Minimum number of jet as input to HitFit in TtH event
0484      */
0485     static const unsigned int MIN_HITFIT_TTH = 6;
0486 
0487     /**
0488        Maximum number of jet as input to HitFit in each event
0489      */
0490     static const unsigned int MAX_HITFIT_JET = 8;
0491 
0492     /**
0493        Maximum number of HitFit permutation in each event.
0494      */
0495     static const unsigned int MAX_HITFIT = 1680;
0496 
0497     /**
0498        Maximum number of fitted variables in HitFit in each event
0499      */
0500     static const unsigned int MAX_HITFIT_VAR = 32;
0501   };
0502 
0503 }  // namespace hitfit
0504 
0505 #endif  // #ifndef RUNHITFIT_H