1 |
< |
#ifndef triggerStudy_cxx |
2 |
< |
#define triggerStudy_cxx |
3 |
< |
#include "triggerStudy.h" |
4 |
< |
#include "triggerStudy.cfg" |
5 |
< |
#include "histo.h" |
6 |
< |
|
7 |
< |
//using namespace tools; |
1 |
> |
#include <iostream> |
2 |
> |
#include <fstream> |
3 |
> |
#include <map> |
4 |
> |
#include <vector> |
5 |
> |
|
6 |
> |
#include <Math/LorentzVector.h> |
7 |
> |
|
8 |
> |
#include "TString.h" |
9 |
> |
#include "TTree.h" |
10 |
> |
#include "TFile.h" |
11 |
> |
|
12 |
> |
#include "plotMaker.h" |
13 |
> |
#include "tools.h" |
14 |
> |
//--------------------------------------------------- declare some special types |
15 |
> |
#ifdef __MAKECINT__ |
16 |
> |
#pragma link C++ class pair<string,bool>+; |
17 |
> |
#pragma link C++ class pair<string,string>+; |
18 |
> |
#pragma link C++ class map<string,bool>+; |
19 |
> |
#pragma link C++ class map<string,string>+; |
20 |
> |
#pragma link C++ class ROOT::Math::PtEtaPhiM4D<float>+; |
21 |
> |
#pragma link C++ class ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<float> >+; |
22 |
> |
#pragma link C++ class vector<ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<float> > >+; |
23 |
> |
#endif |
24 |
|
|
25 |
+ |
typedef ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<float> > LorentzM; |
26 |
|
|
27 |
< |
//================================================================================= mainProgram |
28 |
< |
void triggerStudy::mainProgram(){ |
29 |
< |
tools::enterFcn("mainProgram",1); |
30 |
< |
Loop(); |
31 |
< |
tools::exitFcn("mainProgram",1); |
27 |
> |
//--------------------------------------------------- Structure to store the whole event information in order to pass it to functions |
28 |
> |
struct eventInfo{ |
29 |
> |
vector<string> *DESYtriggerElMatchedTriggerFilter; |
30 |
> |
vector<string> *DESYtriggerMuMatchedTriggerFilter; |
31 |
> |
map<string, string> *DESYtriggerNameMap; |
32 |
> |
vector<int> *electronCharge; |
33 |
> |
vector<LorentzM> *electronP4; |
34 |
> |
int Event; |
35 |
> |
double HT; |
36 |
> |
vector<LorentzM> *jetP4; |
37 |
> |
double MET; |
38 |
> |
vector<int> *muonCharge; |
39 |
> |
vector<LorentzM> *muonP4; |
40 |
> |
map<string, int> *prescaled; |
41 |
> |
int Run; |
42 |
> |
double PUWeight; |
43 |
> |
map<string, bool> *triggered; |
44 |
> |
double Weight; |
45 |
> |
}; |
46 |
> |
|
47 |
> |
|
48 |
> |
//--------------------------------------------------- functions |
49 |
> |
// void init(TString inputFileName); |
50 |
> |
void initBranches(TTree *tree, eventInfo &event); |
51 |
> |
void initVariables(); |
52 |
> |
void Loop(TString inputFileName, TString outputFileName); |
53 |
> |
void plotHistograms(eventInfo& evt, map<TString, plotMaker> &plot); |
54 |
> |
void printElectronInfo(eventInfo& evt, ostream& os=cout); |
55 |
> |
void printEventInfo(eventInfo& evt, ostream& os=cout); |
56 |
> |
void printMuonInfo(eventInfo& evt, ostream& os=cout); |
57 |
> |
|
58 |
> |
|
59 |
> |
//================================================================================= triggerStudy |
60 |
> |
//main function which will be called |
61 |
> |
//here, it is possible to run over multiple files and to estimate trigger efficiencies for different samples |
62 |
> |
void triggerStudy(TString inputFileName = "SusyCAF_Tree_9_1_UMa_out_tree.root"){ |
63 |
> |
// init(inputFileName); |
64 |
> |
//Loop(inputFileName, "TTJets.root"); |
65 |
> |
// Loop("SusyCAF_Tree_n722_3403013856_out_tree.root", "TTJets.root"); |
66 |
> |
Loop("TTJets_SUMMER12_TrigStudy-mu_noTail_Tree.root", "TTJets.root"); |
67 |
> |
|
68 |
> |
//Loop(inputFileName, "Run2012C.root"); |
69 |
|
} |
70 |
|
|
71 |
|
|
72 |
< |
//================================================================================= Loop |
73 |
< |
void triggerStudy::Loop(){ |
74 |
< |
tools::enterFcn("Loop",1,1); |
75 |
< |
timer.Start("Loop"); |
76 |
< |
vector<UInt_t> loopEvents; |
77 |
< |
|
78 |
< |
for(Long64_t jentry=startEvent; jentry<nentries + startEvent; ++jentry){ |
79 |
< |
tools::progress(jentry); |
80 |
< |
inputTree->GetEntry(jentry); |
81 |
< |
//initVariables(jentry); |
82 |
< |
|
83 |
< |
//makeHistograms("_before"); |
84 |
< |
//makeHistograms("_after"); |
85 |
< |
} |
86 |
< |
timer.Stop("Loop"); |
87 |
< |
tools::exitFcn("Loop",1,1); |
72 |
> |
//================================================================================= plotHistograms |
73 |
> |
void plotHistograms(eventInfo& evt, map<TString, plotMaker> &plot){ |
74 |
> |
plot["event"].addh1d("muMultiplicity", "muMultiplicity", "muon multiplicity", "events", 5, -0.5, 4.5, evt.muonP4->size(), evt.Weight); |
75 |
> |
plot["event"].addh1d("elMultiplicity", "elMultiplicity", "electron multiplicity", "events", 5, -0.5, 4.5, evt.electronP4->size(), evt.Weight); |
76 |
> |
plot["event"].addh1d("jetMultiplicity", "jetMultiplicity", "jet multiplicity", "events", 10, -0.5, 9.5, evt.jetP4->size(), evt.Weight); |
77 |
> |
|
78 |
> |
|
79 |
> |
|
80 |
> |
|
81 |
> |
// for(Int_t i=0,N=muonP4->size(); i<N; ++i){ |
82 |
> |
// //cout<<"muonP4["<<i<<"] = " << (*muonP4)[i]<< endl; |
83 |
> |
// // myPlot.addh1d("MuPt", "MuPt", "p_T(#mu) [GeV]", "events", 100, 0., 300., muonP4->at(i).pt(), Weight); |
84 |
> |
// //myPlot.h1d ("MuPt", "MuPt", "p_T(#mu) [GeV]", "events", 100, 0., 300., muonP4->at(i).pt(), Weight); |
85 |
> |
// |
86 |
> |
// //cout<<"myPlot.h1d.size() = " << myPlot.h1d.size() << endl; |
87 |
> |
// |
88 |
> |
// } |
89 |
> |
|
90 |
|
} |
91 |
|
|
92 |
|
|
93 |
+ |
//================================================================================= Loop |
94 |
+ |
void Loop(TString inputFileName, TString outputFileName){ |
95 |
+ |
//timer.Start("Loop"); |
96 |
+ |
TString treeName = "trigStudyTree"; |
97 |
+ |
map<TString, plotMaker> myPlots; |
98 |
+ |
plotMaker myPlot; |
99 |
+ |
|
100 |
+ |
//--------------------------------------------------- open file and read in leafs |
101 |
+ |
TFile* inputFile = new TFile(inputFileName,"READ"); |
102 |
+ |
if (!inputFile->IsOpen()) std::cout<<"Could not open file "<<inputFileName<<std::endl; |
103 |
+ |
TTree* inputTree= (TTree*)inputFile->Get(treeName); |
104 |
+ |
inputTree->SetBranchStatus("*",0); |
105 |
+ |
|
106 |
+ |
eventInfo event; |
107 |
+ |
initBranches(inputTree, event); |
108 |
+ |
//--------------------------------------------------- Event Loop |
109 |
+ |
int nEvents=inputTree->GetEntries(); |
110 |
+ |
cout<<endl; |
111 |
+ |
cout<<"///////////////////////////////////////////////////////////////////////////////"<<endl; |
112 |
+ |
cout<<"////////////////////////////// Starting Event Loop ////////////////////////////"<<endl; |
113 |
+ |
cout<<"///////////////////////////////////////////////////////////////////////////////"<<endl; |
114 |
+ |
cout<<"Investigate File: " << inputFileName << endl; |
115 |
+ |
cout<<"Read out TTree: " << treeName << endl; |
116 |
+ |
cout<<"Number of events: " << nEvents << endl; |
117 |
+ |
cout<<"-------------------------------------------------------------------------------"<<endl; |
118 |
+ |
cout<<endl; |
119 |
+ |
cout<<"Looping over events..."<<endl; |
120 |
+ |
for (int iEvent=0; iEvent<nEvents; ++iEvent){ |
121 |
+ |
tools::progress(iEvent); |
122 |
+ |
inputTree->GetEntry(iEvent); |
123 |
+ |
// printEventInfo(event); |
124 |
+ |
// printMuonInfo(event); |
125 |
+ |
// printElectronInfo(event); |
126 |
+ |
plotHistograms(event, myPlots); |
127 |
+ |
//tools::progressReset(); |
128 |
+ |
} |
129 |
+ |
|
130 |
+ |
// for (int iEvent=0; iEvent<3000; ++iEvent){ |
131 |
+ |
// tools::progress(iEvent); |
132 |
+ |
// inputTree->GetEntry(iEvent); |
133 |
+ |
// //printEventInfo(event); |
134 |
+ |
// //printMuonInfo(event); |
135 |
+ |
// //printElectronInfo(event); |
136 |
+ |
// //plotHistograms(event, myPlots); |
137 |
+ |
// //tools::progressReset(); |
138 |
+ |
// } |
139 |
+ |
|
140 |
+ |
//--------------------------------------------------- Save all histograms in the appropriate folders |
141 |
+ |
TString option="RECREATE"; |
142 |
+ |
for(typename map<TString, plotMaker>::iterator it = myPlots.begin(); it != myPlots.end(); ++it){ |
143 |
+ |
it->second.savePlots(outputFileName, option, it->first); |
144 |
+ |
option="UPDATE"; |
145 |
+ |
} |
146 |
+ |
//timer.Stop("Loop"); |
147 |
+ |
} |
148 |
|
|
149 |
|
|
150 |
< |
|
151 |
< |
//================================================================================= initVariables |
152 |
< |
void triggerStudy::initVariables(){ |
153 |
< |
tools::enterFcn("initVariables",2); |
154 |
< |
|
155 |
< |
//cout<<"dataset = " << dataset << endl; |
156 |
< |
// Candidates .clear(); |
157 |
< |
|
158 |
< |
tools::exitFcn("initVariables",2); |
150 |
> |
//================================================================================= initBranches |
151 |
> |
void initBranches(TTree *tree, eventInfo& evt){ |
152 |
> |
//--------------------------------------------------- initialize event info |
153 |
> |
evt.DESYtriggerElMatchedTriggerFilter = 0; |
154 |
> |
evt.DESYtriggerMuMatchedTriggerFilter = 0; |
155 |
> |
evt.DESYtriggerNameMap = 0; |
156 |
> |
evt.electronCharge = 0; |
157 |
> |
evt.electronP4 = 0; |
158 |
> |
evt.Event = 0; |
159 |
> |
evt.HT = 0.; |
160 |
> |
evt.jetP4 = 0; |
161 |
> |
evt.MET = 0.; |
162 |
> |
evt.muonCharge = 0; |
163 |
> |
evt.muonP4 = 0; |
164 |
> |
evt.prescaled = 0; |
165 |
> |
evt.Run = 0; |
166 |
> |
evt.PUWeight = 0.; |
167 |
> |
evt.triggered = 0; |
168 |
> |
evt.Weight = 0.; |
169 |
> |
|
170 |
> |
|
171 |
> |
// tree->SetBranchStatus("DESYtriggerElMatchedTriggerFilter", 1); |
172 |
> |
// tree->SetBranchStatus("DESYtriggerMuMatchedTriggerFilter", 1); |
173 |
> |
// tree->SetBranchStatus("DESYtriggerNameMap*", 1); |
174 |
> |
// tree->SetBranchStatus("electronCharge", 1); |
175 |
> |
// tree->SetBranchStatus("electronP4", 1); |
176 |
> |
// tree->SetBranchStatus("Event", 1); |
177 |
> |
// tree->SetBranchStatus("HT", 1); |
178 |
> |
// tree->SetBranchStatus("jetP4", 1); |
179 |
> |
// tree->SetBranchStatus("MET", 1); |
180 |
> |
// tree->SetBranchStatus("muonCharge", 1); |
181 |
> |
// tree->SetBranchStatus("muonP4", 1); |
182 |
> |
// tree->SetBranchStatus("prescaled", 1); |
183 |
> |
// tree->SetBranchStatus("Run", 1); |
184 |
> |
// tree->SetBranchStatus("PUWeight", 1); |
185 |
> |
// tree->SetBranchStatus("triggered", 1); |
186 |
> |
// tree->SetBranchStatus("Weight", 1); |
187 |
> |
|
188 |
> |
tree->SetBranchStatus("DESYtriggerElMatchedTriggerFilter*", 1); |
189 |
> |
tree->SetBranchStatus("DESYtriggerMuMatchedTriggerFilter*", 1); |
190 |
> |
tree->SetBranchStatus("DESYtriggerNameMap*", 1); |
191 |
> |
tree->SetBranchStatus("electronCharge*", 1); |
192 |
> |
tree->SetBranchStatus("electronP4*", 1); |
193 |
> |
tree->SetBranchStatus("Event*", 1); |
194 |
> |
tree->SetBranchStatus("HT*", 1); |
195 |
> |
tree->SetBranchStatus("jetP4*", 1); |
196 |
> |
tree->SetBranchStatus("MET*", 1); |
197 |
> |
tree->SetBranchStatus("muonCharge*", 1); |
198 |
> |
tree->SetBranchStatus("muonP4*", 1); |
199 |
> |
tree->SetBranchStatus("prescaled*", 1); |
200 |
> |
tree->SetBranchStatus("Run*", 1); |
201 |
> |
tree->SetBranchStatus("PUWeight*", 1); |
202 |
> |
tree->SetBranchStatus("triggered*", 1); |
203 |
> |
tree->SetBranchStatus("Weight*", 1); |
204 |
> |
|
205 |
> |
|
206 |
> |
//--------------------------------------------------- assign branches to event structure |
207 |
> |
tree->SetBranchAddress("DESYtriggerElMatchedTriggerFilter", &(evt.DESYtriggerElMatchedTriggerFilter)); |
208 |
> |
tree->SetBranchAddress("DESYtriggerMuMatchedTriggerFilter",&(evt.DESYtriggerMuMatchedTriggerFilter)); |
209 |
> |
tree->SetBranchAddress("DESYtriggerNameMap",&(evt.DESYtriggerNameMap)); |
210 |
> |
tree->SetBranchAddress("electronCharge",&(evt.electronCharge)); |
211 |
> |
tree->SetBranchAddress("electronP4",&(evt.electronP4)); |
212 |
> |
tree->SetBranchAddress("Event",&(evt.Event)); |
213 |
> |
tree->SetBranchAddress("HT",&(evt.HT)); |
214 |
> |
tree->SetBranchAddress("jetP4",&(evt.jetP4)); |
215 |
> |
tree->SetBranchAddress("MET",&(evt.MET)); |
216 |
> |
tree->SetBranchAddress("muonCharge",&(evt.muonCharge)); |
217 |
> |
tree->SetBranchAddress("muonP4",&(evt.muonP4)); |
218 |
> |
tree->SetBranchAddress("prescaled",&(evt.prescaled)); |
219 |
> |
tree->SetBranchAddress("Run",&(evt.Run)); |
220 |
> |
tree->SetBranchAddress("PUWeight",&(evt.PUWeight)); |
221 |
> |
tree->SetBranchAddress("triggered",&(evt.triggered)); |
222 |
> |
tree->SetBranchAddress("Weight",&(evt.Weight)); |
223 |
> |
|
224 |
> |
|
225 |
> |
|
226 |
> |
|
227 |
> |
|
228 |
> |
|
229 |
> |
|
230 |
> |
// tree->SetBranchStatus("DESY*", 1); |
231 |
> |
// tree->SetBranchStatus("muonP4", 1); |
232 |
> |
// tree->SetBranchStatus("jetP4", 1); |
233 |
> |
// tree->SetBranchStatus("electronP4", 1); |
234 |
> |
// tree->SetBranchStatus("Weight", 1); |
235 |
> |
|
236 |
|
} |
237 |
|
|
238 |
|
|
239 |
+ |
//================================================================================= printEventInfo |
240 |
+ |
void printEventInfo(eventInfo& evt, ostream& os){ |
241 |
+ |
os<<endl; |
242 |
+ |
os<<"///////////////////////////////////////////////////////"<<endl; |
243 |
+ |
os<<"///////////////////// Event Info //////////////////////"<<endl; |
244 |
+ |
os<<"///////////////////////////////////////////////////////"<<endl; |
245 |
+ |
os<<endl; |
246 |
+ |
os<<"-----------------------------------------"<<endl; |
247 |
+ |
os<<"Run = "<<evt.Run<<endl; |
248 |
+ |
os<<"Event = "<<evt.Event<<endl; |
249 |
+ |
os<<"Weight = "<<evt.Weight<<endl; |
250 |
+ |
os<<"PUWeight = "<<evt.PUWeight<<endl; |
251 |
+ |
os<<"-----------------------------------------"<<endl; |
252 |
+ |
os<<"HT = "<<evt.HT<<endl; |
253 |
+ |
os<<"MET = "<<evt.MET<<endl; |
254 |
+ |
os<<"-----------------------------------------"<<endl; |
255 |
+ |
os<<"No. of Muons = "<<evt.muonP4->size()<<endl; |
256 |
+ |
os<<"No. of Electrons = "<<evt.electronP4->size()<<endl; |
257 |
+ |
os<<"No. of Jets = "<<evt.jetP4->size()<<endl; |
258 |
+ |
os<<"-----------------------------------------"<<endl; |
259 |
+ |
os<<"muonCharge.size() = "<<evt.muonCharge->size()<<endl; |
260 |
+ |
os<<"electronCharge.size() = "<<evt.electronCharge->size()<<endl; |
261 |
+ |
os<<"-----------------------------------------"<<endl; |
262 |
+ |
os<<"MuMatchedTriggerFilter.size() = "<<evt.DESYtriggerMuMatchedTriggerFilter->size()<<endl; |
263 |
+ |
os<<"ElMatchedTriggerFilter.size() = "<<evt.DESYtriggerElMatchedTriggerFilter->size()<<endl; |
264 |
+ |
os<<"-----------------------------------------"<<endl; |
265 |
+ |
os<<"triggered.size() = "<<evt.triggered->size()<<endl; |
266 |
+ |
os<<"prescaled.size() = "<<evt.prescaled->size()<<endl; |
267 |
+ |
os<<"DESYTriggerMap.size() = "<<evt.DESYtriggerNameMap->size()<<endl; |
268 |
+ |
os<<"-----------------------------------------"<<endl; |
269 |
+ |
os<<endl; |
270 |
+ |
|
271 |
+ |
//tools::printVector<string>("jetP4", *(evt.jetP4)); |
272 |
+ |
//tools::printVector<string>("DESYtriggerMuMatchedTriggerFilter", *(evt.DESYtriggerMuMatchedTriggerFilter)); |
273 |
+ |
//tools::printVector<string>("DESYtriggerElMatchedTriggerFilter", *(evt.DESYtriggerElMatchedTriggerFilter)); |
274 |
+ |
//tools::printVector<string>("DESYtriggerNameMap", *(evt.DESYtriggerNameMap)); |
275 |
+ |
//tools::printVector<string>("prescaled", *(evt.prescaled)); |
276 |
+ |
//tools::printVector<string>("triggered", *(evt.triggered)); |
277 |
+ |
} |
278 |
|
|
279 |
|
|
280 |
+ |
//================================================================================= printMuonInfo |
281 |
+ |
void printMuonInfo(eventInfo& evt, ostream& os){ |
282 |
+ |
os<<endl; |
283 |
+ |
os<<"///////////////////////////////////////////////////////"<<endl; |
284 |
+ |
os<<"////////////////////// Muon Info //////////////////////"<<endl; |
285 |
+ |
os<<"///////////////////////////////////////////////////////"<<endl; |
286 |
+ |
os<<endl; |
287 |
+ |
tools::printVector<LorentzM>("muonP4", *(evt.muonP4), os); |
288 |
+ |
tools::printVector<int>("muonCharge", *(evt.muonCharge), os); |
289 |
+ |
//------------------------ print invariant mass from all possible muon pairs |
290 |
+ |
if(evt.muonP4->size()>=2){ |
291 |
+ |
os<<"-------------> Invariant masses of all possible muon pairs:"<<endl; |
292 |
+ |
for(Int_t i=0,N=evt.muonP4->size(); i<N-1; ++i){ |
293 |
+ |
for(Int_t j=i+1; j<N; ++j){ |
294 |
+ |
Double_t minv = (evt.muonP4->at(i) + evt.muonP4->at(j)).mass(); |
295 |
+ |
os<<"Minv("<<i<<" + " <<j<<") = "<<minv<<endl; |
296 |
+ |
} |
297 |
+ |
} |
298 |
+ |
os<<endl; |
299 |
+ |
} |
300 |
+ |
//------------------------ print matching info |
301 |
+ |
vector<string> matchInfo = *(evt.DESYtriggerMuMatchedTriggerFilter); |
302 |
+ |
for(Int_t i=0,N=matchInfo.size(); i<N; ++i){ |
303 |
+ |
vector<TString> singleMatchInfo = tools::splitToWords(matchInfo[i], ";"); |
304 |
+ |
os<<"----------------------------------------------------------------------------> Matches for muon "<<i<<":"<< |
305 |
+ |
endl; |
306 |
+ |
tools::printVector<TString>("matched TriggerFilter", singleMatchInfo, os); |
307 |
+ |
} |
308 |
+ |
os<<endl; |
309 |
+ |
} |
310 |
|
|
311 |
|
|
312 |
+ |
//================================================================================= printElectronInfo |
313 |
+ |
void printElectronInfo(eventInfo& evt, ostream& os){ |
314 |
+ |
os<<endl; |
315 |
+ |
os<<"///////////////////////////////////////////////////////"<<endl; |
316 |
+ |
os<<"///////////////////// Electron Info ///////////////////"<<endl; |
317 |
+ |
os<<"///////////////////////////////////////////////////////"<<endl; |
318 |
+ |
os<<endl; |
319 |
+ |
tools::printVector<LorentzM>("electronP4", *(evt.electronP4), os); |
320 |
+ |
tools::printVector<int>("electronCharge", *(evt.electronCharge), os); |
321 |
+ |
//------------------------ print invariant mass from all possible electron pairs |
322 |
+ |
if(evt.electronP4->size()>=2){ |
323 |
+ |
os<<"-------------> Invariant masses of all possible electron pairs:"<<endl; |
324 |
+ |
for(Int_t i=0,N=evt.electronP4->size(); i<N-1; ++i){ |
325 |
+ |
for(Int_t j=i+1; j<N; ++j){ |
326 |
+ |
Double_t minv = (evt.electronP4->at(i) + evt.electronP4->at(j)).mass(); |
327 |
+ |
os<<"Minv("<<i<<" + " <<j<<") = "<<minv<<endl; |
328 |
+ |
} |
329 |
+ |
} |
330 |
+ |
os<<endl; |
331 |
+ |
} |
332 |
+ |
//------------------------ print matching info |
333 |
+ |
vector<string> matchInfo = *(evt.DESYtriggerElMatchedTriggerFilter); |
334 |
+ |
for(Int_t i=0,N=matchInfo.size(); i<N; ++i){ |
335 |
+ |
vector<TString> singleMatchInfo = tools::splitToWords(matchInfo[i], ";"); |
336 |
+ |
os<<"----------------------------------------------------------------------------> Matches for electron "<<i<<":"<< |
337 |
+ |
endl; |
338 |
+ |
tools::printVector<TString>("matched TriggerFilter", singleMatchInfo, os); |
339 |
+ |
} |
340 |
+ |
os<<endl; |
341 |
+ |
} |
342 |
|
|
343 |
|
|
344 |
|
|
345 |
+ |
//================================================================================= initVariables |
346 |
+ |
void initVariables(){ |
347 |
+ |
//cout<<"dataset = " << dataset << endl; |
348 |
+ |
//Candidates .clear(); |
349 |
+ |
} |
350 |
|
|
351 |
|
|
352 |
|
|
61 |
– |
#endif |
353 |
|
|
354 |
|
|
355 |
|
|