<commit_before>/*
 * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * 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.
 */

#ifndef otbScalarImageToHigherOrderTexturesFilter_hxx
#define otbScalarImageToHigherOrderTexturesFilter_hxx

#include "otbScalarImageToHigherOrderTexturesFilter.h"
#include "itkImageRegionIteratorWithIndex.h"
#include "itkImageRegionIterator.h"
#include "itkProgressReporter.h"

namespace otb
{
template <class TInputImage, class TOutputImage>
ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::ScalarImageToHigherOrderTexturesFilter() :
  m_Radius(),
  m_NumberOfBinsPerAxis(8),
  m_InputImageMinimum(0),
  m_InputImageMaximum(255),
  m_FastCalculations(false),
  m_SubsampleFactor(),
  m_SubsampleOffset()
{
  // There are 10 outputs corresponding to the 8 textures indices
  this->SetNumberOfRequiredOutputs(10);

  // Create the 11 outputs
  this->SetNthOutput(0, OutputImageType::New());
  this->SetNthOutput(1, OutputImageType::New());
  this->SetNthOutput(2, OutputImageType::New());
  this->SetNthOutput(3, OutputImageType::New());
  this->SetNthOutput(4, OutputImageType::New());
  this->SetNthOutput(5, OutputImageType::New());
  this->SetNthOutput(6, OutputImageType::New());
  this->SetNthOutput(7, OutputImageType::New());
  this->SetNthOutput(8, OutputImageType::New());
  this->SetNthOutput(9, OutputImageType::New());

  m_Radius.Fill(10);

  // Set the offset directions to their defaults: half of all the possible
  // directions 1 pixel away. (The other half is included by symmetry.)
  // We use a neighborhood iterator to calculate the appropriate offsets.
  typedef itk::Neighborhood<typename InputImageType::PixelType,
    InputImageType::ImageDimension> NeighborhoodType;
  NeighborhoodType hood;
  hood.SetRadius( 1 );

  // select all "previous" neighbors that are face+edge+vertex
  // connected to the current pixel. do not include the center pixel.
  unsigned int centerIndex = hood.GetCenterNeighborhoodIndex();
  OffsetVectorPointer offsets = OffsetVector::New();
  for( unsigned int d = 0; d < centerIndex; d++ )
    {
    OffsetType offset = hood.GetOffset( d );
    offsets->push_back( offset );
    }
  this->SetOffsets( offsets );

  this->m_SubsampleFactor.Fill(1);
  this->m_SubsampleOffset.Fill(0);
}

template <class TInputImage, class TOutputImage>
ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::~ScalarImageToHigherOrderTexturesFilter()
{}

template <class TInputImage, class TOutputImage>
typename ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::OutputImageType *
ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::GetShortRunEmphasisOutput()
{
  if (this->GetNumberOfOutputs() < 1)
    {
    return nullptr;
    }
  return static_cast<OutputImageType *>(this->GetOutput(0));
}

template <class TInputImage, class TOutputImage>
typename ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::OutputImageType *
ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::GetLongRunEmphasisOutput()
{
  if (this->GetNumberOfOutputs() < 2)
    {
    return nullptr;
    }
  return static_cast<OutputImageType *>(this->GetOutput(1));
}

template <class TInputImage, class TOutputImage>
typename ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::OutputImageType *
ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::GetGreyLevelNonuniformityOutput()
{
  if (this->GetNumberOfOutputs() < 3)
    {
    return nullptr;
    }
  return static_cast<OutputImageType *>(this->GetOutput(2));
}

template <class TInputImage, class TOutputImage>
typename ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::OutputImageType *
ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::GetRunLengthNonuniformityOutput()
{
  if (this->GetNumberOfOutputs() < 4)
    {
    return nullptr;
    }
  return static_cast<OutputImageType *>(this->GetOutput(3));
}

template <class TInputImage, class TOutputImage>
typename ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::OutputImageType *
ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::GetLowGreyLevelRunEmphasisOutput()
{
  if (this->GetNumberOfOutputs() < 5)
    {
    return nullptr;
    }
  return static_cast<OutputImageType *>(this->GetOutput(4));
}

template <class TInputImage, class TOutputImage>
typename ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::OutputImageType *
ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::GetHighGreyLevelRunEmphasisOutput()
{
  if (this->GetNumberOfOutputs() < 6)
    {
    return nullptr;
    }
  return static_cast<OutputImageType *>(this->GetOutput(5));
}

template <class TInputImage, class TOutputImage>
typename ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::OutputImageType *
ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::GetShortRunLowGreyLevelEmphasisOutput()
{
  if (this->GetNumberOfOutputs() < 7)
    {
    return nullptr;
    }
  return static_cast<OutputImageType *>(this->GetOutput(6));
}

template <class TInputImage, class TOutputImage>
typename ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::OutputImageType *
ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::GetShortRunHighGreyLevelEmphasisOutput()
{
  if (this->GetNumberOfOutputs() < 8)
    {
    return nullptr;
    }
  return static_cast<OutputImageType *>(this->GetOutput(7));
}

template <class TInputImage, class TOutputImage>
typename ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::OutputImageType *
ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::GetLongRunLowGreyLevelEmphasisOutput()
{
  if (this->GetNumberOfOutputs() < 9)
    {
    return nullptr;
    }
  return static_cast<OutputImageType *>(this->GetOutput(8));
}

template <class TInputImage, class TOutputImage>
typename ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::OutputImageType *
ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::GetLongRunHighGreyLevelEmphasisOutput()
{
  if (this->GetNumberOfOutputs() < 10)
    {
    return nullptr;
    }
  return static_cast<OutputImageType *>(this->GetOutput(9));
}

template <class TInputImage, class TOutputImage>
void
ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::SetOffset( const OffsetType offset )
{
  OffsetVectorPointer offsetVector = OffsetVector::New();
  offsetVector->push_back( offset );
  this->SetOffsets( offsetVector );
}

template <class TInputImage, class TOutputImage>
void
ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::GenerateOutputInformation()
{
  // First, call superclass implementation
  Superclass::GenerateOutputInformation();

  // Compute output size, origin & spacing
  InputRegionType inputRegion = this->GetInput()->GetLargestPossibleRegion();
  OutputRegionType outputRegion;
  outputRegion.SetIndex(0,0);
  outputRegion.SetIndex(1,0);
  outputRegion.SetSize(0, 1 + (inputRegion.GetSize(0) - 1 - m_SubsampleOffset[0]) / m_SubsampleFactor[0]);
  outputRegion.SetSize(1, 1 + (inputRegion.GetSize(1) - 1 - m_SubsampleOffset[1]) / m_SubsampleFactor[1]);

  typename OutputImageType::SpacingType outSpacing = this->GetInput()->GetSignedSpacing();
  outSpacing[0] *= m_SubsampleFactor[0];
  outSpacing[1] *= m_SubsampleFactor[1];

  typename OutputImageType::PointType outOrigin;
  this->GetInput()->TransformIndexToPhysicalPoint(inputRegion.GetIndex()+m_SubsampleOffset,outOrigin);

  for (unsigned int i=0 ; i < this->GetNumberOfOutputs() ; i++)
    {
    OutputImagePointerType outputPtr = this->GetOutput(i);
    outputPtr->SetLargestPossibleRegion(outputRegion);
    outputPtr->SetOrigin(outOrigin);
    outputPtr->SetSignedSpacing(outSpacing);
    }
}

template <class TInputImage, class TOutputImage>
void
ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::GenerateInputRequestedRegion()
{
  // First, call superclass implementation
  Superclass::GenerateInputRequestedRegion();

  // Retrieve the input and output pointers
  InputImagePointerType  inputPtr = const_cast<InputImageType *>(this->GetInput());
  OutputImagePointerType outputPtr = this->GetOutput();

  if (!inputPtr || !outputPtr)
    {
    return;
    }

  // Retrieve the output requested region
  // We use only the first output since requested regions for all outputs are enforced to be equal
  // by the default GenerateOutputRequestedRegiont() implementation
  OutputRegionType outputRequestedRegion = outputPtr->GetRequestedRegion();
  typename OutputRegionType::IndexType outputIndex = outputRequestedRegion.GetIndex();
  typename OutputRegionType::SizeType  outputSize   = outputRequestedRegion.GetSize();
  InputRegionType inputLargest = inputPtr->GetLargestPossibleRegion();

  // Convert index and size to full grid
  outputIndex[0] = outputIndex[0] * m_SubsampleFactor[0] + m_SubsampleOffset[0] + inputLargest.GetIndex(0);
  outputIndex[1] = outputIndex[1] * m_SubsampleFactor[1] + m_SubsampleOffset[1] + inputLargest.GetIndex(1);
  outputSize[0] = 1 + (outputSize[0] - 1) * m_SubsampleFactor[0];
  outputSize[1] = 1 + (outputSize[1] - 1) * m_SubsampleFactor[1];

  InputRegionType inputRequestedRegion(outputIndex,outputSize);

  // Apply the radius
  inputRequestedRegion.PadByRadius(m_Radius);

  // Try to apply the requested region to the input image
  if (inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion()))
    {
    inputPtr->SetRequestedRegion(inputRequestedRegion);
    }
  else
    {
    // Build an exception
    itk::InvalidRequestedRegionError e(__FILE__, __LINE__);
    e.SetLocation(ITK_LOCATION);
    e.SetDescription("Requested region is (at least partially) outside the largest possible region.");
    e.SetDataObject(inputPtr);
    throw e;
    }
}

template <class TInputImage, class TOutputImage>
void
ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::ThreadedGenerateData(const OutputRegionType& outputRegionForThread, itk::ThreadIdType threadId)
{
  // Retrieve the input and output pointers
  InputImagePointerType  inputPtr  = const_cast<InputImageType *>(this->GetInput());

  typedef typename itk::ImageRegionIterator<OutputImageType> IteratorType;
  std::vector<IteratorType> outputImagesIterators;

  for (unsigned int i = 0; i < this->GetNumberOfOutputs(); ++i)
    {
    outputImagesIterators.push_back( IteratorType(this->GetOutput(i), outputRegionForThread) );
    outputImagesIterators[i].GoToBegin();
    }

  // Compute the max possible run length (in physical unit)
  typename InputImageType::PointType  topLeftPoint;
  typename InputImageType::PointType  bottomRightPoint;
  inputPtr->TransformIndexToPhysicalPoint( outputImagesIterators[0].GetIndex() - m_Radius, topLeftPoint );
  inputPtr->TransformIndexToPhysicalPoint( outputImagesIterators[0].GetIndex() + m_Radius, bottomRightPoint );
  double maxDistance = topLeftPoint.EuclideanDistanceTo(bottomRightPoint);

  InputRegionType inputLargest = inputPtr->GetLargestPossibleRegion();

  // Set-up progress reporting
  itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());

  // Iterate on outputs to compute textures
  while ( !outputImagesIterators[0].IsAtEnd() )
    {
    // Compute the region on which run-length matrix will be estimated
    typename InputRegionType::IndexType inputIndex;
    typename InputRegionType::SizeType  inputSize;

    // Convert index to full grid
    typename OutputImageType::IndexType outIndex;

    for (unsigned int dim = 0; dim < InputImageType::ImageDimension; ++dim)
      {
      outIndex[dim] = outputImagesIterators[0].GetIndex()[dim] * m_SubsampleFactor[dim]
        + m_SubsampleOffset[dim] + inputLargest.GetIndex(dim);
      inputIndex[dim] = outIndex[dim] - m_Radius[dim];
      inputSize[dim] = 2 * m_Radius[dim] + 1;
      }

    // Build the input  region
    InputRegionType inputRegion;
    inputRegion.SetIndex(inputIndex);
    inputRegion.SetSize(inputSize);

    inputRegion.Crop(inputPtr->GetBufferedRegion());

    // Create a local image corresponding to the input region
    InputImagePointerType localInputImage = InputImageType::New();
    localInputImage->SetRegions(inputRegion);
    localInputImage->Allocate();
    typedef itk::ImageRegionIteratorWithIndex<InputImageType> ImageRegionIteratorType;
    ImageRegionIteratorType itInputPtr(inputPtr, inputRegion);
    ImageRegionIteratorType itLocalInputImage(localInputImage, inputRegion);
    for (itInputPtr.GoToBegin(), itLocalInputImage.GoToBegin();
        !itInputPtr.IsAtEnd();
        ++itInputPtr, ++itLocalInputImage)
      {
      itLocalInputImage.Set(itInputPtr.Get());
      }

    typename ScalarImageToRunLengthFeaturesFilterType::Pointer runLengthFeatureCalculator = ScalarImageToRunLengthFeaturesFilterType::New();
    runLengthFeatureCalculator->SetInput(localInputImage);
    runLengthFeatureCalculator->SetOffsets(m_Offsets);
    runLengthFeatureCalculator->SetNumberOfBinsPerAxis(m_NumberOfBinsPerAxis);
    runLengthFeatureCalculator->SetPixelValueMinMax(m_InputImageMinimum, m_InputImageMaximum);
    runLengthFeatureCalculator->SetDistanceValueMinMax(0, maxDistance);

    runLengthFeatureCalculator->Update();

    typename ScalarImageToRunLengthFeaturesFilterType::FeatureValueVector&
      featuresMeans = *(runLengthFeatureCalculator->GetFeatureMeans().GetPointer());

    // Fill output
    for (unsigned int i = 0; i < this->GetNumberOfOutputs(); ++i)
    {
    // Fill output
    outputImagesIterators[i].Set(featuresMeans[i]);
    // Increment iterators
    ++outputImagesIterators[i];
    }
    // Update progress
    progress.CompletedPixel();
    }
}

} // End namespace otb

#endif
<commit_msg>REFAC: rm cast and change some types<commit_after>/*
 * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * 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.
 */

#ifndef otbScalarImageToHigherOrderTexturesFilter_hxx
#define otbScalarImageToHigherOrderTexturesFilter_hxx

#include "otbScalarImageToHigherOrderTexturesFilter.h"
#include "itkImageRegionIteratorWithIndex.h"
#include "itkImageRegionIterator.h"
#include "itkProgressReporter.h"

namespace otb
{
template <class TInputImage, class TOutputImage>
ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::ScalarImageToHigherOrderTexturesFilter() :
  m_Radius(),
  m_NumberOfBinsPerAxis(8),
  m_InputImageMinimum(0),
  m_InputImageMaximum(255),
  m_FastCalculations(false),
  m_SubsampleFactor(),
  m_SubsampleOffset()
{
  // There are 10 outputs corresponding to the 8 textures indices
  this->SetNumberOfRequiredOutputs(10);

  // Create the 11 outputs
  this->SetNthOutput(0, OutputImageType::New());
  this->SetNthOutput(1, OutputImageType::New());
  this->SetNthOutput(2, OutputImageType::New());
  this->SetNthOutput(3, OutputImageType::New());
  this->SetNthOutput(4, OutputImageType::New());
  this->SetNthOutput(5, OutputImageType::New());
  this->SetNthOutput(6, OutputImageType::New());
  this->SetNthOutput(7, OutputImageType::New());
  this->SetNthOutput(8, OutputImageType::New());
  this->SetNthOutput(9, OutputImageType::New());

  m_Radius.Fill(10);

  // Set the offset directions to their defaults: half of all the possible
  // directions 1 pixel away. (The other half is included by symmetry.)
  // We use a neighborhood iterator to calculate the appropriate offsets.
  typedef itk::Neighborhood<typename InputImageType::PixelType,
    InputImageType::ImageDimension> NeighborhoodType;
  NeighborhoodType hood;
  hood.SetRadius( 1 );

  // select all "previous" neighbors that are face+edge+vertex
  // connected to the current pixel. do not include the center pixel.
  unsigned int centerIndex = hood.GetCenterNeighborhoodIndex();
  OffsetVectorPointer offsets = OffsetVector::New();
  for( unsigned int d = 0; d < centerIndex; d++ )
    {
    OffsetType offset = hood.GetOffset( d );
    offsets->push_back( offset );
    }
  this->SetOffsets( offsets );

  this->m_SubsampleFactor.Fill(1);
  this->m_SubsampleOffset.Fill(0);
}

template <class TInputImage, class TOutputImage>
ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::~ScalarImageToHigherOrderTexturesFilter()
{}

template <class TInputImage, class TOutputImage>
typename ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::OutputImageType *
ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::GetShortRunEmphasisOutput()
{
  this->GetOutput(0);
}

template <class TInputImage, class TOutputImage>
typename ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::OutputImageType *
ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::GetLongRunEmphasisOutput()
{
  this->GetOutput(1);
}

template <class TInputImage, class TOutputImage>
typename ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::OutputImageType *
ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::GetGreyLevelNonuniformityOutput()
{
  this->GetOutput(2);
}

template <class TInputImage, class TOutputImage>
typename ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::OutputImageType *
ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::GetRunLengthNonuniformityOutput()
{
  this->GetOutput(3);
}

template <class TInputImage, class TOutputImage>
typename ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::OutputImageType *
ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::GetLowGreyLevelRunEmphasisOutput()
{
  this->GetOutput(4);
}

template <class TInputImage, class TOutputImage>
typename ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::OutputImageType *
ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::GetHighGreyLevelRunEmphasisOutput()
{
  this->GetOutput(5);
}

template <class TInputImage, class TOutputImage>
typename ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::OutputImageType *
ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::GetShortRunLowGreyLevelEmphasisOutput()
{
  this->GetOutput(6);
}

template <class TInputImage, class TOutputImage>
typename ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::OutputImageType *
ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::GetShortRunHighGreyLevelEmphasisOutput()
{
  this->GetOutput(7);
}

template <class TInputImage, class TOutputImage>
typename ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::OutputImageType *
ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::GetLongRunLowGreyLevelEmphasisOutput()
{
  this->GetOutput(8);
}

template <class TInputImage, class TOutputImage>
typename ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::OutputImageType *
ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::GetLongRunHighGreyLevelEmphasisOutput()
{
  this->GetOutput(9);
}

template <class TInputImage, class TOutputImage>
void
ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::SetOffset( const OffsetType offset )
{
  OffsetVectorPointer offsetVector = OffsetVector::New();
  offsetVector->push_back( offset );
  this->SetOffsets( offsetVector );
}

template <class TInputImage, class TOutputImage>
void
ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::GenerateOutputInformation()
{
  // Compute output size, origin & spacing
  const InputImageType * inputPtr = this->GetInput();
  InputRegionType inputRegion = inputPtr->GetLargestPossibleRegion();
  OutputRegionType outputRegion;
  outputRegion.SetIndex(0,0);
  outputRegion.SetIndex(1,0);
  outputRegion.SetSize(0, 1 + (inputRegion.GetSize(0) - 1 - m_SubsampleOffset[0]) / m_SubsampleFactor[0]);
  outputRegion.SetSize(1, 1 + (inputRegion.GetSize(1) - 1 - m_SubsampleOffset[1]) / m_SubsampleFactor[1]);

  typename OutputImageType::SpacingType outSpacing = inputPtr->GetSignedSpacing();
  outSpacing[0] *= m_SubsampleFactor[0];
  outSpacing[1] *= m_SubsampleFactor[1];

  typename OutputImageType::PointType outOrigin;
  inputPtr->TransformIndexToPhysicalPoint(inputRegion.GetIndex()+m_SubsampleOffset,outOrigin);

  for (unsigned int i=0 ; i < this->GetNumberOfOutputs() ; i++)
    {
    OutputImagePointerType outputPtr = this->GetOutput(i);
    outputPtr->CopyInformation(inputPtr);
    outputPtr->SetLargestPossibleRegion(outputRegion);
    outputPtr->SetOrigin(outOrigin);
    outputPtr->SetSignedSpacing(outSpacing);
    }
}

template <class TInputImage, class TOutputImage>
void
ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::GenerateInputRequestedRegion()
{
  // First, call superclass implementation
  Superclass::GenerateInputRequestedRegion();

  // Retrieve the input and output pointers
  InputImagePointerType  inputPtr = const_cast<InputImageType *>(this->GetInput());
  OutputImagePointerType outputPtr = this->GetOutput();

  if (!inputPtr || !outputPtr)
    {
    return;
    }

  // Retrieve the output requested region
  // We use only the first output since requested regions for all outputs are enforced to be equal
  // by the default GenerateOutputRequestedRegiont() implementation
  OutputRegionType outputRequestedRegion = outputPtr->GetRequestedRegion();
  typename OutputRegionType::IndexType outputIndex = outputRequestedRegion.GetIndex();
  typename OutputRegionType::SizeType  outputSize   = outputRequestedRegion.GetSize();
  InputRegionType inputLargest = inputPtr->GetLargestPossibleRegion();

  // Convert index and size to full grid
  outputIndex[0] = outputIndex[0] * m_SubsampleFactor[0] + m_SubsampleOffset[0] + inputLargest.GetIndex(0);
  outputIndex[1] = outputIndex[1] * m_SubsampleFactor[1] + m_SubsampleOffset[1] + inputLargest.GetIndex(1);
  outputSize[0] = 1 + (outputSize[0] - 1) * m_SubsampleFactor[0];
  outputSize[1] = 1 + (outputSize[1] - 1) * m_SubsampleFactor[1];

  InputRegionType inputRequestedRegion(outputIndex,outputSize);

  // Apply the radius
  inputRequestedRegion.PadByRadius(m_Radius);

  // Try to apply the requested region to the input image
  if (inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion()))
    {
    inputPtr->SetRequestedRegion(inputRequestedRegion);
    }
  else
    {
    // Build an exception
    itk::InvalidRequestedRegionError e(__FILE__, __LINE__);
    e.SetLocation(ITK_LOCATION);
    e.SetDescription("Requested region is (at least partially) outside the largest possible region.");
    e.SetDataObject(inputPtr);
    throw e;
    }
}

template <class TInputImage, class TOutputImage>
void
ScalarImageToHigherOrderTexturesFilter<TInputImage, TOutputImage>
::ThreadedGenerateData(const OutputRegionType& outputRegionForThread, itk::ThreadIdType threadId)
{
  // Retrieve the input and output pointers
  const InputImageType *  inputPtr  = this->GetInput();

  typedef typename itk::ImageRegionIterator<OutputImageType> IteratorType;
  std::vector<IteratorType> outputImagesIterators;

  for (unsigned int i = 0; i < this->GetNumberOfOutputs(); ++i)
    {
    outputImagesIterators.push_back( IteratorType(this->GetOutput(i), outputRegionForThread) );
    outputImagesIterators[i].GoToBegin();
    }

  // Compute the max possible run length (in physical unit)
  typename InputImageType::PointType  topLeftPoint;
  typename InputImageType::PointType  bottomRightPoint;
  inputPtr->TransformIndexToPhysicalPoint( outputImagesIterators[0].GetIndex() - m_Radius, topLeftPoint );
  inputPtr->TransformIndexToPhysicalPoint( outputImagesIterators[0].GetIndex() + m_Radius, bottomRightPoint );
  double maxDistance = topLeftPoint.EuclideanDistanceTo(bottomRightPoint);

  InputRegionType inputLargest = inputPtr->GetLargestPossibleRegion();

  // Set-up progress reporting
  itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());

  // Iterate on outputs to compute textures
  while ( !outputImagesIterators[0].IsAtEnd() )
    {
    // Compute the region on which run-length matrix will be estimated
    typename InputRegionType::IndexType inputIndex;
    typename InputRegionType::SizeType  inputSize;

    // Convert index to full grid
    typename OutputImageType::IndexType outIndex;

    for (unsigned int dim = 0; dim < InputImageType::ImageDimension; ++dim)
      {
      outIndex[dim] = outputImagesIterators[0].GetIndex()[dim] * m_SubsampleFactor[dim]
        + m_SubsampleOffset[dim] + inputLargest.GetIndex(dim);
      inputIndex[dim] = outIndex[dim] - m_Radius[dim];
      inputSize[dim] = 2 * m_Radius[dim] + 1;
      }

    // Build the input  region
    InputRegionType inputRegion;
    inputRegion.SetIndex(inputIndex);
    inputRegion.SetSize(inputSize);

    inputRegion.Crop(inputPtr->GetBufferedRegion());

    // Create a local image corresponding to the input region
    InputImagePointerType localInputImage = InputImageType::New();
    localInputImage->SetRegions(inputRegion);
    localInputImage->Allocate();
    typedef itk::ImageRegionIteratorWithIndex<InputImageType> ImageRegionIteratorType;
    typedef itk::ImageRegionConstIteratorWithIndex<InputImageType> ImageRegionConstIteratorType;
    ImageRegionConstIteratorType itInputPtr(inputPtr, inputRegion);
    ImageRegionIteratorType itLocalInputImage(localInputImage, inputRegion);
    for (itInputPtr.GoToBegin(), itLocalInputImage.GoToBegin();
        !itInputPtr.IsAtEnd();
        ++itInputPtr, ++itLocalInputImage)
      {
      itLocalInputImage.Set(itInputPtr.Get());
      }

    typename ScalarImageToRunLengthFeaturesFilterType::Pointer runLengthFeatureCalculator = ScalarImageToRunLengthFeaturesFilterType::New();
    runLengthFeatureCalculator->SetInput(localInputImage);
    runLengthFeatureCalculator->SetOffsets(m_Offsets);
    runLengthFeatureCalculator->SetNumberOfBinsPerAxis(m_NumberOfBinsPerAxis);
    runLengthFeatureCalculator->SetPixelValueMinMax(m_InputImageMinimum, m_InputImageMaximum);
    runLengthFeatureCalculator->SetDistanceValueMinMax(0, maxDistance);

    runLengthFeatureCalculator->Update();

    typename ScalarImageToRunLengthFeaturesFilterType::FeatureValueVector&
      featuresMeans = *(runLengthFeatureCalculator->GetFeatureMeans().GetPointer());

    // Fill output
    for (unsigned int i = 0; i < this->GetNumberOfOutputs(); ++i)
    {
    // Fill output
    outputImagesIterators[i].Set(featuresMeans[i]);
    // Increment iterators
    ++outputImagesIterators[i];
    }
    // Update progress
    progress.CompletedPixel();
    }
}

} // End namespace otb

#endif
<|endoftext|>


<commit_before>#if defined(__CLING__)
#include "AliMultDepSpecAnalysisTask.h"
#endif

AliMultDepSpecAnalysisTask* AddTask_mkrueger_MultDepSpec(TString controlstring, Int_t cutModeLow = 100, Int_t cutModeHigh = 121)
{

  // settings:
  Bool_t includeCrosscheckHistos = kFALSE;
  Bool_t is2013pA = kFALSE;
  UInt_t offlineTriggerMask = AliVEvent::kINT7;
  Bool_t is2015Data = kFALSE;
  Bool_t isPbPbAnalysis = kFALSE;

  Int_t maxMultiplicity = 100;
  Float_t etaCut = 0.8;
  if(controlstring.Contains("eta03")) etaCut = 0.3;

  Float_t lowerPtCut = 0.15;
  Float_t upperPtCut = 10.;

  string colsys = "pp";

  const Int_t nMultSteps = 3;
  Int_t multSteps[] = {100, 0, 0};
  Int_t multBinWidth[] = {1,1,1};

  Int_t nBinsCent = 1;
  Double_t centBinEdgesDummy[2] = {0., 100.};
  Double_t centBinEdgesUsed[9] = {0., 5., 10., 20., 40., 60., 80., 90., 100.};
  Double_t* centBinEdges = centBinEdgesDummy;

  if(controlstring.Contains("pp")){
    if(controlstring.Contains("performanceHistos")) includeCrosscheckHistos = kTRUE;
    if(controlstring.Contains("5TeV")) is2015Data = kTRUE;
    if(controlstring.Contains("7TeV")) offlineTriggerMask = AliVEvent::kMB;
    if(controlstring.Contains("2TeV")) offlineTriggerMask = AliVEvent::kMB;
    if(controlstring.Contains("09TeV")) offlineTriggerMask = AliVEvent::kMB;
  }
  if(controlstring.Contains("XeXe"))  {
    colsys = "XeXe";
    multSteps[0] = 3500;  multBinWidth[0] = 1;
    multSteps[1] = 0;    multBinWidth[1] = 1;
    multSteps[2] = 0;    multBinWidth[2] = 1;
    nBinsCent = 8;
    centBinEdges = centBinEdgesUsed;
  }
  if(controlstring.Contains("pPb"))  {
    colsys = "pPb";
    multSteps[0] = 200;   multBinWidth[0] = 1;
    multSteps[1] = 0;     multBinWidth[1] = 1;
    multSteps[2] = 0;     multBinWidth[2] = 1;
    is2013pA = kTRUE;
  }
  if(controlstring.Contains("PbPb")) {
    isPbPbAnalysis = kTRUE;
    is2015Data = kTRUE;
    colsys = "PbPb";
    multSteps[0] = 4500;   multBinWidth[0] = 1;
    multSteps[1] = 0;    multBinWidth[1] = 1;
    multSteps[2] = 0;    multBinWidth[2] = 1;
    nBinsCent = 8;
    centBinEdges = centBinEdgesUsed;
    if(controlstring.Contains("2TeV")){offlineTriggerMask = AliVEvent::kMB; is2015Data = kFALSE;}
  }
  if(controlstring.Contains("oldTrigger")){offlineTriggerMask = AliVEvent::kMB;}

  // Binning in Multiplicity
  const Int_t nBinsMult = multSteps[0]+ multSteps[1] + multSteps[2] + 1;
  Double_t multBinEdges[nBinsMult+1];
  multBinEdges[0] = -0.5;
  multBinEdges[1] = 0.5;
  Int_t startBin = 1;
  Int_t endBin = 1;
  for(Int_t multStep = 0; multStep < nMultSteps; multStep++){
    endBin += multSteps[multStep];
    for(Int_t multBin = startBin; multBin < endBin; multBin++)  {
      multBinEdges[multBin+1] = multBinEdges[multBin] + multBinWidth[multStep];
    }
    startBin = endBin;
  }

  AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();

  if (!mgr) {
    Error("AddTask_mkrueger_MultDepSpec", "No analysis manager found.");
    return 0;
  }

  // Switch off all AliInfo (too much output!!!)
  AliLog::SetGlobalLogLevel(AliLog::kError);
  mgr->SetDebugLevel(0);

  TString type = mgr->GetInputEventHandler()->GetDataType(); // can be "ESD" or "AOD"
  Bool_t hasMC = (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler() != 0x0);

  if(controlstring.Contains("PbPb") && hasMC) offlineTriggerMask = AliVEvent::kMB;
  if(controlstring.Contains("highMult")){offlineTriggerMask = AliVEvent::kHighMult;}

  AliMultDepSpecAnalysisTask* mainTask = NULL;

  char taskName[100] = "";

  if(controlstring.Contains("logBinsPt")){

    Double_t minPt = 0.1;
    Double_t maxPt = 100.;
    Int_t nbinsPt = 30;

    Double_t logminPt = TMath::Log10(minPt);
    Double_t logmaxPt = TMath::Log10(maxPt);
    Double_t binwidth = (logmaxPt-logminPt)/nbinsPt;
    Double_t* binsPt =  new Double_t[nbinsPt+1];
    binsPt[0] = minPt;
    for (Int_t i = 1; i <= nbinsPt; i++) {
      binsPt[i] = minPt + TMath::Power(10, logminPt + i*binwidth);
    }
  }
  if(controlstring.Contains("noCent")) {
    nBinsCent = 1;
    centBinEdges = centBinEdgesDummy;
  }

  for(Int_t cutMode = cutModeLow; cutMode <= cutModeHigh; cutMode++){
    sprintf(taskName, "mkrueger_%s_eta_%.2f_cutMode_%d", colsys.c_str(), etaCut, cutMode);

    AliMultDepSpecAnalysisTask* task = new AliMultDepSpecAnalysisTask(taskName);

    if(controlstring.Contains("fullPt")){
      upperPtCut = 50;
      lowerPtCut = 0.15;
//      Double_t pTBinEdgesLarge[69] = {0.,0.05,0.1,0.15,0.2,0.25,0.3,0.35,0.4,0.45,0.5,0.55,0.6,0.65,0.7,0.75,0.8,0.85,0.9,0.95,1.0,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,2.0,2.2,2.4,2.6,2.8,3.0,3.2,3.4,3.6,3.8,4.0,4.5,5.0,5.5,6.0,6.5,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,18.0,20.0,22.0,24.0,26.0,28.0,30.0,32.0,34.0,36.0,40.0,45.0,50.0};
//      Double_t pTBinEdgesLarge[54] = {0.,0.05,0.1,0.15,0.2,0.25,0.3,0.35,0.4,0.45,0.5,0.55,0.6,0.65,0.7,0.75,0.8,0.85,0.9,0.95,1.0,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,2.0,2.2,2.4,2.6,2.8,3.0,3.2,3.4,3.6,3.8,4.0,4.5,5.0,5.5,6.0,6.5,7.0,8.0,9.0,10.0,20.0,30.0,40.0,50.0};
      Double_t pTBinEdgesLarge[53] = {0.1,0.15,0.2,0.25,0.3,0.35,0.4,0.45,0.5,0.55,0.6,0.65,0.7,0.75,0.8,0.85,0.9,0.95,1.0,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,2.0,2.2,2.4,2.6,2.8,3.0,3.2,3.4,3.6,3.8,4.0,4.5,5.0,5.5,6.0,6.5,7.0,8.0,9.0,10.0,20.0,30.0,40.0,50.0,60.0};
      task->SetBinsPt(52, pTBinEdgesLarge);
    }

    task->SetIncludeCrosscheckHistos(includeCrosscheckHistos);
    task->Set2013pA(is2013pA);

    // general cuts
    task->SelectCollisionCandidates(offlineTriggerMask);
    task->SetTriggerMask(offlineTriggerMask);

    task->SetUseMC(hasMC);
    if(type.Contains("ESD")) task->SetUseESD();
    else task->SetUseAOD();
    task->SetBinsMult(nBinsMult, multBinEdges);
    task->SetBinsCent(nBinsCent, centBinEdges);

    // nominal cut-setting:
    task->SetMinEta(-etaCut);
    task->SetMaxEta(etaCut);
    task->SetMinPt(lowerPtCut);
    task->SetMaxPt(upperPtCut);

    task->Set2013pA(kFALSE);
    task->Set2015data(is2015Data);

    task->SetMeanXYZv(0.0,0.0,0.0);
    task->SetSigmaMeanXYZv(1.0,1.0,10.0);
    task->SetZvtx(10.);

    // Quality cuts for tracks
    task->SetTPCRefit(kTRUE);
    task->SetITSRefit(kTRUE);
    task->SetKinkDaughters(kFALSE);
    task->SetRatioCrossedRowsOverFindableClustersTPC(0.8);
    task->SetFractionSharedClustersTPC(0.4);
    task->SetMaxchi2perTPCclu(4.);
    task->SetClusterReqITS(kTRUE);
    task->SetMaxchi2perITSclu(36.);
    task->SetDCAtoVertex2D(kFALSE);
    task->SetSigmaToVertex(kFALSE);
    task->SetDCAtoVertexZ(2.0);
    task->SetDCAtoVertexXYPtDep("0.0182+0.0350/pt^1.01");
    task->SetMaxChi2TPCConstrained(36.); // was excluded for some reason?
    task->SetMinLenghtInActiveZoneTPC(0);
    task->SetGeometricalCut(kTRUE,3,130,1.5,0.85,0.7); ///if kTRUE comment CrossedRowsTPC cut
    // task->SetMinCrossedRowsTPC(120);

//MC1--
      if(cutMode == 100) mainTask = task; // has no particular use... just to return task with nominal cut setting in macro

    // cut-variation:
      if(cutMode == 101) {task->SetMaxchi2perITSclu(25.);}
      if(cutMode == 102) {task->SetMaxchi2perITSclu(49.);}

      if(cutMode == 103) {task->SetMaxchi2perTPCclu(3); }
      if(cutMode == 104) {task->SetMaxchi2perTPCclu(5); }
//MC2--
      if(cutMode == 105) {task->SetRatioCrossedRowsOverFindableClustersTPC(0.7);}
      if(cutMode == 106) {task->SetRatioCrossedRowsOverFindableClustersTPC(0.9);}

      if(cutMode == 107) {task->SetFractionSharedClustersTPC(0.2);}
      if(cutMode == 108) {task->SetFractionSharedClustersTPC(1.0);}
//MC3--
      if(cutMode == 109) {task->SetMaxChi2TPCConstrained(25.);}
      if(cutMode == 110) {task->SetMaxChi2TPCConstrained(49.);}

      if(cutMode == 111) {task->SetDCAtoVertexXYPtDep("0.0104+0.0200/pt^1.01");}
      if(cutMode == 112) {task->SetDCAtoVertexXYPtDep("0.0260+0.0500/pt^1.01");}
//MC4--
      if(cutMode == 113) {task->SetDCAtoVertexZ(1.0);}
      if(cutMode == 114) {task->SetDCAtoVertexZ(5.0);}

      if(cutMode == 115) {task->SetClusterReqITS(kFALSE);}
//MC5--
      if(cutMode == 116) {task->SetGeometricalCut(kTRUE,3,120,1.5,0.85,0.7);}
      if(cutMode == 117) {task->SetGeometricalCut(kTRUE,3,140,1.5,0.85,0.7);}

      if(cutMode == 118) {task->SetGeometricalCut(kTRUE,4,130,1.5,0.85,0.7);}
      if(cutMode == 119) {task->SetGeometricalCut(kTRUE,2,130,1.5,0.85,0.7);}

      // event cut varaitions
      if(cutMode == 120) task->SetZvtx(5.);
      if(cutMode == 121) task->SetZvtx(20.);

  // hang task in train

    mgr->AddTask(task);

    AliAnalysisDataContainer* cinput = mgr->GetCommonInputContainer();
    AliAnalysisDataContainer* coutput = mgr->CreateContainer(taskName,
							    TList::Class(),
							    AliAnalysisManager::kOutputContainer,
							    "AnalysisResults.root");

    mgr->ConnectInput(task, 0, cinput);
    mgr->ConnectOutput(task, 1, coutput);

  }

  return mainTask;

}
<commit_msg>PWGLF::AliMultDepSpec:: added option to change mult binning<commit_after>#if defined(__CLING__)
#include "AliMultDepSpecAnalysisTask.h"
#endif

AliMultDepSpecAnalysisTask* AddTask_mkrueger_MultDepSpec(TString controlstring, Int_t cutModeLow = 100, Int_t cutModeHigh = 121)
{

  // settings:
  Bool_t includeCrosscheckHistos = kFALSE;
  Bool_t is2013pA = kFALSE;
  UInt_t offlineTriggerMask = AliVEvent::kINT7;
  Bool_t is2015Data = kFALSE;
  Bool_t isPbPbAnalysis = kFALSE;

  Int_t maxMultiplicity = 100;
  Float_t etaCut = 0.8;
  if(controlstring.Contains("eta03")) etaCut = 0.3;

  Float_t lowerPtCut = 0.15;
  Float_t upperPtCut = 10.;

  string colsys = "pp";

  const Int_t nMultSteps = 3;
  Int_t multSteps[] = {100, 0, 0};
  Int_t multBinWidth[] = {1,1,1};

  Int_t nBinsCent = 1;
  Double_t centBinEdgesDummy[2] = {0., 100.};
  Double_t centBinEdgesUsed[9] = {0., 5., 10., 20., 40., 60., 80., 90., 100.};
  Double_t* centBinEdges = centBinEdgesDummy;

  if(controlstring.Contains("pp")){
    if(controlstring.Contains("performanceHistos")) includeCrosscheckHistos = kTRUE;
    if(controlstring.Contains("5TeV")) is2015Data = kTRUE;
    if(controlstring.Contains("7TeV")) offlineTriggerMask = AliVEvent::kMB;
    if(controlstring.Contains("2TeV")) offlineTriggerMask = AliVEvent::kMB;
    if(controlstring.Contains("09TeV")) offlineTriggerMask = AliVEvent::kMB;
  }
  if(controlstring.Contains("XeXe"))  {
    colsys = "XeXe";
    multSteps[0] = 3500;  multBinWidth[0] = 1;
    multSteps[1] = 0;    multBinWidth[1] = 1;
    multSteps[2] = 0;    multBinWidth[2] = 1;
    nBinsCent = 8;
    centBinEdges = centBinEdgesUsed;
  }
  if(controlstring.Contains("pPb"))  {
    colsys = "pPb";
    multSteps[0] = 200;   multBinWidth[0] = 1;
    multSteps[1] = 0;     multBinWidth[1] = 1;
    multSteps[2] = 0;     multBinWidth[2] = 1;
    is2013pA = kTRUE;
  }
  if(controlstring.Contains("PbPb")) {
    isPbPbAnalysis = kTRUE;
    is2015Data = kTRUE;
    colsys = "PbPb";
    multSteps[0] = 4500;   multBinWidth[0] = 1;
    multSteps[1] = 0;    multBinWidth[1] = 1;
    multSteps[2] = 0;    multBinWidth[2] = 1;
    nBinsCent = 8;
    centBinEdges = centBinEdgesUsed;
    if(controlstring.Contains("2TeV")){offlineTriggerMask = AliVEvent::kMB; is2015Data = kFALSE;}
  }
  if(controlstring.Contains("oldTrigger")){offlineTriggerMask = AliVEvent::kMB;}

  if(controlstring.Contains("largeBins")) {
    multSteps[0] = 450;   multBinWidth[0] = 10;
    multSteps[1] = 0;    multBinWidth[1] = 1;
    multSteps[2] = 0;    multBinWidth[2] = 1;
  }

  // Binning in Multiplicity
  const Int_t nBinsMult = multSteps[0]+ multSteps[1] + multSteps[2] + 1;
  Double_t multBinEdges[nBinsMult+1];
  multBinEdges[0] = -0.5;
  multBinEdges[1] = 0.5;
  Int_t startBin = 1;
  Int_t endBin = 1;
  for(Int_t multStep = 0; multStep < nMultSteps; multStep++){
    endBin += multSteps[multStep];
    for(Int_t multBin = startBin; multBin < endBin; multBin++)  {
      multBinEdges[multBin+1] = multBinEdges[multBin] + multBinWidth[multStep];
    }
    startBin = endBin;
  }

  AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();

  if (!mgr) {
    Error("AddTask_mkrueger_MultDepSpec", "No analysis manager found.");
    return 0;
  }

  // Switch off all AliInfo (too much output!!!)
  AliLog::SetGlobalLogLevel(AliLog::kError);
  mgr->SetDebugLevel(0);

  TString type = mgr->GetInputEventHandler()->GetDataType(); // can be "ESD" or "AOD"
  Bool_t hasMC = (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler() != 0x0);

  if(controlstring.Contains("PbPb") && hasMC) offlineTriggerMask = AliVEvent::kMB;
  if(controlstring.Contains("highMult")){offlineTriggerMask = AliVEvent::kHighMult;}

  AliMultDepSpecAnalysisTask* mainTask = NULL;

  char taskName[100] = "";

  if(controlstring.Contains("logBinsPt")){

    Double_t minPt = 0.1;
    Double_t maxPt = 100.;
    Int_t nbinsPt = 30;

    Double_t logminPt = TMath::Log10(minPt);
    Double_t logmaxPt = TMath::Log10(maxPt);
    Double_t binwidth = (logmaxPt-logminPt)/nbinsPt;
    Double_t* binsPt =  new Double_t[nbinsPt+1];
    binsPt[0] = minPt;
    for (Int_t i = 1; i <= nbinsPt; i++) {
      binsPt[i] = minPt + TMath::Power(10, logminPt + i*binwidth);
    }
  }
  if(controlstring.Contains("noCent")) {
    nBinsCent = 1;
    centBinEdges = centBinEdgesDummy;
  }

  for(Int_t cutMode = cutModeLow; cutMode <= cutModeHigh; cutMode++){
    sprintf(taskName, "mkrueger_%s_eta_%.2f_cutMode_%d", colsys.c_str(), etaCut, cutMode);

    AliMultDepSpecAnalysisTask* task = new AliMultDepSpecAnalysisTask(taskName);

    if(controlstring.Contains("fullPt")){
      upperPtCut = 50;
      lowerPtCut = 0.15;
//      Double_t pTBinEdgesLarge[69] = {0.,0.05,0.1,0.15,0.2,0.25,0.3,0.35,0.4,0.45,0.5,0.55,0.6,0.65,0.7,0.75,0.8,0.85,0.9,0.95,1.0,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,2.0,2.2,2.4,2.6,2.8,3.0,3.2,3.4,3.6,3.8,4.0,4.5,5.0,5.5,6.0,6.5,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,18.0,20.0,22.0,24.0,26.0,28.0,30.0,32.0,34.0,36.0,40.0,45.0,50.0};
//      Double_t pTBinEdgesLarge[54] = {0.,0.05,0.1,0.15,0.2,0.25,0.3,0.35,0.4,0.45,0.5,0.55,0.6,0.65,0.7,0.75,0.8,0.85,0.9,0.95,1.0,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,2.0,2.2,2.4,2.6,2.8,3.0,3.2,3.4,3.6,3.8,4.0,4.5,5.0,5.5,6.0,6.5,7.0,8.0,9.0,10.0,20.0,30.0,40.0,50.0};
      Double_t pTBinEdgesLarge[53] = {0.1,0.15,0.2,0.25,0.3,0.35,0.4,0.45,0.5,0.55,0.6,0.65,0.7,0.75,0.8,0.85,0.9,0.95,1.0,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,2.0,2.2,2.4,2.6,2.8,3.0,3.2,3.4,3.6,3.8,4.0,4.5,5.0,5.5,6.0,6.5,7.0,8.0,9.0,10.0,20.0,30.0,40.0,50.0,60.0};
      task->SetBinsPt(52, pTBinEdgesLarge);
    }

    task->SetIncludeCrosscheckHistos(includeCrosscheckHistos);
    task->Set2013pA(is2013pA);

    // general cuts
    task->SelectCollisionCandidates(offlineTriggerMask);
    task->SetTriggerMask(offlineTriggerMask);

    task->SetUseMC(hasMC);
    if(type.Contains("ESD")) task->SetUseESD();
    else task->SetUseAOD();
    task->SetBinsMult(nBinsMult, multBinEdges);
    task->SetBinsCent(nBinsCent, centBinEdges);

    // nominal cut-setting:
    task->SetMinEta(-etaCut);
    task->SetMaxEta(etaCut);
    task->SetMinPt(lowerPtCut);
    task->SetMaxPt(upperPtCut);

    task->Set2013pA(kFALSE);
    task->Set2015data(is2015Data);

    task->SetMeanXYZv(0.0,0.0,0.0);
    task->SetSigmaMeanXYZv(1.0,1.0,10.0);
    task->SetZvtx(10.);

    // Quality cuts for tracks
    task->SetTPCRefit(kTRUE);
    task->SetITSRefit(kTRUE);
    task->SetKinkDaughters(kFALSE);
    task->SetRatioCrossedRowsOverFindableClustersTPC(0.8);
    task->SetFractionSharedClustersTPC(0.4);
    task->SetMaxchi2perTPCclu(4.);
    task->SetClusterReqITS(kTRUE);
    task->SetMaxchi2perITSclu(36.);
    task->SetDCAtoVertex2D(kFALSE);
    task->SetSigmaToVertex(kFALSE);
    task->SetDCAtoVertexZ(2.0);
    task->SetDCAtoVertexXYPtDep("0.0182+0.0350/pt^1.01");
    task->SetMaxChi2TPCConstrained(36.); // was excluded for some reason?
    task->SetMinLenghtInActiveZoneTPC(0);
    task->SetGeometricalCut(kTRUE,3,130,1.5,0.85,0.7); ///if kTRUE comment CrossedRowsTPC cut
    // task->SetMinCrossedRowsTPC(120);

//MC1--
      if(cutMode == 100) mainTask = task; // has no particular use... just to return task with nominal cut setting in macro

    // cut-variation:
      if(cutMode == 101) {task->SetMaxchi2perITSclu(25.);}
      if(cutMode == 102) {task->SetMaxchi2perITSclu(49.);}

      if(cutMode == 103) {task->SetMaxchi2perTPCclu(3); }
      if(cutMode == 104) {task->SetMaxchi2perTPCclu(5); }
//MC2--
      if(cutMode == 105) {task->SetRatioCrossedRowsOverFindableClustersTPC(0.7);}
      if(cutMode == 106) {task->SetRatioCrossedRowsOverFindableClustersTPC(0.9);}

      if(cutMode == 107) {task->SetFractionSharedClustersTPC(0.2);}
      if(cutMode == 108) {task->SetFractionSharedClustersTPC(1.0);}
//MC3--
      if(cutMode == 109) {task->SetMaxChi2TPCConstrained(25.);}
      if(cutMode == 110) {task->SetMaxChi2TPCConstrained(49.);}

      if(cutMode == 111) {task->SetDCAtoVertexXYPtDep("0.0104+0.0200/pt^1.01");}
      if(cutMode == 112) {task->SetDCAtoVertexXYPtDep("0.0260+0.0500/pt^1.01");}
//MC4--
      if(cutMode == 113) {task->SetDCAtoVertexZ(1.0);}
      if(cutMode == 114) {task->SetDCAtoVertexZ(5.0);}

      if(cutMode == 115) {task->SetClusterReqITS(kFALSE);}
//MC5--
      if(cutMode == 116) {task->SetGeometricalCut(kTRUE,3,120,1.5,0.85,0.7);}
      if(cutMode == 117) {task->SetGeometricalCut(kTRUE,3,140,1.5,0.85,0.7);}

      if(cutMode == 118) {task->SetGeometricalCut(kTRUE,4,130,1.5,0.85,0.7);}
      if(cutMode == 119) {task->SetGeometricalCut(kTRUE,2,130,1.5,0.85,0.7);}

      // event cut varaitions
      if(cutMode == 120) task->SetZvtx(5.);
      if(cutMode == 121) task->SetZvtx(20.);

  // hang task in train

    mgr->AddTask(task);

    AliAnalysisDataContainer* cinput = mgr->GetCommonInputContainer();
    AliAnalysisDataContainer* coutput = mgr->CreateContainer(taskName,
							    TList::Class(),
							    AliAnalysisManager::kOutputContainer,
							    "AnalysisResults.root");

    mgr->ConnectInput(task, 0, cinput);
    mgr->ConnectOutput(task, 1, coutput);

  }

  return mainTask;

}
<|endoftext|>


<commit_before><commit_msg>Added dumping of MirroredX & MirroredY properties<commit_after><|endoftext|>


<commit_before>// ======================================================================== //
// Copyright 2009-2016 Intel Corporation                                    //
//                                                                          //
// 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.                                           //
// ======================================================================== //

// own
#include "Importer.h"
// ospcommon
#include "common/FileName.h"
// tinyxml
#include "TinyXML2.h"
// std
#include <stdexcept>
#include <libgen.h>

namespace ospray {
  namespace importer {

    void importVolumeRAW(const FileName &fileName, Volume *volume);
    void importVolumeRM(const FileName &fileName, Volume *volume);

    void importVolume(const FileName &fileName, Volume *volume)
    {
      const std::string ext = fileName.ext();
      if (ext == "raw" || ext == "gz") {
        importVolumeRAW(fileName, volume);
      } else if (ext == "bob") {
        importVolumeRM(fileName, volume);
      } else {
        throw std::runtime_error("unknown volume format '"+ext+"'");
      }

      // post-checks
      assert(volume->handle != nullptr);
      assert(!volume->bounds.empty());
    }

    vec2i parseInt2(const tinyxml2::XMLNode *node)
    {
      vec2i v;
      int rc = sscanf(node->ToElement()->GetText(),"%i %i",&v.x,&v.y);
      (void)rc;
      assert(rc == 2);
      return v;
    }
    vec3i parseInt3(const tinyxml2::XMLNode *node)
    {
      vec3i v;
      int rc = sscanf(node->ToElement()->GetText(),"%i %i %i",&v.x,&v.y,&v.z);
      (void)rc;
      assert(rc == 3);
      return v;
    }

    float parseFloat1(const tinyxml2::XMLNode *node)
    {
      float v;
      int rc = sscanf(node->ToElement()->GetText(),"%f",&v);
      (void)rc;
      assert(rc == 1);
      return v;
    }
    vec2f parseFloat2(const tinyxml2::XMLNode *node)
    {
      vec2f v;
      int rc = sscanf(node->ToElement()->GetText(),"%f %f",&v.x,&v.y);
      (void)rc;
      assert(rc == 2);
      return v;
    }
    vec3f parseFloat3(const tinyxml2::XMLNode *node)
    {
      vec3f v;
      int rc = sscanf(node->ToElement()->GetText(),"%f %f %f",&v.x,&v.y,&v.z);
      (void)rc;
      assert(rc == 3);
      return v;
    }

    void importVolume(const FileName &orgFileName,
                      Group *group,
                      const tinyxml2::XMLNode *root)
    {
      const char *dpFromEnv = getenv("OSPRAY_DATA_PARALLEL");

      Volume *volume = new Volume;
      if (dpFromEnv) {
        // Create the OSPRay object.
        osp::vec3i blockDims;
        int rc = sscanf(dpFromEnv, "%dx%dx%d",
                        &blockDims.x, &blockDims.y, &blockDims.z);
        if (rc != 3) {
          throw std::runtime_error("could not parse OSPRAY_DATA_PARALLEL "
                                   "env-var. Must be of format <X>x<Y>x<>Z "
                                   "(e.g., '4x4x4'");
        }
        volume->handle = ospNewVolume("data_distributed_volume");
        if (volume->handle == nullptr) {
          throw std::runtime_error("#loaders.ospObjectFile: could not create "
                                   "volume ...");
        }
        ospSetVec3i(volume->handle,"num_dp_blocks",blockDims);
      } else {
        // Create the OSPRay object.
        volume->handle = ospNewVolume("block_bricked_volume");
      }

      if (volume->handle == nullptr) {
        throw std::runtime_error("#loaders.ospObjectFile: could not create "
                                 "volume ...");
      }

      // Temporary storage for the file name attribute if specified.
      const char *volumeFilename = nullptr;

      // Iterate over object attributes.
      for (const tinyxml2::XMLNode *node = root->FirstChild();
           node;
           node = node->NextSibling()) {

        // Volume size in voxels per dimension.
        if (!strcmp(node->ToElement()->Name(), "dimensions"))
          { volume->dimensions = parseInt3(node);  continue; }

        // File containing a volume specification and / or voxel data.
        if (!strcmp(node->ToElement()->Name(), "filename"))
          { volumeFilename = node->ToElement()->GetText();  continue; }

        // Grid origin in world coordinates.
        if (!strcmp(node->ToElement()->Name(), "gridOrigin"))
          { volume->gridOrigin = parseFloat3(node);  continue; }

        // Grid spacing in each dimension in world coordinates.
        if (!strcmp(node->ToElement()->Name(), "gridSpacing"))
          { volume->gridSpacing = parseFloat3(node);  continue; }

        // Sampling rate for ray casting based renderers.
        if (!strcmp(node->ToElement()->Name(), "samplingRate"))
          { volume->samplingRate = parseFloat1(node);  continue; }

        // Subvolume offset from origin within the full volume.
        if (!strcmp(node->ToElement()->Name(), "subvolumeOffsets"))
          { volume->subVolumeOffsets = parseInt3(node);  continue; }

        // Subvolume dimensions within the full volume.
        if (!strcmp(node->ToElement()->Name(), "subvolumeDimensions"))
          { volume->subVolumeDimensions = parseInt3(node);  continue; }

        // Subvolume steps in each dimension; can be used to subsample.
        if (!strcmp(node->ToElement()->Name(), "subvolumeSteps"))
          { volume->subVolumeSteps = parseInt3(node);  continue; }

        // Voxel value range.
        if (!strcmp(node->ToElement()->Name(), "voxelRange"))
          { volume->voxelRange = parseFloat2(node);  continue; }

        // Voxel type string.
        if (!strcmp(node->ToElement()->Name(), "voxelType"))
          { volume->voxelType = node->ToElement()->GetText();  continue; }

        // Error check.
        exitOnCondition(true, "unrecognized XML element type '" +
                        std::string(node->ToElement()->Name()) + "'");
      }

      // Load the contents of the volume file if specified.
      if (volumeFilename != nullptr) {

        // Some implementations of 'dirname()' are destructive.
        char *duplicateFilename = strdup(orgFileName.str().c_str());

        // The volume file path is absolute.
        if (volumeFilename[0] == '/')
          importVolume(volumeFilename, volume);
        else {
          importVolume((std::string(dirname(duplicateFilename))
                        + "/" + volumeFilename).c_str(), volume);
        }

        // Free the temporary character array.
        if (duplicateFilename != nullptr)
          free(duplicateFilename);
      }

      group->volume.push_back(volume);
    }

    void importTriangleMesh(Group *group, const tinyxml2::XMLNode *node)
    {
      throw std::runtime_error("importTriangleMesh: not yet implemented");
    }

    void importLight(Group *group, const tinyxml2::XMLNode *node)
    {
      throw std::runtime_error("importLight: not yet implemented");
    }

    void importObject(const FileName &orgFileName,
                      Group *group,
                      const tinyxml2::XMLNode *node)
    {
      // OSPRay light object.
      if (!strcmp(node->ToElement()->Name(), "light"))
        importLight(group,node);

      // OSPRay triangle mesh object.
      else if (!strcmp(node->ToElement()->Name(), "triangleMesh"))
        importTriangleMesh(group,node);

      // OSPRay volume object.
      else if (!strcmp(node->ToElement()->Name(), "volume"))
        importVolume(orgFileName,group,node);

      // No other object types are currently supported.
      else
        exitOnCondition(true, "unrecognized XML element type '"
                        + std::string(node->ToElement()->Name()) + "'");
    }

    void importOSP(const FileName &fileName, Group *existingGroupToAddTo)
    {
      // The XML document container.
      tinyxml2::XMLDocument xml(true, tinyxml2::COLLAPSE_WHITESPACE);

      // Read the XML object file.
      exitOnCondition(xml.LoadFile(fileName.str().c_str()) != tinyxml2::XML_SUCCESS,
                      "unable to read object file '" + fileName.str() + "'");

      Group *group = existingGroupToAddTo ? existingGroupToAddTo : new Group;

      // Iterate over the object entries, skip the XML declaration and comments.
      for (const tinyxml2::XMLNode *node = xml.FirstChild();
           node;
           node = node->NextSibling()) {
        if (node->ToElement())
          importObject(fileName,group,node);
      }

      // post-checks:
      for (size_t i = 0; i < group->volume.size(); i++) {
        assert(group->volume[i]->handle != nullptr);
        assert(!group->volume[i]->bounds.empty());
      }
    }
  }
}
<commit_msg>Correctly set the gridOrigin and gridSpacing XML params<commit_after>// ======================================================================== //
// Copyright 2009-2016 Intel Corporation                                    //
//                                                                          //
// 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.                                           //
// ======================================================================== //

// own
#include "Importer.h"
// ospcommon
#include "common/FileName.h"
// tinyxml
#include "TinyXML2.h"
// std
#include <stdexcept>
#include <libgen.h>

namespace ospray {
  namespace importer {

    void importVolumeRAW(const FileName &fileName, Volume *volume);
    void importVolumeRM(const FileName &fileName, Volume *volume);

    void importVolume(const FileName &fileName, Volume *volume)
    {
      const std::string ext = fileName.ext();
      if (ext == "raw" || ext == "gz") {
        importVolumeRAW(fileName, volume);
      } else if (ext == "bob") {
        importVolumeRM(fileName, volume);
      } else {
        throw std::runtime_error("unknown volume format '"+ext+"'");
      }

      // post-checks
      assert(volume->handle != nullptr);
      assert(!volume->bounds.empty());
    }

    vec2i parseInt2(const tinyxml2::XMLNode *node)
    {
      vec2i v;
      int rc = sscanf(node->ToElement()->GetText(),"%i %i",&v.x,&v.y);
      (void)rc;
      assert(rc == 2);
      return v;
    }
    vec3i parseInt3(const tinyxml2::XMLNode *node)
    {
      vec3i v;
      int rc = sscanf(node->ToElement()->GetText(),"%i %i %i",&v.x,&v.y,&v.z);
      (void)rc;
      assert(rc == 3);
      return v;
    }

    float parseFloat1(const tinyxml2::XMLNode *node)
    {
      float v;
      int rc = sscanf(node->ToElement()->GetText(),"%f",&v);
      (void)rc;
      assert(rc == 1);
      return v;
    }
    vec2f parseFloat2(const tinyxml2::XMLNode *node)
    {
      vec2f v;
      int rc = sscanf(node->ToElement()->GetText(),"%f %f",&v.x,&v.y);
      (void)rc;
      assert(rc == 2);
      return v;
    }
    vec3f parseFloat3(const tinyxml2::XMLNode *node)
    {
      vec3f v;
      int rc = sscanf(node->ToElement()->GetText(),"%f %f %f",&v.x,&v.y,&v.z);
      (void)rc;
      assert(rc == 3);
      return v;
    }

    void importVolume(const FileName &orgFileName,
                      Group *group,
                      const tinyxml2::XMLNode *root)
    {
      const char *dpFromEnv = getenv("OSPRAY_DATA_PARALLEL");

      Volume *volume = new Volume;
      if (dpFromEnv) {
        // Create the OSPRay object.
        osp::vec3i blockDims;
        int rc = sscanf(dpFromEnv, "%dx%dx%d",
                        &blockDims.x, &blockDims.y, &blockDims.z);
        if (rc != 3) {
          throw std::runtime_error("could not parse OSPRAY_DATA_PARALLEL "
                                   "env-var. Must be of format <X>x<Y>x<>Z "
                                   "(e.g., '4x4x4'");
        }
        volume->handle = ospNewVolume("data_distributed_volume");
        if (volume->handle == nullptr) {
          throw std::runtime_error("#loaders.ospObjectFile: could not create "
                                   "volume ...");
        }
        ospSetVec3i(volume->handle,"num_dp_blocks",blockDims);
      } else {
        // Create the OSPRay object.
        volume->handle = ospNewVolume("block_bricked_volume");
      }

      if (volume->handle == nullptr) {
        throw std::runtime_error("#loaders.ospObjectFile: could not create "
                                 "volume ...");
      }

      // Temporary storage for the file name attribute if specified.
      const char *volumeFilename = nullptr;

      // Iterate over object attributes.
      for (const tinyxml2::XMLNode *node = root->FirstChild();
           node;
           node = node->NextSibling()) {

        // Volume size in voxels per dimension.
        if (!strcmp(node->ToElement()->Name(), "dimensions")) {
          volume->dimensions = parseInt3(node);
          continue;
        }

        // File containing a volume specification and / or voxel data.
        if (!strcmp(node->ToElement()->Name(), "filename")) {
          volumeFilename = node->ToElement()->GetText();
          continue;
        }

        // Grid origin in world coordinates.
        if (!strcmp(node->ToElement()->Name(), "gridOrigin")) {
          volume->gridOrigin = parseFloat3(node);
          ospSetVec3f(volume->handle, "gridOrigin", (osp::vec3f&)volume->gridOrigin);
          continue;
        }

        // Grid spacing in each dimension in world coordinates.
        if (!strcmp(node->ToElement()->Name(), "gridSpacing")) {
          volume->gridSpacing = parseFloat3(node);
          ospSetVec3f(volume->handle, "gridSpacing", (osp::vec3f&)volume->gridSpacing);
          continue;
        }

        // Sampling rate for ray casting based renderers.
        if (!strcmp(node->ToElement()->Name(), "samplingRate")) {
          volume->samplingRate = parseFloat1(node);
          ospSet1f(volume->handle, "samplingRate", volume->samplingRate);
          continue;
        }

        // Subvolume offset from origin within the full volume.
        if (!strcmp(node->ToElement()->Name(), "subvolumeOffsets")) {
          volume->subVolumeOffsets = parseInt3(node);
          continue;
        }

        // Subvolume dimensions within the full volume.
        if (!strcmp(node->ToElement()->Name(), "subvolumeDimensions")) {
          volume->subVolumeDimensions = parseInt3(node);
          continue;
        }

        // Subvolume steps in each dimension; can be used to subsample.
        if (!strcmp(node->ToElement()->Name(), "subvolumeSteps")) {
          volume->subVolumeSteps = parseInt3(node);
          continue;
        }

        // Voxel value range.
        if (!strcmp(node->ToElement()->Name(), "voxelRange")) {
          volume->voxelRange = parseFloat2(node);
          continue;
        }

        // Voxel type string.
        if (!strcmp(node->ToElement()->Name(), "voxelType")) {
          volume->voxelType = node->ToElement()->GetText();
          continue;
        }

        // Error check.
        exitOnCondition(true, "unrecognized XML element type '" +
                        std::string(node->ToElement()->Name()) + "'");
      }

      // Load the contents of the volume file if specified.
      if (volumeFilename != nullptr) {

        // Some implementations of 'dirname()' are destructive.
        char *duplicateFilename = strdup(orgFileName.str().c_str());

        // The volume file path is absolute.
        if (volumeFilename[0] == '/')
          importVolume(volumeFilename, volume);
        else {
          importVolume((std::string(dirname(duplicateFilename))
                        + "/" + volumeFilename).c_str(), volume);
        }

        // Free the temporary character array.
        if (duplicateFilename != nullptr)
          free(duplicateFilename);
      }

      group->volume.push_back(volume);
    }

    void importTriangleMesh(Group *group, const tinyxml2::XMLNode *node)
    {
      throw std::runtime_error("importTriangleMesh: not yet implemented");
    }

    void importLight(Group *group, const tinyxml2::XMLNode *node)
    {
      throw std::runtime_error("importLight: not yet implemented");
    }

    void importObject(const FileName &orgFileName,
                      Group *group,
                      const tinyxml2::XMLNode *node)
    {
      // OSPRay light object.
      if (!strcmp(node->ToElement()->Name(), "light"))
        importLight(group,node);

      // OSPRay triangle mesh object.
      else if (!strcmp(node->ToElement()->Name(), "triangleMesh"))
        importTriangleMesh(group,node);

      // OSPRay volume object.
      else if (!strcmp(node->ToElement()->Name(), "volume"))
        importVolume(orgFileName,group,node);

      // No other object types are currently supported.
      else
        exitOnCondition(true, "unrecognized XML element type '"
                        + std::string(node->ToElement()->Name()) + "'");
    }

    void importOSP(const FileName &fileName, Group *existingGroupToAddTo)
    {
      // The XML document container.
      tinyxml2::XMLDocument xml(true, tinyxml2::COLLAPSE_WHITESPACE);

      // Read the XML object file.
      exitOnCondition(xml.LoadFile(fileName.str().c_str()) != tinyxml2::XML_SUCCESS,
                      "unable to read object file '" + fileName.str() + "'");

      Group *group = existingGroupToAddTo ? existingGroupToAddTo : new Group;

      // Iterate over the object entries, skip the XML declaration and comments.
      for (const tinyxml2::XMLNode *node = xml.FirstChild();
           node;
           node = node->NextSibling()) {
        if (node->ToElement())
          importObject(fileName,group,node);
      }

      // post-checks:
      for (size_t i = 0; i < group->volume.size(); i++) {
        assert(group->volume[i]->handle != nullptr);
        assert(!group->volume[i]->bounds.empty());
      }
    }
  }
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2004-2006 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Kevin Lim
 */

#include "base/intmath.hh"
#include "cpu/pred/tournament.hh"

TournamentBP::TournamentBP(unsigned _localPredictorSize,
                           unsigned _localCtrBits,
                           unsigned _localHistoryTableSize,
                           unsigned _localHistoryBits,
                           unsigned _globalPredictorSize,
                           unsigned _globalCtrBits,
                           unsigned _globalHistoryBits,
                           unsigned _choicePredictorSize,
                           unsigned _choiceCtrBits,
                           unsigned _instShiftAmt)
    : localPredictorSize(_localPredictorSize),
      localCtrBits(_localCtrBits),
      localHistoryTableSize(_localHistoryTableSize),
      localHistoryBits(_localHistoryBits),
      globalPredictorSize(_globalPredictorSize),
      globalCtrBits(_globalCtrBits),
      globalHistoryBits(_globalHistoryBits),
      choicePredictorSize(_globalPredictorSize),
      choiceCtrBits(_choiceCtrBits),
      instShiftAmt(_instShiftAmt)
{
    if (!isPowerOf2(localPredictorSize)) {
        fatal("Invalid local predictor size!\n");
    }

    //Setup the array of counters for the local predictor
    localCtrs.resize(localPredictorSize);

    for (int i = 0; i < localPredictorSize; ++i)
        localCtrs[i].setBits(localCtrBits);

    localPredictorMask = floorPow2(localPredictorSize) - 1;

    if (!isPowerOf2(localHistoryTableSize)) {
        fatal("Invalid local history table size!\n");
    }

    //Setup the history table for the local table
    localHistoryTable.resize(localHistoryTableSize);

    for (int i = 0; i < localHistoryTableSize; ++i)
        localHistoryTable[i] = 0;

    // Setup the local history mask
    localHistoryMask = (1 << localHistoryBits) - 1;

    if (!isPowerOf2(globalPredictorSize)) {
        fatal("Invalid global predictor size!\n");
    }

    //Setup the array of counters for the global predictor
    globalCtrs.resize(globalPredictorSize);

    for (int i = 0; i < globalPredictorSize; ++i)
        globalCtrs[i].setBits(globalCtrBits);

    //Clear the global history
    globalHistory = 0;
    // Setup the global history mask
    globalHistoryMask = (1 << globalHistoryBits) - 1;

    if (!isPowerOf2(choicePredictorSize)) {
        fatal("Invalid choice predictor size!\n");
    }

    //Setup the array of counters for the choice predictor
    choiceCtrs.resize(choicePredictorSize);

    for (int i = 0; i < choicePredictorSize; ++i)
        choiceCtrs[i].setBits(choiceCtrBits);

    // @todo: Allow for different thresholds between the predictors.
    threshold = (1 << (localCtrBits - 1)) - 1;
}

inline
unsigned
TournamentBP::calcLocHistIdx(Addr &branch_addr)
{
    // Get low order bits after removing instruction offset.
    return (branch_addr >> instShiftAmt) & (localHistoryTableSize - 1);
}

inline
void
TournamentBP::updateGlobalHistTaken()
{
    globalHistory = (globalHistory << 1) | 1;
    globalHistory = globalHistory & globalHistoryMask;
}

inline
void
TournamentBP::updateGlobalHistNotTaken()
{
    globalHistory = (globalHistory << 1);
    globalHistory = globalHistory & globalHistoryMask;
}

inline
void
TournamentBP::updateLocalHistTaken(unsigned local_history_idx)
{
    localHistoryTable[local_history_idx] =
        (localHistoryTable[local_history_idx] << 1) | 1;
}

inline
void
TournamentBP::updateLocalHistNotTaken(unsigned local_history_idx)
{
    localHistoryTable[local_history_idx] =
        (localHistoryTable[local_history_idx] << 1);
}

bool
TournamentBP::lookup(Addr &branch_addr, void * &bp_history)
{
    bool local_prediction;
    unsigned local_history_idx;
    unsigned local_predictor_idx;

    bool global_prediction;
    bool choice_prediction;

    //Lookup in the local predictor to get its branch prediction
    local_history_idx = calcLocHistIdx(branch_addr);
    local_predictor_idx = localHistoryTable[local_history_idx]
        & localPredictorMask;
    local_prediction = localCtrs[local_predictor_idx].read() > threshold;

    //Lookup in the global predictor to get its branch prediction
    global_prediction = globalCtrs[globalHistory].read() > threshold;

    //Lookup in the choice predictor to see which one to use
    choice_prediction = choiceCtrs[globalHistory].read() > threshold;

    // Create BPHistory and pass it back to be recorded.
    BPHistory *history = new BPHistory;
    history->globalHistory = globalHistory;
    history->localPredTaken = local_prediction;
    history->globalPredTaken = global_prediction;
    history->globalUsed = choice_prediction;
    bp_history = (void *)history;

    assert(globalHistory < globalPredictorSize &&
           local_history_idx < localHistoryTableSize &&
           local_predictor_idx < localPredictorSize);

    // Commented code is for doing speculative update of counters and
    // all histories.
    if (choice_prediction) {
        if (global_prediction) {
//            updateHistoriesTaken(local_history_idx);
//            globalCtrs[globalHistory].increment();
//            localCtrs[local_history_idx].increment();
            updateGlobalHistTaken();
            return true;
        } else {
//            updateHistoriesNotTaken(local_history_idx);
//            globalCtrs[globalHistory].decrement();
//            localCtrs[local_history_idx].decrement();
            updateGlobalHistNotTaken();
            return false;
        }
    } else {
        if (local_prediction) {
//            updateHistoriesTaken(local_history_idx);
//            globalCtrs[globalHistory].increment();
//            localCtrs[local_history_idx].increment();
            updateGlobalHistTaken();
            return true;
        } else {
//            updateHistoriesNotTaken(local_history_idx);
//            globalCtrs[globalHistory].decrement();
//            localCtrs[local_history_idx].decrement();
            updateGlobalHistNotTaken();
            return false;
        }
    }
}

void
TournamentBP::uncondBr(void * &bp_history)
{
    // Create BPHistory and pass it back to be recorded.
    BPHistory *history = new BPHistory;
    history->globalHistory = globalHistory;
    history->localPredTaken = true;
    history->globalPredTaken = true;
    bp_history = static_cast<void *>(history);

    updateGlobalHistTaken();
}

void
TournamentBP::update(Addr &branch_addr, bool taken, void *bp_history)
{
    unsigned local_history_idx;
    unsigned local_predictor_idx;
    unsigned local_predictor_hist;

    // Get the local predictor's current prediction
    local_history_idx = calcLocHistIdx(branch_addr);
    local_predictor_hist = localHistoryTable[local_history_idx];
    local_predictor_idx = local_predictor_hist & localPredictorMask;

    // Update the choice predictor to tell it which one was correct if
    // there was a prediction.
    if (bp_history) {
        BPHistory *history = static_cast<BPHistory *>(bp_history);
        if (history->localPredTaken != history->globalPredTaken) {
            // If the local prediction matches the actual outcome,
            // decerement the counter.  Otherwise increment the
            // counter.
            if (history->localPredTaken == taken) {
                choiceCtrs[globalHistory].decrement();
            } else if (history->globalPredTaken == taken){
                choiceCtrs[globalHistory].increment();
            }
        }

        // We're done with this history, now delete it.
        delete history;
    }

    assert(globalHistory < globalPredictorSize &&
           local_history_idx < localHistoryTableSize &&
           local_predictor_idx < localPredictorSize);

    // Update the counters and local history with the proper
    // resolution of the branch.  Global history is updated
    // speculatively and restored upon squash() calls, so it does not
    // need to be updated.
    if (taken) {
        localCtrs[local_predictor_idx].increment();
        globalCtrs[globalHistory].increment();

        updateLocalHistTaken(local_history_idx);
    } else {
        localCtrs[local_predictor_idx].decrement();
        globalCtrs[globalHistory].decrement();

        updateLocalHistNotTaken(local_history_idx);
    }
}

void
TournamentBP::squash(void *bp_history)
{
    BPHistory *history = static_cast<BPHistory *>(bp_history);

    // Restore global history to state prior to this branch.
    globalHistory = history->globalHistory;

    // Delete this BPHistory now that we're done with it.
    delete history;
}

#ifdef DEBUG
int
TournamentBP::BPHistory::newCount = 0;
#endif
<commit_msg>Branch predictor: Fixes the tournament branch predictor.<commit_after>/*
 * Copyright (c) 2004-2006 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Kevin Lim
 */

#include "base/intmath.hh"
#include "cpu/pred/tournament.hh"

TournamentBP::TournamentBP(unsigned _localPredictorSize,
                           unsigned _localCtrBits,
                           unsigned _localHistoryTableSize,
                           unsigned _localHistoryBits,
                           unsigned _globalPredictorSize,
                           unsigned _globalHistoryBits,
                           unsigned _globalCtrBits,
                           unsigned _choicePredictorSize,
                           unsigned _choiceCtrBits,
                           unsigned _instShiftAmt)
    : localPredictorSize(_localPredictorSize),
      localCtrBits(_localCtrBits),
      localHistoryTableSize(_localHistoryTableSize),
      localHistoryBits(_localHistoryBits),
      globalPredictorSize(_globalPredictorSize),
      globalCtrBits(_globalCtrBits),
      globalHistoryBits(_globalHistoryBits),
      choicePredictorSize(_globalPredictorSize),
      choiceCtrBits(_choiceCtrBits),
      instShiftAmt(_instShiftAmt)
{
    if (!isPowerOf2(localPredictorSize)) {
        fatal("Invalid local predictor size!\n");
    }

    //Setup the array of counters for the local predictor
    localCtrs.resize(localPredictorSize);

    for (int i = 0; i < localPredictorSize; ++i)
        localCtrs[i].setBits(localCtrBits);

    localPredictorMask = floorPow2(localPredictorSize) - 1;

    if (!isPowerOf2(localHistoryTableSize)) {
        fatal("Invalid local history table size!\n");
    }

    //Setup the history table for the local table
    localHistoryTable.resize(localHistoryTableSize);

    for (int i = 0; i < localHistoryTableSize; ++i)
        localHistoryTable[i] = 0;

    // Setup the local history mask
    localHistoryMask = (1 << localHistoryBits) - 1;

    if (!isPowerOf2(globalPredictorSize)) {
        fatal("Invalid global predictor size!\n");
    }

    //Setup the array of counters for the global predictor
    globalCtrs.resize(globalPredictorSize);

    for (int i = 0; i < globalPredictorSize; ++i)
        globalCtrs[i].setBits(globalCtrBits);

    //Clear the global history
    globalHistory = 0;
    // Setup the global history mask
    globalHistoryMask = (1 << globalHistoryBits) - 1;

    if (!isPowerOf2(choicePredictorSize)) {
        fatal("Invalid choice predictor size!\n");
    }

    //Setup the array of counters for the choice predictor
    choiceCtrs.resize(choicePredictorSize);

    for (int i = 0; i < choicePredictorSize; ++i)
        choiceCtrs[i].setBits(choiceCtrBits);

    // @todo: Allow for different thresholds between the predictors.
    threshold = (1 << (localCtrBits - 1)) - 1;
}

inline
unsigned
TournamentBP::calcLocHistIdx(Addr &branch_addr)
{
    // Get low order bits after removing instruction offset.
    return (branch_addr >> instShiftAmt) & (localHistoryTableSize - 1);
}

inline
void
TournamentBP::updateGlobalHistTaken()
{
    globalHistory = (globalHistory << 1) | 1;
    globalHistory = globalHistory & globalHistoryMask;
}

inline
void
TournamentBP::updateGlobalHistNotTaken()
{
    globalHistory = (globalHistory << 1);
    globalHistory = globalHistory & globalHistoryMask;
}

inline
void
TournamentBP::updateLocalHistTaken(unsigned local_history_idx)
{
    localHistoryTable[local_history_idx] =
        (localHistoryTable[local_history_idx] << 1) | 1;
}

inline
void
TournamentBP::updateLocalHistNotTaken(unsigned local_history_idx)
{
    localHistoryTable[local_history_idx] =
        (localHistoryTable[local_history_idx] << 1);
}

bool
TournamentBP::lookup(Addr &branch_addr, void * &bp_history)
{
    bool local_prediction;
    unsigned local_history_idx;
    unsigned local_predictor_idx;

    bool global_prediction;
    bool choice_prediction;

    //Lookup in the local predictor to get its branch prediction
    local_history_idx = calcLocHistIdx(branch_addr);
    local_predictor_idx = localHistoryTable[local_history_idx]
        & localPredictorMask;
    local_prediction = localCtrs[local_predictor_idx].read() > threshold;

    //Lookup in the global predictor to get its branch prediction
    global_prediction = globalCtrs[globalHistory].read() > threshold;

    //Lookup in the choice predictor to see which one to use
    choice_prediction = choiceCtrs[globalHistory].read() > threshold;

    // Create BPHistory and pass it back to be recorded.
    BPHistory *history = new BPHistory;
    history->globalHistory = globalHistory;
    history->localPredTaken = local_prediction;
    history->globalPredTaken = global_prediction;
    history->globalUsed = choice_prediction;
    bp_history = (void *)history;

    assert(globalHistory < globalPredictorSize &&
           local_history_idx < localHistoryTableSize &&
           local_predictor_idx < localPredictorSize);

    // Commented code is for doing speculative update of counters and
    // all histories.
    if (choice_prediction) {
        if (global_prediction) {
//            updateHistoriesTaken(local_history_idx);
//            globalCtrs[globalHistory].increment();
//            localCtrs[local_history_idx].increment();
            updateGlobalHistTaken();
            return true;
        } else {
//            updateHistoriesNotTaken(local_history_idx);
//            globalCtrs[globalHistory].decrement();
//            localCtrs[local_history_idx].decrement();
            updateGlobalHistNotTaken();
            return false;
        }
    } else {
        if (local_prediction) {
//            updateHistoriesTaken(local_history_idx);
//            globalCtrs[globalHistory].increment();
//            localCtrs[local_history_idx].increment();
            updateGlobalHistTaken();
            return true;
        } else {
//            updateHistoriesNotTaken(local_history_idx);
//            globalCtrs[globalHistory].decrement();
//            localCtrs[local_history_idx].decrement();
            updateGlobalHistNotTaken();
            return false;
        }
    }
}

void
TournamentBP::uncondBr(void * &bp_history)
{
    // Create BPHistory and pass it back to be recorded.
    BPHistory *history = new BPHistory;
    history->globalHistory = globalHistory;
    history->localPredTaken = true;
    history->globalPredTaken = true;
    bp_history = static_cast<void *>(history);

    updateGlobalHistTaken();
}

void
TournamentBP::update(Addr &branch_addr, bool taken, void *bp_history)
{
    unsigned local_history_idx;
    unsigned local_predictor_idx;
    unsigned local_predictor_hist;

    // Get the local predictor's current prediction
    local_history_idx = calcLocHistIdx(branch_addr);
    local_predictor_hist = localHistoryTable[local_history_idx];
    local_predictor_idx = local_predictor_hist & localPredictorMask;

    // Update the choice predictor to tell it which one was correct if
    // there was a prediction.
    if (bp_history) {
        BPHistory *history = static_cast<BPHistory *>(bp_history);
        if (history->localPredTaken != history->globalPredTaken) {
            // If the local prediction matches the actual outcome,
            // decerement the counter.  Otherwise increment the
            // counter.
            if (history->localPredTaken == taken) {
                choiceCtrs[history->globalHistory].decrement();
            } else if (history->globalPredTaken == taken){
                choiceCtrs[history->globalHistory].increment();
            }

        }

        // Update the counters and local history with the proper
        // resolution of the branch.  Global history is updated
        // speculatively and restored upon squash() calls, so it does not
        // need to be updated.
        if (taken) {
               localCtrs[local_predictor_idx].increment();
               globalCtrs[history->globalHistory].increment();

               updateLocalHistTaken(local_history_idx);
        } else {
               localCtrs[local_predictor_idx].decrement();
               globalCtrs[history->globalHistory].decrement();

               updateLocalHistNotTaken(local_history_idx);
       }

       bool mispredict = false;

       //global predictor used and mispredicted
       if (history->globalUsed && history->globalPredTaken != taken)
           mispredict = true;
       //local predictor used and mispredicted
       else if (!history->globalUsed && history->localPredTaken != taken)
           mispredict = true;

       if (mispredict) {
           if (taken) {
              globalHistory = globalHistory | 1;
           } else {
              unsigned mask = globalHistoryMask - 1;
              globalHistory = globalHistory & mask;
           }

        }
        // We're done with this history, now delete it.
        delete history;
    }

    assert(globalHistory < globalPredictorSize &&
           local_history_idx < localHistoryTableSize &&
           local_predictor_idx < localPredictorSize);

}

void
TournamentBP::squash(void *bp_history)
{
    BPHistory *history = static_cast<BPHistory *>(bp_history);

    // Restore global history to state prior to this branch.
    globalHistory = history->globalHistory;

    // Delete this BPHistory now that we're done with it.
    delete history;
}

#ifdef DEBUG
int
TournamentBP::BPHistory::newCount = 0;
#endif
<|endoftext|>


<commit_before>class ExitCounter{
    public:
        static int get();
        static int dec();
    private:
        // If fastforwarding is turned of the count
        // needs to be manually changed to 0 here.
        ExitCounter(){ count=1; };
        static ExitCounter * instance;
        int count;

};
<commit_msg>To run without fast forwarding global_exit_count needs to start at 0<commit_after>class ExitCounter{
    public:
        static int get();
        static int dec();
    private:
        // If fastforwarding is turned of the count
        // needs to be manually changed to 0 here.
        ExitCounter(){ count=0; };
        static ExitCounter * instance;
        int count;

};
<|endoftext|>