Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:27:04

0001 #include "Fireworks/Core/interface/BuilderUtils.h"
0002 #include "Fireworks/Core/interface/Context.h"
0003 #include "Fireworks/Core/interface/FWProxyBuilderBase.h"
0004 
0005 #include "FWCore/Common/interface/EventBase.h"
0006 
0007 #include "TGeoBBox.h"
0008 #include "TColor.h"
0009 #include "TROOT.h"
0010 #include "TEveBox.h"
0011 #include "TEveScalableStraightLineSet.h"
0012 #include "TEveStraightLineSet.h"
0013 #include "TEveTrans.h"
0014 #include "TEveGeoNode.h"
0015 #include "TEveGeoShape.h"
0016 
0017 #include <cmath>
0018 #include <ctime>
0019 
0020 namespace fireworks {
0021   std::pair<double, double> getPhiRange(const std::vector<double>& phis, double phi) {
0022     double min = 100;
0023     double max = -100;
0024 
0025     for (std::vector<double>::const_iterator i = phis.begin(); i != phis.end(); ++i) {
0026       double aphi = *i;
0027       // make phi continuous around jet phi
0028       if (aphi - phi > M_PI)
0029         aphi -= 2 * M_PI;
0030       if (phi - aphi > M_PI)
0031         aphi += 2 * M_PI;
0032       if (aphi > max)
0033         max = aphi;
0034       if (aphi < min)
0035         min = aphi;
0036     }
0037 
0038     if (min > max)
0039       return std::pair<double, double>(0, 0);
0040 
0041     return std::pair<double, double>(min, max);
0042   }
0043 
0044   TEveGeoShape* getShape(const char* name, TGeoBBox* shape, Color_t color) {
0045     TEveGeoShape* egs = new TEveGeoShape(name);
0046     TColor* c = gROOT->GetColor(color);
0047     Float_t rgba[4] = {1, 0, 0, 1};
0048     if (c) {
0049       rgba[0] = c->GetRed();
0050       rgba[1] = c->GetGreen();
0051       rgba[2] = c->GetBlue();
0052     }
0053     egs->SetMainColorRGB(rgba[0], rgba[1], rgba[2]);
0054     egs->SetShape(shape);
0055     return egs;
0056   }
0057 
0058   void addRhoZEnergyProjection(FWProxyBuilderBase* pb,
0059                                TEveElement* container,
0060                                double r_ecal,
0061                                double z_ecal,
0062                                double theta_min,
0063                                double theta_max,
0064                                double phi) {
0065     TEveGeoManagerHolder gmgr(TEveGeoShape::GetGeoMangeur());
0066     double z1 = r_ecal / tan(theta_min);
0067     if (z1 > z_ecal)
0068       z1 = z_ecal;
0069     if (z1 < -z_ecal)
0070       z1 = -z_ecal;
0071     double z2 = r_ecal / tan(theta_max);
0072     if (z2 > z_ecal)
0073       z2 = z_ecal;
0074     if (z2 < -z_ecal)
0075       z2 = -z_ecal;
0076     double r1 = z_ecal * fabs(tan(theta_min));
0077     if (r1 > r_ecal)
0078       r1 = r_ecal;
0079     if (phi < 0)
0080       r1 = -r1;
0081     double r2 = z_ecal * fabs(tan(theta_max));
0082     if (r2 > r_ecal)
0083       r2 = r_ecal;
0084     if (phi < 0)
0085       r2 = -r2;
0086 
0087     if (fabs(r2 - r1) > 1) {
0088       TGeoBBox* sc_box = new TGeoBBox(0., fabs(r2 - r1) / 2, 1);
0089       TEveGeoShape* element = new TEveGeoShape("r-segment");
0090       element->SetShape(sc_box);
0091       TEveTrans& t = element->RefMainTrans();
0092       t(1, 4) = 0;
0093       t(2, 4) = (r2 + r1) / 2;
0094       t(3, 4) = fabs(z2) > fabs(z1) ? z2 : z1;
0095       pb->setupAddElement(element, container);
0096     }
0097     if (fabs(z2 - z1) > 1) {
0098       TGeoBBox* sc_box = new TGeoBBox(0., 1, (z2 - z1) / 2);
0099       TEveGeoShape* element = new TEveGeoShape("z-segment");
0100       element->SetShape(sc_box);
0101       TEveTrans& t = element->RefMainTrans();
0102       t(1, 4) = 0;
0103       t(2, 4) = fabs(r2) > fabs(r1) ? r2 : r1;
0104       t(3, 4) = (z2 + z1) / 2;
0105       pb->setupAddElement(element, container);
0106     }
0107   }
0108 
0109   std::string getTimeGMT(const edm::EventBase& event) {
0110     time_t t(event.time().value() >> 32);
0111     std::string text(asctime(gmtime(&t)));
0112     size_t pos = text.find('\n');
0113     if (pos != std::string::npos)
0114       text = text.substr(0, pos);
0115     text += " GMT";
0116     return text;
0117   }
0118 
0119   std::string getLocalTime(const edm::EventBase& event) {
0120     time_t t(event.time().value() >> 32);
0121     struct tm* xx = localtime(&t);
0122     std::string text(asctime(xx));
0123     size_t pos = text.find('\n');
0124     if (pos != std::string::npos)
0125       text = text.substr(0, pos);
0126     text += " ";
0127     if (xx->tm_isdst)
0128       text += tzname[1];
0129     else
0130       text += tzname[0];
0131     return text;
0132   }
0133 
0134   void invertBox(std::vector<float>& corners) {
0135     std::swap(corners[0], corners[9]);
0136     std::swap(corners[1], corners[10]);
0137     std::swap(corners[2], corners[11]);
0138 
0139     std::swap(corners[3], corners[6]);
0140     std::swap(corners[4], corners[7]);
0141     std::swap(corners[5], corners[8]);
0142 
0143     std::swap(corners[12], corners[21]);
0144     std::swap(corners[13], corners[22]);
0145     std::swap(corners[14], corners[23]);
0146 
0147     std::swap(corners[15], corners[18]);
0148     std::swap(corners[16], corners[19]);
0149     std::swap(corners[17], corners[20]);
0150   }
0151 
0152   void addBox(const std::vector<float>& corners, TEveElement* comp, FWProxyBuilderBase* pb) {
0153     TEveBox* eveBox = new TEveBox("Box");
0154     eveBox->SetDrawFrame(false);
0155     eveBox->SetPickable(true);
0156     eveBox->SetVertices(&corners[0]);
0157 
0158     pb->setupAddElement(eveBox, comp);
0159   }
0160 
0161   void addCircle(double eta,
0162                  double phi,
0163                  double radius,
0164                  const unsigned int nLineSegments,
0165                  TEveElement* comp,
0166                  FWProxyBuilderBase* pb) {
0167     TEveStraightLineSet* container = new TEveStraightLineSet;
0168 
0169     for (unsigned int iphi = 0; iphi < nLineSegments; ++iphi) {
0170       container->AddLine(eta + radius * cos(2 * M_PI / nLineSegments * iphi),
0171                          phi + radius * sin(2 * M_PI / nLineSegments * iphi),
0172                          0.01,
0173                          eta + radius * cos(2 * M_PI / nLineSegments * (iphi + 1)),
0174                          phi + radius * sin(2 * M_PI / nLineSegments * (iphi + 1)),
0175                          0.01);
0176     }
0177     pb->setupAddElement(container, comp);
0178   }
0179 
0180   void addDashedArrow(double phi, double size, TEveElement* comp, FWProxyBuilderBase* pb) {
0181     TEveScalableStraightLineSet* marker = new TEveScalableStraightLineSet;
0182     marker->SetLineWidth(1);
0183     marker->SetLineStyle(2);
0184     marker->AddLine(0, 0, 0, size * cos(phi), size * sin(phi), 0);
0185     marker->AddLine(size * 0.9 * cos(phi + 0.03), size * 0.9 * sin(phi + 0.03), 0, size * cos(phi), size * sin(phi), 0);
0186     marker->AddLine(size * 0.9 * cos(phi - 0.03), size * 0.9 * sin(phi - 0.03), 0, size * cos(phi), size * sin(phi), 0);
0187     pb->setupAddElement(marker, comp);
0188   }
0189 
0190   void addDashedLine(double phi, double theta, double size, TEveElement* comp, FWProxyBuilderBase* pb) {
0191     double r(0);
0192     if (theta < pb->context().caloTransAngle() || M_PI - theta < pb->context().caloTransAngle())
0193       r = pb->context().caloZ2() / fabs(cos(theta));
0194     else
0195       r = pb->context().caloR1() / sin(theta);
0196 
0197     TEveStraightLineSet* marker = new TEveStraightLineSet;
0198     marker->SetLineWidth(2);
0199     marker->SetLineStyle(2);
0200     marker->AddLine(r * cos(phi) * sin(theta),
0201                     r * sin(phi) * sin(theta),
0202                     r * cos(theta),
0203                     (r + size) * cos(phi) * sin(theta),
0204                     (r + size) * sin(phi) * sin(theta),
0205                     (r + size) * cos(theta));
0206     pb->setupAddElement(marker, comp);
0207   }
0208 
0209   void addDoubleLines(double phi, TEveElement* comp, FWProxyBuilderBase* pb) {
0210     TEveStraightLineSet* mainLine = new TEveStraightLineSet;
0211     mainLine->AddLine(-5.191, phi, 0.01, 5.191, phi, 0.01);
0212     pb->setupAddElement(mainLine, comp);
0213 
0214     phi = phi > 0 ? phi - M_PI : phi + M_PI;
0215     TEveStraightLineSet* secondLine = new TEveStraightLineSet;
0216     secondLine->SetLineStyle(7);
0217     secondLine->AddLine(-5.191, phi, 0.01, 5.191, phi, 0.01);
0218     pb->setupAddElement(secondLine, comp);
0219   }
0220 
0221   //______________________________________________________________________________
0222   void energyScaledBox3DCorners(const float* corners, float scale, std::vector<float>& scaledCorners, bool invert) {
0223     std::vector<float> centre(3, 0);
0224 
0225     for (unsigned int i = 0; i < 24; i += 3) {
0226       centre[0] += corners[i];
0227       centre[1] += corners[i + 1];
0228       centre[2] += corners[i + 2];
0229     }
0230 
0231     for (unsigned int i = 0; i < 3; ++i)
0232       centre[i] *= 1.0f / 8.0f;
0233 
0234     // Coordinates for a scaled version of the original box
0235     for (unsigned int i = 0; i < 24; i += 3) {
0236       scaledCorners[i] = centre[0] + (corners[i] - centre[0]) * scale;
0237       scaledCorners[i + 1] = centre[1] + (corners[i + 1] - centre[1]) * scale;
0238       scaledCorners[i + 2] = centre[2] + (corners[i + 2] - centre[2]) * scale;
0239     }
0240 
0241     if (invert)
0242       invertBox(scaledCorners);
0243   }
0244 
0245   void drawEnergyScaledBox3D(const float* corners, float scale, TEveElement* comp, FWProxyBuilderBase* pb, bool invert) {
0246     std::vector<float> scaledCorners(24);
0247     energyScaledBox3DCorners(corners, scale, scaledCorners, invert);
0248     addBox(scaledCorners, comp, pb);
0249   }
0250   //______________________________________________________________________________
0251 
0252   void etScaledBox3DCorners(
0253       const float* corners, float energy, float maxEnergy, std::vector<float>& scaledCorners, bool invert) {
0254     std::vector<float> centre(3, 0);
0255 
0256     for (unsigned int i = 0; i < 24; i += 3) {
0257       centre[0] += corners[i];
0258       centre[1] += corners[i + 1];
0259       centre[2] += corners[i + 2];
0260     }
0261 
0262     for (unsigned int i = 0; i < 3; ++i)
0263       centre[i] *= 1.0f / 8.0f;
0264 
0265     TEveVector c(centre[0], centre[1], centre[2]);
0266     float scale = energy / maxEnergy * sin(c.Theta());
0267 
0268     // Coordinates for a scaled version of the original box
0269     for (unsigned int i = 0; i < 24; i += 3) {
0270       scaledCorners[i] = centre[0] + (corners[i] - centre[0]) * scale;
0271       scaledCorners[i + 1] = centre[1] + (corners[i + 1] - centre[1]) * scale;
0272       scaledCorners[i + 2] = centre[2] + (corners[i + 2] - centre[2]) * scale;
0273     }
0274 
0275     if (invert)
0276       invertBox(scaledCorners);
0277   }
0278 
0279   void drawEtScaledBox3D(
0280       const float* corners, float energy, float maxEnergy, TEveElement* comp, FWProxyBuilderBase* pb, bool invert) {
0281     std::vector<float> scaledCorners(24);
0282     etScaledBox3DCorners(corners, energy, maxEnergy, scaledCorners, invert);
0283     addBox(scaledCorners, comp, pb);
0284   }
0285 
0286   //______________________________________________________________________________
0287   void energyTower3DCorners(const float* corners, float scale, std::vector<float>& scaledCorners, bool reflect) {
0288     for (int i = 0; i < 24; ++i)
0289       scaledCorners[i] = corners[i];
0290     // Coordinates of a front face scaled
0291     if (reflect) {
0292       // We know, that an ES rechit geometry in -Z needs correction.
0293       // The back face is actually its front face.
0294       for (unsigned int i = 0; i < 12; i += 3) {
0295         TEveVector diff(
0296             corners[i] - corners[i + 12], corners[i + 1] - corners[i + 13], corners[i + 2] - corners[i + 14]);
0297         diff.Normalize();
0298         diff *= scale;
0299 
0300         scaledCorners[i] = corners[i] + diff.fX;
0301         scaledCorners[i + 1] = corners[i + 1] + diff.fY;
0302         scaledCorners[i + 2] = corners[i + 2] + diff.fZ;
0303       }
0304     } else {
0305       for (unsigned int i = 0; i < 12; i += 3) {
0306         TEveVector diff(
0307             corners[i + 12] - corners[i], corners[i + 13] - corners[i + 1], corners[i + 14] - corners[i + 2]);
0308         diff.Normalize();
0309         diff *= scale;
0310 
0311         scaledCorners[i] = corners[i + 12];
0312         scaledCorners[i + 1] = corners[i + 13];
0313         scaledCorners[i + 2] = corners[i + 14];
0314 
0315         scaledCorners[i + 12] = corners[i + 12] + diff.fX;
0316         scaledCorners[i + 13] = corners[i + 13] + diff.fY;
0317         scaledCorners[i + 14] = corners[i + 14] + diff.fZ;
0318       }
0319     }
0320   }
0321 
0322   void drawEnergyTower3D(const float* corners, float scale, TEveElement* comp, FWProxyBuilderBase* pb, bool reflect) {
0323     std::vector<float> scaledCorners(24);
0324     energyTower3DCorners(corners, scale, scaledCorners, reflect);
0325     addBox(scaledCorners, comp, pb);
0326   }
0327 
0328   //______________________________________________________________________________
0329 
0330   void etTower3DCorners(const float* corners, float scale, std::vector<float>& scaledCorners, bool reflect) {
0331     for (int i = 0; i < 24; ++i)
0332       scaledCorners[i] = corners[i];
0333     // Coordinates of a front face scaled
0334     if (reflect) {
0335       // We know, that an ES rechit geometry in -Z needs correction.
0336       // The back face is actually its front face.
0337       for (unsigned int i = 0; i < 12; i += 3) {
0338         TEveVector diff(
0339             corners[i] - corners[i + 12], corners[i + 1] - corners[i + 13], corners[i + 2] - corners[i + 14]);
0340         diff.Normalize();
0341         diff *= (scale * sin(diff.Theta()));
0342 
0343         scaledCorners[i] = corners[i] + diff.fX;
0344         scaledCorners[i + 1] = corners[i + 1] + diff.fY;
0345         scaledCorners[i + 2] = corners[i + 2] + diff.fZ;
0346       }
0347     } else {
0348       for (unsigned int i = 0; i < 12; i += 3) {
0349         TEveVector diff(
0350             corners[i + 12] - corners[i], corners[i + 13] - corners[i + 1], corners[i + 14] - corners[i + 2]);
0351         diff.Normalize();
0352         diff *= (scale * sin(diff.Theta()));
0353 
0354         scaledCorners[i] = corners[i + 12];
0355         scaledCorners[i + 1] = corners[i + 13];
0356         scaledCorners[i + 2] = corners[i + 14];
0357 
0358         scaledCorners[i + 12] = corners[i + 12] + diff.fX;
0359         scaledCorners[i + 13] = corners[i + 13] + diff.fY;
0360         scaledCorners[i + 14] = corners[i + 14] + diff.fZ;
0361       }
0362     }
0363   }
0364 
0365   void drawEtTower3D(const float* corners, float scale, TEveElement* comp, FWProxyBuilderBase* pb, bool reflect) {
0366     std::vector<float> scaledCorners(24);
0367     etTower3DCorners(corners, scale, scaledCorners, reflect);
0368     addBox(scaledCorners, comp, pb);
0369   }
0370 
0371 }  // namespace fireworks