<commit_before>AliAnalysisTask* AddTaskFilteredTree(TString outputFile="")
{
  gSystem->Load("libANALYSIS");
  gSystem->Load("libANALYSISalice");
  gSystem->Load("libTender");
  gSystem->Load("libCORRFW");
  gSystem->Load("libPWGUDbase");
  gSystem->Load("libTPCcalib");
  gSystem->Load("libPWGPP");
  gSystem->Load("libPWGLFspectra");
  ::Info("AddTaskFilteredTree","BEGIN");
  printf("AddTaskFilteredTree::BEGIN\n");
  gRandom->SetSeed(0);

  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();

  if (!mgr) {
    Error("AddTaskFilteredTree", "No analysis manager found.");
    return 0;
  }

  // Switch off all AliInfo (too much output!!!)
  AliLog::SetGlobalLogLevel(AliLog::kError);
  mgr->SetDebugLevel(0);

  //
  // Create physics trigger selection class
  //
  //AliPhysicsSelection *physTrigSel =  new AliPhysicsSelection();

  //
  // Create event cuts
  //
  Float_t zvWindow = 30. ;

  AliFilteredTreeEventCuts *evtCuts = new AliFilteredTreeEventCuts("AliFilteredTreeEventCuts","Event cuts");
  evtCuts->SetZvRange(-zvWindow,zvWindow);
  evtCuts->SetMeanXYZv(0.0,0.0,0.0);
  evtCuts->SetSigmaMeanXYZv(1.0,1.0,10.0);
  evtCuts->SetTriggerRequired(kFALSE);
  //evtCuts->SetTriggerRequired(kTRUE);

  //
  // Create geom. acceptance cuts
  //
  Float_t etaWindow = 1.0 ;
  Float_t ptMin = 0.15 ;

  AliFilteredTreeAcceptanceCuts *accCuts = new AliFilteredTreeAcceptanceCuts("AliFilteredTreeAcceptanceCuts","Geom. acceptance cuts");
  accCuts->SetEtaRange(-etaWindow,etaWindow);
  accCuts->SetPtRange(ptMin,1.e10);
  accCuts->SetMaxDCAr(3.0);
  accCuts->SetMaxDCAz(30.0);

  //
  // Create standard esd track cuts
  //

  AliESDtrackCuts* esdTrackCuts = CreateCuts();
  if (!esdTrackCuts) {
    printf("ERROR: esdTrackCuts could not be created\n");
    return;
  } else {
    esdTrackCuts->SetHistogramsOn(kTRUE);
  }
  Bool_t hasMC=(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler()!=0x0);

  //
  // Create task
  //
  AliAnalysisTaskFilteredTree *task = new AliAnalysisTaskFilteredTree("AliAnalysisTaskFilteredTree");
  //task->SetUseMCInfo(hasMC);
  //task->SetLowPtTrackDownscaligF(1.e4);
  //task->SetLowPtV0DownscaligF(1.e2);
  task->SetLowPtTrackDownscaligF(1.e5);
  task->SetLowPtV0DownscaligF(2.e3);
  task->SetProcessAll(kTRUE);
  task->SetProcessCosmics(kTRUE);
  if (gSystem->Getenv("AliAnalysisTaskFilteredTree_SetLowPtTrackDownscalingF")) {
    Float_t downscale=TString(gSystem->Getenv("AliAnalysisTaskFilteredTree_SetLowPtTrackDownscalingF")).Atof();
    task->SetLowPtTrackDownscaligF(downscale);
    printf("AliAnalysisTaskFilteredTree_SetLowPtTrackDownscalingF: From env. variable\t%f\n", downscale);
  }else {
    ::Info("AliAnalysisTaskFilteredTree__SetLowPtTrackDownscalingF", "Use default");
    printf("AliAnalysisTaskFilteredTree_SetLowPtV0DownscalingF::Use DEFAULT\t%s\n",task->GetLowPtTracksDownscaligF());
  }
  if (gSystem->Getenv("AliAnalysisTaskFilteredTree_SetLowPtV0DownscalingF")) {
    Float_t downscale=TString(gSystem->Getenv("AliAnalysisTaskFilteredTree_SetLowPtV0DownscalingF")).Atof();
    task->SetLowPtV0DownscaligF(downscale);
    printf("AliAnalysisTaskFilteredTree_SetLowPtV0DownscalingF:From enc. variable\t%f\n",downscale);
  }else {
    printf("AliAnalysisTaskFilteredTree_SetLowPtV0DownscalingF::Use DEFAULT\t%f\n",task->GetLowPtV0DownscaligF());
  }
  //task->Dump();
  //task->SetProcessAll(kFALSE);
  //task->SetFillTrees(kFALSE); // only histograms are filled

  // trigger
  //task->SelectCollisionCandidates(AliVEvent::kMB);

  //
  // set analysis options from the Helper here !!!
  //
  // AlidNdPtHelper::OutputObject outputObject = AlidNdPtHelper::kCutAnalysisPbPb;
  // AlidNdPtHelper::ParticleMode particleMode = AlidNdPtHelper::kAllPart ;
  //AlidNdPtHelper::AnalysisMode analysisMode = AlidNdPtHelper::kTPCITS;

  task->SetEventCuts(evtCuts);
  task->SetAcceptanceCuts(accCuts);
  task->SetTrackCuts(esdTrackCuts);
  task->SetAnalysisMode(AliAnalysisTaskFilteredTree::kTPCITSAnalysisMode);
  task->SetCentralityEstimator("V0M");

  // Add task
  mgr->AddTask(task);

  // Create containers for input
  AliAnalysisDataContainer *cinput = mgr->GetCommonInputContainer();
  mgr->ConnectInput(task, 0, cinput);

  if (outputFile.IsNull())
    outputFile=Form("%s", AliAnalysisManager::GetCommonFileName());

  AliAnalysisDataContainer *coutput1 = mgr->CreateContainer("filtered1", TTree::Class(), AliAnalysisManager::kOutputContainer, outputFile.Data());
  mgr->ConnectOutput(task, 1, coutput1);
  AliAnalysisDataContainer *coutput2 = mgr->CreateContainer("filtered2", TTree::Class(), AliAnalysisManager::kOutputContainer, outputFile.Data());
  mgr->ConnectOutput(task, 2, coutput2);
  AliAnalysisDataContainer *coutput3 = mgr->CreateContainer("filtered3", TTree::Class(), AliAnalysisManager::kOutputContainer, outputFile.Data());
  mgr->ConnectOutput(task, 3, coutput3);
  AliAnalysisDataContainer *coutput4 = mgr->CreateContainer("filtered4", TTree::Class(), AliAnalysisManager::kOutputContainer, outputFile.Data());
  mgr->ConnectOutput(task, 4, coutput4);
  AliAnalysisDataContainer *coutput5 = mgr->CreateContainer("filtered5", TTree::Class(), AliAnalysisManager::kOutputContainer, outputFile.Data());
  mgr->ConnectOutput(task, 5, coutput5);
  AliAnalysisDataContainer *coutput6 = mgr->CreateContainer("filtered6", TTree::Class(), AliAnalysisManager::kOutputContainer, outputFile.Data());
  mgr->ConnectOutput(task, 6, coutput6);

 // store histograms in the separate file
  TString outputFileHisto = "PtResHistograms.root";

  AliAnalysisDataContainer *coutput7 = mgr->CreateContainer("histo7", TList::Class(), AliAnalysisManager::kOutputContainer, outputFileHisto.Data());
  mgr->ConnectOutput(task, 7, coutput7);

   ::Info("AddTaskFilteredTree","END");
  printf("AddTaskFilteredTree::END\n");
  return task;
}

AliESDtrackCuts* CreateCuts(Bool_t fieldOn = kTRUE, Bool_t hists = kTRUE)
{
  AliESDtrackCuts* esdTrackCuts = new AliESDtrackCuts("AliESDtrackCuts");
  if(!esdTrackCuts) return 0;

  if (hists)
    esdTrackCuts->DefineHistograms(1);

  Double_t cov1, cov2, cov3, cov4, cov5;
  Double_t nSigma;
  Double_t maxDCAtoVertex, maxDCAtoVertexXY, maxDCAtoVertexZ;
  Double_t minNClustersTPC;
  Double_t maxChi2PerClusterTPC;
  Double_t minPt, maxPt;

  //
  // TPC
  //
  esdTrackCuts->SetRequireTPCRefit(kTRUE);
  esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
  //
  // ITS
  //
  //esdTrackCuts->SetRequireITSRefit(kTRUE);
  //esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
  //

  TString tag = "TPC+ITS refit and KinkRejection required - for cut studies";

  // cuts for data without field
  if (!fieldOn)
  {
    cov5 = 1e10;
    tag += " without field";
  }

  Printf("Created track cuts for: %s", tag.Data());

  return esdTrackCuts;
}
<commit_msg>ATO-245-Fix to previously introduced bug<commit_after>AliAnalysisTask* AddTaskFilteredTree(TString outputFile="")
{
  gSystem->Load("libANALYSIS");
  gSystem->Load("libANALYSISalice");
  gSystem->Load("libTender");
  gSystem->Load("libCORRFW");
  gSystem->Load("libPWGUDbase");
  gSystem->Load("libTPCcalib");
  gSystem->Load("libPWGPP");
  gSystem->Load("libPWGLFspectra");
  ::Info("AddTaskFilteredTree","BEGIN");
  printf("AddTaskFilteredTree::BEGIN\n");
  gRandom->SetSeed(0);

  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();

  if (!mgr) {
    Error("AddTaskFilteredTree", "No analysis manager found.");
    return 0;
  }

  // Switch off all AliInfo (too much output!!!)
  AliLog::SetGlobalLogLevel(AliLog::kError);
  mgr->SetDebugLevel(0);

  //
  // Create physics trigger selection class
  //
  //AliPhysicsSelection *physTrigSel =  new AliPhysicsSelection();

  //
  // Create event cuts
  //
  Float_t zvWindow = 30. ;

  AliFilteredTreeEventCuts *evtCuts = new AliFilteredTreeEventCuts("AliFilteredTreeEventCuts","Event cuts");
  evtCuts->SetZvRange(-zvWindow,zvWindow);
  evtCuts->SetMeanXYZv(0.0,0.0,0.0);
  evtCuts->SetSigmaMeanXYZv(1.0,1.0,10.0);
  evtCuts->SetTriggerRequired(kFALSE);
  //evtCuts->SetTriggerRequired(kTRUE);

  //
  // Create geom. acceptance cuts
  //
  Float_t etaWindow = 1.0 ;
  Float_t ptMin = 0.15 ;

  AliFilteredTreeAcceptanceCuts *accCuts = new AliFilteredTreeAcceptanceCuts("AliFilteredTreeAcceptanceCuts","Geom. acceptance cuts");
  accCuts->SetEtaRange(-etaWindow,etaWindow);
  accCuts->SetPtRange(ptMin,1.e10);
  accCuts->SetMaxDCAr(3.0);
  accCuts->SetMaxDCAz(30.0);

  //
  // Create standard esd track cuts
  //

  AliESDtrackCuts* esdTrackCuts = CreateCuts();
  if (!esdTrackCuts) {
    printf("ERROR: esdTrackCuts could not be created\n");
    return;
  } else {
    esdTrackCuts->SetHistogramsOn(kTRUE);
  }
  Bool_t hasMC=(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler()!=0x0);

  //
  // Create task
  //
  AliAnalysisTaskFilteredTree *task = new AliAnalysisTaskFilteredTree("AliAnalysisTaskFilteredTree");
  //task->SetUseMCInfo(hasMC);
  //task->SetLowPtTrackDownscaligF(1.e4);
  //task->SetLowPtV0DownscaligF(1.e2);
  task->SetLowPtTrackDownscaligF(1.e5);
  task->SetLowPtV0DownscaligF(2.e3);
  task->SetProcessAll(kTRUE);
  task->SetProcessCosmics(kTRUE);
  if (gSystem->Getenv("AliAnalysisTaskFilteredTree_SetLowPtTrackDownscalingF")) {
    Float_t downscale=TString(gSystem->Getenv("AliAnalysisTaskFilteredTree_SetLowPtTrackDownscalingF")).Atof();
    task->SetLowPtTrackDownscaligF(downscale);
    printf("AliAnalysisTaskFilteredTree_SetLowPtTrackDownscalingF: From env. variable\t%f\n", downscale);
  }else {
    ::Info("AliAnalysisTaskFilteredTree__SetLowPtTrackDownscalingF", "Use default");
    printf("AliAnalysisTaskFilteredTree_SetLowPtV0DownscalingF::Use DEFAULT\t%s\n");
  }
  if (gSystem->Getenv("AliAnalysisTaskFilteredTree_SetLowPtV0DownscalingF")) {
    Float_t downscale=TString(gSystem->Getenv("AliAnalysisTaskFilteredTree_SetLowPtV0DownscalingF")).Atof();
    task->SetLowPtV0DownscaligF(downscale);
    printf("AliAnalysisTaskFilteredTree_SetLowPtV0DownscalingF:From enc. variable\t%f\n",downscale);
  }else {
    printf("AliAnalysisTaskFilteredTree_SetLowPtV0DownscalingF::Use DEFAULT\t%f\n");
  }
  //task->Dump();
  //task->SetProcessAll(kFALSE);
  //task->SetFillTrees(kFALSE); // only histograms are filled

  // trigger
  //task->SelectCollisionCandidates(AliVEvent::kMB);

  //
  // set analysis options from the Helper here !!!
  //
  // AlidNdPtHelper::OutputObject outputObject = AlidNdPtHelper::kCutAnalysisPbPb;
  // AlidNdPtHelper::ParticleMode particleMode = AlidNdPtHelper::kAllPart ;
  //AlidNdPtHelper::AnalysisMode analysisMode = AlidNdPtHelper::kTPCITS;

  task->SetEventCuts(evtCuts);
  task->SetAcceptanceCuts(accCuts);
  task->SetTrackCuts(esdTrackCuts);
  task->SetAnalysisMode(AliAnalysisTaskFilteredTree::kTPCITSAnalysisMode);
  task->SetCentralityEstimator("V0M");

  // Add task
  mgr->AddTask(task);

  // Create containers for input
  AliAnalysisDataContainer *cinput = mgr->GetCommonInputContainer();
  mgr->ConnectInput(task, 0, cinput);

  if (outputFile.IsNull())
    outputFile=Form("%s", AliAnalysisManager::GetCommonFileName());

  AliAnalysisDataContainer *coutput1 = mgr->CreateContainer("filtered1", TTree::Class(), AliAnalysisManager::kOutputContainer, outputFile.Data());
  mgr->ConnectOutput(task, 1, coutput1);
  AliAnalysisDataContainer *coutput2 = mgr->CreateContainer("filtered2", TTree::Class(), AliAnalysisManager::kOutputContainer, outputFile.Data());
  mgr->ConnectOutput(task, 2, coutput2);
  AliAnalysisDataContainer *coutput3 = mgr->CreateContainer("filtered3", TTree::Class(), AliAnalysisManager::kOutputContainer, outputFile.Data());
  mgr->ConnectOutput(task, 3, coutput3);
  AliAnalysisDataContainer *coutput4 = mgr->CreateContainer("filtered4", TTree::Class(), AliAnalysisManager::kOutputContainer, outputFile.Data());
  mgr->ConnectOutput(task, 4, coutput4);
  AliAnalysisDataContainer *coutput5 = mgr->CreateContainer("filtered5", TTree::Class(), AliAnalysisManager::kOutputContainer, outputFile.Data());
  mgr->ConnectOutput(task, 5, coutput5);
  AliAnalysisDataContainer *coutput6 = mgr->CreateContainer("filtered6", TTree::Class(), AliAnalysisManager::kOutputContainer, outputFile.Data());
  mgr->ConnectOutput(task, 6, coutput6);

 // store histograms in the separate file
  TString outputFileHisto = "PtResHistograms.root";

  AliAnalysisDataContainer *coutput7 = mgr->CreateContainer("histo7", TList::Class(), AliAnalysisManager::kOutputContainer, outputFileHisto.Data());
  mgr->ConnectOutput(task, 7, coutput7);

   ::Info("AddTaskFilteredTree","END");
  printf("AddTaskFilteredTree::END\n");
  return task;
}

AliESDtrackCuts* CreateCuts(Bool_t fieldOn = kTRUE, Bool_t hists = kTRUE)
{
  AliESDtrackCuts* esdTrackCuts = new AliESDtrackCuts("AliESDtrackCuts");
  if(!esdTrackCuts) return 0;

  if (hists)
    esdTrackCuts->DefineHistograms(1);

  Double_t cov1, cov2, cov3, cov4, cov5;
  Double_t nSigma;
  Double_t maxDCAtoVertex, maxDCAtoVertexXY, maxDCAtoVertexZ;
  Double_t minNClustersTPC;
  Double_t maxChi2PerClusterTPC;
  Double_t minPt, maxPt;

  //
  // TPC
  //
  esdTrackCuts->SetRequireTPCRefit(kTRUE);
  esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
  //
  // ITS
  //
  //esdTrackCuts->SetRequireITSRefit(kTRUE);
  //esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
  //

  TString tag = "TPC+ITS refit and KinkRejection required - for cut studies";

  // cuts for data without field
  if (!fieldOn)
  {
    cov5 = 1e10;
    tag += " without field";
  }

  Printf("Created track cuts for: %s", tag.Data());

  return esdTrackCuts;
}
<|endoftext|>


<commit_before>#include "RigidBodyEditor.hpp"

#include <Engine/Component/RigidBody.hpp>
#include <Engine/Component/Shape.hpp>
#include <Engine/Entity/Entity.hpp>
#include <Engine/Manager/Managers.hpp>
#include <Engine/Manager/PhysicsManager.hpp>
#include <imgui.h>

namespace GUI {
    void RigidBodyEditor::Show(Component::RigidBody* comp) {
        GetData(comp);

        auto shapeComp = comp->entity->GetComponent<Component::Shape>();
        if (shapeComp) {
            ImGui::Indent();

            if (ImGui::InputFloat("Mass", &mass))
                Managers().physicsManager->SetMass(comp, mass);

            float friction = comp->GetFriction();
            if (ImGui::InputFloat("Friction", &friction))
                Managers().physicsManager->SetFriction(comp, friction);

            bool kinematic = comp->IsKinematic();
            if (ImGui::Checkbox("Kinematic", &kinematic)) {
                if (kinematic)
                    Managers().physicsManager->MakeKinematic(comp);
                else
                    Managers().physicsManager->MakeDynamic(comp);
            }

            ImGui::Unindent();
        }
        else {
            ImGui::Indent();
            ImGui::TextWrapped("A rigid body is only valid with a complementary shape component. Please add one to allow editing this component.");
            ImGui::Unindent();
        }
    }

    void RigidBodyEditor::GetData(Component::RigidBody* comp) {
        mass = Managers().physicsManager->GetMass(comp);
    }
}
<commit_msg>Editor support for setting rolling friction.<commit_after>#include "RigidBodyEditor.hpp"

#include <Engine/Component/RigidBody.hpp>
#include <Engine/Component/Shape.hpp>
#include <Engine/Entity/Entity.hpp>
#include <Engine/Manager/Managers.hpp>
#include <Engine/Manager/PhysicsManager.hpp>
#include <imgui.h>

namespace GUI {
    void RigidBodyEditor::Show(Component::RigidBody* comp) {
        GetData(comp);

        auto shapeComp = comp->entity->GetComponent<Component::Shape>();
        if (shapeComp) {
            ImGui::Indent();

            if (ImGui::InputFloat("Mass", &mass))
                Managers().physicsManager->SetMass(comp, mass);

            float friction = comp->GetFriction();
            if (ImGui::InputFloat("Friction", &friction))
                Managers().physicsManager->SetFriction(comp, friction);

            float rollingFriction = comp->GetRollingFriction();
            if (ImGui::InputFloat("Rolling friction", &rollingFriction))
                Managers().physicsManager->SetRollingFriction(comp, rollingFriction);

            bool kinematic = comp->IsKinematic();
            if (ImGui::Checkbox("Kinematic", &kinematic)) {
                if (kinematic)
                    Managers().physicsManager->MakeKinematic(comp);
                else
                    Managers().physicsManager->MakeDynamic(comp);
            }

            ImGui::Unindent();
        }
        else {
            ImGui::Indent();
            ImGui::TextWrapped("A rigid body is only valid with a complementary shape component. Please add one to allow editing this component.");
            ImGui::Unindent();
        }
    }

    void RigidBodyEditor::GetData(Component::RigidBody* comp) {
        mass = Managers().physicsManager->GetMass(comp);
    }
}
<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2014-2016 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

/*!
 * \file
 * \brief Contains the probabilistic pooling expressions.
*/

#pragma once

//Get the implementations
#include "etl/impl/prob_pooling.hpp"

namespace etl {

/*!
 * \brief A configurable expression for FFT
 * \tparam T The value type
 * \tparam D The number of dimensions of the FFT
 * \tparam Impl The implementation to use
 */
template <typename T, std::size_t D, typename Impl>
struct basic_pmp_h_expr : impl_expr<basic_pmp_h_expr<T, D, Impl>> {
    using this_type  = basic_pmp_h_expr<T, D, Impl>; ///< The type of this expression
    using value_type = T;                          ///< The value type

    static constexpr bool is_gpu = false; ///< Indicate if the expression is executed on GPU

    /*!
     * \brief The result type for a given sub expression type
     * \tparam A The sub epxpression type
     */
    template <typename A>
    using result_type = detail::expr_result_t<this_type, A>;

    /*!
     * \brief Apply the expression
     * \param a The sub expression
     * \param c The expression where to store the results
     */
    template <typename A, typename C>
    static void apply(A&& a, C&& c) {
        static_assert(is_etl_expr<A>::value && is_etl_expr<C>::value, "Probabilistic Max Pooling only supported for ETL expressions");

        Impl::apply(
            make_temporary(std::forward<A>(a)),
            std::forward<C>(c));
    }

    /*!
     * \brief Returns a textual representation of the operation
     * \return a textual representation of the operation
     */
    static std::string desc() noexcept {
        return "pmp_h";
    }

    /*!
     * \brief Returns the DDth dimension of the expression
     * \tparam A The sub expression type
     * \tparam DD The dimension to get
     * \return the DDth dimension of the expression
     */
    template <typename A, std::size_t DD>
    static constexpr std::size_t dim() {
        return decay_traits<A>::template dim<DD>();
    }

    /*!
     * \brief Returns the dth dimension of the expression
     * \param a The sub expression
     * \param d The dimension to get
     * \return the dth dimension of the expression
     */
    template <typename A>
    static std::size_t dim(const A& a, std::size_t d) {
        return etl_traits<A>::dim(a, d);
    }

    /*!
     * \brief Returns the size of the expression
     * \param a The sub expression
     * \return the size of the expression
     */
    template <typename A>
    static std::size_t size(const A& a) {
        return etl::size(a);
    }

    /*!
     * \brief Returns the size of the expression
     * \return the size of the expression
     */
    template <typename A>
    static constexpr std::size_t size() {
        return etl::decay_traits<A>::size();
    }

    /*!
     * \brief Returns the storage order of the expression.
     * \return the storage order of the expression
     */
    template <typename A>
    static constexpr etl::order order() {
        return decay_traits<A>::storage_order;
    }

    /*!
     * \brief Returns the number of dimensions of the expression
     * \return the number of dimensions of the expression
     */
    static constexpr std::size_t dimensions() {
        return D;
    }
};

/*!
 * \brief Expression for 2D FFT
 */
template <typename T, size_t D, size_t C1, size_t C2>
using pmp_h_2d_expr = basic_pmp_h_expr<T, D, detail::pmp_2d_impl<D, C1, C2>>;

/*!
 * \brief A configurable expression for FFT
 * \tparam T The value type
 * \tparam D The number of dimensions of the FFT
 * \tparam Impl The implementation to use
 */
template <typename T, std::size_t D, typename Impl>
struct dyn_basic_pmp_h_expr : impl_expr<basic_pmp_h_expr<T, D, Impl>> {
    using this_type  = dyn_basic_pmp_h_expr<T, D, Impl>; ///< The type of this expression
    using value_type = T;                          ///< The value type

    static constexpr bool is_gpu = false; ///< Indicate if the expression is executed on GPU

    Impl impl; ///< The implementation operator

    /*!
     * \brief Construct a new dyn_basic_pmp_h_expr and forward all
     * the arguments to the implementation
     * \param args The arguments to forward
     */
    dyn_basic_pmp_h_expr(size_t c1, size_t c2) : impl(c1, c2){
        //Nothing else to init
    }

    /*!
     * \brief The result type for a given sub expression type
     * \tparam A The sub epxpression type
     */
    template <typename A>
    using result_type = detail::expr_result_t<this_type, A>;

    /*!
     * \brief Apply the expression
     * \param a The sub expression
     * \param c The expression where to store the results
     */
    template <typename A, typename C>
    void apply(A&& a, C&& c) const {
        static_assert(is_etl_expr<A>::value && is_etl_expr<C>::value, "Probabilistic Max Pooling only supported for ETL expressions");

        impl.apply(
            make_temporary(std::forward<A>(a)),
            std::forward<C>(c));
    }

    /*!
     * \brief Returns a textual representation of the operation
     * \return a textual representation of the operation
     */
    static std::string desc() noexcept {
        return "dyn_pmp_h";
    }

    /*!
     * \brief Returns the DDth dimension of the expression
     * \tparam A The sub expression type
     * \tparam DD The dimension to get
     * \return the DDth dimension of the expression
     */
    template <typename A, std::size_t DD>
    static constexpr std::size_t dim() {
        return decay_traits<A>::template dim<DD>();
    }

    /*!
     * \brief Returns the dth dimension of the expression
     * \param a The sub expression
     * \param d The dimension to get
     * \return the dth dimension of the expression
     */
    template <typename A>
    static std::size_t dim(const A& a, std::size_t d) {
        return etl_traits<A>::dim(a, d);
    }

    /*!
     * \brief Returns the size of the expression
     * \param a The sub expression
     * \return the size of the expression
     */
    template <typename A>
    static std::size_t size(const A& a) {
        return etl::size(a);
    }

    /*!
     * \brief Returns the size of the expression
     * \return the size of the expression
     */
    template <typename A>
    static constexpr std::size_t size() {
        return etl::decay_traits<A>::size();
    }

    /*!
     * \brief Returns the storage order of the expression.
     * \return the storage order of the expression
     */
    template <typename A>
    static constexpr etl::order order() {
        return decay_traits<A>::storage_order;
    }

    /*!
     * \brief Returns the number of dimensions of the expression
     * \return the number of dimensions of the expression
     */
    static constexpr std::size_t dimensions() {
        return D;
    }
};

/*!
 * \brief Expression for 2D FFT
 */
template <typename T, size_t D>
using dyn_pmp_h_2d_expr = dyn_basic_pmp_h_expr<T, D, detail::dyn_pmp_2d_impl<D>>;

} //end of namespace etl
<commit_msg>Cleanup<commit_after>//=======================================================================
// Copyright (c) 2014-2016 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

/*!
 * \file
 * \brief Contains the probabilistic pooling expressions.
*/

#pragma once

//Get the implementations
#include "etl/impl/prob_pooling.hpp"

namespace etl {

/*!
 * \brief A configurable expression for FFT
 * \tparam T The value type
 * \tparam D The number of dimensions of the FFT
 * \tparam Impl The implementation to use
 */
template <typename T, size_t D, size_t C1, size_t C2, typename Impl>
struct basic_pmp_h_expr : impl_expr<basic_pmp_h_expr<T, D, C1, C2, Impl>> {
    using this_type  = basic_pmp_h_expr<T, D, C1, C2, Impl>; ///< The type of this expression
    using value_type = T;                          ///< The value type

    static constexpr bool is_gpu = false; ///< Indicate if the expression is executed on GPU

    /*!
     * \brief The result type for a given sub expression type
     * \tparam A The sub epxpression type
     */
    template <typename A>
    using result_type = detail::expr_result_t<this_type, A>;

    /*!
     * \brief Apply the expression
     * \param a The sub expression
     * \param c The expression where to store the results
     */
    template <typename A, typename C>
    static void apply(A&& a, C&& c) {
        static_assert(is_etl_expr<A>::value && is_etl_expr<C>::value, "Probabilistic Max Pooling only supported for ETL expressions");

        Impl::apply(
            make_temporary(std::forward<A>(a)),
            std::forward<C>(c));
    }

    /*!
     * \brief Returns a textual representation of the operation
     * \return a textual representation of the operation
     */
    static std::string desc() noexcept {
        return "pmp_h";
    }

    /*!
     * \brief Returns the DDth dimension of the expression
     * \tparam A The sub expression type
     * \tparam DD The dimension to get
     * \return the DDth dimension of the expression
     */
    template <typename A, std::size_t DD>
    static constexpr std::size_t dim() {
        return
            DD == 0 ? decay_traits<A>::template dim<0>() / C1
                    : decay_traits<A>::template dim<1>() / C2;
    }

    /*!
     * \brief Returns the dth dimension of the expression
     * \param a The sub expression
     * \param d The dimension to get
     * \return the dth dimension of the expression
     */
    template <typename A>
    static std::size_t dim(const A& a, std::size_t d) {
        return
            d == 0 ? decay_traits<A>::dim(a, 0) / C1
                    : decay_traits<A>::dim(a, 1) / C2;
    }

    /*!
     * \brief Returns the size of the expression
     * \param a The sub expression
     * \return the size of the expression
     */
    template <typename A>
    static std::size_t size(const A& a) {
        return etl::size(a) / (C1 * C2);
    }

    /*!
     * \brief Returns the size of the expression
     * \return the size of the expression
     */
    template <typename A>
    static constexpr std::size_t size() {
        return etl::decay_traits<A>::size() / (C1 * C2);
    }

    /*!
     * \brief Returns the storage order of the expression.
     * \return the storage order of the expression
     */
    template <typename A>
    static constexpr etl::order order() {
        return decay_traits<A>::storage_order;
    }

    /*!
     * \brief Returns the number of dimensions of the expression
     * \return the number of dimensions of the expression
     */
    static constexpr std::size_t dimensions() {
        return D;
    }
};

/*!
 * \brief Expression for 2D FFT
 */
template <typename T, size_t D, size_t C1, size_t C2>
using pmp_h_2d_expr = basic_pmp_h_expr<T, D, 1, 1, detail::pmp_2d_impl<D, C1, C2>>;

/*!
 * \brief A configurable expression for FFT
 * \tparam T The value type
 * \tparam D The number of dimensions of the FFT
 * \tparam Impl The implementation to use
 */
template <typename T, std::size_t D, typename Impl>
struct dyn_basic_pmp_h_expr : impl_expr<dyn_basic_pmp_h_expr<T, D, Impl>> {
    using this_type  = dyn_basic_pmp_h_expr<T, D, Impl>; ///< The type of this expression
    using value_type = T;                          ///< The value type

    static constexpr bool is_gpu = false; ///< Indicate if the expression is executed on GPU

    Impl impl; ///< The implementation operator

    /*!
     * \brief Construct a new dyn_basic_pmp_h_expr and forward all
     * the arguments to the implementation
     * \param args The arguments to forward
     */
    dyn_basic_pmp_h_expr(size_t c1, size_t c2) : impl(c1, c2){
        //Nothing else to init
    }

    /*!
     * \brief The result type for a given sub expression type
     * \tparam A The sub epxpression type
     */
    template <typename A>
    using result_type = detail::expr_result_t<this_type, A>;

    /*!
     * \brief Apply the expression
     * \param a The sub expression
     * \param c The expression where to store the results
     */
    template <typename A, typename C>
    void apply(A&& a, C&& c) const {
        static_assert(is_etl_expr<A>::value && is_etl_expr<C>::value, "Probabilistic Max Pooling only supported for ETL expressions");

        impl.apply(
            make_temporary(std::forward<A>(a)),
            std::forward<C>(c));
    }

    /*!
     * \brief Returns a textual representation of the operation
     * \return a textual representation of the operation
     */
    static std::string desc() noexcept {
        return "dyn_pmp_h";
    }

    /*!
     * \brief Returns the DDth dimension of the expression
     * \tparam A The sub expression type
     * \tparam DD The dimension to get
     * \return the DDth dimension of the expression
     */
    template <typename A, std::size_t DD>
    static constexpr std::size_t dim() {
        return decay_traits<A>::template dim<DD>();
    }

    /*!
     * \brief Returns the dth dimension of the expression
     * \param a The sub expression
     * \param d The dimension to get
     * \return the dth dimension of the expression
     */
    template <typename A>
    static std::size_t dim(const A& a, std::size_t d) {
        return etl_traits<A>::dim(a, d);
    }

    /*!
     * \brief Returns the size of the expression
     * \param a The sub expression
     * \return the size of the expression
     */
    template <typename A>
    static std::size_t size(const A& a) {
        return etl::size(a);
    }

    /*!
     * \brief Returns the size of the expression
     * \return the size of the expression
     */
    template <typename A>
    static constexpr std::size_t size() {
        return etl::decay_traits<A>::size();
    }

    /*!
     * \brief Returns the storage order of the expression.
     * \return the storage order of the expression
     */
    template <typename A>
    static constexpr etl::order order() {
        return decay_traits<A>::storage_order;
    }

    /*!
     * \brief Returns the number of dimensions of the expression
     * \return the number of dimensions of the expression
     */
    static constexpr std::size_t dimensions() {
        return D;
    }
};

/*!
 * \brief Expression for 2D FFT
 */
template <typename T, size_t D>
using dyn_pmp_h_2d_expr = dyn_basic_pmp_h_expr<T, D, detail::dyn_pmp_2d_impl<D>>;

} //end of namespace etl
<|endoftext|>


<commit_before>// Copyright 2019 Open Source Robotics Foundation, Inc.
//
// 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.

#include <gtest/gtest.h>
#include "rosidl_generator_cpp/msg/empty.hpp"
#include "rosidl_generator_cpp/msg/strings.hpp"
#include "rosidl_generator_cpp/srv/empty.hpp"

using rosidl_generator_traits::is_message;
using rosidl_generator_traits::is_service;
using rosidl_generator_traits::is_service_request;
using rosidl_generator_traits::is_service_response;

// Empty testing struct
struct Message {};

// Empty testing struct, with template instantiation
struct Message2 {};

template<>
struct rosidl_generator_traits::is_message<Message2>: std::true_type {};

TEST(Test_rosidl_generator_traits, is_message) {
  // A message is not a service
  using Empty = rosidl_generator_cpp::msg::Empty;
  EXPECT_TRUE(is_message<Empty>());
  EXPECT_FALSE(is_service<Empty>());
  EXPECT_FALSE(is_service_request<Empty>());
  EXPECT_FALSE(is_service_response<Empty>());

  // A message is not a service
  using Strings = rosidl_generator_cpp::msg::Strings;
  EXPECT_TRUE(is_message<Strings>());
  EXPECT_FALSE(is_service<Strings>());
  EXPECT_FALSE(is_service_request<Strings>());
  EXPECT_FALSE(is_service_response<Strings>());

  // Other datatypes should have is_message == false
  EXPECT_FALSE(is_message<double>());
  EXPECT_FALSE(is_message<Message>());

  // Unless the template has been specifically instantiated for the type
  EXPECT_TRUE(is_message<Message2>());
}

TEST(Test_rosidl_generator_traits, is_service) {
  using Service = rosidl_generator_cpp::srv::Empty;
  using ServiceReq = Service::Request;
  using ServiceResp = Service::Response;

  EXPECT_TRUE(is_service<Service>());
  EXPECT_FALSE(is_message<Service>());
  EXPECT_FALSE(is_service_request<Service>());
  EXPECT_FALSE(is_service_response<Service>());

  // Requests are additionally messages
  EXPECT_FALSE(is_service<ServiceReq>());
  EXPECT_TRUE(is_message<ServiceReq>());
  EXPECT_TRUE(is_service_request<ServiceReq>());
  EXPECT_FALSE(is_service_response<ServiceReq>());

  // Responses are additionally messages
  EXPECT_FALSE(is_service<ServiceResp>());
  EXPECT_TRUE(is_message<ServiceResp>());
  EXPECT_FALSE(is_service_request<ServiceResp>());
  EXPECT_TRUE(is_service_response<ServiceResp>());
}
<commit_msg>Declaring is_message in namespace rosidl_generator_traits. (#512)<commit_after>// Copyright 2019 Open Source Robotics Foundation, Inc.
//
// 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.

#include <gtest/gtest.h>
#include "rosidl_generator_cpp/msg/empty.hpp"
#include "rosidl_generator_cpp/msg/strings.hpp"
#include "rosidl_generator_cpp/srv/empty.hpp"

using rosidl_generator_traits::is_message;
using rosidl_generator_traits::is_service;
using rosidl_generator_traits::is_service_request;
using rosidl_generator_traits::is_service_response;

// Empty testing struct
struct Message {};

// Empty testing struct, with template instantiation
struct Message2 {};

namespace rosidl_generator_traits
{

template<>
struct is_message<Message2>: std::true_type {};

}  // namespace rosidl_generator_traits

TEST(Test_rosidl_generator_traits, is_message) {
  // A message is not a service
  using Empty = rosidl_generator_cpp::msg::Empty;
  EXPECT_TRUE(is_message<Empty>());
  EXPECT_FALSE(is_service<Empty>());
  EXPECT_FALSE(is_service_request<Empty>());
  EXPECT_FALSE(is_service_response<Empty>());

  // A message is not a service
  using Strings = rosidl_generator_cpp::msg::Strings;
  EXPECT_TRUE(is_message<Strings>());
  EXPECT_FALSE(is_service<Strings>());
  EXPECT_FALSE(is_service_request<Strings>());
  EXPECT_FALSE(is_service_response<Strings>());

  // Other datatypes should have is_message == false
  EXPECT_FALSE(is_message<double>());
  EXPECT_FALSE(is_message<Message>());

  // Unless the template has been specifically instantiated for the type
  EXPECT_TRUE(is_message<Message2>());
}

TEST(Test_rosidl_generator_traits, is_service) {
  using Service = rosidl_generator_cpp::srv::Empty;
  using ServiceReq = Service::Request;
  using ServiceResp = Service::Response;

  EXPECT_TRUE(is_service<Service>());
  EXPECT_FALSE(is_message<Service>());
  EXPECT_FALSE(is_service_request<Service>());
  EXPECT_FALSE(is_service_response<Service>());

  // Requests are additionally messages
  EXPECT_FALSE(is_service<ServiceReq>());
  EXPECT_TRUE(is_message<ServiceReq>());
  EXPECT_TRUE(is_service_request<ServiceReq>());
  EXPECT_FALSE(is_service_response<ServiceReq>());

  // Responses are additionally messages
  EXPECT_FALSE(is_service<ServiceResp>());
  EXPECT_TRUE(is_message<ServiceResp>());
  EXPECT_FALSE(is_service_request<ServiceResp>());
  EXPECT_TRUE(is_service_response<ServiceResp>());
}
<|endoftext|>


<commit_before>#include "SoapyAudio.hpp"

#ifdef USE_HAMLIB
RigThread::RigThread() {
    terminated.store(true);
}

RigThread::~RigThread() {

}

#ifdef __APPLE__
void *RigThread::threadMain() {
    terminated.store(false);
    run();
    return this;
};

void *RigThread::pthread_helper(void *context) {
    return ((RigThread *) context)->threadMain();
};
#else
void RigThread::threadMain() {
    terminated.store(false);
    run();
};
#endif

void RigThread::setup(rig_model_t rig_model, std::string rig_file, int serial_rate) {
    rigModel = rig_model;
    rigFile = rig_file;
    serialRate = serial_rate;
};

void RigThread::run() {
    int retcode, status;

    SoapySDR_log(SOAPY_SDR_DEBUG, "Rig thread starting.");

    rig = rig_init(rigModel);
	strncpy(rig->state.rigport.pathname, rigFile.c_str(), FILPATHLEN - 1);
	rig->state.rigport.parm.serial.rate = serialRate;
	retcode = rig_open(rig);
	char *info_buf = (char *)rig_get_info(rig);
    SoapySDR_logf(SOAPY_SDR_DEBUG, "Rig Info: %s", info_buf);

    while (!terminated.load()) {
        std::this_thread::sleep_for(std::chrono::milliseconds(150));
        if (freqChanged.load()) {
            status = rig_get_freq(rig, RIG_VFO_CURR, &freq);
            if (freq != newFreq) {
                freq = newFreq;
                rig_set_freq(rig, RIG_VFO_CURR, freq);
                SoapySDR_logf(SOAPY_SDR_DEBUG, "Set Rig Freq: %f", newFreq);
            }

            freqChanged.store(false);
        } else {
            status = rig_get_freq(rig, RIG_VFO_CURR, &freq);
        }

        SoapySDR_logf(SOAPY_SDR_DEBUG, "Rig Freq: %f", freq);
    }

    rig_close(rig);
    rig_cleanup(rig);

    SoapySDR_log(SOAPY_SDR_DEBUG, "Rig thread exiting.");
};

freq_t RigThread::getFrequency() {
    if (freqChanged.load()) {
        return newFreq;
    } else {
        return freq;
    }
}

void RigThread::setFrequency(freq_t new_freq) {
    newFreq = new_freq;
    freqChanged.store(true);
}

void RigThread::terminate() {
    terminated.store(true);
};

bool RigThread::isTerminated() {
    return terminated.load();
}
#endif<commit_msg>RigThread error checking<commit_after>#include "SoapyAudio.hpp"

#ifdef USE_HAMLIB
RigThread::RigThread() {
    terminated.store(true);
}

RigThread::~RigThread() {

}

#ifdef __APPLE__
void *RigThread::threadMain() {
    terminated.store(false);
    run();
    return this;
};

void *RigThread::pthread_helper(void *context) {
    return ((RigThread *) context)->threadMain();
};
#else
void RigThread::threadMain() {
    terminated.store(false);
    run();
};
#endif

void RigThread::setup(rig_model_t rig_model, std::string rig_file, int serial_rate) {
    rigModel = rig_model;
    rigFile = rig_file;
    serialRate = serial_rate;
};

void RigThread::run() {
    int retcode, status;

    SoapySDR_log(SOAPY_SDR_DEBUG, "Rig thread starting.");

    rig = rig_init(rigModel);
	strncpy(rig->state.rigport.pathname, rigFile.c_str(), FILPATHLEN - 1);
	rig->state.rigport.parm.serial.rate = serialRate;
	retcode = rig_open(rig);

    if (retcode != 0) {
        SoapySDR_log(SOAPY_SDR_ERROR, "Rig failed to init.");
        terminated.store(true);
        return;
    }

	char *info_buf = (char *)rig_get_info(rig);
    SoapySDR_logf(SOAPY_SDR_DEBUG, "Rig Info: %s", info_buf);

    while (!terminated.load()) {
        std::this_thread::sleep_for(std::chrono::milliseconds(150));
        if (freqChanged.load()) {
            status = rig_get_freq(rig, RIG_VFO_CURR, &freq);
            if (freq != newFreq) {
                freq = newFreq;
                rig_set_freq(rig, RIG_VFO_CURR, freq);
                SoapySDR_logf(SOAPY_SDR_DEBUG, "Set Rig Freq: %f", newFreq);
            }

            freqChanged.store(false);
        } else {
            status = rig_get_freq(rig, RIG_VFO_CURR, &freq);
        }

        SoapySDR_logf(SOAPY_SDR_DEBUG, "Rig Freq: %f", freq);
    }

    rig_close(rig);
    rig_cleanup(rig);

    SoapySDR_log(SOAPY_SDR_DEBUG, "Rig thread exiting.");
};

freq_t RigThread::getFrequency() {
    if (freqChanged.load()) {
        return newFreq;
    } else {
        return freq;
    }
}

void RigThread::setFrequency(freq_t new_freq) {
    newFreq = new_freq;
    freqChanged.store(true);
}

void RigThread::terminate() {
    terminated.store(true);
};

bool RigThread::isTerminated() {
    return terminated.load();
}
#endif<|endoftext|>


<commit_before>// File:        altorenderer.cpp
// Description: ALTO rendering interface
// Author:      Jake Sebright

// (C) Copyright 2018
// 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.

#include <memory>
#include <sstream>  // for std::stringstream
#include "baseapi.h"
#ifdef _WIN32
# include "host.h"    // windows.h for MultiByteToWideChar, ...
#endif
#include "renderer.h"
#include "strngs.h" // for STRING

namespace tesseract {

/// Add coordinates to specified TextBlock, TextLine or String bounding box.
/// Add word confidence if adding to a String bounding box.
///
static void AddBoxToAlto(const ResultIterator* it, PageIteratorLevel level,
                         std::stringstream& alto_str) {
  int left, top, right, bottom;
  it->BoundingBox(level, &left, &top, &right, &bottom);

  int hpos = left;
  int vpos = top;
  int height = bottom - top;
  int width = right - left;

  alto_str << " HPOS=\"" << hpos << "\"";
  alto_str << " VPOS=\"" << vpos << "\"";
  alto_str << " WIDTH=\"" << width << "\"";
  alto_str << " HEIGHT=\"" << height << "\"";

  if (level == RIL_WORD) {
    int wc = it->Confidence(RIL_WORD);
    alto_str << " WC=\"0." << wc << "\"";
  } else {
    alto_str << ">";
  }
}

///
/// Append the ALTO XML for the beginning of the document
///
bool TessAltoRenderer::BeginDocumentHandler() {
  AppendString(
      "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
      "<alto xmlns=\"http://www.loc.gov/standards/alto/ns-v3#\" "
      "xmlns:xlink=\"http://www.w3.org/1999/xlink\" "
      "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
      "xsi:schemaLocation=\"http://www.loc.gov/standards/alto/ns-v3# "
      "http://www.loc.gov/alto/v3/alto-3-0.xsd\">\n"
      "\t<Description>\n"
      "\t\t<MeasurementUnit>pixel</MeasurementUnit>\n"
      "\t\t<sourceImageInformation>\n"
      "\t\t\t<fileName>");

  AppendString(title());

  AppendString(
      "</fileName>\n"
      "\t\t</sourceImageInformation>\n"
      "\t\t<OCRProcessing ID=\"OCR_0\">\n"
      "\t\t\t<ocrProcessingStep>\n"
      "\t\t\t\t<processingSoftware>\n"
      "\t\t\t\t\t<softwareName>tesseract ");
  AppendString(TessBaseAPI::Version());
  AppendString(
      "</softwareName>\n"
      "\t\t\t\t</processingSoftware>\n"
      "\t\t\t</ocrProcessingStep>\n"
      "\t\t</OCRProcessing>\n"
      "\t</Description>\n"
      "\t<Layout>\n");

  return true;
}

///
/// Append the ALTO XML for the layout of the image
///
bool TessAltoRenderer::AddImageHandler(TessBaseAPI* api) {
  const std::unique_ptr<const char[]> text(api->GetAltoText(imagenum()));
  if (text == nullptr) return false;

  AppendString(text.get());

  return true;
}

///
/// Append the ALTO XML for the end of the document
///
bool TessAltoRenderer::EndDocumentHandler() {
  AppendString("\t</Layout>\n</alto>\n");

  return true;
}

TessAltoRenderer::TessAltoRenderer(const char* outputbase)
    : TessResultRenderer(outputbase, "xml") {}

///
/// Make an XML-formatted string with ALTO markup from the internal
/// data structures.
///
char* TessBaseAPI::GetAltoText(int page_number) {
  return GetAltoText(nullptr, page_number);
}

///
/// Make an XML-formatted string with ALTO markup from the internal
/// data structures.
///
char* TessBaseAPI::GetAltoText(ETEXT_DESC* monitor, int page_number) {
  if (tesseract_ == nullptr || (page_res_ == nullptr && Recognize(monitor) < 0))
    return nullptr;

  int lcnt = 0, bcnt = 0, wcnt = 0;

  if (input_file_ == nullptr) SetInputName(nullptr);

#ifdef _WIN32
  // convert input name from ANSI encoding to utf-8
  int str16_len =
      MultiByteToWideChar(CP_ACP, 0, input_file_->c_str(), -1, nullptr, 0);
  wchar_t* uni16_str = new WCHAR[str16_len];
  str16_len = MultiByteToWideChar(CP_ACP, 0, input_file_->c_str(), -1,
                                  uni16_str, str16_len);
  int utf8_len = WideCharToMultiByte(CP_UTF8, 0, uni16_str, str16_len, nullptr,
                                     0, nullptr, nullptr);
  char* utf8_str = new char[utf8_len];
  WideCharToMultiByte(CP_UTF8, 0, uni16_str, str16_len, utf8_str, utf8_len,
                      nullptr, nullptr);
  *input_file_ = utf8_str;
  delete[] uni16_str;
  delete[] utf8_str;
#endif

  std::stringstream alto_str;
  alto_str
      << "\t\t<Page WIDTH=\"" << rect_width_ << "\" HEIGHT=\""
      << rect_height_
      << "\" PHYSICAL_IMG_NR=\"" << page_number << "\""
      << " ID=\"page_" << page_number << "\">\n"
      << "\t\t\t<PrintSpace HPOS=\"0\" VPOS=\"0\""
      << " WIDTH=\"" << rect_width_ << "\""
      << " HEIGHT=\"" << rect_height_ << "\">\n";

  ResultIterator* res_it = GetIterator();
  while (!res_it->Empty(RIL_BLOCK)) {
    if (res_it->Empty(RIL_WORD)) {
      res_it->Next(RIL_WORD);
      continue;
    }

    if (res_it->IsAtBeginningOf(RIL_BLOCK)) {
      alto_str << "\t\t\t\t<TextBlock ID=\"block_" << bcnt << "\"";
      AddBoxToAlto(res_it, RIL_BLOCK, alto_str);
      alto_str << "\n";
    }

    if (res_it->IsAtBeginningOf(RIL_TEXTLINE)) {
      alto_str << "\t\t\t\t\t<TextLine ID=\"line_" << lcnt << "\"";
      AddBoxToAlto(res_it, RIL_TEXTLINE, alto_str);
      alto_str << "\n";
    }

    alto_str << "\t\t\t\t\t\t<String ID=\"string_" << wcnt << "\"";
    AddBoxToAlto(res_it, RIL_WORD, alto_str);
    alto_str << " CONTENT=\"";

    bool last_word_in_line = res_it->IsAtFinalElement(RIL_TEXTLINE, RIL_WORD);
    bool last_word_in_block = res_it->IsAtFinalElement(RIL_BLOCK, RIL_WORD);

    int left, top, right, bottom;
    res_it->BoundingBox(RIL_WORD, &left, &top, &right, &bottom);

    do {
      const std::unique_ptr<const char[]> grapheme(
          res_it->GetUTF8Text(RIL_SYMBOL));
      if (grapheme && grapheme[0] != 0) {
        alto_str << HOcrEscape(grapheme.get()).c_str();
      }
      res_it->Next(RIL_SYMBOL);
    } while (!res_it->Empty(RIL_BLOCK) && !res_it->IsAtBeginningOf(RIL_WORD));

    alto_str << "\"/>";

    wcnt++;

    if (last_word_in_line) {
      alto_str << "\n\t\t\t\t\t</TextLine>\n";
      lcnt++;
    } else {
      int hpos = right;
      int vpos = top;
      res_it->BoundingBox(RIL_WORD, &left, &top, &right, &bottom);
      int width = left - hpos;
      alto_str << "<SP WIDTH=\"" << width << "\" VPOS=\"" << vpos
               << "\" HPOS=\"" << hpos << "\"/>\n";
    }

    if (last_word_in_block) {
      alto_str << "\t\t\t\t</TextBlock>\n";
      bcnt++;
    }
  }

  alto_str << "\t\t\t</PrintSpace>\n"
           << "\t\t</Page>\n";
  const std::string& text = alto_str.str();

  char* result = new char[text.length() + 1];
  strcpy(result, text.c_str());
  delete res_it;
  return result;
}

}  // namespace tesseract
<commit_msg>Use "C" locale for ALTO output<commit_after>// File:        altorenderer.cpp
// Description: ALTO rendering interface
// Author:      Jake Sebright

// (C) Copyright 2018
// 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.

#include <memory>
#include <sstream>  // for std::stringstream
#include "baseapi.h"
#ifdef _WIN32
# include "host.h"    // windows.h for MultiByteToWideChar, ...
#endif
#include "renderer.h"
#include "strngs.h" // for STRING

namespace tesseract {

/// Add coordinates to specified TextBlock, TextLine or String bounding box.
/// Add word confidence if adding to a String bounding box.
///
static void AddBoxToAlto(const ResultIterator* it, PageIteratorLevel level,
                         std::stringstream& alto_str) {
  int left, top, right, bottom;
  it->BoundingBox(level, &left, &top, &right, &bottom);

  int hpos = left;
  int vpos = top;
  int height = bottom - top;
  int width = right - left;

  alto_str << " HPOS=\"" << hpos << "\"";
  alto_str << " VPOS=\"" << vpos << "\"";
  alto_str << " WIDTH=\"" << width << "\"";
  alto_str << " HEIGHT=\"" << height << "\"";

  if (level == RIL_WORD) {
    int wc = it->Confidence(RIL_WORD);
    alto_str << " WC=\"0." << wc << "\"";
  } else {
    alto_str << ">";
  }
}

///
/// Append the ALTO XML for the beginning of the document
///
bool TessAltoRenderer::BeginDocumentHandler() {
  AppendString(
      "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
      "<alto xmlns=\"http://www.loc.gov/standards/alto/ns-v3#\" "
      "xmlns:xlink=\"http://www.w3.org/1999/xlink\" "
      "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
      "xsi:schemaLocation=\"http://www.loc.gov/standards/alto/ns-v3# "
      "http://www.loc.gov/alto/v3/alto-3-0.xsd\">\n"
      "\t<Description>\n"
      "\t\t<MeasurementUnit>pixel</MeasurementUnit>\n"
      "\t\t<sourceImageInformation>\n"
      "\t\t\t<fileName>");

  AppendString(title());

  AppendString(
      "</fileName>\n"
      "\t\t</sourceImageInformation>\n"
      "\t\t<OCRProcessing ID=\"OCR_0\">\n"
      "\t\t\t<ocrProcessingStep>\n"
      "\t\t\t\t<processingSoftware>\n"
      "\t\t\t\t\t<softwareName>tesseract ");
  AppendString(TessBaseAPI::Version());
  AppendString(
      "</softwareName>\n"
      "\t\t\t\t</processingSoftware>\n"
      "\t\t\t</ocrProcessingStep>\n"
      "\t\t</OCRProcessing>\n"
      "\t</Description>\n"
      "\t<Layout>\n");

  return true;
}

///
/// Append the ALTO XML for the layout of the image
///
bool TessAltoRenderer::AddImageHandler(TessBaseAPI* api) {
  const std::unique_ptr<const char[]> text(api->GetAltoText(imagenum()));
  if (text == nullptr) return false;

  AppendString(text.get());

  return true;
}

///
/// Append the ALTO XML for the end of the document
///
bool TessAltoRenderer::EndDocumentHandler() {
  AppendString("\t</Layout>\n</alto>\n");

  return true;
}

TessAltoRenderer::TessAltoRenderer(const char* outputbase)
    : TessResultRenderer(outputbase, "xml") {}

///
/// Make an XML-formatted string with ALTO markup from the internal
/// data structures.
///
char* TessBaseAPI::GetAltoText(int page_number) {
  return GetAltoText(nullptr, page_number);
}

///
/// Make an XML-formatted string with ALTO markup from the internal
/// data structures.
///
char* TessBaseAPI::GetAltoText(ETEXT_DESC* monitor, int page_number) {
  if (tesseract_ == nullptr || (page_res_ == nullptr && Recognize(monitor) < 0))
    return nullptr;

  int lcnt = 0, bcnt = 0, wcnt = 0;

  if (input_file_ == nullptr) SetInputName(nullptr);

#ifdef _WIN32
  // convert input name from ANSI encoding to utf-8
  int str16_len =
      MultiByteToWideChar(CP_ACP, 0, input_file_->c_str(), -1, nullptr, 0);
  wchar_t* uni16_str = new WCHAR[str16_len];
  str16_len = MultiByteToWideChar(CP_ACP, 0, input_file_->c_str(), -1,
                                  uni16_str, str16_len);
  int utf8_len = WideCharToMultiByte(CP_UTF8, 0, uni16_str, str16_len, nullptr,
                                     0, nullptr, nullptr);
  char* utf8_str = new char[utf8_len];
  WideCharToMultiByte(CP_UTF8, 0, uni16_str, str16_len, utf8_str, utf8_len,
                      nullptr, nullptr);
  *input_file_ = utf8_str;
  delete[] uni16_str;
  delete[] utf8_str;
#endif

  std::stringstream alto_str;
  // Use "C" locale (needed for int values larger than 999).
  alto_str.imbue(std::locale::classic());
  alto_str
      << "\t\t<Page WIDTH=\"" << rect_width_ << "\" HEIGHT=\""
      << rect_height_
      << "\" PHYSICAL_IMG_NR=\"" << page_number << "\""
      << " ID=\"page_" << page_number << "\">\n"
      << "\t\t\t<PrintSpace HPOS=\"0\" VPOS=\"0\""
      << " WIDTH=\"" << rect_width_ << "\""
      << " HEIGHT=\"" << rect_height_ << "\">\n";

  ResultIterator* res_it = GetIterator();
  while (!res_it->Empty(RIL_BLOCK)) {
    if (res_it->Empty(RIL_WORD)) {
      res_it->Next(RIL_WORD);
      continue;
    }

    if (res_it->IsAtBeginningOf(RIL_BLOCK)) {
      alto_str << "\t\t\t\t<TextBlock ID=\"block_" << bcnt << "\"";
      AddBoxToAlto(res_it, RIL_BLOCK, alto_str);
      alto_str << "\n";
    }

    if (res_it->IsAtBeginningOf(RIL_TEXTLINE)) {
      alto_str << "\t\t\t\t\t<TextLine ID=\"line_" << lcnt << "\"";
      AddBoxToAlto(res_it, RIL_TEXTLINE, alto_str);
      alto_str << "\n";
    }

    alto_str << "\t\t\t\t\t\t<String ID=\"string_" << wcnt << "\"";
    AddBoxToAlto(res_it, RIL_WORD, alto_str);
    alto_str << " CONTENT=\"";

    bool last_word_in_line = res_it->IsAtFinalElement(RIL_TEXTLINE, RIL_WORD);
    bool last_word_in_block = res_it->IsAtFinalElement(RIL_BLOCK, RIL_WORD);

    int left, top, right, bottom;
    res_it->BoundingBox(RIL_WORD, &left, &top, &right, &bottom);

    do {
      const std::unique_ptr<const char[]> grapheme(
          res_it->GetUTF8Text(RIL_SYMBOL));
      if (grapheme && grapheme[0] != 0) {
        alto_str << HOcrEscape(grapheme.get()).c_str();
      }
      res_it->Next(RIL_SYMBOL);
    } while (!res_it->Empty(RIL_BLOCK) && !res_it->IsAtBeginningOf(RIL_WORD));

    alto_str << "\"/>";

    wcnt++;

    if (last_word_in_line) {
      alto_str << "\n\t\t\t\t\t</TextLine>\n";
      lcnt++;
    } else {
      int hpos = right;
      int vpos = top;
      res_it->BoundingBox(RIL_WORD, &left, &top, &right, &bottom);
      int width = left - hpos;
      alto_str << "<SP WIDTH=\"" << width << "\" VPOS=\"" << vpos
               << "\" HPOS=\"" << hpos << "\"/>\n";
    }

    if (last_word_in_block) {
      alto_str << "\t\t\t\t</TextBlock>\n";
      bcnt++;
    }
  }

  alto_str << "\t\t\t</PrintSpace>\n"
           << "\t\t</Page>\n";
  const std::string& text = alto_str.str();

  char* result = new char[text.length() + 1];
  strcpy(result, text.c_str());
  delete res_it;
  return result;
}

}  // namespace tesseract
<|endoftext|>


<commit_before>#include "scanscalar.h"
#include "scanner.h"
#include "exp.h"
#include "exceptions.h"
#include "token.h"

namespace YAML
{
	// ScanScalar
	// . This is where the scalar magic happens.
	//
	// . We do the scanning in three phases:
	//   1. Scan until newline
	//   2. Eat newline
	//   3. Scan leading blanks.
	//
	// . Depending on the parameters given, we store or stop
	//   and different places in the above flow.
	std::string ScanScalar(Stream& INPUT, ScanScalarParams& params)
	{
		bool foundNonEmptyLine = false;
		bool emptyLine = false, moreIndented = false;
		std::string scalar;
		params.leadingSpaces = false;

		while(INPUT) {
			// ********************************
			// Phase #1: scan until line ending
			while(!params.end.Matches(INPUT) && !Exp::Break.Matches(INPUT)) {
				if(INPUT.peek() == EOF)
					break;

				// document indicator?
				if(INPUT.column == 0 && Exp::DocIndicator.Matches(INPUT)) {
					if(params.onDocIndicator == BREAK)
						break;
					else if(params.onDocIndicator == THROW)
						throw IllegalDocIndicator();
				}

				foundNonEmptyLine = true;

				// escaped newline? (only if we're escaping on slash)
				if(params.escape == '\\' && Exp::EscBreak.Matches(INPUT)) {
					int n = Exp::EscBreak.Match(INPUT);
					INPUT.eat(n);
					continue;
				}

				// escape this?
				if(INPUT.peek() == params.escape) {
					scalar += Exp::Escape(INPUT);
					continue;
				}

				// otherwise, just add the damn character
				scalar += INPUT.get();
			}

			// eof? if we're looking to eat something, then we throw
			if(INPUT.peek() == EOF) {
				if(params.eatEnd)
					throw IllegalEOF();
				break;
			}

			// doc indicator?
			if(params.onDocIndicator == BREAK && INPUT.column == 0 && Exp::DocIndicator.Matches(INPUT))
				break;

			// are we done via character match?
			int n = params.end.Match(INPUT);
			if(n >= 0) {
				if(params.eatEnd)
					INPUT.eat(n);
				break;
			}

			// ********************************
			// Phase #2: eat line ending
			n = Exp::Break.Match(INPUT);
			INPUT.eat(n);

			// ********************************
			// Phase #3: scan initial spaces

			// first the required indentation
			while(INPUT.peek() == ' ' && (INPUT.column < params.indent || (params.detectIndent && !foundNonEmptyLine)))
				INPUT.eat(1);

			// update indent if we're auto-detecting
			if(params.detectIndent && !foundNonEmptyLine)
				params.indent = std::max(params.indent, INPUT.column);

			// and then the rest of the whitespace
			while(Exp::Blank.Matches(INPUT)) {
				// we check for tabs that masquerade as indentation
				if(INPUT.peek() == '\t'&& INPUT.column < params.indent && params.onTabInIndentation == THROW)
					throw IllegalTabInIndentation();

				if(!params.eatLeadingWhitespace)
					break;

				INPUT.eat(1);
			}

			// was this an empty line?
			bool nextEmptyLine = Exp::Break.Matches(INPUT);
			bool nextMoreIndented = (INPUT.peek() == ' ');

			// TODO: for block scalars, we always start with a newline, so we should fold OR keep that

			if(params.fold && !emptyLine && !nextEmptyLine && !moreIndented && !nextMoreIndented)
				scalar += " ";
			else
				scalar += "\n";

			emptyLine = nextEmptyLine;
			moreIndented = nextMoreIndented;

			// are we done via indentation?
			if(!emptyLine && INPUT.column < params.indent) {
				params.leadingSpaces = true;
				break;
			}
		}

		// post-processing
		if(params.trimTrailingSpaces) {
			unsigned pos = scalar.find_last_not_of(' ');
			if(pos < scalar.size())
				scalar.erase(pos + 1);
		}

		if(params.chomp <= 0) {
			unsigned pos = scalar.find_last_not_of('\n');
			if(params.chomp == 0 && pos + 1 < scalar.size())
				scalar.erase(pos + 2);
			else if(params.chomp == -1 && pos < scalar.size())
				scalar.erase(pos + 1);
		}

		return scalar;
	}
}
<commit_msg>Fixed opening newline bug for block scalars.<commit_after>#include "scanscalar.h"
#include "scanner.h"
#include "exp.h"
#include "exceptions.h"
#include "token.h"

namespace YAML
{
	// ScanScalar
	// . This is where the scalar magic happens.
	//
	// . We do the scanning in three phases:
	//   1. Scan until newline
	//   2. Eat newline
	//   3. Scan leading blanks.
	//
	// . Depending on the parameters given, we store or stop
	//   and different places in the above flow.
	std::string ScanScalar(Stream& INPUT, ScanScalarParams& params)
	{
		bool foundNonEmptyLine = false, pastOpeningBreak = false;
		bool emptyLine = false, moreIndented = false;
		std::string scalar;
		params.leadingSpaces = false;

		while(INPUT) {
			// ********************************
			// Phase #1: scan until line ending
			while(!params.end.Matches(INPUT) && !Exp::Break.Matches(INPUT)) {
				if(INPUT.peek() == EOF)
					break;

				// document indicator?
				if(INPUT.column == 0 && Exp::DocIndicator.Matches(INPUT)) {
					if(params.onDocIndicator == BREAK)
						break;
					else if(params.onDocIndicator == THROW)
						throw IllegalDocIndicator();
				}

				foundNonEmptyLine = true;
				pastOpeningBreak = true;

				// escaped newline? (only if we're escaping on slash)
				if(params.escape == '\\' && Exp::EscBreak.Matches(INPUT)) {
					int n = Exp::EscBreak.Match(INPUT);
					INPUT.eat(n);
					continue;
				}

				// escape this?
				if(INPUT.peek() == params.escape) {
					scalar += Exp::Escape(INPUT);
					continue;
				}

				// otherwise, just add the damn character
				scalar += INPUT.get();
			}

			// eof? if we're looking to eat something, then we throw
			if(INPUT.peek() == EOF) {
				if(params.eatEnd)
					throw IllegalEOF();
				break;
			}

			// doc indicator?
			if(params.onDocIndicator == BREAK && INPUT.column == 0 && Exp::DocIndicator.Matches(INPUT))
				break;

			// are we done via character match?
			int n = params.end.Match(INPUT);
			if(n >= 0) {
				if(params.eatEnd)
					INPUT.eat(n);
				break;
			}

			// ********************************
			// Phase #2: eat line ending
			n = Exp::Break.Match(INPUT);
			INPUT.eat(n);

			// ********************************
			// Phase #3: scan initial spaces

			// first the required indentation
			while(INPUT.peek() == ' ' && (INPUT.column < params.indent || (params.detectIndent && !foundNonEmptyLine)))
				INPUT.eat(1);

			// update indent if we're auto-detecting
			if(params.detectIndent && !foundNonEmptyLine)
				params.indent = std::max(params.indent, INPUT.column);

			// and then the rest of the whitespace
			while(Exp::Blank.Matches(INPUT)) {
				// we check for tabs that masquerade as indentation
				if(INPUT.peek() == '\t'&& INPUT.column < params.indent && params.onTabInIndentation == THROW)
					throw IllegalTabInIndentation();

				if(!params.eatLeadingWhitespace)
					break;

				INPUT.eat(1);
			}

			// was this an empty line?
			bool nextEmptyLine = Exp::Break.Matches(INPUT);
			bool nextMoreIndented = (INPUT.peek() == ' ');

			// for block scalars, we always start with a newline, so we should ignore it (not fold or keep)
			if(pastOpeningBreak) {
				if(params.fold && !emptyLine && !nextEmptyLine && !moreIndented && !nextMoreIndented)
					scalar += " ";
				else
					scalar += "\n";
			}

			emptyLine = nextEmptyLine;
			moreIndented = nextMoreIndented;
			pastOpeningBreak = true;

			// are we done via indentation?
			if(!emptyLine && INPUT.column < params.indent) {
				params.leadingSpaces = true;
				break;
			}
		}

		// post-processing
		if(params.trimTrailingSpaces) {
			unsigned pos = scalar.find_last_not_of(' ');
			if(pos < scalar.size())
				scalar.erase(pos + 1);
		}

		if(params.chomp <= 0) {
			unsigned pos = scalar.find_last_not_of('\n');
			if(params.chomp == 0 && pos + 1 < scalar.size())
				scalar.erase(pos + 2);
			else if(params.chomp == -1 && pos < scalar.size())
				scalar.erase(pos + 1);
		}

		return scalar;
	}
}
<|endoftext|>


<commit_before>#ifndef KGR_KANGARU_INCLUDE_KANGARU_DETAIL_SERVICE_MAP_HPP
#define KGR_KANGARU_INCLUDE_KANGARU_DETAIL_SERVICE_MAP_HPP

#include "traits.hpp"

namespace kgr {

/*
 * This class is the type when referring to a group of maps.
 * This can be used with kgr::AutoCall and mapped operator services.
 */
template<typename...>
struct Map {};

/*
 * This is the type you receive in a service_map function.
 * This was previously kgr::Map in kangaru 3.x.y
 */
template<typename = void>
struct map_t {};

namespace detail {

/*
 * Trait that determines if a type is a map type.
 */
template<typename T>
struct is_map : std::false_type {};

/*
 * This is the specialization when T is a kgr::Map.
 */
template<typename... Ts>
struct is_map<Map<Ts...>> : std::true_type {};

/*
 * This is a trait that tell if the service S is mapped in M
 */
template<typename, typename, typename = void>
struct is_mapped : std::false_type {};

template<typename M, typename S>
using is_valid_entry = std::is_convertible<ServiceType<decltype(service_map(std::declval<S>(), std::declval<M>()))>, S>;

template<typename S>
using is_valid_void_entry = std::is_convertible<ServiceType<decltype(service_map(std::declval<S>()))>, S>;

/*
 * Specialization when map M maps the service S
 */
template<typename M, typename S>
struct is_mapped<Map<M>, S, enable_if_t<is_valid_entry<map_t<M>, S>::value>> : std::true_type {};

/*
 * Specialization for an empty map, equivalent for a void map
 */
template<typename S>
struct is_mapped<Map<>, S, enable_if_t<is_valid_entry<map_t<>, S>::value>> : std::true_type {};

/*
 * Specialization when no map is specified.
 */
template<typename S>
struct is_mapped<void, S, enable_if_t<is_valid_void_entry<S>::value>> : std::true_type {};

/*
 * Trait that extranct the mapped service type given the parameter and a group of maps.
 */
template<typename, typename, typename = void>
struct map_entry {};

/*
 * When no service map entry has been found for First, continue with the next map
 */
template<typename First, typename... Maps, typename P>
struct map_entry<Map<First, Maps...>, P, enable_if_t<!is_mapped<Map<First>, P>::value>> : map_entry<Map<Maps...>, P> {};

/*
 * Case when a map has been found.
 * We proceed to create an alias for the mapped definition.
 */
template<typename First, typename... Maps, typename P>
struct map_entry<Map<First, Maps...>, P, enable_if_t<is_mapped<Map<First>, P>::value>> {
	using Service = decltype(service_map(std::declval<P>(), std::declval<map_t<First> >()));
};

/*
 * Case when a map has been found for an empty map.
 * We proceed to create an alias for the mapped definition.
 */
template<typename P>
struct map_entry<Map<>, P, enable_if_t<is_mapped<Map<>, P>::value>> {
	using Service = decltype(service_map(std::declval<P>(), std::declval<map_t<> >()));
};

/*
 * Case when the empty map does not yeild any mapped service.
 * We proceed to extend an try the void map.
 */
template<typename P>
struct map_entry<Map<>, P, enable_if_t<!is_mapped<Map<>, P>::value>> : map_entry<void, P> {};

/*
 * Case when the only service map found has no map specified at all.
 */
template<typename P>
struct map_entry<void, P, enable_if_t<is_mapped<void, P>::value>> {
	using Service = decltype(service_map(std::declval<P>()));
};

/*
 * Trait to tell if a parameter is mapped using the map group Map.
 */
template<typename Map, typename T, typename = void>
struct is_complete_map : std::false_type {};

template<typename Map, typename T>
struct is_complete_map<Map, T, void_t<typename detail::map_entry<Map, T>::Service>> : std::true_type {};

} // namespace detail

/*
 * This is an alias for the mapped definition in a service map.
 */
template<typename T, typename Map = kgr::Map<>>
using service_map_t = typename detail::map_entry<Map, T>::Service;

} // namespace kgr

#endif // KGR_KANGARU_INCLUDE_KANGARU_DETAIL_SERVICE_MAP_HPP
<commit_msg>Fixed service map in Visual studio<commit_after>#ifndef KGR_KANGARU_INCLUDE_KANGARU_DETAIL_SERVICE_MAP_HPP
#define KGR_KANGARU_INCLUDE_KANGARU_DETAIL_SERVICE_MAP_HPP

#include "traits.hpp"

namespace kgr {

/*
 * This class is the type when referring to a group of maps.
 * This can be used with kgr::AutoCall and mapped operator services.
 */
template<typename...>
struct Map {};

/*
 * This is the type you receive in a service_map function.
 * This was previously kgr::Map in kangaru 3.x.y
 */
template<typename = void>
struct map_t {};

namespace detail {

/*
 * Trait that determines if a type is a map type.
 */
template<typename T>
struct is_map : std::false_type {};

/*
 * This is the specialization when T is a kgr::Map.
 */
template<typename... Ts>
struct is_map<Map<Ts...>> : std::true_type {};

/*
 * Trait that returns the return type of the service_map function
 */
template<typename, typename, typename = void>
struct map_result {};

/*
* Specialization of map_result when service_map() exist for S with the map M.
*/
template<typename S, typename M>
struct map_result<S, M, void_t<decltype(service_map(std::declval<S>(), std::declval<M>()))>> {
	using type = decltype(service_map(std::declval<S>(), std::declval<M>()));
};

/*
* Specialization of map_result when service_map() exist for S with no map.
*/
template<typename S>
struct map_result<S, void, void_t<decltype(service_map(std::declval<S>()))>> {
	using type = decltype(service_map(std::declval<S>()));
};

/*
 * Alias for map_result::type
 */
template<typename S, typename M>
using map_result_t = typename map_result<S, M>::type;

/*
 * This is a trait that tell if the service S is mapped in M
 */
template<typename, typename, typename = void>
struct is_mapped : std::false_type {};

/*
 * Trait that check if the result of the map is a valid service that forwards something convertible to S.
 */
template<typename M, typename S>
using is_valid_entry = std::is_convertible<ServiceType<map_result_t<S, M>>, S>;

/*
 * Specialization when map M maps the service S
 */
template<typename M, typename S>
struct is_mapped<Map<M>, S, enable_if_t<is_valid_entry<map_t<M>, S>::value>> : std::true_type {};

/*
 * Specialization for an empty map, equivalent for a void map
 */
template<typename S>
struct is_mapped<Map<>, S, enable_if_t<is_valid_entry<map_t<>, S>::value>> : std::true_type {};

/*
 * Specialization when no map is specified.
 */
template<typename S>
struct is_mapped<void, S, enable_if_t<is_valid_entry<void, S>::value>> : std::true_type {};

/*
 * Trait that extranct the mapped service type given the parameter and a group of maps.
 */
template<typename, typename, typename = void>
struct map_entry {};

/*
 * When no service map entry has been found for First, continue with the next map
 */
template<typename First, typename... Maps, typename P>
struct map_entry<Map<First, Maps...>, P, enable_if_t<!is_mapped<Map<First>, P>::value>> : map_entry<Map<Maps...>, P> {};

/*
 * Case when a map has been found.
 * We proceed to create an alias for the mapped definition.
 */
template<typename First, typename... Maps, typename P>
struct map_entry<Map<First, Maps...>, P, enable_if_t<is_mapped<Map<First>, P>::value>> {
	using Service = map_result_t<P, map_t<First>>;
};

/*
 * Case when a map has been found for an empty map.
 * We proceed to create an alias for the mapped definition.
 */
template<typename P>
struct map_entry<Map<>, P, enable_if_t<is_mapped<Map<>, P>::value>> {
	using Service = map_result_t<P, map_t<>>;
};

/*
 * Case when the empty map does not yeild any mapped service.
 * We proceed to extend an try the void map.
 */
template<typename P>
struct map_entry<Map<>, P, enable_if_t<!is_mapped<Map<>, P>::value>> : map_entry<void, P> {};

/*
 * Case when the only service map found has no map specified at all.
 */
template<typename P>
struct map_entry<void, P, enable_if_t<is_mapped<void, P>::value>> {
	using Service = map_result_t<P, void>;
};

/*
 * Trait to tell if a parameter is mapped using the map group Map.
 */
template<typename Map, typename T, typename = void>
struct is_complete_map : std::false_type {};

/*
* Specialization of is_complete_map when the service T is mapped in Map
*/
template<typename Map, typename T>
struct is_complete_map<Map, T, void_t<typename detail::map_entry<Map, T>::Service>> : std::true_type {};

} // namespace detail

/*
 * This is an alias for the mapped definition in a service map.
 */
template<typename T, typename Map = kgr::Map<>>
using service_map_t = typename detail::map_entry<Map, T>::Service;

} // namespace kgr

#endif // KGR_KANGARU_INCLUDE_KANGARU_DETAIL_SERVICE_MAP_HPP
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p10/procedures/hwp/pm/p10_update_ec_state.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2019,2022                        */
/* [+] 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  p10_update_ec_state.C
/// @brief Update the core configured data in CCSR register and then deals with
///        deconfigured cores to verify the chiplet state..if it is still running then
///        will put the core to stop 11 state
///
/// *HWP HW Owner        : Greg Still <stillgs@us.ibm.com>
/// *HWP FW Owner        : Prasad Bg Ranganath <prasadbgr@in.ibm.com>
/// *HWP Team            : PM
/// *HWP Level           : 2
/// *HWP Consumed by     : HB,PGPE,CME,OCC
///

// -----------------------------------------------------------------------------
//  Includes
// -----------------------------------------------------------------------------
#include "p10_update_ec_state.H"
#include <p10_pm_util.H>
#include "p10_hcd_common.H"
#include "p10_hcd_cache_stopclocks.H"
#include "p10_hcd_core_poweroff.H"
#include "p10_hcd_l3_purge.H"
#include "p10_hcd_l2_purge.H"
#include "p10_hcd_powerbus_purge.H"
#include "p10_hcd_l2_tlbie_quiesce.H"
#include "p10_hcd_ncu_purge.H"
#include "p10_hcd_chtm_purge.H"
#include "p10_hcd_core_stopclocks.H"
#include "p10_hcd_cache_poweroff.H"
#include "p10_hcd_core_shadows_disable.H"
#include "p10_hcd_core_stopgrid.H"
#include <p10_scom_proc.H>
#include <p10_scom_c.H>
#include <p10_scom_eq.H>

using namespace scomt;
using namespace proc;
using namespace c;
using namespace eq;

// -----------------------------------------------------------------------------
//  Function prototypes
// -----------------------------------------------------------------------------
static fapi2::ReturnCode update_ec_config(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target);

fapi2::ReturnCode verify_ec_hw_state(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target);

fapi2::ReturnCode p10_check_core_l3_clock_power_state(
    const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_core_target,
    uint8_t i_core_unit_pos);

// -----------------------------------------------------------------------------
//  Constants
// -----------------------------------------------------------------------------

// See .H for documentation
fapi2::ReturnCode p10_update_ec_state(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
{

    FAPI_IMP("> p10_update_ec_state");

    FAPI_TRY(update_ec_config(i_target),
             "Error update_core_config detected");
    //TODO Need to find the right way to get deconfigured target
    FAPI_TRY(verify_ec_hw_state(i_target));

fapi_try_exit:
    FAPI_INF("< p10_update_ec_state");

    return fapi2::current_err;
} // END p10_update_ec_state

fapi2::ReturnCode verify_ec_hw_state(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
{
    FAPI_INF (">>verify_hw_state");
    uint8_t l_core_unit_pos;

    std::vector<fapi2::Target<fapi2::TARGET_TYPE_CORE> >l_core_list;
    FAPI_TRY(getDeconfiguredTargets(i_target, l_core_list));

    for (auto l_core : l_core_list)
    {

        FAPI_TRY(FAPI_ATTR_GET( fapi2::ATTR_CHIP_UNIT_POS,
                                l_core,
                                l_core_unit_pos));
        FAPI_INF("Core present but non functional %d",
                 l_core_unit_pos);

        //Check the clock state and power state
// RTC 249759: temporarily enable deconfigured cores/L3 to check for PFET state
//        FAPI_TRY(p10_check_core_l3_clock_power_state(l_core, l_core_unit_pos));

    }

fapi_try_exit:
    FAPI_INF("< update_core_config...");
    return fapi2::current_err;

}

/// @brief Update the CCSR for cores
///
/// @param[in]     i_target   Reference to TARGET_TYPE_PROC_CHIP target
/// @return  FAPI2_RC_SUCCESS if success, else error code.
static fapi2::ReturnCode update_ec_config(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
{
    FAPI_INF("> update_core_config...");

    uint8_t l_present_core_unit_pos;
    uint8_t l_functional_core_unit_pos;
    fapi2::buffer<uint64_t> l_core_config = 0;
    fapi2::buffer<uint64_t> l_pscom_config = 0;

    auto l_core_present_vector =
        i_target.getChildren<fapi2::TARGET_TYPE_CORE>
        (fapi2::TARGET_STATE_PRESENT);

    auto l_core_functional_vector =
        i_target.getChildren<fapi2::TARGET_TYPE_CORE>
        (fapi2::TARGET_STATE_FUNCTIONAL);

    FAPI_INF("  Number of present cores = %d; Number of functional cores = %d",
             l_core_present_vector.size(),
             l_core_functional_vector.size());

    // For each present core,  set multicast groups and the CCSR
    for (auto core_present_it : l_core_present_vector)
    {
        FAPI_TRY(FAPI_ATTR_GET( fapi2::ATTR_CHIP_UNIT_POS,
                                core_present_it,
                                l_present_core_unit_pos));

        FAPI_INF("  Checking if present EC %d is functional",
                 l_present_core_unit_pos);

        for (auto core_functional_it : l_core_functional_vector)
        {
            FAPI_TRY(FAPI_ATTR_GET( fapi2::ATTR_CHIP_UNIT_POS,
                                    core_functional_it,
                                    l_functional_core_unit_pos));
            FAPI_DBG("  Functional EC %d",
                     l_functional_core_unit_pos);

            if (l_functional_core_unit_pos == l_present_core_unit_pos)
            {
                // Set the appropriate bit in the Core Configuration Status
                // Register buffer
                FAPI_INF("  Setting EC %d as good in value to be written to CCSR",
                         l_present_core_unit_pos);
                l_core_config.setBit(l_present_core_unit_pos);

                auto l_eq = core_functional_it.getParent<fapi2::TARGET_TYPE_EQ>();

                l_present_core_unit_pos = l_present_core_unit_pos % 4;

                //Update the pscom enable bit
                l_pscom_config.setBit(l_present_core_unit_pos + 5);

                FAPI_TRY(fapi2::putScom(l_eq, CPLT_CTRL3_WO_OR, l_pscom_config));
                break;
            }  // Current core
        } // Functional core loop
    }  // Present core loop

    // Write the recalculated OCC Core Configuration Status Register
    FAPI_INF("  Writing OCC CCSR");
    FAPI_TRY(fapi2::putScom(i_target, TP_TPCHIP_OCC_OCI_OCB_CCSR_RW, l_core_config));

fapi_try_exit:
    FAPI_INF("< update_core_config...");
    return fapi2::current_err;

}

#define CORE_START_POSITION 5
#define CACHE_START_POSITION 9

fapi2::ReturnCode p10_check_core_l3_clock_power_state(
    const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_core_target,
    uint8_t i_core_unit_pos)
{
    fapi2::buffer<uint64_t> l_data = 0;
    uint64_t l_pfet_sense = 0;
    uint8_t l_core_relative_pos  = i_core_unit_pos % 4;
    uint8_t l_l3_relative_pos    = i_core_unit_pos % 4;
    uint8_t l_core_clock_State = 0;
    uint8_t l_l3_clock_State = 0;

    do
    {
        auto l_eq_target = i_core_target.getParent<fapi2::TARGET_TYPE_EQ>();
        //Read the power state of core/l2
        FAPI_TRY(GET_CPMS_CL2_PFETSTAT(i_core_target, l_data));
        GET_CPMS_CL2_PFETSTAT_VDD_PFETS_ENABLED_SENSE(l_data, l_pfet_sense);

        //verify L3/core clocks are on
        FAPI_TRY(GET_CLOCK_STAT_SL(l_eq_target, l_data));
        l_core_clock_State = l_data & BIT64(l_core_relative_pos + CORE_START_POSITION);
        l_l3_clock_State   = l_data & BIT64(l_l3_relative_pos + CACHE_START_POSITION);

        //Verify core is powered on
        //If core is powered on
        //  then if core(ECl2) clocks are on
        //      then need to purge the l2 and stop the core clocks
        //  if L3 clocks are on
        //      then purge L3 and stop the l3 clocks
        //  Power off the core and L3
        if( l_pfet_sense)
        {
            if (!l_core_clock_State)
            {
                FAPI_TRY(p10_hcd_l2_purge(i_core_target));
                FAPI_TRY(p10_hcd_l2_tlbie_quiesce(i_core_target));
                FAPI_TRY(p10_hcd_ncu_purge(i_core_target));
                FAPI_TRY(p10_hcd_core_shadows_disable(i_core_target));
                FAPI_TRY(p10_hcd_core_stopclocks(i_core_target));
                FAPI_TRY(p10_hcd_core_stopgrid(i_core_target));
            }

            FAPI_TRY(p10_hcd_core_poweroff(i_core_target));

            if (!l_l3_clock_State)
            {
                FAPI_TRY(p10_hcd_chtm_purge(i_core_target));
                FAPI_TRY(p10_hcd_l3_purge(i_core_target));
                FAPI_TRY(p10_hcd_powerbus_purge(i_core_target));
                FAPI_TRY(p10_hcd_cache_stopclocks(i_core_target));
            }

            FAPI_TRY(p10_hcd_cache_poweroff(i_core_target));
        }
    }
    while(0);

fapi_try_exit:
    FAPI_INF("< p10_check_core_clock_power_state...");
    return fapi2::current_err;

}
<commit_msg>PM: p10_update_ec procedure bug fix and enable core/L3 pfet state<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p10/procedures/hwp/pm/p10_update_ec_state.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2019,2022                        */
/* [+] 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  p10_update_ec_state.C
/// @brief Update the core configured data in CCSR register and then deals with
///        deconfigured cores to verify the chiplet state..if it is still running then
///        will put the core to stop 11 state
///
/// *HWP HW Owner        : Greg Still <stillgs@us.ibm.com>
/// *HWP FW Owner        : Prasad Bg Ranganath <prasadbgr@in.ibm.com>
/// *HWP Team            : PM
/// *HWP Level           : 2
/// *HWP Consumed by     : HB,PGPE,CME,OCC
///

// -----------------------------------------------------------------------------
//  Includes
// -----------------------------------------------------------------------------
#include "p10_update_ec_state.H"
#include <p10_pm_util.H>
#include "p10_hcd_common.H"
#include "p10_hcd_cache_stopclocks.H"
#include "p10_hcd_core_poweroff.H"
#include "p10_hcd_l3_purge.H"
#include "p10_hcd_l2_purge.H"
#include "p10_hcd_powerbus_purge.H"
#include "p10_hcd_l2_tlbie_quiesce.H"
#include "p10_hcd_ncu_purge.H"
#include "p10_hcd_chtm_purge.H"
#include "p10_hcd_core_stopclocks.H"
#include "p10_hcd_cache_poweroff.H"
#include "p10_hcd_core_shadows_disable.H"
#include "p10_hcd_core_stopgrid.H"
#include <p10_scom_proc.H>
#include <p10_scom_c.H>
#include <p10_scom_eq.H>

using namespace scomt;
using namespace proc;
using namespace c;
using namespace eq;

#define CL2_START_POSITION 5
#define L3_START_POSITION 9
#define MMA_START_POSITION 15
// -----------------------------------------------------------------------------
//  Function prototypes
// -----------------------------------------------------------------------------
static fapi2::ReturnCode update_ec_config(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target);

fapi2::ReturnCode verify_ec_hw_state(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target);

fapi2::ReturnCode clear_atomic_lock(
    const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_core_target,
    const uint32_t i_lockId);

fapi2::ReturnCode set_atomic_lock(
    const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_core_target,
    uint32_t& o_lockId);

fapi2::ReturnCode powerdown_deconfigured_cl2_l3(
    const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_core_target,
    uint8_t i_core_unit_pos);

// -----------------------------------------------------------------------------
//  Constants
// -----------------------------------------------------------------------------

// See .H for documentation
fapi2::ReturnCode p10_update_ec_state(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
{

    FAPI_IMP("> p10_update_ec_state");

    FAPI_TRY(update_ec_config(i_target),
             "Error update_core_config detected");

    FAPI_TRY(verify_ec_hw_state(i_target));

fapi_try_exit:
    FAPI_INF("< p10_update_ec_state");

    return fapi2::current_err;
} // END p10_update_ec_state

fapi2::ReturnCode verify_ec_hw_state(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
{
    FAPI_INF (">>verify_hw_state");
    uint8_t l_core_unit_pos;

    std::vector<fapi2::Target<fapi2::TARGET_TYPE_CORE> >l_core_list;
    FAPI_TRY(getDeconfiguredTargets(i_target, l_core_list));

    for (auto l_core : l_core_list)
    {

        FAPI_TRY(FAPI_ATTR_GET( fapi2::ATTR_CHIP_UNIT_POS,
                                l_core,
                                l_core_unit_pos));
        FAPI_INF("Core present but non functional %d",
                 l_core_unit_pos);

        //Check the clock state and power state
// RTC 249759: temporarily enable deconfigured cores/L3 to check for PFET state
        FAPI_TRY(powerdown_deconfigured_cl2_l3(l_core, l_core_unit_pos));

    }

fapi_try_exit:
    FAPI_INF("<< verify_hw_state...");
    return fapi2::current_err;

}

/// @brief Update the CCSR for cores
///
/// @param[in]     i_target   Reference to TARGET_TYPE_PROC_CHIP target
/// @return  FAPI2_RC_SUCCESS if success, else error code.
static fapi2::ReturnCode update_ec_config(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
{
    FAPI_INF("> update_ec_config...");

    uint8_t l_present_core_unit_pos;
    uint8_t l_functional_core_unit_pos;
    fapi2::buffer<uint64_t> l_core_config = 0;
    fapi2::buffer<uint64_t> l_pg_config = 0;

    auto l_core_present_vector =
        i_target.getChildren<fapi2::TARGET_TYPE_CORE>
        (fapi2::TARGET_STATE_PRESENT);

    auto l_core_functional_vector =
        i_target.getChildren<fapi2::TARGET_TYPE_CORE>
        (fapi2::TARGET_STATE_FUNCTIONAL);

    FAPI_INF("  Number of present cores = %d; Number of functional cores = %d",
             l_core_present_vector.size(),
             l_core_functional_vector.size());

    // For each present core,set region partial good and OCC CCSR bits
    for (auto core_present_it : l_core_present_vector)
    {
        FAPI_TRY(FAPI_ATTR_GET( fapi2::ATTR_CHIP_UNIT_POS,
                                core_present_it,
                                l_present_core_unit_pos));

        FAPI_INF("  Checking if present EC %d is functional",
                 l_present_core_unit_pos);

        for (auto core_functional_it : l_core_functional_vector)
        {
            FAPI_TRY(FAPI_ATTR_GET( fapi2::ATTR_CHIP_UNIT_POS,
                                    core_functional_it,
                                    l_functional_core_unit_pos));
            FAPI_DBG("  Functional EC %d",
                     l_functional_core_unit_pos);

            if (l_functional_core_unit_pos == l_present_core_unit_pos)
            {
                // Set the appropriate bit in the Core Configuration Status
                // Register buffer
                FAPI_INF("  Setting EC %d as good in value to be written to CCSR",
                         l_present_core_unit_pos);
                l_core_config.setBit(l_present_core_unit_pos);

                auto l_eq = core_functional_it.getParent<fapi2::TARGET_TYPE_EQ>();

                l_present_core_unit_pos = l_present_core_unit_pos % 4;

                //Update the pg bits
                l_pg_config.setBit(l_present_core_unit_pos + CL2_START_POSITION); //ecl2
                l_pg_config.setBit(l_present_core_unit_pos + L3_START_POSITION); //l3
                l_pg_config.setBit(l_present_core_unit_pos + MMA_START_POSITION); //mma

                //setting Region Partial Good bits
                FAPI_TRY(fapi2::putScom(l_eq, CPLT_CTRL2_WO_OR, l_pg_config));
                break;
            }  // Current core
        } // Functional core loop
    }  // Present core loop

    // Write the recalculated OCC Core Configuration Status Register
    FAPI_INF("  Writing OCC CCSR");
    FAPI_TRY(fapi2::putScom(i_target, TP_TPCHIP_OCC_OCI_OCB_CCSR_RW, l_core_config));

fapi_try_exit:
    FAPI_INF("<< update_ec_config...");
    return fapi2::current_err;

}

fapi2::ReturnCode powerdown_deconfigured_cl2_l3(
    const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_core_target,
    uint8_t i_core_unit_pos)
{
    fapi2::buffer<uint64_t> l_data = 0;

    uint64_t l_cl2_pfet_sense = 0;
    uint64_t l_l3_pfet_sense = 0;
    uint8_t l_core_relative_pos  = i_core_unit_pos % 4;
    uint8_t l_core_clock_State = 0;
    uint8_t l_l3_clock_State = 0;
    fapi2::buffer<uint64_t> l_pscom_pg_config = 0;
    uint32_t l_lockId = 0;

    do
    {
        auto l_eq_target = i_core_target.getParent<fapi2::TARGET_TYPE_EQ>();

        FAPI_TRY(set_atomic_lock(i_core_target, l_lockId));

        //Update the pscom enable and pg bits to temporarily allow controlling
        //of now deconfigured elements.
        l_pscom_pg_config.setBit(l_core_relative_pos + CL2_START_POSITION); //ecl2
        l_pscom_pg_config.setBit(l_core_relative_pos + L3_START_POSITION); //l3
        l_pscom_pg_config.setBit(l_core_relative_pos + MMA_START_POSITION); //mma

        FAPI_TRY(fapi2::putScom(l_eq_target, CPLT_CTRL3_WO_OR, l_pscom_pg_config));
        FAPI_TRY(fapi2::putScom(l_eq_target, CPLT_CTRL2_WO_OR, l_pscom_pg_config));

        //verify L3/core clocks are on
        FAPI_TRY(GET_CLOCK_STAT_SL(l_eq_target, l_data));

        l_core_clock_State = l_data.getBit(l_core_relative_pos + CL2_START_POSITION);
        l_l3_clock_State = l_data.getBit(l_core_relative_pos + L3_START_POSITION);
        FAPI_INF("Core position %d CL2 state  %d L3 state %d", l_core_relative_pos,
                 l_core_clock_State, l_l3_clock_State);

        if (!l_core_clock_State)
        {
            //Read the power state of core/l2
            FAPI_TRY(GET_CPMS_CL2_PFETSTAT(i_core_target, l_data));
            GET_CPMS_CL2_PFETSTAT_VDD_PFETS_ENABLED_SENSE(l_data, l_cl2_pfet_sense);
        }

        if (!l_l3_clock_State)
        {
            //Read the power state of L3
            FAPI_TRY(GET_CPMS_L3_PFETSTAT(i_core_target, l_data));
            GET_CPMS_L3_PFETSTAT_VDD_PFETS_ENABLED_SENSE(l_data, l_l3_pfet_sense);
        }

        if ( l_core_clock_State && l_l3_clock_State)
        {
            FAPI_INF("Both L3 and L2 units are powered off and clock off");
            break;
        }

        //Verify core is powered on
        //If core is powered on
        //  then if core(ECl2) clocks are on
        //      then need to purge the l2 and stop the core clocks
        //  if L3 clocks are on
        //      then purge L3 and stop the l3 clocks
        //  Power off the core and L3
        if( l_cl2_pfet_sense)
        {
            if (!l_core_clock_State)
            {
                FAPI_TRY(p10_hcd_l2_purge(i_core_target));
                FAPI_TRY(p10_hcd_l2_tlbie_quiesce(i_core_target));
                FAPI_TRY(p10_hcd_ncu_purge(i_core_target));
                FAPI_TRY(p10_hcd_core_shadows_disable(i_core_target));
                FAPI_TRY(p10_hcd_core_stopclocks(i_core_target));
                FAPI_TRY(p10_hcd_core_stopgrid(i_core_target));
            }

            FAPI_TRY(p10_hcd_core_poweroff(i_core_target));
        }

        if (l_l3_pfet_sense)
        {
            if (!l_l3_clock_State)
            {
                FAPI_TRY(p10_hcd_chtm_purge(i_core_target));
                FAPI_TRY(p10_hcd_l3_purge(i_core_target));
                FAPI_TRY(p10_hcd_powerbus_purge(i_core_target));
                FAPI_TRY(p10_hcd_cache_stopclocks(i_core_target));
            }

            FAPI_TRY(p10_hcd_cache_poweroff(i_core_target));
        }

        //Restore the original values
        FAPI_TRY(fapi2::putScom(l_eq_target, CPLT_CTRL3_WO_CLEAR, l_pscom_pg_config));
        FAPI_TRY(fapi2::putScom(l_eq_target, CPLT_CTRL2_WO_CLEAR, l_pscom_pg_config));

        FAPI_TRY(clear_atomic_lock(i_core_target, l_lockId));
    }
    while(0);

fapi_try_exit:
    FAPI_INF("< p10_check_core_clock_power_state...");
    return fapi2::current_err;

}

fapi2::ReturnCode set_atomic_lock(
    const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_core_target,
    uint32_t& o_lock_id)
{
    fapi2::buffer<uint64_t> l_data = 0;
    fapi2::buffer<uint64_t> l_buf = 0;
    fapi2::ReturnCode l_rc;

    auto l_eq_target = i_core_target.getParent<fapi2::TARGET_TYPE_EQ>();

    //Grab the lock
    FAPI_TRY(GET_CTRL_ATOMIC_LOCK_REG(l_eq_target, l_data));
    SET_CTRL_ATOMIC_LOCK_REG_LOCK_ENABLE(l_data);
    l_rc = PUT_CTRL_ATOMIC_LOCK_REG(l_eq_target, l_data);

    if ( l_rc) //Resource busy
    {
        for (auto i = 0  ; i < 50; i++)
        {
            fapi2::delay(10000000, 10); //10ms
            l_rc = PUT_CTRL_ATOMIC_LOCK_REG(l_eq_target, l_data);

            if (l_rc == fapi2::FAPI2_RC_SUCCESS)
            {
                break;
            }
        }

        if (l_rc)
        {
            FAPI_ASSERT(false,
                        fapi2::SET_ATOMIC_LOCK_BUSY()
                        .set_CORE_TARGET(i_core_target)
                        .set_DATA(l_data),
                        "Update ec: atomic lock access error");
        }
    }
    else if (l_rc == fapi2::FAPI2_RC_SUCCESS)
    {
        FAPI_TRY(GET_CTRL_ATOMIC_LOCK_REG(l_eq_target, l_data));
        GET_CTRL_ATOMIC_LOCK_REG_ID(l_data, l_buf);

        if (!GET_CTRL_ATOMIC_LOCK_REG_LOCK_ENABLE(l_data)  ||
            (l_buf != 0x9 && l_buf != 0x2 && l_buf != 0xE)) //hostboot Id/FSI2PIB/SBE
        {
            FAPI_ASSERT(false,
                        fapi2::SET_ATOMIC_LOCK_FAIL()
                        .set_CORE_TARGET(i_core_target)
                        .set_DATA(l_data),
                        "Update ec: couldn't grab atomic lock");
        }
    }

    o_lock_id = l_buf;

fapi_try_exit:
    FAPI_INF("< set_atomic_lock...");
    return fapi2::current_err;
}

fapi2::ReturnCode clear_atomic_lock(
    const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_core_target,
    const uint32_t i_lockId)
{
    fapi2::buffer<uint64_t> l_data = 0;
    fapi2::buffer<uint64_t> l_buf = 0;
    fapi2::ReturnCode l_rc;

    auto l_eq_target = i_core_target.getParent<fapi2::TARGET_TYPE_EQ>();
    //Clear the lock
    FAPI_TRY(GET_CTRL_ATOMIC_LOCK_REG(l_eq_target, l_data));
    GET_CTRL_ATOMIC_LOCK_REG_ID(l_data, l_buf);

    if ( i_lockId == l_buf)
    {
        l_data.flush<0>();
        FAPI_TRY(PUT_CTRL_ATOMIC_LOCK_REG(l_eq_target, l_data));
    }
    else
    {
        FAPI_ASSERT(false,
                    fapi2::ATOMIC_LOCK_OWNER_ID_INVALID()
                    .set_CORE_TARGET(i_core_target)
                    .set_ACTUAL_LOCK_ID(l_buf)
                    .set_EXPECTED_LOCK_ID(i_lockId),
                    ": atomic lock access error");
    }

fapi_try_exit:
    FAPI_INF("< p10_check_core_clock_power_state...");
    return fapi2::current_err;
}
<|endoftext|>