+
+
+
+
+//_____________________________________________________________________________
+void AliReconstruction::CreateTag(TFile* file)
+{
+ //GRP
+ Float_t lhcLuminosity = 0.0;
+ TString lhcState = "test";
+ UInt_t detectorMask = 0;
+
+ /////////////
+ //muon code//
+ ////////////
+ Double_t fMUONMASS = 0.105658369;
+ //Variables
+ Double_t fX,fY,fZ ;
+ Double_t fThetaX, fThetaY, fPyz, fChisquare;
+ Double_t fPxRec,fPyRec, fPzRec, fEnergy;
+ Int_t fCharge;
+ TLorentzVector fEPvector;
+
+ Float_t fZVertexCut = 10.0;
+ Float_t fRhoVertexCut = 2.0;
+
+ Float_t fLowPtCut = 1.0;
+ Float_t fHighPtCut = 3.0;
+ Float_t fVeryHighPtCut = 10.0;
+ ////////////
+
+ Double_t partFrac[5] = {0.01, 0.01, 0.85, 0.10, 0.05};
+
+ // Creates the tags for all the events in a given ESD file
+ Int_t ntrack;
+ Int_t nProtons, nKaons, nPions, nMuons, nElectrons;
+ Int_t nPos, nNeg, nNeutr;
+ Int_t nK0s, nNeutrons, nPi0s, nGamas;
+ Int_t nCh1GeV, nCh3GeV, nCh10GeV;
+ Int_t nMu1GeV, nMu3GeV, nMu10GeV;
+ Int_t nEl1GeV, nEl3GeV, nEl10GeV;
+ Float_t maxPt = .0, meanPt = .0, totalP = .0;
+ Int_t fVertexflag;
+ Int_t iRunNumber = 0;
+ TString fVertexName("default");
+
+ AliRunTag *tag = new AliRunTag();
+ AliEventTag *evTag = new AliEventTag();
+ TTree ttag("T","A Tree with event tags");
+ TBranch * btag = ttag.Branch("AliTAG", &tag);
+ btag->SetCompressionLevel(9);
+
+ AliInfo(Form("Creating the tags......."));
+
+ if (!file || !file->IsOpen()) {
+ AliError(Form("opening failed"));
+ delete file;
+ return ;
+ }
+ Int_t lastEvent = 0;
+ TTree *t = (TTree*) file->Get("esdTree");
+ TBranch * b = t->GetBranch("ESD");
+ AliESD *esd = 0;
+ b->SetAddress(&esd);
+
+ b->GetEntry(fFirstEvent);
+ Int_t iInitRunNumber = esd->GetRunNumber();
+
+ Int_t iNumberOfEvents = (Int_t)b->GetEntries();
+ if(fLastEvent != -1) iNumberOfEvents = fLastEvent + 1;
+ for (Int_t iEventNumber = fFirstEvent; iEventNumber < iNumberOfEvents; iEventNumber++) {
+ ntrack = 0;
+ nPos = 0;
+ nNeg = 0;
+ nNeutr =0;
+ nK0s = 0;
+ nNeutrons = 0;
+ nPi0s = 0;
+ nGamas = 0;
+ nProtons = 0;
+ nKaons = 0;
+ nPions = 0;
+ nMuons = 0;
+ nElectrons = 0;
+ nCh1GeV = 0;
+ nCh3GeV = 0;
+ nCh10GeV = 0;
+ nMu1GeV = 0;
+ nMu3GeV = 0;
+ nMu10GeV = 0;
+ nEl1GeV = 0;
+ nEl3GeV = 0;
+ nEl10GeV = 0;
+ maxPt = .0;
+ meanPt = .0;
+ totalP = .0;
+ fVertexflag = 0;
+
+ b->GetEntry(iEventNumber);
+ iRunNumber = esd->GetRunNumber();
+ if(iRunNumber != iInitRunNumber) AliFatal("Inconsistency of run numbers in the AliESD!!!");
+ const AliESDVertex * vertexIn = esd->GetVertex();
+ if (!vertexIn) AliError("ESD has not defined vertex.");
+ if (vertexIn) fVertexName = vertexIn->GetName();
+ if(fVertexName != "default") fVertexflag = 1;
+ for (Int_t iTrackNumber = 0; iTrackNumber < esd->GetNumberOfTracks(); iTrackNumber++) {
+ AliESDtrack * esdTrack = esd->GetTrack(iTrackNumber);
+ UInt_t status = esdTrack->GetStatus();
+
+ //select only tracks with ITS refit
+ if ((status&AliESDtrack::kITSrefit)==0) continue;
+ //select only tracks with TPC refit
+ if ((status&AliESDtrack::kTPCrefit)==0) continue;
+
+ //select only tracks with the "combined PID"
+ if ((status&AliESDtrack::kESDpid)==0) continue;
+ Double_t p[3];
+ esdTrack->GetPxPyPz(p);
+ Double_t momentum = sqrt(pow(p[0],2) + pow(p[1],2) + pow(p[2],2));
+ Double_t fPt = sqrt(pow(p[0],2) + pow(p[1],2));
+ totalP += momentum;
+ meanPt += fPt;
+ if(fPt > maxPt) maxPt = fPt;
+
+ if(esdTrack->GetSign() > 0) {
+ nPos++;
+ if(fPt > fLowPtCut) nCh1GeV++;
+ if(fPt > fHighPtCut) nCh3GeV++;
+ if(fPt > fVeryHighPtCut) nCh10GeV++;
+ }
+ if(esdTrack->GetSign() < 0) {
+ nNeg++;
+ if(fPt > fLowPtCut) nCh1GeV++;
+ if(fPt > fHighPtCut) nCh3GeV++;
+ if(fPt > fVeryHighPtCut) nCh10GeV++;
+ }
+ if(esdTrack->GetSign() == 0) nNeutr++;
+
+ //PID
+ Double_t prob[5];
+ esdTrack->GetESDpid(prob);
+
+ Double_t rcc = 0.0;
+ for(Int_t i = 0; i < AliPID::kSPECIES; i++) rcc += prob[i]*partFrac[i];
+ if(rcc == 0.0) continue;
+ //Bayes' formula
+ Double_t w[5];
+ for(Int_t i = 0; i < AliPID::kSPECIES; i++) w[i] = prob[i]*partFrac[i]/rcc;
+
+ //protons
+ if ((w[4]>w[3])&&(w[4]>w[2])&&(w[4]>w[1])&&(w[4]>w[0])) nProtons++;
+ //kaons
+ if ((w[3]>w[4])&&(w[3]>w[2])&&(w[3]>w[1])&&(w[3]>w[0])) nKaons++;
+ //pions
+ if ((w[2]>w[4])&&(w[2]>w[3])&&(w[2]>w[1])&&(w[2]>w[0])) nPions++;
+ //electrons
+ if ((w[0]>w[4])&&(w[0]>w[3])&&(w[0]>w[2])&&(w[0]>w[1])) {
+ nElectrons++;
+ if(fPt > fLowPtCut) nEl1GeV++;
+ if(fPt > fHighPtCut) nEl3GeV++;
+ if(fPt > fVeryHighPtCut) nEl10GeV++;
+ }
+ ntrack++;
+ }//track loop
+
+ /////////////
+ //muon code//
+ ////////////
+ Int_t nMuonTracks = esd->GetNumberOfMuonTracks();
+ // loop over all reconstructed tracks (also first track of combination)
+ for (Int_t iTrack = 0; iTrack < nMuonTracks; iTrack++) {
+ AliESDMuonTrack* muonTrack = esd->GetMuonTrack(iTrack);
+ if (muonTrack == 0x0) continue;
+
+ // Coordinates at vertex
+ fZ = muonTrack->GetZ();
+ fY = muonTrack->GetBendingCoor();
+ fX = muonTrack->GetNonBendingCoor();
+
+ fThetaX = muonTrack->GetThetaX();
+ fThetaY = muonTrack->GetThetaY();
+
+ fPyz = 1./TMath::Abs(muonTrack->GetInverseBendingMomentum());
+ fPzRec = - fPyz / TMath::Sqrt(1.0 + TMath::Tan(fThetaY)*TMath::Tan(fThetaY));
+ fPxRec = fPzRec * TMath::Tan(fThetaX);
+ fPyRec = fPzRec * TMath::Tan(fThetaY);
+ fCharge = Int_t(TMath::Sign(1.,muonTrack->GetInverseBendingMomentum()));
+
+ //ChiSquare of the track if needed
+ fChisquare = muonTrack->GetChi2()/(2.0 * muonTrack->GetNHit() - 5);
+ fEnergy = TMath::Sqrt(fMUONMASS * fMUONMASS + fPxRec * fPxRec + fPyRec * fPyRec + fPzRec * fPzRec);
+ fEPvector.SetPxPyPzE(fPxRec, fPyRec, fPzRec, fEnergy);
+
+ // total number of muons inside a vertex cut
+ if((TMath::Abs(fZ)<fZVertexCut) && (TMath::Sqrt(fY*fY+fX*fX)<fRhoVertexCut)) {
+ nMuons++;
+ if(fEPvector.Pt() > fLowPtCut) {
+ nMu1GeV++;
+ if(fEPvector.Pt() > fHighPtCut) {
+ nMu3GeV++;
+ if (fEPvector.Pt() > fVeryHighPtCut) {
+ nMu10GeV++;
+ }
+ }
+ }
+ }
+ }//muon track loop
+
+ // Fill the event tags
+ if(ntrack != 0)
+ meanPt = meanPt/ntrack;
+
+ evTag->SetEventId(iEventNumber+1);
+ if (vertexIn) {
+ evTag->SetVertexX(vertexIn->GetXv());
+ evTag->SetVertexY(vertexIn->GetYv());
+ evTag->SetVertexZ(vertexIn->GetZv());
+ evTag->SetVertexZError(vertexIn->GetZRes());
+ }
+ evTag->SetVertexFlag(fVertexflag);
+
+ evTag->SetT0VertexZ(esd->GetT0zVertex());
+
+ evTag->SetTriggerMask(esd->GetTriggerMask());
+ evTag->SetTriggerCluster(esd->GetTriggerCluster());
+
+ evTag->SetZDCNeutron1Energy(esd->GetZDCN1Energy());
+ evTag->SetZDCProton1Energy(esd->GetZDCP1Energy());
+ evTag->SetZDCNeutron2Energy(esd->GetZDCN2Energy());
+ evTag->SetZDCProton2Energy(esd->GetZDCP2Energy());
+ evTag->SetZDCEMEnergy(esd->GetZDCEMEnergy());
+ evTag->SetNumOfParticipants(esd->GetZDCParticipants());
+
+
+ evTag->SetNumOfTracks(esd->GetNumberOfTracks());
+ evTag->SetNumOfPosTracks(nPos);
+ evTag->SetNumOfNegTracks(nNeg);
+ evTag->SetNumOfNeutrTracks(nNeutr);
+
+ evTag->SetNumOfV0s(esd->GetNumberOfV0s());
+ evTag->SetNumOfCascades(esd->GetNumberOfCascades());
+ evTag->SetNumOfKinks(esd->GetNumberOfKinks());
+ evTag->SetNumOfPMDTracks(esd->GetNumberOfPmdTracks());
+
+ evTag->SetNumOfProtons(nProtons);
+ evTag->SetNumOfKaons(nKaons);
+ evTag->SetNumOfPions(nPions);
+ evTag->SetNumOfMuons(nMuons);
+ evTag->SetNumOfElectrons(nElectrons);
+ evTag->SetNumOfPhotons(nGamas);
+ evTag->SetNumOfPi0s(nPi0s);
+ evTag->SetNumOfNeutrons(nNeutrons);
+ evTag->SetNumOfKaon0s(nK0s);
+
+ evTag->SetNumOfChargedAbove1GeV(nCh1GeV);
+ evTag->SetNumOfChargedAbove3GeV(nCh3GeV);
+ evTag->SetNumOfChargedAbove10GeV(nCh10GeV);
+ evTag->SetNumOfMuonsAbove1GeV(nMu1GeV);
+ evTag->SetNumOfMuonsAbove3GeV(nMu3GeV);
+ evTag->SetNumOfMuonsAbove10GeV(nMu10GeV);
+ evTag->SetNumOfElectronsAbove1GeV(nEl1GeV);
+ evTag->SetNumOfElectronsAbove3GeV(nEl3GeV);
+ evTag->SetNumOfElectronsAbove10GeV(nEl10GeV);
+
+ evTag->SetNumOfPHOSClusters(esd->GetNumberOfPHOSClusters());
+ evTag->SetNumOfEMCALClusters(esd->GetNumberOfEMCALClusters());
+
+ evTag->SetTotalMomentum(totalP);
+ evTag->SetMeanPt(meanPt);
+ evTag->SetMaxPt(maxPt);
+
+ tag->SetLHCTag(lhcLuminosity,lhcState);
+ tag->SetDetectorTag(detectorMask);
+
+ tag->SetRunId(iInitRunNumber);
+ tag->AddEventTag(*evTag);
+ }
+ if(fLastEvent == -1) lastEvent = (Int_t)b->GetEntries();
+ else lastEvent = fLastEvent;
+
+ ttag.Fill();
+ tag->Clear();
+
+ char fileName[256];
+ sprintf(fileName, "Run%d.Event%d_%d.ESD.tag.root",
+ tag->GetRunId(),fFirstEvent,lastEvent );
+ AliInfo(Form("writing tags to file %s", fileName));
+ AliDebug(1, Form("writing tags to file %s", fileName));
+
+ TFile* ftag = TFile::Open(fileName, "recreate");
+ ftag->cd();
+ ttag.Write();
+ ftag->Close();
+ file->cd();
+ delete tag;
+ delete evTag;
+}
+
+//_____________________________________________________________________________
+void AliReconstruction::ESDFile2AODFile(TFile* esdFile, TFile* aodFile)
+{
+ // write all files from the given esd file to an aod file
+
+ // create an AliAOD object
+ AliAODEvent *aod = new AliAODEvent();
+ aod->CreateStdContent();
+
+ // go to the file
+ aodFile->cd();
+
+ // create the tree
+ TTree *aodTree = new TTree("AOD", "AliAOD tree");
+ aodTree->Branch(aod->GetList());
+
+ // connect to ESD
+ TTree *t = (TTree*) esdFile->Get("esdTree");
+ TBranch *b = t->GetBranch("ESD");
+ AliESD *esd = 0;
+ b->SetAddress(&esd);
+
+ Int_t nEvents = b->GetEntries();
+
+ // set arrays and pointers
+ Float_t posF[3];
+ Double_t pos[3];
+ Double_t p[3];
+ Double_t covVtx[6];
+ Double_t covTr[21];
+ Double_t pid[10];
+
+ // loop over events and fill them
+ for (Int_t iEvent = 0; iEvent < nEvents; ++iEvent) {
+ b->GetEntry(iEvent);
+
+ // Multiplicity information needed by the header (to be revised!)
+ Int_t nTracks = esd->GetNumberOfTracks();
+ Int_t nPosTracks = 0;
+ for (Int_t iTrack=0; iTrack<nTracks; ++iTrack)
+ if (esd->GetTrack(iTrack)->GetSign()> 0) nPosTracks++;
+
+ // create the header
+ aod->AddHeader(new AliAODHeader(esd->GetRunNumber(),
+ esd->GetBunchCrossNumber(),
+ esd->GetOrbitNumber(),
+ esd->GetPeriodNumber(),
+ nTracks,
+ nPosTracks,
+ nTracks-nPosTracks,
+ esd->GetMagneticField(),
+ -999., // fill muon magnetic field
+ -999., // centrality; to be filled, still
+ esd->GetZDCN1Energy(),
+ esd->GetZDCP1Energy(),
+ esd->GetZDCN2Energy(),
+ esd->GetZDCP2Energy(),
+ esd->GetZDCEMEnergy(),
+ esd->GetTriggerMask(),
+ esd->GetTriggerCluster(),
+ esd->GetEventType()));
+
+ Int_t nV0s = esd->GetNumberOfV0s();
+ Int_t nCascades = esd->GetNumberOfCascades();
+ Int_t nKinks = esd->GetNumberOfKinks();
+ Int_t nVertices = nV0s + nCascades + nKinks;
+
+ aod->ResetStd(nTracks, nVertices);
+ AliAODTrack *aodTrack;
+
+
+ // Array to take into account the tracks already added to the AOD
+ Bool_t * usedTrack = NULL;
+ if (nTracks>0) {
+ usedTrack = new Bool_t[nTracks];
+ for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) usedTrack[iTrack]=kFALSE;
+ }
+ // Array to take into account the V0s already added to the AOD
+ Bool_t * usedV0 = NULL;
+ if (nV0s>0) {
+ usedV0 = new Bool_t[nV0s];
+ for (Int_t iV0=0; iV0<nV0s; ++iV0) usedV0[iV0]=kFALSE;
+ }
+ // Array to take into account the kinks already added to the AOD
+ Bool_t * usedKink = NULL;
+ if (nKinks>0) {
+ usedKink = new Bool_t[nKinks];
+ for (Int_t iKink=0; iKink<nKinks; ++iKink) usedKink[iKink]=kFALSE;
+ }
+
+ // Access to the AOD container of vertices
+ TClonesArray &vertices = *(aod->GetVertices());
+ Int_t jVertices=0;
+
+ // Access to the AOD container of tracks
+ TClonesArray &tracks = *(aod->GetTracks());
+ Int_t jTracks=0;
+
+ // Add primary vertex. The primary tracks will be defined
+ // after the loops on the composite objects (V0, cascades, kinks)
+ const AliESDVertex *vtx = esd->GetPrimaryVertex();
+
+ vtx->GetXYZ(pos); // position
+ vtx->GetCovMatrix(covVtx); //covariance matrix
+
+ AliAODVertex * primary = new(vertices[jVertices++])
+ AliAODVertex(pos, covVtx, vtx->GetChi2toNDF(), NULL, AliAODVertex::kPrimary);
+
+ // Create vertices starting from the most complex objects
+
+ // Cascades
+ for (Int_t nCascade = 0; nCascade < nCascades; ++nCascade) {
+ AliESDcascade *cascade = esd->GetCascade(nCascade);
+
+ cascade->GetXYZ(pos[0], pos[1], pos[2]);
+ cascade->GetPosCovXi(covVtx);
+
+ // Add the cascade vertex
+ AliAODVertex * vcascade = new(vertices[jVertices++]) AliAODVertex(pos,
+ covVtx,
+ cascade->GetChi2Xi(), // = chi2/NDF since NDF = 2*2-3
+ primary,
+ AliAODVertex::kCascade);
+
+ primary->AddDaughter(vcascade);
+
+ // Add the V0 from the cascade. The ESD class have to be optimized...
+ // Now we have to search for the corresponding Vo in the list of V0s
+ // using the indeces of the positive and negative tracks
+
+ Int_t posFromV0 = cascade->GetPindex();
+ Int_t negFromV0 = cascade->GetNindex();
+
+
+ AliESDv0 * v0 = 0x0;
+ Int_t indV0 = -1;
+
+ for (Int_t iV0=0; iV0<nV0s; ++iV0) {
+
+ v0 = esd->GetV0(iV0);
+ Int_t posV0 = v0->GetPindex();
+ Int_t negV0 = v0->GetNindex();
+
+ if (posV0==posFromV0 && negV0==negFromV0) {
+ indV0 = iV0;
+ break;
+ }
+ }
+
+ AliAODVertex * vV0FromCascade = 0x0;
+
+ if (indV0>-1 && !usedV0[indV0] ) {
+
+ // the V0 exists in the array of V0s and is not used
+
+ usedV0[indV0] = kTRUE;
+
+ v0->GetXYZ(pos[0], pos[1], pos[2]);
+ v0->GetPosCov(covVtx);
+
+ vV0FromCascade = new(vertices[jVertices++]) AliAODVertex(pos,
+ covVtx,
+ v0->GetChi2V0(), // = chi2/NDF since NDF = 2*2-3
+ vcascade,
+ AliAODVertex::kV0);
+ } else {
+
+ // the V0 doesn't exist in the array of V0s or was used
+ cerr << "Error: event " << iEvent << " cascade " << nCascade
+ << " The V0 " << indV0
+ << " doesn't exist in the array of V0s or was used!" << endl;
+
+ cascade->GetXYZ(pos[0], pos[1], pos[2]);
+ cascade->GetPosCov(covVtx);
+
+ vV0FromCascade = new(vertices[jVertices++]) AliAODVertex(pos,
+ covVtx,
+ v0->GetChi2V0(), // = chi2/NDF since NDF = 2*2-3
+ vcascade,
+ AliAODVertex::kV0);
+ vcascade->AddDaughter(vV0FromCascade);
+ }
+
+ // Add the positive tracks from the V0
+
+ if (! usedTrack[posFromV0]) {
+
+ usedTrack[posFromV0] = kTRUE;
+
+ AliESDtrack *esdTrack = esd->GetTrack(posFromV0);
+ esdTrack->GetPxPyPz(p);
+ esdTrack->GetXYZ(pos);
+ esdTrack->GetCovarianceXYZPxPyPz(covTr);
+ esdTrack->GetESDpid(pid);
+
+ vV0FromCascade->AddDaughter(aodTrack =
+ new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
+ esdTrack->GetLabel(),
+ p,
+ kTRUE,
+ pos,
+ kFALSE,
+ covTr,
+ (Short_t)esdTrack->GetSign(),
+ esdTrack->GetITSClusterMap(),
+ pid,
+ vV0FromCascade,
+ kTRUE, // check if this is right
+ kFALSE, // check if this is right
+ AliAODTrack::kSecondary)
+ );
+ aodTrack->ConvertAliPIDtoAODPID();
+ }
+ else {
+ cerr << "Error: event " << iEvent << " cascade " << nCascade
+ << " track " << posFromV0 << " has already been used!" << endl;
+ }
+
+ // Add the negative tracks from the V0
+
+ if (!usedTrack[negFromV0]) {
+
+ usedTrack[negFromV0] = kTRUE;
+
+ AliESDtrack *esdTrack = esd->GetTrack(negFromV0);
+ esdTrack->GetPxPyPz(p);
+ esdTrack->GetXYZ(pos);
+ esdTrack->GetCovarianceXYZPxPyPz(covTr);
+ esdTrack->GetESDpid(pid);
+
+ vV0FromCascade->AddDaughter(aodTrack =
+ new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
+ esdTrack->GetLabel(),
+ p,
+ kTRUE,
+ pos,
+ kFALSE,
+ covTr,
+ (Short_t)esdTrack->GetSign(),
+ esdTrack->GetITSClusterMap(),
+ pid,
+ vV0FromCascade,
+ kTRUE, // check if this is right
+ kFALSE, // check if this is right
+ AliAODTrack::kSecondary)
+ );
+ aodTrack->ConvertAliPIDtoAODPID();
+ }
+ else {
+ cerr << "Error: event " << iEvent << " cascade " << nCascade
+ << " track " << negFromV0 << " has already been used!" << endl;
+ }
+
+ // Add the bachelor track from the cascade
+
+ Int_t bachelor = cascade->GetBindex();
+
+ if(!usedTrack[bachelor]) {
+
+ usedTrack[bachelor] = kTRUE;
+
+ AliESDtrack *esdTrack = esd->GetTrack(bachelor);
+ esdTrack->GetPxPyPz(p);
+ esdTrack->GetXYZ(pos);
+ esdTrack->GetCovarianceXYZPxPyPz(covTr);
+ esdTrack->GetESDpid(pid);
+
+ vcascade->AddDaughter(aodTrack =
+ new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
+ esdTrack->GetLabel(),
+ p,
+ kTRUE,
+ pos,
+ kFALSE,
+ covTr,
+ (Short_t)esdTrack->GetSign(),
+ esdTrack->GetITSClusterMap(),
+ pid,
+ vcascade,
+ kTRUE, // check if this is right
+ kFALSE, // check if this is right
+ AliAODTrack::kSecondary)
+ );
+ aodTrack->ConvertAliPIDtoAODPID();
+ }
+ else {
+ cerr << "Error: event " << iEvent << " cascade " << nCascade
+ << " track " << bachelor << " has already been used!" << endl;
+ }
+
+ // Add the primary track of the cascade (if any)
+
+ } // end of the loop on cascades
+
+ // V0s
+
+ for (Int_t nV0 = 0; nV0 < nV0s; ++nV0) {
+
+ if (usedV0[nV0]) continue; // skip if aready added to the AOD
+
+ AliESDv0 *v0 = esd->GetV0(nV0);
+
+ v0->GetXYZ(pos[0], pos[1], pos[2]);
+ v0->GetPosCov(covVtx);
+
+ AliAODVertex * vV0 =
+ new(vertices[jVertices++]) AliAODVertex(pos,
+ covVtx,
+ v0->GetChi2V0(), // = chi2/NDF since NDF = 2*2-3
+ primary,
+ AliAODVertex::kV0);
+ primary->AddDaughter(vV0);
+
+ Int_t posFromV0 = v0->GetPindex();
+ Int_t negFromV0 = v0->GetNindex();
+
+ // Add the positive tracks from the V0
+
+ if (!usedTrack[posFromV0]) {
+
+ usedTrack[posFromV0] = kTRUE;
+
+ AliESDtrack *esdTrack = esd->GetTrack(posFromV0);
+ esdTrack->GetPxPyPz(p);
+ esdTrack->GetXYZ(pos);
+ esdTrack->GetCovarianceXYZPxPyPz(covTr);
+ esdTrack->GetESDpid(pid);
+
+ vV0->AddDaughter(aodTrack =
+ new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
+ esdTrack->GetLabel(),
+ p,
+ kTRUE,
+ pos,
+ kFALSE,
+ covTr,
+ (Short_t)esdTrack->GetSign(),
+ esdTrack->GetITSClusterMap(),
+ pid,
+ vV0,
+ kTRUE, // check if this is right
+ kFALSE, // check if this is right
+ AliAODTrack::kSecondary)
+ );
+ aodTrack->ConvertAliPIDtoAODPID();
+ }
+ else {
+ cerr << "Error: event " << iEvent << " V0 " << nV0
+ << " track " << posFromV0 << " has already been used!" << endl;
+ }
+
+ // Add the negative tracks from the V0
+
+ if (!usedTrack[negFromV0]) {
+
+ usedTrack[negFromV0] = kTRUE;
+
+ AliESDtrack *esdTrack = esd->GetTrack(negFromV0);
+ esdTrack->GetPxPyPz(p);
+ esdTrack->GetXYZ(pos);
+ esdTrack->GetCovarianceXYZPxPyPz(covTr);
+ esdTrack->GetESDpid(pid);
+
+ vV0->AddDaughter(aodTrack =
+ new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
+ esdTrack->GetLabel(),
+ p,
+ kTRUE,
+ pos,
+ kFALSE,
+ covTr,
+ (Short_t)esdTrack->GetSign(),
+ esdTrack->GetITSClusterMap(),
+ pid,
+ vV0,
+ kTRUE, // check if this is right
+ kFALSE, // check if this is right
+ AliAODTrack::kSecondary)
+ );
+ aodTrack->ConvertAliPIDtoAODPID();
+ }
+ else {
+ cerr << "Error: event " << iEvent << " V0 " << nV0
+ << " track " << negFromV0 << " has already been used!" << endl;
+ }
+
+ } // end of the loop on V0s
+
+ // Kinks: it is a big mess the access to the information in the kinks
+ // The loop is on the tracks in order to find the mother and daugther of each kink
+
+
+ for (Int_t iTrack=0; iTrack<nTracks; ++iTrack) {
+
+
+ AliESDtrack * esdTrack = esd->GetTrack(iTrack);
+
+ Int_t ikink = esdTrack->GetKinkIndex(0);
+
+ if (ikink) {
+ // Negative kink index: mother, positive: daughter
+
+ // Search for the second track of the kink
+
+ for (Int_t jTrack = iTrack+1; jTrack<nTracks; ++jTrack) {
+
+ AliESDtrack * esdTrack1 = esd->GetTrack(jTrack);
+
+ Int_t jkink = esdTrack1->GetKinkIndex(0);
+
+ if ( TMath::Abs(ikink)==TMath::Abs(jkink) ) {
+
+ // The two tracks are from the same kink
+
+ if (usedKink[TMath::Abs(ikink)-1]) continue; // skip used kinks
+
+ Int_t imother = -1;
+ Int_t idaughter = -1;
+
+ if (ikink<0 && jkink>0) {
+
+ imother = iTrack;
+ idaughter = jTrack;
+ }
+ else if (ikink>0 && jkink<0) {
+
+ imother = jTrack;
+ idaughter = iTrack;
+ }
+ else {
+ cerr << "Error: Wrong combination of kink indexes: "
+ << ikink << " " << jkink << endl;
+ continue;
+ }
+
+ // Add the mother track
+
+ AliAODTrack * mother = NULL;
+
+ if (!usedTrack[imother]) {
+
+ usedTrack[imother] = kTRUE;
+
+ AliESDtrack *esdTrack = esd->GetTrack(imother);
+ esdTrack->GetPxPyPz(p);
+ esdTrack->GetXYZ(pos);
+ esdTrack->GetCovarianceXYZPxPyPz(covTr);
+ esdTrack->GetESDpid(pid);
+
+ mother =
+ new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
+ esdTrack->GetLabel(),
+ p,
+ kTRUE,
+ pos,
+ kFALSE,
+ covTr,
+ (Short_t)esdTrack->GetSign(),
+ esdTrack->GetITSClusterMap(),
+ pid,
+ primary,
+ kTRUE, // check if this is right
+ kTRUE, // check if this is right
+ AliAODTrack::kPrimary);
+ primary->AddDaughter(mother);
+ mother->ConvertAliPIDtoAODPID();
+ }
+ else {
+ cerr << "Error: event " << iEvent << " kink " << TMath::Abs(ikink)-1
+ << " track " << imother << " has already been used!" << endl;
+ }
+
+ // Add the kink vertex
+ AliESDkink * kink = esd->GetKink(TMath::Abs(ikink)-1);
+
+ AliAODVertex * vkink =
+ new(vertices[jVertices++]) AliAODVertex(kink->GetPosition(),
+ NULL,
+ 0.,
+ mother,
+ AliAODVertex::kKink);
+ // Add the daughter track
+
+ AliAODTrack * daughter = NULL;
+
+ if (!usedTrack[idaughter]) {
+
+ usedTrack[idaughter] = kTRUE;
+
+ AliESDtrack *esdTrack = esd->GetTrack(idaughter);
+ esdTrack->GetPxPyPz(p);
+ esdTrack->GetXYZ(pos);
+ esdTrack->GetCovarianceXYZPxPyPz(covTr);
+ esdTrack->GetESDpid(pid);
+
+ daughter =
+ new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
+ esdTrack->GetLabel(),
+ p,
+ kTRUE,
+ pos,
+ kFALSE,
+ covTr,
+ (Short_t)esdTrack->GetSign(),
+ esdTrack->GetITSClusterMap(),
+ pid,
+ vkink,
+ kTRUE, // check if this is right
+ kTRUE, // check if this is right
+ AliAODTrack::kPrimary);
+ vkink->AddDaughter(daughter);
+ daughter->ConvertAliPIDtoAODPID();
+ }
+ else {
+ cerr << "Error: event " << iEvent << " kink " << TMath::Abs(ikink)-1
+ << " track " << idaughter << " has already been used!" << endl;
+ }
+
+
+ }
+ }
+
+ }
+
+ }
+
+
+ // Tracks (primary and orphan)
+
+ for (Int_t nTrack = 0; nTrack < nTracks; ++nTrack) {
+
+
+ if (usedTrack[nTrack]) continue;
+
+ AliESDtrack *esdTrack = esd->GetTrack(nTrack);
+ esdTrack->GetPxPyPz(p);
+ esdTrack->GetXYZ(pos);
+ esdTrack->GetCovarianceXYZPxPyPz(covTr);
+ esdTrack->GetESDpid(pid);
+
+ Float_t impactXY, impactZ;
+
+ esdTrack->GetImpactParameters(impactXY,impactZ);
+
+ if (impactXY<3) {
+ // track inside the beam pipe
+
+ primary->AddDaughter(aodTrack =
+ new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
+ esdTrack->GetLabel(),
+ p,
+ kTRUE,
+ pos,
+ kFALSE,
+ covTr,
+ (Short_t)esdTrack->GetSign(),
+ esdTrack->GetITSClusterMap(),
+ pid,
+ primary,
+ kTRUE, // check if this is right
+ kTRUE, // check if this is right
+ AliAODTrack::kPrimary)
+ );
+ aodTrack->ConvertAliPIDtoAODPID();
+ }
+ else {
+ // outside the beam pipe: orphan track
+ aodTrack =
+ new(tracks[jTracks++]) AliAODTrack(esdTrack->GetID(),
+ esdTrack->GetLabel(),
+ p,
+ kTRUE,
+ pos,
+ kFALSE,
+ covTr,
+ (Short_t)esdTrack->GetSign(),
+ esdTrack->GetITSClusterMap(),
+ pid,
+ NULL,
+ kFALSE, // check if this is right
+ kFALSE, // check if this is right
+ AliAODTrack::kOrphan);
+ aodTrack->ConvertAliPIDtoAODPID();
+ }
+ } // end of loop on tracks
+
+ // muon tracks
+ Int_t nMuTracks = esd->GetNumberOfMuonTracks();
+ for (Int_t nMuTrack = 0; nMuTrack < nMuTracks; ++nMuTrack) {
+
+ AliESDMuonTrack *esdMuTrack = esd->GetMuonTrack(nMuTrack);
+ p[0] = esdMuTrack->Px();
+ p[1] = esdMuTrack->Py();
+ p[2] = esdMuTrack->Pz();
+ pos[0] = primary->GetX();
+ pos[1] = primary->GetY();
+ pos[2] = primary->GetZ();
+
+ // has to be changed once the muon pid is provided by the ESD
+ for (Int_t i = 0; i < 10; pid[i++] = 0.); pid[AliAODTrack::kMuon]=1.;
+
+ primary->AddDaughter(
+ new(tracks[jTracks++]) AliAODTrack(0, // no ID provided
+ 0, // no label provided
+ p,
+ kTRUE,
+ pos,
+ kFALSE,
+ NULL, // no covariance matrix provided
+ (Short_t)-99, // no charge provided
+ 0, // no ITSClusterMap
+ pid,
+ primary,
+ kTRUE, // check if this is right
+ kTRUE, // not used for vertex fit
+ AliAODTrack::kPrimary)
+ );
+ }
+
+ // Access to the AOD container of clusters
+ TClonesArray &clusters = *(aod->GetClusters());
+ Int_t jClusters=0;
+
+ // Calo Clusters
+ Int_t nClusters = esd->GetNumberOfCaloClusters();
+
+ for (Int_t iClust=0; iClust<nClusters; ++iClust) {
+
+ AliESDCaloCluster * cluster = esd->GetCaloCluster(iClust);
+
+ Int_t id = cluster->GetID();
+ Int_t label = -1;
+ Float_t energy = cluster->GetClusterEnergy();
+ cluster->GetGlobalPosition(posF);
+ AliAODVertex *prodVertex = primary;
+ AliAODTrack *primTrack = NULL;
+ Char_t ttype=AliAODCluster::kUndef;
+
+ if (cluster->IsPHOS()) ttype=AliAODCluster::kPHOSNeutral;
+ else if (cluster->IsEMCAL()) {
+
+ if (cluster->GetClusterType() == AliESDCaloCluster::kPseudoCluster)
+ ttype = AliAODCluster::kEMCALPseudoCluster;
+ else
+ ttype = AliAODCluster::kEMCALClusterv1;
+
+ }
+
+ new(clusters[jClusters++]) AliAODCluster(id,
+ label,
+ energy,
+ pos,
+ NULL, // no covariance matrix provided
+ NULL, // no pid for clusters provided
+ prodVertex,
+ primTrack,
+ ttype);
+
+ } // end of loop on calo clusters
+
+ delete [] usedTrack;
+ delete [] usedV0;
+ delete [] usedKink;
+
+ // fill the tree for this event
+ aodTree->Fill();
+ } // end of event loop
+
+ aodTree->GetUserInfo()->Add(aod);
+
+ // close ESD file
+ esdFile->Close();
+
+ // write the tree to the specified file
+ aodFile = aodTree->GetCurrentFile();
+ aodFile->cd();
+ aodTree->Write();
+
+ return;
+}
+
+
+void AliReconstruction::WriteAlignmentData(AliESD* esd)
+{
+ // Write space-points which are then used in the alignment procedures
+ // For the moment only ITS, TRD and TPC
+
+ // Load TOF clusters
+ if (fTracker[3]){
+ fLoader[3]->LoadRecPoints("read");
+ TTree* tree = fLoader[3]->TreeR();
+ if (!tree) {
+ AliError(Form("Can't get the %s cluster tree", fgkDetectorName[3]));
+ return;
+ }
+ fTracker[3]->LoadClusters(tree);
+ }
+ Int_t ntracks = esd->GetNumberOfTracks();
+ for (Int_t itrack = 0; itrack < ntracks; itrack++)
+ {
+ AliESDtrack *track = esd->GetTrack(itrack);
+ Int_t nsp = 0;
+ Int_t idx[200];
+ for (Int_t iDet = 3; iDet >= 0; iDet--)
+ nsp += track->GetNcls(iDet);
+ if (nsp) {
+ AliTrackPointArray *sp = new AliTrackPointArray(nsp);
+ track->SetTrackPointArray(sp);
+ Int_t isptrack = 0;
+ for (Int_t iDet = 3; iDet >= 0; iDet--) {
+ AliTracker *tracker = fTracker[iDet];
+ if (!tracker) continue;
+ Int_t nspdet = track->GetNcls(iDet);
+ if (nspdet <= 0) continue;
+ track->GetClusters(iDet,idx);
+ AliTrackPoint p;
+ Int_t isp = 0;
+ Int_t isp2 = 0;
+ while (isp < nspdet) {
+ Bool_t isvalid = tracker->GetTrackPoint(idx[isp2],p); isp2++;
+ const Int_t kNTPCmax = 159;
+ if (iDet==1 && isp2>kNTPCmax) break; // to be fixed
+ if (!isvalid) continue;
+ sp->AddPoint(isptrack,&p); isptrack++; isp++;
+ }
+ }
+ }
+ }
+ if (fTracker[3]){
+ fTracker[3]->UnloadClusters();
+ fLoader[3]->UnloadRecPoints();
+ }
+}
+
+//_____________________________________________________________________________
+void AliReconstruction::FillRawDataErrorLog(Int_t iEvent, AliESD* esd)
+{
+ // The method reads the raw-data error log
+ // accumulated within the rawReader.
+ // It extracts the raw-data errors related to
+ // the current event and stores them into
+ // a TClonesArray inside the esd object.
+
+ if (!fRawReader) return;
+
+ for(Int_t i = 0; i < fRawReader->GetNumberOfErrorLogs(); i++) {
+
+ AliRawDataErrorLog *log = fRawReader->GetErrorLog(i);
+ if (!log) continue;
+ if (iEvent != log->GetEventNumber()) continue;
+
+ esd->AddRawDataErrorLog(log);
+ }
+
+}