Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-09-07 04:36:20

0001 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0002 #include "Fireworks/Calo/interface/FWHeatmapProxyBuilderTemplate.h"
0003 #include "Fireworks/Core/interface/FWEventItem.h"
0004 #include "Fireworks/Core/interface/FWGeometry.h"
0005 #include "Fireworks/Core/interface/BuilderUtils.h"
0006 #include "DataFormats/HGCalReco/interface/Trackster.h"
0007 #include "DataFormats/CaloRecHit/interface/CaloCluster.h"
0008 #include "DataFormats/Common/interface/ValueMap.h"
0009 #include "DataFormats/ForwardDetId/interface/HGCSiliconDetId.h"
0010 #include "DataFormats/ForwardDetId/interface/HGCScintillatorDetId.h"
0011 #include "DataFormats/DetId/interface/DetId.h"
0012 
0013 #include "TEveBoxSet.h"
0014 #include "TEveStraightLineSet.h"
0015 
0016 class FWTracksterHitsProxyBuilder : public FWHeatmapProxyBuilderTemplate<ticl::Trackster> {
0017 public:
0018   FWTracksterHitsProxyBuilder(void) {}
0019   ~FWTracksterHitsProxyBuilder(void) override {}
0020 
0021   REGISTER_PROXYBUILDER_METHODS();
0022 
0023   FWTracksterHitsProxyBuilder(const FWTracksterHitsProxyBuilder &) = delete;                   // stop default
0024   const FWTracksterHitsProxyBuilder &operator=(const FWTracksterHitsProxyBuilder &) = delete;  // stop default
0025 
0026 private:
0027   edm::Handle<edm::ValueMap<std::pair<float, float>>> TimeValueMapHandle_;
0028   edm::Handle<std::vector<reco::CaloCluster>> layerClustersHandle_;
0029   double timeLowerBound_, timeUpperBound_;
0030   long layer_;
0031   double saturation_energy_;
0032   bool heatmap_;
0033   bool z_plus_;
0034   bool z_minus_;
0035   bool enableTimeFilter_;
0036   bool enableSeedLines_;
0037   bool enablePositionLines_;
0038   bool enableEdges_;
0039 
0040   void setItem(const FWEventItem *iItem) override;
0041 
0042   void build(const FWEventItem *iItem, TEveElementList *product, const FWViewContext *vc) override;
0043   void build(const ticl::Trackster &iData,
0044              unsigned int iIndex,
0045              TEveElement &oItemHolder,
0046              const FWViewContext *) override;
0047 };
0048 
0049 void FWTracksterHitsProxyBuilder::setItem(const FWEventItem *iItem) {
0050   FWHeatmapProxyBuilderTemplate::setItem(iItem);
0051   if (iItem) {
0052     iItem->getConfig()->assertParam("Cluster(0)/RecHit(1)", false);
0053     iItem->getConfig()->assertParam("EnableSeedLines", false);
0054     iItem->getConfig()->assertParam("EnablePositionLines", false);
0055     iItem->getConfig()->assertParam("EnableEdges", false);
0056     iItem->getConfig()->assertParam("EnableTimeFilter", false);
0057     iItem->getConfig()->assertParam("TimeLowerBound(ns)", 0.01, 0.0, 75.0);
0058     iItem->getConfig()->assertParam("TimeUpperBound(ns)", 0.01, 0.0, 75.0);
0059   }
0060 }
0061 
0062 void FWTracksterHitsProxyBuilder::build(const FWEventItem *iItem, TEveElementList *product, const FWViewContext *vc) {
0063   iItem->getEvent()->getByLabel(edm::InputTag("hgcalLayerClusters", "timeLayerCluster"), TimeValueMapHandle_);
0064   iItem->getEvent()->getByLabel(edm::InputTag("hgcalLayerClusters"), layerClustersHandle_);
0065   if (TimeValueMapHandle_.isValid()) {
0066     timeLowerBound_ = item()->getConfig()->value<double>("TimeLowerBound(ns)");
0067     timeUpperBound_ = item()->getConfig()->value<double>("TimeUpperBound(ns)");
0068     if (timeLowerBound_ > timeUpperBound_) {
0069       edm::LogWarning("InvalidParameters")
0070           << "lower time bound is larger than upper time bound. Maybe opposite is desired?";
0071     }
0072   } else {
0073     iItem->getEvent()->getByLabel(edm::InputTag("hgcalMergeLayerClusters", "timeLayerCluster"), TimeValueMapHandle_);
0074     edm::LogWarning("DataNotFound|InvalidData")
0075         << __FILE__ << ":" << __LINE__
0076         << " couldn't locate 'hgcalLayerClusters:timeLayerCluster' ValueMap in input file. Trying to access "
0077            "'hgcalMergeLayerClusters:timeLayerClusters' ValueMap";
0078     if (!TimeValueMapHandle_.isValid()) {
0079       edm::LogWarning("DataNotFound|InvalidData")
0080           << __FILE__ << ":" << __LINE__
0081           << " couldn't locate 'hgcalMergeLayerClusters:timeLayerCluster' ValueMap in input file.";
0082     }
0083   }
0084 
0085   if (!layerClustersHandle_.isValid()) {
0086     iItem->getEvent()->getByLabel(edm::InputTag("hgcalMergeLayerClusters"), layerClustersHandle_);
0087     edm::LogWarning("DataNotFound|InvalidData")
0088         << __FILE__ << ":" << __LINE__
0089         << " couldn't locate 'hgcalLayerClusters' collection "
0090            "in input file. Trying to access 'hgcalMergeLayerClusters' collection.";
0091     if (!layerClustersHandle_.isValid()) {
0092       edm::LogWarning("DataNotFound|InvalidData")
0093           << __FILE__ << ":" << __LINE__ << " couldn't locate 'hgcalMergeLayerClusters' collection in input file.";
0094     }
0095   }
0096 
0097   layer_ = item()->getConfig()->value<long>("Layer");
0098   saturation_energy_ = item()->getConfig()->value<double>("EnergyCutOff");
0099   heatmap_ = item()->getConfig()->value<bool>("Heatmap");
0100   z_plus_ = item()->getConfig()->value<bool>("Z+");
0101   z_minus_ = item()->getConfig()->value<bool>("Z-");
0102   enableTimeFilter_ = item()->getConfig()->value<bool>("EnableTimeFilter");
0103   enableSeedLines_ = item()->getConfig()->value<bool>("EnableSeedLines");
0104   enablePositionLines_ = item()->getConfig()->value<bool>("EnablePositionLines");
0105   enableEdges_ = item()->getConfig()->value<bool>("EnableEdges");
0106 
0107   FWHeatmapProxyBuilderTemplate::build(iItem, product, vc);
0108 }
0109 
0110 void FWTracksterHitsProxyBuilder::build(const ticl::Trackster &iData,
0111                                         unsigned int iIndex,
0112                                         TEveElement &oItemHolder,
0113                                         const FWViewContext *) {
0114   if (enableTimeFilter_ && TimeValueMapHandle_.isValid()) {
0115     const float time = TimeValueMapHandle_->get(iIndex).first;
0116     if (time < timeLowerBound_ || time > timeUpperBound_)
0117       return;
0118   }
0119 
0120   const ticl::Trackster &trackster = iData;
0121   const size_t N = trackster.vertices().size();
0122   const std::vector<reco::CaloCluster> &layerClusters = *layerClustersHandle_;
0123 
0124   TEveBoxSet *hex_boxset = new TEveBoxSet();
0125   if (!heatmap_)
0126     hex_boxset->UseSingleColor();
0127   hex_boxset->SetPickable(true);
0128   hex_boxset->Reset(TEveBoxSet::kBT_Hex, true, 64);
0129 
0130   TEveBoxSet *boxset = new TEveBoxSet();
0131   if (!heatmap_)
0132     boxset->UseSingleColor();
0133   boxset->SetPickable(true);
0134   boxset->Reset(TEveBoxSet::kBT_FreeBox, true, 64);
0135 
0136   TEveStraightLineSet *seed_marker = nullptr;
0137   if (enableSeedLines_) {
0138     seed_marker = new TEveStraightLineSet("seeds");
0139     seed_marker->SetLineWidth(2);
0140     seed_marker->SetLineColor(kOrange + 10);
0141     seed_marker->GetLinePlex().Reset(sizeof(TEveStraightLineSet::Line_t), 2 * N);
0142   }
0143 
0144   TEveStraightLineSet *position_marker = nullptr;
0145   if (enablePositionLines_) {
0146     position_marker = new TEveStraightLineSet("positions");
0147     position_marker->SetLineWidth(2);
0148     position_marker->SetLineColor(kOrange);
0149     position_marker->GetLinePlex().Reset(sizeof(TEveStraightLineSet::Line_t), 2 * N);
0150   }
0151 
0152   for (size_t i = 0; i < N; ++i) {
0153     const reco::CaloCluster layerCluster = layerClusters[trackster.vertices(i)];
0154     std::vector<std::pair<DetId, float>> clusterDetIds = layerCluster.hitsAndFractions();
0155 
0156     for (std::vector<std::pair<DetId, float>>::iterator it = clusterDetIds.begin(), itEnd = clusterDetIds.end();
0157          it != itEnd;
0158          ++it) {
0159       const float *corners = item()->getGeom()->getCorners(it->first);
0160       if (corners == nullptr)
0161         continue;
0162 
0163       if (heatmap_ && hitmap->find(it->first) == hitmap->end())
0164         continue;
0165 
0166       const float *parameters = item()->getGeom()->getParameters(it->first);
0167       const float *shapes = item()->getGeom()->getShapePars(it->first);
0168 
0169       if (parameters == nullptr || shapes == nullptr)
0170         continue;
0171 
0172       const int total_points = parameters[0];
0173       const int layer = parameters[1];
0174       const int zside = parameters[2];
0175       const bool isSilicon = parameters[3];
0176 
0177       // discard everything that's not at the side that we are intersted in
0178       auto const z_selection_is_on = z_plus_ ^ z_minus_;
0179       auto const z_plus_selection_ok = z_plus_ && (zside == 1);
0180       auto const z_minus_selection_ok = z_minus_ && (zside == -1);
0181       if (!z_minus_ && !z_plus_)
0182         break;
0183       if (z_selection_is_on && !(z_plus_selection_ok || z_minus_selection_ok))
0184         break;
0185 
0186       if (layer_ > 0 && layer != layer_)
0187         break;
0188 
0189       // seed and cluster position
0190       if (layerCluster.seed().rawId() == it->first.rawId()) {
0191         const float crossScale = 0.2f + fmin(layerCluster.energy(), 5.0f);
0192         if (enableSeedLines_) {
0193           // center of RecHit
0194           const float center[3] = {corners[total_points * 3 + 0],
0195                                    corners[total_points * 3 + 1],
0196                                    corners[total_points * 3 + 2] + shapes[3] * 0.5f};
0197 
0198           // draw 3D cross
0199           seed_marker->AddLine(
0200               center[0] - crossScale, center[1], center[2], center[0] + crossScale, center[1], center[2]);
0201           seed_marker->AddLine(
0202               center[0], center[1] - crossScale, center[2], center[0], center[1] + crossScale, center[2]);
0203         }
0204 
0205         if (enablePositionLines_) {
0206           auto const &pos = layerCluster.position();
0207           const float position_crossScale = crossScale * 0.5;
0208           position_marker->AddLine(
0209               pos.x() - position_crossScale, pos.y(), pos.z(), pos.x() + position_crossScale, pos.y(), pos.z());
0210           position_marker->AddLine(
0211               pos.x(), pos.y() - position_crossScale, pos.z(), pos.x(), pos.y() + position_crossScale, pos.z());
0212         }
0213       }
0214 
0215       const float energy =
0216           fmin((item()->getConfig()->value<bool>("Cluster(0)/RecHit(1)") ? hitmap->at(it->first)->energy()
0217                                                                          : layerCluster.energy()) /
0218                    saturation_energy_,
0219                1.0f);
0220       const uint8_t colorFactor = gradient_steps * energy;
0221       auto transparency = item()->modelInfo(iIndex).displayProperties().transparency();
0222       UChar_t alpha = (255 * (100 - transparency)) / 100;
0223 
0224       // Scintillator
0225       if (!isSilicon) {
0226         const int total_vertices = 3 * total_points;
0227 
0228         std::vector<float> pnts(24);
0229         for (int i = 0; i < total_points; ++i) {
0230           pnts[i * 3 + 0] = corners[i * 3];
0231           pnts[i * 3 + 1] = corners[i * 3 + 1];
0232           pnts[i * 3 + 2] = corners[i * 3 + 2];
0233 
0234           pnts[(i * 3 + 0) + total_vertices] = corners[i * 3];
0235           pnts[(i * 3 + 1) + total_vertices] = corners[i * 3 + 1];
0236           pnts[(i * 3 + 2) + total_vertices] = corners[i * 3 + 2] + shapes[3];
0237         }
0238         boxset->AddBox(&pnts[0]);
0239         if (heatmap_) {
0240           energy
0241               ? boxset->DigitColor(gradient[0][colorFactor], gradient[1][colorFactor], gradient[2][colorFactor], alpha)
0242               : boxset->DigitColor(64, 64, 64, alpha);
0243         }
0244       }
0245       // Silicon
0246       else {
0247         constexpr int offset = 9;
0248 
0249         float centerX = (corners[6] + corners[6 + offset]) / 2;
0250         float centerY = (corners[7] + corners[7 + offset]) / 2;
0251         float radius = fabs(corners[6] - corners[6 + offset]) / 2;
0252         hex_boxset->AddHex(TEveVector(centerX, centerY, corners[2]), radius, shapes[2], shapes[3]);
0253         if (heatmap_) {
0254           energy ? hex_boxset->DigitColor(
0255                        gradient[0][colorFactor], gradient[1][colorFactor], gradient[2][colorFactor], alpha)
0256                  : hex_boxset->DigitColor(64, 64, 64, alpha);
0257         } else {
0258           hex_boxset->CSCApplyMainColorToMatchingChildren();
0259           hex_boxset->CSCApplyMainTransparencyToMatchingChildren();
0260           hex_boxset->SetMainColor(item()->modelInfo(iIndex).displayProperties().color());
0261           hex_boxset->SetMainTransparency(item()->defaultDisplayProperties().transparency());
0262         }
0263       }
0264     }  // End of loop over rechits of a single layercluster
0265   }  // End loop over the layerclusters of the trackster
0266 
0267   hex_boxset->RefitPlex();
0268   boxset->RefitPlex();
0269   setupAddElement(hex_boxset, &oItemHolder);
0270   setupAddElement(boxset, &oItemHolder);
0271 
0272   if (enableSeedLines_)
0273     oItemHolder.AddElement(seed_marker);
0274 
0275   if (enablePositionLines_)
0276     oItemHolder.AddElement(position_marker);
0277 
0278   if (enableEdges_) {
0279     auto &edges = trackster.edges();
0280 
0281     TEveStraightLineSet *adjacent_marker = new TEveStraightLineSet("adj_edges");
0282     adjacent_marker->SetLineWidth(2);
0283     adjacent_marker->SetLineColor(kYellow);
0284     adjacent_marker->GetLinePlex().Reset(sizeof(TEveStraightLineSet::Line_t), edges.size());
0285 
0286     TEveStraightLineSet *non_adjacent_marker = new TEveStraightLineSet("non_adj_edges");
0287     non_adjacent_marker->SetLineWidth(2);
0288     non_adjacent_marker->SetLineColor(kRed);
0289     non_adjacent_marker->GetLinePlex().Reset(sizeof(TEveStraightLineSet::Line_t), edges.size());
0290 
0291     for (auto edge : edges) {
0292       auto doublet = std::make_pair(layerClusters[edge[0]], layerClusters[edge[1]]);
0293 
0294       int layerIn = item()->getGeom()->getParameters(doublet.first.seed())[1];
0295       int layerOut = item()->getGeom()->getParameters(doublet.second.seed())[1];
0296 
0297       const bool isAdjacent = std::abs(layerOut - layerIn) == 1;
0298 
0299       // draw 3D cross
0300       if (layer_ == 0 || std::abs(layerIn - layer_) == 0 || std::abs(layerOut - layer_) == 0) {
0301         if (isAdjacent)
0302           adjacent_marker->AddLine(doublet.first.x(),
0303                                    doublet.first.y(),
0304                                    doublet.first.z(),
0305                                    doublet.second.x(),
0306                                    doublet.second.y(),
0307                                    doublet.second.z());
0308         else
0309           non_adjacent_marker->AddLine(doublet.first.x(),
0310                                        doublet.first.y(),
0311                                        doublet.first.z(),
0312                                        doublet.second.x(),
0313                                        doublet.second.y(),
0314                                        doublet.second.z());
0315       }
0316     }  // End of loop over all edges of the trackster
0317     oItemHolder.AddElement(adjacent_marker);
0318     oItemHolder.AddElement(non_adjacent_marker);
0319   }
0320 }
0321 
0322 REGISTER_FWPROXYBUILDER(FWTracksterHitsProxyBuilder, ticl::Trackster, "Trackster hits", FWViewType::kISpyBit);