+//______________________________________________________________________________
+Bool_t AliReconstruction::ProcessEvent(void* event)
+{
+ // Method that is used in case the event loop
+ // is steered from outside, for example by AMORE
+ // 'event' is a pointer to the DATE event in the memory
+
+ if (fRawReader) delete fRawReader;
+ fRawReader = new AliRawReaderDate(event);
+ fStatus = ProcessEvent(fRunLoader->GetNumberOfEvents());
+ delete fRawReader;
+ fRawReader = NULL;
+
+ return fStatus;
+}
+
+//______________________________________________________________________________
+Bool_t AliReconstruction::ParseOutput()
+{
+ // The method parses the output file
+ // location string in order to steer
+ // properly the selector
+
+ TPMERegexp re1("(\\w+\\.zip#\\w+\\.root):([,*\\w+\\.root,*]+)@dataset://(\\w++)");
+ TPMERegexp re2("(\\w+\\.root)?@?dataset://(\\w++)");
+
+ if (re1.Match(fESDOutput) == 4) {
+ // root archive with output files stored and regustered
+ // in proof dataset
+ gProof->AddInput(new TNamed("PROOF_OUTPUTFILE",re1[1].Data()));
+ gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION",re1[3].Data()));
+ gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_DATASET",""));
+ gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_ARCHIVE",re1[2].Data()));
+ AliInfo(Form("%s files will be stored within %s in dataset %s",
+ re1[2].Data(),
+ re1[1].Data(),
+ re1[3].Data()));
+ }
+ else if (re2.Match(fESDOutput) == 3) {
+ // output file stored and registered
+ // in proof dataset
+ gProof->AddInput(new TNamed("PROOF_OUTPUTFILE",(re2[1].IsNull()) ? "AliESDs.root" : re2[1].Data()));
+ gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION",re2[2].Data()));
+ gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_DATASET",""));
+ AliInfo(Form("%s will be stored in dataset %s",
+ (re2[1].IsNull()) ? "AliESDs.root" : re2[1].Data(),
+ re2[2].Data()));
+ }
+ else {
+ if (fESDOutput.IsNull()) {
+ // Output location not given.
+ // Assuming xrootd has been already started and
+ // the output file has to be sent back
+ // to the client machine
+ TString esdUrl(Form("root://%s/%s/",
+ TUrl(gSystem->HostName()).GetHostFQDN(),
+ gSystem->pwd()));
+ gProof->AddInput(new TNamed("PROOF_OUTPUTFILE","AliESDs.root"));
+ gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION",esdUrl.Data()));
+ AliInfo(Form("AliESDs.root will be stored in %s",
+ esdUrl.Data()));
+ }
+ else {
+ // User specified an output location.
+ // Ones has just to parse it here
+ TUrl outputUrl(fESDOutput.Data());
+ TString outputFile(gSystem->BaseName(outputUrl.GetFile()));
+ gProof->AddInput(new TNamed("PROOF_OUTPUTFILE",outputFile.IsNull() ? "AliESDs.root" : outputFile.Data()));
+ TString outputLocation(outputUrl.GetUrl());
+ outputLocation.ReplaceAll(outputFile.Data(),"");
+ gProof->AddInput(new TNamed("PROOF_OUTPUTFILE_LOCATION",outputLocation.Data()));
+ AliInfo(Form("%s will be stored in %s",
+ outputFile.IsNull() ? "AliESDs.root" : outputFile.Data(),
+ outputLocation.Data()));
+ }
+ }
+
+ return kTRUE;
+}
+
+//______________________________________________________________________________
+Bool_t AliReconstruction::IsHighPt() const {
+ // Selection of events containing "high" pT tracks
+ // If at least one track is found within 1.5 and 100 GeV (pT)
+ // that was reconstructed by both ITS and TPC, the event is accepted
+
+ // Track cuts
+ const Double_t pTmin = 1.5;
+ const Double_t pTmax = 100;
+ ULong_t mask = 0;
+ mask |= (AliESDtrack::kITSrefit);
+ mask |= (AliESDtrack::kTPCrefit);
+ const Double_t pTminCosmic = 5.;
+ const Double_t pTmaxCosmic = 100;
+ ULong_t maskCosmic = 0;
+ Int_t cosmicCount=0;
+ maskCosmic |= (AliESDtrack::kTPCrefit);
+
+ Bool_t isOK = kFALSE;
+
+ if (fesd && fesd->GetEventType()==AliRawEventHeaderBase::kPhysicsEvent) {
+ // Check if this ia a physics event (code 7)
+ Int_t ntrk = fesd->GetNumberOfTracks();
+ for (Int_t itrk=0; itrk<ntrk; ++itrk) {
+
+ AliESDtrack * trk = fesd->GetTrack(itrk);
+ if (trk
+ && trk->Pt() > pTmin
+ && trk->Pt() < pTmax
+ && (trk->GetStatus() & mask) == mask ) {
+
+ isOK = kTRUE;
+ break;
+ }
+ if (trk
+ && trk->GetInnerParam()
+ && trk->GetInnerParam()->Pt() > pTminCosmic
+ && trk->GetInnerParam()->Pt() < pTmaxCosmic
+ && (trk->GetStatus() & maskCosmic) == maskCosmic ) {
+
+ cosmicCount++;
+ break;
+ }
+ }
+ if (cosmicCount>1) isOK=kTRUE;
+ }
+ return isOK;
+}
+
+//______________________________________________________________________________
+Bool_t AliReconstruction::IsCosmicOrCalibSpecie() const {
+ // Select cosmic or calibration events
+
+ Bool_t isOK = kFALSE;
+
+ if (fesd && fesd->GetEventType()==AliRawEventHeaderBase::kPhysicsEvent) {
+ // Check if this ia a physics event (code 7)
+
+ UInt_t specie = fesd->GetEventSpecie();
+ if (specie==AliRecoParam::kCosmic || specie==AliRecoParam::kCalib) {
+ isOK = kTRUE;
+ }
+ }
+ return isOK;
+}
+
+//______________________________________________________________________________
+void AliReconstruction::WriteESDfriend() {
+ // Fill the ESD friend in the tree. The required fraction of ESD friends is stored
+ // in fFractionFriends. We select events where we store the ESD friends according
+ // to the following algorithm:
+ // 1. Store all Cosmic or Calibration events within the required fraction
+ // 2. Sample "high Pt" events within the remaining fraction after step 1.
+ // 3. Sample randomly events if we still have remaining slot
+
+ fNall++;
+ Bool_t isSelected = kFALSE;
+ //
+ // Store all friends for B field OFF
+ if (TMath::Abs(AliTrackerBase::GetBz())<0.5) isSelected=kTRUE;
+
+ if (IsCosmicOrCalibSpecie()) { // Selection of calib or cosmic events
+ fNspecie++;
+ Double_t curentSpecieFraction = ((Double_t)(fNspecie+1))/((Double_t)(fNall+1));
+ // "Bayesian" estimate supposing that without events all the events are of the required type
+
+ Double_t rnd = gRandom->Rndm()*curentSpecieFraction;
+ if (rnd<fFractionFriends) {
+ isSelected = kTRUE;
+ fSspecie++;
+ }
+ }
+
+ Double_t remainingFraction = fFractionFriends;
+ remainingFraction -= ((Double_t)(fSspecie)/(Double_t)(fNall));
+
+ if (IsHighPt()) { // Selection of "high Pt" events
+ fNhighPt++;
+ Double_t curentHighPtFraction = ((Double_t)(fNhighPt+1))/((Double_t)(fNall+1));
+ // "Bayesian" estimate supposing that without events all the events are of the required type
+
+ if (!isSelected) {
+ Double_t rnd = gRandom->Rndm()*curentHighPtFraction;
+ if (rnd<remainingFraction) {
+ isSelected = kTRUE;
+ fShighPt++;
+ }
+ }
+ }
+ remainingFraction -= ((Double_t)(fShighPt)/(Double_t)(fNall));
+
+ // Random selection to fill the remaining fraction (if any)
+ if (!isSelected) {
+ Double_t rnd = gRandom->Rndm();
+ if (rnd<remainingFraction) {
+ isSelected = kTRUE;
+ }
+ }
+
+ if (!isSelected) {
+ fesdf->~AliESDfriend();
+ new (fesdf) AliESDfriend(); // Reset...
+ fesdf->SetSkipBit(kTRUE);
+ }
+
+ ftreeF->Fill();
+}