MaCh3  2.2.3
Reference Guide
Functions
MaCh3Utils Namespace Reference

Functions

void MaCh3Welcome ()
 KS: Prints welcome message with MaCh3 logo. More...
 
std::string GetMaCh3Version ()
 KS: Get version of MaCh3. More...
 
void GetOSInfo ()
 KS: Find out more about operational system. More...
 
void GetCPUInfo ()
 KS: Check what CPU you are using. More...
 
void NThreadsSanity ()
 KS: Check if user is not using huge number of threads and throw error. More...
 
void GetGPUInfo ()
 KS: Check what GPU you are using. More...
 
void GetDiskUsage ()
 KS: Find out about Disk usage. More...
 
std::string TerminalToString (std::string cmd)
 KS: Convoluted code to grab output from terminal to string. More...
 
void EstimateDataTransferRate (TChain *chain, const Long64_t entry)
 KS: Check what CPU you are using. More...
 
void PrintProgressBar (const Long64_t Done, const Long64_t All)
 KS: Simply print progress bar. More...
 
int getValue (const std::string &Type)
 CW: Get info like RAM. More...
 
int parseLine (const std::string &line)
 CW: Get memory, which is probably silly. More...
 
void PrintConfig (const YAML::Node &node)
 KS: Print Yaml config using logger. More...
 
void Print (const TTree *tree)
 
void MaCh3Usage (int argc, char **argv)
 KS: Almost all MaCh3 executables have the same usage, prepare simple printer. More...
 
double GetMassFromPDG (const int PDG)
 Return mass for given PDG. More...
 
int PDGToNuOscillatorFlavour (const int NuPdg)
 Convert from PDG flavour to NuOscillator type beware that in the case of anti-neutrinos the NuOscillator type simply gets multiplied by -1. More...
 
std::string FormatDouble (const double value, const int precision)
 Convert double into string for precision, useful for playing with yaml if you don't want to have in config floating point precision... More...
 

Function Documentation

◆ EstimateDataTransferRate()

void MaCh3Utils::EstimateDataTransferRate ( TChain *  chain,
const Long64_t  entry 
)

KS: Check what CPU you are using.

Definition at line 196 of file Monitor.cpp.

196  {
197 // ************************
198  TStopwatch timer;
199 
200  timer.Start();
201  Int_t bytesProcessed{ chain->GetEntry(entry) };
202 
203  timer.Stop();
204 
205  Double_t timeInSeconds = timer.RealTime();
206  Double_t dataRateMBps = (double(bytesProcessed) / (1024.0 * 1024.0)) / timeInSeconds;
207 
208  MACH3LOG_INFO("Data transfer: {} B, rate: {:.2f} MB/s", bytesProcessed, dataRateMBps);
209 }
#define MACH3LOG_INFO
Definition: MaCh3Logger.h:25

◆ FormatDouble()

std::string MaCh3Utils::FormatDouble ( const double  value,
const int  precision 
)
inline

Convert double into string for precision, useful for playing with yaml if you don't want to have in config floating point precision...

Definition at line 429 of file SampleStructs.h.

429  {
430  // ***************************
431  std::ostringstream oss;
432  oss << std::fixed << std::setprecision(precision) << value;
433  return oss.str();
434  }

◆ GetCPUInfo()

void MaCh3Utils::GetCPUInfo ( )

KS: Check what CPU you are using.

Definition at line 99 of file Monitor.cpp.

99  {
100 // ************************
101  //KS: Use -m 1 to limit to only one grep because in one computing node there is a lot of CPU which are the same
102  MACH3LOG_INFO("Using following CPU:");
103 
104  MACH3LOG_INFO("{}", TerminalToString("cat /proc/cpuinfo | grep -m 1 name"));
105  MACH3LOG_INFO("{}", TerminalToString("cat /proc/cpuinfo | grep -m 1 MHz"));
106  //KS: Below code is convoluted because I mostly work on English based Linux but sometimes on Polish based Linux, this ensures it works on both. We can add support for other languages if needed
107  MACH3LOG_INFO("{}", TerminalToString("lscpu | grep -i Archit"));
108  MACH3LOG_INFO("{}", TerminalToString("lscpu | grep -m 1 -E 'L1d |L1d:'"));
109  MACH3LOG_INFO("{}", TerminalToString("lscpu | grep -m 1 -E 'L1i |L1i:'"));
110  MACH3LOG_INFO("{}", TerminalToString("lscpu | grep -m 1 -E 'L2 |L2:'"));
111  MACH3LOG_INFO("{}", TerminalToString("lscpu | grep -m 1 -E 'L3 |L3:'"));
112  MACH3LOG_INFO("{}", TerminalToString("lscpu | grep -m 1 -E 'Thread.* per core:|Wątków na rdzeń:'"));
113  MACH3LOG_INFO("{}", TerminalToString("lscpu | grep -m 1 -E '^CPU(:|\\(s\\)):?\\s+[0-9]+'"));
114  MACH3LOG_INFO("With available threads {}", M3::GetNThreads());
115 
116  NThreadsSanity();
117  //KS: /proc/cpuinfo and lscpu holds much more info I have limited it but one can expand it if needed
118 }
int GetNThreads()
number of threads which we need for example for TRandom3
Definition: Monitor.cpp:357
std::string TerminalToString(std::string cmd)
KS: Convoluted code to grab output from terminal to string.
Definition: Monitor.cpp:178
void NThreadsSanity()
KS: Check if user is not using huge number of threads and throw error.
Definition: Monitor.cpp:122

◆ GetDiskUsage()

void MaCh3Utils::GetDiskUsage ( )

KS: Find out about Disk usage.

Definition at line 168 of file Monitor.cpp.

168  {
169 // ************************
170  MACH3LOG_INFO("Disk Usage:");
171 
172  // Get disk usage
173  MACH3LOG_INFO("{}", TerminalToString("df -h --total | grep total"));
174 }

◆ GetGPUInfo()

void MaCh3Utils::GetGPUInfo ( )

KS: Check what GPU you are using.

Definition at line 143 of file Monitor.cpp.

143  {
144 // ************************
145 #ifdef MaCh3_CUDA
146  MACH3LOG_INFO("Using following GPU:");
147  // Print GPU name
148  MACH3LOG_INFO("GPU Name: {}", TerminalToString("nvidia-smi --query-gpu=name --format=csv,noheader"));
149  // Print number of GPUs
150  MACH3LOG_INFO("Number of GPUs: {}", TerminalToString("nvidia-smi --query-gpu=count --format=csv,noheader"));
151  // Print total VRAM
152  MACH3LOG_INFO("Total VRAM: {} MB", TerminalToString("nvidia-smi --query-gpu=memory.total --format=csv,noheader,nounits"));
153  // Print Driver Version
154  MACH3LOG_INFO("Driver Version: {}", TerminalToString("nvidia-smi --query-gpu=driver_version --format=csv,noheader"));
155  // Print N GPU thread
156  MACH3LOG_INFO("Currently used GPU has: {} threads", GetNumGPUThreads());
157  // Print L2 cache
158  MACH3LOG_INFO("Currently used GPU has: {} KB L2 cache", GetL2CacheSize() / 1024);
159  // Shared memory info
160  MACH3LOG_INFO("Max shared memory per block: {} KB", GetSharedMemoryPerBlock() / 1024);
161  // Print 1D texture size
162  MACH3LOG_INFO("Max 1D texture size: {}", GetMaxTexture1DSize());
163 #endif
164 }
size_t GetMaxTexture1DSize(const int device)
KS: Get the maximum size for 1D textures on the specified GPU device.
Definition: gpuUtils.cu:134
int GetNumGPUThreads(const int Device)
KS: Get number of GPU threads for currently used GPU.
Definition: gpuUtils.cu:102
size_t GetL2CacheSize(const int device)
KS: Get L2 cache size (in bytes) for the specified GPU device.
Definition: gpuUtils.cu:122
size_t GetSharedMemoryPerBlock(const int device)
KS: Returns the maximum shared memory per block for a given GPU device.
Definition: gpuUtils.cu:146

◆ GetMaCh3Version()

std::string MaCh3Utils::GetMaCh3Version ( )

KS: Get version of MaCh3.

Returns
The current MaCh3 version as a string.

This function fetches and returns the version of the MaCh3 software being used.

Definition at line 46 of file Monitor.cpp.

46  {
47 // ************************
48  //KS: Find MaCh3 version based on header file. There could be better way to just include version.h but as long as we don't have to hardcode version I am content
49  std::string MaCh3_VERSION = "";
50 
51  if(std::getenv("MaCh3_ROOT") == nullptr){
52  throw MaCh3Exception(__FILE__, __LINE__, "Error: you haven't sourced setup.MaCh3.sh in core!");
53  }
54 
55  std::string file = std::string(std::getenv("MaCh3_ROOT")) + "/version.h";
56  // Open the version.h file
57  std::ifstream versionFile(file);
58 
59  // Check if the file is opened successfully
60  if (!versionFile.is_open()) {
61  MACH3LOG_ERROR("Error: Couldn't open version.h {}", file);
62  throw MaCh3Exception(__FILE__, __LINE__);
63  }
64 
65  std::string line;
66  const std::string searchKey = "MaCh3_VERSION=";
67 
68  // Read each line from the file
69  while (std::getline(versionFile, line)) {
70  // Search for the line containing MaCh3_VERSION
71  auto pos = line.find(searchKey);
72  if (pos != std::string::npos) {
73  // Extract the version string
74  MaCh3_VERSION = line.substr(pos + searchKey.length());
75  MaCh3_VERSION.erase(0, MaCh3_VERSION.find_first_not_of("\"")); // Remove leading quote
76  MaCh3_VERSION.erase(MaCh3_VERSION.find_last_not_of("\";") + 1); // Remove trailing quote and semicolon
77  break; // Stop searching once found
78  }
79  }
80  // Close the file
81  versionFile.close();
82 
83  return MaCh3_VERSION;
84 }
#define MACH3LOG_ERROR
Definition: MaCh3Logger.h:27
Custom exception class for MaCh3 errors.

◆ GetMassFromPDG()

double MaCh3Utils::GetMassFromPDG ( const int  PDG)
inline

Return mass for given PDG.

Note
Get the mass of a particle from the PDG In GeV, not MeV!
Todo:
this could be constexpr in c++17 [23] (particle masses) [33] (nuclear masses)

Definition at line 344 of file SampleStructs.h.

344  {
345  // *****************************
346  switch (abs(PDG)) {
347  // Leptons
348  case 11: return 0.00051099895; // e
349  case 13: return 0.1056583755; // mu
350  case 15: return 1.77693; // tau
351  // Neutrinos
352  case 12:
353  case 14:
354  case 16:
355  return 0.;
356  // Photon
357  case 22: return 0.;
358  // Mesons
359  case 211: return 0.13957039; // pi_+/-
360  case 111: return 0.1349768; // pi_0
361  case 221: return 0.547862; // eta
362  case 311: // K_0
363  case 130: // K_0_L
364  case 310: // K_0_S
365  return 0.497611;
366  case 321: return 0.493677; // K_+/-
367  // Baryons
368  case 2112: return 0.939565; // n
369  case 2212: return 0.938272; // p
370  case 3122: return 1.115683; // lambda
371  case 3222: return 1.118937; // sig_+
372  case 3112: return 1.197449; // sig_-
373  case 3212: return 1.192642; // sig_0
374  // Nuclei
375  case 1000050110: return 10.255103; // Boron-11
376  case 1000060120: return 11.177929; // Carbon-12
377  case 1000070140: return 13.043781; // Nitrogen-14
378  case 1000080160: return 14.899169; // Oxygen-16
379  case 1000090190: return 17.696901; // Fluorine-19
380  case 1000110230: return 21.414835; // Sodium-23
381  case 1000130270: return 25.133144; // Aluminum-27
382  case 1000140280: return 26.060342; // Silicon-28
383  case 1000190390: return 36.294463; // Potassium-39
384  case 1000180400: return 37.224724; // Argon-40
385  case 1000220480: return 44.663224; // Titanium-48
386  case 1000300640: return 59.549619; // Zinc-64
387  default:
388  MACH3LOG_ERROR("Haven't got a saved mass for PDG: {}", PDG);
389  MACH3LOG_ERROR("Please implement me!");
390  throw MaCh3Exception(__FILE__, __LINE__);
391  } // End switch
392  MACH3LOG_ERROR("Warning, didn't catch a saved mass");
393  return 0;
394  }

◆ GetOSInfo()

void MaCh3Utils::GetOSInfo ( )

KS: Find out more about operational system.

Definition at line 88 of file Monitor.cpp.

88  {
89 // ************************
90  MACH3LOG_INFO("Operating System Information:");
91 
92  // Distribution and version
93  MACH3LOG_INFO("Distribution: {}", TerminalToString("lsb_release -d | awk -F':' '{print $2}'"));
94  MACH3LOG_INFO("Kernel Version: {}", TerminalToString("uname -r"));
95 }

◆ getValue()

int MaCh3Utils::getValue ( const std::string &  Type)

CW: Get info like RAM.

Parameters
TypeThe type of system information to retrieve (e.g., RAM, CPU usage).
Returns
The requested system information as an integer.

This function fetches system information like RAM usage or other hardware details based on the specified type.

Definition at line 236 of file Monitor.cpp.

236  { //Note: this value is in KB!
237 // ***************************************************************************
238  std::ifstream file("/proc/self/status");
239  int result = -1;
240  std::string line;
241 
242  if (Type == "VmSize")
243  {
244  while (std::getline(file, line))
245  {
246  if (line.compare(0, 7, "VmSize:") == 0)
247  {
248  result = parseLine(line.substr(7));
249  break;
250  }
251  }
252  }
253  else if (Type == "VmRSS")
254  {
255  while (std::getline(file, line))
256  {
257  if (line.compare(0, 6, "VmRSS:") == 0)
258  {
259  result = parseLine(line.substr(6));
260  break;
261  }
262  }
263  }
264  else if (Type == "MemTotal")
265  {
266  std::ifstream meminfo("/proc/meminfo");
267  while (std::getline(meminfo, line))
268  {
269  if (line.find("MemTotal:") != std::string::npos) {
270  result = parseLine(line.substr(9));
271  break;
272  }
273  }
274  }
275  else
276  {
277  MACH3LOG_ERROR("Not supported getValue: {}", Type);
278  throw MaCh3Exception(__FILE__, __LINE__);
279  }
280  return result;
281 }
int parseLine(const std::string &line)
CW: Get memory, which is probably silly.
Definition: Monitor.cpp:285

◆ MaCh3Usage()

void MaCh3Utils::MaCh3Usage ( int  argc,
char **  argv 
)

KS: Almost all MaCh3 executables have the same usage, prepare simple printer.

Parameters
argcThe number of command-line arguments.
argvThe array of command-line arguments.

This function prints a simple usage guide for MaCh3 executables, typically called when incorrect arguments are passed.

Definition at line 344 of file Monitor.cpp.

344  {
345 // ***************************************************************************
346  if (argc != 2) {
347  MACH3LOG_ERROR("Wrong usage of MaCh3 executable!");
348  MACH3LOG_ERROR("Syntax is $: {} config.yaml", argv[0]);
349  MACH3LOG_ERROR("Where config.yaml is a valid config file, compatible with the manager class (manager/manager.cpp/h)");
350  throw MaCh3Exception(__FILE__, __LINE__);
351  }
352 }

◆ MaCh3Welcome()

void MaCh3Utils::MaCh3Welcome ( )

KS: Prints welcome message with MaCh3 logo.

Definition at line 12 of file Monitor.cpp.

12  {
13 // *************************
14  // KS: Just make sure we only call it once
15  static bool MaCh3WelcomeInitialised = false;
16 
17  if(MaCh3WelcomeInitialised) return;
18 
19  std::string MaCh3_VERSION = GetMaCh3Version();
20 
21  MACH3LOG_INFO("##################################");
22  MACH3LOG_INFO("Welcome to: ");
23  MACH3LOG_INFO(" __ __ _____ _ ____ ");
24  MACH3LOG_INFO(" | \\/ | / ____| | |___ \\ ");
25  MACH3LOG_INFO(" | \\ / | __ _| | | |__ __) |");
26  MACH3LOG_INFO(" | |\\/| |/ _` | | | '_ \\ |__ < ");
27  MACH3LOG_INFO(" | | | | (_| | |____| | | |___) |");
28  MACH3LOG_INFO(" |_| |_|\\__,_|\\_____|_| |_|____/ ");
29  MACH3LOG_INFO("Version: {}", MaCh3_VERSION);
30  MACH3LOG_INFO("##################################");
31 
32  GetCPUInfo();
33 
34  GetGPUInfo();
35 
36  #ifdef DEBUG
37  GetOSInfo();
38  GetDiskUsage();
39  #endif
40 
41  MaCh3WelcomeInitialised = true;
42 }
void GetOSInfo()
KS: Find out more about operational system.
Definition: Monitor.cpp:88
std::string GetMaCh3Version()
KS: Get version of MaCh3.
Definition: Monitor.cpp:46
void GetDiskUsage()
KS: Find out about Disk usage.
Definition: Monitor.cpp:168
void GetCPUInfo()
KS: Check what CPU you are using.
Definition: Monitor.cpp:99
void GetGPUInfo()
KS: Check what GPU you are using.
Definition: Monitor.cpp:143

◆ NThreadsSanity()

void MaCh3Utils::NThreadsSanity ( )

KS: Check if user is not using huge number of threads and throw error.

Definition at line 122 of file Monitor.cpp.

122  {
123 // ************************
124  //KS: If OMP_NUM_THREADS is exported, assume user did this on purpose
125  if (std::getenv("OMP_NUM_THREADS") != nullptr) return;
126 
127  const int nThreads = M3::GetNThreads();
128  constexpr int MaxAllowedThreads = 16;
129  constexpr int RecommendedThreads = 8;
130 
131  if (nThreads > MaxAllowedThreads) {
132  MACH3LOG_CRITICAL("You specified more than {} threads ({})", MaxAllowedThreads, nThreads);
133  MACH3LOG_CRITICAL("With so many threads code will be slower, please use:");
134  MACH3LOG_CRITICAL("export OMP_NUM_THREADS={}", RecommendedThreads);
135  MACH3LOG_CRITICAL("To use different number of threads");
136  throw MaCh3Exception(__FILE__, __LINE__, "Too many threads");
137  }
138 }
#define MACH3LOG_CRITICAL
Definition: MaCh3Logger.h:28

◆ parseLine()

int MaCh3Utils::parseLine ( const std::string &  line)

CW: Get memory, which is probably silly.

Parameters
lineThe line of text to parse.
Returns
The extracted memory value as an integer.

This function is used to parse a line of text and extract memory-related information.

Definition at line 285 of file Monitor.cpp.

285  {
286 // ***************************************************************************
287  std::istringstream iss(line);
288  int value;
289  iss >> value;
290  return value;
291 }

◆ PDGToNuOscillatorFlavour()

int MaCh3Utils::PDGToNuOscillatorFlavour ( const int  NuPdg)
inline

Convert from PDG flavour to NuOscillator type beware that in the case of anti-neutrinos the NuOscillator type simply gets multiplied by -1.

Definition at line 401 of file SampleStructs.h.

401  {
402  int NuOscillatorFlavour = M3::_BAD_INT_;
403  switch(std::abs(NuPdg)){
404  case NuPDG::kNue:
405  NuOscillatorFlavour = NuOscillator::kElectron;
406  break;
407  case NuPDG::kNumu:
408  NuOscillatorFlavour = NuOscillator::kMuon;
409  break;
410  case NuPDG::kNutau:
411  NuOscillatorFlavour = NuOscillator::kTau;
412  break;
413  default:
414  MACH3LOG_ERROR("Unknown Neutrino PDG {}, cannot convert to NuOscillator type", NuPdg);
415  break;
416  }
417 
418  //This is very cheeky but if the PDG is negative then multiply the PDG by -1
419  // This is consistent with the treatment that NuOscillator expects as enums only
420  // exist for the generic matter flavour and not the anti-matter version
421  if(NuPdg < 0){NuOscillatorFlavour *= -1;}
422 
423  return NuOscillatorFlavour;
424  }
@ kNutau
@ kNue
@ kNumu
constexpr static const int _BAD_INT_
Default value used for int initialisation.
Definition: Core.h:48

◆ Print()

void MaCh3Utils::Print ( const TTree *  tree)
Parameters
treecontent of TTree using logger

Definition at line 310 of file Monitor.cpp.

310  {
311 // ***************************************************************************
312  if (!tree) return;
313 
314  // Create a temporary file to capture stdout
315  FILE* tmpFile = tmpfile();
316  if (!tmpFile) return;
317 
318  // Save old stdout
319  int oldStdout = dup(fileno(stdout));
320  // Redirect stdout to tmpFile
321  dup2(fileno(tmpFile), fileno(stdout));
322 
323  tree->Print(); // ROOT writes to stdout
324 
325  fflush(stdout);
326  // Restore old stdout
327  dup2(oldStdout, fileno(stdout));
328  close(oldStdout);
329 
330  // Read tmpFile content
331  fseek(tmpFile, 0, SEEK_SET);
332  char buffer[1024];
333  while (fgets(buffer, sizeof(buffer), tmpFile)) {
334  std::string line(buffer);
335  if (!line.empty() && line.back() == '\n') line.pop_back();
336  MACH3LOG_INFO("{}", line);
337  }
338 
339  fclose(tmpFile);
340 }

◆ PrintConfig()

void MaCh3Utils::PrintConfig ( const YAML::Node &  node)

KS: Print Yaml config using logger.

Parameters
nodeyaml config node

Definition at line 295 of file Monitor.cpp.

295  {
296 // ***************************************************************************
297  std::stringstream ss;
298  ss << node;
299  std::string yamlString = ss.str();
300 
301  std::istringstream iss(yamlString);
302  std::string line;
303  while (std::getline(iss, line)) {
304  MACH3LOG_INFO("{}", line);
305  }
306 }

◆ PrintProgressBar()

void MaCh3Utils::PrintProgressBar ( const Long64_t  Done,
const Long64_t  All 
)

KS: Simply print progress bar.

Parameters
DoneThe number of tasks completed.
AllThe total number of tasks.

This function prints a progress bar to the terminal, indicating the percentage of tasks completed.

Definition at line 213 of file Monitor.cpp.

213  {
214 // ************************
215  double progress = double(Done)/double(All);
216  const int barWidth = 20;
217  std::ostringstream progressBar;
218 
219  progressBar << "[";
220  int pos = int(barWidth * progress);
221  for (int i = 0; i < barWidth; ++i) {
222  if (i < pos)
223  progressBar << "=";
224  else if (i == pos)
225  progressBar << ">";
226  else
227  progressBar << " ";
228  }
229 
230  progressBar << "] " << std::setw(3) << Done <<"/"<< All<<" ("<<static_cast<int>(progress * 100.0)<<"%)\r";
231  MACH3LOG_INFO("{}", progressBar.str());
232 }

◆ TerminalToString()

std::string MaCh3Utils::TerminalToString ( std::string  cmd)

KS: Convoluted code to grab output from terminal to string.

Parameters
cmdThe terminal command to execute.
Returns
The output of the terminal command as a string.

Definition at line 178 of file Monitor.cpp.

178  {
179 // ************************
180  std::array<char, 128> buffer;
181  std::string result;
182  std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd.c_str(), "r"), pclose);
183  if (!pipe) {
184  throw MaCh3Exception(__FILE__, __LINE__, "popen() failed!");
185  }
186  while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
187  result += buffer.data();
188  }
189  // Remove trailing newline characters
190  result.erase(std::remove(result.begin(), result.end(), '\n'), result.end());
191  return result;
192 }