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