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