BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSColours.cc
1/*
2Beam Delivery Simulation (BDSIM) Copyright (C) Royal Holloway,
3University of London 2001 - 2024.
4
5This file is part of BDSIM.
6
7BDSIM is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published
9by the Free Software Foundation version 3 of the License.
10
11BDSIM is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with BDSIM. If not, see <http://www.gnu.org/licenses/>.
18*/
19#include "BDSColours.hh"
20#include "BDSDebug.hh"
21#include "BDSException.hh"
22#include "BDSUtilities.hh"
23
24#include "globals.hh" // geant4 types / globals
25#include "G4Colour.hh"
26
27#include <iomanip>
28#include <map>
29#include <sstream>
30
31BDSColours* BDSColours::instance = nullptr;
32
34{
35 if (!instance)
36 {instance = new BDSColours();}
37 return instance;
38}
39
40BDSColours::~BDSColours()
41{
42 instance = nullptr;
43}
44
46{
47 magnetName[1] = "sectorbend";
48 magnetName[2] = "quadrupole";
49 magnetName[3] = "sextupole";
50 magnetName[4] = "octupole";
51 magnetName[5] = "decapole";
52
53 // colour definitions (red,green,blue)
54 // some additional info:
55 // http://geant4.web.cern.ch/geant4/G4UsersDocuments/UsersGuides/ForApplicationDeveloper/html/Visualization/attributes.html
56 // https://en.wikipedia.org/wiki/Web_colors
57
58 // special
59 colours["default"] = new G4Colour(0.9, 0.9, 0.9); // almost white
60 colours["warning"] = new G4Colour(1, 0.078, 0.576); // hot warning pink
61
62 // visualisation of trajectories
63 colours["traj_neutral"] = new G4Colour(0.2, 0.7, 0.0, 0.2); // 0 charge - nicer green 0, semi-transparent as tonnes of photons usually
64 colours["traj_positive"] = new G4Colour(0.0, 0.2, 0.9); // nicer blue
65 colours["traj_negative"] = new G4Colour(0.8, 0.0, 0.0); // nicer red
66
67 // tunnel
68 colours["tunnel"] = new G4Colour(0.545, 0.533, 0.470); // a nice grey
69 colours["tunnelfloor"] = new G4Colour(0.5, 0.5, 0.45); // another grey
70 colours["soil"] = new G4Colour(0.545, 0.353, 0, 0.4);// brown
71
72 // elements - one for each type in parser/elementtype.cc
73 colours["marker"] = colours["default"];
74 colours["beampipe"] = new G4Colour(0.4, 0.4, 0.4); // dark grey
75 colours["drift"] = colours["beampipe"];
76 colours["sectorbend"] = new G4Colour(0, 0.4, 0.8); // blue
77 colours["sbend"] = colours["sectorbend"];
78 colours["rectangularbend"] = colours["sectorbend"];
79 colours["rbend"] = colours["sectorbend"];
80 colours["quadrupole"] = new G4Colour(0.82, 0.1, 0.1); // red
81 colours["sextupole"] = new G4Colour(1, 0.8, 0); // yellow
82 colours["octupole"] = new G4Colour(0, 0.6, 0.3); // green
83 colours["decapole"] = new G4Colour(0.3, 0.2, 0.7); // purple
84 colours["solenoid"] = new G4Colour(1, 0.549, 0, 0.7);// orange - semi transparent to see coil
85 colours["multipole"] = new G4Colour(0.466, 0.533, 0.6); // slate gray
86 colours["rfcavity"] = new G4Colour(0.466, 0.533, 0.6); // slate gray
87 colours["rf"] = colours["rfcavity"];
88 colours["rfx"] = colours["rf"];
89 colours["rfy"] = colours["rf"];
90 colours["srfcavity"] = new G4Colour(0.69, 0.769, 0.871); // light steel blue
91 colours["collimator"] = new G4Colour(0.25, 0.4, 0.2); // dark green
92 colours["ecol"] = colours["collimator"];
93 colours["jcol"] = colours["collimator"];
94 colours["rcol"] = colours["collimator"];
95 colours["jcol"] = colours["collimator"];
96 colours["bmcol"] = colours["collimator"];
97 colours["target"] = colours["collimator"];
98 colours["muonspoiler"] = new G4Colour(0, 0.807, 0.819); // "light blue" / tab blue
99 colours["vkicker"] = new G4Colour(0.73, 0.33, 0.83); // blue
100 colours["hkicker"] = new G4Colour(0.3, 0.2, 0.7); // blue
101 colours["kicker"] = colours["sectorbend"];
102 colours["tkicker"] = colours["kicker"];
103 colours["degrader"] = new G4Colour(0.625, 0.625, 0.625); // silver
104 colours["wirescanner"] = colours["tunnel"]; // grey
105 colours["undulator"] = new G4Colour(0.625, 0.625, 0.625); // silver
106 colours["shield"] = colours["tunnel"];
107 colours["crystal"] = colours["srfcavity"];
108 colours["thinmultipole"] = colours["default"];
109 colours["dipolefringe"] = colours["default"];
110 colours["rmatrix"] = colours["default"];
111 colours["thinrmatrix"] = colours["rmatrix"];
112 colours["paralleltransporter"] = colours["default"];
113 colours["element"] = colours["default"];
114 colours["screen"] = new G4Colour(0.69, 0.769, 0.871); // slate grey
115 colours["awakescreen"] = colours["screen"];
116 colours["awakespectrometer"]= colours["sectorbend"];
117 colours["gap"] = colours["default"];
118 colours["opaquebox"] = new G4Colour(0.2, 0.2, 0.2, 0.2); // dark grey but mostly transparent
119 colours["gaborlens"] = new G4Colour(0.212, 0.655, 0.816);// cerulean blue
120
121 // some specific materials
122 colours["iron"] = new G4Colour(0.509, 0.321, 0.294);
123 colours["kapton"] = new G4Colour(0.929, 0.380, 0.082, 0.5);
124 colours["lead"] = new G4Colour(0.377, 0.408, 0.451);
125 colours["water"] = new G4Colour(0, 0.4, 0.8, 0.5);
126
127 // element parts
128 colours["coil"] = new G4Colour(0.722, 0.451, 0.2); // copper
129 colours["copper"] = colours["coil"];
130 colours["LHCcopperskin"] = new G4Colour(0.722, 0.525, 0.043); // copper
131 colours["LHCcoil"] = new G4Colour(0.9, 0.75, 0); // gold-ish
132 colours["LHCcollar"] = new G4Colour(0.9, 0.9, 0.9); // gainsboro
133 colours["LHCyoke"] = new G4Colour(0, 0.5, 1.0); // LHC blue
134 colours["LHCyokered"] = new G4Colour(*(colours["quadrupole"]));// quadrupole red
135 colours["gdml"] = new G4Colour(0.4, 0.2, 0); // poo brown
136 colours["screenframe"] = new G4Colour(0.7, 0.7, 0.7, 0.4);// light grey, semi-transparent
137 colours["capillaryouter"] = colours["collimator"];
138 colours["capillarygas"] = new G4Colour(0.82, 0.1, 0.1, 0.4); // red, semi-transparent
139 colours["electrode"] = colours["screen"];
140
141 // general
142 colours["white"] = new G4Colour(G4Colour::White());
143 colours["gray"] = new G4Colour(G4Colour::Gray());
144 colours["grey"] = new G4Colour(G4Colour::Grey());
145 colours["black"] = new G4Colour(G4Colour::Black());
146 colours["brown"] = new G4Colour(G4Colour::Brown());
147 colours["red"] = new G4Colour(G4Colour::Red());
148 colours["green"] = new G4Colour(G4Colour::Green());
149 colours["blue"] = new G4Colour(G4Colour::Blue());
150 colours["cyan"] = new G4Colour(G4Colour::Cyan());
151 colours["magenta"] = new G4Colour(G4Colour::Magenta());
152 colours["yellow"] = new G4Colour(G4Colour::Yellow());
153 colours["reallyreallydarkgrey"] = new G4Colour(0.2, 0.2, 0.2);
154
155#ifdef BDSDEBUG
156 Print();
157#endif
158}
159
160void BDSColours::DefineColour(const G4String& name,
161 G4double red,
162 G4double green,
163 G4double blue,
164 G4double alpha,
165 G4bool normaliseTo255)
166{
167 if (colours.find(name) != colours.end())
168 {
169 G4cerr << "Colour \"" << name << "\" is already defined - clashing definitions" << G4endl;
170 G4cout << "Already defined colours are " << G4endl;
171 Print();
172 throw BDSException(__METHOD_NAME__, "duplicate colour definition");
173 }
174
175 BDS::EnsureInLimits(red,0,255);
176 BDS::EnsureInLimits(green,0,255);
177 BDS::EnsureInLimits(blue,0,255);
178 BDS::EnsureInLimits(alpha,0,1);
179 G4Colour* newColour;
180 if (normaliseTo255)
181 {newColour = new G4Colour(red/255.,green/255.,blue/255.,alpha);}
182 else
183 {newColour = new G4Colour(red, green, blue, alpha);}
184 colours[name] = newColour;
185}
186
188{
189 // auto-generate the manual colour table in rst syntax
190 G4cout << __METHOD_NAME__ << "Colour Table" << G4endl;
191 G4cout << "This is only the pre-defined BDSIM colours and not the user-defined ones." << G4endl;
192 G4cout << "+---------------------+-----+-----+-----+------+" << G4endl;
193 G4cout << "| Name | R | G | B | A |" << G4endl;
194 G4cout << "+=====================+=====+=====+=====+======+" << G4endl;
195 for (const auto& col : colours)
196 {
197 int r = (int)(col.second->GetRed() * 255);
198 int g = (int)(col.second->GetGreen() * 255);
199 int b = (int)(col.second->GetBlue() * 255);
200 double a = col.second->GetAlpha();
201 G4cout << "| " << std::setw(20) << col.first << "| "
202 << std::setw(3) << r << " | "
203 << std::setw(3) << g << " | "
204 << std::setw(3) << b << " | "
205 << std::setw(4) << a << " |" << G4endl;
206 G4cout << "+---------------------+-----+-----+-----+------+" << G4endl;
207 }
208}
209
210G4Colour* BDSColours::GetColour(G4double red,
211 G4double green,
212 G4double blue,
213 G4double alpha)
214{
215 BDSColourKey key = {red, green, blue, alpha};
216 auto search = anonymousColours.find(key);
217 if (search != anonymousColours.end())
218 {return search->second;}
219 else
220 {
221 BDS::EnsureInLimits(red, 0, 255);
222 BDS::EnsureInLimits(green, 0, 255);
223 BDS::EnsureInLimits(blue, 0, 255);
224 BDS::EnsureInLimits(alpha, 0, 1);
225 auto result = new G4Colour(red, green, blue, alpha);
226 anonymousColours[key] = result;
227 return result;
228 }
229}
230
231G4Colour* BDSColours::GetColour(const G4String& type,
232 G4bool normaliseTo255)
233{
234 G4String colourName = type;
235 G4bool canDefine = false;
236 if (BDS::StrContains(type, ":"))
237 {
238 colourName = type.substr(0, type.find(":"));
239 canDefine = true;
240 }
241
242 auto it = colours.find(colourName);
243 if (it != colours.end())
244 {// colour must therefore exist
245 return it->second;
246 }
247 else if (it == colours.end() && canDefine)
248 {
249 G4double r = 240;
250 G4double g = 240;
251 G4double b = 240; // default rgb is almost white but visible
252 G4String rgb = type.substr(type.find(":")+1); // everything after ':'
253 std::stringstream ss(rgb);
254 G4double a = 1;
255 ss >> r >> g >> b;
256 if (ss.rdbuf()->in_avail() != 0)
257 {ss >> a;}
258 DefineColour(colourName, r, g, b, a, normaliseTo255);
259 return colours[colourName];
260 }
261 else
262 {throw BDSException(__METHOD_NAME__, "unknown colour \"" + type + "\"");}
263}
Colour class that holds all colours used in BDSIM.
Definition BDSColours.hh:34
G4Colour * GetColour(G4double red, G4double green, G4double blue, G4double alpha=1)
Get a cached anonymous colour by values.
std::map< BDSColourKey, G4Colour * > anonymousColours
Definition BDSColours.hh:78
static BDSColours * Instance()
singleton pattern
Definition BDSColours.cc:33
void DefineColour(const G4String &name, G4double red, G4double green, G4double blue, G4double alpha=1, G4bool normaliseTo255=true)
Define a new colour.
BDSColours()
Private constructor as singleton.
Definition BDSColours.cc:45
void Print()
std::map< G4int, G4String > magnetName
Definition BDSColours.hh:70
std::map< G4String, G4Colour * > colours
A map of the colour for each type or component by name.
Definition BDSColours.hh:73
General exception with possible name of object and message.
G4bool StrContains(const G4String &str, const G4String &test)
Utility function to simplify lots of syntax changes for pedantic g4 changes.
void EnsureInLimits(G4double &value, G4double lowerLimit, G4double upperLimit)