File indexing completed on 2023-03-17 11:01:13
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
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
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
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
0291 if (reflect) {
0292
0293
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
0334 if (reflect) {
0335
0336
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 }