Removing warnings
[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 <cstdlib>
131 #include "AliEventSelector.h"
132 #include "Riostream.h"
133
134 ClassImp(AliEventSelector) // Class implementation to enable ROOT I/O
135
136 AliEventSelector::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 ///////////////////////////////////////////////////////////////////////////
195 AliEventSelector::~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 ///////////////////////////////////////////////////////////////////////////
217 AliEventSelector::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 ///////////////////////////////////////////////////////////////////////////
262 void 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 ///////////////////////////////////////////////////////////////////////////
296 void 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 ///////////////////////////////////////////////////////////////////////////
313 void 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 ///////////////////////////////////////////////////////////////////////////
368 void 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 ///////////////////////////////////////////////////////////////////////////
393 void 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 ///////////////////////////////////////////////////////////////////////////
592 void 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 ///////////////////////////////////////////////////////////////////////////
690 void 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 ///////////////////////////////////////////////////////////////////////////
768 void 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 ///////////////////////////////////////////////////////////////////////////
951 void 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 ///////////////////////////////////////////////////////////////////////////
1110 void 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 ///////////////////////////////////////////////////////////////////////////
1147 TObject* 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 ///////////////////////////////////////////////////////////////////////////