<commit_before>#include <Poco/Exception.h>

#include "di/Injectable.h"
#include "service/GatewayMessageServiceImpl.h"

BEEEON_OBJECT_BEGIN(BeeeOn, GatewayMessageServiceImpl)
BEEEON_OBJECT_CASTABLE(GatewayMessageService)
BEEEON_OBJECT_CASTABLE(DeviceListener)
BEEEON_OBJECT_PROPERTY("gatewayMessageDao", &GatewayMessageServiceImpl::setGatewayMessageDao)
BEEEON_OBJECT_PROPERTY("accessPolicy", &GatewayMessageServiceImpl::setAccessPolicy)
BEEEON_OBJECT_PROPERTY("transactionManager", &GatewayMessageServiceImpl::setTransactionManager)
BEEEON_OBJECT_PROPERTY("gatewayMessagesLimit", &GatewayMessageServiceImpl::setGatewayMessagesLimit)
BEEEON_OBJECT_END(BeeeOn, GatewayMessageServiceImpl)

using namespace std;
using namespace Poco;
using namespace Poco::JSON;
using namespace BeeeOn;

GatewayMessageServiceImpl::GatewayMessageServiceImpl()
{
}

void GatewayMessageServiceImpl::setAccessPolicy(GatewayMessageAccessPolicy::Ptr policy)
{
	m_policy = policy;
}

void GatewayMessageServiceImpl::setGatewayMessageDao(GatewayMessageDao::Ptr dao)
{
	m_dao = dao;
}

void GatewayMessageServiceImpl::setGatewayMessagesLimit(int limit)
{
	if (limit < 1)
		throw InvalidArgumentException("gatewayMessagesLimit must be at least 1");

	m_gatewayMessagesLimit = limit;
}

bool GatewayMessageServiceImpl::doFetch(
		Relation<GatewayMessage, Gateway> &input)
{
	m_policy->assure(
		GatewayMessageAccessPolicy::ACTION_USER_GET,
		input,
		input.base());

	return m_dao->fetch(input.target(), input.base());
}

void GatewayMessageServiceImpl::doFetchMany(
		Relation<vector<GatewayMessage>, Gateway> &input)
{
	m_policy->assure(
		GatewayMessageAccessPolicy::ACTION_USER_GET,
		input,
		input.base());

	m_dao->fetchBy(input.target(), input.base());
}

bool GatewayMessageServiceImpl::doRemove(
		Relation<GatewayMessage, Gateway> &input)
{
	m_policy->assure(
		GatewayMessageAccessPolicy::ACTION_USER_REMOVE,
		input,
		input.base());

	return m_dao->remove(input.target(), input.base());
}

void GatewayMessageServiceImpl::onRefusedNewDevice(const DeviceEvent &e)
{
	GatewayMessage message;
	message.setGateway({e.gatewayID()});
	message.setAt({});
	message.setSeverity(GatewayMessage::SEVERITY_WARN);
	message.setKey("gateway.new_device_refused");

	Object::Ptr context = new Object;
	context->set("gateway_id", e.gatewayID().toString());
	context->set("device_id", e.deviceID().toString());

	message.setContext(context);

	BEEEON_TRANSACTION(m_dao->insert(message, m_gatewayMessagesLimit));
}

void GatewayMessageServiceImpl::onPairFailed(const DeviceEvent &e)
{
	GatewayMessage message;
	message.setGateway({e.gatewayID()});
	message.setAt({});
	message.setSeverity(GatewayMessage::SEVERITY_ERROR);
	message.setKey("gateway.pair_device_failed");

	Object::Ptr context = new Object;
	context->set("gateway_id", e.gatewayID().toString());
	context->set("device_id", e.deviceID().toString());

	message.setContext(context);

	BEEEON_TRANSACTION(m_dao->insert(message, m_gatewayMessagesLimit));
}

void GatewayMessageServiceImpl::onUnpairFailed(const DeviceEvent &e)
{
	GatewayMessage message;
	message.setGateway({e.gatewayID()});
	message.setAt({});
	message.setSeverity(GatewayMessage::SEVERITY_ERROR);
	message.setKey("gateway.unpair_device_failed");

	Object::Ptr context = new Object;
	context->set("gateway_id", e.gatewayID().toString());
	context->set("device_id", e.deviceID().toString());

	message.setContext(context);

	BEEEON_TRANSACTION(m_dao->insert(message, m_gatewayMessagesLimit));
}
<commit_msg>GatewayMessageServiceImpl: fix missing initial value of gatewayMessagesLimit<commit_after>#include <Poco/Exception.h>

#include "di/Injectable.h"
#include "service/GatewayMessageServiceImpl.h"

BEEEON_OBJECT_BEGIN(BeeeOn, GatewayMessageServiceImpl)
BEEEON_OBJECT_CASTABLE(GatewayMessageService)
BEEEON_OBJECT_CASTABLE(DeviceListener)
BEEEON_OBJECT_PROPERTY("gatewayMessageDao", &GatewayMessageServiceImpl::setGatewayMessageDao)
BEEEON_OBJECT_PROPERTY("accessPolicy", &GatewayMessageServiceImpl::setAccessPolicy)
BEEEON_OBJECT_PROPERTY("transactionManager", &GatewayMessageServiceImpl::setTransactionManager)
BEEEON_OBJECT_PROPERTY("gatewayMessagesLimit", &GatewayMessageServiceImpl::setGatewayMessagesLimit)
BEEEON_OBJECT_END(BeeeOn, GatewayMessageServiceImpl)

using namespace std;
using namespace Poco;
using namespace Poco::JSON;
using namespace BeeeOn;

GatewayMessageServiceImpl::GatewayMessageServiceImpl():
	m_gatewayMessagesLimit(64)
{
}

void GatewayMessageServiceImpl::setAccessPolicy(GatewayMessageAccessPolicy::Ptr policy)
{
	m_policy = policy;
}

void GatewayMessageServiceImpl::setGatewayMessageDao(GatewayMessageDao::Ptr dao)
{
	m_dao = dao;
}

void GatewayMessageServiceImpl::setGatewayMessagesLimit(int limit)
{
	if (limit < 1)
		throw InvalidArgumentException("gatewayMessagesLimit must be at least 1");

	m_gatewayMessagesLimit = limit;
}

bool GatewayMessageServiceImpl::doFetch(
		Relation<GatewayMessage, Gateway> &input)
{
	m_policy->assure(
		GatewayMessageAccessPolicy::ACTION_USER_GET,
		input,
		input.base());

	return m_dao->fetch(input.target(), input.base());
}

void GatewayMessageServiceImpl::doFetchMany(
		Relation<vector<GatewayMessage>, Gateway> &input)
{
	m_policy->assure(
		GatewayMessageAccessPolicy::ACTION_USER_GET,
		input,
		input.base());

	m_dao->fetchBy(input.target(), input.base());
}

bool GatewayMessageServiceImpl::doRemove(
		Relation<GatewayMessage, Gateway> &input)
{
	m_policy->assure(
		GatewayMessageAccessPolicy::ACTION_USER_REMOVE,
		input,
		input.base());

	return m_dao->remove(input.target(), input.base());
}

void GatewayMessageServiceImpl::onRefusedNewDevice(const DeviceEvent &e)
{
	GatewayMessage message;
	message.setGateway({e.gatewayID()});
	message.setAt({});
	message.setSeverity(GatewayMessage::SEVERITY_WARN);
	message.setKey("gateway.new_device_refused");

	Object::Ptr context = new Object;
	context->set("gateway_id", e.gatewayID().toString());
	context->set("device_id", e.deviceID().toString());

	message.setContext(context);

	BEEEON_TRANSACTION(m_dao->insert(message, m_gatewayMessagesLimit));
}

void GatewayMessageServiceImpl::onPairFailed(const DeviceEvent &e)
{
	GatewayMessage message;
	message.setGateway({e.gatewayID()});
	message.setAt({});
	message.setSeverity(GatewayMessage::SEVERITY_ERROR);
	message.setKey("gateway.pair_device_failed");

	Object::Ptr context = new Object;
	context->set("gateway_id", e.gatewayID().toString());
	context->set("device_id", e.deviceID().toString());

	message.setContext(context);

	BEEEON_TRANSACTION(m_dao->insert(message, m_gatewayMessagesLimit));
}

void GatewayMessageServiceImpl::onUnpairFailed(const DeviceEvent &e)
{
	GatewayMessage message;
	message.setGateway({e.gatewayID()});
	message.setAt({});
	message.setSeverity(GatewayMessage::SEVERITY_ERROR);
	message.setKey("gateway.unpair_device_failed");

	Object::Ptr context = new Object;
	context->set("gateway_id", e.gatewayID().toString());
	context->set("device_id", e.deviceID().toString());

	message.setContext(context);

	BEEEON_TRANSACTION(m_dao->insert(message, m_gatewayMessagesLimit));
}
<|endoftext|>


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

Program:   Medical Imaging & Interaction Toolkit
Module:    $RCSfile: QmitkTrackingDeviceWidget.cpp $
Language:  C++
Date:      $Date: 2009-05-12 19:14:45 +0200 (Di, 12 Mai 2009) $
Version:   $Revision: 1.12 $

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 "QmitkNavigationToolManagementWidget.h"

//mitk headers
#include "mitkTrackingTypes.h"
#include <mitkSTLFileReader.h>
#include <mitkSurface.h>
#include <mitkNavigationToolReader.h>
#include <mitkNavigationToolWriter.h>
#include <mitkNavigationToolStorage.h>
#include <mitkNavigationToolStorageDeserializer.h>
#include <mitkNavigationToolStorageSerializer.h>

//qt headers
#include <qfiledialog.h>
#include <qmessagebox.h>

const std::string QmitkNavigationToolManagementWidget::VIEW_ID = "org.mitk.views.navigationtoolmanagementwidget";

QmitkNavigationToolManagementWidget::QmitkNavigationToolManagementWidget(QWidget* parent, Qt::WindowFlags f)
  : QWidget(parent, f)
{
  m_Controls = NULL;
  CreateQtPartControl(this);
  CreateConnections();
  m_NavigationToolStorage = mitk::NavigationToolStorage::New();
  m_Controls->m_SurfaceChooser->SetAutoSelectNewItems(true);
}

QmitkNavigationToolManagementWidget::~QmitkNavigationToolManagementWidget()
{
}

void QmitkNavigationToolManagementWidget::CreateQtPartControl(QWidget *parent)
  {
    if (!m_Controls)
    {
    // create GUI widgets
    m_Controls = new Ui::QmitkNavigationToolManagementWidgetControls;
    m_Controls->setupUi(parent);
    }
  }

void QmitkNavigationToolManagementWidget::CreateConnections()
  {
    if ( m_Controls )
    {
      //main widget page:
      connect( (QObject*)(m_Controls->m_AddTool), SIGNAL(clicked()), this, SLOT(OnAddTool()) );
      connect( (QObject*)(m_Controls->m_DeleteTool), SIGNAL(clicked()), this, SLOT(OnDeleteTool()) );
      connect( (QObject*)(m_Controls->m_EditTool), SIGNAL(clicked()), this, SLOT(OnEditTool()) );
      connect( (QObject*)(m_Controls->m_LoadSingleTool), SIGNAL(clicked()), this, SLOT(OnLoadSingleTool()) );
      connect( (QObject*)(m_Controls->m_SaveSingleTool), SIGNAL(clicked()), this, SLOT(OnSaveSingleTool()) );
      connect( (QObject*)(m_Controls->m_LoadStorage), SIGNAL(clicked()), this, SLOT(OnLoadStorage()) );
      connect( (QObject*)(m_Controls->m_SaveStorage), SIGNAL(clicked()), this, SLOT(OnSaveStorage()) );

      //widget page "add tool":
      connect( (QObject*)(m_Controls->m_AddToolCancel), SIGNAL(clicked()), this, SLOT(OnAddToolCancel()) );
      connect( (QObject*)(m_Controls->m_AddToolSave), SIGNAL(clicked()), this, SLOT(OnAddToolSave()) );
      connect( (QObject*)(m_Controls->m_LoadSurface), SIGNAL(clicked()), this, SLOT(OnLoadSurface()) );
      connect( (QObject*)(m_Controls->m_LoadCalibrationFile), SIGNAL(clicked()), this, SLOT(OnLoadCalibrationFile()) );
    }
  }

void QmitkNavigationToolManagementWidget::Initialize(mitk::DataStorage* dataStorage)
  {
  m_DataStorage = dataStorage;
  }

//##################################################################################
//############################## slots: main widget ################################
//##################################################################################

void QmitkNavigationToolManagementWidget::OnAddTool()
  {
    //initialize UI components
    m_Controls->m_SurfaceChooser->SetDataStorage(m_DataStorage);
    m_Controls->AddToolLabel->setText("Add Tool:");
    m_Controls->m_MainWidgets->setCurrentIndex(1);

    //reset input fields
    m_Controls->m_ToolNameEdit->setText("");
    m_Controls->m_IdentifierEdit->setText("NavigationTool#"+QString::number(m_NavigationToolStorage->GetToolCount()));
    m_Controls->m_SerialNumberEdit->setText("");
    m_Controls->m_CalibrationFileName->setText("");

    m_edit = false;
  }

void QmitkNavigationToolManagementWidget::OnDeleteTool()
  {
    //if no item is selected, show error message:
    if (m_Controls->m_ToolList->currentItem() == NULL) {MessageBox("Error: Please select tool first!");return;}

    m_DataStorage->Remove(m_NavigationToolStorage->GetTool(m_Controls->m_ToolList->currentIndex().row())->GetDataTreeNode());
    m_NavigationToolStorage->DeleteTool(m_Controls->m_ToolList->currentIndex().row());
    UpdateToolTable();

  }

void QmitkNavigationToolManagementWidget::OnEditTool()
  {
    //if no item is selected, show error message:
    if (m_Controls->m_ToolList->currentItem() == NULL) {MessageBox("Error: Please select tool first!");return;}

    //initialize UI components
    m_Controls->m_SurfaceChooser->SetDataStorage(m_DataStorage);
    m_Controls->AddToolLabel->setText("Edit Tool:");
    m_Controls->m_MainWidgets->setCurrentIndex(1);

    //fill forms
    mitk::NavigationTool::Pointer selectedTool = m_NavigationToolStorage->GetTool(m_Controls->m_ToolList->currentIndex().row());
    m_Controls->m_ToolNameEdit->setText(QString(selectedTool->GetDataTreeNode()->GetName().c_str()));
    m_Controls->m_IdentifierEdit->setText(QString(selectedTool->GetIdentifier().c_str()));
    m_Controls->m_SerialNumberEdit->setText(QString(selectedTool->GetSerialNumber().c_str()));
    switch(selectedTool->GetTrackingDeviceType())
      {
      case mitk::NDIAurora:
              m_Controls->m_TrackingDeviceTypeChooser->setCurrentIndex(0);break;
      case mitk::NDIPolaris:
              m_Controls->m_TrackingDeviceTypeChooser->setCurrentIndex(1);break;
      case mitk::ClaronMicron:
              m_Controls->m_TrackingDeviceTypeChooser->setCurrentIndex(2);break;
      default:
              m_Controls->m_TrackingDeviceTypeChooser->setCurrentIndex(0);
      }
    m_Controls->m_CalibrationFileName->setText(QString(selectedTool->GetCalibrationFile().c_str()));
    switch(selectedTool->GetType())
      {
      case mitk::NavigationTool::Instrument:
        m_Controls->m_ToolTypeChooser->setCurrentIndex(0); break;
      case mitk::NavigationTool::Fiducial:
        m_Controls->m_ToolTypeChooser->setCurrentIndex(1); break;
      case mitk::NavigationTool::Skinmarker:
        m_Controls->m_ToolTypeChooser->setCurrentIndex(2); break;
      case mitk::NavigationTool::Unknown:
        m_Controls->m_ToolTypeChooser->setCurrentIndex(3); break;
      }
    m_edit = true;
  }

void QmitkNavigationToolManagementWidget::OnLoadSingleTool()
  {
    mitk::NavigationToolReader::Pointer myReader = mitk::NavigationToolReader::New(m_DataStorage);
    mitk::NavigationTool::Pointer readTool = myReader->DoRead(QFileDialog::getOpenFileName(NULL,tr("Open Navigation Tool"), "/", "*.*").toAscii().data());
    if (readTool.IsNull()) MessageBox("Error: " + myReader->GetErrorMessage());
    else
      {
      if (!m_NavigationToolStorage->AddTool(readTool))
        {
        MessageBox("Error: Can't add tool!");
        m_DataStorage->Remove(readTool->GetDataTreeNode());
        }
      UpdateToolTable();
      }
  }

void QmitkNavigationToolManagementWidget::OnSaveSingleTool()
  {
    //if no item is selected, show error message:
    if (m_Controls->m_ToolList->currentItem() == NULL) {MessageBox("Error: Please select tool first!");return;}

    mitk::NavigationToolWriter::Pointer myWriter = mitk::NavigationToolWriter::New();
    if (!myWriter->DoWrite(QFileDialog::getSaveFileName(NULL,tr("Save Navigation Tool"), "/", "*.*").toAscii().data(),m_NavigationToolStorage->GetTool(m_Controls->m_ToolList->currentIndex().row())))
      MessageBox("Error: "+ myWriter->GetErrorMessage());
  }

void QmitkNavigationToolManagementWidget::OnLoadStorage()
  {
    mitk::NavigationToolStorageDeserializer::Pointer myDeserializer = mitk::NavigationToolStorageDeserializer::New(m_DataStorage);
    std::string filename = QFileDialog::getOpenFileName(NULL,tr("Open Navigation Tool"), "/", "*.*").toAscii().data();
    mitk::NavigationToolStorage::Pointer tempStorage = myDeserializer->Deserialize(filename);
    if (tempStorage.IsNull()) MessageBox("Error" + myDeserializer->GetErrorMessage());
    else
      {
      m_NavigationToolStorage = tempStorage;
      m_Controls->m_StorageName->setText(filename.c_str());
      }
    UpdateToolTable();
  }

void QmitkNavigationToolManagementWidget::OnSaveStorage()
  {
    mitk::NavigationToolStorageSerializer::Pointer mySerializer = mitk::NavigationToolStorageSerializer::New();
    std::string filename = QFileDialog::getSaveFileName(NULL,tr("Save Navigation Tool"), "/", "*.*").toAscii().data();
    if (!mySerializer->Serialize(filename,m_NavigationToolStorage)) MessageBox("Error: " + mySerializer->GetErrorMessage());
    else m_Controls->m_StorageName->setText(QString(filename.c_str()));
  }

//##################################################################################
//############################## slots: add tool widget ############################
//##################################################################################

void QmitkNavigationToolManagementWidget::OnAddToolSave()
  {
    mitk::NavigationTool::Pointer workTool;

    if (m_edit) //here we edit a existing tool
      {
      workTool = m_NavigationToolStorage->GetTool(m_Controls->m_ToolList->currentIndex().row());

      //edit existing DataTreeNode...
      workTool->GetDataTreeNode()->SetName(m_Controls->m_ToolNameEdit->text().toLatin1());
      workTool->GetDataTreeNode()->SetData(m_Controls->m_SurfaceChooser->GetSelectedNode()->GetData());
      }
    else //here we create a new tool
      {
      workTool = mitk::NavigationTool::New();

      //create DataTreeNode...
      mitk::DataTreeNode::Pointer newNode = mitk::DataTreeNode::New();
      newNode->SetName(m_Controls->m_ToolNameEdit->text().toLatin1());
      newNode->SetData(m_Controls->m_SurfaceChooser->GetSelectedNode()->GetData());
      m_DataStorage->Add(newNode);
      workTool->SetDataTreeNode(newNode);
      }

    //fill NavigationTool object
    workTool->SetCalibrationFile(m_Controls->m_CalibrationFileName->text().toAscii().data());
    workTool->SetIdentifier(m_Controls->m_IdentifierEdit->text().toAscii().data());
    workTool->SetSerialNumber(m_Controls->m_SerialNumberEdit->text().toAscii().data());
    //Tracking Device
    if (m_Controls->m_TrackingDeviceTypeChooser->currentText()=="NDI Aurora") workTool->SetTrackingDeviceType(mitk::NDIAurora);
    else if (m_Controls->m_TrackingDeviceTypeChooser->currentText()=="NDI Polaris") workTool->SetTrackingDeviceType(mitk::NDIPolaris);
    else if (m_Controls->m_TrackingDeviceTypeChooser->currentText()=="Claron Technology Micron Tracker") workTool->SetTrackingDeviceType(mitk::ClaronMicron);
    else workTool->SetTrackingDeviceType(mitk::TrackingSystemNotSpecified);
    //ToolType
    if (m_Controls->m_ToolTypeChooser->currentText()=="Instrument") workTool->SetType(mitk::NavigationTool::Instrument);
    else if (m_Controls->m_ToolTypeChooser->currentText()=="Fiducial") workTool->SetType(mitk::NavigationTool::Fiducial);
    else if (m_Controls->m_ToolTypeChooser->currentText()=="Skinmarker") workTool->SetType(mitk::NavigationTool::Skinmarker);
    else workTool->SetType(mitk::NavigationTool::Unknown);

    if (!m_edit) m_NavigationToolStorage->AddTool(workTool);

    UpdateToolTable();

    m_Controls->m_MainWidgets->setCurrentIndex(0);
  }

void QmitkNavigationToolManagementWidget::OnAddToolCancel()
  {
    m_Controls->m_MainWidgets->setCurrentIndex(0);
  }

void QmitkNavigationToolManagementWidget::OnLoadSurface()
  {
    std::string filename = QFileDialog::getOpenFileName(NULL,tr("Open Surface"), "/", "*.stl").toLatin1().data();
    mitk::STLFileReader::Pointer stlReader = mitk::STLFileReader::New();
    try
      {
      stlReader->SetFileName( filename.c_str() );
      stlReader->Update();
      }
    catch (...)
      {
      }

    if ( stlReader->GetOutput() == NULL );
    else
      {
      mitk::DataTreeNode::Pointer newNode = mitk::DataTreeNode::New();
      newNode->SetName(filename);
      newNode->SetData(stlReader->GetOutput());
      m_DataStorage->Add(newNode);
      }
  }

void QmitkNavigationToolManagementWidget::OnLoadCalibrationFile()
  {
    m_Controls->m_CalibrationFileName->setText(QFileDialog::getOpenFileName(NULL,tr("Open Calibration File"), "/", "*.*"));
  }

//##################################################################################
//############################## private help methods ##############################
//##################################################################################
void QmitkNavigationToolManagementWidget::UpdateToolTable()
  {
  m_Controls->m_ToolList->clear();
  for(int i=0; i<m_NavigationToolStorage->GetToolCount(); i++)
    {
      QString currentTool = "Tool" + QString::number(i) + ": " + QString(m_NavigationToolStorage->GetTool(i)->GetDataTreeNode()->GetName().c_str())+ " ";
      switch (m_NavigationToolStorage->GetTool(i)->GetTrackingDeviceType())
        {
        case mitk::ClaronMicron:
              currentTool += "(MicronTracker/"; break;
        case mitk::NDIAurora:
              currentTool += "(NDI Aurora/"; break;
        case mitk::NDIPolaris:
              currentTool += "(NDI Polaris/"; break;
        default:
              currentTool += "(unknown tracking system/"; break;
        }
      switch (m_NavigationToolStorage->GetTool(i)->GetType())
        {
        case mitk::NavigationTool::Instrument:
              currentTool += "Instrument)"; break;
        case mitk::NavigationTool::Fiducial:
              currentTool += "Fiducial)"; break;
        case mitk::NavigationTool::Skinmarker:
              currentTool += "Skinmarker)"; break;
        default:
              currentTool += "Unknown)";
        }
      m_Controls->m_ToolList->addItem(currentTool);
    }

  }

void QmitkNavigationToolManagementWidget::MessageBox(std::string s)
  {
  QMessageBox msgBox;
  msgBox.setText(s.c_str());
  msgBox.exec();
  }<commit_msg>FIX (#3167): Fixed bug in tool edit mode. The right DataTreeNode is selected now.<commit_after>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Module:    $RCSfile: QmitkTrackingDeviceWidget.cpp $
Language:  C++
Date:      $Date: 2009-05-12 19:14:45 +0200 (Di, 12 Mai 2009) $
Version:   $Revision: 1.12 $

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 "QmitkNavigationToolManagementWidget.h"

//mitk headers
#include "mitkTrackingTypes.h"
#include <mitkSTLFileReader.h>
#include <mitkSurface.h>
#include <mitkNavigationToolReader.h>
#include <mitkNavigationToolWriter.h>
#include <mitkNavigationToolStorage.h>
#include <mitkNavigationToolStorageDeserializer.h>
#include <mitkNavigationToolStorageSerializer.h>

//qt headers
#include <qfiledialog.h>
#include <qmessagebox.h>

const std::string QmitkNavigationToolManagementWidget::VIEW_ID = "org.mitk.views.navigationtoolmanagementwidget";

QmitkNavigationToolManagementWidget::QmitkNavigationToolManagementWidget(QWidget* parent, Qt::WindowFlags f)
  : QWidget(parent, f)
{
  m_Controls = NULL;
  CreateQtPartControl(this);
  CreateConnections();
  m_NavigationToolStorage = mitk::NavigationToolStorage::New();
  m_Controls->m_SurfaceChooser->SetAutoSelectNewItems(true);
}

QmitkNavigationToolManagementWidget::~QmitkNavigationToolManagementWidget()
{
}

void QmitkNavigationToolManagementWidget::CreateQtPartControl(QWidget *parent)
  {
    if (!m_Controls)
    {
    // create GUI widgets
    m_Controls = new Ui::QmitkNavigationToolManagementWidgetControls;
    m_Controls->setupUi(parent);
    }
  }

void QmitkNavigationToolManagementWidget::CreateConnections()
  {
    if ( m_Controls )
    {
      //main widget page:
      connect( (QObject*)(m_Controls->m_AddTool), SIGNAL(clicked()), this, SLOT(OnAddTool()) );
      connect( (QObject*)(m_Controls->m_DeleteTool), SIGNAL(clicked()), this, SLOT(OnDeleteTool()) );
      connect( (QObject*)(m_Controls->m_EditTool), SIGNAL(clicked()), this, SLOT(OnEditTool()) );
      connect( (QObject*)(m_Controls->m_LoadSingleTool), SIGNAL(clicked()), this, SLOT(OnLoadSingleTool()) );
      connect( (QObject*)(m_Controls->m_SaveSingleTool), SIGNAL(clicked()), this, SLOT(OnSaveSingleTool()) );
      connect( (QObject*)(m_Controls->m_LoadStorage), SIGNAL(clicked()), this, SLOT(OnLoadStorage()) );
      connect( (QObject*)(m_Controls->m_SaveStorage), SIGNAL(clicked()), this, SLOT(OnSaveStorage()) );

      //widget page "add tool":
      connect( (QObject*)(m_Controls->m_AddToolCancel), SIGNAL(clicked()), this, SLOT(OnAddToolCancel()) );
      connect( (QObject*)(m_Controls->m_AddToolSave), SIGNAL(clicked()), this, SLOT(OnAddToolSave()) );
      connect( (QObject*)(m_Controls->m_LoadSurface), SIGNAL(clicked()), this, SLOT(OnLoadSurface()) );
      connect( (QObject*)(m_Controls->m_LoadCalibrationFile), SIGNAL(clicked()), this, SLOT(OnLoadCalibrationFile()) );
    }
  }

void QmitkNavigationToolManagementWidget::Initialize(mitk::DataStorage* dataStorage)
  {
  m_DataStorage = dataStorage;
  }

//##################################################################################
//############################## slots: main widget ################################
//##################################################################################

void QmitkNavigationToolManagementWidget::OnAddTool()
  {
    //initialize UI components
    m_Controls->m_SurfaceChooser->SetDataStorage(m_DataStorage);
    m_Controls->AddToolLabel->setText("Add Tool:");
    m_Controls->m_MainWidgets->setCurrentIndex(1);

    //reset input fields
    m_Controls->m_ToolNameEdit->setText("");
    m_Controls->m_IdentifierEdit->setText("NavigationTool#"+QString::number(m_NavigationToolStorage->GetToolCount()));
    m_Controls->m_SerialNumberEdit->setText("");
    m_Controls->m_CalibrationFileName->setText("");

    m_edit = false;
  }

void QmitkNavigationToolManagementWidget::OnDeleteTool()
  {
    //if no item is selected, show error message:
    if (m_Controls->m_ToolList->currentItem() == NULL) {MessageBox("Error: Please select tool first!");return;}

    m_DataStorage->Remove(m_NavigationToolStorage->GetTool(m_Controls->m_ToolList->currentIndex().row())->GetDataTreeNode());
    m_NavigationToolStorage->DeleteTool(m_Controls->m_ToolList->currentIndex().row());
    UpdateToolTable();

  }

void QmitkNavigationToolManagementWidget::OnEditTool()
  {
    //if no item is selected, show error message:
    if (m_Controls->m_ToolList->currentItem() == NULL) {MessageBox("Error: Please select tool first!");return;}

    //initialize UI components
    m_Controls->m_SurfaceChooser->SetDataStorage(m_DataStorage);
    m_Controls->AddToolLabel->setText("Edit Tool:");
    m_Controls->m_MainWidgets->setCurrentIndex(1);

    //fill forms
    mitk::NavigationTool::Pointer selectedTool = m_NavigationToolStorage->GetTool(m_Controls->m_ToolList->currentIndex().row());
    m_Controls->m_ToolNameEdit->setText(QString(selectedTool->GetDataTreeNode()->GetName().c_str()));
    m_Controls->m_IdentifierEdit->setText(QString(selectedTool->GetIdentifier().c_str()));
    m_Controls->m_SerialNumberEdit->setText(QString(selectedTool->GetSerialNumber().c_str()));
    switch(selectedTool->GetTrackingDeviceType())
      {
      case mitk::NDIAurora:
              m_Controls->m_TrackingDeviceTypeChooser->setCurrentIndex(0);break;
      case mitk::NDIPolaris:
              m_Controls->m_TrackingDeviceTypeChooser->setCurrentIndex(1);break;
      case mitk::ClaronMicron:
              m_Controls->m_TrackingDeviceTypeChooser->setCurrentIndex(2);break;
      default:
              m_Controls->m_TrackingDeviceTypeChooser->setCurrentIndex(0);
      }
    m_Controls->m_CalibrationFileName->setText(QString(selectedTool->GetCalibrationFile().c_str()));
    switch(selectedTool->GetType())
      {
      case mitk::NavigationTool::Instrument:
        m_Controls->m_ToolTypeChooser->setCurrentIndex(0); break;
      case mitk::NavigationTool::Fiducial:
        m_Controls->m_ToolTypeChooser->setCurrentIndex(1); break;
      case mitk::NavigationTool::Skinmarker:
        m_Controls->m_ToolTypeChooser->setCurrentIndex(2); break;
      case mitk::NavigationTool::Unknown:
        m_Controls->m_ToolTypeChooser->setCurrentIndex(3); break;
      }

    m_Controls->m_SurfaceChooser->SetSelectedNode(selectedTool->GetDataTreeNode());
    m_edit = true;
  }

void QmitkNavigationToolManagementWidget::OnLoadSingleTool()
  {
    mitk::NavigationToolReader::Pointer myReader = mitk::NavigationToolReader::New(m_DataStorage);
    mitk::NavigationTool::Pointer readTool = myReader->DoRead(QFileDialog::getOpenFileName(NULL,tr("Open Navigation Tool"), "/", "*.*").toAscii().data());
    if (readTool.IsNull()) MessageBox("Error: " + myReader->GetErrorMessage());
    else
      {
      if (!m_NavigationToolStorage->AddTool(readTool))
        {
        MessageBox("Error: Can't add tool!");
        m_DataStorage->Remove(readTool->GetDataTreeNode());
        }
      UpdateToolTable();
      }
  }

void QmitkNavigationToolManagementWidget::OnSaveSingleTool()
  {
    //if no item is selected, show error message:
    if (m_Controls->m_ToolList->currentItem() == NULL) {MessageBox("Error: Please select tool first!");return;}

    mitk::NavigationToolWriter::Pointer myWriter = mitk::NavigationToolWriter::New();
    if (!myWriter->DoWrite(QFileDialog::getSaveFileName(NULL,tr("Save Navigation Tool"), "/", "*.*").toAscii().data(),m_NavigationToolStorage->GetTool(m_Controls->m_ToolList->currentIndex().row())))
      MessageBox("Error: "+ myWriter->GetErrorMessage());
  }

void QmitkNavigationToolManagementWidget::OnLoadStorage()
  {
    mitk::NavigationToolStorageDeserializer::Pointer myDeserializer = mitk::NavigationToolStorageDeserializer::New(m_DataStorage);
    std::string filename = QFileDialog::getOpenFileName(NULL,tr("Open Navigation Tool"), "/", "*.*").toAscii().data();
    mitk::NavigationToolStorage::Pointer tempStorage = myDeserializer->Deserialize(filename);
    if (tempStorage.IsNull()) MessageBox("Error" + myDeserializer->GetErrorMessage());
    else
      {
      m_NavigationToolStorage = tempStorage;
      m_Controls->m_StorageName->setText(filename.c_str());
      }
    UpdateToolTable();
  }

void QmitkNavigationToolManagementWidget::OnSaveStorage()
  {
    mitk::NavigationToolStorageSerializer::Pointer mySerializer = mitk::NavigationToolStorageSerializer::New();
    std::string filename = QFileDialog::getSaveFileName(NULL,tr("Save Navigation Tool"), "/", "*.*").toAscii().data();
    if (!mySerializer->Serialize(filename,m_NavigationToolStorage)) MessageBox("Error: " + mySerializer->GetErrorMessage());
    else m_Controls->m_StorageName->setText(QString(filename.c_str()));
  }

//##################################################################################
//############################## slots: add tool widget ############################
//##################################################################################

void QmitkNavigationToolManagementWidget::OnAddToolSave()
  {
    mitk::NavigationTool::Pointer workTool;

    if (m_edit) //here we edit a existing tool
      {
      workTool = m_NavigationToolStorage->GetTool(m_Controls->m_ToolList->currentIndex().row());

      //edit existing DataTreeNode...
      workTool->GetDataTreeNode()->SetName(m_Controls->m_ToolNameEdit->text().toLatin1());
      workTool->GetDataTreeNode()->SetData(m_Controls->m_SurfaceChooser->GetSelectedNode()->GetData());
      }
    else //here we create a new tool
      {
      workTool = mitk::NavigationTool::New();

      //create DataTreeNode...
      mitk::DataTreeNode::Pointer newNode = mitk::DataTreeNode::New();
      newNode->SetName(m_Controls->m_ToolNameEdit->text().toLatin1());
      newNode->SetData(m_Controls->m_SurfaceChooser->GetSelectedNode()->GetData());
      m_DataStorage->Add(newNode);
      workTool->SetDataTreeNode(newNode);
      }

    //fill NavigationTool object
    workTool->SetCalibrationFile(m_Controls->m_CalibrationFileName->text().toAscii().data());
    workTool->SetIdentifier(m_Controls->m_IdentifierEdit->text().toAscii().data());
    workTool->SetSerialNumber(m_Controls->m_SerialNumberEdit->text().toAscii().data());
    //Tracking Device
    if (m_Controls->m_TrackingDeviceTypeChooser->currentText()=="NDI Aurora") workTool->SetTrackingDeviceType(mitk::NDIAurora);
    else if (m_Controls->m_TrackingDeviceTypeChooser->currentText()=="NDI Polaris") workTool->SetTrackingDeviceType(mitk::NDIPolaris);
    else if (m_Controls->m_TrackingDeviceTypeChooser->currentText()=="Claron Technology Micron Tracker") workTool->SetTrackingDeviceType(mitk::ClaronMicron);
    else workTool->SetTrackingDeviceType(mitk::TrackingSystemNotSpecified);
    //ToolType
    if (m_Controls->m_ToolTypeChooser->currentText()=="Instrument") workTool->SetType(mitk::NavigationTool::Instrument);
    else if (m_Controls->m_ToolTypeChooser->currentText()=="Fiducial") workTool->SetType(mitk::NavigationTool::Fiducial);
    else if (m_Controls->m_ToolTypeChooser->currentText()=="Skinmarker") workTool->SetType(mitk::NavigationTool::Skinmarker);
    else workTool->SetType(mitk::NavigationTool::Unknown);

    if (!m_edit) m_NavigationToolStorage->AddTool(workTool);

    UpdateToolTable();

    m_Controls->m_MainWidgets->setCurrentIndex(0);
  }

void QmitkNavigationToolManagementWidget::OnAddToolCancel()
  {
    m_Controls->m_MainWidgets->setCurrentIndex(0);
  }

void QmitkNavigationToolManagementWidget::OnLoadSurface()
  {
    std::string filename = QFileDialog::getOpenFileName(NULL,tr("Open Surface"), "/", "*.stl").toLatin1().data();
    mitk::STLFileReader::Pointer stlReader = mitk::STLFileReader::New();
    try
      {
      stlReader->SetFileName( filename.c_str() );
      stlReader->Update();
      }
    catch (...)
      {
      }

    if ( stlReader->GetOutput() == NULL );
    else
      {
      mitk::DataTreeNode::Pointer newNode = mitk::DataTreeNode::New();
      newNode->SetName(filename);
      newNode->SetData(stlReader->GetOutput());
      m_DataStorage->Add(newNode);
      }
  }

void QmitkNavigationToolManagementWidget::OnLoadCalibrationFile()
  {
    m_Controls->m_CalibrationFileName->setText(QFileDialog::getOpenFileName(NULL,tr("Open Calibration File"), "/", "*.*"));
  }

//##################################################################################
//############################## private help methods ##############################
//##################################################################################
void QmitkNavigationToolManagementWidget::UpdateToolTable()
  {
  m_Controls->m_ToolList->clear();
  for(int i=0; i<m_NavigationToolStorage->GetToolCount(); i++)
    {
      QString currentTool = "Tool" + QString::number(i) + ": " + QString(m_NavigationToolStorage->GetTool(i)->GetDataTreeNode()->GetName().c_str())+ " ";
      switch (m_NavigationToolStorage->GetTool(i)->GetTrackingDeviceType())
        {
        case mitk::ClaronMicron:
              currentTool += "(MicronTracker/"; break;
        case mitk::NDIAurora:
              currentTool += "(NDI Aurora/"; break;
        case mitk::NDIPolaris:
              currentTool += "(NDI Polaris/"; break;
        default:
              currentTool += "(unknown tracking system/"; break;
        }
      switch (m_NavigationToolStorage->GetTool(i)->GetType())
        {
        case mitk::NavigationTool::Instrument:
              currentTool += "Instrument)"; break;
        case mitk::NavigationTool::Fiducial:
              currentTool += "Fiducial)"; break;
        case mitk::NavigationTool::Skinmarker:
              currentTool += "Skinmarker)"; break;
        default:
              currentTool += "Unknown)";
        }
      m_Controls->m_ToolList->addItem(currentTool);
    }

  }

void QmitkNavigationToolManagementWidget::MessageBox(std::string s)
  {
  QMessageBox msgBox;
  msgBox.setText(s.c_str());
  msgBox.exec();
  }<|endoftext|>


<commit_before>#define BOOST_TEST_MODULE gotools-core/testCurveCreators
#include <boost/test/unit_test.hpp>

#include <fstream>
#include "GoTools/geometry/SplineCurve.h"
#include "GoTools/geometry/SplineSurface.h"
#include "GoTools/creators/CurveCreators.h"
#include "GoTools/geometry/ObjectHeader.h"

using namespace Go;
using std::vector;
using std::string;
using std::ifstream;

struct Config {
public:
    Config()
    {

        datadir = "data/"; // Relative to build/gotools-core

        infiles.push_back(datadir + "spline_surface_1.g2");
        infiles.push_back(datadir + "spline_curve_1.g2");

        // This curve produces a "max_trace_diff" slightly above the tolerance.
        // On the other hand, a sampling (see below) produces a result that is
        // slightly *below* the tolerance. This may indicate a problem with the
        // function CurveOnSurface::maxTraceDiff().
        infiles.push_back(datadir + "spline_curve_2.g2");

        infiles.push_back(datadir + "spline_curve_3.g2");
        infiles.push_back(datadir + "spline_curve_4.g2");

    }

public:
    ObjectHeader header;
    string datadir;
    vector<string> infiles;
    vector<int> numobjects;

};

BOOST_FIXTURE_TEST_CASE(testCurveCreators, Config)
{
    ifstream in(infiles[0].c_str());
    shared_ptr<SplineSurface> surface(new SplineSurface());
    header.read(in);
    surface->read(in);
    shared_ptr<ParamSurface> ps = dynamic_pointer_cast<ParamSurface>(surface);

    //in = ifstream(infiles[1].c_str());
    in = ifstream(infiles[2].c_str());
    shared_ptr<SplineCurve> curve(new SplineCurve());
    header.read(in);
    curve->read(in);
    shared_ptr<ParamCurve> pc = dynamic_pointer_cast<ParamCurve>(curve);

    shared_ptr<Point> pt1(new Point(1.0, 0.0));
    shared_ptr<Point> pt2(new Point(0.99999940509745666, 0.97064663782299587));

    double eps = 0.001;
    bool preferparameter = false;

    shared_ptr<CurveOnSurface> cos(new CurveOnSurface(ps, pc, preferparameter));
    cos->ensureParCrvExistence(eps);

    int nmb_seg_samples = 20;
    double max_trace_diff = cos->maxTraceDiff(nmb_seg_samples);

    // The 'CHECK' version is temporarily commented out. Using the 'WARN'
    // version in stead in order to not cause an error.
    //BOOST_CHECK_SMALL(max_trace_diff, eps);
    BOOST_WARN_SMALL(max_trace_diff, eps);

    max_trace_diff = -1.0;
    double tg1 = pc->startparam();
    double tg2 = pc->endparam();
    double tdelg = (tg2-tg1)/(double)(nmb_seg_samples-1);

    int ki;
    double tg;
    for (ki=0, tg=tg1; ki<nmb_seg_samples; ++ki, tg+=tdelg)
      {
	Point clo_pt, pntg;
	Point par(0.0, 0.0);
	double dist;
        pc->point(pntg, tg);
        ps->closestPoint(pntg, par[0], par[1], clo_pt, dist, eps);
	if (dist > max_trace_diff)
	  max_trace_diff = dist;
      }
    BOOST_CHECK_SMALL(max_trace_diff, eps);

}
<commit_msg>Bugfix<commit_after>#define BOOST_TEST_MODULE gotools-core/testCurveCreators
#include <boost/test/unit_test.hpp>

#include <fstream>
#include "GoTools/geometry/SplineCurve.h"
#include "GoTools/geometry/SplineSurface.h"
#include "GoTools/creators/CurveCreators.h"
#include "GoTools/geometry/ObjectHeader.h"

using namespace Go;
using std::vector;
using std::string;
using std::ifstream;

struct Config {
public:
    Config()
    {

        datadir = "data/"; // Relative to build/gotools-core

        infiles.push_back(datadir + "spline_surface_1.g2");
        infiles.push_back(datadir + "spline_curve_1.g2");

        // This curve produces a "max_trace_diff" slightly above the tolerance.
        // On the other hand, a sampling (see below) produces a result that is
        // slightly *below* the tolerance. This may indicate a problem with the
        // function CurveOnSurface::maxTraceDiff().
        infiles.push_back(datadir + "spline_curve_2.g2");

        infiles.push_back(datadir + "spline_curve_3.g2");
        infiles.push_back(datadir + "spline_curve_4.g2");

    }

public:
    ObjectHeader header;
    string datadir;
    vector<string> infiles;
    vector<int> numobjects;

};

BOOST_FIXTURE_TEST_CASE(testCurveCreators, Config)
{
    ifstream in1(infiles[0].c_str());
    shared_ptr<SplineSurface> surface(new SplineSurface());
    header.read(in1);
    surface->read(in1);
    shared_ptr<ParamSurface> ps = dynamic_pointer_cast<ParamSurface>(surface);

    //in = ifstream(infiles[1].c_str());
    ifstream in2(infiles[2].c_str());
    shared_ptr<SplineCurve> curve(new SplineCurve());
    header.read(in2);
    curve->read(in2);
    shared_ptr<ParamCurve> pc = dynamic_pointer_cast<ParamCurve>(curve);

    shared_ptr<Point> pt1(new Point(1.0, 0.0));
    shared_ptr<Point> pt2(new Point(0.99999940509745666, 0.97064663782299587));

    double eps = 0.001;
    bool preferparameter = false;

    shared_ptr<CurveOnSurface> cos(new CurveOnSurface(ps, pc, preferparameter));
    cos->ensureParCrvExistence(eps);

    int nmb_seg_samples = 20;
    double max_trace_diff = cos->maxTraceDiff(nmb_seg_samples);

    // The 'CHECK' version is temporarily commented out. Using the 'WARN'
    // version in stead in order to not cause an error.
    //BOOST_CHECK_SMALL(max_trace_diff, eps);
    BOOST_WARN_SMALL(max_trace_diff, eps);

    max_trace_diff = -1.0;
    double tg1 = pc->startparam();
    double tg2 = pc->endparam();
    double tdelg = (tg2-tg1)/(double)(nmb_seg_samples-1);

    int ki;
    double tg;
    for (ki=0, tg=tg1; ki<nmb_seg_samples; ++ki, tg+=tdelg)
      {
	Point clo_pt, pntg;
	Point par(0.0, 0.0);
	double dist;
        pc->point(pntg, tg);
        ps->closestPoint(pntg, par[0], par[1], clo_pt, dist, eps);
	if (dist > max_trace_diff)
	  max_trace_diff = dist;
      }
    BOOST_CHECK_SMALL(max_trace_diff, eps);

}
<|endoftext|>


<commit_before>#include <stdio.h>
#include <stdarg.h>
#include <time.h>

#include "logger.h"
#include "util.h"

int has_init = 0;
char log_file[BUFFER_SIZE];

static int init_log(){
  	has_init = 1;

	char time_buffer[26];
	time_t timer;
    struct tm* tm_info;

    time(&timer);
    tm_info = localtime(&timer);

    strftime(time_buffer, 26, "%Y-%m-%d_%H.%M.%S.log", tm_info);

	sprintf(log_file, "log/%s", time_buffer);
  	FILE *fp = fopen(log_file, "w");

  	if(!fp){
		fprintf(stderr, "failed to create log file");
		return 1;
	}

	fclose(fp);
	return 0;
}

void no_log(){
	has_init = -1;
}

int logger(const char *format, ...){

	if(has_init == 0){
		init_log();
		logger("Initializing log.");
	}else if(has_init > 0){

		FILE *fp = fopen(log_file, "a");

		if (!fp)
		{
			fprintf(stderr, "failed to open log file\n");
			return 1;
		}
		char time_buffer[26];
		char buffer[255];

		va_list argv;
		va_start(argv, format);
		vsprintf(buffer, format, argv);
		va_end(argv);

		time_t timer;
		struct tm* tm_info;

		time(&timer);
		tm_info = localtime(&timer);

		strftime(time_buffer, 26, "%Y-%m-%d %H:%M:%S", tm_info);

		fprintf(fp, "[%s] %s\n", time_buffer, buffer);

		fclose(fp);
	}

	return 0;
}<commit_msg>TIME_BUFFER definition in logger<commit_after>#include <stdio.h>
#include <stdarg.h>
#include <time.h>

#include "logger.h"
#include "util.h"

#define TIME_BUFFER 26

int has_init = 0;
char log_file[BUFFER_SIZE];

static int init_log(){
  	has_init = 1;

	char time_buffer[TIME_BUFFER];
	time_t timer;
    struct tm* tm_info;

    time(&timer);
    tm_info = localtime(&timer);

    strftime(time_buffer, TIME_BUFFER, "%Y-%m-%d_%H.%M.%S.log", tm_info);

	sprintf(log_file, "log/%s", time_buffer);
  	FILE *fp = fopen(log_file, "w");

  	if(!fp){
		fprintf(stderr, "failed to create log file");
		return 1;
	}

	fclose(fp);
	return 0;
}

void no_log(){
	has_init = -1;
}

int logger(const char *format, ...){

	if(has_init == 0){
		init_log();
		logger("Initializing log.");
	}else if(has_init > 0){

		FILE *fp = fopen(log_file, "a");

		if (!fp)
		{
			fprintf(stderr, "failed to open log file\n");
			return 1;
		}
		char time_buffer[TIME_BUFFER];
		char buffer[BUFFER_SIZE];

		va_list argv;
		va_start(argv, format);
		vsprintf(buffer, format, argv);
		va_end(argv);

		time_t timer;
		struct tm* tm_info;

		time(&timer);
		tm_info = localtime(&timer);

		strftime(time_buffer, TIME_BUFFER, "%Y-%m-%d %H:%M:%S", tm_info);

		fprintf(fp, "[%s] %s\n", time_buffer, buffer);

		fclose(fp);
	}

	return 0;
}<|endoftext|>


<commit_before>#ifndef LOCK_QUEUE
#define LOCK_QUEUE
#include<memory>	//allocator, shared_ptr
#include<utility>	//move
#include"Node.hpp"
#include"../tool/CAlloc_obj.hpp"

namespace nThread
{
	template<class T,class Mutex,class Alloc=std::allocator<T>>
	struct Lock_queue
	{
		using allocator_type=Alloc;
		using element_type=Node<nTool::CAlloc_obj<T,Alloc>>;
		using mutex_type=Mutex;
		using size_type=typename nTool::CAlloc_obj<T,Alloc>::size_type;
		using value_type=T;
		std::shared_ptr<element_type> begin;
		std::shared_ptr<element_type> end;
		mutex_type mut;
		Lock_queue()
			:begin{make_shared<element_type>()},end{make_shared<element_type>()}
		{
			begin->next=end;
		}
		Lock_queue(const Lock_queue &)=delete;
		void emplace(std::shared_ptr<element_type> &&val)
		{
			val->next.reset();
			std::lock_guard<mutex_type> lock{mut};
			emplace_(std::move(val));
		}
		//do not call other member functions (including const member functions) at same time
		inline void emplace_not_ts(std::shared_ptr<element_type> &&val) noexcept
		{
			emplace_(std::move(val));
		}
		inline bool empty() const noexcept
		{
			return !std::atomic_load_explicit(&begin->next,std::memory_order_acquire)->next;
		}
		std::shared_ptr<element_type> pop()
		{
			std::lock_guard<mutex_type> lock{mut};
			return pop_();
		}
		std::shared_ptr<element_type> pop_if_exist()
		{
			if(empty())
				return std::shared_ptr<element_type>{};
			std::lock_guard<mutex_type> lock{mut};
			if(empty())
				return std::shared_ptr<element_type>{};
			return pop_();
		}
		//do not call other member functions (including const member functions) at same time
		std::shared_ptr<element_type> pop_not_ts() noexcept
		{
			const std::shared_ptr<element_type> node{std::move(begin->next)};
			begin->next=node->next;
			return node;
		}
		Lock_queue& operator=(const Lock_queue &)=delete;
	private:
		void emplace_(std::shared_ptr<element_type> &&val) noexcept
		{
			end->next=val;
			std::swap(end->data,val->data);
			end=std::move(val);
		}
		std::shared_ptr<element_type> pop_() noexcept
		{
			const std::shared_ptr<element_type> node{begin->next};
			std::atomic_store_explicit(&begin->next,node->next,std::memory_order_release);
			return node;
		}
	};
}

#endif<commit_msg>speed up<commit_after>#ifndef LOCK_QUEUE
#define LOCK_QUEUE
#include<memory>	//allocator, shared_ptr
#include<utility>	//move
#include"Node.hpp"
#include"../tool/CAlloc_obj.hpp"

namespace nThread
{
	template<class T,class Mutex,class Alloc=std::allocator<T>>
	struct Lock_queue
	{
		using allocator_type=Alloc;
		using element_type=Node<nTool::CAlloc_obj<T,Alloc>>;
		using mutex_type=Mutex;
		using size_type=typename nTool::CAlloc_obj<T,Alloc>::size_type;
		using value_type=T;
		std::shared_ptr<element_type> begin;
		std::shared_ptr<element_type> end;
		mutex_type mut;
		Lock_queue()
			:end{make_shared<element_type>()}
		{
			begin=end;
		}
		Lock_queue(const Lock_queue &)=delete;
		void emplace(std::shared_ptr<element_type> &&val)
		{
			val->next.reset();
			std::lock_guard<mutex_type> lock{mut};
			emplace_(std::move(val));
		}
		//do not call other member functions (including const member functions) at same time
		inline void emplace_not_ts(std::shared_ptr<element_type> &&val) noexcept
		{
			emplace_(std::move(val));
		}
		inline bool empty() const noexcept
		{
			return !std::atomic_load_explicit(&begin,std::memory_order_acquire)->next;
		}
		std::shared_ptr<element_type> pop()
		{
			std::lock_guard<mutex_type> lock{mut};
			return pop_();
		}
		std::shared_ptr<element_type> pop_if_exist()
		{
			if(empty())
				return std::shared_ptr<element_type>{};
			std::lock_guard<mutex_type> lock{mut};
			if(empty())
				return std::shared_ptr<element_type>{};
			return pop_();
		}
		//do not call other member functions (including const member functions) at same time
		std::shared_ptr<element_type> pop_not_ts() noexcept
		{
			const std::shared_ptr<element_type> node{std::move(begin)};
			begin=node->next;
			return node;
		}
		Lock_queue& operator=(const Lock_queue &)=delete;
	private:
		void emplace_(std::shared_ptr<element_type> &&val) noexcept
		{
			end->next=val;
			std::swap(end->data,val->data);
			end=std::move(val);
		}
		std::shared_ptr<element_type> pop_() noexcept
		{
			const std::shared_ptr<element_type> node{begin};
			std::atomic_store_explicit(&begin,node->next,std::memory_order_release);
			return node;
		}
	};
}

#endif<|endoftext|>


<commit_before>#ifndef LDID_HPP
#define LDID_HPP

#include <cstdlib>
#include <map>
#include <set>
#include <sstream>
#include <streambuf>
#include <string>
#include <vector>

namespace ldid {

// I wish Apple cared about providing quality toolchains :/

template <typename Function_>
class Functor;

template <typename Type_, typename... Args_>
class Functor<Type_ (Args_...)> {
  public:
    virtual Type_ operator ()(Args_... args) const = 0;
};

template <typename Function_>
class FunctorImpl;

template <typename Value_, typename Type_, typename... Args_>
class FunctorImpl<Type_ (Value_::*)(Args_...) const> :
    public Functor<Type_ (Args_...)>
{
  private:
    const Value_ *value_;

  public:
    FunctorImpl(const Value_ &value) :
        value_(&value)
    {
    }

    virtual Type_ operator ()(Args_... args) const {
        return (*value_)(args...);
    }
};

template <typename Function_>
FunctorImpl<decltype(&Function_::operator())> fun(const Function_ &value) {
    return value;
}

class Folder {
  public:
    virtual void Save(const std::string &path, bool edit, const void *flag, const Functor<void (std::streambuf &)> &code) = 0;
    virtual bool Look(const std::string &path) const = 0;
    virtual void Open(const std::string &path, const Functor<void (std::streambuf &, const void *)> &code) const = 0;
    virtual void Find(const std::string &path, const Functor<void (const std::string &)> &code, const Functor<void (const std::string &, const Functor<std::string ()> &)> &link) const = 0;
};

class DiskFolder :
    public Folder
{
  private:
    const std::string path_;
    std::map<std::string, std::string> commit_;

    std::string Path(const std::string &path) const;

    void Find(const std::string &root, const std::string &base, const Functor<void (const std::string &)> &code, const Functor<void (const std::string &, const Functor<std::string ()> &)> &link) const;

  public:
    DiskFolder(const std::string &path);
    ~DiskFolder();

    virtual void Save(const std::string &path, bool edit, const void *flag, const Functor<void (std::streambuf &)> &code);
    virtual bool Look(const std::string &path) const;
    virtual void Open(const std::string &path, const Functor<void (std::streambuf &, const void *)> &code) const;
    virtual void Find(const std::string &path, const Functor<void (const std::string &)> &code, const Functor<void (const std::string &, const Functor<std::string ()> &)> &link) const;
};

class SubFolder :
    public Folder
{
  private:
    Folder &parent_;
    std::string path_;

  public:
    SubFolder(Folder &parent, const std::string &path);

    virtual void Save(const std::string &path, bool edit, const void *flag, const Functor<void (std::streambuf &)> &code);
    virtual bool Look(const std::string &path) const;
    virtual void Open(const std::string &path, const Functor<void (std::streambuf &, const void *)> &code) const;
    virtual void Find(const std::string &path, const Functor<void (const std::string &)> &code, const Functor<void (const std::string &, const Functor<std::string ()> &)> &link) const;
};

class UnionFolder :
    public Folder
{
  private:
    class StringBuffer :
        public std::stringbuf
    {
      public:
        StringBuffer() {
        }

        StringBuffer(const StringBuffer &rhs) :
            std::stringbuf(rhs.str())
        {
        }
    };

    Folder &parent_;
    std::set<std::string> deletes_;

    std::map<std::string, std::string> remaps_;
    mutable std::map<std::string, std::pair<StringBuffer, const void *>> resets_;

    std::string Map(const std::string &path) const;
    void Map(const std::string &path, const Functor<void (const std::string &)> &code, const std::string &file, const Functor<void (const Functor<void (std::streambuf &, const void *)> &)> &save) const;

  public:
    UnionFolder(Folder &parent);

    virtual void Save(const std::string &path, bool edit, const void *flag, const Functor<void (std::streambuf &)> &code);
    virtual bool Look(const std::string &path) const;
    virtual void Open(const std::string &path, const Functor<void (std::streambuf &, const void *)> &code) const;
    virtual void Find(const std::string &path, const Functor<void (const std::string &)> &code, const Functor<void (const std::string &, const Functor<std::string ()> &)> &link) const;

    void operator ()(const std::string &from) {
        deletes_.insert(from);
    }

    void operator ()(const std::string &from, const std::string &to) {
        operator ()(from);
        remaps_[to] = from;
    }

    std::stringbuf &operator ()(const std::string &from, const void *flag) {
        operator ()(from);
        auto &reset(resets_[from]);
        reset.second = flag;
        return reset.first;
    }
};

struct Bundle {
    std::string path;
    std::vector<char> hash;
};

Bundle Sign(const std::string &root, Folder &folder, const std::string &key, const std::string &requirement, const Functor<std::string (const std::string &, const std::string &)> &alter);

typedef std::map<uint32_t, std::vector<char>> Slots;

std::vector<char> Sign(const void *idata, size_t isize, std::streambuf &output, const std::string &identifier, const std::string &entitlements, const std::string &requirement, const std::string &key, const Slots &slots);

}

#endif//LDID_HPP
<commit_msg>We need Path in DiskFolder subclass to forge flag.<commit_after>#ifndef LDID_HPP
#define LDID_HPP

#include <cstdlib>
#include <map>
#include <set>
#include <sstream>
#include <streambuf>
#include <string>
#include <vector>

namespace ldid {

// I wish Apple cared about providing quality toolchains :/

template <typename Function_>
class Functor;

template <typename Type_, typename... Args_>
class Functor<Type_ (Args_...)> {
  public:
    virtual Type_ operator ()(Args_... args) const = 0;
};

template <typename Function_>
class FunctorImpl;

template <typename Value_, typename Type_, typename... Args_>
class FunctorImpl<Type_ (Value_::*)(Args_...) const> :
    public Functor<Type_ (Args_...)>
{
  private:
    const Value_ *value_;

  public:
    FunctorImpl(const Value_ &value) :
        value_(&value)
    {
    }

    virtual Type_ operator ()(Args_... args) const {
        return (*value_)(args...);
    }
};

template <typename Function_>
FunctorImpl<decltype(&Function_::operator())> fun(const Function_ &value) {
    return value;
}

class Folder {
  public:
    virtual void Save(const std::string &path, bool edit, const void *flag, const Functor<void (std::streambuf &)> &code) = 0;
    virtual bool Look(const std::string &path) const = 0;
    virtual void Open(const std::string &path, const Functor<void (std::streambuf &, const void *)> &code) const = 0;
    virtual void Find(const std::string &path, const Functor<void (const std::string &)> &code, const Functor<void (const std::string &, const Functor<std::string ()> &)> &link) const = 0;
};

class DiskFolder :
    public Folder
{
  private:
    const std::string path_;
    std::map<std::string, std::string> commit_;

  protected:
    std::string Path(const std::string &path) const;

  private:
    void Find(const std::string &root, const std::string &base, const Functor<void (const std::string &)> &code, const Functor<void (const std::string &, const Functor<std::string ()> &)> &link) const;

  public:
    DiskFolder(const std::string &path);
    ~DiskFolder();

    virtual void Save(const std::string &path, bool edit, const void *flag, const Functor<void (std::streambuf &)> &code);
    virtual bool Look(const std::string &path) const;
    virtual void Open(const std::string &path, const Functor<void (std::streambuf &, const void *)> &code) const;
    virtual void Find(const std::string &path, const Functor<void (const std::string &)> &code, const Functor<void (const std::string &, const Functor<std::string ()> &)> &link) const;
};

class SubFolder :
    public Folder
{
  private:
    Folder &parent_;
    std::string path_;

  public:
    SubFolder(Folder &parent, const std::string &path);

    virtual void Save(const std::string &path, bool edit, const void *flag, const Functor<void (std::streambuf &)> &code);
    virtual bool Look(const std::string &path) const;
    virtual void Open(const std::string &path, const Functor<void (std::streambuf &, const void *)> &code) const;
    virtual void Find(const std::string &path, const Functor<void (const std::string &)> &code, const Functor<void (const std::string &, const Functor<std::string ()> &)> &link) const;
};

class UnionFolder :
    public Folder
{
  private:
    class StringBuffer :
        public std::stringbuf
    {
      public:
        StringBuffer() {
        }

        StringBuffer(const StringBuffer &rhs) :
            std::stringbuf(rhs.str())
        {
        }
    };

    Folder &parent_;
    std::set<std::string> deletes_;

    std::map<std::string, std::string> remaps_;
    mutable std::map<std::string, std::pair<StringBuffer, const void *>> resets_;

    std::string Map(const std::string &path) const;
    void Map(const std::string &path, const Functor<void (const std::string &)> &code, const std::string &file, const Functor<void (const Functor<void (std::streambuf &, const void *)> &)> &save) const;

  public:
    UnionFolder(Folder &parent);

    virtual void Save(const std::string &path, bool edit, const void *flag, const Functor<void (std::streambuf &)> &code);
    virtual bool Look(const std::string &path) const;
    virtual void Open(const std::string &path, const Functor<void (std::streambuf &, const void *)> &code) const;
    virtual void Find(const std::string &path, const Functor<void (const std::string &)> &code, const Functor<void (const std::string &, const Functor<std::string ()> &)> &link) const;

    void operator ()(const std::string &from) {
        deletes_.insert(from);
    }

    void operator ()(const std::string &from, const std::string &to) {
        operator ()(from);
        remaps_[to] = from;
    }

    std::stringbuf &operator ()(const std::string &from, const void *flag) {
        operator ()(from);
        auto &reset(resets_[from]);
        reset.second = flag;
        return reset.first;
    }
};

struct Bundle {
    std::string path;
    std::vector<char> hash;
};

Bundle Sign(const std::string &root, Folder &folder, const std::string &key, const std::string &requirement, const Functor<std::string (const std::string &, const std::string &)> &alter);

typedef std::map<uint32_t, std::vector<char>> Slots;

std::vector<char> Sign(const void *idata, size_t isize, std::streambuf &output, const std::string &identifier, const std::string &entitlements, const std::string &requirement, const std::string &key, const Slots &slots);

}

#endif//LDID_HPP
<|endoftext|>


<commit_before>
#include "Context.h"
#include <GL/glew.h>

#include "Utilities.h"

namespace ion
{
	namespace GL
	{
		void Context::Init()
		{
			CheckedGLCall(glEnable(GL_DEPTH_TEST));
			CheckedGLCall(glDepthFunc(GL_LEQUAL));

			CheckedGLCall(glEnable(GL_TEXTURE_2D));
		}

		void Context::Clear(std::initializer_list<EBuffer> Buffers)
		{
			static u32 const BufferLookup[3] =
			{
				GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT
			};
			int BitMask = 0;
			for (auto Buffer : Buffers)
				BitMask |= BufferLookup[(int) Buffer];
			CheckedGLCall(glClear(BitMask));
		}

		vec2i Context::GetViewportSize()
		{
			int viewport[4];
			CheckedGLCall(glGetIntegerv(GL_VIEWPORT, viewport));

			return vec2i(viewport[2] - viewport[0], viewport[3] - viewport[1]);
		}
	}
}
<commit_msg>Fix GL::Context setup (no texture enabling needed?)<commit_after>
#include "Context.h"
#include <GL/glew.h>

#include "Utilities.h"

namespace ion
{
	namespace GL
	{
		void Context::Init()
		{
			CheckedGLCall(glEnable(GL_DEPTH_TEST));
			CheckedGLCall(glDepthFunc(GL_LEQUAL));
		}

		void Context::Clear(std::initializer_list<EBuffer> Buffers)
		{
			static u32 const BufferLookup[3] =
			{
				GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT
			};
			int BitMask = 0;
			for (auto Buffer : Buffers)
				BitMask |= BufferLookup[(int) Buffer];
			CheckedGLCall(glClear(BitMask));
		}

		vec2i Context::GetViewportSize()
		{
			int viewport[4];
			CheckedGLCall(glGetIntegerv(GL_VIEWPORT, viewport));

			return vec2i(viewport[2] - viewport[0], viewport[3] - viewport[1]);
		}
	}
}
<|endoftext|>


<commit_before>#include "runtime_internal.h"
#include "HalideRuntimeQurt.h"
#include "printer.h"
#include "qurt.h"

using namespace Halide::Runtime::Internal::Qurt;

extern "C" {

enum qurt_hvx_mode_t {
    QURT_HVX_MODE_64B = 0,
    QURT_HVX_MODE_128B = 1,
};

extern int qurt_hvx_lock(qurt_hvx_mode_t);
extern int qurt_hvx_unlock();

WEAK int halide_qurt_hvx_lock(void *user_context, int size) {
    qurt_hvx_mode_t mode;
    switch (size) {
    case 64: mode = QURT_HVX_MODE_64B; break;
    case 128: mode = QURT_HVX_MODE_128B; break;
    default:
        error(user_context) << "HVX lock size must be 64 or 128.\n";
        return -1;
    }

    debug(user_context) << "QuRT: qurt_hvx_lock(" << mode << ") ->\n";
    int result = qurt_hvx_lock(mode);
    debug(user_context) << "        " << result;
    if (result != QURT_EOK) {
        error(user_context) << "qurt_hvx_lock failed\n";
        return -1;
    }

    return 0;
}

WEAK int halide_qurt_hvx_unlock(void *user_context) {
    debug(user_context) << "QuRT: qurt_hvx_unlock ->\n";
    int result = qurt_hvx_unlock();
    debug(user_context) << "        " << result;
    if (result != QURT_EOK) {
        error(user_context) << "qurt_hvx_unlock failed\n";
        return -1;
    }

    return 0;
}

WEAK void halide_qurt_hvx_unlock_as_destructor(void *user_context, void * /*obj*/) {
    halide_qurt_hvx_unlock(user_context);
}

}
<commit_msg>Fix badly formatted output.<commit_after>#include "runtime_internal.h"
#include "HalideRuntimeQurt.h"
#include "printer.h"
#include "qurt.h"

using namespace Halide::Runtime::Internal::Qurt;

extern "C" {

enum qurt_hvx_mode_t {
    QURT_HVX_MODE_64B = 0,
    QURT_HVX_MODE_128B = 1,
};

extern int qurt_hvx_lock(qurt_hvx_mode_t);
extern int qurt_hvx_unlock();

WEAK int halide_qurt_hvx_lock(void *user_context, int size) {
    qurt_hvx_mode_t mode;
    switch (size) {
    case 64: mode = QURT_HVX_MODE_64B; break;
    case 128: mode = QURT_HVX_MODE_128B; break;
    default:
        error(user_context) << "HVX lock size must be 64 or 128.\n";
        return -1;
    }

    debug(user_context) << "QuRT: qurt_hvx_lock(" << mode << ") ->\n";
    int result = qurt_hvx_lock(mode);
    debug(user_context) << "        " << result << "\n";
    if (result != QURT_EOK) {
        error(user_context) << "qurt_hvx_lock failed\n";
        return -1;
    }

    return 0;
}

WEAK int halide_qurt_hvx_unlock(void *user_context) {
    debug(user_context) << "QuRT: qurt_hvx_unlock ->\n";
    int result = qurt_hvx_unlock();
    debug(user_context) << "        " << result << "\n";
    if (result != QURT_EOK) {
        error(user_context) << "qurt_hvx_unlock failed\n";
        return -1;
    }

    return 0;
}

WEAK void halide_qurt_hvx_unlock_as_destructor(void *user_context, void * /*obj*/) {
    halide_qurt_hvx_unlock(user_context);
}

}
<|endoftext|>


<commit_before>// @(#)root/hist:$Id$
// Author: Rene Brun   14/07/2009

/*************************************************************************
 * Copyright (C) 1995-2009, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "TGraphTime.h"
#include "TROOT.h"
#include "TVirtualPad.h"
#include "TH1.h"
#include "TText.h"
#include "TObjArray.h"
#include "TSystem.h"

ClassImp(TGraphTime)

//______________________________________________________________________________
//
// TGraphTime is used to draw a set of objects evolving with nsteps in time between tmin and tmax.
// each time step has a new list of objects. This list can be identical to
// the list of objects in the previous steps, but with different attributes.
//   see example of use in $ROOTSYS/tutorials/graphs/gtime.C

//______________________________________________________________________________
TGraphTime::TGraphTime(): TNamed()
{
   // Marker default constructor.

   fSleepTime = 0;
   fNsteps    = 0;
   fXmin      = 0;
   fXmax      = 1;
   fYmin      = 0;
   fYmax      = 1;
   fSteps     = 0;
   fFrame     = 0;
}

//______________________________________________________________________________
TGraphTime::TGraphTime(Int_t nsteps, Double_t xmin, Double_t ymin, Double_t xmax, Double_t ymax)
      :TNamed()
{
   // Create a TGraphTime with nsteps in range [xmin,xmax][ymin,ymax]

   if (nsteps <= 0) {
      Warning("TGraphTime", "Number of steps %d changed to 100",nsteps);
      nsteps = 100;
   }
   fSleepTime = 0;
   fNsteps    = nsteps;
   fXmin      = xmin;
   fXmax      = xmax;
   fYmin      = ymin;
   fYmax      = ymax;
   fSteps     = new TObjArray(nsteps+1);
   fFrame     = new TH1D("frame","",100,fXmin,fXmax);
   fFrame->SetMinimum(ymin);
   fFrame->SetMaximum(ymax);
   fFrame->SetStats(0);
}

//______________________________________________________________________________
TGraphTime::~TGraphTime()
{
   // GraphTime default destructor.

   if (!fSteps) return;
   fSteps->Delete();
   delete fSteps; fSteps=0;
}

//______________________________________________________________________________
TGraphTime::TGraphTime(const TGraphTime &gtime) : TNamed(gtime)
{
   // copy constructor.

   fSleepTime = gtime.fSleepTime;
   fNsteps    = gtime.fNsteps;
   fXmin      = gtime.fXmin;
   fXmax      = gtime.fXmax;
   fYmin      = gtime.fYmin;
   fYmax      = gtime.fYmax;
   fSteps     = new TObjArray(fNsteps+1);
   fFrame     = new TH1D("frame","",100,fXmin,fXmax);
   fFrame->SetMinimum(fYmin);
   fFrame->SetMaximum(fYmax);
   fFrame->SetStats(0);
}

//______________________________________________________________________________
Int_t TGraphTime::Add(const TObject *obj, Int_t slot)
{
   // Add one object to a time slot.
   // TGraphTime becomes the owner of this object.

   if (!fSteps) {
      fNsteps = 100;
      fSteps = new TObjArray(fNsteps+1);
   }
   if (slot < 0 || slot >= fNsteps) return -1;
   TList *list = (TList*)fSteps->UncheckedAt(slot);
   if (!list) {
      list = new TList();
      fSteps->AddAt(list,slot);
   }
   list->Add((TObject*)obj);
   return slot;
}

//______________________________________________________________________________
void TGraphTime::Draw(Option_t *option)
{
   // Draw this TGraphTime with its current attributes.
   // if option "time" is specified the current time value is drawn at
   //  the top right corner

   if (!gPad) {
      gROOT->MakeDefCanvas();
      gPad->SetFillColor(41);
      gPad->SetFrameFillColor(19);
      gPad->SetGrid();
   }
   if (fFrame) fFrame->Draw();
   Paint(option);

}

//______________________________________________________________________________
void TGraphTime::Paint(Option_t *option)
{
   // Paint this marker with its current attributes.

   TString opt = option;
   opt.ToLower();
   TObject *frame = gPad->GetPrimitive("frame");
   TList *list = 0;
   TText *text = 0;
   if (opt.Contains("time")) {
      text = new TText();
      text->SetNDC();
      text->SetTextSize(0.05);
      text->SetTextAlign(23);
   }

   for (Int_t s=0;s<fNsteps;s++) {
      list = (TList*)fSteps->UncheckedAt(s);
      if (list) {
         gPad->GetListOfPrimitives()->Remove(frame);
         gPad->GetListOfPrimitives()->Clear();
         if (frame) gPad->GetListOfPrimitives()->Add(frame);
         list->Draw("");
         if (text) text->DrawText(.94,.98,Form("%d",s));
         gPad->Update();
         if (fSleepTime > 0) gSystem->Sleep(fSleepTime);
      }
   }
   delete text;
}
<commit_msg>Temporarely disable option "time" to avoid a dependency of libPad on Windows.<commit_after>// @(#)root/hist:$Id$
// Author: Rene Brun   14/07/2009

/*************************************************************************
 * Copyright (C) 1995-2009, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "TGraphTime.h"
#include "TROOT.h"
#include "TVirtualPad.h"
#include "TH1.h"
//#include "TText.h"
#include "TObjArray.h"
#include "TSystem.h"

ClassImp(TGraphTime)

//______________________________________________________________________________
//
// TGraphTime is used to draw a set of objects evolving with nsteps in time between tmin and tmax.
// each time step has a new list of objects. This list can be identical to
// the list of objects in the previous steps, but with different attributes.
//   see example of use in $ROOTSYS/tutorials/graphs/gtime.C

//______________________________________________________________________________
TGraphTime::TGraphTime(): TNamed()
{
   // Marker default constructor.

   fSleepTime = 0;
   fNsteps    = 0;
   fXmin      = 0;
   fXmax      = 1;
   fYmin      = 0;
   fYmax      = 1;
   fSteps     = 0;
   fFrame     = 0;
}

//______________________________________________________________________________
TGraphTime::TGraphTime(Int_t nsteps, Double_t xmin, Double_t ymin, Double_t xmax, Double_t ymax)
      :TNamed()
{
   // Create a TGraphTime with nsteps in range [xmin,xmax][ymin,ymax]

   if (nsteps <= 0) {
      Warning("TGraphTime", "Number of steps %d changed to 100",nsteps);
      nsteps = 100;
   }
   fSleepTime = 0;
   fNsteps    = nsteps;
   fXmin      = xmin;
   fXmax      = xmax;
   fYmin      = ymin;
   fYmax      = ymax;
   fSteps     = new TObjArray(nsteps+1);
   fFrame     = new TH1D("frame","",100,fXmin,fXmax);
   fFrame->SetMinimum(ymin);
   fFrame->SetMaximum(ymax);
   fFrame->SetStats(0);
}

//______________________________________________________________________________
TGraphTime::~TGraphTime()
{
   // GraphTime default destructor.

   if (!fSteps) return;
   fSteps->Delete();
   delete fSteps; fSteps=0;
}

//______________________________________________________________________________
TGraphTime::TGraphTime(const TGraphTime &gtime) : TNamed(gtime)
{
   // copy constructor.

   fSleepTime = gtime.fSleepTime;
   fNsteps    = gtime.fNsteps;
   fXmin      = gtime.fXmin;
   fXmax      = gtime.fXmax;
   fYmin      = gtime.fYmin;
   fYmax      = gtime.fYmax;
   fSteps     = new TObjArray(fNsteps+1);
   fFrame     = new TH1D("frame","",100,fXmin,fXmax);
   fFrame->SetMinimum(fYmin);
   fFrame->SetMaximum(fYmax);
   fFrame->SetStats(0);
}

//______________________________________________________________________________
Int_t TGraphTime::Add(const TObject *obj, Int_t slot)
{
   // Add one object to a time slot.
   // TGraphTime becomes the owner of this object.

   if (!fSteps) {
      fNsteps = 100;
      fSteps = new TObjArray(fNsteps+1);
   }
   if (slot < 0 || slot >= fNsteps) return -1;
   TList *list = (TList*)fSteps->UncheckedAt(slot);
   if (!list) {
      list = new TList();
      fSteps->AddAt(list,slot);
   }
   list->Add((TObject*)obj);
   return slot;
}

//______________________________________________________________________________
void TGraphTime::Draw(Option_t *option)
{
   // Draw this TGraphTime with its current attributes.
   // if option "time" is specified the current time value is drawn at
   //  the top right corner

   if (!gPad) {
      gROOT->MakeDefCanvas();
      gPad->SetFillColor(41);
      gPad->SetFrameFillColor(19);
      gPad->SetGrid();
   }
   if (fFrame) fFrame->Draw();
   Paint(option);

}

//______________________________________________________________________________
void TGraphTime::Paint(Option_t *option)
{
   // Paint this marker with its current attributes.

   TString opt = option;
   opt.ToLower();
   TObject *frame = gPad->GetPrimitive("frame");
   TList *list = 0;
   //TText *text = 0;
   //if (opt.Contains("time")) {
   //   text = new TText();
   //   text->SetNDC();
   //   text->SetTextSize(0.05);
   //   text->SetTextAlign(23);
   //}

   for (Int_t s=0;s<fNsteps;s++) {
      list = (TList*)fSteps->UncheckedAt(s);
      if (list) {
         gPad->GetListOfPrimitives()->Remove(frame);
         gPad->GetListOfPrimitives()->Clear();
         if (frame) gPad->GetListOfPrimitives()->Add(frame);
         list->Draw("");
         //if (text) text->DrawText(.94,.98,Form("%d",s));
         gPad->Update();
         if (fSleepTime > 0) gSystem->Sleep(fSleepTime);
      }
   }
   //delete text;
}
<|endoftext|>


<commit_before>#include <cerrno>
#include <sys/resource.h>
#include <fcntl.h>

#include "fdcache.h"
#include "log.h"
#include "failure.h"
#include "tools.h"

#define NOFILE_MAX 4096
#define NOFILE_RESERVE 64

/* Determine the system limit on open file descriptors */
static int get_max_open_files() {
    int limit = 0;
    struct rlimit nofile;
    if (getrlimit(RLIMIT_NOFILE, &nofile)) {
        log_error("Unable to get NOFILE limit: %s", strerror(errno));
    } else {
        // It shouldn't be bigger than _SC_OPEN_MAX
        long open_max = sysconf(_SC_OPEN_MAX);
        limit = nofile.rlim_cur > open_max ? open_max : nofile.rlim_cur;
    }
    // Returns 0 if there was a problem
    return limit;
}

/* Get the number of open file descriptors */
static int get_nr_open_fds() {
    // Save this so that we don't lose the original error
    int saverr = errno;

    int limit = get_max_open_files();

    int fd;
    int openfds = 0;
    for (fd=0; fd<=limit; fd++) {
        // If this returns -1, then the fd is not valid
        // Otherwise, it is valid
        if (fcntl(fd, F_GETFD, 0) != -1) {
            openfds++;
        }
    }

    // Restore the error
    errno = saverr;

    return openfds;
}

FDEntry::FDEntry(const string &filename, FILE *file) {
    this->filename = filename;
    this->file = file;
    this->prev = NULL;
    this->next = NULL;
}

FDEntry::~FDEntry() {
    if (this->file != NULL) {
        fclose(this->file);
        this->file = NULL;
    }
}

FDCache::FDCache(unsigned maxsize) {
    this->maxsize = maxsize;
    this->first = NULL;
    this->last = NULL;
    this->hits = 0;
    this->misses = 0;

    // Determine the system limit
    int limit = get_max_open_files();
    log_debug("Open files limit = %d", limit);

    // Log the number of currently open files
    if (log_debug()) {
        log_debug("Number of open files = %d", get_nr_open_fds());
    }

    // Determine the maximum number of open files allowed
    if (maxsize == 0) {
        if (limit < 0) {
            // If there is no limit, then allow the max
            this->maxsize = NOFILE_MAX;
        } else if (limit == 0) {
            // If we couldn't find the limit, then the default is 64
            this->maxsize = 64;
        } else if (limit > NOFILE_MAX) {
            // No more than the max
            this->maxsize = NOFILE_MAX;
        } else {
            // In this case we reserve descriptors for other parts of the system
            // In the worst case we require at least 1 open descriptor
            this->maxsize = limit-NOFILE_RESERVE < 1 ? 1 : limit-NOFILE_RESERVE;
        }
    } else if (maxsize > limit) {
        myfailure("Setting for max cached files is greater than system limit:"
                  " %d > %d", maxsize, limit);
    }

    log_info("Setting max cached files = %u", this->maxsize);
}

FDCache::~FDCache() {
    this->close();
}

void FDCache::close() {
    FDEntry *i = first;
    while (i!=NULL) {
        FDEntry *next = i->next;
        delete i;
        i = next;
    }
    byname.clear();
    first = NULL;
    last = NULL;
}

int FDCache::size() {
    return this->byname.size();
}

double FDCache::hitrate() {
    double total = this->hits + this->misses;
    if (total == 0) {
        return 1.0;
    }
    return this->hits / total;
}

void FDCache::access(FDEntry *entry) {
    if (first == entry) {
        return;
    }

    // Make sure it is a valid request
    if (byname.size() == 0) {
        myfailure("Empty list");
    }
    if (entry == NULL) {
        myfailure("Invalid entry");
        return; /* Silence static analyzer */
    }
    if (entry->prev && entry->prev->next != entry) {
        myfailure("Entry not in list");
    }
    if (entry->next && entry->next->prev != entry) {
        myfailure("Entry not in list");
    }

    // If it is last, we need to update the last pointer
    if (last == entry) {
        last = entry->prev;
    }

    if (entry->prev) {
        entry->prev->next = entry->next;
    }
    if (entry->next) {
        entry->next->prev = entry->prev;
    }

    entry->prev = NULL;
    entry->next = first;
    first->prev = entry;
    first = entry;
}

void FDCache::push(FDEntry *entry) {
    // If there are too many descriptors in the cache,
    // then remove some
    while (this->byname.size() >= this->maxsize) {
        FDEntry *remove = this->pop();
        if (remove == NULL) {
            myfailure("Expected an entry");
        }
        delete remove;
    }

    if (last == NULL) {
        last = entry;
    }
    entry->next = first;
    entry->prev = NULL;
    if (first != NULL) {
        first->prev = entry;
    }
    first = entry;
    byname[entry->filename] = entry;

    log_trace("Adding %s to FDCache", entry->filename.c_str());
}

FDEntry *FDCache::pop() {
    if (last == NULL) {
        return NULL;
    }

    FDEntry *remove = last;

    byname.erase(last->filename);

    if (first == last) {
        // If it is the last one, then
        // the list is empty
        first = NULL;
        last = NULL;
    } else {
        last = last->prev;
        last->next = NULL;
    }

    log_trace("Evicting %s from FDCache", remove->filename.c_str());

    return remove;
}

FILE *FDCache::open(string filename) {
    // If the file is already in the cache, then
    // return it
    map<string, FDEntry *>::iterator i;
    i = byname.find(filename);
    if (i == byname.end()) {
        this->misses += 1;
    } else {
        this->hits += 1;
        FDEntry *entry = i->second;
        access(entry);
        return entry->file;
    }

    // Create directories as needed on file creation
    if (filename.find("/") != string::npos) {
        string path = filename.substr(0, filename.rfind("/"));
        if (mkdirs(path.c_str()) < 0) {
            log_error("Unable to create directory %s: %s", path.c_str(),
                    strerror(errno));
            return NULL;
        }
    }

    // We always open the file for append because this may be one of many
    // records we need to write to the file
    FILE *file = fopen(filename.c_str(), "a");
    if (file == NULL) {
        return NULL;
    }

    FDEntry *entry = new FDEntry(filename, file);
    push(entry);

    return file;
}

int FDCache::write(string filename, const char *data, int size) {
    FILE *file = open(filename);
    if (file == NULL) {
        log_error("Error opening file %s: %s", filename.c_str(),
                strerror(errno));

        if (errno == ENFILE || errno == EMFILE) {
            // If it failed because the fd limit was exceeded,
            // then log how many we have open to see if it was
            // us causing the problem.
            log_error("Number of open files: %d", get_nr_open_fds());
        }

        return -1;
    }

    int rc = fwrite(data, 1, size, file);
    if (rc != size) {
        log_error("Error writing %d bytes to %s: %s", size, filename.c_str(),
                strerror(errno));
        return -1;
    }
    if (fflush(file) != 0) {
        log_error("fflush failed on file %s: %s", filename.c_str(),
                strerror(errno));
        return -1;
    }
#ifdef SYNC_IODATA
#ifdef DARWIN
    // OSX does not have fdatasync
    rc = fsync(fileno(file));
#else
    rc = fdatasync(fileno(file));
#endif
    if (rc != 0) {
        log_error("fsync/fdatasync failed on file %s: %s", filename.c_str(),
                strerror(errno));
        return -1;
    }
#endif
    return 0;
}

<commit_msg>PMC: Clean up warnings<commit_after>#include <cerrno>
#include <sys/resource.h>
#include <fcntl.h>

#include "fdcache.h"
#include "log.h"
#include "failure.h"
#include "tools.h"

#define NOFILE_MAX 4096
#define NOFILE_RESERVE 64

/* Determine the system limit on open file descriptors */
static unsigned get_max_open_files() {
    unsigned limit = 0;
    struct rlimit nofile;
    if (getrlimit(RLIMIT_NOFILE, &nofile)) {
        log_error("Unable to get NOFILE limit: %s", strerror(errno));
    } else {
        limit = nofile.rlim_cur;

        // It shouldn't be bigger than _SC_OPEN_MAX
        long open_max = sysconf(_SC_OPEN_MAX);
        if (limit > open_max) {
            limit = open_max;
        }
    }
    // Returns 0 if there was a problem
    return limit;
}

/* Get the number of open file descriptors */
static unsigned get_nr_open_fds() {
    // Save this so that we don't lose the original error
    int saverr = errno;

    unsigned limit = get_max_open_files();

    unsigned fd;
    unsigned openfds = 0;
    for (fd=0; fd<=limit; fd++) {
        // If this returns -1, then the fd is not valid
        // Otherwise, it is valid
        if (fcntl(fd, F_GETFD, 0) != -1) {
            openfds++;
        }
    }

    // Restore the error
    errno = saverr;

    return openfds;
}

FDEntry::FDEntry(const string &filename, FILE *file) {
    this->filename = filename;
    this->file = file;
    this->prev = NULL;
    this->next = NULL;
}

FDEntry::~FDEntry() {
    if (this->file != NULL) {
        fclose(this->file);
        this->file = NULL;
    }
}

FDCache::FDCache(unsigned maxsize) {
    this->maxsize = maxsize;
    this->first = NULL;
    this->last = NULL;
    this->hits = 0;
    this->misses = 0;

    // Determine the system limit
    unsigned limit = get_max_open_files();
    log_debug("Open files limit = %u", limit);

    // Log the number of currently open files
    if (log_debug()) {
        log_debug("Number of open files = %u", get_nr_open_fds());
    }

    // Determine the maximum number of open files allowed
    if (maxsize == 0) {
        if (limit < 0) {
            // If there is no limit, then allow the max
            this->maxsize = NOFILE_MAX;
        } else if (limit == 0) {
            // If we couldn't find the limit, then the default is 64
            this->maxsize = 64;
        } else if (limit > NOFILE_MAX) {
            // No more than the max
            this->maxsize = NOFILE_MAX;
        } else {
            // In this case we reserve descriptors for other parts of the system
            // In the worst case we require at least 1 open descriptor
            this->maxsize = limit-NOFILE_RESERVE < 1 ? 1 : limit-NOFILE_RESERVE;
        }
    } else if (maxsize > limit) {
        myfailure("Setting for max cached files is greater than system limit:"
                  " %d > %d", maxsize, limit);
    }

    log_info("Setting max cached files = %u", this->maxsize);
}

FDCache::~FDCache() {
    this->close();
}

void FDCache::close() {
    FDEntry *i = first;
    while (i!=NULL) {
        FDEntry *next = i->next;
        delete i;
        i = next;
    }
    byname.clear();
    first = NULL;
    last = NULL;
}

int FDCache::size() {
    return this->byname.size();
}

double FDCache::hitrate() {
    double total = this->hits + this->misses;
    if (total == 0) {
        return 1.0;
    }
    return this->hits / total;
}

void FDCache::access(FDEntry *entry) {
    if (first == entry) {
        return;
    }

    // Make sure it is a valid request
    if (byname.size() == 0) {
        myfailure("Empty list");
    }
    if (entry == NULL) {
        myfailure("Invalid entry");
        return; /* Silence static analyzer */
    }
    if (entry->prev && entry->prev->next != entry) {
        myfailure("Entry not in list");
    }
    if (entry->next && entry->next->prev != entry) {
        myfailure("Entry not in list");
    }

    // If it is last, we need to update the last pointer
    if (last == entry) {
        last = entry->prev;
    }

    if (entry->prev) {
        entry->prev->next = entry->next;
    }
    if (entry->next) {
        entry->next->prev = entry->prev;
    }

    entry->prev = NULL;
    entry->next = first;
    first->prev = entry;
    first = entry;
}

void FDCache::push(FDEntry *entry) {
    // If there are too many descriptors in the cache,
    // then remove some
    while (this->byname.size() >= this->maxsize) {
        FDEntry *remove = this->pop();
        if (remove == NULL) {
            myfailure("Expected an entry");
        }
        delete remove;
    }

    if (last == NULL) {
        last = entry;
    }
    entry->next = first;
    entry->prev = NULL;
    if (first != NULL) {
        first->prev = entry;
    }
    first = entry;
    byname[entry->filename] = entry;

    log_trace("Adding %s to FDCache", entry->filename.c_str());
}

FDEntry *FDCache::pop() {
    if (last == NULL) {
        return NULL;
    }

    FDEntry *remove = last;

    byname.erase(last->filename);

    if (first == last) {
        // If it is the last one, then
        // the list is empty
        first = NULL;
        last = NULL;
    } else {
        last = last->prev;
        last->next = NULL;
    }

    log_trace("Evicting %s from FDCache", remove->filename.c_str());

    return remove;
}

FILE *FDCache::open(string filename) {
    // If the file is already in the cache, then
    // return it
    map<string, FDEntry *>::iterator i;
    i = byname.find(filename);
    if (i == byname.end()) {
        this->misses += 1;
    } else {
        this->hits += 1;
        FDEntry *entry = i->second;
        access(entry);
        return entry->file;
    }

    // Create directories as needed on file creation
    if (filename.find("/") != string::npos) {
        string path = filename.substr(0, filename.rfind("/"));
        if (mkdirs(path.c_str()) < 0) {
            log_error("Unable to create directory %s: %s", path.c_str(),
                    strerror(errno));
            return NULL;
        }
    }

    // We always open the file for append because this may be one of many
    // records we need to write to the file
    FILE *file = fopen(filename.c_str(), "a");
    if (file == NULL) {
        return NULL;
    }

    FDEntry *entry = new FDEntry(filename, file);
    push(entry);

    return file;
}

int FDCache::write(string filename, const char *data, int size) {
    FILE *file = open(filename);
    if (file == NULL) {
        log_error("Error opening file %s: %s", filename.c_str(),
                strerror(errno));

        if (errno == ENFILE || errno == EMFILE) {
            // If it failed because the fd limit was exceeded,
            // then log how many we have open to see if it was
            // us causing the problem.
            log_error("Number of open files: %u", get_nr_open_fds());
        }

        return -1;
    }

    int rc = fwrite(data, 1, size, file);
    if (rc != size) {
        log_error("Error writing %d bytes to %s: %s", size, filename.c_str(),
                strerror(errno));
        return -1;
    }
    if (fflush(file) != 0) {
        log_error("fflush failed on file %s: %s", filename.c_str(),
                strerror(errno));
        return -1;
    }
#ifdef SYNC_IODATA
#ifdef DARWIN
    // OSX does not have fdatasync
    rc = fsync(fileno(file));
#else
    rc = fdatasync(fileno(file));
#endif
    if (rc != 0) {
        log_error("fsync/fdatasync failed on file %s: %s", filename.c_str(),
                strerror(errno));
        return -1;
    }
#endif
    return 0;
}

<|endoftext|>


<commit_before>#include <pybind11/pybind11.h>

#include <avogadro/core/cube.h>
#include <avogadro/core/gaussiansettools.h>
#include <avogadro/core/molecule.h>

namespace py = pybind11;

using namespace Avogadro;
using namespace Avogadro::Core;

PYBIND11_MODULE(core, m)
{
  m.doc() = "AvogadroCore Python binding";

  using atomBase = AtomTemplate<Molecule>;
  py::class_<atomBase>(m, "atomBase");
  py::class_<Atom, atomBase>(m, "Atom")
    .def_property_readonly("index", &Atom::index, "Index in the molecule")
    .def_property("atomic_number", &Atom::atomicNumber, &Atom::setAtomicNumber,
                  "The atomic number")
    .def("is_valid", &Atom::isValid, "Check if the object is valid");

  using bondBase = BondTemplate<Molecule>;
  py::class_<bondBase>(m, "bondBase");
  py::class_<Bond, bondBase>(m, "Bond")
    .def_property_readonly("index", &Bond::index, "Index in the molecule")
    .def_property("order", &Bond::order, &Bond::setOrder,
                  "The order of the bond (single = 1, double = 2, etc")
    .def("is_valid", &Bond::isValid, "Check if the object is valid")
    .def("atom1", &Bond::atom1, "The first atom")
    .def("atom2", &Bond::atom2, "The second atom");

  bool (Cube::*setLimits0)(const Molecule&, double, double) = &Cube::setLimits;
  py::class_<Cube>(m, "Cube").def(
    "set_limits", setLimits0, "Set the limits based on the molecule geometry");

  Index (Molecule::*atomCount0)() const = &Molecule::atomCount;
  Index (Molecule::*atomCount1)(unsigned char) const = &Molecule::atomCount;
  Bond (Molecule::*addBond1)(Index, Index, unsigned char) = &Molecule::addBond;
  Bond (Molecule::*addBond2)(const Atom&, const Atom&, unsigned char) =
    &Molecule::addBond;

  py::class_<Molecule>(m, "Molecule")
    .def(py::init<>())
    .def("add_atom", &Molecule::addAtom, "Add an atom")
    .def("atom_count", atomCount0, "The number of atoms")
    .def("atom_count", atomCount1,
         "The number of atoms with the supplied atomic number")
    .def("add_bond", addBond1, "Add a new bond", py::arg("a1"), py::arg("a2"),
         py::arg("order") = 1)
    .def("add_bond", addBond2, "Add a new bond", py::arg("a1"), py::arg("a2"),
         py::arg("order") = 1)
    .def("bond_count", &Molecule::bondCount, "The number of bonds")
    .def("add_cube", &Molecule::addCube, py::return_value_policy::reference,
         "Add a new cube")
    .def("cube_count", &Molecule::cubeCount, "The number of cubes")
    .def("has_custom_elements", &Molecule::hasCustomElements,
         "Returns true if the molecule contains any custom elements")
    .def("formula", &Molecule::formula, "The chemical formula of the molecule",
         py::arg("delimiter") = "", py::arg("show_counts_over") = 1)
    .def("mass", &Molecule::mass, "The mass of the molecule");

  bool (GaussianSetTools::*calculateMolecularOrbital0)(Cube&, int) const =
    &GaussianSetTools::calculateMolecularOrbital;
  py::class_<GaussianSetTools>(m, "GaussianSetTools")
    .def(py::init<Molecule*>())
    .def("calculate_molecular_orbital", calculateMolecularOrbital0,
         "Calculate the molecular orbital and set values in the cube");
}
<commit_msg>Expose calculateElectronDensity in the python bindings<commit_after>#include <pybind11/pybind11.h>

#include <avogadro/core/cube.h>
#include <avogadro/core/gaussiansettools.h>
#include <avogadro/core/molecule.h>

namespace py = pybind11;

using namespace Avogadro;
using namespace Avogadro::Core;

PYBIND11_MODULE(core, m)
{
  m.doc() = "AvogadroCore Python binding";

  using atomBase = AtomTemplate<Molecule>;
  py::class_<atomBase>(m, "atomBase");
  py::class_<Atom, atomBase>(m, "Atom")
    .def_property_readonly("index", &Atom::index, "Index in the molecule")
    .def_property("atomic_number", &Atom::atomicNumber, &Atom::setAtomicNumber,
                  "The atomic number")
    .def("is_valid", &Atom::isValid, "Check if the object is valid");

  using bondBase = BondTemplate<Molecule>;
  py::class_<bondBase>(m, "bondBase");
  py::class_<Bond, bondBase>(m, "Bond")
    .def_property_readonly("index", &Bond::index, "Index in the molecule")
    .def_property("order", &Bond::order, &Bond::setOrder,
                  "The order of the bond (single = 1, double = 2, etc")
    .def("is_valid", &Bond::isValid, "Check if the object is valid")
    .def("atom1", &Bond::atom1, "The first atom")
    .def("atom2", &Bond::atom2, "The second atom");

  bool (Cube::*setLimits0)(const Molecule&, double, double) = &Cube::setLimits;
  py::class_<Cube>(m, "Cube").def(
    "set_limits", setLimits0, "Set the limits based on the molecule geometry");

  Index (Molecule::*atomCount0)() const = &Molecule::atomCount;
  Index (Molecule::*atomCount1)(unsigned char) const = &Molecule::atomCount;
  Bond (Molecule::*addBond1)(Index, Index, unsigned char) = &Molecule::addBond;
  Bond (Molecule::*addBond2)(const Atom&, const Atom&, unsigned char) =
    &Molecule::addBond;

  py::class_<Molecule>(m, "Molecule")
    .def(py::init<>())
    .def("add_atom", &Molecule::addAtom, "Add an atom")
    .def("atom_count", atomCount0, "The number of atoms")
    .def("atom_count", atomCount1,
         "The number of atoms with the supplied atomic number")
    .def("add_bond", addBond1, "Add a new bond", py::arg("a1"), py::arg("a2"),
         py::arg("order") = 1)
    .def("add_bond", addBond2, "Add a new bond", py::arg("a1"), py::arg("a2"),
         py::arg("order") = 1)
    .def("bond_count", &Molecule::bondCount, "The number of bonds")
    .def("add_cube", &Molecule::addCube, py::return_value_policy::reference,
         "Add a new cube")
    .def("cube_count", &Molecule::cubeCount, "The number of cubes")
    .def("has_custom_elements", &Molecule::hasCustomElements,
         "Returns true if the molecule contains any custom elements")
    .def("formula", &Molecule::formula, "The chemical formula of the molecule",
         py::arg("delimiter") = "", py::arg("show_counts_over") = 1)
    .def("mass", &Molecule::mass, "The mass of the molecule");

  bool (GaussianSetTools::*calculateMolecularOrbital0)(Cube&, int) const =
    &GaussianSetTools::calculateMolecularOrbital;
  bool (GaussianSetTools::*calculateElectronDensity0)(Cube&) const =
    &GaussianSetTools::calculateElectronDensity;
  bool (GaussianSetTools::*calculateSpinDensity0)(Cube&) const =
    &GaussianSetTools::calculateSpinDensity;
  py::class_<GaussianSetTools>(m, "GaussianSetTools")
    .def(py::init<Molecule*>())
    .def("calculate_molecular_orbital", calculateMolecularOrbital0,
         "Calculate the molecular orbital and set values in the cube")
    .def("calculate_electron_density", calculateElectronDensity0,
         "Calculate the electron density and set values in the cube")
    .def("calculate_spin_density", calculateSpinDensity0,
         "Calculate the spin density and set values in the cube");
}
<|endoftext|>