Exemple #1
0
std::vector<Id::Type> PFBlock::linkedIds(IdType uniqueid, Edge::EdgeType edgetype) const {
  /// Returns list of all linked ids of a given edge type that are connected to a given id -
  /// TODO think about sorting
  Ids linkedIds;
  for (auto key : linkedEdgeKeys(uniqueid, edgetype)) {
    auto found = m_edges.find(key);
    if (found == m_edges.end()) throw std::range_error("Required EdgeKey is missing from Linked Edges collection");
    linkedIds.push_back(found->second.otherid(uniqueid));
  }
  // std::sort(linkedIds.begin(), linkedIds.end(), [this, uniqueid](IdType a, IdType b) -> bool
  //                  { return this->compareEdges(a, b, uniqueid); } );
  return linkedIds;
}
void PFReconstructor::reconstructHcal(const PFBlock& block, IdType hcalId) {
  /*
   block: element ids and edges
   hcalid: id of the hcal being processed her

   has hcal and has a track
   -> add up all connected tracks, turn each track into a charged hadron
   -> add up all ecal energies
   -> if track energies is greater than hcal energy then turn the missing energies into an ecal (photon)
   NB this links the photon to the hcal rather than the ecals
   -> if track energies are less than hcal then make a neutral hadron with rest of hcal energy and turn all ecals into
   photons
   has hcal but no track (nb by design there will be no attached ecals because hcal ecal links have been removed)
   -> make a neutral hadron
   has hcals
   -> each hcal is treated using rules above
   */

  // hcal used to make ecal_in has a couple of possible issues
  // m_pfEvent.HCALCluster(hcalId);

  // TODO assert(len(block.linked_ids(hcalid, "hcal_hcal"))==0  )
  // TODO sorting Ids trackids =    block.sort_distance_energy(hcalid, block.linked_ids(hcalid, "hcal_track") )

  Ids ecalIds;
  Ids trackIds = block.linkedIds(hcalId, Edge::EdgeType::kHcalTrack);
#if WITHSORT
  std::sort(trackIds.begin(), trackIds.end());
#endif
  for (auto trackId : trackIds) {
    for (auto ecalId : block.linkedIds(trackId, Edge::EdgeType::kEcalTrack)) {
      /*the ecals get all grouped together for all tracks in the block
       # Maybe we want to link ecals to their closest track etc?
       # this might help with history work
       # ask colin.*/
      if (!m_locked[ecalId]) {
        ecalIds.push_back(ecalId);
        m_locked[ecalId] = true;
      }
    }
  }
#if WITHSORT
  std::sort(trackIds.begin(), trackIds.end());
  std::sort(ecalIds.begin(), ecalIds.end());
#endif
  // hcal should be the only remaining linked hcal cluster (closest one)
  const Cluster& hcal = m_pfEvent.HCALCluster(hcalId);
  double hcalEnergy = hcal.energy();
  double ecalEnergy = 0.;
  double trackEnergy = 0.;

  if (!trackIds.empty()) {
    for (auto id : trackIds) {
      const Track& track = m_pfEvent.tracks().at(id);
      insertParticle(block, reconstructTrack(track));
      trackEnergy += track.energy();
    }
    for (auto id : ecalIds) {
      ecalEnergy += m_pfEvent.ECALCluster(id).energy();
    }
    double deltaERel = (hcalEnergy + ecalEnergy) / trackEnergy - 1.;
    double caloERes = neutralHadronEnergyResolution(hcal);
    /*self.log.info( 'dE/p, res = {derel}, {res} '.format(
     derel = delta_e_rel,
     res = calo_eres ))*/
    if (deltaERel > nsigmaHcal(hcal) * caloERes) {  //# approx means hcal energy + ecal energies > track energies

      double excess = deltaERel * trackEnergy;  // energy in excess of track energies
      // print( 'excess = {excess:5.2f}, ecal_E = {ecal_e:5.2f}, diff = {diff:5.2f}'.format(
      //   excess=excess, ecal_e = ecal_energy, diff=excess-ecal_energy))
      if (excess <= ecalEnergy) { /* # approx means hcal energy > track energies
                                   # Make a photon from the ecal energy
                                   # We make only one photon using only the combined ecal energies*/
        insertParticle(block, reconstructCluster(hcal, papas::Layer::kEcal, excess));
      }

      else {  // approx means that hcal energy>track energies so we must have a neutral hadron
              // excess-ecal_energy is approximately hcal energy  - track energies
        insertParticle(block, reconstructCluster(hcal, papas::Layer::kHcal, excess - ecalEnergy));
        if (ecalEnergy) {
          // make a photon from the remaining ecal energies
          // again history is confusingbecause hcal is used to provide direction
          // be better to make several smaller photons one per ecal?
          insertParticle(block, reconstructCluster(hcal, papas::Layer::kEcal, ecalEnergy));
        }
      }
    }
  } else {  // # case whether there are no tracks make a neutral hadron for each hcal
            //# note that hcal-ecal links have been removed so hcal should only be linked to
            //# other hcals

    insertParticle(block, reconstructCluster(hcal, papas::Layer::kHcal));
  }
  m_locked[hcalId] = true;
}