<commit_before>//
// C++ Interface: BuiltinFuncs
//
// Description:
//
//
// Author: Carmelo Piccione <carmelo.piccione@gmail.com>, (C) 2007
//
// Copyright: See COPYING file that comes with this distribution
//
//

#ifndef _BUILTIN_FUNCS_HPP
#define _BUILTIN_FUNCS_HPP

#include "Common.hpp"
#include "Func.hpp"
#include <cmath>
#include <cstdlib>
#include <cassert>

#include "RandomNumberGenerators.hpp"

/* Wrappers for all the builtin functions
   The arg_list pointer is a list of floats. Its
   size is equal to the number of arguments the parameter
   takes */
class FuncWrappers {

/* Values to optimize the sigmoid function */
static const int R =  32767;
static const int RR = 65534;

public:

static inline float int_wrapper(float * arg_list) {

return floor(arg_list[0]);

}

static inline float sqr_wrapper(float * arg_list) {

return pow(2, arg_list[0]);
}

static inline float sign_wrapper(float * arg_list) {

return -arg_list[0];
}

static inline float min_wrapper(float * arg_list) {

if (arg_list[0] > arg_list[1])
return arg_list[1];

return arg_list[0];
}

static inline float max_wrapper(float * arg_list) {

if (arg_list[0] > arg_list[1])
return arg_list[0];

return arg_list[1];
}

/* consult your AI book */
static inline float sigmoid_wrapper(float * arg_list) {
return (RR / (1 + exp( -(((float)(arg_list[0])) * arg_list[1]) / R) - R));
}

static inline float bor_wrapper(float * arg_list) {

return (float)((int)arg_list[0] || (int)arg_list[1]);
}

static inline float band_wrapper(float * arg_list) {
return (float)((int)arg_list[0] && (int)arg_list[1]);
}

static inline float bnot_wrapper(float * arg_list) {
return (float)(!(int)arg_list[0]);
}

static inline float if_wrapper(float * arg_list) {

if ((int)arg_list[0] == 0)
return arg_list[2];
return arg_list[1];
}

static inline float rand_wrapper(float * arg_list) {
float l=1;

//  printf("RAND ARG:(%d)\n", (int)arg_list[0]);
if ((int)arg_list[0] > 0)
	l  = (float) RandomNumberGenerators::uniformInteger((int)arg_list[0]);

return l;
}

static inline float equal_wrapper(float * arg_list) {
	return (arg_list[0] == arg_list[1]);
}

static inline float above_wrapper(float * arg_list) {

return (arg_list[0] > arg_list[1]);
}

static inline float below_wrapper(float * arg_list) {

return (arg_list[0] < arg_list[1]);
}

static float sin_wrapper(float * arg_list) {

  assert(arg_list);
//return .5;
float d = sinf(*arg_list);
return d;
//return (sin (arg_list[0]));
}

static inline float cos_wrapper(float * arg_list) {
return (cos (arg_list[0]));
}

static inline float tan_wrapper(float * arg_list) {
return (tan(arg_list[0]));
}

static inline float asin_wrapper(float * arg_list) {
return (asin (arg_list[0]));
}

static inline float acos_wrapper(float * arg_list) {
return (acos (arg_list[0]));
}

static inline float atan_wrapper(float * arg_list) {
return (atan (arg_list[0]));
}

static inline float atan2_wrapper(float * arg_list) {
return (atan2 (arg_list[0], arg_list[1]));
}

static inline float pow_wrapper(float * arg_list) {
return (pow (arg_list[0], arg_list[1]));
}

static inline float exp_wrapper(float * arg_list) {
return (exp(arg_list[0]));
}

static inline float abs_wrapper(float * arg_list) {
return (fabs(arg_list[0]));
}

static inline float log_wrapper(float* arg_list) {
return (log (arg_list[0]));
}

static inline float log10_wrapper(float * arg_list) {
return (log10 (arg_list[0]));
}

static inline float sqrt_wrapper(float * arg_list) {
return (sqrt (arg_list[0]));
}

static inline float nchoosek_wrapper(float * arg_list) {
unsigned long cnm = 1UL;
int i, f;
int n, m;

n = (int)arg_list[0];
m = (int)arg_list[1];

if (m*2 >n) m = n-m;
for (i=1 ; i <= m; n--, i++)
{
if ((f=n) % i == 0)
f   /= i;
else  cnm /= i;
cnm *= f;
}
return (float)cnm;
}

static inline float fact_wrapper(float * arg_list) {

int result = 1;

int n = (int)arg_list[0];

while (n > 1) {
result = result * n;
n--;
}
return (float)result;
}
};

#include <map>
class BuiltinFuncs {

public:

    static int init_builtin_func_db();
    static int destroy_builtin_func_db();
    static int load_all_builtin_func();
    static int load_builtin_func( const std::string & name, float (*func_ptr)(float*), int num_args );

    static int insert_func( Func *func );
    static int remove_func( Func *func );
    static Func *find_func( const std::string & name );
private:
     static std::map<std::string, Func*> builtin_func_tree;
     static volatile bool initialized;
};

#endif
<commit_msg>another crucial fix by mastertrenten. --this line, and those below, will be ignored--<commit_after>//
// C++ Interface: BuiltinFuncs
//
// Description:
//
//
// Author: Carmelo Piccione <carmelo.piccione@gmail.com>, (C) 2007
//
// Copyright: See COPYING file that comes with this distribution
//
//

#ifndef _BUILTIN_FUNCS_HPP
#define _BUILTIN_FUNCS_HPP

#include "Common.hpp"
#include "Func.hpp"
#include <cmath>
#include <cstdlib>
#include <cassert>

#include "RandomNumberGenerators.hpp"

/* Wrappers for all the builtin functions
   The arg_list pointer is a list of floats. Its
   size is equal to the number of arguments the parameter
   takes */
class FuncWrappers {

/* Values to optimize the sigmoid function */
static const int R =  32767;
static const int RR = 65534;

public:

static inline float int_wrapper(float * arg_list) {

return floor(arg_list[0]);

}

static inline float sqr_wrapper(float * arg_list) {
	return pow(arg_list[0], 2);
}

static inline float sigmoid_wrapper(float * arg_list)
{
	const double t = (1+exp(-arg_list[0]*arg_list[1]));
	return (fabs(t) > 0.00001) ? 1.0/t : 0;
}

static inline float sign_wrapper(float * arg_list) {

return -arg_list[0];
}

static inline float min_wrapper(float * arg_list) {

if (arg_list[0] > arg_list[1])
return arg_list[1];

return arg_list[0];
}

static inline float max_wrapper(float * arg_list) {

if (arg_list[0] > arg_list[1])
return arg_list[0];

return arg_list[1];
}

static inline float bor_wrapper(float * arg_list) {

return (float)((int)arg_list[0] || (int)arg_list[1]);
}

static inline float band_wrapper(float * arg_list) {
return (float)((int)arg_list[0] && (int)arg_list[1]);
}

static inline float bnot_wrapper(float * arg_list) {
return (float)(!(int)arg_list[0]);
}

static inline float if_wrapper(float * arg_list) {

if ((int)arg_list[0] == 0)
return arg_list[2];
return arg_list[1];
}

static inline float rand_wrapper(float * arg_list) {
float l=1;

//  printf("RAND ARG:(%d)\n", (int)arg_list[0]);
if ((int)arg_list[0] > 0)
	l  = (float) RandomNumberGenerators::uniformInteger((int)arg_list[0]);

return l;
}

static inline float equal_wrapper(float * arg_list) {
	return (arg_list[0] == arg_list[1]);
}

static inline float above_wrapper(float * arg_list) {

return (arg_list[0] > arg_list[1]);
}

static inline float below_wrapper(float * arg_list) {

return (arg_list[0] < arg_list[1]);
}

static float sin_wrapper(float * arg_list) {

  assert(arg_list);
//return .5;
float d = sinf(*arg_list);
return d;
//return (sin (arg_list[0]));
}

static inline float cos_wrapper(float * arg_list) {
return (cos (arg_list[0]));
}

static inline float tan_wrapper(float * arg_list) {
return (tan(arg_list[0]));
}

static inline float asin_wrapper(float * arg_list) {
return (asin (arg_list[0]));
}

static inline float acos_wrapper(float * arg_list) {
return (acos (arg_list[0]));
}

static inline float atan_wrapper(float * arg_list) {
return (atan (arg_list[0]));
}

static inline float atan2_wrapper(float * arg_list) {
return (atan2 (arg_list[0], arg_list[1]));
}

static inline float pow_wrapper(float * arg_list) {
return (pow (arg_list[0], arg_list[1]));
}

static inline float exp_wrapper(float * arg_list) {
return (exp(arg_list[0]));
}

static inline float abs_wrapper(float * arg_list) {
return (fabs(arg_list[0]));
}

static inline float log_wrapper(float* arg_list) {
return (log (arg_list[0]));
}

static inline float log10_wrapper(float * arg_list) {
return (log10 (arg_list[0]));
}

static inline float sqrt_wrapper(float * arg_list) {
return (sqrt (arg_list[0]));
}

static inline float nchoosek_wrapper(float * arg_list) {
unsigned long cnm = 1UL;
int i, f;
int n, m;

n = (int)arg_list[0];
m = (int)arg_list[1];

if (m*2 >n) m = n-m;
for (i=1 ; i <= m; n--, i++)
{
if ((f=n) % i == 0)
f   /= i;
else  cnm /= i;
cnm *= f;
}
return (float)cnm;
}

static inline float fact_wrapper(float * arg_list) {

int result = 1;

int n = (int)arg_list[0];

while (n > 1) {
result = result * n;
n--;
}
return (float)result;
}
};

#include <map>
class BuiltinFuncs {

public:

    static int init_builtin_func_db();
    static int destroy_builtin_func_db();
    static int load_all_builtin_func();
    static int load_builtin_func( const std::string & name, float (*func_ptr)(float*), int num_args );

    static int insert_func( Func *func );
    static int remove_func( Func *func );
    static Func *find_func( const std::string & name );
private:
     static std::map<std::string, Func*> builtin_func_tree;
     static volatile bool initialized;
};

#endif
<|endoftext|>


<commit_before><commit_msg>Hardcoding version string for lef to 5.8<commit_after><|endoftext|>


<commit_before>/**
 * @file
 *
 * @brief Some common functions in use for testing framework
 *
 * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
 */

#ifndef KDB_TESTS_HPP
#define KDB_TESTS_HPP

#include <kdb.hpp>
#include <key.hpp>
#include <keyset.hpp>

#include <cstdlib>
#include <cstring>
#include <exception>
#include <iostream>
#include <string>

#include <gtest/gtest.h>

using namespace std;
using namespace kdb;

#define succeed_if(x, y) ASSERT_TRUE (x) << y;
#define exit_if_fail(x, y) ASSERT_TRUE (x) << y;
#define succeed_if_same(x, y, message) ASSERT_EQ (x, y) << message;

#endif
<commit_msg>Tests: Remove trailing semicolons from macros<commit_after>/**
 * @file
 *
 * @brief Some common functions in use for testing framework
 *
 * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
 */

#ifndef KDB_TESTS_HPP
#define KDB_TESTS_HPP

#include <kdb.hpp>
#include <key.hpp>
#include <keyset.hpp>

#include <cstdlib>
#include <cstring>
#include <exception>
#include <iostream>
#include <string>

#include <gtest/gtest.h>

using namespace std;
using namespace kdb;

#define succeed_if(x, y) ASSERT_TRUE (x) << y
#define exit_if_fail(x, y) ASSERT_TRUE (x) << y
#define succeed_if_same(x, y, message) ASSERT_EQ (x, y) << message

#endif
<|endoftext|>


<commit_before>#include "GHIElectronics_TinyCLR_Devices.h"

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::get_WriteBufferSize___I4(const TinyCLR_Interop_MethodData md) {

    return TinyCLR_Result::NotImplemented;
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::set_WriteBufferSize___VOID__I4(const TinyCLR_Interop_MethodData md) {

    return TinyCLR_Result::NotImplemented;
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::get_ReadBufferSize___I4(const TinyCLR_Interop_MethodData md) {

    return TinyCLR_Result::NotImplemented;
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::set_ReadBufferSize___VOID__I4(const TinyCLR_Interop_MethodData md) {

    return TinyCLR_Result::NotImplemented;
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::get_MessagesToWrite___I4(const TinyCLR_Interop_MethodData md) {

    return TinyCLR_Result::NotImplemented;
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::get_MessagesToRead___I4(const TinyCLR_Interop_MethodData md) {

    return TinyCLR_Result::NotImplemented;
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::get_CanWriteMessage___BOOLEAN(const TinyCLR_Interop_MethodData md) {

    return TinyCLR_Result::NotImplemented;
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::get_CanReadMessage___BOOLEAN(const TinyCLR_Interop_MethodData md) {

    return TinyCLR_Result::NotImplemented;
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::get_WriteErrorCount___I4(const TinyCLR_Interop_MethodData md) {

    return TinyCLR_Result::NotImplemented;
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::get_ReadErrorCount___I4(const TinyCLR_Interop_MethodData md) {

    return TinyCLR_Result::NotImplemented;
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::get_SourceClock___I4(const TinyCLR_Interop_MethodData md) {

    return TinyCLR_Result::NotImplemented;
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::Enable___VOID(const TinyCLR_Interop_MethodData md) {

    return TinyCLR_Result::NotImplemented;
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::Disable___VOID(const TinyCLR_Interop_MethodData md) {

    return TinyCLR_Result::NotImplemented;
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::WriteMessages___I4__SZARRAY_GHIElectronicsTinyCLRDevicesCanCanMessage__I4__I4(const TinyCLR_Interop_MethodData md) {

    return TinyCLR_Result::NotImplemented;
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::ReadMessages___I4__SZARRAY_GHIElectronicsTinyCLRDevicesCanCanMessage__I4__I4(const TinyCLR_Interop_MethodData md) {

    return TinyCLR_Result::NotImplemented;
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::SetBitTiming___VOID__GHIElectronicsTinyCLRDevicesCanCanBitTiming(const TinyCLR_Interop_MethodData md) {

    return TinyCLR_Result::NotImplemented;
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::SetExplicitFilters___VOID__SZARRAY_I4(const TinyCLR_Interop_MethodData md) {

    return TinyCLR_Result::NotImplemented;
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::SetGroupFilters___VOID__SZARRAY_I4__SZARRAY_I4(const TinyCLR_Interop_MethodData md) {

    return TinyCLR_Result::NotImplemented;
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::ClearWriteBuffer___VOID(const TinyCLR_Interop_MethodData md) {

    return TinyCLR_Result::NotImplemented;
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::ClearReadBuffer___VOID(const TinyCLR_Interop_MethodData md) {

    return TinyCLR_Result::NotImplemented;
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::Acquire___VOID(const TinyCLR_Interop_MethodData md) {

    return TinyCLR_Result::NotImplemented;
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::Release___VOID(const TinyCLR_Interop_MethodData md) {

    return TinyCLR_Result::NotImplemented;
}
<commit_msg>Implement CAN interopt<commit_after>#include "GHIElectronics_TinyCLR_Devices.h"
#include "GHIElectronics_TinyCLR_InteropUtil.h"

void TinyCLR_Can_ErrorReceivedIsr(const TinyCLR_Can_Controller* self, TinyCLR_Can_Error error) {
    auto interopProvider = reinterpret_cast<const TinyCLR_Interop_Manager*>(apiManager->FindDefault(apiManager, TinyCLR_Api_Type::InteropManager));

    auto controllerIndex = *(reinterpret_cast<int32_t*>(self->ApiInfo->State));

    if (interopProvider != nullptr)
        interopProvider->RaiseEvent(interopProvider, "GHIElectronics.TinyCLR.NativeEventNames.Can.ErrorReceived", self->ApiInfo->Name, controllerIndex, (uint64_t)error, 0, 0);
}

void TinyCLR_Can_MessageReceivedIsr(const TinyCLR_Can_Controller* self, size_t count) {
    auto interopProvider = reinterpret_cast<const TinyCLR_Interop_Manager*>(apiManager->FindDefault(apiManager, TinyCLR_Api_Type::InteropManager));

    auto controllerIndex = *(reinterpret_cast<int32_t*>(self->ApiInfo->State));

    if (interopProvider != nullptr)
        interopProvider->RaiseEvent(interopProvider, "GHIElectronics.TinyCLR.NativeEventNames.Can.MessageReceived", self->ApiInfo->Name, controllerIndex, (uint64_t)count, 0, 0);
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::get_WriteBufferSize___I4(const TinyCLR_Interop_MethodData md) {
    auto provider = reinterpret_cast<const TinyCLR_Can_Controller*>(TinyCLR_Interop_GetArgument(md, FIELD___impl___I));
    auto ret = TinyCLR_Interop_GetReturn(md);

    ret.Data.Numeric->I4 = provider->GetWriteBufferSize(provider);

    return TinyCLR_Result::Success;
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::set_WriteBufferSize___VOID__I4(const TinyCLR_Interop_MethodData md) {
    auto provider = reinterpret_cast<const TinyCLR_Can_Controller*>(TinyCLR_Interop_GetArgument(md, FIELD___impl___I));
    auto arg1 = TinyCLR_Interop_GetArguments(md, 0);

    return provider->SetWriteBufferSize(provider, arg1.Data.Numeric->U4);
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::get_ReadBufferSize___I4(const TinyCLR_Interop_MethodData md) {
    auto provider = reinterpret_cast<const TinyCLR_Can_Controller*>(TinyCLR_Interop_GetArgument(md, FIELD___impl___I));
    auto ret = TinyCLR_Interop_GetReturn(md);

    ret.Data.Numeric->I4 = provider->GetReadBufferSize(provider);

    return TinyCLR_Result::Success;
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::set_ReadBufferSize___VOID__I4(const TinyCLR_Interop_MethodData md) {
    auto provider = reinterpret_cast<const TinyCLR_Can_Controller*>(TinyCLR_Interop_GetArgument(md, FIELD___impl___I));
    auto arg1 = TinyCLR_Interop_GetArguments(md, 0);

    return provider->SetReadBufferSize(provider, arg1.Data.Numeric->U4);
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::get_MessagesToWrite___I4(const TinyCLR_Interop_MethodData md) {
    auto provider = reinterpret_cast<const TinyCLR_Can_Controller*>(TinyCLR_Interop_GetArgument(md, FIELD___impl___I));
    auto ret = TinyCLR_Interop_GetReturn(md);

    ret.Data.Numeric->I4 = provider->GetMessagesToWrite(provider);

    return TinyCLR_Result::Success;
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::get_MessagesToRead___I4(const TinyCLR_Interop_MethodData md) {
    auto provider = reinterpret_cast<const TinyCLR_Can_Controller*>(TinyCLR_Interop_GetArgument(md, FIELD___impl___I));
    auto ret = TinyCLR_Interop_GetReturn(md);

    ret.Data.Numeric->I4 = provider->GetMessagesToRead(provider);

    return TinyCLR_Result::Success;
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::get_CanWriteMessage___BOOLEAN(const TinyCLR_Interop_MethodData md) {
    auto provider = reinterpret_cast<const TinyCLR_Can_Controller*>(TinyCLR_Interop_GetArgument(md, FIELD___impl___I));
    auto ret = TinyCLR_Interop_GetReturn(md);

    ret.Data.Numeric->Boolean = provider->CanWriteMessage(provider);

    return TinyCLR_Result::Success;
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::get_CanReadMessage___BOOLEAN(const TinyCLR_Interop_MethodData md) {
    auto provider = reinterpret_cast<const TinyCLR_Can_Controller*>(TinyCLR_Interop_GetArgument(md, FIELD___impl___I));
    auto ret = TinyCLR_Interop_GetReturn(md);

    ret.Data.Numeric->Boolean = provider->CanReadMessage(provider);

    return TinyCLR_Result::Success;
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::get_WriteErrorCount___I4(const TinyCLR_Interop_MethodData md) {
    auto provider = reinterpret_cast<const TinyCLR_Can_Controller*>(TinyCLR_Interop_GetArgument(md, FIELD___impl___I));
    auto ret = TinyCLR_Interop_GetReturn(md);

    ret.Data.Numeric->I4 = provider->GetWriteErrorCount(provider);

    return TinyCLR_Result::Success;
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::get_ReadErrorCount___I4(const TinyCLR_Interop_MethodData md) {
    auto provider = reinterpret_cast<const TinyCLR_Can_Controller*>(TinyCLR_Interop_GetArgument(md, FIELD___impl___I));
    auto ret = TinyCLR_Interop_GetReturn(md);

    ret.Data.Numeric->I4 = provider->GetReadErrorCount(provider);

    return TinyCLR_Result::Success;
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::get_SourceClock___I4(const TinyCLR_Interop_MethodData md) {
    auto provider = reinterpret_cast<const TinyCLR_Can_Controller*>(TinyCLR_Interop_GetArgument(md, FIELD___impl___I));
    auto ret = TinyCLR_Interop_GetReturn(md);

    ret.Data.Numeric->I4 = provider->GetSourceClock(provider);

    return TinyCLR_Result::Success;
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::Enable___VOID(const TinyCLR_Interop_MethodData md) {
    auto provider = reinterpret_cast<const TinyCLR_Can_Controller*>(TinyCLR_Interop_GetArgument(md, FIELD___impl___I));

    return provider->Enable(provider);
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::Disable___VOID(const TinyCLR_Interop_MethodData md) {
    auto provider = reinterpret_cast<const TinyCLR_Can_Controller*>(TinyCLR_Interop_GetArgument(md, FIELD___impl___I));

    return provider->Disable(provider);
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::WriteMessages___I4__SZARRAY_GHIElectronicsTinyCLRDevicesCanCanMessage__I4__I4(const TinyCLR_Interop_MethodData md) {
    auto interop = md.InteropManager;

    uint8_t* data;

    uint32_t arbID;

    bool extendedId;
    bool remoteTransmissionRequest;

    size_t length;

    int32_t offset;
    int32_t count;
    int32_t sent = 0;

    const TinyCLR_Interop_ClrObject* msgObj;

    TinyCLR_Interop_ClrValue managedValueMessages, managedValueOffset, managedValueCount, ret;
    TinyCLR_Interop_ClrValue fldData, fldarbID, fldLen, fldRtr, fldEid;

    managedValueMessages = TinyCLR_Interop_GetArguments(md, 0);
    managedValueOffset = TinyCLR_Interop_GetArguments(md, 1);
    managedValueCount = TinyCLR_Interop_GetArguments(md, 2);
    ret = TinyCLR_Interop_GetReturn(md);

    offset = managedValueOffset.Data.Numeric->I4;
    count = managedValueCount.Data.Numeric->I4;

    auto msgArray = reinterpret_cast<TinyCLR_Interop_ClrObjectReference*>(managedValueMessages.Data.SzArray.Data);

    auto provider = reinterpret_cast<const TinyCLR_Can_Controller*>(TinyCLR_Interop_GetArgument(md, FIELD___impl___I));

    int i = 0;

    while (i < offset) {
        i++;
        msgArray++;
    }

    for (i = 0; i < count; i++) {
        interop->ExtractObjectFromReference(interop, msgArray, msgObj);

        interop->GetField(interop, msgObj, Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_CanMessage::FIELD___data___SZARRAY_U1, fldData);
        interop->GetField(interop, msgObj, Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_CanMessage::FIELD___ArbitrationId__BackingField___I4, fldarbID);
        interop->GetField(interop, msgObj, Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_CanMessage::FIELD___Length__BackingField___I4, fldLen);
        interop->GetField(interop, msgObj, Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_CanMessage::FIELD___IsRemoteTransmissionRequest__BackingField___BOOLEAN, fldRtr);
        interop->GetField(interop, msgObj, Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_CanMessage::FIELD___IsExtendedId__BackingField___BOOLEAN, fldEid);

        data = reinterpret_cast<uint8_t*>(fldData.Data.SzArray.Data);
        arbID = fldarbID.Data.Numeric->I4;
        length = fldLen.Data.Numeric->I4 & 0xFF;

        remoteTransmissionRequest = (fldRtr.Data.Numeric->I4 != 0) ? true : false;
        extendedId = (fldEid.Data.Numeric->I4 != 0) ? true : false;

        if (provider->WriteMessage(provider, arbID, extendedId, remoteTransmissionRequest, data, length) != TinyCLR_Result::Success)
            break;

        msgArray++;
        sent++;
    }

    ret.Data.Numeric->I4 = sent;

    return TinyCLR_Result::Success;
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::ReadMessages___I4__SZARRAY_GHIElectronicsTinyCLRDevicesCanCanMessage__I4__I4(const TinyCLR_Interop_MethodData md) {
    auto interop = md.InteropManager;

    uint8_t* data;

    uint32_t arbID;
    size_t length;

    bool extendedId;
    bool remoteTransmissionRequest;

    uint64_t ts;

    int32_t offset;
    int32_t count;
    int32_t sent = 0;

    const TinyCLR_Interop_ClrObject* msgObj;

    TinyCLR_Interop_ClrValue managedValueMessages, managedValueOffset, managedValueCount, ret;
    TinyCLR_Interop_ClrValue fldData, fldarbID, fldLen, fldRtr, fldEid, fldts;

    managedValueMessages = TinyCLR_Interop_GetArguments(md, 0);
    managedValueOffset = TinyCLR_Interop_GetArguments(md, 1);
    managedValueCount = TinyCLR_Interop_GetArguments(md, 2);
    ret = TinyCLR_Interop_GetReturn(md);

    offset = managedValueOffset.Data.Numeric->I4;
    count = managedValueCount.Data.Numeric->I4;

    auto msgArray = reinterpret_cast<TinyCLR_Interop_ClrObjectReference*>(managedValueMessages.Data.SzArray.Data);

    auto provider = reinterpret_cast<const TinyCLR_Can_Controller*>(TinyCLR_Interop_GetArgument(md, FIELD___impl___I));

    auto availableMsgCount = provider->GetMessagesToRead(provider);

    int32_t read = 0;

    if (availableMsgCount > count)
        availableMsgCount = count;

    int i = 0;

    while (i < offset) {
        i++;
        msgArray++;
    }

    for (i = 0; i < availableMsgCount; i++) {
        interop->ExtractObjectFromReference(interop, msgArray, msgObj);

        interop->GetField(interop, msgObj, Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_CanMessage::FIELD___data___SZARRAY_U1, fldData);
        interop->GetField(interop, msgObj, Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_CanMessage::FIELD___ArbitrationId__BackingField___I4, fldarbID);
        interop->GetField(interop, msgObj, Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_CanMessage::FIELD___Length__BackingField___I4, fldLen);
        interop->GetField(interop, msgObj, Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_CanMessage::FIELD___IsRemoteTransmissionRequest__BackingField___BOOLEAN, fldRtr);
        interop->GetField(interop, msgObj, Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_CanMessage::FIELD___IsExtendedId__BackingField___BOOLEAN, fldEid);
        interop->GetField(interop, msgObj, Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_CanMessage::FIELD___TimeStamp__BackingField___mscorlibSystemDateTime, fldts);

        data = reinterpret_cast<uint8_t*>(fldData.Data.SzArray.Data);

        if (provider->ReadMessage(provider, arbID, extendedId, remoteTransmissionRequest, data, length, ts) != TinyCLR_Result::Success)
            break;

        fldarbID.Data.Numeric->I4 = arbID;
        fldLen.Data.Numeric->I4 = length & 0xF;
        fldRtr.Data.Numeric->I4 = (remoteTransmissionRequest != false) ? 1 : 0;
        fldEid.Data.Numeric->I4 = (extendedId != false) ? 1 : 0;
        fldts.Data.Numeric->I8 = ts;

        read++;
        msgArray++;
    }

    ret.Data.Numeric->I4 = read;

    return TinyCLR_Result::Success;
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::SetBitTiming___VOID__GHIElectronicsTinyCLRDevicesCanCanBitTiming(const TinyCLR_Interop_MethodData md) {
    auto arg = TinyCLR_Interop_GetArguments(md, 0);
    auto arg1 = TinyCLR_Interop_GetField(md, arg.Object, Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_CanBitTiming::FIELD___Propagation__BackingField___I4);
    auto arg2 = TinyCLR_Interop_GetField(md, arg.Object, Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_CanBitTiming::FIELD___Phase1__BackingField___I4);
    auto arg3 = TinyCLR_Interop_GetField(md, arg.Object, Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_CanBitTiming::FIELD___Phase2__BackingField___I4);
    auto arg4 = TinyCLR_Interop_GetField(md, arg.Object, Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_CanBitTiming::FIELD___BaudratePrescaler__BackingField___I4);
    auto arg5 = TinyCLR_Interop_GetField(md, arg.Object, Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_CanBitTiming::FIELD___SynchronizationJumpWidth__BackingField___I4);
    auto arg6 = TinyCLR_Interop_GetField(md, arg.Object, Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_CanBitTiming::FIELD___UseMultiBitSampling__BackingField___BOOLEAN);

    auto provider = reinterpret_cast<const TinyCLR_Can_Controller*>(TinyCLR_Interop_GetArgument(md, FIELD___impl___I));

    int32_t propagation = arg1.Data.Numeric->I4;
    int32_t phase1 = arg2.Data.Numeric->I4;
    int32_t phase2 = arg3.Data.Numeric->I4;

    int32_t brp = arg4.Data.Numeric->I4;
    int32_t synchronizationJumpWidth = arg5.Data.Numeric->I4;
    int32_t useMultiBitSampling = arg6.Data.Numeric->Boolean;

    return  provider->SetBitTiming(provider, propagation, phase1, phase2, brp, synchronizationJumpWidth, useMultiBitSampling);
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::SetExplicitFilters___VOID__SZARRAY_I4(const TinyCLR_Interop_MethodData md) {
    auto provider = reinterpret_cast<const TinyCLR_Can_Controller*>(TinyCLR_Interop_GetArgument(md, FIELD___impl___I));
    auto arg = TinyCLR_Interop_GetArguments(md, 0);

    uint32_t* filterData = reinterpret_cast<uint32_t*>(arg.Data.SzArray.Data);

    int32_t length = arg.Data.SzArray.Length;

    if (filterData == nullptr || length == 0)
        return  TinyCLR_Result::NullReference;

    return provider->SetExplicitFilters(provider, filterData, length);
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::SetGroupFilters___VOID__SZARRAY_I4__SZARRAY_I4(const TinyCLR_Interop_MethodData md) {
    auto provider = reinterpret_cast<const TinyCLR_Can_Controller*>(TinyCLR_Interop_GetArgument(md, FIELD___impl___I));

    auto arg0 = TinyCLR_Interop_GetArguments(md, 0);
    auto arg1 = TinyCLR_Interop_GetArguments(md, 1);

    uint32_t* lowerBounds = reinterpret_cast<uint32_t*>(arg0.Data.SzArray.Data);
    uint32_t* upperBounds = reinterpret_cast<uint32_t*>(arg1.Data.SzArray.Data);

    size_t length = arg0.Data.SzArray.Length;

    if (lowerBounds == nullptr || upperBounds == nullptr || length == 0)
        return  TinyCLR_Result::NullReference;

    return provider->SetGroupFilters(provider, lowerBounds, upperBounds, length);
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::ClearWriteBuffer___VOID(const TinyCLR_Interop_MethodData md) {
    auto provider = reinterpret_cast<const TinyCLR_Can_Controller*>(TinyCLR_Interop_GetArgument(md, FIELD___impl___I));

    return provider->ClearWriteBuffer(provider);
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::ClearReadBuffer___VOID(const TinyCLR_Interop_MethodData md) {
    auto provider = reinterpret_cast<const TinyCLR_Can_Controller*>(TinyCLR_Interop_GetArgument(md, FIELD___impl___I));

    return provider->ClearReadBuffer(provider);
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::Acquire___VOID(const TinyCLR_Interop_MethodData md) {
    auto provider = reinterpret_cast<const TinyCLR_Can_Controller*>(TinyCLR_Interop_GetArgument(md, FIELD___impl___I));

    if (provider != nullptr) {
        if (provider->Acquire(provider) == TinyCLR_Result::Success) {
            provider->SetMessageReceivedHandler(provider, TinyCLR_Can_MessageReceivedIsr);
            provider->SetErrorReceivedHandler(provider, TinyCLR_Can_ErrorReceivedIsr);

            return TinyCLR_Result::Success;
        }

        return TinyCLR_Result::SharingViolation;
    }

    return TinyCLR_Result::ArgumentNull;
}

TinyCLR_Result Interop_GHIElectronics_TinyCLR_Devices_GHIElectronics_TinyCLR_Devices_Can_Provider_CanControllerApiWrapper::Release___VOID(const TinyCLR_Interop_MethodData md) {
    auto provider = reinterpret_cast<const TinyCLR_Can_Controller*>(TinyCLR_Interop_GetArgument(md, FIELD___impl___I));

    return provider->Release(provider);
}
<|endoftext|>


<commit_before>#include <iostream>
#include <vector>
#include <map>
#include <node.h>
#include <cmath>

#include "PSATResult.h"
#include "calculator/EstimateFLA.h"
#include "calculator/MotorCurrent.h"
#include "calculator/MotorEfficiency.h"
#include "calculator/MotorPowerFactor.h"
#include "calculator/OptimalPrePumpEff.h"
#include "calculator/OptimalSpecificSpeedCorrection.h"
#include "calculator/OptimalDeviationFactor.h"

using namespace v8;
using namespace std;

Isolate* iso;
Local<Object> inp;
Local<Object> r;

double Get(const char *nm) {
	auto rObj = inp->ToObject()->Get(String::NewFromUtf8(iso,nm));
	if (rObj->IsUndefined()) {
		cout << nm << endl;;
		assert(!"defined");
	}
	return rObj->NumberValue();
}
void SetR(const char *nm, double n) {
	r->Set(String::NewFromUtf8(iso,nm),Number::New(iso,n));
}

Motor::LineFrequency line() {
	return (Motor::LineFrequency)(int)(!Get("line"));
}
Motor::EfficiencyClass effCls() {
	return (Motor::EfficiencyClass)(int)Get("efficiency_class");
}
Pump::Drive drive() {
	return (Pump::Drive)(int)Get("drive");
}
Pump::Style style() {
	return (Pump::Style)(int)Get("pump_style");
}

void Setup(const FunctionCallbackInfo<Value>& args) {
	iso = args.GetIsolate();
	inp = args[0]->ToObject();
	r = Object::New(iso);
	args.GetReturnValue().Set(r);
}

void Results(const FunctionCallbackInfo<Value>& args) {
	Setup(args);

	Pump pump(style(),Get("pump_specified")/100,Get("pump_rated_speed"),drive(),
			Get("viscosity"),Get("specific_gravity"),Get("stages"),(Pump::Speed)(int)(!Get("fixed_speed")));
	Motor motor(line(),Get("motor_rated_power"),Get("motor_rated_speed"),effCls(),
			Get("efficiency"),Get("motor_rated_voltage"),Get("motor_rated_flc"),Get("margin"));
	Financial fin(Get("fraction")/100,Get("cost"));
	FieldData fd(Get("flow"),Get("head"),(FieldData::LoadEstimationMethod)(Get("motor_field_power")>0?0:1),
			Get("motor_field_power"),Get("motor_field_current"),Get("motor_field_voltage"));
	PSATResult psat(pump,motor,fin,fd);
	psat.calculateExisting();
	psat.calculateOptimal();
	auto ex = psat.getExisting(), opt = psat.getOptimal();

	map<const char *,vector<double>> out = {
		{"Pump Efficiency",{ex.pumpEfficiency_*100,opt.pumpEfficiency_*100}},
		{"Motor Rated Power",{ex.motorRatedPower_,opt.motorRatedPower_}},
		{"Motor Shaft Power",{ex.motorShaftPower_,opt.motorShaftPower_}},
		{"Pump Shaft Power",{ex.pumpShaftPower_,opt.pumpShaftPower_}},
		{"Motor Efficiency",{ex.motorEfficiency_,opt.motorEfficiency_}},
		{"Motor Power Factor",{ex.motorPowerFactor_,opt.motorPowerFactor_}},
		{"Motor Current",{ex.motorCurrent_,opt.motorCurrent_}},
		{"Motor Power", {ex.motorPower_,opt.motorPower_}},
		{"Annual Energy", {ex.annualEnergy_,opt.annualEnergy_}},
		{"Annual Cost", {ex.annualCost_*1000,opt.annualCost_*1000}},
		{"Savings Potential", {psat.getAnnualSavingsPotential()*1000,-1}},
		{"Optimization Rating", {psat.getOptimizationRating(),-1}}
	};
	for(auto p: out) {
		auto a = Array::New(iso);
		a->Set(0,Number::New(iso,p.second[0]));
		a->Set(1,Number::New(iso,p.second[1]));
		r->Set(String::NewFromUtf8(iso,p.first),a);
	}
}

void EstFLA(const FunctionCallbackInfo<Value>& args) {
	Setup(args);
	EstimateFLA fla(Get("motor_rated_power"),Get("motor_rated_speed"),line(),effCls(),
		Get("efficiency"),Get("motor_rated_voltage"));
	fla.calculate();
	args.GetReturnValue().Set(fla.getEstimatedFLA());
}

void MotorPerformance(const FunctionCallbackInfo<Value>& args) {
	Setup(args);

	MotorEfficiency mef(line(),Get("motor_rated_speed"),effCls(),Get("efficiency"),Get("motor_rated_power"),Get("load_factor"));
	auto mefVal = mef.calculate();
	SetR("efficiency",mefVal*100);

	MotorCurrent mc(Get("motor_rated_power"),Get("motor_rated_speed"),line(),effCls(),Get("efficiency"),Get("load_factor"),Get("motor_rated_voltage"),Get("flc"));
	auto mcVal = mc.calculate();
	SetR("current",mcVal/Get("flc")*100);

	MotorPowerFactor pf(Get("motor_rated_power"),Get("load_factor"),mcVal,mefVal,Get("motor_rated_voltage"));
	SetR("pf",pf.calculate()*100);
}

void PumpEfficiency(const FunctionCallbackInfo<Value>& args) {
	Setup(args);
	OptimalPrePumpEff pef(style(), 0, Get("flow"));
	auto v = pef.calculate();
	SetR("average",v);
	SetR("max",v*OptimalDeviationFactor(Get("flow")).calculate());
}

void AchievableEfficiency(const FunctionCallbackInfo<Value>& args) {
	Setup(args);
	args.GetReturnValue().Set(
		OptimalSpecificSpeedCorrection(style(), Get("specific_speed")).calculate()*100);
}

void Nema(const FunctionCallbackInfo<Value>& args) {
	Setup(args);

	args.GetReturnValue().Set(
		MotorEfficiency(line(),Get("motor_rated_speed"),effCls(),Get("efficiency"),Get("motor_rated_power"),1).calculate()*100
	);
}

//TODO round vs js round; loosen up to make next test case
void Check(double exp, double act, const char* nm="") {
	//cout << "e " << exp << "; a " << act << endl;
	// if (isnan(act) || (abs(exp-act)>.01*exp)) {
	auto p = 10;
	if (isnan(act) || ( (round(exp*p)/p)!=round(act*p)/p)) {
		printf("\"%s\" TEST FAILED: %f %f\n",nm,exp,act);
		assert(!"equal");
	}
}

void Check100(double exp, double act, const char* nm="") {
	Check(exp,act*100,nm);
}

void Test(const FunctionCallbackInfo<Value>& args) {
		EstimateFLA fla(200,1780,(Motor::LineFrequency)1,(Motor::EfficiencyClass)(1),0,460);
		fla.calculate();
		Check(225.8,fla.getEstimatedFLA());

// motor perf

	{
		MotorCurrent mc(200,1780,Motor::LineFrequency::FREQ60,Motor::EfficiencyClass::ENERGY_EFFICIENT,0,.25,460,225.8);
		auto mcVal = mc.calculate();
		Check100(36.11,mcVal/225.8);
	}
	{
		MotorEfficiency mef(Motor::LineFrequency::FREQ60,1780,Motor::EfficiencyClass::ENERGY_EFFICIENT,0,200,.75);
		auto mefVal = mef.calculate();
		Check100(95.69,mefVal);

		MotorCurrent mc(200,1780,Motor::LineFrequency::FREQ60,Motor::EfficiencyClass::ENERGY_EFFICIENT,0,.75,460,225.8);
		auto mcVal = mc.calculate();
		Check100(76.63,mcVal/225.8);

		MotorPowerFactor pf(200,.75,mcVal,mefVal,460);
		Check100(84.82,pf.calculate());
	}

//nema
	{
		MotorEfficiency mef(Motor::LineFrequency::FREQ60,1200, Motor::EfficiencyClass::ENERGY_EFFICIENT,0,200,1);
		//Check100(95,mef.calculate());
	}

//pump eff
	{
		OptimalPrePumpEff pef(Pump::Style::END_SUCTION_ANSI_API, 0, 2000);
		OptimalDeviationFactor df(2000);

		//cout <<  pef.calculate() << ";" << df.calculate();
		//Check(87.1,pef.calculate()*df.calculate());
	}

//spec speed

	{
		OptimalSpecificSpeedCorrection cor(Pump::Style::END_SUCTION_ANSI_API, 1170);
		//Check100(2.3,cor.calculate());
	}
	return;

	#define BASE \
		Pump pump(Pump::Style::END_SUCTION_ANSI_API,0,1780,Pump::Drive::DIRECT_DRIVE,\
			1,1,1,Pump::Speed::NOT_FIXED_SPEED);\
		Motor motor(Motor::LineFrequency::FREQ60,200,1780,\
				Motor::EfficiencyClass::ENERGY_EFFICIENT,0,460,225.8,0);\
		Financial fin(1,.05);\
		FieldData fd(2000,277,FieldData::LoadEstimationMethod::POWER,\
				150,0,460);

	#define CALC \
		PSATResult psat(pump,motor,fin,fd);\
		psat.calculateExisting();\
		auto ex = psat.getExisting();

	for (int i=1; i<=10000; i=i+2) {
		BASE
		CALC
		Check(ex.motorShaftPower_,ex.motorShaftPower_,"SAME");
	}

	{
		BASE
		motor.setMotorRpm(1786);
		fd.setMotorPower(80);
		CALC
		Check(101.9,ex.motorShaftPower_);
		Check100(95,ex.motorEfficiency_);
		Check100(79.1,ex.motorPowerFactor_);
		Check(127,ex.motorCurrent_);
	}
	{
		BASE
		fd.setMotorPower(80);
		motor.setMotorRatedPower(100);
		motor.setFullLoadAmps(113.8);
		CALC
		Check(101.8,ex.motorShaftPower_);
		Check100(94.9,ex.motorEfficiency_);
		Check100(86.7,ex.motorPowerFactor_);
		Check(115.8,ex.motorCurrent_);
	}
	{
		BASE
		fd.setMotorPower(80);
		fd.setVoltage(260);
		CALC
		Check(101.9,ex.motorShaftPower_);
		Check100(95,ex.motorEfficiency_);
		Check100(138.8,ex.motorPowerFactor_);
		Check(128,ex.motorCurrent_);
	}
	{
		BASE
		motor.setMotorRpm(1200);
		fd.setMotorPower(80);
		motor.setFullLoadAmps(235.3);
		CALC
		Check(101.4,ex.motorShaftPower_);
		Check100(94.5,ex.motorEfficiency_);
		Check100(74.3,ex.motorPowerFactor_);
		Check(135.1,ex.motorCurrent_);
	}
	{
		BASE
		fd.setMotorPower(111.855);
		CALC
		Check(143.4,ex.motorShaftPower_);
		Check100(95.6,ex.motorEfficiency_);
		Check100(84.3,ex.motorPowerFactor_);
		Check(166.5,ex.motorCurrent_);
	}
	{
		BASE
		fd.setMotorPower(80);
		motor.setMotorRatedVoltage(200);
		motor.setFullLoadAmps(519.3);
		CALC
		Check(101.9,ex.motorShaftPower_);
		Check100(95,ex.motorEfficiency_);
		Check100(35.2,ex.motorPowerFactor_);
		Check(284.9,ex.motorCurrent_);
	}
	{
		BASE
		CALC
		Check(217.5,ex.motorCurrent_);
	}
	{
		BASE
		fd.setLoadEstimationMethod(FieldData::LoadEstimationMethod::CURRENT);
		fd.setMotorAmps(218);
		fd.setMotorPower(0);
		CALC
		Check(150.4,ex.motorPower_);
		Check100(72.5,ex.pumpEfficiency_);
	}
	{
		BASE
		fd.setMotorPower(80);
		CALC
		Check(700.8,ex.annualEnergy_);
	}
	{
		BASE
		fin.setOperatingFraction(.25);
		CALC
		Check(328.5,ex.annualEnergy_);
		Check(16.4,ex.annualCost_);
	}
	{
		BASE
		motor.setFullLoadAmps(300);
		CALC
		Check(288.9,ex.motorCurrent_);
	}
	{
		BASE
		motor.setEfficiencyClass(Motor::EfficiencyClass(0));
		CALC
		Check(213.7,ex.motorCurrent_);
	}
	{
		BASE
		motor.setEfficiencyClass(Motor::EfficiencyClass(2));
		motor.setSpecifiedEfficiency(75);
		CALC
		Check(173.7,ex.motorCurrent_);
	}
	cout << "done";
}

void InitTest(const FunctionCallbackInfo<Value>& args) {
	Setup(args);
	args.GetReturnValue().Set(String::NewFromUtf8(iso,"SUCCESS"));
}

void Init(Local<Object> exports) {
	NODE_SET_METHOD(exports, "results", Results);
	NODE_SET_METHOD(exports, "estFLA", EstFLA);
	NODE_SET_METHOD(exports, "motorPerformance", MotorPerformance);
	NODE_SET_METHOD(exports, "pumpEfficiency", PumpEfficiency);
	NODE_SET_METHOD(exports, "achievableEfficiency", AchievableEfficiency);
	NODE_SET_METHOD(exports, "nema", Nema);
	NODE_SET_METHOD(exports, "test", Test);
	NODE_SET_METHOD(exports, "initTest", InitTest);
}

NODE_MODULE(bridge, Init)

<commit_msg>no message<commit_after>#include <iostream>
#include <vector>
#include <map>
#include <node.h>
#include <cmath>

#include "PSATResult.h"
#include "calculator/EstimateFLA.h"
#include "calculator/MotorCurrent.h"
#include "calculator/MotorEfficiency.h"
#include "calculator/MotorPowerFactor.h"
#include "calculator/OptimalPrePumpEff.h"
#include "calculator/OptimalSpecificSpeedCorrection.h"
#include "calculator/OptimalDeviationFactor.h"

using namespace v8;
using namespace std;

// Setup

Isolate* iso;
Local<Object> inp;
Local<Object> r;

void Setup(const FunctionCallbackInfo<Value>& args) {
	iso = args.GetIsolate();
	inp = args[0]->ToObject();
	r = Object::New(iso);
	args.GetReturnValue().Set(r);
}

double Get(const char *nm) {
	auto rObj = inp->ToObject()->Get(String::NewFromUtf8(iso,nm));
	if (rObj->IsUndefined()) {
		cout << nm << endl;;
		assert(!"defined");
	}
	return rObj->NumberValue();
}

void SetR(const char *nm, double n) {
	r->Set(String::NewFromUtf8(iso,nm),Number::New(iso,n));
}

// Fields

Motor::LineFrequency line() {
	return (Motor::LineFrequency)(int)(!Get("line"));
}
Motor::EfficiencyClass effCls() {
	return (Motor::EfficiencyClass)(int)Get("efficiency_class");
}
Pump::Drive drive() {
	return (Pump::Drive)(int)Get("drive");
}
Pump::Style style() {
	return (Pump::Style)(int)Get("pump_style");
}

// Operations

void Results(const FunctionCallbackInfo<Value>& args) {
	Setup(args);

	Pump pump(style(),Get("pump_specified")/100,Get("pump_rated_speed"),drive(),
			Get("viscosity"),Get("specific_gravity"),Get("stages"),(Pump::Speed)(int)(!Get("fixed_speed")));
	Motor motor(line(),Get("motor_rated_power"),Get("motor_rated_speed"),effCls(),
			Get("efficiency"),Get("motor_rated_voltage"),Get("motor_rated_flc"),Get("margin"));
	Financial fin(Get("fraction")/100,Get("cost"));
	FieldData fd(Get("flow"),Get("head"),(FieldData::LoadEstimationMethod)(Get("motor_field_power")>0?0:1),
			Get("motor_field_power"),Get("motor_field_current"),Get("motor_field_voltage"));
	PSATResult psat(pump,motor,fin,fd);
	psat.calculateExisting();
	psat.calculateOptimal();
	auto ex = psat.getExisting(), opt = psat.getOptimal();

	map<const char *,vector<double>> out = {
		{"Pump Efficiency",{ex.pumpEfficiency_*100,opt.pumpEfficiency_*100}},
		{"Motor Rated Power",{ex.motorRatedPower_,opt.motorRatedPower_}},
		{"Motor Shaft Power",{ex.motorShaftPower_,opt.motorShaftPower_}},
		{"Pump Shaft Power",{ex.pumpShaftPower_,opt.pumpShaftPower_}},
		{"Motor Efficiency",{ex.motorEfficiency_,opt.motorEfficiency_}},
		{"Motor Power Factor",{ex.motorPowerFactor_,opt.motorPowerFactor_}},
		{"Motor Current",{ex.motorCurrent_,opt.motorCurrent_}},
		{"Motor Power", {ex.motorPower_,opt.motorPower_}},
		{"Annual Energy", {ex.annualEnergy_,opt.annualEnergy_}},
		{"Annual Cost", {ex.annualCost_*1000,opt.annualCost_*1000}},
		{"Savings Potential", {psat.getAnnualSavingsPotential()*1000,-1}},
		{"Optimization Rating", {psat.getOptimizationRating(),-1}}
	};
	for(auto p: out) {
		auto a = Array::New(iso);
		a->Set(0,Number::New(iso,p.second[0]));
		a->Set(1,Number::New(iso,p.second[1]));
		r->Set(String::NewFromUtf8(iso,p.first),a);
	}
}

void EstFLA(const FunctionCallbackInfo<Value>& args) {
	Setup(args);
	EstimateFLA fla(Get("motor_rated_power"),Get("motor_rated_speed"),line(),effCls(),
		Get("efficiency"),Get("motor_rated_voltage"));
	fla.calculate();
	args.GetReturnValue().Set(fla.getEstimatedFLA());
}

void MotorPerformance(const FunctionCallbackInfo<Value>& args) {
	Setup(args);

	MotorEfficiency mef(line(),Get("motor_rated_speed"),effCls(),Get("efficiency"),Get("motor_rated_power"),Get("load_factor"));
	auto mefVal = mef.calculate();
	SetR("efficiency",mefVal*100);

	MotorCurrent mc(Get("motor_rated_power"),Get("motor_rated_speed"),line(),effCls(),Get("efficiency"),Get("load_factor"),Get("motor_rated_voltage"),Get("flc"));
	auto mcVal = mc.calculate();
	SetR("current",mcVal/Get("flc")*100);

	MotorPowerFactor pf(Get("motor_rated_power"),Get("load_factor"),mcVal,mefVal,Get("motor_rated_voltage"));
	SetR("pf",pf.calculate()*100);
}

void PumpEfficiency(const FunctionCallbackInfo<Value>& args) {
	Setup(args);
	OptimalPrePumpEff pef(style(), 0, Get("flow"));
	auto v = pef.calculate();
	SetR("average",v);
	SetR("max",v*OptimalDeviationFactor(Get("flow")).calculate());
}

void AchievableEfficiency(const FunctionCallbackInfo<Value>& args) {
	Setup(args);
	args.GetReturnValue().Set(
		OptimalSpecificSpeedCorrection(style(), Get("specific_speed")).calculate()*100);
}

void Nema(const FunctionCallbackInfo<Value>& args) {
	Setup(args);

	args.GetReturnValue().Set(
		MotorEfficiency(line(),Get("motor_rated_speed"),effCls(),Get("efficiency"),Get("motor_rated_power"),1).calculate()*100
	);
}

// Test

void Check(double exp, double act, const char* nm="") {
	//cout << "e " << exp << "; a " << act << endl;
	// if (isnan(act) || (abs(exp-act)>.01*exp)) {
	auto p = 10;
	if (isnan(act) || ( (round(exp*p)/p)!=round(act*p)/p)) {
		printf("\"%s\" TEST FAILED: %f %f\n",nm,exp,act);
		assert(!"equal");
	}
}

void Check100(double exp, double act, const char* nm="") {
	Check(exp,act*100,nm);
}

void Test(const FunctionCallbackInfo<Value>& args) {
		EstimateFLA fla(200,1780,(Motor::LineFrequency)1,(Motor::EfficiencyClass)(1),0,460);
		fla.calculate();
		Check(225.8,fla.getEstimatedFLA());

// motor perf

	{
		MotorCurrent mc(200,1780,Motor::LineFrequency::FREQ60,Motor::EfficiencyClass::ENERGY_EFFICIENT,0,.25,460,225.8);
		auto mcVal = mc.calculate();
		Check100(36.11,mcVal/225.8);
	}
	{
		MotorEfficiency mef(Motor::LineFrequency::FREQ60,1780,Motor::EfficiencyClass::ENERGY_EFFICIENT,0,200,.75);
		auto mefVal = mef.calculate();
		Check100(95.69,mefVal);

		MotorCurrent mc(200,1780,Motor::LineFrequency::FREQ60,Motor::EfficiencyClass::ENERGY_EFFICIENT,0,.75,460,225.8);
		auto mcVal = mc.calculate();
		Check100(76.63,mcVal/225.8);

		MotorPowerFactor pf(200,.75,mcVal,mefVal,460);
		Check100(84.82,pf.calculate());
	}

// nema

	{
		MotorEfficiency mef(Motor::LineFrequency::FREQ60,1200, Motor::EfficiencyClass::ENERGY_EFFICIENT,0,200,1);
		//Check100(95,mef.calculate());
	}

// pump eff

	{
		OptimalPrePumpEff pef(Pump::Style::END_SUCTION_ANSI_API, 0, 2000);
		OptimalDeviationFactor df(2000);

		//cout <<  pef.calculate() << ";" << df.calculate();
		//Check(87.1,pef.calculate()*df.calculate());
	}

// spec speed

	{
		OptimalSpecificSpeedCorrection cor(Pump::Style::END_SUCTION_ANSI_API, 1170);
		//Check100(2.3,cor.calculate());
	}
	return;

	#define BASE \
		Pump pump(Pump::Style::END_SUCTION_ANSI_API,0,1780,Pump::Drive::DIRECT_DRIVE,\
			1,1,1,Pump::Speed::NOT_FIXED_SPEED);\
		Motor motor(Motor::LineFrequency::FREQ60,200,1780,\
				Motor::EfficiencyClass::ENERGY_EFFICIENT,0,460,225.8,0);\
		Financial fin(1,.05);\
		FieldData fd(2000,277,FieldData::LoadEstimationMethod::POWER,\
				150,0,460);

	#define CALC \
		PSATResult psat(pump,motor,fin,fd);\
		psat.calculateExisting();\
		auto ex = psat.getExisting();

	for (int i=1; i<=10000; i=i+2) {
		BASE
		CALC
		Check(ex.motorShaftPower_,ex.motorShaftPower_,"SAME");
	}

	{
		BASE
		motor.setMotorRpm(1786);
		fd.setMotorPower(80);
		CALC
		Check(101.9,ex.motorShaftPower_);
		Check100(95,ex.motorEfficiency_);
		Check100(79.1,ex.motorPowerFactor_);
		Check(127,ex.motorCurrent_);
	}
	{
		BASE
		fd.setMotorPower(80);
		motor.setMotorRatedPower(100);
		motor.setFullLoadAmps(113.8);
		CALC
		Check(101.8,ex.motorShaftPower_);
		Check100(94.9,ex.motorEfficiency_);
		Check100(86.7,ex.motorPowerFactor_);
		Check(115.8,ex.motorCurrent_);
	}
	{
		BASE
		fd.setMotorPower(80);
		fd.setVoltage(260);
		CALC
		Check(101.9,ex.motorShaftPower_);
		Check100(95,ex.motorEfficiency_);
		Check100(138.8,ex.motorPowerFactor_);
		Check(128,ex.motorCurrent_);
	}
	{
		BASE
		motor.setMotorRpm(1200);
		fd.setMotorPower(80);
		motor.setFullLoadAmps(235.3);
		CALC
		Check(101.4,ex.motorShaftPower_);
		Check100(94.5,ex.motorEfficiency_);
		Check100(74.3,ex.motorPowerFactor_);
		Check(135.1,ex.motorCurrent_);
	}
	{
		BASE
		fd.setMotorPower(111.855);
		CALC
		Check(143.4,ex.motorShaftPower_);
		Check100(95.6,ex.motorEfficiency_);
		Check100(84.3,ex.motorPowerFactor_);
		Check(166.5,ex.motorCurrent_);
	}
	{
		BASE
		fd.setMotorPower(80);
		motor.setMotorRatedVoltage(200);
		motor.setFullLoadAmps(519.3);
		CALC
		Check(101.9,ex.motorShaftPower_);
		Check100(95,ex.motorEfficiency_);
		Check100(35.2,ex.motorPowerFactor_);
		Check(284.9,ex.motorCurrent_);
	}
	{
		BASE
		CALC
		Check(217.5,ex.motorCurrent_);
	}
	{
		BASE
		fd.setLoadEstimationMethod(FieldData::LoadEstimationMethod::CURRENT);
		fd.setMotorAmps(218);
		fd.setMotorPower(0);
		CALC
		Check(150.4,ex.motorPower_);
		Check100(72.5,ex.pumpEfficiency_);
	}
	{
		BASE
		fd.setMotorPower(80);
		CALC
		Check(700.8,ex.annualEnergy_);
	}
	{
		BASE
		fin.setOperatingFraction(.25);
		CALC
		Check(328.5,ex.annualEnergy_);
		Check(16.4,ex.annualCost_);
	}
	{
		BASE
		motor.setFullLoadAmps(300);
		CALC
		Check(288.9,ex.motorCurrent_);
	}
	{
		BASE
		motor.setEfficiencyClass(Motor::EfficiencyClass(0));
		CALC
		Check(213.7,ex.motorCurrent_);
	}
	{
		BASE
		motor.setEfficiencyClass(Motor::EfficiencyClass(2));
		motor.setSpecifiedEfficiency(75);
		CALC
		Check(173.7,ex.motorCurrent_);
	}
	cout << "done";
}

void InitTest(const FunctionCallbackInfo<Value>& args) {
	Setup(args);
	args.GetReturnValue().Set(String::NewFromUtf8(iso,"SUCCESS"));
}

// v8

void Init(Local<Object> exports) {
	NODE_SET_METHOD(exports, "results", Results);
	NODE_SET_METHOD(exports, "estFLA", EstFLA);
	NODE_SET_METHOD(exports, "motorPerformance", MotorPerformance);
	NODE_SET_METHOD(exports, "pumpEfficiency", PumpEfficiency);
	NODE_SET_METHOD(exports, "achievableEfficiency", AchievableEfficiency);
	NODE_SET_METHOD(exports, "nema", Nema);
	NODE_SET_METHOD(exports, "test", Test);
	NODE_SET_METHOD(exports, "initTest", InitTest);
}

NODE_MODULE(bridge, Init)
<|endoftext|>


<commit_before>/* FasTC
 * Copyright (c) 2013 University of North Carolina at Chapel Hill.
 * All rights reserved.
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for educational, research, and non-profit purposes, without
 * fee, and without a written agreement is hereby granted, provided that the
 * above copyright notice, this paragraph, and the following four paragraphs
 * appear in all copies.
 *
 * Permission to incorporate this software into commercial products may be
 * obtained by contacting the authors or the Office of Technology Development
 * at the University of North Carolina at Chapel Hill <otd@unc.edu>.
 *
 * This software program and documentation are copyrighted by the University of
 * North Carolina at Chapel Hill. The software program and documentation are
 * supplied "as is," without any accompanying services from the University of
 * North Carolina at Chapel Hill or the authors. The University of North
 * Carolina at Chapel Hill and the authors do not warrant that the operation of
 * the program will be uninterrupted or error-free. The end-user understands
 * that the program was developed for research purposes and is advised not to
 * rely exclusively on the program for any reason.
 *
 * IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE
 * AUTHORS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
 * OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF
 * THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA
 * AT CHAPEL HILL OR THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 *
 * THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY
 * DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY
 * STATUTORY WARRANTY OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON
 * AN "AS IS" BASIS, AND THE UNIVERSITY  OF NORTH CAROLINA AT CHAPEL HILL AND
 * THE AUTHORS HAVE NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
 * ENHANCEMENTS, OR MODIFICATIONS.
 *
 * Please send all BUG REPORTS to <pavel@cs.unc.edu>.
 *
 * The authors may be contacted via:
 *
 * Pavel Krajcevski
 * Dept of Computer Science
 * 201 S Columbia St
 * Frederick P. Brooks, Jr. Computer Science Bldg
 * Chapel Hill, NC 27599-3175
 * USA
 *
 * <http://gamma.cs.unc.edu/FasTC/>
 */

#include "PVRTCCompressor.h"

#include <algorithm>
#include <cassert>
#include <iostream>
#include <vector>

#include "Pixel.h"
#include "Image.h"
#include "Block.h"

namespace PVRTCC {

  static uint32 Interleave(uint16 inx, uint16 iny) {
    // Taken from:
    // http://graphics.stanford.edu/~seander/bithacks.html#InterleaveBMN

    static const uint32 B[] = {0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF};
    static const uint32 S[] = {1, 2, 4, 8};

    uint32 x = static_cast<uint32>(inx);
    uint32 y = static_cast<uint32>(iny);

    x = (x | (x << S[3])) & B[3];
    x = (x | (x << S[2])) & B[2];
    x = (x | (x << S[1])) & B[1];
    x = (x | (x << S[0])) & B[0];

    y = (y | (y << S[3])) & B[3];
    y = (y | (y << S[2])) & B[2];
    y = (y | (y << S[1])) & B[1];
    y = (y | (y << S[0])) & B[0];

    return x | (y << 1);
  }

  template <typename T>
  static T Clamp(const T &v, const T &low, const T &high) {
    return ::std::min(::std::max(low, v), high);
  }

  template <typename T>
  static T Lookup(const ::std::vector<T> &vals,
                  uint32 x, uint32 y,
                  uint32 width, uint32 height,
                  const EWrapMode wrapMode) {
    while(x >= width) {
      if(wrapMode == eWrapMode_Wrap) {
        x -= width;
      } else {
        x = width - 1;
      }
    }

    while(x < 0) {
      if(wrapMode == eWrapMode_Wrap) {
        x += width;
      } else {
        x = 0;
      }
    }

    while(y >= height) {
      if(wrapMode == eWrapMode_Wrap) {
        y -= height;
      } else {
        y = height - 1;
      }
    }

    while(y < 0) {
      if(wrapMode == eWrapMode_Wrap) {
        y += height;
      } else {
        y = 0;
      }
    }

    return vals[y * width + x];
  }

  void Compress(const CompressionJob &dcj,
                bool bTwoBitMode,
                const EWrapMode wrapMode) {
    Image img(dcj.height, dcj.width);
    uint32 nPixels = dcj.height * dcj.width;
    for(uint32 i = 0; i < nPixels; i++) {
      uint32 x = i % dcj.width;
      uint32 y = i / dcj.width;

      const uint32 *pixels = reinterpret_cast<const uint32 *>(dcj.inBuf);
      img(x, y).UnpackRGBA(pixels[i]);
    }

    Image original = img;
    img.DebugOutput("Original");

    // Downscale it using anisotropic diffusion based scheme in order to preserve
    // image features, then reupscale and compute deltas. Use deltas to generate
    // initial A & B images followed by modulation data.
    img.ContentAwareDownscale(1, 1, eWrapMode_Wrap, true);
    img.ContentAwareDownscale(1, 1, eWrapMode_Wrap, false);

    Image downscaled = img;

    // Upscale it again
    img.BilinearUpscale(2, 2, eWrapMode_Wrap);

    img.DebugOutput("Reconstruction");

    // Compute difference...
    ::std::vector<int16> difference;
    difference.resize(dcj.height * dcj.width * 4);
    for(uint32 j = 0; j < dcj.height; j++) {
      for(uint32 i = 0; i < dcj.width; i++) {
        for(uint32 c = 0; c < 4; c++) {
          int16 o = original(i, j).Component(c);
          int16 n = img(i, j).Component(c);
          difference[j*dcj.width*4 + i*4 + c] = o - n;
        }
      }
    }

    // Go over the 7x7 texel blocks and extract bounding box diagonals for each
    // block. We should be able to choose which diagonal we want...
    const uint32 kKernelSz = 7;
    ::std::vector<int16> maxDiff;
    ::std::vector<int16> minDiff;

    const uint32 kNumBlockChannels = dcj.height * dcj.width / 4;
    maxDiff.resize(kNumBlockChannels);
    minDiff.resize(kNumBlockChannels);

    for(uint32 j = 2; j < dcj.height; j += 4) {
      for(uint32 i = 2; i < dcj.width; i += 4) {
        const uint32 startX = i - (kKernelSz / 2);
        const uint32 startY = j - (kKernelSz / 2);
        for(uint32 c = 0; c < 4; c++) {
          int32 pos = 0;
          int32 neg = 0;
          for(uint32 y = startY; y < startY + kKernelSz; y++) {
            for(uint32 x = startX; x < startX + kKernelSz; x++) {
              int16 val = Lookup(difference, x*4 + c, y,
                                 dcj.width*4, dcj.height, wrapMode);
              if(val > 0) {
                pos += val;
              } else {
                neg += val;
              }
            }
          }

          uint32 blockIdx = ((j-2)/4) * dcj.width + (i-2) + c;
          assert(blockIdx < kNumBlockChannels);
          if(pos > -neg) {
            maxDiff[blockIdx] = pos;
            minDiff[blockIdx] = 0;
          } else {
            maxDiff[blockIdx] = 0;
            minDiff[blockIdx] = neg;
          }
        }
      }
    }

    // Add maxDiff to image to get high signal, and lowdiff to image to
    // get low signal...
    Image imgA = downscaled;
    Image imgB = downscaled;

    for(uint32 j = 0; j < dcj.height / 4; j++) {
      for(uint32 i = 0; i < dcj.width / 4; i++) {
        for(uint32 c = 0; c < 4; c++) {
          const uint32 cIdx = j*dcj.width/4 + i*4 + c;
          uint8 &a = imgA(i, j).Component(c);
          a = static_cast<uint8>(Clamp<int16>(a + maxDiff[cIdx], 0, 255));

          uint8 &b = imgB(i, j).Component(c);
          b = static_cast<uint8>(Clamp<int16>(b + minDiff[cIdx], 0, 255));
        }
      }
    }

    imgA.DebugOutput("ImageA");
    imgB.DebugOutput("ImageB");

    // Determine modulation values...
    Image upA = imgA;
    Image upB = imgB;

    upA.BilinearUpscale(2, 2, wrapMode);
    upB.BilinearUpscale(2, 2, wrapMode);

    assert(upA.GetHeight() == dcj.height && upA.GetWidth() == dcj.width);
    assert(upB.GetHeight() == dcj.height && upB.GetWidth() == dcj.width);

    upA.DebugOutput("UpscaledA");
    upB.DebugOutput("UpscaledB");

    // Choose the most appropriate modulation values for the two images...
    ::std::vector<uint8> modValues;
    modValues.resize(dcj.width * dcj.height);
    for(uint32 j = 0; j < dcj.height; j++) {
      for(uint32 i = 0; i < dcj.width; i++) {
        uint8 &mv = modValues[j * dcj.width + i];

        const Pixel pa = upA(i, j);
        const Pixel pb = upB(i, j);
        const Pixel po = original(i, j);

        // !FIXME! there are two modulation modes... we're only using one.
        uint8 modSteps[4] = { 8, 5, 3, 0 };
        uint8 bestMod = 0;
        uint32 bestError = 0xFFFFFFFF;
        for(uint32 s = 0; s < 4; s++) {
          uint32 error = 0;
          for(uint32 c = 0; c < 4; c++) {
            uint16 va = static_cast<uint16>(pa.Component(c));
            uint16 vb = static_cast<uint16>(pb.Component(c));
            uint16 vo = static_cast<uint16>(po.Component(c));

            uint16 lerpVal = modSteps[s];
            uint16 res = (va * (8 - lerpVal) + vb * lerpVal) / 8;
            uint16 e = (res > vo)? res - vo : vo - res;
            error += e * e;
          }

          if(error < bestError) {
            bestError = error;
            bestMod = s;
          }
        }

        mv = bestMod;
      }
    }

    // Pack everything into a PVRTC blocks.
    const uint32 blocksW = dcj.width / 4;
    const uint32 blocksH = dcj.height / 4;

    assert(imgA.GetHeight() == blocksH);
    assert(imgA.GetWidth() == blocksW);

    std::vector<uint64> blocks;
    blocks.reserve(blocksW * blocksH);
    for(uint32 j = 0; j < blocksH; j++) {
      for(uint32 i = 0; i < blocksW; i++) {
        Block b;
        b.SetColorA(imgA(i, j), true);
        b.SetColorB(imgB(i, j), true);
        for(uint32 t = 0; t < 16; t++) {
          uint32 x = i*4 + (t%4);
          uint32 y = j*4 + (t/4);
          b.SetLerpValue(t, modValues[y*dcj.width + x]);
        }
        blocks.push_back(b.Pack());
      }
    }

    // Spit out the blocks...
    for(uint32 j = 0; j < blocksH; j++) {
      for(uint32 i = 0; i < blocksW; i++) {

        // The blocks are initially arranged in morton order. Let's
        // linearize them...
        uint32 idx = Interleave(j, i);

        uint64 *outPtr = reinterpret_cast<uint64 *>(dcj.outBuf);
        outPtr[idx] = blocks[j*blocksW + i];
      }
    }
  }

}  // namespace PVRTCC
<commit_msg>Update compressor to do a simple bounding box algorithm... results are still bad but better than what we've been getting.<commit_after>/* FasTC
 * Copyright (c) 2013 University of North Carolina at Chapel Hill.
 * All rights reserved.
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for educational, research, and non-profit purposes, without
 * fee, and without a written agreement is hereby granted, provided that the
 * above copyright notice, this paragraph, and the following four paragraphs
 * appear in all copies.
 *
 * Permission to incorporate this software into commercial products may be
 * obtained by contacting the authors or the Office of Technology Development
 * at the University of North Carolina at Chapel Hill <otd@unc.edu>.
 *
 * This software program and documentation are copyrighted by the University of
 * North Carolina at Chapel Hill. The software program and documentation are
 * supplied "as is," without any accompanying services from the University of
 * North Carolina at Chapel Hill or the authors. The University of North
 * Carolina at Chapel Hill and the authors do not warrant that the operation of
 * the program will be uninterrupted or error-free. The end-user understands
 * that the program was developed for research purposes and is advised not to
 * rely exclusively on the program for any reason.
 *
 * IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE
 * AUTHORS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
 * OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF
 * THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA
 * AT CHAPEL HILL OR THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 *
 * THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY
 * DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY
 * STATUTORY WARRANTY OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON
 * AN "AS IS" BASIS, AND THE UNIVERSITY  OF NORTH CAROLINA AT CHAPEL HILL AND
 * THE AUTHORS HAVE NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
 * ENHANCEMENTS, OR MODIFICATIONS.
 *
 * Please send all BUG REPORTS to <pavel@cs.unc.edu>.
 *
 * The authors may be contacted via:
 *
 * Pavel Krajcevski
 * Dept of Computer Science
 * 201 S Columbia St
 * Frederick P. Brooks, Jr. Computer Science Bldg
 * Chapel Hill, NC 27599-3175
 * USA
 *
 * <http://gamma.cs.unc.edu/FasTC/>
 */

#include "PVRTCCompressor.h"

#include <algorithm>
#include <cassert>
#include <iostream>
#include <vector>

#include "Pixel.h"
#include "Image.h"
#include "Block.h"

namespace PVRTCC {

  static uint32 Interleave(uint16 inx, uint16 iny) {
    // Taken from:
    // http://graphics.stanford.edu/~seander/bithacks.html#InterleaveBMN

    static const uint32 B[] = {0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF};
    static const uint32 S[] = {1, 2, 4, 8};

    uint32 x = static_cast<uint32>(inx);
    uint32 y = static_cast<uint32>(iny);

    x = (x | (x << S[3])) & B[3];
    x = (x | (x << S[2])) & B[2];
    x = (x | (x << S[1])) & B[1];
    x = (x | (x << S[0])) & B[0];

    y = (y | (y << S[3])) & B[3];
    y = (y | (y << S[2])) & B[2];
    y = (y | (y << S[1])) & B[1];
    y = (y | (y << S[0])) & B[0];

    return x | (y << 1);
  }

  template <typename T>
  static T Clamp(const T &v, const T &low, const T &high) {
    return ::std::min(::std::max(low, v), high);
  }

  static const Pixel &Lookup(const Image &img,
                             int32 x, int32 y,
                             uint32 width, uint32 height,
                             const EWrapMode wrapMode) {
    while(x >= width) {
      if(wrapMode == eWrapMode_Wrap) {
        x -= width;
      } else {
        x = width - 1;
      }
    }

    while(x < 0) {
      if(wrapMode == eWrapMode_Wrap) {
        x += width;
      } else {
        x = 0;
      }
    }

    while(y >= height) {
      if(wrapMode == eWrapMode_Wrap) {
        y -= height;
      } else {
        y = height - 1;
      }
    }

    while(y < 0) {
      if(wrapMode == eWrapMode_Wrap) {
        y += height;
      } else {
        y = 0;
      }
    }

    return img(x, y);
  }

  void Compress(const CompressionJob &dcj,
                bool bTwoBitMode,
                const EWrapMode wrapMode) {
    Image img(dcj.height, dcj.width);
    uint32 nPixels = dcj.height * dcj.width;
    for(uint32 i = 0; i < nPixels; i++) {
      uint32 x = i % dcj.width;
      uint32 y = i / dcj.width;

      const uint32 *pixels = reinterpret_cast<const uint32 *>(dcj.inBuf);
      img(x, y).UnpackRGBA(pixels[i]);
    }

    Image original = img;
    img.DebugOutput("Original");

    // Downscale it using anisotropic diffusion based scheme in order to preserve
    // image features, then reupscale and compute deltas. Use deltas to generate
    // initial A & B images followed by modulation data.
    img.ContentAwareDownscale(1, 1, eWrapMode_Wrap, true);
    img.ContentAwareDownscale(1, 1, eWrapMode_Wrap, false);

    Image downscaled = img;

    // Upscale it again
    img.BilinearUpscale(2, 2, eWrapMode_Wrap);

    img.DebugOutput("Reconstruction");

    // Compute difference...
    ::std::vector<int16> difference;
    difference.resize(dcj.height * dcj.width * 4);
    for(uint32 j = 0; j < dcj.height; j++) {
      for(uint32 i = 0; i < dcj.width; i++) {
        for(uint32 c = 0; c < 4; c++) {
          int16 o = original(i, j).Component(c);
          int16 n = img(i, j).Component(c);
          difference[j*dcj.width*4 + i*4 + c] = o - n;
        }
      }
    }

    const uint32 blocksW = dcj.width / 4;
    const uint32 blocksH = dcj.height / 4;

    // Go over the 7x7 texel blocks and extract bounding box diagonals for each
    // block. We should be able to choose which diagonal we want...
    const uint32 kKernelSz = 7;

    Image imgA = downscaled;
    Image imgB = downscaled;
    for(uint32 j = 0; j < blocksH; j++) {
      for(uint32 i = 0; i < blocksW; i++) {
        int32 startX = i*4 + 2 - (kKernelSz / 2);
        int32 startY = j*4 + 2 - (kKernelSz / 2);
        for(int32 y = startY; y < startY + kKernelSz; y++) {
          for(int32 x = startX; x < startX + kKernelSz; x++) {
            const Pixel &po = Lookup(original, x, y, dcj.width, dcj.height, wrapMode);
            Pixel &pa = imgA(i, j);
            Pixel &pb = imgB(i, j);
            for(uint32 c = 0; c < 4; c++) {
              pa.Component(c) = ::std::max(po.Component(c), pa.Component(c));
              pb.Component(c) = ::std::min(po.Component(c), pb.Component(c));
            }
          }
        }
      }
    }

    imgA.DebugOutput("ImageA");
    imgB.DebugOutput("ImageB");

    // Determine modulation values...
    Image upA = imgA;
    Image upB = imgB;

    upA.BilinearUpscale(2, 2, wrapMode);
    upB.BilinearUpscale(2, 2, wrapMode);

    assert(upA.GetHeight() == dcj.height && upA.GetWidth() == dcj.width);
    assert(upB.GetHeight() == dcj.height && upB.GetWidth() == dcj.width);

    upA.DebugOutput("UpscaledA");
    upB.DebugOutput("UpscaledB");

    // Choose the most appropriate modulation values for the two images...
    ::std::vector<uint8> modValues;
    modValues.resize(dcj.width * dcj.height);
    for(uint32 j = 0; j < dcj.height; j++) {
      for(uint32 i = 0; i < dcj.width; i++) {
        uint8 &mv = modValues[j * dcj.width + i];

        const Pixel pa = upA(i, j);
        const Pixel pb = upB(i, j);
        const Pixel po = original(i, j);

        // !FIXME! there are two modulation modes... we're only using one.
        uint8 modSteps[4] = { 8, 5, 3, 0 };
        uint8 bestMod = 0;
        uint32 bestError = 0xFFFFFFFF;
        for(uint32 s = 0; s < 4; s++) {
          uint32 error = 0;
          for(uint32 c = 0; c < 4; c++) {
            uint16 va = static_cast<uint16>(pa.Component(c));
            uint16 vb = static_cast<uint16>(pb.Component(c));
            uint16 vo = static_cast<uint16>(po.Component(c));

            uint16 lerpVal = modSteps[s];
            uint16 res = (va * (8 - lerpVal) + vb * lerpVal) / 8;
            uint16 e = (res > vo)? res - vo : vo - res;
            error += e * e;
          }

          if(error < bestError) {
            bestError = error;
            bestMod = s;
          }
        }

        mv = bestMod;
      }
    }

    // Pack everything into a PVRTC blocks.
    assert(imgA.GetHeight() == blocksH);
    assert(imgA.GetWidth() == blocksW);

    std::vector<uint64> blocks;
    blocks.reserve(blocksW * blocksH);
    for(uint32 j = 0; j < blocksH; j++) {
      for(uint32 i = 0; i < blocksW; i++) {
        Block b;
        b.SetColorA(imgA(i, j), true);
        b.SetColorB(imgB(i, j), true);
        for(uint32 t = 0; t < 16; t++) {
          uint32 x = i*4 + (t%4);
          uint32 y = j*4 + (t/4);
          b.SetLerpValue(t, modValues[y*dcj.width + x]);
        }
        blocks.push_back(b.Pack());
      }
    }

    // Spit out the blocks...
    for(uint32 j = 0; j < blocksH; j++) {
      for(uint32 i = 0; i < blocksW; i++) {

        // The blocks are initially arranged in morton order. Let's
        // linearize them...
        uint32 idx = Interleave(j, i);

        uint64 *outPtr = reinterpret_cast<uint64 *>(dcj.outBuf);
        outPtr[idx] = blocks[j*blocksW + i];
      }
    }
  }

}  // namespace PVRTCC
<|endoftext|>


<commit_before>/**************************************************************************
* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
*                                                                        *
* Author: The ALICE Off-line Project.                                    *
* Contributors are mentioned in the code where appropriate.              *
*                                                                        *
* Permission to use, copy, modify and distribute this software and its   *
* documentation strictly for non-commercial purposes is hereby granted   *
* without fee, provided that the above copyright notice appears in all   *
* copies and that both the copyright notice and this permission notice   *
* appear in the supporting documentation. The authors make no claims     *
* about the suitability of this software for any purpose. It is          *
* provided "as is" without express or implied warranty.                  *
**************************************************************************/

//------------------------------------------------------------------------------
// Implementation of the AliPerformanceTask class. It checks reconstruction performance
// for the reconstructed vs MC particle tracks under several conditions. For real data
// the control QA histograms are filled.
//
// The comparison output objects deriving from AliPerformanceObject
// (e.g. AliPerformanceRes, AliPerformanceEff, AliPerformanceDEdx, AliPerformanceDCA ...)
// are stored in the output file (details in description of these classes).
//
// Author: J.Otwinowski 01/04/2009
// Changes by M.Knichel 15/10/2010
//------------------------------------------------------------------------------

#include "iostream"

#include "TChain.h"
#include "TTree.h"
#include "TH1F.h"
#include "TCanvas.h"
#include "TList.h"
#include "TFile.h"
#include "TSystem.h"

#include "AliAnalysisTask.h"
#include "AliAnalysisManager.h"
#include "AliESDEvent.h"
#include "AliESDfriend.h"
#include "AliMCEvent.h"
#include "AliESDInputHandler.h"
#include "AliMCEventHandler.h"
#include "AliESDVertex.h"
#include "AliMagF.h"
#include "AliTracker.h"
#include "AliGeomManager.h"

#include "AliMCInfo.h"
#include "AliESDRecInfo.h"
#include "AliMCInfoCuts.h"
#include "AliRecInfoCuts.h"
#include "AliComparisonObject.h"
#include "AliPerformanceObject.h"
#include "AliTPCPerformanceSummary.h"
#include "AliPerformanceTPC.h"
#include "AliPerformanceDEdx.h"
#include "AliPerformanceTask.h"

using namespace std;

ClassImp(AliPerformanceTask)

//_____________________________________________________________________________
AliPerformanceTask::AliPerformanceTask()
  : AliAnalysisTaskSE("Performance")
  , fESD(0)
  , fESDfriend(0)
  , fMC(0)
  , fOutput(0)
  , fOutputSummary(0)
  , fPitList(0)
  , fCompList(0)
  , fUseMCInfo(kFALSE)
  , fUseESDfriend(kFALSE)
  , fUseHLT(kFALSE)
{
  // Dummy Constructor
  // should not be used
}

//_____________________________________________________________________________
AliPerformanceTask::AliPerformanceTask(const char *name, const char */*title*/)
  : AliAnalysisTaskSE(name)
  , fESD(0)
  , fESDfriend(0)
  , fMC(0)
  , fOutput(0)
  , fOutputSummary(0)
  , fPitList(0)
  , fCompList(0)
  , fUseMCInfo(kFALSE)
  , fUseESDfriend(kFALSE)
  , fUseHLT(kFALSE)
{
  // Constructor

  // Define input and output slots here
  DefineOutput(1, TList::Class());
  DefineOutput(2, TTree::Class());

  // create the list for comparison objects
  fCompList = new TList;
}

//_____________________________________________________________________________
AliPerformanceTask::~AliPerformanceTask()
{
  if (fOutput)     delete fOutput;    fOutput   = 0;
  if (fOutputSummary) delete fOutputSummary; fOutputSummary = 0;
  if (fCompList)   delete fCompList;  fCompList = 0;
}

//_____________________________________________________________________________
Bool_t AliPerformanceTask::AddPerformanceObject(AliPerformanceObject *pObj)
{
  // add comparison object to the list
  if(pObj == 0) {
    Printf("ERROR: Could not add comparison object");
    return kFALSE;
  }

  // add object to the list
  fCompList->AddLast(pObj);

return kTRUE;
}

//_____________________________________________________________________________
void AliPerformanceTask::UserCreateOutputObjects()
{
  // Create histograms
  // Called once

  // create output list
  fOutput = new TList;
  fOutput->SetOwner();
  fPitList = fOutput->MakeIterator();

  // create output list
  //fOutputSummary = new TTree;

  // add comparison objects to the output
  AliPerformanceObject *pObj=0;
  Int_t count=0;
  TIterator *pitCompList = fCompList->MakeIterator();
  pitCompList->Reset();
  while(( pObj = (AliPerformanceObject *)pitCompList->Next()) != NULL) {
    fOutput->Add(pObj);
    count++;
  }
  Printf("UserCreateOutputObjects(): Number of output comparison objects: %d \n", count);

  PostData(1, fOutput);
  //PostData(2, fOutputSummary);
}

//_____________________________________________________________________________
void AliPerformanceTask::UserExec(Option_t *)
{
  // Main loop
  // Called for each event

  // Decide whether to use HLT or Offline ESD
  if(fUseHLT){

    AliESDInputHandler *esdH = dynamic_cast<AliESDInputHandler*>
      (AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());

    if (!esdH) {
      printf("ERROR: Could not get ESDInputHandler");
      return;
    }
    fESD = esdH->GetHLTEvent();
  }// end if fUseHLT
  else
    fESD = (AliESDEvent*) (InputEvent());

  if(fUseESDfriend)
    {
      fESDfriend = static_cast<AliESDfriend*>(fESD->FindListObject("AliESDfriend"));
      if(!fESDfriend) {
        Printf("ERROR: ESD friends not available");
      }
    }

  if(fUseMCInfo) {
      fMC = MCEvent();
  }

  //
  AliPerformanceObject *pObj=0;

  if (!fESD) {
    Printf("ERROR: ESD event not available");
    return;
  }

  if (fUseMCInfo && !fMC) {
    Printf("ERROR: MC event not available");
    return;
  }

  if(fUseESDfriend)
  {
    if(!fESDfriend) {
    Printf("ERROR: ESD friends not available");
    }
  }

  // Process comparison
  fPitList->Reset();
  while(( pObj = (AliPerformanceObject *)fPitList->Next()) != NULL) {
    pObj->Exec(fMC,fESD,fESDfriend,fUseMCInfo,fUseESDfriend);
  }

  // Post output data.
  PostData(1, fOutput);
}

//_____________________________________________________________________________
void AliPerformanceTask::Terminate(Option_t *)
{
  // Called once at the end

  // check output data
    fOutputSummary = dynamic_cast<TTree*> (GetOutputData(2));
    fOutput = dynamic_cast<TList*> (GetOutputData(1));
    if (!fOutput) {
        Printf("ERROR: AliPerformanceTask::Terminate(): fOutput data not available  ..." );
        return;
   }
    if (fOutputSummary) { delete fOutputSummary; fOutputSummary=0; }
    AliPerformanceObject* pObj=0;
    AliPerformanceTPC*  pTPC = 0;
    AliPerformanceDEdx* pDEdx = 0;
    TIterator* itOut = fOutput->MakeIterator();
    itOut->Reset();
    while(( pObj = dynamic_cast<AliPerformanceObject*>(itOut->Next())) != NULL) {
        if (!  pTPC) {  pTPC = dynamic_cast<AliPerformanceTPC*>(pObj); }
        if (! pDEdx) { pDEdx = dynamic_cast<AliPerformanceDEdx*>(pObj); }
    }
    if (! AliCDBManager::Instance()->GetDefaultStorage()) { AliCDBManager::Instance()->SetDefaultStorage("raw://"); }
    TUUID uuid;
    TString tmpFile = gSystem->TempDirectory() + TString("/TPCQASummary.") + uuid.AsString() + TString(".root");
    AliTPCPerformanceSummary::WriteToFile(pTPC, pDEdx, tmpFile.Data());
    TChain* chain = new TChain("tpcQA");
    chain->Add(tmpFile.Data());
    TTree *tree = chain->CopyTree("1");
    if (chain) { delete chain; chain=0; }
    fOutputSummary = tree;

     // Post output data.
     PostData(2, fOutputSummary);

}

//_____________________________________________________________________________
void AliPerformanceTask::FinishTaskOutput()
{
    // called once at the end of each job (on the workernode)
    //
    // projects THnSparse to TH1,2,3

    fOutput = dynamic_cast<TList*> (GetOutputData(1));
    if (!fOutput) {
        Printf("ERROR: AliPerformanceTask::FinishTaskOutput(): fOutput data not available  ..." );
        return;
   }

      AliPerformanceObject* pObj=0;
      TIterator* itOut = fOutput->MakeIterator();
      itOut->Reset();
      while(( pObj = dynamic_cast<AliPerformanceObject*>(itOut->Next())) != NULL) {
          pObj->SetRunNumber(fCurrentRunNumber);
          pObj->Analyse();
      }

     // Post output data.
     PostData(1, fOutput);
}

//_____________________________________________________________________________
Bool_t AliPerformanceTask::Notify()
{
  static Int_t count = 0;
  count++;
  Printf("Processing %d. file", count);

  return kTRUE;
}
<commit_msg>missing include<commit_after>/**************************************************************************
* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
*                                                                        *
* Author: The ALICE Off-line Project.                                    *
* Contributors are mentioned in the code where appropriate.              *
*                                                                        *
* Permission to use, copy, modify and distribute this software and its   *
* documentation strictly for non-commercial purposes is hereby granted   *
* without fee, provided that the above copyright notice appears in all   *
* copies and that both the copyright notice and this permission notice   *
* appear in the supporting documentation. The authors make no claims     *
* about the suitability of this software for any purpose. It is          *
* provided "as is" without express or implied warranty.                  *
**************************************************************************/

//------------------------------------------------------------------------------
// Implementation of the AliPerformanceTask class. It checks reconstruction performance
// for the reconstructed vs MC particle tracks under several conditions. For real data
// the control QA histograms are filled.
//
// The comparison output objects deriving from AliPerformanceObject
// (e.g. AliPerformanceRes, AliPerformanceEff, AliPerformanceDEdx, AliPerformanceDCA ...)
// are stored in the output file (details in description of these classes).
//
// Author: J.Otwinowski 01/04/2009
// Changes by M.Knichel 15/10/2010
//------------------------------------------------------------------------------

#include "iostream"

#include "TChain.h"
#include "TTree.h"
#include "TH1F.h"
#include "TCanvas.h"
#include "TList.h"
#include "TFile.h"
#include "TSystem.h"

#include "AliAnalysisTask.h"
#include "AliAnalysisManager.h"
#include "AliESDEvent.h"
#include "AliESDfriend.h"
#include "AliMCEvent.h"
#include "AliESDInputHandler.h"
#include "AliMCEventHandler.h"
#include "AliESDVertex.h"
#include "AliMagF.h"
#include "AliTracker.h"
#include "AliGeomManager.h"
#include "AliCDBManager.h"

#include "AliMCInfo.h"
#include "AliESDRecInfo.h"
#include "AliMCInfoCuts.h"
#include "AliRecInfoCuts.h"
#include "AliComparisonObject.h"
#include "AliPerformanceObject.h"
#include "AliTPCPerformanceSummary.h"
#include "AliPerformanceTPC.h"
#include "AliPerformanceDEdx.h"
#include "AliPerformanceTask.h"

using namespace std;

ClassImp(AliPerformanceTask)

//_____________________________________________________________________________
AliPerformanceTask::AliPerformanceTask()
  : AliAnalysisTaskSE("Performance")
  , fESD(0)
  , fESDfriend(0)
  , fMC(0)
  , fOutput(0)
  , fOutputSummary(0)
  , fPitList(0)
  , fCompList(0)
  , fUseMCInfo(kFALSE)
  , fUseESDfriend(kFALSE)
  , fUseHLT(kFALSE)
{
  // Dummy Constructor
  // should not be used
}

//_____________________________________________________________________________
AliPerformanceTask::AliPerformanceTask(const char *name, const char */*title*/)
  : AliAnalysisTaskSE(name)
  , fESD(0)
  , fESDfriend(0)
  , fMC(0)
  , fOutput(0)
  , fOutputSummary(0)
  , fPitList(0)
  , fCompList(0)
  , fUseMCInfo(kFALSE)
  , fUseESDfriend(kFALSE)
  , fUseHLT(kFALSE)
{
  // Constructor

  // Define input and output slots here
  DefineOutput(1, TList::Class());
  DefineOutput(2, TTree::Class());

  // create the list for comparison objects
  fCompList = new TList;
}

//_____________________________________________________________________________
AliPerformanceTask::~AliPerformanceTask()
{
  if (fOutput)     delete fOutput;    fOutput   = 0;
  if (fOutputSummary) delete fOutputSummary; fOutputSummary = 0;
  if (fCompList)   delete fCompList;  fCompList = 0;
}

//_____________________________________________________________________________
Bool_t AliPerformanceTask::AddPerformanceObject(AliPerformanceObject *pObj)
{
  // add comparison object to the list
  if(pObj == 0) {
    Printf("ERROR: Could not add comparison object");
    return kFALSE;
  }

  // add object to the list
  fCompList->AddLast(pObj);

return kTRUE;
}

//_____________________________________________________________________________
void AliPerformanceTask::UserCreateOutputObjects()
{
  // Create histograms
  // Called once

  // create output list
  fOutput = new TList;
  fOutput->SetOwner();
  fPitList = fOutput->MakeIterator();

  // create output list
  //fOutputSummary = new TTree;

  // add comparison objects to the output
  AliPerformanceObject *pObj=0;
  Int_t count=0;
  TIterator *pitCompList = fCompList->MakeIterator();
  pitCompList->Reset();
  while(( pObj = (AliPerformanceObject *)pitCompList->Next()) != NULL) {
    fOutput->Add(pObj);
    count++;
  }
  Printf("UserCreateOutputObjects(): Number of output comparison objects: %d \n", count);

  PostData(1, fOutput);
  //PostData(2, fOutputSummary);
}

//_____________________________________________________________________________
void AliPerformanceTask::UserExec(Option_t *)
{
  // Main loop
  // Called for each event

  // Decide whether to use HLT or Offline ESD
  if(fUseHLT){

    AliESDInputHandler *esdH = dynamic_cast<AliESDInputHandler*>
      (AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());

    if (!esdH) {
      printf("ERROR: Could not get ESDInputHandler");
      return;
    }
    fESD = esdH->GetHLTEvent();
  }// end if fUseHLT
  else
    fESD = (AliESDEvent*) (InputEvent());

  if(fUseESDfriend)
    {
      fESDfriend = static_cast<AliESDfriend*>(fESD->FindListObject("AliESDfriend"));
      if(!fESDfriend) {
        Printf("ERROR: ESD friends not available");
      }
    }

  if(fUseMCInfo) {
      fMC = MCEvent();
  }

  //
  AliPerformanceObject *pObj=0;

  if (!fESD) {
    Printf("ERROR: ESD event not available");
    return;
  }

  if (fUseMCInfo && !fMC) {
    Printf("ERROR: MC event not available");
    return;
  }

  if(fUseESDfriend)
  {
    if(!fESDfriend) {
    Printf("ERROR: ESD friends not available");
    }
  }

  // Process comparison
  fPitList->Reset();
  while(( pObj = (AliPerformanceObject *)fPitList->Next()) != NULL) {
    pObj->Exec(fMC,fESD,fESDfriend,fUseMCInfo,fUseESDfriend);
  }

  // Post output data.
  PostData(1, fOutput);
}

//_____________________________________________________________________________
void AliPerformanceTask::Terminate(Option_t *)
{
  // Called once at the end

  // check output data
    fOutputSummary = dynamic_cast<TTree*> (GetOutputData(2));
    fOutput = dynamic_cast<TList*> (GetOutputData(1));
    if (!fOutput) {
        Printf("ERROR: AliPerformanceTask::Terminate(): fOutput data not available  ..." );
        return;
   }
    if (fOutputSummary) { delete fOutputSummary; fOutputSummary=0; }
    AliPerformanceObject* pObj=0;
    AliPerformanceTPC*  pTPC = 0;
    AliPerformanceDEdx* pDEdx = 0;
    TIterator* itOut = fOutput->MakeIterator();
    itOut->Reset();
    while(( pObj = dynamic_cast<AliPerformanceObject*>(itOut->Next())) != NULL) {
        if (!  pTPC) {  pTPC = dynamic_cast<AliPerformanceTPC*>(pObj); }
        if (! pDEdx) { pDEdx = dynamic_cast<AliPerformanceDEdx*>(pObj); }
    }
    if (! AliCDBManager::Instance()->GetDefaultStorage()) { AliCDBManager::Instance()->SetDefaultStorage("raw://"); }
    TUUID uuid;
    TString tmpFile = gSystem->TempDirectory() + TString("/TPCQASummary.") + uuid.AsString() + TString(".root");
    AliTPCPerformanceSummary::WriteToFile(pTPC, pDEdx, tmpFile.Data());
    TChain* chain = new TChain("tpcQA");
    chain->Add(tmpFile.Data());
    TTree *tree = chain->CopyTree("1");
    if (chain) { delete chain; chain=0; }
    fOutputSummary = tree;

     // Post output data.
     PostData(2, fOutputSummary);

}

//_____________________________________________________________________________
void AliPerformanceTask::FinishTaskOutput()
{
    // called once at the end of each job (on the workernode)
    //
    // projects THnSparse to TH1,2,3

    fOutput = dynamic_cast<TList*> (GetOutputData(1));
    if (!fOutput) {
        Printf("ERROR: AliPerformanceTask::FinishTaskOutput(): fOutput data not available  ..." );
        return;
   }

      AliPerformanceObject* pObj=0;
      TIterator* itOut = fOutput->MakeIterator();
      itOut->Reset();
      while(( pObj = dynamic_cast<AliPerformanceObject*>(itOut->Next())) != NULL) {
          pObj->SetRunNumber(fCurrentRunNumber);
          pObj->Analyse();
      }

     // Post output data.
     PostData(1, fOutput);
}

//_____________________________________________________________________________
Bool_t AliPerformanceTask::Notify()
{
  static Int_t count = 0;
  count++;
  Printf("Processing %d. file", count);

  return kTRUE;
}
<|endoftext|>


<commit_before>/** @file

  A brief file description

  @section license License

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.
 */

/****************************************************************************

  Basic Threads

**************************************************************************/
#include "P_EventSystem.h"
#include "ts/ink_string.h"

///////////////////////////////////////////////
// Common Interface impl                     //
///////////////////////////////////////////////

static ink_thread_key init_thread_key();

ink_hrtime Thread::cur_time                       = ink_get_hrtime_internal();
inkcoreapi ink_thread_key Thread::thread_data_key = init_thread_key();

Thread::Thread()
{
  mutex = new_ProxyMutex();
  MUTEX_TAKE_LOCK(mutex, (EThread *)this);
  mutex->nthread_holding += THREAD_MUTEX_THREAD_HOLDING;
}

Thread::~Thread()
{
  ink_release_assert(mutex->thread_holding == (EThread *)this);
  mutex->nthread_holding -= THREAD_MUTEX_THREAD_HOLDING;
  MUTEX_UNTAKE_LOCK(mutex, (EThread *)this);
}

ink_thread_key
init_thread_key()
{
  ink_thread_key_create(&Thread::thread_data_key, nullptr);
  return Thread::thread_data_key;
}

///////////////////////////////////////////////
// Unix & non-NT Interface impl              //
///////////////////////////////////////////////

struct thread_data_internal {
  ThreadFunction f;                  ///< Function to excecute in the thread.
  Thread *me;                        ///< The class instance.
  char name[MAX_THREAD_NAME_LENGTH]; ///< Name for the thread.
};

static void *
spawn_thread_internal(void *a)
{
  auto *p = static_cast<thread_data_internal *>(a);

  p->me->set_specific();
  ink_set_thread_name(p->name);

  if (p->f) {
    p->f();
  } else {
    p->me->execute();
  }

  delete p;
  return nullptr;
}

ink_thread
Thread::start(const char *name, void *stack, size_t stacksize, ThreadFunction const &f)
{
  auto *p = new thread_data_internal{f, this, ""};

  ink_zero(p->name);
  ink_strlcpy(p->name, name, MAX_THREAD_NAME_LENGTH);
  if (stacksize == 0) {
    stacksize = DEFAULT_STACKSIZE;
  }
  tid = ink_thread_create(spawn_thread_internal, p, 0, stacksize, stack);

  return tid;
}
<commit_msg>Fix race condition in thread startup.<commit_after>/** @file

  A brief file description

  @section license License

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.
 */

/****************************************************************************

  Basic Threads

**************************************************************************/
#include "P_EventSystem.h"
#include "ts/ink_string.h"

///////////////////////////////////////////////
// Common Interface impl                     //
///////////////////////////////////////////////

static ink_thread_key init_thread_key();

ink_hrtime Thread::cur_time                       = ink_get_hrtime_internal();
inkcoreapi ink_thread_key Thread::thread_data_key = init_thread_key();

Thread::Thread()
{
  mutex = new_ProxyMutex();
  MUTEX_TAKE_LOCK(mutex, (EThread *)this);
  mutex->nthread_holding += THREAD_MUTEX_THREAD_HOLDING;
}

Thread::~Thread()
{
  ink_release_assert(mutex->thread_holding == (EThread *)this);
  mutex->nthread_holding -= THREAD_MUTEX_THREAD_HOLDING;
  MUTEX_UNTAKE_LOCK(mutex, (EThread *)this);
}

ink_thread_key
init_thread_key()
{
  ink_thread_key_create(&Thread::thread_data_key, nullptr);
  return Thread::thread_data_key;
}

///////////////////////////////////////////////
// Unix & non-NT Interface impl              //
///////////////////////////////////////////////

struct thread_data_internal {
  ThreadFunction f;                  ///< Function to excecute in the thread.
  Thread *me;                        ///< The class instance.
  ink_mutex mutex;                   ///< Startup mutex.
  char name[MAX_THREAD_NAME_LENGTH]; ///< Name for the thread.
};

static void *
spawn_thread_internal(void *a)
{
  auto *p = static_cast<thread_data_internal *>(a);

  { // force wait until parent thread is ready.
    ink_scoped_mutex_lock lock(p->mutex);
  }
  ink_mutex_destroy(&p->mutex);

  p->me->set_specific();
  ink_set_thread_name(p->name);

  if (p->f) {
    p->f();
  } else {
    p->me->execute();
  }

  delete p;
  return nullptr;
}

ink_thread
Thread::start(const char *name, void *stack, size_t stacksize, ThreadFunction const &f)
{
  auto *p = new thread_data_internal{f, this, {}, {0}};

  ink_zero(p->name);
  ink_strlcpy(p->name, name, MAX_THREAD_NAME_LENGTH);
  ink_mutex_init(&p->mutex);
  if (stacksize == 0) {
    stacksize = DEFAULT_STACKSIZE;
  }
  { // must force assignment to complete before thread touches "this".
    ink_scoped_mutex_lock lock(&p->mutex);
    tid = ink_thread_create(spawn_thread_internal, p, 0, stacksize, stack);
  }

  return tid;
}
<|endoftext|>