<commit_before>/**************************************************************************
 * Copyright(c) 1998-2009, 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.                  *
 **************************************************************************/

//-----------------------------------------------------------------
//         AliAnalysisTaskSpectraAllChAOD class
//-----------------------------------------------------------------

#include "TChain.h"
#include "TTree.h"
#include "TLegend.h"
#include "TH1F.h"
#include "TH2F.h"
#include "THnSparse.h"
#include "TCanvas.h"
#include "AliAnalysisTask.h"
#include "AliAODTrack.h"
#include "AliAODMCParticle.h"
#include "AliVParticle.h"
#include "AliAODEvent.h"
#include "AliAODInputHandler.h"
#include "AliAnalysisTaskSpectraAllChAOD.h"
#include "AliAnalysisTaskESDfilter.h"
#include "AliAnalysisDataContainer.h"
#include "AliSpectraAODTrackCuts.h"
#include "AliSpectraAODEventCuts.h"
#include "AliHelperPID.h"
#include "AliPIDCombined.h"
#include "AliCentrality.h"
#include "TProof.h"
#include "AliVEvent.h"
#include "AliStack.h"
#include <TMCProcess.h>

#include <iostream>

using namespace AliHelperPIDNameSpace;
using namespace std;

ClassImp(AliAnalysisTaskSpectraAllChAOD)

//________________________________________________________________________
AliAnalysisTaskSpectraAllChAOD::AliAnalysisTaskSpectraAllChAOD(const char *name) : AliAnalysisTaskSE(name),
  fAOD(0x0),
  fTrackCuts(0x0),
  fEventCuts(0x0),
  fHelperPID(0x0),
  fIsMC(0),
  fDoDoubleCounting(0),
  fFillOnlyEvents(0),
  fCharge(0),
  fVZEROside(0),
  fOutput(0x0),
  fnCentBins(20),
  fnQvecBins(100),
  fnNchBins(200),
  fIsQvecCalibMode(0),
  fQvecUpperLim(100)
{
  // Default constructor
  DefineInput(0, TChain::Class());
  DefineOutput(1, TList::Class());
  DefineOutput(2, AliSpectraAODEventCuts::Class());
  DefineOutput(3, AliSpectraAODTrackCuts::Class());
  DefineOutput(4, AliHelperPID::Class());
}

//________________________________________________________________________
void AliAnalysisTaskSpectraAllChAOD::UserCreateOutputObjects()
{
  // create output objects
  fOutput=new TList();
  fOutput->SetOwner();
  fOutput->SetName("fOutput");

  if (!fTrackCuts) AliFatal("Track Cuts should be set in the steering macro");
  if (!fEventCuts) AliFatal("Event Cuts should be set in the steering macro");
  if (!fHelperPID)  AliFatal("HelperPID should be set in the steering macro");

  // binning common to all the THn
  const Double_t ptBins[] = {0.20,0.30,0.4,0.5,0.6,0.7,0.8,0.9,1.0,1.2,1.4,1.6,1.8,2.0,2.4,2.8,3.2,3.6,4.0,5.0,6.0,7.0,8.0,9.0,10.,12.,15.};
  const Int_t nptBins=26;

  //dimensions of THnSparse for tracks
  const Int_t nvartrk=7;
  //                                             pt          cent          Q vec     IDrec      IDgen       isph         y
  Int_t    binsHistRealTrk[nvartrk] = {      nptBins, fnCentBins,     fnQvecBins,        4,        3,         2,        2};
  Double_t xminHistRealTrk[nvartrk] = {         0.,          0.,              0.,       -.5,      -0.5,      -0.5,    -0.5};
  Double_t xmaxHistRealTrk[nvartrk] = {       10.,       100., fQvecUpperLim,      3.5,      2.5,       1.5,     0.5};
  THnSparseF* NSparseHistTrk = new THnSparseF("NSparseHistTrk","NSparseHistTrk",nvartrk,binsHistRealTrk,xminHistRealTrk,xmaxHistRealTrk);
  NSparseHistTrk->GetAxis(0)->SetTitle("#it{p}_{T,rec}");
  NSparseHistTrk->GetAxis(0)->SetName("pT_rec");
  NSparseHistTrk->SetBinEdges(0,ptBins);
  NSparseHistTrk->GetAxis(1)->SetTitle(Form("%s cent",fEventCuts->GetCentralityMethod().Data()));
  NSparseHistTrk->GetAxis(1)->SetName(Form("%s_cent",fEventCuts->GetCentralityMethod().Data()));
  NSparseHistTrk->GetAxis(2)->SetTitle("Q vec");
  NSparseHistTrk->GetAxis(2)->SetName("Q_vec");
  NSparseHistTrk->GetAxis(3)->SetTitle("ID rec");
  NSparseHistTrk->GetAxis(3)->SetName("ID_rec");
  NSparseHistTrk->GetAxis(4)->SetTitle("ID gen");
  NSparseHistTrk->GetAxis(4)->SetName("ID_gen");
  NSparseHistTrk->GetAxis(5)->SetTitle("isph");
  NSparseHistTrk->GetAxis(5)->SetName("isph");
  NSparseHistTrk->GetAxis(6)->SetTitle("y");
  NSparseHistTrk->GetAxis(6)->SetName("y");
  fOutput->Add(NSparseHistTrk);

  //dimensions of THnSparse for stack
  const Int_t nvarst=6;
  //                                             pt          cent    IDgen        isph        y    etaselected
  Int_t    binsHistRealSt[nvarst] = {      nptBins,  fnCentBins,        3,         2,        2,             1};
  Double_t xminHistRealSt[nvarst] = {         0.,           0.,      -0.5,      -0.5,    -0.5,            0.5};
  Double_t xmaxHistRealSt[nvarst] = {       10.,        100.,      2.5,       1.5,      0.5,           1.5};
  THnSparseF* NSparseHistSt = new THnSparseF("NSparseHistSt","NSparseHistSt",nvarst,binsHistRealSt,xminHistRealSt,xmaxHistRealSt);
  NSparseHistSt->GetAxis(0)->SetTitle("#it{p}_{T,gen}");
  NSparseHistSt->SetBinEdges(0,ptBins);
  NSparseHistSt->GetAxis(0)->SetName("pT_rec");
  NSparseHistSt->GetAxis(1)->SetTitle(Form("%s cent",fEventCuts->GetCentralityMethod().Data()));
  NSparseHistSt->GetAxis(1)->SetName(Form("%s_cent",fEventCuts->GetCentralityMethod().Data()));
  NSparseHistSt->GetAxis(2)->SetTitle("ID gen");
  NSparseHistSt->GetAxis(2)->SetName("ID_gen");
  NSparseHistSt->GetAxis(3)->SetTitle("isph");
  NSparseHistSt->GetAxis(3)->SetName("isph");
  NSparseHistSt->GetAxis(4)->SetTitle("y");
  NSparseHistSt->GetAxis(4)->SetName("y");
  NSparseHistSt->GetAxis(5)->SetTitle("etaselected");
  NSparseHistSt->GetAxis(5)->SetName("etaselected");
  fOutput->Add(NSparseHistSt);

  //dimensions of THnSparse for the normalization
  const Int_t nvarev=3;
  //                                             cent             Q vec                Nch
  Int_t    binsHistRealEv[nvarev] = {    fnCentBins,      fnQvecBins,           fnNchBins};
  Double_t xminHistRealEv[nvarev] = {           0.,               0.,                   0.};
  Double_t xmaxHistRealEv[nvarev] = {       100.,  fQvecUpperLim,               2000.};
  THnSparseF* NSparseHistEv = new THnSparseF("NSparseHistEv","NSparseHistEv",nvarev,binsHistRealEv,xminHistRealEv,xmaxHistRealEv);
  NSparseHistEv->GetAxis(0)->SetTitle(Form("%s cent",fEventCuts->GetCentralityMethod().Data()));
  NSparseHistEv->GetAxis(0)->SetName(Form("%s_cent",fEventCuts->GetCentralityMethod().Data()));
  NSparseHistEv->GetAxis(1)->SetTitle("Q vec");
  NSparseHistEv->GetAxis(1)->SetName("Q_vec");
  NSparseHistEv->GetAxis(2)->SetTitle("N charged");
  NSparseHistEv->GetAxis(2)->SetName("N_ch");
  fOutput->Add(NSparseHistEv);

  PostData(1, fOutput  );
  PostData(2, fEventCuts);
  PostData(3, fTrackCuts);
  PostData(4, fHelperPID);
}

//________________________________________________________________________

void AliAnalysisTaskSpectraAllChAOD::UserExec(Option_t *)
{
  //Printf("An event");
  // main event loop
  fAOD = dynamic_cast<AliAODEvent*>(fInputEvent);
  if (!fAOD) {
    AliWarning("ERROR: AliAODEvent not available \n");
    return;
  }

  if (strcmp(fAOD->ClassName(), "AliAODEvent"))
    {
      AliFatal("Not processing AODs");
    }

  if(!fEventCuts->IsSelected(fAOD,fTrackCuts))return;//event selection

  //Default TPC priors
  if(fHelperPID->GetPIDType()==kBayes)fHelperPID->GetPIDCombined()->SetDefaultTPCPriors();//FIXME maybe this can go in the UserCreateOutputObject?

  Double_t Qvec=0.;//in case of MC we save space in the memory
  if(!fIsMC){
    if(fIsQvecCalibMode){
      if(fVZEROside==0)Qvec=fEventCuts->GetqV0A();
      else if (fVZEROside==1)Qvec=fEventCuts->GetqV0C();
    }
    else Qvec=fEventCuts->GetQvecPercentile(fVZEROside);
  }

  Double_t Cent=fEventCuts->GetCent();

  // First do MC to fill up the MC particle array
  TClonesArray *arrayMC = 0;
  if (fIsMC)
    {
      arrayMC = (TClonesArray*) fAOD->GetList()->FindObject(AliAODMCParticle::StdBranchName());
      if (!arrayMC) {
	AliFatal("Error: MC particles branch not found!\n");
      }
      Int_t nMC = arrayMC->GetEntries();
      for (Int_t iMC = 0; iMC < nMC; iMC++)
	{
	  AliAODMCParticle *partMC = (AliAODMCParticle*) arrayMC->At(iMC);
	  if(!partMC->Charge()) continue;//Skip neutrals
	  if(fCharge != 0 && partMC->Charge()*fCharge < 0.) continue;//if fCharge != 0 only select fCharge

	  //flag to select particle in the same ETA acceptance of the tracks (to be used for the comparison with AllCh)
	  Double_t etaselected=-1.;
	  if(partMC->Eta()<fTrackCuts->GetEtaMin() || partMC->Eta()>fTrackCuts->GetEtaMax())etaselected=1.;

	  //pt     cent    IDgen        isph        y
 	  Double_t varSt[6];
	  varSt[0]=partMC->Pt();
	  varSt[1]=Cent;
	  varSt[2]=(Double_t)fHelperPID->GetParticleSpecies(partMC);
	  varSt[3]=(Double_t)partMC->IsPhysicalPrimary();
	  varSt[4]=partMC->Y();
	  varSt[5]=etaselected;
	  ((THnSparseF*)fOutput->FindObject("NSparseHistSt"))->Fill(varSt);//stack loop

	  //Printf("a particle");

	}
    }

  //main loop on tracks

  Int_t Nch = 0.;

  for (Int_t iTracks = 0; iTracks < fAOD->GetNumberOfTracks(); iTracks++) {
    AliAODTrack* track = fAOD->GetTrack(iTracks);
    if(fCharge != 0 && track->Charge() != fCharge) continue;//if fCharge != 0 only select fCharge
    if (!fTrackCuts->IsSelected(track,kTRUE)) continue; //track selection (rapidity selection NOT in the standard cuts)
    if(!fFillOnlyEvents){
      Int_t IDrec=fHelperPID->GetParticleSpecies(track,kTRUE);//id from detector
      Double_t y= track->Y(fHelperPID->GetMass((AliHelperParticleSpecies_t)IDrec));
      Int_t IDgen=kSpUndefined;//set if MC
      Int_t isph=-999;
      //Int_t iswd=-999;

      if (arrayMC) {
	AliAODMCParticle *partMC = (AliAODMCParticle*) arrayMC->At(TMath::Abs(track->GetLabel()));
	if (!partMC) {
	  AliError("Cannot get MC particle");
	  continue;
	}
	IDgen=fHelperPID->GetParticleSpecies(partMC);
	isph=partMC->IsPhysicalPrimary();
	//iswd=partMC->IsSecondaryFromWeakDecay();//FIXME not working on old productions - removed Apr 8th 2014
      }

    //pt     cent    Q vec     IDrec     IDgen       isph      y
      Double_t varTrk[7];
      varTrk[0]=track->Pt();
      varTrk[1]=Cent;
      varTrk[2]=Qvec;
      varTrk[3]=(Double_t)IDrec;
      varTrk[4]=(Double_t)IDgen;
      varTrk[5]=(Double_t)isph;
      varTrk[6]=y;
      ((THnSparseF*)fOutput->FindObject("NSparseHistTrk"))->Fill(varTrk);//track loop

      //for nsigma PID fill double counting of ID
      if(fHelperPID->GetPIDType()<kBayes && fDoDoubleCounting){//only nsigma
	Bool_t *HasDC;
	HasDC=fHelperPID->GetDoubleCounting(track,kTRUE);//get the array with double counting
	for(Int_t ipart=0;ipart<kNSpecies;ipart++){
	  if(HasDC[ipart]==kTRUE){
	    varTrk[3]=(Double_t)ipart;
	    ((THnSparseF*)fOutput->FindObject("NSparseHistTrk"))->Fill(varTrk);//track loop
	  }
	}
      }

      //fill all charged (3)
      varTrk[3]=3.;
      varTrk[4]=3.;
      ((THnSparseF*)fOutput->FindObject("NSparseHistTrk"))->Fill(varTrk);//track loop
    }//end if fFillOnlyEvents

    //Printf("a track");

    Nch++;
  } // end loop on tracks

  Double_t varEv[3];
  varEv[0]=Cent;
  varEv[1]=Qvec;
  varEv[2]=Nch;
  ((THnSparseF*)fOutput->FindObject("NSparseHistEv"))->Fill(varEv);//event loop

  PostData(1, fOutput  );
  PostData(2, fEventCuts);
  PostData(3, fTrackCuts);
  PostData(4, fHelperPID);
}

//_________________________________________________________________
void   AliAnalysisTaskSpectraAllChAOD::Terminate(Option_t *)
{
  // Terminate
}
<commit_msg>eta selection fixed<commit_after>/**************************************************************************
 * Copyright(c) 1998-2009, 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.                  *
 **************************************************************************/

//-----------------------------------------------------------------
//         AliAnalysisTaskSpectraAllChAOD class
//-----------------------------------------------------------------

#include "TChain.h"
#include "TTree.h"
#include "TLegend.h"
#include "TH1F.h"
#include "TH2F.h"
#include "THnSparse.h"
#include "TCanvas.h"
#include "AliAnalysisTask.h"
#include "AliAODTrack.h"
#include "AliAODMCParticle.h"
#include "AliVParticle.h"
#include "AliAODEvent.h"
#include "AliAODInputHandler.h"
#include "AliAnalysisTaskSpectraAllChAOD.h"
#include "AliAnalysisTaskESDfilter.h"
#include "AliAnalysisDataContainer.h"
#include "AliSpectraAODTrackCuts.h"
#include "AliSpectraAODEventCuts.h"
#include "AliHelperPID.h"
#include "AliPIDCombined.h"
#include "AliCentrality.h"
#include "TProof.h"
#include "AliVEvent.h"
#include "AliStack.h"
#include <TMCProcess.h>

#include <iostream>

using namespace AliHelperPIDNameSpace;
using namespace std;

ClassImp(AliAnalysisTaskSpectraAllChAOD)

//________________________________________________________________________
AliAnalysisTaskSpectraAllChAOD::AliAnalysisTaskSpectraAllChAOD(const char *name) : AliAnalysisTaskSE(name),
  fAOD(0x0),
  fTrackCuts(0x0),
  fEventCuts(0x0),
  fHelperPID(0x0),
  fIsMC(0),
  fDoDoubleCounting(0),
  fFillOnlyEvents(0),
  fCharge(0),
  fVZEROside(0),
  fOutput(0x0),
  fnCentBins(20),
  fnQvecBins(100),
  fnNchBins(200),
  fIsQvecCalibMode(0),
  fQvecUpperLim(100)
{
  // Default constructor
  DefineInput(0, TChain::Class());
  DefineOutput(1, TList::Class());
  DefineOutput(2, AliSpectraAODEventCuts::Class());
  DefineOutput(3, AliSpectraAODTrackCuts::Class());
  DefineOutput(4, AliHelperPID::Class());
}

//________________________________________________________________________
void AliAnalysisTaskSpectraAllChAOD::UserCreateOutputObjects()
{
  // create output objects
  fOutput=new TList();
  fOutput->SetOwner();
  fOutput->SetName("fOutput");

  if (!fTrackCuts) AliFatal("Track Cuts should be set in the steering macro");
  if (!fEventCuts) AliFatal("Event Cuts should be set in the steering macro");
  if (!fHelperPID)  AliFatal("HelperPID should be set in the steering macro");

  // binning common to all the THn
  const Double_t ptBins[] = {0.20,0.30,0.4,0.5,0.6,0.7,0.8,0.9,1.0,1.2,1.4,1.6,1.8,2.0,2.4,2.8,3.2,3.6,4.0,5.0,6.0,7.0,8.0,9.0,10.,12.,15.};
  const Int_t nptBins=26;

  //dimensions of THnSparse for tracks
  const Int_t nvartrk=7;
  //                                             pt          cent          Q vec     IDrec      IDgen       isph         y
  Int_t    binsHistRealTrk[nvartrk] = {      nptBins, fnCentBins,     fnQvecBins,        4,        3,         2,        2};
  Double_t xminHistRealTrk[nvartrk] = {         0.,          0.,              0.,       -.5,      -0.5,      -0.5,    -0.5};
  Double_t xmaxHistRealTrk[nvartrk] = {       10.,       100., fQvecUpperLim,      3.5,      2.5,       1.5,     0.5};
  THnSparseF* NSparseHistTrk = new THnSparseF("NSparseHistTrk","NSparseHistTrk",nvartrk,binsHistRealTrk,xminHistRealTrk,xmaxHistRealTrk);
  NSparseHistTrk->GetAxis(0)->SetTitle("#it{p}_{T,rec}");
  NSparseHistTrk->GetAxis(0)->SetName("pT_rec");
  NSparseHistTrk->SetBinEdges(0,ptBins);
  NSparseHistTrk->GetAxis(1)->SetTitle(Form("%s cent",fEventCuts->GetCentralityMethod().Data()));
  NSparseHistTrk->GetAxis(1)->SetName(Form("%s_cent",fEventCuts->GetCentralityMethod().Data()));
  NSparseHistTrk->GetAxis(2)->SetTitle("Q vec");
  NSparseHistTrk->GetAxis(2)->SetName("Q_vec");
  NSparseHistTrk->GetAxis(3)->SetTitle("ID rec");
  NSparseHistTrk->GetAxis(3)->SetName("ID_rec");
  NSparseHistTrk->GetAxis(4)->SetTitle("ID gen");
  NSparseHistTrk->GetAxis(4)->SetName("ID_gen");
  NSparseHistTrk->GetAxis(5)->SetTitle("isph");
  NSparseHistTrk->GetAxis(5)->SetName("isph");
  NSparseHistTrk->GetAxis(6)->SetTitle("y");
  NSparseHistTrk->GetAxis(6)->SetName("y");
  fOutput->Add(NSparseHistTrk);

  //dimensions of THnSparse for stack
  const Int_t nvarst=6;
  //                                             pt          cent    IDgen        isph        y    etaselected
  Int_t    binsHistRealSt[nvarst] = {      nptBins,  fnCentBins,        3,         2,        2,             1};
  Double_t xminHistRealSt[nvarst] = {         0.,           0.,      -0.5,      -0.5,    -0.5,            0.5};
  Double_t xmaxHistRealSt[nvarst] = {       10.,        100.,      2.5,       1.5,      0.5,           1.5};
  THnSparseF* NSparseHistSt = new THnSparseF("NSparseHistSt","NSparseHistSt",nvarst,binsHistRealSt,xminHistRealSt,xmaxHistRealSt);
  NSparseHistSt->GetAxis(0)->SetTitle("#it{p}_{T,gen}");
  NSparseHistSt->SetBinEdges(0,ptBins);
  NSparseHistSt->GetAxis(0)->SetName("pT_rec");
  NSparseHistSt->GetAxis(1)->SetTitle(Form("%s cent",fEventCuts->GetCentralityMethod().Data()));
  NSparseHistSt->GetAxis(1)->SetName(Form("%s_cent",fEventCuts->GetCentralityMethod().Data()));
  NSparseHistSt->GetAxis(2)->SetTitle("ID gen");
  NSparseHistSt->GetAxis(2)->SetName("ID_gen");
  NSparseHistSt->GetAxis(3)->SetTitle("isph");
  NSparseHistSt->GetAxis(3)->SetName("isph");
  NSparseHistSt->GetAxis(4)->SetTitle("y");
  NSparseHistSt->GetAxis(4)->SetName("y");
  NSparseHistSt->GetAxis(5)->SetTitle("etaselected");
  NSparseHistSt->GetAxis(5)->SetName("etaselected");
  fOutput->Add(NSparseHistSt);

  //dimensions of THnSparse for the normalization
  const Int_t nvarev=3;
  //                                             cent             Q vec                Nch
  Int_t    binsHistRealEv[nvarev] = {    fnCentBins,      fnQvecBins,           fnNchBins};
  Double_t xminHistRealEv[nvarev] = {           0.,               0.,                   0.};
  Double_t xmaxHistRealEv[nvarev] = {       100.,  fQvecUpperLim,               2000.};
  THnSparseF* NSparseHistEv = new THnSparseF("NSparseHistEv","NSparseHistEv",nvarev,binsHistRealEv,xminHistRealEv,xmaxHistRealEv);
  NSparseHistEv->GetAxis(0)->SetTitle(Form("%s cent",fEventCuts->GetCentralityMethod().Data()));
  NSparseHistEv->GetAxis(0)->SetName(Form("%s_cent",fEventCuts->GetCentralityMethod().Data()));
  NSparseHistEv->GetAxis(1)->SetTitle("Q vec");
  NSparseHistEv->GetAxis(1)->SetName("Q_vec");
  NSparseHistEv->GetAxis(2)->SetTitle("N charged");
  NSparseHistEv->GetAxis(2)->SetName("N_ch");
  fOutput->Add(NSparseHistEv);

  PostData(1, fOutput  );
  PostData(2, fEventCuts);
  PostData(3, fTrackCuts);
  PostData(4, fHelperPID);
}

//________________________________________________________________________

void AliAnalysisTaskSpectraAllChAOD::UserExec(Option_t *)
{
  //Printf("An event");
  // main event loop
  fAOD = dynamic_cast<AliAODEvent*>(fInputEvent);
  if (!fAOD) {
    AliWarning("ERROR: AliAODEvent not available \n");
    return;
  }

  if (strcmp(fAOD->ClassName(), "AliAODEvent"))
    {
      AliFatal("Not processing AODs");
    }

  if(!fEventCuts->IsSelected(fAOD,fTrackCuts))return;//event selection

  //Default TPC priors
  if(fHelperPID->GetPIDType()==kBayes)fHelperPID->GetPIDCombined()->SetDefaultTPCPriors();//FIXME maybe this can go in the UserCreateOutputObject?

  Double_t Qvec=0.;//in case of MC we save space in the memory
  if(!fIsMC){
    if(fIsQvecCalibMode){
      if(fVZEROside==0)Qvec=fEventCuts->GetqV0A();
      else if (fVZEROside==1)Qvec=fEventCuts->GetqV0C();
    }
    else Qvec=fEventCuts->GetQvecPercentile(fVZEROside);
  }

  Double_t Cent=fEventCuts->GetCent();

  // First do MC to fill up the MC particle array
  TClonesArray *arrayMC = 0;
  if (fIsMC)
    {
      arrayMC = (TClonesArray*) fAOD->GetList()->FindObject(AliAODMCParticle::StdBranchName());
      if (!arrayMC) {
	AliFatal("Error: MC particles branch not found!\n");
      }
      Int_t nMC = arrayMC->GetEntries();
      for (Int_t iMC = 0; iMC < nMC; iMC++)
	{
	  AliAODMCParticle *partMC = (AliAODMCParticle*) arrayMC->At(iMC);
	  if(!partMC->Charge()) continue;//Skip neutrals
	  if(fCharge != 0 && partMC->Charge()*fCharge < 0.) continue;//if fCharge != 0 only select fCharge

	  //flag to select particle in the same ETA acceptance of the tracks (to be used for the comparison with AllCh)
	  Double_t etaselected=-1.;
	  if(partMC->Eta()>=fTrackCuts->GetEtaMin() && partMC->Eta()<=fTrackCuts->GetEtaMax())etaselected=1.;

	  //pt     cent    IDgen        isph        y
 	  Double_t varSt[6];
	  varSt[0]=partMC->Pt();
	  varSt[1]=Cent;
	  varSt[2]=(Double_t)fHelperPID->GetParticleSpecies(partMC);
	  varSt[3]=(Double_t)partMC->IsPhysicalPrimary();
	  varSt[4]=partMC->Y();
	  varSt[5]=etaselected;
	  ((THnSparseF*)fOutput->FindObject("NSparseHistSt"))->Fill(varSt);//stack loop

	  //Printf("a particle");

	}
    }

  //main loop on tracks

  Int_t Nch = 0.;

  for (Int_t iTracks = 0; iTracks < fAOD->GetNumberOfTracks(); iTracks++) {
    AliAODTrack* track = fAOD->GetTrack(iTracks);
    if(fCharge != 0 && track->Charge() != fCharge) continue;//if fCharge != 0 only select fCharge
    if (!fTrackCuts->IsSelected(track,kTRUE)) continue; //track selection (rapidity selection NOT in the standard cuts)
    if(!fFillOnlyEvents){
      Int_t IDrec=fHelperPID->GetParticleSpecies(track,kTRUE);//id from detector
      Double_t y= track->Y(fHelperPID->GetMass((AliHelperParticleSpecies_t)IDrec));
      Int_t IDgen=kSpUndefined;//set if MC
      Int_t isph=-999;
      //Int_t iswd=-999;

      if (arrayMC) {
	AliAODMCParticle *partMC = (AliAODMCParticle*) arrayMC->At(TMath::Abs(track->GetLabel()));
	if (!partMC) {
	  AliError("Cannot get MC particle");
	  continue;
	}
	IDgen=fHelperPID->GetParticleSpecies(partMC);
	isph=partMC->IsPhysicalPrimary();
	//iswd=partMC->IsSecondaryFromWeakDecay();//FIXME not working on old productions - removed Apr 8th 2014
      }

    //pt     cent    Q vec     IDrec     IDgen       isph      y
      Double_t varTrk[7];
      varTrk[0]=track->Pt();
      varTrk[1]=Cent;
      varTrk[2]=Qvec;
      varTrk[3]=(Double_t)IDrec;
      varTrk[4]=(Double_t)IDgen;
      varTrk[5]=(Double_t)isph;
      varTrk[6]=y;
      ((THnSparseF*)fOutput->FindObject("NSparseHistTrk"))->Fill(varTrk);//track loop

      //for nsigma PID fill double counting of ID
      if(fHelperPID->GetPIDType()<kBayes && fDoDoubleCounting){//only nsigma
	Bool_t *HasDC;
	HasDC=fHelperPID->GetDoubleCounting(track,kTRUE);//get the array with double counting
	for(Int_t ipart=0;ipart<kNSpecies;ipart++){
	  if(HasDC[ipart]==kTRUE){
	    varTrk[3]=(Double_t)ipart;
	    ((THnSparseF*)fOutput->FindObject("NSparseHistTrk"))->Fill(varTrk);//track loop
	  }
	}
      }

      //fill all charged (3)
      varTrk[3]=3.;
      varTrk[4]=3.;
      ((THnSparseF*)fOutput->FindObject("NSparseHistTrk"))->Fill(varTrk);//track loop
    }//end if fFillOnlyEvents

    //Printf("a track");

    Nch++;
  } // end loop on tracks

  Double_t varEv[3];
  varEv[0]=Cent;
  varEv[1]=Qvec;
  varEv[2]=Nch;
  ((THnSparseF*)fOutput->FindObject("NSparseHistEv"))->Fill(varEv);//event loop

  PostData(1, fOutput  );
  PostData(2, fEventCuts);
  PostData(3, fTrackCuts);
  PostData(4, fHelperPID);
}

//_________________________________________________________________
void   AliAnalysisTaskSpectraAllChAOD::Terminate(Option_t *)
{
  // Terminate
}
<|endoftext|>


<commit_before>//===- llvm/unittest/Support/ReverseIterationTest.cpp ---------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
//
// Reverse Iteration unit tests.
//
//===---------------------------------------------------------------------===//

#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/ReverseIteration.h"
#include "gtest/gtest.h"

using namespace llvm;

TEST(ReverseIterationTest, DenseMapTest1) {
  static_assert(detail::IsPointerLike<int *>::value,
                "int * is pointer-like");
  static_assert(detail::IsPointerLike<uintptr_t>::value,
                "uintptr_t is pointer-like");
  static_assert(!detail::IsPointerLike<int>::value,
                "int is not pointer-like");
  static_assert(detail::IsPointerLike<void *>::value,
                "void * is pointer-like");
  struct IncompleteType;
  static_assert(detail::IsPointerLike<IncompleteType *>::value,
                "incomplete * is pointer-like");

  // For a DenseMap with non-pointer-like keys, forward iteration equals
  // reverse iteration.
  DenseMap<int, int> Map;
  int Keys[] = { 1, 2, 3, 4 };

  // Insert keys into the DenseMap.
  for (auto Key: Keys)
    Map[Key] = 0;

  // Note: This is the observed order of keys in the DenseMap.
  // If there is any change in the behavior of the DenseMap, this order
  // would need to be adjusted accordingly.
  int IterKeys[] = { 2, 4, 1, 3 };

  // Check that the DenseMap is iterated in the expected order.
  for (const auto &Tuple : zip(Map, IterKeys))
    ASSERT_EQ(std::get<0>(Tuple).first, std::get<1>(Tuple));

  // Check operator++ (post-increment).
  int i = 0;
  for (auto iter = Map.begin(), end = Map.end(); iter != end; iter++, ++i)
    ASSERT_EQ(iter->first, IterKeys[i]);
}

// Define a pointer-like int.
struct PtrLikeInt { int value; };

template<> struct DenseMapInfo<PtrLikeInt *> {
  static PtrLikeInt *getEmptyKey() {
    static PtrLikeInt EmptyKey;
    return &EmptyKey;
  }

  static PtrLikeInt *getTombstoneKey() {
    static PtrLikeInt TombstoneKey;
    return &TombstoneKey;
  }

  static int getHashValue(const PtrLikeInt *P) {
    return P->value;
  }

  static bool isEqual(const PtrLikeInt *LHS, const PtrLikeInt *RHS) {
    return LHS == RHS;
  }
};

TEST(ReverseIterationTest, DenseMapTest2) {
  static_assert(detail::IsPointerLike<PtrLikeInt *>::value,
                "PtrLikeInt * is pointer-like");

  PtrLikeInt a = {4}, b = {8}, c = {12}, d = {16};
  PtrLikeInt *Keys[] = { &a, &b, &c, &d };

  // Insert keys into the DenseMap.
  DenseMap<PtrLikeInt *, int> Map;
  for (auto *Key : Keys)
    Map[Key] = Key->value;

  // Note: If there is any change in the behavior of the DenseMap,
  // the observed order of keys would need to be adjusted accordingly.
  if (shouldReverseIterate<PtrLikeInt *>())
    std::reverse(&Keys[0], &Keys[4]);

  // Check that the DenseMap is iterated in the expected order.
  for (const auto &Tuple : zip(Map, Keys))
    ASSERT_EQ(std::get<0>(Tuple).second, std::get<1>(Tuple)->value);

  // Check operator++ (post-increment).
  int i = 0;
  for (auto iter = Map.begin(), end = Map.end(); iter != end; iter++, ++i)
    ASSERT_EQ(iter->second, Keys[i]->value);
}
<commit_msg>[unittest/ReverseIteration] Unbreak when compiling with GCC.<commit_after>//===- llvm/unittest/Support/ReverseIterationTest.cpp ---------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
//
// Reverse Iteration unit tests.
//
//===---------------------------------------------------------------------===//

#include "llvm/Support/ReverseIteration.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseMapInfo.h"
#include "gtest/gtest.h"

using namespace llvm;

TEST(ReverseIterationTest, DenseMapTest1) {
  static_assert(detail::IsPointerLike<int *>::value,
                "int * is pointer-like");
  static_assert(detail::IsPointerLike<uintptr_t>::value,
                "uintptr_t is pointer-like");
  static_assert(!detail::IsPointerLike<int>::value,
                "int is not pointer-like");
  static_assert(detail::IsPointerLike<void *>::value,
                "void * is pointer-like");
  struct IncompleteType;
  static_assert(detail::IsPointerLike<IncompleteType *>::value,
                "incomplete * is pointer-like");

  // For a DenseMap with non-pointer-like keys, forward iteration equals
  // reverse iteration.
  DenseMap<int, int> Map;
  int Keys[] = { 1, 2, 3, 4 };

  // Insert keys into the DenseMap.
  for (auto Key: Keys)
    Map[Key] = 0;

  // Note: This is the observed order of keys in the DenseMap.
  // If there is any change in the behavior of the DenseMap, this order
  // would need to be adjusted accordingly.
  int IterKeys[] = { 2, 4, 1, 3 };

  // Check that the DenseMap is iterated in the expected order.
  for (const auto &Tuple : zip(Map, IterKeys))
    ASSERT_EQ(std::get<0>(Tuple).first, std::get<1>(Tuple));

  // Check operator++ (post-increment).
  int i = 0;
  for (auto iter = Map.begin(), end = Map.end(); iter != end; iter++, ++i)
    ASSERT_EQ(iter->first, IterKeys[i]);
}

// Define a pointer-like int.
struct PtrLikeInt { int value; };

namespace llvm {

template<> struct DenseMapInfo<PtrLikeInt *> {
  static PtrLikeInt *getEmptyKey() {
    static PtrLikeInt EmptyKey;
    return &EmptyKey;
  }

  static PtrLikeInt *getTombstoneKey() {
    static PtrLikeInt TombstoneKey;
    return &TombstoneKey;
  }

  static int getHashValue(const PtrLikeInt *P) {
    return P->value;
  }

  static bool isEqual(const PtrLikeInt *LHS, const PtrLikeInt *RHS) {
    return LHS == RHS;
  }
};

} // end namespace llvm

TEST(ReverseIterationTest, DenseMapTest2) {
  static_assert(detail::IsPointerLike<PtrLikeInt *>::value,
                "PtrLikeInt * is pointer-like");

  PtrLikeInt a = {4}, b = {8}, c = {12}, d = {16};
  PtrLikeInt *Keys[] = { &a, &b, &c, &d };

  // Insert keys into the DenseMap.
  DenseMap<PtrLikeInt *, int> Map;
  for (auto *Key : Keys)
    Map[Key] = Key->value;

  // Note: If there is any change in the behavior of the DenseMap,
  // the observed order of keys would need to be adjusted accordingly.
  if (shouldReverseIterate<PtrLikeInt *>())
    std::reverse(&Keys[0], &Keys[4]);

  // Check that the DenseMap is iterated in the expected order.
  for (const auto &Tuple : zip(Map, Keys))
    ASSERT_EQ(std::get<0>(Tuple).second, std::get<1>(Tuple)->value);

  // Check operator++ (post-increment).
  int i = 0;
  for (auto iter = Map.begin(), end = Map.end(); iter != end; iter++, ++i)
    ASSERT_EQ(iter->second, Keys[i]->value);
}
<|endoftext|>


<commit_before>/*
 * Software License Agreement (BSD License)
 *
 *  Point Cloud Library (PCL) - www.pointclouds.org
 *  Copyright (c) 2010-2012, Willow Garage, Inc.
 *  Copyright (c) 2012-, Open Perception, Inc.
 *
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of the copyright holder(s) nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef PCL_FILTERS_IMPL_MODEL_OUTLIER_REMOVAL_HPP_
#define PCL_FILTERS_IMPL_MODEL_OUTLIER_REMOVAL_HPP_

#include <pcl/filters/model_outlier_removal.h>
#include <pcl/common/io.h>
#include <pcl/sample_consensus/sac_model_circle.h>
#include <pcl/sample_consensus/sac_model_cylinder.h>
#include <pcl/sample_consensus/sac_model_cone.h>
#include <pcl/sample_consensus/sac_model_line.h>
#include <pcl/sample_consensus/sac_model_normal_plane.h>
#include <pcl/sample_consensus/sac_model_normal_sphere.h>
#include <pcl/sample_consensus/sac_model_parallel_plane.h>
#include <pcl/sample_consensus/sac_model_normal_parallel_plane.h>
#include <pcl/sample_consensus/sac_model_parallel_line.h>
#include <pcl/sample_consensus/sac_model_perpendicular_plane.h>
#include <pcl/sample_consensus/sac_model_plane.h>
#include <pcl/sample_consensus/sac_model_sphere.h>

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> bool
pcl::ModelOutlierRemoval<PointT>::initSACModel (pcl::SacModel model_type)
{
  // Build the model
  switch (model_type)
  {
    case SACMODEL_PLANE:
    {
      PCL_DEBUG ("[pcl::%s::initSACModel] Using a model of type: modelPLANE\n", getClassName ().c_str ());
      model_.reset (new SampleConsensusModelPlane<PointT> (input_));
      break;
    }
    case SACMODEL_LINE:
    {
      PCL_DEBUG ("[pcl::%s::initSACModel] Using a model of type: modelLINE\n", getClassName ().c_str ());
      model_.reset (new SampleConsensusModelLine<PointT> (input_));
      break;
    }
    case SACMODEL_CIRCLE2D:
    {
      PCL_DEBUG ("[pcl::%s::initSACModel] Using a model of type: modelCIRCLE2D\n", getClassName ().c_str ());
      model_.reset (new SampleConsensusModelCircle2D<PointT> (input_));
      break;
    }
    case SACMODEL_SPHERE:
    {
      PCL_DEBUG ("[pcl::%s::initSACModel] Using a model of type: modelSPHERE\n", getClassName ().c_str ());
      model_.reset (new SampleConsensusModelSphere<PointT> (input_));
      break;
    }
    case SACMODEL_PARALLEL_LINE:
    {
      PCL_DEBUG ("[pcl::%s::initSACModel] Using a model of type: modelPARALLEL_LINE\n", getClassName ().c_str ());
      model_.reset (new SampleConsensusModelParallelLine<PointT> (input_));
      break;
    }
    case SACMODEL_PERPENDICULAR_PLANE:
    {
      PCL_DEBUG ("[pcl::%s::initSACModel] Using a model of type: modelPERPENDICULAR_PLANE\n", getClassName ().c_str ());
      model_.reset (new SampleConsensusModelPerpendicularPlane<PointT> (input_));
      break;
    }
    case SACMODEL_CYLINDER:
    {
      PCL_DEBUG ("[pcl::%s::segment] Using a model of type: modelCYLINDER\n", getClassName ().c_str ());
      model_.reset (new SampleConsensusModelCylinder<PointT, pcl::Normal> (input_));
      break;
    }
    case SACMODEL_NORMAL_PLANE:
    {
      PCL_DEBUG ("[pcl::%s::segment] Using a model of type: modelNORMAL_PLANE\n", getClassName ().c_str ());
      model_.reset (new SampleConsensusModelNormalPlane<PointT, pcl::Normal> (input_));
      break;
    }
    case SACMODEL_CONE:
    {
      PCL_DEBUG ("[pcl::%s::segment] Using a model of type: modelCONE\n", getClassName ().c_str ());
      model_.reset (new SampleConsensusModelCone<PointT, pcl::Normal> (input_));
      break;
    }
    case SACMODEL_NORMAL_SPHERE:
    {
      PCL_DEBUG ("[pcl::%s::segment] Using a model of type: modelNORMAL_SPHERE\n", getClassName ().c_str ());
      model_.reset (new SampleConsensusModelNormalSphere<PointT, pcl::Normal> (input_));
      break;
    }
    case SACMODEL_NORMAL_PARALLEL_PLANE:
    {
      PCL_DEBUG ("[pcl::%s::segment] Using a model of type: modelNORMAL_PARALLEL_PLANE\n", getClassName ().c_str ());
      model_.reset (new SampleConsensusModelNormalParallelPlane<PointT, pcl::Normal> (input_));
      break;
    }
    case SACMODEL_PARALLEL_PLANE:
    {
      PCL_DEBUG ("[pcl::%s::segment] Using a model of type: modelPARALLEL_PLANE\n", getClassName ().c_str ());
      model_.reset (new SampleConsensusModelParallelPlane<PointT> (input_));
      break;
    }
    default:
    {
      PCL_ERROR ("[pcl::%s::initSACModel] No valid model given!\n", getClassName ().c_str ());
      return (false);
    }
  }
  return (true);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> void
pcl::ModelOutlierRemoval<PointT>::applyFilter (PointCloud &output)
{
  std::vector<int> indices;
  if (keep_organized_)
  {
    bool temp = extract_removed_indices_;
    extract_removed_indices_ = true;
    applyFilterIndices (indices);
    extract_removed_indices_ = temp;

    output = *input_;
    for (int rii = 0; rii < static_cast<int> (removed_indices_->size ()); ++rii)  // rii = removed indices iterator
      output.points[ (*removed_indices_)[rii]].x = output.points[ (*removed_indices_)[rii]].y = output.points[ (*removed_indices_)[rii]].z = user_filter_value_;
    if (!pcl_isfinite (user_filter_value_))
      output.is_dense = false;
  }
  else
  {
    applyFilterIndices (indices);
    copyPointCloud (*input_, indices, output);
  }
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> void
pcl::ModelOutlierRemoval<PointT>::applyFilterIndices (std::vector<int> &indices)
{
  //The arrays to be used
  indices.resize (indices_->size ());
  removed_indices_->resize (indices_->size ());
  int oii = 0, rii = 0;  // oii = output indices iterator, rii = removed indices iterator
  //is the filtersetup correct?
  bool valid_setup = true;

  valid_setup &= initSACModel (model_type_);

  typedef SampleConsensusModelFromNormals<PointT, pcl::Normal> SACModelFromNormals;
  // Returns NULL if cast isn't possible
  SACModelFromNormals *model_from_normals = dynamic_cast<SACModelFromNormals *> (& (*model_));

  if (model_from_normals)
  {
    if (!cloud_normals_)
    {
      valid_setup = false;
      PCL_ERROR ("[pcl::ModelOutlierRemoval::applyFilterIndices]: no normals cloud set.\n");
    }
    else
    {
      model_from_normals->setNormalDistanceWeight (normals_distance_weight_);
      model_from_normals->setInputNormals (cloud_normals_);
    }
  }

  //if the filter setup is invalid filter for nan and return;
  if (!valid_setup)
  {
    for (int iii = 0; iii < static_cast<int> (indices_->size ()); ++iii)  // iii = input indices iterator
    {
      // Non-finite entries are always passed to removed indices
      if (!pcl_isfinite (input_->points[ (*indices_)[iii]].x) || !pcl_isfinite (input_->points[ (*indices_)[iii]].y)
          || !pcl_isfinite (input_->points[ (*indices_)[iii]].z))
      {
        if (extract_removed_indices_)
          (*removed_indices_)[rii++] = (*indices_)[iii];
        continue;
      }
      indices[oii++] = (*indices_)[iii];
    }
    return;
  }
  // check distance of pointcloud to model
  std::vector<double> distances;
  //TODO: get signed distances !
  model_->getDistancesToModel (model_coefficients_, distances);
  bool thresh_result;

  // Filter for non-finite entries and the specified field limits
  for (int iii = 0; iii < static_cast<int> (indices_->size ()); ++iii)  // iii = input indices iterator
  {
    // Non-finite entries are always passed to removed indices
    if (!pcl_isfinite (input_->points[ (*indices_)[iii]].x) || !pcl_isfinite (input_->points[ (*indices_)[iii]].y)
        || !pcl_isfinite (input_->points[ (*indices_)[iii]].z))
    {
      if (extract_removed_indices_)
        (*removed_indices_)[rii++] = (*indices_)[iii];
      continue;
    }

    // use threshold function to seperate outliers from inliers:
    thresh_result = threshold_function_ (distances[iii]);

    // in normal mode: define outliers as false thresh_result
    if (!negative_ && !thresh_result)
    {
      if (extract_removed_indices_)
        (*removed_indices_)[rii++] = (*indices_)[iii];
      continue;
    }

    // in negative_ mode: define outliers as true thresh_result
    if (negative_ && thresh_result)
    {
      if (extract_removed_indices_)
        (*removed_indices_)[rii++] = (*indices_)[iii];
      continue;
    }

    // Otherwise it was a normal point for output (inlier)
    indices[oii++] = (*indices_)[iii];

  }

  // Resize the output arrays
  indices.resize (oii);
  removed_indices_->resize (rii);

}

#define PCL_INSTANTIATE_ModelOutlierRemoval(T) template class PCL_EXPORTS pcl::ModelOutlierRemoval<T>;

#endif  // PCL_FILTERS_IMPL_MODEL_OUTLIER_REMOVAL_HPP_
<commit_msg>Use pcl::isFinite instead of pcl_isfinite<commit_after>/*
 * Software License Agreement (BSD License)
 *
 *  Point Cloud Library (PCL) - www.pointclouds.org
 *  Copyright (c) 2010-2012, Willow Garage, Inc.
 *  Copyright (c) 2012-, Open Perception, Inc.
 *
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of the copyright holder(s) nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef PCL_FILTERS_IMPL_MODEL_OUTLIER_REMOVAL_HPP_
#define PCL_FILTERS_IMPL_MODEL_OUTLIER_REMOVAL_HPP_

#include <pcl/filters/model_outlier_removal.h>
#include <pcl/common/io.h>
#include <pcl/sample_consensus/sac_model_circle.h>
#include <pcl/sample_consensus/sac_model_cylinder.h>
#include <pcl/sample_consensus/sac_model_cone.h>
#include <pcl/sample_consensus/sac_model_line.h>
#include <pcl/sample_consensus/sac_model_normal_plane.h>
#include <pcl/sample_consensus/sac_model_normal_sphere.h>
#include <pcl/sample_consensus/sac_model_parallel_plane.h>
#include <pcl/sample_consensus/sac_model_normal_parallel_plane.h>
#include <pcl/sample_consensus/sac_model_parallel_line.h>
#include <pcl/sample_consensus/sac_model_perpendicular_plane.h>
#include <pcl/sample_consensus/sac_model_plane.h>
#include <pcl/sample_consensus/sac_model_sphere.h>

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> bool
pcl::ModelOutlierRemoval<PointT>::initSACModel (pcl::SacModel model_type)
{
  // Build the model
  switch (model_type)
  {
    case SACMODEL_PLANE:
    {
      PCL_DEBUG ("[pcl::%s::initSACModel] Using a model of type: modelPLANE\n", getClassName ().c_str ());
      model_.reset (new SampleConsensusModelPlane<PointT> (input_));
      break;
    }
    case SACMODEL_LINE:
    {
      PCL_DEBUG ("[pcl::%s::initSACModel] Using a model of type: modelLINE\n", getClassName ().c_str ());
      model_.reset (new SampleConsensusModelLine<PointT> (input_));
      break;
    }
    case SACMODEL_CIRCLE2D:
    {
      PCL_DEBUG ("[pcl::%s::initSACModel] Using a model of type: modelCIRCLE2D\n", getClassName ().c_str ());
      model_.reset (new SampleConsensusModelCircle2D<PointT> (input_));
      break;
    }
    case SACMODEL_SPHERE:
    {
      PCL_DEBUG ("[pcl::%s::initSACModel] Using a model of type: modelSPHERE\n", getClassName ().c_str ());
      model_.reset (new SampleConsensusModelSphere<PointT> (input_));
      break;
    }
    case SACMODEL_PARALLEL_LINE:
    {
      PCL_DEBUG ("[pcl::%s::initSACModel] Using a model of type: modelPARALLEL_LINE\n", getClassName ().c_str ());
      model_.reset (new SampleConsensusModelParallelLine<PointT> (input_));
      break;
    }
    case SACMODEL_PERPENDICULAR_PLANE:
    {
      PCL_DEBUG ("[pcl::%s::initSACModel] Using a model of type: modelPERPENDICULAR_PLANE\n", getClassName ().c_str ());
      model_.reset (new SampleConsensusModelPerpendicularPlane<PointT> (input_));
      break;
    }
    case SACMODEL_CYLINDER:
    {
      PCL_DEBUG ("[pcl::%s::segment] Using a model of type: modelCYLINDER\n", getClassName ().c_str ());
      model_.reset (new SampleConsensusModelCylinder<PointT, pcl::Normal> (input_));
      break;
    }
    case SACMODEL_NORMAL_PLANE:
    {
      PCL_DEBUG ("[pcl::%s::segment] Using a model of type: modelNORMAL_PLANE\n", getClassName ().c_str ());
      model_.reset (new SampleConsensusModelNormalPlane<PointT, pcl::Normal> (input_));
      break;
    }
    case SACMODEL_CONE:
    {
      PCL_DEBUG ("[pcl::%s::segment] Using a model of type: modelCONE\n", getClassName ().c_str ());
      model_.reset (new SampleConsensusModelCone<PointT, pcl::Normal> (input_));
      break;
    }
    case SACMODEL_NORMAL_SPHERE:
    {
      PCL_DEBUG ("[pcl::%s::segment] Using a model of type: modelNORMAL_SPHERE\n", getClassName ().c_str ());
      model_.reset (new SampleConsensusModelNormalSphere<PointT, pcl::Normal> (input_));
      break;
    }
    case SACMODEL_NORMAL_PARALLEL_PLANE:
    {
      PCL_DEBUG ("[pcl::%s::segment] Using a model of type: modelNORMAL_PARALLEL_PLANE\n", getClassName ().c_str ());
      model_.reset (new SampleConsensusModelNormalParallelPlane<PointT, pcl::Normal> (input_));
      break;
    }
    case SACMODEL_PARALLEL_PLANE:
    {
      PCL_DEBUG ("[pcl::%s::segment] Using a model of type: modelPARALLEL_PLANE\n", getClassName ().c_str ());
      model_.reset (new SampleConsensusModelParallelPlane<PointT> (input_));
      break;
    }
    default:
    {
      PCL_ERROR ("[pcl::%s::initSACModel] No valid model given!\n", getClassName ().c_str ());
      return (false);
    }
  }
  return (true);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> void
pcl::ModelOutlierRemoval<PointT>::applyFilter (PointCloud &output)
{
  std::vector<int> indices;
  if (keep_organized_)
  {
    bool temp = extract_removed_indices_;
    extract_removed_indices_ = true;
    applyFilterIndices (indices);
    extract_removed_indices_ = temp;

    output = *input_;
    for (int rii = 0; rii < static_cast<int> (removed_indices_->size ()); ++rii)  // rii = removed indices iterator
      output.points[ (*removed_indices_)[rii]].x = output.points[ (*removed_indices_)[rii]].y = output.points[ (*removed_indices_)[rii]].z = user_filter_value_;
    if (!pcl_isfinite (user_filter_value_))
      output.is_dense = false;
  }
  else
  {
    applyFilterIndices (indices);
    copyPointCloud (*input_, indices, output);
  }
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointT> void
pcl::ModelOutlierRemoval<PointT>::applyFilterIndices (std::vector<int> &indices)
{
  //The arrays to be used
  indices.resize (indices_->size ());
  removed_indices_->resize (indices_->size ());
  int oii = 0, rii = 0;  // oii = output indices iterator, rii = removed indices iterator
  //is the filtersetup correct?
  bool valid_setup = true;

  valid_setup &= initSACModel (model_type_);

  typedef SampleConsensusModelFromNormals<PointT, pcl::Normal> SACModelFromNormals;
  // Returns NULL if cast isn't possible
  SACModelFromNormals *model_from_normals = dynamic_cast<SACModelFromNormals *> (& (*model_));

  if (model_from_normals)
  {
    if (!cloud_normals_)
    {
      valid_setup = false;
      PCL_ERROR ("[pcl::ModelOutlierRemoval::applyFilterIndices]: no normals cloud set.\n");
    }
    else
    {
      model_from_normals->setNormalDistanceWeight (normals_distance_weight_);
      model_from_normals->setInputNormals (cloud_normals_);
    }
  }

  //if the filter setup is invalid filter for nan and return;
  if (!valid_setup)
  {
    for (int iii = 0; iii < static_cast<int> (indices_->size ()); ++iii)  // iii = input indices iterator
    {
      // Non-finite entries are always passed to removed indices
      if (!isFinite (input_->points[ (*indices_)[iii]]))
      {
        if (extract_removed_indices_)
          (*removed_indices_)[rii++] = (*indices_)[iii];
        continue;
      }
      indices[oii++] = (*indices_)[iii];
    }
    return;
  }
  // check distance of pointcloud to model
  std::vector<double> distances;
  //TODO: get signed distances !
  model_->getDistancesToModel (model_coefficients_, distances);
  bool thresh_result;

  // Filter for non-finite entries and the specified field limits
  for (int iii = 0; iii < static_cast<int> (indices_->size ()); ++iii)  // iii = input indices iterator
  {
    // Non-finite entries are always passed to removed indices
    if (!isFinite (input_->points[ (*indices_)[iii]]))
    {
      if (extract_removed_indices_)
        (*removed_indices_)[rii++] = (*indices_)[iii];
      continue;
    }

    // use threshold function to seperate outliers from inliers:
    thresh_result = threshold_function_ (distances[iii]);

    // in normal mode: define outliers as false thresh_result
    if (!negative_ && !thresh_result)
    {
      if (extract_removed_indices_)
        (*removed_indices_)[rii++] = (*indices_)[iii];
      continue;
    }

    // in negative_ mode: define outliers as true thresh_result
    if (negative_ && thresh_result)
    {
      if (extract_removed_indices_)
        (*removed_indices_)[rii++] = (*indices_)[iii];
      continue;
    }

    // Otherwise it was a normal point for output (inlier)
    indices[oii++] = (*indices_)[iii];

  }

  // Resize the output arrays
  indices.resize (oii);
  removed_indices_->resize (rii);

}

#define PCL_INSTANTIATE_ModelOutlierRemoval(T) template class PCL_EXPORTS pcl::ModelOutlierRemoval<T>;

#endif  // PCL_FILTERS_IMPL_MODEL_OUTLIER_REMOVAL_HPP_
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_mc.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file p9_mss_draminit_mc.C
/// @brief Initialize the memory controller to take over the DRAM
///
// *HWP HWP Owner: Jacob Harvey <jlharvey@us.ibm.com>
// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 3
// *HWP Consumed by: FSP:HB

#include <fapi2.H>
#include <mss.H>

#include <p9_mc_scom_addresses_fld.H>
#include <p9_mss_draminit_mc.H>
#include <lib/fir/unmask.H>
#include <generic/memory/lib/utils/find.H>
#include <lib/utils/count_dimm.H>

using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_MCA;
using fapi2::TARGET_TYPE_MCS;

extern "C"
{
///
/// @brief Initialize the MC now that DRAM is up
/// @param[in] i_target, the McBIST of the ports
/// @return FAPI2_RC_SUCCESS iff ok
///
    fapi2::ReturnCode p9_mss_draminit_mc( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target )
    {
        FAPI_INF("Start draminit MC");

        // No need to check to see if we have ports - this loop will just be skipped
        for (const auto& p : mss::find_targets<fapi2::TARGET_TYPE_MCA>(i_target))
        {
            //skip this MCA if we have no DIMM's configured
            if(mss::count_dimm(p) == 0)
            {
                FAPI_INF("No DIMM's configured on %s. Skipping this MCA.", mss::c_str(p));
                continue;
            }

            // Setup the MC port/dimm address translation registers
            FAPI_TRY( mss::mc::setup_xlate_map(p), "%s Failed setup_xlate_map", mss::c_str(i_target) );

            // Setup the read_pointer_delay
            // TK: Do we need to do this in general or is this a place holder until the
            // init file gets here?
            {
                fapi2::buffer<uint64_t> l_data;
                FAPI_TRY( mss::getScom(p, MCA_RECR, l_data) );
                l_data.insertFromRight<MCA_RECR_MBSECCQ_READ_POINTER_DELAY, MCA_RECR_MBSECCQ_READ_POINTER_DELAY_LEN>(0x1);
                FAPI_DBG("writing read pointer delay 0x%016lx %s", l_data, mss::c_str(p));
                FAPI_TRY( mss::putScom(p, MCA_RECR, l_data) );
            }

            //Enable Power management based off of mrw_power_control_requested
            //Needs to be set near end of IPL
            FAPI_INF("Enable Power min max domains");
            {
                fapi2::buffer<uint64_t> l_data;
                uint8_t  l_pwr_cntrl = 0;
                FAPI_TRY(mss::getScom(p, MCA_MBARPC0Q, l_data));
                FAPI_TRY(mss::mrw_power_control_requested(l_pwr_cntrl));

                const bool is_pwr_cntrl = ((l_pwr_cntrl == fapi2::ENUM_ATTR_MSS_MRW_POWER_CONTROL_REQUESTED_POWER_DOWN)
                                           || (l_pwr_cntrl == fapi2::ENUM_ATTR_MSS_MRW_IDLE_POWER_CONTROL_REQUESTED_PD_AND_STR)
                                           || (l_pwr_cntrl == fapi2::ENUM_ATTR_MSS_MRW_IDLE_POWER_CONTROL_REQUESTED_PD_AND_STR_CLK_STOP));

                l_data.writeBit<MCA_MBARPC0Q_CFG_MIN_MAX_DOMAINS_ENABLE>(is_pwr_cntrl);

                FAPI_TRY( mss::putScom(p, MCA_MBARPC0Q, l_data) );

            }

            // Set the IML Complete bit MBSSQ(3) (SCOM Addr: 0x02011417) to indicate that IML has completed
            // Can't find MBSSQ or the iml_complete bit - asked Steve. Gary VH created this bit as a scratch
            // 'you are hre bit' and it was removed for Nimbus. Gary VH asked for it to be put back in. Not
            // sure if that happened yet. BRS (2/16).

            // Reset addr_mux_sel to “0” to allow the MCA to take control of the DDR interface over from CCS.
            // (Note: this step must remain in this procedure to ensure that data path is placed into mainline
            // mode prior to running memory diagnostics. This step may be superfluous but not harmful.)
            // Note: addr_mux_sel is set low in p9_mss_draminit(), however that might be a work-around so we
            // set it low here kind of like belt-and-suspenders. BRS
            FAPI_TRY( mss::change_addr_mux_sel(p, mss::LOW),
                      "%s Failed to change_addr_mux_sel", mss::c_str(i_target) );

            // Re-enable port fails. Turned off in draminit_training
            FAPI_TRY( mss::change_port_fail_disable(p, mss::OFF ),
                      "%s Failed to change_port_fail_disable", mss::c_str(i_target) );

            // MC work around for OE bug (seen in periodics + PHY)
#ifndef REMOVE_FOR_DD2
            // Turn on output-enable always on. Shelton tells me they'll fix for DD2
            FAPI_TRY( mss::change_oe_always_on(p, mss::ON ), "%s Failed to change_oe_always_on", mss::c_str(i_target) );
#endif
            // Step Two.1: Check RCD protect time on RDIMM and LRDIMM
            // Step Two.2: Enable address inversion on each MBA for ALL CARDS

            // Start the refresh engines by setting MBAREF0Q(0) = “1”. Note that the remaining bits in
            // MBAREF0Q should retain their initialization values.
            FAPI_TRY( mss::change_refresh_enable(p, mss::HIGH), "%s Failed change_refresh_enable", mss::c_str(i_target) );

            // Power management is handled in the init file. (or should be BRS)

            // Enabling periodic calibration
            FAPI_TRY( mss::enable_periodic_cal(p), "%s Failed enable_periodic_cal", mss::c_str(i_target) );

            // Step Six: Setup Control Bit ECC
            FAPI_TRY( mss::enable_read_ecc(p), "%s Failed enable_read_ecc", mss::c_str(i_target) );

            // apply marks from MVPD
            FAPI_TRY( mss::apply_mark_store(p), "%s Failed enable_read_ecc", mss::c_str(i_target) );
        }

        // At this point the DDR interface must be monitored for memory errors. Memory related FIRs should be unmasked.
        FAPI_TRY( mss::unmask::after_draminit_mc(i_target), "%s Failed after_draminit_mc", mss::c_str(i_target) );

    fapi_try_exit:
        FAPI_INF("End draminit MC");
        return fapi2::current_err;
    }
}
<commit_msg>Disabled TCE corrections for MNFG Threshold<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_mc.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file p9_mss_draminit_mc.C
/// @brief Initialize the memory controller to take over the DRAM
///
// *HWP HWP Owner: Jacob Harvey <jlharvey@us.ibm.com>
// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 3
// *HWP Consumed by: FSP:HB

#include <fapi2.H>
#include <mss.H>

#include <p9_mc_scom_addresses_fld.H>
#include <p9_mss_draminit_mc.H>
#include <lib/fir/unmask.H>
#include <generic/memory/lib/utils/find.H>
#include <lib/utils/count_dimm.H>

using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_MCA;
using fapi2::TARGET_TYPE_MCS;

extern "C"
{
///
/// @brief Initialize the MC now that DRAM is up
/// @param[in] i_target, the McBIST of the ports
/// @return FAPI2_RC_SUCCESS iff ok
///
    fapi2::ReturnCode p9_mss_draminit_mc( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target )
    {
        FAPI_INF("Start draminit MC");

        // No need to check to see if we have ports - this loop will just be skipped
        for (const auto& p : mss::find_targets<fapi2::TARGET_TYPE_MCA>(i_target))
        {
            //skip this MCA if we have no DIMM's configured
            if(mss::count_dimm(p) == 0)
            {
                FAPI_INF("No DIMM's configured on %s. Skipping this MCA.", mss::c_str(p));
                continue;
            }

            // Setup the MC port/dimm address translation registers
            FAPI_TRY( mss::mc::setup_xlate_map(p), "%s Failed setup_xlate_map", mss::c_str(i_target) );

            // Setup the read_pointer_delay
            // TK: Do we need to do this in general or is this a place holder until the
            // init file gets here?
            FAPI_TRY( mss::setup_read_pointer_delay(p), "Failed to setup read pointer delay for %s", mss::c_str(p));

            //Enable Power management based off of mrw_power_control_requested
            //Needs to be set near end of IPL
            FAPI_INF("Enable Power min max domains");
            {
                fapi2::buffer<uint64_t> l_data;
                uint8_t  l_pwr_cntrl = 0;
                FAPI_TRY(mss::getScom(p, MCA_MBARPC0Q, l_data));
                FAPI_TRY(mss::mrw_power_control_requested(l_pwr_cntrl));

                const bool is_pwr_cntrl = ((l_pwr_cntrl == fapi2::ENUM_ATTR_MSS_MRW_POWER_CONTROL_REQUESTED_POWER_DOWN)
                                           || (l_pwr_cntrl == fapi2::ENUM_ATTR_MSS_MRW_IDLE_POWER_CONTROL_REQUESTED_PD_AND_STR)
                                           || (l_pwr_cntrl == fapi2::ENUM_ATTR_MSS_MRW_IDLE_POWER_CONTROL_REQUESTED_PD_AND_STR_CLK_STOP));

                l_data.writeBit<MCA_MBARPC0Q_CFG_MIN_MAX_DOMAINS_ENABLE>(is_pwr_cntrl);

                FAPI_TRY( mss::putScom(p, MCA_MBARPC0Q, l_data) );

            }

            // Set the IML Complete bit MBSSQ(3) (SCOM Addr: 0x02011417) to indicate that IML has completed
            // Can't find MBSSQ or the iml_complete bit - asked Steve. Gary VH created this bit as a scratch
            // 'you are hre bit' and it was removed for Nimbus. Gary VH asked for it to be put back in. Not
            // sure if that happened yet. BRS (2/16).

            // Reset addr_mux_sel to “0” to allow the MCA to take control of the DDR interface over from CCS.
            // (Note: this step must remain in this procedure to ensure that data path is placed into mainline
            // mode prior to running memory diagnostics. This step may be superfluous but not harmful.)
            // Note: addr_mux_sel is set low in p9_mss_draminit(), however that might be a work-around so we
            // set it low here kind of like belt-and-suspenders. BRS
            FAPI_TRY( mss::change_addr_mux_sel(p, mss::LOW),
                      "%s Failed to change_addr_mux_sel", mss::c_str(i_target) );

            // Re-enable port fails. Turned off in draminit_training
            FAPI_TRY( mss::change_port_fail_disable(p, mss::OFF ),
                      "%s Failed to change_port_fail_disable", mss::c_str(i_target) );

            // MC work around for OE bug (seen in periodics + PHY)
#ifndef REMOVE_FOR_DD2
            // Turn on output-enable always on. Shelton tells me they'll fix for DD2
            FAPI_TRY( mss::change_oe_always_on(p, mss::ON ), "%s Failed to change_oe_always_on", mss::c_str(i_target) );
#endif
            // Step Two.1: Check RCD protect time on RDIMM and LRDIMM
            // Step Two.2: Enable address inversion on each MBA for ALL CARDS

            // Start the refresh engines by setting MBAREF0Q(0) = “1”. Note that the remaining bits in
            // MBAREF0Q should retain their initialization values.
            FAPI_TRY( mss::change_refresh_enable(p, mss::HIGH), "%s Failed change_refresh_enable", mss::c_str(i_target) );

            // Power management is handled in the init file. (or should be BRS)

            // Enabling periodic calibration
            FAPI_TRY( mss::enable_periodic_cal(p), "%s Failed enable_periodic_cal", mss::c_str(i_target) );

            // Step Six: Setup Control Bit ECC
            FAPI_TRY( mss::enable_read_ecc(p), "%s Failed enable_read_ecc", mss::c_str(i_target) );

            // apply marks from MVPD
            FAPI_TRY( mss::apply_mark_store(p), "%s Failed enable_read_ecc", mss::c_str(i_target) );
        }

        // At this point the DDR interface must be monitored for memory errors. Memory related FIRs should be unmasked.
        FAPI_TRY( mss::unmask::after_draminit_mc(i_target), "%s Failed after_draminit_mc", mss::c_str(i_target) );

    fapi_try_exit:
        FAPI_INF("End draminit MC");
        return fapi2::current_err;
    }
}
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: chips/p9/procedures/hwp/pm/p9_pm_ocb_indir_access.C $         */
/*                                                                        */
/* IBM CONFIDENTIAL                                                       */
/*                                                                        */
/* EKB Project                                                            */
/*                                                                        */
/* COPYRIGHT 2015,2016                                                    */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* The source code for this program is not published or otherwise         */
/* divested of its trade secrets, irrespective of what has been           */
/* deposited with the U.S. Copyright Office.                              */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
/// @file p9_pm_ocb_indir_access.C
/// @brief Performs the data transfer to/from an OCB indirect channel

// *HWP HWP Owner       : Amit Kumar <akumar3@us.ibm.com>
// *HWP HWP Backup Owner: Greg Still <stillgs@us.ibm.com>
// *HWP FW Owner        : Sangeetha T S <sangeet2@in.ibm.com>
// *HWP Team            : PM
// *HWP Level           : 2
// *HWP Consumed by     : FSP:HS

///
/// High-level procedure flow:
/// @verbatim
///     1) Check if the channel for access is valid.
///     2) For the PUT operation, the data from the buffer will be written
///        into the OCB Data register in blocks of 64bits;
///        from where eventually the data will be written to SRAM.
///     3) For GET operation, the data read from the SRAM will be retrieved from
///        the DATA register and written into the buffer in blocks of 64bits.
/// @endverbatim
///

// ----------------------------------------------------------------------
// Includes
// ----------------------------------------------------------------------
#include <p9_pm_ocb_indir_access.H>

// ----------------------------------------------------------------------
// Constant definitions
// ----------------------------------------------------------------------

enum
{
    OCB_FULL_POLL_MAX = 4,
    OCB_FULL_POLL_DELAY_HDW = 0,
    OCB_FULL_POLL_DELAY_SIM = 0
};

fapi2::ReturnCode p9_pm_ocb_indir_access(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
    const p9ocb::PM_OCB_CHAN_NUM  i_ocb_chan,
    const p9ocb::PM_OCB_ACCESS_OP i_ocb_op,
    const uint32_t                i_ocb_req_length,
    const bool                    i_oci_address_valid,
    const uint32_t                i_oci_address,
    uint32_t&                     o_ocb_act_length,
    uint64_t*                     io_ocb_buffer)
{
    FAPI_IMP("Enter p9_pm_ocb_indir_access...");
    FAPI_DBG("Channel : %d, Operation : %d, No.of 8B Blocks of Data: %d",
             i_ocb_chan, i_ocb_op, i_ocb_req_length);

    uint64_t l_OCBAR_address   = 0;
    uint64_t l_OCBDR_address   = 0;
    uint64_t l_OCBCSR_address  = 0;
    uint64_t l_OCBSHCS_address = 0;
    o_ocb_act_length = 0;

    FAPI_DBG("Checking channel validity");

    switch ( i_ocb_chan )
    {
        case p9ocb::OCB_CHAN0:
            l_OCBAR_address   = PU_OCB_PIB_OCBAR0;
            l_OCBDR_address   = PU_OCB_PIB_OCBDR0;
            l_OCBCSR_address  = PU_OCB_PIB_OCBCSR0_RO;
            l_OCBSHCS_address = PU_OCB_OCI_OCBSHCS0_SCOM;
            break;

        case p9ocb::OCB_CHAN1:
            l_OCBAR_address   = PU_OCB_PIB_OCBAR1;
            l_OCBDR_address   = PU_OCB_PIB_OCBDR1;
            l_OCBCSR_address  = PU_OCB_PIB_OCBCSR1_RO;
            l_OCBSHCS_address = PU_OCB_OCI_OCBSHCS1_SCOM;
            break;

        case p9ocb::OCB_CHAN2:
            l_OCBAR_address   = PU_OCB_PIB_OCBAR2;
            l_OCBDR_address   = PU_OCB_PIB_OCBDR2;
            l_OCBCSR_address  = PU_OCB_PIB_OCBCSR2_RO;
            l_OCBSHCS_address = PU_OCB_OCI_OCBSHCS2_SCOM;
            break;

        case p9ocb::OCB_CHAN3:
            l_OCBAR_address   = PU_OCB_PIB_OCBAR3;
            l_OCBDR_address   = PU_OCB_PIB_OCBDR3;
            l_OCBCSR_address  = PU_OCB_PIB_OCBCSR3_RO;
            l_OCBSHCS_address = PU_OCB_OCI_OCBSHCS3_SCOM;
            break;
    }

    // Verify if a valid valid address provided
    // If the address is provided
    //     Use it for the Get / Put operation
    //     The following cases apply:
    //     Circular      : OCBAR is irrelevant; write it anyway
    //     Linear        : OCBAR will set the accessed location
    //     Linear Stream : OCBAR will establish the address from which
    //                     auto-increment will commence after the first access
    // Else
    //     Circular      : OCBAR is irrelevant
    //     Linear        : OCBAR will continue to access the same location
    //     Linear Stream : OCBAR will auto-increment
    if ( i_oci_address_valid )
    {
        FAPI_DBG(" OCI Address : 0x%08X", i_oci_address);
        fapi2::buffer<uint64_t> l_data64;
        l_data64.insert<0, 32>(i_oci_address);

        FAPI_TRY(fapi2::putScom(i_target, l_OCBAR_address, l_data64));
    }

    // PUT Operation
    if ( i_ocb_op == p9ocb::OCB_PUT )
    {
        FAPI_INF("OCB access for data write operation");
        FAPI_ASSERT(io_ocb_buffer != NULL,
                    fapi2::PROCPM_OCB_PUT_NO_DATA_ERROR(),
                    "No data provided for PUT operation");

        fapi2::buffer<uint64_t> l_data64;
        FAPI_TRY(fapi2::getScom(i_target, l_OCBCSR_address, l_data64));

        // The following check for circular mode is an additional check
        // performed to ensure a valid data access.
        if (l_data64.getBit<4>() && l_data64.getBit<5>())
        {
            FAPI_DBG("Circular mode detected.");
            // Check if push queue is enabled. If not, let the store occur
            // anyway to let the PIB error response return occur. (that is
            // what will happen if this checking code were not here)
            FAPI_TRY(fapi2::getScom(i_target, l_OCBSHCS_address, l_data64));

            if (l_data64.getBit<31>())
            {
                FAPI_DBG("Poll for a non-full condition to a push queue to "
                         "avoid data corruption problem");
                bool l_push_ok_flag = false;
                uint8_t l_counter = 0;

                do
                {
                    // If the OCB_OCI_OCBSHCS0_PUSH_FULL bit (bit 0) is clear,
                    // proceed. Otherwise, poll
                    if (!l_data64.getBit<0>())
                    {
                        l_push_ok_flag = true;
                        FAPI_DBG("Push queue not full. Proceeding");
                        break;
                    }

                    // Delay, before next polling.
                    fapi2::delay(OCB_FULL_POLL_DELAY_HDW,
                                 OCB_FULL_POLL_DELAY_SIM);

                    FAPI_TRY(fapi2::getScom(i_target,
                                            l_OCBSHCS_address,
                                            l_data64));
                    l_counter++;
                }
                while (l_counter < OCB_FULL_POLL_MAX);

                FAPI_ASSERT((true == l_push_ok_flag),
                            fapi2::PROCPM_OCB_PUT_DATA_POLL_NOT_FULL_ERROR().
                            set_PUSHQ_STATE(l_data64),
                            "Polling timeout waiting on push non-full");
            }
        }

        // Walk the input buffer (io_ocb_buffer) 8B (64bits) at a time to write
        // the channel data register
        for(uint32_t l_index = 0; l_index < i_ocb_req_length; l_index++)
        {
            l_data64.insertFromRight(io_ocb_buffer[l_index], 0, 64);
            FAPI_TRY(fapi2::putScom(i_target, l_OCBDR_address, l_data64),
                     "ERROR:Failed to complete write to channel data register");
            o_ocb_act_length++;
            FAPI_DBG("data(64 bits): 0x%016lX written to channel data register",
                     io_ocb_buffer[l_index]);
        }

        FAPI_DBG("%d blocks(64bits each) of data put", o_ocb_act_length);
    }
    // GET Operation
    else if( i_ocb_op == p9ocb::OCB_GET )
    {
        FAPI_INF("OCB access for data read operation");

        fapi2::buffer<uint64_t> l_data64;
        uint64_t l_data = 0;

        for (uint32_t l_loopCount = 0; l_loopCount < i_ocb_req_length;
             l_loopCount++)
        {
            FAPI_TRY(fapi2::getScom(i_target, l_OCBDR_address, l_data64),
                     "ERROR: Failed to read data from channel %d", i_ocb_chan);
            l_data64.extract(l_data, 0, 64);
            io_ocb_buffer[l_loopCount] = l_data;
            o_ocb_act_length++;
            FAPI_DBG("data(64 bits): 0x%016lX read from channel data register",
                     io_ocb_buffer[l_loopCount]);
        }

        FAPI_DBG("%d blocks(64bits each) of data retrieved",
                 o_ocb_act_length);
    }

    FAPI_IMP("Exit p9_pm_ocb_indir_access...");

fapi_try_exit:
    return fapi2::current_err;

}
<commit_msg>Fixes for OCB channel init and access<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: chips/p9/procedures/hwp/pm/p9_pm_ocb_indir_access.C $         */
/*                                                                        */
/* IBM CONFIDENTIAL                                                       */
/*                                                                        */
/* EKB Project                                                            */
/*                                                                        */
/* COPYRIGHT 2015,2016                                                    */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* The source code for this program is not published or otherwise         */
/* divested of its trade secrets, irrespective of what has been           */
/* deposited with the U.S. Copyright Office.                              */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
/// @file p9_pm_ocb_indir_access.C
/// @brief Performs the data transfer to/from an OCB indirect channel

// *HWP HWP Owner       : Amit Kumar <akumar3@us.ibm.com>
// *HWP HWP Backup Owner: Greg Still <stillgs@us.ibm.com>
// *HWP FW Owner        : Sangeetha T S <sangeet2@in.ibm.com>
// *HWP Team            : PM
// *HWP Level           : 2
// *HWP Consumed by     : FSP:HS

///
/// High-level procedure flow:
/// @verbatim
///     1) Check if the channel for access is valid.
///     2) For the PUT operation, the data from the buffer will be written
///        into the OCB Data register in blocks of 64bits;
///        from where eventually the data will be written to SRAM.
///     3) For GET operation, the data read from the SRAM will be retrieved from
///        the DATA register and written into the buffer in blocks of 64bits.
/// @endverbatim
///

// ----------------------------------------------------------------------
// Includes
// ----------------------------------------------------------------------
#include <p9_pm_ocb_indir_access.H>

// ----------------------------------------------------------------------
// Constant definitions
// ----------------------------------------------------------------------

enum
{
    OCB_FULL_POLL_MAX = 4,
    OCB_FULL_POLL_DELAY_HDW = 0,
    OCB_FULL_POLL_DELAY_SIM = 0
};

fapi2::ReturnCode p9_pm_ocb_indir_access(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
    const p9ocb::PM_OCB_CHAN_NUM  i_ocb_chan,
    const p9ocb::PM_OCB_ACCESS_OP i_ocb_op,
    const uint32_t                i_ocb_req_length,
    const bool                    i_oci_address_valid,
    const uint32_t                i_oci_address,
    uint32_t&                     o_ocb_act_length,
    uint64_t*                     io_ocb_buffer)
{
    FAPI_IMP("Enter p9_pm_ocb_indir_access...");
    FAPI_DBG("Channel : %d, Operation : %d, No.of 8B Blocks of Data: %d",
             i_ocb_chan, i_ocb_op, i_ocb_req_length);

    uint64_t l_OCBAR_address   = 0;
    uint64_t l_OCBDR_address   = 0;
    uint64_t l_OCBCSR_address  = 0;
    uint64_t l_OCBSHCS_address = 0;
    o_ocb_act_length = 0;

    FAPI_DBG("Checking channel validity");

    switch ( i_ocb_chan )
    {
        case p9ocb::OCB_CHAN0:
            l_OCBAR_address   = PU_OCB_PIB_OCBAR0;
            l_OCBDR_address   = PU_OCB_PIB_OCBDR0;
            l_OCBCSR_address  = PU_OCB_PIB_OCBCSR0_RO;
            l_OCBSHCS_address = PU_OCB_OCI_OCBSHCS0_SCOM;
            break;

        case p9ocb::OCB_CHAN1:
            l_OCBAR_address   = PU_OCB_PIB_OCBAR1;
            l_OCBDR_address   = PU_OCB_PIB_OCBDR1;
            l_OCBCSR_address  = PU_OCB_PIB_OCBCSR1_RO;
            l_OCBSHCS_address = PU_OCB_OCI_OCBSHCS1_SCOM;
            break;

        case p9ocb::OCB_CHAN2:
            l_OCBAR_address   = PU_OCB_PIB_OCBAR2;
            l_OCBDR_address   = PU_OCB_PIB_OCBDR2;
            l_OCBCSR_address  = PU_OCB_PIB_OCBCSR2_RO;
            l_OCBSHCS_address = PU_OCB_OCI_OCBSHCS2_SCOM;
            break;

        case p9ocb::OCB_CHAN3:
            l_OCBAR_address   = PU_OCB_PIB_OCBAR3;
            l_OCBDR_address   = PU_OCB_PIB_OCBDR3;
            l_OCBCSR_address  = PU_OCB_PIB_OCBCSR3_RO;
            l_OCBSHCS_address = PU_OCB_OCI_OCBSHCS3_SCOM;
            break;
    }

    // Verify if a valid valid address provided
    // If the address is provided
    //     Use it for the Get / Put operation
    //     The following cases apply:
    //     Circular      : OCBAR is irrelevant; write it anyway
    //     Linear        : OCBAR will set the accessed location
    //     Linear Stream : OCBAR will establish the address from which
    //                     auto-increment will commence after the first access
    // Else
    //     Circular      : OCBAR is irrelevant
    //     Linear        : OCBAR will continue to access the same location
    //     Linear Stream : OCBAR will auto-increment
    if ( i_oci_address_valid )
    {
        FAPI_DBG(" OCI Address : 0x%08X", i_oci_address);
        fapi2::buffer<uint64_t> l_data64;
        l_data64.insert<0, 32>(i_oci_address);

        FAPI_TRY(fapi2::putScom(i_target, l_OCBAR_address, l_data64));
    }

    // PUT Operation
    if ( i_ocb_op == p9ocb::OCB_PUT )
    {
        FAPI_INF("OCB access for data write operation");
        FAPI_ASSERT(io_ocb_buffer != NULL,
                    fapi2::PM_OCB_PUT_NO_DATA_ERROR(),
                    "No data provided for PUT operation");

        fapi2::buffer<uint64_t> l_data64;
        FAPI_TRY(fapi2::getScom(i_target, l_OCBCSR_address, l_data64));

        // The following check for circular mode is an additional check
        // performed to ensure a valid data access.
        if (l_data64.getBit<4>() && l_data64.getBit<5>())
        {
            FAPI_DBG("Circular mode detected.");
            // Check if push queue is enabled. If not, let the store occur
            // anyway to let the PIB error response return occur. (that is
            // what will happen if this checking code were not here)
            FAPI_TRY(fapi2::getScom(i_target, l_OCBSHCS_address, l_data64));

            if (l_data64.getBit<31>())
            {
                FAPI_DBG("Poll for a non-full condition to a push queue to "
                         "avoid data corruption problem");
                bool l_push_ok_flag = false;
                uint8_t l_counter = 0;

                do
                {
                    // If the OCB_OCI_OCBSHCS0_PUSH_FULL bit (bit 0) is clear,
                    // proceed. Otherwise, poll
                    if (!l_data64.getBit<0>())
                    {
                        l_push_ok_flag = true;
                        FAPI_DBG("Push queue not full. Proceeding");
                        break;
                    }

                    // Delay, before next polling.
                    fapi2::delay(OCB_FULL_POLL_DELAY_HDW,
                                 OCB_FULL_POLL_DELAY_SIM);

                    FAPI_TRY(fapi2::getScom(i_target,
                                            l_OCBSHCS_address,
                                            l_data64));
                    l_counter++;
                }
                while (l_counter < OCB_FULL_POLL_MAX);

                FAPI_ASSERT((true == l_push_ok_flag),
                            fapi2::PM_OCB_PUT_DATA_POLL_NOT_FULL_ERROR().
                            set_PUSHQ_STATE(l_data64),
                            "Polling timeout waiting on push non-full");
            }
        }

        // Walk the input buffer (io_ocb_buffer) 8B (64bits) at a time to write
        // the channel data register
        for(uint32_t l_index = 0; l_index < i_ocb_req_length; l_index++)
        {
            l_data64.insertFromRight(io_ocb_buffer[l_index], 0, 64);
            FAPI_TRY(fapi2::putScom(i_target, l_OCBDR_address, l_data64),
                     "ERROR:Failed to complete write to channel data register");
            o_ocb_act_length++;
            FAPI_DBG("data(64 bits): 0x%016lX written to channel data register",
                     io_ocb_buffer[l_index]);
        }

        FAPI_DBG("%d blocks(64bits each) of data put", o_ocb_act_length);
    }
    // GET Operation
    else if( i_ocb_op == p9ocb::OCB_GET )
    {
        FAPI_INF("OCB access for data read operation");

        fapi2::buffer<uint64_t> l_data64;
        uint64_t l_data = 0;

        for (uint32_t l_loopCount = 0; l_loopCount < i_ocb_req_length;
             l_loopCount++)
        {
            FAPI_TRY(fapi2::getScom(i_target, l_OCBDR_address, l_data64),
                     "ERROR: Failed to read data from channel %d", i_ocb_chan);
            l_data64.extract(l_data, 0, 64);
            io_ocb_buffer[l_loopCount] = l_data;
            o_ocb_act_length++;
            FAPI_DBG("data(64 bits): 0x%016lX read from channel data register",
                     io_ocb_buffer[l_loopCount]);
        }

        FAPI_DBG("%d blocks(64bits each) of data retrieved",
                 o_ocb_act_length);
    }

    FAPI_IMP("Exit p9_pm_ocb_indir_access...");

fapi_try_exit:
    return fapi2::current_err;

}
<|endoftext|>