Added classes for UPC analysis
authorjaroslav <jaroslav.adam@cern.ch>
Sat, 13 Dec 2014 20:18:15 +0000 (21:18 +0100)
committerjaroslav <jaroslav.adam@cern.ch>
Sat, 13 Dec 2014 20:30:22 +0000 (21:30 +0100)
PWGUD/UPC/AddTaskUpcFilter.C [new file with mode: 0644]
PWGUD/UPC/AliAnalysisTaskUpcFilterSemiforward.cxx [new file with mode: 0644]
PWGUD/UPC/AliAnalysisTaskUpcFilterSemiforward.h [new file with mode: 0644]
PWGUD/UPC/AliUPCEvent.cxx [new file with mode: 0644]
PWGUD/UPC/AliUPCEvent.h [new file with mode: 0644]
PWGUD/UPC/AliUPCMuonTrack.cxx [new file with mode: 0644]
PWGUD/UPC/AliUPCMuonTrack.h [new file with mode: 0644]
PWGUD/UPC/AliUPCTrack.cxx [new file with mode: 0644]
PWGUD/UPC/AliUPCTrack.h [new file with mode: 0644]

diff --git a/PWGUD/UPC/AddTaskUpcFilter.C b/PWGUD/UPC/AddTaskUpcFilter.C
new file mode 100644 (file)
index 0000000..be60513
--- /dev/null
@@ -0,0 +1,42 @@
+AliAnalysisTaskUpcFilterSemiforward *AddTaskUpcFilter() {
+  //--- get the current analysis manager ---//
+  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+  if (!mgr) {
+      Error("AddTask_UpcFilter", "No analysis manager found.");
+      return 0;
+   }
+  
+  // Check the analysis type using the event handlers connected to the analysis manager.
+  //==============================================================================
+  if (!mgr->GetInputEventHandler()) {
+    Error("AddTask_UpcFilter", "This task requires an input event handler");
+    return 0;
+  }
+
+  Bool_t isESD = kFALSE;
+  TString inputDataType = mgr->GetInputEventHandler()->GetDataType();
+  if( inputDataType.Contains("ESD") ) isESD = kTRUE;
+  Bool_t isMC = kFALSE;
+  if( mgr->GetMCtruthEventHandler() ) isMC = kTRUE;
+
+  // Create tasks
+  AliAnalysisTaskUpcFilterSemiforward *task = new AliAnalysisTaskUpcFilterSemiforward();
+  task->SetIsESD( isESD );
+  task->SetIsMC( isMC );
+  mgr->AddTask(task);
+
+  // Create containers for input/output
+  AliAnalysisDataContainer *cinput = mgr->GetCommonInputContainer();
+  AliAnalysisDataContainer *coutput = mgr->CreateContainer("UPCTree", TTree::Class(), AliAnalysisManager::kOutputContainer, Form("%s:UpcFilter", AliAnalysisManager::GetCommonFileName()));
+  AliAnalysisDataContainer *coutput2 = mgr->CreateContainer("HistList", TList::Class(), AliAnalysisManager::kOutputContainer, Form("%s:UpcFilter", AliAnalysisManager::GetCommonFileName()));
+
+  // Connect input/output
+  mgr->ConnectInput(task, 0, cinput);
+  mgr->ConnectOutput(task, 1, coutput);
+  mgr->ConnectOutput(task, 2, coutput2);
+
+return task;
+
+}
+
diff --git a/PWGUD/UPC/AliAnalysisTaskUpcFilterSemiforward.cxx b/PWGUD/UPC/AliAnalysisTaskUpcFilterSemiforward.cxx
new file mode 100644 (file)
index 0000000..ee58bc9
--- /dev/null
@@ -0,0 +1,746 @@
+
+//_____________________________________________________________________________
+//    Class for semiforward UPC filter
+//    Author: Jaroslav Adam
+//
+//    Fill structure of AliUPCEvent
+//_____________________________________________________________________________
+
+// c++ headers
+#include <iostream>
+#include <string.h>
+
+// root headers
+#include "TList.h"
+#include "TH1I.h"
+#include "TTree.h"
+#include "TClonesArray.h"
+#include "TParticle.h"
+#include "TObjString.h"
+#include "TFile.h"
+#include "TArrayF.h"
+
+// aliroot headers
+#include "AliAnalysisManager.h"
+#include "AliInputEventHandler.h"
+#include "AliESDEvent.h"
+#include "AliAODEvent.h"
+#include "AliMCEvent.h"
+#include "AliAODVZERO.h"
+#include "AliAODZDC.h"
+#include "AliAODVertex.h"
+#include "AliESDVZERO.h"
+#include "AliESDZDC.h"
+#include "AliESDVertex.h"
+#include "AliAODTrack.h"
+#include "AliMultiplicity.h"
+#include "AliESDtrack.h"
+#include "AliESDMuonTrack.h"
+#include "AliAODMCParticle.h"
+#include "AliMCParticle.h"
+#include "AliTriggerAnalysis.h"
+#include "AliMuonTrackCuts.h"
+#include "AliESDtrackCuts.h"
+#include "AliAODPid.h"
+#include "AliGenEventHeader.h"
+#include "AliAODMCHeader.h"
+
+// my headers
+#include "AliAnalysisTaskUpcFilterSemiforward.h"
+#include "AliUPCTrack.h"
+#include "AliUPCMuonTrack.h"
+#include "AliUPCEvent.h"
+
+ClassImp(AliAnalysisTaskUpcFilterSemiforward);
+
+// task for upc semiforward filter
+// jaroslav.adam@cern.ch
+
+//_____________________________________________________________________________
+AliAnalysisTaskUpcFilterSemiforward::AliAnalysisTaskUpcFilterSemiforward(const char *name)
+ :AliAnalysisTaskSE(name),
+  fIsESD(0), fIsMC(0), fMuonCuts(0x0), fTriggerAna(0x0), fCutsList(0x0),
+  fHistList(0x0), fCounter(0x0), fTriggerCounter(0x0),
+  fUPCEvent(0x0), fUPCTree(0x0)
+{
+
+  // Constructor
+
+  DefineOutput(1, TTree::Class());
+  DefineOutput(2, TList::Class());
+
+}//AliAnalysisTaskUpcFilterSemiforward
+
+//_____________________________________________________________________________
+AliAnalysisTaskUpcFilterSemiforward::~AliAnalysisTaskUpcFilterSemiforward()
+{
+  // destructor
+
+  if(fHistList) {delete fHistList; fHistList = 0x0;}
+  if(fCounter) {delete fCounter; fCounter = 0x0;}
+  if(fTriggerCounter) {delete fTriggerCounter; fTriggerCounter = 0x0;}
+  if(fUPCEvent) {delete fUPCEvent; fUPCEvent = 0x0;}
+  if(fUPCTree) {delete fUPCTree; fUPCTree = 0x0;}
+  if(fMuonCuts) {delete fMuonCuts; fMuonCuts = 0x0;}
+  if(fTriggerAna) {delete fTriggerAna; fTriggerAna = 0x0;}
+  if(fCutsList) {delete[] fCutsList; fCutsList=0x0;}
+
+}//~AliAnalysisTaskUpcFilterSemiforward
+
+//_____________________________________________________________________________
+void AliAnalysisTaskUpcFilterSemiforward::UserCreateOutputObjects()
+{
+  //muon track cuts
+  fMuonCuts = new AliMuonTrackCuts("StdMuonCuts", "StdMuonCuts");
+  fMuonCuts->SetFilterMask ( AliMuonTrackCuts::kMuPdca );
+  fMuonCuts->Print("mask");
+  fMuonCuts->SetAllowDefaultParams(kTRUE);
+  fMuonCuts->SetPassName("muon_pass2");
+
+  //trigger analysis for SPD FO fired chips in MC
+  fTriggerAna = new AliTriggerAnalysis();
+  fTriggerAna->SetAnalyzeMC( fIsMC );
+
+  //ESD track cuts
+  if( fIsESD ) {
+    fCutsList = new AliESDtrackCuts*[32];
+    for(UInt_t i=0; i<32; i++) fCutsList[i] = 0x0;
+
+    // bits 0 - 10 set in $ALICE_ROOT/ANALYSIS/ESDfilter/macros/AddTaskESDFilter.C
+
+    // Cuts on primary tracks
+    AliESDtrackCuts* esdTrackCutsL = AliESDtrackCuts::GetStandardTPCOnlyTrackCuts();
+    fCutsList[0] = esdTrackCutsL;
+
+    // standard cuts with very loose DCA
+    AliESDtrackCuts* esdTrackCutsH = AliESDtrackCuts::GetStandardITSTPCTrackCuts2011(kFALSE); 
+    esdTrackCutsH->SetMaxDCAToVertexXY(2.4);
+    esdTrackCutsH->SetMaxDCAToVertexZ(3.2);
+    esdTrackCutsH->SetDCAToVertex2D(kTRUE);
+    fCutsList[4] = esdTrackCutsH;
+
+    // standard cuts with tight DCA cut
+    AliESDtrackCuts *esdTrackCutsH2 = AliESDtrackCuts::GetStandardITSTPCTrackCuts2011();
+    fCutsList[5] = esdTrackCutsH2;
+
+    // bits 11 - 31 free
+
+    // selection by Daniele, UPC meeting, 15 July 2014
+    // https://indico.cern.ch/event/330483/contribution/3/material/slides/0.pdf
+
+    AliESDtrackCuts *cuts11 = new AliESDtrackCuts();
+    cuts11->SetMinNClustersTPC(70);
+    cuts11->SetRequireTPCRefit(kTRUE);
+    cuts11->SetRequireITSRefit(kTRUE);
+    cuts11->SetMaxChi2PerClusterTPC(4);
+    cuts11->SetAcceptKinkDaughters(kFALSE);
+    cuts11->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+    cuts11->SetMaxDCAToVertexXYPtDep("0.0105+0.0350/pt^1.01");
+    cuts11->SetMaxDCAToVertexZ(2);
+    cuts11->SetDCAToVertex2D(kFALSE);
+    cuts11->SetRequireSigmaToVertex(kFALSE);
+    cuts11->SetMaxChi2PerClusterITS(5.);
+    fCutsList[11] = cuts11;
+
+    AliESDtrackCuts *cuts12 = new AliESDtrackCuts();
+    cuts12->SetMinNClustersTPC(70);
+    cuts12->SetRequireTPCRefit(kTRUE);
+    cuts12->SetRequireITSRefit(kTRUE);
+    cuts12->SetMaxChi2PerClusterTPC(4);
+    cuts12->SetAcceptKinkDaughters(kFALSE);
+    cuts12->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+    cuts12->SetMaxDCAToVertexXYPtDep("0.0105+0.0350/pt^1.01");
+    cuts12->SetMaxDCAToVertexZ(2);
+    cuts12->SetDCAToVertex2D(kFALSE);
+    cuts12->SetRequireSigmaToVertex(kFALSE);
+    fCutsList[12] = cuts12;
+
+    // setting in Evgeny's trees
+    AliESDtrackCuts *cuts13 = AliESDtrackCuts::GetStandardITSTPCTrackCuts2011();
+    cuts13->SetMaxChi2TPCConstrainedGlobal(1e+10);
+    fCutsList[13] = cuts13;
+
+  }
+
+  //output histograms
+  fHistList = new TList();
+  fHistList->SetOwner();
+  fCounter = new TH1I("fCounter", "fCounter", 30, 1, 31);
+  fHistList->Add(fCounter);
+  fTriggerCounter = new TH2I("fTriggerCounter", "fTriggerCounter", 3000, 195000, 198000, NTRG+1, 0, NTRG+1);
+  fHistList->Add(fTriggerCounter);
+
+  //output tree
+  fUPCEvent  = new AliUPCEvent();
+  fUPCEvent->SetIsMC( fIsMC );
+  fUPCEvent->SetIsESD( fIsESD );
+
+  TDirectory *pwd = gDirectory;
+  OpenFile(1);
+  fUPCTree = new TTree("fUPCTree", "fUPCTree");
+  pwd->cd();
+  fUPCTree->Branch("fUPCEvent", &fUPCEvent);
+
+  PostData(1, fUPCTree);
+  PostData(2, fHistList);
+
+}//UserCreateOutputObjects
+
+//_____________________________________________________________________________
+void AliAnalysisTaskUpcFilterSemiforward::NotifyRun()
+{
+
+  //cout<<"AliAnalysisTaskUpcFilterSemiforward::NotifyRun()"<<endl;
+
+  fMuonCuts->SetRun(fInputHandler); // use input handler from AliAnalysisTaskSE
+
+  if( fIsESD ) { ((AliESDEvent*) InputEvent())->InitMagneticField(); }
+
+}//NotifyRun
+
+//_____________________________________________________________________________
+void AliAnalysisTaskUpcFilterSemiforward::UserExec(Option_t *) 
+{
+
+  //cout<<"#################### Next event ##################"<<endl;
+
+  // input event
+  AliVEvent *vEvent = InputEvent();
+  if(!vEvent) return;
+
+  fUPCEvent->ClearEvent();
+
+  fCounter->Fill( 1 ); // 1 = analyzed events
+
+  // trigger
+  TString trigger = vEvent->GetFiredTriggerClasses();
+  Bool_t trgClasses[NTRG]; // array of fired trigger classes
+  for(Int_t itrg=0; itrg<NTRG; itrg++) trgClasses[itrg] = kFALSE;
+
+  trgClasses[1] = trigger.Contains("CMUP6-B"); // p-Pb FW
+  trgClasses[2] = trigger.Contains("CMUP3-B"); // Pb-p FW
+  trgClasses[3] = trigger.Contains("CMUP8-B"); // Pb-p FW
+
+  trgClasses[4] = trigger.Contains("CMUP7-B"); // p-Pb SFW
+  trgClasses[5] = trigger.Contains("CMUP5-B"); // Pb-p SFW
+  trgClasses[6] = trigger.Contains("CMUP9-B"); // Pb-p SFW
+
+  trgClasses[7] = trigger.Contains("CCUP7-B"); // CEN
+
+  trgClasses[8] = trigger.Contains("CMUP7-ACE");
+  trgClasses[9] = trigger.Contains("CMUP5-ACE");
+  trgClasses[10]= trigger.Contains("CMUP9-ACE");
+
+  Bool_t isTrg = kFALSE;
+  for(Int_t itrg=1; itrg<NTRG; itrg++) {
+    if(!trgClasses[itrg]) continue;
+    //trigger at itrg is fired
+    fUPCEvent->SetTriggerClass( itrg , kTRUE );
+    fTriggerCounter->Fill( vEvent->GetRunNumber() , itrg );
+    isTrg = kTRUE;
+  }
+  if(!isTrg && !fIsMC) {PostData(2, fHistList); return;}
+  //event passed the trigger
+
+  fCounter->Fill( 2 ); // 2 = events after trigger (ESD and AOD)
+
+  // ESD / AOD specific tasks: MC, SPD FO, L0 inputs, SPD tracklets, tracks, ZDC tdc
+  Bool_t stat;
+  if( fIsESD ) stat = RunESD();
+  if(!fIsESD ) stat = RunAOD();
+  if( !stat && !fIsMC ) {PostData(2, fHistList); return;}
+  //event passed ESD / AOD specific selection
+
+  fCounter->Fill( 3 ); // 3 = events after ESD / AOD specific part
+
+  // input data
+  const char *filnam = ((TTree*) GetInputData(0))->GetCurrentFile()->GetName();
+  // reconstruction pass: -1 = unknown, 1 = pass1, 2 = pass2, counter indices: 9 (unknown), 11 (pass1), 12 (pass2)
+  fUPCEvent->SetRecoPass( -1 );
+  if( strstr(filnam,"/pass1/") ) {fUPCEvent->SetRecoPass( 1 ); fCounter->Fill( 11 );}
+  if( strstr(filnam,"/pass2/") ) {fUPCEvent->SetRecoPass( 2 ); fCounter->Fill( 12 );}
+  if( fUPCEvent->GetRecoPass() < 0 ) fCounter->Fill( 9 );
+  fUPCEvent->SetInputFileName( filnam );
+  fUPCEvent->SetEventNumber( ((TTree*) GetInputData(0))->GetTree()->GetReadEntry() );
+  fUPCEvent->SetRunNumber( vEvent->GetRunNumber() );
+
+  //VZERO
+  AliVVZERO *dataVZERO = vEvent->GetVZEROData();
+  if(!dataVZERO) {PostData(2, fHistList); return;}
+
+  fUPCEvent->SetV0ADecision( dataVZERO->GetV0ADecision() );
+  fUPCEvent->SetV0CDecision( dataVZERO->GetV0CDecision() );
+  for (UInt_t iv=0; iv<32; iv++) {
+    if( dataVZERO->BBTriggerV0C((Int_t)iv) ) fUPCEvent->SetBBtriggerV0Cmask(iv);
+    if( dataVZERO->GetBBFlag((Int_t)iv) ) fUPCEvent->SetBBFlagV0Cmask(iv);
+  }
+
+  //ZDC
+  AliVZDC *dataZDC = vEvent->GetZDCData();
+  if(!dataZDC) {PostData(2, fHistList); return;}
+
+  //energy in ZDC
+  Double_t eZnc=0., eZpc=0., eZna=0., eZpa=0.;
+  for(Int_t i=0; i<5; i++) {
+    eZnc += dataZDC->GetZNCTowerEnergy()[i];
+    eZpc += dataZDC->GetZPCTowerEnergy()[i];
+    eZna += dataZDC->GetZNATowerEnergy()[i];
+    eZpa += dataZDC->GetZPATowerEnergy()[i];
+  }
+  fUPCEvent->SetZNCEnergy( eZnc );
+  fUPCEvent->SetZPCEnergy( eZpc );
+  fUPCEvent->SetZNAEnergy( eZna );
+  fUPCEvent->SetZPAEnergy( eZpa );
+
+  //default primary vertex
+  const AliVVertex *vtx = vEvent->GetPrimaryVertex();
+  if(!vtx) {PostData(2, fHistList); return;}
+  Double_t pos[3]; vtx->GetXYZ(pos);
+  Double_t cov[6]; vtx->GetCovarianceMatrix(cov);
+  fUPCEvent->SetPrimaryVertex(pos, vtx->GetChi2perNDF(), cov, vtx->GetNContributors());
+  const char *vtxtitle = vtx->GetTitle();
+  fUPCEvent->SetPrimaryVertexTitle( vtxtitle );
+
+  fCounter->Fill( 4 ); // 4 = events written to the tree (ESD and AOD)
+
+  fUPCTree ->Fill();
+  PostData(1, fUPCTree);
+  PostData(2, fHistList);
+
+}//UserExec
+
+//_____________________________________________________________________________
+Bool_t AliAnalysisTaskUpcFilterSemiforward::RunAOD()
+{
+  //cout<<"#################### AOD event ##################"<<endl;
+
+  //input AOD event
+  AliAODEvent *aodEvent = (AliAODEvent*) InputEvent();
+  if(!aodEvent) return kFALSE;
+
+  fCounter->Fill( 22 ); // 22 = AOD analyzed events
+
+  if(fIsMC) RunAODMC( (TClonesArray*) aodEvent->GetList()->FindObject(AliAODMCParticle::StdBranchName()),
+                      (AliAODMCHeader*) aodEvent->FindListObject(AliAODMCHeader::StdBranchName())
+                    );
+
+  //nominal interaction point
+  static AliAODVertex *vtx0 = 0x0;
+  if( !vtx0 ) {
+    // make a vertex at coordinates 0, 0, 0
+    vtx0 = new AliAODVertex();
+    vtx0->SetX(0.); vtx0->SetY(0.); vtx0->SetZ(0.);
+  }
+
+  //array of tracks for DCAs calculation
+  //static TClonesArray *trackArray = 0x0;
+  //if( !trackArray ) trackArray = new TClonesArray("AliAODTrack", 3); // number of DCAs
+
+  Double_t pxpypz[3];
+  UChar_t maskMan;
+  Double_t xyzDca[2], cov[3];
+  Float_t b[2], covF[3];
+  Int_t nmun=0, ncen=0;
+  // AOD tracks loop
+  for(Int_t itr=0; itr<aodEvent->GetNumberOfTracks(); itr++) {
+    AliAODTrack *trk = aodEvent->GetTrack(itr);
+    if( !trk ) continue;
+
+    //muon track
+    if( trk->IsMuonTrack() ) {
+
+      AliUPCMuonTrack *upcMuon = fUPCEvent->AddMuonTrack();
+      upcMuon->SetPtEtaPhi( trk->Pt(), trk->Eta(), trk->Phi() );
+      upcMuon->SetCharge( trk->Charge() );
+      upcMuon->SetMatchTrigger( trk->GetMatchTrigger() );
+      upcMuon->SetRAtAbsorberEnd( trk->GetRAtAbsorberEnd() );
+      upcMuon->SetChi2perNDF( trk->Chi2perNDF() );
+      upcMuon->SetDCA( trk->DCA() );
+      upcMuon->SetPxDCA( fMuonCuts->IsSelected(trk) );
+
+      nmun++;
+    }
+    //central track
+    else {
+
+      maskMan = 0;
+      if( trk->HasPointOnITSLayer(0) )                 { maskMan |= 1 << 0; }
+      if( trk->HasPointOnITSLayer(1) )                 { maskMan |= 1 << 1; }
+      if( trk->GetStatus() & AliESDtrack::kITSrefit )  { maskMan |= 1 << 2; }
+      if( trk->GetStatus() & AliESDtrack::kTPCrefit )  { maskMan |= 1 << 3; }
+
+      //selection for at least one point in ITS and TPC refit
+      //if( !(maskMan & (1 << 0)) && !(maskMan & (1 << 1)) ) continue;
+      //if( !(maskMan & (1 << 3)) ) continue;
+
+      //selection for its refit and tpc refit
+      //if( !(maskMan & (1 << 2)) || !(maskMan & (1 << 3)) ) continue;
+
+      //selection for tpc refit
+      //if( !(maskMan & (1 << 3)) ) continue;
+
+      //selection for at least one point in SPD and ITS refit and TPC refit
+      //if( !(maskMan & (1 << 0)) && !(maskMan & (1 << 1)) ) continue;
+      //if( !(maskMan & (1 << 2)) || !(maskMan & (1 << 3)) ) continue;
+
+      //selection for at least one point in SPD and at least one TPC cluster
+      if( !(maskMan & (1 << 0)) && !(maskMan & (1 << 1)) ) continue;
+      if( trk->GetTPCNcls() == 0 ) continue;
+
+      trk->GetPxPyPz(pxpypz);
+      AliAODPid *apid = trk->GetDetPid();
+      if(!apid) continue;
+
+      AliUPCTrack *upcTrack = fUPCEvent->AddTrack();
+      upcTrack->SetPxPyPz( pxpypz );
+      upcTrack->SetMaskMan( maskMan );
+      upcTrack->SetFilterMap( trk->GetFilterMap() );
+      upcTrack->SetCharge( trk->Charge() );
+      upcTrack->SetChi2perNDF( trk->Chi2perNDF() );
+      upcTrack->SetTPCmomentum( apid->GetTPCmomentum() );
+      upcTrack->SetTPCsignal( apid->GetTPCsignal() );
+      upcTrack->SetTPCNcls( trk->GetTPCNcls() );
+      upcTrack->SetTPCCrossedRows( (Float_t) trk->GetTPCNCrossedRows() );
+      upcTrack->SetTPCNclsF( trk->GetTPCNclsF() );
+      upcTrack->SetTPCNclsS( trk->GetTPCnclsS() );
+      upcTrack->SetITSClusterMap( trk->GetITSClusterMap() );
+
+      //array for DCA
+      //trackArray->Clear("C");
+      //new((*trackArray)[0]) AliAODTrack(*trk);
+      //new((*trackArray)[1]) AliAODTrack(*trk);
+      //new((*trackArray)[2]) AliAODTrack(*trk);
+
+      //DCA to default primary vertex
+      AliAODTrack *track1 = (AliAODTrack*) trk->Clone("track1");
+      //AliAODTrack *track1 = (AliAODTrack*) trackArray->At( 0 );
+      track1->PropagateToDCA(aodEvent->GetPrimaryVertex(), aodEvent->GetMagneticField(), 9999., xyzDca, cov);
+      for(Int_t i=0; i<2; i++) {b[i] = (Float_t) xyzDca[i]; covF[i] = (Float_t) cov[i];}
+      upcTrack->SetImpactParameters(b, covF);
+      delete track1;
+
+      //DCA to SPD vertex
+      track1 = (AliAODTrack*) trk->Clone("track1");
+      //track1 = (AliAODTrack*) trackArray->At( 1 );
+      track1->PropagateToDCA(aodEvent->GetPrimaryVertexSPD(), aodEvent->GetMagneticField(), 9999., xyzDca, cov);
+      for(Int_t i=0; i<2; i++) {b[i] = (Float_t) xyzDca[i]; covF[i] = (Float_t) cov[i];}
+      upcTrack->SetImpactParametersSPD(b, covF);
+      delete track1;
+
+      //DCA to nominal interaction point
+      track1 = (AliAODTrack*) trk->Clone("track1");
+      //track1 = (AliAODTrack*) trackArray->At( 2 );
+      track1->PropagateToDCA(vtx0, aodEvent->GetMagneticField(), 9999., xyzDca, cov);
+      for(Int_t i=0; i<2; i++) {b[i] = (Float_t) xyzDca[i]; covF[i] = (Float_t) cov[i];}
+      upcTrack->SetImpactParametersIP(b, covF);
+      delete track1;
+
+      ncen++;
+    }
+  }// AOD tracks loop
+
+  //selection for at least one muon or central track
+  if( nmun + ncen < 1 ) return kFALSE;
+
+  //selection for at least one muon and at least one central track
+  //if( nmun < 1 || ncen < 1 ) return kFALSE;
+
+
+  // L0 trigger inputs
+  fUPCEvent->SetL0inputs( aodEvent->GetHeader()->GetL0TriggerInputs() );
+
+  // Tracklets
+  fUPCEvent->SetNumberOfTracklets( aodEvent->GetTracklets()->GetNumberOfTracklets() );
+
+  // AOD ZDC for TDC
+  AliAODZDC *dataZDCAOD = aodEvent->GetZDCData();
+  if(!dataZDCAOD) {PostData(2, fHistList); return kFALSE;}
+
+  Bool_t znctdc = kFALSE, znatdc = kFALSE;
+  if( dataZDCAOD->GetZNCTime() != 0. ) znctdc = kTRUE;
+  if( dataZDCAOD->GetZNATime() != 0. ) znatdc = kTRUE;
+  fUPCEvent->SetZNCtdc( znctdc );
+  fUPCEvent->SetZNAtdc( znatdc );
+  fUPCEvent->SetZPCtdc( kFALSE );
+  fUPCEvent->SetZPAtdc( kFALSE );
+
+  //SPD primary vertex in AOD
+  AliAODVertex *vtx = aodEvent->GetPrimaryVertexSPD();
+  if(!vtx) {PostData(2, fHistList); return kFALSE;}
+  Double_t posVtx[3]; vtx->GetXYZ( posVtx );
+  Double_t covVtx[6]; vtx->GetCovarianceMatrix( covVtx );
+  fUPCEvent->SetPrimaryVertexSPD(posVtx, vtx->GetChi2perNDF(), covVtx, vtx->GetNContributors());
+  const char *vtxtitle = vtx->GetTitle();
+  fUPCEvent->SetPrimaryVertexSPDtitle( vtxtitle );
+
+  return kTRUE;
+
+}//RunAOD
+
+//_____________________________________________________________________________
+void AliAnalysisTaskUpcFilterSemiforward::RunAODMC(TClonesArray *arrayMC, AliAODMCHeader *headerMC)
+{
+  // run over AOD mc particles
+
+  if( !arrayMC || !headerMC ) return;
+
+  //generated vertex in AOD MC
+  Double_t vtxD[3]; headerMC->GetVertex( vtxD );
+  Float_t vtxF[3]; for(Int_t i=0; i<3; i++) vtxF[i] = (Float_t) vtxD[i];
+  fUPCEvent->SetPrimaryVertexMC( vtxF );
+
+  //loop over mc particles
+  for(Int_t imc=0; imc<arrayMC->GetEntriesFast(); imc++) {
+    AliAODMCParticle *aodmc = (AliAODMCParticle*) arrayMC->At(imc);
+    if(!aodmc) continue;
+
+    if(aodmc->GetMother() >= 0) continue;
+
+    TParticle *part = fUPCEvent->AddMCParticle();
+    part->SetMomentum(aodmc->Px(), aodmc->Py(), aodmc->Pz(), aodmc->E());
+    part->SetProductionVertex(aodmc->Xv(), aodmc->Yv(), aodmc->Zv(), aodmc->T());
+    part->SetFirstMother(aodmc->GetMother());
+    part->SetLastDaughter(aodmc->GetNDaughters());
+    part->SetPdgCode(aodmc->GetPdgCode());
+    part->SetUniqueID(imc);
+  }//loop over mc particles
+
+}//RunAODMC
+
+//_____________________________________________________________________________
+Bool_t AliAnalysisTaskUpcFilterSemiforward::RunESD()
+{
+  //cout<<"#################### ESD event ##################"<<endl;
+
+  // Input ESD event
+  AliESDEvent *esdEvent = (AliESDEvent*) InputEvent();
+  if(!esdEvent) return kFALSE;
+
+  fCounter->Fill( 21 ); // 21 = ESD analyzed events
+
+  if(fIsMC) {
+    fUPCEvent->SetNSPDfiredInner( fTriggerAna->SPDFiredChips(esdEvent,1,kFALSE,1) );
+    fUPCEvent->SetNSPDfiredOuter( fTriggerAna->SPDFiredChips(esdEvent,1,kFALSE,2) );
+
+    RunESDMC();
+  }
+
+  static AliESDVertex *vtx0 = 0x0;
+  if( !vtx0 ) {
+    // make a vertex at coordinates 0, 0, 0
+    vtx0 = new AliESDVertex();
+    vtx0->SetXv(0.); vtx0->SetYv(0.); vtx0->SetZv(0.);
+  }
+
+  // ESD central tracks
+  Double_t pxpypz[3];
+  Float_t b[2]; Float_t cov[3];
+  UChar_t maskMan;
+  UInt_t filterMap;
+  Int_t nmun=0, ncen=0;
+  //ESD central tracks loop
+  for(Int_t itr=0; itr<esdEvent->GetNumberOfTracks(); itr++) {
+    AliESDtrack *eTrack = esdEvent->GetTrack(itr);
+    if( !eTrack ) continue;
+
+    // manual filter
+    maskMan = 0;
+    if( eTrack->HasPointOnITSLayer(0) )                 { maskMan |= 1 << 0; }
+    if( eTrack->HasPointOnITSLayer(1) )                 { maskMan |= 1 << 1; }
+    if( eTrack->GetStatus() & AliESDtrack::kITSrefit )  { maskMan |= 1 << 2; }
+    if( eTrack->GetStatus() & AliESDtrack::kTPCrefit )  { maskMan |= 1 << 3; }
+    if( eTrack->GetKinkIndex(0) > 0 )                   { maskMan |= 1 << 4; } // bit set if track is kink candidate
+
+    //selection for at least one point in ITS and TPC refit
+    //if( !(maskMan & (1 << 0)) && !(maskMan & (1 << 1)) ) continue;
+    //if( !(maskMan & (1 << 3)) ) continue;
+
+    //selection for its refit and tpc refit
+    //if( !(maskMan & (1 << 2)) || !(maskMan & (1 << 3)) ) continue;
+
+    //selection for tpc refit
+    //if( !(maskMan & (1 << 3)) ) continue;
+
+    //selection for at least one point in SPD and ITS refit and TPC refit
+    //if( !(maskMan & (1 << 0)) && !(maskMan & (1 << 1)) ) continue;
+    //if( !(maskMan & (1 << 2)) || !(maskMan & (1 << 3)) ) continue;
+
+    //selection for at least one point in SPD and at least one TPC cluster
+    if( !(maskMan & (1 << 0)) && !(maskMan & (1 << 1)) ) continue;
+    if( eTrack->GetTPCNcls() == 0 ) continue;
+
+    //central track accepted to write to the UPC event
+
+    // various configurations of AliESDtrackCuts
+    filterMap = 0;
+    for(UInt_t i=0; i<32; i++) {
+      if( !fCutsList[i] ) continue;
+
+      if( fCutsList[i]->AcceptTrack(eTrack) ) { filterMap |= 1 << i; }
+    }
+
+    eTrack->GetPxPyPz(pxpypz);
+
+    //fill UPC track
+    AliUPCTrack *upcTrack = fUPCEvent->AddTrack();
+    upcTrack->SetPxPyPz( pxpypz );
+    upcTrack->SetMaskMan( maskMan );
+    upcTrack->SetFilterMap( filterMap );
+    upcTrack->SetCharge( eTrack->Charge() );
+    upcTrack->SetChi2perNDF( eTrack->GetTPCchi2()/((Double_t) eTrack->GetTPCNcls()) ); // TPC chi2 used to fill this data member in esd
+    upcTrack->SetTPCmomentum( eTrack->GetTPCmomentum() );
+    upcTrack->SetTPCsignal( eTrack->GetTPCsignal() );
+    upcTrack->SetTPCNcls( eTrack->GetTPCNcls() );
+    upcTrack->SetTPCCrossedRows( eTrack->GetTPCCrossedRows() );
+    upcTrack->SetTPCNclsF( eTrack->GetTPCNclsF() );
+    upcTrack->SetTPCNclsS( eTrack->GetTPCnclsS() );
+    upcTrack->SetITSchi2perNDF( eTrack->GetITSchi2()/((Double_t) eTrack->GetNcls(0)) );
+    upcTrack->SetITSClusterMap( eTrack->GetITSClusterMap() );
+
+    //DCA to default primary vertex
+    eTrack->GetImpactParameters(b, cov);
+    upcTrack->SetImpactParameters(b, cov);
+
+    //DCA to SPD vertex
+    AliESDtrack *track1 = (AliESDtrack*) eTrack->Clone("track1");
+    track1->RelateToVertex( esdEvent->GetPrimaryVertexSPD(), esdEvent->GetMagneticField(), 9999. );
+    track1->GetImpactParameters(b, cov);
+    upcTrack->SetImpactParametersSPD(b, cov);
+    delete track1;
+
+    //DCA to nominal interaction point
+    track1 = (AliESDtrack*) eTrack->Clone("track1");
+    track1->RelateToVertex( vtx0, esdEvent->GetMagneticField(), 9999. );
+    track1->GetImpactParameters(b, cov);
+    upcTrack->SetImpactParametersIP(b, cov);
+    delete track1;
+
+    ncen++;
+  } //ESD central tracks loop
+
+  // ESD muon tracks
+  //muon tracks loop
+  for(Int_t itr=0; itr<esdEvent->GetNumberOfMuonTracks(); itr++) {
+    AliESDMuonTrack *mTrack = esdEvent->GetMuonTrack(itr);
+    if( !mTrack ) continue;
+
+    AliUPCMuonTrack *upcMuon = fUPCEvent->AddMuonTrack();
+    upcMuon->SetPtEtaPhi( mTrack->Pt(), mTrack->Eta(), mTrack->Phi() );
+    upcMuon->SetCharge( mTrack->Charge() );
+    upcMuon->SetMatchTrigger( mTrack->GetMatchTrigger() );
+    upcMuon->SetRAtAbsorberEnd( mTrack->GetRAtAbsorberEnd() );
+    upcMuon->SetChi2perNDF( mTrack->GetChi2()/((Double_t) mTrack->GetNDF()) );
+    upcMuon->SetDCA( mTrack->GetDCA() );
+    upcMuon->SetPxDCA( fMuonCuts->IsSelected(mTrack) );
+
+    nmun++;
+  } //muon tracks loop
+
+  //selection for at least one muon or central track
+  if( nmun + ncen < 1 ) return kFALSE;
+
+  //selection for at least one muon and at least one central track
+  //if( nmun < 1 || ncen < 1 ) return kFALSE;
+
+  // L0 trigger inputs
+  fUPCEvent->SetL0inputs( esdEvent->GetHeader()->GetL0TriggerInputs() );
+
+  //Tracklets
+  fUPCEvent->SetNumberOfTracklets( esdEvent->GetMultiplicity()->GetNumberOfTracklets() );
+
+  // ESD ZDC for TDC
+  AliESDZDC *dataZDCESD = esdEvent->GetESDZDC();
+  if(!dataZDCESD) {PostData(2, fHistList); return kFALSE;}
+
+  Bool_t znctdc = kFALSE, zpctdc = kFALSE, znatdc = kFALSE, zpatdc = kFALSE;
+  for(Int_t iz=0;iz<4;iz++) {
+    if( dataZDCESD->GetZDCTDCData(10,iz) ) znctdc = kTRUE;
+    if( dataZDCESD->GetZDCTDCData(11,iz) ) zpctdc = kTRUE;
+    if( dataZDCESD->GetZDCTDCData(12,iz) ) znatdc = kTRUE;
+    if( dataZDCESD->GetZDCTDCData(13,iz) ) zpatdc = kTRUE;
+  }
+  fUPCEvent->SetZNCtdc( znctdc );
+  fUPCEvent->SetZPCtdc( zpctdc );
+  fUPCEvent->SetZNAtdc( znatdc );
+  fUPCEvent->SetZPAtdc( zpatdc );
+
+  //SPD primary vertex in ESD
+  const AliESDVertex *vtx = esdEvent->GetPrimaryVertexSPD();
+  if(!vtx) {PostData(2, fHistList); return kFALSE;}
+  Double_t posVtx[3]; vtx->GetXYZ( posVtx );
+  Double_t covVtx[6]; vtx->GetCovarianceMatrix( covVtx );
+  fUPCEvent->SetPrimaryVertexSPD(posVtx, vtx->GetChi2perNDF(), covVtx, vtx->GetNContributors());
+  const char *vtxtitle = vtx->GetTitle();
+  fUPCEvent->SetPrimaryVertexSPDtitle( vtxtitle );
+
+  return kTRUE;
+
+}//RunESD
+
+//_____________________________________________________________________________
+void AliAnalysisTaskUpcFilterSemiforward::RunESDMC()
+{
+  // ESD MC particles
+
+  AliMCEvent *mcEvent = MCEvent();
+  if(!mcEvent) {cout<<"Error: no ESD MC found"<<endl; return;}
+
+  //generated vertex
+  TArrayF vtx(3);
+  mcEvent->GenEventHeader()->PrimaryVertex(vtx);
+  fUPCEvent->SetPrimaryVertexMC( vtx.GetArray() );
+
+  //loop over mc particles
+  for(Int_t imc=0; imc<mcEvent->GetNumberOfTracks(); imc++) {
+    AliMCParticle *esdmc = (AliMCParticle*) mcEvent->GetTrack(imc);
+    if(!esdmc) continue;
+
+    if(esdmc->GetMother() >= 0) continue;
+
+    TParticle *part = fUPCEvent->AddMCParticle();
+    part->SetMomentum(esdmc->Px(), esdmc->Py(), esdmc->Pz(), esdmc->E());
+    part->SetProductionVertex(esdmc->Xv(), esdmc->Yv(), esdmc->Zv(), 0.);
+    part->SetFirstMother(esdmc->GetMother());
+    part->SetLastDaughter(esdmc->GetLastDaughter()-esdmc->GetFirstDaughter()+1);
+    part->SetPdgCode(esdmc->PdgCode());
+    part->SetUniqueID(imc);
+  }//loop over mc particles
+
+}//RunESDMC
+
+//_____________________________________________________________________________
+void AliAnalysisTaskUpcFilterSemiforward::Terminate(Option_t *) 
+{
+
+  cout<<"Analysis complete."<<endl;
+}//Terminate
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/PWGUD/UPC/AliAnalysisTaskUpcFilterSemiforward.h b/PWGUD/UPC/AliAnalysisTaskUpcFilterSemiforward.h
new file mode 100644 (file)
index 0000000..2b83fc9
--- /dev/null
@@ -0,0 +1,59 @@
+#ifndef ALIANALYSISTASKUPCFILTERSEMIFORWARD_H
+#define ALIANALYSISTASKUPCFILTERSEMIFORWARD_H
+
+// task for upc semiforward filter
+// creates upc event from esd or aod
+//
+// jaroslav.adam@cern.ch
+
+#define NTRG 24
+#include "AliAnalysisTaskSE.h"
+
+class AliUPCEvent;
+
+class AliAnalysisTaskUpcFilterSemiforward : public AliAnalysisTaskSE {
+ public:
+  AliAnalysisTaskUpcFilterSemiforward(const char *name="AliAnalysisTaskUpcFilterSemiforward");
+  virtual ~AliAnalysisTaskUpcFilterSemiforward();
+
+  void SetIsESD(Bool_t isESD) {fIsESD = isESD;}
+  void SetIsMC(Bool_t isMC) {fIsMC = isMC;}
+  virtual void UserCreateOutputObjects();
+  virtual void NotifyRun();
+  virtual void UserExec(Option_t *option);
+  Bool_t RunAOD();
+  void RunAODMC(TClonesArray *arrayMC, AliAODMCHeader *headerMC);
+  Bool_t RunESD();
+  void RunESDMC();
+  virtual void Terminate(Option_t *);
+
+ private:
+  AliAnalysisTaskUpcFilterSemiforward(const AliAnalysisTaskUpcFilterSemiforward &o); // not implemented
+  AliAnalysisTaskUpcFilterSemiforward &operator=(const AliAnalysisTaskUpcFilterSemiforward &o); // not implemented
+
+  Bool_t fIsESD; // analysis type, ESD / AOD
+  Bool_t fIsMC; // mc or data selection
+
+  AliMuonTrackCuts *fMuonCuts; // class for muon track cuts, used for pDCA
+  AliTriggerAnalysis *fTriggerAna; // class for trigger analysis, used for fired SPD FO
+  AliESDtrackCuts **fCutsList; // array of pointers to filtering task for ESD tracks
+
+  TList *fHistList; // list of output histograms
+  TH1I *fCounter; // analysis counter
+  TH2I *fTriggerCounter; // counter of triggers per run
+  AliUPCEvent *fUPCEvent; // output UPC event
+  TTree *fUPCTree; // output tree
+
+  ClassDef(AliAnalysisTaskUpcFilterSemiforward, 1); 
+};
+
+#endif
+
+
+
+
+
+
+
+
+
diff --git a/PWGUD/UPC/AliUPCEvent.cxx b/PWGUD/UPC/AliUPCEvent.cxx
new file mode 100644 (file)
index 0000000..91ce276
--- /dev/null
@@ -0,0 +1,458 @@
+
+//_____________________________________________________________________________
+//    Class for UPC data
+//    Author: Jaroslav Adam
+//
+//    UPC event containing trigger, VZERO, ZDC, tracks and MC
+//_____________________________________________________________________________
+
+#include "TH1I.h"
+#include "TObjString.h"
+#include "TString.h"
+#include "TClonesArray.h"
+#include "TParticle.h"
+
+#include "AliUPCTrack.h"
+#include "AliUPCMuonTrack.h"
+
+#include "AliUPCEvent.h"
+
+ClassImp(AliUPCEvent)
+
+TClonesArray *AliUPCEvent::fgUPCTracks = 0;
+TClonesArray *AliUPCEvent::fgUPCMuonTracks = 0;
+TClonesArray *AliUPCEvent::fgMCParticles = 0;
+
+//_____________________________________________________________________________
+AliUPCEvent::AliUPCEvent()
+ :TObject(),
+  fFlags(0), fL0inputs(0), fRecoPass(0),
+  fDataFilnam(0x0), fEvtNum(0), fRunNum(0),
+  fVtxChi2perNDF(0), fVtxNContributors(0), fVtxTitle(0x0),
+  fVtxSPDchi2perNDF(0), fVtxSPDnContributors(0), fVtxSPDtitle(0x0),
+  fNTracklets(0), fNSPDfiredInner(0), fNSPDfiredOuter(0),
+  fV0ADecision(0), fV0CDecision(0), fBBtriggerV0C(0), fBBFlagV0C(0),
+  fZNCEnergy(0), fZPCEnergy(0), fZNAEnergy(0), fZPAEnergy(0),
+  fZNCtdc(0), fZPCtdc(0), fZNAtdc(0), fZPAtdc(0),
+  fUPCTracks(0x0), fNtracks(0), fUPCMuonTracks(0x0), fNmuons(0),
+  fMCParticles(0x0), fNmc(0)
+{
+  // Default constructor
+
+  for(Int_t itrg=0; itrg<NTRG; itrg++) fTrgClasses[itrg] = kFALSE;
+  for(Int_t i=0; i<3; i++) {fVtxPos[i] = 0.; fVtxSPDpos[i] = 0.; fVtxMCpos[i] = 0.;}
+  for(Int_t i=0; i<6; i++) {fVtxCov[i] = 0.; fVtxSPDcov[i] = 0.;}
+
+  if(!fgUPCTracks) {
+    fgUPCTracks = new TClonesArray("AliUPCTrack");
+    fUPCTracks = fgUPCTracks;
+    fUPCTracks->SetOwner(kTRUE);
+  }
+  if(!fgUPCMuonTracks) {
+    fgUPCMuonTracks = new TClonesArray("AliUPCMuonTrack");
+    fUPCMuonTracks = fgUPCMuonTracks;
+    fUPCMuonTracks->SetOwner(kTRUE);
+  }
+
+
+  if(!fDataFilnam) {
+    fDataFilnam = new TObjString();
+    fDataFilnam->SetString("");
+  }
+
+  if(!fVtxTitle) {
+    fVtxTitle = new TObjString();
+    fVtxTitle->SetString("");
+  }
+
+  if(!fVtxSPDtitle) {
+    fVtxSPDtitle = new TObjString();
+    fVtxSPDtitle->SetString("");
+  }
+
+  //if(!fUPCTracks) fUPCTracks = new TClonesArray("AliUPCTrack");
+  //if(!fUPCMuonTracks) fUPCMuonTracks = new TClonesArray("AliUPCMuonTrack");
+}
+
+//_____________________________________________________________________________
+AliUPCEvent::~AliUPCEvent()
+{
+  // destructor
+
+  if(fDataFilnam) {delete fDataFilnam; fDataFilnam = 0x0;}
+  if(fVtxTitle) {delete fVtxTitle; fVtxTitle=0x0;}
+  if(fVtxSPDtitle) {delete fVtxSPDtitle; fVtxSPDtitle=0x0;}
+  if(fUPCTracks) {delete fUPCTracks; fUPCTracks = 0x0;}
+  if(fUPCMuonTracks) {delete fUPCMuonTracks; fUPCMuonTracks = 0x0;}
+  if(fMCParticles) {delete fMCParticles; fMCParticles = 0x0;}
+}
+
+//_____________________________________________________________________________
+void AliUPCEvent::ClearEvent()
+{
+  // clear event variables
+
+  Clear(); // Clear to TObject
+
+  fBBtriggerV0C = 0;
+  fBBFlagV0C = 0;
+  for(Int_t itrg=0; itrg<NTRG; itrg++) fTrgClasses[itrg] = kFALSE;
+
+  if(fUPCTracks) {fUPCTracks->Clear("C"); fNtracks = 0;}
+  if(fUPCMuonTracks) {fUPCMuonTracks->Clear("C"); fNmuons = 0;}
+  if(fMCParticles) {fMCParticles->Clear("C"); fNmc = 0;}
+}
+
+//_____________________________________________________________________________
+void AliUPCEvent::SetIsESD(Bool_t isESD)
+{
+  //set event as created from ESD, otherwise AOD assumed
+
+  if(!isESD) return;
+
+  fFlags |= (1 << 0);
+
+}
+
+//_____________________________________________________________________________
+void AliUPCEvent::SetIsMC(Bool_t isMC)
+{
+  // set the event as MC, initialize mc array
+
+  if(!isMC) return;
+
+  if(!fgMCParticles) {
+    fgMCParticles = new TClonesArray("TParticle");
+    fMCParticles = fgMCParticles;
+    fMCParticles->SetOwner(kTRUE);
+  }
+  fFlags |= (1 << 1);
+
+}
+
+//_____________________________________________________________________________
+void AliUPCEvent::SetTriggerClass(Int_t idx, Bool_t fired)
+{
+  // set trigger class at index idx
+
+  if(idx < 0 || idx >= NTRG) return;
+  fTrgClasses[idx] = fired;
+}
+
+//_____________________________________________________________________________
+void AliUPCEvent::SetInputFileName(const char *s)
+{
+  // set name of the input file
+
+  fDataFilnam->Clear();
+  fDataFilnam->SetString(s);
+
+}
+
+//_____________________________________________________________________________
+void AliUPCEvent::SetPrimaryVertex(Double_t *pos, Double_t chi2, Double_t *cov, Int_t ncontrib)
+{
+  // set default primary vertex
+
+  for(Int_t i=0; i<3; i++) fVtxPos[i] = pos[i];
+  for(Int_t i=0; i<6; i++) fVtxCov[i] = cov[i];
+  fVtxChi2perNDF = chi2;
+  fVtxNContributors = ncontrib;
+}
+
+//_____________________________________________________________________________
+void AliUPCEvent::SetPrimaryVertexTitle(const char *s)
+{
+  // set title of default primary vertex
+
+  fVtxTitle->Clear();
+  fVtxTitle->SetString(s);
+}
+
+//_____________________________________________________________________________
+void AliUPCEvent::SetPrimaryVertexSPD(Double_t *pos, Double_t chi2, Double_t *cov, Int_t ncontrib)
+{
+  // set SPD primary vertex
+
+  for(Int_t i=0; i<3; i++) fVtxSPDpos[i] = pos[i];
+  for(Int_t i=0; i<6; i++) fVtxSPDcov[i] = cov[i];
+  fVtxSPDchi2perNDF = chi2;
+  fVtxSPDnContributors = ncontrib;
+}
+
+//_____________________________________________________________________________
+void AliUPCEvent::SetPrimaryVertexSPDtitle(const char *s)
+{
+  // set title of default primary vertex
+
+  fVtxSPDtitle->Clear();
+  fVtxSPDtitle->SetString(s);
+}
+
+//_____________________________________________________________________________
+void AliUPCEvent::SetPrimaryVertexMC(Float_t *pos)
+{
+  // set generated primary vertex
+
+  for(Int_t i=0; i<3; i++) fVtxMCpos[i] = pos[i];
+}
+
+//_____________________________________________________________________________
+void AliUPCEvent::SetBBtriggerV0Cmask(UInt_t ibit)
+{
+  // fill offline fired cells in V0C setting the corresponding bits in the bit mask
+  // AliUPCEvent::ClearEvent should be called to initialize the mask
+
+  fBBtriggerV0C |= (1 << ibit);
+}
+
+//_____________________________________________________________________________
+void AliUPCEvent::SetBBFlagV0Cmask(UInt_t ibit)
+{
+  // fill online fired cells in V0C setting the corresponding bits in the bit mask
+  // AliUPCEvent::ClearEvent should be called to initialize the mask
+
+  fBBFlagV0C |= (1 << ibit);
+}
+
+//_____________________________________________________________________________
+AliUPCTrack *AliUPCEvent::AddTrack(void)
+{
+  // construct new upc central track
+/*
+  if(!fgUPCTracks) {
+    fgUPCTracks = new TClonesArray("AliUPCTrack");
+    fUPCTracks = fgUPCTracks;
+    fUPCTracks->SetOwner(kTRUE);
+  }
+*/
+  if(!fUPCTracks) return 0x0;
+
+  AliUPCTrack *track = (AliUPCTrack*) fUPCTracks->ConstructedAt(fNtracks++);
+  return track;
+}
+
+//_____________________________________________________________________________
+AliUPCMuonTrack *AliUPCEvent::AddMuonTrack(void)
+{
+  // construct new upc muon track
+
+  if(!fUPCMuonTracks) return 0x0;
+
+  AliUPCMuonTrack *track = (AliUPCMuonTrack*) fUPCMuonTracks->ConstructedAt(fNmuons++);
+  return track;
+}
+
+//_____________________________________________________________________________
+TParticle *AliUPCEvent::AddMCParticle(void)
+{
+  // construct new mc TParticle
+
+  if(!fMCParticles) return 0x0;
+
+  TParticle *part = (TParticle*) fMCParticles->ConstructedAt(fNmc++);
+  return part;
+}
+
+//_____________________________________________________________________________
+Bool_t AliUPCEvent::GetIsESD(void) const
+{
+  // return kTRUE if event is ESD, otherwise AOD assumed
+
+  if( fFlags & (1 << 0) ) return kTRUE;
+
+  return kFALSE;
+
+}
+
+//_____________________________________________________________________________
+Bool_t AliUPCEvent::GetIsMC(void) const
+{
+  // return kTRUE if event is MC
+
+  if( fFlags & (1 << 1) ) return kTRUE;
+
+  return kFALSE;
+
+}
+
+//_____________________________________________________________________________
+Bool_t AliUPCEvent::GetFlagBit(UChar_t ibit) const
+{
+  // return kTRUE if bit is set
+
+  if( fFlags & (1 << ibit) ) return kTRUE;
+
+  return kFALSE;
+
+}
+
+//_____________________________________________________________________________
+Bool_t AliUPCEvent::GetTriggerClass(Int_t idx) const
+{
+  // returns kTRUE if trigger class at idx was fired, otherwise kFALSE;
+
+  if(idx < 0 || idx >= NTRG) return kFALSE;
+  return fTrgClasses[idx];
+}
+
+//_____________________________________________________________________________
+void AliUPCEvent::GetPrimaryVertex(Double_t *pos, Double_t &chi2, Double_t *cov, Int_t &ncontrib) const
+{
+  // get default primary vertex
+
+  for(Int_t i=0; i<3; i++) pos[i] = fVtxPos[i];
+  for(Int_t i=0; i<6; i++) cov[i] = fVtxCov[i];
+  chi2 = fVtxChi2perNDF;
+  ncontrib = fVtxNContributors;
+}
+
+//_____________________________________________________________________________
+void AliUPCEvent::GetPrimaryVertexSPD(Double_t *pos, Double_t &chi2, Double_t *cov, Int_t &ncontrib) const
+{
+  // get SPD primary vertex
+
+  for(Int_t i=0; i<3; i++) pos[i] = fVtxSPDpos[i];
+  for(Int_t i=0; i<6; i++) cov[i] = fVtxSPDcov[i];
+  chi2 = fVtxSPDchi2perNDF;
+  ncontrib = fVtxSPDnContributors;
+}
+
+//_____________________________________________________________________________
+void AliUPCEvent::GetPrimaryVertexMC(Float_t *pos) const
+{
+  // get generated primary vertex
+
+  for(Int_t i=0; i<3; i++) pos[i] = fVtxMCpos[i];
+}
+
+//_____________________________________________________________________________
+Int_t AliUPCEvent::GetNV0ChitsOffline(void) const
+{
+  // get number of fired cells of V0C, offline
+
+  Int_t nHits = 0;
+  for (UInt_t iv=0; iv<32; iv++) {if( fBBtriggerV0C & (1 << iv) ) nHits++;}
+
+  return nHits;
+}
+
+//_____________________________________________________________________________
+Int_t AliUPCEvent::GetNV0ChitsOnline(void) const
+{
+  // get number of fired cells of V0C, online
+
+  Int_t nHits = 0;
+  for (UInt_t iv=0; iv<32; iv++) {if( fBBFlagV0C & (1 << iv) ) nHits++;}
+
+  return nHits;
+}
+
+//_____________________________________________________________________________
+Bool_t AliUPCEvent::GetAllZDCtdc(void) const
+{
+  // get the final tdc of all ZDCs, return kTRUE if at least one tdc is set,
+  // return kFALSE only if all tdc are empty
+
+  if( fZNCtdc || fZPCtdc || fZNAtdc || fZPAtdc ) return kTRUE;
+  return kFALSE;
+}
+
+//_____________________________________________________________________________
+AliUPCTrack *AliUPCEvent::GetTrack(Int_t iTrack) const
+{
+  // get upc central track
+
+  if(!fUPCTracks) return 0x0;
+
+  return (AliUPCTrack*) fUPCTracks->At(iTrack);
+}
+
+//_____________________________________________________________________________
+AliUPCMuonTrack *AliUPCEvent::GetMuonTrack(Int_t iTrack) const
+{
+  // get upc muon track
+
+  if(!fUPCMuonTracks) return 0x0;
+
+  return (AliUPCMuonTrack*) fUPCMuonTracks->At(iTrack);
+}
+
+//_____________________________________________________________________________
+TParticle *AliUPCEvent::GetMCParticle(Int_t iMC) const
+{
+  // get mc TParticle
+
+  if(!fMCParticles) return 0x0;
+
+  return (TParticle*) fMCParticles->At(iMC);
+}
+
+/*
+//_____________________________________________________________________________
+AliUPCEvent::AliUPCEvent(const AliUPCEvent &o)
+ :TObject(o),
+  fNTracklets(o.fNTracklets)
+{
+
+  // Copy constructor
+
+}
+
+//_____________________________________________________________________________
+AliUPCEvent &AliUPCEvent::operator=(const AliUPCEvent &o)
+{
+
+  if(this==&o) return *this;
+  AliUPCEvent::operator=(o);
+
+  // Assignment operator
+  fNTracklets = o.fNTracklets;
+
+  return *this;
+
+}
+*/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/PWGUD/UPC/AliUPCEvent.h b/PWGUD/UPC/AliUPCEvent.h
new file mode 100644 (file)
index 0000000..6555e69
--- /dev/null
@@ -0,0 +1,182 @@
+#ifndef ALIUPCEVENT_H
+#define ALIUPCEVENT_H
+
+//_____________________________________________________________________________
+//    Class for UPC data
+//    Author: Jaroslav Adam
+//_____________________________________________________________________________
+
+#define NTRG 24
+#include "TObject.h"
+
+class AliUPCEvent : public TObject
+{
+public:
+  AliUPCEvent();
+  virtual ~AliUPCEvent();
+
+  void ClearEvent(void);
+
+  //Setters
+  void SetIsESD(Bool_t isESD=kTRUE);
+  void SetIsMC(Bool_t isMC=kTRUE);
+  void SetFlagBit(UChar_t ibit) {fFlags |= (1 << ibit);}
+  void ResetFlagBits(void) {fFlags = 0;}
+
+  void SetL0inputs(UInt_t inputs) {fL0inputs=inputs;}
+  void SetTriggerClass(Int_t idx, Bool_t fired);
+  void SetRecoPass(Char_t passId) {fRecoPass=passId;}
+  void SetInputFileName(const char *s);
+  void SetEventNumber(Long64_t evt) {fEvtNum=evt;}
+  void SetRunNumber(Int_t run) {fRunNum=run;}
+
+  void SetPrimaryVertex(Double_t *pos, Double_t chi2, Double_t *cov, Int_t ncontrib);
+  void SetPrimaryVertexTitle(const char *s);
+  void SetPrimaryVertexSPD(Double_t *pos, Double_t chi2, Double_t *cov, Int_t ncontrib);
+  void SetPrimaryVertexSPDtitle(const char *s);
+  void SetPrimaryVertexMC(Float_t *pos);
+
+  void SetNumberOfTracklets(Int_t tcklets) {fNTracklets=tcklets;}
+  void SetNSPDfiredInner(Int_t nInner) {fNSPDfiredInner=nInner;}
+  void SetNSPDfiredOuter(Int_t nOuter) {fNSPDfiredOuter=nOuter;}
+
+  void SetV0ADecision(Int_t decision) {fV0ADecision=decision;}
+  void SetV0CDecision(Int_t decision) {fV0CDecision=decision;}
+  void SetBBtriggerV0Cmask(UInt_t ibit);
+  void SetBBFlagV0Cmask(UInt_t ibit);
+
+  void SetZNCEnergy(Double_t energy) {fZNCEnergy = energy;}
+  void SetZPCEnergy(Double_t energy) {fZPCEnergy = energy;}
+  void SetZNAEnergy(Double_t energy) {fZNAEnergy = energy;}
+  void SetZPAEnergy(Double_t energy) {fZPAEnergy = energy;}
+  void SetZNCtdc(Bool_t tdc) {fZNCtdc = tdc;}
+  void SetZPCtdc(Bool_t tdc) {fZPCtdc = tdc;}
+  void SetZNAtdc(Bool_t tdc) {fZNAtdc = tdc;}
+  void SetZPAtdc(Bool_t tdc) {fZPAtdc = tdc;}
+
+  AliUPCTrack *AddTrack(void);
+  AliUPCMuonTrack *AddMuonTrack(void);
+
+  TParticle *AddMCParticle(void);
+
+  //Getters
+  Bool_t GetIsESD(void) const;
+  Bool_t GetIsMC(void) const;
+  Bool_t GetFlagBit(UChar_t ibit) const;
+  UChar_t GetFlag(void) const { return fFlags; }
+
+  UInt_t GetL0inputs(void) const { return fL0inputs; }
+  Bool_t GetTriggerClass(Int_t idx) const;
+  Char_t GetRecoPass(void) const { return fRecoPass; }
+  TObjString *GetInputFileName(void) const { return fDataFilnam; }
+  Long64_t GetEventNumber(void) const { return fEvtNum; }
+  Int_t GetRunNumber(void) const { return fRunNum; }
+
+  void GetPrimaryVertex(Double_t *pos, Double_t &chi2, Double_t *cov, Int_t &ncontrib) const;
+  TObjString *GetPrimaryVertexTitle(void) const { return fVtxTitle; }
+  void GetPrimaryVertexSPD(Double_t *pos, Double_t &chi2, Double_t *cov, Int_t &ncontrib) const;
+  TObjString *GetPrimaryVertexSPDtitle(void) const { return fVtxSPDtitle; }
+  void GetPrimaryVertexMC(Float_t *pos) const;
+
+  Int_t GetNumberOfTracklets(void) const { return fNTracklets; }
+  Int_t GetNSPDfiredInner(void) const { return fNSPDfiredInner; }
+  Int_t GetNSPDfiredOuter(void) const { return fNSPDfiredOuter; }
+
+  Int_t GetV0ADecision(void) const { return fV0ADecision; }
+  Int_t GetV0CDecision(void) const { return fV0CDecision; }
+  UInt_t GetBBtriggerV0C(void) const { return fBBtriggerV0C; }
+  UInt_t GetBBFlagV0C(void) const { return fBBFlagV0C; }
+  Int_t GetNV0ChitsOffline(void) const;
+  Int_t GetNV0ChitsOnline(void) const;
+
+  Double_t GetZNCEnergy(void) const { return fZNCEnergy; }
+  Double_t GetZPCEnergy(void) const { return fZPCEnergy; }
+  Double_t GetZNAEnergy(void) const { return fZNAEnergy; }
+  Double_t GetZPAEnergy(void) const { return fZPAEnergy; }
+  Bool_t GetZNCtdc(void) const { return fZNCtdc; }
+  Bool_t GetZPCtdc(void) const { return fZPCtdc; }
+  Bool_t GetZNAtdc(void) const { return fZNAtdc; }
+  Bool_t GetZPAtdc(void) const { return fZPAtdc; }
+  Bool_t GetAllZDCtdc(void) const;
+
+  Int_t GetNumberOfTracks(void) const { return fNtracks; }
+  AliUPCTrack *GetTrack(Int_t iTrack) const;
+  Int_t GetNumberOfMuonTracks(void) const { return fNmuons; }
+  AliUPCMuonTrack *GetMuonTrack(Int_t iTrack) const;
+
+  Int_t GetNumberOfMCParticles(void) const { return fNmc; }
+  TParticle *GetMCParticle(Int_t iMC) const;
+
+protected:
+  AliUPCEvent(const AliUPCEvent &o); // not implemented
+  AliUPCEvent &operator=(const AliUPCEvent &o); // not implemented
+
+  UChar_t fFlags; // event flags bits: 0 = ESD, 1 = MC
+  UInt_t fL0inputs; // L0 trigger inputs
+  Bool_t fTrgClasses[NTRG]; // fired trigger classes
+  Char_t fRecoPass; // reconstruction pass identifier
+  TObjString *fDataFilnam; //-> input file name and path
+  Long64_t fEvtNum; // event number in input file
+  Int_t fRunNum; // run number
+  Double_t fVtxPos[3]; // default primary vertex position
+  Double_t fVtxChi2perNDF; // chi2/ndf of vertex fit
+  Double_t fVtxCov[6]; // vertex covariance matrix
+  Int_t fVtxNContributors; // # of tracklets/tracks used for the estimate
+  TObjString *fVtxTitle; //-> title of default primary vertex
+  Double_t fVtxSPDpos[3]; // SPD primary vertex position
+  Double_t fVtxSPDchi2perNDF; // chi2/ndf of vertex fit
+  Double_t fVtxSPDcov[6]; // vertex covariance matrix
+  Int_t fVtxSPDnContributors; // # of tracklets/tracks used for the estimate
+  TObjString *fVtxSPDtitle; //-> title of SPD primary vertex
+  Float_t fVtxMCpos[3]; // MC primary vertex position
+  Int_t fNTracklets; // number of SPD tracklets
+  Int_t fNSPDfiredInner; // number of fired SPD FO chips, inner layer
+  Int_t fNSPDfiredOuter; // number of fired SPD FO chips, outer layer
+  Int_t fV0ADecision; // V0A decision, set by enumeration: kV0Invalid = -1, kV0Empty = 0, kV0BB, kV0BG, kV0Fake
+  Int_t fV0CDecision; // V0C decision
+  UInt_t fBBtriggerV0C; // offline beam-beam flags in V0C one bit per cell
+  UInt_t fBBFlagV0C; // online beam-beam flags in V0C one bit per cell
+  Double_t fZNCEnergy; // reconstructed energy in the neutron ZDC, C-side
+  Double_t fZPCEnergy; // reconstructed energy in the proton ZDC, C-side
+  Double_t fZNAEnergy; // reconstructed energy in the neutron ZDC, A-side
+  Double_t fZPAEnergy; // reconstructed energy in the proton ZDC, A-side
+  Bool_t fZNCtdc; // ZDC TDC data, NC
+  Bool_t fZPCtdc; // ZDC TDC data, PC
+  Bool_t fZNAtdc; // ZDC TDC data, NA
+  Bool_t fZPAtdc; // ZDC TDC data, PA
+  TClonesArray *fUPCTracks; //-> array of central upc tracks
+  Int_t fNtracks; // number of central upc tracks in event
+  TClonesArray *fUPCMuonTracks; //-> array of muon upc tracks
+  Int_t fNmuons; // number of muon upc tracks in event
+  TClonesArray *fMCParticles; // array of MC particles
+  Int_t fNmc; // number of mc particles in event
+
+  static TClonesArray *fgUPCTracks; // array of central upc tracks
+  static TClonesArray *fgUPCMuonTracks; // array of muon upc tracks
+  static TClonesArray *fgMCParticles; // array of MC particles
+
+  ClassDef(AliUPCEvent,1)
+};
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/PWGUD/UPC/AliUPCMuonTrack.cxx b/PWGUD/UPC/AliUPCMuonTrack.cxx
new file mode 100644 (file)
index 0000000..06d44e9
--- /dev/null
@@ -0,0 +1,76 @@
+
+//_____________________________________________________________________________
+//    Class for UPC muon track
+//    Author: Jaroslav Adam
+//
+//    contains parameters of the muon track relevant for UPC analysis
+//_____________________________________________________________________________
+
+#include "TLorentzVector.h"
+
+#include "AliUPCMuonTrack.h"
+
+ClassImp(AliUPCMuonTrack)
+
+//_____________________________________________________________________________
+AliUPCMuonTrack::AliUPCMuonTrack()
+ :TObject(),
+  fPt(0), fEta(0), fPhi(0), fCharge(0), fMatchTrigger(0), fRabs(0),
+  fChi2perNDF(0), fDca(0), fPdca(0),
+  fkMuonMass(0.105658)
+{
+
+  // Default constructor
+
+
+}
+
+void AliUPCMuonTrack::GetMomentum(TLorentzVector *v) const
+{
+  // get track 4-momentum
+  v->SetPtEtaPhiM(fPt,fEta,fPhi,fkMuonMass);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/PWGUD/UPC/AliUPCMuonTrack.h b/PWGUD/UPC/AliUPCMuonTrack.h
new file mode 100644 (file)
index 0000000..debe20e
--- /dev/null
@@ -0,0 +1,84 @@
+#ifndef ALIUPCMUONTRACK_H
+#define ALIUPCMUONTRACK_H
+
+//_____________________________________________________________________________
+//    Class for UPC data
+//    Author: Jaroslav Adam
+//_____________________________________________________________________________
+
+#include "TObject.h"
+
+class TLorentzVector;
+
+class AliUPCMuonTrack : public TObject
+{
+public:
+  AliUPCMuonTrack();
+
+  virtual ~AliUPCMuonTrack() {};
+
+  //Setters
+  void SetPtEtaPhi(Double_t pt, Double_t eta, Double_t phi) {fPt=pt; fEta=eta; fPhi=phi;}
+
+  void SetCharge(Short_t charge) {fCharge=charge;}
+
+  void SetMatchTrigger(Int_t match) {fMatchTrigger=match;}
+  void SetRAtAbsorberEnd(Double_t rabs) {fRabs=rabs;}
+  void SetChi2perNDF(Double_t chi2) {fChi2perNDF=chi2;}
+  void SetDCA(Double_t dca) {fDca=dca;}
+  void SetPxDCA(Bool_t pdca) {fPdca=pdca;}
+
+  //Getters
+  //virtual void GetPtEtaPhi(Double_t pt, Double_t eta, Double_t phi) const {pt=fPt; eta=fEta; phi=fPhi;}
+  Double_t GetPt(void) const { return fPt; }
+  Double_t GetEta(void) const { return fEta; }
+  Double_t GetPhi(void) const { return fPhi; }
+  void GetMomentum(TLorentzVector *v) const;
+
+  Short_t GetCharge(void) const { return fCharge; }
+
+  Int_t GetMatchTrigger(void) const { return fMatchTrigger; }
+  Double_t GetRAtAbsorberEnd(void) const { return fRabs; }
+  Double_t GetChi2perNDF(void) const { return fChi2perNDF; }
+  Double_t GetDCA(void) const { return fDca; }
+  Bool_t GetPxDCA(void) const { return fPdca; }
+
+protected:
+  AliUPCMuonTrack(const AliUPCMuonTrack &o);
+  AliUPCMuonTrack &operator=(const AliUPCMuonTrack &o);
+
+  Double_t fPt; // transversal momentum
+  Double_t fEta; // pseudorapidity
+  Double_t fPhi; // azimutal angle
+  Short_t fCharge; // track charge
+  Int_t fMatchTrigger; // muon trigger match
+  Double_t fRabs; // transverse position r of the track at the end of the absorber
+  Double_t fChi2perNDF; // chi2/NDF of momentum fit
+  Double_t fDca; // Distance of Closest Approach in the vertex plane
+  Bool_t fPdca; // pDCA by AliMuonTrackCuts
+
+  const Double_t fkMuonMass; // mass of muon
+
+  ClassDef(AliUPCMuonTrack,1)
+};
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/PWGUD/UPC/AliUPCTrack.cxx b/PWGUD/UPC/AliUPCTrack.cxx
new file mode 100644 (file)
index 0000000..18aec22
--- /dev/null
@@ -0,0 +1,166 @@
+
+//_____________________________________________________________________________
+//    Class for UPC data
+//    Author: Jaroslav Adam
+//
+//    contains parameters of the central track relevant for UPC analysis
+//_____________________________________________________________________________
+
+#include "TLorentzVector.h"
+
+#include "AliUPCTrack.h"
+
+ClassImp(AliUPCTrack)
+
+//_____________________________________________________________________________
+AliUPCTrack::AliUPCTrack()
+ :TObject(),
+  fCharge(0), fMaskMan(0), fFilterMap(0), fChi2perNDF(0),
+  fTPCmomentum(0), fTPCsignal(0), fTPCncls(0),
+  fTPCrows(0), fTPCnclsF(0), fTPCnclsS(0),
+  fITSchi2perNDF(0), fITSClusterMap(0)
+{
+
+  // Default constructor
+
+  for(Int_t i=0; i<2; i++) {fDZ[i] = 0.; fdzSPD[i] = 0.; fdzIP[i] = 0.;}
+  for(Int_t i=0; i<3; i++) {fP[i] = 0.; fCov[i] = 0.; fCovSPD[i] = 0.; fCovIP[i] = 0.;}
+}
+
+//_____________________________________________________________________________
+void AliUPCTrack::Clear(Option_t *)
+{
+  // clear track flags
+
+  fMaskMan = 0;
+  fFilterMap = 0;
+}
+
+//_____________________________________________________________________________
+void AliUPCTrack::SetImpactParameters(Float_t *p, Float_t *cov)
+{
+  // set impact parameters in XY and Z to default primary vertex
+
+  for(Int_t i=0; i<2; i++) {
+    fDZ[i] = p[i];
+    fCov[i] = cov[i];
+  }
+  fCov[2] = cov[2];
+}
+
+//_____________________________________________________________________________
+void AliUPCTrack::SetImpactParametersSPD(Float_t *p, Float_t *cov)
+{
+  // set SPD impact parameters
+
+  for(Int_t i=0; i<2; i++) {
+    fdzSPD[i] = p[i];
+    fCovSPD[i] = cov[i];
+  }
+  fCovSPD[2] = cov[2];
+}
+
+//_____________________________________________________________________________
+void AliUPCTrack::SetImpactParametersIP(Float_t *p, Float_t *cov)
+{
+  // set impact parameters to nominal interaction point
+
+  for(Int_t i=0; i<2; i++) {
+    fdzIP[i] = p[i];
+    fCovIP[i] = cov[i];
+  }
+  fCovIP[2] = cov[2];
+}
+
+//_____________________________________________________________________________
+void AliUPCTrack::GetMomentum(TLorentzVector *v, Double_t mass) const
+{
+  // get track 4-momentum
+  v->SetXYZM(fP[0],fP[1],fP[2],mass);
+}
+
+Int_t AliUPCTrack::GetITSNcls(void) const
+{
+  // number of points in ITS
+
+  Int_t ncls = 0;
+
+  for(UChar_t i=0; i<6; i++) if( fITSClusterMap & (1 << i) ) ncls++;
+
+  return ncls;
+}
+
+//_____________________________________________________________________________
+void AliUPCTrack::GetImpactParameters(Double_t *p, Double_t *cov) const
+{
+  // get impact parameters in XY and Z to default primary vertex
+
+  for(Int_t i=0; i<2; i++) {
+    p[i] = (Double_t) fDZ[i];
+    cov[i] = (Double_t) fCov[i];
+  }
+  cov[2] = (Double_t) fCov[2];
+}
+
+//_____________________________________________________________________________
+void AliUPCTrack::GetImpactParametersSPD(Double_t *p, Double_t *cov) const
+{
+  // get SPD impact parameters
+
+  for(Int_t i=0; i<2; i++) {
+    p[i] = (Double_t) fdzSPD[i];
+    cov[i] = (Double_t) fCovSPD[i];
+  }
+  cov[2] = (Double_t) fCovSPD[2];
+}
+
+//_____________________________________________________________________________
+void AliUPCTrack::GetImpactParametersIP(Double_t *p, Double_t *cov) const
+{
+  // get impact parameters to nominal interaction point
+
+  for(Int_t i=0; i<2; i++) {
+    p[i] = (Double_t) fdzIP[i];
+    cov[i] = (Double_t) fCovIP[i];
+  }
+  cov[2] = (Double_t) fCovIP[2];
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/PWGUD/UPC/AliUPCTrack.h b/PWGUD/UPC/AliUPCTrack.h
new file mode 100644 (file)
index 0000000..9fc8f48
--- /dev/null
@@ -0,0 +1,119 @@
+#ifndef ALIUPCTRACK_H
+#define ALIUPCTRACK_H
+
+//_____________________________________________________________________________
+//    Class for UPC data
+//    Author: Jaroslav Adam
+//_____________________________________________________________________________
+
+#include "TObject.h"
+
+class TLorentzVector;
+
+class AliUPCTrack : public TObject
+{
+public:
+  AliUPCTrack();
+
+  virtual ~AliUPCTrack() {};
+
+  void Clear(Option_t * /*option*/ ="");
+
+  //Setters
+  void SetPxPyPz(Double_t p[3]) {fP[0]=p[0]; fP[1]=p[1]; fP[2]=p[2];}
+  void SetCharge(Short_t charge) {fCharge=charge;}
+  void SetMaskMan(UChar_t mask) {fMaskMan=mask;}
+  void SetFilterMap(UInt_t map) {fFilterMap=map;}
+  void SetFilterBit(UInt_t ibit) {fFilterMap |= (1 << ibit);}
+  void SetChi2perNDF(Double_t chi2) {fChi2perNDF=chi2;}
+
+  void SetTPCmomentum(Double_t momentum) {fTPCmomentum=momentum;}
+  void SetTPCsignal(Double_t signal) {fTPCsignal=signal;}
+  void SetTPCNcls(UShort_t ncls) {fTPCncls=ncls;}
+  void SetTPCCrossedRows(Float_t nrows) {fTPCrows=nrows;}
+  void SetTPCNclsF(UShort_t ncls) {fTPCnclsF=ncls;}
+  void SetTPCNclsS(UShort_t ncls) {fTPCnclsS=ncls;}
+
+  void SetITSchi2perNDF(Double_t chi2) {fITSchi2perNDF=chi2;}
+  void SetITSClusterMap(UChar_t cmap) {fITSClusterMap=cmap;}
+
+  void SetImpactParameters(Float_t *p, Float_t *cov);
+  void SetImpactParametersSPD(Float_t *p, Float_t *cov);
+  void SetImpactParametersIP(Float_t *p, Float_t *cov);
+
+  //Getters
+  void GetPxPyPz(Double_t p[3]) const {p[0]=fP[0]; p[1]=fP[1]; p[2]=fP[2];}
+  void GetMomentum(TLorentzVector *v, Double_t mass) const;
+  Short_t GetCharge(void) const { return fCharge; }
+  UChar_t GetMaskMan(void) const { return fMaskMan; }
+  UInt_t GetFilterMap(void) const { return fFilterMap; }
+  Bool_t TestFilterBit(UInt_t filterBit) const {return (Bool_t) ((filterBit & fFilterMap) != 0);}
+  Double_t GetChi2perNDF(void) const { return fChi2perNDF; }
+
+  Double_t GetTPCmomentum(void) const { return fTPCmomentum; }
+  Double_t GetTPCsignal(void) const { return fTPCsignal; }
+  UShort_t GetTPCNcls() const { return fTPCncls; }
+  Float_t GetTPCCrossedRows() const { return fTPCrows; }
+  UShort_t GetTPCNclsF() const { return fTPCnclsF; }
+  UShort_t GetTPCNclsS() const { return fTPCnclsS; }
+
+  Double_t GetITSchi2perNDF(void) const { return fITSchi2perNDF; }
+  UChar_t GetITSClusterMap(void) const { return fITSClusterMap; }
+  Int_t GetITSNcls(void) const;
+
+  void GetImpactParameters(Double_t &xy, Double_t &z) const {xy = (Double_t) fDZ[0]; z = (Double_t) fDZ[1];}
+  void GetImpactParameters(Double_t *p, Double_t *cov) const;
+
+  void GetImpactParametersSPD(Double_t &xy, Double_t &z) const {xy = (Double_t) fdzSPD[0]; z = (Double_t) fdzSPD[1];}
+  void GetImpactParametersSPD(Double_t *p, Double_t *cov) const;
+
+  void GetImpactParametersIP(Double_t &xy, Double_t &z) const {xy = (Double_t) fdzIP[0]; z = (Double_t) fdzIP[1];}
+  void GetImpactParametersIP(Double_t *p, Double_t *cov) const;
+
+protected:
+  AliUPCTrack(const AliUPCTrack &o);
+  AliUPCTrack &operator=(const AliUPCTrack &o);
+
+  Double_t fP[3]; // momentum px, py, pz
+  Short_t fCharge; // track charge
+  UChar_t fMaskMan; // 8-bit filter mask, manual fill
+  UInt_t fFilterMap; // // filter information, one bit per set of cuts, 32 bit
+  Double_t fChi2perNDF; // chi2/NDF of momentum fit
+  Double_t fTPCmomentum; // tpc momentum
+  Double_t fTPCsignal; // tpc dEdx signal
+  UShort_t fTPCncls; // number of clusters assigned in the TPC
+  Float_t fTPCrows; // number of of crossed raws in TPC
+  UShort_t fTPCnclsF; // number of findable clusters in the TPC
+  UShort_t fTPCnclsS; // number of shared clusters in the TPC
+  Double_t fITSchi2perNDF; // chi2 in ITS per cluster
+  UChar_t fITSClusterMap; // map of clusters, one bit per a layer
+  Float_t fDZ[2]; // impact parameters in XY and Z to default primary vertex
+  Float_t fCov[3]; // Covariance matrix of the impact parameters
+  Float_t fdzSPD[2]; // SPD impact parameters in XY and Z
+  Float_t fCovSPD[3]; // Covariance matrix of the impact parameters to the SPD vertex
+  Float_t fdzIP[2]; // impact parameters in XY and Z to nominal interaction point
+  Float_t fCovIP[3]; // Covariance matrix of the impact parameters to nominal interaction point
+
+  ClassDef(AliUPCTrack,1)
+};
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+