]> git.uio.no Git - u/mrichter/AliRoot.git/blob - JETAN/AliUA1JetFinderV1.cxx
Do not allocate fixed size arrays via new
[u/mrichter/AliRoot.git] / JETAN / AliUA1JetFinderV1.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 // UA1 Cone Algorithm Jet finder
20 // manages the search for jets
21 // Author: Rafael.Diaz.Valdes@cern.ch
22 // (version in c++)
23 //---------------------------------------------------------------------
24
25 #include <TArrayF.h>
26 #include <TClonesArray.h>
27 #include <TFile.h>
28 #include <TH1F.h>
29 #include <TH2F.h>
30 #include <TLorentzVector.h>
31
32 #include "AliUA1JetFinderV1.h"
33 #include "AliUA1JetHeaderV1.h"
34 #include "AliJetReaderHeader.h"
35 #include "AliJetReader.h"
36 #include "AliJetHeader.h"
37
38
39 #include "AliAODJet.h"
40 #include "AliLog.h"
41
42
43 ClassImp(AliUA1JetFinderV1)
44
45 /////////////////////////////////////////////////////////////////////
46
47 AliUA1JetFinderV1::AliUA1JetFinderV1() :
48     AliJetFinder(),
49     fLego(0)
50 {
51   // Constructor
52 }
53
54 ////////////////////////////////////////////////////////////////////////
55
56 AliUA1JetFinderV1::~AliUA1JetFinderV1()
57
58 {
59   // destructor
60   delete fLego;
61   fLego = 0;
62 }
63
64 ////////////////////////////////////////////////////////////////////////
65
66
67 void AliUA1JetFinderV1::FindJets()
68
69 {
70   //1) Fill cell map array
71   //2) calculate total energy and fluctuation level
72   //3) Run algorithm
73   //   3.1) look centroides in cell map
74   //   3.2) calculate total energy in cones
75   //   3.3) flag as a possible jet
76   //   3.4) reorder cones by energy
77   //4) subtract backg in accepted jets
78   //5) fill AliJet list
79
80   // transform input to pt,eta,phi plus lego
81     
82   AliUA1JetHeaderV1* header = (AliUA1JetHeaderV1*) fHeader;
83   TClonesArray *lvArray = fReader->GetMomentumArray();
84   Int_t nIn =  lvArray->GetEntries();
85   if (nIn == 0) return;
86
87   // local arrays for input
88   Float_t* ptT   = new Float_t[nIn];
89   Float_t* etaT  = new Float_t[nIn];
90   Float_t* phiT  = new Float_t[nIn];
91   Int_t*   injet = new Int_t[nIn];
92
93   //total energy in array
94   Float_t  etbgTotal = 0.0;
95   TH1F* hPtTotal = new TH1F("hPt","Pt distribution of all particles ",100,0.0,15.0);
96
97   // load input vectors and calculate total energy in array
98   for (Int_t i = 0; i < nIn; i++){
99     TLorentzVector *lv = (TLorentzVector*) lvArray->At(i);
100     ptT[i]  = lv->Pt();
101     etaT[i] = lv->Eta();
102     phiT[i] = ((lv->Phi() < 0) ? (lv->Phi()) + 2 * TMath::Pi() : lv->Phi());
103     if (fReader->GetCutFlag(i) != 1) continue;
104     fLego ->Fill(etaT[i], phiT[i], ptT[i]);
105     hPtTotal->Fill(ptT[i]);
106     etbgTotal+= ptT[i];
107   }
108
109   // calculate total energy and fluctuation in map
110   Double_t meanpt = hPtTotal->GetMean();
111   Double_t ptRMS  = hPtTotal->GetRMS();
112   Double_t npart  = hPtTotal->GetEntries();
113   Double_t dEtTotal = (TMath::Sqrt(npart))*TMath::Sqrt(meanpt * meanpt + ptRMS*ptRMS);
114
115   // arrays to hold jets
116   const int kMaxJets = 30;
117   Float_t etaJet[kMaxJets];
118   Float_t phiJet[kMaxJets];
119   Float_t etJet[kMaxJets];
120   Float_t etsigJet[kMaxJets]; //signal et in jet
121   Float_t etallJet[kMaxJets];  // total et in jet (tmp variable)
122   Int_t ncellsJet[kMaxJets];
123   Int_t multJet[kMaxJets];
124   Int_t nJets; // to hold number of jets found by algorithm
125   Int_t nj;    // number of jets accepted
126   Float_t prec  = header->GetPrecBg();
127   Float_t bgprec = 1;
128   while(bgprec > prec){
129      //reset jet arrays in memory
130      memset(etaJet,0,sizeof(Float_t)*kMaxJets);
131      memset(phiJet,0,sizeof(Float_t)*kMaxJets);
132      memset(etJet,0,sizeof(Float_t)*kMaxJets);
133      memset(etallJet,0,sizeof(Float_t)*kMaxJets);
134      memset(etsigJet,0,sizeof(Float_t)*kMaxJets);
135      memset(ncellsJet,0,sizeof(Int_t)*kMaxJets);
136      memset(multJet,0,sizeof(Int_t)*kMaxJets);
137      nJets = 0;
138      nj = 0;
139      // reset particles-jet array in memory
140      memset(injet,-1,sizeof(Int_t)*nIn);
141      //run cone algorithm finder
142      RunAlgoritm(etbgTotal,dEtTotal,nJets,etJet,etaJet,phiJet,etallJet,ncellsJet);
143      //run background subtraction
144      if(nJets > header->GetNAcceptJets()) // limited number of accepted jets per event
145        nj = header->GetNAcceptJets();
146      else
147        nj = nJets;
148      //subtract background
149      Float_t etbgTotalN = 0.0; //new background
150      if(header->GetBackgMode() == 1) // standar
151         SubtractBackg(nIn,nj,etbgTotalN,ptT,etaT,phiT,etJet,etaJet,phiJet,etsigJet,multJet,injet);
152      if(header->GetBackgMode() == 2) //cone
153         SubtractBackgCone(nIn,nj,etbgTotalN,ptT,etaT,phiT,etJet,etaJet,phiJet,etsigJet,multJet,injet);
154      if(header->GetBackgMode() == 3) //ratio
155         SubtractBackgRatio(nIn,nj,etbgTotalN,ptT,etaT,phiT,etJet,etaJet,phiJet,etsigJet,multJet,injet);
156      if(header->GetBackgMode() == 4) //statistic
157         SubtractBackgStat(nIn,nj,etbgTotalN,ptT,etaT,phiT,etJet,etaJet,phiJet,etsigJet,multJet,injet);
158      //calc precision
159      if(etbgTotalN != 0.0)
160         bgprec = (etbgTotal - etbgTotalN)/etbgTotalN;
161      else
162         bgprec = 0;
163      etbgTotal = etbgTotalN; // update with new background estimation
164   } //end while
165
166   // add tracks to the jet if it wasn't yet done                                                         
167   if (header->GetBackgMode() == 0){
168     Float_t rc= header->GetRadius();
169     for(Int_t jpart = 0; jpart < nIn; jpart++){ // loop for all particles in array                     
170       for(Int_t ijet=0; ijet<nj; ijet++){
171         Float_t deta = etaT[jpart] - etaJet[ijet];
172         Float_t dphi = phiT[jpart] - phiJet[ijet];
173         if (dphi < -TMath::Pi()) dphi= -dphi - 2.0 * TMath::Pi();
174         if (dphi >  TMath::Pi()) dphi = 2.0 * TMath::Pi() - dphi;
175         Float_t dr = TMath::Sqrt(deta * deta + dphi * dphi);
176         if(dr <= rc){ // particles inside this cone                                                    
177           injet[jpart] = ijet;
178           break;
179         }
180       }// end jets loop                                                                                
181     } //end particle loop                                                                              
182   }
183   
184   // add jets to list
185   Int_t* idxjets = new Int_t[nj];
186   Int_t nselectj = 0;
187 //  printf("Found %d jets \n", nj);
188   
189   TRefArray *refs = 0;
190   Bool_t fromAod = !strcmp(fReader->ClassName(),"AliJetAODReader");
191   if (fromAod) refs = fReader->GetReferences();
192   for(Int_t kj=0; kj<nj; kj++){
193      if ((etaJet[kj] > (header->GetJetEtaMax())) ||
194           (etaJet[kj] < (header->GetJetEtaMin())) ||
195           (etJet[kj] < header->GetMinJetEt())) continue; // acceptance eta range and etmin
196       Float_t px, py,pz,en; // convert to 4-vector
197       px = etJet[kj] * TMath::Cos(phiJet[kj]);
198       py = etJet[kj] * TMath::Sin(phiJet[kj]);
199       pz = etJet[kj] / TMath::Tan(2.0 * TMath::ATan(TMath::Exp(-etaJet[kj])));
200       en = TMath::Sqrt(px * px + py * py + pz * pz);
201       
202       AliAODJet jet(px, py, pz, en);
203
204       if (fromAod){
205         for(Int_t jpart = 0; jpart < nIn; jpart++) // loop for all particles in array
206           if (injet[jpart] == kj && fReader->GetCutFlag(jpart) == 1)
207                     jet.AddTrack(refs->At(jpart));  // check if the particle belongs to the jet and add the ref
208       }
209       
210       //jet.Print("");
211       
212       AddJet(jet);
213       
214       idxjets[nselectj] = kj;
215       nselectj++;
216   } //end particle loop
217
218   //add signal percentage and total signal  in AliJets for analysis tool
219   Float_t* percentage  = new Float_t[nselectj];
220   Int_t* ncells      = new Int_t[nselectj];
221   Int_t* mult        = new Int_t[nselectj];
222   for(Int_t i = 0; i< nselectj; i++){
223      percentage[i] = etsigJet[idxjets[i]]/etJet[idxjets[i]];
224      ncells[i] = ncellsJet[idxjets[i]];
225      mult[i] = multJet[idxjets[i]];
226   }
227    //add particle-injet relationship ///
228    for(Int_t bj = 0; bj < nIn; bj++){
229        if(injet[bj] == -1) continue; //background particle
230        Int_t bflag = 0;
231        for(Int_t ci = 0; ci< nselectj; ci++){
232            if(injet[bj] == idxjets[ci]){
233               injet[bj]= ci;
234               bflag++;
235               break;
236            }
237        }
238        if(bflag == 0) injet[bj] = -1; // set as background particle
239    }
240
241   //delete
242   delete [] ptT;
243   delete [] etaT;
244   delete [] phiT;
245   delete [] injet;
246   delete hPtTotal;
247   delete [] idxjets;
248   delete [] percentage;
249   delete [] ncells;
250   delete [] mult;
251 }
252
253 ////////////////////////////////////////////////////////////////////////
254
255 void AliUA1JetFinderV1::RunAlgoritm(Float_t etbgTotal, Double_t dEtTotal, Int_t& nJets,
256                                   Float_t* etJet,Float_t* etaJet, Float_t* phiJet,
257                                   Float_t* etallJet, Int_t* ncellsJet)
258 {
259
260    //dump lego
261   AliUA1JetHeaderV1* header = (AliUA1JetHeaderV1*) fHeader;
262   const Int_t nBinsMax = 120000; // we use a fixed array not to fragment memory
263   
264   const Int_t nBinEta = header->GetLegoNbinEta();
265   const Int_t nBinPhi = header->GetLegoNbinPhi();
266   if((nBinPhi*nBinEta)>nBinsMax){
267     AliError("Too many bins of the ETA-PHI histogram");
268   }
269
270   Float_t etCell[nBinsMax];   //! Cell Energy
271   Float_t etaCell[nBinsMax];  //! Cell eta
272   Float_t phiCell[nBinsMax];  //! Cell phi
273   Short_t   flagCell[nBinsMax]; //! Cell flag
274
275   Int_t nCell = 0;
276   TAxis* xaxis = fLego->GetXaxis();
277   TAxis* yaxis = fLego->GetYaxis();
278   Float_t e = 0.0;
279   for (Int_t i = 1; i <= nBinEta; i++) {
280       for (Int_t j = 1; j <= nBinPhi; j++) {
281                e = fLego->GetBinContent(i,j);
282                if (e < 0.0) continue; // don't include this cells
283                Float_t eta  = xaxis->GetBinCenter(i);
284                Float_t phi  = yaxis->GetBinCenter(j);
285                etCell[nCell]  = e;
286                etaCell[nCell] = eta;
287                phiCell[nCell] = phi;
288                flagCell[nCell] = 0; //default
289                nCell++;
290       }
291   }
292
293   // Parameters from header
294   Float_t minmove = header->GetMinMove();
295   Float_t maxmove = header->GetMaxMove();
296   Float_t rc      = header->GetRadius();
297   Float_t etseed  = header->GetEtSeed();
298   //Float_t etmin   = header->GetMinJetEt();
299
300
301
302   // tmp array of jets form algoritm
303   Float_t etaAlgoJet[30];
304   Float_t phiAlgoJet[30];
305   Float_t etAlgoJet[30];
306   Int_t   ncellsAlgoJet[30];
307
308   //run algorithm//
309
310   // sort cells by et
311   Int_t * index  = new Int_t[nCell];
312   TMath::Sort(nCell, etCell, index);
313   // variable used in centroide loop
314   Float_t eta   = 0.0;
315   Float_t phi   = 0.0;
316   Float_t eta0  = 0.0;
317   Float_t phi0  = 0.0;
318   Float_t etab  = 0.0;
319   Float_t phib  = 0.0;
320   Float_t etas  = 0.0;
321   Float_t phis  = 0.0;
322   Float_t ets   = 0.0;
323   Float_t deta  = 0.0;
324   Float_t dphi  = 0.0;
325   Float_t dr    = 0.0;
326   Float_t etsb  = 0.0;
327   Float_t etasb = 0.0;
328   Float_t phisb = 0.0;
329   Float_t dphib = 0.0;
330   
331
332   for(Int_t icell = 0; icell < nCell; icell++){
333         Int_t jcell = index[icell];
334         if(etCell[jcell] <= etseed) continue; // if cell energy is low et seed
335         if(flagCell[jcell] != 0) continue; // if cell was used before
336         eta  = etaCell[jcell];
337         phi  = phiCell[jcell];
338         eta0 = eta;
339         phi0 = phi;
340         etab = eta;
341         phib = phi;
342         ets  = etCell[jcell];
343         etas = 0.0;
344         phis = 0.0;
345         etsb = ets;
346         etasb = 0.0;
347         phisb = 0.0;
348         for(Int_t kcell =0; kcell < nCell; kcell++){
349             Int_t lcell = index[kcell];
350             if(lcell == jcell)                 continue; // cell itself
351             if(flagCell[lcell] != 0)           continue; // cell used before
352             if(etCell[lcell] > etCell[jcell])  continue; // can this happen
353             //calculate dr
354             deta = etaCell[lcell] - eta;
355             dphi = TMath::Abs(phiCell[lcell] - phi);
356             if (dphi > TMath::Pi()) dphi = 2. * TMath::Pi() - dphi;
357             dr = TMath::Sqrt(deta * deta + dphi * dphi);
358             if(dr <= rc){
359                // calculate offset from initiate cell
360                deta = etaCell[lcell] - eta0;
361                dphi = phiCell[lcell] - phi0;
362                if (dphi < - TMath::Pi()) dphi=  dphi + 2.0 * TMath::Pi();
363                if (dphi >   TMath::Pi()) dphi = dphi - 2.0 * TMath::Pi();
364                
365                etas = etas + etCell[lcell]*deta;
366                phis = phis + etCell[lcell]*dphi;
367                ets = ets + etCell[lcell];
368                //new weighted eta and phi including this cell
369                eta = eta0 + etas/ets;
370                phi = phi0 + phis/ets;
371                // if cone does not move much, just go to next step
372                dphib = TMath::Abs(phi - phib);
373                if (dphib > TMath::Pi()) dphib = 2. * TMath::Pi() - dphib;
374                dr = TMath::Sqrt((eta-etab)*(eta-etab) + dphib * dphib);
375                if(dr <= minmove) break;
376                // cone should not move more than max_mov
377                dr = TMath::Sqrt((etas/ets)*(etas/ets) + (phis/ets)*(phis/ets));
378                if(dr > maxmove){
379                    eta = etab;
380                    phi = phib;
381                    ets = etsb;
382                    etas = etasb;
383                    phis = phisb;
384                } else { // store this loop information
385                    etab  = eta;
386                    phib  = phi;
387                    etsb  = ets;
388                    etasb = etas;
389                    phisb = phis;
390                }
391             } // inside cone
392         }//end of cells loop looking centroide
393
394         //avoid cones overloap (to be implemented in the future)
395
396         //flag cells in Rc, estimate total energy in cone
397         Float_t etCone = 0.0;
398         Int_t   nCellIn = 0;
399         rc = header->GetRadius();
400         for(Int_t ncell =0; ncell < nCell; ncell++){
401             if(flagCell[ncell] != 0) continue; // cell used before
402            //calculate dr
403             deta = etaCell[ncell] - eta;
404                  dphi = phiCell[ncell] - phi;
405                  if (dphi < -TMath::Pi()) dphi= -dphi - 2.0 * TMath::Pi();
406                  if (dphi > TMath::Pi()) dphi = 2.0 * TMath::Pi() - dphi;
407                  dr = TMath::Sqrt(deta * deta + dphi * dphi);
408             if(dr <= rc){  // cell in cone
409                flagCell[ncell] = -1;
410                etCone+=etCell[ncell];
411                nCellIn++;
412             }
413         }
414
415         // select jets with et > background
416         // estimate max fluctuation of background in cone
417         Double_t ncellin = (Double_t)nCellIn;
418         Double_t ntcell  = (Double_t)nCell;
419         Double_t etbmax = (etbgTotal + dEtTotal )*(ncellin/ntcell);
420         // min cone et
421         Double_t etcmin = etCone ;  // could be used etCone - etmin !!
422         //desicions !! etbmax < etcmin
423         for(Int_t mcell =0; mcell < nCell; mcell++){
424             if(flagCell[mcell] == -1){
425               if(etbmax < etcmin)
426                  flagCell[mcell] = 1; //flag cell as used
427               else
428                  flagCell[mcell] = 0; // leave it free
429             }
430         }
431         //store tmp jet info !!!
432        if(etbmax < etcmin) {
433              etaAlgoJet[nJets] = eta;
434              phiAlgoJet[nJets] = phi;
435              etAlgoJet[nJets] = etCone;
436              ncellsAlgoJet[nJets] = nCellIn;
437              nJets++;
438         }
439
440   } // end of cells loop
441
442   //reorder jets by et in cone
443   //sort jets by energy
444   Int_t * idx  = new Int_t[nJets];
445   TMath::Sort(nJets, etAlgoJet, idx);
446   for(Int_t p = 0; p < nJets; p++){
447      etaJet[p] = etaAlgoJet[idx[p]];
448      phiJet[p] = phiAlgoJet[idx[p]];
449      etJet[p] = etAlgoJet[idx[p]];
450      etallJet[p] = etAlgoJet[idx[p]];
451      ncellsJet[p] = ncellsAlgoJet[idx[p]];
452   }
453
454
455   //delete
456   delete[] index;
457   delete[] idx;
458
459 }
460 ////////////////////////////////////////////////////////////////////////
461
462 void AliUA1JetFinderV1::SubtractBackg(const Int_t& nIn, const Int_t&nJ, Float_t&etbgTotalN,
463                                       const Float_t* ptT, const Float_t* etaT, const Float_t* phiT,
464                                       Float_t* etJet, const Float_t* etaJet, const Float_t* phiJet, Float_t* etsigJet,
465                                       Int_t* multJet, Int_t* injet)
466 {
467   //background subtraction using cone method but without correction in dE/deta distribution
468
469   //calculate energy inside and outside cones
470   AliUA1JetHeaderV1* header = (AliUA1JetHeaderV1*) fHeader;
471   Float_t rc= header->GetRadius();
472   Float_t etIn[30];
473   Float_t etOut = 0;
474   for(Int_t jpart = 0; jpart < nIn; jpart++){ // loop for all particles in array
475      // if((fReader->GetCutFlag(jpart)) != 1) continue; // pt cut
476      for(Int_t ijet=0; ijet<nJ; ijet++){
477          Float_t deta = etaT[jpart] - etaJet[ijet];
478               Float_t dphi = phiT[jpart] - phiJet[ijet];
479          if (dphi < -TMath::Pi()) dphi= -dphi - 2.0 * TMath::Pi();
480               if (dphi > TMath::Pi()) dphi = 2.0 * TMath::Pi() - dphi;
481               Float_t dr = TMath::Sqrt(deta * deta + dphi * dphi);
482          if(dr <= rc){ // particles inside this cone
483              multJet[ijet]++;
484              injet[jpart] = ijet;
485              if((fReader->GetCutFlag(jpart)) == 1){ // pt cut
486                 etIn[ijet] += ptT[jpart];
487                 if(fReader->GetSignalFlag(jpart) == 1) etsigJet[ijet]+= ptT[jpart];
488              }
489              break;
490          }
491      }// end jets loop
492      if(injet[jpart] == -1 && fReader->GetCutFlag(jpart) == 1)
493         etOut += ptT[jpart]; // particle outside cones and pt cut
494   } //end particle loop
495
496   //estimate jets and background areas
497   Float_t areaJet[30];
498   Float_t areaOut = 4*(header->GetLegoEtaMax())*TMath::Pi();
499   for(Int_t k=0; k<nJ; k++){
500       Float_t detamax = etaJet[k] + rc;
501       Float_t detamin = etaJet[k] - rc;
502       Float_t accmax = 0.0; Float_t accmin = 0.0;
503       if(detamax > header->GetLegoEtaMax()){ // sector outside etamax
504          Float_t h = header->GetLegoEtaMax() - etaJet[k];
505          accmax = rc*rc*TMath::ACos(h/rc) - h*TMath::Sqrt(rc*rc - h*h);
506       }
507       if(detamin < header->GetLegoEtaMin()){ // sector outside etamin
508          Float_t h = header->GetLegoEtaMax() + etaJet[k];
509          accmin = rc*rc*TMath::ACos(h/rc) - h*TMath::Sqrt(rc*rc - h*h);
510       }
511       areaJet[k] = rc*rc*TMath::Pi() - accmax - accmin;
512       areaOut = areaOut - areaJet[k];
513   }
514   //subtract background using area method
515   for(Int_t ljet=0; ljet<nJ; ljet++){
516      Float_t areaRatio = areaJet[ljet]/areaOut;
517      etJet[ljet] = etIn[ljet]-etOut*areaRatio; // subtraction
518   }
519
520   // estimate new total background
521   Float_t areaT = 4*(header->GetLegoEtaMax())*TMath::Pi();
522   etbgTotalN = etOut*areaT/areaOut;
523
524
525 }
526
527 ////////////////////////////////////////////////////////////////////////
528
529 void AliUA1JetFinderV1::SubtractBackgStat(const Int_t& nIn, const Int_t&nJ,Float_t&etbgTotalN,
530                                           const Float_t* ptT, const Float_t* etaT, const Float_t* phiT,
531                                           Float_t* etJet, const Float_t* etaJet, const Float_t* phiJet, Float_t* etsigJet,
532                                           Int_t* multJet, Int_t* injet)
533 {
534
535   //background subtraction using statistical method
536   AliUA1JetHeaderV1* header = (AliUA1JetHeaderV1*) fHeader;
537   Float_t etbgStat = header->GetBackgStat(); // pre-calculated background
538
539   //calculate energy inside
540   Float_t rc= header->GetRadius();
541   Float_t etIn[30];
542
543   for(Int_t jpart = 0; jpart < nIn; jpart++){ // loop for all particles in array
544      //if((fReader->GetCutFlag(jpart)) != 1) continue; // pt cut
545      for(Int_t ijet=0; ijet<nJ; ijet++){
546          Float_t deta = etaT[jpart] - etaJet[ijet];
547               Float_t dphi = phiT[jpart] - phiJet[ijet];
548          if (dphi < -TMath::Pi()) dphi= -dphi - 2.0 * TMath::Pi();
549               if (dphi > TMath::Pi()) dphi = 2.0 * TMath::Pi() - dphi;
550               Float_t dr = TMath::Sqrt(deta * deta + dphi * dphi);
551          if(dr <= rc){ // particles inside this cone
552              multJet[ijet]++;
553              injet[jpart] = ijet;
554              if((fReader->GetCutFlag(jpart)) == 1){ // pt cut
555                 etIn[ijet]+= ptT[jpart];
556                 if(fReader->GetSignalFlag(jpart) == 1) etsigJet[ijet] += ptT[jpart];
557              }
558              break;
559          }
560      }// end jets loop
561   } //end particle loop
562
563   //calc jets areas
564   Float_t areaJet[30];
565   Float_t areaOut = 4*(header->GetLegoEtaMax())*TMath::Pi();
566   for(Int_t k=0; k<nJ; k++){
567       Float_t detamax = etaJet[k] + rc;
568       Float_t detamin = etaJet[k] - rc;
569       Float_t accmax = 0.0; Float_t accmin = 0.0;
570       if(detamax > header->GetLegoEtaMax()){ // sector outside etamax
571          Float_t h = header->GetLegoEtaMax() - etaJet[k];
572          accmax = rc*rc*TMath::ACos(h/rc) - h*TMath::Sqrt(rc*rc - h*h);
573       }
574       if(detamin < header->GetLegoEtaMin()){ // sector outside etamin
575          Float_t h = header->GetLegoEtaMax() + etaJet[k];
576          accmin = rc*rc*TMath::ACos(h/rc) - h*TMath::Sqrt(rc*rc - h*h);
577       }
578       areaJet[k] = rc*rc*TMath::Pi() - accmax - accmin;
579   }
580
581   //subtract background using area method
582   for(Int_t ljet=0; ljet<nJ; ljet++){
583      Float_t areaRatio = areaJet[ljet]/areaOut;
584      etJet[ljet] = etIn[ljet]-etbgStat*areaRatio; // subtraction
585   }
586
587   etbgTotalN = etbgStat;
588
589 }
590
591 ////////////////////////////////////////////////////////////////////////
592
593 void AliUA1JetFinderV1::SubtractBackgCone(const Int_t& nIn, const Int_t&nJ,Float_t& etbgTotalN,
594                                           const Float_t* ptT, const Float_t* etaT, const Float_t* phiT,
595                                           Float_t* etJet, const Float_t* etaJet, const Float_t* phiJet, Float_t* etsigJet,
596                                           Int_t* multJet, Int_t* injet)
597 {
598    // Cone background subtraction method taking into acount dEt/deta distribution
599     AliUA1JetHeaderV1* header = (AliUA1JetHeaderV1*) fHeader;
600    //general
601    Float_t rc= header->GetRadius();
602    Float_t etamax = header->GetLegoEtaMax();
603    Float_t etamin = header->GetLegoEtaMin();
604    Int_t ndiv = 100;
605
606    // jet energy and area arrays
607    TH1F* hEtJet[30];
608    TH1F* hAreaJet[30];
609    for(Int_t mjet=0; mjet<nJ; mjet++){
610      char hEtname[256]; char hAreaname[256];
611      sprintf(hEtname, "hEtJet%d", mjet); sprintf(hAreaname, "hAreaJet%d", mjet);
612      hEtJet[mjet] = new TH1F(hEtname,"et dist in eta ",ndiv,etamin,etamax);
613      hAreaJet[mjet] = new TH1F(hAreaname,"area dist in eta ",ndiv,etamin,etamax);
614   }
615    // background energy and area
616    TH1F* hEtBackg = new TH1F("hEtBackg"," backg et dist in eta ",ndiv,etamin,etamax);
617    TH1F* hAreaBackg = new TH1F("hAreaBackg","backg area dist in eta ",ndiv,etamin,etamax);
618
619    //fill energies
620    for(Int_t jpart = 0; jpart < nIn; jpart++){ // loop for all particles in array
621      for(Int_t ijet=0; ijet<nJ; ijet++){  // loop for all jets
622          Float_t deta = etaT[jpart] - etaJet[ijet];
623          Float_t dphi = phiT[jpart] - phiJet[ijet];
624          if (dphi < -TMath::Pi()) dphi= -dphi - 2.0 * TMath::Pi();
625          if (dphi > TMath::Pi()) dphi = 2.0 * TMath::Pi() - dphi;
626          Float_t dr = TMath::Sqrt(deta * deta + dphi * dphi);
627          if(dr <= rc){ // particles inside this cone
628              injet[jpart] = ijet;
629              multJet[ijet]++;
630              if((fReader->GetCutFlag(jpart)) == 1){// pt cut
631                 hEtJet[ijet]->Fill(etaT[jpart],ptT[jpart]); //particle inside cone
632                 if(fReader->GetSignalFlag(jpart) == 1) etsigJet[ijet] += ptT[jpart];
633              }
634              break;
635          }
636      }// end jets loop
637      if(injet[jpart] == -1  && fReader->GetCutFlag(jpart) == 1)
638         hEtBackg->Fill(etaT[jpart],ptT[jpart]); // particle outside cones
639   } //end particle loop
640
641    //calc areas
642    Float_t eta0 = etamin;
643    Float_t etaw = (etamax - etamin)/((Float_t)ndiv);
644    Float_t eta1 = eta0 + etaw;
645    for(Int_t etabin = 0; etabin< ndiv; etabin++){ // loop for all eta bins
646       Float_t etac = eta0 + etaw/2.0;
647       Float_t areabg = etaw*2.0*TMath::Pi();
648       for(Int_t ijet=0; ijet<nJ; ijet++){  // loop for all jets
649           Float_t deta0 = TMath::Abs(eta0 - etaJet[ijet]);
650           Float_t deta1 = TMath::Abs(eta1 - etaJet[ijet]);
651           Float_t acc0 = 0.0; Float_t acc1 = 0.0;
652           Float_t areaj = 0.0;
653           if(deta0 > rc && deta1 < rc){
654              acc1 = rc*rc*TMath::ACos(deta1/rc) - deta1*TMath::Sqrt(rc*rc - deta1*deta1);
655              areaj = acc1;
656           }
657           if(deta0 < rc && deta1 > rc){
658              acc0 = rc*rc*TMath::ACos(deta0/rc) - deta0*TMath::Sqrt(rc*rc - deta0*deta0);
659              areaj = acc0;
660           }
661           if(deta0 < rc && deta1 < rc){
662              acc0 = rc*rc*TMath::ACos(deta0/rc) - deta0*TMath::Sqrt(rc*rc - deta0*deta0);
663              acc1 = rc*rc*TMath::ACos(deta1/rc) - deta1*TMath::Sqrt(rc*rc - deta1*deta1);
664              if(eta1<etaJet[ijet]) areaj = acc1-acc0;  // case 1
665              if((eta0 < etaJet[ijet]) && (etaJet[ijet]<eta1)) areaj = rc*rc*TMath::Pi() - acc1 -acc0; // case 2
666              if(etaJet[ijet] < eta0) areaj = acc0 -acc1; // case 3
667           }
668           hAreaJet[ijet]->Fill(etac,areaj);
669           areabg = areabg - areaj;
670       } // end jets loop
671       hAreaBackg->Fill(etac,areabg);
672       eta0 = eta1;
673       eta1 = eta1 + etaw;
674    } // end loop for all eta bins
675
676    //subtract background
677    for(Int_t kjet=0; kjet<nJ; kjet++){
678        etJet[kjet] = 0.0; // first  clear etJet for this jet
679        for(Int_t bin = 0; bin< ndiv; bin++){
680            if(hAreaJet[kjet]->GetBinContent(bin)){
681               Float_t areab = hAreaBackg->GetBinContent(bin);
682               Float_t etb = hEtBackg->GetBinContent(bin);
683               Float_t areaR = (hAreaJet[kjet]->GetBinContent(bin))/areab;
684               etJet[kjet] = etJet[kjet] + ((hEtJet[kjet]->GetBinContent(bin)) - etb*areaR); //subtraction
685            }
686        }
687    }
688
689    // calc background total
690    Double_t etOut = hEtBackg->Integral();
691    Double_t areaOut = hAreaBackg->Integral();
692    Float_t areaT = 4*(header->GetLegoEtaMax())*TMath::Pi();
693    etbgTotalN = etOut*areaT/areaOut;
694
695    //delete
696    for(Int_t ljet=0; ljet<nJ; ljet++){  // loop for all jets
697        delete hEtJet[ljet];
698        delete hAreaJet[ljet];
699    }
700
701    delete hEtBackg;
702    delete hAreaBackg;
703 }
704
705 ////////////////////////////////////////////////////////////////////////
706
707
708 void AliUA1JetFinderV1::SubtractBackgRatio(const Int_t& nIn, const Int_t&nJ, Float_t& etbgTotalN,
709                                            const Float_t* ptT, const Float_t* etaT, const Float_t* phiT,
710                                            Float_t* etJet, const Float_t* etaJet, const Float_t* phiJet, Float_t* etsigJet,
711                                            Int_t* multJet, Int_t* injet)
712 {
713    // Ratio background subtraction method taking into acount dEt/deta distribution
714     AliUA1JetHeaderV1* header = (AliUA1JetHeaderV1*) fHeader;
715    //factor F calc before
716     Float_t bgRatioCut = header->GetBackgCutRatio();
717
718
719    //general
720    Float_t rc= header->GetRadius();
721    Float_t etamax = header->GetLegoEtaMax();
722    Float_t etamin = header->GetLegoEtaMin();
723    Int_t ndiv = 100;
724
725    // jet energy and area arrays
726    TH1F* hEtJet[30];
727    TH1F* hAreaJet[30];
728    for(Int_t mjet=0; mjet<nJ; mjet++){
729      char hEtname[256]; char hAreaname[256];
730      sprintf(hEtname, "hEtJet%d", mjet); sprintf(hAreaname, "hAreaJet%d", mjet);
731      hEtJet[mjet] = new TH1F(hEtname,"et dist in eta ",ndiv,etamin,etamax);        // change range
732      hAreaJet[mjet] = new TH1F(hAreaname,"area dist in eta ",ndiv,etamin,etamax);  // change range
733   }
734    // background energy and area
735    TH1F* hEtBackg = new TH1F("hEtBackg"," backg et dist in eta ",ndiv,etamin,etamax);         // change range
736    TH1F* hAreaBackg = new TH1F("hAreaBackg","backg area dist in eta ",ndiv,etamin,etamax);  // change range
737
738    //fill energies
739    for(Int_t jpart = 0; jpart < nIn; jpart++){ // loop for all particles in array
740      //if((fReader->GetCutFlag(jpart)) != 1) continue;
741      for(Int_t ijet=0; ijet<nJ; ijet++){  // loop for all jets
742          Float_t deta = etaT[jpart] - etaJet[ijet];
743               Float_t dphi = phiT[jpart] - phiJet[ijet];
744          if (dphi < -TMath::Pi()) dphi= -dphi - 2.0 * TMath::Pi();
745               if (dphi > TMath::Pi()) dphi = 2.0 * TMath::Pi() - dphi;
746               Float_t dr = TMath::Sqrt(deta * deta + dphi * dphi);
747          if(dr <= rc){ // particles inside this cone
748             multJet[ijet]++;
749             injet[jpart] = ijet;
750             if((fReader->GetCutFlag(jpart)) == 1){ //pt cut
751                hEtJet[ijet]->Fill(etaT[jpart],ptT[jpart]); //particle inside cone and pt cut
752                if(fReader->GetSignalFlag(jpart) == 1) etsigJet[ijet] += ptT[jpart];
753             }
754             break;
755          }
756      }// end jets loop
757      if(injet[jpart] == -1) hEtBackg->Fill(etaT[jpart],ptT[jpart]); // particle outside cones
758   } //end particle loop
759
760    //calc areas
761    Float_t eta0 = etamin;
762    Float_t etaw = (etamax - etamin)/((Float_t)ndiv);
763    Float_t eta1 = eta0 + etaw;
764    for(Int_t etabin = 0; etabin< ndiv; etabin++){ // loop for all eta bins
765       Float_t etac = eta0 + etaw/2.0;
766       Float_t areabg = etaw*2.0*TMath::Pi();
767       for(Int_t ijet=0; ijet<nJ; ijet++){  // loop for all jets
768           Float_t deta0 = TMath::Abs(eta0 - etaJet[ijet]);
769           Float_t deta1 = TMath::Abs(eta1 - etaJet[ijet]);
770           Float_t acc0 = 0.0; Float_t acc1 = 0.0;
771           Float_t areaj = 0.0;
772           if(deta0 > rc && deta1 < rc){
773              acc1 = rc*rc*TMath::ACos(deta1/rc) - deta1*TMath::Sqrt(rc*rc - deta1*deta1);
774              areaj = acc1;
775           }
776           if(deta0 < rc && deta1 > rc){
777              acc0 = rc*rc*TMath::ACos(deta0/rc) - deta0*TMath::Sqrt(rc*rc - deta0*deta0);
778              areaj = acc0;
779           }
780           if(deta0 < rc && deta1 < rc){
781              acc0 = rc*rc*TMath::ACos(deta0/rc) - deta0*TMath::Sqrt(rc*rc - deta0*deta0);
782              acc1 = rc*rc*TMath::ACos(deta1/rc) - deta1*TMath::Sqrt(rc*rc - deta1*deta1);
783              if(eta1<etaJet[ijet]) areaj = acc1-acc0;  // case 1
784              if((eta0 < etaJet[ijet]) && (etaJet[ijet]<eta1)) areaj = rc*rc*TMath::Pi() - acc1 -acc0; // case 2
785              if(etaJet[ijet] < eta0) areaj = acc0 -acc1; // case 3
786           }
787           hAreaJet[ijet]->Fill(etac,areaj);
788           areabg = areabg - areaj;
789       } // end jets loop
790       hAreaBackg->Fill(etac,areabg);
791       eta0 = eta1;
792       eta1 = eta1 + etaw;
793    } // end loop for all eta bins
794
795    //subtract background
796    for(Int_t kjet=0; kjet<nJ; kjet++){
797        etJet[kjet] = 0.0; // first  clear etJet for this jet
798        for(Int_t bin = 0; bin< ndiv; bin++){
799            if(hAreaJet[kjet]->GetBinContent(bin)){
800               Float_t areab = hAreaBackg->GetBinContent(bin);
801               Float_t etb = hEtBackg->GetBinContent(bin);
802               Float_t areaR = (hAreaJet[kjet]->GetBinContent(bin))/areab;
803               etJet[kjet] = etJet[kjet] + ((hEtJet[kjet]->GetBinContent(bin)) - etb*areaR*bgRatioCut); //subtraction
804            }
805        }
806    }
807
808    // calc background total
809    Double_t etOut = hEtBackg->Integral();
810    Double_t areaOut = hAreaBackg->Integral();
811    Float_t areaT = 4*(header->GetLegoEtaMax())*TMath::Pi();
812    etbgTotalN = etOut*areaT/areaOut;
813
814    //delete
815    for(Int_t ljet=0; ljet<nJ; ljet++){  // loop for all jets
816        delete hEtJet[ljet];
817        delete hAreaJet[ljet];
818    }
819
820    delete hEtBackg;
821    delete hAreaBackg;
822 }
823
824 ////////////////////////////////////////////////////////////////////////
825
826
827 void AliUA1JetFinderV1::Reset()
828 {
829   fLego->Reset();
830   AliJetFinder::Reset();
831 }
832
833 ////////////////////////////////////////////////////////////////////////
834
835 void AliUA1JetFinderV1::WriteJHeaderToFile() const
836 {
837   AliUA1JetHeaderV1* header = (AliUA1JetHeaderV1*) fHeader;
838   header->Write();
839 }
840
841 ////////////////////////////////////////////////////////////////////////
842
843 void AliUA1JetFinderV1::Init()
844 {
845   // initializes some variables
846   AliUA1JetHeaderV1* header = (AliUA1JetHeaderV1*) fHeader;
847   fLego = new
848     TH2F("legoH","eta-phi",
849          header->GetLegoNbinEta(), header->GetLegoEtaMin(),
850          header->GetLegoEtaMax(),  header->GetLegoNbinPhi(),
851          header->GetLegoPhiMin(),  header->GetLegoPhiMax());
852   // Do not store in current dir
853   fLego->SetDirectory(0);
854
855 }