]> git.uio.no Git - u/mrichter/AliRoot.git/blob - EMCAL/jetfinder/AliEMCALJetFinderAlgoOmni.cxx
correcting HLT build system (bug https://savannah.cern.ch/bugs/?56546)
[u/mrichter/AliRoot.git] / EMCAL / jetfinder / AliEMCALJetFinderAlgoOmni.cxx
1
2 //THIS Also includes summing ALL cells in the jetcone towards the jet energy NOT just those above threshold!!!!!
3
4
5 /**************************************************************************
6  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
7  *                                                                        *
8  * Author: The ALICE Off-line Project.                                    *
9  * Contributors are mentioned in the code where appropriate.              *
10  *                                                                        *
11  * Permission to use, copy, modify and distribute this software and its   *
12  * documentation strictly for non-commercial purposes is hereby granted   *
13  * without fee, provided that the above copyright notice appears in all   *
14  * copies and that both the copyright notice and this permission notice   *
15  * appear in the supporting documentation. The authors make no claims     *
16  * about the suitability of this software for any purpose. It is          *
17  * provided "as is" without express or implied warranty.                  *
18  **************************************************************************/
19
20 /*
21  
22 $Log$
23 Revision 1.2  2006/06/02 23:03:03  pavlinov
24 ALICE numbering scheme
25
26 Revision 1.1  2006/02/28 21:56:34  jklay
27 moving jetfinder code to subdirectory
28
29 Revision 1.16  2006/02/15 15:11:05  pavlinov
30 update of Jenn and Marco
31
32 Revision 1.15  2004/11/22 19:52:05  mhorner
33 Make sure pi0 get through
34
35 Revision 1.14  2004/04/02 17:11:33  mhorner
36 Marco's bug - fixes implemented
37
38 Revision 1.13  2004/03/26 01:00:38  mhorner
39 Implementing Marco's optimisations
40
41 Revision 1.12  2004/03/15 19:59:37  mhorner
42 Pyhtia comparison extended
43
44 Revision 1.11  2004/03/09 17:06:38  mhorner
45 Made more robust
46
47 Revision 1.10  2004/03/06 01:56:09  mhorner
48 Pythai comp code
49
50 Revision 1.9  2004/02/23 20:37:32  mhorner
51 changed geometry call
52
53 Revision 1.8  2004/01/29 23:28:44  mhorner
54 Jet Finder - hard coded geom parameters removed
55
56 Revision 1.7  2004/01/21 22:27:47  mhorner
57 Cleaning up coding conventions
58
59 Revision 1.6  2003/10/28 13:54:30  schutz
60 Compilation warnings fixed
61
62 Revision 1.5  2003/09/23 13:31:41  mhorner
63 Changed coordinate system
64
65 Revision 1.4  2003/09/19 13:16:20  mhorner
66 Added additional jet energy info
67
68
69 Revision 1.3  2003/09/04 12:49:56  mhorner
70 Changed hadron correction and added saving EMCAL and track contributions
71
72 */
73
74
75 //*--Author: Sarah Blyth (LBL)
76 //*--Based on UA1 jet algorithm from LUND JETSET called from EMC-erj
77
78 #include "TTask.h"
79 #include "TMath.h"
80 #include "TParticle.h"
81 #include "AliRun.h"
82 #include "AliRunLoader.h"
83 #include "AliEMCALJetFinderInput.h"
84 #include "AliEMCALJetFinderOutput.h"
85 #include "AliEMCALJetFinderAlgo.h"
86 #include "AliEMCALJetFinderAlgoOmni.h"
87 #include "AliEMCALJetFinderAlgoUA1Unit.h"
88 #include "AliEMCALGeometry.h"
89 #include "AliEMCALLoader.h"
90 #include "AliEMCAL.h"
91 #include "AliEMCALDigit.h"
92 #include "AliEMCALJet.h"
93
94
95 ClassImp(AliEMCALJetFinderAlgoOmni) 
96
97 AliEMCALJetFinderAlgoOmni::AliEMCALJetFinderAlgoOmni() :
98   fUnit(0),fUnitNoCuts(0),fHadCorr(0),fBGType(kRatio),fNumIter(0),
99   fNumUnits(0),fESeed(0.),fConeRad(0.),fJetEMin(0.),fEtMin(0.),
100   fMinMove(0.),fMaxMove(0.),fBGMaxMove(0.),fPtCut(0.),fBGPar(0.),
101   fEBGTotal(0.),fEBGTotalOld(0.),fEBGAve(0.),fEnergy(0.),fJetEta(0.),
102   fJetPhi(0.),fEtaInit(0.),fPhiInit(0.),fEtaB(0.),fPhiB(0.),fJetESum(0.),
103   fJetEtaSum(0.),fJetPhiSum(0.),fDEta(0.),fDPhi(0.),fDistP(0.),fDistI(0.),
104   fTempE(0.),fRad(0.),fNumInCone(0),fNumJets(0),fArrayInitialised(0)
105 {
106  //Default constructor
107 if (fDebug>0) Info("AliEMCALJetFinderAlgoOmni","Beginning Default Constructor");
108   AliEMCALGeometry * geom = AliEMCALGeometry::GetInstance("EMCAL_55_25","EMCAL");
109   fNumIter           = 0;
110   fNumUnits          = geom->GetNTowers();     //Number of towers in EMCAL
111   fESeed             = 5.0;       //Default value
112   fConeRad           = 0.3;       //Default value
113   fJetEMin           = 10.0;      //Default value
114   fEtMin             = 0.0;      //Default value
115   fMinMove           = 0.05;      //From original UA1 JetFinder
116   fMaxMove           = 0.15;      //From original UA1 JetFinder
117   fBGMaxMove         = 0.035;     //From original UA1 JetFinder
118   fPtCut             = 0;         
119   fHadCorr           = 0;       
120   fEBGTotal          = 1.0;       //Set to 1 so that no div by zero in first FindJets() loop
121   fEBGTotalOld       = 0.0;
122   fEBGAve            = 0.0;
123   fEnergy            = 0.0;
124   fJetEta            = 0.0;
125   fJetPhi            = 0.0;
126   fEtaInit           = 0.0;
127   fPhiInit           = 0.0;
128   fEtaB              = 0.0;
129   fPhiB              = 0.0;
130   fJetESum           = 0.0;
131   fJetEtaSum         = 0.0;
132   fJetPhiSum         = 0.0;
133   fDEta              = 0.0;
134   fDPhi              = 0.0;
135   fDistP             = 0.0;
136   fDistI             = 0.0;
137   fTempE             = 0.0;
138   fRad               = 2.0;      //Set to 2 to start 
139   fNumInCone         = 0;
140   fNumJets           = 0;
141   fArrayInitialised  = 0;        //Set to FALSE to start
142   fBGType            = kRatio;   //Set Ratio method as default BG subtraction method 
143   fBGPar             = -1.0;      //Set to 1 to start
144 }
145
146
147 AliEMCALJetFinderAlgoOmni::AliEMCALJetFinderAlgoOmni(const AliEMCALJetFinderAlgoOmni& jfao) 
148   : AliEMCALJetFinderAlgo(jfao),
149     fUnit(jfao.fUnit),fUnitNoCuts(jfao.fUnitNoCuts),fHadCorr(jfao.fHadCorr),
150     fBGType(jfao.fBGType),fNumIter(jfao.fNumIter),fNumUnits(jfao.fNumUnits),
151     fESeed(jfao.fESeed),fConeRad(jfao.fConeRad),fJetEMin(jfao.fJetEMin),
152     fEtMin(jfao.fEtMin), fMinMove(jfao.fMinMove),fMaxMove(jfao.fMaxMove),
153     fBGMaxMove(jfao.fBGMaxMove),fPtCut(jfao.fPtCut),fBGPar(jfao.fBGPar),
154     fEBGTotal(jfao.fEBGTotal),fEBGTotalOld(jfao.fEBGTotalOld),fEBGAve(jfao.fEBGAve),
155     fEnergy(jfao.fEnergy),fJetEta(jfao.fJetEta), fJetPhi(jfao.fJetPhi),fEtaInit(jfao.fEtaInit),
156     fPhiInit(jfao.fPhiInit),fEtaB(jfao.fEtaB),fPhiB(jfao.fPhiB),fJetESum(jfao.fJetESum),
157     fJetEtaSum(jfao.fJetEtaSum),fJetPhiSum(jfao.fJetPhiSum),fDEta(jfao.fDEta),fDPhi(jfao.fDPhi),
158     fDistP(jfao.fDistP),fDistI(jfao.fDistI),fTempE(jfao.fTempE),fRad(jfao.fRad),
159     fNumInCone(jfao.fNumInCone),fNumJets(jfao.fNumJets),fArrayInitialised(jfao.fArrayInitialised)
160 {
161   //copy ctor
162 }
163
164  AliEMCALJetFinderAlgoOmni::~AliEMCALJetFinderAlgoOmni()
165    {
166      //Destructor
167      if (fDebug>0) Info("AliEMCALJetFinderAlgoOmni","Beginning Destructor");
168      delete[] fUnit;
169      delete[] fUnitNoCuts;
170    }
171
172  void AliEMCALJetFinderAlgoOmni::SetJetFindingParameters
173                                (Int_t numUnits, Float_t eSeed, Float_t coneRad, Float_t jetEMin, Float_t etMin, 
174                                Float_t minMove, Float_t maxMove, Float_t bgMaxMove)
175    {
176      //Sets parameters for the JetFinding algorithm
177      if (fDebug>1) Info("SetJetFindingParameters","Setting parameters for JetFinding");
178
179      SetNumUnits(numUnits);
180      SetJetESeed(eSeed);
181      SetConeRad(coneRad);
182      SetJetEMin(jetEMin);
183      SetEtMin(etMin);
184      SetMinMove(minMove);
185      SetMaxMove(maxMove);
186      SetBGMaxMove(bgMaxMove);
187    }
188
189  void AliEMCALJetFinderAlgoOmni::SetJetFindingParameters
190                                (Int_t numUnits, Float_t eSeed, Float_t coneRad, Float_t jetEMin, Float_t etMin)
191    {
192      //Sets fewer parameters for the JetFinding algorithm
193      if (fDebug>1) Info("SetJetFindingParameters","Setting parameters for JetFinding");
194
195      SetNumUnits(numUnits);
196      SetJetESeed(eSeed);
197      SetConeRad(coneRad);
198      SetJetEMin(jetEMin);
199      SetEtMin(etMin);
200      SetMinMove(fMinMove);
201      SetMaxMove(fMaxMove);
202      SetBGMaxMove(fBGMaxMove);
203    }
204
205  void AliEMCALJetFinderAlgoOmni::InitUnitArray()
206    {
207      //Initialises unit arrays
208      if(fArrayInitialised) delete [] fUnit;
209      if(fArrayInitialised) delete [] fUnitNoCuts;
210      fUnit = new AliEMCALJetFinderAlgoUA1Unit[fNumUnits];
211      fUnitNoCuts = new AliEMCALJetFinderAlgoUA1Unit[fNumUnits];
212      fArrayInitialised = 1;
213    }
214
215  void AliEMCALJetFinderAlgoOmni::FillUnitArray(AliEMCALJetFinderAlgoUA1FillUnitFlagType_t flag)
216    {
217            // Fill the unit array 
218      if (fDebug>1) Info("FillUnitArray","Beginning FillUnitArray");
219          //    AliEMCAL* pEMCAL = (AliEMCAL*) gAlice->GetModule("EMCAL");
220          //   if (pEMCAL){ 
221          //          AliEMCALGeometry* geom =  AliEMCALGeometry::GetInstance(pEMCAL->GetTitle(), "");
222          //     }else
223          //    {
224
225      AliEMCALGeometry * geom = AliEMCALGeometry::GetInstance();
226      if (geom == 0)
227       geom = AliEMCALGeometry::GetInstance("EMCAL_55_25","EMCAL");
228
229         //    }
230          
231      AliEMCALJetFinderAlgoUA1FillUnitFlagType_t option = flag;
232      Int_t         numTracks, numDigits;
233     
234      //Loops over all elements in the AliEMCALJetFinderAlgoUA1Unit array and 
235      //fills the objects with relevant values from the Data Input object
236      if (fDebug>10) Info("FillUnitArray","Filling array with Unit objects");
237      if (fDebug>15) Info("FillUnitArray","NTracks %i NDigits %i",fInputPointer->GetNTracks(),fInputPointer->GetNDigits());
238          numTracks = fInputPointer->GetNTracks();
239          numDigits = fInputPointer->GetNDigits();
240          TParticle         *myPart;
241          AliEMCALDigit     *myDigit;
242      if (!fPythiaComparison)
243      {
244          //Fill units with Track info if appropriate
245          if(option==kFillTracksOnly || option ==kFillAll) 
246            {          
247             for(Int_t j=0; j<numTracks; j++)
248             {
249              myPart = fInputPointer->GetTrack(j);
250              Float_t eta = myPart->Eta();
251              //   have to be tune for TRD1; May 31,06 
252              // Float_t  phi = myPart->Phi();
253              // Int_t towerID = geom->TowerIndexFromEtaPhi(eta,180.0/TMath::Pi()*phi);
254              Int_t towerID = 0; 
255
256              Float_t  pT = myPart->Pt();
257              Float_t unitEnergy = fUnit[towerID-1].GetUnitEnergy(); 
258              Float_t unitEnergyNoCuts = fUnitNoCuts[towerID-1].GetUnitEnergy();
259
260              
261              //OLD WAY:   //Do Hadron Correction
262               if(fHadCorr != 0)
263                {
264                  Double_t   fullP = myPart->P();
265                  Double_t   hCEnergy = fHadCorr->GetEnergy(fullP, (Double_t)eta);
266                  unitEnergy -= hCEnergy*TMath::Sin(myPart->Theta());
267                  unitEnergyNoCuts -= hCEnergy*TMath::Sin(myPart->Theta());
268                  fUnit[towerID-1].SetUnitEnergy(unitEnergy);
269                  fUnitNoCuts[towerID-1].SetUnitEnergy(unitEnergyNoCuts);
270                } //end Hadron Correction loop 
271               
272     
273              /*
274               //Do Hadron Correction with propagate phi for the track
275               if(fHadCorr != 0)
276                 {
277                   Bool_t curl = 1;
278                   Float_t deltaPhi;
279                   TParticlePDG *pdg = myPart->GetPDG();
280                   if(pdg->Charge() < 0)
281                     {
282                       deltaPhi = PropagatePhi(myPart->Pt(), -1.0, curl);
283                     }
284                   else{
285                     deltaPhi = PropagatePhi(myPart->Pt(), 1.0, curl);
286                   }
287                   phi += deltaPhi;
288                   //Get new tower id for cell that track would curve into
289                   Int_t towerID2;
290                   if(phi>(TMath::Pi()/180.0)*geom->GetArm1PhiMax() || phi<(TMath::Pi()/180.0)*geom->GetArm1PhiMin())
291                     {
292                       towerID2 = -1;
293                     }
294                   else{
295                       towerID2 = geom->TowerIndexFromEtaPhi(eta,180.0/TMath::Pi()*phi);
296                     }
297                   
298                   if(towerID2 != -1)
299                     {
300                       //Find unit energy of new tower
301                       Float_t unitEnergy2 = fUnit[towerID2-1].GetUnitEnergy();
302                       Float_t unitEnergy2NoCuts = fUnitNoCuts[towerID2-1].GetUnitEnergy();
303                       Double_t   fullP = myPart->P();
304                       Double_t   hCEnergy = fHadCorr->GetEnergy(fullP, (Double_t)eta);
305                       unitEnergy2 -= hCEnergy*TMath::Sin(myPart->Theta());
306                       unitEnergy2NoCuts -= hCEnergy*TMath::Sin(myPart->Theta());
307                       fUnit[towerID2-1].SetUnitEnergy(unitEnergy2);
308                       fUnitNoCuts[towerID2-1].SetUnitEnergy(unitEnergy2NoCuts);
309                     }//end if for towerID2
310                 }//end Hadron Correction loop
311              */
312
313               fUnitNoCuts[towerID-1].SetUnitEnergy(unitEnergyNoCuts + pT);
314              //Do Pt cut on tracks
315              if(fPtCut != 0 && pT < fPtCut) continue;
316
317              fUnit[towerID-1].SetUnitEnergy(unitEnergy+pT);
318
319              }//end tracks loop
320            }//end Tracks condition
321
322
323          //Fill units with Digit info if appropriate
324          if(option ==kFillDigitsOnly || option ==kFillAll)
325            {
326             for(Int_t k=0; k<numDigits; k++)
327             {
328              myDigit = fInputPointer->GetDigit(k);
329              if (fDebug>10) Info("FillUnitArray","getting digits %i %i numdigits",k,numDigits );
330              Int_t towerID = myDigit->GetId();
331              Int_t amplitude = myDigit->GetAmp();     //Gets the integer valued amplitude of the digit
332              Float_t amp = (Float_t)amplitude;        //Need to typecast to Float_t before doing real energy conversion
333              Float_t digitEnergy = amp/10000000.0;    //Factor of 10 million needed to convert!
334              Float_t unitEnergy = fUnit[towerID-1].GetUnitEnergy() + digitEnergy;
335              Float_t unitEnergyNoCuts = fUnitNoCuts[towerID-1].GetUnitEnergy() + digitEnergy;
336              fUnit[towerID-1].SetUnitEnergy(unitEnergy);
337              fUnitNoCuts[towerID-1].SetUnitEnergy(unitEnergyNoCuts);
338             }//end digits loop
339            }//end digits condition
340
341          //Set all unit flags, Eta, Phi
342          for(Int_t i=0; i<fNumUnits; i++)
343            {
344              if (fDebug>10) Info("FillUnitArray","Setting all units outside jets");
345              //Set all units to be outside a jet initially
346              fUnit[i].SetUnitFlag(kOutJet);           
347              fUnit[i].SetUnitID(i+1);
348              Float_t eta;
349              Float_t phi;
350              geom->EtaPhiFromIndex(fUnit[i].GetUnitID(), eta, phi);
351              fUnit[i].SetUnitEta(eta);
352              fUnit[i].SetUnitPhi(phi*TMath::Pi()/180.0);
353              //Set all units to be outside a jet initially
354              fUnitNoCuts[i].SetUnitFlag(kOutJet);          
355              fUnitNoCuts[i].SetUnitID(i+1);
356              eta = 0.0;
357              phi = 0.0;
358              geom->EtaPhiFromIndex(fUnitNoCuts[i].GetUnitID(), eta, phi);
359              fUnitNoCuts[i].SetUnitEta(eta);
360              fUnitNoCuts[i].SetUnitPhi(phi*TMath::Pi()/180.0);
361              //      if(i>13000) cout<<"!!!!!!!!!!!!!!!!!For unit0, eta="<<eta<<" and phi="<<phi*TMath::Pi()/180.0<<" and ID="<<fUnit[i].GetUnitID()<<endl;
362              //  if(fUnit[i].GetUnitEnergy()>0) cout<<"Unit ID "<<fUnit[i].GetUnitID() <<"with eta="<<eta<<" and phi="<<phi*TMath::Pi()/180.0<<" has energy="<<fUnit[i].GetUnitEnergy()<<endl;
363            }//end loop over all units in array (same as all towers in EMCAL)
364
365      }
366      if (fPythiaComparison)
367      {
368              for(Int_t j=0; j<numTracks; j++)                            
369              {
370                      myPart = fInputPointer->GetTrack(j);
371                      fUnit[j].SetUnitID(j);
372                      fUnit[j].SetUnitFlag(kOutJet);
373                      fUnit[j].SetUnitEta(myPart->Eta());
374                      fUnit[j].SetUnitPhi(myPart->Phi());
375                      if (myPart->Energy()*TMath::Sin(myPart->Theta()) > fPtCut || myPart->GetPDG()->Charge() == 0.0  )
376                      {
377                              fUnit[j].SetUnitEnergy(myPart->Energy()*TMath::Sin(myPart->Theta()));
378                      }else
379                      {
380                              fUnit[j].SetUnitEnergy(0.00);
381                      }
382                      fUnitNoCuts[j].SetUnitID(j);
383                      fUnitNoCuts[j].SetUnitFlag(kOutJet);
384                      fUnitNoCuts[j].SetUnitEta(myPart->Eta());
385                      fUnitNoCuts[j].SetUnitPhi(myPart->Phi());
386                      fUnitNoCuts[j].SetUnitEnergy(myPart->Energy()*TMath::Sin(myPart->Theta()));
387              }
388              for(Int_t k=numTracks; k < fNumUnits; k++)
389              {
390                      fUnit[k].SetUnitID(k);
391                      fUnit[k].SetUnitFlag(kBelowMinEt);
392                      fUnit[k].SetUnitEta(0.0);
393                      fUnit[k].SetUnitPhi(0.0);
394                      fUnit[k].SetUnitEnergy(0.0);                    
395                      fUnitNoCuts[k].SetUnitID(k);
396                      fUnitNoCuts[k].SetUnitFlag(kBelowMinEt);
397                      fUnitNoCuts[k].SetUnitEta(0.0);
398                      fUnitNoCuts[k].SetUnitPhi(0.0);
399                      fUnitNoCuts[k].SetUnitEnergy(0.0);                   
400              }
401      }
402
403
404
405    }
406
407
408  void AliEMCALJetFinderAlgoOmni::Sort(AliEMCALJetFinderAlgoUA1Unit *unit, Int_t length)
409  {
410    //Calls the recursive quicksort method to sort unit objects in decending order of Energy
411    if (fDebug>1) Info("Sort","Sorting Unit objects");
412    QS(unit, 0, length-1);
413  }
414   
415
416  void AliEMCALJetFinderAlgoOmni::QS(AliEMCALJetFinderAlgoUA1Unit *unit, Int_t left, Int_t right)
417  {
418   //Sorts the AliEMCALJetFinderAlgoUA1Unit objects in decending order of Energy
419    if (fDebug>111) Info("QS","QuickSorting Unit objects");   
420
421    Int_t    i;
422    Int_t    j;
423    AliEMCALJetFinderAlgoUA1Unit  unitFirst;
424    AliEMCALJetFinderAlgoUA1Unit  unitSecond;
425
426    i = left;
427    j = right;
428    unitFirst = unit[(left+right)/2];
429
430  do
431   {
432     while( (unit[i].GetUnitEnergy() > unitFirst.GetUnitEnergy()) && (i < right)) i++;
433     while( (unitFirst.GetUnitEnergy() > unit[j].GetUnitEnergy()) && (j > left)) j--;
434
435     if(i <= j)
436       {
437         unitSecond = unit[i];
438         unit[i] = unit[j];
439         unit[j] = unitSecond;
440         i++;
441         j--;
442       }//end if
443   }while(i <= j);
444
445  if(left < j) QS(unit, left, j);
446  if(i < right) QS(unit, i, right);
447  }
448
449
450  void AliEMCALJetFinderAlgoOmni::FindBG()
451  {
452    if(fBGType == kRatio) RatioBG();
453    else if(fBGType == kCone) ConeBG();
454    else if(fBGType == kConstant) ConstantBG();
455  }
456
457  void AliEMCALJetFinderAlgoOmni::RatioBG()
458    {
459      //Finds the background energy for the iteration
460      //using the Ratio method
461      if (fDebug>1) Info("FindBG","Finding Average Background"); 
462      //Store BGEperCell from previous iteration!
463      fEBGTotalOld = fEBGTotal;
464      fEBGTotal          = 0.0;
465      Int_t numCone      = 0;
466
467      //If user has not set fBGPar, set it to the default
468      //for TPC = 90% efficiency, PtCut = 2GeV/c, timecut = 30ns
469      if(fBGPar == -1) fBGPar = 0.4685;
470
471      //Loop over all unit objects in the Unit array and link to same
472      //unit ID in NoCuts Unit array
473      for(Int_t i=0; i<fNumUnits; i++)
474        {
475          if(fUnit[i].GetUnitFlag() != kInJet)
476            {
477              Int_t id = fUnit[i].GetUnitID();
478              fEBGTotal += fUnitNoCuts[id-1].GetUnitEnergy();  
479            }
480          else numCone++;
481        }//end for
482
483      fEBGTotal *= fBGPar;
484      fEBGAve = fEBGTotal / (fNumUnits - numCone);
485      if (fDebug>5) Info("FindBG","Average BG is %f: ",fEBGAve); 
486
487      for(Int_t count=0; count<fNumUnits;count++)
488        {
489          fUnit[count].SetUnitFlag(kOutJet);
490        }//end for
491    }
492
493  void AliEMCALJetFinderAlgoOmni::ConeBG()
494    {
495      //Finds the background energy for the iteration
496      //using all energy not contained inside a jet
497      if (fDebug>1) Info("FindBG","Finding Average Background"); 
498      //Store old value of BGEperCell!
499      fEBGTotalOld = fEBGTotal;
500      fEBGTotal          = 0.0;
501      Int_t numCone      = 0;
502
503      //Loop over all unit objects in the array and sum the energy of those not in a jet
504      for(Int_t i=0; i<fNumUnits; i++)
505        {
506          if(fUnit[i].GetUnitFlag() != kInJet)
507            fEBGTotal += fUnit[i].GetUnitEnergy();
508          else numCone++;
509        }//end for
510
511      fEBGAve = fEBGTotal / (fNumUnits - numCone);
512      if (fDebug>5) Info("FindBG","Average BG is %f: ",fEBGAve);      
513
514      for(Int_t count=0; count<fNumUnits;count++)
515        {
516          fUnit[count].SetUnitFlag(kOutJet);
517        }//end for
518    }
519
520  void AliEMCALJetFinderAlgoOmni::ConstantBG()
521    {     
522      //Finds the background energy for the iteration
523      //using all energy not contained inside a jet
524      if (fDebug>1) Info("FindBG","Finding Average Background"); 
525
526      //If user has not set fBGPar, set it to the default
527      //for TPC = 90% efficiency, PtCut = 2GeV/c, timecut = 30ns
528      if(fBGPar == -1) fBGPar = 0.03378;
529
530      fEBGAve = fBGPar;
531      if (fDebug>5) Info("FindBG","Average BG is %f: ",fEBGAve);      
532
533      fEBGTotal          = 0.0;
534      Int_t numCone      = 0;
535      for(Int_t count=0; count<fNumUnits;count++)
536        {
537          if(fUnit[count].GetUnitFlag() == kInJet)
538            {
539              numCone++;
540            }
541          fUnit[count].SetUnitFlag(kOutJet);
542        }//end for
543      fEBGTotal = fEBGAve * (fNumUnits-numCone);
544      fEBGTotalOld = fEBGTotal;
545    }
546
547  void AliEMCALJetFinderAlgoOmni::FindJetEtaPhi(Int_t counter)
548    {
549      //Finds the eta and phi of the jet axis
550      if (fDebug>10) Info("FindJetEtaPhi","Finding Jet Eta and Phi");
551
552      fDEta = fUnit[counter].GetUnitEta() - fEtaInit;
553      fDPhi = fUnit[counter].GetUnitPhi() - fPhiInit;
554
555      fEnergy = fUnit[counter].GetUnitEnergy() - fEBGAve;
556      fJetEtaSum += fEnergy * fDEta;
557      fJetPhiSum += fEnergy * fDPhi;
558      fJetESum += fEnergy;
559      if (fJetESum >1.0e-7)
560      {
561              fJetEta = fEtaInit + (fJetEtaSum / fJetESum);
562              fJetPhi = fPhiInit + (fJetPhiSum / fJetESum);
563      }
564    }
565
566
567  void AliEMCALJetFinderAlgoOmni::FindJetEnergy()
568    {
569      //Finds the energy of the jet after the final axis has been found
570      if (fDebug>1) Info("FindJetEnergy","Finding Jet Energy");
571
572      for(Int_t i=0; i<fNumUnits; i++)
573        {
574          //Loop over all unit objects in the array and find if within cone radius
575          Float_t dEta = fUnit[i].GetUnitEta() - fJetEta;
576          Float_t dPhi = fUnit[i].GetUnitPhi() - fJetPhi;
577          Float_t rad;
578          if ((dEta*dEta) + (dPhi*dPhi)>1.e-7)
579          {
580                  rad = TMath::Sqrt( (dEta*dEta) + (dPhi*dPhi) );
581          }else
582          {
583                  rad=0.0;
584          }
585
586          if(fUnit[i].GetUnitFlag()==kOutJet && rad<= fConeRad)
587            {
588              fUnit[i].SetUnitFlag(kInCurrentJet);
589              Float_t energy = fUnit[i].GetUnitEnergy() - fEBGAve;
590              fJetESum += energy;                             
591              fJetEtaSum += energy * dEta;
592              fJetPhiSum += energy * dPhi;
593              fNumInCone++;                     //Increment the number of cells in the jet cone
594            }//end if
595        }//end for
596    }
597
598
599  void AliEMCALJetFinderAlgoOmni::StoreJetInfo()
600    {
601      //Stores the resulting jet information in appropriate storage structure (TO BE DECIDED!!!!)
602      if (fDebug>1) Info("StoreJetInfo","Storing Jet Information");
603      AliEMCALGeometry * geom = AliEMCALGeometry::GetInstance();
604      if (geom == 0)
605        geom = AliEMCALGeometry::GetInstance("EMCAL_55_25","EMCAL");
606      //Store:
607      //fJetESum is the final jet energy (background has been subtracted)
608      //fJetEta is the final jet Eta
609      //fJetPhi is the final jet Phi
610      //fNumInCone is the final number of cells included in the jet cone
611      //fEtaInit is the eta of the initiator cell
612      //fPhiInit is the phi of the initiator cell
613
614      AliEMCALJet jet(fJetESum,fJetPhi,fJetEta);
615
616       cout<<"For iteration "<<fNumIter <<" and Jet number " <<fNumJets <<endl;
617       cout<<"The jet energy is: " <<fJetESum <<endl;
618       cout<<"The jet eta is ---->" <<fJetEta <<endl;
619       cout<<"The jet phi is ---->" <<fJetPhi <<endl;
620
621      Int_t             numberTracks = fInputPointer->GetNTracks();
622      Int_t             numberDigits = fInputPointer->GetNDigits();
623      AliEMCALDigit     *myD;
624      TParticle         *myP;
625      Int_t             numTracksInCone = 0;
626      Float_t           trackEnergy = 0.0;
627      Float_t           trackEnergyPtCut =0.0; 
628      Float_t           emcalEnergy = 0.0;
629      Float_t           emcalEnergyBGSub = 0.0;
630
631      for(Int_t counter=0; counter<numberTracks; counter++)
632        {
633         myP = fInputPointer->GetTrack(counter);
634         Float_t eta = myP->Eta();
635         Float_t phi = myP->Phi(); 
636         Float_t deta = fJetEta-eta;
637         Float_t dphi = fJetPhi -phi;
638         Float_t rad = TMath::Sqrt( (deta*deta) + (dphi*dphi));
639         if(rad<=fConeRad) numTracksInCone++;
640        }//end for
641
642      Float_t    *pTArray = new Float_t[numTracksInCone];
643      Float_t    *etaArray = new Float_t[numTracksInCone];
644      Float_t    *phiArray = new Float_t[numTracksInCone];
645      Int_t      *pdgArray = new Int_t[numTracksInCone];
646      Int_t             index = 0;
647
648      for(Int_t counter2=0; counter2<numberTracks; counter2++)
649        {
650          myP = fInputPointer->GetTrack(counter2);
651          Float_t eta = myP->Eta();
652          Float_t phi = myP->Phi(); 
653          Float_t deta = fJetEta-eta;
654          Float_t dphi = fJetPhi -phi;
655          Float_t rad ;
656          if ((deta*deta) + (dphi*dphi)>1.e-7)
657          {
658                  rad = TMath::Sqrt( (deta*deta) + (dphi*dphi) );
659          }else
660          {
661                  rad=0.0;
662          }
663
664          if(rad<=fConeRad)
665            {
666              pTArray[index] = myP->Pt();
667              //Calculate track contribution within jetcone
668              trackEnergy += myP->Pt();
669              if(myP->Pt() >= fPtCut) trackEnergyPtCut += myP->Pt();
670              etaArray[index] = eta;
671              phiArray[index] = phi;
672              pdgArray[index] = myP->GetPdgCode();
673              index++;
674              if(fHadCorr != 0)
675              {
676                      Double_t   fullP = myP->P();
677                      Double_t   hCEnergy = fHadCorr->GetEnergy(fullP, (Double_t)eta);
678                      emcalEnergy -= hCEnergy*TMath::Sin(myP->Theta());
679                      emcalEnergyBGSub -= hCEnergy*TMath::Sin(myP->Theta());
680              } //end Hadron Correction loop 
681                            
682            }//end if
683        }//end for
684
685      //Loop over digits to find EMCal contribution within jetcone
686      for(Int_t counter3=0; counter3<numberDigits; counter3++)
687        {
688          myD = fInputPointer->GetDigit(counter3);
689          //GET DIGIT ETA, PHI so that can check if inside R!
690          Float_t eta = 0.0;
691          Float_t phi = 0.0;
692          Int_t iID = myD->GetId();
693          geom->EtaPhiFromIndex(iID, eta, phi);
694          Float_t deta = fJetEta-eta;
695          Float_t dphi = fJetPhi -(TMath::Pi()/180.0)*phi;
696          //Float_t rad = TMath::Sqrt( (deta*deta) + (dphi*dphi));
697          Float_t rad ;
698          if ((deta*deta) + (dphi*dphi)>1.e-7)
699          {
700                  rad = TMath::Sqrt( (deta*deta) + (dphi*dphi) );
701          }else
702          {
703                  rad=0.0;
704          }
705
706          if(rad<=fConeRad)
707            {
708          Int_t amplitude = myD->GetAmp();     //Gets the integer valued amplitude of the digit
709          Float_t amp = (Float_t)amplitude;        //Need to typecast to Float_t before doing real energy conversion
710          Float_t digitEnergy = amp/10000000.0;    //Factor of 10 million needed to convert!
711          emcalEnergy += digitEnergy;
712          emcalEnergyBGSub += (digitEnergy - fEBGAve);
713            }//end if
714        }//end count3 for
715
716      //Save in JET object
717      jet.SetTrackList(numTracksInCone,pTArray, etaArray, phiArray, pdgArray);
718      jet.SetEMCALEnergy(emcalEnergy);
719      jet.SetEMCALEnergyBGSub(emcalEnergyBGSub);
720      jet.SetTrackEnergy(trackEnergy);
721      jet.SetTrackEnergyPtCut(trackEnergyPtCut);
722      fOutputPointer->AddJet(&jet);
723      delete[] pTArray;
724      delete[] etaArray;
725      delete[] phiArray;
726      delete[] pdgArray;
727    }
728
729
730  void AliEMCALJetFinderAlgoOmni::FindJets()
731    {
732      //Runs the complete UA1 JetFinding algorithm to find jets!
733      if (fDebug>1) Info("FindJets","Starting Jet Finding!!!");
734
735      //If the array of JetFinderUnit objects has not been initialised then initialise with default settings
736      if(!fArrayInitialised) 
737       {
738        InitUnitArray();
739        FillUnitArray(kFillAll);
740       }//end if
741      if (fDebug>1) Info("FindJets","Unit array filled");
742
743      //Step 1. Sort the array in descending order of Energy
744      Sort(fUnit,fNumUnits);
745
746      //Step 2. Set the number of iterations and Number of jets found to zero to start
747      fNumIter = 0;
748      fNumJets = 0;
749
750      //Step 3. Begin the iteration loop to find jets
751      //Need to iterate the algorithm while number of iterations<2 OR number of iterations<10 AND 
752      //the value of the average background has changed more than specified amount
753      //Min iterations = 2, Max iterations = 10
754      //while(fNumIter<2 || (fNumIter <10 && ( (fEBGTotal-fEBGTotalOld)/fEBGTotal) > fBGMaxMove) )
755
756      while(fNumIter<2 || (fNumIter <10 && ( fEBGTotal-fEBGTotalOld) > fEBGTotal*fBGMaxMove) )
757        {
758         if (fDebug>1) Info("FindJets","Starting BIG iteration ---> %i",fNumIter);
759
760          //Step 4. Find the value of the average background energy
761          FindBG();
762          fOutputPointer->Reset(kResetJets); //Reset output object to store info for new iteration
763          fNumJets=0;
764
765          //Loop over the array of unit objects and flag those with energy below MinCellEt
766          Int_t numbelow = 0;
767          for(Int_t j=0; j<fNumUnits; j++)
768            {
769              if( (fUnit[j].GetUnitEnergy()-fEBGAve) < fEtMin)
770                 {       
771                   //          fUnit[j].SetUnitFlag(kBelowMinEt);    TAKING OUT kBelow flag
772                   numbelow++;
773                 }//end if
774            }//end for
775          //cout<<"THERE WERE "<<numbelow<<" units with E <EtMin!!!!!!!!!!!!!!!"<<endl;
776
777          //Do quick check if there are no jets upfront
778          // if(fUnit[0].GetUnitFlag() == kBelowMinEt)
779          if( (fUnit[0].GetUnitEnergy()-fEBGAve) < fEtMin)
780            {
781             cout <<"There are no jets for this event!" <<endl;
782             break;
783            }//end if
784
785          //Step 5. Begin with the first jet candidate cell (JET SEED LOOP)
786          if (fDebug>5) Info("FindJets","Beginning JET SEED LOOP");
787          for(Int_t count=0; count<fNumUnits; count++)
788            {
789
790 //CHECK CONDITION HERE _ NOT SURE IF SHOULD MAYBE BE: GetUnitEnergy()-fEBGAve >fESeed?????????????????????????????
791              if(fUnit[count].GetUnitEnergy()>=fESeed && fUnit[count].GetUnitFlag()==kOutJet)
792                {
793                  fEnergy = fUnit[count].GetUnitEnergy() - fEBGAve;
794                  fJetEta = fUnit[count].GetUnitEta();
795                  fJetPhi = fUnit[count].GetUnitPhi();
796                  Int_t seedID = fUnit[count].GetUnitID();
797                  if (fDebug>5) Info("FindJets","Inside first candidate jet seed loop for time : %i", count);
798                  if (fDebug>5) Info("FindJets","Found candidate energy %f ",fEnergy);
799                  if (fDebug>5) Info("FindJets","Found candidate eta %f ", fJetEta);
800                  if (fDebug>5) Info("FindJets","Found candidate phi %f ", fJetPhi);
801                  if (fDebug>5) Info("FindJets","Found candidate ID %i", seedID);
802
803                  fEtaInit = fJetEta;
804                  fPhiInit = fJetPhi;
805                  fEtaB = fJetEta;
806                  fPhiB = fJetPhi;
807                  Int_t testflag = 1;
808                  do
809                    {
810                  fJetESum = 0.0;
811                  fJetEtaSum = 0.0;
812                  fJetPhiSum = 0.0;
813        
814          //Step 6. Find Jet Eta and Phi
815                  //Loop over all units in the array to find the ones in the jet cone and determine contrib to Jet eta, phi
816                      for(Int_t count1=0; count1<fNumUnits; count1++)               
817                        {
818                          if(fUnit[count1].GetUnitID() == seedID && testflag)
819                          {
820                                  testflag=0;
821                                  continue;   //skip unit if the jetseed to avoid doublecounting
822                          }
823                          if(fUnit[count1].GetUnitFlag() == kOutJet)
824                            {
825                              fDEta = fUnit[count1].GetUnitEta() - fJetEta;
826                              fDPhi = fUnit[count1].GetUnitPhi() - fJetPhi;
827                              if ( (fDEta*fDEta) + (fDPhi*fDPhi) >1.e-7)
828                              {
829                                      fRad = TMath::Sqrt( (fDEta*fDEta) + (fDPhi*fDPhi) );
830                              }else
831                              {
832                                      fRad=0.000;
833                              }
834                              if(fRad <= fConeRad)
835                                {
836                                  FindJetEtaPhi(count1); 
837                                }//end if
838                            }//end if
839                        }//end for (Jet Eta, Phi LOOP)
840                              
841                       //Find the distance cone centre moved from previous cone centre
842                       if (fDebug>10) Info("FindJets","Checking if cone move small enough");
843                       if (((fJetEta-fEtaB)*(fJetEta-fEtaB)) + ((fJetPhi-fPhiB)*(fJetPhi-fPhiB))  >1.e-7)
844                       {
845                               fDistP = TMath::Sqrt( ((fJetEta-fEtaB)*(fJetEta-fEtaB)) + ((fJetPhi-fPhiB)*(fJetPhi-fPhiB)) );
846                       }else
847                       {
848                               fDistP = 0.00;
849                       }
850                       //     if(fDistP <= fMinMove) break;
851                              
852
853                       //Find the distance cone centre is from initiator cell
854                       if (fDebug>10) Info("FindJets","Checking if cone move too large");
855                       if ( ((fJetEtaSum)*(fJetEtaSum))+((fJetPhiSum)*(fJetPhiSum)) >1.e-7)
856                       {
857                               fDistI = TMath::Sqrt( ((fJetEtaSum/fJetESum)*(fJetEtaSum/fJetESum)) + ((fJetPhiSum/fJetESum)*
858                                                                                                     (fJetPhiSum/fJetESum)));
859                       }else
860                       {
861                               fDistI = 0.00;
862                       }
863
864                       if(fDistP>fMinMove && fDistI<fMaxMove)
865                         {
866                           fEtaB = fJetEta;
867                           fPhiB = fJetPhi;
868                         }//end if
869                  
870                    }while(fDistP>fMinMove && fDistI<fMaxMove);
871                           
872                  fJetEta = fEtaB;
873                  fJetPhi = fPhiB;
874
875
876        //Step 7. Find the Jet Energy
877                  if (fDebug>1) Info("FindJets","Looking for Jet energy");
878                  fJetESum = 0.0;
879                  fJetEtaSum = 0.0;
880                  fJetPhiSum = 0.0;
881                  fNumInCone = 0;
882                  FindJetEnergy();
883
884                  //cout<<"Number of cells in jet cone is: "<<fNumInCone<<endl;
885
886        //Step 8. Check if the jet is a valid jet
887                  //Check if cluster energy is above Min allowed to be a jet
888 //DID NOT DO THE COSH COMPARISON HERE -> NEED TO CHECK WHICH COMPARISON IS BEST!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
889                  if (fDebug>5) Info("FindJets","Checking cluster is valid jet");
890                  if(fJetESum < fJetEMin)
891                    {
892                      for(Int_t count2=0; count2<fNumUnits; count2++)
893                        {
894                          if(fUnit[count2].GetUnitFlag()==kInCurrentJet || fUnit[count2].GetUnitFlag()==kOutJet)
895                            fUnit[count2].SetUnitFlag(kOutJet);
896                        }//end for
897                    if (fDebug>10) Info("FindJets","NOT a valid jet cell");
898                   }else
899                     {
900                      for(Int_t count2=0; count2<fNumUnits; count2++)
901                        {
902                          if(fUnit[count2].GetUnitFlag()==kInCurrentJet)
903                            {
904                              //      cout<<"Setting unit #"<<count2 <<" to be officially in a jet!"<<endl;
905                            fUnit[count2].SetUnitFlag(kInJet);
906                            }
907                        }//end for                       
908
909  //NEED TO CHECK FINAL WEIRD ITERATION OF ETA AND PHI CHANGES!!!!!!!!!
910                      //  fJetPhi += fJetPhiSum/fJetESum;        //CHECK!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
911                      //  fJetEta += fJetEtaSum/fJetESum;        //CHECK!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
912
913                      fNumJets++;              //Incrementing number of jets found
914                      StoreJetInfo();          //Storing jet info
915
916                  }//end if (check cluster above Min Jet Energy)
917                }//end if (Jet Seed condition)
918            }//end (JET SEED LOOP)
919
920 if (fDebug>5) Info("FindJets","End of BIG iteration number %i",fNumIter);
921 // this->Dump();
922          fNumIter++;
923        }//end 10 iteration WHILE LOOP
924  }
925
926
927
928
929
930
931
932
933
934
935