<commit_before>// This file is a part of the OpenSurgSim project.
// Copyright 2013, SimQuest Solutions Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <memory>
#include <string>

#include "SurgSim/Blocks/BasicSceneElement.h"
#include "SurgSim/Blocks/TransferInputPoseBehavior.h"
#include "SurgSim/Blocks/TransferPoseBehavior.h"
#include "SurgSim/Devices/MultiAxis/MultiAxisDevice.h"
#include "Examples/ExampleStapling/StaplerBehavior.h"
#include "SurgSim/Framework/BehaviorManager.h"
#include "SurgSim/Framework/Runtime.h"
#include "SurgSim/Framework/Scene.h"
#include "SurgSim/Graphics/OsgBoxRepresentation.h"
#include "SurgSim/Graphics/OsgCapsuleRepresentation.h"
#include "SurgSim/Graphics/OsgManager.h"
#include "SurgSim/Graphics/OsgSceneryRepresentation.h"
#include "SurgSim/Graphics/OsgView.h"
#include "SurgSim/Graphics/OsgViewElement.h"
#include "SurgSim/Input/InputComponent.h"
#include "SurgSim/Input/InputManager.h"
#include "SurgSim/Math/BoxShape.h"
#include "SurgSim/Math/CapsuleShape.h"
#include "SurgSim/Math/RigidTransform.h"
#include "SurgSim/Physics/FixedRepresentation.h"
#include "SurgSim/Physics/RigidCollisionRepresentation.h"
#include "SurgSim/Physics/RigidRepresentation.h"
#include "SurgSim/Physics/RigidRepresentationParameters.h"
#include "SurgSim/Physics/PhysicsManager.h"
#include "SurgSim/Physics/VirtualToolCoupler.h"

using SurgSim::Blocks::TransferInputPoseBehavior;
using SurgSim::Blocks::TransferPoseBehavior;
using SurgSim::Blocks::BasicSceneElement;
using SurgSim::Framework::BehaviorManager;
using SurgSim::Framework::Scene;
using SurgSim::Framework::SceneElement;
using SurgSim::Framework::Runtime;
using SurgSim::Device::MultiAxisDevice;
using SurgSim::Graphics::BoxRepresentation;
using SurgSim::Graphics::CapsuleRepresentation;
using SurgSim::Graphics::OsgBoxRepresentation;
using SurgSim::Graphics::OsgCapsuleRepresentation;
using SurgSim::Graphics::OsgManager;
using SurgSim::Graphics::OsgSceneryRepresentation;
using SurgSim::Graphics::OsgViewElement;
using SurgSim::Graphics::SceneryRepresentation;
using SurgSim::Graphics::ViewElement;
using SurgSim::Math::BoxShape;
using SurgSim::Math::CapsuleShape;
using SurgSim::Math::makeRigidTransform;
using SurgSim::Math::Quaterniond;
using SurgSim::Math::RigidTransform3d;
using SurgSim::Math::Vector3d;
using SurgSim::Input::DeviceInterface;
using SurgSim::Input::InputComponent;
using SurgSim::Input::InputManager;
using SurgSim::Physics::FixedRepresentation;
using SurgSim::Physics::PhysicsManager;
using SurgSim::Physics::RigidRepresentationParameters;
using SurgSim::Physics::RigidCollisionRepresentation;
using SurgSim::Physics::RigidRepresentation;
using SurgSim::Physics::VirtualToolCoupler;

/// Load scenery object from file.
/// \param name Name of this scenery representation.
/// \param fileName Name of the file from which the scenery representation is loaded.
/// \param pose The pose of the loaded scenery representation.
/// \return A SceneElement containing the scenery representation.
std::shared_ptr<SceneElement> createSceneryObject(const std::string& name,
												  const std::string& fileName,
												  const RigidTransform3d& pose)
{
	std::shared_ptr<SceneryRepresentation> sceneryRepresentation =
		std::make_shared<OsgSceneryRepresentation>(name + "SceneryRepresentation");
	sceneryRepresentation->setFileName(fileName);
	sceneryRepresentation->setInitialPose(pose);

	std::shared_ptr<BasicSceneElement> sceneElement = std::make_shared<BasicSceneElement>(name + "SceneElement");
	sceneElement->addComponent(sceneryRepresentation);

	return sceneElement;
}

std::shared_ptr<ViewElement> createView()
{
	std::shared_ptr<OsgViewElement> view = std::make_shared<OsgViewElement>("StaplingDemoView");

	view->enableManipulator(true);
	view->setManipulatorParameters(Vector3d(0.0, 0.5, 0.5), Vector3d::Zero());

	return view;
}

std::shared_ptr<SceneElement> createStapler(const std::string& name)
{
	// Since there is no collision mesh loader yet, use a capsule shape as the collision representation of the stapler.
	std::shared_ptr<CapsuleShape> capsuleShape = std::make_shared<CapsuleShape>(0.1, 0.02); // Unit: meter
	RigidRepresentationParameters params;
	params.setDensity(8050); // Stainless steel (in Kg.m-3)
	params.setShapeUsedForMassInertia(capsuleShape);
	std::shared_ptr<RigidRepresentation> physicsRepresentation =
		std::make_shared<RigidRepresentation>(name + "Physics");
	physicsRepresentation->setInitialParameters(params);

	std::shared_ptr<RigidCollisionRepresentation> collisionRepresentation =
		std::make_shared<RigidCollisionRepresentation>(name + "Collision");
	collisionRepresentation->setRigidRepresentation(physicsRepresentation);

	std::shared_ptr<InputComponent> inputComponent = std::make_shared<InputComponent>("InputComponent");
	inputComponent->setDeviceName("MultiAxisDevice");

	std::shared_ptr<VirtualToolCoupler> inputVTC = std::make_shared<VirtualToolCoupler>("VTC");
	inputVTC->setInput(inputComponent);
	inputVTC->setRepresentation(physicsRepresentation);
	inputVTC->setAngularDamping(params.getMass() * 10e-2);
	inputVTC->setAngularStiffness(params.getMass() * 50.0);
	inputVTC->setLinearDamping(params.getMass() * 10.0);
	inputVTC->setLinearStiffness(params.getMass() * 200.0);

	// A stapler behavior controls the release of stale when a button is pushed on the device.
	// Also, it is aware of collisions of the stapler.
	std::shared_ptr<StaplerBehavior> staplerBehavior = std::make_shared<StaplerBehavior>(name + "StaplerBehavior");
	staplerBehavior->setInputComponent(inputComponent);
	staplerBehavior->setStaplerRepresentation(collisionRepresentation);

	std::shared_ptr<SceneryRepresentation> staplerSceneryRepresentation =
		std::make_shared<OsgSceneryRepresentation>(name + "SceneryRepresentation");
	staplerSceneryRepresentation->setFileName("Geometry/stapler.obj");
	// Connect inputComponent to graphical representation.
	std::shared_ptr<TransferInputPoseBehavior> transferInputPose =
		std::make_shared<TransferInputPoseBehavior>(name + "Input to Graphics");
	transferInputPose->setPoseSender(inputComponent);
	transferInputPose->setPoseReceiver(staplerSceneryRepresentation);

	// Visualization of the collision representation.
	std::shared_ptr<CapsuleRepresentation> osgCapsuleRepresentation =
		std::make_shared<OsgCapsuleRepresentation>("capsule representation");
	osgCapsuleRepresentation->setHeight(capsuleShape->getLength());
	osgCapsuleRepresentation->setRadius(capsuleShape->getRadius());
	// Connect physical representation to graphical representation.
	std::shared_ptr<TransferPoseBehavior> transferPose =
		std::make_shared<TransferPoseBehavior>(name + "Physics to Graphics");
	transferPose->setPoseSender(physicsRepresentation);
	transferPose->setPoseReceiver(osgCapsuleRepresentation);

	std::shared_ptr<SceneElement> staplerSceneElement = std::make_shared<BasicSceneElement>(name + "SceneElement");
	staplerSceneElement->addComponent(physicsRepresentation);
	staplerSceneElement->addComponent(collisionRepresentation);
	staplerSceneElement->addComponent(osgCapsuleRepresentation);
	staplerSceneElement->addComponent(staplerSceneryRepresentation);
	staplerSceneElement->addComponent(inputComponent);
	staplerSceneElement->addComponent(inputVTC);
	staplerSceneElement->addComponent(staplerBehavior);
	staplerSceneElement->addComponent(transferInputPose);
	staplerSceneElement->addComponent(transferPose);

	return staplerSceneElement;
}

std::shared_ptr<SceneElement> createArm(const std::string& name, const RigidTransform3d& pose)
{
	// Load graphic representation for armSceneElement
	std::shared_ptr<SceneElement> armSceneElement = createSceneryObject(name, "Geometry/forearm.osgb", pose);

	std::shared_ptr<BoxRepresentation> boxRepresentation =
		std::make_shared<OsgBoxRepresentation>("capsule representation");
	boxRepresentation->setSize(0.635, 0.05, 0.05); // Unit: meter
	boxRepresentation->setInitialPose(pose);

	// Since there is no collision mesh loader yet, use a box shape as the collision representation of the arm.
	std::shared_ptr<BoxShape> boxShape = std::make_shared<BoxShape>(boxRepresentation->getSizeX(),
																	boxRepresentation->getSizeY(),
																	boxRepresentation->getSizeZ());

	RigidRepresentationParameters params;
	params.setDensity(1062); // Average human body density  (in Kg.m-3)
	params.setShapeUsedForMassInertia(boxShape);

	std::shared_ptr<FixedRepresentation> physicsRepresentation =
		std::make_shared<FixedRepresentation>(name + "Physics");
	physicsRepresentation->setInitialParameters(params);
	physicsRepresentation->setInitialPose(pose);

	std::shared_ptr<RigidCollisionRepresentation> collisionRepresentation =
		std::make_shared<RigidCollisionRepresentation>(name + "Collision");
	collisionRepresentation->setRigidRepresentation(physicsRepresentation);

	std::shared_ptr<TransferPoseBehavior> transferPose =
		std::make_shared<TransferPoseBehavior>("Physics to Graphics Pose");
	transferPose->setPoseSender(physicsRepresentation);
	transferPose->setPoseReceiver(boxRepresentation);

	armSceneElement->addComponent(boxRepresentation);
	armSceneElement->addComponent(physicsRepresentation);
	armSceneElement->addComponent(collisionRepresentation);
	armSceneElement->addComponent(transferPose);

	return armSceneElement;
}

int main(int argc, char* argv[])
{
	std::shared_ptr<BehaviorManager> behaviorManager = std::make_shared<BehaviorManager>();
	std::shared_ptr<OsgManager> graphicsManager = std::make_shared<OsgManager>();
	std::shared_ptr<InputManager> inputManager    = std::make_shared<InputManager>();
	std::shared_ptr<PhysicsManager>  physicsManager  = std::make_shared<PhysicsManager>();

	std::shared_ptr<Runtime> runtime = std::make_shared<Runtime>("config.txt");
	runtime->addManager(behaviorManager);
	runtime->addManager(graphicsManager);
	runtime->addManager(inputManager);
	runtime->addManager(physicsManager);

	std::shared_ptr<DeviceInterface> device = std::make_shared<MultiAxisDevice>("MultiAxisDevice");
	SURGSIM_ASSERT(device->initialize() == true) <<
		"Could not initialize device " << device->getName() << " for the tool.\n";
	inputManager->addDevice(device);

	std::shared_ptr<SceneElement> staplerSceneElement = createStapler("stapler");
	std::shared_ptr<SceneElement> armSceneElement = createArm("arm",
		makeRigidTransform(Quaterniond::Identity(), SurgSim::Math::Vector3d(0.0, -0.2, 0.0)));

	std::shared_ptr<Scene> scene = runtime->getScene();
	scene->addSceneElement(createView());
	scene->addSceneElement(staplerSceneElement);
	scene->addSceneElement(armSceneElement);

	runtime->execute();

	return 0;
}
<commit_msg>Rotate the box representation for arm and fix name typo.<commit_after>// This file is a part of the OpenSurgSim project.
// Copyright 2013, SimQuest Solutions Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <memory>
#include <string>

#include "SurgSim/Blocks/BasicSceneElement.h"
#include "SurgSim/Blocks/TransferInputPoseBehavior.h"
#include "SurgSim/Blocks/TransferPoseBehavior.h"
#include "SurgSim/Devices/MultiAxis/MultiAxisDevice.h"
#include "Examples/ExampleStapling/StaplerBehavior.h"
#include "SurgSim/Framework/BehaviorManager.h"
#include "SurgSim/Framework/Runtime.h"
#include "SurgSim/Framework/Scene.h"
#include "SurgSim/Graphics/OsgBoxRepresentation.h"
#include "SurgSim/Graphics/OsgCapsuleRepresentation.h"
#include "SurgSim/Graphics/OsgManager.h"
#include "SurgSim/Graphics/OsgSceneryRepresentation.h"
#include "SurgSim/Graphics/OsgView.h"
#include "SurgSim/Graphics/OsgViewElement.h"
#include "SurgSim/Input/InputComponent.h"
#include "SurgSim/Input/InputManager.h"
#include "SurgSim/Math/BoxShape.h"
#include "SurgSim/Math/CapsuleShape.h"
#include "SurgSim/Math/RigidTransform.h"
#include "SurgSim/Physics/FixedRepresentation.h"
#include "SurgSim/Physics/RigidCollisionRepresentation.h"
#include "SurgSim/Physics/RigidRepresentation.h"
#include "SurgSim/Physics/RigidRepresentationParameters.h"
#include "SurgSim/Physics/PhysicsManager.h"
#include "SurgSim/Physics/VirtualToolCoupler.h"

using SurgSim::Blocks::TransferInputPoseBehavior;
using SurgSim::Blocks::TransferPoseBehavior;
using SurgSim::Blocks::BasicSceneElement;
using SurgSim::Framework::BehaviorManager;
using SurgSim::Framework::Scene;
using SurgSim::Framework::SceneElement;
using SurgSim::Framework::Runtime;
using SurgSim::Device::MultiAxisDevice;
using SurgSim::Graphics::BoxRepresentation;
using SurgSim::Graphics::CapsuleRepresentation;
using SurgSim::Graphics::OsgBoxRepresentation;
using SurgSim::Graphics::OsgCapsuleRepresentation;
using SurgSim::Graphics::OsgManager;
using SurgSim::Graphics::OsgSceneryRepresentation;
using SurgSim::Graphics::OsgViewElement;
using SurgSim::Graphics::SceneryRepresentation;
using SurgSim::Graphics::ViewElement;
using SurgSim::Math::BoxShape;
using SurgSim::Math::CapsuleShape;
using SurgSim::Math::makeRigidTransform;
using SurgSim::Math::Quaterniond;
using SurgSim::Math::RigidTransform3d;
using SurgSim::Math::Vector3d;
using SurgSim::Input::DeviceInterface;
using SurgSim::Input::InputComponent;
using SurgSim::Input::InputManager;
using SurgSim::Physics::FixedRepresentation;
using SurgSim::Physics::PhysicsManager;
using SurgSim::Physics::RigidRepresentationParameters;
using SurgSim::Physics::RigidCollisionRepresentation;
using SurgSim::Physics::RigidRepresentation;
using SurgSim::Physics::VirtualToolCoupler;

/// Load scenery object from file.
/// \param name Name of this scenery representation.
/// \param fileName Name of the file from which the scenery representation is loaded.
/// \param pose The pose of the loaded scenery representation.
/// \return A SceneElement containing the scenery representation.
std::shared_ptr<SceneElement> createSceneryObject(const std::string& name,
												  const std::string& fileName,
												  const RigidTransform3d& pose)
{
	std::shared_ptr<SceneryRepresentation> sceneryRepresentation =
		std::make_shared<OsgSceneryRepresentation>(name + "SceneryRepresentation");
	sceneryRepresentation->setFileName(fileName);
	sceneryRepresentation->setInitialPose(pose);

	std::shared_ptr<BasicSceneElement> sceneElement = std::make_shared<BasicSceneElement>(name + "SceneElement");
	sceneElement->addComponent(sceneryRepresentation);

	return sceneElement;
}

std::shared_ptr<ViewElement> createView()
{
	std::shared_ptr<OsgViewElement> view = std::make_shared<OsgViewElement>("StaplingDemoView");

	view->enableManipulator(true);
	view->setManipulatorParameters(Vector3d(0.0, 0.5, 0.5), Vector3d::Zero());

	return view;
}

std::shared_ptr<SceneElement> createStapler(const std::string& name)
{
	// Since there is no collision mesh loader yet, use a capsule shape as the collision representation of the stapler.
	std::shared_ptr<CapsuleShape> capsuleShape = std::make_shared<CapsuleShape>(0.1, 0.02); // Unit: meter
	RigidRepresentationParameters params;
	params.setDensity(8050); // Stainless steel (in Kg.m-3)
	params.setShapeUsedForMassInertia(capsuleShape);
	std::shared_ptr<RigidRepresentation> physicsRepresentation =
		std::make_shared<RigidRepresentation>(name + "Physics");
	physicsRepresentation->setInitialParameters(params);

	std::shared_ptr<RigidCollisionRepresentation> collisionRepresentation =
		std::make_shared<RigidCollisionRepresentation>(name + "Collision");
	collisionRepresentation->setRigidRepresentation(physicsRepresentation);

	std::shared_ptr<InputComponent> inputComponent = std::make_shared<InputComponent>("InputComponent");
	inputComponent->setDeviceName("MultiAxisDevice");

	std::shared_ptr<VirtualToolCoupler> inputVTC = std::make_shared<VirtualToolCoupler>("VTC");
	inputVTC->setInput(inputComponent);
	inputVTC->setRepresentation(physicsRepresentation);
	inputVTC->setAngularDamping(params.getMass() * 10e-2);
	inputVTC->setAngularStiffness(params.getMass() * 50.0);
	inputVTC->setLinearDamping(params.getMass() * 10.0);
	inputVTC->setLinearStiffness(params.getMass() * 200.0);

	// A stapler behavior controls the release of stale when a button is pushed on the device.
	// Also, it is aware of collisions of the stapler.
	std::shared_ptr<StaplerBehavior> staplerBehavior = std::make_shared<StaplerBehavior>(name + "StaplerBehavior");
	staplerBehavior->setInputComponent(inputComponent);
	staplerBehavior->setStaplerRepresentation(collisionRepresentation);

	std::shared_ptr<SceneryRepresentation> staplerSceneryRepresentation =
		std::make_shared<OsgSceneryRepresentation>(name + "SceneryRepresentation");
	staplerSceneryRepresentation->setFileName("Geometry/stapler.obj");
	// Connect inputComponent to graphical representation.
	std::shared_ptr<TransferInputPoseBehavior> transferInputPose =
		std::make_shared<TransferInputPoseBehavior>(name + "Input to Graphics");
	transferInputPose->setPoseSender(inputComponent);
	transferInputPose->setPoseReceiver(staplerSceneryRepresentation);

	// Visualization of the collision representation.
	std::shared_ptr<CapsuleRepresentation> osgCapsuleRepresentation =
		std::make_shared<OsgCapsuleRepresentation>("capsule representation");
	osgCapsuleRepresentation->setHeight(capsuleShape->getLength());
	osgCapsuleRepresentation->setRadius(capsuleShape->getRadius());
	// Connect physical representation to graphical representation.
	std::shared_ptr<TransferPoseBehavior> transferPose =
		std::make_shared<TransferPoseBehavior>(name + "Physics to Graphics");
	transferPose->setPoseSender(physicsRepresentation);
	transferPose->setPoseReceiver(osgCapsuleRepresentation);

	std::shared_ptr<SceneElement> staplerSceneElement = std::make_shared<BasicSceneElement>(name + "SceneElement");
	staplerSceneElement->addComponent(physicsRepresentation);
	staplerSceneElement->addComponent(collisionRepresentation);
	staplerSceneElement->addComponent(osgCapsuleRepresentation);
	staplerSceneElement->addComponent(staplerSceneryRepresentation);
	staplerSceneElement->addComponent(inputComponent);
	staplerSceneElement->addComponent(inputVTC);
	staplerSceneElement->addComponent(staplerBehavior);
	staplerSceneElement->addComponent(transferInputPose);
	staplerSceneElement->addComponent(transferPose);

	return staplerSceneElement;
}

std::shared_ptr<SceneElement> createArm(const std::string& name, const Vector3d& trans)
{
	// Load graphic representation for armSceneElement
	auto pose = makeRigidTransform(Quaterniond::Identity(), trans);
	std::shared_ptr<SceneElement> armSceneElement = createSceneryObject(name, "Geometry/forearm.osgb", pose);

	std::shared_ptr<BoxRepresentation> boxRepresentation =
		std::make_shared<OsgBoxRepresentation>("box representation");
	auto boxQuat =  SurgSim::Math::makeRotationQuaternion(-M_PI / 4, SurgSim::Math::Vector3d(0.0, 1.0, 0.0));
	auto poseRepresentation = makeRigidTransform(boxQuat, trans);
	boxRepresentation->setSize(0.335, 0.05, 0.05); // Unit: meter
	boxRepresentation->setInitialPose(poseRepresentation);

	// Since there is no collision mesh loader yet, use a box shape as the collision representation of the arm.
	std::shared_ptr<BoxShape> boxShape = std::make_shared<BoxShape>(boxRepresentation->getSizeX(),
																	boxRepresentation->getSizeY(),
																	boxRepresentation->getSizeZ());

	RigidRepresentationParameters params;
	params.setDensity(1062); // Average human body density  (in Kg.m-3)
	params.setShapeUsedForMassInertia(boxShape);

	std::shared_ptr<FixedRepresentation> physicsRepresentation =
		std::make_shared<FixedRepresentation>(name + "Physics");
	physicsRepresentation->setInitialParameters(params);
	physicsRepresentation->setInitialPose(poseRepresentation);

	std::shared_ptr<RigidCollisionRepresentation> collisionRepresentation =
		std::make_shared<RigidCollisionRepresentation>(name + "Collision");
	collisionRepresentation->setRigidRepresentation(physicsRepresentation);

	std::shared_ptr<TransferPoseBehavior> transferPose =
		std::make_shared<TransferPoseBehavior>("Physics to Graphics Pose");
	transferPose->setPoseSender(physicsRepresentation);
	transferPose->setPoseReceiver(boxRepresentation);

	armSceneElement->addComponent(boxRepresentation);
	armSceneElement->addComponent(physicsRepresentation);
	armSceneElement->addComponent(collisionRepresentation);
	armSceneElement->addComponent(transferPose);

	return armSceneElement;
}

int main(int argc, char* argv[])
{
	std::shared_ptr<BehaviorManager> behaviorManager = std::make_shared<BehaviorManager>();
	std::shared_ptr<OsgManager> graphicsManager = std::make_shared<OsgManager>();
	std::shared_ptr<InputManager> inputManager    = std::make_shared<InputManager>();
	std::shared_ptr<PhysicsManager>  physicsManager  = std::make_shared<PhysicsManager>();

	std::shared_ptr<Runtime> runtime = std::make_shared<Runtime>("config.txt");
	runtime->addManager(behaviorManager);
	runtime->addManager(graphicsManager);
	runtime->addManager(inputManager);
	runtime->addManager(physicsManager);

	std::shared_ptr<DeviceInterface> device = std::make_shared<MultiAxisDevice>("MultiAxisDevice");
	SURGSIM_ASSERT(device->initialize() == true) <<
		"Could not initialize device " << device->getName() << " for the tool.\n";
	inputManager->addDevice(device);

	std::shared_ptr<SceneElement> staplerSceneElement = createStapler("stapler");
	auto armTrans = Vector3d(0.0, -0.2, 0.0);
	std::shared_ptr<SceneElement> armSceneElement = createArm("arm", armTrans);

	std::shared_ptr<Scene> scene = runtime->getScene();
	scene->addSceneElement(createView());
	scene->addSceneElement(staplerSceneElement);
	scene->addSceneElement(armSceneElement);

	runtime->execute();

	return 0;
}
<|endoftext|>


<commit_before>//#define __HAS_TESTPROP__
//#define __HAS_TESTFIT__
#define __HAS_AMS_OFFICE_LIBS__
#include <CPPLibs/CPPLibs.h>
#include <ROOTLibs/ROOTLibs.h>
#include <TRACKLibs/TRACKLibs.h>

#include "/ams_home/hchou/AMSCore/prod/18Feb13/src/ClassDef.h"
#include "/ams_home/hchou/AMSCore/prod/18Feb13/src/ClassDef.C"

using namespace std;

int main(int argc, char * argv[]) {
    using namespace MGROOT;
    using namespace TrackSys;
    MGROOT::LoadDefaultEnvironment();
    Hist::AddDirectory();

    //google::InitGoogleLogging(argv[0]);
    //google::ParseCommandLineFlags(&argc, &argv, true);
    //google::SetStderrLogging(google::GLOG_FATAL);

    MGConfig::JobOpt opt(argc, argv);

    TChain * dst = new TChain("data");
    for (auto&& file : opt.flist()) dst->Add(file.c_str());

    LIST * fList = new LIST;
    G4MC * fG4mc = (opt.mode() == MGConfig::JobOpt::MODE::MC ) ? new G4MC : nullptr;
    RTI  * fRti  = (opt.mode() == MGConfig::JobOpt::MODE::ISS) ? new RTI  : nullptr;
    TRG  * fTrg  = new TRG ;
    TOF  * fTof  = new TOF ;
    ACC  * fAcc  = new ACC ;
    TRK  * fTrk  = new TRK ;
    TRD  * fTrd  = new TRD ;
    RICH * fRich = new RICH;
    ECAL * fEcal = new ECAL;

    dst->SetBranchAddress("list", &fList);
    if (opt.mode() == MGConfig::JobOpt::MODE::MC)
        dst->SetBranchAddress("g4mc", &fG4mc);
    if (opt.mode() == MGConfig::JobOpt::MODE::ISS)
        dst->SetBranchAddress("rti",  &fRti);
    dst->SetBranchAddress("trg",  &fTrg);
    dst->SetBranchAddress("tof",  &fTof);
    dst->SetBranchAddress("acc",  &fAcc);
    dst->SetBranchAddress("trk",  &fTrk);
    dst->SetBranchAddress("trd",  &fTrd);
    dst->SetBranchAddress("rich", &fRich);
    dst->SetBranchAddress("ecal", &fEcal);

    //---------------------------------------------------------------//
    //---------------------------------------------------------------//
    //---------------------------------------------------------------//
    TFile * ofle = new TFile(Form("%s/app_fill%05ld.root", opt.opath().c_str(), opt.gi()), "RECREATE");

    Axis AXrig("Rigidity [GV]", 100, 0.5, 4000., AxisScale::kLog);
    Axis AXirig("1/Rigidity [1/GV]", AXrig, 1, true);

    Axis AXtrd("TRD Estimator", 200, 0.0, 1.6);
    Hist * hTRDllr_PR = Hist::New("hTRDllr_PR", HistAxis(AXrig, AXtrd, "Events/Bin"));
    Hist * hTRDllr_NR = Hist::New("hTRDllr_NR", HistAxis(AXrig, AXtrd, "Events/Bin"));

    Axis AXchi("Log Chi-square X", 400, -4.0, 8.0);
    Hist * hTRKchix_PR = Hist::New("hTRKchix_PR", HistAxis(AXrig, AXchi, "Events/Bin"));
    Hist * hTRKchix_NR = Hist::New("hTRKchix_NR", HistAxis(AXrig, AXchi, "Events/Bin"));
    Hist * hTRKchiy_PR = Hist::New("hTRKchiy_PR", HistAxis(AXrig, AXchi, "Events/Bin"));
    Hist * hTRKchiy_NR = Hist::New("hTRKchiy_NR", HistAxis(AXrig, AXchi, "Events/Bin"));

    Hist * hCKIRflux = Hist::New("hCKIRflux", HistAxis(AXirig, "Events/Bin"));
    Hist * hCNIRflux = Hist::New("hCNIRflux", HistAxis(AXirig, "Events/Bin"));
    Hist * hKFIRflux = Hist::New("hKFIRflux", HistAxis(AXirig, "Events/Bin"));
    Hist * hHCIRflux = Hist::New("hHCIRflux", HistAxis(AXirig, "Events/Bin"));

    Hist * hCKPRflux = Hist::New("hCKPRflux", HistAxis(AXrig, "Events/Bin"));
    Hist * hCNPRflux = Hist::New("hCNPRflux", HistAxis(AXrig, "Events/Bin"));
    Hist * hKFPRflux = Hist::New("hKFPRflux", HistAxis(AXrig, "Events/Bin"));
    Hist * hHCPRflux = Hist::New("hHCPRflux", HistAxis(AXrig, "Events/Bin"));

    Hist * hCKNRflux = Hist::New("hCKNRflux", HistAxis(AXrig, "Events/Bin"));
    Hist * hCNNRflux = Hist::New("hCNNRflux", HistAxis(AXrig, "Events/Bin"));
    Hist * hKFNRflux = Hist::New("hKFNRflux", HistAxis(AXrig, "Events/Bin"));
    Hist * hHCNRflux = Hist::New("hHCNRflux", HistAxis(AXrig, "Events/Bin"));

    Long64_t printRate = dst->GetEntries();
    std::cout << Form("\n==== Totally Entries %lld ====\n", dst->GetEntries());
    for (Long64_t entry = 0; entry < dst->GetEntries(); ++entry) {
        if (entry%printRate==0) COUT("Entry %lld/%lld\n", entry, dst->GetEntries());
        dst->GetEntry(entry);

        TrackInfo& track = fTrk->track;

        // Geometry (TOF)
        if (fTof->numOfBetaH != 1) continue;
        if (!fTof->statusBetaH) continue;
        if (fTof->betaHPatt != 15) continue;

        // Geometry (TRD)
        if (fTrd->numOfTrack != 1 && fTrd->numOfHTrack != 1) continue;
        if (!fTrd->statusKCls[0]) continue;
        if (fTrd->LLRnhit[0] < 10) continue;

        // Geometry (ACC)
        if (fAcc->clusters.size() != 0) continue;

        // Down-going
        if (fTof->betaH < 0.) continue;

        // Charge
        if (fTof->Qall < 0.8 || fTof->Qall > 1.3) continue;
        if (track.QIn < 0.8 || track.QIn > 1.3) continue;

        // TOF
        if (fTof->normChisqT > 10.) continue;
        if (fTof->normChisqC > 10.) continue;

        if (fTof->numOfInTimeCls > 4) continue;
        if ((fTof->extClsN[0]+fTof->extClsN[1]) > 0 ||
            (fTof->extClsN[2]+fTof->extClsN[3]) > 1) continue;

        // TRD
        if (fTrd->LLRph[0] > 0.3) continue;

        // IGRF RTI
        if (opt.mode() == MGConfig::JobOpt::MODE::ISS && track.status[0][0]) {
            if (std::fabs(track.rig[0][0]) < 1.2 * fRti->cfIGRF[0]) continue;
        }

        Int_t patt = 0;

        Bool_t ck_succ = track.status[0][patt];
        Bool_t cn_succ = track.status[1][patt];
        Bool_t kf_succ = track.status[2][patt];
        Bool_t hc_succ = track.status[3][patt];

        Double_t ck_irig = (ck_succ ? MGMath::ONE/track.rig[0][patt] : 0.);
        Double_t cn_irig = (cn_succ ? MGMath::ONE/track.rig[1][patt] : 0.);
        Double_t kf_irig = (kf_succ ? MGMath::ONE/track.rig[2][patt] : 0.);
        Double_t hc_irig = (hc_succ ? MGMath::ONE/track.rig[3][patt] : 0.);

        Short_t ck_sign = (ck_succ ? (ck_irig>0?1:-1) : 0);
        Short_t cn_sign = (cn_succ ? (cn_irig>0?1:-1) : 0);
        Short_t kf_sign = (kf_succ ? (kf_irig>0?1:-1) : 0);
        Short_t hc_sign = (hc_succ ? (hc_irig>0?1:-1) : 0);

        Double_t ck_rig = (ck_succ ? std::fabs(1.0/ck_irig) : 0.);
        Double_t cn_rig = (cn_succ ? std::fabs(1.0/cn_irig) : 0.);
        Double_t kf_rig = (kf_succ ? std::fabs(1.0/kf_irig) : 0.);
        Double_t hc_rig = (hc_succ ? std::fabs(1.0/hc_irig) : 0.);

        Double_t ck_chix = (ck_succ ? std::log(track.chisq[0][patt][0]) : 0.);
        Double_t cn_chix = (cn_succ ? std::log(track.chisq[1][patt][0]) : 0.);
        Double_t kf_chix = (kf_succ ? std::log(track.chisq[2][patt][0]) : 0.);
        Double_t hc_chix = (hc_succ ? std::log(track.chisq[3][patt][0]) : 0.);

        Double_t ck_chiy = (ck_succ ? std::log(track.chisq[0][patt][1]) : 0.);
        Double_t cn_chiy = (cn_succ ? std::log(track.chisq[1][patt][1]) : 0.);
        Double_t kf_chiy = (kf_succ ? std::log(track.chisq[2][patt][1]) : 0.);
        Double_t hc_chiy = (hc_succ ? std::log(track.chisq[3][patt][1]) : 0.);

        if (ck_succ && ck_sign > 0) hTRDllr_PR->fillH2D(ck_rig, fTrd->LLRep[0], fList->weight);
        if (ck_succ && ck_sign < 0) hTRDllr_NR->fillH2D(ck_rig, fTrd->LLRep[0], fList->weight);
        if (ck_succ && ck_sign > 0) hTRKchix_PR->fillH2D(ck_rig, ck_chix, fList->weight);
        if (ck_succ && ck_sign < 0) hTRKchix_NR->fillH2D(ck_rig, ck_chix, fList->weight);
        if (ck_succ && ck_sign > 0) hTRKchiy_PR->fillH2D(ck_rig, ck_chiy, fList->weight);
        if (ck_succ && ck_sign < 0) hTRKchiy_NR->fillH2D(ck_rig, ck_chiy, fList->weight);

        if (ck_succ) hCKIRflux->fillH1D(ck_irig, fList->weight);
        if (cn_succ) hCNIRflux->fillH1D(cn_irig, fList->weight);
        if (kf_succ) hKFIRflux->fillH1D(kf_irig, fList->weight);
        if (hc_succ) hHCIRflux->fillH1D(hc_irig, fList->weight);

        if (ck_succ && ck_sign > 0) hCKPRflux->fillH1D(ck_rig, fList->weight);
        if (cn_succ && cn_sign > 0) hCNPRflux->fillH1D(cn_rig, fList->weight);
        if (kf_succ && kf_sign > 0) hKFPRflux->fillH1D(kf_rig, fList->weight);
        if (hc_succ && hc_sign > 0) hHCPRflux->fillH1D(hc_rig, fList->weight);

        if (ck_succ && ck_sign < 0) hCKNRflux->fillH1D(ck_rig, fList->weight);
        if (cn_succ && cn_sign < 0) hCNNRflux->fillH1D(cn_rig, fList->weight);
        if (kf_succ && kf_sign < 0) hKFNRflux->fillH1D(kf_rig, fList->weight);
        if (hc_succ && hc_sign < 0) hHCNRflux->fillH1D(hc_rig, fList->weight);
    }
    ofle->Write();
    ofle->Close();

    //---------------------------------------------------------------//
    //---------------------------------------------------------------//
    //---------------------------------------------------------------//
    if (fList) { delete fList; fList = nullptr; }
    if (fG4mc) { delete fG4mc; fG4mc = nullptr; }
    if (fRti ) { delete fRti ; fRti  = nullptr; }
    if (fTrg ) { delete fTrg ; fTrg  = nullptr; }
    if (fTof ) { delete fTof ; fTof  = nullptr; }
    if (fAcc ) { delete fAcc ; fAcc  = nullptr; }
    if (fTrk ) { delete fTrk ; fTrk  = nullptr; }
    if (fTrd ) { delete fTrd ; fTrd  = nullptr; }
    if (fRich) { delete fRich; fRich = nullptr; }
    if (fEcal) { delete fEcal; fEcal = nullptr; }

    return 0;
}
<commit_msg>update<commit_after><|endoftext|>


<commit_before>MatrixXd ones = MatrixXd::Ones(3,3);
EigenSolver<MatrixXd> es(ones);
cout << "The first eigenvector of the 3x3 matrix of ones is:"
     << endl << es.eigenvectors().col(1) << endl;
<commit_msg>Typo in the example for Eigen::SelfAdjointEigenSolver::eigenvectors, the first eigenvector should be col(0) not col(1)<commit_after>MatrixXd ones = MatrixXd::Ones(3,3);
EigenSolver<MatrixXd> es(ones);
cout << "The first eigenvector of the 3x3 matrix of ones is:"
     << endl << es.eigenvectors().col(0) << endl;
<|endoftext|>


<commit_before>/*--------------------------------------------------------------------------
File   : PTHSensorTag.cpp

Author : Hoang Nguyen Hoan          May 8, 2017

Desc   : Environmental Sensor BLE demo
		 This application demo shows BLE connectionless using EHAL library
		 It advertises Barometric Pressure, Temperature & Humidity data
		 in manufacturer specific data

Copyright (c) 2017, I-SYST inc., all rights reserved

Permission to use, copy, modify, and distribute this software for any purpose
with or without fee is hereby granted, provided that the above copyright
notice and this permission notice appear in all copies, and none of the
names : I-SYST or its contributors may be used to endorse or
promote products derived from this software without specific prior written
permission.

For info or contributing contact : hnhoan at i-syst dot com

THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

----------------------------------------------------------------------------
Modified by          Date              Description

----------------------------------------------------------------------------*/
#include <string.h>

#include "istddef.h"
#include "ble_app.h"
#include "ble_service.h"
#include "blueio_board.h"
#include "uart.h"
#include "i2c.h"
#include "spi.h"
#include "custom_board.h"
#include "iopincfg.h"
#include "app_util_platform.h"
#include "app_scheduler.h"
#include "pth_bme280.h"
#include "pth_ms8607.h"
#include "timer_nrf5x.h"

#define DEVICE_NAME                     "PTHSensorTag"                            /**< Name of device. Will be included in the advertising data. */

#define PTH_BME280

// Use timer to update data
// NOTE :	RTC timer 0 used by radio, RTC Timer 1 used by SDK
//			Only RTC timer 2 is usable with Softdevice for nRF52, not avail on nRF51
//
#ifdef NRF52
#define USE_TIMER_UPDATE
#define NEBLINA_MODULE
#endif

// NOTE : Min advertisement interval for S130 v2 is 100 ms
#define APP_ADV_INTERVAL                MSEC_TO_UNITS(100, UNIT_0_625_MS)             /**< The advertising interval (in units of 0.625 ms. This value corresponds to 40 ms). */
#ifdef USE_TIMER_UPDATE
// Use timer to update date
#define APP_ADV_TIMEOUT_IN_SECONDS      0                                         /**< The advertising timeout (in units of seconds). */
#else
// Use advertisement timeout to update data
#define APP_ADV_TIMEOUT_IN_SECONDS      1                                         /**< The advertising timeout (in units of seconds). */
#endif

void TimerHandler(Timer *pTimer, uint32_t Evt);

uint8_t g_AdvDataBuff[sizeof(PTHSENSOR_DATA) + 1] = {
	BLEAPP_ADV_MANDATA_TYPE_PTH,
};

BLEAPP_ADV_MANDATA &g_AdvData = *(BLEAPP_ADV_MANDATA*)g_AdvDataBuff;

// Evironmental Sensor Data to advertise
PTHSENSOR_DATA &g_PTHData = *(PTHSENSOR_DATA *)g_AdvData.Data;

const static TIMER_CFG s_TimerCfg = {
    .DevNo = 2,
	.ClkSrc = TIMER_CLKSRC_DEFAULT,
	.Freq = 0,			// 0 => Default highest frequency
	.IntPrio = APP_IRQ_PRIORITY_LOW,
	.EvtHandler = TimerHandler
};

TimerLFnRF5x g_Timer;

const BLEAPP_CFG s_BleAppCfg = {
	{ // Clock config nrf_clock_lf_cfg_t
#ifdef IMM_NRF51822
		NRF_CLOCK_LF_SRC_RC,	// Source RC
		1, 1, 0
#else
		NRF_CLOCK_LF_SRC_XTAL,	// Source 32KHz XTAL
		0, 0, NRF_CLOCK_LF_ACCURACY_20_PPM// NRF_CLOCK_LF_XTAL_ACCURACY_20_PPM
#endif

	},
	0, 						// Number of central link
	0, 						// Number of peripheral link
	BLEAPP_MODE_NOCONNECT,   // Connectionless beacon type
	DEVICE_NAME,                 // Device name
	ISYST_BLUETOOTH_ID,     // PnP Bluetooth/USB vendor id
	1,                      // PnP Product ID
	0,						// Pnp prod version
	false,					// Enable device information service (DIS)
	NULL,
	(uint8_t*)&g_AdvDataBuff,   // Manufacture specific data to advertise
	sizeof(g_AdvDataBuff),      // Length of manufacture specific data
	BLEAPP_SECTYPE_NONE,    // Secure connection type
	BLEAPP_SECEXCHG_NONE,   // Security key exchange
	NULL,      				// Service uuids to advertise
	0, 						// Total number of uuids
	APP_ADV_INTERVAL,       // Advertising interval in msec
	APP_ADV_TIMEOUT_IN_SECONDS,	// Advertising timeout in sec
	100,                          // Slow advertising interval, if > 0, fallback to
								// slow interval on adv timeout and advertise until connected
	0,
	0,
	-1,    // Led port nuber
	-1,     // Led pin number
	NULL						// RTOS Softdevice handler
};

// Motsai Neblina V2 module uses SPI interface

#define NEBLINA_SPI_BOSCH_DEVNO            2
#define NEBLINA_SPI_BOSCH_MISO_PORT        0
#define NEBLINA_SPI_BOSCH_MISO_PIN         13
#define NEBLINA_SPI_BOSCH_MISO_PINOP       1
#define NEBLINA_SPI_BOSCH_MOSI_PORT        0
#define NEBLINA_SPI_BOSCH_MOSI_PIN         12
#define NEBLINA_SPI_BOSCH_MOSI_PINOP       1
#define NEBLINA_SPI_BOSCH_SCK_PORT         0
#define NEBLINA_SPI_BOSCH_SCK_PIN          11
#define NEBLINA_SPI_BOSCH_SCK_PINOP        1
#define NEBLINA_SPI_BME280_CS_IDX          1
#define NEBLINA_SPI_BME280_CS_PORT         0
#define NEBLINA_SPI_BME280_CS_PIN          26
#define NEBLINA_SPI_BME280_CS_PINOP        1

static const IOPINCFG gsSpiBoschPin[] = {
    {NEBLINA_SPI_BOSCH_SCK_PORT, NEBLINA_SPI_BOSCH_SCK_PIN, NEBLINA_SPI_BOSCH_SCK_PINOP,
     IOPINDIR_OUTPUT, IOPINRES_NONE, IOPINTYPE_NORMAL},
    {NEBLINA_SPI_BOSCH_MISO_PORT, NEBLINA_SPI_BOSCH_MISO_PIN, NEBLINA_SPI_BOSCH_MISO_PINOP,
     IOPINDIR_INPUT, IOPINRES_NONE, IOPINTYPE_NORMAL},
    {NEBLINA_SPI_BOSCH_MOSI_PORT, NEBLINA_SPI_BOSCH_MOSI_PIN, NEBLINA_SPI_BOSCH_MOSI_PINOP,
     IOPINDIR_OUTPUT, IOPINRES_NONE, IOPINTYPE_NORMAL},
    {NEBLINA_SPI_BME280_CS_PORT, NEBLINA_SPI_BME280_CS_PIN, NEBLINA_SPI_BME280_CS_PINOP,
     IOPINDIR_OUTPUT, IOPINRES_PULLUP, IOPINTYPE_NORMAL},
};

static const SPICFG s_SpiCfg = {
    NEBLINA_SPI_BOSCH_DEVNO,
    SPIMODE_MASTER,
    gsSpiBoschPin,
    sizeof( gsSpiBoschPin ) / sizeof( IOPINCFG ),
    8000000,   // Speed in Hz
    8,      // Data Size
    5,      // Max retries
    SPIDATABIT_MSB,
    SPIDATAPHASE_SECOND_CLK, // Data phase
    SPICLKPOL_LOW,         // clock polarity
    SPICSEL_AUTO,
    6, //APP_IRQ_PRIORITY_LOW,      // Interrupt priority
    nullptr
};

SPI g_Spi;

// Configure I2C interface
static const I2CCFG s_I2cCfg = {
	0,			// I2C device number
	{

#ifdef PTH_BME280

		{BLUEIO_TAG_BME280_I2C_SDA_PORT, BLUEIO_TAG_BME280_I2C_SDA_PIN, BLUEIO_TAG_BME280_I2C_SDA_PINOP, IOPINDIR_BI, IOPINRES_NONE, IOPINTYPE_NORMAL},	// RX
		{BLUEIO_TAG_BME280_I2C_SCL_PORT, BLUEIO_TAG_BME280_I2C_SCL_PIN, BLUEIO_TAG_BME280_I2C_SCL_PINOP, IOPINDIR_OUTPUT, IOPINRES_NONE, IOPINTYPE_NORMAL},	// TX
#else
		{0, 4, 0, IOPINDIR_BI, IOPINRES_NONE, IOPINTYPE_NORMAL},	// RX
		{0, 3, 0, IOPINDIR_OUTPUT, IOPINRES_NONE, IOPINTYPE_NORMAL},	// TX
#endif
	},
	100000,	// Rate
	I2CMODE_MASTER,
	0,			// Slave address
	5,			// Retry
	7,			// Interrupt prio
	NULL		// Event callback
};

// I2C interface instance
I2C g_I2c;

#ifdef NEBLINA_MODULE
DeviceIntrf *g_pIntrf = &g_Spi;
#else
DeviceIntrf *g_pIntrf = &g_I2c;
#endif

// Configure environmental sensor
static PTHSENSOR_CFG s_PthSensorCfg = {
#ifdef NEBLINA_MODULE
    0,      // SPI CS index 0
#else
	BME280_I2C_DEV_ADDR0,   // I2C device address
#endif
	PTHSENSOR_OPMODE_SINGLE,
	0
};

// Environmental sensor instance
PthBme280 g_Bme280Sensor;
PthMS8607 g_MS8607Sensor;

#ifdef PTH_BME280
PTHSensor &g_PthSensor = g_Bme280Sensor;
#else
PTHSensor &g_PthSensor = g_MS8607Sensor;
#endif

void ReadPTHData()
{
    g_pIntrf->Enable();

	PTHSENSOR_DATA data;

	g_PthSensor.ReadPTH(data);

	// NOTE : M0 does not access unaligned data
	// use local 4 bytes align stack variable then mem copy
	memcpy(&g_PTHData, &data, sizeof(PTHSENSOR_DATA));

	// Update advertisement data
	BleAppAdvManDataSet(g_AdvDataBuff, sizeof(g_AdvDataBuff));

	g_pIntrf->Disable();
}

void TimerHandler(Timer *pTimer, uint32_t Evt)
{
    if (Evt & TIMER_EVT_TRIGGER(0))
    {
    	ReadPTHData();
    }
}

void BlePeriphEvtUserHandler(ble_evt_t * p_ble_evt)
{
#ifndef USE_TIMER_UPDATE
    if (p_ble_evt->header.evt_id == BLE_GAP_EVT_TIMEOUT)
    {
    	// Update environmental sensor data everytime advertisement timeout
    	// for re-advertisement
    	ReadPTHData();
    }
#endif
}

void HardwareInit()
{
	// Initialize I2C
#ifdef NEBLINA_MODULE
    g_Spi.Init(s_SpiCfg);
#else
    g_I2c.Init(s_I2cCfg);
#endif

	// Inititalize sensor
    g_PthSensor.Init(s_PthSensorCfg, g_pIntrf);

    // Update sensor data
    PTHSENSOR_DATA pthdata;
	g_PthSensor.ReadPTH(pthdata);

	// Do memcpy to adv data. Due to byte alignment, cannot read directly into
	// adv data
	memcpy(g_AdvData.Data, &pthdata, sizeof(PTHSENSOR_DATA));

	g_pIntrf->Disable();

#ifdef USE_TIMER_UPDATE
    g_Timer.Init(s_TimerCfg);
	uint64_t period = g_Timer.EnableTimerTrigger(0, 500UL, TIMER_TRIG_TYPE_CONTINUOUS);
#endif
}

int main()
{
    HardwareInit();

    BleAppInit((const BLEAPP_CFG *)&s_BleAppCfg, true);

    BleAppRun();

	return 0;
}

<commit_msg>Add DC/DC enable<commit_after>/*--------------------------------------------------------------------------
File   : PTHSensorTag.cpp

Author : Hoang Nguyen Hoan          May 8, 2017

Desc   : Environmental Sensor BLE demo
		 This application demo shows BLE connectionless using EHAL library
		 It advertises Barometric Pressure, Temperature & Humidity data
		 in manufacturer specific data

Copyright (c) 2017, I-SYST inc., all rights reserved

Permission to use, copy, modify, and distribute this software for any purpose
with or without fee is hereby granted, provided that the above copyright
notice and this permission notice appear in all copies, and none of the
names : I-SYST or its contributors may be used to endorse or
promote products derived from this software without specific prior written
permission.

For info or contributing contact : hnhoan at i-syst dot com

THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

----------------------------------------------------------------------------
Modified by          Date              Description

----------------------------------------------------------------------------*/
#include <string.h>

#include "istddef.h"
#include "ble_app.h"
#include "ble_service.h"
#include "nrf_power.h"

#include "blueio_board.h"
#include "uart.h"
#include "i2c.h"
#include "spi.h"
#include "custom_board.h"
#include "iopincfg.h"
#include "app_util_platform.h"
#include "app_scheduler.h"
#include "pth_bme280.h"
#include "pth_ms8607.h"
#include "timer_nrf5x.h"

#define DEVICE_NAME                     "PTHSensorTag"                            /**< Name of device. Will be included in the advertising data. */

#define PTH_BME280

// Use timer to update data
// NOTE :	RTC timer 0 used by radio, RTC Timer 1 used by SDK
//			Only RTC timer 2 is usable with Softdevice for nRF52, not avail on nRF51
//
#ifdef NRF52
#define USE_TIMER_UPDATE
#define NEBLINA_MODULE
#endif

// NOTE : Min advertisement interval for S130 v2 is 100 ms
#define APP_ADV_INTERVAL                MSEC_TO_UNITS(100, UNIT_0_625_MS)             /**< The advertising interval (in units of 0.625 ms. This value corresponds to 40 ms). */
#ifdef USE_TIMER_UPDATE
// Use timer to update date
#define APP_ADV_TIMEOUT_IN_SECONDS      0                                         /**< The advertising timeout (in units of seconds). */
#else
// Use advertisement timeout to update data
#define APP_ADV_TIMEOUT_IN_SECONDS      1                                         /**< The advertising timeout (in units of seconds). */
#endif

void TimerHandler(Timer *pTimer, uint32_t Evt);

uint8_t g_AdvDataBuff[sizeof(PTHSENSOR_DATA) + 1] = {
	BLEAPP_ADV_MANDATA_TYPE_PTH,
};

BLEAPP_ADV_MANDATA &g_AdvData = *(BLEAPP_ADV_MANDATA*)g_AdvDataBuff;

// Evironmental Sensor Data to advertise
PTHSENSOR_DATA &g_PTHData = *(PTHSENSOR_DATA *)g_AdvData.Data;

const static TIMER_CFG s_TimerCfg = {
    .DevNo = 2,
	.ClkSrc = TIMER_CLKSRC_DEFAULT,
	.Freq = 0,			// 0 => Default highest frequency
	.IntPrio = APP_IRQ_PRIORITY_LOW,
	.EvtHandler = TimerHandler
};

TimerLFnRF5x g_Timer;

const BLEAPP_CFG s_BleAppCfg = {
	{ // Clock config nrf_clock_lf_cfg_t
#ifdef IMM_NRF51822
		NRF_CLOCK_LF_SRC_RC,	// Source RC
		1, 1, 0
#else
		NRF_CLOCK_LF_SRC_XTAL,	// Source 32KHz XTAL
		0, 0, NRF_CLOCK_LF_ACCURACY_20_PPM// NRF_CLOCK_LF_XTAL_ACCURACY_20_PPM
#endif

	},
	0, 						// Number of central link
	0, 						// Number of peripheral link
	BLEAPP_MODE_NOCONNECT,   // Connectionless beacon type
	DEVICE_NAME,                 // Device name
	ISYST_BLUETOOTH_ID,     // PnP Bluetooth/USB vendor id
	1,                      // PnP Product ID
	0,						// Pnp prod version
	false,					// Enable device information service (DIS)
	NULL,
	(uint8_t*)&g_AdvDataBuff,   // Manufacture specific data to advertise
	sizeof(g_AdvDataBuff),      // Length of manufacture specific data
	BLEAPP_SECTYPE_NONE,    // Secure connection type
	BLEAPP_SECEXCHG_NONE,   // Security key exchange
	NULL,      				// Service uuids to advertise
	0, 						// Total number of uuids
	APP_ADV_INTERVAL,       // Advertising interval in msec
	APP_ADV_TIMEOUT_IN_SECONDS,	// Advertising timeout in sec
	100,                          // Slow advertising interval, if > 0, fallback to
								// slow interval on adv timeout and advertise until connected
	0,
	0,
	-1,    // Led port nuber
	-1,     // Led pin number
	NULL						// RTOS Softdevice handler
};

// Motsai Neblina V2 module uses SPI interface

#define NEBLINA_SPI_BOSCH_DEVNO            2
#define NEBLINA_SPI_BOSCH_MISO_PORT        0
#define NEBLINA_SPI_BOSCH_MISO_PIN         13
#define NEBLINA_SPI_BOSCH_MISO_PINOP       1
#define NEBLINA_SPI_BOSCH_MOSI_PORT        0
#define NEBLINA_SPI_BOSCH_MOSI_PIN         12
#define NEBLINA_SPI_BOSCH_MOSI_PINOP       1
#define NEBLINA_SPI_BOSCH_SCK_PORT         0
#define NEBLINA_SPI_BOSCH_SCK_PIN          11
#define NEBLINA_SPI_BOSCH_SCK_PINOP        1
#define NEBLINA_SPI_BME280_CS_IDX          1
#define NEBLINA_SPI_BME280_CS_PORT         0
#define NEBLINA_SPI_BME280_CS_PIN          26
#define NEBLINA_SPI_BME280_CS_PINOP        1

static const IOPINCFG gsSpiBoschPin[] = {
    {NEBLINA_SPI_BOSCH_SCK_PORT, NEBLINA_SPI_BOSCH_SCK_PIN, NEBLINA_SPI_BOSCH_SCK_PINOP,
     IOPINDIR_OUTPUT, IOPINRES_NONE, IOPINTYPE_NORMAL},
    {NEBLINA_SPI_BOSCH_MISO_PORT, NEBLINA_SPI_BOSCH_MISO_PIN, NEBLINA_SPI_BOSCH_MISO_PINOP,
     IOPINDIR_INPUT, IOPINRES_NONE, IOPINTYPE_NORMAL},
    {NEBLINA_SPI_BOSCH_MOSI_PORT, NEBLINA_SPI_BOSCH_MOSI_PIN, NEBLINA_SPI_BOSCH_MOSI_PINOP,
     IOPINDIR_OUTPUT, IOPINRES_NONE, IOPINTYPE_NORMAL},
    {NEBLINA_SPI_BME280_CS_PORT, NEBLINA_SPI_BME280_CS_PIN, NEBLINA_SPI_BME280_CS_PINOP,
     IOPINDIR_OUTPUT, IOPINRES_PULLUP, IOPINTYPE_NORMAL},
};

static const SPICFG s_SpiCfg = {
    NEBLINA_SPI_BOSCH_DEVNO,
    SPIMODE_MASTER,
    gsSpiBoschPin,
    sizeof( gsSpiBoschPin ) / sizeof( IOPINCFG ),
    8000000,   // Speed in Hz
    8,      // Data Size
    5,      // Max retries
    SPIDATABIT_MSB,
    SPIDATAPHASE_SECOND_CLK, // Data phase
    SPICLKPOL_LOW,         // clock polarity
    SPICSEL_AUTO,
    6, //APP_IRQ_PRIORITY_LOW,      // Interrupt priority
    nullptr
};

SPI g_Spi;

// Configure I2C interface
static const I2CCFG s_I2cCfg = {
	0,			// I2C device number
	{

#ifdef PTH_BME280

		{BLUEIO_TAG_BME280_I2C_SDA_PORT, BLUEIO_TAG_BME280_I2C_SDA_PIN, BLUEIO_TAG_BME280_I2C_SDA_PINOP, IOPINDIR_BI, IOPINRES_NONE, IOPINTYPE_NORMAL},	// RX
		{BLUEIO_TAG_BME280_I2C_SCL_PORT, BLUEIO_TAG_BME280_I2C_SCL_PIN, BLUEIO_TAG_BME280_I2C_SCL_PINOP, IOPINDIR_OUTPUT, IOPINRES_NONE, IOPINTYPE_NORMAL},	// TX
#else
		{0, 4, 0, IOPINDIR_BI, IOPINRES_NONE, IOPINTYPE_NORMAL},	// RX
		{0, 3, 0, IOPINDIR_OUTPUT, IOPINRES_NONE, IOPINTYPE_NORMAL},	// TX
#endif
	},
	100000,	// Rate
	I2CMODE_MASTER,
	0,			// Slave address
	5,			// Retry
	7,			// Interrupt prio
	NULL		// Event callback
};

// I2C interface instance
I2C g_I2c;

#ifdef NEBLINA_MODULE
DeviceIntrf *g_pIntrf = &g_Spi;
#else
DeviceIntrf *g_pIntrf = &g_I2c;
#endif

// Configure environmental sensor
static PTHSENSOR_CFG s_PthSensorCfg = {
#ifdef NEBLINA_MODULE
    0,      // SPI CS index 0
#else
	BME280_I2C_DEV_ADDR0,   // I2C device address
#endif
	PTHSENSOR_OPMODE_SINGLE,
	0
};

// Environmental sensor instance
PthBme280 g_Bme280Sensor;
PthMS8607 g_MS8607Sensor;

#ifdef PTH_BME280
PTHSensor &g_PthSensor = g_Bme280Sensor;
#else
PTHSensor &g_PthSensor = g_MS8607Sensor;
#endif

void ReadPTHData()
{
    g_pIntrf->Enable();

	PTHSENSOR_DATA data;

	g_PthSensor.ReadPTH(data);

	// NOTE : M0 does not access unaligned data
	// use local 4 bytes align stack variable then mem copy
	memcpy(&g_PTHData, &data, sizeof(PTHSENSOR_DATA));

	// Update advertisement data
	BleAppAdvManDataSet(g_AdvDataBuff, sizeof(g_AdvDataBuff));

	g_pIntrf->Disable();
}

void TimerHandler(Timer *pTimer, uint32_t Evt)
{
    if (Evt & TIMER_EVT_TRIGGER(0))
    {
    	ReadPTHData();
    }
}

void BlePeriphEvtUserHandler(ble_evt_t * p_ble_evt)
{
#ifndef USE_TIMER_UPDATE
    if (p_ble_evt->header.evt_id == BLE_GAP_EVT_TIMEOUT)
    {
    	// Update environmental sensor data everytime advertisement timeout
    	// for re-advertisement
    	ReadPTHData();
    }
#endif
}

void HardwareInit()
{
	// Set this only if nRF is power at 2V or more
	nrf_power_dcdcen_set(true);

	// Initialize I2C
#ifdef NEBLINA_MODULE
    g_Spi.Init(s_SpiCfg);
#else
    g_I2c.Init(s_I2cCfg);
#endif

	// Inititalize sensor
    g_PthSensor.Init(s_PthSensorCfg, g_pIntrf);

    // Update sensor data
    PTHSENSOR_DATA pthdata;
	g_PthSensor.ReadPTH(pthdata);

	// Do memcpy to adv data. Due to byte alignment, cannot read directly into
	// adv data
	memcpy(g_AdvData.Data, &pthdata, sizeof(PTHSENSOR_DATA));

	g_pIntrf->Disable();

#ifdef USE_TIMER_UPDATE
    g_Timer.Init(s_TimerCfg);
	uint64_t period = g_Timer.EnableTimerTrigger(0, 500UL, TIMER_TRIG_TYPE_CONTINUOUS);
#endif
}

int main()
{
    HardwareInit();

    BleAppInit((const BLEAPP_CFG *)&s_BleAppCfg, true);

    BleAppRun();

	return 0;
}

<|endoftext|>


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

#include <liblocate/utils.h>

class utils_test : public testing::Test
{
public:
    utils_test()
    {
    }
};

TEST_F(utils_test, unifiedPath_NoPath)
{
    char * str1 = "A-string";

    unifiedPath(str1, strlen(str1));

    EXPECT_STREQ(str1, "A-string");
}

TEST_F(utils_test, unifiedPath_UnixPath)
{
    char * str1 = "/usr/include/c++/v1/tuple";

    unifiedPath(str1, strlen(str1));

    EXPECT_STREQ(str1, "/usr/include/c++/v1/tuple");
}

TEST_F(utils_test, unifiedPath_WindowsPath)
{
    char * str1 = "C:\\dev\\include\\c++\\v1\\tuple";

    unifiedPath(str1, strlen(str1));

    EXPECT_STREQ(str1, "C:/dev/include/c++/v1/tuple");
}
<commit_msg>First C tests<commit_after>
#include <gmock/gmock.h>

#include <liblocate/utils.h>

class utils_test : public testing::Test
{
public:
    utils_test()
    {
    }
};

TEST_F(utils_test, unifiedPath_NoPath)
{
    const char * source = "A-string";
    const char * expected = "A-string";

    const unsigned int length = strlen(source);
    char * actual = reinterpret_cast<char*>(malloc(sizeof(char) * length+1));
    memcpy(actual, source, length+1);

    unifiedPath(actual, length);

    EXPECT_STREQ(expected, actual);
}

TEST_F(utils_test, unifiedPath_UnixPath)
{
    const char * source = "/usr/include/c++/v1/tuple";
    const char * expected = "/usr/include/c++/v1/tuple";

    const unsigned int length = strlen(source);
    char * actual = reinterpret_cast<char*>(malloc(sizeof(char) * length+1));
    memcpy(actual, source, length+1);

    unifiedPath(actual, length);

    EXPECT_STREQ(expected, actual);
}

TEST_F(utils_test, unifiedPath_WindowsPath)
{
    const char * source = "C:\\dev\\include\\c++\\v1\\tuple";
    const char * expected = "C:/dev/include/c++/v1/tuple";

    const unsigned int length = strlen(source);
    char * actual = reinterpret_cast<char*>(malloc(sizeof(char) * length+1));
    memcpy(actual, source, length+1);

    unifiedPath(actual, length);

    EXPECT_STREQ(expected, actual);
}
<|endoftext|>


<commit_before>// Copyright (c) 2015
// Author: Chrono Law
#include <std.hpp>
#include <stack>
using namespace std;

//#define BOOST_THREAD_PROVIDES_VARIADIC_THREAD
//#define BOOST_THREAD_PROVIDES_FUTURE
#define BOOST_THREAD_VERSION 4
#include <boost/bind.hpp>
#include <boost/atomic.hpp>
#include <boost/thread.hpp>
#include <boost/thread/lock_factories.hpp>
using namespace boost;

//////////////////////////////////////////

#include <boost/chrono.hpp>
using namespace boost::chrono;
seconds operator"" _s(unsigned long long n)
{
    return seconds(n);
}

milliseconds operator"" _ms(unsigned long long n)
{
    return milliseconds(n);
}
//////////////////////////////////////////
class buffer
{
    private:
        mutex mu;
        condition_variable_any cond_put;
        condition_variable_any cond_get;

        stack<int> stk;
        int un_read,capacity;

        bool is_full()
        {   return un_read == capacity; }

        bool is_empty()
        {   return un_read == 0 ;   }
    public:
        buffer(size_t n):un_read(0),capacity(n){}

        void put(int x)
        {
            {
                auto lock = make_unique_lock(mu);
                cond_put.wait(lock,
                    [this]{return un_read < capacity;});
                //for(;is_full();)
                //{
                //    cout << "full waiting... "  << endl;
                //    cond_put.wait(lock);
                //}
                stk.push(x);
                ++un_read;
            }
            cond_get.notify_one();
        }

        void get(int *x)
        {
            {
                auto lock = make_unique_lock(mu);
                cond_get.wait(lock,
                    [this]{return un_read > 0;});
                //for(;is_empty();)
                //{
                //    cout << "empty waiting... " << endl;
                //    cond_get.wait(lock);
                //}
                --un_read;
                *x = stk.top();
                stk.pop();
            }
            cond_put.notify_one();
        }
};

buffer buf(5);

void producer(int n)
{
    for (int i = 0;i < n; ++i)
    {
        cout << "put " << i << endl;
        buf.put(i);
    }
}

void consumer( int n)
{
    int x;
    for (int i = 0;i < n; ++i)
    {
        buf.get(&x);
        cout << "get " << x << endl;
    }
}

void case1()
{
    thread_group tg;

    tg.create_thread(bind(producer, 20));
    tg.create_thread(bind(consumer, 10));
    tg.create_thread(bind(consumer, 10));

    tg.join_all();
}

//////////////////////////////////////////
//#include <future>
void dummy(int n)
{
    for(int i = 0;i < n; ++i);
    cout << n << endl;
}
void case2()
{
    //auto x = async(&dummy, 10);
    //x.wait();

    boost::async(bind(dummy, 10));

    auto f = boost::async([]{cout << "hello" << endl;});
    f.wait();

    async(launch::async, dummy, 100);
}

//////////////////////////////////////////
int fab(int n)
{
    if (n == 0 || n == 1)
    {   return 1;   }
    return fab(n-1) + fab(n-2);
}

void case3()
{
    auto f5 = async(fab, 5);
    auto f7 = async(launch::async, fab, 7);

    cout << f5.get() + f7.get() << endl;
    assert(!f5.valid() && !f7.valid());

    auto f10 = async(fab, 10);
    auto s = f10.wait_for(100_ms);

    if(f10.valid())
    {
        assert(s == future_status::ready);
        cout << f10.get() << endl;
    }

    vector<boost::future<int>> vec;
    for(int i = 0;i < 5; ++i)
    {
        vec.push_back(async(fab, i + 10));
    }

    wait_for_any(vec[3], vec[4], vec[2]);
    for(auto& x : vec)
    {
        if(x.valid())
        {   cout << x.get() << endl;        }
    }

    //wait_for_all(vec.begin(), vec.end());

    //for(auto& x : vec)
    //{
    //    cout << x.get() << ',';
    //}
    cout << endl;
}

//////////////////////////////////////////
void case4()
{
    //shared_future<int> f5 = async(fab, 5);
    auto f5 = async(fab, 5).share();
    //cout << f5.get() << endl;

    auto func = [](decltype(f5) f){
        cout << "[" << f.get() << "]";
        };

    async(func, f5);
    async(func, f5);

    this_thread::sleep_for(100_ms);

    assert(f5.valid());
}

//////////////////////////////////////////
void case5()
{
    auto func = [](int n, promise<int>& p){
        p.set_value(fab(n));
    };

    promise<int> p;

    thread(func, 10, boost::ref(p)).detach();

    auto f = p.get_future();
    cout << f.get() << endl;

}

//////////////////////////////////////////
void case6()
{
    atomic<int> x;
    barrier br(5);

    auto func = [&](){
        cout << "thread"<< ++x <<" arrived barrier." << endl;
        br.wait();
        cout << "thread run."  << endl;
    };

    thread_group tg;
    for (int i = 0;i < 5;++i)
    {
        tg.create_thread(func);
    }
    tg.join_all();
}

//////////////////////////////////////////

void case7()
{
    thread_specific_ptr<int> pi;

    auto func = [&]{
        pi.reset(new int());

        ++(*pi);
        cout << "thread v=" << *pi <<  endl;
    };
    async(func);
    async(func);

    this_thread::sleep_for(100_ms);
}

//////////////////////////////////////////

int main()
{
    cout << "thread v=" << BOOST_THREAD_VERSION << endl;
    //case1();
    case2();
    case3();
    case4();
    case5();
    case6();
    case7();
    //case8();
}

<commit_msg>fix boost::atomic<commit_after>// Copyright (c) 2015
// Author: Chrono Law
#include <std.hpp>
#include <stack>
using namespace std;

//#define BOOST_THREAD_PROVIDES_VARIADIC_THREAD
//#define BOOST_THREAD_PROVIDES_FUTURE
#define BOOST_THREAD_VERSION 4
#include <boost/bind.hpp>
#include <boost/atomic.hpp>
#include <boost/thread.hpp>
#include <boost/thread/lock_factories.hpp>
using namespace boost;

//////////////////////////////////////////

#include <boost/chrono.hpp>
using namespace boost::chrono;
seconds operator"" _s(unsigned long long n)
{
    return seconds(n);
}

milliseconds operator"" _ms(unsigned long long n)
{
    return milliseconds(n);
}
//////////////////////////////////////////
class buffer
{
    private:
        mutex mu;
        condition_variable_any cond_put;
        condition_variable_any cond_get;

        stack<int> stk;
        int un_read,capacity;

        bool is_full()
        {   return un_read == capacity; }

        bool is_empty()
        {   return un_read == 0 ;   }
    public:
        buffer(size_t n):un_read(0),capacity(n){}

        void put(int x)
        {
            {
                auto lock = make_unique_lock(mu);
                cond_put.wait(lock,
                    [this]{return un_read < capacity;});
                //for(;is_full();)
                //{
                //    cout << "full waiting... "  << endl;
                //    cond_put.wait(lock);
                //}
                stk.push(x);
                ++un_read;
            }
            cond_get.notify_one();
        }

        void get(int *x)
        {
            {
                auto lock = make_unique_lock(mu);
                cond_get.wait(lock,
                    [this]{return un_read > 0;});
                //for(;is_empty();)
                //{
                //    cout << "empty waiting... " << endl;
                //    cond_get.wait(lock);
                //}
                --un_read;
                *x = stk.top();
                stk.pop();
            }
            cond_put.notify_one();
        }
};

buffer buf(5);

void producer(int n)
{
    for (int i = 0;i < n; ++i)
    {
        cout << "put " << i << endl;
        buf.put(i);
    }
}

void consumer( int n)
{
    int x;
    for (int i = 0;i < n; ++i)
    {
        buf.get(&x);
        cout << "get " << x << endl;
    }
}

void case1()
{
    thread_group tg;

    tg.create_thread(bind(producer, 20));
    tg.create_thread(bind(consumer, 10));
    tg.create_thread(bind(consumer, 10));

    tg.join_all();
}

//////////////////////////////////////////
//#include <future>
void dummy(int n)
{
    for(int i = 0;i < n; ++i);
    cout << n << endl;
}
void case2()
{
    //auto x = async(&dummy, 10);
    //x.wait();

    boost::async(bind(dummy, 10));

    auto f = boost::async([]{cout << "hello" << endl;});
    f.wait();

    async(launch::async, dummy, 100);
}

//////////////////////////////////////////
int fab(int n)
{
    if (n == 0 || n == 1)
    {   return 1;   }
    return fab(n-1) + fab(n-2);
}

void case3()
{
    auto f5 = async(fab, 5);
    auto f7 = async(launch::async, fab, 7);

    cout << f5.get() + f7.get() << endl;
    assert(!f5.valid() && !f7.valid());

    auto f10 = async(fab, 10);
    auto s = f10.wait_for(100_ms);

    if(f10.valid())
    {
        assert(s == future_status::ready);
        cout << f10.get() << endl;
    }

    vector<boost::future<int>> vec;
    for(int i = 0;i < 5; ++i)
    {
        vec.push_back(async(fab, i + 10));
    }

    wait_for_any(vec[3], vec[4], vec[2]);
    for(auto& x : vec)
    {
        if(x.valid())
        {   cout << x.get() << endl;        }
    }

    //wait_for_all(vec.begin(), vec.end());

    //for(auto& x : vec)
    //{
    //    cout << x.get() << ',';
    //}
    cout << endl;
}

//////////////////////////////////////////
void case4()
{
    //shared_future<int> f5 = async(fab, 5);
    auto f5 = async(fab, 5).share();
    //cout << f5.get() << endl;

    auto func = [](decltype(f5) f){
        cout << "[" << f.get() << "]";
        };

    async(func, f5);
    async(func, f5);

    this_thread::sleep_for(100_ms);

    assert(f5.valid());
}

//////////////////////////////////////////
void case5()
{
    auto func = [](int n, promise<int>& p){
        p.set_value(fab(n));
    };

    promise<int> p;

    thread(func, 10, boost::ref(p)).detach();

    auto f = p.get_future();
    cout << f.get() << endl;

}

//////////////////////////////////////////
void case6()
{
    boost::atomic<int> x;
    barrier br(5);

    auto func = [&](){
        cout << "thread"<< ++x <<" arrived barrier." << endl;
        br.wait();
        cout << "thread run."  << endl;
    };

    thread_group tg;
    for (int i = 0;i < 5;++i)
    {
        tg.create_thread(func);
    }
    tg.join_all();
}

//////////////////////////////////////////

void case7()
{
    thread_specific_ptr<int> pi;

    auto func = [&]{
        pi.reset(new int());

        ++(*pi);
        cout << "thread v=" << *pi <<  endl;
    };
    async(func);
    async(func);

    this_thread::sleep_for(100_ms);
}

//////////////////////////////////////////

int main()
{
    cout << "thread v=" << BOOST_THREAD_VERSION << endl;
    //case1();
    case2();
    case3();
    case4();
    case5();
    case6();
    case7();
    //case8();
}

<|endoftext|>


<commit_before><commit_msg>VRC7 modulator disabled for testing -- doesn't sound right.  Will have to check O-scope to see where the wave is going wrong.<commit_after><|endoftext|>


<commit_before>// Copyright since 2016 : Evgenii Shatunov (github.com/FrankStain/jnipp-test)
// Apache 2.0 License
#include <main.h>
#include <gtest/gtest.h>

#define DECLARE_MEMBER_FIELD_TEST_ENV( TYPE, NAME )															\
	Jni::ClassHandle class_handle{ "com/pfs/jnipptest/TestFieldStorage" };									\
																											\
	Jni::FieldHandle<TYPE>	field{ class_handle, "m_" NAME "_field" };										\
	Jni::ObjectHandle		test_object{ Jni::ObjectHandle::NewObject( class_handle ) };					\
																											\
	EXPECT_TRUE( field );																					\
	EXPECT_TRUE( test_object )

#define DECLARE_STATIC_FIELD_TEST_ENV( TYPE, NAME )															\
	Jni::ClassHandle class_handle{ "com/pfs/jnipptest/TestStaticFieldStorage" };							\
																											\
	Jni::StaticFieldHandle<TYPE>	field{ class_handle, NAME "_field" };									\
																											\
	EXPECT_TRUE( field )

#define DECLARE_MEMBER_FUNCTION_TEST_ENV( NAME, RET, ... )													\
	Jni::ClassHandle derived_class{ "com/pfs/jnipptest/TestFunctionDerivedContainer" };						\
	Jni::ClassHandle basic_class{ derived_class.GetParentClassHandle() };									\
																											\
	Jni::FunctionHandle<RET, ##__VA_ARGS__>	func{ basic_class, NAME };										\
	Jni::FieldHandle<bool>					call_check{ basic_class, "m_is_called" };						\
	Jni::ObjectHandle						test_object{ Jni::ObjectHandle::NewObject( derived_class ) };	\
																											\
	EXPECT_TRUE( func );																					\
	EXPECT_TRUE( call_check );																				\
	EXPECT_TRUE( test_object )

#define EXAMINE_MEMBER_FUNCTION_CALL_FLAG( ... )															\
	{																										\
		bool is_called = false;																				\
		EXPECT_TRUE( call_check.GetValue( test_object, is_called ) );										\
		EXPECT_TRUE( is_called );																			\
	}

#define DECLARE_STATIC_FUNCTION_TEST_ENV( NAME, RET, ... )													\
	Jni::ClassHandle class_handle{ "com/pfs/jnipptest/TestStaticFunctionContainer" };						\
																											\
	Jni::StaticFunctionHandle<RET, ##__VA_ARGS__>	func{ class_handle, NAME };								\
	Jni::StaticFieldHandle<bool>					call_check{ class_handle, "is_called" };				\
																											\
	EXPECT_TRUE( func );																					\
	EXPECT_TRUE( call_check );																				\
	EXPECT_TRUE( call_check.SetValue( false ) )

#define EXAMINE_STATIC_FUNCTION_CALL_FLAG( ... )															\
	{																										\
		bool is_called = false;																				\
		EXPECT_TRUE( call_check.GetValue( is_called ) );													\
		EXPECT_TRUE( is_called );																			\
	}

TEST( TestEnvironment, Allocation )
{
	Jni::JniEnv	local_env;

	EXPECT_TRUE( local_env.IsValid() );
	EXPECT_TRUE( local_env );
};

TEST( TestEnvironment, MemberFieldGetValue )
{
	DECLARE_MEMBER_FIELD_TEST_ENV( bool, "bool" );

	Jni::JniEnv local_env;
	bool field_value;
	EXPECT_TRUE( local_env.GetValue( field, test_object, field_value ) );

	EXPECT_TRUE( field_value );
};

TEST( TestEnvironment, StaticFieldGetValue )
{
	DECLARE_STATIC_FIELD_TEST_ENV( bool, "bool" );

	Jni::JniEnv local_env;
	bool field_value;
	EXPECT_TRUE( local_env.GetValue( field, field_value ) );

	EXPECT_TRUE( field_value );
};

TEST( TestEnvironment, MemberFieldSetValue )
{
	DECLARE_MEMBER_FIELD_TEST_ENV( std::string, "string" );

	Jni::JniEnv local_env;
	const char* field_value = "Hello Jni++";
	EXPECT_TRUE( local_env.SetValue( field, test_object, { field_value } ) );

	std::string field_check;
	EXPECT_TRUE( local_env.GetValue( field, test_object, field_check ) );

	EXPECT_STREQ( field_value, field_check.c_str() );
};

TEST( TestEnvironment, StaticFieldSetValue )
{
	DECLARE_STATIC_FIELD_TEST_ENV( std::string, "string" );

	Jni::JniEnv local_env;
	const char* field_value = "Hello Jni++";
	EXPECT_TRUE( local_env.SetValue( field, { field_value } ) );

	std::string field_check;
	EXPECT_TRUE( local_env.GetValue( field, field_check ) );

	EXPECT_STREQ( field_value, field_check.c_str() );
};

TEST( TestEnvironment, CallMemberFunction )
{
	DECLARE_MEMBER_FUNCTION_TEST_ENV( "StringTwoArguments", std::string, std::string, std::string );

	Jni::JniEnv local_env;

	auto ret = local_env.Call( func, test_object, { "1" }, { "2" } );
	EXAMINE_MEMBER_FUNCTION_CALL_FLAG();

	EXPECT_STREQ( "1 2", ret.c_str() );
};

TEST( TestEnvironment, CallStaticFunction )
{
	DECLARE_STATIC_FUNCTION_TEST_ENV( "StringTwoArguments", std::string, std::string, std::string );

	Jni::JniEnv local_env;

	auto ret = local_env.Call( func, { "1" }, { "2" } );
	EXAMINE_STATIC_FUNCTION_CALL_FLAG();

	EXPECT_STREQ( "1 2", ret.c_str() );
};
<commit_msg>Full tests for Jni++ Environment.<commit_after>// Copyright since 2016 : Evgenii Shatunov (github.com/FrankStain/jnipp-test)
// Apache 2.0 License
#include <main.h>
#include <gtest/gtest.h>

#define DECLARE_MEMBER_FIELD_TEST_ENV( TYPE, NAME )															\
	Jni::ClassHandle class_handle{ "com/pfs/jnipptest/TestFieldStorage" };									\
																											\
	Jni::FieldHandle<TYPE>	field{ class_handle, "m_" NAME "_field" };										\
	Jni::ObjectHandle		test_object{ Jni::ObjectHandle::NewObject( class_handle ) };					\
																											\
	EXPECT_TRUE( field );																					\
	EXPECT_TRUE( test_object )

#define DECLARE_STATIC_FIELD_TEST_ENV( TYPE, NAME )															\
	Jni::ClassHandle class_handle{ "com/pfs/jnipptest/TestStaticFieldStorage" };							\
																											\
	Jni::StaticFieldHandle<TYPE>	field{ class_handle, NAME "_field" };									\
	EXPECT_TRUE( field );																					\
																											\
	Jni::StaticFunctionHandle<void> reset_func{ class_handle, "Reset" };									\
	reset_func.Call()

#define DECLARE_MEMBER_FUNCTION_TEST_ENV( NAME, RET, ... )													\
	Jni::ClassHandle basic_class{ "com/pfs/jnipptest/TestFunctionContainer" };								\
																											\
	Jni::FunctionHandle<RET, ##__VA_ARGS__>	func{ basic_class, NAME };										\
	Jni::FieldHandle<bool>					call_check{ basic_class, "m_is_called" };						\
	Jni::ObjectHandle						test_object{ Jni::ObjectHandle::NewObject( basic_class ) };		\
																											\
	EXPECT_TRUE( func );																					\
	EXPECT_TRUE( call_check );																				\
	EXPECT_TRUE( test_object )

#define DECLARE_MEMBER_NONVIRTUAL_FUNCTION_TEST_ENV( NAME, RET, ... )										\
	Jni::ClassHandle derived_class{ "com/pfs/jnipptest/TestFunctionDerivedContainer" };						\
	Jni::ClassHandle basic_class{ derived_class.GetParentClassHandle() };									\
																											\
	Jni::FunctionHandle<RET, ##__VA_ARGS__>	func{ basic_class, NAME };										\
	Jni::FieldHandle<bool>					call_check{ basic_class, "m_is_called" };						\
	Jni::ObjectHandle						test_object{ Jni::ObjectHandle::NewObject( derived_class ) };	\
																											\
	EXPECT_TRUE( func );																					\
	EXPECT_TRUE( call_check );																				\
	EXPECT_TRUE( test_object )

#define EXAMINE_MEMBER_FUNCTION_CALL_FLAG( ... )															\
	{																										\
		bool is_called = false;																				\
		EXPECT_TRUE( call_check.GetValue( test_object, is_called ) );										\
		EXPECT_TRUE( is_called );																			\
	}

#define DECLARE_STATIC_FUNCTION_TEST_ENV( NAME, RET, ... )													\
	Jni::ClassHandle class_handle{ "com/pfs/jnipptest/TestStaticFunctionContainer" };						\
																											\
	Jni::StaticFunctionHandle<RET, ##__VA_ARGS__>	func{ class_handle, NAME };								\
	Jni::StaticFieldHandle<bool>					call_check{ class_handle, "is_called" };				\
																											\
	EXPECT_TRUE( func );																					\
	EXPECT_TRUE( call_check );																				\
	EXPECT_TRUE( call_check.SetValue( false ) )

#define EXAMINE_STATIC_FUNCTION_CALL_FLAG( ... )															\
	{																										\
		bool is_called = false;																				\
		EXPECT_TRUE( call_check.GetValue( is_called ) );													\
		EXPECT_TRUE( is_called );																			\
	}

TEST( TestEnvironment, Allocation )
{
	Jni::JniEnv	local_env;

	EXPECT_TRUE( local_env.IsValid() );
	EXPECT_TRUE( local_env );
};

TEST( TestEnvironment, MemberFieldGetValue )
{
	DECLARE_MEMBER_FIELD_TEST_ENV( bool, "bool" );

	Jni::JniEnv local_env;
	bool field_value;
	EXPECT_TRUE( local_env.GetValue( field, test_object, field_value ) );

	EXPECT_TRUE( field_value );
};

TEST( TestEnvironment, StaticFieldGetValue )
{
	DECLARE_STATIC_FIELD_TEST_ENV( bool, "bool" );

	Jni::JniEnv local_env;
	bool field_value;
	EXPECT_TRUE( local_env.GetValue( field, field_value ) );

	EXPECT_TRUE( field_value );
};

TEST( TestEnvironment, MemberFieldSetValue )
{
	DECLARE_MEMBER_FIELD_TEST_ENV( std::string, "string" );

	Jni::JniEnv local_env;
	const char* field_value = "Hello Jni++";
	EXPECT_TRUE( local_env.SetValue( field, test_object, field_value ) );

	std::string field_check;
	EXPECT_TRUE( local_env.GetValue( field, test_object, field_check ) );

	EXPECT_STREQ( field_value, field_check.c_str() );
};

TEST( TestEnvironment, StaticFieldSetValue )
{
	DECLARE_STATIC_FIELD_TEST_ENV( std::string, "string" );

	Jni::JniEnv local_env;
	const char* field_value = "Hello Jni++";
	EXPECT_TRUE( local_env.SetValue( field, field_value ) );

	std::string field_check;
	EXPECT_TRUE( local_env.GetValue( field, field_check ) );

	EXPECT_STREQ( field_value, field_check.c_str() );
};

TEST( TestEnvironment, CallMemberFunction )
{
	DECLARE_MEMBER_FUNCTION_TEST_ENV( "StringTwoArguments", std::string, std::string, std::string );

	Jni::JniEnv local_env;

	auto ret = local_env.Call( func, test_object, "1", "2" );
	EXAMINE_MEMBER_FUNCTION_CALL_FLAG();

	EXPECT_STREQ( "1 2", ret.c_str() );
};

TEST( TestEnvironment, CallStaticFunction )
{
	DECLARE_STATIC_FUNCTION_TEST_ENV( "StringTwoArguments", std::string, std::string, std::string );

	Jni::JniEnv local_env;

	auto ret = local_env.Call( func, "1", "2" );
	EXAMINE_STATIC_FUNCTION_CALL_FLAG();

	EXPECT_STREQ( "1 2", ret.c_str() );
};
<|endoftext|>


<commit_before>/* This software is distributed under BSD 3-clause license (see LICENSE file).
 *
 * Copyright (c) 2012-2013 Sergey Lisitsyn
 */

#ifndef TAPKEE_MDS_H_
#define TAPKEE_MDS_H_

/* Tapkee includes */
#include <shogun/lib/tapkee/tapkee_defines.hpp>
#include <shogun/lib/tapkee/utils/time.hpp>
/* End of Tapkee includes */

#include <algorithm>

using std::random_shuffle;
using std::fill;

namespace tapkee
{
namespace tapkee_internal
{

template <class RandomAccessIterator>
Landmarks select_landmarks_random(RandomAccessIterator begin, RandomAccessIterator end, ScalarType ratio)
{
	Landmarks landmarks;
	landmarks.reserve(end-begin);
	for (RandomAccessIterator iter=begin; iter!=end; ++iter)
		landmarks.push_back(iter-begin);
	random_shuffle(landmarks.begin(),landmarks.end());
	landmarks.erase(landmarks.begin() + static_cast<IndexType>(landmarks.size()*ratio),landmarks.end());
	return landmarks;
}

template <class RandomAccessIterator, class PairwiseCallback>
DenseSymmetricMatrix compute_distance_matrix(RandomAccessIterator begin, RandomAccessIterator /*end*/,
                                             const Landmarks& landmarks, PairwiseCallback callback)
{
	timed_context context("Multidimensional scaling distance matrix computation");

	const IndexType n_landmarks = landmarks.size();
	DenseSymmetricMatrix distance_matrix(n_landmarks,n_landmarks);

#pragma omp parallel shared(begin,landmarks,distance_matrix,callback) default(none)
	{
		IndexType i_index_iter,j_index_iter;
#pragma omp for nowait
		for (i_index_iter=0; i_index_iter<n_landmarks; ++i_index_iter)
		{
			for (j_index_iter=i_index_iter; j_index_iter<n_landmarks; ++j_index_iter)
			{
				ScalarType d = callback(begin[landmarks[i_index_iter]],begin[landmarks[j_index_iter]]);
				d *= d;
				distance_matrix(i_index_iter,j_index_iter) = d;
				distance_matrix(j_index_iter,i_index_iter) = d;
			}
		}
	}
	return distance_matrix;
};

template <class RandomAccessIterator, class PairwiseCallback>
EmbeddingResult triangulate(RandomAccessIterator begin, RandomAccessIterator end, PairwiseCallback distance_callback,
                            const Landmarks& landmarks, const DenseVector& landmark_distances_squared,
                            EmbeddingResult& landmarks_embedding, IndexType target_dimension)
{
	timed_context context("Landmark triangulation");

	bool* to_process = new bool[end-begin];
	fill(to_process,to_process+(end-begin),true);

	DenseMatrix embedding((end-begin),target_dimension);

	for (Landmarks::const_iterator iter=landmarks.begin();
			iter!=landmarks.end(); ++iter)
	{
		to_process[*iter] = false;
		embedding.row(*iter).noalias() = landmarks_embedding.first.row(iter-landmarks.begin());
	}

	for (IndexType i=0; i<target_dimension; ++i)
		landmarks_embedding.first.col(i).array() /= landmarks_embedding.second(i);

#pragma omp parallel shared(begin,end,to_process,distance_callback,landmarks, \
		landmarks_embedding,landmark_distances_squared,embedding) default(none)
	{
		DenseVector distances_to_landmarks = DenseVector(landmarks.size());
		IndexType index_iter;
#pragma omp for nowait
		for (index_iter=0; index_iter<IndexType(end-begin); ++index_iter)
		{
			if (!to_process[index_iter])
				continue;

			for (IndexType i=0; i<distances_to_landmarks.size(); ++i)
			{
				ScalarType d = distance_callback(begin[index_iter],begin[landmarks[i]]);
				distances_to_landmarks(i) = d*d;
			}
			//distances_to_landmarks.array().square();

			distances_to_landmarks -= landmark_distances_squared;
			embedding.row(index_iter).noalias() = -0.5*landmarks_embedding.first.transpose()*distances_to_landmarks;
		}
	}

	delete[] to_process;

	return EmbeddingResult(embedding,DenseVector());
}

template <class RandomAccessIterator, class PairwiseCallback>
DenseSymmetricMatrix compute_distance_matrix(RandomAccessIterator begin, RandomAccessIterator end,
                                             PairwiseCallback callback)
{
	timed_context context("Multidimensional scaling distance matrix computation");

	const IndexType n_vectors = end-begin;
	DenseSymmetricMatrix distance_matrix(n_vectors,n_vectors);

#pragma omp parallel shared(begin,distance_matrix,callback) default(none)
	{
		IndexType i_index_iter,j_index_iter;
#pragma omp for nowait
		for (i_index_iter=0; i_index_iter<n_vectors; ++i_index_iter)
		{
			for (j_index_iter=i_index_iter; j_index_iter<n_vectors; ++j_index_iter)
			{
				ScalarType d = callback(begin[i_index_iter],begin[j_index_iter]);
				d *= d;
				distance_matrix(i_index_iter,j_index_iter) = d;
				distance_matrix(j_index_iter,i_index_iter) = d;
			}
		}
	}
	return distance_matrix;
};

}
}

#endif
<commit_msg>Hopefully last update of tapkee before release<commit_after>/* This software is distributed under BSD 3-clause license (see LICENSE file).
 *
 * Copyright (c) 2012-2013 Sergey Lisitsyn
 */

#ifndef TAPKEE_MDS_H_
#define TAPKEE_MDS_H_

/* Tapkee includes */
#include <shogun/lib/tapkee/tapkee_defines.hpp>
#include <shogun/lib/tapkee/utils/time.hpp>
/* End of Tapkee includes */

#include <algorithm>

using std::random_shuffle;
using std::fill;

namespace tapkee
{
namespace tapkee_internal
{

template <class RandomAccessIterator>
Landmarks select_landmarks_random(RandomAccessIterator begin, RandomAccessIterator end, ScalarType ratio)
{
	Landmarks landmarks;
	landmarks.reserve(end-begin);
	for (RandomAccessIterator iter=begin; iter!=end; ++iter)
		landmarks.push_back(iter-begin);
	random_shuffle(landmarks.begin(),landmarks.end());
	landmarks.erase(landmarks.begin() + static_cast<IndexType>(landmarks.size()*ratio),landmarks.end());
	return landmarks;
}

template <class RandomAccessIterator, class PairwiseCallback>
DenseSymmetricMatrix compute_distance_matrix(RandomAccessIterator begin, RandomAccessIterator /*end*/,
                                             const Landmarks& landmarks, PairwiseCallback callback)
{
	timed_context context("Multidimensional scaling distance matrix computation");

	const IndexType n_landmarks = landmarks.size();
	DenseSymmetricMatrix distance_matrix(n_landmarks,n_landmarks);

#pragma omp parallel shared(begin,landmarks,distance_matrix,callback) default(none)
	{
		IndexType i_index_iter,j_index_iter;
#pragma omp for nowait
		for (i_index_iter=0; i_index_iter<n_landmarks; ++i_index_iter)
		{
			for (j_index_iter=i_index_iter; j_index_iter<n_landmarks; ++j_index_iter)
			{
				ScalarType d = callback(begin[landmarks[i_index_iter]],begin[landmarks[j_index_iter]]);
				d *= d;
				distance_matrix(i_index_iter,j_index_iter) = d;
				distance_matrix(j_index_iter,i_index_iter) = d;
			}
		}
	}
	return distance_matrix;
};

template <class RandomAccessIterator, class PairwiseCallback>
EmbeddingResult triangulate(RandomAccessIterator begin, RandomAccessIterator end, PairwiseCallback distance_callback,
                            const Landmarks& landmarks, const DenseVector& landmark_distances_squared,
                            EmbeddingResult& landmarks_embedding, IndexType target_dimension)
{
	timed_context context("Landmark triangulation");

	const IndexType n_vectors = end-begin;
	const IndexType n_landmarks = landmarks.size();

	bool* to_process = new bool[n_vectors];
	fill(to_process,to_process+n_vectors,true);

	DenseMatrix embedding(n_vectors,target_dimension);

	for (IndexType index_iter=0; index_iter<n_landmarks; ++index_iter)
	{
		to_process[landmarks[index_iter]] = false;
		embedding.row(landmarks[index_iter]).noalias() = landmarks_embedding.first.row(index_iter);
	}

	for (IndexType i=0; i<target_dimension; ++i)
		landmarks_embedding.first.col(i).array() /= landmarks_embedding.second(i);

#pragma omp parallel shared(begin,end,to_process,distance_callback,landmarks, \
		landmarks_embedding,landmark_distances_squared,embedding) default(none)
	{
		DenseVector distances_to_landmarks(n_landmarks);
		IndexType index_iter;
#pragma omp for nowait
		for (index_iter=0; index_iter<n_vectors; ++index_iter)
		{
			if (!to_process[index_iter])
				continue;

			for (IndexType i=0; i<n_landmarks; ++i)
			{
				ScalarType d = distance_callback(begin[index_iter],begin[landmarks[i]]);
				distances_to_landmarks(i) = d*d;
			}
			//distances_to_landmarks.array().square();

			distances_to_landmarks -= landmark_distances_squared;
			embedding.row(index_iter).noalias() = -0.5*landmarks_embedding.first.transpose()*distances_to_landmarks;
		}
	}

	delete[] to_process;

	return EmbeddingResult(embedding,DenseVector());
}

template <class RandomAccessIterator, class PairwiseCallback>
DenseSymmetricMatrix compute_distance_matrix(RandomAccessIterator begin, RandomAccessIterator end,
                                             PairwiseCallback callback)
{
	timed_context context("Multidimensional scaling distance matrix computation");

	const IndexType n_vectors = end-begin;
	DenseSymmetricMatrix distance_matrix(n_vectors,n_vectors);

#pragma omp parallel shared(begin,distance_matrix,callback) default(none)
	{
		IndexType i_index_iter,j_index_iter;
#pragma omp for nowait
		for (i_index_iter=0; i_index_iter<n_vectors; ++i_index_iter)
		{
			for (j_index_iter=i_index_iter; j_index_iter<n_vectors; ++j_index_iter)
			{
				ScalarType d = callback(begin[i_index_iter],begin[j_index_iter]);
				d *= d;
				distance_matrix(i_index_iter,j_index_iter) = d;
				distance_matrix(j_index_iter,i_index_iter) = d;
			}
		}
	}
	return distance_matrix;
};

}
}

#endif
<|endoftext|>


<commit_before>//  Copyright 2016 Peter Georg
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.

#include "memoryregion.hpp"
#include <stdexcept>

#ifdef VERBS_ODP
#include "odp.hpp"
#endif // VERBS_ODP

pMR::verbs::MemoryRegion::MemoryRegion(Context &context,
    ProtectionDomain &protectionDomain, void *buffer, std::uint32_t size,
    int access)
{
#ifdef VERBS_ODP
    access = updateMemoryRegionAccessODP(context, access);
#endif // VERBS_ODP

    if(size > context.getMaxMemoryRegionSize() ||
        size > context.getMaxMessageSize())
    {
        throw std::length_error("pMR: Message size overflow.");
    }

    registerMemoryRegion(protectionDomain, buffer, size, access);
}

pMR::verbs::MemoryRegion::~MemoryRegion()
{
    if(getLength() > 0)
    {
        ibv_dereg_mr(mMemoryRegion);
    }
    else
    {
        delete mMemoryRegion;
    }
}

ibv_mr *pMR::verbs::MemoryRegion::get()
{
    return mMemoryRegion;
}

ibv_mr const *pMR::verbs::MemoryRegion::get() const
{
    return mMemoryRegion;
}

std::uint64_t pMR::verbs::MemoryRegion::getAddress() const
{
    return {reinterpret_cast<std::uintptr_t>(mMemoryRegion->addr)};
}

std::uint32_t pMR::verbs::MemoryRegion::getLKey() const
{
    return {mMemoryRegion->lkey};
}

std::uint32_t pMR::verbs::MemoryRegion::getRKey() const
{
    return {mMemoryRegion->rkey};
}

std::uint32_t pMR::verbs::MemoryRegion::getLength() const
{
    return {static_cast<std::uint32_t>(mMemoryRegion->length)};
}

void pMR::verbs::MemoryRegion::registerMemoryRegion(
    ProtectionDomain &protectionDomain, void *buffer, std::uint32_t const size,
    int const access)
{
    if(size > 0)
    {
        mMemoryRegion =
            ibv_reg_mr(protectionDomain.get(), buffer, {size}, {access});

        if(!mMemoryRegion)
        {
            throw std::runtime_error("pMR: Could not register Memory Region.");
        }
    }
    else
    {
        mMemoryRegion = new ibv_mr;
        mMemoryRegion->addr = buffer;
        mMemoryRegion->lkey = 0;
        mMemoryRegion->rkey = 0;
        mMemoryRegion->length = 0;
    }
}
<commit_msg>Better handle zero-sized memory regions<commit_after>//  Copyright 2016 Peter Georg
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.

#include "memoryregion.hpp"
#include <stdexcept>

#ifdef VERBS_ODP
#include "odp.hpp"
#endif // VERBS_ODP

pMR::verbs::MemoryRegion::MemoryRegion(Context &context,
    ProtectionDomain &protectionDomain, void *buffer, std::uint32_t size,
    int access)
{
#ifdef VERBS_ODP
    access = updateMemoryRegionAccessODP(context, access);
#endif // VERBS_ODP

    if(size > context.getMaxMemoryRegionSize() ||
        size > context.getMaxMessageSize())
    {
        throw std::length_error("pMR: Message size overflow.");
    }

    registerMemoryRegion(protectionDomain, buffer, size, access);
}

pMR::verbs::MemoryRegion::~MemoryRegion()
{
    ibv_dereg_mr(mMemoryRegion);
}

ibv_mr *pMR::verbs::MemoryRegion::get()
{
    return mMemoryRegion;
}

ibv_mr const *pMR::verbs::MemoryRegion::get() const
{
    return mMemoryRegion;
}

std::uint64_t pMR::verbs::MemoryRegion::getAddress() const
{
    return {reinterpret_cast<std::uintptr_t>(mMemoryRegion->addr)};
}

std::uint32_t pMR::verbs::MemoryRegion::getLKey() const
{
    return {mMemoryRegion->lkey};
}

std::uint32_t pMR::verbs::MemoryRegion::getRKey() const
{
    return {mMemoryRegion->rkey};
}

std::uint32_t pMR::verbs::MemoryRegion::getLength() const
{
    return {static_cast<std::uint32_t>(mMemoryRegion->length)};
}

void pMR::verbs::MemoryRegion::registerMemoryRegion(
    ProtectionDomain &protectionDomain, void *buffer, std::uint32_t const size,
    int const access)
{
    if(size == 0 && buffer == nullptr)
    {
        buffer = &mMemoryRegion;
    }
    mMemoryRegion =
        ibv_reg_mr(protectionDomain.get(), buffer, {size}, {access});

    if(!mMemoryRegion)
    {
        throw std::runtime_error("pMR: Could not register Memory Region.");
    }
}
<|endoftext|>