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

  Program:   Visualization Toolkit
  Module:    vtkDotProductSimilarity.cxx

-------------------------------------------------------------------------
  Copyright 2008 Sandia Corporation.
  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
  the U.S. Government retains certain rights in this software.
-------------------------------------------------------------------------

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

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

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

#include "vtkArrayData.h"
#include "vtkCommand.h"
#include "vtkDotProductSimilarity.h"
#include "vtkDenseArray.h"
#include "vtkDoubleArray.h"
#include "vtkIdTypeArray.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkSmartPointer.h"
#include "vtkTable.h"

#include <vtksys/stl/algorithm>
#include <vtkstd/map>
#include <vtkstd/stdexcept>

// threshold_multimap
// This strange little fellow is used by the vtkDotProductSimilarity
// implementation.  It provides the interface
// of a vtkstd::multimap, but it enforces several constraints on its contents:
//
// There is an upper-limit on the number of values stored in the container.
// There is a lower threshold on key-values stored in the container.
// The key threshold can be overridden by specifying a lower-limit on the
// number of values stored in the container.

template<typename KeyT, typename ValueT>
class threshold_multimap :
  public vtkstd::multimap<KeyT, ValueT, vtkstd::less<KeyT> >
{
  typedef vtkstd::multimap<KeyT, ValueT, vtkstd::less<KeyT> > container_t;

public:
  threshold_multimap(KeyT minimum_threshold, size_t minimum_count, size_t maximum_count) :
    MinimumThreshold(minimum_threshold),
    MinimumCount(vtkstd::max(static_cast<size_t>(0), minimum_count)),
    MaximumCount(vtkstd::max(static_cast<size_t>(0), maximum_count))
  {
  }

  void insert(const typename container_t::value_type& value)
  {
    // Insert the value into the container ...
    container_t::insert(value);

    // Prune small values down to our minimum size ...
    while((this->size() > this->MinimumCount) && (this->begin()->first < this->MinimumThreshold))
      this->erase(this->begin());

    // Prune small values down to our maximum size ...
    while(this->size() > this->MaximumCount)
      this->erase(this->begin());
  }

private:
  typename container_t::iterator insert(typename container_t::iterator where, const typename container_t::value_type& value);
  template<class InIt>
  void insert(InIt first, InIt last);

  KeyT MinimumThreshold;
  size_t MinimumCount;
  size_t MaximumCount;
};

// ----------------------------------------------------------------------

vtkCxxRevisionMacro(vtkDotProductSimilarity, "1.2");
vtkStandardNewMacro(vtkDotProductSimilarity);

// ----------------------------------------------------------------------

vtkDotProductSimilarity::vtkDotProductSimilarity() :
  VectorDimension(1),
  MinimumThreshold(1),
  MinimumCount(1),
  MaximumCount(10),
  UpperDiagonal(true),
  Diagonal(false),
  LowerDiagonal(false),
  FirstSecond(true),
  SecondFirst(true)
{
  this->SetNumberOfInputPorts(2);
  this->SetNumberOfOutputPorts(1);
}

// ----------------------------------------------------------------------

vtkDotProductSimilarity::~vtkDotProductSimilarity()
{
}

// ----------------------------------------------------------------------

void vtkDotProductSimilarity::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
  os << indent << "VectorDimension: " << this->VectorDimension << endl;
  os << indent << "MinimumThreshold: " << this->MinimumThreshold << endl;
  os << indent << "MinimumCount: " << this->MinimumCount << endl;
  os << indent << "MaximumCount: " << this->MaximumCount << endl;
}

int vtkDotProductSimilarity::FillInputPortInformation(int port, vtkInformation* info)
{
  switch(port)
    {
    case 0:
      info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkArrayData");
      return 1;
    case 1:
      info->Set(vtkAlgorithm::INPUT_IS_OPTIONAL(), 1);
      info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkArrayData");
      return 1;
    }

  return 0;
}

// ----------------------------------------------------------------------

static double DotProduct(vtkDenseArray<double>* input_a, vtkDenseArray<double>* input_b, const vtkIdType vector_a, const vtkIdType vector_b, const vtkIdType vector_dimension, const vtkIdType component_dimension, const vtkIdType component_count)
{
  vtkArrayCoordinates coordinates_a(0, 0);
  vtkArrayCoordinates coordinates_b(0, 0);

  coordinates_a[vector_dimension] = vector_a;
  coordinates_b[vector_dimension] = vector_b;

  double dot_product = 0.0;
  for(vtkIdType component = 0; component != component_count; ++component)
    {
    coordinates_a[component_dimension] = component;
    coordinates_b[component_dimension] = component;
    dot_product += input_a->GetValue(coordinates_a) * input_b->GetValue(coordinates_b);
    }
  return dot_product;
}

int vtkDotProductSimilarity::RequestData(
  vtkInformation*,
  vtkInformationVector** inputVector,
  vtkInformationVector* outputVector)
{
  try
    {
    // Enforce our preconditions ...
    vtkArrayData* const input_a = vtkArrayData::GetData(inputVector[0]);
    if(!input_a)
      throw vtkstd::runtime_error("Missing array data input on input port 0.");
    if(input_a->GetNumberOfArrays() != 1)
      throw vtkstd::runtime_error("Array data on input port 0 must contain exactly one array.");
    vtkDenseArray<double>* const input_array_a = vtkDenseArray<double>::SafeDownCast(input_a->GetArray(0));
    if(!input_array_a)
      throw vtkstd::runtime_error("Array on input port 0 must be a vtkDenseArray<double>.");
    if(input_array_a->GetDimensions() != 2)
      throw vtkstd::runtime_error("Array on input port 0 must be a matrix.");

    vtkArrayData* const input_b = vtkArrayData::GetData(inputVector[1]);
    vtkDenseArray<double>* input_array_b = 0;
    if(input_b)
      {
      if(input_b->GetNumberOfArrays() != 1)
        throw vtkstd::runtime_error("Array data on input port 1 must contain exactly one array.");
      input_array_b = vtkDenseArray<double>::SafeDownCast(input_b->GetArray(0));
      if(!input_array_b)
        throw vtkstd::runtime_error("Array on input port 1 must be a vtkDenseArray<double>.");
      if(input_array_b->GetDimensions() != 2)
        throw vtkstd::runtime_error("Array on input port 1 must be a matrix.");
      }

    const vtkIdType vector_dimension = this->VectorDimension;
    if(vector_dimension != 0 && vector_dimension != 1)
      throw vtkstd::runtime_error("VectorDimension must be zero or one.");

    const vtkIdType component_dimension = 1 - vector_dimension;

    const vtkIdType vector_count_a = input_array_a->GetExtents()[vector_dimension];
    const vtkIdType component_count_a = input_array_a->GetExtents()[component_dimension];

    const vtkIdType vector_count_b = input_array_b ? input_array_b->GetExtents()[vector_dimension] : 0;
    const vtkIdType component_count_b = input_array_b ? input_array_b->GetExtents()[component_dimension] : 0;

    if(input_array_b && (component_count_a != component_count_b))
      throw vtkstd::runtime_error("Input array vector lengths must match.");

    // Get output arrays ...
    vtkTable* const output = vtkTable::GetData(outputVector);

    vtkIdTypeArray* const source_array = vtkIdTypeArray::New();
    source_array->SetName("source");

    vtkIdTypeArray* const target_array = vtkIdTypeArray::New();
    target_array->SetName("target");

    vtkDoubleArray* const similarity_array = vtkDoubleArray::New();
    similarity_array->SetName("similarity");

    // Okay let outside world know that I'm starting
    double progress = 0;
    this->InvokeEvent(vtkCommand::ProgressEvent, &progress);

    typedef threshold_multimap<double, vtkIdType> similarities_t;
    if(input_array_b)
      {
      // Compare the first matrix with the second matrix ...
      if(this->FirstSecond)
        {
        for(vtkIdType vector_a = 0; vector_a != vector_count_a; ++vector_a)
          {
          similarities_t similarities(this->MinimumThreshold, this->MinimumCount, this->MaximumCount);

          for(vtkIdType vector_b = 0; vector_b != vector_count_b; ++vector_b)
            {
            // Can't use vtkstd::make_pair - see http://sahajtechstyle.blogspot.com/2007/11/whats-wrong-with-sun-studio-c.html
            similarities.insert(vtkstd::pair<const double, vtkIdType>(DotProduct(input_array_a, input_array_b, vector_a, vector_b, vector_dimension, component_dimension, component_count_a), vector_b));
            }

          for(similarities_t::const_iterator similarity = similarities.begin(); similarity != similarities.end(); ++similarity)
            {
            source_array->InsertNextValue(vector_a);
            target_array->InsertNextValue(similarity->second);
            similarity_array->InsertNextValue(similarity->first);
            }
          }
        }
      // Compare the second matrix with the first matrix ...
      if(this->SecondFirst)
        {
        for(vtkIdType vector_b = 0; vector_b != vector_count_b; ++vector_b)
          {
          similarities_t similarities(this->MinimumThreshold, this->MinimumCount, this->MaximumCount);

          for(vtkIdType vector_a = 0; vector_a != vector_count_a; ++vector_a)
            {
            // Can't use vtkstd::make_pair - see http://sahajtechstyle.blogspot.com/2007/11/whats-wrong-with-sun-studio-c.html
            similarities.insert(vtkstd::pair<const double, vtkIdType>(DotProduct(input_array_b, input_array_a, vector_b, vector_a, vector_dimension, component_dimension, component_count_a), vector_a));
            }

          for(similarities_t::const_iterator similarity = similarities.begin(); similarity != similarities.end(); ++similarity)
            {
            source_array->InsertNextValue(vector_b);
            target_array->InsertNextValue(similarity->second);
            similarity_array->InsertNextValue(similarity->first);
            }
          }
        }
      }
    // Compare the one matrix with itself ...
    else
      {
      for(vtkIdType vector_a = 0; vector_a != vector_count_a; ++vector_a)
        {
        similarities_t similarities(this->MinimumThreshold, this->MinimumCount, this->MaximumCount);

        for(vtkIdType vector_b = 0; vector_b != vector_count_a; ++vector_b)
          {
          if((vector_b > vector_a) && !this->UpperDiagonal)
            continue;

          if((vector_b == vector_a) && !this->Diagonal)
            continue;

          if((vector_b < vector_a) && !this->LowerDiagonal)
            continue;

          // Can't use vtkstd::make_pair - see http://sahajtechstyle.blogspot.com/2007/11/whats-wrong-with-sun-studio-c.html
          similarities.insert(vtkstd::pair<const double, vtkIdType>(DotProduct(input_array_a, input_array_a, vector_a, vector_b, vector_dimension, component_dimension, component_count_a), vector_b));
          }

        for(similarities_t::const_iterator similarity = similarities.begin(); similarity != similarities.end(); ++similarity)
          {
          source_array->InsertNextValue(vector_a);
          target_array->InsertNextValue(similarity->second);
          similarity_array->InsertNextValue(similarity->first);
          }
        }
      }

    output->AddColumn(source_array);
    output->AddColumn(target_array);
    output->AddColumn(similarity_array);

    source_array->Delete();
    target_array->Delete();
    similarity_array->Delete();

    return 1;
    }
  catch(vtkstd::exception& e)
    {
    vtkErrorMacro(<< "unhandled exception: " << e.what());
    return 0;
    }
  catch(...)
    {
    vtkErrorMacro(<< "unknown exception");
    return 0;
    }
}

<commit_msg>STYLE: Add missing parameters to vtkDotProductSimilarity::PrintSelf().<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkDotProductSimilarity.cxx

-------------------------------------------------------------------------
  Copyright 2008 Sandia Corporation.
  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
  the U.S. Government retains certain rights in this software.
-------------------------------------------------------------------------

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

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

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

#include "vtkArrayData.h"
#include "vtkCommand.h"
#include "vtkDotProductSimilarity.h"
#include "vtkDenseArray.h"
#include "vtkDoubleArray.h"
#include "vtkIdTypeArray.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkSmartPointer.h"
#include "vtkTable.h"

#include <vtksys/stl/algorithm>
#include <vtkstd/map>
#include <vtkstd/stdexcept>

// threshold_multimap
// This strange little fellow is used by the vtkDotProductSimilarity
// implementation.  It provides the interface
// of a vtkstd::multimap, but it enforces several constraints on its contents:
//
// There is an upper-limit on the number of values stored in the container.
// There is a lower threshold on key-values stored in the container.
// The key threshold can be overridden by specifying a lower-limit on the
// number of values stored in the container.

template<typename KeyT, typename ValueT>
class threshold_multimap :
  public vtkstd::multimap<KeyT, ValueT, vtkstd::less<KeyT> >
{
  typedef vtkstd::multimap<KeyT, ValueT, vtkstd::less<KeyT> > container_t;

public:
  threshold_multimap(KeyT minimum_threshold, size_t minimum_count, size_t maximum_count) :
    MinimumThreshold(minimum_threshold),
    MinimumCount(vtkstd::max(static_cast<size_t>(0), minimum_count)),
    MaximumCount(vtkstd::max(static_cast<size_t>(0), maximum_count))
  {
  }

  void insert(const typename container_t::value_type& value)
  {
    // Insert the value into the container ...
    container_t::insert(value);

    // Prune small values down to our minimum size ...
    while((this->size() > this->MinimumCount) && (this->begin()->first < this->MinimumThreshold))
      this->erase(this->begin());

    // Prune small values down to our maximum size ...
    while(this->size() > this->MaximumCount)
      this->erase(this->begin());
  }

private:
  typename container_t::iterator insert(typename container_t::iterator where, const typename container_t::value_type& value);
  template<class InIt>
  void insert(InIt first, InIt last);

  KeyT MinimumThreshold;
  size_t MinimumCount;
  size_t MaximumCount;
};

// ----------------------------------------------------------------------

vtkCxxRevisionMacro(vtkDotProductSimilarity, "1.3");
vtkStandardNewMacro(vtkDotProductSimilarity);

// ----------------------------------------------------------------------

vtkDotProductSimilarity::vtkDotProductSimilarity() :
  VectorDimension(1),
  MinimumThreshold(1),
  MinimumCount(1),
  MaximumCount(10),
  UpperDiagonal(true),
  Diagonal(false),
  LowerDiagonal(false),
  FirstSecond(true),
  SecondFirst(true)
{
  this->SetNumberOfInputPorts(2);
  this->SetNumberOfOutputPorts(1);
}

// ----------------------------------------------------------------------

vtkDotProductSimilarity::~vtkDotProductSimilarity()
{
}

// ----------------------------------------------------------------------

void vtkDotProductSimilarity::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
  os << indent << "VectorDimension: " << this->VectorDimension << endl;
  os << indent << "MinimumThreshold: " << this->MinimumThreshold << endl;
  os << indent << "MinimumCount: " << this->MinimumCount << endl;
  os << indent << "MaximumCount: " << this->MaximumCount << endl;
  os << indent << "UpperDiagonal: " << this->UpperDiagonal << endl;
  os << indent << "Diagonal: " << this->Diagonal << endl;
  os << indent << "LowerDiagonal: " << this->LowerDiagonal << endl;
  os << indent << "FirstSecond: " << this->FirstSecond << endl;
  os << indent << "SecondFirst: " << this->SecondFirst << endl;
}

int vtkDotProductSimilarity::FillInputPortInformation(int port, vtkInformation* info)
{
  switch(port)
    {
    case 0:
      info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkArrayData");
      return 1;
    case 1:
      info->Set(vtkAlgorithm::INPUT_IS_OPTIONAL(), 1);
      info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkArrayData");
      return 1;
    }

  return 0;
}

// ----------------------------------------------------------------------

static double DotProduct(vtkDenseArray<double>* input_a, vtkDenseArray<double>* input_b, const vtkIdType vector_a, const vtkIdType vector_b, const vtkIdType vector_dimension, const vtkIdType component_dimension, const vtkIdType component_count)
{
  vtkArrayCoordinates coordinates_a(0, 0);
  vtkArrayCoordinates coordinates_b(0, 0);

  coordinates_a[vector_dimension] = vector_a;
  coordinates_b[vector_dimension] = vector_b;

  double dot_product = 0.0;
  for(vtkIdType component = 0; component != component_count; ++component)
    {
    coordinates_a[component_dimension] = component;
    coordinates_b[component_dimension] = component;
    dot_product += input_a->GetValue(coordinates_a) * input_b->GetValue(coordinates_b);
    }
  return dot_product;
}

int vtkDotProductSimilarity::RequestData(
  vtkInformation*,
  vtkInformationVector** inputVector,
  vtkInformationVector* outputVector)
{
  try
    {
    // Enforce our preconditions ...
    vtkArrayData* const input_a = vtkArrayData::GetData(inputVector[0]);
    if(!input_a)
      throw vtkstd::runtime_error("Missing array data input on input port 0.");
    if(input_a->GetNumberOfArrays() != 1)
      throw vtkstd::runtime_error("Array data on input port 0 must contain exactly one array.");
    vtkDenseArray<double>* const input_array_a = vtkDenseArray<double>::SafeDownCast(input_a->GetArray(0));
    if(!input_array_a)
      throw vtkstd::runtime_error("Array on input port 0 must be a vtkDenseArray<double>.");
    if(input_array_a->GetDimensions() != 2)
      throw vtkstd::runtime_error("Array on input port 0 must be a matrix.");

    vtkArrayData* const input_b = vtkArrayData::GetData(inputVector[1]);
    vtkDenseArray<double>* input_array_b = 0;
    if(input_b)
      {
      if(input_b->GetNumberOfArrays() != 1)
        throw vtkstd::runtime_error("Array data on input port 1 must contain exactly one array.");
      input_array_b = vtkDenseArray<double>::SafeDownCast(input_b->GetArray(0));
      if(!input_array_b)
        throw vtkstd::runtime_error("Array on input port 1 must be a vtkDenseArray<double>.");
      if(input_array_b->GetDimensions() != 2)
        throw vtkstd::runtime_error("Array on input port 1 must be a matrix.");
      }

    const vtkIdType vector_dimension = this->VectorDimension;
    if(vector_dimension != 0 && vector_dimension != 1)
      throw vtkstd::runtime_error("VectorDimension must be zero or one.");

    const vtkIdType component_dimension = 1 - vector_dimension;

    const vtkIdType vector_count_a = input_array_a->GetExtents()[vector_dimension];
    const vtkIdType component_count_a = input_array_a->GetExtents()[component_dimension];

    const vtkIdType vector_count_b = input_array_b ? input_array_b->GetExtents()[vector_dimension] : 0;
    const vtkIdType component_count_b = input_array_b ? input_array_b->GetExtents()[component_dimension] : 0;

    if(input_array_b && (component_count_a != component_count_b))
      throw vtkstd::runtime_error("Input array vector lengths must match.");

    // Get output arrays ...
    vtkTable* const output = vtkTable::GetData(outputVector);

    vtkIdTypeArray* const source_array = vtkIdTypeArray::New();
    source_array->SetName("source");

    vtkIdTypeArray* const target_array = vtkIdTypeArray::New();
    target_array->SetName("target");

    vtkDoubleArray* const similarity_array = vtkDoubleArray::New();
    similarity_array->SetName("similarity");

    // Okay let outside world know that I'm starting
    double progress = 0;
    this->InvokeEvent(vtkCommand::ProgressEvent, &progress);

    typedef threshold_multimap<double, vtkIdType> similarities_t;
    if(input_array_b)
      {
      // Compare the first matrix with the second matrix ...
      if(this->FirstSecond)
        {
        for(vtkIdType vector_a = 0; vector_a != vector_count_a; ++vector_a)
          {
          similarities_t similarities(this->MinimumThreshold, this->MinimumCount, this->MaximumCount);

          for(vtkIdType vector_b = 0; vector_b != vector_count_b; ++vector_b)
            {
            // Can't use vtkstd::make_pair - see http://sahajtechstyle.blogspot.com/2007/11/whats-wrong-with-sun-studio-c.html
            similarities.insert(vtkstd::pair<const double, vtkIdType>(DotProduct(input_array_a, input_array_b, vector_a, vector_b, vector_dimension, component_dimension, component_count_a), vector_b));
            }

          for(similarities_t::const_iterator similarity = similarities.begin(); similarity != similarities.end(); ++similarity)
            {
            source_array->InsertNextValue(vector_a);
            target_array->InsertNextValue(similarity->second);
            similarity_array->InsertNextValue(similarity->first);
            }
          }
        }
      // Compare the second matrix with the first matrix ...
      if(this->SecondFirst)
        {
        for(vtkIdType vector_b = 0; vector_b != vector_count_b; ++vector_b)
          {
          similarities_t similarities(this->MinimumThreshold, this->MinimumCount, this->MaximumCount);

          for(vtkIdType vector_a = 0; vector_a != vector_count_a; ++vector_a)
            {
            // Can't use vtkstd::make_pair - see http://sahajtechstyle.blogspot.com/2007/11/whats-wrong-with-sun-studio-c.html
            similarities.insert(vtkstd::pair<const double, vtkIdType>(DotProduct(input_array_b, input_array_a, vector_b, vector_a, vector_dimension, component_dimension, component_count_a), vector_a));
            }

          for(similarities_t::const_iterator similarity = similarities.begin(); similarity != similarities.end(); ++similarity)
            {
            source_array->InsertNextValue(vector_b);
            target_array->InsertNextValue(similarity->second);
            similarity_array->InsertNextValue(similarity->first);
            }
          }
        }
      }
    // Compare the one matrix with itself ...
    else
      {
      for(vtkIdType vector_a = 0; vector_a != vector_count_a; ++vector_a)
        {
        similarities_t similarities(this->MinimumThreshold, this->MinimumCount, this->MaximumCount);

        for(vtkIdType vector_b = 0; vector_b != vector_count_a; ++vector_b)
          {
          if((vector_b > vector_a) && !this->UpperDiagonal)
            continue;

          if((vector_b == vector_a) && !this->Diagonal)
            continue;

          if((vector_b < vector_a) && !this->LowerDiagonal)
            continue;

          // Can't use vtkstd::make_pair - see http://sahajtechstyle.blogspot.com/2007/11/whats-wrong-with-sun-studio-c.html
          similarities.insert(vtkstd::pair<const double, vtkIdType>(DotProduct(input_array_a, input_array_a, vector_a, vector_b, vector_dimension, component_dimension, component_count_a), vector_b));
          }

        for(similarities_t::const_iterator similarity = similarities.begin(); similarity != similarities.end(); ++similarity)
          {
          source_array->InsertNextValue(vector_a);
          target_array->InsertNextValue(similarity->second);
          similarity_array->InsertNextValue(similarity->first);
          }
        }
      }

    output->AddColumn(source_array);
    output->AddColumn(target_array);
    output->AddColumn(similarity_array);

    source_array->Delete();
    target_array->Delete();
    similarity_array->Delete();

    return 1;
    }
  catch(vtkstd::exception& e)
    {
    vtkErrorMacro(<< "unhandled exception: " << e.what());
    return 0;
    }
  catch(...)
    {
    vtkErrorMacro(<< "unknown exception");
    return 0;
    }
}

<|endoftext|>


<commit_before>/* -------------------------------------------------------------------------- *
 *                        OpenSim:  ModelComponent.cpp                        *
 * -------------------------------------------------------------------------- *
 * The OpenSim API is a toolkit for musculoskeletal modeling and simulation.  *
 * See http://opensim.stanford.edu and the NOTICE file for more information.  *
 * OpenSim is developed at Stanford University and supported by the US        *
 * National Institutes of Health (U54 GM072970, R24 HD065690) and by DARPA    *
 * through the Warrior Web program.                                           *
 *                                                                            *
 * Copyright (c) 2005-2013 Stanford University and the Authors                *
 * Author(s): Ajay Seth, Michael Sherman                                      *
 *                                                                            *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may    *
 * not use this file except in compliance with the License. You may obtain a  *
 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0.         *
 *                                                                            *
 * Unless required by applicable law or agreed to in writing, software        *
 * distributed under the License is distributed on an "AS IS" BASIS,          *
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
 * See the License for the specific language governing permissions and        *
 * limitations under the License.                                             *
 * -------------------------------------------------------------------------- */

// INCLUDES
#include "OpenSim/Simulation/Model/ModelComponent.h"
#include "OpenSim/Simulation/Model/Model.h"

using namespace SimTK;

namespace OpenSim {

//==============================================================================
//                             MODEL COMPONENT
//==============================================================================
ModelComponent::ModelComponent() : _model(NULL)
{
    constructProperty_GeometrySet();
}

ModelComponent::ModelComponent(const std::string& fileName, bool updFromXMLNode)
:   Component(fileName, updFromXMLNode), _model(NULL)
{
    constructProperty_GeometrySet();
}

ModelComponent::ModelComponent(SimTK::Xml::Element& element)
:   Component(element), _model(NULL)
{
    constructProperty_GeometrySet();
}

const Model& ModelComponent::getModel() const
{
    if(!_model)
        throw Exception("ModelComponent::getModel(): component '" + getName() +
        "' of type " + getConcreteClassName() + " does not belong to a model. "
            "Have you called Model::initSystem()?");
    return *_model;
}

Model& ModelComponent::updModel()
{
    if(!_model)
        throw Exception("ModelComponent::updModel(): component '" + getName() +
        "' of type " + getConcreteClassName() + " does not belong to a model. "
            "Have you called Model::initSystem()?");
    return *_model;
}

void ModelComponent::extendConnect(Component &root)
{
    Super::extendConnect(root);
	Model* model = dynamic_cast<Model*>(&root);
	// Allow (model) component to include its own subcomponents
	// before calling the base method which automatically invokes
	// connect all the subcomponents.
	if (model)
		connectToModel(*model);
}

void ModelComponent::extendFinalizeFromProperties()
{
    Super::extendFinalizeFromProperties();
    int geomSize = getProperty_GeometrySet().size();
    if (geomSize > 0){
        for (int i = 0; i < geomSize; ++i){
            if (findComponent(get_GeometrySet(i).getName()) == nullptr){
                addComponent(&upd_GeometrySet(i));
            }
            upd_GeometrySet(i).setOwnerModelComponent(*this);
        }
    }
}
// Base class implementation of virtual method.
void ModelComponent::connectToModel(Model& model)
{
    _model = &model;
    extendConnectToModel(model);
}

// Base class implementation of virtual method.
void ModelComponent::generateDecorations
    (bool                                        fixed,
    const ModelDisplayHints&                    hints,
    const SimTK::State&                         state,
    SimTK::Array_<SimTK::DecorativeGeometry>&   appendToThis) const
{
    for(unsigned int i=0; i < _components.size(); i++){
		ModelComponent *mc = dynamic_cast<ModelComponent*>(_components[i]);
        if (mc)
            mc->generateDecorations(fixed,hints,state,appendToThis);
	}
}

void ModelComponent::adoptGeometry(OpenSim::Geometry* geom) {
    append_GeometrySet(*geom);
    addComponent(geom); // Geometry is a subcomponent.
    geom->setOwnerModelComponent(*this);
    return;
}

const SimTK::DefaultSystemSubsystem& ModelComponent::
getDefaultSubsystem() const
{   return getModel().getDefaultSubsystem(); }

const SimTK::DefaultSystemSubsystem& ModelComponent::
updDefaultSubsystem()
{   return updModel().updDefaultSubsystem(); }

} // end of namespace OpenSim
<commit_msg>Make sure geometry has unique name in scope as it'll be used for PathName later on. Nsme defaults to bodyName_geom_XX. Classname alone doesn't allow for multiple Spheres, or Bricks, or Cyls...<commit_after>/* -------------------------------------------------------------------------- *
 *                        OpenSim:  ModelComponent.cpp                        *
 * -------------------------------------------------------------------------- *
 * The OpenSim API is a toolkit for musculoskeletal modeling and simulation.  *
 * See http://opensim.stanford.edu and the NOTICE file for more information.  *
 * OpenSim is developed at Stanford University and supported by the US        *
 * National Institutes of Health (U54 GM072970, R24 HD065690) and by DARPA    *
 * through the Warrior Web program.                                           *
 *                                                                            *
 * Copyright (c) 2005-2013 Stanford University and the Authors                *
 * Author(s): Ajay Seth, Michael Sherman                                      *
 *                                                                            *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may    *
 * not use this file except in compliance with the License. You may obtain a  *
 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0.         *
 *                                                                            *
 * Unless required by applicable law or agreed to in writing, software        *
 * distributed under the License is distributed on an "AS IS" BASIS,          *
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
 * See the License for the specific language governing permissions and        *
 * limitations under the License.                                             *
 * -------------------------------------------------------------------------- */

// INCLUDES
#include "OpenSim/Simulation/Model/ModelComponent.h"
#include "OpenSim/Simulation/Model/Model.h"

using namespace SimTK;

namespace OpenSim {

//==============================================================================
//                             MODEL COMPONENT
//==============================================================================
ModelComponent::ModelComponent() : _model(NULL)
{
    constructProperty_GeometrySet();
}

ModelComponent::ModelComponent(const std::string& fileName, bool updFromXMLNode)
:   Component(fileName, updFromXMLNode), _model(NULL)
{
    constructProperty_GeometrySet();
}

ModelComponent::ModelComponent(SimTK::Xml::Element& element)
:   Component(element), _model(NULL)
{
    constructProperty_GeometrySet();
}

const Model& ModelComponent::getModel() const
{
    if(!_model)
        throw Exception("ModelComponent::getModel(): component '" + getName() +
        "' of type " + getConcreteClassName() + " does not belong to a model. "
            "Have you called Model::initSystem()?");
    return *_model;
}

Model& ModelComponent::updModel()
{
    if(!_model)
        throw Exception("ModelComponent::updModel(): component '" + getName() +
        "' of type " + getConcreteClassName() + " does not belong to a model. "
            "Have you called Model::initSystem()?");
    return *_model;
}

void ModelComponent::extendConnect(Component &root)
{
    Super::extendConnect(root);
	Model* model = dynamic_cast<Model*>(&root);
	// Allow (model) component to include its own subcomponents
	// before calling the base method which automatically invokes
	// connect all the subcomponents.
	if (model)
		connectToModel(*model);
}

void ModelComponent::extendFinalizeFromProperties()
{
    Super::extendFinalizeFromProperties();
    int geomSize = getProperty_GeometrySet().size();
    if (geomSize > 0){
        for (int i = 0; i < geomSize; ++i){
            if (findComponent(get_GeometrySet(i).getName()) == nullptr){
                addComponent(&upd_GeometrySet(i));
            }
            upd_GeometrySet(i).setOwnerModelComponent(*this);
        }
    }
}
// Base class implementation of virtual method.
void ModelComponent::connectToModel(Model& model)
{
    _model = &model;
    extendConnectToModel(model);
}

// Base class implementation of virtual method.
void ModelComponent::generateDecorations
    (bool                                        fixed,
    const ModelDisplayHints&                    hints,
    const SimTK::State&                         state,
    SimTK::Array_<SimTK::DecorativeGeometry>&   appendToThis) const
{
    for(unsigned int i=0; i < _components.size(); i++){
		ModelComponent *mc = dynamic_cast<ModelComponent*>(_components[i]);
        if (mc)
            mc->generateDecorations(fixed,hints,state,appendToThis);
	}
}

void ModelComponent::adoptGeometry(OpenSim::Geometry* geom) {
    // Check that name exists and is unique as it's used to form PathName
    if (geom->getName().empty()){
        bool nameFound = false;
        int index = 1;
        while (!nameFound){
            std::stringstream ss;
            // generate candiate name
            ss << getName() << "_geom_" << index;
            std::string candidate = ss.str();
            bool exists = false;
            for (int idx = 0; idx < getProperty_GeometrySet().size() && !exists; idx++){
                if (get_GeometrySet(idx).getName() == candidate){
                    exists = true;
                    break;
                }
            }
            if (!exists){
                nameFound = true;
                geom->setName(candidate);
            }
            else
                index++;
        }

    }
    append_GeometrySet(*geom);
    addComponent(geom); // Geometry is a subcomponent.
    geom->setOwnerModelComponent(*this);
    return;
}

const SimTK::DefaultSystemSubsystem& ModelComponent::
getDefaultSubsystem() const
{   return getModel().getDefaultSubsystem(); }

const SimTK::DefaultSystemSubsystem& ModelComponent::
updDefaultSubsystem()
{   return updModel().updDefaultSubsystem(); }

} // end of namespace OpenSim
<|endoftext|>


<commit_before>//-----------------------------------------------
//
//	This file is part of the Siv3D Engine.
//
//	Copyright (c) 2008-2021 Ryo Suzuki
//	Copyright (c) 2016-2021 OpenSiv3D Project
//
//	Licensed under the MIT License.
//
//-----------------------------------------------

# include <Siv3D/PointVector.hpp>
# include <Siv3D/EngineLog.hpp>
# include "VideoCapture.hpp"

namespace s3d
{
	namespace detail
	{
		using siv3dOpenCameraCallback = void(*)(GLuint elementID, void* userData);
		using siv3dVideoTimeUpdateCallback = void(*)(void* userData);
		using siv3dPlayVideoCallback = void(*)(void* userData);

        __attribute__((import_name("siv3dOpenVideo")))
		extern void siv3dOpenVideo(const char* filepath, siv3dOpenCameraCallback callback, void* callbackArg);

		__attribute__((import_name("siv3dOpenCamera")))
		extern void siv3dOpenCamera(int width, int height, siv3dOpenCameraCallback callback, void* callbackArg);

        __attribute__((import_name("siv3dRegisterVideoTimeUpdateCallback")))
        extern void siv3dRegisterVideoTimeUpdateCallback(GLuint elementID, siv3dVideoTimeUpdateCallback callback, void* callbackArg);

		__attribute__((import_name("siv3dQueryVideoPlaybackedTime")))
		extern double siv3dQueryVideoPlaybackedTime(GLuint elementID);

        __attribute__((import_name("siv3dSetVideoPlaybackedTime")))
		extern void siv3dSetVideoPlaybackedTime(GLuint elementID, double time);

        __attribute__((import_name("siv3dQueryVideoDuration")))
		extern double siv3dQueryVideoDuration(GLuint elementID);

        __attribute__((import_name("siv3dQueryVideoEnded")))
		extern bool siv3dQueryVideoEnded(GLuint elementID);

        __attribute__((import_name("siv3dQueryVideoPreference")))
		extern void siv3dQueryVideoPreference(GLuint elementID, int* width, int* height, double* fps);

		__attribute__((import_name("siv3dCaptureVideoFrame")))
		extern void siv3dCaptureVideoFrame(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLuint elementID);

		__attribute__((import_name("siv3dPlayVideo")))
		extern void siv3dPlayVideo(GLuint elementID);

		__attribute__((import_name("siv3dStopVideo")))
		extern void siv3dStopVideo(GLuint elementID);

		__attribute__((import_name("siv3dDestroyVideo")))
		extern void siv3dDestroyVideo(GLuint elementID);

    }

    WebCameraCapture::WebCameraCapture()
    {
        ::glGenTextures(1, &m_videoBufferTexture);
        ::glBindTexture(GL_TEXTURE_2D, m_videoBufferTexture);
        {
            ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
            ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        }
        ::glBindTexture(GL_TEXTURE_2D, 0);

        ::glGenFramebuffers(1, &m_videoBufferFrameBuffer);
    }

    WebCameraCapture::~WebCameraCapture()
    {
        release();

        ::glDeleteTextures(1, &m_videoBufferTexture);
        ::glDeleteFramebuffers(1, &m_videoBufferFrameBuffer);
    }

    bool WebCameraCapture::openCamera()
    {
        m_shouldAutoPlay = true;

        detail::siv3dOpenCamera(m_captureResolution.x, m_captureResolution.y, &OnOpened, this);

        return true;
    }

    bool WebCameraCapture::openVideo(FilePathView filepath)
    {
        detail::siv3dOpenVideo(filepath.narrow().c_str(), &OnOpened, this);
        return true;
    }

    void WebCameraCapture::play()
    {
        detail::siv3dPlayVideo(m_videoElementID);
    }

    void WebCameraCapture::seek(double time)
    {
        detail::siv3dSetVideoPlaybackedTime(m_videoElementID, time);
    }

    double WebCameraCapture::tell() const
    {
       return m_lastCapturedFrameTime;
    }

    void WebCameraCapture::stop()
    {
        detail::siv3dStopVideo(m_videoElementID);
    }

    void WebCameraCapture::release()
    {
        if (m_videoElementID != 0)
        {
            // detail::siv3dRegisterVideoTimeUpdateCallback(m_videoElementID, nullptr, nullptr);
            detail::siv3dDestroyVideo(m_videoElementID);
        }

        m_videoElementID = 0;
    }

    void WebCameraCapture::setResolution(const Size& resolution)
    {
        m_captureResolution = resolution;
    }

    Size WebCameraCapture::getResolution() const
    {
        return m_captureResolution;
    }

    double WebCameraCapture::getFPS() const
    {
        return m_playbackFPS;
    }

    double WebCameraCapture::getDuration() const
    {
        return m_videoDuration;
    }

    bool WebCameraCapture::grab()
    {
        auto hasNewFrame = m_hasNewFrame;
        m_hasNewFrame = false;
        return hasNewFrame;
    }

    void WebCameraCapture::capture()
    {
        ::glBindTexture(GL_TEXTURE_2D, m_videoBufferTexture);
        {
            detail::siv3dCaptureVideoFrame(
                GL_TEXTURE_2D, 0, GL_RGBA8,
                m_captureResolution.x, m_captureResolution.y,
                0, GL_RGBA, GL_UNSIGNED_BYTE, m_videoElementID);
        }
        ::glBindTexture(GL_TEXTURE_2D, 0);
    }

    GLuint WebCameraCapture::retrieve() const
    {
        return m_videoBufferFrameBuffer;
    }

    bool WebCameraCapture::isOpened() const
    {
        return m_videoElementID != 0;
    }

    bool WebCameraCapture::isReachedEnd() const
    {
        return detail::siv3dQueryVideoEnded(m_videoElementID);
    }

    void WebCameraCapture::OnOpened(GLuint elementID, void* userData)
    {
        auto& webcam = *static_cast<WebCameraCapture*>(userData);

        webcam.m_videoElementID = elementID;
        webcam.m_videoDuration = detail::siv3dQueryVideoDuration(elementID);

        detail::siv3dQueryVideoPreference(elementID, &webcam.m_captureResolution.x, &webcam.m_captureResolution.y, &webcam.m_playbackFPS);
        webcam.prepareBuffers();

        // detail::siv3dRegisterVideoTimeUpdateCallback(elementID, WebCameraCapture::OnUpdated, &webcam);

        if (webcam.m_shouldAutoPlay)
        {
            detail::siv3dPlayVideo(elementID);
        }
    }

    void WebCameraCapture::OnUpdated(void* userData)
    {
        auto& webcam = *static_cast<WebCameraCapture*>(userData);

        webcam.capture();
        webcam.m_hasNewFrame = true;

        double currentTime =  detail::siv3dQueryVideoPlaybackedTime(webcam.m_videoElementID);
        webcam.m_lastCapturedFrameTime = currentTime;
    }

    void WebCameraCapture::prepareBuffers()
    {
        ::glBindTexture(GL_TEXTURE_2D, m_videoBufferTexture);
        {
            ::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_captureResolution.x, m_captureResolution.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
        }
        ::glBindTexture(GL_TEXTURE_2D, 0);

        ::glBindFramebuffer(GL_FRAMEBUFFER, m_videoBufferFrameBuffer);
        {
            ::glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_videoBufferTexture, 0);

            if (::glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
            {
                LOG_ERROR(U"Incomplete Framebuffer");
                return;
            }
        }
        ::glBindFramebuffer(GL_FRAMEBUFFER, 0);
    }

}
<commit_msg>[Web] ensure that passed pointer passed into js is aligned<commit_after>//-----------------------------------------------
//
//	This file is part of the Siv3D Engine.
//
//	Copyright (c) 2008-2021 Ryo Suzuki
//	Copyright (c) 2016-2021 OpenSiv3D Project
//
//	Licensed under the MIT License.
//
//-----------------------------------------------

# include <Siv3D/PointVector.hpp>
# include <Siv3D/EngineLog.hpp>
# include "VideoCapture.hpp"

namespace s3d
{
	namespace detail
	{
		using siv3dOpenCameraCallback = void(*)(GLuint elementID, void* userData);
		using siv3dVideoTimeUpdateCallback = void(*)(void* userData);
		using siv3dPlayVideoCallback = void(*)(void* userData);

        __attribute__((import_name("siv3dOpenVideo")))
		extern void siv3dOpenVideo(const char* filepath, siv3dOpenCameraCallback callback, void* callbackArg);

		__attribute__((import_name("siv3dOpenCamera")))
		extern void siv3dOpenCamera(int width, int height, siv3dOpenCameraCallback callback, void* callbackArg);

        __attribute__((import_name("siv3dRegisterVideoTimeUpdateCallback")))
        extern void siv3dRegisterVideoTimeUpdateCallback(GLuint elementID, siv3dVideoTimeUpdateCallback callback, void* callbackArg);

		__attribute__((import_name("siv3dQueryVideoPlaybackedTime")))
		extern double siv3dQueryVideoPlaybackedTime(GLuint elementID);

        __attribute__((import_name("siv3dSetVideoPlaybackedTime")))
		extern void siv3dSetVideoPlaybackedTime(GLuint elementID, double time);

        __attribute__((import_name("siv3dQueryVideoDuration")))
		extern double siv3dQueryVideoDuration(GLuint elementID);

        __attribute__((import_name("siv3dQueryVideoEnded")))
		extern bool siv3dQueryVideoEnded(GLuint elementID);

        __attribute__((import_name("siv3dQueryVideoPreference")))
		extern void siv3dQueryVideoPreference(GLuint elementID, int* width, int* height, double* fps);

		__attribute__((import_name("siv3dCaptureVideoFrame")))
		extern void siv3dCaptureVideoFrame(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLuint elementID);

		__attribute__((import_name("siv3dPlayVideo")))
		extern void siv3dPlayVideo(GLuint elementID);

		__attribute__((import_name("siv3dStopVideo")))
		extern void siv3dStopVideo(GLuint elementID);

		__attribute__((import_name("siv3dDestroyVideo")))
		extern void siv3dDestroyVideo(GLuint elementID);

    }

    WebCameraCapture::WebCameraCapture()
    {
        ::glGenTextures(1, &m_videoBufferTexture);
        ::glBindTexture(GL_TEXTURE_2D, m_videoBufferTexture);
        {
            ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
            ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        }
        ::glBindTexture(GL_TEXTURE_2D, 0);

        ::glGenFramebuffers(1, &m_videoBufferFrameBuffer);
    }

    WebCameraCapture::~WebCameraCapture()
    {
        release();

        ::glDeleteTextures(1, &m_videoBufferTexture);
        ::glDeleteFramebuffers(1, &m_videoBufferFrameBuffer);
    }

    bool WebCameraCapture::openCamera()
    {
        m_shouldAutoPlay = true;

        detail::siv3dOpenCamera(m_captureResolution.x, m_captureResolution.y, &OnOpened, this);

        return true;
    }

    bool WebCameraCapture::openVideo(FilePathView filepath)
    {
        detail::siv3dOpenVideo(filepath.narrow().c_str(), &OnOpened, this);
        return true;
    }

    void WebCameraCapture::play()
    {
        detail::siv3dPlayVideo(m_videoElementID);
    }

    void WebCameraCapture::seek(double time)
    {
        detail::siv3dSetVideoPlaybackedTime(m_videoElementID, time);
    }

    double WebCameraCapture::tell() const
    {
       return m_lastCapturedFrameTime;
    }

    void WebCameraCapture::stop()
    {
        detail::siv3dStopVideo(m_videoElementID);
    }

    void WebCameraCapture::release()
    {
        if (m_videoElementID != 0)
        {
            // detail::siv3dRegisterVideoTimeUpdateCallback(m_videoElementID, nullptr, nullptr);
            detail::siv3dDestroyVideo(m_videoElementID);
        }

        m_videoElementID = 0;
    }

    void WebCameraCapture::setResolution(const Size& resolution)
    {
        m_captureResolution = resolution;
    }

    Size WebCameraCapture::getResolution() const
    {
        return m_captureResolution;
    }

    double WebCameraCapture::getFPS() const
    {
        return m_playbackFPS;
    }

    double WebCameraCapture::getDuration() const
    {
        return m_videoDuration;
    }

    bool WebCameraCapture::grab()
    {
        auto hasNewFrame = m_hasNewFrame;
        m_hasNewFrame = false;
        return hasNewFrame;
    }

    void WebCameraCapture::capture()
    {
        ::glBindTexture(GL_TEXTURE_2D, m_videoBufferTexture);
        {
            detail::siv3dCaptureVideoFrame(
                GL_TEXTURE_2D, 0, GL_RGBA8,
                m_captureResolution.x, m_captureResolution.y,
                0, GL_RGBA, GL_UNSIGNED_BYTE, m_videoElementID);
        }
        ::glBindTexture(GL_TEXTURE_2D, 0);
    }

    GLuint WebCameraCapture::retrieve() const
    {
        return m_videoBufferFrameBuffer;
    }

    bool WebCameraCapture::isOpened() const
    {
        return m_videoElementID != 0;
    }

    bool WebCameraCapture::isReachedEnd() const
    {
        return detail::siv3dQueryVideoEnded(m_videoElementID);
    }

    void WebCameraCapture::OnOpened(GLuint elementID, void* userData)
    {
        auto& webcam = *static_cast<WebCameraCapture*>(userData);

        webcam.m_videoElementID = elementID;
        webcam.m_videoDuration = detail::siv3dQueryVideoDuration(elementID);

        alignas(8) double playbackFPS;

        detail::siv3dQueryVideoPreference(elementID, &webcam.m_captureResolution.x, &webcam.m_captureResolution.y, &playbackFPS);
        webcam.m_playbackFPS = playbackFPS;

        webcam.prepareBuffers();

        // detail::siv3dRegisterVideoTimeUpdateCallback(elementID, WebCameraCapture::OnUpdated, &webcam);

        if (webcam.m_shouldAutoPlay)
        {
            detail::siv3dPlayVideo(elementID);
        }
    }

    void WebCameraCapture::OnUpdated(void* userData)
    {
        auto& webcam = *static_cast<WebCameraCapture*>(userData);

        webcam.capture();
        webcam.m_hasNewFrame = true;

        double currentTime =  detail::siv3dQueryVideoPlaybackedTime(webcam.m_videoElementID);
        webcam.m_lastCapturedFrameTime = currentTime;
    }

    void WebCameraCapture::prepareBuffers()
    {
        ::glBindTexture(GL_TEXTURE_2D, m_videoBufferTexture);
        {
            ::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_captureResolution.x, m_captureResolution.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
        }
        ::glBindTexture(GL_TEXTURE_2D, 0);

        ::glBindFramebuffer(GL_FRAMEBUFFER, m_videoBufferFrameBuffer);
        {
            ::glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_videoBufferTexture, 0);

            if (::glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
            {
                LOG_ERROR(U"Incomplete Framebuffer");
                return;
            }
        }
        ::glBindFramebuffer(GL_FRAMEBUFFER, 0);
    }

}
<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    vtkFixedWidthTextReader.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

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

=========================================================================*/
/*----------------------------------------------------------------------------
 Copyright (c) Sandia Corporation
 See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
----------------------------------------------------------------------------*/

#include "vtkFixedWidthTextReader.h"
#include "vtkCommand.h"
#include "vtkTable.h"
#include "vtkVariantArray.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkInformation.h"
#include "vtkStringArray.h"
#include "vtkStdString.h"
#include <vtkIOStream.h>

#include <vtkstd/algorithm>
#include <vtkstd/vector>
#include <vtkstd/string>
#include <fstream>
#include <ctype.h>

vtkCxxRevisionMacro(vtkFixedWidthTextReader, "1.4");
vtkStandardNewMacro(vtkFixedWidthTextReader);

// Function body at bottom of file
static int splitString(const vtkStdString& input,
                       unsigned int fieldWidth,
                       bool stripWhitespace,
                       vtkstd::vector<vtkStdString>& results,
                       bool includeEmpties=true);

// I need a safe way to read a line of arbitrary length.  It exists on
// some platforms but not others so I'm afraid I have to write it
// myself.
static int my_getline(istream& stream, vtkStdString &output, char delim='\n');

// ----------------------------------------------------------------------

vtkFixedWidthTextReader::vtkFixedWidthTextReader()
{
  this->FileName = NULL;
  this->StripWhiteSpace = false;
  this->HaveHeaders = false;
  this->FieldWidth = 10;
  this->SetNumberOfInputPorts(0);
  this->SetNumberOfOutputPorts(1);
}

// ----------------------------------------------------------------------

vtkFixedWidthTextReader::~vtkFixedWidthTextReader()
{
  this->SetFileName(0);
}

// ----------------------------------------------------------------------

void vtkFixedWidthTextReader::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
  os << indent << "FileName: "
     << (this->FileName ? this->FileName : "(none)") << endl;
  os << indent << "Field width: " << this->FieldWidth << endl;
  os << indent << "Strip leading/trailing whitespace: "
     << (this->StripWhiteSpace ? "Yes" : "No") << endl;
  os << indent << "HaveHeaders: "
     << (this->HaveHeaders ? "Yes" : "No") << endl;
}

// ----------------------------------------------------------------------

int vtkFixedWidthTextReader::RequestData(
                                        vtkInformation*,
                                        vtkInformationVector**,
                                        vtkInformationVector* outputVector)
{
  int numLines = 0;

  // Check that the filename has been specified
  if (!this->FileName)
    {
    vtkErrorMacro("vtkFixedWidthTextReader: You must specify a filename!");
    return 2;
    }

  ifstream infile(this->FileName, ios::in);
  if (!infile || infile.fail())
    {
    vtkErrorMacro(<<"vtkFixedWidthTextReader: Couldn't open file!");
    return 2;
    }

  // The first line of the file might contain the headers, so we want
  // to be a little bit careful about it.  If we don't have headers
  // we'll have to make something up.
  vtkstd::vector<vtkStdString> headers;
  vtkstd::vector<vtkStdString> firstLineFields;
  vtkStdString firstLine;

  my_getline(infile, firstLine);

//  vtkDebugMacro(<<"First line of file: " << firstLine.c_str());

  if (this->HaveHeaders)
    {
    splitString(firstLine,
                this->FieldWidth,
                this->StripWhiteSpace,
                headers);
    }
  else
    {
    splitString(firstLine,
                this->FieldWidth,
                this->StripWhiteSpace,
                firstLineFields);

    for (unsigned int i = 0; i < firstLineFields.size(); ++i)
      {
      // I know it's not a great idea to use sprintf.  It's safe right
      // here because an unsigned int will never take up enough
      // characters to fill up this buffer.
      char fieldName[64];
      sprintf(fieldName, "Field %d", i);
      headers.push_back(fieldName);
      }
    }

  vtkTable *table = vtkTable::GetData(outputVector);

  // Now we can create the arrays that will hold the data for each
  // field.
  vtkstd::vector<vtkStdString>::const_iterator fieldIter;
  for(fieldIter = headers.begin(); fieldIter != headers.end(); ++fieldIter)
    {
    vtkStringArray* array = vtkStringArray::New();
    array->SetName((*fieldIter).c_str());
    table->AddColumn(array);
    array->Delete();
    }

  // If the first line did not contain headers then we need to add it
  // to the table.
  if (!this->HaveHeaders)
    {
    vtkVariantArray* dataArray = vtkVariantArray::New();
    vtkstd::vector<vtkStdString>::const_iterator I;
    for(I = firstLineFields.begin(); I != firstLineFields.end(); ++I)
      {
      dataArray->InsertNextValue(vtkVariant(*I));
      }

    // Insert the data into the table
    table->InsertNextRow(dataArray);
    dataArray->Delete();
    }

  // Read the file line-by-line and add it to the table.
  vtkStdString nextLine;
  while (my_getline(infile, nextLine))
    {
    ++numLines;
    if (numLines > 0 && numLines % 100 == 0)
      {
      float numLinesRead = numLines;
      this->InvokeEvent(vtkCommand::ProgressEvent, &numLinesRead);
      }

    vtkDebugMacro(<<"Next line: " << nextLine.c_str());
    vtkstd::vector<vtkStdString> dataVector;

    // Split string on the delimiters
    splitString(nextLine,
                this->FieldWidth,
                this->StripWhiteSpace,
                dataVector);

    vtkDebugMacro(<<"Split into " << dataVector.size() << " fields");
    // Add data to the output arrays

    // Convert from vector to variant array
    vtkVariantArray* dataArray = vtkVariantArray::New();
    vtkstd::vector<vtkStdString>::const_iterator I;
    for(I = dataVector.begin(); I != dataVector.end(); ++I)
      {
      dataArray->InsertNextValue(vtkVariant(*I));
      }

    // Pad out any missing columns
    while (dataArray->GetNumberOfTuples() < table->GetNumberOfColumns())
      {
      dataArray->InsertNextValue(vtkVariant());
      }

    // Insert the data into the table
    table->InsertNextRow(dataArray);
    dataArray->Delete();
    }

  infile.close();

  return 1;
}

// ----------------------------------------------------------------------

static int
splitString(const vtkStdString& input,
            unsigned int fieldWidth,
            bool stripWhitespace,
            vtkstd::vector<vtkStdString>& results,
            bool includeEmpties)
{
  if (input.size() == 0)
    {
    return 0;
    }

  unsigned int thisField = 0;
  vtkStdString thisFieldText;
  vtkStdString parsedField;

  while (thisField * fieldWidth < input.size())
    {
    thisFieldText = input.substr(thisField*fieldWidth, fieldWidth);

    if (stripWhitespace)
      {
      unsigned int startIndex = 0, endIndex = thisFieldText.size() - 1;
      while (startIndex < thisFieldText.size() &&
             isspace(static_cast<int>(thisFieldText.at(startIndex))))
        {
        ++startIndex;
        }
      while (endIndex > 0 &&
             isspace(static_cast<int>(thisFieldText.at(endIndex))))
        {
        -- endIndex;
        }

      if (startIndex <= endIndex)
        {
        parsedField =
          thisFieldText.substr(startIndex, (endIndex - startIndex) + 1);
        }
      else
        {
        parsedField = vtkStdString();
        }
      }
    else
      {
      parsedField = thisFieldText;
      }
    ++ thisField;
    if (parsedField.size() > 0 || includeEmpties)
      {
      results.push_back(parsedField);
      }
    }

  return results.size();
}

// ----------------------------------------------------------------------

static int
my_getline(istream& in, vtkStdString &out, char delimiter)
{
  out = vtkStdString();
  unsigned int numCharactersRead = 0;
  int nextValue = 0;

  while ((nextValue = in.get()) != EOF &&
         numCharactersRead < out.max_size())
    {
    ++numCharactersRead;

    char downcast = static_cast<char>(nextValue);
    if (downcast != delimiter && downcast != 0x0d)
      {
      out += downcast;
      }
    else
      {
      return numCharactersRead;
      }
    }

  return numCharactersRead;
}

<commit_msg>COMP: Use vtksys headers instead of native<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkFixedWidthTextReader.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

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

=========================================================================*/
/*----------------------------------------------------------------------------
 Copyright (c) Sandia Corporation
 See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
----------------------------------------------------------------------------*/

#include "vtkFixedWidthTextReader.h"
#include "vtkCommand.h"
#include "vtkTable.h"
#include "vtkVariantArray.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkInformation.h"
#include "vtkStringArray.h"
#include "vtkStdString.h"
#include <vtkIOStream.h>

#include <vtksys/stl/algorithm>
#include <vtksys/stl/vector>
#include <vtksys/ios/fstream>

using vtksys_stl::ifstream;
using vtksys_stl::vector;

#include <ctype.h>

vtkCxxRevisionMacro(vtkFixedWidthTextReader, "1.5");
vtkStandardNewMacro(vtkFixedWidthTextReader);

// Function body at bottom of file
static int splitString(const vtkStdString& input,
                       unsigned int fieldWidth,
                       bool stripWhitespace,
                       vector<vtkStdString>& results,
                       bool includeEmpties=true);

// I need a safe way to read a line of arbitrary length.  It exists on
// some platforms but not others so I'm afraid I have to write it
// myself.
static int my_getline(istream& stream, vtkStdString &output, char delim='\n');

// ----------------------------------------------------------------------

vtkFixedWidthTextReader::vtkFixedWidthTextReader()
{
  this->FileName = NULL;
  this->StripWhiteSpace = false;
  this->HaveHeaders = false;
  this->FieldWidth = 10;
  this->SetNumberOfInputPorts(0);
  this->SetNumberOfOutputPorts(1);
}

// ----------------------------------------------------------------------

vtkFixedWidthTextReader::~vtkFixedWidthTextReader()
{
  this->SetFileName(0);
}

// ----------------------------------------------------------------------

void vtkFixedWidthTextReader::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
  os << indent << "FileName: "
     << (this->FileName ? this->FileName : "(none)") << endl;
  os << indent << "Field width: " << this->FieldWidth << endl;
  os << indent << "Strip leading/trailing whitespace: "
     << (this->StripWhiteSpace ? "Yes" : "No") << endl;
  os << indent << "HaveHeaders: "
     << (this->HaveHeaders ? "Yes" : "No") << endl;
}

// ----------------------------------------------------------------------

int vtkFixedWidthTextReader::RequestData(
                                        vtkInformation*,
                                        vtkInformationVector**,
                                        vtkInformationVector* outputVector)
{
  int numLines = 0;

  // Check that the filename has been specified
  if (!this->FileName)
    {
    vtkErrorMacro("vtkFixedWidthTextReader: You must specify a filename!");
    return 2;
    }

  ifstream infile(this->FileName, ios::in);
  if (!infile || infile.fail())
    {
    vtkErrorMacro(<<"vtkFixedWidthTextReader: Couldn't open file!");
    return 2;
    }

  // The first line of the file might contain the headers, so we want
  // to be a little bit careful about it.  If we don't have headers
  // we'll have to make something up.
  vector<vtkStdString> headers;
  vector<vtkStdString> firstLineFields;
  vtkStdString firstLine;

  my_getline(infile, firstLine);

//  vtkDebugMacro(<<"First line of file: " << firstLine.c_str());

  if (this->HaveHeaders)
    {
    splitString(firstLine,
                this->FieldWidth,
                this->StripWhiteSpace,
                headers);
    }
  else
    {
    splitString(firstLine,
                this->FieldWidth,
                this->StripWhiteSpace,
                firstLineFields);

    for (unsigned int i = 0; i < firstLineFields.size(); ++i)
      {
      // I know it's not a great idea to use sprintf.  It's safe right
      // here because an unsigned int will never take up enough
      // characters to fill up this buffer.
      char fieldName[64];
      sprintf(fieldName, "Field %d", i);
      headers.push_back(fieldName);
      }
    }

  vtkTable *table = vtkTable::GetData(outputVector);

  // Now we can create the arrays that will hold the data for each
  // field.
  vector<vtkStdString>::const_iterator fieldIter;
  for(fieldIter = headers.begin(); fieldIter != headers.end(); ++fieldIter)
    {
    vtkStringArray* array = vtkStringArray::New();
    array->SetName((*fieldIter).c_str());
    table->AddColumn(array);
    array->Delete();
    }

  // If the first line did not contain headers then we need to add it
  // to the table.
  if (!this->HaveHeaders)
    {
    vtkVariantArray* dataArray = vtkVariantArray::New();
    vector<vtkStdString>::const_iterator I;
    for(I = firstLineFields.begin(); I != firstLineFields.end(); ++I)
      {
      dataArray->InsertNextValue(vtkVariant(*I));
      }

    // Insert the data into the table
    table->InsertNextRow(dataArray);
    dataArray->Delete();
    }

  // Read the file line-by-line and add it to the table.
  vtkStdString nextLine;
  while (my_getline(infile, nextLine))
    {
    ++numLines;
    if (numLines > 0 && numLines % 100 == 0)
      {
      float numLinesRead = numLines;
      this->InvokeEvent(vtkCommand::ProgressEvent, &numLinesRead);
      }

    vtkDebugMacro(<<"Next line: " << nextLine.c_str());
    vector<vtkStdString> dataVector;

    // Split string on the delimiters
    splitString(nextLine,
                this->FieldWidth,
                this->StripWhiteSpace,
                dataVector);

    vtkDebugMacro(<<"Split into " << dataVector.size() << " fields");
    // Add data to the output arrays

    // Convert from vector to variant array
    vtkVariantArray* dataArray = vtkVariantArray::New();
    vector<vtkStdString>::const_iterator I;
    for(I = dataVector.begin(); I != dataVector.end(); ++I)
      {
      dataArray->InsertNextValue(vtkVariant(*I));
      }

    // Pad out any missing columns
    while (dataArray->GetNumberOfTuples() < table->GetNumberOfColumns())
      {
      dataArray->InsertNextValue(vtkVariant());
      }

    // Insert the data into the table
    table->InsertNextRow(dataArray);
    dataArray->Delete();
    }

  infile.close();

  return 1;
}

// ----------------------------------------------------------------------

static int
splitString(const vtkStdString& input,
            unsigned int fieldWidth,
            bool stripWhitespace,
            vector<vtkStdString>& results,
            bool includeEmpties)
{
  if (input.size() == 0)
    {
    return 0;
    }

  unsigned int thisField = 0;
  vtkStdString thisFieldText;
  vtkStdString parsedField;

  while (thisField * fieldWidth < input.size())
    {
    thisFieldText = input.substr(thisField*fieldWidth, fieldWidth);

    if (stripWhitespace)
      {
      unsigned int startIndex = 0, endIndex = thisFieldText.size() - 1;
      while (startIndex < thisFieldText.size() &&
             isspace(static_cast<int>(thisFieldText.at(startIndex))))
        {
        ++startIndex;
        }
      while (endIndex > 0 &&
             isspace(static_cast<int>(thisFieldText.at(endIndex))))
        {
        -- endIndex;
        }

      if (startIndex <= endIndex)
        {
        parsedField =
          thisFieldText.substr(startIndex, (endIndex - startIndex) + 1);
        }
      else
        {
        parsedField = vtkStdString();
        }
      }
    else
      {
      parsedField = thisFieldText;
      }
    ++ thisField;
    if (parsedField.size() > 0 || includeEmpties)
      {
      results.push_back(parsedField);
      }
    }

  return results.size();
}

// ----------------------------------------------------------------------

static int
my_getline(istream& in, vtkStdString &out, char delimiter)
{
  out = vtkStdString();
  unsigned int numCharactersRead = 0;
  int nextValue = 0;

  while ((nextValue = in.get()) != EOF &&
         numCharactersRead < out.max_size())
    {
    ++numCharactersRead;

    char downcast = static_cast<char>(nextValue);
    if (downcast != delimiter && downcast != 0x0d)
      {
      out += downcast;
      }
    else
      {
      return numCharactersRead;
      }
    }

  return numCharactersRead;
}

<|endoftext|>


<commit_before>/*
 * Earl, the fanciest ETF Packer and Unpacker for Python.
 * Written as a C++ Extension for Maximum Effort and Speed.
 *
 * Copyright 2016 Charles Click under the MIT License.
 */

#define FLOAT_IEEE_EXT "F"
#define BIT_BINARY_EXT "M"
#define SMALL_INTEGER_EXT "a"
#define INTEGER_EXT "b"
#define FLOAT_EXT "c"
#define SMALL_TUPLE_EXT "h"
#define LARGE_TUPLE_EXT "i"
#define NIL_EXT "j"
#define STRING_EXT "k"
#define LIST_EXT "l"
#define BINARY_EXT "m"
#define SMALL_BIG_EXT "n"
#define LARGE_BIG_EXT "o"
#define MAP_EXT "t"

#include <Python.h>
#include <vector>
#include <string>

std::string etf_small_int(int value){

    std::string buffer = SMALL_INTEGER_EXT;
    buffer += char(value);
    return buffer;

}

std::string etf_big_int(unsigned long value){

    std::string buffer = INTEGER_EXT;
    buffer += ((value >> 24) & 0xFF);
    buffer += ((value >> 16) & 0xFF);
    buffer += ((value >> 8) & 0xFF);
    buffer += (value & 0xFF);

    return buffer;

}

std::string etf_string(PyObject *value){

    int len = PyUnicode_GET_LENGTH(value);
    int kind = PyUnicode_KIND(value);

    std::string buffer = STRING_EXT;
    buffer += (len >> 8) & 0xFF;
    buffer += len & 0xFF;

    if (!len or !kind){

        if ( !PyErr_Occurred() ){

            PyErr_SetString(PyExc_RuntimeError, "Failed to process the python string.");

        }

        return NULL;

    }

    for( int i={0}; i < len; i++){

        buffer += char(PyUnicode_READ(kind, PyUnicode_DATA(value), i));

    }

    return buffer;

}

std::string etf_float(double value){

    std::string buffer = FLOAT_IEEE_EXT;

    unsigned char const * p = reinterpret_cast<unsigned char const *>(&value);

    for ( int i={0}; i < sizeof(p); i++ ){

        buffer += (int(p[7-i]) & 0xFF);

    }

    return buffer;

}

std::string etf_tuple(PyObject* tuple){

    Py_ssize_t len = PyTuple_Size(tuple);
    std::string buffer;

    if ( len > 256 ){

        buffer = LARGE_TUPLE_EXT;
        buffer += len & 0xFF;

        for( int ii={0}; ii < len; ii++ ){

            PyObject* temp = PyTuple_GetItem(tuple, ii);

            buffer += SMALL_INTEGER_EXT;
            buffer += char(PyLong_AsUnsignedLong(temp));

        }

    } else {

        buffer = SMALL_TUPLE_EXT;
        buffer += char(len);

        for( int ii={0}; ii < len; ii++ ){

            PyObject* temp = PyTuple_GetItem(tuple, ii);

            buffer += SMALL_INTEGER_EXT;
            buffer += char(PyLong_AsUnsignedLong(temp));

        }

    }

    return buffer;

}

static PyObject* earl_pack(PyObject* self, PyObject *args){

    std::string package;
    std::vector<PyObject*> objects;
    Py_ssize_t len = PyTuple_Size(args);

    if( !len ){

        if( !PyErr_Occurred() ){

            PyErr_SetString(PyExc_SyntaxError, "You must supply at least one argument.");

        }

        return NULL;

    }

    package = "\x83";

    for( int i={0}; i < len; i++ ){

        PyObject* temp = PyTuple_GetItem(args, i);

        if( temp == NULL ){

            if( !PyErr_Occurred() ){

                PyErr_SetString(PyExc_TypeError, "Earl wasn't able to unpack all your arguments for some reason.");

            }
            return NULL;

        }

        if( PyLong_Check(temp) ){

            unsigned long temp_int = PyLong_AsUnsignedLong(temp);
            temp_int < 256 ? package += etf_small_int(temp_int) : package += etf_big_int(temp_int);

        } else if( PyUnicode_Check(temp) ) {

            if( PyUnicode_READY(temp) != 0 ){

                if( !PyErr_Occurred() ){

                    PyErr_SetString(PyExc_RuntimeError, "Earl wasn't able to migrate the Python Unicode data to memory.");

                }
                return NULL;

            }else{

                package += etf_string(temp);

            }

        }else if( PyFloat_Check(temp) ){

            package += etf_float(PyFloat_AsDouble(temp));

        }else if( PyTuple_Check(temp) ){

            package += etf_tuple(temp);

        }else if( PySet_Check(temp) ){

            //package += etf_set(temp);
            break;

        }else if( PyList_Check(temp) ){

            //package += etf_listt(temp);
            break;

        }else if( PyDict_Check(temp) ){

            //package += etf_dict(temp);
            break;

        }else{

            if ( !PyErr_Occurred() ){

                PyErr_SetString(PyExc_TypeError, "Earl can't pack one of the types you gave it!");

            }
            return NULL;

        }

    }

    return Py_BuildValue("y#", package.c_str(), package.length());

}

static char earl_pack_docs[] = "pack(values): Pack a bunch of things into an External Term Format";

static PyMethodDef earlmethods[] = {

    {"pack", earl_pack, METH_VARARGS, earl_pack_docs},
    {NULL, NULL, 0, NULL}

};

static struct PyModuleDef earl = {

    PyModuleDef_HEAD_INIT,
    "earl",
    "Earl is the fanciest External Term Format library for Python.",
    -1,
    earlmethods

};

PyMODINIT_FUNC PyInit_earl(void){

    return PyModule_Create(&earl);

}
<commit_msg>Some work on sets<commit_after>/*
 * Earl, the fanciest ETF Packer and Unpacker for Python.
 * Written as a C++ Extension for Maximum Effort and Speed.
 *
 * Copyright 2016 Charles Click under the MIT License.
 */

#define FLOAT_IEEE_EXT "F"
#define BIT_BINARY_EXT "M"
#define SMALL_INTEGER_EXT "a"
#define INTEGER_EXT "b"
#define FLOAT_EXT "c"
#define SMALL_TUPLE_EXT "h"
#define LARGE_TUPLE_EXT "i"
#define NIL_EXT "j"
#define STRING_EXT "k"
#define LIST_EXT "l"
#define BINARY_EXT "m"
#define SMALL_BIG_EXT "n"
#define LARGE_BIG_EXT "o"
#define MAP_EXT "t"

#include <Python.h>
#include <vector>
#include <string>

std::string etf_small_int(int value){

    std::string buffer = SMALL_INTEGER_EXT;
    buffer += char(value);
    return buffer;

}

std::string etf_big_int(unsigned long value){

    std::string buffer = INTEGER_EXT;
    buffer += ((value >> 24) & 0xFF);
    buffer += ((value >> 16) & 0xFF);
    buffer += ((value >> 8) & 0xFF);
    buffer += (value & 0xFF);

    return buffer;

}

std::string etf_string(PyObject *value){

    int len = PyUnicode_GET_LENGTH(value);
    int kind = PyUnicode_KIND(value);

    std::string buffer = STRING_EXT;
    buffer += (len >> 8) & 0xFF;
    buffer += len & 0xFF;

    if (!len or !kind){

        if ( !PyErr_Occurred() ){

            PyErr_SetString(PyExc_RuntimeError, "Failed to process the python string.");

        }

        return NULL;

    }

    for( int i={0}; i < len; i++){

        buffer += char(PyUnicode_READ(kind, PyUnicode_DATA(value), i));

    }

    return buffer;

}

std::string etf_float(double value){

    std::string buffer = FLOAT_IEEE_EXT;

    unsigned char const * p = reinterpret_cast<unsigned char const *>(&value);

    for ( int i={0}; i < sizeof(p); i++ ){

        buffer += (int(p[7-i]) & 0xFF);

    }

    return buffer;

}

std::string etf_tuple(PyObject* tuple){

    Py_ssize_t len = PyTuple_Size(tuple);
    std::string buffer;

    buffer = (len > 256 ? LARGE_TUPLE_EXT : SMALL_TUPLE_EXT);
    buffer += (len > 256 ? (len & 0xFF) : char(len));

    for( int ii={0}; ii < len; ii++ ){

        PyObject* temp = PyTuple_GetItem(tuple, ii);

        buffer += SMALL_INTEGER_EXT;
        buffer += char(PyLong_AsUnsignedLong(temp));

    }

    return buffer;

}

static PyObject* earl_pack(PyObject* self, PyObject *args){

    std::string package;
    std::vector<PyObject*> objects;
    Py_ssize_t len = PyTuple_Size(args);

    if( !len ){

        if( !PyErr_Occurred() ){

            PyErr_SetString(PyExc_SyntaxError, "You must supply at least one argument.");

        }

        return NULL;

    }

    package = "\x83";

    for( int i={0}; i < len; i++ ){

        PyObject* temp = PyTuple_GetItem(args, i);

        if( temp == NULL ){

            if( !PyErr_Occurred() ){

                PyErr_SetString(PyExc_TypeError, "Earl wasn't able to unpack all your arguments for some reason.");

            }
            return NULL;

        }

        if( PyLong_Check(temp) ){

            unsigned long temp_int = PyLong_AsUnsignedLong(temp);
            temp_int < 256 ? package += etf_small_int(temp_int) : package += etf_big_int(temp_int);

        } else if( PyUnicode_Check(temp) ) {

            if( PyUnicode_READY(temp) != 0 ){

                if( !PyErr_Occurred() ){

                    PyErr_SetString(PyExc_RuntimeError, "Earl wasn't able to migrate the Python Unicode data to memory.");

                }
                return NULL;

            }else{

                package += etf_string(temp);

            }

        }else if( PyFloat_Check(temp) ){

            package += etf_float(PyFloat_AsDouble(temp));

        }else if( PyTuple_Check(temp) ){

            package += etf_tuple(temp);

        }else if( PySet_Check(temp) ){

            package += etf_set(temp);
            break;

        }else if( PyList_Check(temp) ){

            //package += etf_list(temp);
            break;

        }else if( PyDict_Check(temp) ){

            //package += etf_dict(temp);
            break;

        }else{

            if ( !PyErr_Occurred() ){

                PyErr_SetString(PyExc_TypeError, "Earl can't pack one of the types you gave it!");

            }
            return NULL;

        }

    }

    return Py_BuildValue("y#", package.c_str(), package.length());

}

static char earl_pack_docs[] = "pack(values): Pack a bunch of things into an External Term Format";

static PyMethodDef earlmethods[] = {

    {"pack", earl_pack, METH_VARARGS, earl_pack_docs},
    {NULL, NULL, 0, NULL}

};

static struct PyModuleDef earl = {

    PyModuleDef_HEAD_INIT,
    "earl",
    "Earl is the fanciest External Term Format library for Python.",
    -1,
    earlmethods

};

PyMODINIT_FUNC PyInit_earl(void){

    return PyModule_Create(&earl);

}
<|endoftext|>


<commit_before>/*************************************************************************
* Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
*                                                                        *
* Author: The ALICE Off-line Project.                                    *
* Contributors are mentioned in the code where appropriate.              *
*                                                                        *
* Permission to use, copy, modify and distribute this software and its   *
* documentation strictly for non-commercial purposes is hereby granted   *
* without fee, provided that the above copyright notice appears in all   *
* copies and that both the copyright notice and this permission notice   *
* appear in the supporting documentation. The authors make no claims     *
* about the suitability of this software for any purpose. It is          *
* provided "as is" without express or implied warranty.                  *
**************************************************************************/

///////////////////////////////////////////////////////////////////////////
//                Dielectron Variables Manager class                     //
//                                                                       //
/*

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

#include "AliDielectronVarManager.h"

ClassImp(AliDielectronVarManager)

const char* AliDielectronVarManager::fgkParticleNames[AliDielectronVarManager::kNMaxValues] = {
  "Px",
  "Py",
  "Pz",
  "Pt",
  "P",
  "Xv",
  "Yv",
  "Zv",
  "OneOverPt",
  "Phi",
  "Theta",
  "Eta",
  "Y",
  "E",
  "M",
  "Charge",
  "NclsITS",
  "NclsTPC",
  "NFclsTPC",
  "TPCsignalN",
  "NclsTRD",
  "TRDntracklets",
  "TRDpidQuality",
  "ImpactParXY",
  "ImpactParZ",
  "TrackLength",
  "PdgCode",
  "P from InnerParam",
  "TPC signal"
  //
  "Chi2NDF",
  "DecayLength",
  "R",
  "OpeningAngle",
  "Merr",
  "DCA",
  "PairType",
  //
  "X",
  "Y",
  "Z",
  "XRes",
  "YRes",
  "ZRes",
  "NTrk",
  "Tracks"
};

//________________________________________________________________
AliDielectronVarManager::AliDielectronVarManager() :
  TNamed("AliDielectronVarManager","AliDielectronVarManager")
{
  //
  // Default constructor
  //

}

//________________________________________________________________
AliDielectronVarManager::AliDielectronVarManager(const char* name, const char* title) :
  TNamed(name,title)
{
  //
  // Named constructor
  //

}

//________________________________________________________________
AliDielectronVarManager::~AliDielectronVarManager()
{
  //
  // Default destructor
  //
}

<commit_msg>Bug fix.<commit_after>/*************************************************************************
* Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
*                                                                        *
* Author: The ALICE Off-line Project.                                    *
* Contributors are mentioned in the code where appropriate.              *
*                                                                        *
* Permission to use, copy, modify and distribute this software and its   *
* documentation strictly for non-commercial purposes is hereby granted   *
* without fee, provided that the above copyright notice appears in all   *
* copies and that both the copyright notice and this permission notice   *
* appear in the supporting documentation. The authors make no claims     *
* about the suitability of this software for any purpose. It is          *
* provided "as is" without express or implied warranty.                  *
**************************************************************************/

///////////////////////////////////////////////////////////////////////////
//                Dielectron Variables Manager class                     //
//                                                                       //
/*

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

#include "AliDielectronVarManager.h"

ClassImp(AliDielectronVarManager)

const char* AliDielectronVarManager::fgkParticleNames[AliDielectronVarManager::kNMaxValues] = {
  "Px",
  "Py",
  "Pz",
  "Pt",
  "P",
  "Xv",
  "Yv",
  "Zv",
  "OneOverPt",
  "Phi",
  "Theta",
  "Eta",
  "Y",
  "E",
  "M",
  "Charge",
  "NclsITS",
  "NclsTPC",
  "NFclsTPC",
  "TPCsignalN",
  "NclsTRD",
  "TRDntracklets",
  "TRDpidQuality",
  "ImpactParXY",
  "ImpactParZ",
  "TrackLength",
  "PdgCode",
  "P from InnerParam",
  "TPC signal",
  //
  "Chi2NDF",
  "DecayLength",
  "R",
  "OpeningAngle",
  "Merr",
  "DCA",
  "PairType",
  //
  "X",
  "Y",
  "Z",
  "XRes",
  "YRes",
  "ZRes",
  "NTrk",
  "Tracks"
};

//________________________________________________________________
AliDielectronVarManager::AliDielectronVarManager() :
  TNamed("AliDielectronVarManager","AliDielectronVarManager")
{
  //
  // Default constructor
  //

}

//________________________________________________________________
AliDielectronVarManager::AliDielectronVarManager(const char* name, const char* title) :
  TNamed(name,title)
{
  //
  // Named constructor
  //

}

//________________________________________________________________
AliDielectronVarManager::~AliDielectronVarManager()
{
  //
  // Default destructor
  //
}

<|endoftext|>


<commit_before>AliChaoticity *AddTaskChaoticity(bool MCcase=kFALSE, bool Tabulatecase=kFALSE, bool PbPbcase=kTRUE, int CentLow=0, int CentHigh=1, TString inputFileNameWeight = "alien:///alice/cern.ch/user/d/dgangadh/WeightFile.root", TString inputFileNameMomRes = "alien:///alice/cern.ch/user/d/dgangadh/MomResFile.root", TString inputFileNameFSI = "alien:///alice/cern.ch/user/d/dgangadh/KFile.root") {

  //===========================================================================
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    ::Error("AddTaskBF", "No analysis manager to connect to.");
    return NULL;
  }

  //____________________________________________//
  // Create tasks
  AliChaoticity *ChaoticityTask = new AliChaoticity("ChaoticityTask", MCcase, Tabulatecase, PbPbcase, CentLow, CentHigh, kTRUE);
  if(!ChaoticityTask) exit(-1);
  mgr->AddTask(ChaoticityTask);

  // Create ONLY the output containers for the data produced by the task.
  // Get and connect other common input/output containers via the manager as below
  //==============================================================================
  TString outputFileName = AliAnalysisManager::GetCommonFileName();
  outputFileName += ":PWGCF.outputChaoticityAnalysis.root";
  AliAnalysisDataContainer *coutChaoticity = mgr->CreateContainer("ChaoticityOutput", TList::Class(),AliAnalysisManager::kOutputContainer,outputFileName.Data());
  mgr->ConnectInput(ChaoticityTask, 0, mgr->GetCommonInputContainer());
  mgr->ConnectOutput(ChaoticityTask, 1, coutChaoticity);

  TFile *inputFileWeight = 0;
  TFile *inputFileMomRes = 0;
  TFile *inputFileFSI = 0;

  if(!Tabulatecase){
    inputFileWeight = TFile::Open(inputFileNameWeight,"OLD");
    if (!inputFileWeight){
      cout << "Requested file:" << inputFileWeight << " was not opened. ABORT." << endl;
      return;
    }
    ////////////////////////////////////////////////////
    // C2 Weight File
    Int_t ktbins = ChaoticityTask->GetNumKtbins();
    Int_t cbins = ChaoticityTask->GetNumCentbins();
    TH3F *weightHisto[ktbins][cbins] = 0;
    for(Int_t i=0; i<ktbins; i++){
      for(Int_t j=0; j<cbins; j++){
	TString name = "Weight_Kt_";
	name += i;
	name += "_Ky_0_M_";
	name += j;
	name += "_ED_0";

	weightHisto[i][j] = (TH3F*)inputFileWeight->Get(name);
      }
    }
    ChaoticityTask->SetWeightArrays( kTRUE, weightHisto );
    ////////////////////////////////////////////////////
  }// Tabulatecase check

  if(!MCcase && !Tabulatecase){

    inputFileMomRes = TFile::Open(inputFileNameMomRes,"OLD");
    if (!inputFileMomRes){
      cout << "Requested file:" << inputFileMomRes << " was not opened. ABORT." << endl;
      return;
    }
    ////////////////////////////////////////////////////
    // Momentum Resolution File
    TH2D *momResHisto2D = 0;
    momResHisto2D = (TH2D*)inputFileMomRes->Get("MomResHisto_pp");
    ChaoticityTask->SetMomResCorrections( kTRUE, momResHisto2D);
    ////////////////////////////////////////////////////
  }// MCcase and Tabulatecase check

  ////////////////////////////////////////////////////
  // FSI File
  inputFileFSI = TFile::Open(inputFileNameFSI,"OLD");
  if (!inputFileFSI){
    cout << "Requested file:" << inputFileFSI << " was not opened. ABORT." << endl;
    return;
  }
  TH2D *FSI2gaus[2];
  TH2D *FSI2therm[2];
  TH3D *FSI3ss[6];
  TH3D *FSI3os[6];
  FSI2gaus[0] = (TH2D*)inputFileFSI->Get("K2ssG");
  FSI2gaus[1] = (TH2D*)inputFileFSI->Get("K2osG");
  FSI2therm[0] = (TH2D*)inputFileFSI->Get("K2ssT");
  FSI2therm[1] = (TH2D*)inputFileFSI->Get("K2osT");
  for(Int_t CB=0; CB<6; CB++) {
    TString *nameSS=new TString("K3ss_");
    *nameSS += CB;
    FSI3ss[CB] = (TH3D*)inputFileFSI->Get(nameSS->Data());
    TString *nameOS=new TString("K3os_");
    *nameOS += CB;
    FSI3os[CB] = (TH3D*)inputFileFSI->Get(nameOS->Data());
  }
  //
  FSI2gaus[0]->SetDirectory(0);
  FSI2gaus[1]->SetDirectory(0);
  FSI2therm[0]->SetDirectory(0);
  FSI2therm[1]->SetDirectory(0);
  for(Int_t CB=0; CB<6; CB++) {
    FSI3ss[CB]->SetDirectory(0);
    FSI3os[CB]->SetDirectory(0);
  }
  ChaoticityTask->SetFSICorrelations( kTRUE, FSI2gaus, FSI2therm , FSI3os, FSI3ss);
  ////////////////////////////////////////////////////

  // Return the task pointer
  return ChaoticityTask;
}
<commit_msg>hard-coded enum access (AddTask compatibility)<commit_after>AliChaoticity *AddTaskChaoticity(bool MCcase=kFALSE, bool Tabulatecase=kFALSE, bool PbPbcase=kTRUE, int CentLow=0, int CentHigh=1, TString inputFileNameWeight = "alien:///alice/cern.ch/user/d/dgangadh/WeightFile.root", TString inputFileNameMomRes = "alien:///alice/cern.ch/user/d/dgangadh/MomResFile.root", TString inputFileNameFSI = "alien:///alice/cern.ch/user/d/dgangadh/KFile.root") {

  //===========================================================================
  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    ::Error("AddTaskBF", "No analysis manager to connect to.");
    return NULL;
  }

  //____________________________________________//
  // Create tasks
  AliChaoticity *ChaoticityTask = new AliChaoticity("ChaoticityTask", MCcase, Tabulatecase, PbPbcase, CentLow, CentHigh, kTRUE);
  if(!ChaoticityTask) exit(-1);
  mgr->AddTask(ChaoticityTask);

  // Create ONLY the output containers for the data produced by the task.
  // Get and connect other common input/output containers via the manager as below
  //==============================================================================
  TString outputFileName = AliAnalysisManager::GetCommonFileName();
  outputFileName += ":PWGCF.outputChaoticityAnalysis.root";
  AliAnalysisDataContainer *coutChaoticity = mgr->CreateContainer("ChaoticityOutput", TList::Class(),AliAnalysisManager::kOutputContainer,outputFileName.Data());
  mgr->ConnectInput(ChaoticityTask, 0, mgr->GetCommonInputContainer());
  mgr->ConnectOutput(ChaoticityTask, 1, coutChaoticity);

  TFile *inputFileWeight = 0;
  TFile *inputFileMomRes = 0;
  TFile *inputFileFSI = 0;

  if(!Tabulatecase){
    inputFileWeight = TFile::Open(inputFileNameWeight,"OLD");
    if (!inputFileWeight){
      cout << "Requested file:" << inputFileWeight << " was not opened. ABORT." << endl;
      return;
    }
    ////////////////////////////////////////////////////
    // C2 Weight File
    Int_t ktbins = 3;// ChaoticityTask->GetNumKtbins();
    Int_t cbins = 10;// ChaoticityTask->GetNumCentbins();
    TH3F *weightHisto[ktbins][cbins] = 0;
    for(Int_t i=0; i<ktbins; i++){
      for(Int_t j=0; j<cbins; j++){
	TString name = "Weight_Kt_";
	name += i;
	name += "_Ky_0_M_";
	name += j;
	name += "_ED_0";

	weightHisto[i][j] = (TH3F*)inputFileWeight->Get(name);
      }
    }
    ChaoticityTask->SetWeightArrays( kTRUE, weightHisto );
    ////////////////////////////////////////////////////
  }// Tabulatecase check

  if(!MCcase && !Tabulatecase){

    inputFileMomRes = TFile::Open(inputFileNameMomRes,"OLD");
    if (!inputFileMomRes){
      cout << "Requested file:" << inputFileMomRes << " was not opened. ABORT." << endl;
      return;
    }
    ////////////////////////////////////////////////////
    // Momentum Resolution File
    TH2D *momResHisto2D = 0;
    momResHisto2D = (TH2D*)inputFileMomRes->Get("MomResHisto_pp");
    ChaoticityTask->SetMomResCorrections( kTRUE, momResHisto2D);
    ////////////////////////////////////////////////////
  }// MCcase and Tabulatecase check

  ////////////////////////////////////////////////////
  // FSI File
  inputFileFSI = TFile::Open(inputFileNameFSI,"OLD");
  if (!inputFileFSI){
    cout << "Requested file:" << inputFileFSI << " was not opened. ABORT." << endl;
    return;
  }
  TH2D *FSI2gaus[2];
  TH2D *FSI2therm[2];
  TH3D *FSI3ss[6];
  TH3D *FSI3os[6];
  FSI2gaus[0] = (TH2D*)inputFileFSI->Get("K2ssG");
  FSI2gaus[1] = (TH2D*)inputFileFSI->Get("K2osG");
  FSI2therm[0] = (TH2D*)inputFileFSI->Get("K2ssT");
  FSI2therm[1] = (TH2D*)inputFileFSI->Get("K2osT");
  for(Int_t CB=0; CB<6; CB++) {
    TString *nameSS=new TString("K3ss_");
    *nameSS += CB;
    FSI3ss[CB] = (TH3D*)inputFileFSI->Get(nameSS->Data());
    TString *nameOS=new TString("K3os_");
    *nameOS += CB;
    FSI3os[CB] = (TH3D*)inputFileFSI->Get(nameOS->Data());
  }
  //
  FSI2gaus[0]->SetDirectory(0);
  FSI2gaus[1]->SetDirectory(0);
  FSI2therm[0]->SetDirectory(0);
  FSI2therm[1]->SetDirectory(0);
  for(Int_t CB=0; CB<6; CB++) {
    FSI3ss[CB]->SetDirectory(0);
    FSI3os[CB]->SetDirectory(0);
  }
  ChaoticityTask->SetFSICorrelations( kTRUE, FSI2gaus, FSI2therm , FSI3os, FSI3ss);
  ////////////////////////////////////////////////////

  // Return the task pointer
  return ChaoticityTask;
}
<|endoftext|>