<commit_before>#ifndef stack_cpp
#define stack_cpp
#pragma once
#include <iostream>
#include <memory>

class bitset
{
public:
	explicit
		bitset(size_t size) /*strong*/;

	bitset(bitset const & other) = delete;
	auto operator =(bitset const & other)->bitset & = delete;

	bitset(bitset && other) = delete;
	auto operator =(bitset && other)->bitset & = delete;

	auto set(size_t index) /*strong*/ -> void;
	auto reset(size_t index) /*strong*/ -> void;
	auto test(size_t index) /*strong*/ -> bool;

	auto size() /*noexcept*/ -> size_t;
	auto counter() /*noexcept*/ -> size_t;

private:
	std::unique_ptr<bool[]>  ptr_;
	size_t size_;
	size_t counter_;
};

bitset::bitset(size_t size) : ptr_(std::make_unique<bool[]>(size)), size_(size), counter_(0) {}

auto bitset::set(size_t index) -> void
{ if (index >= 0 && index < size_) {
	ptr_[index] = true;
	++counter_; }
	else throw;
}

auto bitset::reset(size_t index) -> void
{	if (index >= 0 && index < size_)
	{
		ptr_[index] = false;
		--counter_;
	}
else throw;
}

auto bitset::test(size_t index) -> bool
{
	if (index >= 0 && index < size_)
	{
		return !ptr_[index];
	}
	else throw;

}
auto bitset::size() -> size_t
{
	return size_;
}

auto bitset::counter() -> size_t
{
	return counter_;
}

template <typename T>
class allocator
{
public:
	explicit
		allocator(std::size_t size = 0) /*strong*/;
	allocator(allocator const & other) /*strong*/;
	auto operator =(allocator const & other)->allocator & = delete;
	~allocator();

	auto resize() /*strong*/ -> void;

	auto construct(T * ptr, T const & value) /*strong*/ -> void;
	auto destroy(T * ptr) /*noexcept*/ -> void;

	auto get() /*noexcept*/ -> T *;
	auto get() const /*noexcept*/ -> T const *;

	auto count() const /*noexcept*/ -> size_t;
	auto full() const /*noexcept*/ -> bool;
	auto empty() const /*noexcept*/ -> bool;
private:
	auto destroy(T * first, T * last) /*noexcept*/ -> void;
	auto swap(allocator & other) /*noexcept*/ -> void;

	T * ptr_;
	size_t size_;
	std::unique_ptr<bitset> map_;
};

template <typename T>
class stack
{
public:
	explicit
		stack(size_t size = 0);
	auto operator =(stack const & other) /*strong*/ -> stack &;

	auto empty() const /*noexcept*/ -> bool;
	auto count() const /*noexcept*/ -> size_t;

	auto push(T const & value) /*strong*/ -> void;
	auto pop() /*strong*/ -> void;
	auto top() /*strong*/ -> T &;
	auto top() const /*strong*/ -> T const &;

private:
	allocator<T> allocator_;

	auto throw_is_empty() const -> void;
};

template <typename T>
allocator<T>::allocator(size_t size) : ptr_((T*)(operator new(size*sizeof(T)))), size_(size), map_(std::make_unique<bitset>(size)) {};

template<typename T>
	allocator<T>::allocator(allocator const& other) :
ptr_(static_cast<T*>(operator new(other.size_))),
size_(other.size_), map_(std::make_unique<bitset>(size_)){
	for (size_t i; i < size_; i++)
		construct(ptr_ + i, other.ptr_[i]);
}
template<typename T>
allocator<T>::~allocator() { operator delete(ptr_); }

template<typename T>
auto allocator<T>::resize() -> void
{
	allocator<T> buff(size_ * 2 + (size_ == 0));
	for (size_t i = 0; i < size_; i++) construct(buff.ptr_ + i, ptr_[i]);
	this->swap(buff);
}

template<typename T>
auto allocator<T>::construct(T * ptr, T const & value)->void {
	if (ptr >= ptr_&&ptr < ptr_ + size_&&map_->test(ptr - ptr_)) {
		new(ptr)T(value);
		map_->set(ptr - ptr_);
	}
	else throw("error");
}

template<typename T>
auto allocator<T>::destroy(T * ptr) -> void {
	ptr->~T();
	map_->reset(ptr-ptr_);
}

template<typename T>
auto allocator<T>::destroy(T * first, T * last) -> void
{
	for (; first != last; ++first) {
		destroy(&*first);
	}
}

template<typename T>
auto allocator<T>::get()-> T* {
	return ptr_;
}

template<typename T>
auto allocator<T>::get() const -> T const * {
	return ptr_;
}

template<typename T>
auto allocator<T>::count() const -> size_t
{
	return map_->counter();
}

template<typename T>
auto allocator<T>::full() const -> bool
{
	return map_->counter()==size_;
}

template<typename T>
auto allocator<T>::empty() const -> bool
{
	return map_->counter()==0;
}

template<typename T>
auto allocator<T>::swap(allocator & other) -> void {
	std::swap(ptr_, other.ptr_);
	std::swap(map_, other.map_);
	std::swap(size_, other.size_);
}

template <typename T>
size_t stack<T>::count() const
{
	return allocator_.count_;
}
template <typename T>
stack<T>::stack(size_t size) :allocator<T>(size) {}

template <typename T>
void stack<T>::push(T const &item) {
	if (allocator_.full()) allocator_.resize();
	allocator_.construct(allocator_.get() + this->count(), value);
template<typename T>

void stack<T>::pop()
{
	if (this->count() > 0)
		allocator_.destroy(allocator_.get() + this->count());
	else throw_is_empty();
}
template<typename T>
auto stack<T>::top() -> T &
{
	if (allocator<T>::count_ == 0) {
		throw_is_empty();
	}
	return allocator<T>::ptr_[allocator<T>::count_ - 1];
}

template<typename T>
auto stack<T>::top() const -> T const &
{
	if (allocator<T>::count_ == 0) {
		throw_is_empty();
	}
	return allocator<T>::ptr_[allocator<T>::count_ - 1];
}

template<typename T>
auto stack<T>::throw_is_empty() const -> void
{
		throw("Stack is empty!");
}

template<typename T>
auto stack<T>::operator=(stack const & right) -> stack & {
	if (this != &right) {
		stack<T> temp(right.size_);
		while (temp.count_ < right.count_) {
			construct(temp.ptr_ + temp.count_, right.ptr_[temp.count_]);
			++temp.count_;
		}
		this->swap(temp);
	}
	return *this;
}

template<typename T>
auto stack<T>::empty() const -> bool {
	return allocator_.empty;

#endif
<commit_msg>Update stack.hpp<commit_after>#ifndef stack_cpp
#define stack_cpp
#pragma once
#include <iostream>
#include <memory>

class bitset
{
public:
	explicit
		bitset(size_t size) /*strong*/;

	bitset(bitset const & other) = delete;
	auto operator =(bitset const & other)->bitset & = delete;

	bitset(bitset && other) = delete;
	auto operator =(bitset && other)->bitset & = delete;

	auto set(size_t index) /*strong*/ -> void;
	auto reset(size_t index) /*strong*/ -> void;
	auto test(size_t index) /*strong*/ -> bool;

	auto size() /*noexcept*/ -> size_t;
	auto counter() /*noexcept*/ -> size_t;

private:
	std::unique_ptr<bool[]>  ptr_;
	size_t size_;
	size_t counter_;
};

bitset::bitset(size_t size) : ptr_(std::make_unique<bool[]>(size)), size_(size), counter_(0) {}

auto bitset::set(size_t index) -> void
{ if (index >= 0 && index < size_) {
	ptr_[index] = true;
	++counter_; }
	else throw;
}

auto bitset::reset(size_t index) -> void
{	if (index >= 0 && index < size_)
	{
		ptr_[index] = false;
		--counter_;
	}
else throw;
}

auto bitset::test(size_t index) -> bool
{
	if (index >= 0 && index < size_)
	{
		return !ptr_[index];
	}
	else throw;

}
auto bitset::size() -> size_t
{
	return size_;
}

auto bitset::counter() -> size_t
{
	return counter_;
}

template <typename T>
class allocator
{
public:
	explicit
		allocator(std::size_t size = 0) /*strong*/;
	allocator(allocator const & other) /*strong*/;
	auto operator =(allocator const & other)->allocator & = delete;
	~allocator();

	auto resize() /*strong*/ -> void;

	auto construct(T * ptr, T const & value) /*strong*/ -> void;
	auto destroy(T * ptr) /*noexcept*/ -> void;

	auto get() /*noexcept*/ -> T *;
	auto get() const /*noexcept*/ -> T const *;

	auto count() const /*noexcept*/ -> size_t;
	auto full() const /*noexcept*/ -> bool;
	auto empty() const /*noexcept*/ -> bool;
private:
	auto destroy(T * first, T * last) /*noexcept*/ -> void;
	auto swap(allocator & other) /*noexcept*/ -> void;

	T * ptr_;
	size_t size_;
	std::unique_ptr<bitset> map_;
};

template <typename T>
class stack
{
public:
	explicit
		stack(size_t size = 0);
	auto operator =(stack const & other) /*strong*/ -> stack &;

	auto empty() const /*noexcept*/ -> bool;
	auto count() const /*noexcept*/ -> size_t;

	auto push(T const & value) /*strong*/ -> void;
	auto pop() /*strong*/ -> void;
	auto top() /*strong*/ -> T &;
	auto top() const /*strong*/ -> T const &;

private:
	allocator<T> allocator_;

	auto throw_is_empty() const -> void;
};

template <typename T>
allocator<T>::allocator(size_t size) : ptr_((T*)(operator new(size*sizeof(T)))), size_(size), map_(std::make_unique<bitset>(size)) {};

template<typename T>
	allocator<T>::allocator(allocator const& other) :
ptr_(static_cast<T*>(operator new(other.size_))),
size_(other.size_), map_(std::make_unique<bitset>(size_)){
	for (size_t i; i < size_; i++)
		construct(ptr_ + i, other.ptr_[i]);
}
template<typename T>
allocator<T>::~allocator() { operator delete(ptr_); }

template<typename T>
auto allocator<T>::resize() -> void
{
	allocator<T> buff(size_ * 2 + (size_ == 0));
	for (size_t i = 0; i < size_; i++) construct(buff.ptr_ + i, ptr_[i]);
	this->swap(buff);
}

template<typename T>
auto allocator<T>::construct(T * ptr, T const & value)->void {
	if (ptr >= ptr_&&ptr < ptr_ + size_&&map_->test(ptr - ptr_)) {
		new(ptr)T(value);
		map_->set(ptr - ptr_);
	}
	else throw("error");
}

template<typename T>
auto allocator<T>::destroy(T * ptr) -> void {
	ptr->~T();
	map_->reset(ptr-ptr_);
}

template<typename T>
auto allocator<T>::destroy(T * first, T * last) -> void
{
	for (; first != last; ++first) {
		destroy(&*first);
	}
}

template<typename T>
auto allocator<T>::get()-> T* {
	return ptr_;
}

template<typename T>
auto allocator<T>::get() const -> T const * {
	return ptr_;
}

template<typename T>
auto allocator<T>::count() const -> size_t
{
	return map_->counter();
}

template<typename T>
auto allocator<T>::full() const -> bool
{
	return map_->counter()==size_;
}

template<typename T>
auto allocator<T>::empty() const -> bool
{
	return map_->counter()==0;
}

template<typename T>
auto allocator<T>::swap(allocator & other) -> void {
	std::swap(ptr_, other.ptr_);
	std::swap(map_, other.map_);
	std::swap(size_, other.size_);
}

template <typename T>
size_t stack<T>::count() const
{
	return allocator_.count_;
}
template <typename T>
stack<T>::stack(size_t size) :allocator<T>(size) {}

template <typename T>
void stack<T>::push(T const &item) {
	if (allocator_.full()) allocator_.resize();
	allocator_.construct(allocator_.get() + this->count(), item;
}
template<typename T>
void stack<T>::pop()
{
	if (this->count() > 0)
		allocator_.destroy(allocator_.get() + this->count());
	else throw_is_empty();
}
template<typename T>
auto stack<T>::top() -> T &
{
	if (allocator<T>::count_ == 0) {
		throw_is_empty();
	}
	return allocator<T>::ptr_[allocator<T>::count_ - 1];
}

template<typename T>
auto stack<T>::top() const -> T const &
{
	if (allocator<T>::count_ == 0) {
		throw_is_empty();
	}
	return allocator<T>::ptr_[allocator<T>::count_ - 1];
}

template<typename T>
auto stack<T>::throw_is_empty() const -> void
{
		throw("Stack is empty!");
}

template<typename T>
auto stack<T>::operator=(stack const & right) -> stack & {
	if (this != &right) {
		stack<T> temp(right.size_);
		while (temp.count_ < right.count_) {
			construct(temp.ptr_ + temp.count_, right.ptr_[temp.count_]);
			++temp.count_;
		}
		this->swap(temp);
	}
	return *this;
}

template<typename T>
auto stack<T>::empty() const -> bool {
	return allocator_.empty;

#endif
<|endoftext|>


<commit_before><commit_msg>Removed unused include<commit_after><|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2014 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#ifndef UTILS_HPP
#define UTILS_HPP

template<typename Container>
void scale_each(Container& values){
    for(auto& vec : values){
        for(auto& v : vec){
            v /= 255.0;
        }
    }
}

template<typename Container>
void binarize_each(Container& values, double threshold = 30.0){
    for(auto& vec : values){
        for(auto& v : vec){
            v = v > threshold ? 1.0 : 0.0;
        }
    }
}

template<typename Container>
double mean(const Container& container){
    double mean = 0.0;
    for(auto& value : container){
        mean += value;
    }
    return mean / container.size();
}

template<typename Container>
double stddev(const Container& container, double mean){
    double std = 0.0;
    for(auto& value : container){
        std += (value - mean) * (value - mean);
    }
    return std::sqrt(std / container.size());
}

template<typename Container>
void normalize(Container& values){
    for(auto& vec : values){
        //zero-mean
        auto m = mean(vec);
        for(auto& v : vec){
            v -= m;
        }
        //unit variance
        auto s = stddev(vec, 0.0);
        for(auto& v : vec){
            v /= s;
        }
    }
}

#endif
<commit_msg>Fix missing include<commit_after>//=======================================================================
// Copyright (c) 2014 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#ifndef UTILS_HPP
#define UTILS_HPP

#include <cmath>

template<typename Container>
void scale_each(Container& values){
    for(auto& vec : values){
        for(auto& v : vec){
            v /= 255.0;
        }
    }
}

template<typename Container>
void binarize_each(Container& values, double threshold = 30.0){
    for(auto& vec : values){
        for(auto& v : vec){
            v = v > threshold ? 1.0 : 0.0;
        }
    }
}

template<typename Container>
double mean(const Container& container){
    double mean = 0.0;
    for(auto& value : container){
        mean += value;
    }
    return mean / container.size();
}

template<typename Container>
double stddev(const Container& container, double mean){
    double std = 0.0;
    for(auto& value : container){
        std += (value - mean) * (value - mean);
    }
    return std::sqrt(std / container.size());
}

template<typename Container>
void normalize(Container& values){
    for(auto& vec : values){
        //zero-mean
        auto m = mean(vec);
        for(auto& v : vec){
            v -= m;
        }
        //unit variance
        auto s = stddev(vec, 0.0);
        for(auto& v : vec){
            v /= s;
        }
    }
}

#endif
<|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2014-2015, Image Engine Design Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//      * Redistributions of source code must retain the above
//        copyright notice, this list of conditions and the following
//        disclaimer.
//
//      * Redistributions in binary form must reproduce the above
//        copyright notice, this list of conditions and the following
//        disclaimer in the documentation and/or other materials provided with
//        the distribution.
//
//      * Neither the name of John Haddon nor the names of
//        any other contributors to this software may be used to endorse or
//        promote products derived from this software without specific prior
//        written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
//
//////////////////////////////////////////////////////////////////////////

#include "GafferTest/ContextTest.h"

#include "GafferTest/Assert.h"

#include "Gaffer/Context.h"

#include "IECore/Timer.h"
#include "IECore/VectorTypedData.h"
#include "IECore/PathMatcherData.h"

#include "boost/lexical_cast.hpp"
#include "tbb/parallel_for.h"
#include <unordered_set>

using namespace std;
using namespace boost;
using namespace IECore;
using namespace Gaffer;

// A test useful for assessing the performance
// of the Context class.
void GafferTest::testManyContexts()
{
	// our typical context doesn't have a huge number of keys - we'll
	// use a working set of 20 for this test.

	ContextPtr base = new Context();
	const int numKeys = 20;
	vector<InternedString> keys;
	for( int i = 0; i < numKeys; ++i )
	{
		InternedString key = string( "testKey" ) + lexical_cast<string>( i );
		keys.push_back( key );
		base->set( key, -1 - i );
	}
	const MurmurHash baseHash = base->hash();

	// then typically we create new temporary contexts based on that one,
	// change a value or two, and then continue.

	Timer t;
	for( int i = 0; i < 1000000; ++i )
	{
		// In order to efficiently manipulate a context, we need to create an EditableScope.
		// ( On the other hand, using a Context directly copies new memory for the value to
		// create a fully independent context, which is pretty slow ).
		Context::EditableScope tmp( base.get() );
		tmp.set( keys[i%numKeys], &i );
		GAFFERTEST_ASSERT( tmp.context()->get<int>( keys[i%numKeys] ) == i );
		GAFFERTEST_ASSERT( tmp.context()->hash() != baseHash );
	}
}

// Useful for assessing the performance of substitutions.
void GafferTest::testManySubstitutions()
{
	ContextPtr context = new Context();
	context->set( "foodType", std::string( "kipper" ) );
	context->set( "cookingMethod", std::string( "smoke" ) );

	const std::string phrase( "${cookingMethod} me a ${foodType}" );
	const std::string expectedResult( "smoke me a kipper" );

	Timer t;
	for( int i = 0; i < 1000000; ++i )
	{
		const std::string s = context->substitute( phrase );
		GAFFERTEST_ASSERT( s == expectedResult );
	}
}

// Useful for assessing the performance of environment variable substitutions.
void GafferTest::testManyEnvironmentSubstitutions()
{
	ContextPtr context = new Context();

	const std::string phrase( "${GAFFER_ROOT}" );
	const std::string expectedResult( getenv( "GAFFER_ROOT") );

	Timer t;
	for( int i = 0; i < 1000000; ++i )
	{
		const std::string s = context->substitute( phrase );
		GAFFERTEST_ASSERT( s == expectedResult );
	}
}

// Tests that scoping a null context is a no-op
void GafferTest::testScopingNullContext()
{
	ContextPtr context = new Context();
	context->set( "foodType", std::string( "kipper" ) );
	context->set( "cookingMethod", std::string( "smoke" ) );

	const std::string phrase( "${cookingMethod} me a ${foodType}" );
	const std::string expectedResult( "smoke me a kipper" );

	{
		Context::Scope scope( context.get() );
		const std::string s = Context::current()->substitute( phrase );
		GAFFERTEST_ASSERT( s == expectedResult );

		const Context *nullContext = nullptr;
		{
			Context::Scope scope( nullContext );
			const std::string s = Context::current()->substitute( phrase );
			GAFFERTEST_ASSERT( s == expectedResult );
		}
	}
}

void GafferTest::testEditableScope()
{
	testEditableScopeTyped<IECore::IntData>( 10, 20 );
	testEditableScopeTyped<IECore::FloatData>( 10.0, 20.0 );
	testEditableScopeTyped<IECore::StringData>( std::string( "a" ), std::string( "b" ) );
	testEditableScopeTyped<IECore::InternedStringData>( IECore::InternedString( "a" ), IECore::InternedString( "b" ) );
	testEditableScopeTyped<IECore::FloatVectorData>( std::vector<float>{ 1, 2, 3, 4 }, std::vector<float>{ 5, 6, 7 } );
	testEditableScopeTyped<IECore::StringVectorData>( std::vector<std::string>{ "a", "AA" }, std::vector<std::string>{ "bbbbbbb" } );
	testEditableScopeTyped<IECore::InternedStringVectorData>( std::vector<IECore::InternedString>{ "a", "AA" }, std::vector<IECore::InternedString>{ "bbbbbbb" } );

	PathMatcher a;
	a.addPath( "/a/y" );
	a.addPath( "/b/y" );
	a.addPath( "/c/y" );
	PathMatcher b;
	b.addPath( "/a/x" );
	b.addPath( "/b/x" );
	testEditableScopeTyped<IECore::PathMatcherData>( a, b );

	// Test specific calls for dealing with time
	Gaffer::ContextPtr baseContext = new Gaffer::Context();
	Gaffer::Context::EditableScope scope( baseContext.get() );
	const Gaffer::Context *currentContext = Gaffer::Context::current();

	scope.setFrame( 5 );
	GAFFERTEST_ASSERT( currentContext->getFrame() == 5 );

	float framesPerSecond = 8;
	scope.setFramesPerSecond( &framesPerSecond );
	GAFFERTEST_ASSERT( currentContext->getFramesPerSecond() == 8 );

	scope.setTime( 9 );
	GAFFERTEST_ASSERT( currentContext->getFrame() == 72 );

	scope.setTime( 8.5 );
	GAFFERTEST_ASSERT( currentContext->getFrame() == 68 );

}

// Create the number of contexts specified, and return counts for how many collisions there are
// in each of the four 32 bit sections of the context hash.  MurmurHash performs good mixing, so
// the four sections should be independent, and as long as collisions within each section occur only
// at the expected rate, the chance of a full collision across all 4 should be infinitesimal
// ( we don't want to check for collisions in the whole 128 bit hash, since it would take years
// for one to occur randomly )
// "mode" switches betwen 4 modes for creating contexts:
//   0 :  1 entry with a single increment int
//   1 :  40 fixed strings, plus a single incrementing int
//   2 :  20 random floats
//   3 :  an even mixture of the previous 3 modes
// "seed" can be used to perform different runs to get an average number.
// The goal is that regardless of how we create the contexts, they are all unique, and should therefore
// have an identical chance of collisions if our hashing performs ideally.
std::tuple<int,int,int,int> GafferTest::countContextHash32Collisions( int contexts, int mode, int seed )
{
	std::unordered_set<uint32_t> used[4];

	InternedString a( "a" );
	InternedString numberNames[40];
	for( int i = 0; i < 40; i++ )
	{
		numberNames[i] = InternedString( i );
	}

	unsigned int rand_seed = seed;
	int collisions[4] = {0,0,0,0};
	for( int i = 0; i < contexts; i++ )
	{
		int curMode = mode;
		int elementSeed = seed * contexts + i;
		if( curMode == 3 )
		{
			curMode = i % 3;
			elementSeed = seed * contexts + i / 3;
		}

		Context c;
		if( curMode == 0 )
		{
			c.set( a, elementSeed );
		}
		else if( curMode == 1 )
		{
			for( int j = 0; j < 40; j++ )
			{
				c.set( numberNames[j], j );
			}
			c.set( a, elementSeed );
		}
		else if( curMode == 2 )
		{
			for( int j = 0; j < 20; j++ )
			{
				c.set( numberNames[j], rand_r( &rand_seed ) );
			}
		}

		if( !used[0].insert( (uint32_t)( c.hash().h1() ) ).second )
		{
			collisions[0]++;
		}
		if( !used[1].insert( (uint32_t)( c.hash().h1() >> 32 ) ).second )
		{
			collisions[1]++;
		}
		if( !used[2].insert( (uint32_t)( c.hash().h2() ) ).second )
		{
			collisions[2]++;
		}
		if( !used[3].insert( (uint32_t)( c.hash().h2() >> 32 ) ).second )
		{
			collisions[3]++;
		}
	}

	return std::make_tuple( collisions[0], collisions[1], collisions[2], collisions[3] );
}

void GafferTest::testContextHashPerformance( int numEntries, int entrySize, bool startInitialized )
{
	// We usually deal with contexts that already have some stuff in them, so adding some entries
	// to the context makes this test more realistic
	ContextPtr baseContext = new Context();
	for( int i = 0; i < numEntries; i++ )
	{
		baseContext->set( InternedString( i ), std::string( entrySize, 'x') );
	}

	const InternedString varyingVarName = "varyVar";
	if( startInitialized )
	{
		baseContext->set( varyingVarName, -1 );
	}

	Context::Scope baseScope( baseContext.get() );

	const ThreadState &threadState = ThreadState::current();

	tbb::parallel_for( tbb::blocked_range<int>( 0, 10000000 ), [&threadState, &varyingVarName]( const tbb::blocked_range<int> &r )
		{
			for( int i = r.begin(); i != r.end(); ++i )
			{
				Context::EditableScope scope( threadState );
				scope.set( varyingVarName, &i );

				// This call is relied on by ValuePlug's HashCacheKey, so it is crucial that it be fast
				scope.context()->hash();
			}
		}
	);

}

void GafferTest::testContextCopyPerformance( int numEntries, int entrySize )
{
	// We usually deal with contexts that already have some stuff in them, so adding some entries
	// to the context makes this test more realistic
	ContextPtr baseContext = new Context();
	for( int i = 0; i < numEntries; i++ )
	{
		baseContext->set( InternedString( i ), std::string( entrySize, 'x') );
	}

	const InternedString varyingVarName = "varyVar";

	tbb::parallel_for( tbb::blocked_range<int>( 0, 1000000 ), [&baseContext, &varyingVarName]( const tbb::blocked_range<int> &r )
		{
			for( int i = r.begin(); i != r.end(); ++i )
			{
				ContextPtr copy = new Context( *baseContext );
			}
		}
	);

}
<commit_msg>ContextTest : Remove unused variable<commit_after>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2014-2015, Image Engine Design Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//      * Redistributions of source code must retain the above
//        copyright notice, this list of conditions and the following
//        disclaimer.
//
//      * Redistributions in binary form must reproduce the above
//        copyright notice, this list of conditions and the following
//        disclaimer in the documentation and/or other materials provided with
//        the distribution.
//
//      * Neither the name of John Haddon nor the names of
//        any other contributors to this software may be used to endorse or
//        promote products derived from this software without specific prior
//        written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
//
//////////////////////////////////////////////////////////////////////////

#include "GafferTest/ContextTest.h"

#include "GafferTest/Assert.h"

#include "Gaffer/Context.h"

#include "IECore/Timer.h"
#include "IECore/VectorTypedData.h"
#include "IECore/PathMatcherData.h"

#include "boost/lexical_cast.hpp"
#include "tbb/parallel_for.h"
#include <unordered_set>

using namespace std;
using namespace boost;
using namespace IECore;
using namespace Gaffer;

// A test useful for assessing the performance
// of the Context class.
void GafferTest::testManyContexts()
{
	// our typical context doesn't have a huge number of keys - we'll
	// use a working set of 20 for this test.

	ContextPtr base = new Context();
	const int numKeys = 20;
	vector<InternedString> keys;
	for( int i = 0; i < numKeys; ++i )
	{
		InternedString key = string( "testKey" ) + lexical_cast<string>( i );
		keys.push_back( key );
		base->set( key, -1 - i );
	}
	const MurmurHash baseHash = base->hash();

	// then typically we create new temporary contexts based on that one,
	// change a value or two, and then continue.

	Timer t;
	for( int i = 0; i < 1000000; ++i )
	{
		// In order to efficiently manipulate a context, we need to create an EditableScope.
		// ( On the other hand, using a Context directly copies new memory for the value to
		// create a fully independent context, which is pretty slow ).
		Context::EditableScope tmp( base.get() );
		tmp.set( keys[i%numKeys], &i );
		GAFFERTEST_ASSERT( tmp.context()->get<int>( keys[i%numKeys] ) == i );
		GAFFERTEST_ASSERT( tmp.context()->hash() != baseHash );
	}
}

// Useful for assessing the performance of substitutions.
void GafferTest::testManySubstitutions()
{
	ContextPtr context = new Context();
	context->set( "foodType", std::string( "kipper" ) );
	context->set( "cookingMethod", std::string( "smoke" ) );

	const std::string phrase( "${cookingMethod} me a ${foodType}" );
	const std::string expectedResult( "smoke me a kipper" );

	Timer t;
	for( int i = 0; i < 1000000; ++i )
	{
		const std::string s = context->substitute( phrase );
		GAFFERTEST_ASSERT( s == expectedResult );
	}
}

// Useful for assessing the performance of environment variable substitutions.
void GafferTest::testManyEnvironmentSubstitutions()
{
	ContextPtr context = new Context();

	const std::string phrase( "${GAFFER_ROOT}" );
	const std::string expectedResult( getenv( "GAFFER_ROOT") );

	Timer t;
	for( int i = 0; i < 1000000; ++i )
	{
		const std::string s = context->substitute( phrase );
		GAFFERTEST_ASSERT( s == expectedResult );
	}
}

// Tests that scoping a null context is a no-op
void GafferTest::testScopingNullContext()
{
	ContextPtr context = new Context();
	context->set( "foodType", std::string( "kipper" ) );
	context->set( "cookingMethod", std::string( "smoke" ) );

	const std::string phrase( "${cookingMethod} me a ${foodType}" );
	const std::string expectedResult( "smoke me a kipper" );

	{
		Context::Scope scope( context.get() );
		const std::string s = Context::current()->substitute( phrase );
		GAFFERTEST_ASSERT( s == expectedResult );

		const Context *nullContext = nullptr;
		{
			Context::Scope scope( nullContext );
			const std::string s = Context::current()->substitute( phrase );
			GAFFERTEST_ASSERT( s == expectedResult );
		}
	}
}

void GafferTest::testEditableScope()
{
	testEditableScopeTyped<IECore::IntData>( 10, 20 );
	testEditableScopeTyped<IECore::FloatData>( 10.0, 20.0 );
	testEditableScopeTyped<IECore::StringData>( std::string( "a" ), std::string( "b" ) );
	testEditableScopeTyped<IECore::InternedStringData>( IECore::InternedString( "a" ), IECore::InternedString( "b" ) );
	testEditableScopeTyped<IECore::FloatVectorData>( std::vector<float>{ 1, 2, 3, 4 }, std::vector<float>{ 5, 6, 7 } );
	testEditableScopeTyped<IECore::StringVectorData>( std::vector<std::string>{ "a", "AA" }, std::vector<std::string>{ "bbbbbbb" } );
	testEditableScopeTyped<IECore::InternedStringVectorData>( std::vector<IECore::InternedString>{ "a", "AA" }, std::vector<IECore::InternedString>{ "bbbbbbb" } );

	PathMatcher a;
	a.addPath( "/a/y" );
	a.addPath( "/b/y" );
	a.addPath( "/c/y" );
	PathMatcher b;
	b.addPath( "/a/x" );
	b.addPath( "/b/x" );
	testEditableScopeTyped<IECore::PathMatcherData>( a, b );

	// Test specific calls for dealing with time
	Gaffer::ContextPtr baseContext = new Gaffer::Context();
	Gaffer::Context::EditableScope scope( baseContext.get() );
	const Gaffer::Context *currentContext = Gaffer::Context::current();

	scope.setFrame( 5 );
	GAFFERTEST_ASSERT( currentContext->getFrame() == 5 );

	float framesPerSecond = 8;
	scope.setFramesPerSecond( &framesPerSecond );
	GAFFERTEST_ASSERT( currentContext->getFramesPerSecond() == 8 );

	scope.setTime( 9 );
	GAFFERTEST_ASSERT( currentContext->getFrame() == 72 );

	scope.setTime( 8.5 );
	GAFFERTEST_ASSERT( currentContext->getFrame() == 68 );

}

// Create the number of contexts specified, and return counts for how many collisions there are
// in each of the four 32 bit sections of the context hash.  MurmurHash performs good mixing, so
// the four sections should be independent, and as long as collisions within each section occur only
// at the expected rate, the chance of a full collision across all 4 should be infinitesimal
// ( we don't want to check for collisions in the whole 128 bit hash, since it would take years
// for one to occur randomly )
// "mode" switches betwen 4 modes for creating contexts:
//   0 :  1 entry with a single increment int
//   1 :  40 fixed strings, plus a single incrementing int
//   2 :  20 random floats
//   3 :  an even mixture of the previous 3 modes
// "seed" can be used to perform different runs to get an average number.
// The goal is that regardless of how we create the contexts, they are all unique, and should therefore
// have an identical chance of collisions if our hashing performs ideally.
std::tuple<int,int,int,int> GafferTest::countContextHash32Collisions( int contexts, int mode, int seed )
{
	std::unordered_set<uint32_t> used[4];

	InternedString a( "a" );
	InternedString numberNames[40];
	for( int i = 0; i < 40; i++ )
	{
		numberNames[i] = InternedString( i );
	}

	unsigned int rand_seed = seed;
	int collisions[4] = {0,0,0,0};
	for( int i = 0; i < contexts; i++ )
	{
		int curMode = mode;
		int elementSeed = seed * contexts + i;
		if( curMode == 3 )
		{
			curMode = i % 3;
			elementSeed = seed * contexts + i / 3;
		}

		Context c;
		if( curMode == 0 )
		{
			c.set( a, elementSeed );
		}
		else if( curMode == 1 )
		{
			for( int j = 0; j < 40; j++ )
			{
				c.set( numberNames[j], j );
			}
			c.set( a, elementSeed );
		}
		else if( curMode == 2 )
		{
			for( int j = 0; j < 20; j++ )
			{
				c.set( numberNames[j], rand_r( &rand_seed ) );
			}
		}

		if( !used[0].insert( (uint32_t)( c.hash().h1() ) ).second )
		{
			collisions[0]++;
		}
		if( !used[1].insert( (uint32_t)( c.hash().h1() >> 32 ) ).second )
		{
			collisions[1]++;
		}
		if( !used[2].insert( (uint32_t)( c.hash().h2() ) ).second )
		{
			collisions[2]++;
		}
		if( !used[3].insert( (uint32_t)( c.hash().h2() >> 32 ) ).second )
		{
			collisions[3]++;
		}
	}

	return std::make_tuple( collisions[0], collisions[1], collisions[2], collisions[3] );
}

void GafferTest::testContextHashPerformance( int numEntries, int entrySize, bool startInitialized )
{
	// We usually deal with contexts that already have some stuff in them, so adding some entries
	// to the context makes this test more realistic
	ContextPtr baseContext = new Context();
	for( int i = 0; i < numEntries; i++ )
	{
		baseContext->set( InternedString( i ), std::string( entrySize, 'x') );
	}

	const InternedString varyingVarName = "varyVar";
	if( startInitialized )
	{
		baseContext->set( varyingVarName, -1 );
	}

	Context::Scope baseScope( baseContext.get() );

	const ThreadState &threadState = ThreadState::current();

	tbb::parallel_for( tbb::blocked_range<int>( 0, 10000000 ), [&threadState, &varyingVarName]( const tbb::blocked_range<int> &r )
		{
			for( int i = r.begin(); i != r.end(); ++i )
			{
				Context::EditableScope scope( threadState );
				scope.set( varyingVarName, &i );

				// This call is relied on by ValuePlug's HashCacheKey, so it is crucial that it be fast
				scope.context()->hash();
			}
		}
	);

}

void GafferTest::testContextCopyPerformance( int numEntries, int entrySize )
{
	// We usually deal with contexts that already have some stuff in them, so adding some entries
	// to the context makes this test more realistic
	ContextPtr baseContext = new Context();
	for( int i = 0; i < numEntries; i++ )
	{
		baseContext->set( InternedString( i ), std::string( entrySize, 'x') );
	}

	tbb::parallel_for(
		tbb::blocked_range<int>( 0, 1000000 ),
		[&baseContext]( const tbb::blocked_range<int> &r )
		{
			for( int i = r.begin(); i != r.end(); ++i )
			{
				ContextPtr copy = new Context( *baseContext );
			}
		}
	);

}
<|endoftext|>


<commit_before><commit_msg>Add constant for VPD #W keyword<commit_after><|endoftext|>


<commit_before>/*
contact: Boris.Polishchuk@cern.ch
link: see comments in the $ALICE_ROOT/PHOS/AliPHOSRcuDA1.cxx
reference run: /alice/data/2009/LHC09b_PHOS/000075883/raw/09000075883017.20.root
run type: PHYSICS
DA type: MON
number of events needed: 1000
input files: Mod0RCU0.data Mod0RCU1.data Mod0RCU2.data Mod0RCU3.data Mod1RCU0.data Mod1RCU1.data Mod1RCU2.data Mod1RCU3.data Mod2RCU0.data Mod2RCU1.data Mod2RCU2.data Mod2RCU3.data Mod3RCU0.data Mod3RCU1.data Mod3RCU2.data Mod3RCU3.data Mod4RCU0.data Mod4RCU1.data Mod4RCU2.data Mod4RCU3.data zs.txt
Output files: PHOS_Calib.root
Trigger types used: PHYSICS
*/

#include "event.h"
#include "monitor.h"
extern "C" {
#include "daqDA.h"
}

#include <stdio.h>
#include <stdlib.h>

#include <TSystem.h>
#include <TROOT.h>
#include <TPluginManager.h>

#include "AliRawReader.h"
#include "AliRawReaderDate.h"
#include "AliPHOSRcuDA1.h"
#include "AliPHOSRawFitterv0.h"
#include "AliCaloAltroMapping.h"
#include "AliCaloRawStreamV3.h"
#include "AliLog.h"

/* Main routine
      Arguments:
      1- monitoring data source
*/
int main(int argc, char **argv) {

  gROOT->GetPluginManager()->AddHandler("TVirtualStreamerInfo",
					"*",
					"TStreamerInfo",
					"RIO",
					"TStreamerInfo()");

  AliLog::SetGlobalDebugLevel(0) ;
  AliLog::SetGlobalLogLevel(AliLog::kFatal);

  int status;

  if (argc!=2) {
    printf("Wrong number of arguments\n");
    return -1;
  }

  /* Retrieve ZS parameters from DAQ DB */
  const char* zsfile = "zs.txt";
  int failZS = daqDA_DB_getFile(zsfile, zsfile);

  Int_t offset,threshold;

  if(!failZS) {
    FILE *f = fopen(zsfile,"r");
    int scan = fscanf(f,"%d %d",&offset,&threshold);
  }

  /* Retrieve mapping files from DAQ DB */
  const char* mapFiles[20] = {
    "Mod0RCU0.data",
    "Mod0RCU1.data",
    "Mod0RCU2.data",
    "Mod0RCU3.data",
    "Mod1RCU0.data",
    "Mod1RCU1.data",
    "Mod1RCU2.data",
    "Mod1RCU3.data",
    "Mod2RCU0.data",
    "Mod2RCU1.data",
    "Mod2RCU2.data",
    "Mod2RCU3.data",
    "Mod3RCU0.data",
    "Mod3RCU1.data",
    "Mod3RCU2.data",
    "Mod3RCU3.data",
    "Mod4RCU0.data",
    "Mod4RCU1.data",
    "Mod4RCU2.data",
    "Mod4RCU3.data"
  };

  for(Int_t iFile=0; iFile<20; iFile++) {
    int failed = daqDA_DB_getFile(mapFiles[iFile], mapFiles[iFile]);
    if(failed) {
      printf("Cannot retrieve file %s from DAQ DB. Exit.\n",mapFiles[iFile]);
      return -1;
    }
  }

  /* Open mapping files */
  AliAltroMapping *mapping[20];
  TString path = "./";

  path += "Mod";
  TString path2;
  TString path3;
  Int_t iMap = 0;

  for(Int_t iMod = 0; iMod < 5; iMod++) {
    path2 = path;
    path2 += iMod;
    path2 += "RCU";

    for(Int_t iRCU=0; iRCU<4; iRCU++) {
      path3 = path2;
      path3 += iRCU;
      path3 += ".data";
      mapping[iMap] = new AliCaloAltroMapping(path3.Data());
      iMap++;
    }
  }

  /* define data source : this is argument 1 */
  status=monitorSetDataSource( argv[1] );
  if (status!=0) {
    printf("monitorSetDataSource() failed : %s\n",monitorDecodeError(status));
    return -1;
  }

  /* declare monitoring program */
  status=monitorDeclareMp( __FILE__ );
  if (status!=0) {
    printf("monitorDeclareMp() failed : %s\n",monitorDecodeError(status));
    return -1;
  }

  /* define wait event timeout - 1s max */
  monitorSetNowait();
  monitorSetNoWaitNetworkTimeout(1000);

   /* init some counters */
  int nevents_physics=0;
  int nevents_total=0;

  AliRawReader *rawReader = NULL;
  AliPHOSRcuDA1* dAs[5];

  for(Int_t iMod=0; iMod<5; iMod++) {
    dAs[iMod] = 0;
  }

  Float_t e[64][56][2];
  Float_t t[64][56][2];

  for(Int_t iX=0; iX<64; iX++) {
    for(Int_t iZ=0; iZ<56; iZ++) {
      for(Int_t iGain=0; iGain<2; iGain++) {
	e[iX][iZ][iGain] = 0.;
	t[iX][iZ][iGain] = 0.;
      }
    }
  }

  Int_t cellX    = -1;
  Int_t cellZ    = -1;
  Int_t nBunches =  0;
  Int_t sigStart, sigLength;
  Int_t caloFlag;

  /* main loop (infinite) */
  for(;;) {
    struct eventHeaderStruct *event;
    eventTypeType eventT;

    /* check shutdown condition */
    if (daqDA_checkShutdown()) {break;}

    /* get next event (blocking call until timeout) */
    status=monitorGetEventDynamic((void **)&event);
    if (status==MON_ERR_EOF) {
      printf ("End of File detected\n");
      break; /* end of monitoring file has been reached */
    }

    if (status!=0) {
      printf("monitorGetEventDynamic() failed : %s\n",monitorDecodeError(status));
      break;
    }

    /* retry if got no event */
    if (event==NULL) {
      continue;
    }

    /* use event - here, just write event id to result file */
    eventT=event->eventType;

    if (eventT==PHYSICS_EVENT) {

      rawReader = new AliRawReaderDate((void*)event);
      AliCaloRawStreamV3 stream(rawReader,"PHOS",mapping);
      AliPHOSRawFitterv0 fitter;
      fitter.SubtractPedestals(kTRUE); // assume that data is non-ZS

      if(!failZS) {
	fitter.SubtractPedestals(kFALSE);
	fitter.SetAmpOffset(offset);
	fitter.SetAmpThreshold(threshold);
      }

      while (stream.NextDDL()) {
	while (stream.NextChannel()) {

	  /* Retrieve ZS parameters from data*/
	  if(failZS) {
	    short value = stream.GetAltroCFG1();
	    bool ZeroSuppressionEnabled = (value >> 15) & 0x1;
	    bool AutomaticBaselineSubtraction = (value >> 14) & 0x1;
	    if(ZeroSuppressionEnabled) {
	      offset = (value >> 10) & 0xf;
	      threshold = value & 0x3ff;
	      fitter.SubtractPedestals(kFALSE);
	      fitter.SetAmpOffset(offset);
	      fitter.SetAmpThreshold(threshold);
	    }
	  }

	  cellX    = stream.GetCellX();
	  cellZ    = stream.GetCellZ();
	  caloFlag = stream.GetCaloFlag();  // 0=LG, 1=HG, 2=TRU

	  if(caloFlag!=0 && caloFlag!=1) continue; //TRU data!

	  // In case of oscillating signals with ZS,
	  //a channel can have several bunches.

	  nBunches = 0;
	  while (stream.NextBunch()) {
	    nBunches++;
	    if (nBunches > 1) continue;
	    sigStart  = stream.GetStartTimeBin();
	    sigLength = stream.GetBunchLength();
	    fitter.SetChannelGeo(stream.GetModule(),cellX,cellZ,caloFlag);
	    fitter.Eval(stream.GetSignals(),sigStart,sigLength);
	  } // End of NextBunch()

	  if (nBunches != 1) continue;

	  e[cellX][cellZ][caloFlag] = fitter.GetEnergy();
	  t[cellX][cellZ][caloFlag] = fitter.GetTime();
	}

	if(stream.GetModule()<0 || stream.GetModule()>4) continue;

	if(dAs[stream.GetModule()])
	  dAs[stream.GetModule()]->FillHistograms(e,t);
	else {
	  dAs[stream.GetModule()] = new AliPHOSRcuDA1(stream.GetModule(),-1,0);
	  dAs[stream.GetModule()]->FillHistograms(e,t);
	}

	for(Int_t iX=0; iX<64; iX++) {
	  for(Int_t iZ=0; iZ<56; iZ++) {
	    for(Int_t iGain=0; iGain<2; iGain++) {
	      e[iX][iZ][iGain] = 0.;
	      t[iX][iZ][iGain] = 0.;
	    }
	  }
	}

      }

//       da1.FillHistograms(e,t);
//     //da1.UpdateHistoFile();

	delete rawReader;
	nevents_physics++;
    }

    nevents_total++;

    /* free resources */
    free(event);

    /* exit when last event received, no need to wait for TERM signal */
    if (eventT==END_OF_RUN) {
      printf("EOR event detected\n");
      break;
    }
  }

  for(Int_t i = 0; i < 20; i++) delete mapping[i];

  /* Be sure that all histograms are saved */

  const TH2F* h2=0;
  const TH1F* h1=0;
  char localfile[128];

  sprintf(localfile,"PHOS_Calib.root");
  TFile* f = new TFile(localfile,"recreate");

  for(Int_t iMod=0; iMod<5; iMod++) {
    if(!dAs[iMod]) continue;

    printf("DA1 for module %d detected.\n",iMod);

    for(Int_t iX=0; iX<64; iX++) {
      for(Int_t iZ=0; iZ<56; iZ++) {

	h1 = dAs[iMod]->GetHgLgRatioHistogram(iX,iZ); // High Gain/Low Gain ratio
	if(h1) h1->Write();

	for(Int_t iGain=0; iGain<2; iGain++) {
	  h2 = dAs[iMod]->GetTimeEnergyHistogram(iX,iZ,iGain); // Time vs Energy
	  if(h2) h2->Write();
	}
      }
    }
  }

  f->Close();

  /* Store output files to the File Exchange Server */
  daqDA_FES_storeFile(localfile,"AMPLITUDES");

  return status;
}
<commit_msg>Added possibility to accumulate statistics through the number of runs.<commit_after>/*
contact: Boris.Polishchuk@cern.ch
link: see comments in the $ALICE_ROOT/PHOS/AliPHOSRcuDA1.cxx
reference run: /alice/data/2009/LHC09b_PHOS/000075883/raw/09000075883017.20.root
run type: PHYSICS
DA type: MON
number of events needed: 1000
input files: Mod0RCU0.data Mod0RCU1.data Mod0RCU2.data Mod0RCU3.data Mod1RCU0.data Mod1RCU1.data Mod1RCU2.data Mod1RCU3.data Mod2RCU0.data Mod2RCU1.data Mod2RCU2.data Mod2RCU3.data Mod3RCU0.data Mod3RCU1.data Mod3RCU2.data Mod3RCU3.data Mod4RCU0.data Mod4RCU1.data Mod4RCU2.data Mod4RCU3.data zs.txt
Output files: PHOS_Calib_Total.root contains cumulative statistics for a number of runs.
Trigger types used: PHYSICS
*/

#include "event.h"
#include "monitor.h"
extern "C" {
#include "daqDA.h"
}

#include <stdio.h>
#include <stdlib.h>

#include <TSystem.h>
#include <TROOT.h>
#include <TPluginManager.h>

#include "AliRawReader.h"
#include "AliRawReaderDate.h"
#include "AliPHOSRcuDA1.h"
#include "AliPHOSRawFitterv0.h"
#include "AliCaloAltroMapping.h"
#include "AliCaloRawStreamV3.h"
#include "AliLog.h"

/* Main routine
      Arguments:
      1- monitoring data source
*/
int main(int argc, char **argv) {

  gROOT->GetPluginManager()->AddHandler("TVirtualStreamerInfo",
					"*",
					"TStreamerInfo",
					"RIO",
					"TStreamerInfo()");

  AliLog::SetGlobalDebugLevel(0) ;
  AliLog::SetGlobalLogLevel(AliLog::kFatal);

  int status;

  if (argc!=2) {
    printf("Wrong number of arguments\n");
    return -1;
  }

  /* Retrieve ZS parameters from DAQ DB */
  const char* zsfile = "zs.txt";
  int failZS = daqDA_DB_getFile(zsfile, zsfile);

  Int_t offset,threshold;

  if(!failZS) {
    FILE *f = fopen(zsfile,"r");
    int scan = fscanf(f,"%d %d",&offset,&threshold);
  }

  /* Retrieve mapping files from DAQ DB */
  const char* mapFiles[20] = {
    "Mod0RCU0.data",
    "Mod0RCU1.data",
    "Mod0RCU2.data",
    "Mod0RCU3.data",
    "Mod1RCU0.data",
    "Mod1RCU1.data",
    "Mod1RCU2.data",
    "Mod1RCU3.data",
    "Mod2RCU0.data",
    "Mod2RCU1.data",
    "Mod2RCU2.data",
    "Mod2RCU3.data",
    "Mod3RCU0.data",
    "Mod3RCU1.data",
    "Mod3RCU2.data",
    "Mod3RCU3.data",
    "Mod4RCU0.data",
    "Mod4RCU1.data",
    "Mod4RCU2.data",
    "Mod4RCU3.data"
  };

  for(Int_t iFile=0; iFile<20; iFile++) {
    int failed = daqDA_DB_getFile(mapFiles[iFile], mapFiles[iFile]);
    if(failed) {
      printf("Cannot retrieve file %s from DAQ DB. Exit.\n",mapFiles[iFile]);
      return -1;
    }
  }

  /* Open mapping files */
  AliAltroMapping *mapping[20];
  TString path = "./";

  path += "Mod";
  TString path2;
  TString path3;
  Int_t iMap = 0;

  for(Int_t iMod = 0; iMod < 5; iMod++) {
    path2 = path;
    path2 += iMod;
    path2 += "RCU";

    for(Int_t iRCU=0; iRCU<4; iRCU++) {
      path3 = path2;
      path3 += iRCU;
      path3 += ".data";
      mapping[iMap] = new AliCaloAltroMapping(path3.Data());
      iMap++;
    }
  }

  /* define data source : this is argument 1 */
  status=monitorSetDataSource( argv[1] );
  if (status!=0) {
    printf("monitorSetDataSource() failed : %s\n",monitorDecodeError(status));
    return -1;
  }

  /* declare monitoring program */
  status=monitorDeclareMp( __FILE__ );
  if (status!=0) {
    printf("monitorDeclareMp() failed : %s\n",monitorDecodeError(status));
    return -1;
  }

  /* define wait event timeout - 1s max */
  monitorSetNowait();
  monitorSetNoWaitNetworkTimeout(1000);

   /* init some counters */
  int nevents_physics=0;
  int nevents_total=0;

  AliRawReader *rawReader = NULL;
  AliPHOSRcuDA1* dAs[5];

  for(Int_t iMod=0; iMod<5; iMod++) {
    dAs[iMod] = 0;
  }

  Float_t e[64][56][2];
  Float_t t[64][56][2];

  for(Int_t iX=0; iX<64; iX++) {
    for(Int_t iZ=0; iZ<56; iZ++) {
      for(Int_t iGain=0; iGain<2; iGain++) {
	e[iX][iZ][iGain] = 0.;
	t[iX][iZ][iGain] = 0.;
      }
    }
  }

  Int_t cellX    = -1;
  Int_t cellZ    = -1;
  Int_t nBunches =  0;
  Int_t sigStart, sigLength;
  Int_t caloFlag;

  /* main loop (infinite) */
  for(;;) {
    struct eventHeaderStruct *event;
    eventTypeType eventT;

    /* check shutdown condition */
    if (daqDA_checkShutdown()) {break;}

    /* get next event (blocking call until timeout) */
    status=monitorGetEventDynamic((void **)&event);
    if (status==MON_ERR_EOF) {
      printf ("End of File detected\n");
      break; /* end of monitoring file has been reached */
    }

    if (status!=0) {
      printf("monitorGetEventDynamic() failed : %s\n",monitorDecodeError(status));
      break;
    }

    /* retry if got no event */
    if (event==NULL) {
      continue;
    }

    /* use event - here, just write event id to result file */
    eventT=event->eventType;

    if (eventT==PHYSICS_EVENT) {

      rawReader = new AliRawReaderDate((void*)event);
      AliCaloRawStreamV3 stream(rawReader,"PHOS",mapping);
      AliPHOSRawFitterv0 fitter;
      fitter.SubtractPedestals(kTRUE); // assume that data is non-ZS

      if(!failZS) {
	fitter.SubtractPedestals(kFALSE);
	fitter.SetAmpOffset(offset);
	fitter.SetAmpThreshold(threshold);
      }

      while (stream.NextDDL()) {
	while (stream.NextChannel()) {

	  /* Retrieve ZS parameters from data*/
	  if(failZS) {
	    short value = stream.GetAltroCFG1();
	    bool ZeroSuppressionEnabled = (value >> 15) & 0x1;
	    bool AutomaticBaselineSubtraction = (value >> 14) & 0x1;
	    if(ZeroSuppressionEnabled) {
	      offset = (value >> 10) & 0xf;
	      threshold = value & 0x3ff;
	      fitter.SubtractPedestals(kFALSE);
	      fitter.SetAmpOffset(offset);
	      fitter.SetAmpThreshold(threshold);
	    }
	  }

	  cellX    = stream.GetCellX();
	  cellZ    = stream.GetCellZ();
	  caloFlag = stream.GetCaloFlag();  // 0=LG, 1=HG, 2=TRU

	  if(caloFlag!=0 && caloFlag!=1) continue; //TRU data!

	  // In case of oscillating signals with ZS,
	  //a channel can have several bunches.

	  nBunches = 0;
	  while (stream.NextBunch()) {
	    nBunches++;
	    if (nBunches > 1) continue;
	    sigStart  = stream.GetStartTimeBin();
	    sigLength = stream.GetBunchLength();
	    fitter.SetChannelGeo(stream.GetModule(),cellX,cellZ,caloFlag);
	    fitter.Eval(stream.GetSignals(),sigStart,sigLength);
	  } // End of NextBunch()

	  if (nBunches != 1) continue;

	  e[cellX][cellZ][caloFlag] = fitter.GetEnergy();
	  t[cellX][cellZ][caloFlag] = fitter.GetTime();
	}

	if(stream.GetModule()<0 || stream.GetModule()>4) continue;

	if(dAs[stream.GetModule()])
	  dAs[stream.GetModule()]->FillHistograms(e,t);
	else {
	  dAs[stream.GetModule()] = new AliPHOSRcuDA1(stream.GetModule(),-1,0);
	  dAs[stream.GetModule()]->FillHistograms(e,t);
	}

	for(Int_t iX=0; iX<64; iX++) {
	  for(Int_t iZ=0; iZ<56; iZ++) {
	    for(Int_t iGain=0; iGain<2; iGain++) {
	      e[iX][iZ][iGain] = 0.;
	      t[iX][iZ][iGain] = 0.;
	    }
	  }
	}

      }

//       da1.FillHistograms(e,t);
//     //da1.UpdateHistoFile();

	delete rawReader;
	nevents_physics++;
    }

    nevents_total++;

    /* free resources */
    free(event);

    /* exit when last event received, no need to wait for TERM signal */
    if (eventT==END_OF_RUN) {
      printf("EOR event detected\n");
      break;
    }
  }

  for(Int_t i = 0; i < 20; i++) delete mapping[i];

  /* Be sure that all histograms are saved */

  char h2name[80];
  char totfile[80];

  //Write the Total file (accumulated statistics for number of runs)
  sprintf(totfile,"PHOS_Calib_Total.root");
  TFile * ftot = new TFile(totfile,"update");

  if (!ftot->IsZombie()){
    printf("Updating file %s.\n",ftot->GetName());

    for(Int_t iMod=0; iMod<5; iMod++) {
      if(!dAs[iMod]) continue;

      printf("DA1 for module %d detected.\n",iMod);

      for(Int_t iX=0; iX<64; iX++) {
	for(Int_t iZ=0; iZ<56; iZ++) {

	  for(Int_t iGain=0; iGain<2; iGain++) {
	    sprintf(h2name,"%d_%d_%d_%d",iMod,iX,iZ,iGain);
	    TH2F* h2tot = (TH2F*)ftot->Get(h2name);
	    const TH2F* h2run = dAs[iMod]->GetTimeEnergyHistogram(iX,iZ,iGain); // Time vs Energy
	    if(!h2tot && h2run) h2run->Write();
	    if(h2tot && h2run) { h2tot->Add(h2run); h2tot->Write(h2tot->GetName(),TObject::kWriteDelete); }
	  }
	}
      }
    }
  }

  ftot->Close();

  /* Store output files to the File Exchange Server */
  daqDA_FES_storeFile(totfile,"AMPLITUDES");

  return status;
}
<|endoftext|>


<commit_before>// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.

// Make sure LLVMFuzzerInitialize is called.
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static char *argv0;

extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv) {
  assert(*argc > 0);
  argv0 = **argv;
  fprintf(stderr, "LLVMFuzzerInitialize: %s\n", argv0);
  return 0;
}

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
  if (Size == strlen(argv0) &&
      !strncmp(reinterpret_cast<const char *>(Data), argv0, Size)) {
    fprintf(stderr, "BINGO %s\n", argv0);
    exit(1);
  }
  return 0;
}
<commit_msg>[libFuzzer] Un-reverting change in tests after fixing the failure on Linux.<commit_after>// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.

// Make sure LLVMFuzzerInitialize is called.
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static char *argv0;

extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv) {
  assert(*argc > 0);
  argv0 = **argv;
  fprintf(stderr, "LLVMFuzzerInitialize: %s\n", argv0);
  return 0;
}

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
  if (Size == strlen(argv0) &&
      !memmem(Data, Size, argv0, Size)) {
    fprintf(stderr, "BINGO %s\n", argv0);
    exit(1);
  }
  return 0;
}
<|endoftext|>


<commit_before>#include "Globals.h"

#include "FluidSimulator.h"
#include "../World.h"

cFluidSimulator::cFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid) :
	super(a_World),
	m_FluidBlock(a_Fluid),
	m_StationaryFluidBlock(a_StationaryFluid)
{
}

bool cFluidSimulator::IsAllowedBlock(BLOCKTYPE a_BlockType)
{
	return ((a_BlockType == m_FluidBlock) || (a_BlockType == m_StationaryFluidBlock));
}

bool cFluidSimulator::CanWashAway(BLOCKTYPE a_BlockType)
{
	switch (a_BlockType)
	{
		case E_BLOCK_BROWN_MUSHROOM:
		case E_BLOCK_CACTUS:
		case E_BLOCK_COBWEB:
		case E_BLOCK_CROPS:
		case E_BLOCK_DEAD_BUSH:
		case E_BLOCK_RAIL:
		case E_BLOCK_REDSTONE_TORCH_OFF:
		case E_BLOCK_REDSTONE_TORCH_ON:
		case E_BLOCK_REDSTONE_WIRE:
		case E_BLOCK_RED_MUSHROOM:
		case E_BLOCK_RED_ROSE:
		case E_BLOCK_SNOW:
		case E_BLOCK_SUGARCANE:
		case E_BLOCK_TALL_GRASS:
		case E_BLOCK_TORCH:
		case E_BLOCK_YELLOW_FLOWER:
		{
			return true;
		}
		default:
		{
			return false;
		}
	}
}

bool cFluidSimulator::IsSolidBlock(BLOCKTYPE a_BlockType)
{
	return !IsPassableForFluid(a_BlockType);
}

bool cFluidSimulator::IsPassableForFluid(BLOCKTYPE a_BlockType)
{
	return (
		(a_BlockType == E_BLOCK_AIR) ||
		(a_BlockType == E_BLOCK_FIRE) ||
		IsAllowedBlock(a_BlockType) ||
		CanWashAway(a_BlockType)
	);
}

bool cFluidSimulator::IsHigherMeta(NIBBLETYPE a_Meta1, NIBBLETYPE a_Meta2)
{
	if (a_Meta1 == 0)
	{
		// Source block is higher than anything, even itself.
		return true;
	}
	if ((a_Meta1 & 0x08) != 0)
	{
		// Falling fluid is higher than anything, including self
		return true;
	}

	if (a_Meta2 == 0)
	{
		// Second block is a source and first block isn't
		return false;
	}
	if ((a_Meta2 & 0x08) != 0)
	{
		// Second block is falling and the first one is neither a source nor falling
		return false;
	}

	// All special cases have been handled, now it's just a raw comparison:
	return (a_Meta1 < a_Meta2);
}

// TODO Not working very well yet :s
Direction cFluidSimulator::GetFlowingDirection(int a_X, int a_Y, int a_Z, bool a_Over)
{
	if ((a_Y < 0) || (a_Y >= cChunkDef::Height))
	{
		return NONE;
	}
	BLOCKTYPE BlockID = m_World.GetBlock(a_X, a_Y, a_Z);
	if (!IsAllowedBlock(BlockID))	// No Fluid -> No Flowing direction :D
	{
		return NONE;
	}

	/*
	Disabled because of causing problems and being useless atm
	char BlockBelow = m_World.GetBlock(a_X, a_Y - 1, a_Z);		//If there is nothing or fluid below it -> dominating flow is down :D
	if (BlockBelow == E_BLOCK_AIR || IsAllowedBlock(BlockBelow))
		return Y_MINUS;
	*/

	NIBBLETYPE LowestPoint = m_World.GetBlockMeta(a_X, a_Y, a_Z);	//Current Block Meta so only lower points will be counted
	int X = 0, Z = 0;									//Lowest Pos will be stored here

	if (IsAllowedBlock(m_World.GetBlock(a_X, a_Y + 1, a_Z)) && a_Over)		//check for upper block to flow because this also affects the flowing direction
	{
		return GetFlowingDirection(a_X, a_Y + 1, a_Z, false);
	}

	std::vector< Vector3i * > Points;

	Points.reserve(4);	//Already allocate 4 places :D

	//add blocks around the checking pos
	Points.push_back(new Vector3i(a_X - 1, a_Y, a_Z));
	Points.push_back(new Vector3i(a_X + 1, a_Y, a_Z));
	Points.push_back(new Vector3i(a_X, a_Y, a_Z + 1));
	Points.push_back(new Vector3i(a_X, a_Y, a_Z - 1));

	for (std::vector<Vector3i *>::iterator it = Points.begin(); it < Points.end(); it++)
	{
		Vector3i *Pos = (*it);
		char BlockID = m_World.GetBlock(Pos->x, Pos->y, Pos->z);
		if(IsAllowedBlock(BlockID))
		{
			char Meta = m_World.GetBlockMeta(Pos->x, Pos->y, Pos->z);

			if(Meta > LowestPoint)
			{
				LowestPoint = Meta;
				X = Pos->x;
				Pos->y; //Remove if no side effects
				Z = Pos->z;
			}
		}else if(BlockID == E_BLOCK_AIR)
		{
			LowestPoint = 9;		//This always dominates
			X = Pos->x;
			Pos->y; //Remove if no side effects
			Z = Pos->z;

		}
		delete Pos;
	}

	if (LowestPoint == m_World.GetBlockMeta(a_X, a_Y, a_Z))
		return NONE;

	if (a_X - X > 0)
	{
		return X_MINUS;
	}

	if (a_X - X < 0)
	{
		return X_PLUS;
	}

	if (a_Z - Z > 0)
	{
		return Z_MINUS;
	}

	if (a_Z - Z < 0)
	{
		return Z_PLUS;
	}

	return NONE;
}

<commit_msg>Removed unused lookups<commit_after>#include "Globals.h"

#include "FluidSimulator.h"
#include "../World.h"

cFluidSimulator::cFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid) :
	super(a_World),
	m_FluidBlock(a_Fluid),
	m_StationaryFluidBlock(a_StationaryFluid)
{
}

bool cFluidSimulator::IsAllowedBlock(BLOCKTYPE a_BlockType)
{
	return ((a_BlockType == m_FluidBlock) || (a_BlockType == m_StationaryFluidBlock));
}

bool cFluidSimulator::CanWashAway(BLOCKTYPE a_BlockType)
{
	switch (a_BlockType)
	{
		case E_BLOCK_BROWN_MUSHROOM:
		case E_BLOCK_CACTUS:
		case E_BLOCK_COBWEB:
		case E_BLOCK_CROPS:
		case E_BLOCK_DEAD_BUSH:
		case E_BLOCK_RAIL:
		case E_BLOCK_REDSTONE_TORCH_OFF:
		case E_BLOCK_REDSTONE_TORCH_ON:
		case E_BLOCK_REDSTONE_WIRE:
		case E_BLOCK_RED_MUSHROOM:
		case E_BLOCK_RED_ROSE:
		case E_BLOCK_SNOW:
		case E_BLOCK_SUGARCANE:
		case E_BLOCK_TALL_GRASS:
		case E_BLOCK_TORCH:
		case E_BLOCK_YELLOW_FLOWER:
		{
			return true;
		}
		default:
		{
			return false;
		}
	}
}

bool cFluidSimulator::IsSolidBlock(BLOCKTYPE a_BlockType)
{
	return !IsPassableForFluid(a_BlockType);
}

bool cFluidSimulator::IsPassableForFluid(BLOCKTYPE a_BlockType)
{
	return (
		(a_BlockType == E_BLOCK_AIR) ||
		(a_BlockType == E_BLOCK_FIRE) ||
		IsAllowedBlock(a_BlockType) ||
		CanWashAway(a_BlockType)
	);
}

bool cFluidSimulator::IsHigherMeta(NIBBLETYPE a_Meta1, NIBBLETYPE a_Meta2)
{
	if (a_Meta1 == 0)
	{
		// Source block is higher than anything, even itself.
		return true;
	}
	if ((a_Meta1 & 0x08) != 0)
	{
		// Falling fluid is higher than anything, including self
		return true;
	}

	if (a_Meta2 == 0)
	{
		// Second block is a source and first block isn't
		return false;
	}
	if ((a_Meta2 & 0x08) != 0)
	{
		// Second block is falling and the first one is neither a source nor falling
		return false;
	}

	// All special cases have been handled, now it's just a raw comparison:
	return (a_Meta1 < a_Meta2);
}

// TODO Not working very well yet :s
Direction cFluidSimulator::GetFlowingDirection(int a_X, int a_Y, int a_Z, bool a_Over)
{
	if ((a_Y < 0) || (a_Y >= cChunkDef::Height))
	{
		return NONE;
	}
	BLOCKTYPE BlockID = m_World.GetBlock(a_X, a_Y, a_Z);
	if (!IsAllowedBlock(BlockID))	// No Fluid -> No Flowing direction :D
	{
		return NONE;
	}

	/*
	Disabled because of causing problems and being useless atm
	char BlockBelow = m_World.GetBlock(a_X, a_Y - 1, a_Z);		//If there is nothing or fluid below it -> dominating flow is down :D
	if (BlockBelow == E_BLOCK_AIR || IsAllowedBlock(BlockBelow))
		return Y_MINUS;
	*/

	NIBBLETYPE LowestPoint = m_World.GetBlockMeta(a_X, a_Y, a_Z);	//Current Block Meta so only lower points will be counted
	int X = 0, Z = 0;									//Lowest Pos will be stored here

	if (IsAllowedBlock(m_World.GetBlock(a_X, a_Y + 1, a_Z)) && a_Over)		//check for upper block to flow because this also affects the flowing direction
	{
		return GetFlowingDirection(a_X, a_Y + 1, a_Z, false);
	}

	std::vector< Vector3i * > Points;

	Points.reserve(4);	//Already allocate 4 places :D

	//add blocks around the checking pos
	Points.push_back(new Vector3i(a_X - 1, a_Y, a_Z));
	Points.push_back(new Vector3i(a_X + 1, a_Y, a_Z));
	Points.push_back(new Vector3i(a_X, a_Y, a_Z + 1));
	Points.push_back(new Vector3i(a_X, a_Y, a_Z - 1));

	for (std::vector<Vector3i *>::iterator it = Points.begin(); it < Points.end(); it++)
	{
		Vector3i *Pos = (*it);
		char BlockID = m_World.GetBlock(Pos->x, Pos->y, Pos->z);
		if(IsAllowedBlock(BlockID))
		{
			char Meta = m_World.GetBlockMeta(Pos->x, Pos->y, Pos->z);

			if(Meta > LowestPoint)
			{
				LowestPoint = Meta;
				X = Pos->x;
				Z = Pos->z;
			}
		}else if(BlockID == E_BLOCK_AIR)
		{
			LowestPoint = 9;		//This always dominates
			X = Pos->x;
			Z = Pos->z;

		}
		delete Pos;
	}

	if (LowestPoint == m_World.GetBlockMeta(a_X, a_Y, a_Z))
		return NONE;

	if (a_X - X > 0)
	{
		return X_MINUS;
	}

	if (a_X - X < 0)
	{
		return X_PLUS;
	}

	if (a_Z - Z > 0)
	{
		return Z_MINUS;
	}

	if (a_Z - Z < 0)
	{
		return Z_PLUS;
	}

	return NONE;
}

<|endoftext|>


<commit_before>#include "BatmanScene.h"
#include "DrawingSettings.h"

// OpenGL imports
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>

BatmanScene::BatmanScene() :
    Scene(),
    pi(3.141592)
{
    createScene();
}

void BatmanScene::createScene()
{
    GLfloat light_position[] = {0.0, 1.0, 1.0, 0.0};
    glLightfv(GL_LIGHT0, GL_POSITION, light_position);

    setupCamera();

    // cannot put more than 7 rigidity for cloth
    cape = new Cloth(15.0, 15.0, 15, 2);

    setupClothTips();
    setClothMass(1.0);
    // createRunningScene();
    createCenterCollisionBallScene();
    addForces();

    time = 0.0;
}

void BatmanScene::createRunningScene()
{
    setupFeet();
    createBoundaries();
}

void BatmanScene::addForces()
{
    Vector3 gravity(0.0, -1.0, 0.0);
    Vector3 wind(0.0, 0.0, 10.0);

    cape->addForce(gravity);
    cape->addForce(wind);
}

void BatmanScene::createCenterCollisionBallScene()
{
    otherSpheres.push_back(Sphere(Vector3(7.5, 10.0, 5.0), 2.0));
}

void BatmanScene::setupFeet()
{
    Vector3 centerBetweenFeet(5.0, 2.0, -1.0);

    // left foot
    leftFoot.push_back(Sphere(centerBetweenFeet +  Vector3(-2.0, 0.0, 0.0 ), 1.2));

    // right foot
    rightFoot.push_back(Sphere(centerBetweenFeet + Vector3( 2.0, 0.0, 0.0 ), 1.2));
}

void BatmanScene::setupCamera()
{
    nearPlane = 1.0;
    farPlane  = 200.0;

    camera = new Camera();
    camera->setPosition(Vector3(-10.0, 7.5, 20.0));
    camera->setViewDirection(Vector3(1.0, 0.0, -1.0));
    camera->setUpDirection(Vector3(0.0, 1.0, 0.0));
    camera->saveCameraSetup();
}

void BatmanScene::setClothMass(float mass)
{
    for(int x = 0; x < cape->getNumberNodesWidth() - 1; x += 1)
    {
        for(int y = 0; y < cape->getNumberNodesHeight() - 1; y += 1)
        {
            cape->getNode(x, y)->setMass(mass);
        }
    }
}

void BatmanScene::setupClothTips()
{
    cape->getNode(0                              , cape->getNumberNodesHeight() - 1)->setMoveable(false);
    cape->getNode(cape->getNumberNodesWidth() - 1, cape->getNumberNodesHeight() - 1)->setMoveable(false);
}

void BatmanScene::createBoundaries()
{
    float spacing = cape->getClothWidth() / cape->getNumberNodesWidth();
    for(int x = 0; x < cape->getNumberNodesWidth(); x += 1)
    {
        float xPos = x * spacing;

        for(int y = 0; y < cape->getNumberNodesHeight(); y += 1)
        {
            float yPos = y * spacing;

            // put elements in rectangular grid with yPos depth
            boundaries.push_back(Sphere(Vector3(xPos, yPos, -1.0), 0.5));
            boundaries.push_back(Sphere(Vector3(xPos, yPos, -yPos) + Vector3(0.0, 0.0, 15), 0.5));
        }
    }
}

void BatmanScene::translateBoundaries()
{
    float leftShoulderZ = cape->getNode(0, cape->getNumberNodesHeight() - 1)->getPosition().z;

    for(std::vector<Sphere>::iterator it = boundaries.begin();
        it != boundaries.end();
        ++it)
    {
        it->translate(Vector3(0.0, 0.0, leftShoulderZ) - boundaries[0].getCenter());
    }
}

void BatmanScene::simulate()
{
    float timeStep = DrawingSettings::getInstance()->getTimeStep();
    if(timeStep != 0.0)
    {
        time += timeStep;
        cape->applyForces(timeStep);
        cape->satisfyConstraints();

        // swingLeftFoot();
        // swingLeftShoulder();
        // swingRightFoot();
        // swingRightShoulder();

        // translateBoundaries();
        // cape->handleSphereIntersections(&leftFoot);
        // cape->handleSphereIntersections(&rightFoot);
        // cape->handleSphereIntersections(&boundaries);
        cape->handleSphereIntersections(&otherSpheres);
        cape->handleSelfIntersections();
    }
}

void BatmanScene::drawFeet()
{
    drawBodyElement(&leftFoot);
    drawBodyElement(&rightFoot);
}

void BatmanScene::drawOtherSpheres()
{
    drawBodyElement(&otherSpheres);
}

void BatmanScene::draw()
{
    DrawingSettings::getInstance()->chooseRenderingMethod();
    drawWorldAxis();
    cape->draw();
    drawFeet();
    drawOtherSpheres();

    // TODO : remove
    drawBodyElement(&boundaries);
}

void BatmanScene::drawBodyElement(std::vector<Sphere>* elements)
{
    for(std::vector<Sphere>::iterator sphereIterator = elements->begin();
        sphereIterator != elements->end();
        ++sphereIterator)
    {
        sphereIterator->draw();
    }
}

void BatmanScene::swingLeftFoot()
{
    Sphere* left = &leftFoot[0];
    float r = 1.5;
    float t = time * 100;

    float x = left->getCenter().x;
    float y = r  * (1 - cos(t));
    float z = -r * (t - sin(t));

    Vector3 position(x, y, z);
    left->setCenter(position);
}

void BatmanScene::swingRightFoot()
{
    Sphere* right = &rightFoot[0];
    float r = 1.5;
    float t = time * 100;

    float x = right->getCenter().x;
    float y = r  * (1 - cos(t - pi));
    float z = -r * (t - sin(t - pi));

    Vector3 position(x, y, z);
    right->setCenter(position);
}

void BatmanScene::swingLeftShoulder()
{
    Node* left = cape->getNode(0, cape->getNumberNodesHeight() - 1);
    float r = 1.5;
    float t = time * 100;

    float x = left->getPosition().x;
    float y = left->getPosition().y;
    float z = -r * (t - sin(t - pi));

    Vector3 position(x, y, z);
    left->setPosition(position);
}

void BatmanScene::swingRightShoulder()
{
    Node* right = cape->getNode(cape->getNumberNodesWidth() - 1, cape->getNumberNodesHeight() - 1);
    float r = 1.5;
    float t = time * 100;

    float x = right->getPosition().x;
    float y = right->getPosition().y;
    float z = -r * (t - sin(t));

    Vector3 position(x, y, z);
    right->setPosition(position);
}<commit_msg>running scene boolean<commit_after>#include "BatmanScene.h"
#include "DrawingSettings.h"

// OpenGL imports
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>

BatmanScene::BatmanScene() :
    Scene(),
    pi(3.141592)
{
    createScene();
}

void BatmanScene::createScene()
{
    GLfloat light_position[] = {0.0, 1.0, 1.0, 0.0};
    glLightfv(GL_LIGHT0, GL_POSITION, light_position);

    setupCamera();

    // cannot put more than 7 rigidity for cloth
    cape = new Cloth(15.0, 15.0, 20, 2);

    setupClothTips();
    setClothMass(1.0);
    createRunningScene();
    // createCenterCollisionBallScene();
    addForces();

    time = 0.0;
}

void BatmanScene::createRunningScene()
{
    setupFeet();
    createBoundaries();
}

void BatmanScene::addForces()
{
    Vector3 gravity(0.0, -1.0, 0.0);
    Vector3 wind(0.0, 0.0, 10.0);

    cape->addForce(gravity);
    cape->addForce(wind);
}

void BatmanScene::createCenterCollisionBallScene()
{
    otherSpheres.push_back(Sphere(Vector3(7.5, 10.0, 5.0), 2.0));
}

void BatmanScene::setupFeet()
{
    Vector3 centerBetweenFeet(5.0, 2.0, -1.0);

    // left foot
    leftFoot.push_back(Sphere(centerBetweenFeet +  Vector3(-2.0, 0.0, 0.0 ), 1.2));

    // right foot
    rightFoot.push_back(Sphere(centerBetweenFeet + Vector3( 2.0, 0.0, 0.0 ), 1.2));
}

void BatmanScene::setupCamera()
{
    nearPlane = 1.0;
    farPlane  = 200.0;

    camera = new Camera();
    camera->setPosition(Vector3(-10.0, 7.5, 20.0));
    camera->setViewDirection(Vector3(1.0, 0.0, -1.0));
    camera->setUpDirection(Vector3(0.0, 1.0, 0.0));
    camera->saveCameraSetup();
}

void BatmanScene::setClothMass(float mass)
{
    for(int x = 0; x < cape->getNumberNodesWidth() - 1; x += 1)
    {
        for(int y = 0; y < cape->getNumberNodesHeight() - 1; y += 1)
        {
            cape->getNode(x, y)->setMass(mass);
        }
    }
}

void BatmanScene::setupClothTips()
{
    cape->getNode(0                              , cape->getNumberNodesHeight() - 1)->setMoveable(false);
    cape->getNode(cape->getNumberNodesWidth() - 1, cape->getNumberNodesHeight() - 1)->setMoveable(false);
}

void BatmanScene::createBoundaries()
{
    float spacing = cape->getClothWidth() / cape->getNumberNodesWidth();
    for(int x = 0; x < cape->getNumberNodesWidth(); x += 1)
    {
        float xPos = x * spacing;

        for(int y = 0; y < cape->getNumberNodesHeight(); y += 1)
        {
            float yPos = y * spacing;

            // put elements in rectangular grid with yPos depth
            boundaries.push_back(Sphere(Vector3(xPos, yPos, -1.0), 0.5));
            boundaries.push_back(Sphere(Vector3(xPos, yPos, -yPos) + Vector3(0.0, 0.0, 15), 0.5));
        }
    }
}

void BatmanScene::translateBoundaries()
{
    float leftShoulderZ = cape->getNode(0, cape->getNumberNodesHeight() - 1)->getPosition().z;

    for(std::vector<Sphere>::iterator it = boundaries.begin();
        it != boundaries.end();
        ++it)
    {
        it->translate(Vector3(0.0, 0.0, leftShoulderZ) - boundaries[0].getCenter());
    }
}

void BatmanScene::simulate()
{
    float timeStep = DrawingSettings::getInstance()->getTimeStep();
    if(timeStep != 0.0)
    {
        time += timeStep;
        cape->applyForces(timeStep);
        cape->satisfyConstraints();

        if(runningSceneEnabled)
        {
            swingLeftFoot();
            swingLeftShoulder();
            swingRightFoot();
            swingRightShoulder();

            translateBoundaries();
            cape->handleSphereIntersections(&leftFoot);
            cape->handleSphereIntersections(&rightFoot);
            cape->handleSphereIntersections(&boundaries);
        }
        else
        {
            cape->handleSphereIntersections(&otherSpheres);
        }

        cape->handleSelfIntersections();
    }
}

void BatmanScene::drawFeet()
{
    drawBodyElement(&leftFoot);
    drawBodyElement(&rightFoot);
}

void BatmanScene::drawOtherSpheres()
{
    drawBodyElement(&otherSpheres);
}

void BatmanScene::draw()
{
    DrawingSettings::getInstance()->chooseRenderingMethod();
    drawWorldAxis();
    cape->draw();
    drawFeet();
    drawOtherSpheres();

    // TODO : remove
    drawBodyElement(&boundaries);
}

void BatmanScene::drawBodyElement(std::vector<Sphere>* elements)
{
    for(std::vector<Sphere>::iterator sphereIterator = elements->begin();
        sphereIterator != elements->end();
        ++sphereIterator)
    {
        sphereIterator->draw();
    }
}

void BatmanScene::swingLeftFoot()
{
    Sphere* left = &leftFoot[0];
    float r = 1.5;
    float t = time * 100;

    float x = left->getCenter().x;
    float y = r  * (1 - cos(t));
    float z = -r * (t - sin(t));

    Vector3 position(x, y, z);
    left->setCenter(position);
}

void BatmanScene::swingRightFoot()
{
    Sphere* right = &rightFoot[0];
    float r = 1.5;
    float t = time * 100;

    float x = right->getCenter().x;
    float y = r  * (1 - cos(t - pi));
    float z = -r * (t - sin(t - pi));

    Vector3 position(x, y, z);
    right->setCenter(position);
}

void BatmanScene::swingLeftShoulder()
{
    Node* left = cape->getNode(0, cape->getNumberNodesHeight() - 1);
    float r = 1.5;
    float t = time * 100;

    float x = left->getPosition().x;
    float y = left->getPosition().y;
    float z = -r * (t - sin(t - pi));

    Vector3 position(x, y, z);
    left->setPosition(position);
}

void BatmanScene::swingRightShoulder()
{
    Node* right = cape->getNode(cape->getNumberNodesWidth() - 1, cape->getNumberNodesHeight() - 1);
    float r = 1.5;
    float t = time * 100;

    float x = right->getPosition().x;
    float y = right->getPosition().y;
    float z = -r * (t - sin(t));

    Vector3 position(x, y, z);
    right->setPosition(position);
}<|endoftext|>


<commit_before><commit_msg>INTEGRATION: CWS oj30 (1.38.98); FILE MERGED 2008/01/10 07:59:45 oj 1.38.98.1: #i85085# add std<commit_after><|endoftext|>


<commit_before>#ifndef ALEPH_PERSISTENCE_PAIRS_HH__
#define ALEPH_PERSISTENCE_PAIRS_HH__

#include "BoundaryMatrix.hh"
#include "PersistencePairing.hh"

#include <iostream>
#include <tuple>

namespace aleph
{

template <class ReductionAlgorithm, class Representation> void computePersistencePairs( const BoundaryMatrix<Representation>& M )
{
  using Index              = typename Representation::Index;
  using PersistencePairing = PersistencePairing<Index>;

  BoundaryMatrix<Representation> B = M;

  ReductionAlgorithm reductionAlgorithm;
  reductionAlgorithm( B );

  PersistencePairing pairing;

  auto numColumns = B.getNumColumns();

  for( Index j = Index(0); j < numColumns; j++ )
  {
    Index i;
    bool valid;

    std::tie( i, valid ) = B.getMaximumIndex( j );
    if( valid )
    {
      std::cout << "Pair: " << i << "--" << j << std::endl;

      pairing.add( i, j );
    }
  }
}

}

#endif
<commit_msg>Extended calculation of persistence pairs<commit_after>#ifndef ALEPH_PERSISTENCE_PAIRS_HH__
#define ALEPH_PERSISTENCE_PAIRS_HH__

#include "BoundaryMatrix.hh"
#include "PersistencePairing.hh"

#include <iostream>
#include <tuple>

namespace aleph
{

template <
  class ReductionAlgorithm,
  class Representation
> PersistencePairing<typename Representation::Index> computePersistencePairs( const BoundaryMatrix<Representation>& M )
{
  using Index              = typename Representation::Index;
  using PersistencePairing = PersistencePairing<Index>;

  BoundaryMatrix<Representation> B = M;

  ReductionAlgorithm reductionAlgorithm;
  reductionAlgorithm( B );

  PersistencePairing pairing;

  auto numColumns = B.getNumColumns();

  for( Index j = Index(0); j < numColumns; j++ )
  {
    Index i;
    bool valid;

    std::tie( i, valid ) = B.getMaximumIndex( j );
    if( valid )
    {
      std::cout << "Pair: " << i << "--" << j << std::endl;

      pairing.add( i, j );
    }
  }

  return pairing;
}

}

#endif
<|endoftext|>


<commit_before>/*
Copyright 2017 Intel Corporation

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

#include <assert.h>
#include <thread>
#include <windows.h>

#include "CommandLine.hpp"
#include "PresentMon.hpp"

namespace {

enum {
    HOTKEY_ID = 0x80,

    WM_STOP_ETW_THREADS = WM_USER + 0,
};

HWND g_hWnd = 0;
bool g_originalScrollLockEnabled = false;

std::thread g_EtwConsumingThread;
bool g_StopEtwThreads = true;

bool EtwThreadsRunning()
{
    return g_EtwConsumingThread.joinable();
}

void StartEtwThreads(CommandLineArgs const& args)
{
    assert(!EtwThreadsRunning());
    assert(EtwThreadsShouldQuit());
    g_StopEtwThreads = false;
    g_EtwConsumingThread = std::thread(EtwConsumingThread, args);
}

void StopEtwThreads(CommandLineArgs* args)
{
    assert(EtwThreadsRunning());
    assert(g_StopEtwThreads == false);
    g_StopEtwThreads = true;
    g_EtwConsumingThread.join();
    args->mRecordingCount++;
}

BOOL WINAPI ConsoleCtrlHandler(
    _In_ DWORD dwCtrlType
    )
{
    (void) dwCtrlType;
    PostStopRecording();
    PostQuitProcess();
    return TRUE;
}

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    auto args = (CommandLineArgs*) GetWindowLongPtrW(hWnd, GWLP_USERDATA);

    switch (uMsg) {
    case WM_HOTKEY:
        if (wParam == HOTKEY_ID) {
            if (EtwThreadsRunning()) {
                StopEtwThreads(args);
            } else {
                StartEtwThreads(*args);
            }
        }
        break;

    case WM_STOP_ETW_THREADS:
        if (EtwThreadsRunning()) {
            StopEtwThreads(args);
        }
        break;
    }

    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

HWND CreateMessageQueue(CommandLineArgs& args)
{
    WNDCLASSEXW Class = { sizeof(Class) };
    Class.lpfnWndProc = WindowProc;
    Class.lpszClassName = L"PresentMon";
    if (!RegisterClassExW(&Class)) {
        fprintf(stderr, "error: failed to register hotkey class.\n");
        return 0;
    }

    HWND hWnd = CreateWindowExW(0, Class.lpszClassName, L"PresentMonWnd", 0, 0, 0, 0, 0, HWND_MESSAGE, 0, 0, nullptr);
    if (!hWnd) {
        fprintf(stderr, "error: failed to create hotkey window.\n");
        return 0;
    }

    if (args.mHotkeySupport) {
        if (!RegisterHotKey(hWnd, HOTKEY_ID, args.mHotkeyModifiers, args.mHotkeyVirtualKeyCode)) {
            fprintf(stderr, "error: failed to register hotkey.\n");
            DestroyWindow(hWnd);
            return 0;
        }
    }

    SetWindowLongPtrW(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(&args));

    return hWnd;
}

bool HaveAdministratorPrivileges()
{
    enum {
        PRIVILEGE_UNKNOWN,
        PRIVILEGE_ELEVATED,
        PRIVILEGE_NOT_ELEVATED,
    } static privilege = PRIVILEGE_UNKNOWN;

    if (privilege == PRIVILEGE_UNKNOWN) {
        typedef BOOL(WINAPI *OpenProcessTokenProc)(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle);
        typedef BOOL(WINAPI *GetTokenInformationProc)(HANDLE TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, LPVOID TokenInformation, DWORD TokenInformationLength, DWORD *ReturnLength);
        HMODULE advapi = LoadLibraryA("advapi32");
        if (advapi) {
            OpenProcessTokenProc OpenProcessToken = (OpenProcessTokenProc)GetProcAddress(advapi, "OpenProcessToken");
            GetTokenInformationProc GetTokenInformation = (GetTokenInformationProc)GetProcAddress(advapi, "GetTokenInformation");
            if (OpenProcessToken && GetTokenInformation) {
                HANDLE hToken = NULL;
                if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) {
                    /** BEGIN WORKAROUND: struct TOKEN_ELEVATION and enum value
                     * TokenElevation are not defined in the vs2003 headers, so
                     * we reproduce them here. **/
                    enum { WA_TokenElevation = 20 };
                    struct {
                        DWORD TokenIsElevated;
                    } token = {};
                    /** END WA **/

                    DWORD dwSize = 0;
                    if (GetTokenInformation(hToken, (TOKEN_INFORMATION_CLASS) WA_TokenElevation, &token, sizeof(token), &dwSize)) {
                        privilege = token.TokenIsElevated ? PRIVILEGE_ELEVATED : PRIVILEGE_NOT_ELEVATED;
                    }

                    CloseHandle(hToken);
                }
            }
            FreeLibrary(advapi);
        }
    }

    return privilege == PRIVILEGE_ELEVATED;
}

}

bool EtwThreadsShouldQuit()
{
    return g_StopEtwThreads;
}

void PostToggleRecording(CommandLineArgs const& args)
{
    PostMessage(g_hWnd, WM_HOTKEY, HOTKEY_ID, args.mHotkeyModifiers & ~MOD_NOREPEAT);
}

void PostStopRecording()
{
    PostMessage(g_hWnd, WM_STOP_ETW_THREADS, 0, 0);
}

void PostQuitProcess()
{
    PostMessage(g_hWnd, WM_QUIT, 0, 0);
}

int main(int argc, char** argv)
{
    // Parse command line arguments
    CommandLineArgs args;
    if (!ParseCommandLine(argc, argv, &args)) {
        return 1;
    }

    // Check required privilege
    if (!args.mEtlFileName && !HaveAdministratorPrivileges()) {
        if (args.mTryToElevate) {
            fprintf(stderr, "warning: process requires administrator privilege; attempting to elevate.\n");
            if (!RestartAsAdministrator(argc, argv)) {
                return 1;
            }
        } else {
            fprintf(stderr, "error: process requires administrator privilege.\n");
        }
        return 2;
    }

    int ret = 0;

    // Set console title to command line arguments
    SetConsoleTitle(argc, argv);

    // If the user wants to use the scroll lock key as an indicator of when
    // present mon is recording events, make sure it is disabled to start.
    if (args.mScrollLockIndicator) {
        g_originalScrollLockEnabled = EnableScrollLock(false);
    }

    // Create a message queue to handle WM_HOTKEY, WM_STOP_ETW_THREADS, and
    // WM_QUIT messages.
    HWND hWnd = CreateMessageQueue(args);
    if (hWnd == 0) {
        ret = 3;
        goto clean_up;
    }

    // Set CTRL handler to capture when the user tries to close the process by
    // closing the console window or CTRL-C or similar.  The handler will
    // ignore this and instead post WM_QUIT to our message queue.
    //
    // We must set g_hWnd before setting the handler.
    g_hWnd = hWnd;
    SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE);

    // If the user didn't specify -hotkey, simulate a hotkey press to start the
    // recording right away.
    if (!args.mHotkeySupport) {
        PostToggleRecording(args);
    }

    // Enter the main thread message loop.  This thread will block waiting for
    // any messages, which will control the hotkey-toggling and process
    // shutdown.
    for (MSG message = {}; GetMessageW(&message, hWnd, 0, 0); ) {
        TranslateMessage(&message);
        DispatchMessageW(&message);
    }

    // Everything should be shutdown by now.
    assert(!EtwThreadsRunning());

clean_up:
    // Restore original scroll lock state
    if (args.mScrollLockIndicator) {
        EnableScrollLock(g_originalScrollLockEnabled);
    }

    return ret;
}
<commit_msg>Fix for consistently getting events from processes under separate accounts (like dwm.exe).<commit_after>/*
Copyright 2017 Intel Corporation

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

#include <assert.h>
#include <thread>
#include <windows.h>

#include "CommandLine.hpp"
#include "PresentMon.hpp"

namespace {

enum {
    HOTKEY_ID = 0x80,

    WM_STOP_ETW_THREADS = WM_USER + 0,
};

HWND g_hWnd = 0;
bool g_originalScrollLockEnabled = false;

std::thread g_EtwConsumingThread;
bool g_StopEtwThreads = true;

bool EtwThreadsRunning()
{
    return g_EtwConsumingThread.joinable();
}

void StartEtwThreads(CommandLineArgs const& args)
{
    assert(!EtwThreadsRunning());
    assert(EtwThreadsShouldQuit());
    g_StopEtwThreads = false;
    g_EtwConsumingThread = std::thread(EtwConsumingThread, args);
}

void StopEtwThreads(CommandLineArgs* args)
{
    assert(EtwThreadsRunning());
    assert(g_StopEtwThreads == false);
    g_StopEtwThreads = true;
    g_EtwConsumingThread.join();
    args->mRecordingCount++;
}

BOOL WINAPI ConsoleCtrlHandler(
    _In_ DWORD dwCtrlType
    )
{
    (void) dwCtrlType;
    PostStopRecording();
    PostQuitProcess();
    return TRUE;
}

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    auto args = (CommandLineArgs*) GetWindowLongPtrW(hWnd, GWLP_USERDATA);

    switch (uMsg) {
    case WM_HOTKEY:
        if (wParam == HOTKEY_ID) {
            if (EtwThreadsRunning()) {
                StopEtwThreads(args);
            } else {
                StartEtwThreads(*args);
            }
        }
        break;

    case WM_STOP_ETW_THREADS:
        if (EtwThreadsRunning()) {
            StopEtwThreads(args);
        }
        break;
    }

    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

HWND CreateMessageQueue(CommandLineArgs& args)
{
    WNDCLASSEXW Class = { sizeof(Class) };
    Class.lpfnWndProc = WindowProc;
    Class.lpszClassName = L"PresentMon";
    if (!RegisterClassExW(&Class)) {
        fprintf(stderr, "error: failed to register hotkey class.\n");
        return 0;
    }

    HWND hWnd = CreateWindowExW(0, Class.lpszClassName, L"PresentMonWnd", 0, 0, 0, 0, 0, HWND_MESSAGE, 0, 0, nullptr);
    if (!hWnd) {
        fprintf(stderr, "error: failed to create hotkey window.\n");
        return 0;
    }

    if (args.mHotkeySupport) {
        if (!RegisterHotKey(hWnd, HOTKEY_ID, args.mHotkeyModifiers, args.mHotkeyVirtualKeyCode)) {
            fprintf(stderr, "error: failed to register hotkey.\n");
            DestroyWindow(hWnd);
            return 0;
        }
    }

    SetWindowLongPtrW(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(&args));

    return hWnd;
}

bool HaveAdministratorPrivileges()
{
    enum {
        PRIVILEGE_UNKNOWN,
        PRIVILEGE_ELEVATED,
        PRIVILEGE_NOT_ELEVATED,
    } static privilege = PRIVILEGE_UNKNOWN;

    if (privilege == PRIVILEGE_UNKNOWN) {
        typedef BOOL(WINAPI *OpenProcessTokenProc)(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle);
        typedef BOOL(WINAPI *GetTokenInformationProc)(HANDLE TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, LPVOID TokenInformation, DWORD TokenInformationLength, DWORD *ReturnLength);
        HMODULE advapi = LoadLibraryA("advapi32");
        if (advapi) {
            OpenProcessTokenProc OpenProcessToken = (OpenProcessTokenProc)GetProcAddress(advapi, "OpenProcessToken");
            GetTokenInformationProc GetTokenInformation = (GetTokenInformationProc)GetProcAddress(advapi, "GetTokenInformation");
            if (OpenProcessToken && GetTokenInformation) {
                HANDLE hToken = NULL;
                if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) {
                    /** BEGIN WORKAROUND: struct TOKEN_ELEVATION and enum value
                     * TokenElevation are not defined in the vs2003 headers, so
                     * we reproduce them here. **/
                    enum { WA_TokenElevation = 20 };
                    struct {
                        DWORD TokenIsElevated;
                    } token = {};
                    /** END WA **/

                    DWORD dwSize = 0;
                    if (GetTokenInformation(hToken, (TOKEN_INFORMATION_CLASS) WA_TokenElevation, &token, sizeof(token), &dwSize)) {
                        privilege = token.TokenIsElevated ? PRIVILEGE_ELEVATED : PRIVILEGE_NOT_ELEVATED;
                    }

                    CloseHandle(hToken);
                }
            }
            FreeLibrary(advapi);
        }
    }

    return privilege == PRIVILEGE_ELEVATED;
}

bool SetPrivilege(HANDLE hToken, LPCSTR lpszPrivilege, bool bEnablePrivilege)
{
    bool bPrivilegeSet = false;
    typedef BOOL(WINAPI *LookupPrivilegeValueAProc)(LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid);
    typedef BOOL(WINAPI *AdjustTokenPrivilegesProc)(HANDLE TokenHandle, BOOL DisableAllPrivileges, PTOKEN_PRIVILEGES NewState, DWORD BufferLength, PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength);
    HMODULE advapi = LoadLibraryA("advapi32");
    if (advapi) {
        LookupPrivilegeValueAProc LookupPrivilegeValueA = (LookupPrivilegeValueAProc)GetProcAddress(advapi, "LookupPrivilegeValueA");
        AdjustTokenPrivilegesProc AdjustTokenPrivileges = (AdjustTokenPrivilegesProc)GetProcAddress(advapi, "AdjustTokenPrivileges");
        if (LookupPrivilegeValueA && AdjustTokenPrivileges) {
            LUID luid;
            if (LookupPrivilegeValueA(NULL, lpszPrivilege, &luid)) {
                TOKEN_PRIVILEGES tp;
                tp.PrivilegeCount = 1;
                tp.Privileges[0].Luid = luid;
                tp.Privileges[0].Attributes = bEnablePrivilege ? SE_PRIVILEGE_ENABLED : 0;

                if (AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL)) {
                    if (GetLastError() != ERROR_NOT_ALL_ASSIGNED) {
                        bPrivilegeSet = true;
                    }
                    else {
                        fprintf(stderr, "error: token does not have the specified privilege.\n");
                    }
                }
                else {
                    fprintf(stderr, "error: failed to adjust token privileges (%u).\n", GetLastError());
                }
            }
            else {
                fprintf(stderr, "error: failed to lookup privilege value (%u).\n", GetLastError());
            }
        }
        FreeLibrary(advapi);
    }

    return bPrivilegeSet;
}

bool AdjustPrivileges()
{
    // DWM processes run under a separate account.
    // We need permissions to get data about a process owned by another account.
    bool bPrivilegesSet = false;
    typedef BOOL(WINAPI *OpenProcessTokenProc)(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle);
    HMODULE advapi = LoadLibraryA("advapi32");
    if (advapi) {
        OpenProcessTokenProc OpenProcessToken = (OpenProcessTokenProc)GetProcAddress(advapi, "OpenProcessToken");
        if (OpenProcessToken) {
            HANDLE hToken = NULL;
            if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) {
                if (SetPrivilege(hToken, "SeDebugPrivilege", true)) {
                    bPrivilegesSet = true;
                }
                else {
                    fprintf(stderr, "error: failed to enable SeDebugPrivilege.\n");
                }

                CloseHandle(hToken);
            }
        }
        FreeLibrary(advapi);
    }

    return bPrivilegesSet;
}

}

bool EtwThreadsShouldQuit()
{
    return g_StopEtwThreads;
}

void PostToggleRecording(CommandLineArgs const& args)
{
    PostMessage(g_hWnd, WM_HOTKEY, HOTKEY_ID, args.mHotkeyModifiers & ~MOD_NOREPEAT);
}

void PostStopRecording()
{
    PostMessage(g_hWnd, WM_STOP_ETW_THREADS, 0, 0);
}

void PostQuitProcess()
{
    PostMessage(g_hWnd, WM_QUIT, 0, 0);
}

int main(int argc, char** argv)
{
    // Parse command line arguments
    CommandLineArgs args;
    if (!ParseCommandLine(argc, argv, &args)) {
        return 1;
    }

    // Check required privilege
    if (!args.mEtlFileName && !HaveAdministratorPrivileges()) {
        if (args.mTryToElevate) {
            fprintf(stderr, "warning: process requires administrator privilege; attempting to elevate.\n");
            if (!RestartAsAdministrator(argc, argv)) {
                return 1;
            }
        } else {
            fprintf(stderr, "error: process requires administrator privilege.\n");
        }
        return 2;
    }

    // Adjust process privileges for real-time
    if (!args.mEtlFileName && !AdjustPrivileges()) {
        fprintf(stderr, "error: process requires special privileges.\n");
    }

    int ret = 0;

    // Set console title to command line arguments
    SetConsoleTitle(argc, argv);

    // If the user wants to use the scroll lock key as an indicator of when
    // present mon is recording events, make sure it is disabled to start.
    if (args.mScrollLockIndicator) {
        g_originalScrollLockEnabled = EnableScrollLock(false);
    }

    // Create a message queue to handle WM_HOTKEY, WM_STOP_ETW_THREADS, and
    // WM_QUIT messages.
    HWND hWnd = CreateMessageQueue(args);
    if (hWnd == 0) {
        ret = 3;
        goto clean_up;
    }

    // Set CTRL handler to capture when the user tries to close the process by
    // closing the console window or CTRL-C or similar.  The handler will
    // ignore this and instead post WM_QUIT to our message queue.
    //
    // We must set g_hWnd before setting the handler.
    g_hWnd = hWnd;
    SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE);

    // If the user didn't specify -hotkey, simulate a hotkey press to start the
    // recording right away.
    if (!args.mHotkeySupport) {
        PostToggleRecording(args);
    }

    // Enter the main thread message loop.  This thread will block waiting for
    // any messages, which will control the hotkey-toggling and process
    // shutdown.
    for (MSG message = {}; GetMessageW(&message, hWnd, 0, 0); ) {
        TranslateMessage(&message);
        DispatchMessageW(&message);
    }

    // Everything should be shutdown by now.
    assert(!EtwThreadsRunning());

clean_up:
    // Restore original scroll lock state
    if (args.mScrollLockIndicator) {
        EnableScrollLock(g_originalScrollLockEnabled);
    }

    return ret;
}
<|endoftext|>


<commit_before>#pragma once

#include "xml_doc.hpp"
#include "libxml2_error_handlers.hpp"
#include <libxml/xpath.h>
#include <memory>

class FreeXPathCtxt {
public:
    auto operator( )( xmlXPathContext *xpathCtxt ) const -> void {
        xmlXPathFreeContext( xpathCtxt );
    }
};

class XPathCtxt {
    friend class XPathQuery;

public:
    XPathCtxt( ) : xpathCtxt_{nullptr} {}
    explicit XPathCtxt( const XmlDoc &xml )
        : xpathCtxt_{xmlXPathNewContext( xml.xmlDoc_.get( ) )} {
        xpathHandler_.registerHandler( xpathCtxt_.get( ) );
    }
    XPathCtxt( const XPathCtxt &xpathCtxt ) {
        xpathCtxt_.reset( xmlXPathNewContext( xpathCtxt.xpathCtxt_->doc ) );
        xpathHandler_.registerHandler( xpathCtxt_.get( ) );
    }
    XPathCtxt( XPathCtxt &&xpathCtxt )
        : xpathCtxt_{std::move( xpathCtxt.xpathCtxt_ )},
          xpathHandler_{std::move( xpathCtxt.xpathHandler_ )} {}
    auto operator=( const XPathCtxt &rhs ) -> XPathCtxt & {
        if ( this != &rhs ) {
            xpathCtxt_.reset( xmlXPathNewContext( rhs.xpathCtxt_->doc ) );
            xpathHandler_ = rhs.xpathHandler_;
        }
        return *this;
    }
    auto operator=( XPathCtxt &&xpathCtxt ) -> XPathCtxt & {
        xpathCtxt_ = std::move( xpathCtxt.xpathCtxt_ );
        xpathHandler_ = std::move( xpathCtxt.xpathHandler_ );
        return *this;
    }
    explicit operator bool( ) const { return ( xpathCtxt_ != nullptr ); }
    friend auto operator>>( const XmlDoc &xml, XPathCtxt &xpathCtxt ) -> XPathCtxt & {
        xpathCtxt.xpathCtxt_.reset( xmlXPathNewContext( xml.xmlDoc_.get( ) ) );
        xpathCtxt.xpathHandler_.registerHandler(
            xpathCtxt.xpathCtxt_.get( ) ); // ist this correct?
        return xpathCtxt;
    }
    auto errorHandler( ) const -> const IErrorHandler & { return xpathHandler_; }

private:
    using XPathCtxtT = std::unique_ptr<xmlXPathContext, FreeXPathCtxt>;
    XPathCtxtT xpathCtxt_;
    XPathErrorHandler xpathHandler_;
};

<commit_msg>operator bool() returns false for empty XmlDoc<commit_after>#pragma once

#include "xml_doc.hpp"
#include "libxml2_error_handlers.hpp"
#include <libxml/xpath.h>
#include <memory>
#include <iostream>

class FreeXPathCtxt {
public:
    auto operator( )( xmlXPathContext *xpathCtxt ) const -> void {
        xmlXPathFreeContext( xpathCtxt );
    }
};

class XPathCtxt {
    friend class XPathQuery;

public:
    XPathCtxt( ) : xpathCtxt_{nullptr} {}
    explicit XPathCtxt( const XmlDoc &xml )
        : xpathCtxt_{xmlXPathNewContext( xml.xmlDoc_.get( ) )} {
        xpathHandler_.registerHandler( xpathCtxt_.get( ) );
    }
    XPathCtxt( const XPathCtxt &xpathCtxt ) {
        xpathCtxt_.reset( xmlXPathNewContext( xpathCtxt.xpathCtxt_->doc ) );
        xpathHandler_.registerHandler( xpathCtxt_.get( ) );
    }
    XPathCtxt( XPathCtxt &&xpathCtxt )
        : xpathCtxt_{std::move( xpathCtxt.xpathCtxt_ )},
          xpathHandler_{std::move( xpathCtxt.xpathHandler_ )} {}
    auto operator=( const XPathCtxt &rhs ) -> XPathCtxt & {
        if ( this != &rhs ) {
            xpathCtxt_.reset( xmlXPathNewContext( rhs.xpathCtxt_->doc ) );
            xpathHandler_ = rhs.xpathHandler_;
        }
        return *this;
    }
    auto operator=( XPathCtxt &&xpathCtxt ) -> XPathCtxt & {
        xpathCtxt_ = std::move( xpathCtxt.xpathCtxt_ );
        xpathHandler_ = std::move( xpathCtxt.xpathHandler_ );
        return *this;
    }
    explicit operator bool( ) const {
        return ( xpathCtxt_ != nullptr && xpathCtxt_->doc != nullptr );
    }
    friend auto operator>>( const XmlDoc &xml, XPathCtxt &xpathCtxt ) -> XPathCtxt & {
        xpathCtxt.xpathCtxt_.reset( xmlXPathNewContext( xml.xmlDoc_.get( ) ) );
        xpathCtxt.xpathHandler_.registerHandler(
            xpathCtxt.xpathCtxt_.get( ) ); // ist this correct?
        return xpathCtxt;
    }
    auto errorHandler( ) const -> const IErrorHandler & { return xpathHandler_; }

private:
    using XPathCtxtT = std::unique_ptr<xmlXPathContext, FreeXPathCtxt>;
    XPathCtxtT xpathCtxt_;
    XPathErrorHandler xpathHandler_;
};

<|endoftext|>


<commit_before><commit_msg>Oilpan: Add a comment to markPointer<commit_after><|endoftext|>