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

Program:   Medical Imaging & Interaction Toolkit
Language:  C++
Date:      $Date: 2009-05-12 19:56:03 +0200 (Di, 12 Mai 2009) $
Version:   $Revision: 17179 $

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "QmitkOverlayController.h"

#include "QmitkRenderWindow.h"
#include "QmitkOverlay.h"

#include <QHBoxLayout>
#include <QVBoxLayout>

#include <algorithm>

QmitkOverlayController::QmitkOverlayController( QmitkRenderWindow* rw, mitk::PropertyList* pl )
: QObject(), m_RenderWindow( rw ), m_PropertyList( pl )
{
  this->InitializeOverlayLayout();
  this->AdjustOverlayPosition();
  this->SetOverlayVisibility( true );

  if ( m_PropertyList.IsNull() )
    m_PropertyList = mitk::PropertyList::New();

}

QmitkOverlayController::~QmitkOverlayController()
{
}

void QmitkOverlayController::InitializeOverlayLayout()
{

  this->InitializeWidget( QmitkOverlay::top_Left );
  this->InitializeWidget( QmitkOverlay::top_Center );
  this->InitializeWidget( QmitkOverlay::top_Right );
  this->InitializeWidget( QmitkOverlay::middle_Left );
  this->InitializeWidget( QmitkOverlay::middle_Right );
  this->InitializeWidget( QmitkOverlay::bottom_Left );
  this->InitializeWidget( QmitkOverlay::bottom_Center );
  this->InitializeWidget( QmitkOverlay::bottom_Right );

}

void QmitkOverlayController::InitializeWidget( QmitkOverlay::DisplayPosition pos )
{
  m_PositionedOverlays[ pos ] = new QWidget( m_RenderWindow, Qt::Tool | Qt::FramelessWindowHint );
  m_PositionedOverlays[ pos ]->setAutoFillBackground(false);
  m_PositionedOverlays[ pos ]->setAttribute( Qt::WA_TranslucentBackground, true );
  //m_PositionedOverlays[ pos ]->setAttribute( Qt::WA_MacAlwaysShowToolWindow, true );
  //m_PositionedOverlays[ pos ]->setAttribute( Qt::WA_MacShowFocusRect, false );
  m_PositionedOverlays[ pos ]->setFocusPolicy( Qt::NoFocus );
  QPalette p = QPalette();
  p.setColor( QPalette::Window, Qt::transparent );
  m_PositionedOverlays[ pos ]->setPalette( p );

  switch ( pos )
  {
  case QmitkOverlay::top_Left :
    {
      QVBoxLayout* layout = new QVBoxLayout( m_PositionedOverlays[ pos ] );
      layout->setDirection( QBoxLayout::TopToBottom );
      layout->setAlignment( Qt::AlignLeft );
      break;
    }
  case QmitkOverlay::top_Center :
    {
      QVBoxLayout* layout = new QVBoxLayout( m_PositionedOverlays[ pos ] );
      layout->setDirection( QBoxLayout::TopToBottom );
      layout->setAlignment( Qt::AlignCenter );
      layout->setAlignment( Qt::AlignLeft );
      break;
    }
  case QmitkOverlay::top_Right :
    {
      QVBoxLayout* layout = new QVBoxLayout( m_PositionedOverlays[ pos ] );
      layout->setDirection( QBoxLayout::TopToBottom );
      layout->setAlignment( Qt::AlignRight );
      break;
    }
  case QmitkOverlay::middle_Left :
    {
      QHBoxLayout* layout = new QHBoxLayout( m_PositionedOverlays[ pos ] );
      layout->setDirection( QBoxLayout::LeftToRight );
      layout->setAlignment( Qt::AlignLeft );
      break;

    }
  case QmitkOverlay::middle_Right :
    {
      QHBoxLayout* layout = new QHBoxLayout( m_PositionedOverlays[ pos ] );
      layout->setDirection( QBoxLayout::RightToLeft );
      layout->setAlignment( Qt::AlignRight );
      break;
    }
  case QmitkOverlay::bottom_Left :
    {
      QVBoxLayout* layout = new QVBoxLayout( m_PositionedOverlays[ pos ] );
      layout->setDirection( QBoxLayout::BottomToTop );
      layout->setAlignment( Qt::AlignLeft );
      break;
    }
  case QmitkOverlay::bottom_Center :
    {
      QVBoxLayout* layout = new QVBoxLayout( m_PositionedOverlays[ pos ] );
      layout->setDirection( QBoxLayout::BottomToTop );
      layout->setAlignment( Qt::AlignCenter );
      break;
    }
  case QmitkOverlay::bottom_Right :
    {
      QVBoxLayout* layout = new QVBoxLayout( m_PositionedOverlays[ pos ] );
      layout->setDirection( QBoxLayout::BottomToTop );
      layout->setAlignment( Qt::AlignRight );
      break;
    }
  }
}

void QmitkOverlayController::AdjustOverlayPosition()
{

  if ( m_PositionedOverlays[ QmitkOverlay::top_Left ]->isVisible() )
  {
    QPoint pos = m_RenderWindow->mapToGlobal( QPoint(0,0) );
    m_PositionedOverlays[ QmitkOverlay::top_Left ]->move( pos.x(), pos.y() );
  }

  if ( m_PositionedOverlays[ QmitkOverlay::top_Center ]->isVisible() )
  {
    QWidget* widget = m_PositionedOverlays[ QmitkOverlay::top_Center ];
    QPoint pos = m_RenderWindow->mapToGlobal( QPoint( m_RenderWindow->size().width()/2, 0 ) ) ;
    widget->move( pos.x() - widget->size().width()/2, pos.y() );
  }

  if ( m_PositionedOverlays[ QmitkOverlay::top_Right ]->isVisible() )
  {
    QWidget* widget = m_PositionedOverlays[ QmitkOverlay::top_Right ];
    QPoint pos = m_RenderWindow->mapToGlobal( QPoint( m_RenderWindow->size().width(), 0 ) ) ;
    widget->move( pos.x() - widget->size().width(), pos.y() );
  }

  if ( m_PositionedOverlays[ QmitkOverlay::middle_Left ]->isVisible() )
  {
    QWidget* widget = m_PositionedOverlays[ QmitkOverlay::middle_Left ];
    QPoint pos = m_RenderWindow->mapToGlobal( QPoint( 0, m_RenderWindow->size().height()/2 ) ) ;
    widget->move( pos.x(), pos.y() - widget->size().height()/2 );
  }

  if ( m_PositionedOverlays[ QmitkOverlay::middle_Right ]->isVisible() )
  {
    QWidget* widget = m_PositionedOverlays[ QmitkOverlay::middle_Right ];
    QPoint pos = m_RenderWindow->mapToGlobal( QPoint( m_RenderWindow->size().width(), m_RenderWindow->size().height()/2 ) ) ;
    widget->move( pos.x() - widget->size().width(), pos.y() - widget->size().height()/2 );
  }

  if ( m_PositionedOverlays[ QmitkOverlay::bottom_Left ]->isVisible() )
  {
    QWidget* widget = m_PositionedOverlays[ QmitkOverlay::bottom_Left ];
    QPoint pos = m_RenderWindow->mapToGlobal( QPoint( 0, m_RenderWindow->size().height() ) ) ;
    widget->move( pos.x(), pos.y() - widget->size().height() );
  }

  if ( m_PositionedOverlays[ QmitkOverlay::bottom_Center ]->isVisible() )
  {
    QWidget* widget = m_PositionedOverlays[ QmitkOverlay::bottom_Center ];
    QPoint pos = m_RenderWindow->mapToGlobal( QPoint(  m_RenderWindow->size().width()/2, m_RenderWindow->size().height() ) ) ;
    widget->move( pos.x() - widget->size().width()/2, pos.y() - widget->size().height() );
  }

  if ( m_PositionedOverlays[ QmitkOverlay::bottom_Right ]->isVisible() )
  {
    QWidget* widget = m_PositionedOverlays[ QmitkOverlay::bottom_Right ];
    QPoint pos = m_RenderWindow->mapToGlobal( QPoint(  m_RenderWindow->size().width(), m_RenderWindow->size().height() ) ) ;
    widget->move( pos.x() - widget->size().width(), pos.y() - widget->size().height() );
  }

}

void QmitkOverlayController::SetOverlayVisibility( bool visible )
{
  foreach( QmitkOverlay* overlay, m_AllOverlays )
  {
    if ( visible )
    {
      MITK_INFO << "Setting visible";
      overlay->GetWidget()->show();
    }
    else
    {
      MITK_INFO << "hiding";
      overlay->GetWidget()->hide();
    }
  }
}

void QmitkOverlayController::AddOverlay( QmitkOverlay* overlay )
{
  if ( overlay != NULL )
  {
    QmitkOverlay::DisplayPosition pos = overlay->GetPosition();
    unsigned int layer = overlay->GetLayer();

    m_PropertyList->ConcatenatePropertyList( m_RenderWindow->GetRenderer()->GetRenderingManager()->GetPropertyList(), false );

    overlay->GenerateData( m_PropertyList );

    overlay->GetWidget()->setParent( m_PositionedOverlays[ pos ] );

    int stackLayer = dynamic_cast<QBoxLayout*>( m_PositionedOverlays[ pos ]->layout() )->isEmpty() ? 0 : layer;

    switch ( pos )
    {
      case QmitkOverlay::top_Left : {}
      case QmitkOverlay::middle_Left : {}
      case QmitkOverlay::bottom_Left :
        {
          dynamic_cast<QBoxLayout*>( m_PositionedOverlays[ pos ]->layout() )->insertWidget( overlay->GetLayer(), overlay->GetWidget(), stackLayer, Qt::AlignLeft );
          break;
        }
      case QmitkOverlay::top_Center : {}
      case QmitkOverlay::bottom_Center :
        {
          dynamic_cast<QBoxLayout*>( m_PositionedOverlays[ pos ]->layout() )->insertWidget( overlay->GetLayer(), overlay->GetWidget(), stackLayer, Qt::AlignCenter );
          break;
        }
      case QmitkOverlay::top_Right : {}
      case QmitkOverlay::middle_Right : {}
      case QmitkOverlay::bottom_Right :
        {
          dynamic_cast<QBoxLayout*>( m_PositionedOverlays[ pos ]->layout() )->insertWidget( overlay->GetLayer(), overlay->GetWidget(), stackLayer, Qt::AlignRight );
          break;
        }
    }

    m_PositionedOverlays[ pos ]->show();
    this->AdjustOverlayPosition();
  }
}

void QmitkOverlayController::AlignOverlays()
{
  //MITK_INFO << "mitkOverlayController::AlignOverlays";

  //OverlayVector::iterator overlayIter;

  //for ( overlayIter=m_AllOverlays.begin(); overlayIter!=m_AllOverlays.end(); overlayIter++ )
  //{
  //  int stackLayer = dynamic_cast<QBoxLayout*>( m_PositionedOverlays[ (*overlayIter)->GetPosition() ]->layout() )->isEmpty() ? 0 : layer;
  //  dynamic_cast<QBoxLayout*>( m_PositionedOverlays[ (*overlayIter)->GetPosition() ]->layout() )->addWidget( (*overlayIter)->GetWidget(), stackLayer, Qt::AlignLeft );
  //}
}<commit_msg>ENH (#3463): adding MITK_ERROR in case an invalied QmitkRenderWindow has been set<commit_after>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Language:  C++
Date:      $Date: 2009-05-12 19:56:03 +0200 (Di, 12 Mai 2009) $
Version:   $Revision: 17179 $

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "QmitkOverlayController.h"

#include "QmitkRenderWindow.h"
#include "QmitkOverlay.h"

#include <QHBoxLayout>
#include <QVBoxLayout>

#include <algorithm>

QmitkOverlayController::QmitkOverlayController( QmitkRenderWindow* rw, mitk::PropertyList* pl )
: QObject(), m_RenderWindow( rw ), m_PropertyList( pl )
{
  if ( m_RenderWindow == NULL )
  {
    MITK_ERROR << "invalid QmitkRenderWindow";
    return;
  }

  this->InitializeOverlayLayout();
  this->AdjustOverlayPosition();
  this->SetOverlayVisibility( true );

  if ( m_PropertyList.IsNull() )
    m_PropertyList = mitk::PropertyList::New();

}

QmitkOverlayController::~QmitkOverlayController()
{
}

void QmitkOverlayController::InitializeOverlayLayout()
{

  this->InitializeWidget( QmitkOverlay::top_Left );
  this->InitializeWidget( QmitkOverlay::top_Center );
  this->InitializeWidget( QmitkOverlay::top_Right );
  this->InitializeWidget( QmitkOverlay::middle_Left );
  this->InitializeWidget( QmitkOverlay::middle_Right );
  this->InitializeWidget( QmitkOverlay::bottom_Left );
  this->InitializeWidget( QmitkOverlay::bottom_Center );
  this->InitializeWidget( QmitkOverlay::bottom_Right );

}

void QmitkOverlayController::InitializeWidget( QmitkOverlay::DisplayPosition pos )
{
  m_PositionedOverlays[ pos ] = new QWidget( m_RenderWindow, Qt::Tool | Qt::FramelessWindowHint );
  m_PositionedOverlays[ pos ]->setAutoFillBackground(false);
  m_PositionedOverlays[ pos ]->setAttribute( Qt::WA_TranslucentBackground, true );
  //m_PositionedOverlays[ pos ]->setAttribute( Qt::WA_MacAlwaysShowToolWindow, true );
  //m_PositionedOverlays[ pos ]->setAttribute( Qt::WA_MacShowFocusRect, false );
  m_PositionedOverlays[ pos ]->setFocusPolicy( Qt::NoFocus );
  QPalette p = QPalette();
  p.setColor( QPalette::Window, Qt::transparent );
  m_PositionedOverlays[ pos ]->setPalette( p );

  switch ( pos )
  {
  case QmitkOverlay::top_Left :
    {
      QVBoxLayout* layout = new QVBoxLayout( m_PositionedOverlays[ pos ] );
      layout->setDirection( QBoxLayout::TopToBottom );
      layout->setAlignment( Qt::AlignLeft );
      break;
    }
  case QmitkOverlay::top_Center :
    {
      QVBoxLayout* layout = new QVBoxLayout( m_PositionedOverlays[ pos ] );
      layout->setDirection( QBoxLayout::TopToBottom );
      layout->setAlignment( Qt::AlignCenter );
      layout->setAlignment( Qt::AlignLeft );
      break;
    }
  case QmitkOverlay::top_Right :
    {
      QVBoxLayout* layout = new QVBoxLayout( m_PositionedOverlays[ pos ] );
      layout->setDirection( QBoxLayout::TopToBottom );
      layout->setAlignment( Qt::AlignRight );
      break;
    }
  case QmitkOverlay::middle_Left :
    {
      QHBoxLayout* layout = new QHBoxLayout( m_PositionedOverlays[ pos ] );
      layout->setDirection( QBoxLayout::LeftToRight );
      layout->setAlignment( Qt::AlignLeft );
      break;

    }
  case QmitkOverlay::middle_Right :
    {
      QHBoxLayout* layout = new QHBoxLayout( m_PositionedOverlays[ pos ] );
      layout->setDirection( QBoxLayout::RightToLeft );
      layout->setAlignment( Qt::AlignRight );
      break;
    }
  case QmitkOverlay::bottom_Left :
    {
      QVBoxLayout* layout = new QVBoxLayout( m_PositionedOverlays[ pos ] );
      layout->setDirection( QBoxLayout::BottomToTop );
      layout->setAlignment( Qt::AlignLeft );
      break;
    }
  case QmitkOverlay::bottom_Center :
    {
      QVBoxLayout* layout = new QVBoxLayout( m_PositionedOverlays[ pos ] );
      layout->setDirection( QBoxLayout::BottomToTop );
      layout->setAlignment( Qt::AlignCenter );
      break;
    }
  case QmitkOverlay::bottom_Right :
    {
      QVBoxLayout* layout = new QVBoxLayout( m_PositionedOverlays[ pos ] );
      layout->setDirection( QBoxLayout::BottomToTop );
      layout->setAlignment( Qt::AlignRight );
      break;
    }
  }
}

void QmitkOverlayController::AdjustOverlayPosition()
{

  if ( m_PositionedOverlays[ QmitkOverlay::top_Left ]->isVisible() )
  {
    QPoint pos = m_RenderWindow->mapToGlobal( QPoint(0,0) );
    m_PositionedOverlays[ QmitkOverlay::top_Left ]->move( pos.x(), pos.y() );
  }

  if ( m_PositionedOverlays[ QmitkOverlay::top_Center ]->isVisible() )
  {
    QWidget* widget = m_PositionedOverlays[ QmitkOverlay::top_Center ];
    QPoint pos = m_RenderWindow->mapToGlobal( QPoint( m_RenderWindow->size().width()/2, 0 ) ) ;
    widget->move( pos.x() - widget->size().width()/2, pos.y() );
  }

  if ( m_PositionedOverlays[ QmitkOverlay::top_Right ]->isVisible() )
  {
    QWidget* widget = m_PositionedOverlays[ QmitkOverlay::top_Right ];
    QPoint pos = m_RenderWindow->mapToGlobal( QPoint( m_RenderWindow->size().width(), 0 ) ) ;
    widget->move( pos.x() - widget->size().width(), pos.y() );
  }

  if ( m_PositionedOverlays[ QmitkOverlay::middle_Left ]->isVisible() )
  {
    QWidget* widget = m_PositionedOverlays[ QmitkOverlay::middle_Left ];
    QPoint pos = m_RenderWindow->mapToGlobal( QPoint( 0, m_RenderWindow->size().height()/2 ) ) ;
    widget->move( pos.x(), pos.y() - widget->size().height()/2 );
  }

  if ( m_PositionedOverlays[ QmitkOverlay::middle_Right ]->isVisible() )
  {
    QWidget* widget = m_PositionedOverlays[ QmitkOverlay::middle_Right ];
    QPoint pos = m_RenderWindow->mapToGlobal( QPoint( m_RenderWindow->size().width(), m_RenderWindow->size().height()/2 ) ) ;
    widget->move( pos.x() - widget->size().width(), pos.y() - widget->size().height()/2 );
  }

  if ( m_PositionedOverlays[ QmitkOverlay::bottom_Left ]->isVisible() )
  {
    QWidget* widget = m_PositionedOverlays[ QmitkOverlay::bottom_Left ];
    QPoint pos = m_RenderWindow->mapToGlobal( QPoint( 0, m_RenderWindow->size().height() ) ) ;
    widget->move( pos.x(), pos.y() - widget->size().height() );
  }

  if ( m_PositionedOverlays[ QmitkOverlay::bottom_Center ]->isVisible() )
  {
    QWidget* widget = m_PositionedOverlays[ QmitkOverlay::bottom_Center ];
    QPoint pos = m_RenderWindow->mapToGlobal( QPoint(  m_RenderWindow->size().width()/2, m_RenderWindow->size().height() ) ) ;
    widget->move( pos.x() - widget->size().width()/2, pos.y() - widget->size().height() );
  }

  if ( m_PositionedOverlays[ QmitkOverlay::bottom_Right ]->isVisible() )
  {
    QWidget* widget = m_PositionedOverlays[ QmitkOverlay::bottom_Right ];
    QPoint pos = m_RenderWindow->mapToGlobal( QPoint(  m_RenderWindow->size().width(), m_RenderWindow->size().height() ) ) ;
    widget->move( pos.x() - widget->size().width(), pos.y() - widget->size().height() );
  }

}

void QmitkOverlayController::SetOverlayVisibility( bool visible )
{
  foreach( QmitkOverlay* overlay, m_AllOverlays )
  {
    if ( visible )
    {
      MITK_INFO << "Setting visible";
      overlay->GetWidget()->show();
    }
    else
    {
      MITK_INFO << "hiding";
      overlay->GetWidget()->hide();
    }
  }
}

void QmitkOverlayController::AddOverlay( QmitkOverlay* overlay )
{
  if ( overlay != NULL )
  {
    QmitkOverlay::DisplayPosition pos = overlay->GetPosition();
    unsigned int layer = overlay->GetLayer();

    m_PropertyList->ConcatenatePropertyList( m_RenderWindow->GetRenderer()->GetRenderingManager()->GetPropertyList(), false );

    overlay->GenerateData( m_PropertyList );

    overlay->GetWidget()->setParent( m_PositionedOverlays[ pos ] );

    int stackLayer = dynamic_cast<QBoxLayout*>( m_PositionedOverlays[ pos ]->layout() )->isEmpty() ? 0 : layer;

    switch ( pos )
    {
      case QmitkOverlay::top_Left : {}
      case QmitkOverlay::middle_Left : {}
      case QmitkOverlay::bottom_Left :
        {
          dynamic_cast<QBoxLayout*>( m_PositionedOverlays[ pos ]->layout() )->insertWidget( overlay->GetLayer(), overlay->GetWidget(), stackLayer, Qt::AlignLeft );
          break;
        }
      case QmitkOverlay::top_Center : {}
      case QmitkOverlay::bottom_Center :
        {
          dynamic_cast<QBoxLayout*>( m_PositionedOverlays[ pos ]->layout() )->insertWidget( overlay->GetLayer(), overlay->GetWidget(), stackLayer, Qt::AlignCenter );
          break;
        }
      case QmitkOverlay::top_Right : {}
      case QmitkOverlay::middle_Right : {}
      case QmitkOverlay::bottom_Right :
        {
          dynamic_cast<QBoxLayout*>( m_PositionedOverlays[ pos ]->layout() )->insertWidget( overlay->GetLayer(), overlay->GetWidget(), stackLayer, Qt::AlignRight );
          break;
        }
    }

    m_PositionedOverlays[ pos ]->show();
    this->AdjustOverlayPosition();
  }
}

void QmitkOverlayController::AlignOverlays()
{
  //MITK_INFO << "mitkOverlayController::AlignOverlays";

  //OverlayVector::iterator overlayIter;

  //for ( overlayIter=m_AllOverlays.begin(); overlayIter!=m_AllOverlays.end(); overlayIter++ )
  //{
  //  int stackLayer = dynamic_cast<QBoxLayout*>( m_PositionedOverlays[ (*overlayIter)->GetPosition() ]->layout() )->isEmpty() ? 0 : layer;
  //  dynamic_cast<QBoxLayout*>( m_PositionedOverlays[ (*overlayIter)->GetPosition() ]->layout() )->addWidget( (*overlayIter)->GetWidget(), stackLayer, Qt::AlignLeft );
  //}
}<|endoftext|>


<commit_before>//
// Copyright(c) 2015 Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//

//
// bench.cpp : spdlog benchmarks
//
#include "spdlog/spdlog.h"
#include "spdlog/async.h"
#include "spdlog/sinks/basic_file_sink.h"
#include "spdlog/sinks/daily_file_sink.h"
#include "spdlog/sinks/null_sink.h"
#include "spdlog/sinks/rotating_file_sink.h"

#include "utils.h"
#include <atomic>
#include <cstdlib> // EXIT_FAILURE
#include <memory>
#include <string>
#include <thread>

using namespace std;
using namespace std::chrono;
using namespace spdlog;
using namespace spdlog::sinks;
using namespace utils;

void bench(int howmany, std::shared_ptr<spdlog::logger> log);
void bench_mt(int howmany, std::shared_ptr<spdlog::logger> log, int thread_count);
void bench_default_api(int howmany, std::shared_ptr<spdlog::logger> log);

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

    spdlog::default_logger()->set_pattern("[%^%l%$] %v");
    int howmany = 1000000;
    int queue_size = howmany + 2;
    int threads = 10;
    size_t file_size = 30 * 1024 * 1024;
    size_t rotating_files = 5;

    try
    {

        if (argc > 1)
            howmany = atoi(argv[1]);
        if (argc > 2)
            threads = atoi(argv[2]);
        if (argc > 3)
            queue_size = atoi(argv[3]);

        spdlog::info("**************************************************************");
        spdlog::info("Single thread, {:n} iterations", howmany);
        spdlog::info("**************************************************************");

        auto basic_st = spdlog::basic_logger_st("basic_st", "logs/basic_st.log", true);
        bench(howmany, std::move(basic_st));

        basic_st.reset();
        auto rotating_st = spdlog::rotating_logger_st("rotating_st", "logs/rotating_st.log", file_size, rotating_files);
        bench(howmany, std::move(rotating_st));

        auto daily_st = spdlog::daily_logger_st("daily_st", "logs/daily_st.log");
        bench(howmany, std::move(daily_st));

        bench(howmany, spdlog::create<null_sink_st>("null_st"));

        spdlog::info("**************************************************************");
        spdlog::info("Default API. Single thread, {:n} iterations", howmany);
        spdlog::info("**************************************************************");

        basic_st = spdlog::basic_logger_st("basic_st", "logs/basic_st.log", true);
        bench_default_api(howmany, std::move(basic_st));

        rotating_st = spdlog::rotating_logger_st("rotating_st", "logs/rotating_st.log", file_size, rotating_files);
        bench_default_api(howmany, std::move(rotating_st));

        daily_st = spdlog::daily_logger_st("daily_st", "logs/daily_st.log");
        bench_default_api(howmany, std::move(daily_st));

        bench_default_api(howmany, spdlog::create<null_sink_st>("null_st"));

        spdlog::info("**************************************************************");
        spdlog::info("{:n} threads sharing same logger, {:n} iterations", threads, howmany);
        spdlog::info("**************************************************************");

        auto basic_mt = spdlog::basic_logger_mt("basic_mt", "logs/basic_mt.log", true);
        bench_mt(howmany, std::move(basic_mt), threads);

        auto rotating_mt = spdlog::rotating_logger_mt("rotating_mt", "logs/rotating_mt.log", file_size, rotating_files);
        bench_mt(howmany, std::move(rotating_mt), threads);

        auto daily_mt = spdlog::daily_logger_mt("daily_mt", "logs/daily_mt.log");
        bench_mt(howmany, std::move(daily_mt), threads);
        bench_mt(howmany, spdlog::create<null_sink_mt>("null_mt"), threads);

        spdlog::info("**************************************************************");
        spdlog::info("Asyncronous.. {:n} threads sharing same logger, {:n} iterations", threads, howmany);
        spdlog::info("**************************************************************");

        for (int i = 0; i < 3; ++i)
        {
            spdlog::init_thread_pool(static_cast<size_t>(queue_size), 1);
            auto as = spdlog::basic_logger_mt<spdlog::async_factory>("async", "logs/basic_async.log", true);
            bench_mt(howmany, std::move(as), threads);
        }
    }
    catch (std::exception &ex)
    {
        spdlog::error(ex.what());
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

void bench(int howmany, std::shared_ptr<spdlog::logger> log)
{
    using std::chrono::high_resolution_clock;
    auto start = high_resolution_clock::now();
    for (auto i = 0; i < howmany; ++i)
    {
        log->info("Hello logger: msg number {}", i);
    }

    auto delta = high_resolution_clock::now() - start;
    auto delta_d = duration_cast<duration<double>>(delta).count();

    spdlog::info("{:<16} Elapsed: {:0.2f} secs {:>16n}/sec", log->name(), delta_d, int(howmany / delta_d));
    spdlog::drop(log->name());
}

void bench_mt(int howmany, std::shared_ptr<spdlog::logger> log, int thread_count)
{
    using std::chrono::high_resolution_clock;
    vector<thread> threads;
    auto start = high_resolution_clock::now();
    for (int t = 0; t < thread_count; ++t)
    {
        threads.push_back(std::thread([&]() {
            for (int j = 0; j < howmany / thread_count; j++)
            {
                log->info("Hello logger: msg number {}", j);
            }
        }));
    }

    for (auto &t : threads)
    {
        t.join();
    };

    auto delta = high_resolution_clock::now() - start;
    auto delta_d = duration_cast<duration<double>>(delta).count();
    spdlog::info("{:<16} Elapsed: {:0.2f} secs {:>16n}/sec", log->name(), delta_d, int(howmany / delta_d));
    spdlog::drop(log->name());
}

void bench_default_api(int howmany, std::shared_ptr<spdlog::logger> log)
{
    using std::chrono::high_resolution_clock;
    auto orig_default = spdlog::default_logger();
    spdlog::set_default_logger(log);
    auto start = high_resolution_clock::now();
    for (auto i = 0; i < howmany; ++i)
    {
        spdlog::info("Hello logger: msg number {}", i);
    }

    auto delta = high_resolution_clock::now() - start;
    auto delta_d = duration_cast<duration<double>>(delta).count();
    spdlog::drop(log->name());
    spdlog::set_default_logger(std::move(orig_default));
    spdlog::info("{:<16} Elapsed: {:0.2f} secs {:>16n}/sec", log->name(), delta_d, int(howmany / delta_d));
}
<commit_msg>Code formatting<commit_after>//
// Copyright(c) 2015 Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//

//
// bench.cpp : spdlog benchmarks
//
#include "spdlog/spdlog.h"
#include "spdlog/async.h"
#include "spdlog/sinks/basic_file_sink.h"
#include "spdlog/sinks/daily_file_sink.h"
#include "spdlog/sinks/null_sink.h"
#include "spdlog/sinks/rotating_file_sink.h"

#include "utils.h"
#include <atomic>
#include <cstdlib> // EXIT_FAILURE
#include <memory>
#include <string>
#include <thread>

using namespace std;
using namespace std::chrono;
using namespace spdlog;
using namespace spdlog::sinks;
using namespace utils;

void bench(int howmany, std::shared_ptr<spdlog::logger> log);
void bench_mt(int howmany, std::shared_ptr<spdlog::logger> log, int thread_count);
void bench_default_api(int howmany, std::shared_ptr<spdlog::logger> log);

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

    spdlog::default_logger()->set_pattern("[%^%l%$] %v");
    int howmany = 1000000;
    int queue_size = howmany + 2;
    int threads = 10;
    size_t file_size = 30 * 1024 * 1024;
    size_t rotating_files = 5;

    try
    {

        if (argc > 1)
            howmany = atoi(argv[1]);
        if (argc > 2)
            threads = atoi(argv[2]);
        if (argc > 3)
            queue_size = atoi(argv[3]);

        spdlog::info("**************************************************************");
        spdlog::info("Single thread, {:n} iterations", howmany);
        spdlog::info("**************************************************************");

        auto basic_st = spdlog::basic_logger_st("basic_st", "logs/basic_st.log", true);
        bench(howmany, std::move(basic_st));

        basic_st.reset();
        auto rotating_st = spdlog::rotating_logger_st("rotating_st", "logs/rotating_st.log", file_size, rotating_files);
        bench(howmany, std::move(rotating_st));

        auto daily_st = spdlog::daily_logger_st("daily_st", "logs/daily_st.log");
        bench(howmany, std::move(daily_st));

        bench(howmany, spdlog::create<null_sink_st>("null_st"));

        spdlog::info("**************************************************************");
        spdlog::info("Default API. Single thread, {:n} iterations", howmany);
        spdlog::info("**************************************************************");

        basic_st = spdlog::basic_logger_st("basic_st", "logs/basic_st.log", true);
        bench_default_api(howmany, std::move(basic_st));

        rotating_st = spdlog::rotating_logger_st("rotating_st", "logs/rotating_st.log", file_size, rotating_files);
        bench_default_api(howmany, std::move(rotating_st));

        daily_st = spdlog::daily_logger_st("daily_st", "logs/daily_st.log");
        bench_default_api(howmany, std::move(daily_st));

        bench_default_api(howmany, spdlog::create<null_sink_st>("null_st"));

        spdlog::info("**************************************************************");
        spdlog::info("{:n} threads sharing same logger, {:n} iterations", threads, howmany);
        spdlog::info("**************************************************************");

        auto basic_mt = spdlog::basic_logger_mt("basic_mt", "logs/basic_mt.log", true);
        bench_mt(howmany, std::move(basic_mt), threads);

        auto rotating_mt = spdlog::rotating_logger_mt("rotating_mt", "logs/rotating_mt.log", file_size, rotating_files);
        bench_mt(howmany, std::move(rotating_mt), threads);

        auto daily_mt = spdlog::daily_logger_mt("daily_mt", "logs/daily_mt.log");
        bench_mt(howmany, std::move(daily_mt), threads);
        bench_mt(howmany, spdlog::create<null_sink_mt>("null_mt"), threads);

        spdlog::info("**************************************************************");
        spdlog::info("Asyncronous.. {:n} threads sharing same logger, {:n} iterations", threads, howmany);
        spdlog::info("**************************************************************");

        for (int i = 0; i < 3; ++i)
        {
            spdlog::init_thread_pool(static_cast<size_t>(queue_size), 1);
            auto as = spdlog::basic_logger_mt<spdlog::async_factory>("async", "logs/basic_async.log", true);
            bench_mt(howmany, std::move(as), threads);
        }
    }
    catch (std::exception &ex)
    {
        spdlog::error(ex.what());
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

void bench(int howmany, std::shared_ptr<spdlog::logger> log)
{
    using std::chrono::high_resolution_clock;
    auto start = high_resolution_clock::now();
    for (auto i = 0; i < howmany; ++i)
    {
        log->info("Hello logger: msg number {}", i);
    }

    auto delta = high_resolution_clock::now() - start;
    auto delta_d = duration_cast<duration<double>>(delta).count();

    spdlog::info("{:<16} Elapsed: {:0.2f} secs {:>16n}/sec", log->name(), delta_d, int(howmany / delta_d));
    spdlog::drop(log->name());
}

void bench_mt(int howmany, std::shared_ptr<spdlog::logger> log, int thread_count)
{
    using std::chrono::high_resolution_clock;
    vector<thread> threads;
    auto start = high_resolution_clock::now();
    for (int t = 0; t < thread_count; ++t)
    {
        threads.push_back(std::thread([&]() {
            for (int j = 0; j < howmany / thread_count; j++)
            {
                log->info("Hello logger: msg number {}", j);
            }
        }));
    }

    for (auto &t : threads)
    {
        t.join();
    };

    auto delta = high_resolution_clock::now() - start;
    auto delta_d = duration_cast<duration<double>>(delta).count();
    spdlog::info("{:<16} Elapsed: {:0.2f} secs {:>16n}/sec", log->name(), delta_d, int(howmany / delta_d));
    spdlog::drop(log->name());
}

void bench_default_api(int howmany, std::shared_ptr<spdlog::logger> log)
{
    using std::chrono::high_resolution_clock;
    auto orig_default = spdlog::default_logger();
    spdlog::set_default_logger(log);
    auto start = high_resolution_clock::now();
    for (auto i = 0; i < howmany; ++i)
    {
        spdlog::info("Hello logger: msg number {}", i);
    }

    auto delta = high_resolution_clock::now() - start;
    auto delta_d = duration_cast<duration<double>>(delta).count();
    spdlog::drop(log->name());
    spdlog::set_default_logger(std::move(orig_default));
    spdlog::info("{:<16} Elapsed: {:0.2f} secs {:>16n}/sec", log->name(), delta_d, int(howmany / delta_d));
}
<|endoftext|>


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

#ifndef ADC_DISPLAY_HF_LINACHAIN_HXX
#define ADC_DISPLAY_HF_LINACHAIN_HXX

// BASE CLASSES
#include "htmlfactory.hxx"
#include "out_position.hxx"

class HF_LinkedNameChain : public HtmlMaker
{
  public:
    /** F_LinkMaker makes a link out of the name of the
        parent position.

        Returns true, if there is a link, false if not.
    */
    typedef String (*F_LinkMaker)(const char *);

                        HF_LinkedNameChain(
                            Xml::Element &      o_rOut );
    virtual             ~HF_LinkedNameChain();

    void                Produce_CompleteChain(
                            const output::Position &
                                                i_curPosition,
                            F_LinkMaker         i_linkMaker ) const;
    void                Produce_CompleteChain_forModule(
                            const output::Position &
                                                i_curPosition,  /// current Module's node
                            F_LinkMaker         i_linkMaker ) const;
  private:
    void                produce_Level(
                            output::Node &      i_levelNode,
                            const output::Position &
                                                i_startPosition,
                            F_LinkMaker         i_linkMaker ) const;
};

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

#ifndef ADC_DISPLAY_HF_LINACHAIN_HXX
#define ADC_DISPLAY_HF_LINACHAIN_HXX

// BASE CLASSES
#include "htmlfactory.hxx"
#include "out_position.hxx"

class HF_LinkedNameChain : public HtmlMaker
{
  public:
    /** F_LinkMaker makes a link out of the name of the
        parent position.

        Returns true, if there is a link, false if not.
    */
    typedef String (*F_LinkMaker)(const char *);

                        HF_LinkedNameChain(
                            Xml::Element &      o_rOut );
    virtual             ~HF_LinkedNameChain();

    void                Produce_CompleteChain(
                            const output::Position &
                                                i_curPosition,
                            F_LinkMaker         i_linkMaker ) const;
    void                Produce_CompleteChain_forModule(
                            const output::Position &
                                                i_curPosition,  /// current Module's node
                            F_LinkMaker         i_linkMaker ) const;
  private:
    void                produce_Level(
                            output::Node &      i_levelNode,
                            const output::Position &
                                                i_startPosition,
                            F_LinkMaker         i_linkMaker ) const;
};

#endif
<|endoftext|>


<commit_before>/* * This file is part of meego-im-framework *
 *
 * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * Contact: Nokia Corporation (directui@nokia.com)
 *
 * If you have questions regarding the use of this file, please contact
 * Nokia at directui@nokia.com.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1 as published by the Free Software Foundation
 * and appearing in the file LICENSE.LGPL included in the packaging
 * of this file.
 */

// This file is based on mkeyboardstatetracker.cpp from libmeegotouch

#include "mimhwkeyboardtracker.h"
#include "mimhwkeyboardtracker_p.h"

#include <QCoreApplication>

namespace {
    const char * const keyboardPresent("/maemo/InternalKeyboard/Present");
    const char * const keyboardOpen("/maemo/InternalKeyboard/Open");
}

MImHwKeyboardTrackerPrivate::MImHwKeyboardTrackerPrivate(MImHwKeyboardTracker *q_ptr) :
#ifdef HAVE_CONTEXTSUBSCRIBER
    keyboardOpenProperty(),
#endif
    present(false)
{
#ifdef HAVE_CONTEXTSUBSCRIBER
    ContextProperty keyboardPresentProperty(keyboardPresent);
    keyboardOpenProperty.reset(new ContextProperty(keyboardOpen));
    keyboardPresentProperty.waitForSubscription(true);
    keyboardOpenProperty->waitForSubscription(true);
    present = keyboardPresentProperty.value().toBool();
    if (present) {
        QObject::connect(keyboardOpenProperty.data(), SIGNAL(valueChanged()),
                         q_ptr, SIGNAL(stateChanged()));
    } else {
        keyboardOpenProperty.reset();
    }
#else
    Q_UNUSED(q_ptr);
#endif
}

MImHwKeyboardTrackerPrivate::~MImHwKeyboardTrackerPrivate()
{
}

MImHwKeyboardTracker::MImHwKeyboardTracker()
    : QObject(QCoreApplication::instance()),
      d_ptr(new MImHwKeyboardTrackerPrivate(this))
{
}

MImHwKeyboardTracker::~MImHwKeyboardTracker()
{
}

MImHwKeyboardTracker *MImHwKeyboardTracker::instance()
{
    static MImHwKeyboardTracker tracker;
    return &tracker;
}

bool MImHwKeyboardTracker::isPresent() const
{
    Q_D(const MImHwKeyboardTracker);

    return d->present;
}

bool MImHwKeyboardTracker::isOpen() const
{
    Q_D(const MImHwKeyboardTracker);

    if (!d->present) {
        return false;
    }

#ifdef HAVE_CONTEXTSUBSCRIBER
    return d->keyboardOpenProperty->value().toBool();
#else
    return false;
#endif
}
<commit_msg>Fixes: crash in ut_mimpluginmanager<commit_after>/* * This file is part of meego-im-framework *
 *
 * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * Contact: Nokia Corporation (directui@nokia.com)
 *
 * If you have questions regarding the use of this file, please contact
 * Nokia at directui@nokia.com.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1 as published by the Free Software Foundation
 * and appearing in the file LICENSE.LGPL included in the packaging
 * of this file.
 */

// This file is based on mkeyboardstatetracker.cpp from libmeegotouch

#include "mimhwkeyboardtracker.h"
#include "mimhwkeyboardtracker_p.h"

namespace {
    const char * const keyboardPresent("/maemo/InternalKeyboard/Present");
    const char * const keyboardOpen("/maemo/InternalKeyboard/Open");
}

MImHwKeyboardTrackerPrivate::MImHwKeyboardTrackerPrivate(MImHwKeyboardTracker *q_ptr) :
#ifdef HAVE_CONTEXTSUBSCRIBER
    keyboardOpenProperty(),
#endif
    present(false)
{
#ifdef HAVE_CONTEXTSUBSCRIBER
    ContextProperty keyboardPresentProperty(keyboardPresent);
    keyboardOpenProperty.reset(new ContextProperty(keyboardOpen));
    keyboardPresentProperty.waitForSubscription(true);
    keyboardOpenProperty->waitForSubscription(true);
    present = keyboardPresentProperty.value().toBool();
    if (present) {
        QObject::connect(keyboardOpenProperty.data(), SIGNAL(valueChanged()),
                         q_ptr, SIGNAL(stateChanged()));
    } else {
        keyboardOpenProperty.reset();
    }
#else
    Q_UNUSED(q_ptr);
#endif
}

MImHwKeyboardTrackerPrivate::~MImHwKeyboardTrackerPrivate()
{
}

MImHwKeyboardTracker::MImHwKeyboardTracker()
    : QObject(),
      d_ptr(new MImHwKeyboardTrackerPrivate(this))
{
}

MImHwKeyboardTracker::~MImHwKeyboardTracker()
{
}

// TODO just use a normal instance in the plugin manager instead of singleton
MImHwKeyboardTracker *MImHwKeyboardTracker::instance()
{
    static MImHwKeyboardTracker tracker;
    return &tracker;
}

bool MImHwKeyboardTracker::isPresent() const
{
    Q_D(const MImHwKeyboardTracker);

    return d->present;
}

bool MImHwKeyboardTracker::isOpen() const
{
    Q_D(const MImHwKeyboardTracker);

    if (!d->present) {
        return false;
    }

#ifdef HAVE_CONTEXTSUBSCRIBER
    return d->keyboardOpenProperty->value().toBool();
#else
    return false;
#endif
}
<|endoftext|>


<commit_before>/**
	This software was developed by the University of Tennessee as part of the
	Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
	project funded by the US National Science Foundation.

	If you use DANSE applications to do scientific research that leads to
	publication, we ask that you acknowledge the use of the software with the
	following sentence:

	"This work benefited from DANSE software developed under NSF award DMR-0520547."

	copyright 2008, University of Tennessee
 */

/**
 * Scattering model classes
 * The classes use the IGOR library found in
 *   sansmodels/src/libigor
 *
 */

#include <math.h>
#include "parameters.hh"
#include <stdio.h>
using namespace std;

extern "C" {
	#include "libCylinder.h"
	#include "libStructureFactor.h"
}
#include "cylinder.h"

// Convenience parameter structure
typedef struct {
    double scale;
    double radius;
    double length;
    double sldCyl;
    double sldSolv;
    double background;
    double cyl_theta;
    double cyl_phi;
} CylinderParameters;

CylinderModel :: CylinderModel() {
	scale      = Parameter(1.0);
	radius     = Parameter(20.0, true);
	radius.set_min(0.0);
	length     = Parameter(400.0, true);
	length.set_min(0.0);
	sldCyl   = Parameter(4.e-6);
	sldSolv   = Parameter(1.e-6);
	background = Parameter(0.0);
	cyl_theta  = Parameter(0.0, true);
	cyl_phi    = Parameter(0.0, true);
}

/**
 * Function to evaluate 1D scattering function
 * The NIST IGOR library is used for the actual calculation.
 * @param q: q-value
 * @return: function value
 */
double CylinderModel :: operator()(double q) {
	double dp[6];

	// Fill parameter array for IGOR library
	// Add the background after averaging
	dp[0] = scale();
	dp[1] = radius();
	dp[2] = length();
	dp[3] = sldCyl();
	dp[4] = sldSolv();
	dp[5] = 0.0;

	// Get the dispersion points for the radius
	vector<WeightPoint> weights_rad;
	radius.get_weights(weights_rad);

	// Get the dispersion points for the length
	vector<WeightPoint> weights_len;
	length.get_weights(weights_len);

	// Perform the computation, with all weight points
	double sum = 0.0;
	double norm = 0.0;
	double vol = 0.0;

	// Loop over radius weight points
	for(size_t i=0; i<weights_rad.size(); i++) {
		dp[1] = weights_rad[i].value;

		// Loop over length weight points
		for(size_t j=0; j<weights_len.size(); j++) {
			dp[2] = weights_len[j].value;
			//Un-normalize by volume
			sum += weights_rad[i].weight
				* weights_len[j].weight * CylinderForm(dp, q)
				*pow(weights_rad[i].value,2)*weights_len[j].value;

			//Find average volume
			vol += weights_rad[i].weight
				* weights_len[j].weight *pow(weights_rad[i].value,2)*weights_len[j].value;
			norm += weights_rad[i].weight
				* weights_len[j].weight;
		}
	}
	if (vol != 0.0 && norm != 0.0) {
		//Re-normalize by avg volume
		sum = sum/(vol/norm);}

	return sum/norm + background();
}

/**
 * Function to evaluate 2D scattering function
 * @param pars: parameters of the cylinder
 * @param q: q-value
 * @param q_x: q_x / q
 * @param q_y: q_y / q
 * @return: function value
 */
static double cylinder_analytical_2D_scaled(CylinderParameters *pars, double q, double q_x, double q_y) {
  double cyl_x, cyl_y, cyl_z;
  double q_z;
  double alpha, vol, cos_val;
  double answer;
  //convert angle degree to radian
  double pi = 4.0*atan(1.0);
  double theta = pars->cyl_theta * pi/180.0;
  double phi = pars->cyl_phi * pi/180.0;

    // Cylinder orientation
    cyl_x = sin(theta) * cos(phi);
    cyl_y = sin(theta) * sin(phi);
    cyl_z = cos(theta);

    // q vector
    q_z = 0.0;

    // Compute the angle btw vector q and the
    // axis of the cylinder
    cos_val = cyl_x*q_x + cyl_y*q_y + cyl_z*q_z;

    // The following test should always pass
    if (fabs(cos_val)>1.0) {
      printf("cyl_ana_2D: Unexpected error: |cos(alpha)=%g|>1\n", cos_val);
      printf("cyl_ana_2D: at theta=%g and phi=%g.", theta, phi);
      return 1.0;
    }

    // Note: cos(alpha) = 0 and 1 will get an
    // undefined value from CylKernel
  alpha = acos( cos_val );

  // Call the IGOR library function to get the kernel
  answer = CylKernel(q, pars->radius, pars->length/2.0, alpha) / sin(alpha);

  // Multiply by contrast^2
  answer *= (pars->sldCyl - pars->sldSolv)*(pars->sldCyl - pars->sldSolv);

  //normalize by cylinder volume
  //NOTE that for this (Fournet) definition of the integral, one must MULTIPLY by Vcyl
    vol = acos(-1.0) * pars->radius * pars->radius * pars->length;
  answer *= vol;

  //convert to [cm-1]
  answer *= 1.0e8;

  //Scale
  answer *= pars->scale;

  // add in the background
  answer += pars->background;

  return answer;
}

/**
 * Function to evaluate 2D scattering function
 * @param pars: parameters of the cylinder
 * @param q: q-value
 * @return: function value
 */
static double cylinder_analytical_2DXY(CylinderParameters *pars, double qx, double qy) {
  double q;
  q = sqrt(qx*qx+qy*qy);
  return cylinder_analytical_2D_scaled(pars, q, qx/q, qy/q);
}

/**
 * Function to evaluate 2D scattering function
 * @param q_x: value of Q along x
 * @param q_y: value of Q along y
 * @return: function value
 */
double CylinderModel :: operator()(double qx, double qy) {
	CylinderParameters dp;
	// Fill parameter array
	dp.scale      = scale();
	dp.radius     = radius();
	dp.length     = length();
	dp.sldCyl   = sldCyl();
	dp.sldSolv   = sldSolv();
	dp.background = 0.0;
	dp.cyl_theta  = cyl_theta();
	dp.cyl_phi    = cyl_phi();

	// Get the dispersion points for the radius
	vector<WeightPoint> weights_rad;
	radius.get_weights(weights_rad);

	// Get the dispersion points for the length
	vector<WeightPoint> weights_len;
	length.get_weights(weights_len);

	// Get angular averaging for theta
	vector<WeightPoint> weights_theta;
	cyl_theta.get_weights(weights_theta);

	// Get angular averaging for phi
	vector<WeightPoint> weights_phi;
	cyl_phi.get_weights(weights_phi);

	// Perform the computation, with all weight points
	double sum = 0.0;
	double norm = 0.0;
	double norm_vol = 0.0;
	double vol = 0.0;
	double pi = 4.0*atan(1.0);
	// Loop over radius weight points
	for(size_t i=0; i<weights_rad.size(); i++) {
		dp.radius = weights_rad[i].value;

		// Loop over length weight points
		for(size_t j=0; j<weights_len.size(); j++) {
			dp.length = weights_len[j].value;

			// Average over theta distribution
			for(size_t k=0; k<weights_theta.size(); k++) {
				dp.cyl_theta = weights_theta[k].value;

				// Average over phi distribution
				for(size_t l=0; l<weights_phi.size(); l++) {
					dp.cyl_phi = weights_phi[l].value;
					//Un-normalize by volume
					double _ptvalue = weights_rad[i].weight
						* weights_len[j].weight
						* weights_theta[k].weight
						* weights_phi[l].weight
						* cylinder_analytical_2DXY(&dp, qx, qy)
						*pow(weights_rad[i].value,2)*weights_len[j].value;
					if (weights_theta.size()>1) {
						_ptvalue *= fabs(sin(weights_theta[k].value*pi/180.0));
					}
					sum += _ptvalue;
					//Find average volume
					vol += weights_rad[i].weight
							* weights_len[j].weight
							* pow(weights_rad[i].value,2)*weights_len[j].value;
					//Find norm for volume
					norm_vol += weights_rad[i].weight
							* weights_len[j].weight;

					norm += weights_rad[i].weight
						* weights_len[j].weight
						* weights_theta[k].weight
						* weights_phi[l].weight;

				}
			}
		}
	}
	// Averaging in theta needs an extra normalization
	// factor to account for the sin(theta) term in the
	// integration (see documentation).
	if (weights_theta.size()>1) norm = norm / asin(1.0);
	if (vol != 0.0 && norm_vol != 0.0) {
		//Re-normalize by avg volume
		sum = sum/(vol/norm_vol);}

	return sum/norm + background();
}

/**
 * Function to evaluate 2D scattering function
 * @param pars: parameters of the cylinder
 * @param q: q-value
 * @param phi: angle phi
 * @return: function value
 */
double CylinderModel :: evaluate_rphi(double q, double phi) {
	double qx = q*cos(phi);
	double qy = q*sin(phi);
	return (*this).operator()(qx, qy);
}
/**
 * Function to calculate effective radius
 * @return: effective radius value
 */
double CylinderModel :: calculate_ER() {
	CylinderParameters dp;

	dp.radius     = radius();
	dp.length     = length();
	double rad_out = 0.0;

	// Perform the computation, with all weight points
	double sum = 0.0;
	double norm = 0.0;

	// Get the dispersion points for the major shell
	vector<WeightPoint> weights_length;
	length.get_weights(weights_length);

	// Get the dispersion points for the minor shell
	vector<WeightPoint> weights_radius ;
	radius.get_weights(weights_radius);

	// Loop over major shell weight points
	for(int i=0; i< (int)weights_length.size(); i++) {
		dp.length = weights_length[i].value;
		for(int k=0; k< (int)weights_radius.size(); k++) {
			dp.radius = weights_radius[k].value;
			//Note: output of "DiamCyl(dp.length,dp.radius)" is DIAMETER.
			sum +=weights_length[i].weight
				* weights_radius[k].weight*DiamCyl(dp.length,dp.radius)/2.0;
			norm += weights_length[i].weight* weights_radius[k].weight;
		}
	}
	if (norm != 0){
		//return the averaged value
		rad_out =  sum/norm;}
	else{
		//return normal value
		//Note: output of "DiamCyl(dp.length,dp.radius)" is DIAMETER.
		rad_out = DiamCyl(dp.length,dp.radius)/2.0;}

	return rad_out;
}
double CylinderModel :: calculate_VR() {
  return 1.0;
}
<commit_msg>block alpha=0 that breaks fitting<commit_after>/**
	This software was developed by the University of Tennessee as part of the
	Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
	project funded by the US National Science Foundation.

	If you use DANSE applications to do scientific research that leads to
	publication, we ask that you acknowledge the use of the software with the
	following sentence:

	"This work benefited from DANSE software developed under NSF award DMR-0520547."

	copyright 2008, University of Tennessee
 */

/**
 * Scattering model classes
 * The classes use the IGOR library found in
 *   sansmodels/src/libigor
 *
 */

#include <math.h>
#include "parameters.hh"
#include <stdio.h>
using namespace std;

extern "C" {
	#include "libCylinder.h"
	#include "libStructureFactor.h"
}
#include "cylinder.h"

// Convenience parameter structure
typedef struct {
    double scale;
    double radius;
    double length;
    double sldCyl;
    double sldSolv;
    double background;
    double cyl_theta;
    double cyl_phi;
} CylinderParameters;

CylinderModel :: CylinderModel() {
	scale      = Parameter(1.0);
	radius     = Parameter(20.0, true);
	radius.set_min(0.0);
	length     = Parameter(400.0, true);
	length.set_min(0.0);
	sldCyl   = Parameter(4.e-6);
	sldSolv   = Parameter(1.e-6);
	background = Parameter(0.0);
	cyl_theta  = Parameter(0.0, true);
	cyl_phi    = Parameter(0.0, true);
}

/**
 * Function to evaluate 1D scattering function
 * The NIST IGOR library is used for the actual calculation.
 * @param q: q-value
 * @return: function value
 */
double CylinderModel :: operator()(double q) {
	double dp[6];

	// Fill parameter array for IGOR library
	// Add the background after averaging
	dp[0] = scale();
	dp[1] = radius();
	dp[2] = length();
	dp[3] = sldCyl();
	dp[4] = sldSolv();
	dp[5] = 0.0;

	// Get the dispersion points for the radius
	vector<WeightPoint> weights_rad;
	radius.get_weights(weights_rad);

	// Get the dispersion points for the length
	vector<WeightPoint> weights_len;
	length.get_weights(weights_len);

	// Perform the computation, with all weight points
	double sum = 0.0;
	double norm = 0.0;
	double vol = 0.0;

	// Loop over radius weight points
	for(size_t i=0; i<weights_rad.size(); i++) {
		dp[1] = weights_rad[i].value;

		// Loop over length weight points
		for(size_t j=0; j<weights_len.size(); j++) {
			dp[2] = weights_len[j].value;
			//Un-normalize by volume
			sum += weights_rad[i].weight
				* weights_len[j].weight * CylinderForm(dp, q)
				*pow(weights_rad[i].value,2)*weights_len[j].value;

			//Find average volume
			vol += weights_rad[i].weight
				* weights_len[j].weight *pow(weights_rad[i].value,2)*weights_len[j].value;
			norm += weights_rad[i].weight
				* weights_len[j].weight;
		}
	}
	if (vol != 0.0 && norm != 0.0) {
		//Re-normalize by avg volume
		sum = sum/(vol/norm);}

	return sum/norm + background();
}

/**
 * Function to evaluate 2D scattering function
 * @param pars: parameters of the cylinder
 * @param q: q-value
 * @param q_x: q_x / q
 * @param q_y: q_y / q
 * @return: function value
 */
static double cylinder_analytical_2D_scaled(CylinderParameters *pars, double q, double q_x, double q_y) {
  double cyl_x, cyl_y, cyl_z;
  double q_z;
  double alpha, vol, cos_val;
  double answer;
  //convert angle degree to radian
  double pi = 4.0*atan(1.0);
  double theta = pars->cyl_theta * pi/180.0;
  double phi = pars->cyl_phi * pi/180.0;

    // Cylinder orientation
    cyl_x = sin(theta) * cos(phi);
    cyl_y = sin(theta) * sin(phi);
    cyl_z = cos(theta);

    // q vector
    q_z = 0.0;

    // Compute the angle btw vector q and the
    // axis of the cylinder
    cos_val = cyl_x*q_x + cyl_y*q_y + cyl_z*q_z;

    // The following test should always pass
    if (fabs(cos_val)>1.0) {
      printf("cyl_ana_2D: Unexpected error: |cos(alpha)=%g|>1\n", cos_val);
      printf("cyl_ana_2D: at theta=%g and phi=%g.", theta, phi);
      return 1.0;
    }

    // Note: cos(alpha) = 0 and 1 will get an
    // undefined value from CylKernel
  alpha = acos( cos_val );
  if (alpha == 0.0){
  	alpha = 1.0e-26;
  	}
  // Call the IGOR library function to get the kernel
  answer = CylKernel(q, pars->radius, pars->length/2.0, alpha) / sin(alpha);

  // Multiply by contrast^2
  answer *= (pars->sldCyl - pars->sldSolv)*(pars->sldCyl - pars->sldSolv);

  //normalize by cylinder volume
  //NOTE that for this (Fournet) definition of the integral, one must MULTIPLY by Vcyl
    vol = acos(-1.0) * pars->radius * pars->radius * pars->length;
  answer *= vol;

  //convert to [cm-1]
  answer *= 1.0e8;

  //Scale
  answer *= pars->scale;

  // add in the background
  answer += pars->background;

  return answer;
}

/**
 * Function to evaluate 2D scattering function
 * @param pars: parameters of the cylinder
 * @param q: q-value
 * @return: function value
 */
static double cylinder_analytical_2DXY(CylinderParameters *pars, double qx, double qy) {
  double q;
  q = sqrt(qx*qx+qy*qy);
  return cylinder_analytical_2D_scaled(pars, q, qx/q, qy/q);
}

/**
 * Function to evaluate 2D scattering function
 * @param q_x: value of Q along x
 * @param q_y: value of Q along y
 * @return: function value
 */
double CylinderModel :: operator()(double qx, double qy) {
	CylinderParameters dp;
	// Fill parameter array
	dp.scale      = scale();
	dp.radius     = radius();
	dp.length     = length();
	dp.sldCyl   = sldCyl();
	dp.sldSolv   = sldSolv();
	dp.background = 0.0;
	dp.cyl_theta  = cyl_theta();
	dp.cyl_phi    = cyl_phi();

	// Get the dispersion points for the radius
	vector<WeightPoint> weights_rad;
	radius.get_weights(weights_rad);

	// Get the dispersion points for the length
	vector<WeightPoint> weights_len;
	length.get_weights(weights_len);

	// Get angular averaging for theta
	vector<WeightPoint> weights_theta;
	cyl_theta.get_weights(weights_theta);

	// Get angular averaging for phi
	vector<WeightPoint> weights_phi;
	cyl_phi.get_weights(weights_phi);

	// Perform the computation, with all weight points
	double sum = 0.0;
	double norm = 0.0;
	double norm_vol = 0.0;
	double vol = 0.0;
	double pi = 4.0*atan(1.0);
	// Loop over radius weight points
	for(size_t i=0; i<weights_rad.size(); i++) {
		dp.radius = weights_rad[i].value;

		// Loop over length weight points
		for(size_t j=0; j<weights_len.size(); j++) {
			dp.length = weights_len[j].value;

			// Average over theta distribution
			for(size_t k=0; k<weights_theta.size(); k++) {
				dp.cyl_theta = weights_theta[k].value;

				// Average over phi distribution
				for(size_t l=0; l<weights_phi.size(); l++) {
					dp.cyl_phi = weights_phi[l].value;
					//Un-normalize by volume
					double _ptvalue = weights_rad[i].weight
						* weights_len[j].weight
						* weights_theta[k].weight
						* weights_phi[l].weight
						* cylinder_analytical_2DXY(&dp, qx, qy)
						*pow(weights_rad[i].value,2)*weights_len[j].value;
					if (weights_theta.size()>1) {
						_ptvalue *= fabs(sin(weights_theta[k].value*pi/180.0));
					}
					sum += _ptvalue;
					//Find average volume
					vol += weights_rad[i].weight
							* weights_len[j].weight
							* pow(weights_rad[i].value,2)*weights_len[j].value;
					//Find norm for volume
					norm_vol += weights_rad[i].weight
							* weights_len[j].weight;

					norm += weights_rad[i].weight
						* weights_len[j].weight
						* weights_theta[k].weight
						* weights_phi[l].weight;

				}
			}
		}
	}
	// Averaging in theta needs an extra normalization
	// factor to account for the sin(theta) term in the
	// integration (see documentation).
	if (weights_theta.size()>1) norm = norm / asin(1.0);
	if (vol != 0.0 && norm_vol != 0.0) {
		//Re-normalize by avg volume
		sum = sum/(vol/norm_vol);}

	return sum/norm + background();
}

/**
 * Function to evaluate 2D scattering function
 * @param pars: parameters of the cylinder
 * @param q: q-value
 * @param phi: angle phi
 * @return: function value
 */
double CylinderModel :: evaluate_rphi(double q, double phi) {
	double qx = q*cos(phi);
	double qy = q*sin(phi);
	return (*this).operator()(qx, qy);
}
/**
 * Function to calculate effective radius
 * @return: effective radius value
 */
double CylinderModel :: calculate_ER() {
	CylinderParameters dp;

	dp.radius     = radius();
	dp.length     = length();
	double rad_out = 0.0;

	// Perform the computation, with all weight points
	double sum = 0.0;
	double norm = 0.0;

	// Get the dispersion points for the major shell
	vector<WeightPoint> weights_length;
	length.get_weights(weights_length);

	// Get the dispersion points for the minor shell
	vector<WeightPoint> weights_radius ;
	radius.get_weights(weights_radius);

	// Loop over major shell weight points
	for(int i=0; i< (int)weights_length.size(); i++) {
		dp.length = weights_length[i].value;
		for(int k=0; k< (int)weights_radius.size(); k++) {
			dp.radius = weights_radius[k].value;
			//Note: output of "DiamCyl(dp.length,dp.radius)" is DIAMETER.
			sum +=weights_length[i].weight
				* weights_radius[k].weight*DiamCyl(dp.length,dp.radius)/2.0;
			norm += weights_length[i].weight* weights_radius[k].weight;
		}
	}
	if (norm != 0){
		//return the averaged value
		rad_out =  sum/norm;}
	else{
		//return normal value
		//Note: output of "DiamCyl(dp.length,dp.radius)" is DIAMETER.
		rad_out = DiamCyl(dp.length,dp.radius)/2.0;}

	return rad_out;
}
double CylinderModel :: calculate_VR() {
  return 1.0;
}
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <config_features.h>
#include "formulagroup.hxx"
#include "document.hxx"
#include "formulacell.hxx"
#include "tokenarray.hxx"
#include "compiler.hxx"
#include "interpre.hxx"
#include "scmatrix.hxx"

#include "formula/vectortoken.hxx"

#include <vector>

#define USE_DUMMY_INTERPRETER 1

#if USE_DUMMY_INTERPRETER
#include <cstdio>
#endif

namespace sc {

ScMatrixRef FormulaGroupInterpreterSoftware::inverseMatrix(const ScMatrix& /*rMat*/)
{
    return ScMatrixRef();
}

bool FormulaGroupInterpreterSoftware::interpret(ScDocument& rDoc, const ScAddress& rTopPos,
                                                const ScFormulaCellGroupRef& xGroup,
                                                ScTokenArray& rCode)
{
    // Decompose the group into individual cells and calculate them individually.

    // The caller must ensure that the top position is the start position of
    // the group.

    ScAddress aTmpPos = rTopPos;
    std::vector<double> aResults;
    aResults.reserve(xGroup->mnLength);
    for (SCROW i = 0; i < xGroup->mnLength; ++i, aTmpPos.IncRow())
    {
        ScTokenArray aCode2;
        for (const formula::FormulaToken* p = rCode.First(); p; p = rCode.Next())
        {
            switch (p->GetType())
            {
                case formula::svSingleVectorRef:
                {
                    const formula::SingleVectorRefToken* p2 = static_cast<const formula::SingleVectorRefToken*>(p);
                    const double* pArray = p2->GetArray();
                    aCode2.AddDouble(static_cast<size_t>(i) < p2->GetArrayLength() ? pArray[i] : 0.0);
                }
                break;
                case formula::svDoubleVectorRef:
                {
                    const formula::DoubleVectorRefToken* p2 = static_cast<const formula::DoubleVectorRefToken*>(p);
                    const std::vector<const double*>& rArrays = p2->GetArrays();
                    size_t nColSize = rArrays.size();
                    size_t nRowStart = p2->IsStartFixed() ? 0 : i;
                    size_t nRowEnd = p2->GetRefRowSize() - 1;
                    if (!p2->IsEndFixed())
                        nRowEnd += i;
                    size_t nRowSize = nRowEnd - nRowStart + 1;
                    ScMatrixRef pMat(new ScMatrix(nColSize, nRowSize, 0.0));
                    for (size_t nCol = 0; nCol < nColSize; ++nCol)
                    {
                        const double* pArray = rArrays[nCol];
                        pArray += nRowStart;
                        pMat->PutDouble(pArray, nRowSize, nCol, 0);
                    }

                    ScMatrixToken aTok(pMat);
                    aCode2.AddToken(aTok);
                }
                break;
                default:
                    aCode2.AddToken(*p);
            }
        }

        ScFormulaCell* pDest = rDoc.GetFormulaCell(aTmpPos);
        if (!pDest)
            return false;

        generateRPNCode(rDoc, aTmpPos, aCode2);
        ScInterpreter aInterpreter(pDest, &rDoc, aTmpPos, aCode2);
        aInterpreter.Interpret();
        aResults.push_back(aInterpreter.GetResultToken()->GetDouble());
    } // for loop end (xGroup->mnLength)

    if (!aResults.empty())
        rDoc.SetFormulaResults(rTopPos, &aResults[0], aResults.size());

    return true;
}

// TODO: load module, hook symbol out, check it works, UI on failure etc.
namespace opencl {
    extern sc::FormulaGroupInterpreter *createFormulaGroupInterpreter();
}
FormulaGroupInterpreter *FormulaGroupInterpreter::msInstance = NULL;

#if USE_DUMMY_INTERPRETER
class FormulaGroupInterpreterDummy : public FormulaGroupInterpreter
{
    enum Mode {
        WRITE_OUTPUT = 0
    };
    Mode meMode;
public:
    FormulaGroupInterpreterDummy()
    {
        const char *pValue = getenv("FORMULA_GROUP_DUMMY");
        meMode = static_cast<Mode>(OString(pValue, strlen(pValue)).toInt32());
        fprintf(stderr, "Using Dummy Formula Group interpreter mode %d\n", (int)meMode);
    }

    virtual ScMatrixRef inverseMatrix(const ScMatrix& /*rMat*/)
    {
        return ScMatrixRef();
    }

    virtual bool interpret(ScDocument& rDoc, const ScAddress& rTopPos,
                           const ScFormulaCellGroupRef& xGroup,
                           ScTokenArray& rCode)
    {
        (void)rCode;

        // Write simple data back into the sheet
        if (meMode == WRITE_OUTPUT)
        {
            double *pDoubles = new double[xGroup->mnLength];
            for (sal_Int32 i = 0; i < xGroup->mnLength; i++)
                pDoubles[i] = 42.0 + i;
            rDoc.SetFormulaResults(rTopPos, pDoubles, xGroup->mnLength);
            delete [] pDoubles;
        }
        return true;
    }
};
#endif

/// load and/or configure the correct formula group interpreter
FormulaGroupInterpreter *FormulaGroupInterpreter::getStatic()
{
    static bool bOpenCLEnabled = false;

#if USE_DUMMY_INTERPRETER
    if (getenv("FORMULA_GROUP_DUMMY"))
    {
        delete msInstance;
        return msInstance = new sc::FormulaGroupInterpreterDummy();
    }
#endif

    if ( msInstance &&
         bOpenCLEnabled != ScInterpreter::GetGlobalConfig().mbOpenCLEnabled )
    {
        bOpenCLEnabled = ScInterpreter::GetGlobalConfig().mbOpenCLEnabled;
        delete msInstance;
        msInstance = NULL;
    }

    if ( !msInstance )
    {
#if HAVE_FEATURE_OPENCL
        if ( ScInterpreter::GetGlobalConfig().mbOpenCLEnabled )
            msInstance = sc::opencl::createFormulaGroupInterpreter();
#endif
        if ( !msInstance ) // software fallback
            msInstance = new sc::FormulaGroupInterpreterSoftware();
    }

    return msInstance;
}

void FormulaGroupInterpreter::generateRPNCode(ScDocument& rDoc, const ScAddress& rPos, ScTokenArray& rCode)
{
    // First, generate an RPN (reverse polish notation) token array.
    ScCompiler aComp(&rDoc, rPos, rCode);
    aComp.SetGrammar(rDoc.GetGrammar());
    aComp.CompileTokenArray(); // Create RPN token array.
    // Now, calling FirstRPN() and NextRPN() will return tokens from the RPN token array.
}

}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>Cache select converted tokens to avoid unnecessary token duplication.<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <config_features.h>
#include "formulagroup.hxx"
#include "document.hxx"
#include "formulacell.hxx"
#include "tokenarray.hxx"
#include "compiler.hxx"
#include "interpre.hxx"
#include "scmatrix.hxx"

#include "formula/vectortoken.hxx"

#include <vector>
#include <boost/unordered_map.hpp>

#define USE_DUMMY_INTERPRETER 1

#if USE_DUMMY_INTERPRETER
#include <cstdio>
#endif

namespace sc {

ScMatrixRef FormulaGroupInterpreterSoftware::inverseMatrix(const ScMatrix& /*rMat*/)
{
    return ScMatrixRef();
}

bool FormulaGroupInterpreterSoftware::interpret(ScDocument& rDoc, const ScAddress& rTopPos,
                                                const ScFormulaCellGroupRef& xGroup,
                                                ScTokenArray& rCode)
{
    typedef boost::unordered_map<const formula::FormulaToken*, formula::FormulaTokenRef> CachedTokensType;

    // Decompose the group into individual cells and calculate them individually.

    // The caller must ensure that the top position is the start position of
    // the group.

    ScAddress aTmpPos = rTopPos;
    std::vector<double> aResults;
    aResults.reserve(xGroup->mnLength);
    CachedTokensType aCachedTokens;

    for (SCROW i = 0; i < xGroup->mnLength; ++i, aTmpPos.IncRow())
    {
        ScTokenArray aCode2;
        for (const formula::FormulaToken* p = rCode.First(); p; p = rCode.Next())
        {
            CachedTokensType::iterator it = aCachedTokens.find(p);
            if (it != aCachedTokens.end())
            {
                // This token is cached. Use the cached one.
                aCode2.AddToken(*it->second);
                continue;
            }

            switch (p->GetType())
            {
                case formula::svSingleVectorRef:
                {
                    const formula::SingleVectorRefToken* p2 = static_cast<const formula::SingleVectorRefToken*>(p);
                    const double* pArray = p2->GetArray();
                    aCode2.AddDouble(static_cast<size_t>(i) < p2->GetArrayLength() ? pArray[i] : 0.0);
                }
                break;
                case formula::svDoubleVectorRef:
                {
                    const formula::DoubleVectorRefToken* p2 = static_cast<const formula::DoubleVectorRefToken*>(p);
                    const std::vector<const double*>& rArrays = p2->GetArrays();
                    size_t nColSize = rArrays.size();
                    size_t nRowStart = p2->IsStartFixed() ? 0 : i;
                    size_t nRowEnd = p2->GetRefRowSize() - 1;
                    if (!p2->IsEndFixed())
                        nRowEnd += i;
                    size_t nRowSize = nRowEnd - nRowStart + 1;
                    ScMatrixRef pMat(new ScMatrix(nColSize, nRowSize, 0.0));
                    for (size_t nCol = 0; nCol < nColSize; ++nCol)
                    {
                        const double* pArray = rArrays[nCol];
                        pArray += nRowStart;
                        pMat->PutDouble(pArray, nRowSize, nCol, 0);
                    }

                    if (p2->IsStartFixed() && p2->IsEndFixed())
                    {
                        // Cached the converted token for absolute range referene.
                        formula::FormulaTokenRef xTok(new ScMatrixToken(pMat));
                        aCachedTokens.insert(CachedTokensType::value_type(p, xTok));
                        aCode2.AddToken(*xTok);
                    }
                    else
                    {
                        ScMatrixToken aTok(pMat);
                        aCode2.AddToken(aTok);
                    }
                }
                break;
                default:
                    aCode2.AddToken(*p);
            }
        }

        ScFormulaCell* pDest = rDoc.GetFormulaCell(aTmpPos);
        if (!pDest)
            return false;

        generateRPNCode(rDoc, aTmpPos, aCode2);
        ScInterpreter aInterpreter(pDest, &rDoc, aTmpPos, aCode2);
        aInterpreter.Interpret();
        aResults.push_back(aInterpreter.GetResultToken()->GetDouble());
    } // for loop end (xGroup->mnLength)

    if (!aResults.empty())
        rDoc.SetFormulaResults(rTopPos, &aResults[0], aResults.size());

    return true;
}

// TODO: load module, hook symbol out, check it works, UI on failure etc.
namespace opencl {
    extern sc::FormulaGroupInterpreter *createFormulaGroupInterpreter();
}
FormulaGroupInterpreter *FormulaGroupInterpreter::msInstance = NULL;

#if USE_DUMMY_INTERPRETER
class FormulaGroupInterpreterDummy : public FormulaGroupInterpreter
{
    enum Mode {
        WRITE_OUTPUT = 0
    };
    Mode meMode;
public:
    FormulaGroupInterpreterDummy()
    {
        const char *pValue = getenv("FORMULA_GROUP_DUMMY");
        meMode = static_cast<Mode>(OString(pValue, strlen(pValue)).toInt32());
        fprintf(stderr, "Using Dummy Formula Group interpreter mode %d\n", (int)meMode);
    }

    virtual ScMatrixRef inverseMatrix(const ScMatrix& /*rMat*/)
    {
        return ScMatrixRef();
    }

    virtual bool interpret(ScDocument& rDoc, const ScAddress& rTopPos,
                           const ScFormulaCellGroupRef& xGroup,
                           ScTokenArray& rCode)
    {
        (void)rCode;

        // Write simple data back into the sheet
        if (meMode == WRITE_OUTPUT)
        {
            double *pDoubles = new double[xGroup->mnLength];
            for (sal_Int32 i = 0; i < xGroup->mnLength; i++)
                pDoubles[i] = 42.0 + i;
            rDoc.SetFormulaResults(rTopPos, pDoubles, xGroup->mnLength);
            delete [] pDoubles;
        }
        return true;
    }
};
#endif

/// load and/or configure the correct formula group interpreter
FormulaGroupInterpreter *FormulaGroupInterpreter::getStatic()
{
    static bool bOpenCLEnabled = false;

#if USE_DUMMY_INTERPRETER
    if (getenv("FORMULA_GROUP_DUMMY"))
    {
        delete msInstance;
        return msInstance = new sc::FormulaGroupInterpreterDummy();
    }
#endif

    if ( msInstance &&
         bOpenCLEnabled != ScInterpreter::GetGlobalConfig().mbOpenCLEnabled )
    {
        bOpenCLEnabled = ScInterpreter::GetGlobalConfig().mbOpenCLEnabled;
        delete msInstance;
        msInstance = NULL;
    }

    if ( !msInstance )
    {
#if HAVE_FEATURE_OPENCL
        if ( ScInterpreter::GetGlobalConfig().mbOpenCLEnabled )
            msInstance = sc::opencl::createFormulaGroupInterpreter();
#endif
        if ( !msInstance ) // software fallback
            msInstance = new sc::FormulaGroupInterpreterSoftware();
    }

    return msInstance;
}

void FormulaGroupInterpreter::generateRPNCode(ScDocument& rDoc, const ScAddress& rPos, ScTokenArray& rCode)
{
    // First, generate an RPN (reverse polish notation) token array.
    ScCompiler aComp(&rDoc, rPos, rCode);
    aComp.SetGrammar(rDoc.GetGrammar());
    aComp.CompileTokenArray(); // Create RPN token array.
    // Now, calling FirstRPN() and NextRPN() will return tokens from the RPN token array.
}

}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>// $Id$
// Main authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007

/**************************************************************************
 * Copyright(c) 1998-2008, ALICE Experiment at CERN, all rights reserved. *
 * See http://aliceinfo.cern.ch/Offline/AliRoot/License.html for          *
 * full copyright notice.                                                 *
 **************************************************************************/

#include "AliEveTPCSectorVizEditor.h"
#include <EveDet/AliEveTPCSectorViz.h>

#include <TEveGValuators.h>

#include <TVirtualPad.h>

#include <TGButton.h>
#include <TGNumberEntry.h>
#include <TGSlider.h>
#include <TGDoubleSlider.h>

//______________________________________________________________________________
//
// Editor for AliEveTPCSectorViz.

ClassImp(AliEveTPCSectorVizEditor)

AliEveTPCSectorVizEditor::AliEveTPCSectorVizEditor(const TGWindow *p,
                                       Int_t width, Int_t height,
                                       UInt_t options, Pixel_t back) :
  TGedFrame(p, width, height, options | kVerticalFrame, back),
  fM(0),
  fSectorID  (0), fAutoTrans (0),
  fRnrInn    (0), fRnrOut1   (0), fRnrOut2(0),
  fThreshold (0), fMaxVal    (0),
  fTime      (0)
{
  // Constructor.

  fPriority = 40;

  Int_t labelW = 60;

  MakeTitle("AliEveTPCSectorViz");

  fSectorID = new TEveGValuator(this, "SectorID", 110, 0);
  fSectorID->SetLabelWidth(labelW);
  fSectorID->SetShowSlider(kFALSE);
  fSectorID->SetNELength(4);
  fSectorID->Build();
  fSectorID->SetLimits(0, 35);
  fSectorID->SetToolTip("0-17 +z plate; 18-35 -z plate");
  fSectorID->Connect("ValueSet(Double_t)",
		     "AliEveTPCSectorVizEditor", this, "DoSectorID()");
  // Reuse sectorID for auto-transformation button
  fAutoTrans = new TGCheckButton(fSectorID, "AutoTrans");
  fAutoTrans->SetToolTipText("Automatically set transformation to true position");
  fSectorID->AddFrame(fAutoTrans, new TGLayoutHints(kLHintsLeft, 12, 0, 1, 0));
  fAutoTrans->Connect("Toggled(Bool_t)","AliEveTPCSectorVizEditor", this, "DoAutoTrans()");
  AddFrame(fSectorID, new TGLayoutHints(kLHintsTop, 1, 1, 1, 1));

  {
    TGHorizontalFrame* f = new TGHorizontalFrame(this);

    fRnrInn = new TGCheckButton(f, "Inner");
    f->AddFrame(fRnrInn, new TGLayoutHints(kLHintsTop, 3, 1, 1, 0));
    fRnrInn->Connect("Toggled(Bool_t)","AliEveTPCSectorVizEditor", this, "DoRnrInn()");

    fRnrOut1 = new TGCheckButton(f, "Outer 1");
    f->AddFrame(fRnrOut1, new TGLayoutHints(kLHintsTop, 3, 1, 1, 0));
    fRnrOut1->Connect("Toggled(Bool_t)","AliEveTPCSectorVizEditor", this, "DoRnrOut1()");

    fRnrOut2 = new TGCheckButton(f, "Outer 2");
    f->AddFrame(fRnrOut2, new TGLayoutHints(kLHintsTop, 3, 1, 1, 0));
    fRnrOut2->Connect("Toggled(Bool_t)","AliEveTPCSectorVizEditor", this, "DoRnrOut2()");

    AddFrame(f, new TGLayoutHints(kLHintsTop, 1, 1, 1, 1));
  }

  fThreshold = new TEveGValuator(this, "Threshold", 200, 0);
  fThreshold->SetNELength(4);
  fThreshold->SetLabelWidth(labelW);
  fThreshold->Build();
  fThreshold->GetSlider()->SetWidth(120);
  fThreshold->SetLimits(0,250);
  fThreshold->Connect("ValueSet(Double_t)",
		      "AliEveTPCSectorVizEditor", this, "DoThreshold()");
  AddFrame(fThreshold, new TGLayoutHints(kLHintsTop, 1, 1, 2, 1));

  fMaxVal = new TEveGValuator(this,"MaxVal", 200, 0);
  fMaxVal->SetNELength(4);
  fMaxVal->SetLabelWidth(labelW);
  fMaxVal->Build();
  fMaxVal->GetSlider()->SetWidth(120);
  fMaxVal->SetLimits(0, 500);
  fMaxVal->Connect("ValueSet(Double_t)",
		   "AliEveTPCSectorVizEditor", this, "DoMaxVal()");
  AddFrame(fMaxVal, new TGLayoutHints(kLHintsTop, 1, 1, 2, 1));

  fTime = new TEveGDoubleValuator(this,"Time", 200, 0);
  fTime->SetNELength(4);
  fTime->SetLabelWidth(labelW);
  fTime->Build();
  fTime->GetSlider()->SetWidth(224);
  fTime->SetLimits(0, 1023, TGNumberFormat::kNESInteger);
  fTime->Connect("ValueSet()",
		 "AliEveTPCSectorVizEditor", this, "DoTime()");
  AddFrame(fTime, new TGLayoutHints(kLHintsTop, 1, 1, 2, 1));
}

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

void AliEveTPCSectorVizEditor::SetModel(TObject* obj)
{
  // Set model object.

  fM = dynamic_cast<AliEveTPCSectorViz*>(obj);

  fSectorID->SetValue(fM->fSectorID);
  fAutoTrans->SetState(fM->fAutoTrans  ? kButtonDown : kButtonUp);

  fRnrInn ->SetState(fM->fRnrInn  ? kButtonDown : kButtonUp);
  fRnrOut1->SetState(fM->fRnrOut1 ? kButtonDown : kButtonUp);
  fRnrOut2->SetState(fM->fRnrOut2 ? kButtonDown : kButtonUp);

  fThreshold->SetValue(fM->fThreshold);
  fMaxVal->SetValue(fM->fMaxVal);

  fTime->SetValues(fM->fMinTime, fM->fMaxTime);
}

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

void AliEveTPCSectorVizEditor::DoSectorID()
{
  // Slot for SectorID.

  fM->SetSectorID((Int_t) fSectorID->GetValue());
  Update();
}

void AliEveTPCSectorVizEditor::DoAutoTrans()
{
  // Slot for AutoTrans.

  fM->SetAutoTrans(fAutoTrans->IsOn());
  Update();
}

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

void AliEveTPCSectorVizEditor::DoRnrInn()
{
  // Slot for RnrInn.

  fM->SetRnrInn(fRnrInn->IsOn());
  Update();
}

void AliEveTPCSectorVizEditor::DoRnrOut1()
{
  // Slot for RnrOut1.

  fM->SetRnrOut1(fRnrOut1->IsOn());
  Update();
}

void AliEveTPCSectorVizEditor::DoRnrOut2()
{
  // Slot for RnrOut2.

  fM->SetRnrOut2(fRnrOut2->IsOn());
  Update();
}

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

void AliEveTPCSectorVizEditor::DoThreshold()
{
  // Slot for Threshold.

  fM->SetThreshold((Short_t) fThreshold->GetValue());
  fThreshold->SetValue(fM->fThreshold);
  Update();
}

void AliEveTPCSectorVizEditor::DoMaxVal()
{
  // Slot for MaxVal.

  fM->SetMaxVal((Int_t) fMaxVal->GetValue());
  fMaxVal->SetValue(fM->fMaxVal);
  Update();
}

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

void AliEveTPCSectorVizEditor::DoTime()
{
  // Slot for time-range.

  fM->SetMinTime((Int_t) fTime->GetMin());
  fM->SetMaxTime((Int_t) fTime->GetMax());
  Update();
}
<commit_msg>Coverity<commit_after>// $Id$
// Main authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007

/**************************************************************************
 * Copyright(c) 1998-2008, ALICE Experiment at CERN, all rights reserved. *
 * See http://aliceinfo.cern.ch/Offline/AliRoot/License.html for          *
 * full copyright notice.                                                 *
 **************************************************************************/

#include "AliEveTPCSectorVizEditor.h"
#include <EveDet/AliEveTPCSectorViz.h>

#include <TEveGValuators.h>

#include <TVirtualPad.h>

#include <TGButton.h>
#include <TGNumberEntry.h>
#include <TGSlider.h>
#include <TGDoubleSlider.h>

//______________________________________________________________________________
//
// Editor for AliEveTPCSectorViz.

ClassImp(AliEveTPCSectorVizEditor)

AliEveTPCSectorVizEditor::AliEveTPCSectorVizEditor(const TGWindow *p,
                                       Int_t width, Int_t height,
                                       UInt_t options, Pixel_t back) :
  TGedFrame(p, width, height, options | kVerticalFrame, back),
  fM(0),
  fSectorID  (0), fAutoTrans (0),
  fRnrInn    (0), fRnrOut1   (0), fRnrOut2(0),
  fThreshold (0), fMaxVal    (0),
  fTime      (0)
{
  // Constructor.

  fPriority = 40;

  Int_t labelW = 60;

  MakeTitle("AliEveTPCSectorViz");

  fSectorID = new TEveGValuator(this, "SectorID", 110, 0);
  fSectorID->SetLabelWidth(labelW);
  fSectorID->SetShowSlider(kFALSE);
  fSectorID->SetNELength(4);
  fSectorID->Build();
  fSectorID->SetLimits(0, 35);
  fSectorID->SetToolTip("0-17 +z plate; 18-35 -z plate");
  fSectorID->Connect("ValueSet(Double_t)",
		     "AliEveTPCSectorVizEditor", this, "DoSectorID()");
  // Reuse sectorID for auto-transformation button
  fAutoTrans = new TGCheckButton(fSectorID, "AutoTrans");
  fAutoTrans->SetToolTipText("Automatically set transformation to true position");
  fSectorID->AddFrame(fAutoTrans, new TGLayoutHints(kLHintsLeft, 12, 0, 1, 0));
  fAutoTrans->Connect("Toggled(Bool_t)","AliEveTPCSectorVizEditor", this, "DoAutoTrans()");
  AddFrame(fSectorID, new TGLayoutHints(kLHintsTop, 1, 1, 1, 1));

  {
    TGHorizontalFrame* f = new TGHorizontalFrame(this);

    fRnrInn = new TGCheckButton(f, "Inner");
    f->AddFrame(fRnrInn, new TGLayoutHints(kLHintsTop, 3, 1, 1, 0));
    fRnrInn->Connect("Toggled(Bool_t)","AliEveTPCSectorVizEditor", this, "DoRnrInn()");

    fRnrOut1 = new TGCheckButton(f, "Outer 1");
    f->AddFrame(fRnrOut1, new TGLayoutHints(kLHintsTop, 3, 1, 1, 0));
    fRnrOut1->Connect("Toggled(Bool_t)","AliEveTPCSectorVizEditor", this, "DoRnrOut1()");

    fRnrOut2 = new TGCheckButton(f, "Outer 2");
    f->AddFrame(fRnrOut2, new TGLayoutHints(kLHintsTop, 3, 1, 1, 0));
    fRnrOut2->Connect("Toggled(Bool_t)","AliEveTPCSectorVizEditor", this, "DoRnrOut2()");

    AddFrame(f, new TGLayoutHints(kLHintsTop, 1, 1, 1, 1));
  }

  fThreshold = new TEveGValuator(this, "Threshold", 200, 0);
  fThreshold->SetNELength(4);
  fThreshold->SetLabelWidth(labelW);
  fThreshold->Build();
  fThreshold->GetSlider()->SetWidth(120);
  fThreshold->SetLimits(0,250);
  fThreshold->Connect("ValueSet(Double_t)",
		      "AliEveTPCSectorVizEditor", this, "DoThreshold()");
  AddFrame(fThreshold, new TGLayoutHints(kLHintsTop, 1, 1, 2, 1));

  fMaxVal = new TEveGValuator(this,"MaxVal", 200, 0);
  fMaxVal->SetNELength(4);
  fMaxVal->SetLabelWidth(labelW);
  fMaxVal->Build();
  fMaxVal->GetSlider()->SetWidth(120);
  fMaxVal->SetLimits(0, 500);
  fMaxVal->Connect("ValueSet(Double_t)",
		   "AliEveTPCSectorVizEditor", this, "DoMaxVal()");
  AddFrame(fMaxVal, new TGLayoutHints(kLHintsTop, 1, 1, 2, 1));

  fTime = new TEveGDoubleValuator(this,"Time", 200, 0);
  fTime->SetNELength(4);
  fTime->SetLabelWidth(labelW);
  fTime->Build();
  fTime->GetSlider()->SetWidth(224);
  fTime->SetLimits(0, 1023, TGNumberFormat::kNESInteger);
  fTime->Connect("ValueSet()",
		 "AliEveTPCSectorVizEditor", this, "DoTime()");
  AddFrame(fTime, new TGLayoutHints(kLHintsTop, 1, 1, 2, 1));
}

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

void AliEveTPCSectorVizEditor::SetModel(TObject* obj)
{
  // Set model object.

  fM = static_cast<AliEveTPCSectorViz*>(obj);

  fSectorID->SetValue(fM->fSectorID);
  fAutoTrans->SetState(fM->fAutoTrans  ? kButtonDown : kButtonUp);

  fRnrInn ->SetState(fM->fRnrInn  ? kButtonDown : kButtonUp);
  fRnrOut1->SetState(fM->fRnrOut1 ? kButtonDown : kButtonUp);
  fRnrOut2->SetState(fM->fRnrOut2 ? kButtonDown : kButtonUp);

  fThreshold->SetValue(fM->fThreshold);
  fMaxVal->SetValue(fM->fMaxVal);

  fTime->SetValues(fM->fMinTime, fM->fMaxTime);
}

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

void AliEveTPCSectorVizEditor::DoSectorID()
{
  // Slot for SectorID.

  fM->SetSectorID((Int_t) fSectorID->GetValue());
  Update();
}

void AliEveTPCSectorVizEditor::DoAutoTrans()
{
  // Slot for AutoTrans.

  fM->SetAutoTrans(fAutoTrans->IsOn());
  Update();
}

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

void AliEveTPCSectorVizEditor::DoRnrInn()
{
  // Slot for RnrInn.

  fM->SetRnrInn(fRnrInn->IsOn());
  Update();
}

void AliEveTPCSectorVizEditor::DoRnrOut1()
{
  // Slot for RnrOut1.

  fM->SetRnrOut1(fRnrOut1->IsOn());
  Update();
}

void AliEveTPCSectorVizEditor::DoRnrOut2()
{
  // Slot for RnrOut2.

  fM->SetRnrOut2(fRnrOut2->IsOn());
  Update();
}

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

void AliEveTPCSectorVizEditor::DoThreshold()
{
  // Slot for Threshold.

  fM->SetThreshold((Short_t) fThreshold->GetValue());
  fThreshold->SetValue(fM->fThreshold);
  Update();
}

void AliEveTPCSectorVizEditor::DoMaxVal()
{
  // Slot for MaxVal.

  fM->SetMaxVal((Int_t) fMaxVal->GetValue());
  fMaxVal->SetValue(fM->fMaxVal);
  Update();
}

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

void AliEveTPCSectorVizEditor::DoTime()
{
  // Slot for time-range.

  fM->SetMinTime((Int_t) fTime->GetMin());
  fM->SetMaxTime((Int_t) fTime->GetMax());
  Update();
}
<|endoftext|>