Rivet analyses

W + charm production at 7 TeV

Experiment: ATLAS (LHC)

Inspire ID: 1282447

Status: VALIDATED

Authors: - Kristin Lohwasser

References: - Expt page: ATLAS-STDM-2012-14 - JHEP 1405 (2014) 068 - DOI: 10.1007/JHEP05(2014)068 - arXiv: 1402.6263

Beams: p+ p+

Beam energies: (3500.0, 3500.0)GeV

Run details: - W+c and inclusive double production in pp collisions.

This routine implements the measurement of W boson production in association with a single charm quark with 4.6 fb−1 of pp collision data at $\sqrt{s} = 7$~TeV collected with the ATLAS detector at the Large Hadron Collider. Results are quoted for the W boson production decaying into either an electron or muon and the charm quark being identified as any charmed hadron above 5~GeV inside ΔR = 0.4 of a jet with more than 25~GeV. Alternatively the presence of the charm quark is indicated by the presence of a D or a D* meson with a pT above 8~GeV. The cross sections are quoted for the number of opposite sign minus same sign events, where the signs under consideration are the charge of the W boson and the charmed hadrons tagging the event. Given are the integrated and differential cross sections as a function of the pseudorapidity of the lepton from the W-boson decay are measured. Additionally, the cross-section ratios σ(W+ + barc)/σ(W + c) as well as the pT dependent cross sections of the D/D* mesons normalized to the W inclusive cross sections are published. The measured data is unfolded to the Born level. One should therefore take care to run on samples without QED radiation off of the electrons. IMPORTANT NOTICE — For the MC predictions in the paper, the branching fractions to D and D* mesons have been adapted to be 0.2256 (D) and 0.2287 (D*) (LEP/HERA combination). Some suggestion on how to do post-processing – in case separate samples for W+ + c and W + c and inclusive W are used – are included in the cc-file. This post-processing is needed to properly display the histograms for the cross section ratio plots σ(W+ + barc)/σ(W + c) as well as for the cross section ratios of W + D(*) production over inclusive W production (σ(W+/−D(*))/σ(W+/−)) as a function of the D(*) meson transverse momentum.

Source code:ATLAS_2014_I1282447.cc

// -*- C++ -*-
#include "Rivet/Analysis.hh"
#include "Rivet/Projections/UnstableParticles.hh"
#include "Rivet/Projections/ChargedFinalState.hh"
#include "Rivet/Projections/PromptFinalState.hh"
#include "Rivet/Projections/VetoedFinalState.hh"
#include "Rivet/Projections/MissingMomentum.hh"
#include "Rivet/Projections/LeptonFinder.hh"
#include "Rivet/Projections/FastJets.hh"

namespace Rivet {


  /// @brief ATLAS W+c at 7 TeV
  ///
  /// This routine implements the ATLAS 7 TeV pp W+c analysis.
  ///
  /// Apart from those histograms described and published on HepData, there
  /// are some helper histograms:
  ///
  /// - d02-x01-y01, d02-x01-y02 and d08-x01-y01 are ratios, the nominator ("_plus")
  ///   and denominator ("_minus") histograms are also given, so that the ratios can
  ///   be reconstructed if need be (e.g. when running on separate samples).
  ///
  /// - d05 and d06 are ratios over inclusive W production.
  ///   The routine has to be run on a sample for inclusive W production in order to
  ///   make sure the denominator ("_winc") is correctly filled.
  ///
  /// The ratios can be constructed using the following sample code:
  ///
  /// ```python
  /// ## python divideWCharm.py
  ///
  /// import yoda
  /// hists_wc   = yoda.read("Rivet_Wc.yoda")
  /// hists_winc = yoda.read("Rivet_Winc.yoda")
  ///
  /// ## division histograms --> ONLY for different plus minus runs
  /// # (merge before using yodamerge Rivet_plus.yoda Rivet_minus.yoda > Rivet_Wc.yoda)
  ///
  /// d02y01_plus = hists_wc["/ATLAS_2014_I1282447/d02-x01-y01_plus"]
  /// d02y01_minus = hists_wc["/ATLAS_2014_I1282447/d02-x01-y01_minus"]
  /// ratio_d02y01 =  d02y01_plus.divide(d02y01_minus)
  /// ratio_d02y01.path = "/ATLAS_2014_I1282447/d02-x01-y01"
  ///
  /// d02y02_plus = hists_wc["/ATLAS_2014_I1282447/d02-x01-y02_plus"]
  /// d02y02_minus = hists_wc["/ATLAS_2014_I1282447/d02-x01-y02_minus"]
  /// ratio_d02y02=  d02y02_plus.divide(d02y02_minus)
  /// ratio_d02y02.path = "/ATLAS_2014_I1282447/d02-x01-y02"
  ///
  /// d08y01_plus = hists_wc["/ATLAS_2014_I1282447/d08-x01-y01_plus"]
  /// d08y01_minus = hists_wc["/ATLAS_2014_I1282447/d08-x01-y01_minus"]
  /// ratio_d08y01=  d08y01_plus.divide(d08y01_minus)
  /// ratio_d08y01.path = "/ATLAS_2014_I1282447/d08-x01-y01"
  ///
  /// # inclusive cross section
  /// h_winc = hists_winc["/ATLAS_2014_I1282447/d05-x01-y01"]
  /// h_d    = hists_wc["/ATLAS_2014_I1282447/d01-x01-y02"]
  /// h_dstar= hists_wc["/ATLAS_2014_I1282447/d01-x01-y03"]
  ///
  /// ratio_wd      =  h_d.divide(h_winc)
  /// ratio_wd.path = "/ATLAS_2014_I1282447/d05-x01-y02"
  ///
  /// ratio_wdstar      =  h_d.divide(h_winc)
  /// ratio_wdstar.path = "/ATLAS_2014_I1282447/d05-x01-y03"
  ///
  /// # pT differential
  /// h_winc_plus  = hists_winc["/ATLAS_2014_I1282447/d06-x01-y01_winc"]
  /// h_winc_minus = hists_winc["/ATLAS_2014_I1282447/d06-x01-y02_winc"]
  ///
  /// h_wd_plus      = hists_wc["/ATLAS_2014_I1282447/d06-x01-y01_wplus"]
  /// h_wd_minus     = hists_wc["/ATLAS_2014_I1282447/d06-x01-y02_wminus"]
  /// h_wdstar_plus  = hists_wc["/ATLAS_2014_I1282447/d06-x01-y03_wplus"]
  /// h_wdstar_minus = hists_wc["/ATLAS_2014_I1282447/d06-x01-y04_wminus"]
  ///
  /// ratio_wd_plus       =  h_wd_plus.divide(h_winc_plus)
  /// ratio_wd_plus.path  = "/ATLAS_2014_I1282447/d06-x01-y01"
  /// ratio_wd_minus      =  h_wd_plus.divide(h_winc_minus)
  /// ratio_wd_minus.path = "/ATLAS_2014_I1282447/d06-x01-y02"
  ///
  /// ratio_wdstar_plus       =  h_wdstar_plus.divide(h_winc_plus)
  /// ratio_wdstar_plus.path  = "/ATLAS_2014_I1282447/d06-x01-y03"
  /// ratio_wdstar_minus      =  h_wdstar_plus.divide(h_winc_minus)
  /// ratio_wdstar_minus.path = "/ATLAS_2014_I1282447/d06-x01-y04"
  ///
  /// ratio_wd_plus =  h_wd_plus.divide(h_winc_plus)
  /// ratio_wd_plus.path = "/ATLAS_2014_I1282447/d06-x01-y01"
  /// ratio_wd_minus =  h_wd_plus.divide(h_winc_minus)
  /// ratio_wd_minus.path = "/ATLAS_2014_I1282447/d06-x01-y02"
  ///
  /// h_winc_plus= hists_winc["/ATLAS_2014_I1282447/d06-x01-y01_winc"]
  /// h_winc_minus= hists_winc["/ATLAS_2014_I1282447/d06-x01-y02_winc"]
  ///
  /// ## copy other histograms for plotting
  ///
  /// d01x01y01= hists_wc["/ATLAS_2014_I1282447/d01-x01-y01"]
  /// d01x01y01.path = "/ATLAS_2014_I1282447/d01-x01-y01"
  ///
  /// d01x01y02= hists_wc["/ATLAS_2014_I1282447/d01-x01-y02"]
  /// d01x01y02.path = "/ATLAS_2014_I1282447/d01-x01-y02"
  ///
  /// d01x01y03= hists_wc["/ATLAS_2014_I1282447/d01-x01-y03"]
  /// d01x01y03.path = "/ATLAS_2014_I1282447/d01-x01-y03"
  ///
  /// d03x01y01= hists_wc["/ATLAS_2014_I1282447/d03-x01-y01"]
  /// d03x01y01.path = "/ATLAS_2014_I1282447/d03-x01-y01"
  ///
  /// d03x01y02= hists_wc["/ATLAS_2014_I1282447/d03-x01-y02"]
  /// d03x01y02.path = "/ATLAS_2014_I1282447/d03-x01-y02"
  ///
  /// d04x01y01= hists_wc["/ATLAS_2014_I1282447/d04-x01-y01"]
  /// d04x01y01.path = "/ATLAS_2014_I1282447/d04-x01-y01"
  ///
  /// d04x01y02= hists_wc["/ATLAS_2014_I1282447/d04-x01-y02"]
  /// d04x01y02.path = "/ATLAS_2014_I1282447/d04-x01-y02"
  ///
  /// d04x01y03= hists_wc["/ATLAS_2014_I1282447/d04-x01-y03"]
  /// d04x01y03.path = "/ATLAS_2014_I1282447/d04-x01-y03"
  ///
  /// d04x01y04= hists_wc["/ATLAS_2014_I1282447/d04-x01-y04"]
  /// d04x01y04.path = "/ATLAS_2014_I1282447/d04-x01-y04"
  ///
  /// d07x01y01= hists_wc["/ATLAS_2014_I1282447/d07-x01-y01"]
  /// d07x01y01.path = "/ATLAS_2014_I1282447/d07-x01-y01"
  ///
  /// yoda.write([ratio_d02y01,ratio_d02y02,ratio_d08y01, ratio_wd ,ratio_wdstar,ratio_wd_plus,ratio_wd_minus ,ratio_wdstar_plus,ratio_wdstar_minus,d01x01y01,d01x01y02,d01x01y03,d03x01y01,d03x01y02,d04x01y01,d04x01y02,d04x01y03,d04x01y04,d07x01y01],"validation.yoda")
  /// ```
  ///
  class ATLAS_2014_I1282447 : public Analysis {
  public:

    /// Constructor
    RIVET_DEFAULT_ANALYSIS_CTOR(ATLAS_2014_I1282447);


    /// @name Analysis methods
    /// @{

    /// Book histograms and initialise projections before the run
    void init() {

      // Initialise and register projections here
      Cut cuts = Cuts::abseta < 2.5 && Cuts::pT > 20*GeV;

      /// @note Should use sample WITHOUT QED radiation off the electron
      ///
      ///  This plus PhotonOrigin::ALL would mean dressing only with pi0 -> y y photons!?!
      declare("MET", MissingMomentum());
      LeptonFinder ef(0.1, cuts && Cuts::abspid == PID::ELECTRON);
      declare(ef, "Elecs");
      LeptonFinder mf(0.1, cuts && Cuts::abspid == PID::MUON);
      declare(mf, "Muons");

      // all hadrons that could be coming from a charm decay --
      // -- for safety, use region -3.5 - 3.5
      declare(UnstableParticles(Cuts::abseta < 3.5), "hadrons");

      // Input for the jets: no neutrinos, no muons, and no electron which passed the electron cuts
      // also: NO electron, muon or tau (needed due to ATLAS jet truth reconstruction feature)
      VetoedFinalState veto;
      veto.addVetoOnThisFinalState(ef);
      veto.addVetoOnThisFinalState(mf);
      veto.addVetoPairId(PID::ELECTRON);
      veto.addVetoPairId(PID::MUON);
      veto.addVetoPairId(PID::TAU);

      FastJets jets(veto, JetAlg::ANTIKT, 0.4);
      declare(jets, "jets");

      // Book histograms

      // charge separated integrated cross sections
      book(_hist_wcjet_charge  ,"d01-x01-y01");
      book(_hist_wd_charge     ,"d01-x01-y02");
      book(_hist_wdstar_charge ,"d01-x01-y03");

      // charge integrated total cross sections
      book(_hist_wcjet_ratio,"d02-x01-y01");
      book(_hist_wd_ratio   ,"d02-x01-y02");

      book(_hist_wcjet_minus ,"d02-x01-y01_minus");
      book(_hist_wd_minus    ,"d02-x01-y02_minus");

      book(_hist_wcjet_plus  ,"d02-x01-y01_plus");
      book(_hist_wd_plus     ,"d02-x01-y02_plus");

      // eta distributions
      book(_hist_wplus_wcjet_eta_lep   ,"d03-x01-y01");
      book(_hist_wminus_wcjet_eta_lep  ,"d03-x01-y02");

      book(_hist_wplus_wdminus_eta_lep ,"d04-x01-y01");
      book(_hist_wminus_wdplus_eta_lep ,"d04-x01-y02");
      book(_hist_wplus_wdstar_eta_lep  ,"d04-x01-y03");
      book(_hist_wminus_wdstar_eta_lep ,"d04-x01-y04");

      // ratio of cross section (WD over W inclusive) // postprocess!
      book(_hist_w_inc             ,"d05-x01-y01");
      book(_hist_wd_winc_ratio    ,"d05-x01-y02");
      book(_hist_wdstar_winc_ratio,"d05-x01-y03");

      // ratio of cross section (WD over W inclusive -- function of pT of D meson)
      book(_hist_wplusd_wplusinc_pt_ratio      ,"d06-x01-y01");
      book(_hist_wminusd_wminusinc_pt_ratio    ,"d06-x01-y02");
      book(_hist_wplusdstar_wplusinc_pt_ratio  ,"d06-x01-y03");
      book(_hist_wminusdstar_wminusinc_pt_ratio,"d06-x01-y04");

      // could use for postprocessing!
      book(_hist_wplusd_wplusinc_pt       ,"d06-x01-y01_wplus");
      book(_hist_wminusd_wminusinc_pt     ,"d06-x01-y02_wminus");
      book(_hist_wplusdstar_wplusinc_pt   ,"d06-x01-y03_wplus");
      book(_hist_wminusdstar_wminusinc_pt ,"d06-x01-y04_wminus");

      book(_hist_wplus_winc  ,"d06-x01-y01_winc");
      book(_hist_wminus_winc ,"d06-x01-y02_winc");

      // jet multiplicity of charge integrated W+cjet cross section (+0 or +1 jet in addition to the charm jet)
      book(_hist_wcjet_jets  ,"d07-x01-y01");

      // jet multiplicity of W+cjet cross section ratio (+0 or +1 jet in addition to the charm jet)
      book(_hist_wcjet_jets_ratio ,"d08-x01-y01");
      book(_hist_wcjet_jets_plus   ,"d08-x01-y01_plus");
      book(_hist_wcjet_jets_minus  ,"d08-x01-y01_minus");
    }


    /// Perform the per-event analysis
    void analyze(const Event& event) {

      double charge_weight = 0; // account for OS/SS events
      int    lepton_charge = 0;
      double lepton_eta    = 0.;

      /// Find leptons
      const P4& pmiss = apply<MissingMom>(event, "MET").missingMom();
      if (pmiss.Et() < 25*GeV) vetoEvent;

      // Identify the closest-matching l+MET to m == mW
      const Particles& es = apply<LeptonFinder>(event, "Elecs").particles();
      const int iefound = closestMatchIndex(es, pmiss, Kin::mass, 80.4*GeV, 15*GeV);
      const Particles& mus = apply<LeptonFinder>(event, "Muons").particles();
      const int imfound = closestMatchIndex(mus, pmiss, Kin::mass, 80.4*GeV, 15*GeV);
      if (iefound < 0 && imfound < 0) {
        MSG_DEBUG("No W bosons found");
        vetoEvent;
      }
      if (iefound >= 0 && imfound >= 0) {
        MSG_DEBUG("Multiple W bosons found");
        vetoEvent;
      }

      bool keepevent = false;

      //check electrons
      if (iefound >= 0) {
        const Particle& el = es[iefound];
        if (mT(pmiss, el) > 40*GeV) {
          keepevent = true;
          lepton_charge = el.charge();
          lepton_eta = el.abseta();
        }
      }

      //check muons
      if (imfound >= 0) {
        const Particle& mu = mus[imfound];
        if (mT(pmiss, mu) > 40*GeV) {
          keepevent = true;
          lepton_charge = mu.charge();
          lepton_eta = mu.abseta();
        }
      }

      if (!keepevent) {
        MSG_DEBUG("Event does not pass mT cuts");
        vetoEvent;
      }

      if (lepton_charge > 0) {
        _hist_wplus_winc->fill(10.);
        _hist_wplus_winc->fill(16.);
        _hist_wplus_winc->fill(30.);
        _hist_wplus_winc->fill(60.);
        _hist_w_inc->fill(+1);
      }
      else if (lepton_charge < 0) {
        _hist_wminus_winc->fill(10.);
        _hist_wminus_winc->fill(16.);
        _hist_wminus_winc->fill(30.);
        _hist_wminus_winc->fill(60.);
        _hist_w_inc->fill(-1);
      }

      // Find hadrons in the event
      const UnstableParticles& fs = apply<UnstableParticles>(event, "hadrons");

      /// FIND Different channels
      // 1: wcjet
      // get jets
      const Jets& jets = apply<FastJets>(event, "jets").jetsByPt(Cuts::pT > 25.0*GeV && Cuts::abseta < 2.5);
      // loop over jets to select jets used to match to charm
      Jets js;
      int    matched_charmHadron = 0;
      double charm_charge = 0.;
      int    njets = 0;
      int    nj = 0;
      bool   mat_jet = false;

      double ptcharm = 0;
      if (matched_charmHadron > -1) {
        for (const Jet& j : jets) {
          mat_jet = false;

          njets += 1;
          for (const Particle& p : fs.particles()) {
            /// @todo Avoid touching HepMC!
            ConstGenParticlePtr part = p.genParticle();
            if (p.hasCharm()) {
              //if(isFromBDecay(p)) continue;
              if (p.fromBottom()) continue;
              if (p.pT() < 5*GeV ) continue;
              if (hasCharmedChildren(part)) continue;
              if (deltaR(p, j) < 0.3) {
                mat_jet = true;
                if (p.pT() > ptcharm) {
                  charm_charge = part->pdg_id();
                  ptcharm = p.pT();
                }
              }
            }
          }
          if (mat_jet) nj++;
        }

        if (charm_charge * lepton_charge > 0)  charge_weight = -1;
        else charge_weight = +1;

        if (nj == 1)  {
          if (lepton_charge > 0) {
            _hist_wcjet_charge        ->fill(         1, charge_weight);
            _hist_wcjet_plus          ->fill(         0, charge_weight);
            _hist_wplus_wcjet_eta_lep ->fill(lepton_eta, charge_weight);
            _hist_wcjet_jets_plus     ->fill(njets-1   , charge_weight);
          }
          else if (lepton_charge < 0) {
            _hist_wcjet_charge        ->fill(        -1, charge_weight);
            _hist_wcjet_minus         ->fill(         0, charge_weight);
            _hist_wminus_wcjet_eta_lep->fill(lepton_eta, charge_weight);
            _hist_wcjet_jets_minus    ->fill(njets-1   , charge_weight);
          }

          _hist_wcjet_jets->fill(njets-1, charge_weight);
        }
      }

      // // 1/2: w+d(*) meson

      for (const Particle& p : fs.particles()) {

        /// @todo Avoid touching HepMC!
        ConstGenParticlePtr part = p.genParticle();
        if (p.pT() < 8*GeV)       continue;
        if (fabs(p.eta()) > 2.2)  continue;

        // W+D
        if (abs(part->pdg_id()) == 411) {
          if (lepton_charge * part->pdg_id() > 0)  charge_weight = -1;
          else                                     charge_weight = +1;

          // fill histos
          if (lepton_charge > 0) {
            _hist_wd_charge            ->fill(         1, charge_weight);
            _hist_wd_plus              ->fill(         0, charge_weight);
            _hist_wplus_wdminus_eta_lep->fill(lepton_eta, charge_weight);
            _hist_wplusd_wplusinc_pt   ->fill(    p.pT(), charge_weight);
          }
          else if (lepton_charge < 0) {
            _hist_wd_charge            ->fill(        -1, charge_weight);
            _hist_wd_minus             ->fill(         0, charge_weight);
            _hist_wminus_wdplus_eta_lep->fill(lepton_eta, charge_weight);
            _hist_wminusd_wminusinc_pt ->fill(p.pT()    , charge_weight);
          }
        }

        // W+Dstar
        if ( abs(part->pdg_id()) == 413 ) {
          if (lepton_charge*part->pdg_id() > 0) charge_weight = -1;
          else charge_weight = +1;

          if (lepton_charge > 0) {
            _hist_wdstar_charge->fill(+1, charge_weight);
            _hist_wd_plus->fill( 0, charge_weight);
            _hist_wplus_wdstar_eta_lep->fill( lepton_eta, charge_weight);
            _hist_wplusdstar_wplusinc_pt->fill(  p.pT(), charge_weight);
          }
          else if (lepton_charge < 0) {
            _hist_wdstar_charge->fill(-1, charge_weight);
            _hist_wd_minus->fill(0, charge_weight);
            _hist_wminus_wdstar_eta_lep->fill(lepton_eta, charge_weight);
            _hist_wminusdstar_wminusinc_pt->fill(p.pT(), charge_weight);
          }
        }
      }

    }


    /// Normalise histograms etc., after the run
    void finalize() {

      const double sf = crossSection()/picobarn / sumOfWeights();

      // norm to cross section
      // d01
      scale(_hist_wcjet_charge,  sf);
      scale(_hist_wd_charge,     sf);
      scale(_hist_wdstar_charge, sf);

      //d02
      scale(_hist_wcjet_plus,  sf);
      scale(_hist_wcjet_minus, sf);
      scale(_hist_wd_plus,     sf);
      scale(_hist_wd_minus,    sf);

      divide(_hist_wcjet_plus, _hist_wcjet_minus, _hist_wcjet_ratio);
      divide(_hist_wd_plus,    _hist_wd_minus,    _hist_wd_ratio   );

      //d03
      scale(_hist_wplus_wcjet_eta_lep,  sf);
      scale(_hist_wminus_wcjet_eta_lep, sf);

      //d04
      scale(_hist_wplus_wdminus_eta_lep, crossSection()/picobarn/sumOfWeights());
      scale(_hist_wminus_wdplus_eta_lep, crossSection()/picobarn/sumOfWeights());

      scale(_hist_wplus_wdstar_eta_lep , crossSection()/picobarn/sumOfWeights());
      scale(_hist_wminus_wdstar_eta_lep, crossSection()/picobarn/sumOfWeights());

      //d05
      scale(_hist_w_inc, 0.01 * sf); // in percent --> /100
      divide(_hist_wd_charge,     _hist_w_inc, _hist_wd_winc_ratio    );
      divide(_hist_wdstar_charge, _hist_w_inc, _hist_wdstar_winc_ratio);

      //d06, in percentage!
      scale(_hist_wplusd_wplusinc_pt,       sf);
      scale(_hist_wminusd_wminusinc_pt,     sf);
      scale(_hist_wplusdstar_wplusinc_pt,   sf);
      scale(_hist_wminusdstar_wminusinc_pt, sf);

      scale(_hist_wplus_winc,  0.01 * sf); // in percent --> /100
      scale(_hist_wminus_winc, 0.01 * sf); // in percent --> /100

      divide(_hist_wplusd_wplusinc_pt,       _hist_wplus_winc , _hist_wplusd_wplusinc_pt_ratio      );
      divide(_hist_wminusd_wminusinc_pt,     _hist_wminus_winc, _hist_wminusd_wminusinc_pt_ratio    );
      divide(_hist_wplusdstar_wplusinc_pt,   _hist_wplus_winc , _hist_wplusdstar_wplusinc_pt_ratio  );
      divide(_hist_wminusdstar_wminusinc_pt, _hist_wminus_winc, _hist_wminusdstar_wminusinc_pt_ratio);

      //d07
      scale(_hist_wcjet_jets, sf);

      //d08
      scale(_hist_wcjet_jets_minus, sf);
      scale(_hist_wcjet_jets_plus,  sf);
      divide(_hist_wcjet_jets_plus, _hist_wcjet_jets_minus , _hist_wcjet_jets_ratio);
    }

    /// @}


  private:

    // Data members like post-cuts event weight counters go here

    /// Check whether particle comes from b-decay
    ///
    /// @note Slight difference wrt Rivet's native Particle::fromBottom method!
    bool isFromBDecay(const Particle& p) {
      return p.hasAncestorWith([](const Particle& p)->bool{return p.hasBottom();});
    }

    /// Check whether particle has charmed children
    ///
    /// @todo Use built-in method and avoid HepMC!
    bool hasCharmedChildren(ConstGenParticlePtr part) {

      bool hasCharmedChild = false;
      if (part == nullptr)  return false;

      ConstGenVertexPtr ivtx = part->end_vertex();
      if (ivtx == nullptr)  return false;

      for (ConstGenParticlePtr p2: HepMCUtils::particles(ivtx, Relatives::CHILDREN)) {
        if (p2 == part)  continue;
        hasCharmedChild = PID::hasCharm(p2->pdg_id());
        if (hasCharmedChild == true)  break;
        hasCharmedChild = hasCharmedChildren(p2);
        if (hasCharmedChild == true)  break;
      }
      return hasCharmedChild;
    }


  private:

    /// @name Histograms
    /// @{

    //d01-x01-
    Histo1DPtr   _hist_wcjet_charge;
    Histo1DPtr   _hist_wd_charge;
    Histo1DPtr   _hist_wdstar_charge;

    //d02-x01-
    Estimate1DPtr _hist_wcjet_ratio;
    Estimate1DPtr _hist_wd_ratio;
    Histo1DPtr _hist_wcjet_plus;
    Histo1DPtr _hist_wd_plus;

    Histo1DPtr _hist_wcjet_minus;
    Histo1DPtr _hist_wd_minus;

    //d03-x01-
    Histo1DPtr _hist_wplus_wcjet_eta_lep;
    Histo1DPtr _hist_wminus_wcjet_eta_lep;

    //d04-x01-
    Histo1DPtr _hist_wplus_wdminus_eta_lep;
    Histo1DPtr _hist_wminus_wdplus_eta_lep;

    //d05-x01-
    Histo1DPtr _hist_wplus_wdstar_eta_lep;
    Histo1DPtr _hist_wminus_wdstar_eta_lep;

    // postprocessing histos
    //d05-x01
    Histo1DPtr _hist_w_inc;
    Estimate1DPtr _hist_wd_winc_ratio;
    Estimate1DPtr _hist_wdstar_winc_ratio;

    //d06-x01
    Histo1DPtr _hist_wplus_winc;
    Histo1DPtr _hist_wminus_winc;

    Estimate1DPtr _hist_wplusd_wplusinc_pt_ratio;
    Estimate1DPtr _hist_wminusd_wminusinc_pt_ratio;
    Estimate1DPtr _hist_wplusdstar_wplusinc_pt_ratio;
    Estimate1DPtr _hist_wminusdstar_wminusinc_pt_ratio;

    Histo1DPtr _hist_wplusd_wplusinc_pt ;
    Histo1DPtr _hist_wminusd_wminusinc_pt;
    Histo1DPtr _hist_wplusdstar_wplusinc_pt;
    Histo1DPtr _hist_wminusdstar_wminusinc_pt;

    // d07-x01
    Histo1DPtr _hist_wcjet_jets ;

    //d08-x01
    Estimate1DPtr  _hist_wcjet_jets_ratio ;
    Histo1DPtr    _hist_wcjet_jets_plus ;
    Histo1DPtr    _hist_wcjet_jets_minus;
    /// @}

  };


  RIVET_DECLARE_PLUGIN(ATLAS_2014_I1282447);

}