]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWGJE/AliAnalysisTaskJetCore.cxx
jet shapes&Jet-track correlations for jets depending on their track back-to-back...
[u/mrichter/AliRoot.git] / PWGJE / AliAnalysisTaskJetCore.cxx
1
2 // ******************************************
3 // This task computes several jet observables like 
4 // the fraction of energy in inner and outer coronnas,
5 // jet-track correlations,triggered jet shapes and 
6 // correlation strength distribution of particles inside jets.    
7 // Author: lcunquei@cern.ch
8 // *******************************************
9
10
11 /**************************************************************************
12  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
13  *                                                                        *
14  * Author: The ALICE Off-line Project.                                    *
15  * Contributors are mentioned in the code where appropriate.              *
16  *                                                                        *
17  * Permission to use, copy, modify and distribute this software and its   *
18  * documentation strictly for non-commercial purposes is hereby granted   *
19  * without fee, provided that the above copyright notice appears in all   *
20  * copies and that both the copyright notice and this permission notice   *
21  * appear in the supporting documentation. The authors make no claims     *
22  * about the suitability of this software for any purpose. It is          *
23  * provided "as is" without express or implied warranty.                  *
24  **************************************************************************/
25
26
27 #include "TChain.h"
28 #include "TTree.h"
29 #include "TMath.h"
30 #include "TH1F.h"
31 #include "TH2F.h"
32 #include "TH3F.h"
33 #include "THnSparse.h"
34 #include "TCanvas.h"
35
36 #include "AliLog.h"
37
38 #include "AliAnalysisTask.h"
39 #include "AliAnalysisManager.h"
40
41 #include "AliVEvent.h"
42 #include "AliESDEvent.h"
43 #include "AliESDInputHandler.h"
44 #include "AliCentrality.h"
45 #include "AliAnalysisHelperJetTasks.h"
46 #include "AliInputEventHandler.h"
47 #include "AliAODJetEventBackground.h"
48 #include "AliAnalysisTaskFastEmbedding.h"
49 #include "AliAODEvent.h"
50 #include "AliAODHandler.h"
51 #include "AliAODJet.h"
52
53 #include "AliAnalysisTaskJetCore.h"
54
55 ClassImp(AliAnalysisTaskJetCore)
56
57 AliAnalysisTaskJetCore::AliAnalysisTaskJetCore() :
58 AliAnalysisTaskSE(),
59 fESD(0x0),
60 fAOD(0x0),
61 fAODExtension(0x0),
62 fBackgroundBranch(""),
63 fNonStdFile(""),
64 fIsPbPb(kTRUE),
65 fOfflineTrgMask(AliVEvent::kAny),
66 fMinContribVtx(1),
67 fVtxZMin(-10.),
68 fVtxZMax(10.),
69 fEvtClassMin(0),
70 fEvtClassMax(4),
71 fFilterMask(0),
72 fRadioFrac(0.2),
73 fMinDist(0.1),
74 fCentMin(0.),
75 fCentMax(100.),
76 fNInputTracksMin(0),
77 fNInputTracksMax(-1),
78 fAngStructCloseTracks(0),
79 fCheckMethods(0),
80 fDoEventMixing(0), 
81 fJetEtaMin(-.5),
82 fJetEtaMax(.5),
83 fNevents(0x0),
84 fTindex(0x0),
85 fTrigBufferIndex(0x0),
86 fJetPtMin(20.),
87 fJetTriggerExcludeMask(AliAODJet::kHighTrackPtTriggered),
88 fJetPtFractionMin(0.5),
89 fNMatchJets(4),
90 fMatchMaxDist(0.8),
91 fKeepJets(kFALSE),
92 fkNbranches(2),
93 fkEvtClasses(12),
94 fOutputList(0x0),
95 fbEvent(kTRUE),
96 fHistEvtSelection(0x0),
97 fhnDeltaR(0x0),
98 fhnMixedEvents(0x0),
99 fh2JetCoreMethod1C10(0x0),
100 fh2JetCoreMethod2C10(0x0),
101 fh2JetCoreMethod1C20(0x0),
102 fh2JetCoreMethod2C20(0x0),
103 fh2JetCoreMethod1C30(0x0),
104 fh2JetCoreMethod2C30(0x0),
105 fh2JetCoreMethod1C60(0x0),
106 fh2JetCoreMethod2C60(0x0),
107 fh2AngStructpt1C10(0x0),
108 fh2AngStructpt2C10(0x0),
109 fh2AngStructpt3C10(0x0),
110 fh2AngStructpt4C10(0x0),
111 fh2AngStructpt1C20(0x0),
112 fh2AngStructpt2C20(0x0),
113 fh2AngStructpt3C20(0x0),
114 fh2AngStructpt4C20(0x0),    
115 fh2AngStructpt1C30(0x0),
116 fh2AngStructpt2C30(0x0),
117 fh2AngStructpt3C30(0x0),
118 fh2AngStructpt4C30(0x0),   
119 fh2AngStructpt1C60(0x0),
120 fh2AngStructpt2C60(0x0),
121 fh2AngStructpt3C60(0x0),
122 fh2AngStructpt4C60(0x0),
123 fh3spectriggered(0x0),
124 fh3specbiased(0x0),
125 fh3spectot(0x0)
126
127  
128 {
129    // default Constructor
130
131
132  // Trigger buffer.
133    for(Int_t i=0; i<10; i++) {
134                 for(Int_t j=0; j<7; j++) {
135                         fTrigBuffer[i][j]=0;
136                 }                               
137         }       
138
139
140
141
142
143    fJetBranchName[0] = "";
144    fJetBranchName[1] = "";
145
146    fListJets[0] = new TList;
147    fListJets[1] = new TList;
148 }
149
150 AliAnalysisTaskJetCore::AliAnalysisTaskJetCore(const char *name) :
151 AliAnalysisTaskSE(name),
152 fESD(0x0),
153 fAOD(0x0),
154 fAODExtension(0x0),
155 fBackgroundBranch(""),
156 fNonStdFile(""),
157 fIsPbPb(kTRUE),
158 fOfflineTrgMask(AliVEvent::kAny),
159 fMinContribVtx(1),
160 fVtxZMin(-10.),
161 fVtxZMax(10.),
162 fEvtClassMin(0),
163 fEvtClassMax(4),
164 fFilterMask(0),
165 fRadioFrac(0.2),
166 fMinDist(0.1),
167 fCentMin(0.),
168 fCentMax(100.),
169 fNInputTracksMin(0),
170 fNInputTracksMax(-1),
171 fAngStructCloseTracks(0),
172 fCheckMethods(0),
173 fDoEventMixing(0),
174 fJetEtaMin(-.5),
175 fJetEtaMax(.5),
176 fNevents(0x0),
177 fTindex(0x0),
178 fTrigBufferIndex(0x0),
179 fJetPtMin(20.),
180 fJetTriggerExcludeMask(AliAODJet::kHighTrackPtTriggered),
181 fJetPtFractionMin(0.5),
182 fNMatchJets(4),
183 fMatchMaxDist(0.8),
184 fKeepJets(kFALSE),
185 fkNbranches(2),
186 fkEvtClasses(12),
187 fOutputList(0x0),
188 fbEvent(kTRUE),
189 fHistEvtSelection(0x0),
190 fhnDeltaR(0x0),
191 fhnMixedEvents(0x0),
192 fh2JetCoreMethod1C10(0x0),
193 fh2JetCoreMethod2C10(0x0),
194 fh2JetCoreMethod1C20(0x0),
195 fh2JetCoreMethod2C20(0x0),
196 fh2JetCoreMethod1C30(0x0),
197 fh2JetCoreMethod2C30(0x0),
198 fh2JetCoreMethod1C60(0x0),
199 fh2JetCoreMethod2C60(0x0),
200 fh2AngStructpt1C10(0x0),
201 fh2AngStructpt2C10(0x0),
202 fh2AngStructpt3C10(0x0),
203 fh2AngStructpt4C10(0x0),
204 fh2AngStructpt1C20(0x0),
205 fh2AngStructpt2C20(0x0),
206 fh2AngStructpt3C20(0x0),
207 fh2AngStructpt4C20(0x0),    
208 fh2AngStructpt1C30(0x0),
209 fh2AngStructpt2C30(0x0),
210 fh2AngStructpt3C30(0x0),
211 fh2AngStructpt4C30(0x0),   
212 fh2AngStructpt1C60(0x0),
213 fh2AngStructpt2C60(0x0),
214 fh2AngStructpt3C60(0x0),
215 fh2AngStructpt4C60(0x0),    
216 fh3spectriggered(0x0),
217 fh3specbiased(0x0),
218 fh3spectot(0x0)
219
220  {
221    // Constructor
222
223
224     for(Int_t i=0; i<10; i++) {
225        for(Int_t j=0; j<7; j++) {
226             fTrigBuffer[i][j]=0;
227                 }                               
228     }   
229
230
231
232    fJetBranchName[0] = "";
233    fJetBranchName[1] = "";
234
235    fListJets[0] = new TList;
236    fListJets[1] = new TList;
237
238    DefineOutput(1, TList::Class());
239 }
240
241 AliAnalysisTaskJetCore::~AliAnalysisTaskJetCore()
242 {
243    delete fListJets[0];
244    delete fListJets[1];
245 }
246
247 void AliAnalysisTaskJetCore::SetBranchNames(const TString &branch1, const TString &branch2)
248 {
249    fJetBranchName[0] = branch1;
250    fJetBranchName[1] = branch2;
251 }
252
253 void AliAnalysisTaskJetCore::Init()
254 {
255
256    // check for jet branches
257    if(!strlen(fJetBranchName[0].Data()) || !strlen(fJetBranchName[1].Data())){
258       AliError("Jet branch name not set.");
259    }
260
261 }
262
263 void AliAnalysisTaskJetCore::UserCreateOutputObjects()
264 {
265    // Create histograms
266    // Called once
267    OpenFile(1);
268    if(!fOutputList) fOutputList = new TList;
269    fOutputList->SetOwner(kTRUE);
270
271    Bool_t oldStatus = TH1::AddDirectoryStatus();
272    TH1::AddDirectory(kFALSE);
273
274
275    fHistEvtSelection = new TH1I("fHistEvtSelection", "event selection", 6, -0.5, 5.5);
276    fHistEvtSelection->GetXaxis()->SetBinLabel(1,"ACCEPTED");
277    fHistEvtSelection->GetXaxis()->SetBinLabel(2,"events IN");
278    fHistEvtSelection->GetXaxis()->SetBinLabel(3,"event selection (rejected)");
279    fHistEvtSelection->GetXaxis()->SetBinLabel(4,"vertex cut (rejected)");
280    fHistEvtSelection->GetXaxis()->SetBinLabel(5,"centrality (rejected)");
281    fHistEvtSelection->GetXaxis()->SetBinLabel(6,"multiplicity (rejected)");
282
283      UInt_t entries = 0; // bit coded, see GetDimParams() below 
284      entries = 1<<0 | 1<<1 | 1<<2 | 1<<3 | 1<<4 | 1<<5 | 1<<6 |1<<7; 
285      fhnDeltaR = NewTHnSparseF("fhnDeltaR", entries);
286    
287     
288      UInt_t cifras = 0; // bit coded, see GetDimParams() below 
289      cifras = 1<<0 | 1<<1 | 1<<2 | 1<<3 | 1<<4 | 1<<5 | 1<<6 |1<<7; 
290      fhnMixedEvents = NewTHnSparseF("fhnMixedEvents", cifras);
291
292     if(fCheckMethods){
293
294
295     fh2JetCoreMethod1C10 = new TH2F("JetCoreMethod1C10","",150, 0., 150.,100, 0., 1.5);
296     fh2JetCoreMethod2C10 = new TH2F("JetCoreMethod2C10","",150, 0., 150.,100, 0., 1.5);
297     fh2JetCoreMethod1C20 = new TH2F("JetCoreMethod1C20","",150, 0., 150.,100, 0., 1.5);
298     fh2JetCoreMethod2C20 = new TH2F("JetCoreMethod2C20","",150, 0., 150.,100, 0., 1.5);
299     fh2JetCoreMethod1C30 = new TH2F("JetCoreMethod1C30","",150, 0., 150.,100, 0., 1.5);
300     fh2JetCoreMethod2C30 = new TH2F("JetCoreMethod2C30","",150, 0., 150.,100, 0., 1.5);
301     fh2JetCoreMethod1C60 = new TH2F("JetCoreMethod1C60","",150, 0., 150.,100, 0., 1.5);
302     fh2JetCoreMethod2C60 = new TH2F("JetCoreMethod2C60","",150, 0., 150.,100, 0., 1.5);}
303
304    
305     if(fAngStructCloseTracks>0){
306     fh2AngStructpt1C10 = new TH2F("Ang struct pt1 C10","",15,0.,1.5,150,0.,10.);
307     fh2AngStructpt2C10 = new TH2F("Ang struct pt2 C10","",15,0.,1.5,150,0.,10.);
308     fh2AngStructpt3C10 = new TH2F("Ang struct pt3 C10","",15,0.,1.5,150,0.,10.);
309     fh2AngStructpt4C10 = new TH2F("Ang struct pt4 C10","",15,0.,1.5,150,0.,10.);
310     fh2AngStructpt1C20 = new TH2F("Ang struct pt1 C20","",15,0.,1.5,150,0.,10.);
311     fh2AngStructpt2C20 = new TH2F("Ang struct pt2 C20","",15,0.,1.5,150,0.,10.);
312     fh2AngStructpt3C20 = new TH2F("Ang struct pt3 C20","",15,0.,1.5,150,0.,10.);
313     fh2AngStructpt4C20 = new TH2F("Ang struct pt4 C20","",15,0.,1.5,150,0.,10.);
314     fh2AngStructpt1C30 = new TH2F("Ang struct pt1 C30","",15,0.,1.5,150,0.,10.);
315     fh2AngStructpt2C30 = new TH2F("Ang struct pt2 C30","",15,0.,1.5,150,0.,10.);
316     fh2AngStructpt3C30 = new TH2F("Ang struct pt3 C30","",15,0.,1.5,150,0.,10.);
317     fh2AngStructpt4C30 = new TH2F("Ang struct pt4 C30","",15,0.,1.5,150,0.,10.);
318     fh2AngStructpt1C60 = new TH2F("Ang struct pt1 C60","",15,0.,1.5,150,0.,10.);
319     fh2AngStructpt2C60 = new TH2F("Ang struct pt2 C60","",15,0.,1.5,150,0.,10.);
320     fh2AngStructpt3C60 = new TH2F("Ang struct pt3 C60","",15,0.,1.5,150,0.,10.);
321     fh2AngStructpt4C60 = new TH2F("Ang struct pt4 C60","",15,0.,1.5,150,0.,10.); }
322     fh3spectriggered = new TH3F("Triggered spectrum","",10,0,100,50,0.,200,50,0.,50.);
323     fh3specbiased = new TH3F("Biased spectrum","",10,0,100,50,0.,200.,50,0.,50.);
324     fh3spectot = new TH3F("Total spectrum","",50,0.,200.,50,0.,50.,50,0.,50.);
325
326    fOutputList->Add(fHistEvtSelection);
327
328    fOutputList->Add(fhnDeltaR);
329    
330    fOutputList->Add(fhnMixedEvents);
331          
332      
333   
334       if(fCheckMethods){
335
336       fOutputList->Add(fh2JetCoreMethod1C10);
337       fOutputList->Add(fh2JetCoreMethod2C10);
338       fOutputList->Add(fh2JetCoreMethod1C20);
339       fOutputList->Add(fh2JetCoreMethod2C20);
340       fOutputList->Add(fh2JetCoreMethod1C30);
341       fOutputList->Add(fh2JetCoreMethod2C30);
342       fOutputList->Add(fh2JetCoreMethod1C60);
343       fOutputList->Add(fh2JetCoreMethod2C60);}
344       
345       
346      
347
348
349         if(fAngStructCloseTracks>0){
350        fOutputList->Add(fh2AngStructpt1C10);
351        fOutputList->Add(fh2AngStructpt2C10);
352        fOutputList->Add(fh2AngStructpt3C10);
353        fOutputList->Add(fh2AngStructpt4C10); 
354        fOutputList->Add(fh2AngStructpt1C20);
355        fOutputList->Add(fh2AngStructpt2C20);
356        fOutputList->Add(fh2AngStructpt3C20);
357        fOutputList->Add(fh2AngStructpt4C20); 
358        fOutputList->Add(fh2AngStructpt1C30);
359        fOutputList->Add(fh2AngStructpt2C30);
360        fOutputList->Add(fh2AngStructpt3C30);
361        fOutputList->Add(fh2AngStructpt4C30);
362        fOutputList->Add(fh2AngStructpt1C60);
363        fOutputList->Add(fh2AngStructpt2C60);
364        fOutputList->Add(fh2AngStructpt3C60);
365        fOutputList->Add(fh2AngStructpt4C60);}  
366        fOutputList->Add(fh3spectriggered);
367        fOutputList->Add(fh3specbiased);
368        fOutputList->Add(fh3spectot);
369
370    // =========== Switch on Sumw2 for all histos ===========
371    for (Int_t i=0; i<fOutputList->GetEntries(); ++i) {
372       TH1 *h1 = dynamic_cast<TH1*>(fOutputList->At(i));
373       if (h1){
374          h1->Sumw2();
375          continue;
376       }
377     THnSparse *hn = dynamic_cast<THnSparse*>(fOutputList->At(i));
378       if (hn){
379          hn->Sumw2();
380       }   
381    }
382    TH1::AddDirectory(oldStatus);
383
384    PostData(1, fOutputList);
385 }
386
387 void AliAnalysisTaskJetCore::UserExec(Option_t *)
388 {
389    
390
391    if(!strlen(fJetBranchName[0].Data()) || !strlen(fJetBranchName[1].Data())){
392       AliError("Jet branch name not set.");
393       return;
394    }
395
396    fESD=dynamic_cast<AliESDEvent*>(InputEvent());
397    if (!fESD) {
398       AliError("ESD not available");
399       fAOD = dynamic_cast<AliAODEvent*>(InputEvent());
400    } else {
401       fAOD = dynamic_cast<AliAODEvent*>(AODEvent());
402    }
403  
404     if(fNonStdFile.Length()!=0){
405     // case that we have an AOD extension we need can fetch the jets from the extended output
406     AliAODHandler *aodH = dynamic_cast<AliAODHandler*>(AliAnalysisManager::GetAnalysisManager()->GetOutputEventHandler());
407     fAODExtension = (aodH?aodH->GetExtension(fNonStdFile.Data()):0);
408     if(!fAODExtension){
409       if(fDebug>1)Printf("AODExtension found for %s",fNonStdFile.Data());
410     }}
411     
412
413
414
415
416    // -- event selection --
417    fHistEvtSelection->Fill(1); // number of events before event selection
418
419    // physics selection
420    AliInputEventHandler* inputHandler = (AliInputEventHandler*)
421    ((AliAnalysisManager::GetAnalysisManager())->GetInputEventHandler());
422    cout<<inputHandler->IsEventSelected()<<" "<<fOfflineTrgMask<<endl;
423    if(!(inputHandler->IsEventSelected() & fOfflineTrgMask)){
424       if(fDebug) Printf(" Trigger Selection: event REJECTED ... ");
425       fHistEvtSelection->Fill(2);
426       PostData(1, fOutputList);
427       return;
428    }
429
430    // vertex selection
431    AliAODVertex* primVtx = fAOD->GetPrimaryVertex();
432    Int_t nTracksPrim = primVtx->GetNContributors();
433    if ((nTracksPrim < fMinContribVtx) ||
434          (primVtx->GetZ() < fVtxZMin) ||
435          (primVtx->GetZ() > fVtxZMax) ){
436       if(fDebug) Printf("%s:%d primary vertex z = %f: event REJECTED...",(char*)__FILE__,__LINE__,primVtx->GetZ());
437       fHistEvtSelection->Fill(3);
438       PostData(1, fOutputList);
439       return;
440    }
441
442    // event class selection (from jet helper task)
443    Int_t eventClass = AliAnalysisHelperJetTasks::EventClass();
444    if(fDebug) Printf("Event class %d", eventClass);
445    if (eventClass < fEvtClassMin || eventClass > fEvtClassMax){
446       fHistEvtSelection->Fill(4);
447       PostData(1, fOutputList);
448       return;
449    }
450
451    // centrality selection
452    AliCentrality *cent = 0x0;
453    Double_t centValue = 0.; 
454    if(fESD) cent = fESD->GetCentrality();
455    if(cent) centValue = cent->GetCentralityPercentile("V0M");
456    if(fDebug) printf("centrality: %f\n", centValue);
457    if (centValue < fCentMin || centValue > fCentMax){
458       fHistEvtSelection->Fill(4);
459       PostData(1, fOutputList);
460       return;
461    }
462
463
464    fHistEvtSelection->Fill(0); 
465    // accepted events  
466    // -- end event selection --
467   
468    // get background
469    AliAODJetEventBackground* externalBackground = 0;
470    if(fAOD&&!externalBackground&&fBackgroundBranch.Length()){
471       externalBackground =  (AliAODJetEventBackground*)(fAOD->FindListObject(fBackgroundBranch.Data()));
472       if(!externalBackground)Printf("%s:%d Background branch not found %s",(char*)__FILE__,__LINE__,fBackgroundBranch.Data());;
473    }
474    if(fAODExtension&&!externalBackground&&fBackgroundBranch.Length()){
475      externalBackground =  (AliAODJetEventBackground*)(fAODExtension->GetAOD()->FindListObject(fBackgroundBranch.Data()));
476       if(!externalBackground)Printf("%s:%d Background branch not found %s",(char*)__FILE__,__LINE__,fBackgroundBranch.Data());;
477    }
478    
479    Float_t rho = 0;
480    if(externalBackground)rho = externalBackground->GetBackground(0);
481
482
483    // fetch jets
484    TClonesArray *aodJets[2];
485    aodJets[0]=0;
486    if(fAOD&&!aodJets[0]){
487    aodJets[0] = dynamic_cast<TClonesArray*>(fAOD->FindListObject(fJetBranchName[0].Data())); 
488    aodJets[1] = dynamic_cast<TClonesArray*>(fAOD->FindListObject(fJetBranchName[1].Data()));  }
489    if(fAODExtension && !aodJets[0]){ 
490    aodJets[0] = dynamic_cast<TClonesArray*>(fAODExtension->GetAOD()->FindListObject(fJetBranchName[0].Data())); 
491    aodJets[1] = dynamic_cast<TClonesArray*>(fAODExtension->GetAOD()->FindListObject(fJetBranchName[1].Data()));  }
492
493    //Double_t ptsub[aodJets[0]->GetEntriesFast()];
494    //Int_t inord[aodJets[0]->GetEntriesFast()];
495    //for(Int_t n=0;n<aodJets[0]->GetEntriesFast();n++){
496    //  ptsub[n]=0;
497    //  inord[n]=0;}   
498
499    TList ParticleList;
500    Int_t nT = GetListOfTracks(&ParticleList);
501      for (Int_t iJetType = 0; iJetType < 2; iJetType++) {
502       fListJets[iJetType]->Clear();
503       if (!aodJets[iJetType]) continue;
504
505       if(fDebug) Printf("%s: %d jets",fJetBranchName[iJetType].Data(),aodJets[iJetType]->GetEntriesFast());
506       
507    
508       for (Int_t iJet = 0; iJet < aodJets[iJetType]->GetEntriesFast(); iJet++) {
509          AliAODJet *jet = dynamic_cast<AliAODJet*>((*aodJets[iJetType])[iJet]);
510          if (jet) fListJets[iJetType]->Add(jet);
511          // if(iJetType==0){
512          // ptsub[iJet]=jet->Pt()-rho*jet->EffectiveAreaCharged();}
513       }}
514    
515    Double_t etabig=0;
516    Double_t ptbig=0;
517    Double_t areabig=0;
518    Double_t phibig=0.;
519    Double_t etasmall=0;
520    Double_t ptsmall=0;
521    Double_t areasmall=0;
522    //Double_t distr=0.;
523    Double_t phismall=0.;
524          
525   
526    // Double_t up1[15]={0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.};
527    // Double_t up2[15]={0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.};
528    // Double_t up3[15]={0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.};
529    // Double_t up4[15]={0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.};
530    // Double_t down1[15]={0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.};
531    // Double_t down2[15]={0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.};
532    // Double_t down3[15]={0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.};
533    // Double_t down4[15]={0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.};
534    Int_t iCount=0; 
535    Int_t trigJet=-1;
536    Int_t trigBBTrack=-1;
537    Int_t trigInTrack=-1;
538      
539    for(Int_t i=0; i<fListJets[0]->GetEntries(); ++i){
540            AliAODJet* jetbig = (AliAODJet*)(fListJets[0]->At(i));
541            etabig  = jetbig->Eta();
542            phibig  = jetbig->Phi();
543            ptbig   = jetbig->Pt();
544            if(ptbig==0) continue; 
545            areabig = jetbig->EffectiveAreaCharged();
546            Double_t ptcorr=ptbig-rho*areabig;
547            if(ptcorr<=0) continue;
548            if((etabig<fJetEtaMin)||(etabig>fJetEtaMax)) continue;
549                    Double_t dismin=100.;
550                    Double_t ptmax=-10.; 
551                    Int_t index1=-1;
552                    Int_t index2=-1;
553                   
554                Int_t point=GetHardestTrackBackToJet(jetbig);    
555                AliVParticle *partback = (AliVParticle*)ParticleList.At(point);                            
556                if(!partback) continue; 
557                    fh3spectriggered->Fill(centValue,ptcorr,partback->Pt());
558                        AliAODTrack* leadtrack; 
559                        Int_t ippt=0;
560                        Double_t ppt=-10;   
561                        TRefArray *genTrackList = jetbig->GetRefTracks();
562                        Int_t nTracksGenJet = genTrackList->GetEntriesFast();
563                        AliAODTrack* genTrack;
564                        for(Int_t ir=0; ir<nTracksGenJet; ++ir){
565                        genTrack = (AliAODTrack*)(genTrackList->At(ir));
566                        if(genTrack->Pt()>ppt){ppt=genTrack->Pt();
567                        ippt=ir;}}
568                         leadtrack=(AliAODTrack*)(genTrackList->At(ippt));
569                         if(!leadtrack) continue;
570                         fh3specbiased->Fill(centValue,ptcorr,leadtrack->Pt());
571                         if(centValue<10)fh3spectot->Fill(ptcorr,leadtrack->Pt(),partback->Pt());
572                         //store one trigger info                   
573                         if((partback->Pt()>10.)&&(iCount==0)){                        
574                           trigJet=i;
575                           trigBBTrack=point;
576                           trigInTrack=ippt;
577                           iCount=iCount+1;} 
578
579
580                   if(fCheckMethods){
581                   for(Int_t j=0; j<fListJets[1]->GetEntries(); ++j){
582                   AliAODJet* jetsmall = (AliAODJet*)(fListJets[1]->At(j));
583                   etasmall  = jetsmall->Eta();
584                   phismall = jetsmall->Phi();
585                   ptsmall   = jetsmall->Pt();
586                   areasmall = jetsmall->EffectiveAreaCharged();
587                   Double_t tmpDeltaR=(phismall-phibig)*(phismall-phibig)+(etasmall-etabig)*(etasmall-etabig);
588                   tmpDeltaR=TMath::Sqrt(tmpDeltaR);
589                      //Fraction in the jet core  
590                     if((ptsmall>ptmax)&&(tmpDeltaR<=fRadioFrac)){ptmax=ptsmall;  
591                     index2=j;}  
592                     if(tmpDeltaR<=dismin){ dismin=tmpDeltaR;
593                       index1=j;}} //en of loop over R=0.2 jets
594                 //method1:most concentric jet=core 
595                 if(dismin<fMinDist){ AliAODJet* jetmethod1 = (AliAODJet*)(fListJets[1]->At(index1));       
596                   if(centValue<10) fh2JetCoreMethod1C10->Fill(ptcorr,jetmethod1->Pt()/ptbig);
597                   if((centValue>20)&&(centValue<40)) fh2JetCoreMethod1C20->Fill(ptcorr,jetmethod1->Pt()/ptbig);
598                   if((centValue>30)&&(centValue<60)) fh2JetCoreMethod1C30->Fill(ptcorr,jetmethod1->Pt()/ptbig);
599                   if(centValue>60) fh2JetCoreMethod1C60->Fill(ptcorr,jetmethod1->Pt()/ptbig); }
600                 //method2:hardest contained jet=core   
601                 if(index2!=-1){ 
602                   AliAODJet* jetmethod2 = (AliAODJet*)(fListJets[1]->At(index2));
603                   if(centValue<10) fh2JetCoreMethod2C10->Fill(ptcorr,jetmethod2->Pt()/ptbig);
604                   if((centValue>20)&&(centValue<40)) fh2JetCoreMethod2C20->Fill(ptcorr,jetmethod2->Pt()/ptbig); 
605                   if((centValue>30)&&(centValue<60)) fh2JetCoreMethod2C30->Fill(ptcorr,jetmethod2->Pt()/ptbig);
606                   if(centValue>60) fh2JetCoreMethod2C60->Fill(ptcorr,jetmethod2->Pt()/ptbig); }}  
607
608           for(int it = 0;it<nT;++it){
609           AliVParticle *part = (AliVParticle*)ParticleList.At(it);
610           Double_t deltaR = jetbig->DeltaR(part);
611           Double_t deltaEta = etabig-part->Eta();
612           Double_t deltaPhi=phibig-part->Phi();
613           if(deltaPhi<-0.5*TMath::Pi()) deltaPhi+=2.*TMath::Pi();
614           if(deltaPhi>3./2.*TMath::Pi()) deltaPhi-=2.*TMath::Pi();
615           Double_t jetEntries[8] = {centValue,ptcorr,part->Pt(),deltaR,deltaEta,deltaPhi,leadtrack->Pt(),partback->Pt()};                     fhnDeltaR->Fill(jetEntries);
616           }
617           //end of track loop
618           }
619           //end of jet loop
620
621
622
623
624           if(fDoEventMixing){
625             //check before if the trigger exists
626             // fTrigBuffer[i][0] = zvtx
627             // fTrigBuffer[i][1] = phi
628             // fTrigBuffer[i][2] = eta
629             // fTrigBuffer[i][3] = pt_jet
630             // fTrigBuffer[i][4] = pt_trig
631             // fTrigBuffer[i][5]= pt_track_in
632             // fTrigBuffer[i][6]= centrality
633             if(fTindex==11) fTindex=0;
634             if(fTrigBuffer[fTindex][3]>0){
635             if (TMath::Abs(fTrigBuffer[fTindex][0]-primVtx->GetZ()<2.)){
636             if (TMath::Abs(fTrigBuffer[fTindex][6]-centValue<10)){  
637               
638                         for(int it = 0;it<nT;++it){
639                         AliVParticle *part = (AliVParticle*)ParticleList.At(it);                        Double_t DPhi = fTrigBuffer[fTindex][1] - part->Phi();
640                         Double_t DEta = fTrigBuffer[fTindex][2] - part->Eta();
641                         Double_t DR=TMath::Sqrt(DPhi*DPhi+DEta*DEta);
642                         if(DPhi<-0.5*TMath::Pi()) DPhi+=2.*TMath::Pi();
643                         if(DPhi>3./2.*TMath::Pi()) DPhi-=2.*TMath::Pi();
644                         Double_t triggerEntries[8] = {centValue,fTrigBuffer[fTindex][3],part->Pt(),DR,DEta,DPhi,fTrigBuffer[fTindex][4],fTrigBuffer[fTindex][5]};                      
645                         fhnMixedEvents->Fill(triggerEntries);
646                         }
647                         fNevents=fNevents+1;  
648                         if(fNevents==9) {fTindex=fTindex+1;
649                         fNevents=0;} 
650             }}}
651         
652
653                // Copy the triggers from the current event into the buffer.
654                //again, only if the trigger exists:
655                 if(trigJet>-1){
656                 AliAODJet* jetT = (AliAODJet*)(fListJets[0]->At(trigJet));                 
657                 AliVParticle *partL = (AliVParticle*)ParticleList.At(trigInTrack);
658                 AliVParticle *partT = (AliVParticle*)ParticleList.At(trigBBTrack);         
659                 fTrigBuffer[fTrigBufferIndex][0] = primVtx->GetZ();
660                 fTrigBuffer[fTrigBufferIndex][1] = jetT->Phi();
661                 fTrigBuffer[fTrigBufferIndex][2] = jetT->Eta();
662                 fTrigBuffer[fTrigBufferIndex][3] = jetT->Pt()-rho*jetT->EffectiveAreaCharged();
663                 fTrigBuffer[fTrigBufferIndex][4] = partT->Pt();
664                 fTrigBuffer[fTrigBufferIndex][5] = partL->Pt();
665                 fTrigBuffer[fTrigBufferIndex][6] = centValue;
666                 fTrigBufferIndex++;
667                 if(fTrigBufferIndex==9) fTrigBufferIndex=0;
668                 }
669           }
670           
671
672
673
674
675      //////////////////ANGULAR STRUCTURE//////////////////////////////////////
676
677      //tracks up to R=0.8 distant from the jet axis
678    //   if(fAngStructCloseTracks==1){
679    //    TList CloseTrackList;
680    //    Int_t nn=GetListOfTracksCloseToJet(&CloseTrackList,jetbig);
681    //    Double_t difR=0.04;
682    //    for(Int_t l=0;l<15;l++){
683    //    Double_t rr=l*0.1+0.1;
684    //     for(int it = 0;it<nn;++it){
685    //         AliVParticle *part1 = (AliVParticle*)CloseTrackList.At(it);
686    //         for(int itu=it+1;itu<CloseTrackList.GetEntries();itu++){      
687    //         AliVParticle *part2 = (AliVParticle*)CloseTrackList.At(itu);  
688    //         Double_t ptm=part1->Pt();
689    //         Double_t ptn=part2->Pt(); 
690    //         Double_t Rnm = (part1->Eta()-part2->Eta())*(part1->Eta()-part2->Eta())+(part1->Phi()-part2->Phi())*(part1->Phi()-part2->Phi());
691    //                    Rnm=TMath::Sqrt(Rnm);
692    //                    Double_t deltag=(1./(TMath::Sqrt(2*TMath::Pi())*difR))*TMath::Exp(-1.*(rr-Rnm)*(rr-Rnm)/(2.*difR*difR));      
693    //                    Double_t stepf=0.5*(1.+TMath::Erf((rr-Rnm)/(TMath::Sqrt(2.)*difR)));
694    //                    if((ptcorr<85.) && (ptcorr>=70.)){up1[l]=up1[l]+ptm*ptn*Rnm*Rnm*deltag;
695    //                                                   down1[l]=down1[l]+ptm*ptn*Rnm*Rnm*stepf;}
696    //                    if((ptcorr<100.) && (ptcorr>=85.)){up2[l]=up2[l]+ptm*ptn*Rnm*Rnm*deltag;
697    //                                                   down2[l]=down2[l]+ptm*ptn*Rnm*Rnm*stepf;}  
698    //                    if((ptcorr<120.) && (ptcorr>=100.)){up3[l]=up3[l]+ptm*ptn*Rnm*Rnm*deltag;
699    //                                                    down3[l]=down3[l]+ptm*ptn*Rnm*Rnm*stepf;}
700    //                    if((ptcorr<140.) && (ptcorr>=120.)){up4[l]=up4[l]+ptm*ptn*Rnm*Rnm*deltag;
701    //                   down4[l]=down4[l]+ptm*ptn*Rnm*Rnm*stepf;}}}}
702    //   }
703     
704    //   //only jet constituents
705    //    if(fAngStructCloseTracks==2){
706
707    //    Double_t difR=0.04;
708    //    for(Int_t l=0;l<15;l++){
709    //    Double_t rr=l*0.1+0.1;
710
711     
712    //    AliAODTrack* part1;
713    //    AliAODTrack* part2;
714
715    //        TRefArray *genTrackListb = jetbig->GetRefTracks();
716    //        Int_t nTracksGenJetb = genTrackListb->GetEntriesFast();
717           
718              
719
720    //        for(Int_t it=0; it<nTracksGenJetb; ++it){
721    //           part1 = (AliAODTrack*)(genTrackListb->At(it));
722    //         for(Int_t itu=0; itu<nTracksGenJetb; ++itu){
723    //           part2 = (AliAODTrack*)(genTrackListb->At(itu));
724    //         Double_t ptm=part1->Pt();
725    //         Double_t ptn=part2->Pt(); 
726    //         Double_t Rnm = (part1->Eta()-part2->Eta())*(part1->Eta()-part2->Eta())+(part1->Phi()-part2->Phi())*(part1->Phi()-part2->Phi());
727    //                    Rnm=TMath::Sqrt(Rnm);
728    //                    Double_t deltag=(1./(TMath::Sqrt(2*TMath::Pi())*difR))*TMath::Exp(-1.*(rr-Rnm)*(rr-Rnm)/(2.*difR*difR));
729    //                    Double_t stepf=0.5*(1.+TMath::Erf((rr-Rnm)/(TMath::Sqrt(2.)*difR))); 
730    //                    if((ptcorr<85.) && (ptcorr>=70.)){up1[l]=up1[l]+ptm*ptn*Rnm*Rnm*deltag;
731    //                                                   down1[l]=down1[l]+ptm*ptn*Rnm*Rnm*stepf;}
732    //                    if((ptcorr<100.) && (ptcorr>=85.)){up2[l]=up2[l]+ptm*ptn*Rnm*Rnm*deltag;
733    //                                                   down2[l]=down2[l]+ptm*ptn*Rnm*Rnm*stepf;}  
734    //                    if((ptcorr<120.) && (ptcorr>=100.)){up3[l]=up3[l]+ptm*ptn*Rnm*Rnm*deltag;
735    //                                                    down3[l]=down3[l]+ptm*ptn*Rnm*Rnm*stepf;}
736    //                    if((ptcorr<140.) && (ptcorr>=120.)){up4[l]=up4[l]+ptm*ptn*Rnm*Rnm*deltag;
737    //                   down4[l]=down4[l]+ptm*ptn*Rnm*Rnm*stepf;}}}}}
738    // }
739      // //end loop over R=0.4 jets      
740      // if(fAngStructCloseTracks>0){
741      // for(Int_t l=0;l<15;l++){
742      // Double_t rr=l*0.1+0.1;
743      //    if(down1[l]!=0){  
744      //         if(centValue<10.)fh2AngStructpt1C10->Fill(rr,rr*up1[l]/down1[l]);
745      //    if(centValue>20. && centValue<40.) fh2AngStructpt1C20->Fill(rr,rr*up1[l]/down1[l]);
746      //    if(centValue>30. && centValue<60.) fh2AngStructpt1C30->Fill(rr,rr*up1[l]/down1[l]);
747      //    if(centValue>60.) fh2AngStructpt1C60->Fill(rr,rr*up1[l]/down1[l]);}
748      //    if(down2[l]!=0){  
749      //         if(centValue<10.) fh2AngStructpt2C10->Fill(rr,rr*up2[l]/down2[l]);
750      //    if(centValue>20. && centValue<40.) fh2AngStructpt2C20->Fill(rr,rr*up2[l]/down2[l]);
751      //    if(centValue>30. && centValue<60.) fh2AngStructpt2C30->Fill(rr,rr*up2[l]/down2[l]);
752      //    if(centValue>60.) fh2AngStructpt2C60->Fill(rr,rr*up2[l]/down2[l]);}
753      //    if(down3[l]!=0){  
754      //         if(centValue<10.) fh2AngStructpt3C10->Fill(rr,rr*up3[l]/down3[l]);
755      //    if(centValue>20. && centValue<40.) fh2AngStructpt3C20->Fill(rr,rr*up3[l]/down3[l]);
756      //    if(centValue>30. && centValue<60.) fh2AngStructpt3C30->Fill(rr,rr*up3[l]/down3[l]);
757      //    if(centValue>60.) fh2AngStructpt3C60->Fill(rr,rr*up3[l]/down3[l]);}
758      //    if(down4[l]!=0){  
759      //         if(centValue<10.) fh2AngStructpt4C10->Fill(rr,rr*up4[l]/down4[l]);
760      //    if(centValue>20. && centValue<40.) fh2AngStructpt4C20->Fill(rr,rr*up4[l]/down4[l]);
761      //    if(centValue>30. && centValue<60.) fh2AngStructpt4C30->Fill(rr,rr*up4[l]/down4[l]);
762      //    if(centValue>60.) fh2AngStructpt4C60->Fill(rr,rr*up4[l]/down4[l]);}}}
763
764     
765
766
767
768
769
770    PostData(1, fOutputList);
771 }
772
773 void AliAnalysisTaskJetCore::Terminate(const Option_t *)
774 {
775    // Draw result to the screen
776    // Called once at the end of the query
777
778    if (!GetOutputData(1))
779    return;
780 }
781
782
783
784
785
786
787
788
789
790
791
792 Int_t  AliAnalysisTaskJetCore::GetListOfTracks(TList *list){
793
794     Int_t iCount = 0;
795  
796     
797     for(int it = 0;it < fAOD->GetNumberOfTracks();++it){
798       AliAODTrack *tr = fAOD->GetTrack(it);
799       if((fFilterMask>0)&&!(tr->TestFilterBit(fFilterMask)))continue;
800       if(TMath::Abs(tr->Eta())>0.9)continue;
801       if(tr->Pt()<0.15)continue;
802       list->Add(tr);
803       //cout<<fAOD->GetNumberOfTracks()<<" "<<tr->Pt()<<endl;
804       iCount++;
805     }
806   
807    
808   return iCount;
809  
810 }
811
812    Int_t  AliAnalysisTaskJetCore::GetHardestTrackBackToJet(AliAODJet *jetbig){
813
814    
815     Int_t index=-1;
816     Double_t ptmax=-10;
817     Double_t dphi=0;
818     Double_t dif=0;
819     Int_t iCount=0;
820     for(int it = 0;it < fAOD->GetNumberOfTracks();++it){
821       AliAODTrack *tr = fAOD->GetTrack(it);
822       if((fFilterMask>0)&&!(tr->TestFilterBit(fFilterMask)))continue;
823       if(TMath::Abs(tr->Eta())>0.9)continue;
824       if(tr->Pt()<0.15)continue;
825       iCount=iCount+1;
826       dphi=RelativePhi(tr->Phi(),jetbig->Phi());  
827       if(TMath::Abs(dphi)<TMath::Pi()-0.2) continue;
828       if(tr->Pt()>ptmax){ ptmax=tr->Pt();
829         index=iCount;
830         dif=dphi;  }}
831   
832       return index;
833
834    }
835
836
837
838
839
840
841
842
843
844  Int_t  AliAnalysisTaskJetCore::GetListOfTracksCloseToJet(TList *list,AliAODJet *jetbig){
845
846     Int_t iCount = 0;
847  
848   
849     for(int it = 0;it < fAOD->GetNumberOfTracks();++it){
850       AliAODTrack *tr = fAOD->GetTrack(it);
851       if((fFilterMask>0)&&!(tr->TestFilterBit(fFilterMask)))continue;
852       if(TMath::Abs(tr->Eta())>0.9)continue;
853       if(tr->Pt()<0.15)continue;
854       Double_t disR=jetbig->DeltaR(tr);
855       if(disR>0.8)  continue;
856       list->Add(tr);
857       //cout<<fAOD->GetNumberOfTracks()<<" "<<tr->Pt()<<endl;
858       iCount++;
859     }
860   
861    list->Sort();
862    return iCount;
863
864 }
865
866
867
868
869
870
871
872
873
874
875
876 Int_t AliAnalysisTaskJetCore::GetNInputTracks()
877 {
878
879    Int_t nInputTracks = 0;
880
881    TString jbname(fJetBranchName[1]);
882    //needs complete event, use jets without background subtraction
883    for(Int_t i=1; i<=3; ++i){
884       if(jbname.Contains(Form("B%d",i))) jbname.ReplaceAll(Form("B%d",i),"B0");
885    }
886    // use only HI event
887    if(jbname.Contains("AODextraonly")) jbname.ReplaceAll("AODextraonly","AOD");
888    if(jbname.Contains("AODextra")) jbname.ReplaceAll("AODextra","AOD");
889
890    if(fDebug) Printf("Multiplicity from jet branch %s", jbname.Data());
891    TClonesArray *tmpAODjets = dynamic_cast<TClonesArray*>(fAOD->FindListObject(jbname.Data()));
892    if(!tmpAODjets){
893       Printf("Jet branch %s not found", jbname.Data());
894       Printf("AliAnalysisTaskJetCore::GetNInputTracks FAILED");
895       return -1;
896    }
897    
898    for (Int_t iJet=0; iJet<tmpAODjets->GetEntriesFast(); iJet++){
899       AliAODJet *jet = dynamic_cast<AliAODJet*>((*tmpAODjets)[iJet]);
900       if(!jet) continue;
901       TRefArray *trackList = jet->GetRefTracks();
902       Int_t nTracks = trackList->GetEntriesFast();
903       nInputTracks += nTracks;
904       if(fDebug) Printf("#jet%d: %d tracks", iJet, nTracks);
905    }
906    if(fDebug) Printf("---> input tracks: %d", nInputTracks);
907
908    return nInputTracks;  
909 }
910
911
912
913 Double_t AliAnalysisTaskJetCore::RelativePhi(Double_t mphi,Double_t vphi){
914
915   if (vphi < -1*TMath::Pi()) vphi += (2*TMath::Pi());
916   else if (vphi > TMath::Pi()) vphi -= (2*TMath::Pi());
917   if (mphi < -1*TMath::Pi()) mphi += (2*TMath::Pi());
918   else if (mphi > TMath::Pi()) mphi -= (2*TMath::Pi());
919   double dphi = mphi-vphi;
920   if (dphi < -1*TMath::Pi()) dphi += (2*TMath::Pi());
921   else if (dphi > TMath::Pi()) dphi -= (2*TMath::Pi());
922   return dphi;//dphi in [-Pi, Pi]
923 }
924
925
926
927 THnSparse* AliAnalysisTaskJetCore::NewTHnSparseF(const char* name, UInt_t entries)
928 {
929    // generate new THnSparseF, axes are defined in GetDimParams()
930
931    Int_t count = 0;
932    UInt_t tmp = entries;
933    while(tmp!=0){
934       count++;
935       tmp = tmp &~ -tmp;  // clear lowest bit
936    }
937
938    TString hnTitle(name);
939    const Int_t dim = count;
940    Int_t nbins[dim];
941    Double_t xmin[dim];
942    Double_t xmax[dim];
943
944    Int_t i=0;
945    Int_t c=0;
946    while(c<dim && i<32){
947       if(entries&(1<<i)){
948       
949          TString label("");
950          GetDimParams(i, label, nbins[c], xmin[c], xmax[c]);
951          hnTitle += Form(";%s",label.Data());
952          c++;
953       }
954       
955       i++;
956    }
957    hnTitle += ";";
958
959    return new THnSparseF(name, hnTitle.Data(), dim, nbins, xmin, xmax);
960 }
961
962 void AliAnalysisTaskJetCore::GetDimParams(Int_t iEntry, TString &label, Int_t &nbins, Double_t &xmin, Double_t &xmax)
963 {
964    // stores label and binning of axis for THnSparse
965
966    const Double_t pi = TMath::Pi();
967    
968    switch(iEntry){
969       
970    case 0:
971       label = "V0 centrality (%)";
972      
973          nbins = 10;
974          xmin = 0.;
975          xmax = 100.;
976          break;
977       
978       
979    case 1:
980       label = "corrected jet pt";
981          nbins = 50;
982          xmin = 0.;
983          xmax = 200.;
984           break;
985       
986       
987    case 2:
988       label = "track pT";
989      
990          nbins = 1000;
991          xmin = 0.;
992          xmax = 50;
993          break;
994       
995       
996     case 3:
997       label = "deltaR";
998       nbins = 15;
999       xmin = 0.;
1000       xmax = 1.5;
1001       break;
1002
1003
1004
1005    case 4:
1006       label = "deltaEta";
1007       nbins = 30;
1008       xmin = -1.5;
1009       xmax = 1.5;
1010       break;
1011
1012
1013   case 5:
1014       label = "deltaPhi";
1015       nbins = 90;
1016       xmin = -0.5*pi;
1017       xmax = 1.5*pi;
1018       break;   
1019    
1020       
1021         
1022     case 6:
1023       label = "leading track";
1024       nbins = 50;
1025       xmin = 0;
1026       xmax = 50;
1027       break;
1028            
1029      case 7:
1030     
1031       label = "trigger track";
1032       nbins =50;
1033       xmin = 0;
1034       xmax = 50;
1035       break;
1036
1037
1038    
1039   
1040
1041
1042
1043
1044    }
1045
1046 }
1047