]>
Commit | Line | Data |
---|---|---|
72c0a987 | 1 | // $Id$ |
2 | ||
3 | //************************************************************************** | |
4 | //* This file is property of and copyright by the ALICE Project * | |
5 | //* ALICE Experiment at CERN, All rights reserved. * | |
6 | //* * | |
7 | //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> * | |
8 | //* Sedat Altinpinar <Sedat.Altinpinar@cern.ch> * | |
9 | //* Hege Erdal <hege.erdal@gmail.com> * | |
10 | //* * | |
11 | //* Permission to use, copy, modify and distribute this software and its * | |
12 | //* documentation strictly for non-commercial purposes is hereby granted * | |
13 | //* without fee, provided that the above copyright notice appears in all * | |
14 | //* copies and that both the copyright notice and this permission notice * | |
15 | //* appear in the supporting documentation. The authors make no claims * | |
16 | //* about the suitability of this software for any purpose. It is * | |
17 | //* provided "as is" without express or implied warranty. * | |
18 | //************************************************************************** | |
19 | ||
20 | /// @file AliDxHFEParticleSelection.cxx | |
21 | /// @author Sedat Altinpinar, Hege Erdal, Matthias Richter | |
22 | /// @date 2012-03-19 | |
23 | /// @brief Base class for particle selection | |
24 | /// | |
25 | ||
26 | #include "AliDxHFEParticleSelection.h" | |
93fcaf9f | 27 | #include "AliLog.h" |
72c0a987 | 28 | #include "AliVEvent.h" |
29 | #include "AliVParticle.h" | |
30 | #include "TObjArray.h" | |
93fcaf9f | 31 | #include "TList.h" |
32 | #include "TMath.h" | |
33 | #include "TH1D.h" | |
2229ac91 | 34 | #include "TH2D.h" |
93fcaf9f | 35 | #include "THnSparse.h" |
dfe96b90 | 36 | #include "AliReducedParticle.h" |
93fcaf9f | 37 | #include "TFile.h" |
b4779749 | 38 | #include "TPRegexp.h" // for TStringToken |
93fcaf9f | 39 | #include <iostream> |
72c0a987 | 40 | #include <cerrno> |
93fcaf9f | 41 | #include <memory> |
42 | ||
43 | using namespace std; | |
72c0a987 | 44 | |
45 | /// ROOT macro for the implementation of ROOT specific class methods | |
46 | ClassImp(AliDxHFEParticleSelection) | |
47 | ||
93fcaf9f | 48 | AliDxHFEParticleSelection::AliDxHFEParticleSelection(const char* name, const char* opt) |
49 | : TNamed(name?name:"AliDxHFEParticleSelection", name?name:"AliDxHFEParticleSelection") | |
72c0a987 | 50 | , fOption(opt) |
51 | , fSelectedTracks(NULL) | |
93fcaf9f | 52 | , fControlObjects(NULL) |
53 | , fhEventControl(NULL) | |
54 | , fhTrackControl(NULL) | |
fad30eb8 | 55 | , fhNrTracksPerEvent(NULL) |
d731501a | 56 | , fUseMC(0) |
9535cec9 | 57 | , fVerbosity(0) |
dcf83226 | 58 | , fDimThn(-1) |
59 | , fParticleProperties(NULL) | |
b4779749 | 60 | , fSystem(0) |
72c0a987 | 61 | { |
62 | // constructor | |
63 | // | |
64 | // | |
65 | // | |
66 | // | |
67 | } | |
68 | ||
9535cec9 | 69 | const char* AliDxHFEParticleSelection::fgkEventControlBinNames[]={ |
70 | "nEventsAll", | |
71 | "nEventsSelected", | |
d731501a | 72 | "nEventsWParticle" |
73 | }; | |
74 | ||
75 | const char* AliDxHFEParticleSelection::fgkTrackControlBinNames[]={ | |
76 | "nTrackAll", | |
77 | "nTrackSelected", | |
78 | }; | |
79 | ||
72c0a987 | 80 | AliDxHFEParticleSelection::~AliDxHFEParticleSelection() |
81 | { | |
82 | // destructor | |
dcf83226 | 83 | if (fParticleProperties) delete[] fParticleProperties; |
84 | fParticleProperties=NULL; | |
72c0a987 | 85 | if (fSelectedTracks) delete fSelectedTracks; |
86 | fSelectedTracks=NULL; | |
93fcaf9f | 87 | if (fControlObjects) delete fControlObjects; |
88 | fControlObjects=NULL; | |
9535cec9 | 89 | fhEventControl=NULL; |
90 | fhTrackControl=NULL; | |
fad30eb8 | 91 | fhNrTracksPerEvent=NULL; |
93fcaf9f | 92 | } |
93 | ||
d731501a | 94 | int AliDxHFEParticleSelection::Init() |
95 | { | |
96 | // | |
97 | // Init part sel. Calls InitControlObjects() | |
98 | // | |
99 | ||
100 | InitControlObjects(); | |
101 | return 0; | |
102 | } | |
103 | ||
104 | ||
93fcaf9f | 105 | int AliDxHFEParticleSelection::InitControlObjects() |
106 | { | |
d731501a | 107 | // |
9535cec9 | 108 | // init control objects |
d731501a | 109 | // TODO: Change to private now that have Init()? |
110 | // | |
9535cec9 | 111 | if (fVerbosity>0) { |
112 | AliInfo("Setting up control objects"); | |
113 | } | |
114 | ||
93fcaf9f | 115 | /// init the control objects, can be overloaded by childs which should |
116 | /// call AliDxHFEParticleSelection::InitControlObjects() explicitly | |
fad30eb8 | 117 | TString name; |
118 | name.Form("hEventControl%s", GetName()); | |
119 | fhEventControl=CreateControlHistogram(name.Data(), name.Data(),kNEventPropertyLabels,fgkEventControlBinNames); | |
93fcaf9f | 120 | |
fad30eb8 | 121 | name.Form("hTrackControl%s", GetName()); |
122 | fhTrackControl=CreateControlHistogram(name.Data(), name.Data(),kNTrackPropertyLabels,fgkTrackControlBinNames); | |
123 | ||
124 | name.Form("hNrTracksPerEvent%s", GetName()); | |
125 | fhNrTracksPerEvent=CreateControlHistogram(name.Data(), name.Data(),100); | |
126 | ||
93fcaf9f | 127 | AddControlObject(fhEventControl); |
93fcaf9f | 128 | AddControlObject(fhTrackControl); |
fad30eb8 | 129 | AddControlObject(fhNrTracksPerEvent); |
93fcaf9f | 130 | |
131 | return 0; | |
132 | } | |
133 | ||
2229ac91 | 134 | |
135 | TH1* AliDxHFEParticleSelection::CreateControlHistogram(const char* name, | |
136 | const char* title, | |
137 | int nBins, | |
b4779749 | 138 | double min, |
139 | double max, | |
2229ac91 | 140 | const char** binLabels) const |
141 | { | |
142 | /// create control histogram | |
b4779749 | 143 | std::auto_ptr<TH1> h(new TH1D(name, title, nBins, min, max)); |
2229ac91 | 144 | if (!h.get()) return NULL; |
b4779749 | 145 | if (binLabels) { |
2229ac91 | 146 | for (int iLabel=0; iLabel<nBins; iLabel++) { |
147 | h->GetXaxis()->SetBinLabel(iLabel+1, binLabels[iLabel]); | |
148 | } | |
b4779749 | 149 | } |
2229ac91 | 150 | |
151 | return h.release(); | |
152 | } | |
153 | ||
154 | ||
155 | TH2* AliDxHFEParticleSelection::CreateControl2DHistogram(const char* name, | |
156 | const char* title, | |
157 | double* nBins, | |
158 | const char* xaxis, | |
159 | const char* yaxis | |
160 | ) const | |
161 | { | |
162 | /// create control 2D histogram. Requires as input: | |
163 | // name = name of histogram | |
164 | // title = title of histogram | |
165 | // nBins (array with 6 elements) containing apropriate binning and range for x and y axis | |
166 | // xaxis = title of x axis | |
167 | // yaxis = title of y axis | |
168 | ||
169 | std::auto_ptr<TH2> h(new TH2D(name, title, (Int_t)nBins[0], nBins[1], nBins[2], (Int_t)nBins[3], nBins[4],nBins[5])); | |
170 | if (!h.get()) return NULL; | |
171 | h->GetXaxis()->SetTitle(xaxis); | |
172 | h->GetYaxis()->SetTitle(yaxis); | |
173 | ||
174 | return h.release(); | |
175 | } | |
176 | ||
d731501a | 177 | THnSparse* AliDxHFEParticleSelection::CreateControlTHnSparse(const char* name, |
178 | int thnSize, | |
179 | int* thnBins, | |
180 | double* thnMin, | |
181 | double* thnMax, | |
182 | const char** binLabels) const | |
183 | { | |
184 | // | |
185 | // Creates THnSparse. | |
186 | // | |
187 | ||
188 | AliInfo("Setting up THnSparse"); | |
189 | ||
190 | std::auto_ptr<THnSparseF> th(new THnSparseF(name, name, thnSize, thnBins, thnMin, thnMax)); | |
191 | if (th.get()==NULL) { | |
192 | return NULL; | |
193 | } | |
194 | for (int iLabel=0; iLabel<thnSize; iLabel++) { | |
195 | th->GetAxis(iLabel)->SetTitle(binLabels[iLabel]); | |
196 | ||
197 | } | |
198 | return th.release(); | |
199 | ||
200 | } | |
201 | ||
dcf83226 | 202 | THnSparse* AliDxHFEParticleSelection::DefineTHnSparse() |
d731501a | 203 | { |
204 | // | |
205 | // Defines the THnSparse. For now, only calls CreatControlTHnSparse | |
206 | ||
207 | //TODO: Should make it more general. Or maybe one can use this here, and skip in PartSelEl? | |
208 | ||
dcf83226 | 209 | // here is the only place to change the dimension |
d731501a | 210 | const int thnSize = 3; |
dcf83226 | 211 | InitTHnSparseArray(thnSize); |
212 | ||
d731501a | 213 | const double Pi=TMath::Pi(); |
214 | TString name; | |
dcf83226 | 215 | // 0 1 2 |
216 | // Pt Phi Eta | |
217 | int thnBins [thnSize] = { 1000, 200, 500}; | |
218 | double thnMin [thnSize] = { 0, 0, -1.}; | |
219 | double thnMax [thnSize] = { 100, 2*Pi, 1.}; | |
220 | const char* thnNames[thnSize] = { "Pt","Phi","Eta"}; | |
d731501a | 221 | |
222 | name.Form("%s info", GetName()); | |
223 | ||
dcf83226 | 224 | return CreateControlTHnSparse(name,thnSize,thnBins,thnMin,thnMax,thnNames); |
d731501a | 225 | } |
226 | ||
93fcaf9f | 227 | int AliDxHFEParticleSelection::AddControlObject(TObject* pObj) |
228 | { | |
229 | /// add control object to list, the base class becomes owner of the object | |
230 | if (!pObj) return -EINVAL; | |
231 | if (!fControlObjects) { | |
232 | fControlObjects=new TList; | |
233 | if (!fControlObjects) return -ENOMEM; | |
234 | fControlObjects->SetOwner(); | |
235 | } | |
236 | if (fControlObjects->FindObject(pObj->GetName())) { | |
237 | AliError(Form("ignoring duplicate object '%s' of type %s", pObj->GetName(), pObj->ClassName())); | |
238 | return -EEXIST; | |
239 | } | |
9535cec9 | 240 | if (GetVerbosity()>0) { |
241 | AliInfo(Form("Adding object '%s' of type %s",pObj->GetName(),pObj->ClassName())); | |
242 | } | |
93fcaf9f | 243 | fControlObjects->Add(pObj); |
244 | return 0; | |
245 | } | |
246 | ||
fad30eb8 | 247 | int AliDxHFEParticleSelection::HistogramEventProperties(int histonr,int bin) |
9535cec9 | 248 | { |
249 | /// histogram event properties | |
250 | if (!fControlObjects) return 0; | |
251 | ||
252 | // TODO: use enums for the bins of the control histogram | |
253 | // for now: 0=all, 1=events with D0s, 2=events with correlated D0s | |
fad30eb8 | 254 | if(histonr==kHistoEvent){ |
255 | fhEventControl->Fill(bin); | |
256 | } | |
257 | if(histonr==kHistoNrTracksPrEvent){ | |
258 | fhNrTracksPerEvent->Fill(bin); | |
259 | } | |
9535cec9 | 260 | return 0; |
261 | } | |
262 | ||
263 | int AliDxHFEParticleSelection::HistogramParticleProperties(AliVParticle* p, int selected) | |
93fcaf9f | 264 | { |
265 | /// histogram particle properties | |
d731501a | 266 | |
93fcaf9f | 267 | if (!p) return -EINVAL; |
268 | if (!fControlObjects) return 0; | |
269 | ||
270 | // TODO: use enums for the bins of the control histogram | |
d731501a | 271 | fhTrackControl->Fill(kTrackAll); |
272 | if (selected) fhTrackControl->Fill(kTrackSel); | |
93fcaf9f | 273 | return 0; |
72c0a987 | 274 | } |
275 | ||
dcf83226 | 276 | int AliDxHFEParticleSelection::FillParticleProperties(AliVParticle* p, Double_t* data, int dimension) const |
d731501a | 277 | { |
278 | // fill the data array from the particle data | |
279 | if (!data) return -EINVAL; | |
280 | int i=0; | |
dcf83226 | 281 | if (dimension!=GetDimTHnSparse()) { |
d731501a | 282 | // TODO: think about filling only the available data and throwing a warning |
283 | return -ENOSPC; | |
284 | } | |
285 | data[i++]=p->Pt(); | |
286 | data[i++]=p->Phi(); | |
287 | data[i++]=p->Eta(); | |
288 | return i; | |
289 | } | |
290 | ||
72c0a987 | 291 | TObjArray* AliDxHFEParticleSelection::Select(const AliVEvent* pEvent) |
292 | { | |
9535cec9 | 293 | /// create selection from 'Tracks' member of the event, |
294 | /// array contains only pointers but does not own the objects | |
72c0a987 | 295 | /// object array needs to be deleted by caller |
296 | if (!pEvent) return NULL; | |
297 | TObjArray* selectedTracks=new TObjArray; | |
298 | if (!selectedTracks) return NULL; | |
b86451e1 | 299 | selectedTracks->SetOwner(kFALSE); // creating new track objects below |
72c0a987 | 300 | int nofTracks=pEvent->GetNumberOfTracks(); |
301 | for (int itrack=0; itrack<nofTracks; itrack++) { | |
302 | AliVParticle* track=pEvent->GetTrack(itrack); | |
d731501a | 303 | int selectionCode=IsSelected(track,pEvent); |
9535cec9 | 304 | HistogramParticleProperties(track, selectionCode); |
305 | if (selectionCode==0) continue; | |
dfe96b90 | 306 | selectedTracks->Add(CreateParticle(track)); |
72c0a987 | 307 | } |
308 | return selectedTracks; | |
309 | } | |
310 | ||
9535cec9 | 311 | TObjArray* AliDxHFEParticleSelection::Select(TObjArray* pParticles, const AliVEvent* pEvent) |
72c0a987 | 312 | { |
9535cec9 | 313 | /// create selection from the array of particles, |
314 | /// array contains only pointers but does not own the objects | |
72c0a987 | 315 | /// object array needs to be deleted by caller |
9535cec9 | 316 | if (!pParticles) return NULL; |
72c0a987 | 317 | TObjArray* selectedTracks=new TObjArray; |
318 | if (!selectedTracks) return NULL; | |
b4779749 | 319 | selectedTracks->SetOwner(kFALSE); // creating new track objects below |
9535cec9 | 320 | TIter next(pParticles); |
72c0a987 | 321 | TObject* pObj=NULL; |
9535cec9 | 322 | while ((pObj=next())) { |
72c0a987 | 323 | AliVParticle* track=dynamic_cast<AliVParticle*>(pObj); |
324 | if (!track) continue; | |
9535cec9 | 325 | int selectionCode=IsSelected(track, pEvent); |
326 | HistogramParticleProperties(track, selectionCode); | |
327 | if (selectionCode ==0) continue; | |
dfe96b90 | 328 | selectedTracks->Add(CreateParticle(track)); |
72c0a987 | 329 | } |
330 | return selectedTracks; | |
331 | } | |
332 | ||
333 | int AliDxHFEParticleSelection::CheckAndAdd(AliVParticle* /*p*/) | |
334 | { | |
335 | /// check and add track to internal array | |
336 | /// TODO: check if needed | |
337 | return -ENOSYS; | |
338 | } | |
339 | ||
9535cec9 | 340 | int AliDxHFEParticleSelection::IsSelected(AliVParticle* /*p*/, const AliVEvent* /*e*/) |
72c0a987 | 341 | { |
342 | /// check particle if it passes the selection criteria | |
343 | /// childs can overload, by default all tracks are selected | |
9535cec9 | 344 | return 1; |
72c0a987 | 345 | } |
346 | ||
347 | void AliDxHFEParticleSelection::AliDxHFEParticleSelection::Clear(Option_t * /*option*/) | |
348 | { | |
349 | /// inherited from TObject: cleanup | |
350 | } | |
351 | ||
352 | void AliDxHFEParticleSelection::Print(Option_t */*option*/) const | |
353 | { | |
354 | /// inherited from TObject: print info | |
93fcaf9f | 355 | cout << "====================================================================" << endl; |
356 | TNamed::Print(); | |
357 | if (fControlObjects) fControlObjects->Print(); | |
72c0a987 | 358 | } |
359 | ||
9535cec9 | 360 | void AliDxHFEParticleSelection::SaveAs(const char* filename, Option_t */*option*/) const |
72c0a987 | 361 | { |
93fcaf9f | 362 | /// inherited from TObject: save selection criteria |
9535cec9 | 363 | TString fileoption; |
364 | // TODO: options recreate | |
365 | fileoption="RECREATE"; | |
366 | //else fileoption="UPDATE"; | |
367 | ||
368 | std::auto_ptr<TFile> output(TFile::Open(filename,fileoption)); | |
93fcaf9f | 369 | if (!output.get() || output->IsZombie()) { |
370 | AliError(Form("can not open file %s from writing", filename)); | |
371 | return; | |
372 | } | |
373 | output->cd(); | |
374 | if (fControlObjects) fControlObjects->Write(); | |
375 | output->Close(); | |
376 | } | |
377 | ||
378 | void AliDxHFEParticleSelection::Draw(Option_t* /*option*/) | |
379 | { | |
380 | /// inherited from TObject: draw content | |
381 | ||
382 | // TODO: implement drawing code | |
383 | // - create canvas objects | |
384 | // - plot internal objects | |
385 | // - optionally save canvases to file | |
386 | // | |
387 | // It might be appropriate to have another Draw function taking a | |
388 | // TList as argument and implementing the actual drawing. If this | |
389 | // function is 'static', it can be used stand-alone also from macros | |
390 | } | |
391 | ||
392 | TObject* AliDxHFEParticleSelection::FindObject(const char* name) const | |
393 | { | |
394 | /// inherited from TObject: find object by name | |
395 | ||
396 | if (fControlObjects) { | |
397 | return fControlObjects->FindObject(name); | |
398 | } | |
399 | return NULL; | |
400 | } | |
401 | ||
402 | TObject* AliDxHFEParticleSelection::FindObject(const TObject* obj) const | |
403 | { | |
404 | /// inherited from TObject: find object by pointer | |
405 | if (fControlObjects) { | |
406 | return fControlObjects->FindObject(obj); | |
407 | } | |
408 | return NULL; | |
72c0a987 | 409 | } |
dfe96b90 | 410 | |
411 | AliVParticle *AliDxHFEParticleSelection::CreateParticle(AliVParticle* track) | |
412 | { | |
413 | // Creating object with reduced particle properties | |
414 | AliReducedParticle *part = new AliReducedParticle(track->Eta(), track->Phi(), track->Pt(), track->Charge(), 0); | |
415 | ||
416 | return part; | |
417 | ||
418 | } | |
b4779749 | 419 | |
420 | int AliDxHFEParticleSelection::ParseArguments(const char* arguments) | |
421 | { | |
422 | // parse arguments and set internal flags | |
423 | const char* key=NULL; | |
424 | const TString delimiter(" "); | |
425 | TStringToken token(arguments, delimiter); | |
426 | while (token.NextToken()) { | |
427 | TString argument=token; | |
428 | key="system="; | |
429 | if (argument.BeginsWith(key)) { | |
430 | argument.ReplaceAll(key, ""); | |
431 | if (argument.CompareTo("pp")==0) fSystem=0; | |
432 | else if (argument.CompareTo("Pb-Pb")==0) fSystem=1; | |
433 | else if (argument.CompareTo("p-Pb")==0) fSystem=2; | |
434 | else { | |
435 | AliWarning(Form("can not set collision system, unknown parameter '%s'", argument.Data())); | |
436 | // TODO: check what makes sense | |
437 | fSystem=0; | |
438 | } | |
439 | continue; | |
440 | } | |
441 | ||
442 | AliWarning(Form("unknown argument '%s'", argument.Data())); | |
443 | } | |
444 | ||
445 | return 0; | |
446 | } |