<commit_before>/*
 *          Copyright Andrey Semashev 2007 - 2015.
 * Distributed under the Boost Software License, Version 1.0.
 *    (See accompanying file LICENSE_1_0.txt or copy at
 *          http://www.boost.org/LICENSE_1_0.txt)
 */
/*!
 * \file   formatters/c_decorator.hpp
 * \author Andrey Semashev
 * \date   18.11.2012
 *
 * The header contains implementation of C-style character decorators.
 */

#ifndef BOOST_LOG_EXPRESSIONS_FORMATTERS_C_DECORATOR_HPP_INCLUDED_
#define BOOST_LOG_EXPRESSIONS_FORMATTERS_C_DECORATOR_HPP_INCLUDED_

#include <limits>
#include <boost/range/iterator_range_core.hpp>
#include <boost/log/detail/config.hpp>
#include <boost/log/detail/snprintf.hpp>
#include <boost/log/expressions/formatters/char_decorator.hpp>
#include <boost/log/detail/header.hpp>

#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif

namespace boost {

BOOST_LOG_OPEN_NAMESPACE

namespace expressions {

namespace aux {

template< typename >
struct c_decorator_traits;

#ifdef BOOST_LOG_USE_CHAR
template< >
struct c_decorator_traits< char >
{
    static boost::iterator_range< const char* const* > get_patterns()
    {
        static const char* const patterns[] =
        {
            "\\", "\a", "\b", "\f", "\n", "\r", "\t", "\v", "'", "\"", "?"
        };
        return boost::make_iterator_range(patterns);
    }
    static boost::iterator_range< const char* const* > get_replacements()
    {
        static const char* const replacements[] =
        {
            "\\\\", "\\a", "\\b", "\\f", "\\n", "\\r", "\\t", "\\v", "\\'", "\\\"", "\\?"
        };
        return boost::make_iterator_range(replacements);
    }
    template< unsigned int N >
    static std::size_t print_escaped(char (&buf)[N], char c)
    {
        int n = boost::log::aux::snprintf(buf, N, "\\x%0.2X", static_cast< unsigned int >(static_cast< uint8_t >(c)));
        if (n < 0)
        {
            n = 0;
            buf[0] = '\0';
        }
        return static_cast< unsigned int >(n) >= N ? N - 1 : static_cast< unsigned int >(n);
    }
};
#endif // BOOST_LOG_USE_CHAR

#ifdef BOOST_LOG_USE_WCHAR_T
template< >
struct c_decorator_traits< wchar_t >
{
    static boost::iterator_range< const wchar_t* const* > get_patterns()
    {
        static const wchar_t* const patterns[] =
        {
            L"\\", L"\a", L"\b", L"\f", L"\n", L"\r", L"\t", L"\v", L"'", L"\"", L"?"
        };
        return boost::make_iterator_range(patterns);
    }
    static boost::iterator_range< const wchar_t* const* > get_replacements()
    {
        static const wchar_t* const replacements[] =
        {
            L"\\\\", L"\\a", L"\\b", L"\\f", L"\\n", L"\\r", L"\\t", L"\\v", L"\\'", L"\\\"", L"\\?"
        };
        return boost::make_iterator_range(replacements);
    }
    template< unsigned int N >
    static std::size_t print_escaped(wchar_t (&buf)[N], wchar_t c)
    {
        const wchar_t* format;
        unsigned int val;
        if (sizeof(wchar_t) == 1)
        {
            format = L"\\x%0.2X";
            val = static_cast< uint8_t >(c);
        }
        else if (sizeof(wchar_t) == 2)
        {
            format = L"\\x%0.4X";
            val = static_cast< uint16_t >(c);
        }
        else
        {
            format = L"\\x%0.8X";
            val = static_cast< uint32_t >(c);
        }

        int n = boost::log::aux::swprintf(buf, N, format, val);
        if (n < 0)
        {
            n = 0;
            buf[0] = L'\0';
        }
        return static_cast< unsigned int >(n) >= N ? N - 1 : static_cast< unsigned int >(n);
    }
};
#endif // BOOST_LOG_USE_WCHAR_T

template< typename CharT >
struct c_decorator_gen
{
    typedef CharT char_type;

    template< typename SubactorT >
    BOOST_FORCEINLINE char_decorator_actor< SubactorT, pattern_replacer< char_type > > operator[] (SubactorT const& subactor) const
    {
        typedef c_decorator_traits< char_type > traits_type;
        typedef pattern_replacer< char_type > replacer_type;
        typedef char_decorator_actor< SubactorT, replacer_type > result_type;
        typedef typename result_type::terminal_type terminal_type;
        typename result_type::base_type act = {{ terminal_type(subactor, replacer_type(traits_type::get_patterns(), traits_type::get_replacements())) }};
        return result_type(act);
    }
};

} // namespace aux

/*!
 * C-style decorator generator object. The decorator replaces characters with specific meaning in C
 * language with the corresponding escape sequences. The generator provides <tt>operator[]</tt> that
 * can be used to construct the actual decorator. For example:
 *
 *
 * c_decor[ attr< std::string >("MyAttr") ]
 *
 *
 * For wide-character formatting there is the similar \c wc_decor decorator generator object.
 */
#ifdef BOOST_LOG_USE_CHAR
const aux::c_decorator_gen< char > c_decor = {};
#endif
#ifdef BOOST_LOG_USE_WCHAR_T
const aux::c_decorator_gen< wchar_t > wc_decor = {};
#endif

/*!
 * The function creates a C-style decorator generator for arbitrary character type.
 */
template< typename CharT >
BOOST_FORCEINLINE aux::c_decorator_gen< CharT > make_c_decor()
{
    return aux::c_decorator_gen< CharT >();
}

/*!
 * A character decorator implementation that escapes all non-prontable and non-ASCII characters
 * in the output with C-style escape sequences.
 */
template< typename CharT >
class c_ascii_pattern_replacer :
    public pattern_replacer< CharT >
{
private:
    //! Base type
    typedef pattern_replacer< CharT > base_type;

public:
    //! Result type
    typedef typename base_type::result_type result_type;
    //! Character type
    typedef typename base_type::char_type char_type;
    //! String type
    typedef typename base_type::string_type string_type;

private:
    //! Traits type
    typedef aux::c_decorator_traits< char_type > traits_type;

public:
    //! Default constructor
    c_ascii_pattern_replacer() : base_type(traits_type::get_patterns(), traits_type::get_replacements())
    {
    }

    //! Applies string replacements starting from the specified position
    result_type operator() (string_type& str, typename string_type::size_type start_pos = 0) const
    {
        base_type::operator() (str, start_pos);

        typedef typename string_type::iterator string_iterator;
        for (string_iterator it = str.begin() + start_pos, end = str.end(); it != end; ++it)
        {
            char_type c = *it;
            if (c < 0x20 || c > 0x7e)
            {
                char_type buf[(std::numeric_limits< char_type >::digits + 3) / 4 + 3];
                std::size_t n = traits_type::print_escaped(buf, c);
                std::size_t pos = it - str.begin();
                str.replace(pos, 1, buf, n);
                it = str.begin() + n - 1;
                end = str.end();
            }
        }
    }
};

namespace aux {

template< typename CharT >
struct c_ascii_decorator_gen
{
    typedef CharT char_type;

    template< typename SubactorT >
    BOOST_FORCEINLINE char_decorator_actor< SubactorT, c_ascii_pattern_replacer< char_type > > operator[] (SubactorT const& subactor) const
    {
        typedef c_decorator_traits< char_type > traits_type;
        typedef c_ascii_pattern_replacer< char_type > replacer_type;
        typedef char_decorator_actor< SubactorT, replacer_type > result_type;
        typedef typename result_type::terminal_type terminal_type;
        typename result_type::base_type act = {{ terminal_type(subactor, replacer_type()) }};
        return result_type(act);
    }
};

} // namespace aux

/*!
 * C-style decorator generator object. Acts similarly to \c c_decor, except that \c c_ascii_decor also
 * converts all non-ASCII and non-printable ASCII characters, except for space character, into
 * C-style hexadecimal escape sequences. The generator provides <tt>operator[]</tt> that
 * can be used to construct the actual decorator. For example:
 *
 *
 * c_ascii_decor[ attr< std::string >("MyAttr") ]
 *
 *
 * For wide-character formatting there is the similar \c wc_ascii_decor decorator generator object.
 */
#ifdef BOOST_LOG_USE_CHAR
const aux::c_ascii_decorator_gen< char > c_ascii_decor = {};
#endif
#ifdef BOOST_LOG_USE_WCHAR_T
const aux::c_ascii_decorator_gen< wchar_t > wc_ascii_decor = {};
#endif

/*!
 * The function creates a C-style decorator generator for arbitrary character type.
 */
template< typename CharT >
BOOST_FORCEINLINE aux::c_ascii_decorator_gen< CharT > make_c_ascii_decor()
{
    return aux::c_ascii_decorator_gen< CharT >();
}

} // namespace expressions

BOOST_LOG_CLOSE_NAMESPACE // namespace log

} // namespace boost

#include <boost/log/detail/footer.hpp>

#endif // BOOST_LOG_EXPRESSIONS_FORMATTERS_C_DECORATOR_HPP_INCLUDED_
<commit_msg>Removed unused typedef.<commit_after>/*
 *          Copyright Andrey Semashev 2007 - 2015.
 * Distributed under the Boost Software License, Version 1.0.
 *    (See accompanying file LICENSE_1_0.txt or copy at
 *          http://www.boost.org/LICENSE_1_0.txt)
 */
/*!
 * \file   formatters/c_decorator.hpp
 * \author Andrey Semashev
 * \date   18.11.2012
 *
 * The header contains implementation of C-style character decorators.
 */

#ifndef BOOST_LOG_EXPRESSIONS_FORMATTERS_C_DECORATOR_HPP_INCLUDED_
#define BOOST_LOG_EXPRESSIONS_FORMATTERS_C_DECORATOR_HPP_INCLUDED_

#include <limits>
#include <boost/range/iterator_range_core.hpp>
#include <boost/log/detail/config.hpp>
#include <boost/log/detail/snprintf.hpp>
#include <boost/log/expressions/formatters/char_decorator.hpp>
#include <boost/log/detail/header.hpp>

#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif

namespace boost {

BOOST_LOG_OPEN_NAMESPACE

namespace expressions {

namespace aux {

template< typename >
struct c_decorator_traits;

#ifdef BOOST_LOG_USE_CHAR
template< >
struct c_decorator_traits< char >
{
    static boost::iterator_range< const char* const* > get_patterns()
    {
        static const char* const patterns[] =
        {
            "\\", "\a", "\b", "\f", "\n", "\r", "\t", "\v", "'", "\"", "?"
        };
        return boost::make_iterator_range(patterns);
    }
    static boost::iterator_range< const char* const* > get_replacements()
    {
        static const char* const replacements[] =
        {
            "\\\\", "\\a", "\\b", "\\f", "\\n", "\\r", "\\t", "\\v", "\\'", "\\\"", "\\?"
        };
        return boost::make_iterator_range(replacements);
    }
    template< unsigned int N >
    static std::size_t print_escaped(char (&buf)[N], char c)
    {
        int n = boost::log::aux::snprintf(buf, N, "\\x%0.2X", static_cast< unsigned int >(static_cast< uint8_t >(c)));
        if (n < 0)
        {
            n = 0;
            buf[0] = '\0';
        }
        return static_cast< unsigned int >(n) >= N ? N - 1 : static_cast< unsigned int >(n);
    }
};
#endif // BOOST_LOG_USE_CHAR

#ifdef BOOST_LOG_USE_WCHAR_T
template< >
struct c_decorator_traits< wchar_t >
{
    static boost::iterator_range< const wchar_t* const* > get_patterns()
    {
        static const wchar_t* const patterns[] =
        {
            L"\\", L"\a", L"\b", L"\f", L"\n", L"\r", L"\t", L"\v", L"'", L"\"", L"?"
        };
        return boost::make_iterator_range(patterns);
    }
    static boost::iterator_range< const wchar_t* const* > get_replacements()
    {
        static const wchar_t* const replacements[] =
        {
            L"\\\\", L"\\a", L"\\b", L"\\f", L"\\n", L"\\r", L"\\t", L"\\v", L"\\'", L"\\\"", L"\\?"
        };
        return boost::make_iterator_range(replacements);
    }
    template< unsigned int N >
    static std::size_t print_escaped(wchar_t (&buf)[N], wchar_t c)
    {
        const wchar_t* format;
        unsigned int val;
        if (sizeof(wchar_t) == 1)
        {
            format = L"\\x%0.2X";
            val = static_cast< uint8_t >(c);
        }
        else if (sizeof(wchar_t) == 2)
        {
            format = L"\\x%0.4X";
            val = static_cast< uint16_t >(c);
        }
        else
        {
            format = L"\\x%0.8X";
            val = static_cast< uint32_t >(c);
        }

        int n = boost::log::aux::swprintf(buf, N, format, val);
        if (n < 0)
        {
            n = 0;
            buf[0] = L'\0';
        }
        return static_cast< unsigned int >(n) >= N ? N - 1 : static_cast< unsigned int >(n);
    }
};
#endif // BOOST_LOG_USE_WCHAR_T

template< typename CharT >
struct c_decorator_gen
{
    typedef CharT char_type;

    template< typename SubactorT >
    BOOST_FORCEINLINE char_decorator_actor< SubactorT, pattern_replacer< char_type > > operator[] (SubactorT const& subactor) const
    {
        typedef c_decorator_traits< char_type > traits_type;
        typedef pattern_replacer< char_type > replacer_type;
        typedef char_decorator_actor< SubactorT, replacer_type > result_type;
        typedef typename result_type::terminal_type terminal_type;
        typename result_type::base_type act = {{ terminal_type(subactor, replacer_type(traits_type::get_patterns(), traits_type::get_replacements())) }};
        return result_type(act);
    }
};

} // namespace aux

/*!
 * C-style decorator generator object. The decorator replaces characters with specific meaning in C
 * language with the corresponding escape sequences. The generator provides <tt>operator[]</tt> that
 * can be used to construct the actual decorator. For example:
 *
 *
 * c_decor[ attr< std::string >("MyAttr") ]
 *
 *
 * For wide-character formatting there is the similar \c wc_decor decorator generator object.
 */
#ifdef BOOST_LOG_USE_CHAR
const aux::c_decorator_gen< char > c_decor = {};
#endif
#ifdef BOOST_LOG_USE_WCHAR_T
const aux::c_decorator_gen< wchar_t > wc_decor = {};
#endif

/*!
 * The function creates a C-style decorator generator for arbitrary character type.
 */
template< typename CharT >
BOOST_FORCEINLINE aux::c_decorator_gen< CharT > make_c_decor()
{
    return aux::c_decorator_gen< CharT >();
}

/*!
 * A character decorator implementation that escapes all non-prontable and non-ASCII characters
 * in the output with C-style escape sequences.
 */
template< typename CharT >
class c_ascii_pattern_replacer :
    public pattern_replacer< CharT >
{
private:
    //! Base type
    typedef pattern_replacer< CharT > base_type;

public:
    //! Result type
    typedef typename base_type::result_type result_type;
    //! Character type
    typedef typename base_type::char_type char_type;
    //! String type
    typedef typename base_type::string_type string_type;

private:
    //! Traits type
    typedef aux::c_decorator_traits< char_type > traits_type;

public:
    //! Default constructor
    c_ascii_pattern_replacer() : base_type(traits_type::get_patterns(), traits_type::get_replacements())
    {
    }

    //! Applies string replacements starting from the specified position
    result_type operator() (string_type& str, typename string_type::size_type start_pos = 0) const
    {
        base_type::operator() (str, start_pos);

        typedef typename string_type::iterator string_iterator;
        for (string_iterator it = str.begin() + start_pos, end = str.end(); it != end; ++it)
        {
            char_type c = *it;
            if (c < 0x20 || c > 0x7e)
            {
                char_type buf[(std::numeric_limits< char_type >::digits + 3) / 4 + 3];
                std::size_t n = traits_type::print_escaped(buf, c);
                std::size_t pos = it - str.begin();
                str.replace(pos, 1, buf, n);
                it = str.begin() + n - 1;
                end = str.end();
            }
        }
    }
};

namespace aux {

template< typename CharT >
struct c_ascii_decorator_gen
{
    typedef CharT char_type;

    template< typename SubactorT >
    BOOST_FORCEINLINE char_decorator_actor< SubactorT, c_ascii_pattern_replacer< char_type > > operator[] (SubactorT const& subactor) const
    {
        typedef c_ascii_pattern_replacer< char_type > replacer_type;
        typedef char_decorator_actor< SubactorT, replacer_type > result_type;
        typedef typename result_type::terminal_type terminal_type;
        typename result_type::base_type act = {{ terminal_type(subactor, replacer_type()) }};
        return result_type(act);
    }
};

} // namespace aux

/*!
 * C-style decorator generator object. Acts similarly to \c c_decor, except that \c c_ascii_decor also
 * converts all non-ASCII and non-printable ASCII characters, except for space character, into
 * C-style hexadecimal escape sequences. The generator provides <tt>operator[]</tt> that
 * can be used to construct the actual decorator. For example:
 *
 *
 * c_ascii_decor[ attr< std::string >("MyAttr") ]
 *
 *
 * For wide-character formatting there is the similar \c wc_ascii_decor decorator generator object.
 */
#ifdef BOOST_LOG_USE_CHAR
const aux::c_ascii_decorator_gen< char > c_ascii_decor = {};
#endif
#ifdef BOOST_LOG_USE_WCHAR_T
const aux::c_ascii_decorator_gen< wchar_t > wc_ascii_decor = {};
#endif

/*!
 * The function creates a C-style decorator generator for arbitrary character type.
 */
template< typename CharT >
BOOST_FORCEINLINE aux::c_ascii_decorator_gen< CharT > make_c_ascii_decor()
{
    return aux::c_ascii_decorator_gen< CharT >();
}

} // namespace expressions

BOOST_LOG_CLOSE_NAMESPACE // namespace log

} // namespace boost

#include <boost/log/detail/footer.hpp>

#endif // BOOST_LOG_EXPRESSIONS_FORMATTERS_C_DECORATOR_HPP_INCLUDED_
<|endoftext|>


<commit_before>#include "Animus.h"

CAnimus::CAnimus(void)
{

}

void CAnimus::Begin()
{
  PersMem.Begin(); // loads data from EEPROM to RAM
  AnimusKeyboard.Begin(); // initialise keyboard module
  Comms.Begin(BAUD); // start comms
  Mod.Begin(); // initialise mods
}

void CAnimus::Loop()
{
  MillisLoop(); // checks pseudoRTOS status

  // start of pseudo rtos code
  if (Async1MSDelay()) // should run once every 1 to 1.5ms
  {

    // layering checks in case of layout remapping
    if (Global.KeyLayer >= Global.LAY || Global.TempLayer >= Global.LAY)
    {
      Global.KeyLayer = 0;
      Global.TempLayer = 0;
    }

    KeyScan(); // physical key layers scanned
    // start of physical key loops
    for (byte i = 0; i < Global.ROW; i++) // this is placed inside the 1ms delay to slow it down a bit
    {
      for (byte j = 0; j < Global.COL; j++)
      {
        if (Global.KeyState[j][i] == HIGH) // if key is down
        {
          if (Global.KeyStateCoolDown[j][i] == 0) // if key was not recently released
          {
            PressCoords(j, i);
            Global.LayerState[j][i] = Global.TempLayer;
            PrePress(PersMem.GetKeyData(j, i, Global.TempLayer), PersMem.GetKeyType(j, i, Global.TempLayer));
            PressKey(PersMem.GetKeyData(j, i, Global.TempLayer), PersMem.GetKeyType(j, i, Global.TempLayer));
            Global.KeyStateCoolDown[j][i] = 255;
          }
        }
        else if (Global.KeyState[j][i] == LOW) // if key is up
        {
          if (Global.KeyStateCoolDown[j][i] == 255 - Global.KeyUpDelay) // if key was previously held down
          {
            ReleaseKey(PersMem.GetKeyData(j, i, Global.LayerState[j][i]), PersMem.GetKeyType(j, i, Global.LayerState[j][i]));
            Global.KeyStateCoolDown[j][i] = Global.KeyDownDelay;
          }
        }
      }
    }
    // end of physical key loops
    // start of countdowns
    for (byte i = 0; i < Global.ROW; i++)
    {
      for (byte j = 0; j < Global.COL; j++)
      {
        if (Global.KeyStateCoolDown[j][i] > 0 && Global.KeyStateCoolDown[j][i] != 255 - Global.KeyUpDelay)
        {
          Global.KeyStateCoolDown[j][i]--;
        }
      }
    }
    //end of countdowns
  }
  // end of pesudo rtos
  PersMem.Loop();
  Mod.Loop();
  Comms.Loop();
}

void CAnimus::PressCoords(byte x, byte y)
{
  Mod.PressCoords(x, y);
}

void CAnimus::PrePress(byte val, byte type)
{
  Mod.PrePress(val, type);
}

void CAnimus::PressKey(byte val, byte type)
{
  if (Global.HasUSB)
  {
    if (type == 0) // normal HID keystroke
    {
      AnimusKeyboard.Press(val);
    }
    else if (type == 1) // FN keys
    {
      Global.TempLayer = val;
    }
    else if (type == 2) // move main layer up or down or bitwise rotate the layer
    {
      if (val == 0)
      {
        SwitchLayer(true);
      }
      else if (val == 1)
      {
        SwitchLayer(false);
      }
      else
      {
        RotateLayer(val);
      }
    }
    else if (type == 3) // toggle layers
    {
      if (Global.TempLayer == val)
      {
        Global.TempLayer = Global.KeyLayer;
      }
      else
      {
        Global.TempLayer = val;
      }
    }
  }

  // for other key types, use a mod
  Mod.PressKey(val, type);
}

void CAnimus::ReleaseKey(byte val, byte type)
{
  if (Global.HasUSB)
  {
    if (type == 0)
    {
      AnimusKeyboard.Release(val);

    }
    else if (type == 1)
    {
      Global.TempLayer = Global.KeyLayer;
    }
  }
  Mod.ReleaseKey(val, type);
}

void CAnimus::SwitchLayer(bool increment)
{
  if (increment) // if true, go up a layer
  {
    Global.KeyLayer++;
  }
  else
  {
    Global.KeyLayer--;
  }
  if (Global.KeyLayer > 254) // rollover handling
  {
    Global.KeyLayer = Global.LAY -1;
  }
  else if (Global.KeyLayer >= Global.LAY)
  {
    Global.KeyLayer = 0;
  }

}

void CAnimus::RotateLayer(byte val) // bitwise layer shift
{
  byte newLayer = Global.KeyLayer;
  byte mask = 1 << newLayer;
  if (!val)
  {
    /* No layers are allowed. Do nothing. */
    return;
  }

  /*
  Find the next layer within the bitfield.
  Limit iterations to 10, to ensure no infinite loop.
  */
  for (byte i = 0; i < 10; i++)
  {
    newLayer++;
    mask <<= 1;
    if ((! mask) || (newLayer >= Global.LAY))
    {
      newLayer = 0;
      mask = 1;
    }

    if (val & mask)
    {
      /* newLayer is an allowed layer within the bitfield. */
      break;
    }
  }
  Global.KeyLayer = newLayer;
}

void CAnimus::KeyScan()
{
  for (int i = 0; i < Global.COL; i++)
  {
    pinMode(Global.HPins[i], OUTPUT);

    for (int j = 0; j < Global.ROW; j++)
    {
      byte val = digitalRead(Global.VPins[j]);
      Global.KeyState[i][j] = (val == LOW);
    }

    pinMode(Global.HPins[i], INPUT);
  }
}

void CAnimus::MillisLoop()
{
  CurrentMillis = millis();

  if(CurrentMillis - PreviousMillis >= 1) // this elapses every 1-1.5 ms
  {
    PreviousMillis = CurrentMillis;
    ReadyMillis = true;
  }
  else
  {
    ReadyMillis = false;
  }
}

bool CAnimus::Async1MSDelay()
{
  return ReadyMillis;
}

CAnimus Animus;
<commit_msg>added comment<commit_after>#include "Animus.h"

CAnimus::CAnimus(void)
{

}

void CAnimus::Begin()
{
  PersMem.Begin(); // loads data from EEPROM to RAM
  AnimusKeyboard.Begin(); // initialise keyboard module
  Comms.Begin(BAUD); // start comms
  Mod.Begin(); // initialise mods
}

void CAnimus::Loop()
{
  MillisLoop(); // checks pseudoRTOS status

  // start of pseudo rtos code
  if (Async1MSDelay()) // should run once every 1 to 1.5ms
  {

    // layering checks in case of layout remapping
    if (Global.KeyLayer >= Global.LAY || Global.TempLayer >= Global.LAY)
    {
      Global.KeyLayer = 0;
      Global.TempLayer = 0;
    }

    KeyScan(); // physical key layers scanned
    // start of physical key loops
    for (byte i = 0; i < Global.ROW; i++) // this is placed inside the 1ms delay to slow it down a bit
    {
      for (byte j = 0; j < Global.COL; j++)
      {
        if (Global.KeyState[j][i] == HIGH) // if key is down
        {
          if (Global.KeyStateCoolDown[j][i] == 0) // if key was not recently released
          {
            PressCoords(j, i);
            Global.LayerState[j][i] = Global.TempLayer;
            PrePress(PersMem.GetKeyData(j, i, Global.TempLayer), PersMem.GetKeyType(j, i, Global.TempLayer));
            PressKey(PersMem.GetKeyData(j, i, Global.TempLayer), PersMem.GetKeyType(j, i, Global.TempLayer));
            Global.KeyStateCoolDown[j][i] = 255;
          }
        }
        else if (Global.KeyState[j][i] == LOW) // if key is up
        {
          if (Global.KeyStateCoolDown[j][i] == 255 - Global.KeyUpDelay) // if key was previously held down AND is currently up after KeyUpDelay amount of time
          {
            ReleaseKey(PersMem.GetKeyData(j, i, Global.LayerState[j][i]), PersMem.GetKeyType(j, i, Global.LayerState[j][i]));
            Global.KeyStateCoolDown[j][i] = Global.KeyDownDelay;
          }
        }
      }
    }
    // end of physical key loops
    // start of countdowns
    for (byte i = 0; i < Global.ROW; i++)
    {
      for (byte j = 0; j < Global.COL; j++)
      {
        // what we did here saved 16 bits per key
        if (Global.KeyStateCoolDown[j][i] > 0 && Global.KeyStateCoolDown[j][i] != 255 - Global.KeyUpDelay)
        {
          Global.KeyStateCoolDown[j][i]--; // decrement KeyStateCoolDown if the key is being held down or if it was released, thus activating the keyup and keydown cooldowns
        }
      }
    }
    //end of countdowns
  }
  // end of pesudo rtos
  PersMem.Loop();
  Mod.Loop();
  Comms.Loop();
}

void CAnimus::PressCoords(byte x, byte y)
{
  Mod.PressCoords(x, y);
}

void CAnimus::PrePress(byte val, byte type)
{
  Mod.PrePress(val, type);
}

void CAnimus::PressKey(byte val, byte type)
{
  if (Global.HasUSB)
  {
    if (type == 0) // normal HID keystroke
    {
      AnimusKeyboard.Press(val);
    }
    else if (type == 1) // FN keys
    {
      Global.TempLayer = val;
    }
    else if (type == 2) // move main layer up or down or bitwise rotate the layer
    {
      if (val == 0)
      {
        SwitchLayer(true);
      }
      else if (val == 1)
      {
        SwitchLayer(false);
      }
      else
      {
        RotateLayer(val);
      }
    }
    else if (type == 3) // toggle layers
    {
      if (Global.TempLayer == val)
      {
        Global.TempLayer = Global.KeyLayer;
      }
      else
      {
        Global.TempLayer = val;
      }
    }
  }

  // for other key types, use a mod
  Mod.PressKey(val, type);
}

void CAnimus::ReleaseKey(byte val, byte type)
{
  if (Global.HasUSB)
  {
    if (type == 0)
    {
      AnimusKeyboard.Release(val);

    }
    else if (type == 1)
    {
      Global.TempLayer = Global.KeyLayer;
    }
  }
  Mod.ReleaseKey(val, type);
}

void CAnimus::SwitchLayer(bool increment)
{
  if (increment) // if true, go up a layer
  {
    Global.KeyLayer++;
  }
  else
  {
    Global.KeyLayer--;
  }
  if (Global.KeyLayer > 254) // rollover handling
  {
    Global.KeyLayer = Global.LAY -1;
  }
  else if (Global.KeyLayer >= Global.LAY)
  {
    Global.KeyLayer = 0;
  }

}

void CAnimus::RotateLayer(byte val) // bitwise layer shift
{
  byte newLayer = Global.KeyLayer;
  byte mask = 1 << newLayer;
  if (!val)
  {
    /* No layers are allowed. Do nothing. */
    return;
  }

  /*
  Find the next layer within the bitfield.
  Limit iterations to 10, to ensure no infinite loop.
  */
  for (byte i = 0; i < 10; i++)
  {
    newLayer++;
    mask <<= 1;
    if ((! mask) || (newLayer >= Global.LAY))
    {
      newLayer = 0;
      mask = 1;
    }

    if (val & mask)
    {
      /* newLayer is an allowed layer within the bitfield. */
      break;
    }
  }
  Global.KeyLayer = newLayer;
}

void CAnimus::KeyScan()
{
  for (int i = 0; i < Global.COL; i++)
  {
    pinMode(Global.HPins[i], OUTPUT);

    for (int j = 0; j < Global.ROW; j++)
    {
      byte val = digitalRead(Global.VPins[j]);
      Global.KeyState[i][j] = (val == LOW);
    }

    pinMode(Global.HPins[i], INPUT);
  }
}

void CAnimus::MillisLoop()
{
  CurrentMillis = millis();

  if(CurrentMillis - PreviousMillis >= 1) // this elapses every 1-1.5 ms
  {
    PreviousMillis = CurrentMillis;
    ReadyMillis = true;
  }
  else
  {
    ReadyMillis = false;
  }
}

bool CAnimus::Async1MSDelay()
{
  return ReadyMillis;
}

CAnimus Animus;
<|endoftext|>


<commit_before>/*=========================================================================

Library:   IntersonArray

Copyright Kitware Inc. 28 Corporate Drive,
Clifton Park, NY, 12065, USA.

All rights reserved.

Licensed under the Apache License, Version 2.0 ( the "License" );
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

=========================================================================*/
#include <Windows.h> // Sleep

#include "itkImageFileWriter.h"

#include "IntersonArrayCxxControlsHWControls.h"
#include "IntersonArrayCxxImagingContainer.h"

#include "AcquireIntersonArrayBModeCLP.h"

typedef IntersonArrayCxx::Imaging::Container ContainerType;

const unsigned int Dimension = 3;
typedef ContainerType::PixelType           PixelType;
typedef itk::Image< PixelType, Dimension > ImageType;

struct CallbackClientData
{
  ImageType *        Image;
  itk::SizeValueType FrameIndex;
};

void __stdcall pasteIntoImage( PixelType * buffer, void * clientData )
{
  CallbackClientData * callbackClientData =
    static_cast< CallbackClientData * >( clientData );
  ImageType * image = callbackClientData->Image;

  const ImageType::RegionType & largestRegion =
    image->GetLargestPossibleRegion();
  const ImageType::SizeType imageSize = largestRegion.GetSize();
  const itk::SizeValueType imageFrames = imageSize[2];
  if( callbackClientData->FrameIndex >= imageFrames )
    {
    return;
    }

  const int framePixels = imageSize[0] * imageSize[1];

  PixelType * imageBuffer = image->GetPixelContainer()->GetBufferPointer();
  imageBuffer += framePixels * callbackClientData->FrameIndex;
  std::memcpy( imageBuffer, buffer, framePixels * sizeof( PixelType ) );

  std::cout << "Acquired frame: " << callbackClientData->FrameIndex
    << std::endl;
  ++(callbackClientData->FrameIndex);
}

int main( int argc, char * argv[] )
{
  PARSE_ARGS;

  typedef IntersonArrayCxx::Controls::HWControls HWControlsType;
  HWControlsType hwControls;

  const int steering = 0;
  typedef HWControlsType::FoundProbesType FoundProbesType;
  FoundProbesType foundProbes;
  hwControls.FindAllProbes( foundProbes );
  if( foundProbes.empty() )
    {
    std::cerr << "Could not find the probe." << std::endl;
    return EXIT_FAILURE;
    }
  hwControls.FindMyProbe( 0 );
  const unsigned int probeId = hwControls.GetProbeID();
  if( probeId == 0 )
    {
    std::cerr << "Could not find the probe." << std::endl;
    return EXIT_FAILURE;
    }

  HWControlsType::FrequenciesType frequencies;
  hwControls.GetFrequency( frequencies );
  if( !hwControls.SetFrequencyAndFocus( frequencyIndex, focusIndex,
      steering ) )
    {
    std::cerr << "Could not set the frequency." << std::endl;
    return EXIT_FAILURE;
    }

  if( !hwControls.SendHighVoltage( highVoltage, highVoltage ) )
    {
    std::cerr << "Could not set the high voltage." << std::endl;
    return EXIT_FAILURE;
    }
  if( !hwControls.EnableHighVoltage() )
    {
    std::cerr << "Could not enable high voltage." << std::endl;
    return EXIT_FAILURE;
    }

  if( !hwControls.SendDynamic( gain ) )
    {
    std::cerr << "Could not set dynamic gain." << std::endl;
    }

  hwControls.DisableHardButton();

  ContainerType container;
  container.SetRFData( false );

  const int height = hwControls.GetLinesPerArray();
  const int width = container.MAX_SAMPLES;
  const int depth = 100;
  const int depthCfm = 50;
  if( hwControls.ValidDepth( depth ) == depth )
    {
    ContainerType::ScanConverterError converterErrorIdle =
      container.IdleInitScanConverter( depth, width, height, probeId,
        steering, depthCfm, false, false, 0, false );
    ContainerType::ScanConverterError converterError =
      container.HardInitScanConverter( depth, width, height, steering,
        depthCfm );
    if( converterError != ContainerType::SUCCESS )
      {
      std::cerr << "Error during hard scan converter initialization: "
                << converterError << std::endl;
      return EXIT_FAILURE;
      }
    }
  else
    {
    std::cerr << "Invalid requested depth for probe." << std::endl;
    }

  const int scanWidth = container.GetWidthScan();
  const int scanHeight = container.GetHeightScan();
  std::cout << "Width = " << width << std::endl;
  std::cout << "Height = " << height << std::endl;
  std::cout << "ScanWidth = " << scanWidth << std::endl;
  std::cout << "ScanHeight = " << scanHeight << std::endl;
  std::cout << "MM per Pixel = " << container.GetMmPerPixel() << std::endl;
  std::cout << "Depth: " << depth << "mm" << std::endl;

  const itk::SizeValueType framesToCollect = frames;

  ImageType::Pointer image = ImageType::New();
  typedef ImageType::RegionType RegionType;
  RegionType imageRegion;
  ImageType::IndexType imageIndex;
  imageIndex.Fill( 0 );
  imageRegion.SetIndex( imageIndex );
  ImageType::SizeType imageSize;
  imageSize[0] = width;
  imageSize[1] = height;
  imageSize[2] = framesToCollect;
  imageRegion.SetSize( imageSize );
  image->SetRegions( imageRegion );
  ImageType::SpacingType imageSpacing;
  imageSpacing[ 0 ] = container.GetMmPerPixel();
  imageSpacing[ 1 ] = 38.0 / (height - 1);
  imageSpacing[ 2 ] = 1;
  image->SetSpacing( imageSpacing );
  image->Allocate();

  CallbackClientData clientData;
  clientData.Image = image.GetPointer();
  clientData.FrameIndex = 0;

  container.SetNewImageCallback( &pasteIntoImage, &clientData );
  container.StartReadScan();
  Sleep( 100 ); // "time to start"
  if( !hwControls.StartBmode() )
    {
    std::cerr << "Could not start B-mode collection." << std::endl;
    return EXIT_FAILURE;
    };

  int c = 0;
  while( clientData.FrameIndex < framesToCollect && c < 100 )
    {
    std::cout << clientData.FrameIndex << " of " << framesToCollect
      << std::endl;
    std::cout << c << " of 100" << std::endl;
    Sleep( 100 );
    ++c;
    }

  hwControls.StopAcquisition();
  container.StopReadScan();
  Sleep( 100 ); // "time to stop"

  typedef itk::ImageFileWriter< ImageType > WriterType;
  WriterType::Pointer writer = WriterType::New();
  writer->SetFileName( outputImage );
  writer->SetInput( image );
  try
    {
    writer->Update();
    }
  catch( itk::ExceptionObject & error )
    {
    std::cerr << "Error: " << error << std::endl;
    return EXIT_FAILURE;
    }

  return EXIT_SUCCESS;
}
<commit_msg>BUG: Add correct Direction and Axial spacing for AcquireIntersonArrayBMode<commit_after>/*=========================================================================

Library:   IntersonArray

Copyright Kitware Inc. 28 Corporate Drive,
Clifton Park, NY, 12065, USA.

All rights reserved.

Licensed under the Apache License, Version 2.0 ( the "License" );
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

=========================================================================*/
#include <Windows.h> // Sleep

#include "itkImageFileWriter.h"

#include "IntersonArrayCxxControlsHWControls.h"
#include "IntersonArrayCxxImagingContainer.h"

#include "AcquireIntersonArrayBModeCLP.h"

typedef IntersonArrayCxx::Imaging::Container ContainerType;

const unsigned int Dimension = 3;
typedef ContainerType::PixelType           PixelType;
typedef itk::Image< PixelType, Dimension > ImageType;

struct CallbackClientData
{
  ImageType *        Image;
  itk::SizeValueType FrameIndex;
};

void __stdcall pasteIntoImage( PixelType * buffer, void * clientData )
{
  CallbackClientData * callbackClientData =
    static_cast< CallbackClientData * >( clientData );
  ImageType * image = callbackClientData->Image;

  const ImageType::RegionType & largestRegion =
    image->GetLargestPossibleRegion();
  const ImageType::SizeType imageSize = largestRegion.GetSize();
  const itk::SizeValueType imageFrames = imageSize[2];
  if( callbackClientData->FrameIndex >= imageFrames )
    {
    return;
    }

  const int framePixels = imageSize[0] * imageSize[1];

  PixelType * imageBuffer = image->GetPixelContainer()->GetBufferPointer();
  imageBuffer += framePixels * callbackClientData->FrameIndex;
  std::memcpy( imageBuffer, buffer, framePixels * sizeof( PixelType ) );

  std::cout << "Acquired frame: " << callbackClientData->FrameIndex
    << std::endl;
  ++(callbackClientData->FrameIndex);
}

int main( int argc, char * argv[] )
{
  PARSE_ARGS;

  typedef IntersonArrayCxx::Controls::HWControls HWControlsType;
  HWControlsType hwControls;

  const int steering = 0;
  typedef HWControlsType::FoundProbesType FoundProbesType;
  FoundProbesType foundProbes;
  hwControls.FindAllProbes( foundProbes );
  if( foundProbes.empty() )
    {
    std::cerr << "Could not find the probe." << std::endl;
    return EXIT_FAILURE;
    }
  hwControls.FindMyProbe( 0 );
  const unsigned int probeId = hwControls.GetProbeID();
  if( probeId == 0 )
    {
    std::cerr << "Could not find the probe." << std::endl;
    return EXIT_FAILURE;
    }

  HWControlsType::FrequenciesType frequencies;
  hwControls.GetFrequency( frequencies );
  if( !hwControls.SetFrequencyAndFocus( frequencyIndex, focusIndex,
      steering ) )
    {
    std::cerr << "Could not set the frequency." << std::endl;
    return EXIT_FAILURE;
    }

  if( !hwControls.SendHighVoltage( highVoltage, highVoltage ) )
    {
    std::cerr << "Could not set the high voltage." << std::endl;
    return EXIT_FAILURE;
    }
  if( !hwControls.EnableHighVoltage() )
    {
    std::cerr << "Could not enable high voltage." << std::endl;
    return EXIT_FAILURE;
    }

  if( !hwControls.SendDynamic( gain ) )
    {
    std::cerr << "Could not set dynamic gain." << std::endl;
    }

  hwControls.DisableHardButton();

  ContainerType container;
  container.SetRFData( false );

  const int height = hwControls.GetLinesPerArray();
  const int width = container.MAX_SAMPLES;
  const int depth = 100;
  const int depthCfm = 50;
  if( hwControls.ValidDepth( depth ) == depth )
    {
    ContainerType::ScanConverterError converterErrorIdle =
      container.IdleInitScanConverter( depth, width, height, probeId,
        steering, depthCfm, false, false, 0, false );
    ContainerType::ScanConverterError converterError =
      container.HardInitScanConverter( depth, width, height, steering,
        depthCfm );
    if( converterError != ContainerType::SUCCESS )
      {
      std::cerr << "Error during hard scan converter initialization: "
                << converterError << std::endl;
      return EXIT_FAILURE;
      }
    }
  else
    {
    std::cerr << "Invalid requested depth for probe." << std::endl;
    }

  const int scanWidth = container.GetWidthScan();
  const int scanHeight = container.GetHeightScan();
  std::cout << "Width = " << width << std::endl;
  std::cout << "Height = " << height << std::endl;
  std::cout << "ScanWidth = " << scanWidth << std::endl;
  std::cout << "ScanHeight = " << scanHeight << std::endl;
  std::cout << "MM per Pixel = " << container.GetMmPerPixel() << std::endl;
  std::cout << "Depth: " << depth << "mm" << std::endl;

  const itk::SizeValueType framesToCollect = frames;

  ImageType::Pointer image = ImageType::New();
  typedef ImageType::RegionType RegionType;
  RegionType imageRegion;
  ImageType::IndexType imageIndex;
  imageIndex.Fill( 0 );
  imageRegion.SetIndex( imageIndex );
  ImageType::SizeType imageSize;
  imageSize[0] = width;
  imageSize[1] = height;
  imageSize[2] = framesToCollect;
  imageRegion.SetSize( imageSize );
  image->SetRegions( imageRegion );
  ImageType::SpacingType imageSpacing;
  imageSpacing[ 0 ] = container.GetMmPerPixel() / 10.;
  imageSpacing[ 1 ] = 38.0 / (height - 1);
  imageSpacing[ 2 ] = 1;
  image->SetSpacing( imageSpacing );
  ImageType::DirectionType direction;
  direction.SetIdentity();
  ImageType::DirectionType::InternalMatrixType & vnlDirection = direction.GetVnlMatrix();
  vnlDirection.put(0, 0,  0.0);
  vnlDirection.put(0, 1, -1.0);
  vnlDirection.put(1, 0,  1.0);
  vnlDirection.put(1, 1,  0.0);
  image->SetDirection( direction );
  image->Allocate();

  CallbackClientData clientData;
  clientData.Image = image.GetPointer();
  clientData.FrameIndex = 0;

  container.SetNewImageCallback( &pasteIntoImage, &clientData );
  container.StartReadScan();
  Sleep( 100 ); // "time to start"
  if( !hwControls.StartBmode() )
    {
    std::cerr << "Could not start B-mode collection." << std::endl;
    return EXIT_FAILURE;
    };

  int c = 0;
  while( clientData.FrameIndex < framesToCollect && c < 100 )
    {
    std::cout << clientData.FrameIndex << " of " << framesToCollect
      << std::endl;
    std::cout << c << " of 100" << std::endl;
    Sleep( 100 );
    ++c;
    }

  hwControls.StopAcquisition();
  container.StopReadScan();
  Sleep( 100 ); // "time to stop"

  typedef itk::ImageFileWriter< ImageType > WriterType;
  WriterType::Pointer writer = WriterType::New();
  writer->SetFileName( outputImage );
  writer->SetInput( image );
  try
    {
    writer->Update();
    }
  catch( itk::ExceptionObject & error )
    {
    std::cerr << "Error: " << error << std::endl;
    return EXIT_FAILURE;
    }

  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>// Author: Valeri Fine   21/01/2002
/****************************************************************************
** $Id$
**
** Copyright (C) 2002 by Valeri Fine. Brookhaven National Laboratory.
**                                    All rights reserved.
**
** This file may be distributed under the terms of the Q Public License
** as defined by Trolltech AS of Norway and appearing in the file
** LICENSE.QPL included in the packaging of this file.
**
*****************************************************************************/

/////////////////////////////////////////////////////////////////////////////////
//
// TQtPadFont class is Qt QFont class with TAttText ROOT class interface
//
/////////////////////////////////////////////////////////////////////////////////

#include "TQtPadFont.h"
#include "TSystem.h"
#include "TMath.h"
#include <QFontMetrics>
#include <QDebug>

TString TQtPadFont::fgRomanFontName   = "Times New Roman";
TString TQtPadFont::fgArialFontName   = "Arial";
TString TQtPadFont::fgCourierFontName = "Courier New";
TString TQtPadFont::fgSymbolFontFamily= "Symbol";

//______________________________________________________________________________
static float CalibrateFont()
{
    // Use the ROOT font with ID=1 to calibrate the current font on fly;
    // Environment variable ROOTFONTFACTOR allows to set the factor manually
    static float fontCalibFactor = -1;
    if (fontCalibFactor  < 0 ) {

       const char * envFactor = gSystem->Getenv("ROOTFONTFACTOR");
       bool ok=false;
       if (envFactor && envFactor[0])
          fontCalibFactor= QString(envFactor).toFloat(&ok);
       if (!ok) {
          TQtPadFont pattern;
          pattern.SetTextFont(62);

          int w,h;
          QFontMetrics metrics(pattern);
          w = metrics.width("This is a PX distribution");
          h = metrics.height();

//  X11 returns          h = 12
//  XFT returns          h = 14
//  WIN32 TTF returns    h = 16
//  Nimbus Roman returns h = 18
//  Qt4 XFT              h = 21

#if 0
          qDebug() << " Font metric w = " << w <<" h = "<< h
                   << "points=" << pattern.pointSize()
                   << "pixels=" << pattern.pixelSize()
                   << pattern;
#endif

          float f;
          switch (h) {
             case 12: f = 1.10;  break;// it was  f = 1.13 :-(;
             case 14: f = 0.915; break;// it was f = 0.94  :-(;
             case 16: f = 0.965; break;// to be tested yet
             case 18: f = 0.92;  break;// to be tested yet
             case 20: f = 0.99;  break;// to be tested yet
             case 21: f = 0.90;  break;// to be tested yet
             default: f = 1.10;  break;
          }
          fontCalibFactor = f;
       }
    }
    return fontCalibFactor;
}

//______________________________________________________________________________
static inline float FontMagicFactor(float size)
{
   // Adjust the font size to match that for Postscipt format
   static float calibration =0;
   if (calibration == 0) calibration = CalibrateFont();
   return TMath::Max(calibration*size,Float_t(1.0));
}

//______________________________________________________________________________
TQtPadFont::TQtPadFont(): TAttText()
{fTextFont = -1;fTextSize = -1; }

//______________________________________________________________________________
void  TQtPadFont::SetTextFont(const char *fontname, int italic_, int bold_)
{

   //*-*    mode              : Option message
   //*-*    italic   : Italic attribut of the TTF font
   //*-*    bold     : Weight attribute of the TTF font
   //*-*    fontname : the name of True Type Font (TTF) to draw text.
   //*-*
   //*-*    Set text font to specified name. This function returns 0 if
   //*-*    the specified font is found, 1 if not.

   this->setWeight((long) bold_*10);
   this->setItalic((Bool_t)italic_);
   this->setFamily(fontname);
#if QT_VERSION >= 0x40000
   if (!strcmp(fontname,RomanFontName())) {
      this->setStyleHint(QFont::Serif);
   } else if (!strcmp(fontname,ArialFontName())) {
      this->setStyleHint(QFont::SansSerif);
   } else if (!strcmp(fontname,CourierFontName())){
      this->setStyleHint(QFont::TypeWriter);
   }
   this->setStyleStrategy(QFont::PreferDevice);
#if 0
   qDebug() << "TQtPadFont::SetTextFont:" << fontname
         << this->lastResortFamily ()
         << this->lastResortFont ()
         << this->substitute (fontname)
         << "ROOT  font number=" << fTextFont;
#endif
#endif
#if 0
   qDebug() << "TGQt::SetTextFont font:"    << fontname
            << " bold="  << bold_
            << " italic="<< italic_;
#endif
}

//______________________________________________________________________________
void  TQtPadFont::SetTextFont(Font_t fontnumber)
{
   //*-*-*-*-*-*-*-*-*-*-*-*-*Set current text font number*-*-*-*-*-*-*-*-*-*-*-*
   //*-*                      ===========================
   //*-*  List of the currently supported fonts (screen and PostScript)
   //*-*  =============================================================
   //*-*   Font ID       X11                       Win32 TTF       lfItalic  lfWeight x 10
   //*-*        1 : times-medium-i-normal      "Times New Roman"      1           5
   //*-*        2 : times-bold-r-normal        "Times New Roman"      0           8
   //*-*        3 : times-bold-i-normal        "Times New Roman"      1           8
   //*-*        4 : helvetica-medium-r-normal  "Arial"                0           5
   //*-*        5 : helvetica-medium-o-normal  "Arial"                1           5
   //*-*        6 : helvetica-bold-r-normal    "Arial"                0           8
   //*-*        7 : helvetica-bold-o-normal    "Arial"                1           8
   //*-*        8 : courier-medium-r-normal    "Courier New"          0           5
   //*-*        9 : courier-medium-o-normal    "Courier New"          1           5
   //*-*       10 : courier-bold-r-normal      "Courier New"          0           8
   //*-*       11 : courier-bold-o-normal      "Courier New"          1           8
   //*-*       12 : symbol-medium-r-normal     "Symbol"               0           6
   //*-*       13 : times-medium-r-normal      "Times New Roman"      0           5
   //*-*       14 :                            "Wingdings"            0           5

   if ( (fTextFont == fontnumber)  || (fontnumber <0) ) return;
   TAttText::SetTextFont(fontnumber);

   int it, bld;
   const char *fontName = RomanFontName();

   switch(fTextFont/10) {

   case  1:
      it  = 1;
      bld = 5;
      fontName = RomanFontName();
      break;
   case  2:
      it  = 0;
      bld = 8;
      fontName = RomanFontName();
      break;
   case  3:
      it  = 1;
      bld = 8;
      fontName = RomanFontName();
      break;
   case  4:
      it  = 0;
      bld = 5;
      fontName = ArialFontName();
      break;
   case  5:
      it  = 1;
      bld = 5;
      fontName = ArialFontName();
      break;
   case  6:
      it  = 0;
      bld = 8;
      fontName = ArialFontName();
      break;
   case  7:
      it  = 1;
      bld = 8;
      fontName = ArialFontName();
      break;
   case  8:
      it   = 0;
      bld  = 5;
      fontName = CourierFontName();
      break;
   case  9:
      it  = 1;
      bld = 5;
      fontName = CourierFontName();
      break;
   case 10:
      it  = 0;
      bld = 8;
      fontName = CourierFontName();
      break;
   case 11:
      it  = 1;
      bld = 8;
      fontName = CourierFontName();
      break;
   case 12:
      it  = 0;
      bld = 5;
      fontName = SymbolFontFamily();
      break;
   case 13:
      it  = 0;
      bld = 5;
      fontName = RomanFontName();
      break;
   case 14:
      it  = 0;
      bld = 5;
      fontName = "Wingdings";
      break;
   default:
      it  = 0;
      bld = 5;
      fontName = RomanFontName();
      break;

   }
   SetTextFont(fontName, it, bld);
}

//______________________________________________________________________________
void  TQtPadFont::SetTextSize(Float_t textsize)
{
   //*-*-*-*-*-*-*-*-*-*-*-*-*Set current text size*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
   //*-*                      =====================
   if ( fTextSize != textsize ) {
      TAttText::SetTextSize(textsize);
      if (fTextSize > 0) {
         Int_t   tsize =(Int_t)( textsize+0.5);
         SetTextSizePixels(int(FontMagicFactor(tsize)));
      }
   }
}
//______________________________________________________________________________
 void  TQtPadFont::SetTextSizePixels(Int_t npixels)
 {
    // Set the text pixel size
    TAttText::SetTextSizePixels(npixels);
    if (npixels <=0) npixels=1;
    this->setPixelSize(npixels);
 }
//______________________________________________________________________________
const char *TQtPadFont::RomanFontName()
{
   // Get the system name for the "Roman" font
   return fgRomanFontName;
}

//______________________________________________________________________________
const char *TQtPadFont::ArialFontName()
{
   // Get the system name for the "Arial" font
   return fgArialFontName;
}

//______________________________________________________________________________
const char *TQtPadFont::CourierFontName()
{
   // Get the system name for the "Courier" font
   return fgCourierFontName;
}
//______________________________________________________________________________
const char *TQtPadFont::SymbolFontFamily()
{
   // Get the system name for the "Symbol" font
   return fgSymbolFontFamily;
}
//______________________________________________________________________________
void TQtPadFont::SetSymbolFontFamily(const char *symbolFnName)
{
   // Set the system name for the "Symbol" font
   fgSymbolFontFamily = symbolFnName;  // we need the TString here !!!
}

//______________________________________________________________________________
void   TQtPadFont::SetTextMagnify(Float_t  mgn)
{
   //
   // Scale the font accroding the inout mgn magnification factor
   // mgn        : magnification factor
   // -------
   // see: TVirtualX::DrawText(int x, int y, float angle, float mgn, const char *text, TVirtualX::ETextMode /*mode*/)
   //
    Int_t tsize = (Int_t)(fTextSize+0.5);
    if (TMath::Abs(mgn-1) >0.05)  {
       int pxSize = mgn*FontMagicFactor(tsize);
       if(pxSize<=0) pxSize=1;
       this->setPixelSize(pxSize);
    }
}
<commit_msg>Fix a compilation warning<commit_after>// Author: Valeri Fine   21/01/2002
/****************************************************************************
** $Id$
**
** Copyright (C) 2002 by Valeri Fine. Brookhaven National Laboratory.
**                                    All rights reserved.
**
** This file may be distributed under the terms of the Q Public License
** as defined by Trolltech AS of Norway and appearing in the file
** LICENSE.QPL included in the packaging of this file.
**
*****************************************************************************/

/////////////////////////////////////////////////////////////////////////////////
//
// TQtPadFont class is Qt QFont class with TAttText ROOT class interface
//
/////////////////////////////////////////////////////////////////////////////////

#include "TQtPadFont.h"
#include "TSystem.h"
#include "TMath.h"
#include <QFontMetrics>
#include <QDebug>

TString TQtPadFont::fgRomanFontName   = "Times New Roman";
TString TQtPadFont::fgArialFontName   = "Arial";
TString TQtPadFont::fgCourierFontName = "Courier New";
TString TQtPadFont::fgSymbolFontFamily= "Symbol";

//______________________________________________________________________________
static float CalibrateFont()
{
    // Use the ROOT font with ID=1 to calibrate the current font on fly;
    // Environment variable ROOTFONTFACTOR allows to set the factor manually
    static float fontCalibFactor = -1;
    if (fontCalibFactor  < 0 ) {

       const char * envFactor = gSystem->Getenv("ROOTFONTFACTOR");
       bool ok=false;
       if (envFactor && envFactor[0])
          fontCalibFactor= QString(envFactor).toFloat(&ok);
       if (!ok) {
          TQtPadFont pattern;
          pattern.SetTextFont(62);

          int w,h;
          QFontMetrics metrics(pattern);
          w = metrics.width("This is a PX distribution");
          h = metrics.height();

//  X11 returns          h = 12
//  XFT returns          h = 14
//  WIN32 TTF returns    h = 16
//  Nimbus Roman returns h = 18
//  Qt4 XFT              h = 21

#if 0
          qDebug() << " Font metric w = " << w <<" h = "<< h
                   << "points=" << pattern.pointSize()
                   << "pixels=" << pattern.pixelSize()
                   << pattern;
#endif

          float f;
          switch (h) {
             case 12: f = 1.10;  break;// it was  f = 1.13 :-(;
             case 14: f = 0.915; break;// it was f = 0.94  :-(;
             case 16: f = 0.965; break;// to be tested yet
             case 18: f = 0.92;  break;// to be tested yet
             case 20: f = 0.99;  break;// to be tested yet
             case 21: f = 0.90;  break;// to be tested yet
             default: f = 1.10;  break;
          }
          fontCalibFactor = f;
       }
    }
    return fontCalibFactor;
}

//______________________________________________________________________________
static inline float FontMagicFactor(float size)
{
   // Adjust the font size to match that for Postscipt format
   static float calibration =0;
   if (calibration == 0) calibration = CalibrateFont();
   return TMath::Max(calibration*size,Float_t(1.0));
}

//______________________________________________________________________________
TQtPadFont::TQtPadFont(): TAttText()
{fTextFont = -1;fTextSize = -1; }

//______________________________________________________________________________
void  TQtPadFont::SetTextFont(const char *fontname, int italic_, int bold_)
{

   //*-*    mode              : Option message
   //*-*    italic   : Italic attribut of the TTF font
   //*-*    bold     : Weight attribute of the TTF font
   //*-*    fontname : the name of True Type Font (TTF) to draw text.
   //*-*
   //*-*    Set text font to specified name. This function returns 0 if
   //*-*    the specified font is found, 1 if not.

   this->setWeight((long) bold_*10);
   this->setItalic((Bool_t)italic_);
   this->setFamily(fontname);
#if QT_VERSION >= 0x40000
   if (!strcmp(fontname,RomanFontName())) {
      this->setStyleHint(QFont::Serif);
   } else if (!strcmp(fontname,ArialFontName())) {
      this->setStyleHint(QFont::SansSerif);
   } else if (!strcmp(fontname,CourierFontName())){
      this->setStyleHint(QFont::TypeWriter);
   }
   this->setStyleStrategy(QFont::PreferDevice);
#if 0
   qDebug() << "TQtPadFont::SetTextFont:" << fontname
         << this->lastResortFamily ()
         << this->lastResortFont ()
         << this->substitute (fontname)
         << "ROOT  font number=" << fTextFont;
#endif
#endif
#if 0
   qDebug() << "TGQt::SetTextFont font:"    << fontname
            << " bold="  << bold_
            << " italic="<< italic_;
#endif
}

//______________________________________________________________________________
void  TQtPadFont::SetTextFont(Font_t fontnumber)
{
   //*-*-*-*-*-*-*-*-*-*-*-*-*Set current text font number*-*-*-*-*-*-*-*-*-*-*-*
   //*-*                      ===========================
   //*-*  List of the currently supported fonts (screen and PostScript)
   //*-*  =============================================================
   //*-*   Font ID       X11                       Win32 TTF       lfItalic  lfWeight x 10
   //*-*        1 : times-medium-i-normal      "Times New Roman"      1           5
   //*-*        2 : times-bold-r-normal        "Times New Roman"      0           8
   //*-*        3 : times-bold-i-normal        "Times New Roman"      1           8
   //*-*        4 : helvetica-medium-r-normal  "Arial"                0           5
   //*-*        5 : helvetica-medium-o-normal  "Arial"                1           5
   //*-*        6 : helvetica-bold-r-normal    "Arial"                0           8
   //*-*        7 : helvetica-bold-o-normal    "Arial"                1           8
   //*-*        8 : courier-medium-r-normal    "Courier New"          0           5
   //*-*        9 : courier-medium-o-normal    "Courier New"          1           5
   //*-*       10 : courier-bold-r-normal      "Courier New"          0           8
   //*-*       11 : courier-bold-o-normal      "Courier New"          1           8
   //*-*       12 : symbol-medium-r-normal     "Symbol"               0           6
   //*-*       13 : times-medium-r-normal      "Times New Roman"      0           5
   //*-*       14 :                            "Wingdings"            0           5

   if ( (fTextFont == fontnumber)  || (fontnumber <0) ) return;
   TAttText::SetTextFont(fontnumber);

   int it, bld;
   const char *fontName = RomanFontName();

   switch(fTextFont/10) {

   case  1:
      it  = 1;
      bld = 5;
      fontName = RomanFontName();
      break;
   case  2:
      it  = 0;
      bld = 8;
      fontName = RomanFontName();
      break;
   case  3:
      it  = 1;
      bld = 8;
      fontName = RomanFontName();
      break;
   case  4:
      it  = 0;
      bld = 5;
      fontName = ArialFontName();
      break;
   case  5:
      it  = 1;
      bld = 5;
      fontName = ArialFontName();
      break;
   case  6:
      it  = 0;
      bld = 8;
      fontName = ArialFontName();
      break;
   case  7:
      it  = 1;
      bld = 8;
      fontName = ArialFontName();
      break;
   case  8:
      it   = 0;
      bld  = 5;
      fontName = CourierFontName();
      break;
   case  9:
      it  = 1;
      bld = 5;
      fontName = CourierFontName();
      break;
   case 10:
      it  = 0;
      bld = 8;
      fontName = CourierFontName();
      break;
   case 11:
      it  = 1;
      bld = 8;
      fontName = CourierFontName();
      break;
   case 12:
      it  = 0;
      bld = 5;
      fontName = SymbolFontFamily();
      break;
   case 13:
      it  = 0;
      bld = 5;
      fontName = RomanFontName();
      break;
   case 14:
      it  = 0;
      bld = 5;
      fontName = "Wingdings";
      break;
   default:
      it  = 0;
      bld = 5;
      fontName = RomanFontName();
      break;

   }
   SetTextFont(fontName, it, bld);
}

//______________________________________________________________________________
void  TQtPadFont::SetTextSize(Float_t textsize)
{
   //*-*-*-*-*-*-*-*-*-*-*-*-*Set current text size*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
   //*-*                      =====================
   if ( fTextSize != textsize ) {
      TAttText::SetTextSize(textsize);
      if (fTextSize > 0) {
         Int_t   tsize =(Int_t)( textsize+0.5);
         SetTextSizePixels(int(FontMagicFactor(tsize)));
      }
   }
}
//______________________________________________________________________________
 void  TQtPadFont::SetTextSizePixels(Int_t npixels)
 {
    // Set the text pixel size
    TAttText::SetTextSizePixels(npixels);
    if (npixels <=0) npixels=1;
    this->setPixelSize(npixels);
 }
//______________________________________________________________________________
const char *TQtPadFont::RomanFontName()
{
   // Get the system name for the "Roman" font
   return fgRomanFontName;
}

//______________________________________________________________________________
const char *TQtPadFont::ArialFontName()
{
   // Get the system name for the "Arial" font
   return fgArialFontName;
}

//______________________________________________________________________________
const char *TQtPadFont::CourierFontName()
{
   // Get the system name for the "Courier" font
   return fgCourierFontName;
}
//______________________________________________________________________________
const char *TQtPadFont::SymbolFontFamily()
{
   // Get the system name for the "Symbol" font
   return fgSymbolFontFamily;
}
//______________________________________________________________________________
void TQtPadFont::SetSymbolFontFamily(const char *symbolFnName)
{
   // Set the system name for the "Symbol" font
   fgSymbolFontFamily = symbolFnName;  // we need the TString here !!!
}

//______________________________________________________________________________
void   TQtPadFont::SetTextMagnify(Float_t  mgn)
{
   //
   // Scale the font accroding the inout mgn magnification factor
   // mgn        : magnification factor
   // -------
   // see: TVirtualX::DrawText(int x, int y, float angle, float mgn, const char *text, TVirtualX::ETextMode /*mode*/)
   //
    Int_t tsize = (Int_t)(fTextSize+0.5);
    if (TMath::Abs(mgn-1) >0.05)  {
       int pxSize = int(mgn*FontMagicFactor(tsize));
       if(pxSize<=0) pxSize=1;
       this->setPixelSize(pxSize);
    }
}
<|endoftext|>


<commit_before>//
// Created by Vadim N. on 16/03/2016.
//

// #include "benchutils.h"
#include <Inference>

using namespace ymir;
using namespace std;

int main(int argc, char* argv[]) {

    // if (argc < 2) {
    //   std::cout << "Please re-run the script with the data folder path supplied." << std::endl;
    //   return 1;
    // }

    // std::chrono::system_clock::time_point tp1, tp2;

    // std::vector< std::pair<std::string, size_t> > timepoints;

    // std::vector<prob_t> logLvec;

    // std::string temp_str;

    // time_t vj_single_parse, vdj_single_parse,
    //         vj_single_prob, vj_single_meta,
    //         vj_single_infer, vdj_single_prob,
    //         vdj_single_meta, vdj_single_infer;

    // time_t vj_good_parse, vdj_good_parse,
    //         vj_good_prob, vj_good_meta,
    //         vj_good_infer, vdj_good_prob,
    //         vdj_good_meta, vdj_good_infer;

    // std::string BENCH_DATA_FOLDER = argv[1];

    // std::cout << "Data folder:\t[" << BENCH_DATA_FOLDER << "]" << endl;

    //
    // TCR alpha chain repertoire - VJ recombination
    //
    VDJRecombinationGenes vj_single_genes("Vgene",
                                          "/home/vadim/ymir/benchmark/data/trav.txt",
                                          "Jgene",
                                          "/home/vadim/ymir/benchmark/data/traj.txt");

    VDJRecombinationGenes vj_single_genes2(vj_single_genes);
    // VDJRecombinationGenes vj_single_genes3 = vj_single_genes;
    // vj_single_genes2 = vj_single_genes;

//     string input_alpha_file = "alpha.250k.txt";
//     string input_beta_file = "beta.250k.txt";

//     CDR3NucParser parser;
//     Cloneset cloneset_vj;

//     YMIR_BENCHMARK("Parsing VJ",
//                    parser.openAndParse(BENCH_DATA_FOLDER + input_alpha_file,
//                                        &cloneset_vj,
//                                        vj_single_genes,
//                                        NUCLEOTIDE,
//                                        VJ_RECOMB,
//                                        AlignmentColumnOptions(AlignmentColumnOptions::OVERWRITE, AlignmentColumnOptions::OVERWRITE),
//                                        VDJAlignerParameters(2)))

//     //
//     // TCR beta chain repertoire - VDJ recombination
//     //
// //    VDJRecombinationGenes vdj_single_genes("Vgene",
// //                                    BENCH_DATA_FOLDER + "trbv.txt",
// //                                    "Jgene",
// //                                    BENCH_DATA_FOLDER + "trbj.txt",
// //                                    "Dgene",
// //                                    BENCH_DATA_FOLDER + "trbd.txt");
// //
// //    Cloneset cloneset_vdj;
// //    YMIR_BENCHMARK("Parsing VDJ",
// //                   parser.openAndParse(BENCH_DATA_FOLDER + input_beta_file,
// //                                       &cloneset_vdj,
// //                                       vdj_single_genes,
// //                                       NUCLEOTIDE,
// //                                       VDJ_RECOMB,
// //                                       AlignmentColumnOptions()
// //                                               .setV(AlignmentColumnOptions::USE_PROVIDED)
// //                                               .setD(AlignmentColumnOptions::OVERWRITE)
// //                                               .setJ(AlignmentColumnOptions::USE_PROVIDED),
// //                                       VDJAlignerParameters(3)))

//     //
//     // VJ MAAG
//     //
//     ProbabilisticAssemblingModel vj_single_model(BENCH_DATA_FOLDER + "../../models/hTRA", EMPTY);

//     //
//     // VDJ MAAG
//     //
// //    ProbabilisticAssemblingModel vdj_single_model(BENCH_DATA_FOLDER + "../../models/hTRB", EMPTY);

//     //
//     // Inference
//     //
//     vector<int> vec_sample = {10000, 25000, 50000, 100000, 150000};
//     vec_sample = { 100000 };
//     vector<int> vec_block = {500, 1000, 2000, 5000, 10000}; //, 2000, 5000, 10000};
// //    vec_block = {2000, 5000, 10000};
//     vec_block = { std::stoi(argv[2]) };
//     vector<double> vec_alpha = {.5, .6, .7, .8, .9};
//     vec_alpha = { std::stof(argv[3]) };
//     vector<double> vec_beta =  {.1, .5, 1, 3};
//     vec_beta = { std::stof(argv[4]) };
//     vector<double> vec_K =     {1, 2, 3};
//     vec_K = { std::stod(argv[5]) };
//     ErrorMode error_mode = COMPUTE_ERRORS;

// //    int niter, sample, block;
// //    double alpha;
// //    niter = 10;
// //    int sample = 10000;

// //    RUN_EM_INFERENCE(string("vj"), cloneset_vj, vj_single_model, niter, sample, error_mode)
// //    RUN_EM_INFERENCE(string("vdj"), cloneset_vdj, vdj_single_model, niter, sample, error_mode)
// //    for(auto val_sample: vec_sample) {
// //        RUN_EM_INFERENCE(string("vj"), cloneset_vj, vj_single_model, 40, val_sample, error_mode)
// //    }

// //    ModelParameterVector new_param_vec = vj_single_model.event_probabilities();
// //    new_param_vec.fill(1);
// //    new_param_vec.normaliseEventFamilies();
// //    vj_single_model.updateModelParameterVector(new_param_vec);
// //
// //    auto rep_nonc = cloneset_vj.noncoding().sample(2500);
// //    auto maag_rep = vj_single_model.buildGraphs(rep_nonc, SAVE_METADATA, error_mode, NUCLEOTIDE, true);
// //    vector<prob_t> prob_vec(maag_rep.size(), 0);
// //
// //    vector<bool> good_clonotypes(maag_rep.size(), true);
// //    for (size_t i = 0; i < maag_rep.size(); ++i) {
// //        if (rep_nonc[i].is_good()) {
// //            prob_vec[i] = maag_rep[i].fullProbability();
// //            if (std::isnan(prob_vec[i]) || prob_vec[i] == 0) {
// //                good_clonotypes[i] = false;
// //            }
// //        } else {
// //            good_clonotypes[i] = false;
// //        }
// //    }

//     for(auto val_sample: vec_sample) {
//         for(auto val_block: vec_block) {
//             for (auto val_alpha: vec_alpha) {
//                 for (auto val_beta: vec_beta) {
//                     for (auto val_K: vec_K) {
//                         RUN_SG_INFERENCE(string("vj"), cloneset_vj, vj_single_model, 40, val_block, val_alpha, val_beta, val_K, val_sample, error_mode)
//                     }
//                 }
//             }
//         }
//     }

}
<commit_msg>debug<commit_after>//
// Created by Vadim N. on 16/03/2016.
//

// #include "benchutils.h"
#include <Inference>

using namespace ymir;
using namespace std;

int main(int argc, char* argv[]) {

    // if (argc < 2) {
    //   std::cout << "Please re-run the script with the data folder path supplied." << std::endl;
    //   return 1;
    // }

    // std::chrono::system_clock::time_point tp1, tp2;

    // std::vector< std::pair<std::string, size_t> > timepoints;

    // std::vector<prob_t> logLvec;

    // std::string temp_str;

    // time_t vj_single_parse, vdj_single_parse,
    //         vj_single_prob, vj_single_meta,
    //         vj_single_infer, vdj_single_prob,
    //         vdj_single_meta, vdj_single_infer;

    // time_t vj_good_parse, vdj_good_parse,
    //         vj_good_prob, vj_good_meta,
    //         vj_good_infer, vdj_good_prob,
    //         vdj_good_meta, vdj_good_infer;

    // std::string BENCH_DATA_FOLDER = argv[1];

    // std::cout << "Data folder:\t[" << BENCH_DATA_FOLDER << "]" << endl;

    //
    // TCR alpha chain repertoire - VJ recombination
    //
    VDJRecombinationGenes vj_single_genes("Vgene",
                                          "/home/vadim/ymir/benchmark/data/trav.txt",
                                          "Jgene",
                                          "/home/vadim/ymir/benchmark/data/traj.txt");

    // VDJRecombinationGenes vj_single_genes2(vj_single_genes);
    VDJRecombinationGenes vj_single_genes3;
    vj_single_genes3 = vj_single_genes;

//     string input_alpha_file = "alpha.250k.txt";
//     string input_beta_file = "beta.250k.txt";

//     CDR3NucParser parser;
//     Cloneset cloneset_vj;

//     YMIR_BENCHMARK("Parsing VJ",
//                    parser.openAndParse(BENCH_DATA_FOLDER + input_alpha_file,
//                                        &cloneset_vj,
//                                        vj_single_genes,
//                                        NUCLEOTIDE,
//                                        VJ_RECOMB,
//                                        AlignmentColumnOptions(AlignmentColumnOptions::OVERWRITE, AlignmentColumnOptions::OVERWRITE),
//                                        VDJAlignerParameters(2)))

//     //
//     // TCR beta chain repertoire - VDJ recombination
//     //
// //    VDJRecombinationGenes vdj_single_genes("Vgene",
// //                                    BENCH_DATA_FOLDER + "trbv.txt",
// //                                    "Jgene",
// //                                    BENCH_DATA_FOLDER + "trbj.txt",
// //                                    "Dgene",
// //                                    BENCH_DATA_FOLDER + "trbd.txt");
// //
// //    Cloneset cloneset_vdj;
// //    YMIR_BENCHMARK("Parsing VDJ",
// //                   parser.openAndParse(BENCH_DATA_FOLDER + input_beta_file,
// //                                       &cloneset_vdj,
// //                                       vdj_single_genes,
// //                                       NUCLEOTIDE,
// //                                       VDJ_RECOMB,
// //                                       AlignmentColumnOptions()
// //                                               .setV(AlignmentColumnOptions::USE_PROVIDED)
// //                                               .setD(AlignmentColumnOptions::OVERWRITE)
// //                                               .setJ(AlignmentColumnOptions::USE_PROVIDED),
// //                                       VDJAlignerParameters(3)))

//     //
//     // VJ MAAG
//     //
//     ProbabilisticAssemblingModel vj_single_model(BENCH_DATA_FOLDER + "../../models/hTRA", EMPTY);

//     //
//     // VDJ MAAG
//     //
// //    ProbabilisticAssemblingModel vdj_single_model(BENCH_DATA_FOLDER + "../../models/hTRB", EMPTY);

//     //
//     // Inference
//     //
//     vector<int> vec_sample = {10000, 25000, 50000, 100000, 150000};
//     vec_sample = { 100000 };
//     vector<int> vec_block = {500, 1000, 2000, 5000, 10000}; //, 2000, 5000, 10000};
// //    vec_block = {2000, 5000, 10000};
//     vec_block = { std::stoi(argv[2]) };
//     vector<double> vec_alpha = {.5, .6, .7, .8, .9};
//     vec_alpha = { std::stof(argv[3]) };
//     vector<double> vec_beta =  {.1, .5, 1, 3};
//     vec_beta = { std::stof(argv[4]) };
//     vector<double> vec_K =     {1, 2, 3};
//     vec_K = { std::stod(argv[5]) };
//     ErrorMode error_mode = COMPUTE_ERRORS;

// //    int niter, sample, block;
// //    double alpha;
// //    niter = 10;
// //    int sample = 10000;

// //    RUN_EM_INFERENCE(string("vj"), cloneset_vj, vj_single_model, niter, sample, error_mode)
// //    RUN_EM_INFERENCE(string("vdj"), cloneset_vdj, vdj_single_model, niter, sample, error_mode)
// //    for(auto val_sample: vec_sample) {
// //        RUN_EM_INFERENCE(string("vj"), cloneset_vj, vj_single_model, 40, val_sample, error_mode)
// //    }

// //    ModelParameterVector new_param_vec = vj_single_model.event_probabilities();
// //    new_param_vec.fill(1);
// //    new_param_vec.normaliseEventFamilies();
// //    vj_single_model.updateModelParameterVector(new_param_vec);
// //
// //    auto rep_nonc = cloneset_vj.noncoding().sample(2500);
// //    auto maag_rep = vj_single_model.buildGraphs(rep_nonc, SAVE_METADATA, error_mode, NUCLEOTIDE, true);
// //    vector<prob_t> prob_vec(maag_rep.size(), 0);
// //
// //    vector<bool> good_clonotypes(maag_rep.size(), true);
// //    for (size_t i = 0; i < maag_rep.size(); ++i) {
// //        if (rep_nonc[i].is_good()) {
// //            prob_vec[i] = maag_rep[i].fullProbability();
// //            if (std::isnan(prob_vec[i]) || prob_vec[i] == 0) {
// //                good_clonotypes[i] = false;
// //            }
// //        } else {
// //            good_clonotypes[i] = false;
// //        }
// //    }

//     for(auto val_sample: vec_sample) {
//         for(auto val_block: vec_block) {
//             for (auto val_alpha: vec_alpha) {
//                 for (auto val_beta: vec_beta) {
//                     for (auto val_K: vec_K) {
//                         RUN_SG_INFERENCE(string("vj"), cloneset_vj, vj_single_model, 40, val_block, val_alpha, val_beta, val_K, val_sample, error_mode)
//                     }
//                 }
//             }
//         }
//     }

}
<|endoftext|>


<commit_before>#include <cstdlib>
#include <ctime>
#include <iostream>
#include <iterator>

#include "bench_common.h"
#include <algorithm>
#include <atomic>
#include <boost/program_options.hpp>
#include <chrono>
#include <cmath>
#include <ctime>
#include <dariadb.h>
#include <limits>
#include <random>
#include <storage/capacitor.h>
#include <thread>
#include <utils/fs.h>
#include <utils/metrics.h>

namespace po = boost::program_options;

std::atomic_long append_count{0};
std::atomic_size_t reads_count{0};
bool stop_info = false;
bool stop_readers = false;

class BenchCallback : public dariadb::storage::ReaderClb {
public:
  BenchCallback() { count = 0; }
  void call(const dariadb::Meas &) { count++; }
  size_t count;
};

void show_info(dariadb::storage::Engine *storage) {
  clock_t t0 = clock();
  while (true) {
    std::this_thread::sleep_for(std::chrono::milliseconds(100));

    clock_t t1 = clock();
    auto writes_per_sec =
        append_count.load() / double((t1 - t0) / CLOCKS_PER_SEC);
    auto reads_per_sec =
        reads_count.load() / double((t1 - t0) / CLOCKS_PER_SEC);
    auto queue_sizes = storage->queue_size();
    std::cout << "\r"
              << " in queue: (p:" << queue_sizes.pages_count
              << " cap:" << queue_sizes.cola_count
              << " a:" << queue_sizes.aofs_count << ")"
              << " reads: " << reads_count << " speed:" << reads_per_sec
              << "/sec"
              << " writes: " << append_count << " speed: " << writes_per_sec
              << "/sec progress:"
              << (int64_t(100) * append_count) / dariadb_bench::all_writes
              << "%                ";
    std::cout.flush();
    if (stop_info) {
      std::cout.flush();
      break;
    }
  }
  std::cout << "\n";
}

void reader(dariadb::storage::MeasStorage_ptr ms, dariadb::IdSet all_id_set,
            dariadb::Time from, dariadb::Time to) {
  std::random_device r;
  std::default_random_engine e1(r());
  std::uniform_int_distribution<dariadb::Id> uniform_dist(from, to);
  std::shared_ptr<BenchCallback> clbk{new BenchCallback};

  while (true) {
    clbk->count = 0;
    auto time_point1 = uniform_dist(e1);
    auto f = 0;
    auto t = time_point1;

    auto qi = dariadb::storage::QueryInterval(
        dariadb::IdArray(all_id_set.begin(), all_id_set.end()), 0, f, t);
    ms->readInterval(qi)->readAll(clbk.get());

    reads_count += clbk->count;
    if (stop_readers) {
      break;
    }
  }
}

int main(int argc, char *argv[]) {
  (void)argc;
  (void)argv;
  std::cout << "Performance benchmark" << std::endl;
  std::cout << "Writers count:" << dariadb_bench::total_threads_count
            << std::endl;

  const std::string storage_path = "perf_benchmark_storage";
  bool readers_enable = false;
  bool metrics_enable = false;
  bool readonly = false;
  bool readall_enabled = false;
  bool dont_clean = false;
  po::options_description desc("Allowed options");
  desc.add_options()("help", "produce help message")(
      "readonly", "readonly mode")("readall", "read all benchmark enable.")(
      "dont-clean", "dont clean storage path before start.")(
      "enable-readers",
      po::value<bool>(&readers_enable)->default_value(readers_enable),
      "enable readers threads")(
      "enable-metrics",
      po::value<bool>(&metrics_enable)->default_value(metrics_enable));

  po::variables_map vm;
  try {
    po::store(po::parse_command_line(argc, argv, desc), vm);
  } catch (std::exception &ex) {
    logger("Error: " << ex.what());
    exit(1);
  }
  po::notify(vm);

  if (vm.count("help")) {
    std::cout << desc << std::endl;
    return 1;
  }

  if (metrics_enable) {
    std::cout << "Enable metrics." << std::endl;
  }

  if (vm.count("readonly")) {
    std::cout << "Readonly mode." << std::endl;
    readonly = true;
  }

  if (vm.count("readall")) {
    std::cout << "Read all benchmark enabled." << std::endl;
    readall_enabled = true;
  }

  if (vm.count("dont-clean")) {
    std::cout << "Dont clean storage." << std::endl;
    dont_clean = true;
  }

  if (readers_enable) {
    std::cout << "Readers enable. count: " << dariadb_bench::total_readers_count
              << std::endl;
  }

  {
    std::cout << "Write..." << std::endl;

    const size_t chunk_per_storage = 1024 * 100;
    const size_t chunk_size = 1024;
    const size_t cap_B = 50;
    const size_t max_mem_chunks = 100;

    // dont_clean = true;
    if (!dont_clean && dariadb::utils::fs::path_exists(storage_path)) {
      if (!readonly) {
        std::cout << " remove " << storage_path << std::endl;
        dariadb::utils::fs::rm(storage_path);
      }
    }

    dariadb::Time start_time =
        dariadb::Time(0); // dariadb::timeutil::current_time();
    std::cout << " start time: " << dariadb::timeutil::to_string(start_time)
              << std::endl;
    dariadb::storage::PageManager::Params page_param(
        storage_path, chunk_per_storage, chunk_size);
    dariadb::storage::CapacitorManager::Params cap_param(storage_path, cap_B);
    cap_param.max_levels = 11;
    cap_param.max_closed_caps = 0;
    dariadb::storage::AOFManager::Params aof_param(storage_path, 0);
    aof_param.buffer_size = 1000;
    aof_param.max_size = cap_param.measurements_count();

    cap_param.max_levels = 11;
    auto raw_ptr = new dariadb::storage::Engine(
        aof_param, page_param, cap_param,
        dariadb::storage::Engine::Limits(max_mem_chunks));

    dariadb::storage::MeasStorage_ptr ms{raw_ptr};

    dariadb::IdSet all_id_set;
    append_count = 0;
    stop_info = false;

    std::thread info_thread(show_info, raw_ptr);

    std::vector<std::thread> writers(dariadb_bench::total_threads_count);
    std::vector<std::thread> readers(dariadb_bench::total_readers_count);

    size_t pos = 0;
    for (size_t i = 1; i < dariadb_bench::total_threads_count + 1; i++) {
      auto id_from = dariadb_bench::get_id_from(pos);
      auto id_to = dariadb_bench::get_id_to(pos);
      for (size_t j = id_from; j < id_to; j++) {
        all_id_set.insert(j);
      }
      if (!readonly) {
        std::thread t{dariadb_bench::thread_writer_rnd_stor, dariadb::Id(pos),
                      dariadb::Time(i), &append_count, raw_ptr};
        writers[pos] = std::move(t);
      }
      pos++;
    }
    if (readers_enable) {
      pos = 0;
      for (size_t i = 1; i < dariadb_bench::total_readers_count + 1; i++) {
        std::thread t{reader, ms, all_id_set, dariadb::Time(0),
                      dariadb::timeutil::current_time()};
        readers[pos++] = std::move(t);
      }
    }

    if (!readonly) {
      pos = 0;
      for (size_t i = 1; i < dariadb_bench::total_threads_count + 1; i++) {
        std::thread t = std::move(writers[pos++]);
        t.join();
      }
    }
    stop_readers = true;
    if (readers_enable) {
      pos = 0;
      for (size_t i = 1; i < dariadb_bench::total_readers_count + 1; i++) {
        std::thread t = std::move(readers[pos++]);
        t.join();
      }
    }

    stop_info = true;
    info_thread.join();
    std::cout << " total id:" << all_id_set.size() << std::endl;
    {
      std::cout << "full flush..." << std::endl;
      stop_info = false;
      std::thread flush_info_thread(show_info, raw_ptr);

      auto start = clock();
      raw_ptr->flush();
      auto elapsed = (((float)clock() - start) / CLOCKS_PER_SEC);
      stop_info = true;
      flush_info_thread.join();
      std::cout << "flush time: " << elapsed << std::endl;
    }

    if(!readonly){
	  auto ccount =size_t(raw_ptr->queue_size().cola_count * 0.5);
      std::cout << "drop part caps to "<<ccount<<"..." << std::endl;
      stop_info = false;
      std::thread flush_info_thread(show_info, raw_ptr);

      auto start = clock();
      raw_ptr->drop_part_caps(ccount);
      auto elapsed = (((float)clock() - start) / CLOCKS_PER_SEC);
      stop_info = true;
      flush_info_thread.join();
      std::cout << "drop time: " << elapsed << std::endl;
    }

    auto queue_sizes = raw_ptr->queue_size();
    std::cout << "\r"
              << " in queue: (p:" << queue_sizes.pages_count
              << " cap:" << queue_sizes.cola_count
              << " a:" << queue_sizes.aofs_count << ")"
              << " reads: " << reads_count << " writes: " << append_count
              << std::endl;

    dariadb_bench::readBenchark(all_id_set, ms.get(), 10, start_time,
                                dariadb::timeutil::current_time());

    if (readall_enabled) {
      std::cout << "read all..." << std::endl;
      std::shared_ptr<BenchCallback> clbk{new BenchCallback()};
      auto max_time = ms->maxTime();
      std::cout << " end time: " << dariadb::timeutil::to_string(max_time)
                << std::endl;

      auto start = clock();

      dariadb::storage::QueryInterval qi{
          dariadb::IdArray(all_id_set.begin(), all_id_set.end()), 0, start_time,
          max_time};
      ms->readInterval(qi)->readAll(clbk.get());

      auto elapsed = (((float)clock() - start) / CLOCKS_PER_SEC);
      std::cout << "readed: " << clbk->count << std::endl;
      std::cout << "time: " << elapsed << std::endl;
      auto expected =
          (dariadb_bench::iteration_count * dariadb_bench::total_threads_count *
           dariadb_bench::id_per_thread);

      if (!readonly && (!dont_clean && clbk->count != expected)) {
        std::cout << "expected: " << expected << " get:" << clbk->count
                  << std::endl;
        throw MAKE_EXCEPTION(
            "(clbk->count!=(iteration_count*total_threads_count))");
      } else {
        if (!readonly && (dont_clean && clbk->count < expected)) {
          std::cout << "expected: " << expected << " get:" << clbk->count
                    << std::endl;
          throw MAKE_EXCEPTION(
              "(clbk->count!=(iteration_count*total_threads_count))");
        }
      }
    }
    std::cout << "stoping storage...\n";
    ms = nullptr;
  }

  if (!(dont_clean || readonly) &&
      (dariadb::utils::fs::path_exists(storage_path))) {
    std::cout << "cleaning...\n";
    dariadb::utils::fs::rm(storage_path);
  }

  if (metrics_enable) {
    std::cout << "metrics:\n"
              << dariadb::utils::MetricsManager::instance()->to_string()
              << std::endl;
  }
}
<commit_msg>debug output.<commit_after>#include <cstdlib>
#include <ctime>
#include <iostream>
#include <iterator>

#include "bench_common.h"
#include <algorithm>
#include <atomic>
#include <boost/program_options.hpp>
#include <chrono>
#include <cmath>
#include <ctime>
#include <dariadb.h>
#include <limits>
#include <random>
#include <storage/capacitor.h>
#include <thread>
#include <utils/fs.h>
#include <utils/metrics.h>
#include <utils/thread_manager.h>

namespace po = boost::program_options;

std::atomic_long append_count{0};
std::atomic_size_t reads_count{0};
bool stop_info = false;
bool stop_readers = false;

class BenchCallback : public dariadb::storage::ReaderClb {
public:
  BenchCallback() { count = 0; }
  void call(const dariadb::Meas &v) { count++; all.push_back(v);}
  size_t count;
  dariadb::Meas::MeasList all;
};

void show_info(dariadb::storage::Engine *storage) {
  clock_t t0 = clock();
  while (true) {
    std::this_thread::sleep_for(std::chrono::milliseconds(100));

    clock_t t1 = clock();
    auto writes_per_sec =
        append_count.load() / double((t1 - t0) / CLOCKS_PER_SEC);
    auto reads_per_sec =
        reads_count.load() / double((t1 - t0) / CLOCKS_PER_SEC);
    auto queue_sizes = storage->queue_size();
    std::cout << "\r"
              << " in queue: (p:" << queue_sizes.pages_count
              << " cap:" << queue_sizes.cola_count
              << " a:" << queue_sizes.aofs_count << ")"
              << " reads: " << reads_count << " speed:" << reads_per_sec
              << "/sec"
              << " writes: " << append_count << " speed: " << writes_per_sec
              << "/sec progress:"
              << (int64_t(100) * append_count) / dariadb_bench::all_writes
              << "%                ";
    std::cout.flush();
    if (stop_info) {
      std::cout.flush();
      break;
    }
  }
  std::cout << "\n";
}

void reader(dariadb::storage::MeasStorage_ptr ms, dariadb::IdSet all_id_set,
            dariadb::Time from, dariadb::Time to) {
  std::random_device r;
  std::default_random_engine e1(r());
  std::uniform_int_distribution<dariadb::Id> uniform_dist(from, to);
  std::shared_ptr<BenchCallback> clbk{new BenchCallback};

  while (true) {
    clbk->count = 0;
    auto time_point1 = uniform_dist(e1);
    auto f = 0;
    auto t = time_point1;

    auto qi = dariadb::storage::QueryInterval(
        dariadb::IdArray(all_id_set.begin(), all_id_set.end()), 0, f, t);
    ms->readInterval(qi)->readAll(clbk.get());

    reads_count += clbk->count;
    if (stop_readers) {
      break;
    }
  }
}

int main(int argc, char *argv[]) {
  (void)argc;
  (void)argv;
  std::cout << "Performance benchmark" << std::endl;
  std::cout << "Writers count:" << dariadb_bench::total_threads_count
            << std::endl;

  const std::string storage_path = "perf_benchmark_storage";
  bool readers_enable = false;
  bool metrics_enable = false;
  bool readonly = false;
  bool readall_enabled = false;
  bool dont_clean = false;
  po::options_description desc("Allowed options");
  desc.add_options()("help", "produce help message")(
      "readonly", "readonly mode")("readall", "read all benchmark enable.")(
      "dont-clean", "dont clean storage path before start.")(
      "enable-readers",
      po::value<bool>(&readers_enable)->default_value(readers_enable),
      "enable readers threads")(
      "enable-metrics",
      po::value<bool>(&metrics_enable)->default_value(metrics_enable));

  po::variables_map vm;
  try {
    po::store(po::parse_command_line(argc, argv, desc), vm);
  } catch (std::exception &ex) {
    logger("Error: " << ex.what());
    exit(1);
  }
  po::notify(vm);

  if (vm.count("help")) {
    std::cout << desc << std::endl;
    return 1;
  }

  if (metrics_enable) {
    std::cout << "Enable metrics." << std::endl;
  }

  if (vm.count("readonly")) {
    std::cout << "Readonly mode." << std::endl;
    readonly = true;
  }

  if (vm.count("readall")) {
    std::cout << "Read all benchmark enabled." << std::endl;
    readall_enabled = true;
  }

  if (vm.count("dont-clean")) {
    std::cout << "Dont clean storage." << std::endl;
    dont_clean = true;
  }

  if (readers_enable) {
    std::cout << "Readers enable. count: " << dariadb_bench::total_readers_count
              << std::endl;
  }

  {
    std::cout << "Write..." << std::endl;

    const size_t chunk_per_storage = 1024 * 100;
    const size_t chunk_size = 1024;
    const size_t cap_B = 50;
    const size_t max_mem_chunks = 100;

    // dont_clean = true;
    if (!dont_clean && dariadb::utils::fs::path_exists(storage_path)) {
      if (!readonly) {
        std::cout << " remove " << storage_path << std::endl;
        dariadb::utils::fs::rm(storage_path);
      }
    }

    dariadb::Time start_time =
        dariadb::Time(0); // dariadb::timeutil::current_time();
    std::cout << " start time: " << dariadb::timeutil::to_string(start_time)
              << std::endl;
    dariadb::storage::PageManager::Params page_param(
        storage_path, chunk_per_storage, chunk_size);
    dariadb::storage::CapacitorManager::Params cap_param(storage_path, cap_B);
    cap_param.max_levels = 11;
    cap_param.max_closed_caps = 0;
    dariadb::storage::AOFManager::Params aof_param(storage_path, 0);
    aof_param.buffer_size = 1000;
    aof_param.max_size = cap_param.measurements_count();

    cap_param.max_levels = 11;
    auto raw_ptr = new dariadb::storage::Engine(
        aof_param, page_param, cap_param,
        dariadb::storage::Engine::Limits(max_mem_chunks));

    dariadb::storage::MeasStorage_ptr ms{raw_ptr};

    dariadb::IdSet all_id_set;
    append_count = 0;
    stop_info = false;

    std::thread info_thread(show_info, raw_ptr);

    std::vector<std::thread> writers(dariadb_bench::total_threads_count);
    std::vector<std::thread> readers(dariadb_bench::total_readers_count);

    size_t pos = 0;
    for (size_t i = 1; i < dariadb_bench::total_threads_count + 1; i++) {
      auto id_from = dariadb_bench::get_id_from(pos);
      auto id_to = dariadb_bench::get_id_to(pos);
      for (size_t j = id_from; j < id_to; j++) {
        all_id_set.insert(j);
      }
      if (!readonly) {
        std::thread t{dariadb_bench::thread_writer_rnd_stor, dariadb::Id(pos),
                      dariadb::Time(i), &append_count, raw_ptr};
        writers[pos] = std::move(t);
      }
      pos++;
    }
    if (readers_enable) {
      pos = 0;
      for (size_t i = 1; i < dariadb_bench::total_readers_count + 1; i++) {
        std::thread t{reader, ms, all_id_set, dariadb::Time(0),
                      dariadb::timeutil::current_time()};
        readers[pos++] = std::move(t);
      }
    }

    if (!readonly) {
      pos = 0;
      for (size_t i = 1; i < dariadb_bench::total_threads_count + 1; i++) {
        std::thread t = std::move(writers[pos++]);
        t.join();
      }
    }
    stop_readers = true;
    if (readers_enable) {
      pos = 0;
      for (size_t i = 1; i < dariadb_bench::total_readers_count + 1; i++) {
        std::thread t = std::move(readers[pos++]);
        t.join();
      }
    }

    stop_info = true;
    info_thread.join();
    std::cout << " total id:" << all_id_set.size() << std::endl;
    {
      std::cout << "full flush..." << std::endl;
      stop_info = false;
      std::thread flush_info_thread(show_info, raw_ptr);

      auto start = clock();
      raw_ptr->flush();
      auto elapsed = (((float)clock() - start) / CLOCKS_PER_SEC);
      stop_info = true;
      flush_info_thread.join();
      std::cout << "flush time: " << elapsed << std::endl;
    }

    if(!readonly){
	  auto ccount =size_t(raw_ptr->queue_size().cola_count * 0.5);
      std::cout << "drop part caps to "<<ccount<<"..." << std::endl;
      stop_info = false;
      std::thread flush_info_thread(show_info, raw_ptr);

      auto start = clock();
      raw_ptr->drop_part_caps(ccount);
      raw_ptr->flush();
      auto elapsed = (((float)clock() - start) / CLOCKS_PER_SEC);
      stop_info = true;
      flush_info_thread.join();
      std::cout << "drop time: " << elapsed << std::endl;
    }

    auto queue_sizes = raw_ptr->queue_size();
    std::cout << "\r"
              << " in queue: (p:" << queue_sizes.pages_count
              << " cap:" << queue_sizes.cola_count
              << " a:" << queue_sizes.aofs_count << ")"
              << " reads: " << reads_count << " writes: " << append_count
              << std::endl;

    dariadb_bench::readBenchark(all_id_set, ms.get(), 10, start_time,
                                dariadb::timeutil::current_time());

    std::cout
        << "Active threads: "
        << dariadb::utils::async::ThreadManager::instance()->active_works()
        << std::endl;
    if (readall_enabled) {
      std::cout << "read all..." << std::endl;
      std::shared_ptr<BenchCallback> clbk{new BenchCallback()};
      auto max_time = ms->maxTime();
      std::cout << " end time: " << dariadb::timeutil::to_string(max_time)
                << std::endl;

      auto start = clock();

      dariadb::storage::QueryInterval qi{
          dariadb::IdArray(all_id_set.begin(), all_id_set.end()), 0, start_time,
          max_time};
      ms->readInterval(qi)->readAll(clbk.get());

      auto elapsed = (((float)clock() - start) / CLOCKS_PER_SEC);
      std::cout << "readed: " << clbk->count << std::endl;
      std::cout << "time: " << elapsed << std::endl;
      auto expected =
          (dariadb_bench::iteration_count * dariadb_bench::total_threads_count *
           dariadb_bench::id_per_thread);

      std::map<dariadb::Id, dariadb::Meas::MeasList> _dict;
      for (auto &v : clbk->all) {
        _dict[v.id].push_back(v);
      }

      if (!readonly && (!dont_clean && clbk->count != expected)) {
        std::cout << "expected: " << expected << " get:" << clbk->count
                  << std::endl;

        for(auto&kv:_dict){
            std::cout<<" "<<kv.first<<" -> "<<kv.second.size()<<std::endl;
        }
        throw MAKE_EXCEPTION(
            "(clbk->count!=(iteration_count*total_threads_count))");
      } else {
        if (!readonly && (dont_clean && clbk->count < expected)) {
          std::cout << "expected: " << expected << " get:" << clbk->count
                    << std::endl;
          throw MAKE_EXCEPTION(
              "(clbk->count!=(iteration_count*total_threads_count))");
        }
      }
    }
    std::cout << "stoping storage...\n";
    ms = nullptr;
  }

  if (!(dont_clean || readonly) &&
      (dariadb::utils::fs::path_exists(storage_path))) {
    std::cout << "cleaning...\n";
    dariadb::utils::fs::rm(storage_path);
  }

  if (metrics_enable) {
    std::cout << "metrics:\n"
              << dariadb::utils::MetricsManager::instance()->to_string()
              << std::endl;
  }
}
<|endoftext|>