//=============================================================================
// Return all descendants of level i for a Particle
//=============================================================================
const LHCb::Particle::ConstVector ParticleDescendants::descendants(const LHCb::Particle* P, int maxlevel){
  
  LHCb::Particle::ConstVector Parts ;

  int level = 0 ;
  bool found = false ;
  
  LHCb::Particle::ConstVector mothers ;

  do {
    ++level ;
    LHCb::Particle::ConstVector leveldaughters ;
    if ( level == 1 ) found = addDaughters( P, leveldaughters) ;
    else found = addDaughters( mothers, leveldaughters) ;
    if ( level==maxlevel || maxlevel == 0 ) {
      Parts.insert(Parts.end(),leveldaughters.begin(),leveldaughters.end()) ;
      verbose() << "Level: " << level << " - inserted " << leveldaughters.size() 
                << " daughters to get " << Parts.size() << endmsg ;
    }
    verbose() << "Level " << level << " of " << maxlevel << " : " 
              << leveldaughters.size() << " daughters " << found << endmsg ;
    mothers = leveldaughters ;
  } while ( (maxlevel<=0 || level<=maxlevel) && found ) ;
  
  debug() << "Reached " << level << ". Returning " << Parts.size() 
          << " daughters" << endmsg ;
  
  return Parts ;
}  
//=============================================================================
// Return all daughters of particles in a vector
//=============================================================================
bool ParticleDescendants::addDaughters(const LHCb::Particle::ConstVector& mothers, 
                                       LHCb::Particle::ConstVector& Parts){
  if ( mothers.empty() ) return false ;
  bool found = false ;
  for ( LHCb::Particle::ConstVector::const_iterator i = mothers.begin() ; i!=mothers.end() ; ++i){
    found = ( addDaughters( *i, Parts) || found );
  }
  return found ;
}  
//=============================================================================
// Return all stable descendants of a Particle
//=============================================================================
const LHCb::Particle::ConstVector ParticleDescendants::finalStates(const LHCb::Particle* P){
  LHCb::Particle::ConstVector stables ; // 
  LHCb::Particle::ConstVector all = descendants( P, 0 ); // get them all all
  for ( LHCb::Particle::ConstVector::const_iterator i = all.begin() ; i!=all.end() ; ++i){
    if ( (*i)->isBasicParticle() ) {
      stables.push_back( *i );
      debug() << "Saving a " << (*i)->particleID().pid() << endmsg ;
    } else verbose() << "Discarding a " << (*i)->particleID().pid() << endmsg ;
  } 
  return stables;
}
//=============================================================================
// Return all daughters of particles in a vector
//=============================================================================
bool ParticleDescendants::addDaughters(const LHCb::Particle* M, 
                                       LHCb::Particle::ConstVector& Parts){
  if ( 0==M ) return false;
  if ( M->isBasicParticle() ) return false;  
  const LHCb::Particle::ConstVector dauts = M->daughtersVector();
  Parts.insert(Parts.end(),dauts.begin(),dauts.end());
  verbose() << "Added " << dauts.size() << " daughters" << endmsg ;
  return (!dauts.empty());
  
}
Beispiel #5
0
//=============================================================================
// Main execution
//=============================================================================
StatusCode B2DMuNu::execute() {
  
  if (msgLevel(MSG::DEBUG)) debug() << "==> Execute" << endmsg;
  StatusCode sc = StatusCode::SUCCESS;
  
  //### Extract Run number and Event number ###//
  const LHCb::ODIN* odin = get<LHCb::ODIN>(LHCb::ODINLocation::Default);
  const unsigned int runNum = odin->runNumber(), evNum = odin->eventNumber();
  debug() << "Run number is " << runNum << " and Event ID is " << evNum
          << " at time " << odin->eventTime() << endmsg; //odin->gpsTime() << endmsg;
  counter("EventID")++;
  debug() << "### Processing event number " << counter("EventID").nEntries() << " in job ###" << endmsg;
  
  setFilterPassed(true); // Mandatory. Set to true if event is accepted.

  //### Only run on MC data if requested ###//
  if (m_runMC==1)
  {
    //### Test MC data to see if event warrants reconstruction (Require B0/B- OR B0~/B+ both decaying to muons) ###//
    m_passEvent = 0;
    debug() << "Performing Analysis on MC data" << endmsg;
    sc = loopOnMC();
    if (!sc) return sc;
  }
  
  if (m_passEvent==1) 
  {
    debug() << "### Event number " << counter("EventID").nEntries() << " accepted for analysis buddy ###" << endmsg;
    counter("EventPasses")++;
    
    debug() << "Extracting daughters..." << endmsg;
    LHCb::Particle::ConstVector daughters = this->i_particles();

    if (daughters.size()!=0)
    {
      debug() << "### There are " << daughters.size() << " possible Muons in this event (EventID "
              << counter("EventID").nEntries() << ") ###" << endmsg;
      counter("MuonsPresent")++;
      
      //### Extract muon hits and muon misid if requested ###//
      if (m_muHits) {
        const std::string& strExtra = "Extra";
        Extra* extra = new Extra(strExtra, m_local);
        Tuple fakeTuple = nTuple("fakeMuonTuple");
        sc = extra->fakeMuon(daughters, fakeTuple);
        Tuple hitTuple = nTuple("muonHitTuple");
        sc = extra->muonChamberHits(hitTuple);
        delete extra;
        if (!sc) return sc;
      }

      //### Test - Call loopOnRec ###//
      const std::string& strRec = "Rec";
      Rec* rec = new Rec(strRec, m_local);
      Tuple recAllTuple=nTuple("recAllTuple"), hitDistTuple=nTuple("muHitDistTuple"), motherTuple=nTuple("motherTuple"), 
        candTuple=nTuple("candidateTuple");
      const LHCb::RecVertex::Range prims = this->primaryVertices();
      LHCb::Particle::Vector mothers = 
        rec->loopOnRec(daughters, prims, m_motherID, recAllTuple, hitDistTuple, motherTuple, candTuple, m_runMC);
      
      delete rec;
      if (!sc) return sc;
    }
    else debug() << "### There are no possible muons in the event!! ###" << endmsg;
    debug() << "### Finishing analysis for Event number " << counter("EventID").nEntries() << " ###" << endmsg;
  }
  else
  {
    debug() << "Event rejected" << endmsg;
    counter("EventFails")++;
  }
  
  debug() << "Event fully analysed." << endmsg;
  return StatusCode::SUCCESS;
}