Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-05-26 22:39:30

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     edm::LogWarning("DataNotFound|InvalidData") << "couldn't locate 'timeLayerCluster' ValueMap in root file.";
0074   }
0075 
0076   if (!layerClustersHandle_.isValid()) {
0077     edm::LogWarning("DataNotFound|InvalidData") << "couldn't locate 'timeLayerCluster' ValueMap in root file.";
0078   }
0079 
0080   layer_ = item()->getConfig()->value<long>("Layer");
0081   saturation_energy_ = item()->getConfig()->value<double>("EnergyCutOff");
0082   heatmap_ = item()->getConfig()->value<bool>("Heatmap");
0083   z_plus_ = item()->getConfig()->value<bool>("Z+");
0084   z_minus_ = item()->getConfig()->value<bool>("Z-");
0085   enableTimeFilter_ = item()->getConfig()->value<bool>("EnableTimeFilter");
0086   enableSeedLines_ = item()->getConfig()->value<bool>("EnableSeedLines");
0087   enablePositionLines_ = item()->getConfig()->value<bool>("EnablePositionLines");
0088   enableEdges_ = item()->getConfig()->value<bool>("EnableEdges");
0089 
0090   FWHeatmapProxyBuilderTemplate::build(iItem, product, vc);
0091 }
0092 
0093 void FWTracksterHitsProxyBuilder::build(const ticl::Trackster &iData,
0094                                         unsigned int iIndex,
0095                                         TEveElement &oItemHolder,
0096                                         const FWViewContext *) {
0097   if (enableTimeFilter_ && TimeValueMapHandle_.isValid()) {
0098     const float time = TimeValueMapHandle_->get(iIndex).first;
0099     if (time < timeLowerBound_ || time > timeUpperBound_)
0100       return;
0101   }
0102 
0103   const ticl::Trackster &trackster = iData;
0104   const size_t N = trackster.vertices().size();
0105   const std::vector<reco::CaloCluster> &layerClusters = *layerClustersHandle_;
0106 
0107   TEveBoxSet *hex_boxset = new TEveBoxSet();
0108   if (!heatmap_)
0109     hex_boxset->UseSingleColor();
0110   hex_boxset->SetPickable(true);
0111   hex_boxset->Reset(TEveBoxSet::kBT_Hex, true, 64);
0112 
0113   TEveBoxSet *boxset = new TEveBoxSet();
0114   if (!heatmap_)
0115     boxset->UseSingleColor();
0116   boxset->SetPickable(true);
0117   boxset->Reset(TEveBoxSet::kBT_FreeBox, true, 64);
0118 
0119   TEveStraightLineSet *seed_marker = nullptr;
0120   if (enableSeedLines_) {
0121     seed_marker = new TEveStraightLineSet("seeds");
0122     seed_marker->SetLineWidth(2);
0123     seed_marker->SetLineColor(kOrange + 10);
0124     seed_marker->GetLinePlex().Reset(sizeof(TEveStraightLineSet::Line_t), 2 * N);
0125   }
0126 
0127   TEveStraightLineSet *position_marker = nullptr;
0128   if (enablePositionLines_) {
0129     position_marker = new TEveStraightLineSet("positions");
0130     position_marker->SetLineWidth(2);
0131     position_marker->SetLineColor(kOrange);
0132     position_marker->GetLinePlex().Reset(sizeof(TEveStraightLineSet::Line_t), 2 * N);
0133   }
0134 
0135   for (size_t i = 0; i < N; ++i) {
0136     const reco::CaloCluster layerCluster = layerClusters[trackster.vertices(i)];
0137     std::vector<std::pair<DetId, float>> clusterDetIds = layerCluster.hitsAndFractions();
0138 
0139     for (std::vector<std::pair<DetId, float>>::iterator it = clusterDetIds.begin(), itEnd = clusterDetIds.end();
0140          it != itEnd;
0141          ++it) {
0142       const float *corners = item()->getGeom()->getCorners(it->first);
0143       if (corners == nullptr)
0144         continue;
0145 
0146       if (heatmap_ && hitmap->find(it->first) == hitmap->end())
0147         continue;
0148 
0149       const float *parameters = item()->getGeom()->getParameters(it->first);
0150       const float *shapes = item()->getGeom()->getShapePars(it->first);
0151 
0152       if (parameters == nullptr || shapes == nullptr)
0153         continue;
0154 
0155       const int total_points = parameters[0];
0156       const int layer = parameters[1];
0157       const int zside = parameters[2];
0158       const bool isSilicon = parameters[3];
0159 
0160       // discard everything that's not at the side that we are intersted in
0161       auto const z_selection_is_on = z_plus_ ^ z_minus_;
0162       auto const z_plus_selection_ok = z_plus_ && (zside == 1);
0163       auto const z_minus_selection_ok = z_minus_ && (zside == -1);
0164       if (!z_minus_ && !z_plus_)
0165         break;
0166       if (z_selection_is_on && !(z_plus_selection_ok || z_minus_selection_ok))
0167         break;
0168 
0169       if (layer_ > 0 && layer != layer_)
0170         break;
0171 
0172       // seed and cluster position
0173       if (layerCluster.seed().rawId() == it->first.rawId()) {
0174         const float crossScale = 0.2f + fmin(layerCluster.energy(), 5.0f);
0175         if (enableSeedLines_) {
0176           // center of RecHit
0177           const float center[3] = {corners[total_points * 3 + 0],
0178                                    corners[total_points * 3 + 1],
0179                                    corners[total_points * 3 + 2] + shapes[3] * 0.5f};
0180 
0181           // draw 3D cross
0182           seed_marker->AddLine(
0183               center[0] - crossScale, center[1], center[2], center[0] + crossScale, center[1], center[2]);
0184           seed_marker->AddLine(
0185               center[0], center[1] - crossScale, center[2], center[0], center[1] + crossScale, center[2]);
0186         }
0187 
0188         if (enablePositionLines_) {
0189           auto const &pos = layerCluster.position();
0190           const float position_crossScale = crossScale * 0.5;
0191           position_marker->AddLine(
0192               pos.x() - position_crossScale, pos.y(), pos.z(), pos.x() + position_crossScale, pos.y(), pos.z());
0193           position_marker->AddLine(
0194               pos.x(), pos.y() - position_crossScale, pos.z(), pos.x(), pos.y() + position_crossScale, pos.z());
0195         }
0196       }
0197 
0198       const float energy =
0199           fmin((item()->getConfig()->value<bool>("Cluster(0)/RecHit(1)") ? hitmap->at(it->first)->energy()
0200                                                                          : layerCluster.energy()) /
0201                    saturation_energy_,
0202                1.0f);
0203       const uint8_t colorFactor = gradient_steps * energy;
0204       auto transparency = item()->modelInfo(iIndex).displayProperties().transparency();
0205       UChar_t alpha = (255 * (100 - transparency)) / 100;
0206 
0207       // Scintillator
0208       if (!isSilicon) {
0209         const int total_vertices = 3 * total_points;
0210 
0211         std::vector<float> pnts(24);
0212         for (int i = 0; i < total_points; ++i) {
0213           pnts[i * 3 + 0] = corners[i * 3];
0214           pnts[i * 3 + 1] = corners[i * 3 + 1];
0215           pnts[i * 3 + 2] = corners[i * 3 + 2];
0216 
0217           pnts[(i * 3 + 0) + total_vertices] = corners[i * 3];
0218           pnts[(i * 3 + 1) + total_vertices] = corners[i * 3 + 1];
0219           pnts[(i * 3 + 2) + total_vertices] = corners[i * 3 + 2] + shapes[3];
0220         }
0221         boxset->AddBox(&pnts[0]);
0222         if (heatmap_) {
0223           energy
0224               ? boxset->DigitColor(gradient[0][colorFactor], gradient[1][colorFactor], gradient[2][colorFactor], alpha)
0225               : boxset->DigitColor(64, 64, 64, alpha);
0226         }
0227       }
0228       // Silicon
0229       else {
0230         constexpr int offset = 9;
0231 
0232         float centerX = (corners[6] + corners[6 + offset]) / 2;
0233         float centerY = (corners[7] + corners[7 + offset]) / 2;
0234         float radius = fabs(corners[6] - corners[6 + offset]) / 2;
0235         hex_boxset->AddHex(TEveVector(centerX, centerY, corners[2]), radius, shapes[2], shapes[3]);
0236         if (heatmap_) {
0237           energy ? hex_boxset->DigitColor(
0238                        gradient[0][colorFactor], gradient[1][colorFactor], gradient[2][colorFactor], alpha)
0239                  : hex_boxset->DigitColor(64, 64, 64, alpha);
0240         } else {
0241           hex_boxset->CSCApplyMainColorToMatchingChildren();
0242           hex_boxset->CSCApplyMainTransparencyToMatchingChildren();
0243           hex_boxset->SetMainColor(item()->modelInfo(iIndex).displayProperties().color());
0244           hex_boxset->SetMainTransparency(item()->defaultDisplayProperties().transparency());
0245         }
0246       }
0247     }  // End of loop over rechits of a single layercluster
0248   }    // End loop over the layerclusters of the trackster
0249 
0250   hex_boxset->RefitPlex();
0251   boxset->RefitPlex();
0252   setupAddElement(hex_boxset, &oItemHolder);
0253   setupAddElement(boxset, &oItemHolder);
0254 
0255   if (enableSeedLines_)
0256     oItemHolder.AddElement(seed_marker);
0257 
0258   if (enablePositionLines_)
0259     oItemHolder.AddElement(position_marker);
0260 
0261   if (enableEdges_) {
0262     auto &edges = trackster.edges();
0263 
0264     TEveStraightLineSet *adjacent_marker = new TEveStraightLineSet("adj_edges");
0265     adjacent_marker->SetLineWidth(2);
0266     adjacent_marker->SetLineColor(kYellow);
0267     adjacent_marker->GetLinePlex().Reset(sizeof(TEveStraightLineSet::Line_t), edges.size());
0268 
0269     TEveStraightLineSet *non_adjacent_marker = new TEveStraightLineSet("non_adj_edges");
0270     non_adjacent_marker->SetLineWidth(2);
0271     non_adjacent_marker->SetLineColor(kRed);
0272     non_adjacent_marker->GetLinePlex().Reset(sizeof(TEveStraightLineSet::Line_t), edges.size());
0273 
0274     for (auto edge : edges) {
0275       auto doublet = std::make_pair(layerClusters[edge[0]], layerClusters[edge[1]]);
0276 
0277       int layerIn = item()->getGeom()->getParameters(doublet.first.seed())[1];
0278       int layerOut = item()->getGeom()->getParameters(doublet.second.seed())[1];
0279 
0280       const bool isAdjacent = std::abs(layerOut - layerIn) == 1;
0281 
0282       // draw 3D cross
0283       if (layer_ == 0 || std::abs(layerIn - layer_) == 0 || std::abs(layerOut - layer_) == 0) {
0284         if (isAdjacent)
0285           adjacent_marker->AddLine(doublet.first.x(),
0286                                    doublet.first.y(),
0287                                    doublet.first.z(),
0288                                    doublet.second.x(),
0289                                    doublet.second.y(),
0290                                    doublet.second.z());
0291         else
0292           non_adjacent_marker->AddLine(doublet.first.x(),
0293                                        doublet.first.y(),
0294                                        doublet.first.z(),
0295                                        doublet.second.x(),
0296                                        doublet.second.y(),
0297                                        doublet.second.z());
0298       }
0299     }  // End of loop over all edges of the trackster
0300     oItemHolder.AddElement(adjacent_marker);
0301     oItemHolder.AddElement(non_adjacent_marker);
0302   }
0303 }
0304 
0305 REGISTER_FWPROXYBUILDER(FWTracksterHitsProxyBuilder, ticl::Trackster, "Trackster hits", FWViewType::kISpyBit);