<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: excelhandlers.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: kz $ $Date: 2008-03-05 18:59:05 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include "oox/xls/excelhandlers.hxx"

using ::rtl::OUString;
using ::oox::core::FragmentHandler2;
using ::oox::core::XmlFilterBase;

namespace oox {
namespace xls {

// ============================================================================

OoxWorkbookFragmentBase::OoxWorkbookFragmentBase(
        const WorkbookHelper& rHelper, const OUString& rFragmentPath ) :
    FragmentHandler2( rHelper.getOoxFilter(), rFragmentPath ),
    WorkbookHelper( rHelper )
{
}

// ============================================================================

OoxWorksheetFragmentBase::OoxWorksheetFragmentBase( const WorkbookHelper& rHelper,
        const OUString& rFragmentPath, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, sal_Int32 nSheet ) :
    FragmentHandler2( rHelper.getOoxFilter(), rFragmentPath ),
    WorksheetHelperRoot( rHelper, xProgressBar, eSheetType, nSheet )
{
}

OoxWorksheetFragmentBase::OoxWorksheetFragmentBase(
        const WorksheetHelper& rHelper, const OUString& rFragmentPath ) :
    FragmentHandler2( rHelper.getOoxFilter(), rFragmentPath ),
    WorksheetHelperRoot( rHelper )
{
}

// ============================================================================

} // namespace xls
} // namespace oox

<commit_msg>INTEGRATION: CWS changefileheader (1.2.6); FILE MERGED 2008/03/31 16:21:54 rt 1.2.6.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: excelhandlers.cxx,v $
 * $Revision: 1.3 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#include "oox/xls/excelhandlers.hxx"

using ::rtl::OUString;
using ::oox::core::FragmentHandler2;
using ::oox::core::XmlFilterBase;

namespace oox {
namespace xls {

// ============================================================================

OoxWorkbookFragmentBase::OoxWorkbookFragmentBase(
        const WorkbookHelper& rHelper, const OUString& rFragmentPath ) :
    FragmentHandler2( rHelper.getOoxFilter(), rFragmentPath ),
    WorkbookHelper( rHelper )
{
}

// ============================================================================

OoxWorksheetFragmentBase::OoxWorksheetFragmentBase( const WorkbookHelper& rHelper,
        const OUString& rFragmentPath, ISegmentProgressBarRef xProgressBar, WorksheetType eSheetType, sal_Int32 nSheet ) :
    FragmentHandler2( rHelper.getOoxFilter(), rFragmentPath ),
    WorksheetHelperRoot( rHelper, xProgressBar, eSheetType, nSheet )
{
}

OoxWorksheetFragmentBase::OoxWorksheetFragmentBase(
        const WorksheetHelper& rHelper, const OUString& rFragmentPath ) :
    FragmentHandler2( rHelper.getOoxFilter(), rFragmentPath ),
    WorksheetHelperRoot( rHelper )
{
}

// ============================================================================

} // namespace xls
} // namespace oox

<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "call/version.h"

namespace webrtc {

// The timestamp is always in UTC.
const char* const kSourceTimestamp = "WebRTC source stamp 2021-01-20T04:04:26";

void LoadWebRTCVersionInRegister() {
  // Using volatile to instruct the compiler to not optimize `p` away even
  // if it looks unused.
  const char* volatile p = kSourceTimestamp;
  static_cast<void>(p);
}

}  // namespace webrtc
<commit_msg>Update WebRTC code version (2021-01-21T04:03:14).<commit_after>/*
 *  Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "call/version.h"

namespace webrtc {

// The timestamp is always in UTC.
const char* const kSourceTimestamp = "WebRTC source stamp 2021-01-21T04:03:14";

void LoadWebRTCVersionInRegister() {
  // Using volatile to instruct the compiler to not optimize `p` away even
  // if it looks unused.
  const char* volatile p = kSourceTimestamp;
  static_cast<void>(p);
}

}  // namespace webrtc
<|endoftext|>


<commit_before>/*
 * SuRealPMCB.cc
 *
 * Copyright (C) 2014 OpenCog Foundation
 *
 * Author: William Ma <https://github.com/williampma>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <opencog/nlp/types/atom_types.h>

#include "SuRealPMCB.h"

using namespace opencog::nlp;
using namespace opencog;

/**
 * The constructor for the PatternMatcherCallback.
 *
 * @param pAS    the corresponding AtomSpace
 * @param vars   the set of nodes that should be treated as variables
 */
SuRealPMCB::SuRealPMCB(AtomSpace* pAS, std::set<Handle> vars) : DefaultPatternMatchCB(pAS), m_vars(vars)
{

}

/**
 * Override the variable_match callback.
 *
 * Do the special checking for each variable matches.  Note that variables
 * in SuReal will not just be VariableNode, but any nodes with an actual word
 * (eg. (PredicateNode "runs"), (ConceptNode "dog@1324-12213"), etc).
 *
 * For each variable and its potential solution, the corresponding WordNode
 * will be located.  Then we following the WordNode to find LgWordCset to get
 * the LG dictionary entries.  If the two words have identical LG entries,
 * then the two words matches.  Just one pair of LG entries need to match even
 * if a word has multiple entries.
 *
 * @param hPat    the variable, a node extracted from the original query
 * @param hSoln   the potential mapping
 * @return        true if solution is rejected, false if accepted
 */
bool SuRealPMCB::variable_match(Handle &hPat, Handle &hSoln)
{
    logger().debug("[SuReal] In variable_match, looking at %s", hSoln->toShortString().c_str());

    // reject if the solution is not of the same type
    if (hPat->getType() != hSoln->getType())
        return true;

    // VariableNode can be matched to any VariableNode, similarly for InterpretationNode
    if (hPat->getType() == VARIABLE_NODE || hPat->getType() == INTERPRETATION_NODE)
        return true;

    std::string sPat = _as->getName(hPat);
    std::string sPatWord = sPat.substr(0, sPat.find_first_of('@'));
    std::string sSoln = _as->getName(hSoln);
    std::string sSolnWord = sSoln.substr(0, sSoln.find_first_of('@'));

    // get the WordNode associated with the word (extracted from "word@1234" convention)
    Handle hPatWordNode = _as->getHandle(WORD_NODE, sPatWord);
    Handle hSolnWordNode = _as->getHandle(WORD_NODE, sSolnWord);

    // no WordNode? reject!
    if (hSolnWordNode == Handle::UNDEFINED)
        return true;

    // get the neighbor of each WordNode within LgWordCset
    HandleSeq qPatSet =_as->getNeighbors(hPatWordNode, false, true, LG_WORD_CSET, false);
    HandleSeq qSolnSet = _as->getNeighbors(hSolnWordNode, false, true, LG_WORD_CSET, false);

    // check the HandleSeq to see if there is any pair that is equal (common LG entry)
    std::sort(qPatSet.begin(), qPatSet.end());
    std::sort(qSolnSet.begin(), qSolnSet.end());

    HandleSeq qItrsect;
    std::set_intersection(qPatSet.begin(), qPatSet.end(), qSolnSet.begin(), qSolnSet.end(), std::back_inserter(qItrsect));

    // if there's no common LG dictionary rules, then the two words do not match
    if (qItrsect.empty())
        return true;

    return false;
}

/**
 * Override the clause_match callback.
 *
 * Reject a clause match if the matched link is not in a SetLink linked to an
 * InterpretationNode.  The reason of doing it here instead of earlier in
 * link_match() is because it is possible a SetLink is used for other purpose
 * as part of R2L's output.
 *
 * @param pattrn_link_h   the matched clause, extracted from the input SetLink
 * @param grnd_link_h     the corresponding grounding to be checked
 * @return                true if rejected, false if accepted
 */
bool SuRealPMCB::clause_match(Handle &pattrn_link_h, Handle &grnd_link_h)
{
    logger().debug("[SuReal] In clause_match, looking at %s", grnd_link_h->toShortString().c_str());

    HandleSeq qISet = _as->getIncoming(grnd_link_h);

    // keep only SetLink, and check if any of the SetLink has an InterpretationNode as neightbor
    qISet.erase(std::remove_if(qISet.begin(), qISet.end(), [](Handle& h) { return h->getType() != SET_LINK; }), qISet.end());

    // helper lambda function to check for linkage to an InterpretationNode, given SetLink
    auto hasInterpretation = [this](Handle& h)
    {
        HandleSeq qN = _as->getNeighbors(h, true, false, REFERENCE_LINK, false);
        return std::any_of(qN.begin(), qN.end(), [](Handle& hn) { return hn->getType() == INTERPRETATION_NODE; });
    };

    // reject match (ie. return true) if there is no InterpretationNode
    return not std::any_of(qISet.begin(), qISet.end(), hasInterpretation);
}

/**
 * Implement the grounding method.
 *
 * Check all matched clauses to see if they are all within the same SetLink
 * linking to the same InterpretationNode.  If so, store the solution and try
 * to find more.
 *
 * @param var_soln   the variable & links mapping
 * @param pred_soln  the clause mapping
 * @return           always return false to search for more solutions
 */
bool SuRealPMCB::grounding(const std::map<Handle, Handle> &var_soln, const std::map<Handle, Handle> &pred_soln)
{
    logger().debug("[SuReal] grounding a solution");

    // helper to get the InterpretationNode
    auto getInterpretation = [this](const Handle& h)
    {
        HandleSeq qISet = _as->getIncoming(h);
        qISet.erase(std::remove_if(qISet.begin(), qISet.end(), [](Handle& h) { return h->getType() != SET_LINK; }), qISet.end());

        HandleSeq results;

        for (auto& hSetLink : qISet)
        {
            HandleSeq qN  = _as->getNeighbors(hSetLink, true, false, REFERENCE_LINK, false);
            qN.erase(std::remove_if(qN.begin(), qN.end(), [](Handle& h) { return h->getType() != INTERPRETATION_NODE; }), qN.end());

            results.insert(results.end(), qN.begin(), qN.end());
        }

        return results;
    };

    HandleSeq qItprNode = getInterpretation(pred_soln.begin()->second);
    std::sort(qItprNode.begin(), qItprNode.end());

    // try to find a common InterpretationNode to the solutions
    for (std::map<Handle, Handle>::const_iterator it = ++pred_soln.begin(); it != pred_soln.end(); ++it)
    {
        HandleSeq thisSeq = getInterpretation(it->second);
        std::sort(thisSeq.begin(), thisSeq.end());

        HandleSeq overlapSeq;
        std::set_intersection(qItprNode.begin(), qItprNode.end(), thisSeq.begin(), thisSeq.end(), std::back_inserter(overlapSeq));

        qItprNode = overlapSeq;
    }

    // no common InterpretationNode, ignore this grounding
    if (qItprNode.empty())
        return false;

    // shrink var_soln to only contain solution for the variables
    std::map<Handle, Handle> shrinked_soln;

    for (const auto& kv : var_soln)
    {
        if (m_vars.count(kv.first) == 0)
            continue;

        shrinked_soln[kv.first] = kv.second;
    }

    // store the solution; all common InterpretationNode are solutions for this
    // grounding, so store the solution for each InterpretationNode
    for (auto n : qItprNode)
        m_results[n] = shrinked_soln;

    return false;
}

/**
 * Implement the perform_search method.
 *
 * Similar to DefaultPatternMatcherCB::perform_search, in which we start search
 * by looking at the thinnest clause with constants.  However, since most clauses
 * for SuReal will have 0 constants, most searches will require looking at all
 * the links.  This implementation improves that by looking at links within a
 * SetLink within a ReferenceLink with a InterpretationNode neightbor, thus
 * limiting the search space.
 *
 * @param pPME       pointer to the PatternMatchEngine
 * @param vars       a set of nodes that are variables
 * @param clauses    the clauses for the query
 * @param negations  the negative clauses
 */
void SuRealPMCB::perform_search(PatternMatchEngine* pPME, std::set<Handle>& vars, HandleSeq& clauses, HandleSeq& negations)
{
    size_t bestClauseIndex;
    Handle bestClause, bestSubClause, bestSubNode;

    // find the thinnest clause with constants
    bestSubNode = find_thinnest(clauses, bestSubClause, bestClauseIndex);

    if (bestSubNode != Handle::UNDEFINED && !vars.empty())
    {
        bestClause = clauses[bestClauseIndex];

        logger().debug("[SuReal] Search start node: %s", bestSubNode->toShortString().c_str());
        logger().debug("[SuReal] Start pred is: %s", bestSubClause->toShortString().c_str());

        IncomingSet iset = get_incoming_set(bestSubNode);

        for (auto& l : iset)
        {
            Handle h(l);
            logger().debug("[SuReal] Loop candidate: %s", h->toShortString().c_str());

            if (pPME->do_candidate(bestClause, bestSubClause, h))
                break;
        }

        return;
    }

    // reaching here means no contants, so do some search space reduction here
    bestClause = clauses[0];

    logger().debug("[SuReal] Start pred is: %s", bestClause->toShortString().c_str());

    // helper for checking for InterpretationNode
    auto hasNoInterpretation = [this](Handle& h)
    {
        HandleSeq qISet = _as->getIncoming(h);
        qISet.erase(std::remove_if(qISet.begin(), qISet.end(), [](Handle& hl) { return hl->getType() != SET_LINK; }), qISet.end());

        auto hasNode = [this](Handle& hl)
        {
            HandleSeq qN = _as->getNeighbors(hl, true, false, REFERENCE_LINK, false);
            return std::any_of(qN.begin(), qN.end(), [](Handle& hn) { return hn->getType() == INTERPRETATION_NODE; });
        };

        return not std::any_of(qISet.begin(), qISet.end(), hasNode);
    };

    // keep only links of the same type as bestClause and have linkage to InterpretationNode
    HandleSeq qCandidate;
    _as->getHandlesByType(std::back_inserter(qCandidate), bestClause->getType());
    qCandidate.erase(std::remove_if(qCandidate.begin(), qCandidate.end(), hasNoInterpretation), qCandidate.end());

    for (auto& c : qCandidate)
    {
        logger().debug("[SuReal] Loop candidate: %s", c->toShortString().c_str());

        if (pPME->do_candidate(bestClause, bestClause, c))
            break;
    }
}

/**
 * Override the find_starter method in DefaultPatternMatchCB.
 *
 * Override find_starter so that it will not treat VariableNode variables,
 * but instead compare against the variable list.
 *
 * @param h       same as DefaultPatternMatchCB::find_starter
 * @param depth   same as DefaultPatternMatchCB::find_starter
 * @param start   same as DefaultPatternMatchCB::find_starter
 * @param width   same as DefaultPatternMatchCB::find_starter
 * @return        same as DefaultPatternMatchCB::find_starter but change
 *                the result if is a variable
 */
Handle SuRealPMCB::find_starter(Handle h, size_t& depth, Handle& start, size_t& width)
{
    Handle rh = DefaultPatternMatchCB::find_starter(h, depth, start, width);

    // if the non-VariableNode is actually a variable
    if (m_vars.count(rh) == 1)
        return Handle::UNDEFINED;

    return rh;
}

<commit_msg>Fixed incorrect return value for callback<commit_after>/*
 * SuRealPMCB.cc
 *
 * Copyright (C) 2014 OpenCog Foundation
 *
 * Author: William Ma <https://github.com/williampma>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <opencog/nlp/types/atom_types.h>

#include "SuRealPMCB.h"

using namespace opencog::nlp;
using namespace opencog;

/**
 * The constructor for the PatternMatcherCallback.
 *
 * @param pAS    the corresponding AtomSpace
 * @param vars   the set of nodes that should be treated as variables
 */
SuRealPMCB::SuRealPMCB(AtomSpace* pAS, std::set<Handle> vars) : DefaultPatternMatchCB(pAS), m_vars(vars)
{

}

/**
 * Override the variable_match callback.
 *
 * Do the special checking for each variable matches.  Note that variables
 * in SuReal will not just be VariableNode, but any nodes with an actual word
 * (eg. (PredicateNode "runs"), (ConceptNode "dog@1324-12213"), etc).
 *
 * For each variable and its potential solution, the corresponding WordNode
 * will be located.  Then we following the WordNode to find LgWordCset to get
 * the LG dictionary entries.  If the two words have identical LG entries,
 * then the two words matches.  Just one pair of LG entries need to match even
 * if a word has multiple entries.
 *
 * @param hPat    the variable, a node extracted from the original query
 * @param hSoln   the potential mapping
 * @return        true if solution is rejected, false if accepted
 */
bool SuRealPMCB::variable_match(Handle &hPat, Handle &hSoln)
{
    logger().debug("[SuReal] In variable_match, looking at %s", hSoln->toShortString().c_str());

    // reject if the solution is not of the same type
    if (hPat->getType() != hSoln->getType())
        return true;

    // VariableNode can be matched to any VariableNode, similarly for InterpretationNode
    if (hPat->getType() == VARIABLE_NODE || hPat->getType() == INTERPRETATION_NODE)
        return false;

    std::string sPat = _as->getName(hPat);
    std::string sPatWord = sPat.substr(0, sPat.find_first_of('@'));
    std::string sSoln = _as->getName(hSoln);
    std::string sSolnWord = sSoln.substr(0, sSoln.find_first_of('@'));

    // get the WordNode associated with the word (extracted from "word@1234" convention)
    Handle hPatWordNode = _as->getHandle(WORD_NODE, sPatWord);
    Handle hSolnWordNode = _as->getHandle(WORD_NODE, sSolnWord);

    // no WordNode? reject!
    if (hSolnWordNode == Handle::UNDEFINED)
        return true;

    // get the neighbor of each WordNode within LgWordCset
    HandleSeq qPatSet =_as->getNeighbors(hPatWordNode, false, true, LG_WORD_CSET, false);
    HandleSeq qSolnSet = _as->getNeighbors(hSolnWordNode, false, true, LG_WORD_CSET, false);

    // check the HandleSeq to see if there is any pair that is equal (common LG entry)
    std::sort(qPatSet.begin(), qPatSet.end());
    std::sort(qSolnSet.begin(), qSolnSet.end());

    HandleSeq qItrsect;
    std::set_intersection(qPatSet.begin(), qPatSet.end(), qSolnSet.begin(), qSolnSet.end(), std::back_inserter(qItrsect));

    // if there's no common LG dictionary rules, then the two words do not match
    if (qItrsect.empty())
        return true;

    return false;
}

/**
 * Override the clause_match callback.
 *
 * Reject a clause match if the matched link is not in a SetLink linked to an
 * InterpretationNode.  The reason of doing it here instead of earlier in
 * link_match() is because it is possible a SetLink is used for other purpose
 * as part of R2L's output.
 *
 * @param pattrn_link_h   the matched clause, extracted from the input SetLink
 * @param grnd_link_h     the corresponding grounding to be checked
 * @return                true if rejected, false if accepted
 */
bool SuRealPMCB::clause_match(Handle &pattrn_link_h, Handle &grnd_link_h)
{
    logger().debug("[SuReal] In clause_match, looking at %s", grnd_link_h->toShortString().c_str());

    HandleSeq qISet = _as->getIncoming(grnd_link_h);

    // keep only SetLink, and check if any of the SetLink has an InterpretationNode as neightbor
    qISet.erase(std::remove_if(qISet.begin(), qISet.end(), [](Handle& h) { return h->getType() != SET_LINK; }), qISet.end());

    // helper lambda function to check for linkage to an InterpretationNode, given SetLink
    auto hasInterpretation = [this](Handle& h)
    {
        HandleSeq qN = _as->getNeighbors(h, true, false, REFERENCE_LINK, false);
        return std::any_of(qN.begin(), qN.end(), [](Handle& hn) { return hn->getType() == INTERPRETATION_NODE; });
    };

    // reject match (ie. return true) if there is no InterpretationNode
    return not std::any_of(qISet.begin(), qISet.end(), hasInterpretation);
}

/**
 * Implement the grounding method.
 *
 * Check all matched clauses to see if they are all within the same SetLink
 * linking to the same InterpretationNode.  If so, store the solution and try
 * to find more.
 *
 * @param var_soln   the variable & links mapping
 * @param pred_soln  the clause mapping
 * @return           always return false to search for more solutions
 */
bool SuRealPMCB::grounding(const std::map<Handle, Handle> &var_soln, const std::map<Handle, Handle> &pred_soln)
{
    logger().debug("[SuReal] grounding a solution");

    // helper to get the InterpretationNode
    auto getInterpretation = [this](const Handle& h)
    {
        HandleSeq qISet = _as->getIncoming(h);
        qISet.erase(std::remove_if(qISet.begin(), qISet.end(), [](Handle& h) { return h->getType() != SET_LINK; }), qISet.end());

        HandleSeq results;

        for (auto& hSetLink : qISet)
        {
            HandleSeq qN  = _as->getNeighbors(hSetLink, true, false, REFERENCE_LINK, false);
            qN.erase(std::remove_if(qN.begin(), qN.end(), [](Handle& h) { return h->getType() != INTERPRETATION_NODE; }), qN.end());

            results.insert(results.end(), qN.begin(), qN.end());
        }

        return results;
    };

    HandleSeq qItprNode = getInterpretation(pred_soln.begin()->second);
    std::sort(qItprNode.begin(), qItprNode.end());

    // try to find a common InterpretationNode to the solutions
    for (std::map<Handle, Handle>::const_iterator it = ++pred_soln.begin(); it != pred_soln.end(); ++it)
    {
        HandleSeq thisSeq = getInterpretation(it->second);
        std::sort(thisSeq.begin(), thisSeq.end());

        HandleSeq overlapSeq;
        std::set_intersection(qItprNode.begin(), qItprNode.end(), thisSeq.begin(), thisSeq.end(), std::back_inserter(overlapSeq));

        qItprNode = overlapSeq;
    }

    // no common InterpretationNode, ignore this grounding
    if (qItprNode.empty())
        return false;

    // shrink var_soln to only contain solution for the variables
    std::map<Handle, Handle> shrinked_soln;

    for (const auto& kv : var_soln)
    {
        logger().debug("[SuReal] checking grounding for %s", kv.first->toShortString().c_str());

        if (m_vars.count(kv.first) == 0)
            continue;

        shrinked_soln[kv.first] = kv.second;
    }

    // store the solution; all common InterpretationNode are solutions for this
    // grounding, so store the solution for each InterpretationNode
    for (auto n : qItprNode)
        m_results[n] = shrinked_soln;

    return false;
}

/**
 * Implement the perform_search method.
 *
 * Similar to DefaultPatternMatcherCB::perform_search, in which we start search
 * by looking at the thinnest clause with constants.  However, since most clauses
 * for SuReal will have 0 constants, most searches will require looking at all
 * the links.  This implementation improves that by looking at links within a
 * SetLink within a ReferenceLink with a InterpretationNode neightbor, thus
 * limiting the search space.
 *
 * @param pPME       pointer to the PatternMatchEngine
 * @param vars       a set of nodes that are variables
 * @param clauses    the clauses for the query
 * @param negations  the negative clauses
 */
void SuRealPMCB::perform_search(PatternMatchEngine* pPME, std::set<Handle>& vars, HandleSeq& clauses, HandleSeq& negations)
{
    size_t bestClauseIndex;
    Handle bestClause, bestSubClause, bestSubNode;

    // find the thinnest clause with constants
    bestSubNode = find_thinnest(clauses, bestSubClause, bestClauseIndex);

    if (bestSubNode != Handle::UNDEFINED && !vars.empty())
    {
        bestClause = clauses[bestClauseIndex];

        logger().debug("[SuReal] Search start node: %s", bestSubNode->toShortString().c_str());
        logger().debug("[SuReal] Start pred is: %s", bestSubClause->toShortString().c_str());

        IncomingSet iset = get_incoming_set(bestSubNode);

        for (auto& l : iset)
        {
            Handle h(l);
            logger().debug("[SuReal] Loop candidate: %s", h->toShortString().c_str());

            if (pPME->do_candidate(bestClause, bestSubClause, h))
                break;
        }

        return;
    }

    // reaching here means no contants, so do some search space reduction here
    bestClause = clauses[0];

    logger().debug("[SuReal] Start pred is: %s", bestClause->toShortString().c_str());

    // helper for checking for InterpretationNode
    auto hasNoInterpretation = [this](Handle& h)
    {
        HandleSeq qISet = _as->getIncoming(h);
        qISet.erase(std::remove_if(qISet.begin(), qISet.end(), [](Handle& hl) { return hl->getType() != SET_LINK; }), qISet.end());

        auto hasNode = [this](Handle& hl)
        {
            HandleSeq qN = _as->getNeighbors(hl, true, false, REFERENCE_LINK, false);
            return std::any_of(qN.begin(), qN.end(), [](Handle& hn) { return hn->getType() == INTERPRETATION_NODE; });
        };

        return not std::any_of(qISet.begin(), qISet.end(), hasNode);
    };

    // keep only links of the same type as bestClause and have linkage to InterpretationNode
    HandleSeq qCandidate;
    _as->getHandlesByType(std::back_inserter(qCandidate), bestClause->getType());
    qCandidate.erase(std::remove_if(qCandidate.begin(), qCandidate.end(), hasNoInterpretation), qCandidate.end());

    for (auto& c : qCandidate)
    {
        logger().debug("[SuReal] Loop candidate: %s", c->toShortString().c_str());

        if (pPME->do_candidate(bestClause, bestClause, c))
            break;
    }
}

/**
 * Override the find_starter method in DefaultPatternMatchCB.
 *
 * Override find_starter so that it will not treat VariableNode variables,
 * but instead compare against the variable list.
 *
 * @param h       same as DefaultPatternMatchCB::find_starter
 * @param depth   same as DefaultPatternMatchCB::find_starter
 * @param start   same as DefaultPatternMatchCB::find_starter
 * @param width   same as DefaultPatternMatchCB::find_starter
 * @return        same as DefaultPatternMatchCB::find_starter but change
 *                the result if is a variable
 */
Handle SuRealPMCB::find_starter(Handle h, size_t& depth, Handle& start, size_t& width)
{
    Handle rh = DefaultPatternMatchCB::find_starter(h, depth, start, width);

    // if the non-VariableNode is actually a variable
    if (m_vars.count(rh) == 1)
        return Handle::UNDEFINED;

    return rh;
}

<|endoftext|>


<commit_before>#ifndef UNITTEST_MOCK_STORE_HPP_
#define UNITTEST_MOCK_STORE_HPP_

#include "rdb_protocol/protocol.hpp"

namespace unittest {

class mock_store_t : public store_view_t<rdb_protocol_t> {
public:
    mock_store_t();
    ~mock_store_t();

    void new_read_token(object_buffer_t<fifo_enforcer_sink_t::exit_read_t> *token_out);
    void new_write_token(object_buffer_t<fifo_enforcer_sink_t::exit_write_t> *token_out);

    void do_get_metainfo(order_token_t order_token,
                         object_buffer_t<fifo_enforcer_sink_t::exit_read_t> *token,
                         signal_t *interruptor,
                         metainfo_t *out) THROWS_ONLY(interrupted_exc_t) = 0;

    void set_metainfo(const metainfo_t &new_metainfo,
                      order_token_t order_token,
                      object_buffer_t<fifo_enforcer_sink_t::exit_write_t> *token,
                      signal_t *interruptor) THROWS_ONLY(interrupted_exc_t) = 0;

    void read(
            DEBUG_ONLY(const metainfo_checker_t<rdb_protocol_t> &metainfo_checker, )
            const rdb_protocol_t::read_t &read,
            rdb_protocol_t::read_response_t *response,
            order_token_t order_token,
            read_token_pair_t *token,
            signal_t *interruptor)
        THROWS_ONLY(interrupted_exc_t);

    void write(
            DEBUG_ONLY(const metainfo_checker_t<rdb_protocol_t> &metainfo_checker, )
            const metainfo_t& new_metainfo,
            const rdb_protocol_t::write_t &write,
            rdb_protocol_t::write_response_t *response,
            write_durability_t durability,
            transition_timestamp_t timestamp,
            order_token_t order_token,
            write_token_pair_t *token,
            signal_t *interruptor)
        THROWS_ONLY(interrupted_exc_t);

    bool send_backfill(
            const region_map_t<rdb_protocol_t, state_timestamp_t> &start_point,
            send_backfill_callback_t<rdb_protocol_t> *send_backfill_cb,
            traversal_progress_combiner_t *progress,
            read_token_pair_t *token,
            signal_t *interruptor)
        THROWS_ONLY(interrupted_exc_t);

    void receive_backfill(
            const rdb_protocol_t::backfill_chunk_t &chunk,
            write_token_pair_t *token,
            signal_t *interruptor)
        THROWS_ONLY(interrupted_exc_t);

    void reset_data(
            const rdb_protocol_t::region_t &subregion,
            const metainfo_t &new_metainfo,
            write_token_pair_t *token,
            write_durability_t durability,
            signal_t *interruptor)
            THROWS_ONLY(interrupted_exc_t) = 0;

private:
    fifo_enforcer_source_t token_source_;
    fifo_enforcer_sink_t token_sink_;

    order_sink_t order_sink_;

    rng_t rng_;
    metainfo_t metainfo_;
    std::map<store_key_t, std::pair<repli_timestamp_t, counted_t<const ql::datum_t> > > table_;

    DISABLE_COPYING(mock_store_t);
};

}  // namespace unittest

#endif  // UNITTEST_MOCK_STORE_HPP_
<commit_msg>Removed "= 0" on mock_store_t::reset_data.<commit_after>#ifndef UNITTEST_MOCK_STORE_HPP_
#define UNITTEST_MOCK_STORE_HPP_

#include "rdb_protocol/protocol.hpp"

namespace unittest {

class mock_store_t : public store_view_t<rdb_protocol_t> {
public:
    mock_store_t();
    ~mock_store_t();

    void new_read_token(object_buffer_t<fifo_enforcer_sink_t::exit_read_t> *token_out);
    void new_write_token(object_buffer_t<fifo_enforcer_sink_t::exit_write_t> *token_out);

    void do_get_metainfo(order_token_t order_token,
                         object_buffer_t<fifo_enforcer_sink_t::exit_read_t> *token,
                         signal_t *interruptor,
                         metainfo_t *out) THROWS_ONLY(interrupted_exc_t) = 0;

    void set_metainfo(const metainfo_t &new_metainfo,
                      order_token_t order_token,
                      object_buffer_t<fifo_enforcer_sink_t::exit_write_t> *token,
                      signal_t *interruptor) THROWS_ONLY(interrupted_exc_t) = 0;

    void read(
            DEBUG_ONLY(const metainfo_checker_t<rdb_protocol_t> &metainfo_checker, )
            const rdb_protocol_t::read_t &read,
            rdb_protocol_t::read_response_t *response,
            order_token_t order_token,
            read_token_pair_t *token,
            signal_t *interruptor)
        THROWS_ONLY(interrupted_exc_t);

    void write(
            DEBUG_ONLY(const metainfo_checker_t<rdb_protocol_t> &metainfo_checker, )
            const metainfo_t& new_metainfo,
            const rdb_protocol_t::write_t &write,
            rdb_protocol_t::write_response_t *response,
            write_durability_t durability,
            transition_timestamp_t timestamp,
            order_token_t order_token,
            write_token_pair_t *token,
            signal_t *interruptor)
        THROWS_ONLY(interrupted_exc_t);

    bool send_backfill(
            const region_map_t<rdb_protocol_t, state_timestamp_t> &start_point,
            send_backfill_callback_t<rdb_protocol_t> *send_backfill_cb,
            traversal_progress_combiner_t *progress,
            read_token_pair_t *token,
            signal_t *interruptor)
        THROWS_ONLY(interrupted_exc_t);

    void receive_backfill(
            const rdb_protocol_t::backfill_chunk_t &chunk,
            write_token_pair_t *token,
            signal_t *interruptor)
        THROWS_ONLY(interrupted_exc_t);

    void reset_data(
            const rdb_protocol_t::region_t &subregion,
            const metainfo_t &new_metainfo,
            write_token_pair_t *token,
            write_durability_t durability,
            signal_t *interruptor)
        THROWS_ONLY(interrupted_exc_t);

private:
    fifo_enforcer_source_t token_source_;
    fifo_enforcer_sink_t token_sink_;

    order_sink_t order_sink_;

    rng_t rng_;
    metainfo_t metainfo_;
    std::map<store_key_t, std::pair<repli_timestamp_t, counted_t<const ql::datum_t> > > table_;

    DISABLE_COPYING(mock_store_t);
};

}  // namespace unittest

#endif  // UNITTEST_MOCK_STORE_HPP_
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/include/usr/pnor/pnor_reasoncodes.H $                     */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2011,2015                        */
/* [+] Google Inc.                                                        */
/* [+] 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                                                     */
#ifndef __PNOR_REASONCODES_H
#define __PNOR_REASONCODES_H

#include <hbotcompid.H>

namespace PNOR
{
    enum PNORModuleId
    {
        // pnorrp.C
        MOD_PNORRP_WAITFORMESSAGE       = 0x01, /**< PnorRP::waitForMessage */
        MOD_PNORRP_COMPUTEDEVICEADDR    = 0x02, /**< PnorRP::computeDeviceAddr */
        MOD_PNORRP_GETSECTIONINFO       = 0x03, /**< PnorRP::getSectionInfo */
        MOD_PNORRP_COMPUTESECTION       = 0x04, /**< PnorRP::computeSection */
        MOD_PNORRP_INITDAEMON           = 0x05, /**< PnorRP::initDaemon */
        MOD_PNORRP_READTOC              = 0x06, /**< PnorRP::readTOC */
        MOD_PNORRP_READFROMDEVICE       = 0x07, /**< PnorRP::readFromDevice */
        MOD_PNORRP_WRITETODEVICE        = 0x08, /**< PnorRP::writeToDevice */
        MOD_PNORRP_DIDSTARTUPFAIL       = 0x09, /**< didStartupFail(rc) */
        MOD_PNORRP_FLUSH                = 0x0A, /**< mm_remove_pages */
        MOD_PNORRP_FIXECC               = 0x0B, /**< PnorRP::fixECC */
        MOD_PNORRP_FINDTOC              = 0x0C, /**< PnorRP::findTOC */
        MOD_PNORRP_GETSIDEINFO          = 0x0D, /**< PnorRP::getSideInfo */
        MOD_PNORRP_SETSIDEINFO          = 0x0E, /**< PnorRP::setSideInfo */

        // pnorvalid.C
        MOD_PNORVALID_MAIN              = 0x0E, /**< validateAltMaster */
        MOD_PNORVALID_MAGIC             = 0x0F, /**< validateAltMaster */

        // pnordd.C
        MOD_PNORDD_VERIFYADDRESSRANGE   = 0x11, /**< PnorDD::verifyAddressRange */
        MOD_PNORDD_READFLASH            = 0x12, /**< PnorDD::readFlash */
        MOD_PNORDD_WRITEFLASH           = 0x13, /**< PnorDD::writeFlash */
        MOD_PNORDD_SFCINIT              = 0x14, /**< PnorDD::sfcInit */
        MOD_PNORDD_ERASEFLASH           = 0x15, /**< PnorDD::eraseFlash */
        MOD_PNORDD_CHECKFORERRORS       = 0x16, /**< PnorDD::checkForErrors */

        // sfc_ibm.C
        MOD_SFCIBM_VERIFYADDRESSRANGE   = 0x40, /**< SfcIBM::verifyAddressRange */
        MOD_SFCIBM_READFLASH            = 0x41, /**< SfcIBM::readFlash */
        MOD_SFCIBM_WRITEFLASH           = 0x42, /**< SfcIBM::writeFlash */
        MOD_SFCIBM_POLLOPCOMPLETE       = 0x43, /**< SfcIBM::pollSfcOpComplete */
        MOD_SFCIBM_SFCINIT              = 0x44, /**< SfcIBM::sfcInit */
        MOD_SFCIBM_ERASEFLASH           = 0x45, /**< SfcIBM::eraseFlash */
        MOD_SFCIBM_CHECKFORERRORS       = 0x46, /**< SfcIBM::checkForErrors */
        MOD_SFCIBM_HWRESET              = 0x47, /**< SfcIBM::hwReset */

        // sfc_fake.C
        MOD_SFCFAKE_VERIFYADDRESSRANGE  = 0x60, /**< SfcFake::verifyAddressRange */
        MOD_SFCFAKE_READFLASH           = 0x61, /**< SfcFake::readFlash */
        MOD_SFCFAKE_WRITEFLASH          = 0x62, /**< SfcFake::writeFlash */
        MOD_SFCFAKE_ERASEFLASH          = 0x63, /**< SfcFake::eraseFlash */
        MOD_SFCFAKE_SENDSPICMD          = 0x64, /**< SfcFake::sendSpiCmd */

        // sfc_ast2400.C
        MOD_SFCAST2400_ENABLEWRITEMODE  = 0x80, /**< SfcAST2400::verifyAddressRange */
        MOD_SFCAST2400_READFLASH        = 0x81, /**< SfcAST2400::readFlash */
        MOD_SFCAST2400_WRITEFLASH       = 0x82, /**< SfcAST2400::writeFlash */
        MOD_SFCAST2400_POLLOPCOMPLETE   = 0x83, /**< SfcAST2400::pollSfcOpComplete */
        MOD_SFCAST2400_ERASEFLASH       = 0x84, /**< SfcAST2400::eraseFlash */

        // nor_micron.C
        MOD_NORMICRON_MICRONFLAGSTATUS  = 0xA0, /**< micronFlagStatus */

        //rt_pnor.C
        MOD_RTPNOR_GETSECTIONINFO       = 0xB0, /**< RtPnor::getSectionInfo*/
        MOD_RTPNOR_FLUSH                = 0xB1, /**< RtPnor::flush */
        MOD_RTPNOR_READFROMDEVICE       = 0xB2, /**< RtPnor::readFromDevice */
        MOD_RTPNOR_WRITETODEVICE        = 0xB3, /**< RtPnor::writeToDevice */

        //pnor_common.C
        MOD_PNORCOMMON_PARSETOC        = 0xC0, /**< PNOR::parseTOC */
    };

    enum PNORReasonCode
    {
        RC_INVALID_MESSAGE_TYPE      = PNOR_COMP_ID | 0x01,
        RC_INVALID_ADDRESS           = PNOR_COMP_ID | 0x02,
        RC_INVALID_SECTION           = PNOR_COMP_ID | 0x03,
        RC_EXTERNAL_ERROR            = PNOR_COMP_ID | 0x04,
        RC_STARTUP_FAIL              = PNOR_COMP_ID | 0x05,
        RC_INVALID_ASYNC_MESSAGE     = PNOR_COMP_ID | 0x06,
        RC_UNSUPPORTED_OPERATION     = PNOR_COMP_ID | 0x07,
        RC_LPC_ERROR                 = PNOR_COMP_ID | 0x08,
        RC_BAD_STARTUP_RC            = PNOR_COMP_ID | 0x09,
        //termination_rc
        RC_UNSUPPORTED_HARDWARE      = PNOR_COMP_ID | 0x0A,
        RC_MICRON_INCOMPLETE         = PNOR_COMP_ID | 0x0B,
        //termination_rc
        RC_PARTITION_TABLE_INVALID   = PNOR_COMP_ID | 0x0C,
        //termination_rc
        RC_UNSUPPORTED_MODE          = PNOR_COMP_ID | 0x0D,
        //termination_rc
        RC_UNSUPPORTED_SFCRANGE      = PNOR_COMP_ID | 0x0E,
        //termination_rc
        RC_ECC_UE                    = PNOR_COMP_ID | 0x0F,
        RC_ERROR_IN_STATUS_REG       = PNOR_COMP_ID | 0x10,
        //termination_rc
        RC_REINITIALIZE_SFC          = PNOR_COMP_ID | 0x11,
        RC_SFC_ERROR                 = PNOR_COMP_ID | 0x12,
        //termination_rc
        RC_PNOR_INIT_FAILURE         = PNOR_COMP_ID | 0x13,
        RC_CANNOT_ENABLE_WRITES      = PNOR_COMP_ID | 0x14,
        RC_SFC_TIMEOUT               = PNOR_COMP_ID | 0x15,
        RC_PNOR_READ_FAILED          = PNOR_COMP_ID | 0x16,
        RC_PNOR_WRITE_FAILED         = PNOR_COMP_ID | 0x17,
        RC_CORRUPTED_TOCS            = PNOR_COMP_ID | 0x18,
        RC_BAD_TOC_HEADER            = PNOR_COMP_ID | 0x19,
        RC_SECTION_SIZE_IS_BIG       = PNOR_COMP_ID | 0x1A,
        RC_RTPNOR_INVALID_SECTION    = PNOR_COMP_ID | 0x1B,
        RC_UNCORRECTABLE_ECC         = PNOR_COMP_ID | 0x1C,
        RC_SECTION_SIZE_IS_ZERO      = PNOR_COMP_ID | 0x1D,
        RC_MM_REMOVE_PAGES_FAILED    = PNOR_COMP_ID | 0x1E,
        RC_PNOR_READ_NOT_SUPPORTED   = PNOR_COMP_ID | 0x1F,
        RC_PNOR_WRITE_NOT_SUPPORTED  = PNOR_COMP_ID | 0x20,
        RC_NON_ECC_PROTECTED_SECTION = PNOR_COMP_ID | 0x21,
        RC_WRITABLE_PERM_FAIL        = PNOR_COMP_ID | 0x22,
        RC_WRITE_TRACKED_PERM_FAIL   = PNOR_COMP_ID | 0x23,
        //termination_rc
        RC_PARTITION_TABLE_NOT_FOUND = PNOR_COMP_ID | 0x24,
        //termination_rc
        RC_PARTITION_TABLE_CORRUPTED = PNOR_COMP_ID | 0x25,
        //termination_rc
        RC_FINDTOC_FAILED            = PNOR_COMP_ID | 0x26,
        RC_INVALID_PNOR_SIDE         = PNOR_COMP_ID | 0x27,
        //termination_rc
        RC_INVALID_WORKING_TOC       = PNOR_COMP_ID | 0x28,
        RC_INVALID_TOC               = PNOR_COMP_ID | 0x29,
        RC_WRONG_SIZE_FROM_READ      = PNOR_COMP_ID | 0x2A,
    };

    enum UserDetailsTypes
    {
        PNOR_UDT_NO_FORMAT           = 0x0,
        PNOR_UDT_PNORDD_PARAMETERS   = 0x1,
    };
};

#endif
<commit_msg>Add RC for HWSV to correct PNOR corruption<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/include/usr/pnor/pnor_reasoncodes.H $                     */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2011,2015                        */
/* [+] Google Inc.                                                        */
/* [+] 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                                                     */
#ifndef __PNOR_REASONCODES_H
#define __PNOR_REASONCODES_H

#include <hbotcompid.H>

namespace PNOR
{
    enum PNORModuleId
    {
        // pnorrp.C
        MOD_PNORRP_WAITFORMESSAGE       = 0x01, /**< PnorRP::waitForMessage */
        MOD_PNORRP_COMPUTEDEVICEADDR    = 0x02, /**< PnorRP::computeDeviceAddr */
        MOD_PNORRP_GETSECTIONINFO       = 0x03, /**< PnorRP::getSectionInfo */
        MOD_PNORRP_COMPUTESECTION       = 0x04, /**< PnorRP::computeSection */
        MOD_PNORRP_INITDAEMON           = 0x05, /**< PnorRP::initDaemon */
        MOD_PNORRP_READTOC              = 0x06, /**< PnorRP::readTOC */
        MOD_PNORRP_READFROMDEVICE       = 0x07, /**< PnorRP::readFromDevice */
        MOD_PNORRP_WRITETODEVICE        = 0x08, /**< PnorRP::writeToDevice */
        MOD_PNORRP_DIDSTARTUPFAIL       = 0x09, /**< didStartupFail(rc) */
        MOD_PNORRP_FLUSH                = 0x0A, /**< mm_remove_pages */
        MOD_PNORRP_FIXECC               = 0x0B, /**< PnorRP::fixECC */
        MOD_PNORRP_FINDTOC              = 0x0C, /**< PnorRP::findTOC */
        MOD_PNORRP_GETSIDEINFO          = 0x0D, /**< PnorRP::getSideInfo */
        MOD_PNORRP_SETSIDEINFO          = 0x0E, /**< PnorRP::setSideInfo */

        // pnorvalid.C
        MOD_PNORVALID_MAIN              = 0x0E, /**< validateAltMaster */
        MOD_PNORVALID_MAGIC             = 0x0F, /**< validateAltMaster */

        // pnordd.C
        MOD_PNORDD_VERIFYADDRESSRANGE   = 0x11, /**< PnorDD::verifyAddressRange */
        MOD_PNORDD_READFLASH            = 0x12, /**< PnorDD::readFlash */
        MOD_PNORDD_WRITEFLASH           = 0x13, /**< PnorDD::writeFlash */
        MOD_PNORDD_SFCINIT              = 0x14, /**< PnorDD::sfcInit */
        MOD_PNORDD_ERASEFLASH           = 0x15, /**< PnorDD::eraseFlash */
        MOD_PNORDD_CHECKFORERRORS       = 0x16, /**< PnorDD::checkForErrors */

        // sfc_ibm.C
        MOD_SFCIBM_VERIFYADDRESSRANGE   = 0x40, /**< SfcIBM::verifyAddressRange */
        MOD_SFCIBM_READFLASH            = 0x41, /**< SfcIBM::readFlash */
        MOD_SFCIBM_WRITEFLASH           = 0x42, /**< SfcIBM::writeFlash */
        MOD_SFCIBM_POLLOPCOMPLETE       = 0x43, /**< SfcIBM::pollSfcOpComplete */
        MOD_SFCIBM_SFCINIT              = 0x44, /**< SfcIBM::sfcInit */
        MOD_SFCIBM_ERASEFLASH           = 0x45, /**< SfcIBM::eraseFlash */
        MOD_SFCIBM_CHECKFORERRORS       = 0x46, /**< SfcIBM::checkForErrors */
        MOD_SFCIBM_HWRESET              = 0x47, /**< SfcIBM::hwReset */

        // sfc_fake.C
        MOD_SFCFAKE_VERIFYADDRESSRANGE  = 0x60, /**< SfcFake::verifyAddressRange */
        MOD_SFCFAKE_READFLASH           = 0x61, /**< SfcFake::readFlash */
        MOD_SFCFAKE_WRITEFLASH          = 0x62, /**< SfcFake::writeFlash */
        MOD_SFCFAKE_ERASEFLASH          = 0x63, /**< SfcFake::eraseFlash */
        MOD_SFCFAKE_SENDSPICMD          = 0x64, /**< SfcFake::sendSpiCmd */

        // sfc_ast2400.C
        MOD_SFCAST2400_ENABLEWRITEMODE  = 0x80, /**< SfcAST2400::verifyAddressRange */
        MOD_SFCAST2400_READFLASH        = 0x81, /**< SfcAST2400::readFlash */
        MOD_SFCAST2400_WRITEFLASH       = 0x82, /**< SfcAST2400::writeFlash */
        MOD_SFCAST2400_POLLOPCOMPLETE   = 0x83, /**< SfcAST2400::pollSfcOpComplete */
        MOD_SFCAST2400_ERASEFLASH       = 0x84, /**< SfcAST2400::eraseFlash */

        // nor_micron.C
        MOD_NORMICRON_MICRONFLAGSTATUS  = 0xA0, /**< micronFlagStatus */

        //rt_pnor.C
        MOD_RTPNOR_GETSECTIONINFO       = 0xB0, /**< RtPnor::getSectionInfo*/
        MOD_RTPNOR_FLUSH                = 0xB1, /**< RtPnor::flush */
        MOD_RTPNOR_READFROMDEVICE       = 0xB2, /**< RtPnor::readFromDevice */
        MOD_RTPNOR_WRITETODEVICE        = 0xB3, /**< RtPnor::writeToDevice */

        //pnor_common.C
        MOD_PNORCOMMON_PARSETOC        = 0xC0, /**< PNOR::parseTOC */
    };

    enum PNORReasonCode
    {
        RC_INVALID_MESSAGE_TYPE      = PNOR_COMP_ID | 0x01,
        RC_INVALID_ADDRESS           = PNOR_COMP_ID | 0x02,
        RC_INVALID_SECTION           = PNOR_COMP_ID | 0x03,
        RC_EXTERNAL_ERROR            = PNOR_COMP_ID | 0x04,
        RC_STARTUP_FAIL              = PNOR_COMP_ID | 0x05,
        RC_INVALID_ASYNC_MESSAGE     = PNOR_COMP_ID | 0x06,
        RC_UNSUPPORTED_OPERATION     = PNOR_COMP_ID | 0x07,
        RC_LPC_ERROR                 = PNOR_COMP_ID | 0x08,
        RC_BAD_STARTUP_RC            = PNOR_COMP_ID | 0x09,
        //termination_rc
        RC_UNSUPPORTED_HARDWARE      = PNOR_COMP_ID | 0x0A,
        RC_MICRON_INCOMPLETE         = PNOR_COMP_ID | 0x0B,
        //termination_rc
        RC_PARTITION_TABLE_INVALID   = PNOR_COMP_ID | 0x0C,
        //termination_rc
        RC_UNSUPPORTED_MODE          = PNOR_COMP_ID | 0x0D,
        //termination_rc
        RC_UNSUPPORTED_SFCRANGE      = PNOR_COMP_ID | 0x0E,
        //termination_rc
        RC_ECC_UE                    = PNOR_COMP_ID | 0x0F,
        RC_ERROR_IN_STATUS_REG       = PNOR_COMP_ID | 0x10,
        //termination_rc
        RC_REINITIALIZE_SFC          = PNOR_COMP_ID | 0x11,
        RC_SFC_ERROR                 = PNOR_COMP_ID | 0x12,
        //termination_rc
        RC_PNOR_INIT_FAILURE         = PNOR_COMP_ID | 0x13,
        RC_CANNOT_ENABLE_WRITES      = PNOR_COMP_ID | 0x14,
        RC_SFC_TIMEOUT               = PNOR_COMP_ID | 0x15,
        RC_PNOR_READ_FAILED          = PNOR_COMP_ID | 0x16,
        RC_PNOR_WRITE_FAILED         = PNOR_COMP_ID | 0x17,
        RC_CORRUPTED_TOCS            = PNOR_COMP_ID | 0x18,
        RC_BAD_TOC_HEADER            = PNOR_COMP_ID | 0x19,
        RC_SECTION_SIZE_IS_BIG       = PNOR_COMP_ID | 0x1A,
        RC_RTPNOR_INVALID_SECTION    = PNOR_COMP_ID | 0x1B,
        RC_UNCORRECTABLE_ECC         = PNOR_COMP_ID | 0x1C,
        RC_SECTION_SIZE_IS_ZERO      = PNOR_COMP_ID | 0x1D,
        RC_MM_REMOVE_PAGES_FAILED    = PNOR_COMP_ID | 0x1E,
        RC_PNOR_READ_NOT_SUPPORTED   = PNOR_COMP_ID | 0x1F,
        RC_PNOR_WRITE_NOT_SUPPORTED  = PNOR_COMP_ID | 0x20,
        RC_NON_ECC_PROTECTED_SECTION = PNOR_COMP_ID | 0x21,
        RC_WRITABLE_PERM_FAIL        = PNOR_COMP_ID | 0x22,
        RC_WRITE_TRACKED_PERM_FAIL   = PNOR_COMP_ID | 0x23,
        //termination_rc
        RC_PARTITION_TABLE_NOT_FOUND = PNOR_COMP_ID | 0x24,
        //termination_rc
        RC_PARTITION_TABLE_CORRUPTED = PNOR_COMP_ID | 0x25,
        //termination_rc
        RC_FINDTOC_FAILED            = PNOR_COMP_ID | 0x26,
        RC_INVALID_PNOR_SIDE         = PNOR_COMP_ID | 0x27,
        //termination_rc
        RC_INVALID_WORKING_TOC       = PNOR_COMP_ID | 0x28,
        RC_INVALID_TOC               = PNOR_COMP_ID | 0x29,
        RC_WRONG_SIZE_FROM_READ      = PNOR_COMP_ID | 0x2A,

        //@fixme-RTC:131607-Temporary value to allow HWSV compile
        //termination_rc
        RC_PNOR_CORRUPTION           = PNOR_COMP_ID | 0x99,
    };

    enum UserDetailsTypes
    {
        PNOR_UDT_NO_FORMAT           = 0x0,
        PNOR_UDT_PNORDD_PARAMETERS   = 0x1,
    };
};

#endif
<|endoftext|>


<commit_before>//
// Copyright RIME Developers
// Distributed under the BSD License
//
// 2011-11-23 GONG Chen <chen.sst@gmail.com>
//
#include <algorithm>
#include <rime/common.h>
#include <rime/composition.h>
#include <rime/context.h>
#include <rime/engine.h>
#include <rime/key_event.h>
#include <rime/key_table.h>
#include <rime/schema.h>
#include <rime/switcher.h>
#include <rime/gear/key_binder.h>

using namespace std::placeholders;

namespace rime {

enum KeyBindingCondition {
  kNever,
  kWhenPaging,     // user has changed page
  kWhenHasMenu,    // at least one candidate
  kWhenComposing,  // input string is not empty
  kAlways,
};

static struct KeyBindingConditionDef {
  KeyBindingCondition condition;
  const char* name;
} condition_definitions[] = {
  { kWhenPaging,    "paging"    },
  { kWhenHasMenu,   "has_menu"  },
  { kWhenComposing, "composing" },
  { kAlways,        "always"    },
  { kNever,         NULL        }
};

static KeyBindingCondition translate_condition(const string& str) {
  for (auto* d = condition_definitions; d->name; ++d) {
    if (str == d->name)
      return d->condition;
  }
  return kNever;
}

struct KeyBinding {
  KeyBindingCondition whence;
  KeyEvent target;
  function<void (Engine* engine)> action;

  bool operator< (const KeyBinding& o) const {
    return whence < o.whence;
  }
};

class KeyBindings : public map<KeyEvent,
                                    vector<KeyBinding>> {
 public:
  void LoadBindings(const an<ConfigList>& bindings);
  void Bind(const KeyEvent& key, const KeyBinding& binding);
};

static void toggle_option(Engine* engine, const string& option) {
  if (!engine)
    return;
  Context* ctx = engine->context();
  ctx->set_option(option, !ctx->get_option(option));
}
static void set_option(Engine* engine, const string& option) {
  if (!engine)
    return;
  Context* ctx = engine->context();
  ctx->set_option(option, 1);
}
static void unset_option(Engine* engine, const string& option) {
  if (!engine)
    return;
  Context* ctx = engine->context();
  ctx->set_option(option, 0);
}

static void select_schema(Engine* engine, const string& schema) {
  if (!engine)
    return;
  if (schema == ".next") {
    Switcher switcher(engine);
    switcher.SelectNextSchema();
  }
  else {
    engine->ApplySchema(new Schema(schema));
  }
}

void KeyBindings::LoadBindings(const an<ConfigList>& bindings) {
  if (!bindings)
    return;
  for (size_t i = 0; i < bindings->size(); ++i) {
    auto map = As<ConfigMap>(bindings->GetAt(i));
    if (!map)
      continue;
    auto whence = map->GetValue("when");
    if (!whence)
      continue;
    auto pattern = map->GetValue("accept");
    if (!pattern)
      continue;
    KeyBinding binding;
    binding.whence = translate_condition(whence->str());
    if (binding.whence == kNever) {
      continue;
    }
    KeyEvent key;
    if (!key.Parse(pattern->str())) {
      LOG(WARNING) << "invalid key binding #" << i << ".";
      continue;
    }
    if (auto target = map->GetValue("send")) {
      if (!binding.target.Parse(target->str())) {
        LOG(WARNING) << "invalid key binding #" << i << ".";
        continue;
      }
    }
    else if (auto option = map->GetValue("toggle")) {
      binding.action = std::bind(&toggle_option, _1, option->str());
    }
    else if (auto option = map->GetValue("set_option")) {
      binding.action = std::bind(&set_option, _1, option->str());
    }
    else if (auto option = map->GetValue("unset_option")) {
      binding.action = std::bind(&unset_option, _1, option->str());
    }
    else if (auto schema = map->GetValue("select")) {
      binding.action = std::bind(&select_schema, _1, schema->str());
    }
    else {
      LOG(WARNING) << "invalid key binding #" << i << ".";
      continue;
    }
    Bind(key, binding);
  }
}

void KeyBindings::Bind(const KeyEvent& key, const KeyBinding& binding) {
  auto& vec = (*this)[key];
  // insert before existing binding of the same condition
  auto lb = std::lower_bound(vec.begin(), vec.end(), binding);
  vec.insert(lb, binding);
}

KeyBinder::KeyBinder(const Ticket& ticket) : Processor(ticket),
                                             key_bindings_(new KeyBindings),
                                             redirecting_(false),
                                             last_key_(0) {
  LoadConfig();
}

class KeyBindingConditions : public set<KeyBindingCondition> {
 public:
  explicit KeyBindingConditions(Context* ctx);
};

KeyBindingConditions::KeyBindingConditions(Context* ctx) {
  insert(kAlways);

  if (ctx->IsComposing()) {
    insert(kWhenComposing);
  }

  if (ctx->HasMenu() && !ctx->get_option("ascii_mode")) {
    insert(kWhenHasMenu);
  }

  Composition& comp = ctx->composition();
  if (!comp.empty() && comp.back().HasTag("paging")) {
    insert(kWhenPaging);
  }
}

ProcessResult KeyBinder::ProcessKeyEvent(const KeyEvent& key_event) {
  if (redirecting_ || !key_bindings_ || key_bindings_->empty())
    return kNoop;
  if (ReinterpretPagingKey(key_event))
    return kNoop;
  if (key_bindings_->find(key_event) == key_bindings_->end())
    return kNoop;
  KeyBindingConditions conditions(engine_->context());
  for (const KeyBinding& binding : (*key_bindings_)[key_event]) {
    if (conditions.find(binding.whence) == conditions.end())
      continue;
    PerformKeyBinding(binding);
    return kAccepted;
  }
  // not handled
  return kNoop;
}

void KeyBinder::PerformKeyBinding(const KeyBinding& binding) {
  if (binding.action) {
    binding.action(engine_);
  }
  else {
    redirecting_ = true;
    engine_->ProcessKey(binding.target);
    redirecting_ = false;
  }
}

void KeyBinder::LoadConfig() {
  if (!engine_)
    return;
  Config* config = engine_->schema()->config();
  if (auto bindings = config->GetList("key_binder/bindings"))
    key_bindings_->LoadBindings(bindings);
}

bool KeyBinder::ReinterpretPagingKey(const KeyEvent& key_event) {
  if (key_event.release())
    return false;
  bool ret = false;
  int ch = (key_event.modifier() == 0) ? key_event.keycode() : 0;
  // reinterpret period key followed by alphabetic keys
  // unless period/comma key has been used multiple times
  if (ch == '.' && (last_key_ == '.' || last_key_ == ',')) {
    last_key_ = 0;
    return ret;
  }
  if (last_key_ == '.' && ch >= 'a' && ch <= 'z') {
    Context* ctx = engine_->context();
    const string& input(ctx->input());
    if (!input.empty() && input[input.length() - 1] != '.') {
      LOG(INFO) << "reinterpreted key: '" << last_key_
                << "', successor: '" << (char)ch << "'";
      ctx->PushInput(last_key_);
      ret = true;
    }
  }
  last_key_ = ch;
  return ret;
}

}  // namespace rime
<commit_msg>feat(key_binder): bind key to a key sequence Closes #301<commit_after>//
// Copyright RIME Developers
// Distributed under the BSD License
//
// 2011-11-23 GONG Chen <chen.sst@gmail.com>
//
#include <algorithm>
#include <rime/common.h>
#include <rime/composition.h>
#include <rime/context.h>
#include <rime/engine.h>
#include <rime/key_event.h>
#include <rime/key_table.h>
#include <rime/schema.h>
#include <rime/switcher.h>
#include <rime/gear/key_binder.h>

using namespace std::placeholders;

namespace rime {

enum KeyBindingCondition {
  kNever,
  kWhenPaging,     // user has changed page
  kWhenHasMenu,    // at least one candidate
  kWhenComposing,  // input string is not empty
  kAlways,
};

static struct KeyBindingConditionDef {
  KeyBindingCondition condition;
  const char* name;
} condition_definitions[] = {
  { kWhenPaging,    "paging"    },
  { kWhenHasMenu,   "has_menu"  },
  { kWhenComposing, "composing" },
  { kAlways,        "always"    },
  { kNever,         NULL        }
};

static KeyBindingCondition translate_condition(const string& str) {
  for (auto* d = condition_definitions; d->name; ++d) {
    if (str == d->name)
      return d->condition;
  }
  return kNever;
}

struct KeyBinding {
  KeyBindingCondition whence;
  KeySequence target;
  function<void (Engine* engine)> action;

  bool operator< (const KeyBinding& o) const {
    return whence < o.whence;
  }
};

class KeyBindings : public map<KeyEvent,
                                    vector<KeyBinding>> {
 public:
  void LoadBindings(const an<ConfigList>& bindings);
  void Bind(const KeyEvent& key, const KeyBinding& binding);
};

static void toggle_option(Engine* engine, const string& option) {
  if (!engine)
    return;
  Context* ctx = engine->context();
  ctx->set_option(option, !ctx->get_option(option));
}
static void set_option(Engine* engine, const string& option) {
  if (!engine)
    return;
  Context* ctx = engine->context();
  ctx->set_option(option, 1);
}
static void unset_option(Engine* engine, const string& option) {
  if (!engine)
    return;
  Context* ctx = engine->context();
  ctx->set_option(option, 0);
}

static void select_schema(Engine* engine, const string& schema) {
  if (!engine)
    return;
  if (schema == ".next") {
    Switcher switcher(engine);
    switcher.SelectNextSchema();
  }
  else {
    engine->ApplySchema(new Schema(schema));
  }
}

void KeyBindings::LoadBindings(const an<ConfigList>& bindings) {
  if (!bindings)
    return;
  for (size_t i = 0; i < bindings->size(); ++i) {
    auto map = As<ConfigMap>(bindings->GetAt(i));
    if (!map)
      continue;
    auto whence = map->GetValue("when");
    if (!whence)
      continue;
    auto pattern = map->GetValue("accept");
    if (!pattern)
      continue;
    KeyBinding binding;
    binding.whence = translate_condition(whence->str());
    if (binding.whence == kNever) {
      continue;
    }
    KeyEvent key;
    if (!key.Parse(pattern->str())) {
      LOG(WARNING) << "invalid key binding #" << i << ".";
      continue;
    }
    if (auto target = map->GetValue("send")) {
      KeyEvent key;
      if (key.Parse(target->str())) {
        binding.target.push_back(std::move(key));
      } else {
        LOG(WARNING) << "invalid key binding #" << i << ".";
        continue;
      }
    }
    else if (auto target = map->GetValue("send_sequence")) {
      if (!binding.target.Parse(target->str())) {
        LOG(WARNING) << "invalid key sequence #" << i << ".";
        continue;
      }
    }
    else if (auto option = map->GetValue("toggle")) {
      binding.action = std::bind(&toggle_option, _1, option->str());
    }
    else if (auto option = map->GetValue("set_option")) {
      binding.action = std::bind(&set_option, _1, option->str());
    }
    else if (auto option = map->GetValue("unset_option")) {
      binding.action = std::bind(&unset_option, _1, option->str());
    }
    else if (auto schema = map->GetValue("select")) {
      binding.action = std::bind(&select_schema, _1, schema->str());
    }
    else {
      LOG(WARNING) << "invalid key binding #" << i << ".";
      continue;
    }
    Bind(key, binding);
  }
}

void KeyBindings::Bind(const KeyEvent& key, const KeyBinding& binding) {
  auto& vec = (*this)[key];
  // insert before existing binding of the same condition
  auto lb = std::lower_bound(vec.begin(), vec.end(), binding);
  vec.insert(lb, binding);
}

KeyBinder::KeyBinder(const Ticket& ticket) : Processor(ticket),
                                             key_bindings_(new KeyBindings),
                                             redirecting_(false),
                                             last_key_(0) {
  LoadConfig();
}

class KeyBindingConditions : public set<KeyBindingCondition> {
 public:
  explicit KeyBindingConditions(Context* ctx);
};

KeyBindingConditions::KeyBindingConditions(Context* ctx) {
  insert(kAlways);

  if (ctx->IsComposing()) {
    insert(kWhenComposing);
  }

  if (ctx->HasMenu() && !ctx->get_option("ascii_mode")) {
    insert(kWhenHasMenu);
  }

  Composition& comp = ctx->composition();
  if (!comp.empty() && comp.back().HasTag("paging")) {
    insert(kWhenPaging);
  }
}

ProcessResult KeyBinder::ProcessKeyEvent(const KeyEvent& key_event) {
  if (redirecting_ || !key_bindings_ || key_bindings_->empty())
    return kNoop;
  if (ReinterpretPagingKey(key_event))
    return kNoop;
  if (key_bindings_->find(key_event) == key_bindings_->end())
    return kNoop;
  KeyBindingConditions conditions(engine_->context());
  for (const KeyBinding& binding : (*key_bindings_)[key_event]) {
    if (conditions.find(binding.whence) == conditions.end())
      continue;
    PerformKeyBinding(binding);
    return kAccepted;
  }
  // not handled
  return kNoop;
}

void KeyBinder::PerformKeyBinding(const KeyBinding& binding) {
  if (binding.action) {
    binding.action(engine_);
  }
  else {
    redirecting_ = true;
    for (const KeyEvent& key_event : binding.target) {
      engine_->ProcessKey(key_event);
    }
    redirecting_ = false;
  }
}

void KeyBinder::LoadConfig() {
  if (!engine_)
    return;
  Config* config = engine_->schema()->config();
  if (auto bindings = config->GetList("key_binder/bindings"))
    key_bindings_->LoadBindings(bindings);
}

bool KeyBinder::ReinterpretPagingKey(const KeyEvent& key_event) {
  if (key_event.release())
    return false;
  bool ret = false;
  int ch = (key_event.modifier() == 0) ? key_event.keycode() : 0;
  // reinterpret period key followed by alphabetic keys
  // unless period/comma key has been used multiple times
  if (ch == '.' && (last_key_ == '.' || last_key_ == ',')) {
    last_key_ = 0;
    return ret;
  }
  if (last_key_ == '.' && ch >= 'a' && ch <= 'z') {
    Context* ctx = engine_->context();
    const string& input(ctx->input());
    if (!input.empty() && input[input.length() - 1] != '.') {
      LOG(INFO) << "reinterpreted key: '" << last_key_
                << "', successor: '" << (char)ch << "'";
      ctx->PushInput(last_key_);
      ret = true;
    }
  }
  last_key_ = ch;
  return ret;
}

}  // namespace rime
<|endoftext|>


<commit_before>
template <typename T> __host__ __device__ Vector2<T>::Vector2() { x = y = 0; }

template <typename T>
__host__ __device__ Vector2<T>::Vector2(T _x, T _y) : x(_x), y(_y) {}

template <typename T>
__host__ __device__ Vector2<T>::Vector2(const Point2<T> &p) : x(p.x), y(p.y) {}

template <typename T> __host__ __device__ Vector2<T>::Vector2(T f) {
  x = y = f;
}

template <typename T> __host__ __device__ Vector2<T>::Vector2(T *f) {
  x = f[0];
  y = f[1];
}

template <typename T>
__host__ __device__ T Vector2<T>::operator[](size_t i) const {
  return (&x)[i];
}

template <typename T> __host__ __device__ T &Vector2<T>::operator[](size_t i) {
  return (&x)[i];
}

// arithmetic
template <typename T>
__host__ __device__ Vector2<T> Vector2<T>::
operator+(const Vector2<T> &v) const {
  return Vector2(x + v.x, y + v.y);
}

template <typename T>
__host__ __device__ Vector2<T> &Vector2<T>::operator+=(const Vector2<T> &v) {
  x += v.x;
  y += v.y;
  return *this;
}

template <typename T>
__host__ __device__ Vector2<T> Vector2<T>::
operator-(const Vector2<T> &v) const {
  return Vector2(x - v.x, y - v.y);
}

template <typename T>
__host__ __device__ Vector2<T> &Vector2<T>::operator-=(const Vector2<T> &v) {
  x -= v.x;
  y -= v.y;
  return *this;
}

template <typename T>
__host__ __device__ Vector2<T> Vector2<T>::operator*(T f) const {
  return Vector2(x * f, y * f);
}

template <typename T>
__host__ __device__ Vector2<T> &Vector2<T>::operator*=(T f) {
  x *= f;
  y *= f;
  return *this;
}

template <typename T>
__host__ __device__ Vector2<T> Vector2<T>::operator/(T f) const {
  CHECK_FLOAT_EQUAL(f, 0.f);
  T inv = 1.f / f;
  return Vector2(x * inv, y * inv);
}

template <typename T>
__host__ __device__ Vector2<T> &Vector2<T>::operator/=(T f) {
  CHECK_FLOAT_EQUAL(f, 0.f);
  T inv = 1.f / f;
  x *= inv;
  y *= inv;
  return *this;
}

template <typename T>
__host__ __device__ Vector2<T> Vector2<T>::operator-() const {
  return Vector2(-x, -y);
}

template <typename T>
__host__ __device__ bool Vector2<T>::operator==(const Vector2<T> &v) {
  return Check::isEqual(x, v.x) && Check::isEqual(y, v.y);
}

template <typename T> __host__ __device__ T Vector2<T>::length2() const {
  return x * x + y * y;
}

template <typename T> __host__ __device__ T Vector2<T>::length() const {
  return sqrtf(length2());
}

template <typename T> __host__ __device__ Vector2<T> Vector2<T>::right() const {
  return Vector2(y, -x);
}

template <typename T> __host__ __device__ Vector2<T> Vector2<T>::left() const {
  return Vector2(-y, x);
}

template <typename T>
__host__ __device__ std::ostream &operator<<(std::ostream &os,
                                             const Vector2<T> &v) {
  os << "[vector2]" << v.x << " " << v.y << std::endl;
  return os;
}

template <typename T> __host__ __device__ Vector3<T>::Vector3() {
  x = y = z = 0;
}

template <typename T>
__host__ __device__ Vector3<T>::Vector3(T _f) : x(_f), y(_f), z(_f) {}

template <typename T>
__host__ __device__ Vector3<T>::Vector3(T _x, T _y, T _z)
    : x(_x), y(_y), z(_z) {}

template <typename T> __host__ __device__ Vector3<T>::Vector3(const T *v) {
  x = v[0];
  y = v[1];
  z = v[2];
}

template <typename T>
__host__ __device__ Vector3<T>::Vector3(const Point3<T> &p)
    : x(p.x), y(p.y), z(p.z) {}

template <typename T>
__host__ __device__ bool Vector3<T>::operator==(const Vector3<T> &v) const {
  return Check::isEqual(x, v.x) && Check::isEqual(y, v.y) &&
         Check::isEqual(z, v.z);
}

template <typename T>
__host__ __device__ bool Vector3<T>::operator<(const Vector3<T> &v) const {
  if (x < v.x)
    return true;
  if (y < v.y)
    return true;
  return z < v.z;
}

template <typename T>
__host__ __device__ bool Vector3<T>::operator>(const Vector3<T> &v) const {
  if (x > v.x)
    return true;
  if (y > v.y)
    return true;
  return z > v.z;
}

template <typename T>
__host__ __device__ T Vector3<T>::operator[](int i) const {
  return (&x)[i];
}

template <typename T> __host__ __device__ T &Vector3<T>::operator[](int i) {
  return (&x)[i];
}

template <typename T>
__host__ __device__ Vector2<T> Vector3<T>::xy(int i, int j) const {
  T a = x;
  if (i == 1)
    a = y;
  else if (i == 2)
    a = z;
  T b = y;
  if (j == 0)
    b = x;
  else if (j == 2)
    b = z;
  return Vector2<T>(a, b);
}

template <typename T>
__host__ __device__ Vector3<T> &Vector3<T>::operator=(const T &v) {
  x = y = z = v;
  return *this;
}

template <typename T>
__host__ __device__ Vector3<T> Vector3<T>::
operator+(const Vector3<T> &v) const {
  return Vector3(x + v.x, y + v.y, z + v.z);
}

template <typename T>
__host__ __device__ Vector3<T> &Vector3<T>::operator+=(const Vector3<T> &v) {
  x += v.x;
  y += v.y;
  z += v.z;
  return *this;
}

template <typename T>
__host__ __device__ Vector3<T> Vector3<T>::
operator-(const Vector3<T> &v) const {
  return Vector3(x - v.x, y - v.y, z - v.z);
}

template <typename T>
__host__ __device__ Vector3<T> &Vector3<T>::operator-=(const Vector3<T> &v) {
  x -= v.x;
  y -= v.y;
  z -= v.z;
  return *this;
}

template <typename T>
__host__ __device__ Vector3<T> Vector3<T>::
operator*(const Vector3<T> &v) const {
  return Vector3(x * v.x, y * v.y, z * v.z);
}

template <typename T>
__host__ __device__ Vector3<T> Vector3<T>::operator*(T f) const {
  return Vector3(x * f, y * f, z * f);
}

template <typename T>
__host__ __device__ Vector3<T> &Vector3<T>::operator*=(T f) {
  x *= f;
  y *= f;
  z *= f;
  return *this;
}

template <typename T>
__host__ __device__ Vector3<T> Vector3<T>::operator/(T f) const {
  CHECK_FLOAT_EQUAL(f, 0.f);
  T inv = 1.f / f;
  return Vector3(x * inv, y * inv, z * inv);
}

template <typename T>
__host__ __device__ Vector3<T> &Vector3<T>::operator/=(T f) {
  CHECK_FLOAT_EQUAL(f, 0.f);
  T inv = 1.f / f;
  x *= inv;
  y *= inv;
  z *= inv;
  return *this;
}

template <typename T>
__host__ __device__ Vector3<T> &Vector3<T>::operator/=(const Vector3<T> &v) {
  x /= v.x;
  y /= v.y;
  z /= v.z;
  return *this;
}

template <typename T>
__host__ __device__ Vector3<T> Vector3<T>::operator-() const {
  return Vector3(-x, -y, -z);
}

template <typename T>
__host__ __device__ bool Vector3<T>::operator>=(const Vector3<T> &p) const {
  return x >= p.x && y >= p.y && z >= p.z;
}

template <typename T>
__host__ __device__ bool Vector3<T>::operator<=(const Vector3<T> &p) const {
  return x <= p.x && y <= p.y && z <= p.z;
}

template <typename T> __host__ __device__ T Vector3<T>::length2() const {
  return x * x + y * y + z * z;
}

template <typename T> __host__ __device__ T Vector3<T>::length() const {
  return sqrtf(length2());
}

template <typename T>
__host__ std::ostream &operator<<(std::ostream &os, const Vector3<T> &v) {
  os << "[vector3]" << v.x << " " << v.y << " " << v.z << std::endl;
  return os;
}

template <typename T>
__host__ __device__ T dot(const Vector3<T> &a, const Vector3<T> &b) {
  return a.x * b.x + a.y * b.y + a.z * b.z;
}

template <typename T>
__host__ __device__ Vector3<T> cross(const Vector3<T> &a, const Vector3<T> &b) {
  return Vector3<T>((a.y * b.z) - (a.z * b.y), (a.z * b.x) - (a.x * b.z),
                    (a.x * b.y) - (a.y * b.x));
}

template <typename T>
__host__ __device__ T triple(const Vector3<T> &a, const Vector3<T> &b,
                             const Vector3<T> &c) {
  return dot(a, cross(b, c));
}

template <typename T>
__host__ __device__ Vector3<T> normalize(const Vector3<T> &v) {
  if (v.length2() == 0.f)
    return v;
  return v / v.length();
}<commit_msg>check float equal bug<commit_after>
template <typename T> __host__ __device__ Vector2<T>::Vector2() { x = y = 0; }

template <typename T>
__host__ __device__ Vector2<T>::Vector2(T _x, T _y) : x(_x), y(_y) {}

template <typename T>
__host__ __device__ Vector2<T>::Vector2(const Point2<T> &p) : x(p.x), y(p.y) {}

template <typename T> __host__ __device__ Vector2<T>::Vector2(T f) {
  x = y = f;
}

template <typename T> __host__ __device__ Vector2<T>::Vector2(T *f) {
  x = f[0];
  y = f[1];
}

template <typename T>
__host__ __device__ T Vector2<T>::operator[](size_t i) const {
  return (&x)[i];
}

template <typename T> __host__ __device__ T &Vector2<T>::operator[](size_t i) {
  return (&x)[i];
}

// arithmetic
template <typename T>
__host__ __device__ Vector2<T> Vector2<T>::
operator+(const Vector2<T> &v) const {
  return Vector2(x + v.x, y + v.y);
}

template <typename T>
__host__ __device__ Vector2<T> &Vector2<T>::operator+=(const Vector2<T> &v) {
  x += v.x;
  y += v.y;
  return *this;
}

template <typename T>
__host__ __device__ Vector2<T> Vector2<T>::
operator-(const Vector2<T> &v) const {
  return Vector2(x - v.x, y - v.y);
}

template <typename T>
__host__ __device__ Vector2<T> &Vector2<T>::operator-=(const Vector2<T> &v) {
  x -= v.x;
  y -= v.y;
  return *this;
}

template <typename T>
__host__ __device__ Vector2<T> Vector2<T>::operator*(T f) const {
  return Vector2(x * f, y * f);
}

template <typename T>
__host__ __device__ Vector2<T> &Vector2<T>::operator*=(T f) {
  x *= f;
  y *= f;
  return *this;
}

template <typename T>
__host__ __device__ Vector2<T> Vector2<T>::operator/(T f) const {
  Check::isEqual(f, 0.f);
  T inv = 1.f / f;
  return Vector2(x * inv, y * inv);
}

template <typename T>
__host__ __device__ Vector2<T> &Vector2<T>::operator/=(T f) {
  Check::isEqual(f, 0.f);
  T inv = 1.f / f;
  x *= inv;
  y *= inv;
  return *this;
}

template <typename T>
__host__ __device__ Vector2<T> Vector2<T>::operator-() const {
  return Vector2(-x, -y);
}

template <typename T>
__host__ __device__ bool Vector2<T>::operator==(const Vector2<T> &v) {
  return Check::isEqual(x, v.x) && Check::isEqual(y, v.y);
}

template <typename T> __host__ __device__ T Vector2<T>::length2() const {
  return x * x + y * y;
}

template <typename T> __host__ __device__ T Vector2<T>::length() const {
  return sqrtf(length2());
}

template <typename T> __host__ __device__ Vector2<T> Vector2<T>::right() const {
  return Vector2(y, -x);
}

template <typename T> __host__ __device__ Vector2<T> Vector2<T>::left() const {
  return Vector2(-y, x);
}

template <typename T>
__host__ __device__ std::ostream &operator<<(std::ostream &os,
                                             const Vector2<T> &v) {
  os << "[vector2]" << v.x << " " << v.y << std::endl;
  return os;
}

template <typename T> __host__ __device__ Vector3<T>::Vector3() {
  x = y = z = 0;
}

template <typename T>
__host__ __device__ Vector3<T>::Vector3(T _f) : x(_f), y(_f), z(_f) {}

template <typename T>
__host__ __device__ Vector3<T>::Vector3(T _x, T _y, T _z)
    : x(_x), y(_y), z(_z) {}

template <typename T> __host__ __device__ Vector3<T>::Vector3(const T *v) {
  x = v[0];
  y = v[1];
  z = v[2];
}

template <typename T>
__host__ __device__ Vector3<T>::Vector3(const Point3<T> &p)
    : x(p.x), y(p.y), z(p.z) {}

template <typename T>
__host__ __device__ bool Vector3<T>::operator==(const Vector3<T> &v) const {
  return Check::isEqual(x, v.x) && Check::isEqual(y, v.y) &&
         Check::isEqual(z, v.z);
}

template <typename T>
__host__ __device__ bool Vector3<T>::operator<(const Vector3<T> &v) const {
  if (x < v.x)
    return true;
  if (y < v.y)
    return true;
  return z < v.z;
}

template <typename T>
__host__ __device__ bool Vector3<T>::operator>(const Vector3<T> &v) const {
  if (x > v.x)
    return true;
  if (y > v.y)
    return true;
  return z > v.z;
}

template <typename T>
__host__ __device__ T Vector3<T>::operator[](int i) const {
  return (&x)[i];
}

template <typename T> __host__ __device__ T &Vector3<T>::operator[](int i) {
  return (&x)[i];
}

template <typename T>
__host__ __device__ Vector2<T> Vector3<T>::xy(int i, int j) const {
  T a = x;
  if (i == 1)
    a = y;
  else if (i == 2)
    a = z;
  T b = y;
  if (j == 0)
    b = x;
  else if (j == 2)
    b = z;
  return Vector2<T>(a, b);
}

template <typename T>
__host__ __device__ Vector3<T> &Vector3<T>::operator=(const T &v) {
  x = y = z = v;
  return *this;
}

template <typename T>
__host__ __device__ Vector3<T> Vector3<T>::
operator+(const Vector3<T> &v) const {
  return Vector3(x + v.x, y + v.y, z + v.z);
}

template <typename T>
__host__ __device__ Vector3<T> &Vector3<T>::operator+=(const Vector3<T> &v) {
  x += v.x;
  y += v.y;
  z += v.z;
  return *this;
}

template <typename T>
__host__ __device__ Vector3<T> Vector3<T>::
operator-(const Vector3<T> &v) const {
  return Vector3(x - v.x, y - v.y, z - v.z);
}

template <typename T>
__host__ __device__ Vector3<T> &Vector3<T>::operator-=(const Vector3<T> &v) {
  x -= v.x;
  y -= v.y;
  z -= v.z;
  return *this;
}

template <typename T>
__host__ __device__ Vector3<T> Vector3<T>::
operator*(const Vector3<T> &v) const {
  return Vector3(x * v.x, y * v.y, z * v.z);
}

template <typename T>
__host__ __device__ Vector3<T> Vector3<T>::operator*(T f) const {
  return Vector3(x * f, y * f, z * f);
}

template <typename T>
__host__ __device__ Vector3<T> &Vector3<T>::operator*=(T f) {
  x *= f;
  y *= f;
  z *= f;
  return *this;
}

template <typename T>
__host__ __device__ Vector3<T> Vector3<T>::operator/(T f) const {
  Check::isEqual(f, 0.f);
  T inv = 1.f / f;
  return Vector3(x * inv, y * inv, z * inv);
}

template <typename T>
__host__ __device__ Vector3<T> &Vector3<T>::operator/=(T f) {
  Check::isEqual(f, 0.f);
  T inv = 1.f / f;
  x *= inv;
  y *= inv;
  z *= inv;
  return *this;
}

template <typename T>
__host__ __device__ Vector3<T> &Vector3<T>::operator/=(const Vector3<T> &v) {
  x /= v.x;
  y /= v.y;
  z /= v.z;
  return *this;
}

template <typename T>
__host__ __device__ Vector3<T> Vector3<T>::operator-() const {
  return Vector3(-x, -y, -z);
}

template <typename T>
__host__ __device__ bool Vector3<T>::operator>=(const Vector3<T> &p) const {
  return x >= p.x && y >= p.y && z >= p.z;
}

template <typename T>
__host__ __device__ bool Vector3<T>::operator<=(const Vector3<T> &p) const {
  return x <= p.x && y <= p.y && z <= p.z;
}

template <typename T> __host__ __device__ T Vector3<T>::length2() const {
  return x * x + y * y + z * z;
}

template <typename T> __host__ __device__ T Vector3<T>::length() const {
  return sqrtf(length2());
}

template <typename T>
__host__ std::ostream &operator<<(std::ostream &os, const Vector3<T> &v) {
  os << "[vector3]" << v.x << " " << v.y << " " << v.z << std::endl;
  return os;
}

template <typename T>
__host__ __device__ T dot(const Vector3<T> &a, const Vector3<T> &b) {
  return a.x * b.x + a.y * b.y + a.z * b.z;
}

template <typename T>
__host__ __device__ Vector3<T> cross(const Vector3<T> &a, const Vector3<T> &b) {
  return Vector3<T>((a.y * b.z) - (a.z * b.y), (a.z * b.x) - (a.x * b.z),
                    (a.x * b.y) - (a.y * b.x));
}

template <typename T>
__host__ __device__ T triple(const Vector3<T> &a, const Vector3<T> &b,
                             const Vector3<T> &c) {
  return dot(a, cross(b, c));
}

template <typename T>
__host__ __device__ Vector3<T> normalize(const Vector3<T> &v) {
  if (v.length2() == 0.f)
    return v;
  return v / v.length();
}<|endoftext|>


<commit_before>/**
 * @file hybrid_height.cpp
 *
 * @date Apr 5, 2013
 * @author peramaki
 */

#include "hybrid_height.h"
#include "plugin_factory.h"
#include "logger_factory.h"
#include <boost/lexical_cast.hpp>
#include <boost/thread.hpp>

#define HIMAN_AUXILIARY_INCLUDE

#include "neons.h"

#undef HIMAN_AUXILIARY_INCLUDE

using namespace std;
using namespace himan::plugin;

const string itsName("hybrid_height");

hybrid_height::hybrid_height() : itsFastMode(false)
{
	itsClearTextFormula = "HEIGHT = prevH + (287/9.81) * (T+prevT)/2 * log(prevP / P)";
	itsLogger = logger_factory::Instance()->GetLog(itsName);

}

void hybrid_height::Process(std::shared_ptr<const plugin_configuration> conf)
{
	Init(conf);

	SetParams({param("HL-M", 3, 0, 3, 6)});

	/*
	 * For hybrid height we must go through the levels backwards.
	 */

	itsInfo->LevelOrder(kBottomToTop);

	shared_ptr<neons> theNeons = dynamic_pointer_cast <neons> (plugin_factory::Instance()->Plugin("neons"));

	itsBottomLevel = boost::lexical_cast<int> (theNeons->ProducerMetaData(itsConfiguration->SourceProducer().Id(), "last hybrid level number"));

	itsUseGeopotential = (itsConfiguration->SourceProducer().Id() == 1 || itsConfiguration->SourceProducer().Id() == 199);

	if (!itsConfiguration->Exists("fast_mode") && itsConfiguration->GetValue("fast_mode") == "true")
	{
		itsFastMode = true;
	}
	else if (!itsUseGeopotential)
	{
		// When doing exact calculation we must do them sequentially starting from
		// surface closest to ground because every surface's value is depended
		// on the surface below it. Therefore we cannot parallelize the calculation
		// on level basis.

		if (Dimension() != kTimeDimension)
		{
			itsLogger->Info("Changing leading_dimension to time");
			Dimension(kTimeDimension);
		}
	}

	Start();

}

/*
 * Calculate()
 *
 * This function does the actual calculation.
 */

void hybrid_height::Calculate(shared_ptr<info> myTargetInfo, unsigned short threadIndex)
{

	const param GPParam("P-PA");
	const params PParam= {param("P-HPA"), param("P-PA")};
	const params TParam = { param("T-K"), param("TG-K")};
	const param ZParam("Z-M2S2");

	level H2;//(himan::kHeight, 2, "HEIGHT");
	level H0;//(himan::kHeight, 0, "HEIGHT");
	if ( itsConfiguration->SourceProducer().Id() == 131)
	{
		H2 = level(himan::kGndLayer, 0, "GROUND");
		H0 = level(himan::kGndLayer, 0, "GNDLAYER");
	}
	else
	{
		H2 = level(himan::kHeight, 2, "HEIGHT");
		H0 = level(himan::kHeight, 0, "HEIGHT");
	}

	auto myThreadedLogger = logger_factory::Instance()->GetLog(itsName + "Thread #" + boost::lexical_cast<string> (threadIndex));

	forecast_time forecastTime = myTargetInfo->Time();
	level forecastLevel = myTargetInfo->Level();

	myThreadedLogger->Info("Calculating time " + static_cast<string>(*forecastTime.ValidDateTime()) + " level " + static_cast<string> (forecastLevel));

	/*
		pitääkö tunnistaa tuottaja?
	*/

	level prevLevel;

	bool firstLevel = false;

	if (itsFastMode || myTargetInfo->Level().Value() == itsBottomLevel)
	{
		firstLevel = true;
	}
	else
	{
		prevLevel = level(myTargetInfo->Level());
		prevLevel.Value(myTargetInfo->Level().Value() + 1);

		prevLevel.Index(prevLevel.Index() + 1);
	}

	info_t TInfo, PInfo, prevPInfo, prevTInfo, prevHInfo, GPInfo, zeroGPInfo;

	if (itsUseGeopotential)
	{
		GPInfo = Fetch(forecastTime, forecastLevel, ZParam, false);
		zeroGPInfo = Fetch(forecastTime, H0, ZParam, false);

		SetAB(myTargetInfo, GPInfo);

	}
	else
	{

		if (!firstLevel)
		{
			prevTInfo = Fetch(forecastTime, prevLevel, TParam, false);
			prevPInfo = Fetch(forecastTime, prevLevel, PParam, false);
			prevHInfo = Fetch(forecastTime, prevLevel, param("HL-M"), false);
		}
		else
		{
			prevPInfo = Fetch(forecastTime, H0, GPParam, false);
			prevTInfo = Fetch(forecastTime, H2, TParam, false);
		}

		PInfo = Fetch(forecastTime, forecastLevel, PParam, false);
		TInfo = Fetch(forecastTime, forecastLevel, TParam, false);

		assert(PInfo->Grid()->AB() == TInfo->Grid()->AB());

		SetAB(myTargetInfo, TInfo);

	}

	if ((itsUseGeopotential && (!GPInfo || !zeroGPInfo)) || (!itsUseGeopotential && (!prevTInfo || !prevPInfo || !prevHInfo || !PInfo || !TInfo)))
	{
		myThreadedLogger->Warning("Skipping step " + boost::lexical_cast<string> (forecastTime.Step()) + ", level " + static_cast<string> (forecastLevel));
		return;
	}

	string deviceType = "CPU";

	if (itsUseGeopotential)
	{
		GPInfo->ResetLocation();
		zeroGPInfo->ResetLocation();
	}
	else
	{
		PInfo->ResetLocation();
		TInfo->ResetLocation();
		prevPInfo->ResetLocation();
		prevTInfo->ResetLocation();
		prevHInfo->ResetLocation();
	}

	LOCKSTEP(myTargetInfo)
	{

		if (itsUseGeopotential)
		{
			GPInfo->NextLocation();
			double GP = GPInfo->Value();

			zeroGPInfo->NextLocation();
			double zeroGP = zeroGPInfo->Value();

			if (GP == kFloatMissing || zeroGP == kFloatMissing)
			{
				continue;
			}

			double height = (GP - zeroGP) * himan::constants::kIg;

			myTargetInfo->Value(height);
		}
		else
		{
			TInfo->NextLocation();
			double T = TInfo->Value();

			PInfo->NextLocation();
			double P = PInfo->Value();

			prevTInfo->NextLocation();
			double prevT = prevTInfo->Value();

			prevPInfo->NextLocation();
			double prevP = prevPInfo->Value();

			double prevH = kFloatMissing;

			if (!firstLevel)
			{

				prevHInfo->NextLocation();
				prevH = prevHInfo->Value();

				if (prevH == kFloatMissing )
				{
					continue;
				}
			}

			if (prevT == kFloatMissing || prevP == kFloatMissing || T == kFloatMissing || P == kFloatMissing )
			{
				continue;
			}

			if (firstLevel)
			{
				prevP /= 100.f;
			}

			double Tave = ( T + prevT ) / 2;
			double deltaZ = (287 / 9.81) * Tave * log(prevP / P);

			double totalHeight(0);

			if (firstLevel)
			{
				totalHeight = deltaZ;
			}
			else
			{
				totalHeight = prevH + deltaZ;
			}

			myTargetInfo->Value(totalHeight);

		}
	}

	if (!itsFastMode)
	{
		firstLevel = false;
	}

	myThreadedLogger->Info("[" + deviceType + "] Missing values: " + boost::lexical_cast<string> (myTargetInfo->Data()->MissingCount()) + "/" + boost::lexical_cast<string> (myTargetInfo->Data()->Size()));

}
<commit_msg>some ec fixes<commit_after>/**
 * @file hybrid_height.cpp
 *
 * @date Apr 5, 2013
 * @author peramaki
 */

#include "hybrid_height.h"
#include "plugin_factory.h"
#include "logger_factory.h"
#include <boost/lexical_cast.hpp>
#include <boost/thread.hpp>

#define HIMAN_AUXILIARY_INCLUDE

#include "neons.h"

#undef HIMAN_AUXILIARY_INCLUDE

using namespace std;
using namespace himan::plugin;

const string itsName("hybrid_height");

hybrid_height::hybrid_height() : itsFastMode(false)
{
	itsClearTextFormula = "HEIGHT = prevH + (287/9.81) * (T+prevT)/2 * log(prevP / P)";
	itsLogger = logger_factory::Instance()->GetLog(itsName);

}

void hybrid_height::Process(std::shared_ptr<const plugin_configuration> conf)
{
	Init(conf);

	SetParams({param("HL-M", 3, 0, 3, 6)});

	/*
	 * For hybrid height we must go through the levels backwards.
	 */

	itsInfo->LevelOrder(kBottomToTop);

	shared_ptr<neons> theNeons = dynamic_pointer_cast <neons> (plugin_factory::Instance()->Plugin("neons"));

	itsBottomLevel = boost::lexical_cast<int> (theNeons->ProducerMetaData(itsConfiguration->SourceProducer().Id(), "last hybrid level number"));

	itsUseGeopotential = (itsConfiguration->SourceProducer().Id() == 1 || itsConfiguration->SourceProducer().Id() == 199);

	if (!itsConfiguration->Exists("fast_mode") && itsConfiguration->GetValue("fast_mode") == "true")
	{
		itsFastMode = true;
	}
	else if (!itsUseGeopotential)
	{
		// When doing exact calculation we must do them sequentially starting from
		// surface closest to ground because every surface's value is depended
		// on the surface below it. Therefore we cannot parallelize the calculation
		// on level basis.

		if (Dimension() != kTimeDimension)
		{
			itsLogger->Info("Changing leading_dimension to time");
			Dimension(kTimeDimension);
		}
	}

	Start();

}

/*
 * Calculate()
 *
 * This function does the actual calculation.
 */

void hybrid_height::Calculate(shared_ptr<info> myTargetInfo, unsigned short threadIndex)
{

	const params GPParam { param("PGR-PA"), param("P-PA") };
	const param PParam("P-HPA");
	const params TParam = { param("T-K"), param("TG-K") };
	const param ZParam("Z-M2S2");

	level H2;//(himan::kHeight, 2, "HEIGHT");
	level H0;//(himan::kHeight, 0, "HEIGHT");
	if ( itsConfiguration->SourceProducer().Id() == 131)
	{
		H2 = level(himan::kGround, 0, "GROUND");
		H0 = level(himan::kGround, 0, "GROUND");
	}
	else
	{
		H2 = level(himan::kHeight, 2, "HEIGHT");
		H0 = level(himan::kHeight, 0, "HEIGHT");
	}

	auto myThreadedLogger = logger_factory::Instance()->GetLog(itsName + "Thread #" + boost::lexical_cast<string> (threadIndex));

	forecast_time forecastTime = myTargetInfo->Time();
	level forecastLevel = myTargetInfo->Level();

	myThreadedLogger->Info("Calculating time " + static_cast<string>(*forecastTime.ValidDateTime()) + " level " + static_cast<string> (forecastLevel));

	/*
		pitääkö tunnistaa tuottaja?
	*/

	level prevLevel;

	bool firstLevel = false;

	if (itsFastMode || myTargetInfo->Level().Value() == itsBottomLevel)
	{
		firstLevel = true;
	}
	else
	{
		prevLevel = level(myTargetInfo->Level());
		prevLevel.Value(myTargetInfo->Level().Value() + 1);

		prevLevel.Index(prevLevel.Index() + 1);
	}

	info_t TInfo, PInfo, prevPInfo, prevTInfo, prevHInfo, GPInfo, zeroGPInfo;

	if (itsUseGeopotential)
	{
		GPInfo = Fetch(forecastTime, forecastLevel, ZParam, false);
		zeroGPInfo = Fetch(forecastTime, H0, ZParam, false);

		SetAB(myTargetInfo, GPInfo);

	}
	else
	{

		if (!firstLevel)
		{
			prevTInfo = Fetch(forecastTime, prevLevel, TParam, false);
			prevPInfo = Fetch(forecastTime, prevLevel, PParam, false);
			prevHInfo = Fetch(forecastTime, prevLevel, param("HL-M"), false);
		}
		else
		{
			prevPInfo = Fetch(forecastTime, H0, GPParam, false);
			prevTInfo = Fetch(forecastTime, H2, TParam, false);
		}

		PInfo = Fetch(forecastTime, forecastLevel, PParam, false);
		TInfo = Fetch(forecastTime, forecastLevel, TParam, false);

		assert(PInfo->Grid()->AB() == TInfo->Grid()->AB());

		SetAB(myTargetInfo, TInfo);

	}

	if ((itsUseGeopotential && (!GPInfo || !zeroGPInfo)) || (!itsUseGeopotential && (!prevTInfo || !prevPInfo || ( !prevHInfo && !firstLevel ) || !PInfo || !TInfo)))
	{
		myThreadedLogger->Warning("Skipping step " + boost::lexical_cast<string> (forecastTime.Step()) + ", level " + static_cast<string> (forecastLevel));
		return;
	}

	string deviceType = "CPU";

	if (itsUseGeopotential)
	{
		GPInfo->ResetLocation();
		zeroGPInfo->ResetLocation();
	}
	else
	{
		PInfo->ResetLocation();
		TInfo->ResetLocation();
		prevPInfo->ResetLocation();
		prevTInfo->ResetLocation();
		if (!firstLevel)
		{
			prevHInfo->ResetLocation();
		}
	}

	LOCKSTEP(myTargetInfo)
	{

		if (itsUseGeopotential)
		{
			GPInfo->NextLocation();
			double GP = GPInfo->Value();

			zeroGPInfo->NextLocation();
			double zeroGP = zeroGPInfo->Value();

			if (GP == kFloatMissing || zeroGP == kFloatMissing)
			{
				continue;
			}

			double height = (GP - zeroGP) * himan::constants::kIg;

			myTargetInfo->Value(height);
		}
		else
		{
			TInfo->NextLocation();
			double T = TInfo->Value();

			PInfo->NextLocation();
			double P = PInfo->Value();

			prevTInfo->NextLocation();
			double prevT = prevTInfo->Value();

			prevPInfo->NextLocation();
			double prevP = prevPInfo->Value();

			double prevH = kFloatMissing;

			if (!firstLevel)
			{

				prevHInfo->NextLocation();
				prevH = prevHInfo->Value();

				if (prevH == kFloatMissing )
				{
					continue;
				}
			}

			if (prevT == kFloatMissing || prevP == kFloatMissing || T == kFloatMissing || P == kFloatMissing )
			{
				continue;
			}

			if (firstLevel )//&& !itsConfiguration->SourceProducer().Id() == 131)
			{
				prevP /= 100.f;
			}

			double Tave = ( T + prevT ) / 2;
			cout << "prevP: ";
			cout << prevP << endl;
			cout << "P: ";
			cout << P << endl;
			double deltaZ = (287 / 9.81) * Tave * log(prevP / P);
			cout << "D: ";
			cout << deltaZ << endl;
			double totalHeight(0);

			if (firstLevel)
			{
				totalHeight = deltaZ;
			}
			else
			{
				totalHeight = prevH + deltaZ;
			}

			myTargetInfo->Value(totalHeight);

		}
	}

	if (!itsFastMode)
	{
		firstLevel = false;
	}

	myThreadedLogger->Info("[" + deviceType + "] Missing values: " + boost::lexical_cast<string> (myTargetInfo->Data()->MissingCount()) + "/" + boost::lexical_cast<string> (myTargetInfo->Data()->Size()));

}
<|endoftext|>