// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void MoveData::dataCheck()
{
  setErrorCondition(0);
  DataArrayPath amSrcPath = getAttributeMatrixSource();
  DataArrayPath amDestPath = getAttributeMatrixDestination();
  DataArrayPath daSrcPath = getDataArraySource();

  if (getWhatToMove() == k_MoveAttributeMatrix)
  {
    DataContainer::Pointer amDestDataContainer = getDataContainerArray()->getPrereqDataContainer<AbstractFilter>(this, getDataContainerDestination());
    DataContainer::Pointer amSrcDataContainer = getDataContainerArray()->getPrereqDataContainer<AbstractFilter>(this, amSrcPath.getDataContainerName());
    AttributeMatrix::Pointer amSrcAttributeMatrix = getDataContainerArray()->getPrereqAttributeMatrixFromPath<AbstractFilter>(this, amSrcPath, -301);

    if(getErrorCondition() < 0) { return; }

    if (amSrcDataContainer->getName() == amDestDataContainer->getName())
    {
      QString ss = QObject::tr("The source and destination Data Container are the same.  Is this what you meant to do?");
      notifyWarningMessage(getHumanLabel(), ss, getErrorCondition());
      return;
    }

    amDestDataContainer->addAttributeMatrix(amSrcAttributeMatrix->getName(), amSrcAttributeMatrix);
    amSrcDataContainer->removeAttributeMatrix(amSrcAttributeMatrix->getName());
  }
  else if (getWhatToMove() == k_MoveDataArray )
  {
    AttributeMatrix::Pointer daSrcAttributeMatrix = getDataContainerArray()->getPrereqAttributeMatrixFromPath<AbstractFilter>(this, daSrcPath, -301);
    AttributeMatrix::Pointer daDestAttributeMatrix = getDataContainerArray()->getPrereqAttributeMatrixFromPath<AbstractFilter>(this, amDestPath, -301);
    IDataArray::Pointer daSrcDataArray = getDataContainerArray()->getPrereqIDataArrayFromPath<IDataArray, AbstractFilter>(this, daSrcPath);

    if(getErrorCondition() < 0) { return; }

    if (daDestAttributeMatrix->getNumTuples() != daSrcDataArray->getNumberOfTuples())
    {
      setErrorCondition(-11019);
      QString ss = QObject::tr("The number of tuples of source Attribute Array (%1) and destination Attribute Matrix (%2) do not match").arg(daSrcDataArray->getNumberOfTuples()).arg(daDestAttributeMatrix->getNumTuples());
      notifyErrorMessage(getHumanLabel(), ss, getErrorCondition());
      return;
    }
    else if (amSrcPath == amDestPath)
    {
      QString ss = QObject::tr("The source and destination Attribute Matrix are the same.  Is this what you meant to do?");
      notifyWarningMessage(getHumanLabel(), ss, getErrorCondition());
      return;
    }

    daDestAttributeMatrix->addAttributeArray(daSrcPath.getDataArrayName(), daSrcDataArray);
    daSrcAttributeMatrix->removeAttributeArray(daSrcPath.getDataArrayName());
  }
  else
  {
    setErrorCondition(-11020);
    QString ss = QObject::tr("Neither an Attribute Matrix nor an Attribute Array was selected to be moved");
    notifyErrorMessage(getHumanLabel(), ss, getErrorCondition());
    return;
  }
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void GenerateMisorientationColors::execute()
{
  setErrorCondition(0);
  dataCheck();
  if(getErrorCondition() < 0) { return; }

  size_t totalPoints = m_CellPhasesPtr.lock()->getNumberOfTuples();

  // Make sure we are dealing with a unit 1 vector.
  FloatVec3_t normRefDir = m_ReferenceAxis; // Make a copy of the reference Direction

  MatrixMath::Normalize3x1(normRefDir.x, normRefDir.y, normRefDir.z);
  // Create 1 of every type of Ops class. This condenses the code below
  UInt8ArrayType::Pointer notSupported = UInt8ArrayType::CreateArray(13, "_INTERNAL_USE_ONLY_NotSupportedArray");
  notSupported->initializeWithZeros();

#ifdef DREAM3D_USE_PARALLEL_ALGORITHMS
  tbb::task_scheduler_init init;
  bool doParallel = true;
#endif

#ifdef DREAM3D_USE_PARALLEL_ALGORITHMS
  if (doParallel == true)
  {
    tbb::parallel_for(tbb::blocked_range<size_t>(0, totalPoints),
                      GenerateMisorientationColorsImpl( normRefDir, m_ReferenceAngle, reinterpret_cast<QuatF*>(m_Quats), m_CellPhases, m_CrystalStructures, m_GoodVoxels, notSupported->getPointer(0), m_MisorientationColor), tbb::auto_partitioner());

  }
  else
#endif
  {
    GenerateMisorientationColorsImpl serial( normRefDir, m_ReferenceAngle, reinterpret_cast<QuatF*>(m_Quats), m_CellPhases, m_CrystalStructures, m_GoodVoxels, notSupported->getPointer(0), m_MisorientationColor);
    serial.convert(0, totalPoints);
  }

  QVector<SpaceGroupOps::Pointer> ops = SpaceGroupOps::getOrientationOpsQVector();

  // Check and warn about unsupported crystal symmetries in the computation which will show as black
  for (size_t i = 0; i < notSupported->getNumberOfTuples() - 1; i++)
  {
    if (notSupported->getValue(i) == 1)
    {
      QString msg("The symmetry of ");
      msg.append(ops[i]->getSymmetryName()).append(" is not currently supported for misorientation coloring. Elements with this symmetry have been set to black");
      notifyWarningMessage(getHumanLabel(), msg, -5000);
    }
  }

  // Check for bad voxels which will show up as black also.
  if (notSupported->getValue(12) == 1)
  {
    QString msg("There were elements with an unknown crystal symmetry due most likely being marked as 'a 'bad'. These elements have been colored black BUT black is a valid color for misorientation coloring. Please understand this when visualizing your data");
    notifyWarningMessage(getHumanLabel(), msg, -5001);
  }

  /* Let the GUI know we are done with this filter */
  notifyStatusMessage(getHumanLabel(), "Complete");
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void AbaqusSurfaceMeshWriter::dataCheck()
{
  setErrorCondition(0);

  if (m_OutputFile.isEmpty() == true)
  {
    setErrorCondition(-1003);
    notifyErrorMessage(getHumanLabel(), "The output file must be set", getErrorCondition());
  }

  QFileInfo fi(m_OutputFile);
  QDir parentPath = fi.path();
  if (parentPath.exists() == false)
  {
    QString ss = QObject::tr( "The directory path for the output file does not exist. DREAM.3D will attempt to create this path during execution of the filter");
    notifyWarningMessage(getHumanLabel(), ss, -1);
  }

  QVector<IDataArray::Pointer> dataArrays;

  TriangleGeom::Pointer triangles = getDataContainerArray()->getPrereqGeometryFromDataContainer<TriangleGeom, AbstractFilter>(this, getSurfaceMeshFaceLabelsArrayPath().getDataContainerName());
  if(getErrorCondition() >= 0) { dataArrays.push_back(triangles->getTriangles()); }

  QVector<size_t> cDims(1, 2);
  m_SurfaceMeshFaceLabelsPtr = getDataContainerArray()->getPrereqArrayFromPath<DataArray<int32_t>, AbstractFilter>(this, getSurfaceMeshFaceLabelsArrayPath(), cDims); /* Assigns the shared_ptr<> to an instance variable that is a weak_ptr<> */
  if( NULL != m_SurfaceMeshFaceLabelsPtr.lock().get() ) /* Validate the Weak Pointer wraps a non-NULL pointer to a DataArray<T> object */
  { m_SurfaceMeshFaceLabels = m_SurfaceMeshFaceLabelsPtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray<T> object */
  if(getErrorCondition() >= 0) { dataArrays.push_back(m_SurfaceMeshFaceLabelsPtr.lock()); }

  getDataContainerArray()->validateNumberOfTuples<AbstractFilter>(this, dataArrays);
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void INLWriter::dataCheck()
{
  setErrorCondition(0);

  getDataContainerArray()->getPrereqGeometryFromDataContainer<ImageGeom, AbstractFilter>(this, getFeatureIdsArrayPath().getDataContainerName());

  if (getOutputFile().isEmpty() == true)
  {
    QString ss = QObject::tr("The output file must be set");
    setErrorCondition(-1);
    notifyErrorMessage(getHumanLabel(), ss, getErrorCondition());
  }

  QFileInfo fi(getOutputFile());
  QDir parentPath = fi.path();
  if (parentPath.exists() == false)
  {
    QString ss = QObject::tr("The directory path for the output file does not exist. DREAM.3D will attempt to create this path during execution of the filter");
    notifyWarningMessage(getHumanLabel(), ss, -1);
  }

  QVector<DataArrayPath> cellDataArrayPaths;
  QVector<DataArrayPath> ensembleDataArrayPaths;

  QVector<size_t> cDims(1, 1);
  m_FeatureIdsPtr = getDataContainerArray()->getPrereqArrayFromPath<DataArray<int32_t>, AbstractFilter>(this, getFeatureIdsArrayPath(), cDims); /* Assigns the shared_ptr<> to an instance variable that is a weak_ptr<> */
  if( NULL != m_FeatureIdsPtr.lock().get() ) /* Validate the Weak Pointer wraps a non-NULL pointer to a DataArray<T> object */
  { m_FeatureIds = m_FeatureIdsPtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray<T> object */
  if(getErrorCondition() >= 0) { cellDataArrayPaths.push_back(getFeatureIdsArrayPath()); }

  m_CellPhasesPtr = getDataContainerArray()->getPrereqArrayFromPath<DataArray<int32_t>, AbstractFilter>(this, getCellPhasesArrayPath(), cDims); /* Assigns the shared_ptr<> to an instance variable that is a weak_ptr<> */
  if( NULL != m_CellPhasesPtr.lock().get() ) /* Validate the Weak Pointer wraps a non-NULL pointer to a DataArray<T> object */
  { m_CellPhases = m_CellPhasesPtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray<T> object */
  if(getErrorCondition() >= 0) { cellDataArrayPaths.push_back(getCellPhasesArrayPath()); }

  m_CrystalStructuresPtr = getDataContainerArray()->getPrereqArrayFromPath<DataArray<uint32_t>, AbstractFilter>(this,  getCrystalStructuresArrayPath(), cDims); /* Assigns the shared_ptr<> to an instance variable that is a weak_ptr<> */
  if( NULL != m_CrystalStructuresPtr.lock().get() ) /* Validate the Weak Pointer wraps a non-NULL pointer to a DataArray<T> object */
  { m_CrystalStructures = m_CrystalStructuresPtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray<T> object */
  if(getErrorCondition() >= 0) { ensembleDataArrayPaths.push_back(getCrystalStructuresArrayPath()); }

  m_NumFeaturesPtr = getDataContainerArray()->getPrereqArrayFromPath<DataArray<int32_t>, AbstractFilter>(this,  getNumFeaturesArrayPath(), cDims); /* Assigns the shared_ptr<> to an instance variable that is a weak_ptr<> */
  if( NULL != m_NumFeaturesPtr.lock().get() ) /* Validate the Weak Pointer wraps a non-NULL pointer to a DataArray<T> object */
  { m_NumFeatures = m_NumFeaturesPtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray<T> object */
  if(getErrorCondition() >= 0) { ensembleDataArrayPaths.push_back(getNumFeaturesArrayPath()); }

  m_MaterialNamePtr = getDataContainerArray()->getPrereqArrayFromPath<StringDataArray, AbstractFilter>(this,  getMaterialNameArrayPath(), cDims); /* Assigns the shared_ptr<> to an instance variable that is a weak_ptr<> */
  if(getErrorCondition() >= 0) { ensembleDataArrayPaths.push_back(getMaterialNameArrayPath()); }

  cDims[0] = 3;
  m_CellEulerAnglesPtr = getDataContainerArray()->getPrereqArrayFromPath<DataArray<float>, AbstractFilter>(this, getCellEulerAnglesArrayPath(), cDims); /* Assigns the shared_ptr<> to an instance variable that is a weak_ptr<> */
  if( NULL != m_CellEulerAnglesPtr.lock().get() ) /* Validate the Weak Pointer wraps a non-NULL pointer to a DataArray<T> object */
  { m_CellEulerAngles = m_CellEulerAnglesPtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray<T> object */
  if(getErrorCondition() >= 0) { cellDataArrayPaths.push_back(getCellEulerAnglesArrayPath()); }

  getDataContainerArray()->validateNumberOfTuples<AbstractFilter>(this, cellDataArrayPaths);
  getDataContainerArray()->validateNumberOfTuples<AbstractFilter>(this, ensembleDataArrayPaths);
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void WritePoleFigure::dataCheck()
{
  setErrorCondition(0);

  QDir path(getOutputPath());

  getDataContainerArray()->getPrereqGeometryFromDataContainer<ImageGeom, AbstractFilter>(this, getCellPhasesArrayPath().getDataContainerName());

  if (m_OutputPath.isEmpty() == true)
  {
    setErrorCondition(-1003);
    notifyErrorMessage(getHumanLabel(), "The output directory must be set", getErrorCondition());
  }
  else if (path.exists() == false)
  {
    QString ss = QObject::tr("The directory path for the output file does not exist. DREAM.3D will attempt to create this path during execution of the filter");
    notifyWarningMessage(getHumanLabel(), ss, -1);
  }

  QVector<DataArrayPath> dataArrayPaths;

  QVector<size_t> cDims(1, 3);
  m_CellEulerAnglesPtr = getDataContainerArray()->getPrereqArrayFromPath<DataArray<float>, AbstractFilter>(this, getCellEulerAnglesArrayPath(), cDims); /* Assigns the shared_ptr<> to an instance variable that is a weak_ptr<> */
  if( NULL != m_CellEulerAnglesPtr.lock().get() ) /* Validate the Weak Pointer wraps a non-NULL pointer to a DataArray<T> object */
  { m_CellEulerAngles = m_CellEulerAnglesPtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray<T> object */
  if(getErrorCondition() >= 0) { dataArrayPaths.push_back(getCellEulerAnglesArrayPath()); }

  cDims[0] = 1;
  m_CellPhasesPtr = getDataContainerArray()->getPrereqArrayFromPath<DataArray<int32_t>, AbstractFilter>(this, getCellPhasesArrayPath(), cDims); /* Assigns the shared_ptr<> to an instance variable that is a weak_ptr<> */
  if( NULL != m_CellPhasesPtr.lock().get() ) /* Validate the Weak Pointer wraps a non-NULL pointer to a DataArray<T> object */
  { m_CellPhases = m_CellPhasesPtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray<T> object */
  if(getErrorCondition() >= 0) { dataArrayPaths.push_back(getCellPhasesArrayPath()); }

  m_CrystalStructuresPtr = getDataContainerArray()->getPrereqArrayFromPath<DataArray<uint32_t>, AbstractFilter>(this, getCrystalStructuresArrayPath(), cDims); /* Assigns the shared_ptr<> to an instance variable that is a weak_ptr<> */
  if( NULL != m_CrystalStructuresPtr.lock().get() ) /* Validate the Weak Pointer wraps a non-NULL pointer to a DataArray<T> object */
  { m_CrystalStructures = m_CrystalStructuresPtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray<T> object */

  // The good voxels array is optional, If it is available we are going to use it, otherwise we are going to create it
  cDims[0] = 1;
  m_GoodVoxelsPtr = getDataContainerArray()->getPrereqArrayFromPath<DataArray<bool>, AbstractFilter>(this, getGoodVoxelsArrayPath(), cDims); /* Assigns the shared_ptr<> to an instance variable that is a weak_ptr<> */
  if (NULL != m_GoodVoxelsPtr.lock().get())
  {
    if( NULL != m_GoodVoxelsPtr.lock().get() ) /* Validate the Weak Pointer wraps a non-NULL pointer to a DataArray<T> object */
    { m_GoodVoxels = m_GoodVoxelsPtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray<T> object */
    if(getErrorCondition() >= 0) { dataArrayPaths.push_back(getGoodVoxelsArrayPath()); }
  }
  else
  {
    m_GoodVoxels = NULL;
  }

  getDataContainerArray()->validateNumberOfTuples<AbstractFilter>(this, dataArrayPaths);
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void WriteStatsGenOdfAngleFile::dataCheck()
{
    setErrorCondition(0);

    QString ss;
    if (getOutputFile().isEmpty() == true)
    {
        ss = QObject::tr( "The output file must be set");
        setErrorCondition(-1);
        notifyErrorMessage(getHumanLabel(), ss, getErrorCondition());
    }
    QFileInfo fi(getOutputFile());
    QDir parentPath = fi.path();
    if (parentPath.exists() == false)
    {
        ss = QObject::tr( "The directory path for the output file does not exist");
        notifyWarningMessage(getHumanLabel(), ss, -1);
    }


    QVector<size_t> cDims(1, 1);
    m_CellPhasesPtr = getDataContainerArray()->getPrereqArrayFromPath<DataArray<int32_t>, AbstractFilter>(this, getCellPhasesArrayPath(), cDims); /* Assigns the shared_ptr<> to an instance variable that is a weak_ptr<> */
    if( NULL != m_CellPhasesPtr.lock().get() ) /* Validate the Weak Pointer wraps a non-NULL pointer to a DataArray<T> object */
    {
        m_CellPhases = m_CellPhasesPtr.lock()->getPointer(0);    /* Now assign the raw pointer to data from the DataArray<T> object */
    }

    cDims[0] = 3;
    m_CellEulerAnglesPtr = getDataContainerArray()->getPrereqArrayFromPath<DataArray<float>, AbstractFilter>(this, getCellEulerAnglesArrayPath(), cDims); /* Assigns the shared_ptr<> to an instance variable that is a weak_ptr<> */
    if( NULL != m_CellEulerAnglesPtr.lock().get() ) /* Validate the Weak Pointer wraps a non-NULL pointer to a DataArray<T> object */
    {
        m_CellEulerAngles = m_CellEulerAnglesPtr.lock()->getPointer(0);    /* Now assign the raw pointer to data from the DataArray<T> object */
    }


    if (getUseGoodVoxels() == true)
    {
        // The good voxels array is optional, If it is available we are going to use it, otherwise we are going to create it
        cDims[0] = 1;
        m_GoodVoxelsPtr = getDataContainerArray()->getPrereqArrayFromPath<DataArray<bool>, AbstractFilter>(this, getGoodVoxelsArrayPath(), cDims); /* Assigns the shared_ptr<> to an instance variable that is a weak_ptr<> */
        if( NULL != m_GoodVoxelsPtr.lock().get() ) /* Validate the Weak Pointer wraps a non-NULL pointer to a DataArray<T> object */
        {
            m_GoodVoxels = m_GoodVoxelsPtr.lock()->getPointer(0);    /* Now assign the raw pointer to data from the DataArray<T> object */
        }
    }
    else
    {
        m_GoodVoxels = NULL;
    }

}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void VisualizeGBCDPoleFigure::dataCheck()
{
  setErrorCondition(0);

  getDataContainerArray()->getPrereqGeometryFromDataContainer<TriangleGeom, AbstractFilter>(this, getGBCDArrayPath().getDataContainerName());

  if (getOutputFile().isEmpty() == true)
  {
    QString ss = QObject::tr( "The output file must be set");
    setErrorCondition(-1000);
    notifyErrorMessage(getHumanLabel(), ss, getErrorCondition());
  }

  QFileInfo fi(getOutputFile());
  QDir parentPath = fi.path();
  if (parentPath.exists() == false && getInPreflight())
  {
    QString ss = QObject::tr( "The directory path for the output file does not exist. DREAM.3D will attempt to create this path during execution of the filter");
    notifyWarningMessage(getHumanLabel(), ss, -1);
  }

  if (fi.suffix().compare("") == 0)
  {
    setOutputFile(getOutputFile().append(".vtk"));
  }

  QVector<size_t> cDims(1, 1);
  m_CrystalStructuresPtr = getDataContainerArray()->getPrereqArrayFromPath<DataArray<unsigned int>, AbstractFilter>(this, getCrystalStructuresArrayPath(), cDims); /* Assigns the shared_ptr<> to an instance variable that is a weak_ptr<> */
  if (NULL != m_CrystalStructuresPtr.lock().get()) /* Validate the Weak Pointer wraps a non-NULL pointer to a DataArray<T> object */
  {
    m_CrystalStructures = m_CrystalStructuresPtr.lock()->getPointer(0);
  } /* Now assign the raw pointer to data from the DataArray<T> object */

  IDataArray::Pointer tmpGBCDPtr = getDataContainerArray()->getPrereqIDataArrayFromPath<IDataArray, AbstractFilter>(this, getGBCDArrayPath());
  if(getErrorCondition() < 0) { return; }

  if (NULL != tmpGBCDPtr.get())
  {
    QVector<size_t> cDims = tmpGBCDPtr->getComponentDimensions();
    m_GBCDPtr = getDataContainerArray()->getPrereqArrayFromPath<DataArray<double>, AbstractFilter>(this, getGBCDArrayPath(), cDims); /* Assigns the shared_ptr<> to an instance variable that is a weak_ptr<> */
    if( NULL != m_GBCDPtr.lock().get() ) /* Validate the Weak Pointer wraps a non-NULL pointer to a DataArray<T> object */
    { m_GBCD = m_GBCDPtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray<T> object */
  }

  if (NULL != m_GBCDPtr.lock().get() && getPhaseOfInterest() >= m_GBCDPtr.lock()->getNumberOfTuples())
  {
    QString ss = QObject::tr("The phase index is larger than the number of Ensembles").arg(ClassName());
    setErrorCondition(-1);
    notifyErrorMessage(getHumanLabel(), ss, getErrorCondition());
  }
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void CombineAttributeMatrices::execute()
{
  setErrorCondition(0);
  dataCheck();
  if (getErrorCondition() < 0) { return; }

  DataContainer::Pointer m = getDataContainerArray()->getDataContainer(getFirstAttributeMatrixPath().getDataContainerName());
  AttributeMatrix::Pointer firstAttrMat = m->getAttributeMatrix(getFirstAttributeMatrixPath().getAttributeMatrixName());
  AttributeMatrix::Pointer secondAttrMat = m->getAttributeMatrix(getSecondAttributeMatrixPath().getAttributeMatrixName());
  AttributeMatrix::Pointer combinedAttrMat = m->getAttributeMatrix(getCombinedAttributeMatrixName());
  size_t firstAttrMatNumTuples = firstAttrMat->getNumTuples();

  size_t totalTuples1 = m_SecondIndexPtr.lock()->getNumberOfTuples();
  size_t totalTuples2 = m_SecondIndexPtr.lock()->getNumberOfTuples();
  for (size_t i = 0; i < totalTuples1; i++)
  {
    if (m_FirstIndex > 0) { m_NewIndex[i] = m_FirstIndex[i]; }
  }
  for (size_t i = 0; i < totalTuples2; i++)
  {
    //subtract 1 from the index plus numTuples because the second index should be shifted to account for the zeroth tuple (all AMs above element start at tuple 1)
    if (m_SecondIndex[i] > 0 && m_NewIndex[i] == 0) m_NewIndex[i] = m_SecondIndex[i] + firstAttrMatNumTuples - 1;
    else if (m_SecondIndex[i] > 0 && m_NewIndex[i] != 0)
    {
      QString ss = QObject::tr("When copying the indices, the indices of the two attribute matrices overlapped.  The index of the first attribute matrix was kept.");
      notifyWarningMessage(getHumanLabel(), ss, -111);
    }
  }

  QList<QString> arrayNames = firstAttrMat->getAttributeArrayNames();
  size_t location = 0;
  for (QList<QString>::iterator iter = arrayNames.begin(); iter != arrayNames.end(); ++iter)
  {
    IDataArray::Pointer fromDataArray = firstAttrMat->getAttributeArray(*iter);
    IDataArray::Pointer toDataArray = combinedAttrMat->getAttributeArray(*iter);
    EXECUTE_FUNCTION_TEMPLATE(this, copyData, fromDataArray, fromDataArray, toDataArray, location);
  }

  arrayNames.clear();
  arrayNames = secondAttrMat->getAttributeArrayNames();
  location = firstAttrMatNumTuples;
  for (QList<QString>::iterator iter = arrayNames.begin(); iter != arrayNames.end(); ++iter)
  {
    IDataArray::Pointer fromDataArray = secondAttrMat->getAttributeArray(*iter);
    IDataArray::Pointer toDataArray = combinedAttrMat->getAttributeArray(*iter);
    EXECUTE_FUNCTION_TEMPLATE(this, copyData, fromDataArray, fromDataArray, toDataArray, location);
  }

  notifyStatusMessage(getHumanLabel(), "Complete");
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void WriteImages::dataCheck()
{
  setErrorCondition(0);

  getDataContainerArray()->getPrereqGeometryFromDataContainer<ImageGeom, AbstractFilter>(this, getColorsArrayPath().getDataContainerName());

  QDir dir(getOutputPath());

  if (getOutputPath().isEmpty() == true)
  {
    setErrorCondition(-1003);
    notifyErrorMessage(getHumanLabel(), "The output directory must be set", getErrorCondition());
  }
  else if (dir.exists() == false)
  {
    QString ss = QObject::tr("The output directory path does not exist. DREAM.3D will attempt to create this path during execution");
    notifyWarningMessage(getHumanLabel(), ss, -1);
  }

  IDataArray::Pointer iDa = getDataContainerArray()->getPrereqIDataArrayFromPath<IDataArray, AbstractFilter>(this, getColorsArrayPath());
  if (getErrorCondition() < 0) { return; }

  QVector<size_t> cDims = iDa->getComponentDimensions();

  if (cDims[0] == 1)
  {
    m_ColorsPtr = getDataContainerArray()->getPrereqArrayFromPath<DataArray<uint8_t>, AbstractFilter>(this, getColorsArrayPath(), cDims); /* Assigns the shared_ptr<> to an instance variable that is a weak_ptr<> */
    if (NULL != m_ColorsPtr.lock().get()) /* Validate the Weak Pointer wraps a non-NULL pointer to a DataArray<T> object */
    { m_Colors = m_ColorsPtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray<T> object */
  }
  else if (cDims[0] == 3)
  {
    m_ColorsPtr = getDataContainerArray()->getPrereqArrayFromPath<DataArray<uint8_t>, AbstractFilter>(this, getColorsArrayPath(), cDims); /* Assigns the shared_ptr<> to an instance variable that is a weak_ptr<> */
    if (NULL != m_ColorsPtr.lock().get()) /* Validate the Weak Pointer wraps a non-NULL pointer to a DataArray<T> object */
    { m_Colors = m_ColorsPtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray<T> object */
  }
  else if (cDims[0] == 4)
  {
    m_ColorsPtr = getDataContainerArray()->getPrereqArrayFromPath<DataArray<uint8_t>, AbstractFilter>(this, getColorsArrayPath(), cDims); /* Assigns the shared_ptr<> to an instance variable that is a weak_ptr<> */
    if (NULL != m_ColorsPtr.lock().get()) /* Validate the Weak Pointer wraps a non-NULL pointer to a DataArray<T> object */
    { m_Colors = m_ColorsPtr.lock()->getPointer(0); } /* Now assign the raw pointer to data from the DataArray<T> object */
  }
  else
  {
    setErrorCondition(-1006);
    notifyErrorMessage(getHumanLabel(), "Number of components must be 1 (grayscale), 3 (RGB) or 4 (ARGB) arrays", getErrorCondition());
  }
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void FindFeaturePhases::execute()
{
  setErrorCondition(0);
  dataCheck();
  if(getErrorCondition() < 0) { return; }

  size_t totalPoints = m_FeatureIdsPtr.lock()->getNumberOfTuples();

  int32_t gnum = 0;
  QMap<int32_t, int32_t> featureMap;

  QMap<int32_t, int32_t> warningMap;

  for (size_t i = 0; i < totalPoints; i++)
  {
    gnum = m_FeatureIds[i];
    if (!featureMap.contains(gnum)) { featureMap.insert(gnum, m_CellPhases[i]); }
    int32_t curPhaseVal = featureMap.value(gnum);

    if (curPhaseVal != m_CellPhases[i])
    {
      if(!warningMap.contains(gnum)) { warningMap[gnum] = 1; }
      else {
        warningMap[gnum]++;
      }
    }
    m_FeaturePhases[gnum] = m_CellPhases[i];
  }

  if(warningMap.size() > 0)
  {
    QStringList warnings;
    QString header = QString("Elements from some features did not all have the same phase Id. The last phase Id copied into each feature will be used");
    warnings.append(header);
    QMapIterator<int32_t, int32_t> i(warningMap);
    while (i.hasNext()) {
        i.next();
        QString str;
        QTextStream ss(&str);
        ss << "  Phase Feature " << i.key() << " created " << i.value() << " warnings.";
        warnings.append(str);
    }
    notifyWarningMessage(getHumanLabel(), warnings.join("\n"), getErrorCondition());
  }

  notifyStatusMessage(getHumanLabel(), "Complete");
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void RequiredZThickness::dataCheck()
{
  setErrorCondition(0);
  if(getErrorCondition() < 0) { return; }

  DataContainer::Pointer dataContainer = getDataContainerArray()->getPrereqDataContainer<AbstractFilter>(this, getDataContainerSelection());
  if (getErrorCondition() < 0) { return; }

  ImageGeom::Pointer image = dataContainer->getGeometryAs<ImageGeom>();
  if( NULL == image.get() )
  {
    setErrorCondition(-7789);
    notifyErrorMessage(getHumanLabel(), "Missing Image Geometry in the selected DataContainer", getErrorCondition());
    return;
  }

  size_t dims[3] = { 0, 0, 0 };
  image->getDimensions(dims);


  if (dims[2] < getNumZVoxels() && m_PreflightCheck)
  {
    setErrorCondition(-7787);
    QString str;
    QTextStream ss(&str);
    ss << "Number of Z Voxels does not meet required value during preflight of the filter. \n";
    ss << "  Required Z Voxels: " << m_NumZVoxels << "\n";
    ss << "  Current Z Voxels: " << dims[2];

    notifyErrorMessage(getHumanLabel(), str, getErrorCondition());
  } 
  else if (dims[2] < getNumZVoxels() && !m_PreflightCheck)
  {
    QString str;
    QTextStream ss(&str);
    ss << "Number of Z Voxels does not meet required value during preflight but will be checked during pipeline execution.\n";
    ss << "  Required Z Voxels: " << m_NumZVoxels << "\n";
    ss << "  Current Z Voxels: " << dims[2];

    notifyWarningMessage(getHumanLabel(), str, getErrorCondition());
  }

}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
QString InitializeSyntheticVolume::estimateNumFeatures(IntVec3_t dims, FloatVec3_t res)
{
  float totalvol = 0.0f;
  int32_t phase = 0;

  totalvol = (dims.x * res.x) * (dims.y * res.y) * (dims.z * res.z);
  if (totalvol == 0.0)
  {
    return "-1";
  }

  DataContainerArray::Pointer dca = getDataContainerArray();

  // Get the PhaseTypes - Remember there is a Dummy PhaseType in the first slot of the array
  QVector<size_t> cDims(1, 1); // This states that we are looking for an array with a single component
  UInt32ArrayType::Pointer phaseType = dca->getPrereqArrayFromPath<UInt32ArrayType, AbstractFilter>(NULL, getInputPhaseTypesArrayPath(), cDims);
  if (phaseType.get() == NULL)
  {
    QString ss = QObject::tr("Phase types array could not be downcast using std::dynamic_pointer_cast<T> when estimating the number of grains. The path is %1").arg(getInputPhaseTypesArrayPath().serialize());
    setErrorCondition(-11002);
    notifyErrorMessage(getHumanLabel(), ss, getErrorCondition());
    return "0";
  }


  QVector<size_t> statsDims(1, 1);
  StatsDataArray::Pointer statsPtr = dca->getPrereqArrayFromPath<StatsDataArray, AbstractFilter>(this, getInputStatsArrayPath(), statsDims);
  if (statsPtr.get() == NULL)
  {
    QString ss = QObject::tr("Statistics array could not be downcast using std::dynamic_pointer_cast<T> when estimating the number of grains. The path is %1").arg(getInputStatsArrayPath().serialize());
    notifyErrorMessage(getHumanLabel(), ss, -11001);
    return "0";
  }


  if (!phaseType->isAllocated())
  {
    if (getInputStatsFile().isEmpty())
    {
      QString ss = QObject::tr("Phase types array has not been allocated and the input statistics file is empty");
      setErrorCondition(-1000);
      notifyWarningMessage(getHumanLabel(), ss, getErrorCondition());
      return "-1";
    }
    QFileInfo fi(getInputStatsFile());
    if (fi.exists() == false)
    {
      QString ss = QObject::tr("Phase types array has not been allocated and the input statistics file does not exist at '%1'").arg(fi.absoluteFilePath());
      setErrorCondition(-1001);
      notifyWarningMessage(getHumanLabel(), ss, getErrorCondition());
      return "-1";
    }


    hid_t fileId = -1;
    herr_t err = 0;
    // open the file
    fileId = H5Utilities::openFile(getInputStatsFile().toLatin1().constData(), true);
    // This will make sure if we return early from this method that the HDF5 File is properly closed.
    HDF5ScopedFileSentinel scopedFileSentinel(&fileId, true);

    DataArrayPath dap = getInputPhaseTypesArrayPath();
    // Generate the path to the AttributeMatrix
    QString hPath = DREAM3D::StringConstants::DataContainerGroupName + "/" + dap.getDataContainerName() + "/" + dap.getAttributeMatrixName();
    // Open the AttributeMatrix Group
    hid_t amGid = H5Gopen(fileId, hPath.toLatin1().data(), H5P_DEFAULT );
    scopedFileSentinel.addGroupId(&amGid);
    err = phaseType->readH5Data(amGid);
    if (err < 0)
    {
      QString ss = QObject::tr("Error reading phase type data");
      setErrorCondition(-1003);
      notifyWarningMessage(getHumanLabel(), ss, getErrorCondition());
      return "-1";
    }
    if (!phaseType->isAllocated())
    {
      QString ss = QObject::tr("Phase types Array was not allocated due to an error reading the data from the statistics file %1").arg(fi.absoluteFilePath());
      setErrorCondition(-1002);
      notifyWarningMessage(getHumanLabel(), ss, getErrorCondition());
      return "-1";
    }
  }

  // Create a Reference Variable so we can use the [] syntax
  StatsDataArray& statsDataArray = *(statsPtr.get());

  std::vector<int32_t> primaryphases;
  std::vector<double> primaryphasefractions;
  double totalprimaryfractions = 0.0;
  // find which phases are primary phases

  for (size_t i = 1; i < phaseType->getNumberOfTuples(); ++i)
  {
    if (phaseType->getValue(i) == DREAM3D::PhaseType::PrimaryPhase)
    {
      PrimaryStatsData* pp = PrimaryStatsData::SafePointerDownCast(statsDataArray[i].get());
      primaryphases.push_back(i);
      primaryphasefractions.push_back(pp->getPhaseFraction());
      totalprimaryfractions = totalprimaryfractions + pp->getPhaseFraction();
    }
  }

  // scale the primary phase fractions to total to 1
  for (int32_t i = 0; i < primaryphasefractions.size(); i++)
  {
    primaryphasefractions[i] = primaryphasefractions[i] / totalprimaryfractions;
  }

  SIMPL_RANDOMNG_NEW()
  // generate the Features
  int32_t gid = 1;

  float currentvol = 0.0f;
  float vol = 0.0f;
  float diam = 0.0f;
  bool volgood = false;
  for (int32_t j = 0; j < primaryphases.size(); ++j)
  {
    float curphasetotalvol = totalvol * primaryphasefractions[j];
    while (currentvol < curphasetotalvol)
    {
      volgood = false;
      phase = primaryphases[j];
      PrimaryStatsData* pp = PrimaryStatsData::SafePointerDownCast(statsDataArray[phase].get());
      if (NULL == pp)
      {
        QString ss = QObject::tr("Tried to cast a statsDataArray[%1].get() to a PrimaryStatsData* "
                                 "pointer but this resulted in a NULL pointer.\n")
                     .arg(phase).arg(phase);
        setErrorCondition(-666);
        notifyErrorMessage(getHumanLabel(), ss, getErrorCondition());
        return "-1";
      }
      while (volgood == false)
      {
        volgood = true;
        if (pp->getFeatureSize_DistType() == DREAM3D::DistributionType::LogNormal)
        {
          float avgdiam = pp->getFeatureSizeDistribution().at(0)->getValue(0);
          float sddiam = pp->getFeatureSizeDistribution().at(1)->getValue(0);
          diam = rg.genrand_norm(avgdiam, sddiam);
          diam = expf(diam);
          if (diam >= pp->getMaxFeatureDiameter()) { volgood = false; }
          if (diam < pp->getMinFeatureDiameter()) { volgood = false; }
          vol = (4.0f / 3.0f) * (M_PI) * ((diam * 0.5f) * (diam * 0.5f) * (diam * 0.5f));
        }
      }
      currentvol = currentvol + vol;
      gid++;
    }
  }
  return QString::number(gid);
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void Hex2SqrConverter::execute()
{
  std::stringstream ss;
  herr_t err = 0;

  std::vector<int> indices;
  // Loop on Each EBSD File
  float total = static_cast<float>( m_ZEndIndex - m_ZStartIndex );
  int progress = 0;
  int64_t z = m_ZStartIndex;
  /* There is a frailness about the z index and the file list. The programmer
   * using this code MUST ensure that the list of files that is sent into this
   * class is in the appropriate order to match up with the z index (slice index)
   * otherwise the import will have subtle errors. The programmer is urged NOT to
   * simply gather a list from the file system as those lists are sorted in such
   * a way that if the number of digits appearing in the filename are NOT the same
   * then the list will be wrong, ie, this example:
   *
   * slice_1.ang
   * slice_2.ang
   * ....
   * slice_10.ang
   *
   * Most, if not ALL C++ libraries when asked for that list will return the list
   * sorted like the following:
   *
   * slice_1.ang
   * slice_10.ang
   * slice_2.ang
   *
   * which is going to cause problems because the data is going to be placed
   * into the HDF5 file at the wrong index. YOU HAVE BEEN WARNED.
   */
  // int totalSlicesImported = 0;
  for (std::vector<std::string>::iterator filepath = m_EbsdFileList.begin(); filepath != m_EbsdFileList.end(); ++filepath)
  {
    std::string ebsdFName = *filepath;

    progress = static_cast<int>( z - m_ZStartIndex );
    progress = (int)(100.0f * (float)(progress) / total);
    std::string msg = "Converting File: " + ebsdFName;
    ss.str("");

    notifyStatusMessage(msg.c_str());

    // Write the Manufacturer of the OIM file here
    // This list will grow to be the number of EBSD file formats we support
    std::string ext = MXAFileInfo::extension(ebsdFName);
    std::string base = MXAFileInfo::fileNameWithOutExtension(ebsdFName);
    std::string path = MXAFileInfo::parentPath(ebsdFName);
    if(ext.compare(Ebsd::Ang::FileExt) == 0)
    {
      AngReader reader;
      reader.setFileName(ebsdFName);
      reader.setReadHexGrid(true);
      int err = reader.readFile();

      if(err < 0 && err != -600)
      {
        addErrorMessage(getHumanLabel(), reader.getErrorMessage(), reader.getErrorCode());
        setErrorCondition(reader.getErrorCode());
        return;
      }
      else if(reader.getGrid().find(Ebsd::Ang::SquareGrid) == 0)
      {
        ss.str("");
        ss << "Ang File is already a square grid: " << ebsdFName;
        setErrorCondition(-55000);
        addErrorMessage(getHumanLabel(), ss.str(), getErrorCondition());
        return;
      }
      else
      {
        if (err == -600)
        {
          notifyWarningMessage( reader.getErrorMessage(), reader.getErrorCode() );
        }
        std::string origHeader = reader.getOriginalHeader();
        if (origHeader.empty() == true)
        {
          ss.str();
          ss << "Header could not be retrieved: " << ebsdFName;
          setErrorCondition(-55001);
          addErrorMessage(getHumanLabel(), ss.str(), getErrorCondition());
        }
        char buf[kBufferSize];
        std::stringstream in(origHeader);

        std::string newEbsdFName = path + "/Sqr_" + base + "." + ext;
        std::ofstream outFile;
        outFile.open(newEbsdFName.c_str());

        m_HeaderIsComplete = false;

        float HexXStep = reader.getXStep();
        float HexYStep = reader.getYStep();
        int HexNumColsOdd = reader.getNumOddCols();
        int HexNumColsEven = reader.getNumEvenCols();
        int HexNumRows = reader.getNumRows();
        m_NumCols = (HexNumColsOdd*HexXStep)/m_XResolution;
        m_NumRows = (HexNumRows*HexYStep)/m_YResolution;
        float xSqr, ySqr, xHex1, yHex1, xHex2, yHex2;
        int point, point1, point2;
        int row1, row2, col1, col2;
        float dist1, dist2;
        float* phi1 = reader.getPhi1Pointer();
        float* PHI = reader.getPhiPointer();
        float* phi2 = reader.getPhi2Pointer();
        float* ci = reader.getConfidenceIndexPointer();
        float* iq = reader.getImageQualityPointer();
        float* semsig = reader.getSEMSignalPointer();
        float* fit = reader.getFitPointer();
        int* phase = reader.getPhaseDataPointer();
        while (!in.eof())
        {
          std::string line;
          ::memset(buf, 0, kBufferSize);
          in.getline(buf, kBufferSize);
          line = modifyAngHeaderLine(buf, kBufferSize);
          if(m_HeaderIsComplete == false) outFile << line << std::endl;
        }
        for(int j = 0; j < m_NumRows; j++)
        {
          for(int i = 0; i < m_NumCols; i++)
          {
            xSqr = float(i)*m_XResolution;
            ySqr = float(j)*m_YResolution;
            row1 = ySqr/(HexYStep);
            yHex1 = row1*HexYStep;
            row2 = row1 + 1;
            yHex2 = row2*HexYStep;
            if(row1%2 == 0)
            {
              col1 = xSqr/(HexXStep);
              xHex1 = col1*HexXStep;
              point1 = ((row1/2)*HexNumColsEven) + ((row1/2)*HexNumColsOdd) + col1;
              col2 = (xSqr-(HexXStep/2.0))/(HexXStep);
              xHex2 = col2*HexXStep + (HexXStep/2.0);
              point2 = ((row1/2)*HexNumColsEven) + (((row1/2)+1)*HexNumColsOdd) + col2;
            }
            else
            {
              col1 = (xSqr-(HexXStep/2.0))/(HexXStep);
              xHex1 = col1*HexXStep + (HexXStep/2.0);
              point1 = ((row1/2)*HexNumColsEven) + (((row1/2)+1)*HexNumColsOdd) + col1;
              col2 = xSqr/(HexXStep);
              xHex2 = col2*HexXStep;
              point2 = (((row1/2)+1)*HexNumColsEven) + (((row1/2)+1)*HexNumColsOdd) + col2;
            }
            dist1 = ((xSqr-xHex1)*(xSqr-xHex1)) + ((ySqr-yHex1)*(ySqr-yHex1));
            dist2 = ((xSqr-xHex2)*(xSqr-xHex2)) + ((ySqr-yHex2)*(ySqr-yHex2));
            if(dist1 <= dist2 || row1 == (HexNumRows-1)) {point = point1;}
            else {point = point2;}
            outFile << "  " << phi1[point] << "	" << PHI[point] << "	" << phi2[point] << "	" << xSqr << "	" << ySqr << "	" << iq[point] << "	" << ci[point] << "	" << phase[point] << "	" << semsig[point] << "	" << fit[point] << "	" << std::endl;
          }
        }
      }
    }
    else if(ext.compare(Ebsd::Ctf::FileExt) == 0)
    {
      std::cout << "Ctf files are not on a hexagonal grid and do not need to be converted." << std::endl;
    }
    else
    {
      err = -1;
      ss.str("");
      ss << "The File extension was not detected correctly";
      addErrorMessage(getHumanLabel(), ss.str(), err);
      setErrorCondition(-1);
      return;
    }

  }

  notifyStatusMessage("Import Complete");
}
Exemple #14
0
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void EbsdToH5Ebsd::execute()
{
  std::stringstream ss;
  herr_t err = 0;
  hid_t fileId = -1;

  if(m_OutputFile.empty() == true)
  {
    std::string s("EbsdToH5Ebsd Error: The output file was not set correctly or is empty. The current value is '");
    s.append("'. Please set the output file before running the importer. ");

    ss << "EbsdToH5Ebsd input filename was empty";
    addErrorMessage(getHumanLabel(), ss.str(), err);
    setErrorCondition(-1);
    return;
  }
  // Make sure any directory path is also available as the user may have just typed
  // in a path without actually creating the full path
  std::string parentPath = MXAFileInfo::parentPath(m_OutputFile);
  if(!MXADir::mkdir(parentPath, true))
  {
    std::stringstream ss;
    PipelineMessage em (getHumanLabel(), ss.str(), -1);
    addErrorMessage(em);
    setErrorCondition(-1);
    return;
  }

  // Create File
  fileId = H5Utilities::createFile(m_OutputFile);
  if(fileId < 0)
  {
    err = -1;
    ss.str("");
    ss << "The Output HDF5 file could not be created. Check Permissions, if the File is in use by another program.";
    addErrorMessage(getHumanLabel(), ss.str(), err);
    setErrorCondition(-1);
    return;
  }

  HDF5ScopedFileSentinel sentinel(&fileId, true);

  err = H5Lite::writeScalarDataset(fileId, Ebsd::H5::ZResolution, m_ZResolution);
  if(err < 0)
  {
    ss.str("");
    ss << "Could not write the Z Resolution Scalar to the HDF5 File";
    addErrorMessage(getHumanLabel(), ss.str(), err);
    setErrorCondition(-1);
  }
  unsigned int ui = static_cast<unsigned int>(m_RefFrameZDir);
  err = H5Lite::writeScalarDataset(fileId, Ebsd::H5::StackingOrder, ui);
  if(err < 0)
  {
    ss.str("");
    ss << "Could not write the Stacking Order Scalar to the HDF5 File";
    addErrorMessage(getHumanLabel(), ss.str(), err);
    setErrorCondition(-1);
  }

  std::string s = Ebsd::StackingOrder::Utils::getStringForEnum(m_RefFrameZDir);
  err = H5Lite::writeStringAttribute(fileId, Ebsd::H5::StackingOrder, "Name", s);
  if(err < 0)
  {
    ss.str("");
    ss << "Could not write the Stacking Order Name Attribute to the HDF5 File";
    addErrorMessage(getHumanLabel(), ss.str(), err);
    setErrorCondition(-1);
  }

  err = H5Lite::writeScalarDataset(fileId, Ebsd::H5::SampleTransformationAngle, m_SampleTransformationAngle);
  if(err < 0)
  {
    ss.str("");
    ss << "Could not write the Sample Transformation Angle to the HDF5 File";
    addErrorMessage(getHumanLabel(), ss.str(), err);
    setErrorCondition(-1);
  }

  std::vector<hsize_t> dims(1,3);
  err = H5Lite::writeVectorDataset(fileId, Ebsd::H5::SampleTransformationAxis, dims, m_SampleTransformationAxis);
  if(err < 0)
  {
    ss.str("");
    ss << "Could not write the Sample Transformation Axis to the HDF5 File";
    addErrorMessage(getHumanLabel(), ss.str(), err);
    setErrorCondition(-1);
  }

  err = H5Lite::writeScalarDataset(fileId, Ebsd::H5::EulerTransformationAngle, m_EulerTransformationAngle);
  if(err < 0)
  {
    ss.str("");
    ss << "Could not write the Euler Transformation Angle to the HDF5 File";
    addErrorMessage(getHumanLabel(), ss.str(), err);
    setErrorCondition(-1);
  }

  err = H5Lite::writeVectorDataset(fileId, Ebsd::H5::EulerTransformationAxis, dims, m_EulerTransformationAxis);
  if(err < 0)
  {
    ss.str("");
    ss << "Could not write the Euler Transformation Axis to the HDF5 File";
    addErrorMessage(getHumanLabel(), ss.str(), err);
    setErrorCondition(-1);
  }

  EbsdImporter::Pointer fileImporter;

  // Write the Manufacturer of the OIM file here
  // This list will grow to be the number of EBSD file formats we support
  std::string ext = MXAFileInfo::extension(m_EbsdFileList.front());
  if(ext.compare(Ebsd::Ang::FileExt) == 0)
  {
    err = H5Lite::writeStringDataset(fileId, Ebsd::H5::Manufacturer, Ebsd::Ang::Manufacturer);
    if(err < 0)
    {
      ss.str("");
      ss << "Could not write the Manufacturer Data to the HDF5 File";
      addErrorMessage(getHumanLabel(), ss.str(), err);
      setErrorCondition(-1);
    }
    fileImporter = H5AngImporter::New();
  }
  else if(ext.compare(Ebsd::Ctf::FileExt) == 0)
  {
    err = H5Lite::writeStringDataset(fileId, Ebsd::H5::Manufacturer, Ebsd::Ctf::Manufacturer);
    if(err < 0)
    {
      ss.str("");
      ss << "Could not write the Manufacturer Data to the HDF5 File";
      addErrorMessage(getHumanLabel(), ss.str(), err);
      setErrorCondition(-1);
    }
    fileImporter = H5CtfImporter::New();
  }
  else if(ext.compare(Ebsd::Mic::FileExt) == 0)
  {
    err = H5Lite::writeStringDataset(fileId, Ebsd::H5::Manufacturer, Ebsd::Mic::Manufacturer);
    if(err < 0)
    {
      ss.str("");
      ss << "Could not write the Manufacturer Data to the HDF5 File";
      addErrorMessage(getHumanLabel(), ss.str(), err);
      setErrorCondition(-1);
    }
    fileImporter = H5MicImporter::New();
  }
  else
  {
    err = -1;
    ss.str("");
    ss << "The File extension was not detected correctly";
    addErrorMessage(getHumanLabel(), ss.str(), err);
    setErrorCondition(-1);
    return;
  }

  std::vector<int> indices;
  // Loop on Each EBSD File
  float total = static_cast<float>( m_ZEndIndex - m_ZStartIndex );
  int progress = 0;
  int64_t z = m_ZStartIndex;
  int64_t xDim = 0, yDim = 0;
  float xRes = 0.0f, yRes = 0.0f;
  /* There is a frailness about the z index and the file list. The programmer
   * using this code MUST ensure that the list of files that is sent into this
   * class is in the appropriate order to match up with the z index (slice index)
   * otherwise the import will have subtle errors. The programmer is urged NOT to
   * simply gather a list from the file system as those lists are sorted in such
   * a way that if the number of digits appearing in the filename are NOT the same
   * then the list will be wrong, ie, this example:
   *
   * slice_1.ang
   * slice_2.ang
   * ....
   * slice_10.ang
   *
   * Most, if not ALL C++ libraries when asked for that list will return the list
   * sorted like the following:
   *
   * slice_1.ang
   * slice_10.ang
   * slice_2.ang
   *
   * which is going to cause problems because the data is going to be placed
   * into the HDF5 file at the wrong index. YOU HAVE BEEN WARNED.
   */
  int64_t biggestxDim = 0;
  int64_t biggestyDim = 0;
  int totalSlicesImported = 0;
  for (std::vector<std::string>::iterator filepath = m_EbsdFileList.begin(); filepath != m_EbsdFileList.end(); ++filepath)
  {
    std::string ebsdFName = *filepath;
    progress = static_cast<int>( z - m_ZStartIndex );
    progress = (int)(100.0f * (float)(progress) / total);
    std::string msg = "Converting File: " + ebsdFName;
    ss.str("");

    notifyStatusMessage(msg.c_str());
    err = fileImporter->importFile(fileId, z, ebsdFName);
    if (err < 0)
    {
      if (err != -600)
      {
        setErrorCondition(fileImporter->getErrorCondition());
        notifyErrorMessage(fileImporter->getPipelineMessage(), getErrorCondition());
        return;
      }
      else
      {
        notifyWarningMessage(fileImporter->getPipelineMessage(), fileImporter->getErrorCondition() );
        //setErrorCondition(fileImporter->getErrorCondition() );
        err = 0;
      }
    }
    totalSlicesImported = totalSlicesImported + fileImporter->numberOfSlicesImported();

    fileImporter->getDims(xDim, yDim);
    fileImporter->getResolution(xRes, yRes);
    if(xDim > biggestxDim) biggestxDim = xDim;
    if(yDim > biggestyDim) biggestyDim = yDim;

    indices.push_back( static_cast<int>(z) );
    ++z;
    if(getCancel() == true)
    {
      notifyStatusMessage("Conversion was Canceled");
      return;
    }
  }

  // Write Z index start, Z index end and Z Resolution to the HDF5 file
  err = H5Lite::writeScalarDataset(fileId, Ebsd::H5::ZStartIndex, m_ZStartIndex);
  if(err < 0)
  {
    ss.str("");
    ss << "Could not write the Z Start Index Scalar to the HDF5 File";
    addErrorMessage(getHumanLabel(), ss.str(), err);
    setErrorCondition(-1);
  }

  m_ZEndIndex = m_ZStartIndex + totalSlicesImported - 1;
  err = H5Lite::writeScalarDataset(fileId, Ebsd::H5::ZEndIndex, m_ZEndIndex);
  if(err < 0)
  {
    ss.str("");
    ss << "Could not write the Z End Index Scalar to the HDF5 File";
    addErrorMessage(getHumanLabel(), ss.str(), err);
    setErrorCondition(-1);
  }

  err = H5Lite::writeScalarDataset(fileId, Ebsd::H5::XPoints, biggestxDim);
  if(err < 0)
  {
    ss.str("");
    ss << "Could not write the XPoints Scalar to HDF5 file";
    addErrorMessage(getHumanLabel(), ss.str(), err);
    setErrorCondition(-1);
  }

  err = H5Lite::writeScalarDataset(fileId, Ebsd::H5::YPoints, biggestyDim);
  if(err < 0)
  {
    ss.str("");
    ss << "Could not write the YPoints Scalar to HDF5 file";
    addErrorMessage(getHumanLabel(), ss.str(), err);
    setErrorCondition(-1);
  }

  err = H5Lite::writeScalarDataset(fileId, Ebsd::H5::XResolution, xRes);
  if(err < 0)
  {
    ss.str("");
    ss << "Could not write the XResolution Scalar to HDF5 file";
    addErrorMessage(getHumanLabel(), ss.str(), err);
    setErrorCondition(-1);
  }

  err = H5Lite::writeScalarDataset(fileId, Ebsd::H5::YResolution, yRes);
  if(err < 0)
  {
    ss.str("");
    ss << "Could not write the YResolution Scalar to HDF5 file";
    addErrorMessage(getHumanLabel(), ss.str(), err);
    setErrorCondition(-1);
  }

  if(false == getCancel())
  {
    // Write an Index data set which contains all the z index values which
    // should help speed up the reading side of this file
    std::vector<hsize_t> dims(1, indices.size());
    err = H5Lite::writeVectorDataset(fileId, Ebsd::H5::Index, dims, indices);
  }
  err = H5Utilities::closeFile(fileId);
  fileId = -1;
  notifyStatusMessage("Import Complete");
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void RawBinaryReader::execute()
{
  int err = 0;
  std::stringstream ss;
  setErrorCondition(err);
  VoxelDataContainer* m = getVoxelDataContainer();
  if(NULL == m)
  {
    setErrorCondition(-999);
    notifyErrorMessage("The Voxel DataContainer Object was NULL", -999);
    return;
  }
  setErrorCondition(0);


  // Get the total size of the array from the options
  size_t voxels = m_Dimensions.x * m_Dimensions.y * m_Dimensions.z;
  if (m_OverRideOriginResolution == true)
  {
    m->setOrigin(m_Origin.x, m_Origin.y, m_Origin.z);
    m->setResolution(m_Resolution.x, m_Resolution.y, m_Resolution.z);
  }
  m->setDimensions(m_Dimensions.x, m_Dimensions.y, m_Dimensions.z);


  array = IDataArray::NullPointer();
  if (m_ScalarType == Detail::Int8)
  {
    Int8ArrayType::Pointer p = Int8ArrayType::CreateArray(voxels, m_NumberOfComponents, m_OutputArrayName);
    err = ReadBinaryFile<int8_t>(p, m_InputFile, m_SkipHeaderBytes);
    if (err >= 0 ) { SWAP_ARRAY(p)
          array = p;}
  }
  else if (m_ScalarType == Detail::UInt8)
  {
    UInt8ArrayType::Pointer p = UInt8ArrayType::CreateArray(voxels, m_NumberOfComponents, m_OutputArrayName);
    err = ReadBinaryFile<uint8_t>(p, m_InputFile, m_SkipHeaderBytes);
    if (err >= 0 ) { SWAP_ARRAY(p)
          array = p;}
  }
  else if (m_ScalarType == Detail::Int16)
  {
    Int16ArrayType::Pointer p = Int16ArrayType::CreateArray(voxels, m_NumberOfComponents, m_OutputArrayName);
    err = ReadBinaryFile<int16_t>(p, m_InputFile, m_SkipHeaderBytes);
    if (err >= 0 ) { SWAP_ARRAY(p)
          array = p;}
  }
  else if (m_ScalarType == Detail::UInt16)
  {
    UInt16ArrayType::Pointer p = UInt16ArrayType::CreateArray(voxels, m_NumberOfComponents, m_OutputArrayName);
    err = ReadBinaryFile<uint16_t>(p, m_InputFile, m_SkipHeaderBytes);
    if (err >= 0 ) { SWAP_ARRAY(p)
          array = p;}
  }
  else if (m_ScalarType == Detail::Int32)
  {
    Int32ArrayType::Pointer p = Int32ArrayType::CreateArray(voxels, m_NumberOfComponents, m_OutputArrayName);
    err = ReadBinaryFile<int32_t>(p, m_InputFile, m_SkipHeaderBytes);
    if (err >= 0 ) { SWAP_ARRAY(p)
          array = p;}
  }
  else if (m_ScalarType == Detail::UInt32)
  {
    UInt32ArrayType::Pointer p = UInt32ArrayType::CreateArray(voxels, m_NumberOfComponents, m_OutputArrayName);
    err = ReadBinaryFile<uint32_t>(p, m_InputFile, m_SkipHeaderBytes);
    if (err >= 0 ) { SWAP_ARRAY(p)
          array = p;}
  }
  else if (m_ScalarType == Detail::Int64)
  {
    Int64ArrayType::Pointer p = Int64ArrayType::CreateArray(voxels, m_NumberOfComponents, m_OutputArrayName);
    err = ReadBinaryFile<int64_t>(p, m_InputFile, m_SkipHeaderBytes);
    if (err >= 0 ) { SWAP_ARRAY(p)
          array = p;}
  }
  else if (m_ScalarType == Detail::UInt64)
  {
    UInt64ArrayType::Pointer p = UInt64ArrayType::CreateArray(voxels, m_NumberOfComponents, m_OutputArrayName);
    err = ReadBinaryFile<uint64_t>(p, m_InputFile, m_SkipHeaderBytes);
    if (err >= 0 ) { SWAP_ARRAY(p)
          array = p;}
  }
  else if (m_ScalarType == Detail::Float)
  {
    FloatArrayType::Pointer p = FloatArrayType::CreateArray(voxels, m_NumberOfComponents, m_OutputArrayName);
    err = ReadBinaryFile<float>(p, m_InputFile, m_SkipHeaderBytes);
    if (err >= 0 ) { SWAP_ARRAY(p)
          array = p;}
  }
  else if (m_ScalarType == Detail::Double)
  {
    DoubleArrayType::Pointer p = DoubleArrayType::CreateArray(voxels, m_NumberOfComponents, m_OutputArrayName);
    err = ReadBinaryFile<double>(p, m_InputFile, m_SkipHeaderBytes);
    if (err >= 0 ) { SWAP_ARRAY(p)
          array = p;}
  }

  if (NULL != array.get())
  {
    m->addCellData(array->GetName(), array);
  }
  else if(err == RBR_FILE_NOT_OPEN )
  {
    setErrorCondition(RBR_FILE_NOT_OPEN);
    notifyErrorMessage("RawBinaryReader was unable to open the specified file.", getErrorCondition());
  }
  else if (err == RBR_FILE_TOO_SMALL)
  {
    setErrorCondition(RBR_FILE_TOO_SMALL);
    notifyErrorMessage("The file size is smaller than the allocated size.", getErrorCondition());
  }
  else if (err == RBR_FILE_TOO_BIG)
  {
    notifyWarningMessage("The file size is larger than the allocated size.", RBR_FILE_TOO_BIG);
  }
  else if(err == RBR_READ_EOF)
  {
    setErrorCondition(RBR_READ_EOF);
    notifyErrorMessage("RawBinaryReader read past the end of the specified file.", getErrorCondition());
  }

  /* Let the GUI know we are done with this filter */
  notifyStatusMessage("Complete");
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void WritePoleFigure::execute()
{
  setErrorCondition(0);
  dataCheck();
  if(getErrorCondition() < 0) { return; }

  DataContainer::Pointer m = getDataContainerArray()->getDataContainer(m_CellPhasesArrayPath.getDataContainerName());

  size_t dims[3] = { 0, 0, 0 };
  m->getGeometryAs<ImageGeom>()->getDimensions(dims);

  // Make sure any directory path is also available as the user may have just typed
  // in a path without actually creating the full path
  QDir path(getOutputPath());

  if (!path.mkpath(".") )
  {
    QString ss = QObject::tr("Error creating parent path '%1'").arg(path.absolutePath());
    setErrorCondition(-1);
    notifyErrorMessage(getHumanLabel(), ss, getErrorCondition());
    return;
  }

  bool missingGoodVoxels = true;

  if (NULL != m_GoodVoxels)
  {
    missingGoodVoxels = false;
  }

  // Find how many phases we have by getting the number of Crystal Structures
  size_t numPoints = m->getGeometryAs<ImageGeom>()->getNumberOfElements();
  size_t numPhases = m_CrystalStructuresPtr.lock()->getNumberOfTuples();

  // Loop over all the voxels gathering the Eulers for a specific phase into an array
  for (size_t phase = 1; phase < numPhases; ++phase)
  {
    size_t count = 0;
    // First find out how many voxels we are going to have. This is probably faster to loop twice than to
    // keep allocating memory everytime we find one.
    for (size_t i = 0; i < numPoints; ++i)
    {
      if (m_CellPhases[i] == phase)
      {
        if (missingGoodVoxels == true || m_GoodVoxels[i] == true)
        {
          count++;
        }
      }
    }
    QVector<size_t> eulerCompDim(1, 3);
    FloatArrayType::Pointer subEulers = FloatArrayType::CreateArray(count, eulerCompDim, "Eulers_Per_Phase");
    subEulers->initializeWithValue(std::numeric_limits<float>::signaling_NaN());
    float* eu = subEulers->getPointer(0);

    // Now loop through the eulers again and this time add them to the subEulers Array
    count = 0;
    for (size_t i = 0; i < numPoints; ++i)
    {
      if (m_CellPhases[i] == phase)
      {
        if (missingGoodVoxels == true || m_GoodVoxels[i] == true)
        {
          eu[count * 3] = m_CellEulerAngles[i * 3];
          eu[count * 3 + 1] = m_CellEulerAngles[i * 3 + 1];
          eu[count * 3 + 2] = m_CellEulerAngles[i * 3 + 2];
          count++;
        }
      }
    }
    if (subEulers->getNumberOfTuples() == 0) { continue; } // Skip because we have no Pole Figure data

    QVector<UInt8ArrayType::Pointer> figures;

    PoleFigureConfiguration_t config;
    config.eulers = subEulers.get();
    config.imageDim = getImageSize();
    config.lambertDim = getLambertSize();
    config.numColors = getNumColors();

    QString label("Phase_");
    label.append(QString::number(phase));

    QString ss = QObject::tr("Generating Pole Figures for Phase %1").arg(phase);
    notifyStatusMessage(getMessagePrefix(), getHumanLabel(), ss);

    switch(m_CrystalStructures[phase])
    {
      case Ebsd::CrystalStructure::Cubic_High:
        figures = makePoleFigures<CubicOps>(config);
        break;
      case Ebsd::CrystalStructure::Cubic_Low:
        figures = makePoleFigures<CubicLowOps>(config);
        break;
      case Ebsd::CrystalStructure::Hexagonal_High:
        figures = makePoleFigures<HexagonalOps>(config);
        break;
      case Ebsd::CrystalStructure::Hexagonal_Low:
        figures = makePoleFigures<HexagonalLowOps>(config);
        break;
      case Ebsd::CrystalStructure::Trigonal_High:
        //   figures = makePoleFigures<TrigonalOps>(config);
        notifyWarningMessage(getHumanLabel(), "Trigonal High Symmetry is not supported for Pole figures. This phase will be omitted from results", -1010);
        break;
      case Ebsd::CrystalStructure::Trigonal_Low:
        //  figures = makePoleFigures<TrigonalLowOps>(config);
        notifyWarningMessage(getHumanLabel(), "Trigonal Low Symmetry is not supported for Pole figures. This phase will be omitted from results", -1010);
        break;
      case Ebsd::CrystalStructure::Tetragonal_High:
        //  figures = makePoleFigures<TetragonalOps>(config);
        notifyWarningMessage(getHumanLabel(), "Tetragonal High Symmetry is not supported for Pole figures. This phase will be omitted from results", -1010);
        break;
      case Ebsd::CrystalStructure::Tetragonal_Low:
        //  figures = makePoleFigures<TetragonalLowOps>(config);
        notifyWarningMessage(getHumanLabel(), "Tetragonal Low Symmetry is not supported for Pole figures. This phase will be omitted from results", -1010);
        break;
      case Ebsd::CrystalStructure::OrthoRhombic:
        figures = makePoleFigures<OrthoRhombicOps>(config);
        break;
      case Ebsd::CrystalStructure::Monoclinic:
        figures = makePoleFigures<MonoclinicOps>(config);
        break;
      case Ebsd::CrystalStructure::Triclinic:
        figures = makePoleFigures<TriclinicOps>(config);
        break;
      default:
        break;

    }

    if (figures.size() == 3)
    {
      QImage combinedImage = PoleFigureImageUtilities::Create3ImagePoleFigure(figures[0].get(), figures[1].get(), figures[2].get(), config, getImageLayout());
      writeImage(combinedImage, label);
    }
  }

  /* Let the GUI know we are done with this filter */
  notifyStatusMessage(getHumanLabel(), "Complete");
}