Deleted erroneously added simlinks
[u/mrichter/AliRoot.git] / RALICE / AliEventSelector.cxx
CommitLineData
caa58e1a 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
15
16// $Id$
17
18///////////////////////////////////////////////////////////////////////////
19// Class AliEventSelector
20// TTask based processor to perform generic event selection.
21// This class is derived from AliAstrolab in order to also provide event
22// selection based on space and time matching with external (astrophysical)
23// objects and phenomena.
24//
25// After having applied the various selection criteria, this processor
26// introduces an AliDevice with the name "AliEventSelector" into the event.
27// This device contains named signal slots to indicate the settings
28// of the various selection parameters.
29// One of the slots has the name "Select" and the signal value of this
30// slot indicates the final selection result.
31//
32// value : -1 ==> Event rejected
33// 0 ==> Decision unknown (incomplete selection parameters)
34// 1 ==> Event selected
35//
36// Event selection may be performed based on various selection types,
37// e.g. individual track observables, total event observables or
38// space and time matching with external objects.
39// These types can be (de)activated via the SetSelector member function.
40//
41// The specific selection criteria for each selection type may be
42// specified via the SetRange memberfunction.
43//
44// The logic to be used in the selection process with the various criteria
45// is set via the memberfunction SetLogic.
46// Obviously, matching of tracks with various external objects is always
47// performed in logical "or".
48//
49// For investigation of individual track observables and/or matching with
50// external objects, the user may define a restricted set of tracks to
51// be used in the evaluation procedures. The definition of such a restricted
52// track set is performed via the memberfunction UseTracks.
53//
54// Example :
55// ---------
56// gSystem->Load("ralice");
57//
58// AliEventSelector sel;
59// sel.SetLabPosition(0.5,-90,"deg"); // The South Pole Neutrino Observatory
60// sel.SetLocalFrame(90,180,90,270,0,0); // Local frame has X-axis to the North
61//
62// sel.SetSelector("astro");
63// sel.SetSelector("track");
64// sel.SetSelector("event");
65// sel.SetLogic("and");
66// sel.UseTracks("*");
67//
68// sel.SetRange("track","p",0.5,1e20); // Require at least 500 MeV/c track momentum
69// sel.SetRange("event","ntrk","*",1,3); // Only low multiplicity events
70//
71// // Match with Astrophysical objects within 5 degrees and 10 seconds
72// Float_t da=5;
73// Float_t dt=10;
74// sel.SetAstroMatch(da,dt,"from");
75//
76// // Some observed event to be investigated
77// AliEvent evt;
78// evt.SetUT(1989,7,30,8,14,23,738504,0);
79//
80// Float_t vec[3]={1,23.8,118.65};
81// Ali3Vector r;
82// r.SetVector(vec,"sph","deg");
83//
84// AliTrack t;
85// t.SetNameTitle("SomeTrack","Just a dummy test track");
86// r*=-1; // Let track originate from specified location
87// t.Set3Momentum(r);
88//
89// evt.AddTrack(t);
90//
91// // Enter some external (astrophysical) reference signals
92// Float_t alpha=194818.0;
93// Float_t delta=84400.;
94// sel.SetSignal(alpha,delta,"B",1950,"M",-1,"Altair");
95// alpha=124900.0;
96// delta=272400.;
97// sel.SetSignal(alpha,delta,"B",1950,"M",-1,"NGP");
98// alpha=64508.917;
99// delta=-164258.02;
100// sel.SetSignal(alpha,delta,"J",2000,"M",-1,"Sirius");
101// alpha=23149.08;
102// delta=891550.8;
103// sel.SetSignal(alpha,delta,"J",2000,"M",-1,"Polaris");
104// alpha=43600.;
105// delta=163100.;
106// sel.SetSignal(alpha,delta,"J",2000,"M",-1,"Aldebaran");
107// Float_t l=327.531;
108// Float_t b=-35.8903;
109// Float_t pos[3]={1,90.-b,l};
110// r.SetVector(pos,"sph","deg");
111// sel.SetUT(1989,7,30,8,14,16,0,0);
112// sel.SetSignal(&r,"gal","M",0,-1,"GRB890730"); // This matches our track
113//
114// // List all stored reference objects
115// sel.ListSignals("equ","T",5);
116//
117// // Let's see what the event selection makes of it
118// AliJob q;
119// q.Add(&sel);
120// q.ListEnvironment();
121// q.ProcessObject(&evt);
122//
123// AliDevice* evtsel=(AliDevice*)evt.GetDevice("AliEventSelector");
124// if (evtsel) evtsel->Data();
125//
126//--- Author: Nick van Eijndhoven 17-sep-2007 Utrecht University
127//- Modified: NvE $Date$ Utrecht University
128///////////////////////////////////////////////////////////////////////////
129
b09247a2 130#include <cstdlib>
caa58e1a 131#include "AliEventSelector.h"
132#include "Riostream.h"
133
134ClassImp(AliEventSelector) // Class implementation to enable ROOT I/O
135
136AliEventSelector::AliEventSelector(const char* name,const char* title) : AliAstrolab(name,title)
137{
138// Default constructor.
139
140 fFirst=1;
141 fEvt=0;
142 fParams=0;
143 fSelect=0;
144 fTrackflag=0;
145 fEventflag=0;
146 fAstroflag=0;
147 fLogic=0;
148 fUseNames=0;
149 fUseNtk=0;
150 fAstroDa=-1;
151 fAstroDt=-1;
152 fAstroDir=0;
153
154 for (Int_t i=0; i<=8; i=i+2)
155 {
156 fEventTracks[i]=0;
157 fEventTracks[i+1]=-1;
158 if (i<=4)
159 {
160 fTrackMomenta[i]=0;
161 fTrackMomenta[i+1]=-1;
162 fTrackEnergies[i]=0;
163 fTrackEnergies[i+1]=-1;
164 fEventMomenta[i]=0;
165 fEventMomenta[i+1]=-1;
166 fEventEnergies[i]=0;
167 fEventEnergies[i+1]=-1;
168 }
169 if (i<=2)
170 {
171 fTrackRapidities[i]=0;
172 fTrackRapidities[i+1]=-1;
173 }
174 if (i==0)
175 {
176 fTrackMasses[i]=0;
177 fTrackMasses[i+1]=-1;
178 fEventMasses[i]=0;
179 fEventMasses[i+1]=-1;
180 fTrackCharges[i]=0;
181 fTrackCharges[i+1]=-1;
182 fEventCharges[i]=0;
183 fEventCharges[i+1]=-1;
184 fTrackDevices[i]=0;
185 fTrackDevices[i+1]=-1;
186 fEventDevices[i]=0;
187 fEventDevices[i+1]=-1;
188 }
189 }
190 fTrackDevClass="";
191 fEventDevClass="";
192 fEventTrkName="";
193}
194///////////////////////////////////////////////////////////////////////////
195AliEventSelector::~AliEventSelector()
196{
197// Default destructor.
198
199 if (fParams)
200 {
201 delete fParams;
202 fParams=0;
203 }
204
205 if (fUseNames)
206 {
207 delete fUseNames;
208 fUseNames=0;
209 }
210 if (fUseNtk)
211 {
212 delete fUseNtk;
213 fUseNtk=0;
214 }
215}
216///////////////////////////////////////////////////////////////////////////
217AliEventSelector::AliEventSelector(const AliEventSelector& q) : AliAstrolab(q)
218{
219// Copy constructor
220
221 fFirst=1;
222 fEvt=0;
223 fParams=new AliDevice(*(q.fParams));
224 fSelect=q.fSelect;
225 fTrackflag=q.fTrackflag;
226 fEventflag=q.fEventflag;
227 fAstroflag=q.fAstroflag;
228 fLogic=q.fLogic;
229 fAstroDa=q.fAstroDa;
230 fAstroDt=q.fAstroDt;
231 fAstroDir=q.fAstroDir;
232
233 for (Int_t i=0; i<10; i++)
234 {
235 fEventTracks[i]=q.fEventTracks[i];
236
237 if (i<6)
238 {
239 fTrackMomenta[i]=q.fTrackMomenta[i];
240 fTrackEnergies[i]=q.fTrackEnergies[i];
241 fEventMomenta[i]=q.fEventMomenta[i];
242 fEventEnergies[i]=q.fEventEnergies[i];
243 }
244
245 if (i<4) fTrackRapidities[i]=q.fTrackRapidities[i];
246
247 if (i<2)
248 {
249 fTrackMasses[i]=q.fTrackMasses[i];
250 fEventMasses[i]=q.fEventMasses[i];
251 fTrackCharges[i]=q.fTrackCharges[i];
252 fEventCharges[i]=q.fEventCharges[i];
253 fTrackDevices[i]=q.fTrackDevices[i];
254 fEventDevices[i]=q.fEventDevices[i];
255 }
256 }
257 fTrackDevClass=q.fTrackDevClass;
258 fEventDevClass=q.fEventDevClass;
259 fEventTrkName=q.fEventTrkName;
260}
261///////////////////////////////////////////////////////////////////////////
262void AliEventSelector::SetSelector(TString type,Int_t flag)
263{
264// Specify the selection types to be used.
265// The various types my be selected in a cumulative way by specification
266// of the input argument "type".
267// The various possibilities are :
268//
269// type = "track" ==> Selection based on individual track observables (e.g. Pt)
270// "event" ==> Selection based on total event observables (e.g. Invmass)
271// "astro" ==> Selection based on correlation with external objects
272//
273// The specified selection types can be (de)activated via the input
274// argument "flag".
275//
276// flag = 0 ==> Don't use the specified selection type
277// 1 ==> Use the specified selection type
278//
279// For type="astro" the flag>0 value specifies further selections as follows :
280//
281// flag = 1 ==> Match individual track momentum directions with external (astrophysical) objects
282// 2 ==> Match event total momentum direction with external (astrophysical) objects
283// 3 ==> Match event position with external (astrophysical) objects
284//
285// For further details see memberfunction SetAstroMatch.
286//
287// The default value is flag=1.
288//
289// Note : In the default constructor all selection types are de-activated.
290
291 if (type=="track") fTrackflag=flag;
292 if (type=="event") fEventflag=flag;
293 if (type=="astro") fAstroflag=flag;
294}
295///////////////////////////////////////////////////////////////////////////
296void AliEventSelector::SetLogic(TString type)
297{
298// Set type of the decision logic.
299//
300// type = "and" ==> Event selection based on logical "and"
301// "or" ==> Event selection based on logical "or"
302// "nand" ==> Event selection based on logical "nand"
303// "nor" ==> Event selection based on logical "nor"
304//
305// Note : In the default constructor the decision logic is set to "unknown".
306
307 if (type=="and") fLogic=1;
308 if (type=="or") fLogic=2;
309 if (type=="nand") fLogic=-1;
310 if (type=="nor") fLogic=-2;
311}
312///////////////////////////////////////////////////////////////////////////
313void AliEventSelector::UseTracks(TString name,Int_t n)
314{
315// Specification of the track names to be used for the investigation
316// of individual track observables and matching with external objects.
317//
318// name : Specifies the track name (e.g. "IceDwalk")
319// In case name="*" all track names will be accepted.
320
321// n : Specifies the max. number of these tracks to be used
322//
323// Note : n<0 will use all the existing tracks of the specified name
324//
325// The default is n=-1.
326//
327// Consecutive invokations of this memberfunction with different names
328// will result in an incremental effect.
329//
330// Example :
331// ---------
332// UseTracks("IceDwalk",5);
333// UseTracks("IceLinefit",2);
334// UseTracks("Pythia");
335//
336// This will use the first 5 IceDwalk, the first 2 IceLinefit and all the
337// Pythia tracks which are encountered in the event structure.
338
339 if (!fUseNames)
340 {
341 fUseNames=new TObjArray();
342 fUseNames->SetOwner();
343 }
344
345 if (!fUseNtk) fUseNtk=new TArrayI();
346
347 // Check if this classname has already been specified before
348 TString s;
349 Int_t nen=fUseNames->GetEntries();
350 for (Int_t i=0; i<nen; i++)
351 {
352 TObjString* sx=(TObjString*)fUseNames->At(i);
353 if (!sx) continue;
354 s=sx->GetString();
355 if (s==name) return;
356 }
357
358 // New name to be added into the storage
359 if (nen >= fUseNames->GetSize()) fUseNames->Expand(nen+1);
360 if (nen >= fUseNtk->GetSize()) fUseNtk->Set(nen+1);
361
362 TObjString* namex=new TObjString();
363 namex->SetString(name);
364 fUseNames->Add(namex);
365 fUseNtk->AddAt(n,nen);
366}
367///////////////////////////////////////////////////////////////////////////
368void AliEventSelector::SetAstroMatch(Double_t da,Double_t dt,TString dir)
369{
370// Set the parameters for the matching of reference objects.
371//
372// da : Maximum angular difference in degrees
373// dt : Maximum absolute time difference in seconds
374// dir : "to" ==> Check the location the track (or event) points to
375// "from" ==> Check the location the track (or event) originates from
376
377 fAstroDa=fabs(da);
378 fAstroDt=fabs(dt);
379 fAstroDir=0;
380 if (dir=="to") fAstroDir=1;
381 if (dir=="from") fAstroDir=-1;
382
383 if (!fParams) fParams=new AliDevice();
384
385 fParams->AddNamedSlot("AstroDa");
386 fParams->AddNamedSlot("AstroDt");
387 fParams->AddNamedSlot("AstroDir");
388 fParams->SetSignal(fAstroDa,"AstroDa");
389 fParams->SetSignal(fAstroDt,"AstroDt");
390 fParams->SetSignal(fAstroDir,"AstroDir");
391}
392///////////////////////////////////////////////////////////////////////////
393void AliEventSelector::SetRange(TString type,TString obs,Double_t low,Double_t up)
394{
395// Set range for the specified observable.
396//
397// type : Selection type specifier (e.g. "track" or "event").
398// obs : Observable specification.
399// low : Lower bound of acceptance range
400// up : Upper bound of acceptance range
401//
402// The various observables that are available for selection criteria are :
403//
404// obs : "p" ==> Momentum value in GeV/c
405// "pt" ==> Transverse momentum value in GeV/c
406// "pl" ==> Longitudinal momentum value in GeV/c
407// "e" ==> Energy value in GeV
408// "et" ==> Transverse momentum value in GeV
409// "el" ==> Longitudinal momentum value in GeV
410// "m" ==> (Invariant) mass in GeV/c^2
411// "q" ==> Charge (electron charge is defined as -1)
412// "y" ==> Rapidity (only for "track")
413// "eta" ==> Pseudo-rapidity (only for "track")
414//
415// Note : When up<low the specified observable will not be used for selection.
416//
417// In the default constructor all observables are de-activated for selection.
418
419 if (!fParams) fParams=new AliDevice();
420
421 if (type=="track") // Individual track observables
422 {
423 if (obs=="p")
424 {
425 fTrackMomenta[0]=low;
426 fTrackMomenta[1]=up;
427 fParams->AddNamedSlot("TrackMinP");
428 fParams->AddNamedSlot("TrackMaxP");
429 fParams->SetSignal(low,"TrackMinP");
430 fParams->SetSignal(up,"TrackMaxP");
431 }
432 if (obs=="pt")
433 {
434 fTrackMomenta[2]=low;
435 fTrackMomenta[3]=up;
436 fParams->AddNamedSlot("TrackMinPt");
437 fParams->AddNamedSlot("TrackMaxPt");
438 fParams->SetSignal(low,"TrackMinPt");
439 fParams->SetSignal(up,"TrackMaxPt");
440 }
441 if (obs=="pl")
442 {
443 fTrackMomenta[4]=low;
444 fTrackMomenta[5]=up;
445 fParams->AddNamedSlot("TrackMinPl");
446 fParams->AddNamedSlot("TrackMaxPl");
447 fParams->SetSignal(low,"TrackMinPl");
448 fParams->SetSignal(up,"TrackMaxPl");
449 }
450 if (obs=="e")
451 {
452 fTrackEnergies[0]=low;
453 fTrackEnergies[1]=up;
454 fParams->AddNamedSlot("TrackMinE");
455 fParams->AddNamedSlot("TrackMaxE");
456 fParams->SetSignal(low,"TrackMinE");
457 fParams->SetSignal(up,"TrackMaxE");
458 }
459 if (obs=="et")
460 {
461 fTrackEnergies[2]=low;
462 fTrackEnergies[3]=up;
463 fParams->AddNamedSlot("TrackMinEt");
464 fParams->AddNamedSlot("TrackMaxEt");
465 fParams->SetSignal(low,"TrackMinEt");
466 fParams->SetSignal(up,"TrackMaxEt");
467 }
468 if (obs=="el")
469 {
470 fTrackEnergies[4]=low;
471 fTrackEnergies[5]=up;
472 fParams->AddNamedSlot("TrackMinEl");
473 fParams->AddNamedSlot("TrackMaxEl");
474 fParams->SetSignal(low,"TrackMinEl");
475 fParams->SetSignal(up,"TrackMaxEl");
476 }
477 if (obs=="m")
478 {
479 fTrackMasses[0]=low;
480 fTrackMasses[1]=up;
481 fParams->AddNamedSlot("TrackMinM");
482 fParams->AddNamedSlot("TrackMaxM");
483 fParams->SetSignal(low,"TrackMinM");
484 fParams->SetSignal(up,"TrackMaxM");
485 }
486 if (obs=="q")
487 {
488 fTrackCharges[0]=low;
489 fTrackCharges[1]=up;
490 fParams->AddNamedSlot("TrackMinQ");
491 fParams->AddNamedSlot("TrackMaxQ");
492 fParams->SetSignal(low,"TrackMinQ");
493 fParams->SetSignal(up,"TrackMaxQ");
494 }
495 if (obs=="y")
496 {
497 fTrackRapidities[0]=low;
498 fTrackRapidities[1]=up;
499 fParams->AddNamedSlot("TrackMinY");
500 fParams->AddNamedSlot("TrackMaxY");
501 fParams->SetSignal(low,"TrackMinY");
502 fParams->SetSignal(up,"TrackMaxY");
503 }
504 if (obs=="eta")
505 {
506 fTrackRapidities[2]=low;
507 fTrackRapidities[3]=up;
508 fParams->AddNamedSlot("TrackMinEta");
509 fParams->AddNamedSlot("TrackMaxEta");
510 fParams->SetSignal(low,"TrackMinEta");
511 fParams->SetSignal(up,"TrackMaxEta");
512 }
513 }
514
515 if (type=="event") // Total event observables
516 {
517 if (obs=="p")
518 {
519 fEventMomenta[0]=low;
520 fEventMomenta[1]=up;
521 fParams->AddNamedSlot("EventMinP");
522 fParams->AddNamedSlot("EventMaxP");
523 fParams->SetSignal(low,"EventMinP");
524 fParams->SetSignal(up,"EventMaxP");
525 }
526 if (obs=="pt")
527 {
528 fEventMomenta[2]=low;
529 fEventMomenta[3]=up;
530 fParams->AddNamedSlot("EventMinPt");
531 fParams->AddNamedSlot("EventMaxPt");
532 fParams->SetSignal(low,"EventMinPt");
533 fParams->SetSignal(up,"EventMaxPt");
534 }
535 if (obs=="pl")
536 {
537 fEventMomenta[4]=low;
538 fEventMomenta[5]=up;
539 fParams->AddNamedSlot("EventMinPl");
540 fParams->AddNamedSlot("EventMaxPl");
541 fParams->SetSignal(low,"EventMinPl");
542 fParams->SetSignal(up,"EventMaxPl");
543 }
544 if (obs=="e")
545 {
546 fEventEnergies[0]=low;
547 fEventEnergies[1]=up;
548 fParams->AddNamedSlot("EventMinE");
549 fParams->AddNamedSlot("EventMaxE");
550 fParams->SetSignal(low,"EventMinE");
551 fParams->SetSignal(up,"EventMaxE");
552 }
553 if (obs=="et")
554 {
555 fEventEnergies[2]=low;
556 fEventEnergies[3]=up;
557 fParams->AddNamedSlot("EventMinEt");
558 fParams->AddNamedSlot("EventMaxEt");
559 fParams->SetSignal(low,"EventMinEt");
560 fParams->SetSignal(up,"EventMaxEt");
561 }
562 if (obs=="el")
563 {
564 fEventEnergies[4]=low;
565 fEventEnergies[5]=up;
566 fParams->AddNamedSlot("EventMinEl");
567 fParams->AddNamedSlot("EventMaxEl");
568 fParams->SetSignal(low,"EventMinEl");
569 fParams->SetSignal(up,"EventMaxEl");
570 }
571 if (obs=="m")
572 {
573 fEventMasses[0]=low;
574 fEventMasses[1]=up;
575 fParams->AddNamedSlot("EventMinM");
576 fParams->AddNamedSlot("EventMaxM");
577 fParams->SetSignal(low,"EventMinM");
578 fParams->SetSignal(up,"EventMaxM");
579 }
580 if (obs=="q")
581 {
582 fEventCharges[0]=low;
583 fEventCharges[1]=up;
584 fParams->AddNamedSlot("EventMinQ");
585 fParams->AddNamedSlot("EventMaxQ");
586 fParams->SetSignal(low,"EventMinQ");
587 fParams->SetSignal(up,"EventMaxQ");
588 }
589 }
590}
591///////////////////////////////////////////////////////////////////////////
592void AliEventSelector::SetRange(TString type,TString obs,TString name,Int_t nlow,Int_t nup)
593{
594// Set range for the specified observable.
595//
596// type : Selection type specifier (e.g. "track" or "event").
597// obs : Observable specification.
598// name : (Class) name of the objects to be searched for
599// nlow : Lower bound of acceptance range
600// nup : Upper bound of acceptance range
601//
602// The various observables that are available for selection criteria are :
603//
604// obs : "ndev" ==> Number of associated devices of the specified (derived) class name
605// "ntrk" ==> Number of tracks with the specified name (name="*" ==> all tracks)
606// "ntkc" ==> Total number of charged tracks (no name selection)
607// "ntk0" ==> Total number of neutral tracks (no name selection)
608// "ntk+" ==> Total number of positive tracks (no name selection)
609// "ntk-" ==> Total number of negative tracks (no name selection)
610//
611// Note : For a certain (type,obs) combination only one (class) name can be specified.
612
613 if (!fParams) fParams=new AliDevice();
614
615 if (type=="track") // Individual track observables
616 {
617 if (obs=="ndev")
618 {
619 fTrackDevices[0]=nlow;
620 fTrackDevices[1]=nup;
621 fTrackDevClass=name;
622 fParams->AddNamedSlot("TrackMinNdev");
623 fParams->AddNamedSlot("TrackMaxNdev");
624 fParams->SetSignal(float(nlow),"TrackMinNdev");
625 fParams->SetSignal(float(nup),"TrackMaxNdev");
626 }
627 }
628
629 if (type=="event") // Total event observables
630 {
631 if (obs=="ndev")
632 {
633 fEventDevices[0]=nlow;
634 fEventDevices[1]=nup;
635 fEventDevClass=name;
636 fParams->AddNamedSlot("EventMinNdev");
637 fParams->AddNamedSlot("EventMaxNdev");
638 fParams->SetSignal(float(nlow),"EventMinNdev");
639 fParams->SetSignal(float(nup),"EventMaxNdev");
640 }
641 if (obs=="ntrk")
642 {
643 fEventTracks[0]=nlow;
644 fEventTracks[1]=nup;
645 fEventTrkName=name;
646 fParams->AddNamedSlot("EventMinNtrk");
647 fParams->AddNamedSlot("EventMaxNtrk");
648 fParams->SetSignal(float(nlow),"EventMinNtrk");
649 fParams->SetSignal(float(nup),"EventMaxNtrk");
650 }
651 if (obs=="ntkc")
652 {
653 fEventTracks[2]=nlow;
654 fEventTracks[3]=nup;
655 fParams->AddNamedSlot("EventMinNtkc");
656 fParams->AddNamedSlot("EventMaxNtkc");
657 fParams->SetSignal(float(nlow),"EventMinNtkc");
658 fParams->SetSignal(float(nup),"EventMaxNtkc");
659 }
660 if (obs=="ntk0")
661 {
662 fEventTracks[4]=nlow;
663 fEventTracks[5]=nup;
664 fParams->AddNamedSlot("EventMinNtk0");
665 fParams->AddNamedSlot("EventMaxNtk0");
666 fParams->SetSignal(float(nlow),"EventMinNtk0");
667 fParams->SetSignal(float(nup),"EventMaxNtk0");
668 }
669 if (obs=="ntk+")
670 {
671 fEventTracks[6]=nlow;
672 fEventTracks[7]=nup;
673 fParams->AddNamedSlot("EventMinNtk+");
674 fParams->AddNamedSlot("EventMaxNtk+");
675 fParams->SetSignal(float(nlow),"EventMinNtk+");
676 fParams->SetSignal(float(nup),"EventMaxNtk+");
677 }
678 if (obs=="ntk-")
679 {
680 fEventTracks[8]=nlow;
681 fEventTracks[9]=nup;
682 fParams->AddNamedSlot("EventMinNtk-");
683 fParams->AddNamedSlot("EventMaxNtk-");
684 fParams->SetSignal(float(nlow),"EventMinNtk-");
685 fParams->SetSignal(float(nup),"EventMaxNtk-");
686 }
687 }
688}
689///////////////////////////////////////////////////////////////////////////
690void AliEventSelector::Exec(Option_t* opt)
691{
692// Implementation of the event selection procedures.
693
694 TString name=opt;
695 AliJob* parent=(AliJob*)(gROOT->GetListOfTasks()->FindObject(name.Data()));
696
697 if (!parent) return;
698
699 fEvt=(AliEvent*)parent->GetObject("AliEvent");
700 if (!fEvt) return;
701
702 Int_t ntkmax=0; // Max. number of tracks for a certain name
703 Int_t nnames=0; // Number of track names to be processed
704 if (fUseNames) nnames=fUseNames->GetEntries();
705 TObjString* strx=0;
706 TString str;
707
708 if (fFirst)
709 {
710 cout << " *AliEventSelector* Selection parameters." << endl;
711 cout << " Selection types in use :";
712 if (fTrackflag) cout << " track";
713 if (fEventflag) cout << " event";
714 if (fAstroflag) cout << " astro";
715 if (!fTrackflag && !fEventflag && !fAstroflag) cout << " none";
716 cout << endl;
717 cout << " Selection logic in use :";
718 if (fLogic==1) cout << " and";
719 if (fLogic==2) cout << " or";
720 if (fLogic==-1) cout << " nand";
721 if (fLogic==-2) cout << " nor";
722 if (!fLogic) cout << " unknown";
723 cout << endl;
724 if (nnames) cout << " Track name selections to be processed (-1=all)." << endl;
725 for (Int_t i=0; i<nnames; i++)
726 {
727 strx=(TObjString*)fUseNames->At(i);
728 if (!strx) continue;
729 str=strx->GetString();
730 ntkmax=fUseNtk->At(i);
731 cout << " Maximally " << ntkmax << " track(s) per event of name : " << str.Data() << endl;
732 }
733 cout << endl;
734
735 fFirst=0;
736 }
737
738 // Storage of the used parameters in the AliEventSelector device
739 if (!fParams) fParams=new AliDevice();
740 fParams->SetNameTitle("AliEventSelector","AliEventSelector processor parameters");
741
742 fSelect=0;
743 if (fLogic)
744 {
745 if (fEventflag) Event(); // Check criteria for total event observables
746 if (fTrackflag) Track(0); // Check criteria for total track observables
747 if (fAstroflag) Astro(); // Check for matches with external objects
748 }
749
750 if (fLogic<0) fSelect*=-1; // In case of "nand"/"nor" logic
751
752 fParams->AddNamedSlot("Logic");
753 fParams->SetSignal(float(fLogic),"Logic");
754 fParams->AddNamedSlot("Eventflag");
755 fParams->SetSignal(float(fEventflag),"Eventflag");
756 fParams->AddNamedSlot("Trackflag");
757 fParams->SetSignal(float(fTrackflag),"Trackflag");
758 fParams->AddNamedSlot("Astroflag");
759 fParams->SetSignal(float(fAstroflag),"Astroflag");
760 fParams->AddNamedSlot("Select");
761 fParams->SetSignal(float(fSelect),"Select");
762
763 AliDevice* dx=(AliDevice*)fEvt->GetDevice("AliEventSelector");
764 if (dx) fEvt->RemoveDevice(dx);
765 fEvt->AddDevice(fParams);
766}
767///////////////////////////////////////////////////////////////////////////
768void AliEventSelector::Track(Int_t mode)
769{
770// Check criteria for individual track observables.
771// This memberfunction serves also the track direction checking
772// for external (astrophysical) objects.
773// mode = 0 : Track observables (e.g. P, Pt etc...) are checked
774// 1 : Track direction is checked w.r.t. external (astrophysical) objects
775
776 if (abs(fLogic)==1) fSelect=-1; // Selections are made in logical "(n)and"
777
778 if (fSelect>0) return; // Event is already flagged as select
779
780 if (!fUseNames) return;
781
782 if (mode==1 && !fAstroDir) return;
783
784 Int_t nnames=fUseNames->GetEntries(); // Number of track names to be processed
785 Int_t ntkmax=0; // Max. number of tracks for a certain name
786 TObjString* strx=0;
787 TString str;
788 Int_t ntk;
789
790 AliTrack* track=0;
791 AliTimestamp* ts=0;
792 Ali3Vector p;
793 TObjArray* tracks=0;
794 Double_t val;
795 Int_t ival;
796 for (Int_t i=0; i<nnames; i++) // Loop over selected track names
797 {
798 strx=(TObjString*)fUseNames->At(i);
799 if (!strx) continue;
800 str=strx->GetString();
801 ntkmax=fUseNtk->At(i);
802 if (str=="*")
803 {
804 tracks=fEvt->GetTracks();
805 }
806 else
807 {
808 tracks=fEvt->GetTracks(str);
809 }
810 ntk=0;
811 if (tracks) ntk=tracks->GetEntries();
812 if (ntkmax>0 && ntk>ntkmax) ntk=ntkmax;
813
814 for (Int_t jtk=0; jtk<ntk; jtk++) // Loop over tracks of a certain name
815 {
816 track=(AliTrack*)tracks->At(jtk);
817 if (!track) continue;
818
819 if (!mode) // Check track observables
820 {
821 if (fTrackMomenta[1]>fTrackMomenta[0]) // Selection on P
822 {
823 if (abs(fLogic)==1) fSelect=-1; // Selections are made in logical "(n)and"
824 val=track->GetMomentum(1);
825 if (val>=fTrackMomenta[0] && val<=fTrackMomenta[1])
826 {
827 fSelect=1;
828 if (abs(fLogic)==2) return; // Selections are made in logical "(n)or"
829 }
830 }
831 if (fTrackMomenta[3]>fTrackMomenta[2]) // Selection on Pt
832 {
833 if (abs(fLogic)==1) fSelect=-1; // Selections are made in logical "(n)and"
834 val=track->GetPt(1);
835 if (val>=fTrackMomenta[2] && val<=fTrackMomenta[3])
836 {
837 fSelect=1;
838 if (abs(fLogic)==2) return; // Selections are made in logical "(n)or"
839 }
840 }
841 if (fTrackMomenta[5]>fTrackMomenta[4]) // Selection on Pl
842 {
843 if (abs(fLogic)==1) fSelect=-1; // Selections are made in logical "(n)and"
844 val=track->GetPl(1);
845 if (val>=fTrackMomenta[4] && val<=fTrackMomenta[5])
846 {
847 fSelect=1;
848 if (abs(fLogic)==2) return; // Selections are made in logical "(n)or"
849 }
850 }
851 if (fTrackEnergies[1]>fTrackEnergies[0]) // Selection on E
852 {
853 if (abs(fLogic)==1) fSelect=-1; // Selections are made in logical "(n)and"
854 val=track->GetEnergy(1);
855 if (val>=fTrackEnergies[0] && val<=fTrackEnergies[1])
856 {
857 fSelect=1;
858 if (abs(fLogic)==2) return; // Selections are made in logical "(n)or"
859 }
860 }
861 if (fTrackEnergies[3]>fTrackEnergies[2]) // Selection on Et
862 {
863 if (abs(fLogic)==1) fSelect=-1; // Selections are made in logical "(n)and"
864 val=track->GetEt(1);
865 if (val>=fTrackEnergies[2] && val<=fTrackEnergies[3])
866 {
867 fSelect=1;
868 if (abs(fLogic)==2) return; // Selections are made in logical "(n)or"
869 }
870 }
871 if (fTrackEnergies[5]>fTrackEnergies[4]) // Selection on El
872 {
873 if (abs(fLogic)==1) fSelect=-1; // Selections are made in logical "(n)and"
874 val=track->GetEl(1);
875 if (val>=fTrackEnergies[4] && val<=fTrackEnergies[5])
876 {
877 fSelect=1;
878 if (abs(fLogic)==2) return; // Selections are made in logical "(n)or"
879 }
880 }
881 if (fTrackMasses[1]>fTrackMasses[0]) // Selection on M
882 {
883 if (abs(fLogic)==1) fSelect=-1; // Selections are made in logical "(n)and"
884 val=track->GetMass(1);
885 if (val>=fTrackMasses[0] && val<=fTrackMasses[1])
886 {
887 fSelect=1;
888 if (abs(fLogic)==2) return; // Selections are made in logical "(n)or"
889 }
890 }
891 if (fTrackCharges[1]>fTrackCharges[0]) // Selection on Q
892 {
893 if (abs(fLogic)==1) fSelect=-1; // Selections are made in logical "(n)and"
894 val=track->GetCharge();
895 if (val>=fTrackCharges[0] && val<=fTrackCharges[1])
896 {
897 fSelect=1;
898 if (abs(fLogic)==2) return; // Selections are made in logical "(n)or"
899 }
900 }
901 if (fTrackRapidities[1]>fTrackRapidities[0]) // Selection on Y
902 {
903 if (abs(fLogic)==1) fSelect=-1; // Selections are made in logical "(n)and"
904 val=track->GetRapidity();
905 if (val>=fTrackRapidities[0] && val<=fTrackRapidities[1])
906 {
907 fSelect=1;
908 if (abs(fLogic)==2) return; // Selections are made in logical "(n)or"
909 }
910 }
911 if (fTrackRapidities[3]>fTrackRapidities[2]) // Selection on Eta
912 {
913 if (abs(fLogic)==1) fSelect=-1; // Selections are made in logical "(n)and"
914 val=track->GetPseudoRapidity();
915 if (val>=fTrackRapidities[2] && val<=fTrackRapidities[3])
916 {
917 fSelect=1;
918 if (abs(fLogic)==2) return; // Selections are made in logical "(n)or"
919 }
920 }
921 if (fTrackDevices[1]>fTrackDevices[0]) // Selection on Ndev
922 {
923 if (abs(fLogic)==1) fSelect=-1; // Selections are made in logical "(n)and"
924 ival=track->GetNsignals(fTrackDevClass.Data());
925 if (ival>=fTrackDevices[0] && ival<=fTrackDevices[1])
926 {
927 fSelect=1;
928 if (abs(fLogic)==2) return; // Selections are made in logical "(n)or"
929 }
930 }
931 }
932 if (mode==1) // Check track direction w.r.t. external (astrophysical) objects
933 {
934 p=track->Get3Momentum();
935 if (fAstroDir<0) p*=-1;
936 ts=track->GetTimestamp();
937 if (!ts) ts=(AliTimestamp*)fEvt;
938
939 SetSignal(&p,"loc","T",ts,0,"Track");
940 TArrayI* arr=MatchRefSignal(fAstroDa,"deg",fAstroDt,"s");
941 if (arr)
942 {
943 fSelect=1;
944 return;
945 }
946 }
947 } // End of loop over tracks of a certain name
948 } // End of loop over selected track names
949}
950///////////////////////////////////////////////////////////////////////////
951void AliEventSelector::Event()
952{
953// Check criteria for total event observables.
954
955 if (abs(fLogic)==1) fSelect=-1; // Selections are made in logical "(n)and"
956
957 if (fSelect>0) return; // Event is already flagged as select
958
959 Double_t val=0;
960 Int_t ival=0;
961 if (fEventMomenta[1]>fEventMomenta[0]) // Selection on P
962 {
963 if (abs(fLogic)==1) fSelect=-1; // Selections are made in logical "(n)and"
964 val=fEvt->GetMomentum(1);
965 if (val>=fEventMomenta[0] && val<=fEventMomenta[1])
966 {
967 fSelect=1;
968 if (abs(fLogic)==2) return; // Selections are made in logical "(n)or"
969 }
970 }
971 if (fEventMomenta[3]>fEventMomenta[2]) // Selection on Pt
972 {
973 if (abs(fLogic)==1) fSelect=-1; // Selections are made in logical "(n)and"
974 val=fEvt->GetPt(1);
975 if (val>=fEventMomenta[2] && val<=fEventMomenta[3])
976 {
977 fSelect=1;
978 if (abs(fLogic)==2) return; // Selections are made in logical "(n)or"
979 }
980 }
981 if (fEventMomenta[5]>fEventMomenta[4]) // Selection on Pl
982 {
983 if (abs(fLogic)==1) fSelect=-1; // Selections are made in logical "(n)and"
984 val=fEvt->GetPl(1);
985 if (val>=fEventMomenta[4] && val<=fEventMomenta[5])
986 {
987 fSelect=1;
988 if (abs(fLogic)==2) return; // Selections are made in logical "(n)or"
989 }
990 }
991 if (fEventEnergies[1]>fEventEnergies[0]) // Selection on E
992 {
993 if (abs(fLogic)==1) fSelect=-1; // Selections are made in logical "(n)and"
994 val=fEvt->GetEnergy(1);
995 if (val>=fEventEnergies[0] && val<=fEventEnergies[1])
996 {
997 fSelect=1;
998 if (abs(fLogic)==2) return; // Selections are made in logical "(n)or"
999 }
1000 }
1001 if (fEventEnergies[3]>fEventEnergies[2]) // Selection on Et
1002 {
1003 if (abs(fLogic)==1) fSelect=-1; // Selections are made in logical "(n)and"
1004 val=fEvt->GetEt(1);
1005 if (val>=fEventEnergies[2] && val<=fEventEnergies[3])
1006 {
1007 fSelect=1;
1008 if (abs(fLogic)==2) return; // Selections are made in logical "(n)or"
1009 }
1010 }
1011 if (fEventEnergies[5]>fEventEnergies[4]) // Selection on El
1012 {
1013 if (abs(fLogic)==1) fSelect=-1; // Selections are made in logical "(n)and"
1014 val=fEvt->GetEl(1);
1015 if (val>=fEventEnergies[4] && val<=fEventEnergies[5])
1016 {
1017 fSelect=1;
1018 if (abs(fLogic)==2) return; // Selections are made in logical "(n)or"
1019 }
1020 }
1021 if (fEventMasses[1]>fEventMasses[0]) // Selection on Minv
1022 {
1023 if (abs(fLogic)==1) fSelect=-1; // Selections are made in logical "(n)and"
1024 val=fEvt->GetInvmass(1);
1025 if (val>=fEventMasses[0] && val<=fEventMasses[1])
1026 {
1027 fSelect=1;
1028 if (abs(fLogic)==2) return; // Selections are made in logical "(n)or"
1029 }
1030 }
1031 if (fEventCharges[1]>fEventCharges[0]) // Selection on Q
1032 {
1033 if (abs(fLogic)==1) fSelect=-1; // Selections are made in logical "(n)and"
1034 val=fEvt->GetCharge();
1035 if (val>=fEventCharges[0] && val<=fEventCharges[1])
1036 {
1037 fSelect=1;
1038 if (abs(fLogic)==2) return; // Selections are made in logical "(n)or"
1039 }
1040 }
1041 if (fEventDevices[1]>fEventDevices[0]) // Selection on Ndev
1042 {
1043 if (abs(fLogic)==1) fSelect=-1; // Selections are made in logical "(n)and"
1044 ival=fEvt->GetNdevices(fEventDevClass.Data());
1045 if (ival>=fEventDevices[0] && ival<=fEventDevices[1])
1046 {
1047 fSelect=1;
1048 if (abs(fLogic)==2) return; // Selections are made in logical "(n)or"
1049 }
1050 }
1051 if (fEventTracks[1]>fEventTracks[0]) // Selection on Ntrk
1052 {
1053 if (abs(fLogic)==1) fSelect=-1; // Selections are made in logical "(n)and"
1054 if (fEventTrkName=="*")
1055 {
1056 ival=fEvt->GetNtracks();
1057 }
1058 else
1059 {
1060 ival=fEvt->GetNtracks(fEventTrkName);
1061 }
1062 if (ival>=fEventTracks[0] && ival<=fEventTracks[1])
1063 {
1064 fSelect=1;
1065 if (abs(fLogic)==2) return; // Selections are made in logical "(n)or"
1066 }
1067 }
1068 if (fEventTracks[3]>fEventTracks[2]) // Selection on Ntkc
1069 {
1070 if (abs(fLogic)==1) fSelect=-1; // Selections are made in logical "(n)and"
1071 ival=fEvt->GetNtracks(0,3,0);
1072 if (ival>=fEventTracks[2] && ival<=fEventTracks[3])
1073 {
1074 fSelect=1;
1075 if (abs(fLogic)==2) return; // Selections are made in logical "(n)or"
1076 }
1077 }
1078 if (fEventTracks[5]>fEventTracks[4]) // Selection on Ntk0
1079 {
1080 if (abs(fLogic)==1) fSelect=-1; // Selections are made in logical "(n)and"
1081 ival=fEvt->GetNtracks(0,0,0);
1082 if (ival>=fEventTracks[4] && ival<=fEventTracks[5])
1083 {
1084 fSelect=1;
1085 if (abs(fLogic)==2) return; // Selections are made in logical "(n)or"
1086 }
1087 }
1088 if (fEventTracks[7]>fEventTracks[6]) // Selection on Ntk+
1089 {
1090 if (abs(fLogic)==1) fSelect=-1; // Selections are made in logical "(n)and"
1091 ival=fEvt->GetNtracks(0,1,0);
1092 if (ival>=fEventTracks[6] && ival<=fEventTracks[7])
1093 {
1094 fSelect=1;
1095 if (abs(fLogic)==2) return; // Selections are made in logical "(n)or"
1096 }
1097 }
1098 if (fEventTracks[9]>fEventTracks[8]) // Selection on Ntk-
1099 {
1100 if (abs(fLogic)==1) fSelect=-1; // Selections are made in logical "(n)and"
1101 ival=fEvt->GetNtracks(0,-1,0);
1102 if (ival>=fEventTracks[8] && ival<=fEventTracks[9])
1103 {
1104 fSelect=1;
1105 if (abs(fLogic)==2) return; // Selections are made in logical "(n)or"
1106 }
1107 }
1108}
1109///////////////////////////////////////////////////////////////////////////
1110void AliEventSelector::Astro()
1111{
1112// Check for matches with external objects.
1113
1114 if (abs(fLogic)==1) fSelect=-1; // Selections are made in logical "(n)and"
1115
1116 if (fSelect>0) return; // Event is already flagged as select
1117
1118 // Check track directions w.r.t. external (astrophysical) objects
1119 if (fAstroflag==1)
1120 {
1121 Track(1);
1122 return;
1123 }
1124
1125 // Check total event momentum direction w.r.t. external (astrophysical) objects
1126 if (fAstroflag==2)
1127 {
1128 Ali3Vector p;
1129 p=fEvt->Get3Momentum();
1130 if (fAstroDir<0) p*=-1;
1131 SetSignal(&p,"loc","T",(AliTimestamp*)fEvt,0,"Event");
1132 TArrayI* arr=MatchRefSignal(fAstroDa,"deg",fAstroDt,"s");
1133 if (arr && fLogic) fSelect=1;
1134 return;
1135 }
1136
1137 // Check event position w.r.t. external (astrophysical) objects
1138 if (fAstroflag==3)
1139 {
1140 SetSignal((Ali3Vector*)fEvt,"loc","T",(AliTimestamp*)fEvt,0,"Event");
1141 TArrayI* arr=MatchRefSignal(fAstroDa,"deg",fAstroDt,"s");
1142 if (arr && fLogic) fSelect=1;
1143 return;
1144 }
1145}
1146///////////////////////////////////////////////////////////////////////////
1147TObject* AliEventSelector::Clone(const char* name) const
1148{
1149// Make a deep copy of the current object and provide the pointer to the copy.
1150// This memberfunction enables automatic creation of new objects of the
1151// correct type depending on the object type, a feature which may be very useful
1152// for containers when adding objects in case the container owns the objects.
1153
1154 AliEventSelector* sel=new AliEventSelector(*this);
1155 if (name)
1156 {
1157 if (strlen(name)) sel->SetName(name);
1158 }
1159 return sel;
1160}
1161///////////////////////////////////////////////////////////////////////////