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