FLOW/Tasks/AliAnalysisTaskQAPmdflow.cxx
FLOW/Tasks/AliFlowBayesianPID.cxx
FLOW/Tasks/AliAnalysisTaskPhiFlow.cxx
+ FLOW/Tasks/AliAnalysisTaskFilterFE.cxx
)
string ( REPLACE ".cxx" ".h" HDRS "${SRCS}" )
TString sPOI[2] = {"RP","POI"};
TString sEta[2] = {"Pt","eta"};
TString sWeights[3] = {"uQ","uQuQ","uQQaQb"};
- Int_t iNbins[2];
- Double_t dMin[2], dMax[2];
-
- iNbins[0] = AliFlowCommonConstants::GetMaster()->GetNbinsPt();
- iNbins[1] = AliFlowCommonConstants::GetMaster()->GetNbinsEta();
- dMin[0] = AliFlowCommonConstants::GetMaster()->GetPtMin();
- dMin[1] = AliFlowCommonConstants::GetMaster()->GetEtaMin();
- dMax[0] = AliFlowCommonConstants::GetMaster()->GetPtMax();
- dMax[1] = AliFlowCommonConstants::GetMaster()->GetEtaMax();
for(Int_t iPOI=0; iPOI!=2; ++iPOI) for(Int_t iSpace=0; iSpace!=2; ++iSpace) {
fHistProUQ[iPOI][iSpace] = (TProfile*) uQ->FindObject( Form( "FlowPro_UQ_%s%s_SP", sEta[iSpace].Data(), sPOI[iPOI].Data() ) );
if(!fHistProUQ[iPOI][iSpace]) printf("Error loading fHistProUQ[%d][%d]\n",iPOI,iSpace);
fPhi(0),
fTrackWeight(1.),
fCharge(0),
+ fMass(-1),
fFlowBits(0),
fSubEventBits(0),
fID(-1)
}
//-----------------------------------------------------------------------
-AliFlowTrackSimple::AliFlowTrackSimple(Double_t phi, Double_t eta, Double_t pt, Double_t weight, Int_t charge):
+AliFlowTrackSimple::AliFlowTrackSimple(Double_t phi, Double_t eta, Double_t pt, Double_t weight, Int_t charge, Double_t mass):
TObject(),
fEta(eta),
fPt(pt),
fPhi(phi),
fTrackWeight(weight),
fCharge(charge),
+ fMass(mass),
fFlowBits(0),
fSubEventBits(0),
fID(-1)
fPhi(p->Phi()),
fTrackWeight(1.),
fCharge(0),
+ fMass(-1),
fFlowBits(0),
fSubEventBits(0),
fID(-1)
//ctor
TParticlePDG* ppdg = p->GetPDG();
fCharge = TMath::Nint(ppdg->Charge()/3.0);
+ fMass = ppdg->Mass();
}
//-----------------------------------------------------------------------
fTrackWeight = 1.;
TParticlePDG* ppdg = p->GetPDG();
fCharge = TMath::Nint(ppdg->Charge()/3.0);
+ fMass = ppdg->Mass();
}
//-----------------------------------------------------------------------
fPhi(aTrack.fPhi),
fTrackWeight(aTrack.fTrackWeight),
fCharge(aTrack.fCharge),
+ fMass(aTrack.fMass),
fFlowBits(aTrack.fFlowBits),
fSubEventBits(aTrack.fSubEventBits),
fID(aTrack.fID)
fPhi = aTrack.fPhi;
fTrackWeight = aTrack.fTrackWeight;
fCharge = aTrack.fCharge;
+ fMass = aTrack.fMass;
fFlowBits = aTrack.fFlowBits;
fSubEventBits = aTrack.fSubEventBits;
fID = aTrack.fID;
fPhi=0.0;
fTrackWeight=1.0;
fCharge=0;
+ fMass=-1;
fFlowBits.ResetAllBits();
fSubEventBits.ResetAllBits();
fID=-1;
Double_t Phi() const;
Double_t Weight() const;
Int_t Charge() const;
+ Double_t Mass() const;
Int_t PID() const {return 0;}
Bool_t InRPSelection() const;
void SetPhi(Double_t phi);
void SetWeight(Double_t weight);
void SetCharge(Int_t charge);
+ void SetMass(Double_t mass);
void SetForRPSelection(Bool_t b=kTRUE);
void SetForPOISelection(Bool_t b=kTRUE);
void TagRP(Bool_t b=kTRUE) {SetForRPSelection(b);}
Int_t GetID() const {return fID;}
private:
- AliFlowTrackSimple(Double_t phi, Double_t eta, Double_t pt, Double_t weight, Int_t charge);
+ AliFlowTrackSimple(Double_t phi, Double_t eta, Double_t pt, Double_t weight, Int_t charge, Double_t mass=-1);
Double_t fEta; // eta
Double_t fPt; // pt
Double_t fPhi; // phi
Double_t fTrackWeight; // weight
Int_t fCharge; //charge
+ Double_t fMass; // mass
TBits fFlowBits; // bits to set if track is selected
TBits fSubEventBits;// bits to set if track is selected for a subevent
Int_t fID; // Unique track ID, point back to the ESD track
- ClassDef(AliFlowTrackSimple,1) // macro for rootcint
+ ClassDef(AliFlowTrackSimple,2) // macro for rootcint
};
return this->fTrackWeight; }
inline Int_t AliFlowTrackSimple::Charge() const {
return this->fCharge; }
+inline Double_t AliFlowTrackSimple::Mass() const {
+ return this->fMass; }
//TBits
inline Bool_t AliFlowTrackSimple::InRPSelection() const {
return this->fFlowBits.TestBitNumber(kRP); }
fTrackWeight = val; }
inline void AliFlowTrackSimple::SetCharge(Int_t val) {
fCharge = val; }
+inline void AliFlowTrackSimple::SetMass(Double_t val) {
+ fMass = val; }
//TBits
inline void AliFlowTrackSimple::SetForRPSelection(Bool_t val) {
fFlowBits.SetBitNumber(kRP,val); }
fCutPID(kFALSE),
fPID(0),
fCutCharge(kFALSE),
- fCharge(0)
+ fCharge(0),
+ fCutMass(kFALSE),
+ fMassMax(FLT_MAX),
+ fMassMin(-FLT_MAX)
{
//constructor
}
if(fCutEta) {if (track->Eta() < fEtaMin || track->Eta() >= fEtaMax ) return kFALSE;}
if(fCutPhi) {if (track->Phi() < fPhiMin || track->Phi() >= fPhiMax ) return kFALSE;}
if(fCutCharge) {if (track->Charge() != fCharge) return kFALSE;}
+ if(fCutMass) {if (track->Mass() < fMassMin || track->Mass() >= fMassMax ) return kFALSE;}
//if(fCutPID) {if (track->PID() != fPID) return kFALSE;}
return kTRUE;
}
Int_t charge = TMath::Nint(ppdg->Charge()/3.0); //mc particles have charge in units of 1/3e
return (charge==fCharge);
}
+
+ if (fCutMass) {
+ TParticlePDG* ppdg = track->GetPDG();
+ if (ppdg->Mass() < fMassMin || ppdg->Mass() >= fMassMax )
+ return kFALSE;
+ }
+
return kTRUE;
}
void SetPhiMin(Double_t min) {this->fPhiMin = min; fCutPhi=kTRUE; }
void SetPID(Int_t pid) {this->fPID = pid; fCutPID=kTRUE; }
void SetCharge(Int_t c) {this->fCharge = c; fCutCharge=kTRUE; }
+ void SetMassMax(Double_t max) {this->fMassMax = max; fCutMass=kTRUE; }
+ void SetMassMin(Double_t min) {this->fMassMin = min; fCutMass=kTRUE; }
//getters
Double_t GetPtMax() const {return this->fPtMax; }
Double_t GetPhiMin() const {return this->fPhiMin; }
Int_t GetPID() const {return this->fPID; }
Int_t GetCharge() const {return this->fCharge; }
+ Double_t GetMassMax() const {return this->fMassMax; }
+ Double_t GetMassMin() const {return this->fMassMin; }
//simple method to check if the simple track passes the simple cuts:
Bool_t PassesCuts(const AliFlowTrackSimple *track) const;
Int_t fPID; //pid
Bool_t fCutCharge; //cut on charge?
Int_t fCharge; //charge
+ Bool_t fCutMass; // cut on mass?
+ Double_t fMassMax; //max mass
+ Double_t fMassMin; //min mass
- ClassDef(AliFlowTrackSimpleCuts,1)
+ ClassDef(AliFlowTrackSimpleCuts,2)
};
#endif
--- /dev/null
+/*************************************************************************
+* Copyright(c) 1998-2008, ALICE Experiment at CERN, All rights reserved. *
+* *
+* Author: The ALICE Off-line Project. *
+* Contributors are mentioned in the code where appropriate. *
+* *
+* Permission to use, copy, modify and distribute this software and its *
+* documentation strictly for non-commercial purposes is hereby granted *
+* without fee, provided that the above copyright notice appears in all *
+* copies and that both the copyright notice and this permission notice *
+* appear in the supporting documentation. The authors make no claims *
+* about the suitability of this software for any purpose. It is *
+* provided "as is" without express or implied warranty. *
+**************************************************************************/
+
+////////////////////////////////////////////////////
+// AliAnalysisTaskFilterFE:
+//
+// (re)tag RFP and POI in flowEvent in order to
+// reuse it in train
+////////////////////////////////////////////////////
+
+#include "AliAnalysisManager.h"
+#include "AliAnalysisTaskSE.h"
+#include "AliFlowEventSimple.h"
+#include "AliFlowTrackSimpleCuts.h"
+#include "AliAnalysisTaskFilterFE.h"
+
+ClassImp(AliAnalysisTaskFilterFE)
+
+//________________________________________________________________________
+AliAnalysisTaskFilterFE::AliAnalysisTaskFilterFE() :
+ AliAnalysisTaskSE(),
+ fCutsRFP(NULL),
+ fCutsPOI(NULL),
+ fMinA(-1.0),
+ fMaxA(-0.01),
+ fMinB(0.01),
+ fMaxB(1.0),
+ fFlowEvent(NULL)
+{
+ // Constructor
+ cout<<"AliAnalysisTaskFilterFE::AliAnalysisTaskFilterFE()"<<endl;
+}
+
+//________________________________________________________________________
+AliAnalysisTaskFilterFE::AliAnalysisTaskFilterFE(const char *name, AliFlowTrackSimpleCuts *cutsRFP, AliFlowTrackSimpleCuts *cutsPOI) :
+ AliAnalysisTaskSE(name),
+ fCutsRFP(cutsRFP),
+ fCutsPOI(cutsPOI),
+ fMinA(-1.0),
+ fMaxA(-0.01),
+ fMinB(0.01),
+ fMaxB(1.0),
+ fFlowEvent(NULL)
+{
+ // Constructor
+ cout<<"AliAnalysisTaskFilterFE::AliAnalysisTaskFilterFE(const char *name, ...)"<<endl;
+ DefineInput( 0, AliFlowEventSimple::Class());
+ DefineOutput(1, AliFlowEventSimple::Class());
+}
+
+//________________________________________________________________________
+AliAnalysisTaskFilterFE::~AliAnalysisTaskFilterFE()
+{
+ // Destructor
+ delete fCutsRFP;
+ delete fCutsPOI;
+}
+//________________________________________________________________________
+void AliAnalysisTaskFilterFE::UserCreateOutputObjects()
+{
+ // Called at every worker node to initialize
+ cout<<"AliAnalysisTaskFilterFE::CreateOutputObjects()"<<endl;
+ PostData(1,fFlowEvent);
+}
+
+//________________________________________________________________________
+void AliAnalysisTaskFilterFE::UserExec(Option_t *)
+{
+ // Main loop
+ fFlowEvent = dynamic_cast<AliFlowEventSimple*>(GetInputData(0)); // from TaskSE
+ if (!fFlowEvent) return;
+ if(fCutsRFP) fFlowEvent->TagRP(fCutsRFP);
+ if(fCutsPOI) fFlowEvent->TagPOI(fCutsPOI);
+ fFlowEvent->TagSubeventsInEta(fMinA,fMaxA,fMinB,fMaxB);
+ PostData(1,fFlowEvent);
+}
--- /dev/null
+/////////////////////////////////////////////////////
+// AliAnalysisTaskFilterFE:
+// analysis task to (re)tag RFP and POI of flow event
+//////////////////////////////////////////////////////
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+* See cxx source for full Copyright notice */
+/* $Id: $ */
+
+#ifndef ALIANALYSISTASKFILTERFE_H
+#define ALIANALYSISTASKFILTERFE_H
+
+#include "AliFlowTrackSimpleCuts.h"
+#include "AliFlowEventSimple.h"
+
+class AliAnalysisTaskSE;
+
+class AliAnalysisTaskFilterFE : public AliAnalysisTaskSE {
+ public:
+ AliAnalysisTaskFilterFE();
+ AliAnalysisTaskFilterFE(const char *name, AliFlowTrackSimpleCuts *cutsRFP, AliFlowTrackSimpleCuts *cutsPOI);
+ virtual ~AliAnalysisTaskFilterFE();
+
+ virtual void UserCreateOutputObjects();
+ virtual void UserExec(Option_t *option);
+
+ void SetSubeventEtaRange(Double_t minA, Double_t maxA, Double_t minB, Double_t maxB)
+ {this->fMinA = minA; this->fMaxA = maxA; this->fMinB = minB; this->fMaxB = maxB; }
+
+ private:
+
+ AliAnalysisTaskFilterFE(const AliAnalysisTaskFilterFE& aAnalysisTask);
+ AliAnalysisTaskFilterFE& operator=(const AliAnalysisTaskFilterFE& aAnalysisTask);
+
+ AliFlowTrackSimpleCuts* fCutsRFP; //cuts for RFPs
+ AliFlowTrackSimpleCuts* fCutsPOI; //cuts for POIs
+ Double_t fMinA; //minimum of eta range for subevent A
+ Double_t fMaxA; //maximum of eta range for subevent A
+ Double_t fMinB; //minimum of eta range for subevent B
+ Double_t fMaxB; //maximum of eta range for subevent B
+ AliFlowEventSimple* fFlowEvent; //flowevent
+
+ ClassDef(AliAnalysisTaskFilterFE, 1); // example of analysis
+};
+
+#endif
+
fFlowEvent->Fill( fCutsRP, fCutsPOI );
//fFlowEvent = new AliFlowEvent( fCutsRP, fCutsPOI );
- if (myESD)
+ // if (myESD)
fFlowEvent->SetReferenceMultiplicity(fCutsEvent->GetReferenceMultiplicity(InputEvent()));
if (mcEvent && mcEvent->GenEventHeader()) fFlowEvent->SetMCReactionPlaneAngle(mcEvent);
}
//QA
if (fQAon)
{
- TH1* h1 = static_cast<TH1*>(fQAList->At(3));
+ TH1* h1 = static_cast<TH1*>(fQAList->FindObject("event plane angle"));
h1->Fill(fFlowEvent->GetMCReactionPlaneAngle());
}
AliFlowCandidateTrack::AliFlowCandidateTrack():
AliFlowTrack(),
- fMass(0),
fNDaughters(0)
{
// ctor
AliFlowCandidateTrack::AliFlowCandidateTrack(const AliFlowCandidateTrack& aTrack):
AliFlowTrack(aTrack),
- fMass(aTrack.fMass),
fNDaughters(aTrack.fNDaughters)
{
// ctor
if (this == &aTrack) return *this; //handles self assignment
AliFlowTrack::operator=(aTrack);
- fMass = aTrack.fMass;
fNDaughters = aTrack.fNDaughters;
for(int i=0; i!=5; ++i) {
fDaughter[i] = aTrack.fDaughter[i];
AliFlowCandidateTrack& operator=(const AliFlowCandidateTrack& );
~AliFlowCandidateTrack();
- Double_t Mass(void) const { return fMass; }
- void SetMass(Double_t value) { fMass=value; }
-
Int_t GetNDaughters(void) const { return fNDaughters; }
void AddDaughter(Int_t value) { if(fNDaughters<3) fDaughter[fNDaughters++]=value; }
Int_t GetIDDaughter(Int_t value) const { return fDaughter[value]; }
AliFlowTrack *GetDaughter(Int_t value) const { return fTrack[value]; }
protected:
- Double_t fMass; // mass
Int_t fNDaughters; // number of daughters (5 max)
Int_t fDaughter[5]; // fID of daughter, points back to ESD track
AliFlowTrack *fTrack[5]; // pointer to daughter in FlowEvent
- ClassDef(AliFlowCandidateTrack, 1);
+ ClassDef(AliFlowCandidateTrack, 2);
};
#endif
#include "AliVVertex.h"
#include "AliVEvent.h"
#include "AliESDEvent.h"
+#include "AliAODEvent.h"
+#include "AliAODHeader.h"
#include "AliCentrality.h"
#include "AliESDVZERO.h"
#include "AliMultiplicity.h"
Int_t ncontrib = pvtx->GetNContributors();
Bool_t pass=kTRUE;
AliESDEvent* esdevent = dynamic_cast<AliESDEvent*>(event);
+ AliAODEvent* aodevent = dynamic_cast<AliAODEvent*>(event);
Int_t multTPC = 0;
Int_t multGlobal = 0;
if (fQA)
pass=kFALSE;
}
}
+
+ // Handles AOD event
+ if(aodevent) {
+ if (fCutCentralityPercentile) {
+ AliCentrality* centr = aodevent->GetHeader()->GetCentralityP();
+ if (fUseCentralityUnchecked) {
+ if (!centr->IsEventInCentralityClassUnchecked( fCentralityPercentileMin,
+ fCentralityPercentileMax,
+ CentrMethName(fCentralityPercentileMethod) )) {
+ pass = kFALSE;
+ }
+ } else {
+ if (!centr->IsEventInCentralityClass( fCentralityPercentileMin,
+ fCentralityPercentileMax,
+ CentrMethName(fCentralityPercentileMethod) )) {
+ pass = kFALSE;
+ }
+ }
+ }
+ }
+
if (fCutMeanPt)
{
Float_t meanpt=0.0;
//the case of ESD or AOD
if (esdTrack) { if (!PassesESDcuts(esdTrack)) { pass=kFALSE; } }
- if (aodTrack) { if (!PassesAODcuts(aodTrack)) { pass=kFALSE; } }
+ if (aodTrack) { if (!PassesAODcuts(aodTrack,pass)) { pass=kFALSE; } }
if (fQA)
{
}
//_______________________________________________________________________
-Bool_t AliFlowTrackCuts::PassesAODcuts(const AliAODTrack* track)
+Bool_t AliFlowTrackCuts::PassesAODcuts(const AliAODTrack* track, Bool_t passedFid)
{
//check cuts for AOD
- Bool_t pass = kTRUE;
+ Bool_t pass = passedFid;
if (fCutNClustersTPC)
{
if (fCutDCAToVertexZ && track->ZAtDCA()>GetMaxDCAToVertexZ()) pass=kFALSE;
- if (track->GetTPCsignal() < fMinimalTPCdedx) pass=kFALSE;
+ Double_t dedx = track->GetTPCsignal();
+ if (dedx < fMinimalTPCdedx) pass=kFALSE;
+ Double_t time[5];
+ track->GetIntegratedTimes(time);
+ if (fQA) {
+ Double_t momTPC = track->GetTPCmomentum();
+ QAbefore( 1)->Fill(momTPC,dedx);
+ QAbefore( 5)->Fill(track->Pt(),track->DCA());
+ QAbefore( 6)->Fill(track->Pt(),track->ZAtDCA());
+ if (pass) QAafter( 1)->Fill(momTPC,dedx);
+ if (pass) QAafter( 5)->Fill(track->Pt(),track->DCA());
+ if (pass) QAafter( 6)->Fill(track->Pt(),track->ZAtDCA());
+ QAbefore( 8)->Fill(track->P(),(track->GetTOFsignal()-time[AliPID::kElectron]));
+ if (pass) QAafter( 8)->Fill(track->P(),(track->GetTOFsignal()-time[AliPID::kElectron]));
+ QAbefore( 9)->Fill(track->P(),(track->GetTOFsignal()-time[AliPID::kMuon]));
+ if (pass) QAafter( 9)->Fill(track->P(),(track->GetTOFsignal()-time[AliPID::kMuon]));
+ QAbefore(10)->Fill(track->P(),(track->GetTOFsignal()-time[AliPID::kPion]));
+ if (pass) QAafter( 10)->Fill(track->P(),(track->GetTOFsignal()-time[AliPID::kPion]));
+ QAbefore(11)->Fill(track->P(),(track->GetTOFsignal()-time[AliPID::kKaon]));
+ if (pass) QAafter( 11)->Fill(track->P(),(track->GetTOFsignal()-time[AliPID::kKaon]));
+ QAbefore(12)->Fill(track->P(),(track->GetTOFsignal()-time[AliPID::kProton]));
+ if (pass) QAafter( 12)->Fill(track->P(),(track->GetTOFsignal()-time[AliPID::kProton]));
+ }
return pass;
}
before->Add(hb);//7
after->Add(ha);//7
+ before->Add(new TH2F("TOFkElectron",";p_{t}[GeV/c];TOF signal - IT", kNbinsP,binsP,1000,-2e4, 2e4));//8
+ after->Add( new TH2F("TOFkElectron",";p_{t}[GeV/c];TOF signal - IT", kNbinsP,binsP,1000,-2e4, 2e4));//8
+
+ before->Add(new TH2F("TOFkMuon",";p_{t}[GeV/c];TOF signal - IT", kNbinsP,binsP,1000,-2e4, 2e4));//9
+ after->Add( new TH2F("TOFkMuon",";p_{t}[GeV/c];TOF signal - IT", kNbinsP,binsP,1000,-2e4, 2e4));//9
+
+ before->Add(new TH2F("TOFkPion",";p_{t}[GeV/c];TOF signal - IT", kNbinsP,binsP,1000,-2e4, 2e4));//10
+ after->Add( new TH2F("TOFkPion",";p_{t}[GeV/c];TOF signal - IT", kNbinsP,binsP,1000,-2e4, 2e4));//10
+
+ before->Add(new TH2F("TOFkKaon",";p_{t}[GeV/c];TOF signal - IT", kNbinsP,binsP,1000,-2e4, 2e4));//11
+ after->Add( new TH2F("TOFkKaon",";p_{t}[GeV/c];TOF signal - IT", kNbinsP,binsP,1000,-2e4, 2e4));//11
+
+ before->Add(new TH2F("TOFkProton",";p_{t}[GeV/c];TOF signal - IT", kNbinsP,binsP,1000,-2e4, 2e4));//12
+ after->Add( new TH2F("TOFkProton",";p_{t}[GeV/c];TOF signal - IT", kNbinsP,binsP,1000,-2e4, 2e4));//12
+
TH1::AddDirectory(adddirstatus);
}
//these should maybe be protected
Bool_t PassesCuts(AliVParticle* track);
Bool_t PassesESDcuts(AliESDtrack* track);
- Bool_t PassesAODcuts(const AliAODTrack* track);
+ Bool_t PassesAODcuts(const AliAODTrack* track, Bool_t passFid=kTRUE);
Bool_t PassesPMDcuts(const AliESDPmdTrack* track);
Bool_t PassesV0cuts(Int_t id);
Bool_t PassesCuts(const AliFlowTrackSimple* track);
ALICEINC += -I../$(CORRFW_INCLUDE)
endif
+ifneq ($(PWGflowBase_INCLUDE),)
+ ALICEINC += -I../$(PWGflowBase_INCLUDE)
+endif
+
+#needed by flowTasks
+ALICEINC += -I$(ALICE_ROOT)/TOF
+
+ifneq ($(PWGflowTasks_INCLUDE),)
+ ALICEINC += -I../$(PWGflowTasks_INCLUDE)
+endif
+
# only if no par file was loaded before
#ifeq ($(ALICEINC),-I.)
ifneq ($(ALICE_ROOT),)
TString dypath = gSystem->GetDynamicPath();
dypath.Prepend(".:");
gSystem->SetDynamicPath(dypath);
- gSystem->Load("libPWGflowCommon");
+ gSystem->Load("libPWGflowBase");
gSystem->Load("libPWGflowTasks");
// Set the include paths
- gROOT->ProcessLine(".include PWGflowTasks/FLOW/Tasks");
+ gROOT->ProcessLine(".include PWGflowTasks/FLOW/Tasks $(ALICE_ROOT)/TOF");
// Set our location, so that other packages can find us
gSystem->Setenv("PWGflowTasks_INCLUDE", "PWGflowTasks/FLOW/Tasks");
#pragma link C++ class AliAnalysisTaskQAPmdflow+;
#pragma link C++ class AliFlowBayesianPID+;
#pragma link C++ class AliAnalysisTaskPhiFlow+;
+#pragma link C++ class AliAnalysisTaskFilterFE+;
#endif