BmnRoot 26.10.0-18-g4e3414f9
Software framework of the BM@N experiment
Loading...
Searching...
No Matches
SplitDcmsmm.C
Go to the documentation of this file.
1// Number of tokens in the header part
2const Int_t nHead = 20;
3const Int_t ntokh[nHead] = {7, 10, 6, 6, 8, 10, 16, 16, 16, 13, 13, 13, 13, 16, 2, 8};
4
5// Read file header
6void ReadHeader(ifstream& fin, vector<TString>& header);
7// Read DCMSMM event
8Int_t ReadEvent(ifstream& fin, vector<TString>& evBuff;);
9// Write DCM-SMM event with the assigned number iev
10void WriteEvent(ofstream& fout, vector<TString>& evBuff;);
11// Get a string representation of the ratio: nevent/divider
12TString GetRatioString(Int_t nevent, Int_t divider);
13
14//__________________________________________________________________________
15// Read DCMSMM file f12 and split it into pieces
16void SplitDcmsmm(TString inFile = "./DCMSMM_XeCsI_3.8_AGeV_mb_50k_2.r12", Int_t nbefore = 10000, Int_t nafter = 2500)
17{
18 // trying to get input file from bash environment
19 TString fileIn = TString(gSystem->Getenv("FILEIN"));
20 if (fileIn != "")
21 inFile = fileIn;
22
23 gSystem->ExpandPathName(inFile);
24 // Check if path exists
25 if (gSystem->AccessPathName(inFile.Data(), kFileExists) == true) {
26 cerr << "Error: Path does not exist: " << inFile << endl;
27 return;
28 }
29 // Get detailed path information
30 FileStat_t stat;
31 if (gSystem->GetPathInfo(inFile, stat) != 0) {
32 cerr << "Error: Cannot get path info: " << inFile << endl;
33 return;
34 }
35
36 // Collect files to be processed
37 vector<TString> filesToProcess;
38 // Check if it is a FILE or DIRECTORY
39 if (stat.fMode & S_IFREG) {
40 // === CASE 1: It's a FILE ===
41 // Check extension
42 if (inFile.EndsWith(".r12")) {
43 filesToProcess.push_back(inFile);
44 } else {
45 cerr << "Warning: Input file does not have .r12 extension: " << inFile << endl;
46 return;
47 }
48 } else if (stat.fMode & S_IFDIR) {
49 // === CASE 2: It's a DIRECTORY ===
50 void* dirp = gSystem->OpenDirectory(inFile);
51 if (!dirp) {
52 cerr << "Error: Cannot open directory: " << inFile << endl;
53 return;
54 }
55
56 const char* p_file_name = nullptr;
57 while ((p_file_name = gSystem->GetDirEntry(dirp)) != nullptr) {
58 TString fileName(p_file_name);
59 // Check extension
60 if (fileName.EndsWith(".r12")) {
61 // Build full path
62 TString fullPath = TString(inFile) + "/" + fileName;
63 filesToProcess.push_back(fullPath);
64 }
65 }
66 gSystem->FreeDirectory(dirp);
67 } else {
68 cerr << "Error: Input path is neither a file nor a directory: " << inFile << endl;
69 return;
70 }
71
72 const int nfiles = nbefore / nafter; // number of output files
73 TString event_before_k = TString::Format("%sk", GetRatioString(nbefore, 1000).Data());
74 TString event_after_k = TString::Format("%sk", GetRatioString(nafter, 1000).Data());
75
76 // Process all input files
77 cout << "Found " << filesToProcess.size() << " file(s) to process:" << endl << endl;
78 for (const auto& input_file : filesToProcess) {
79 cout << "Current input file: " << input_file << endl;
80 ifstream fin;
81 fin.open(input_file.Data());
82
83 // read header of the current input file
84 vector<TString> header ReadHeader(fin, header);
85
86 int success = 0, ntot = 0;
87 // Loop over file pieces
88 for (int ifile = 0; ifile < nfiles; ++ifile) {
89 // Change file name
90 TString outFile = input_file;
91 // search for the first position of the string containing number of events
92 // int ip = outFile.First(event_before_k.Data());
93 // search for the last position of the string containing number of events
94 Int_t lastPos = -1, pos = 0;
95 while ((pos = outFile.Index(event_before_k.Data(), pos, TString::kIgnoreCase)) >= 0) {
96 lastPos = pos;
97 pos += 1; // Move forward to find next occurrence
98 }
99 if (lastPos >= 0)
100 outFile.Replace(lastPos, event_before_k.Length(), event_after_k);
101
102 // change number of the file according to the nfiles (number of output files for one input file)
103 int idot = input_file.Last('.');
104 int iund = input_file.Last('_');
105 int last_number = (TString(input_file(iund + 1, idot - iund - 1))).Atoi();
106 int new_last_number = (last_number - 1) * nfiles + ifile + 1;
107 TString str_new_last_number = "";
108 str_new_last_number += new_last_number;
109 outFile.Replace(iund + 2, TString::Itoa(last_number, 10).Length(), str_new_last_number.Data());
110 cout << " Current output file: " << outFile << endl;
111
112 // Open output file
113 ofstream fout;
114 fout.open(outFile.Data());
115 for (int j = 0; j < nHead; ++j)
116 fout << header[j] << endl;
117 // if (ifile == 0) for (int j = 0; j < nHead; ++j) fout << header[j] << endl;
118 Int_t nsel = 0;
119
120 for (Int_t iev = 0; iev < nbefore * 10; ++iev) {
121 vector<TString> evBuff;
122 success = ReadEvent(fin, evBuff);
123 if (success == 99)
124 break; // EOF
125 if (success == 0) {
126 TString evNew;
127 ++nsel;
128 evNew.Form("%9d", nsel);
129 evBuff[0].Replace(0, 9, evNew);
130 WriteEvent(fout, evBuff);
131 }
132 if (iev % 1000 == 0)
133 cout << iev << " " << nsel << " " << success << endl;
134 if (nsel >= nafter)
135 break; // number of selected events reached
136 }
137 cout << " Number of selected events: " << nsel << endl;
138 ntot += nsel;
139 fout.close();
140 // break;
141 if (success == 99)
142 break;
143 } // for (int ifile = 0;
144
145 fin.close();
146 cout << " Total number of events: " << ntot << endl;
147 } // cycle: process all input files
148}
149
150//__________________________________________________________________________
151// Read file header
152void ReadHeader(ifstream& fin, vector<TString>& header)
153{
154 TString chline;
155 for (Int_t ihead = 0; ihead < nHead; ++ihead) {
156 chline.ReadLine(fin, kFALSE);
157 header.push_back(chline);
158 }
159}
160
161//__________________________________________________________________________
162// Read DCMSMM event
163Int_t ReadEvent(ifstream& fin, vector<TString>& evBuff;)
164{
165 TString chline;
166 TObjArray* tokens = NULL;
167 TObjString* objstr = NULL;
168 Int_t success = 1, nPart = 0, nNucl = 0, iok = 0, iev = 0;
169 Float_t b, bx, by, beamA, beamZ;
170 // success = 0; // check
171
172 // for (Int_t ihead = 0; ihead < nHead; ++ihead) {
173 for (Int_t ihead = 0; ihead > -1; ++ihead) {
174 chline.ReadLine(fin, kFALSE);
175 if (fin.eof())
176 return 99; // EOF
177 tokens = chline.Tokenize(" -");
178 Int_t ntok = tokens->GetEntriesFast();
179 if (ntok <= 5 && ntok >= 3) {
180 // Event header
181 // cout << chline << endl;
182 // objstr = (TObjString*) tokens->UncheckedAt(2);
183 // if (!objstr->GetString().Contains("P")) {
184 objstr = (TObjString*)tokens->UncheckedAt(0);
185 TString token = objstr->GetString();
186 if (token.IsDigit()) {
187 sscanf(chline.Data(), "%d %d %f %f %f", &iev, &nPart, &b, &bx, &by);
188 // Impact-parameter
189 Double_t impPar = objstr->GetString().Atof();
190 // bout << iev << " " << nPart << " " << b << " " << bx << " " << by << endl;
191 ++iok;
192 }
193 evBuff.push_back(chline);
194 } else if (ntok == 8) {
195 // Beam remnants
196 objstr = (TObjString*)tokens->UncheckedAt(0);
197 TString token = objstr->GetString();
198 if (token.IsDigit()) {
199 sscanf(chline.Data(), "%d %f %f", &nNucl, &beamA, &beamZ);
200 // tmpout << nNucl << " " << beamA << " " << beamZ << endl;
201 }
202 evBuff.push_back(chline);
203 // Read fragments
204
205 for (int j = 0; j < nNucl; ++j) {
206 chline.ReadLine(fin, kFALSE);
207 evBuff.push_back(chline);
208 }
209 } else if (ntok <= 1)
210 evBuff.push_back(chline); // line with number of particles
211 if (tokens) {
212 tokens->Delete();
213 delete tokens;
214 tokens = NULL;
215 }
216 if (ntok > 1)
217 continue;
218
219 // Read particles
220 //*
221 for (Int_t ipart = 0; ipart < nPart; ++ipart) {
222 chline.ReadLine(fin, kFALSE);
223 evBuff.push_back(chline);
224 }
225 //*/
226
227 return 0; // event processed
228 } // for (Int_t ihead = 0;
229
230 return success;
231}
232
233//__________________________________________________________________________
234// Write DCM-SMM event with the assigned number iev
235void WriteEvent(ofstream& fout, vector<TString>& evBuff;)
236{
237 Int_t nlines = evBuff.size();
238 for (int j = 0; j < nlines; ++j)
239 fout << evBuff[j] << endl;
240}
241
242/**
243 * @brief Get a string representation of the ratio: nevent/divider
244 * If divider is zero, the result is "inf"
245 * The ratio is formatted as string with integer (e.g. "21") or float (e.g. "2.5", without trailing zeros)
246 * @param nevent The numerator of the ratio
247 * @param divider The denominator of the ratio
248 * @return A string representation of the ratio
249 */
251{
252 if (divider == 0)
253 return "inf";
254
255 Double_t ratio = ((double)nevent) / divider;
256 // Format the ratio with a precision of 3
257 TString str = Form("%.3f", ratio);
258
259 // Remove trailing zeros after the decimal point
260 str = str.Strip(TString::kTrailing, '0');
261 // Guarantee that there is a decimal point, not a comma
262 str.ReplaceAll(",", ".");
263 // If there is a decimal point ath the end, remove it
264 if (str.EndsWith("."))
265 str.Remove(str.Length() - 1, 1);
266
267 return str;
268}
int Int_t
float Float_t
constexpr Bool_t kFALSE
double Double_t
Int_t ReadEvent(ifstream &fin, vector< TString > &evBuff;)
const Int_t nHead
Definition SplitDcmsmm.C:2
void ReadHeader(ifstream &fin, vector< TString > &header)
TString GetRatioString(Int_t nevent, Int_t divider)
Get a string representation of the ratio: nevent/divider If divider is zero, the result is "inf" The ...
const Int_t ntokh[nHead]
Definition SplitDcmsmm.C:3
void WriteEvent(ofstream &fout, vector< TString > &evBuff;)
void SplitDcmsmm(TString inFile="./DCMSMM_XeCsI_3.8_AGeV_mb_50k_2.r12", Int_t nbefore=10000, Int_t nafter=2500)
Definition SplitDcmsmm.C:16
char * Form(const char *fmt,...)
kFileExists
R__EXTERN TSystem * gSystem
Int_t GetEntriesFast() const
void Delete(Option_t *option="") override
TObject * UncheckedAt(Int_t i) const
const TString & GetString() const
Ssiz_t Length() const
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Double_t Atof() const
TString & Replace(Ssiz_t pos, Ssiz_t n, const char *s)
const char * Data() const
Ssiz_t Last(char c) const
TObjArray * Tokenize(const TString &delim) const
static TString Format(const char *fmt,...)
static TString Itoa(Int_t value, Int_t base)
void Form(const char *fmt,...)
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
std::istream & ReadLine(std::istream &str, Bool_t skipWhite=kTRUE)