GRSISort "v4.0.0.5"
An extension of the ROOT analysis Framework
Loading...
Searching...
No Matches
TLevelScheme.h
Go to the documentation of this file.
1#ifndef TLEVELSCHEME_H
2#define TLEVELSCHEME_H
3
4#if __cplusplus >= 201703L
5
6#include <iostream>
7#include <vector>
8#include <map>
9#include <utility>
10
11#include "TColor.h"
12#include "TPolyLine.h"
13#include "TArrow.h"
14#include "TPaveLabel.h"
15#include "TLatex.h"
16
17/** \addtogroup GUI
18 * @{
19 */
20
21/////////////////////////////////////////////////////////////////
22///
23/// \class TLevelScheme
24///
25/// This class implements a level scheme. The level scheme has a
26/// vector of bands/groups of levels. Each of the bands contains
27/// a map of levels, and each level has a map of gamma rays draining it.
28/// The gamma rays can have strength assigned to them which then
29/// can translate to the width of their arrows.
30///
31/////////////////////////////////////////////////////////////////
32
33class TLevelScheme;
34
35class TGamma : public TArrow {
36public:
37 explicit TGamma(TLevelScheme* levelScheme = nullptr, std::string label = "", const double& br = 100., const double& ts = 1.);
38 TGamma(const TGamma& rhs);
39 TGamma(TGamma&& rhs) noexcept = default;
40 TGamma& operator=(const TGamma& rhs);
41 TGamma& operator=(TGamma&& rhs) noexcept = default;
42 ~TGamma() = default;
43
44 // setters
45 void Energy(const double val) { fEnergy = val; }
46 void EnergyUncertainty(const double val) { fEnergyUncertainty = val; }
47 void UseTransitionStrength(const bool val)
48 {
49 fUseTransitionStrength = val;
50 UpdateWidth();
51 } // *MENU*
52 void Scaling(const double offset, const double gain)
53 {
54 fScalingOffset = offset;
55 fScalingGain = gain;
56 UpdateWidth();
57 } // *MENU*
58 void BranchingRatio(const double val)
59 {
60 fBranchingRatio = val;
61 UpdateWidth();
62 } // *MENU*
63 void BranchingRatioUncertainty(const double val) { fBranchingRatioUncertainty = val; }
64 void BranchingRatioPercent(const double val) { fBranchingRatioPercent = val; }
65 void BranchingRatioPercentUncertainty(const double val) { fBranchingRatioPercentUncertainty = val; }
66 void TransitionStrength(const double val)
67 {
68 fTransitionStrength = val;
69 UpdateWidth();
70 } // *MENU*
71 void TransitionStrengthUncertainty(const double val) { fTransitionStrengthUncertainty = val; }
72 void LabelText(const char* val)
73 {
74 fLabelText = val;
75 UpdateLabel();
76 } // *MENU*
77 void InitialEnergy(const double val) { fInitialEnergy = val; }
78 void FinalEnergy(const double val) { fFinalEnergy = val; }
79
80 // getters
81 double Energy() const { return fEnergy; }
82 double EnergyUncertainty() const { return fEnergyUncertainty; }
83 bool UseTransitionStrength() const { return fUseTransitionStrength; }
84 double ScalingGain() const { return fScalingGain; }
85 double ScalingOffset() const { return fScalingOffset; }
86 double BranchingRatio() const { return fBranchingRatio; }
87 double BranchingRatioUncertainty() const { return fBranchingRatioUncertainty; }
88 double BranchingRatioPercent() const { return fBranchingRatioPercent; }
89 double BranchingRatioPercentUncertainty() const { return fBranchingRatioPercentUncertainty; }
90 double TransitionStrength() const { return fTransitionStrength; }
91 double TransitionStrengthUncertainty() const { return fTransitionStrengthUncertainty; }
92 double InitialEnergy() const { return fInitialEnergy; }
93 double FinalEnergy() const { return fFinalEnergy; }
94 double Width() const { return (fUseTransitionStrength ? fTransitionStrength : fBranchingRatio); }
95 std::string LabelText() const { return fLabelText; }
96 TLatex* Label() const { return fLabel; }
97
98 std::map<double, double> CoincidentGammas();
99 void PrintCoincidentGammas(); // *MENU*
100
101 std::vector<std::tuple<double, std::vector<double>>> ParallelGammas();
102 void PrintParallelGammas(); // *MENU*
103
104 void Print(Option_t* option = "") const override;
105
106 void UpdateWidth();
107 void UpdateLabel();
108
109 using TArrow::Draw;
110 void Draw(const double& x1, const double& y1, const double& x2, const double& y2);
111
112 void Debug(bool val) { fDebug = val; }
113
114 static void TextSize(float val) { fTextSize = val; }
115 static float TextSize() { return fTextSize; }
116
117private:
118 bool fDebug{false};
119 bool fUseTransitionStrength{false};
120 double fEnergy{0.}; ///< Energy of this gamma ray
121 double fEnergyUncertainty{0.};
122 double fScalingGain{1.};
123 double fScalingOffset{1.};
124 double fBranchingRatio{100.};
125 double fBranchingRatioUncertainty{0.};
126 double fBranchingRatioPercent{100.};
127 double fBranchingRatioPercentUncertainty{0.};
128 double fTransitionStrength{1.};
129 double fTransitionStrengthUncertainty{0.};
130 std::string fLabelText;
131 TLatex* fLabel{nullptr};
132 TLevelScheme* fLevelScheme{nullptr};
133 double fInitialEnergy{0.}; ///< Energy of initial level that emits this gamma ray
134 double fFinalEnergy{0.}; ///< Energy of final level that is populated by this gamma ray
135
136 static float fTextSize;
137
138 /// \cond CLASSIMP
139 ClassDefOverride(TGamma, 1) // NOLINT(readability-else-after-return)
140 /// \endcond
141};
142
143class TLevel : public TPolyLine {
144public:
145 explicit TLevel(TLevelScheme* levelScheme = nullptr, const double& energy = -1., const std::string& label = "");
146 TLevel(const TLevel& rhs);
147 TLevel(TLevel&& rhs) noexcept = default;
148 TLevel& operator=(const TLevel& rhs);
149 TLevel& operator=(TLevel&& rhs) noexcept = default;
150 ~TLevel();
151
152 TGamma* AddGamma(double levelEnergy, const char* label = "", double br = 100., double ts = 1.); // *MENU*
153 TGamma* AddGamma(double levelEnergy, double energyUncertainty, const char* label = "", double br = 100., double ts = 1.);
154
155 void Energy(const double val) { fEnergy = val; } // *MENU*
156 void EnergyUncertainty(const double val) { fEnergyUncertainty = val; } // *MENU*
157 void Label(const char* val) { fLabel = val; } // *MENU*
158 void AddFeeding() { ++fNofFeeding; }
159 void Offset(const double& val) { fOffset = val; }
160
161 void MoveToBand(const char* val); // *MENU*
162
163 double Energy() const { return fEnergy; }
164 double EnergyUncertainty() const { return fEnergyUncertainty; }
165 std::string Label() const { return fLabel; }
166 double Offset() const { return fOffset; }
167
168 std::pair<double, double> GetMinMaxGamma() const;
169 size_t NofDrainingGammas() const { return fGammas.size(); }
170 size_t NofFeedingGammas() const { return fNofFeeding; }
171
172 using TPolyLine::Draw;
173 void Draw(const double& left, const double& right);
174 double DrawLabel(const double& pos);
175 double DrawEnergy(const double& pos);
176
177 std::map<double, TGamma>::iterator begin() { return fGammas.begin(); }
178 std::map<double, TGamma>::iterator end() { return fGammas.end(); }
179 std::map<double, TGamma>::const_iterator begin() const { return fGammas.begin(); }
180 std::map<double, TGamma>::const_iterator end() const { return fGammas.end(); }
181
182 // comparison operators (level-level, level-double, and double-level)
183 friend bool operator<(const TLevel& lhs, const TLevel& rhs) { return lhs.fEnergy < rhs.fEnergy; }
184 friend bool operator>(const TLevel& lhs, const TLevel& rhs) { return rhs < lhs; }
185 friend bool operator<=(const TLevel& lhs, const TLevel& rhs) { return !(rhs < lhs); }
186 friend bool operator>=(const TLevel& lhs, const TLevel& rhs) { return !(lhs < rhs); }
187
188 friend bool operator<(const TLevel& lhs, const double& rhs) { return lhs.fEnergy < rhs; }
189 friend bool operator>(const TLevel& lhs, const double& rhs) { return rhs < lhs; }
190 friend bool operator<=(const TLevel& lhs, const double& rhs) { return !(rhs < lhs); }
191 friend bool operator>=(const TLevel& lhs, const double& rhs) { return !(lhs < rhs); }
192
193 friend bool operator<(const double& lhs, const TLevel& rhs) { return lhs < rhs.fEnergy; }
194 friend bool operator>(const double& lhs, const TLevel& rhs) { return rhs < lhs; }
195 friend bool operator<=(const double& lhs, const TLevel& rhs) { return !(rhs < lhs); }
196 friend bool operator>=(const double& lhs, const TLevel& rhs) { return !(lhs < rhs); }
197
198 void Print(Option_t* option = "") const override;
199
200 void Debug(bool val)
201 {
202 fDebug = val;
203 for(auto& [level, gamma] : fGammas) { gamma.Debug(val); }
204 }
205
206 static void TextSize(float val) { fTextSize = val; }
207 static float TextSize() { return fTextSize; }
208
209private:
210 bool fDebug{false};
211 double fEnergy{0.}; ///< energy of this level
212 double fEnergyUncertainty{0.}; ///< energy uncertainty of this level
213 std::string fLabel; ///< label for this level
214 std::map<double, TGamma> fGammas; ///< gamma rays draining this level, each pointing to a level
215 size_t fNofFeeding{0}; ///< counter for gammas feeding this level
216 TLevelScheme* fLevelScheme{nullptr};
217
218 // graphics elements
219 TLatex* fLevelLabel{nullptr};
220 TLatex* fEnergyLabel{nullptr};
221
222 double fOffset{0.}; ///< y-offset for labels on right and left side of level
223
224 static float fTextSize;
225
226 /// \cond CLASSIMP
227 ClassDefOverride(TLevel, 1) // NOLINT(readability-else-after-return)
228 /// \endcond
229};
230
231class TBand : public TPaveLabel {
232public:
233 explicit TBand(TLevelScheme* levelScheme = nullptr, const std::string& label = "");
234 TBand(const TBand& rhs);
235 TBand(TBand&& rhs) noexcept = default;
236 TBand& operator=(const TBand& rhs);
237 TBand& operator=(TBand&& rhs) noexcept = default;
238 ~TBand() = default;
239
240 TLevel* AddLevel(double energy, const std::string& label); // *MENU*
241 TLevel* AddLevel(const double energy, const char* label)
242 {
243 std::string tmp(label);
244 return AddLevel(energy, tmp);
245 } // *MENU*
246 void AddLevel(TLevel* level);
247 void RemoveLevel(TLevel* level);
248
249 size_t NofLevels() const { return fLevels.size(); }
250 TLevel* GetLevel(double energy);
251 TLevel* FindLevel(double energy, double energyUncertainty);
252 std::pair<double, double> GetMinMaxLevelEnergy() const { return std::make_pair(fLevels.begin()->second.Energy(), fLevels.rbegin()->second.Energy()); }
253 std::pair<double, double> GetMinMaxGamma() const;
254 double Width(double distance) const; ///< return width of this band using provided distance between gammas
255
256 std::map<double, TLevel>::iterator begin() { return fLevels.begin(); }
257 std::map<double, TLevel>::iterator end() { return fLevels.end(); }
258 std::map<double, TLevel>::const_iterator begin() const { return fLevels.begin(); }
259 std::map<double, TLevel>::const_iterator end() const { return fLevels.end(); }
260
261 void Print(Option_t* option = "") const override;
262
263 void Debug(bool val)
264 {
265 fDebug = val;
266 for(auto& [energy, level] : fLevels) { level.Debug(val); }
267 }
268
269private:
270 bool fDebug{false};
271 std::map<double, TLevel> fLevels;
272 TLevelScheme* fLevelScheme{nullptr};
273
274 /// \cond CLASSIMP
275 ClassDefOverride(TBand, 1) // NOLINT(readability-else-after-return)
276 /// \endcond
277};
278
279class TLevelScheme : public TPaveLabel {
280public:
281 enum class EGammaWidth { kNoWidth,
282 kBand,
283 kGlobal };
284
285 explicit TLevelScheme(const std::string& filename = "", bool debug = false);
286 explicit TLevelScheme(const char* filename, bool debug = false) : TLevelScheme(std::string(filename), debug) {}
287 TLevelScheme(const TLevelScheme& rhs);
288 TLevelScheme(TLevelScheme&& rhs) noexcept = default;
289 TLevelScheme& operator=(const TLevelScheme& rhs) = default;
290 TLevelScheme& operator=(TLevelScheme&& rhs) noexcept = default;
291 ~TLevelScheme() = default;
292
293 static void ListLevelSchemes();
294 static TLevelScheme* GetLevelScheme(const char* name);
295
296 TLevel* AddLevel(double energy, const std::string& bandName, const std::string& label);
297 TLevel* AddLevel(const double energy, const char* bandName, const char* label) { return AddLevel(energy, std::string(bandName), std::string(label)); } // *MENU*
298 TLevel* GetLevel(double energy);
299 TLevel* FindLevel(double energy, double energyUncertainty);
300
301 TGamma* FindGamma(double energy, double energyUncertainty = 0.);
302 std::vector<TGamma*> FindGammas(double lowEnergy, double highEnergy);
303
304 std::map<double, double> FeedingGammas(double levelEnergy, double factor = 1.);
305 std::map<double, double> DrainingGammas(double levelEnergy, double factor = 1.);
306 void ResetGammaMap() { fGammaMap.clear(); }
307 std::vector<std::tuple<double, std::vector<double>>> ParallelGammas(double initialEnergy, double finalEnergy, double factor = 1.);
308
309 void MoveToBand(const char* bandName, TLevel* level);
310
311 void UseGlobalGammaWidth(const int val)
312 {
313 fGammaWidth = static_cast<EGammaWidth>(val);
314 Refresh();
315 } // *MENU*
316 void RadwareStyle(const bool val)
317 {
318 fRadwareStyle = val;
319 Refresh();
320 } // *MENU*
321 void GammaDistance(const double val)
322 {
323 fGammaDistance = val;
324 Refresh();
325 } // *MENU*
326 void BandGap(const double val)
327 {
328 fBandGap = val;
329 Refresh();
330 } // *MENU*
331 void LeftMargin(const double val)
332 {
333 fLeftMargin = val;
334 Refresh();
335 } // *MENU*
336 void RightMargin(const double val)
337 {
338 fRightMargin = val;
339 Refresh();
340 } // *MENU*
341 void BottomMargin(const double val)
342 {
343 fBottomMargin = val;
344 Refresh();
345 } // *MENU*
346 void TopMargin(const double val)
347 {
348 fTopMargin = val;
349 Refresh();
350 } // *MENU*
351
352 void Refresh(); // *MENU*
353 void UnZoom() const;
354 void Draw(Option_t* option = "") override;
355
356 void Print(Option_t* option = "") const override;
357
358 void Debug(bool val)
359 {
360 fDebug = val;
361 for(auto& band : fBands) { band.Debug(val); }
362 }
363
364private:
365 void ParseENSDF(const std::string& filename);
366 void DrawAuxillaryLevel(const double& energy, const double& left, const double& right);
367 void BuildGammaMap(double levelEnergy);
368
369 bool fDebug{false};
370 static std::vector<TLevelScheme*> fLevelSchemes;
371
372 std::vector<TBand> fBands;
373 std::multimap<double, TLine> fAuxillaryLevels;
374 std::multimap<double, TGamma*> fGammaMap;
375
376 // nuclide information
377 double fQValue{0.};
378 double fQValueUncertainty{0.};
379 double fNeutronSeparation{0.};
380 double fNeutronSeparationUncertainty{0.};
381
382 // graphics settings
383 EGammaWidth fGammaWidth{EGammaWidth::kNoWidth};
384 bool fRadwareStyle{true};
385 double fGammaDistance{50.};
386 double fBandGap{200.};
387 double fLeftMargin{-1.};
388 double fRightMargin{-1.};
389 double fBottomMargin{-1.};
390 double fTopMargin{-1.};
391 double fMinWidth{1.};
392 double fMaxWidth{10.};
393
394 // original canvas range
395 double fX1{0.};
396 double fY1{0.};
397 double fX2{0.};
398 double fY2{0.};
399
400 /// \cond CLASSIMP
401 ClassDefOverride(TLevelScheme, 1) // NOLINT(readability-else-after-return)
402 /// \endcond
403};
404/*! @} */
405
406#endif
407#endif