Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
REveJetCone.cxx
Go to the documentation of this file.
1 // @(#)root/eve7:$Id$
2 // Author: Matevz Tadel, Jochen Thaeder 2009, 2018
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #include <ROOT/REveJetCone.hxx>
13 #include <ROOT/REveTrans.hxx>
15 #include <ROOT/REveRenderData.hxx>
16 
17 #include "TMath.h"
18 #include "TClass.h"
19 
20 #include <cassert>
21 
22 #include "json.hpp"
23 
24 
25 using namespace ROOT::Experimental;
26 namespace REX = ROOT::Experimental;
27 
28 /** \class REveJetCone
29 \ingroup REve
30 Draws a jet cone with leading particle is specified in (eta,phi) and
31 cone radius is given.
32 
33 If Apex is not set, default is (0.,0.,0.)
34 In case of cylinder was set, cone is cut at the cylinder edges.
35 
36 Example :
37 ~~~ {.cpp}
38  Float_t coneEta = r.Uniform(-0.9, 0.9);
39  Float_t conePhi = r.Uniform(0.0, TwoPi() );
40  Float_t coneRadius = 0.4;
41 
42  REveJetCone* jetCone = new REveJetCone("JetCone");
43  jetCone->SetCylinder(250, 250);
44  if (jetCone->AddCone(coneEta, conePhi, coneRadius) != -1)
45  gEve->AddElement(jetCone);
46 ~~~
47 
48 #### Implementation notes
49 
50 REveVector fLimits encodes the following information:
51  - fY, fZ: barrel radius and endcap z-position;
52  if both are 0, fX encodes the spherical radius
53  - fX : scaling for length of the cone
54 */
55 
56 ////////////////////////////////////////////////////////////////////////////////
57 /// Constructor.
58 
59 REveJetCone::REveJetCone(const Text_t* n, const Text_t* t) :
60  REveShape(n, t),
61  fApex(),
62  fLimits(), fThetaC(10),
63  fEta(0), fPhi(0), fDEta(0), fDPhi(0), fNDiv(36)
64 {
65  fFillColor = kGreen;
66 }
67 
68 ////////////////////////////////////////////////////////////////////////////////
69 /// Set Number of Divisions
70 ////////////////////////////////////////////////////////////////////////////////
71 void REveJetCone::SetNDiv(Int_t n)
72 {
73  fNDiv = TMath::Max(4, n);
74  if (fNDiv % 4 > 0) { fNDiv += 4 - fNDiv % 4; };
75  StampObjProps();
76 }
77 
78 ////////////////////////////////////////////////////////////////////////////////
79 /// Fill core part of JSON representation.
80 
81 Int_t REveJetCone::WriteCoreJson(nlohmann::json &j, Int_t rnr_offset)
82 {
83  Int_t ret = REveElement::WriteCoreJson(j, rnr_offset);
84 
85  j["fMainColor"] = GetFillColor();
86  j["fLineColor"] = GetLineColor();
87  j["fNDiv"] = GetNDiv();
88 
89  return ret;
90 }
91 
92 ////////////////////////////////////////////////////////////////////////////////
93 /// Crates 3D point array for rendering.
94 
95 void REveJetCone::BuildRenderData()
96 {
97  assert(fNDiv > 2);
98 
99  const Int_t NP = 1 + fNDiv;
100 
101  fRenderData = std::make_unique<REveRenderData>("makeJet", 3 * NP);
102 
103  fRenderData->PushV(fApex);
104 
105  Float_t angle_step = TMath::TwoPi() / fNDiv;
106  Float_t angle = 0;
107  for (Int_t i = 0; i < fNDiv; ++i, angle += angle_step)
108  {
109  fRenderData->PushV( CalcBaseVec(angle) );
110  }
111 }
112 
113 ////////////////////////////////////////////////////////////////////////////////
114 /// Compute bounding-box of the data.
115 
116 void REveJetCone::ComputeBBox()
117 {
118  BBoxInit();
119  BBoxCheckPoint(fApex);
120  BBoxCheckPoint(CalcBaseVec(0));
121  BBoxCheckPoint(CalcBaseVec(TMath::PiOver2()));
122  BBoxCheckPoint(CalcBaseVec(TMath::Pi()));
123  BBoxCheckPoint(CalcBaseVec(TMath::Pi() + TMath::PiOver2()));
124 }
125 
126 ////////////////////////////////////////////////////////////////////////////////
127 /// Virtual from REveProjectable, returns REveJetConeProjected class.
128 
129 TClass* REveJetCone::ProjectedClass(const REveProjection*) const
130 {
131  return TClass::GetClass<REveJetConeProjected>();
132 }
133 
134 ////////////////////////////////////////////////////////////////////////////////
135 /// Add jet cone.
136 /// parameters are :
137 /// - (eta,phi) : of the center/leading particle
138 /// - cone_r : cone radius in eta-phi space
139 /// - length : length of the cone
140 /// - if cylinder is set and length is adapted to cylinder.
141 /// - if length is given, it will be used as scalar factor
142 /// - if cylinder is not set, length is used as length of the cone
143 /// Return 0 on success.
144 
145 Int_t REveJetCone::AddCone(Float_t eta, Float_t phi, Float_t cone_r, Float_t length)
146 {
147  return AddEllipticCone(eta, phi, cone_r, cone_r, length);
148 }
149 
150 ////////////////////////////////////////////////////////////////////////////////
151 /// Add jet cone.
152 /// parameters are :
153 /// - (eta,phi) : of the center/leading particle
154 /// - (reta, rphi) : radius of cone in eta-phi space
155 /// - length : length of the cone
156 /// - if cylinder is set and length is adapted to cylinder.
157 /// - if length is given, it will be used as scalar factor
158 /// - if cylinder is not set, length is used as length of the cone
159 /// Returns 0 on success.
160 
161 Int_t REveJetCone::AddEllipticCone(Float_t eta, Float_t phi, Float_t reta, Float_t rphi, Float_t length)
162 {
163  if (length != 0) fLimits.fX = length;
164 
165  if (fLimits.IsZero())
166  return -1;
167 
168  fEta = eta; fPhi = phi; fDEta = reta; fDPhi = rphi;
169 
170  return 0;
171 }
172 
173 ////////////////////////////////////////////////////////////////////////////////
174 /// Fill REveVector with eta and phi, magnitude 1.
175 
176 REveVector REveJetCone::CalcEtaPhiVec(Float_t eta, Float_t phi) const
177 {
178  using namespace TMath;
179 
180  return REveVector(Cos(phi) / CosH(eta), Sin(phi) / CosH(eta), TanH(eta));
181 }
182 
183 ////////////////////////////////////////////////////////////////////////////////
184 /// Returns point on the base of the cone with given eta and phi.
185 
186 REveVector REveJetCone::CalcBaseVec(Float_t eta, Float_t phi) const
187 {
188  using namespace TMath;
189 
190  REveVector vec = CalcEtaPhiVec(eta, phi);
191 
192  // -- Set length of the contourPoint
193  if (fLimits.fY != 0 && fLimits.fZ != 0)
194  {
195  Float_t theta = vec.Theta();
196  if (theta < fThetaC)
197  vec *= fLimits.fZ / Cos(theta);
198  else if (theta > Pi() - fThetaC)
199  vec *= fLimits.fZ / Cos(theta - Pi());
200  else
201  vec *= fLimits.fY / Sin(theta);
202 
203  if (fLimits.fX != 0) vec *= fLimits.fX;
204  }
205  else
206  {
207  vec *= fLimits.fX;
208  }
209 
210  return vec;
211 }
212 
213 ////////////////////////////////////////////////////////////////////////////////
214 /// Returns point on the base of the cone with internal angle alpha:
215 /// alpha = 0 -> max eta, alpha = pi/2 -> max phi, ...
216 
217 REveVector REveJetCone::CalcBaseVec(Float_t alpha) const
218 {
219  using namespace TMath;
220 
221  return CalcBaseVec(fEta + fDEta * Cos(alpha), fPhi + fDPhi * Sin(alpha));
222 }
223 
224 ////////////////////////////////////////////////////////////////////////////////
225 /// Returns true if the cone is in barrel / endcap transition region.
226 
227 Bool_t REveJetCone::IsInTransitionRegion() const
228 {
229  using namespace TMath;
230 
231  Float_t tm = CalcBaseVec(0).Theta();
232  Float_t tM = CalcBaseVec(Pi()).Theta();
233 
234  return (tM > fThetaC && tm < fThetaC) ||
235  (tM > Pi() - fThetaC && tm < Pi() - fThetaC);
236 }
237 
238 
239 /** \class REveJetConeProjected
240 \ingroup REve
241 Projection of REveJetCone.
242 */
243 
244 ////////////////////////////////////////////////////////////////////////////////
245 /// Constructor.
246 
247 REveJetConeProjected::REveJetConeProjected(const std::string& n, const std::string& t) :
248  REveShape(n, t)
249 {
250 }
251 
252 ////////////////////////////////////////////////////////////////////////////////
253 /// Destructor.
254 
255 REveJetConeProjected::~REveJetConeProjected()
256 {
257 }
258 
259 ////////////////////////////////////////////////////////////////////////////////
260 /// Crates 3D point array for rendering.
261 
262 void REveJetConeProjected::BuildRenderData()
263 {
264  static const REveException kEH("REveJetConeProjected::BuildRenderData ");
265 
266  REveProjection *P = GetManager()->GetProjection();
267  REveJetCone *C = dynamic_cast<REveJetCone*>(GetProjectable());
268 
269  fRenderData = std::make_unique<REveRenderData>("makeJetProjected", 4);
270 
271  std::vector<REveVector> V;
272  V.reserve(4);
273  V.resize(3);
274 
275  switch (P->GetType())
276  {
277  case REveProjection::kPT_RPhi:
278  {
279  V[0] = C->fApex;
280  V[1] = C->CalcBaseVec(TMath::Pi() + TMath::PiOver2());
281  V[2] = C->CalcBaseVec(TMath::PiOver2());
282 
283  for (Int_t i = 0; i < 3; ++i)
284  P->ProjectVector(V[i], fDepth);
285 
286  break;
287  }
288 
289  case REveProjection::kPT_RhoZ:
290  {
291  V[0] = C->fApex;
292  V[1] = C->CalcBaseVec(0);
293  V[2] = C->CalcBaseVec(TMath::Pi());
294 
295  Float_t tm = V[1].Theta();
296  Float_t tM = V[2].Theta();
297 
298  if (tM > C->fThetaC && tm < C->fThetaC)
299  {
300  REveVector v(0, C->fLimits.fY, C->fLimits.fZ);
301 
302  V.push_back(C->CalcBaseVec(v.Eta(), C->fPhi));
303  }
304 
305  if (tM > TMath::Pi() - C->fThetaC && tm < TMath::Pi() - C->fThetaC)
306  {
307  REveVector v(0, C->fLimits.fY, -C->fLimits.fZ);
308 
309  V.push_back(C->CalcBaseVec(v.Eta(), C->fPhi));
310  }
311 
312  for (auto &v : V) P->ProjectVector(v, fDepth);
313 
314  std::sort(V.begin() + 1, V.end(),
315  [](const auto& a, const auto &b) -> bool
316  { return a.Phi() < b.Phi(); });
317 
318  break;
319  }
320 
321  default:
322  throw kEH + "Unsupported projection type.";
323  }
324 
325  for (auto &v : V) fRenderData->PushV(v);
326 }
327 
328 ////////////////////////////////////////////////////////////////////////////////
329 /// Compute bounding-box, virtual from TAttBBox.
330 
331 void REveJetConeProjected::ComputeBBox()
332 {
333  BBoxInit();
334 
335  REveJetCone *cone = dynamic_cast<REveJetCone*>(fProjectable);
336  REveProjection *proj = GetManager()->GetProjection();
337  REveVector v;
338  v = cone->fApex; proj->ProjectVector(v, fDepth); BBoxCheckPoint(v);
339  v = cone->CalcBaseVec(0); proj->ProjectVector(v, fDepth); BBoxCheckPoint(v);
340  v = cone->CalcBaseVec(TMath::PiOver2()); proj->ProjectVector(v, fDepth); BBoxCheckPoint(v);
341  v = cone->CalcBaseVec(TMath::Pi()); proj->ProjectVector(v, fDepth); BBoxCheckPoint(v);
342  v = cone->CalcBaseVec(TMath::Pi() + TMath::PiOver2()); proj->ProjectVector(v, fDepth); BBoxCheckPoint(v);
343 }
344 
345 ////////////////////////////////////////////////////////////////////////////////
346 /// This is virtual method from base-class REveProjected.
347 
348 void REveJetConeProjected::SetDepthLocal(Float_t d)
349 {
350  SetDepthCommon(d, this, fBBox);
351 }
352 
353 ////////////////////////////////////////////////////////////////////////////////
354 /// This is virtual method from base-class REveProjected.
355 
356 void REveJetConeProjected::SetProjection(REveProjectionManager* mng, REveProjectable* model)
357 {
358  REveProjected::SetProjection(mng, model);
359  CopyVizParams(dynamic_cast<REveElement*>(model));
360 }
361 
362 ////////////////////////////////////////////////////////////////////////////////
363 /// Re-project the jet-cone.
364 
365 void REveJetConeProjected::UpdateProjection()
366 {
367 }