]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWG/DevNanoAOD/AliNanoAODReplicator.cxx
Adding back file removed by mistake
[u/mrichter/AliRoot.git] / PWG / DevNanoAOD / AliNanoAODReplicator.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: AliNanoAODReplicator.cxx 56492 2012-05-15 18:42:47Z pcrochet $
17
18 // Implementation of a branch replicator 
19 // to produce nanoAODs.
20 //
21 //
22 // This replicator is in charge of replicating the tracks,vertices,headers
23 // branches of a standard AOD or ESD file into a nanoAODs 
24 // (AliAOD.Special.root)
25 // 
26 // The class was inspired by AliAODMuonReplicator
27 // 
28 // Author: Michele Floris, michele.floris@cern.ch
29
30
31 class AliESDv0;
32 class AliESDVertex;
33 class AliAODVertex;
34 class AliAODRecoDecay;
35
36 #include "AliAODDimuon.h"
37 #include "AliAODEvent.h"
38 #include "AliAODMCHeader.h"
39 #include "AliAODMCParticle.h"
40 #include "AliAODTZERO.h"
41 #include "AliAODTrack.h"
42 #include "AliAODVZERO.h"
43 #include "AliAnalysisCuts.h"
44 #include "TF1.h"
45 #include "AliExternalTrackParam.h"
46 #include "AliESDv0.h"
47 #include "AliAODv0.h"
48 #include "AliPIDResponse.h"
49 #include <iostream>
50 #include <cassert>
51 #include "AliESDtrack.h"
52 #include "TObjArray.h"
53 #include "AliAnalysisFilter.h"
54 #include "AliNanoAODTrack.h"
55
56 #include <TFile.h>
57 #include <TDatabasePDG.h>
58 #include <TString.h>
59 #include <TList.h>
60 #include "AliLog.h"
61 #include "AliVEvent.h"
62 #include "AliVVertex.h"
63 #include "AliVTrack.h"
64 #include "AliVertexerTracks.h"
65 #include "AliKFVertex.h"
66 #include "AliESDEvent.h"
67 #include "AliESDVertex.h"
68 #include "AliESDtrackCuts.h"
69 #include "AliAODEvent.h"
70 #include "AliAnalysisFilter.h"
71
72 #include "AliNanoAODReplicator.h"
73 #include "TH1.h"
74 #include "TCanvas.h"
75 #include "AliNanoAODHeader.h"
76 #include "AliNanoAODCustomSetter.h"
77
78 using std::cout;
79 using std::endl;
80
81 ClassImp(AliNanoAODReplicator)
82
83 //_____________________________________________________________________________
84 AliNanoAODReplicator::AliNanoAODReplicator() :
85 AliAODBranchReplicator(), 
86   fTrackCut(0), fTracks(0x0), fHeader(0x0), fNTracksVariables(0), // FIXME: Start using cuts, and check if fNTracksVariables is needed
87   fVertices(0x0), 
88   fList(0x0),
89   fMCParticles(0x0),
90   fMCHeader(0x0),
91   fMCMode(0),
92   fLabelMap(),
93   fParticleSelected(),
94   fVarList(""),
95   fVarListHeader(""),
96   fCustomSetter(0){
97   // Default ctor. we need it to avoid instantiating a wrong mapping when reading from file 
98   }
99
100 AliNanoAODReplicator::AliNanoAODReplicator(const char* name, const char* title,
101                                            const char * varlist,
102                                            AliAnalysisCuts* trackCut,
103                                            Int_t mcMode
104                                              ) :
105   AliAODBranchReplicator(name,title), 
106
107   fTrackCut(trackCut), fTracks(0x0), fHeader(0x0), fNTracksVariables(0), // FIXME: Start using cuts, and check if fNTracksVariables is needed
108   fVertices(0x0), 
109   fList(0x0),
110   fMCParticles(0x0),
111   fMCHeader(0x0),
112   fMCMode(mcMode),
113   fLabelMap(),
114   fParticleSelected(),
115   fVarList(varlist),
116   fVarListHeader(""),// FIXME: this should be set to a meaningful value: add an arg to the constructor
117   fCustomSetter(0)
118 {
119   // default ctor
120   AliNanoAODTrackMapping * tm =new AliNanoAODTrackMapping(fVarList);
121   fNTracksVariables = tm->GetSize();  
122   //  tm->Print();
123 }
124
125 //_____________________________________________________________________________
126 AliNanoAODReplicator::~AliNanoAODReplicator()
127 {
128   // dtor
129   delete fTrackCut;
130   delete fList;
131 }
132
133 //_____________________________________________________________________________
134 void AliNanoAODReplicator::SelectParticle(Int_t i)
135 {
136   // taking the absolute values here, need to take care 
137   // of negative daughter and mother
138   // IDs when setting!
139   
140   if (!IsParticleSelected(TMath::Abs(i)))
141   {
142     fParticleSelected.Add(TMath::Abs(i),1);    
143   }
144 }
145
146 //_____________________________________________________________________________
147 Bool_t AliNanoAODReplicator::IsParticleSelected(Int_t i)  
148 {
149   // taking the absolute values here, need to take 
150   // care with negative daughter and mother
151   // IDs when setting!
152   return (fParticleSelected.GetValue(TMath::Abs(i))==1);
153 }
154
155
156 //_____________________________________________________________________________
157 void AliNanoAODReplicator::CreateLabelMap(const AliAODEvent& source)
158 {  
159   //
160   // this should be called once all selections are done 
161   // This method associates to the original index of the mc particle
162   // (i) the new one (j). J runs only over particles which are
163   // actually kept.
164   //
165   
166   fLabelMap.Delete();
167   
168   TClonesArray* mcParticles = static_cast<TClonesArray*>(source.FindListObject(AliAODMCParticle::StdBranchName()));
169   
170   Int_t j(0);
171   Int_t i(0); // We need i, we cannot rely on part->GetLabel, because some of the original mc particles are not kept in the stack, apparently
172   
173   TIter next(mcParticles);
174
175   while ( next() )
176   {
177     if (IsParticleSelected(i))
178     {
179       fLabelMap.Add(i,j++);
180       //      std::cout << i <<  "->" << j-1 << std::endl;
181     }
182     ++i;
183   }  
184
185
186 }
187
188 //_____________________________________________________________________________
189 Int_t AliNanoAODReplicator::GetNewLabel(Int_t i) 
190 {
191   // Gets the label from the new created Map
192   // Call CreatLabelMap before
193   // otherwise only 0 returned
194   return fLabelMap.GetValue(TMath::Abs(i));
195 }
196
197 //_____________________________________________________________________________
198 void AliNanoAODReplicator::FilterMC(const AliAODEvent& source)
199 {
200   // Filter MC information
201
202
203   AliAODMCHeader* mcHeader(0x0);
204   TClonesArray* mcParticles(0x0);
205   
206   fParticleSelected.Delete();
207
208   //  std::cout << "MC Mode: " << fMCMode << ", Tracks " << fTracks->GetEntries() << std::endl;
209   
210   if ( fMCMode>=2 && !fTracks->GetEntries() ) {
211     return;
212   }
213   // for fMCMode==1 we only copy MC information for events where there's at least one muon track
214     
215   mcHeader = static_cast<AliAODMCHeader*>(source.FindListObject(AliAODMCHeader::StdBranchName()));
216   
217   if ( mcHeader ) 
218     {
219       *fMCHeader = *mcHeader;
220     }
221   
222   
223   mcParticles = static_cast<TClonesArray*>(source.FindListObject(AliAODMCParticle::StdBranchName()));
224   
225   if ( mcParticles && fMCMode>=2 )
226     {
227       // keep all primaries
228       TIter nextPart(mcParticles);
229       static Int_t iev = -1; // FIXME: remove this (debug)
230       iev ++;
231       AliAODMCParticle * prim = 0;
232       Int_t iprim = 0;  // We need iprim, we cannot rely on part->GetLabel, because some of the original mc particles are not kept in the stack, apparently
233       // also select all charged primaries 
234       while ((prim = (AliAODMCParticle*) nextPart())) {
235         if(prim->IsPhysicalPrimary() && prim->Charge()) SelectParticle(iprim);
236         // FIXME DEBUG
237         if(iev == 2009) {
238           // std::cout << "IEV " << iev << std::endl;
239           // std::cout << " PART " << iprim << " " << prim->IsPhysicalPrimary() <<","<<prim->Charge() << "=" << IsParticleSelected(iprim) <<  std::endl;
240           if(iprim == 15) {
241             prim->Print();
242           }
243           
244         }
245         iprim++;
246       } 
247
248       // loop on (kept) tracks to find their ancestors
249       TIter nextTRACK(fTracks);
250       AliNanoAODTrack* track;
251     
252       while ( ( track = static_cast<AliNanoAODTrack*>(nextTRACK()) ) )
253         {
254           Int_t label = TMath::Abs(track->GetLabel()); 
255       
256           while ( label >= 0 ) 
257             {
258               SelectParticle(label);
259               AliAODMCParticle* mother = static_cast<AliAODMCParticle*>(mcParticles->UncheckedAt(label));
260               if (!mother)
261                 {
262                   AliError(Form("Got a null mother ! Check that ! (label %d",label)); // FIXME: I think this error is not needed
263                   label = -1;
264                 }
265               else
266                 {
267                   label = mother->GetMother();// do not only keep particles which created a track, but all their mothers
268                 }
269             }
270         }
271     
272       CreateLabelMap(source);
273     
274       // Actual filtering and label remapping (shamelessly taken for the implementation of AliAODHandler::StoreMCParticles)
275       TIter nextMC(mcParticles);
276       AliAODMCParticle* p;
277       Int_t nmc(0);  // We need nmc, we cannot rely on part->GetLabel, because some of the original mc particles are not kept in the stack, apparently
278       Int_t nmcout(0);
279     
280       while ( ( p = static_cast<AliAODMCParticle*>(nextMC()) ) )
281         {
282           AliAODMCParticle c(*p);
283
284           if ( IsParticleSelected(nmc) )
285             {
286               // 
287               Int_t d0 =  p->GetDaughter(0);
288               Int_t d1 =  p->GetDaughter(1);
289               Int_t m =   p->GetMother();
290         
291               // other than for the track labels, negative values mean
292               // no daughter/mother so preserve it
293         
294               if(d0<0 && d1<0)
295                 {
296                   // no first daughter -> no second daughter
297                   // nothing to be done
298                   // second condition not needed just for sanity check at the end
299                   c.SetDaughter(0,d0);
300                   c.SetDaughter(1,d1);
301                 } else if(d1 < 0 && d0 >= 0) 
302                 {
303                   // Only one daughter
304                   // second condition not needed just for sanity check at the end
305                   if(IsParticleSelected(d0))
306                     {
307                       c.SetDaughter(0,GetNewLabel(d0));
308                     } else 
309                     {
310                       c.SetDaughter(0,-1);
311                     }
312                   c.SetDaughter(1,d1);
313                 }
314               else if (d0 > 0 && d1 > 0 )
315                 {
316                   // we have two or more daughters loop on the stack to see if they are
317                   // selected
318                   Int_t d0tmp = -1;
319                   Int_t d1tmp = -1;
320                   for (int id = d0; id<=d1;++id)
321                     {
322                       if (IsParticleSelected(id))
323                         {
324                           if(d0tmp==-1)
325                             {
326                               // first time
327                               d0tmp = GetNewLabel(id);
328                               d1tmp = d0tmp; // this is to have the same schema as on the stack i.e. with one daugther d0 and d1 are the same 
329                             }
330                           else d1tmp = GetNewLabel(id);
331                         }
332                     }
333                   c.SetDaughter(0,d0tmp);
334                   c.SetDaughter(1,d1tmp);
335                 } else 
336                 {
337                   AliFatal(Form("Unxpected indices %d %d",d0,d1));
338                 }
339         
340               if ( m < 0 )
341                 {
342                   c.SetMother(m);
343                 } else 
344                 {
345                   if (IsParticleSelected(m)) 
346                     {
347                       c.SetMother(GetNewLabel(m));              
348                     }
349                   // else // FIXME: re-enable this checj. Sometimes it gets here. Still to be understood why
350                   //   {
351                   //     //                   AliError(Form("PROBLEM Mother not selected %d", m));              
352                   //   }
353                 }
354         
355               new ((*fMCParticles)[nmcout++]) AliAODMCParticle(c);
356             }
357       
358           ++nmc;        
359         } //closes loop over MC particles
360     
361       // now remap the tracks...
362     
363       TIter nextTrack(fTracks);
364       AliNanoAODTrack* t;
365       //      std::cout << "Remapping tracks" << std::endl;
366     
367       while ( ( t = dynamic_cast<AliNanoAODTrack*>(nextTrack()) ) )
368         {
369           
370           t->SetLabel(GetNewLabel(t->GetLabel()));
371         }
372     
373     } // closes fMCMode == 1
374   else if ( mcParticles ) 
375     {
376       // simple copy of input MC particles to ouput MC particles
377       TIter nextMC(mcParticles);
378       AliAODMCParticle* p;
379       Int_t nmcout(0);
380     
381       while ( ( p = static_cast<AliAODMCParticle*>(nextMC()) ) )
382         {
383           new ((*fMCParticles)[nmcout++]) AliAODMCParticle(*p);
384         }
385     }
386   
387   AliDebug(1,Form("input mc %d output mc %d",
388                   mcParticles ? mcParticles->GetEntries() : 0,
389                   fMCParticles ? fMCParticles->GetEntries() : 0));
390   
391   Printf("input mc %d output mc %d",
392                   mcParticles ? mcParticles->GetEntries() : 0,
393                   fMCParticles ? fMCParticles->GetEntries() : 0);
394   
395
396 }
397
398 // //_____________________________________________________________________________
399 TList* AliNanoAODReplicator::GetList() const
400 {
401   // return (and build if not already done) our internal list of managed objects
402   
403   if (!fList)
404     {
405       fList = new TList;
406       fList->SetOwner(kTRUE);
407
408       fTracks = new TClonesArray("AliNanoAODTrack");      
409       fTracks->SetName("tracks"); // TODO: consider the possibility to use a different name to distinguish in AliAODEvent
410       fList->Add(fTracks);    
411
412       fHeader = new AliNanoAODHeader(2);// TODO: to be customized
413       fHeader->SetName("header"); // TODO: consider the possibility to use a different name to distinguish in AliAODEvent
414       fList->Add(fHeader);    
415
416
417       fVertices = new TClonesArray("AliAODVertex",2);
418       fVertices->SetName("vertices");    
419     
420         
421       fList->Add(fVertices);
422     
423       if ( fMCMode > 0 )
424         {
425           fMCHeader = new AliAODMCHeader;    
426           fMCParticles = new TClonesArray("AliAODMCParticle",1000);
427           fMCParticles->SetName(AliAODMCParticle::StdBranchName());
428           fList->Add(fMCHeader);
429           fList->Add(fMCParticles);
430         }
431     }
432   return fList;
433 }
434
435 //_____________________________________________________________________________
436 void AliNanoAODReplicator::ReplicateAndFilter(const AliAODEvent& source)
437 //void AliNanoAODReplicator::ReplicateAndFilter(AliAODEvent *source)
438 {
439   // Replicate (and filter if filters are there) the relevant parts we're interested in AODEvent
440   
441
442   // assert(fTracks!=0x0);
443   
444   //*fTZERO = *(source.GetTZEROData());
445   
446   
447
448   fTracks->Clear("C");                  
449   assert(fVertices!=0x0);
450   fVertices->Clear("C");
451   if (fMCMode > 0){
452     if(!fMCHeader) {
453       AliFatal(Form("fMCMode = %d, but MC header not found", fMCMode));
454     }
455     fMCHeader->Reset();
456     if(!fMCParticles){
457       AliFatal(Form("fMCMode = %d, but MC particles not found", fMCMode));
458     }
459     fMCParticles->Clear("C");
460   }
461   Int_t ntracks(0);
462   Int_t input(0);
463
464   AliAODVertex *vtx = source.GetPrimaryVertex();
465
466   // TODO: implement header!
467   //  *fHeader = *source.GetHeader();
468   if(fCustomSetter){
469     // Set custom variables in the header if the callback is set
470     fCustomSetter->SetNanoAODHeader(&source, fHeader);
471   }
472
473
474   //  Int_t nindices=0;
475   const Int_t entries = source.GetNumberOfTracks();
476
477   Double_t pos[3],cov[6];
478   vtx->GetXYZ(pos);
479   vtx->GetCovarianceMatrix(cov);
480   
481   if(entries<=0) return;
482
483   if(vtx->GetNContributors()<1) {
484     // SPD vertex cut
485     vtx =source.GetPrimaryVertexSPD();    
486     if(vtx->GetNContributors()<1) { // FIXME: Keep this cut?
487       Info("AliNanoAODReplicator","No good vertex, skip event");
488       return; // NO GOOD VERTEX, SKIP EVENT 
489     }
490   }
491   
492   
493   for(Int_t j=0; j<entries; j++){
494     
495     AliVTrack *track = (AliVTrack*)source.GetTrack(j);
496     
497     AliAODTrack *aodtrack =(AliAODTrack*)track;// FIXME DYNAMIC CAST?
498     if(!fTrackCut->IsSelected(aodtrack)) continue;
499
500     AliNanoAODTrack * special = new  AliNanoAODTrack (aodtrack, fVarList);
501     
502     if(fCustomSetter) fCustomSetter->SetNanoAODTrack(aodtrack, special);
503     (*fTracks)[ntracks++] = special;
504     //new((*fTracks)[ntrac\ks++])
505   }  
506   //----------------------------------------------------------
507   
508   TIter nextV(source.GetVertices());
509   AliAODVertex* v;
510   Int_t nvertices(0);
511   
512   while ( ( v = static_cast<AliAODVertex*>(nextV()) ) )
513     {
514       AliAODVertex* tmp = v->CloneWithoutRefs();
515       AliAODVertex* copiedVertex = new((*fVertices)[nvertices++]) AliAODVertex(*tmp);
516       
517       // to insure the main vertex retains the ncontributors information
518       // (which is otherwise computed dynamically from
519       // references to tracks, which we do not keep in muon aods...)
520       // we set it here
521       
522       copiedVertex->SetNContributors(v->GetNContributors()); 
523       
524       //  fVertices->Delete();
525       //          delete copiedVertex;
526       delete tmp;
527     }
528   
529   
530   AliDebug(1,Form("input mu tracks=%d tracks=%d vertices=%d",
531                   input,fTracks->GetEntries(),fVertices->GetEntries())); 
532   
533   
534   // Finally, deal with MC information, if needed
535   
536   if ( fMCMode > 0 ) {
537     FilterMC(source);      
538   }
539   
540
541 }
542
543
544
545 //-----------------------------------------------------------------------------
546
547 //----------------------------------------------------------------------------
548         
549
550 //-----------------------------------------------------------------------------
551
552 // AliAODVertex* AliNanoAODReplicator::PrimaryVertex(const TObjArray *trkArray,
553 //                                                 AliAODEvent &event) const
554 // {
555 //   // Returns primary vertex to be used for this candidate
556 //   //AliCodeTimerAuto("",0);
557
558 //   AliESDVertex *vertexESD = 0;
559 //   AliAODVertex *vertexAOD = 0;
560
561
562 //   if(!fRecoPrimVtxSkippingTrks && !fRmTrksFromPrimVtx) { 
563 //     // primary vertex from the input event
564     
565 //     vertexESD = new AliESDVertex(*fV1);
566
567 //   } else {
568 //     // primary vertex specific to this candidate
569
570 //     Int_t nTrks = trkArray->GetEntriesFast();
571 //     AliVertexerTracks *vertexer = new AliVertexerTracks(event.GetMagneticField());
572
573 //     if(fRecoPrimVtxSkippingTrks) { 
574 //       // recalculating the vertex
575       
576 //       if(strstr(fV1->GetTitle(),"VertexerTracksWithConstraint")) {
577 //      Float_t diamondcovxy[3];
578 //      event.GetDiamondCovXY(diamondcovxy);
579 //      Double_t pos[3]={event.GetDiamondX(),event.GetDiamondY(),0.};
580 //      Double_t cov[6]={diamondcovxy[0],diamondcovxy[1],diamondcovxy[2],0.,0.,10.*10.};
581 //      AliESDVertex *diamond = new AliESDVertex(pos,cov,1.,1);
582 //      vertexer->SetVtxStart(diamond);
583 //      delete diamond; diamond=NULL;
584 //      if(strstr(fV1->GetTitle(),"VertexerTracksWithConstraintOnlyFitter")) 
585 //        vertexer->SetOnlyFitter();
586 //       }
587 //       Int_t skipped[1000];
588 //       Int_t nTrksToSkip=0,id;
589 //       AliExternalTrackParam *t = 0;
590 //       for(Int_t i=0; i<nTrks; i++) {
591 //      t = (AliExternalTrackParam*)trkArray->UncheckedAt(i);
592 //      id = (Int_t)t->GetID();
593 //      if(id<0) continue;
594 //      skipped[nTrksToSkip++] = id;
595 //       }
596 //       // TEMPORARY FIX
597 //       // For AOD, skip also tracks without covariance matrix
598 //       if(fInputAOD) {
599 //      Double_t covtest[21];
600 //      for(Int_t j=0; j<event.GetNumberOfTracks(); j++) {
601 //        AliVTrack *vtrack = (AliVTrack*)event.GetTrack(j);
602 //        if(!vtrack->GetCovarianceXYZPxPyPz(covtest)) {
603 //          id = (Int_t)vtrack->GetID();
604 //          if(id<0) continue;
605 //          skipped[nTrksToSkip++] = id;
606 //        }
607 //      }
608 //       }
609 //       for(Int_t ijk=nTrksToSkip; ijk<1000; ijk++) skipped[ijk]=-1;
610 //       //
611 //       vertexer->SetSkipTracks(nTrksToSkip,skipped);
612 //       vertexESD = (AliESDVertex*)vertexer->FindPrimaryVertex(event); 
613       
614 //     } else if(fRmTrksFromPrimVtx && nTrks>0) { 
615 //       // removing the prongs tracks
616       
617 //       TObjArray rmArray(nTrks);
618 //       UShort_t *rmId = new UShort_t[nTrks];
619 //       AliESDtrack *esdTrack = 0;
620 //       AliESDtrack *t = 0;
621 //       for(Int_t i=0; i<nTrks; i++) {
622 //      t = (AliESDtrack*)trkArray->UncheckedAt(i);
623 //      esdTrack = new AliESDtrack(*t);
624 //      rmArray.AddLast(esdTrack);
625 //      if(esdTrack->GetID()>=0) {
626 //        rmId[i]=(UShort_t)esdTrack->GetID();
627 //      } else {
628 //        rmId[i]=9999;
629 //      }
630 //       }
631 //       Float_t diamondxy[2]={event.GetDiamondX(),event.GetDiamondY()};
632 //       vertexESD = vertexer->RemoveTracksFromVertex(fV1,&rmArray,rmId,diamondxy);
633 //       delete [] rmId; rmId=NULL;
634 //       rmArray.Delete();
635       
636 //     }
637
638 //     if(!vertexESD) return vertexAOD;
639 //     if(vertexESD->GetNContributors()<=0) { 
640 //       //AliDebug(2,"vertexing failed"); 
641 //       delete vertexESD; vertexESD=NULL;
642 //       return vertexAOD;
643 //     }
644
645 //     delete vertexer; vertexer=NULL;
646
647 //   }
648
649 //   // convert to AliAODVertex
650 //   Double_t pos[3],cov[6],chi2perNDF;
651 //   vertexESD->GetXYZ(pos); // position
652 //   vertexESD->GetCovMatrix(cov); //covariance matrix
653 //   chi2perNDF = vertexESD->GetChi2toNDF();
654 //   delete vertexESD; vertexESD=NULL;
655
656 //   vertexAOD = new AliAODVertex(pos,cov,chi2perNDF);
657
658 //   return vertexAOD;
659 // }
660
661 //_____________________________________________________________________________
662
663
664
665 // //---------------------------------------------------------------------------
666
667 void AliNanoAODReplicator::Terminate(){
668
669 }