// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
int H5PrimaryStatsDataDelegate::readPrimaryStatsData(PrimaryStatsData* data, hid_t groupId)
{
  int err = 0;
  //Read the NumFields
  err = readBoundaryArea(data, groupId);

  //Read the PhaseFraction
  err = readPhaseFraction(data, groupId);

  // Read the Grain Diameter Info
  err = readGrainDiameterInfo(data, groupId);

  // Read the Grain Size Distribution
  uint32_t dType = readDistributionType(groupId, DREAM3D::HDF5::Grain_Size_Distribution);
  data->setGrainSize_DistType(dType);
  data->setGrainSizeDistribution(createDistributionVector(data->getGrainSize_DistType()));
  err = readDistributionData(groupId,
                DREAM3D::HDF5::Grain_Size_Distribution,
                data->getGrainSizeDistribution());

   // Read the Bin Numbers
   err = readBinNumbers(data, groupId);

   // Read the B Over A
   dType = readDistributionType(groupId, DREAM3D::HDF5::Grain_SizeVBoverA_Distributions);
   data->setBOverA_DistType(dType);
   data->setGrainSize_BOverA( createDistributionVector(data->getBOverA_DistType()));
   err = readDistributionData(groupId,
                                DREAM3D::HDF5::Grain_SizeVBoverA_Distributions,
                                data->getGrainSize_BOverA());

   // Read the C Over A
   dType = readDistributionType(groupId, DREAM3D::HDF5::Grain_SizeVCoverA_Distributions);
   data->setCOverA_DistType(dType);
   data->setGrainSize_COverA( createDistributionVector(data->getCOverA_DistType()));
   err = readDistributionData(groupId,
                                DREAM3D::HDF5::Grain_SizeVCoverA_Distributions,
                                data->getGrainSize_COverA());

   // Read the Neighbors
   dType = readDistributionType(groupId, DREAM3D::HDF5::Grain_SizeVNeighbors_Distributions);
   data->setNeighbors_DistType(dType);
   data->setGrainSize_Neighbors( createDistributionVector(data->getNeighbors_DistType()));
   err = readDistributionData(groupId,
                                DREAM3D::HDF5::Grain_SizeVNeighbors_Distributions,
                                data->getGrainSize_Neighbors());

   // Read the Omegas
   dType = readDistributionType(groupId, DREAM3D::HDF5::Grain_SizeVOmega3_Distributions);
   data->setOmegas_DistType(dType);
   data->setGrainSize_Omegas( createDistributionVector(data->getOmegas_DistType()));
   err = readDistributionData(groupId,
                                DREAM3D::HDF5::Grain_SizeVOmega3_Distributions,
                                data->getGrainSize_Omegas());

   // Read the Misorientation Bins
   FloatArrayType::Pointer misoBins = FloatArrayType::CreateArray(0, DREAM3D::HDF5::MisorientationBins);
   err = misoBins->readH5Data(groupId);
   if (err < 0)
   {
     misoBins = FloatArrayType::NullPointer();
   }
   data->setMisorientationBins(misoBins);
   err = readMDFWeights(groupId, data);

   // Read the ODF Data
   FloatArrayType::Pointer odfBins = FloatArrayType::CreateArray(0, DREAM3D::HDF5::ODF);
   err = odfBins->readH5Data(groupId);
   if (err < 0)
   {
     odfBins = FloatArrayType::NullPointer();
   }
   data->setODF(odfBins);
   err = readODFWeights(groupId, data);

   // Read the Axis ODF Data
   FloatArrayType::Pointer axisOdfBins = FloatArrayType::CreateArray(0, DREAM3D::HDF5::AxisOrientation);
   err = axisOdfBins->readH5Data(groupId);
   if (err < 0)
   {
     axisOdfBins = FloatArrayType::NullPointer();
   }
   data->setAxisOrientation(axisOdfBins);
   err = readAxisODFWeights(groupId, data);

  return err;
}
Beispiel #2
0
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void InsertAtoms::execute()
{
  setErrorCondition(0);
  dataCheck();
  if(getErrorCondition() < 0) { return; }

  // Validate that the selected AvgQuats array has tuples equal to the largest
  // Feature Id; the filter would not crash otherwise, but the user should
  // be notified of unanticipated behavior ; this cannot be done in the dataCheck since
  // we don't have acces to the data yet
  int32_t numFeaturesIn = static_cast<int32_t>(m_AvgQuatsPtr.lock()->getNumberOfTuples());
  bool mismatchedFeatures = true;
  int32_t largestFeature = 0;
  size_t numTuples = m_SurfaceMeshFaceLabelsPtr.lock()->getNumberOfTuples();
  for (size_t i = 0; i < numTuples; i++)
  {
    if (m_SurfaceMeshFaceLabels[2 * i] > largestFeature)
    {
      largestFeature = m_SurfaceMeshFaceLabels[2 * i];
      if (largestFeature >= numFeaturesIn)
      {
        mismatchedFeatures = true;
        break;
      }
    }
    else if (m_SurfaceMeshFaceLabels[2 * i + 1] > largestFeature)
    {
      largestFeature = m_SurfaceMeshFaceLabels[2 * i + 1];
      if (largestFeature >= numFeaturesIn)
      {
        mismatchedFeatures = true;
        break;
      }
    }
  }

  if (mismatchedFeatures == true)
  {
    QString ss = QObject::tr("The number of Features in the AvgQuats array (%1) is larger than the largest Feature Id in the SurfaceMeshFaceLabels array").arg(numFeaturesIn);
    setErrorCondition(-5555);
    notifyErrorMessage(getHumanLabel(), ss, getErrorCondition());
    return;
  }

  if (largestFeature != (numFeaturesIn - 1))
  {
    QString ss = QObject::tr("The number of Features in the AvgQuats array (%1) does not match the largest Feature Id in the SurfaceMeshFaceLabels array").arg(numFeaturesIn);
    setErrorCondition(-5555);
    notifyErrorMessage(getHumanLabel(), ss, getErrorCondition());
    return;
  }

  FloatVec3_t latticeConstants;
  latticeConstants.x = m_LatticeConstants.x / 10000.0;
  latticeConstants.y = m_LatticeConstants.y / 10000.0;
  latticeConstants.z = m_LatticeConstants.z / 10000.0;

  DataContainer::Pointer sm = getDataContainerArray()->getDataContainer(getSurfaceMeshFaceLabelsArrayPath().getDataContainerName());
  SIMPL_RANDOMNG_NEW()

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

  // pull down faces
  TriangleGeom::Pointer triangleGeom = sm->getGeometryAs<TriangleGeom>();
  int64_t numFaces = m_SurfaceMeshFaceLabelsPtr.lock()->getNumberOfTuples();

  // create array to hold bounding vertices for each face
  FloatArrayType::Pointer llPtr = FloatArrayType::CreateArray(3, "Lower_Left_Internal_Use_Only");
  FloatArrayType::Pointer urPtr = FloatArrayType::CreateArray(3, "Upper_Right_Internal_Use_Only");
  float* ll = llPtr->getPointer(0);
  float* ur = urPtr->getPointer(0);
  VertexGeom::Pointer faceBBs = VertexGeom::CreateGeometry(2 * numFaces, "faceBBs");

  // walk through faces to see how many features there are
  int32_t g1 = 0, g2 = 0;
  int32_t maxFeatureId = 0;
  for (int64_t i = 0; i < numFaces; i++)
  {
    g1 = m_SurfaceMeshFaceLabels[2 * i];
    g2 = m_SurfaceMeshFaceLabels[2 * i + 1];
    if (g1 > maxFeatureId) { maxFeatureId = g1; }
    if (g2 > maxFeatureId) { maxFeatureId = g2; }
  }

  // add one to account for feature 0
  int32_t numFeatures = maxFeatureId + 1;

  // create a dynamic list array to hold face lists
  Int32Int32DynamicListArray::Pointer faceLists = Int32Int32DynamicListArray::New();
  QVector<int32_t> linkCount(numFeatures, 0);

  // fill out lists with number of references to cells
  typedef boost::shared_array<int32_t> SharedInt32Array_t;
  SharedInt32Array_t linkLocPtr(new int32_t[numFaces]);
  int32_t* linkLoc = linkLocPtr.get();

  ::memset(linkLoc, 0, numFaces * sizeof(int32_t));

  // traverse data to determine number of faces belonging to each feature
  for (int64_t i = 0; i < numFaces; i++)
  {
    g1 = m_SurfaceMeshFaceLabels[2 * i];
    g2 = m_SurfaceMeshFaceLabels[2 * i + 1];
    if (g1 > 0) { linkCount[g1]++; }
    if (g2 > 0) { linkCount[g2]++; }
  }

  // now allocate storage for the faces
  faceLists->allocateLists(linkCount);

  // traverse data again to get the faces belonging to each feature
  for (int64_t i = 0; i < numFaces; i++)
  {
    g1 = m_SurfaceMeshFaceLabels[2 * i];
    g2 = m_SurfaceMeshFaceLabels[2 * i + 1];
    if (g1 > 0) { faceLists->insertCellReference(g1, (linkLoc[g1])++, i); }
    if (g2 > 0) { faceLists->insertCellReference(g2, (linkLoc[g2])++, i); }
    // find bounding box for each face
    GeometryMath::FindBoundingBoxOfFace(triangleGeom, i, ll, ur);
    faceBBs->setCoords(2 * i, ll);
    faceBBs->setCoords(2 * i + 1, ur);
  }

  // generate the list of sampling points fom subclass
  QVector<VertexGeom::Pointer> points(numFeatures);
  QVector<BoolArrayType::Pointer> inFeature(numFeatures);
  for (int32_t i = 0; i < numFeatures; i++)
  {
    points[i] = VertexGeom::CreateGeometry(0, "_INTERNAL_USE_ONLY_points");
    inFeature[i] = BoolArrayType::CreateArray(0, "_INTERNAL_USE_ONLY_inside");
  }

  QuatF* avgQuats = reinterpret_cast<QuatF*>(m_AvgQuats);

#ifdef SIMPLib_USE_PARALLEL_ALGORITHMS
  if (doParallel == true)
  {
    tbb::parallel_for(tbb::blocked_range<size_t>(0, numFeatures),
                      InsertAtomsImpl(triangleGeom, faceLists, faceBBs, avgQuats, latticeConstants, m_Basis, points, inFeature), tbb::auto_partitioner());

  }
  else
#endif
  {
    InsertAtomsImpl serial(triangleGeom, faceLists, faceBBs, avgQuats, latticeConstants, m_Basis, points, inFeature);
    serial.checkPoints(0, numFeatures);
  }

  assign_points(points, inFeature);

  notifyStatusMessage(getHumanLabel(), "Complete");
}
Beispiel #3
0
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
FloatArrayType::Pointer AngleFileLoader::loadData()
{
  FloatArrayType::Pointer angles = FloatArrayType::NullPointer();

  // Make sure the input file variable is not empty
  if (m_InputFile.size() == 0)
  {
    setErrorMessage("Input File Path is empty");
    setErrorCode(-1);
    return angles;
  }

  QFileInfo fi(getInputFile());

  // Make sure the file exists on disk
  if (fi.exists() == false)
  {
    setErrorMessage("Input File does not exist at path");
    setErrorCode(-2);
    return angles;
  }

  // Make sure we have a valid angle representation
  if(m_AngleRepresentation != EulerAngles
      && m_AngleRepresentation != QuaternionAngles
      && m_AngleRepresentation != RodriguezAngles)
  {
    setErrorMessage("The Angle representation was not set to anything known to this code");
    setErrorCode(-3);
    return angles;
  }


  // The format of the file is quite simple. Comment lines start with a "#" symbol
  // The only Key-Value pair we are looking for is 'Angle Count' which will have
  // the total number of angles that will be read

  int numOrients = 0;
  QByteArray buf;

  // Open the file and read the first line
  QFile reader(getInputFile());
  if (!reader.open(QIODevice::ReadOnly | QIODevice::Text))
  {
    QString msg = QObject::tr("Angle file could not be opened: %1").arg(getInputFile());
    setErrorCode(-100);
    setErrorMessage(msg);
    return angles;
  }

  bool ok = false;
  buf = reader.readLine();
  while(buf[0] == '#')
  {
    buf = reader.readLine();
  }
  buf = buf.trimmed();

  //Split the next line into a pair of tokens delimited by the ":" character
  QList<QByteArray> tokens = buf.split(':');
  if(tokens.count() != 2)
  {
    QString msg = QObject::tr("Proper Header was not detected. The file should have a single header line of 'Angle Count:XXXX'");
    setErrorCode(-101);
    setErrorMessage(msg);
    return angles;
  }

  if(tokens[0].toStdString().compare("Angle Count") != 0)
  {
    QString msg = QObject::tr("Proper Header was not detected. The file should have a single header line of 'Angle Count:XXXX'");
    setErrorCode(-102);
    setErrorMessage(msg);
    return angles;
  }
  numOrients = tokens[1].toInt(&ok, 10);

  // Allocate enough for the angles
  QVector<size_t> dims(1, 5);
  angles = FloatArrayType::CreateArray(numOrients, dims, "EulerAngles_From_File");

  for(int i = 0; i < numOrients; i++)
  {
    float weight = 0.0f;
    float sigma = 1.0f;
    buf = reader.readLine();
    // Skip any lines that start with a '#' character
    if(buf[0] == '#') { continue; }
    buf = buf.trimmed();

    // Remove multiple Delimiters if wanted by the user.
    if (m_IgnoreMultipleDelimiters == true)
    {
      buf = buf.simplified();
    }
    tokens = buf.split( *(getDelimiter().toLatin1().data()));

    FOrientArrayType euler(3);
    if (m_AngleRepresentation == EulerAngles)
    {
      euler[0] = tokens[0].toFloat(&ok);
      euler[1] = tokens[1].toFloat(&ok);
      euler[2] = tokens[2].toFloat(&ok);
      weight = tokens[3].toFloat(&ok);
      sigma = tokens[4].toFloat(&ok);
    }
    else if (m_AngleRepresentation == QuaternionAngles)
    {
      FOrientArrayType quat(4);
      quat[0] = tokens[0].toFloat(&ok);
      quat[1] = tokens[1].toFloat(&ok);
      quat[2] = tokens[2].toFloat(&ok);
      quat[3] = tokens[3].toFloat(&ok);
      FOrientTransformsType::qu2eu(quat, euler);
      weight = tokens[4].toFloat(&ok);
      sigma = tokens[5].toFloat(&ok);
    }
    else if (m_AngleRepresentation == RodriguezAngles)
    {
      FOrientArrayType rod(4, 0.0);
      rod[0] = tokens[0].toFloat(&ok);
      rod[1] = tokens[1].toFloat(&ok);
      rod[2] = tokens[2].toFloat(&ok);
      FOrientTransformsType::ro2eu(rod, euler);
      weight = tokens[3].toFloat(&ok);
      sigma = tokens[4].toFloat(&ok);
    }

    // Values in File are in Radians and the user wants them in Degrees
    if (m_FileAnglesInDegrees == false && m_OutputAnglesInDegrees == true)
    {
      euler[0] = euler[0] * SIMPLib::Constants::k_RadToDeg;
      euler[1] = euler[1] * SIMPLib::Constants::k_RadToDeg;
      euler[2] = euler[2] * SIMPLib::Constants::k_RadToDeg;
    }
    // Values are in Degrees but user wants them in Radians
    else if (m_FileAnglesInDegrees == true && m_OutputAnglesInDegrees == false)
    {
      euler[0] = euler[0] * SIMPLib::Constants::k_DegToRad;
      euler[1] = euler[1] * SIMPLib::Constants::k_DegToRad;
      euler[2] = euler[2] * SIMPLib::Constants::k_DegToRad;
    }

    // Store the values into our array
    angles->setComponent(i, 0, euler[0]);
    angles->setComponent(i, 1, euler[1]);
    angles->setComponent(i, 2, euler[2]);
    angles->setComponent(i, 3, weight);
    angles->setComponent(i, 4, sigma);
    //   qDebug() << "reading line: " << i ;
  }



  return angles;
}
Beispiel #4
0
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void VisualizeGBCDGMT::execute()
{
  setErrorCondition(0);
  dataCheck();
  if(getErrorCondition() < 0) { return; }

  DataContainer::Pointer sm = getDataContainerArray()->getDataContainer(getGBCDArrayPath().getDataContainerName());

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

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

  QFile file(getOutputFile());
  if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
  {
    QString ss = QObject::tr("Error opening output file '%1'").arg(getOutputFile());
    setErrorCondition(-100);
    notifyErrorMessage(getHumanLabel(), ss, getErrorCondition());
    return;
  }

  FloatArrayType::Pointer gbcdDeltasArray = FloatArrayType::CreateArray(5, "GBCDDeltas");
  gbcdDeltasArray->initializeWithZeros();

  FloatArrayType::Pointer gbcdLimitsArray = FloatArrayType::CreateArray(10, "GBCDLimits");
  gbcdLimitsArray->initializeWithZeros();

  Int32ArrayType::Pointer gbcdSizesArray = Int32ArrayType::CreateArray(5, "GBCDSizes");
  gbcdSizesArray->initializeWithZeros();

  float* gbcdDeltas = gbcdDeltasArray->getPointer(0);
  int32_t* gbcdSizes = gbcdSizesArray->getPointer(0);
  float* gbcdLimits = gbcdLimitsArray->getPointer(0);

  // Original Ranges from Dave R.
  //m_GBCDlimits[0] = 0.0f;
  //m_GBCDlimits[1] = cosf(1.0f*m_pi);
  //m_GBCDlimits[2] = 0.0f;
  //m_GBCDlimits[3] = 0.0f;
  //m_GBCDlimits[4] = cosf(1.0f*m_pi);
  //m_GBCDlimits[5] = 2.0f*m_pi;
  //m_GBCDlimits[6] = cosf(0.0f);
  //m_GBCDlimits[7] = 2.0f*m_pi;
  //m_GBCDlimits[8] = 2.0f*m_pi;
  //m_GBCDlimits[9] = cosf(0.0f);

  // Greg R. Ranges
  gbcdLimits[0] = 0.0f;
  gbcdLimits[1] = 0.0f;
  gbcdLimits[2] = 0.0f;
  gbcdLimits[3] = -sqrtf(SIMPLib::Constants::k_Pi / 2.0f);
  gbcdLimits[4] = -sqrtf(SIMPLib::Constants::k_Pi / 2.0f);
  gbcdLimits[5] = SIMPLib::Constants::k_Pi / 2.0f;
  gbcdLimits[6] = 1.0f;
  gbcdLimits[7] = SIMPLib::Constants::k_Pi / 2.0f;
  gbcdLimits[8] = sqrtf(SIMPLib::Constants::k_Pi / 2.0f);
  gbcdLimits[9] = sqrtf(SIMPLib::Constants::k_Pi / 2.0f);

  // get num components of GBCD
  QVector<size_t> cDims = m_GBCDPtr.lock()->getComponentDimensions();

  gbcdSizes[0] = cDims[0];
  gbcdSizes[1] = cDims[1];
  gbcdSizes[2] = cDims[2];
  gbcdSizes[3] = cDims[3];
  gbcdSizes[4] = cDims[4];

  gbcdDeltas[0] = (gbcdLimits[5] - gbcdLimits[0]) / float(gbcdSizes[0]);
  gbcdDeltas[1] = (gbcdLimits[6] - gbcdLimits[1]) / float(gbcdSizes[1]);
  gbcdDeltas[2] = (gbcdLimits[7] - gbcdLimits[2]) / float(gbcdSizes[2]);
  gbcdDeltas[3] = (gbcdLimits[8] - gbcdLimits[3]) / float(gbcdSizes[3]);
  gbcdDeltas[4] = (gbcdLimits[9] - gbcdLimits[4]) / float(gbcdSizes[4]);

  float vec[3] = { 0.0f, 0.0f, 0.0f };
  float vec2[3] = { 0.0f, 0.0f, 0.0f };
  float rotNormal[3] = { 0.0f, 0.0f, 0.0f };
  float rotNormal2[3] = { 0.0f, 0.0f, 0.0f };
  float sqCoord[2] = { 0.0f, 0.0f };
  float dg[3][3] = { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } };
  float dgt[3][3] = { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } };
  float dg1[3][3] = { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } };
  float dg2[3][3] = { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } };
  float sym1[3][3] = { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } };
  float sym2[3][3] = { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } };
  float sym2t[3][3] = { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } };
  float mis_euler1[3] = { 0.0f, 0.0f, 0.0f };

  float misAngle = m_MisorientationRotation.angle * SIMPLib::Constants::k_PiOver180;
  float normAxis[3] = { m_MisorientationRotation.h, m_MisorientationRotation.k, m_MisorientationRotation.l };
  MatrixMath::Normalize3x1(normAxis);
  // convert axis angle to matrix representation of misorientation
  FOrientArrayType om(9, 0.0f);
  FOrientTransformsType::ax2om(FOrientArrayType(normAxis[0], normAxis[1], normAxis[2], misAngle), om);
  om.toGMatrix(dg);

  // take inverse of misorientation variable to use for switching symmetry
  MatrixMath::Transpose3x3(dg, dgt);

  // Get our SpaceGroupOps pointer for the selected crystal structure
  SpaceGroupOps::Pointer orientOps = m_OrientationOps[m_CrystalStructures[m_PhaseOfInterest]];

  // get number of symmetry operators
  int32_t n_sym = orientOps->getNumSymOps();

  int32_t thetaPoints = 120;
  int32_t phiPoints = 30;
  float thetaRes = 360.0f / float(thetaPoints);
  float phiRes = 90.0f / float(phiPoints);
  float theta = 0.0f, phi = 0.0f;
  float thetaRad = 0.0f, phiRad = 0.0f;
  float degToRad = SIMPLib::Constants::k_PiOver180;
  float sum = 0.0f;
  int32_t count = 0;
  bool nhCheck = false;
  int32_t hemisphere = 0;

  int32_t shift1 = gbcdSizes[0];
  int32_t shift2 = gbcdSizes[0] * gbcdSizes[1];
  int32_t shift3 = gbcdSizes[0] * gbcdSizes[1] * gbcdSizes[2];
  int32_t shift4 = gbcdSizes[0] * gbcdSizes[1] * gbcdSizes[2] * gbcdSizes[3];

  int64_t totalGBCDBins = gbcdSizes[0] * gbcdSizes[1] * gbcdSizes[2] * gbcdSizes[3] * gbcdSizes[4] * 2;

  std::vector<float> gmtValues;

  for (int32_t k = 0; k < phiPoints + 1; k++)
  {
    for (int32_t l = 0; l < thetaPoints + 1; l++)
    {
      // get (x,y) for stereographic projection pixel
      theta = float(l) * thetaRes;
      phi = float(k) * phiRes;
      thetaRad = theta * degToRad;
      phiRad = phi * degToRad;
      sum = 0.0f;
      count = 0;
      vec[0] = sinf(phiRad) * cosf(thetaRad);
      vec[1] = sinf(phiRad) * sinf(thetaRad);
      vec[2] = cosf(phiRad);
      MatrixMath::Multiply3x3with3x1(dgt, vec, vec2);

      // Loop over all the symetry operators in the given cystal symmetry
      for (int32_t i = 0; i < n_sym; i++)
      {
        // get symmetry operator1
        orientOps->getMatSymOp(i, sym1);
        for (int32_t j = 0; j < n_sym; j++)
        {
          // get symmetry operator2
          orientOps->getMatSymOp(j, sym2);
          MatrixMath::Transpose3x3(sym2, sym2t);
          // calculate symmetric misorientation
          MatrixMath::Multiply3x3with3x3(dg, sym2t, dg1);
          MatrixMath::Multiply3x3with3x3(sym1, dg1, dg2);
          // convert to euler angle
          FOrientArrayType mEuler(mis_euler1, 3);
          FOrientTransformsType::om2eu(FOrientArrayType(dg2), mEuler);
          if (mis_euler1[0] < SIMPLib::Constants::k_PiOver2 && mis_euler1[1] < SIMPLib::Constants::k_PiOver2 && mis_euler1[2] < SIMPLib::Constants::k_PiOver2)
          {
            mis_euler1[1] = cosf(mis_euler1[1]);
            // find bins in GBCD
            int32_t location1 = int32_t((mis_euler1[0] - gbcdLimits[0]) / gbcdDeltas[0]);
            int32_t location2 = int32_t((mis_euler1[1] - gbcdLimits[1]) / gbcdDeltas[1]);
            int32_t location3 = int32_t((mis_euler1[2] - gbcdLimits[2]) / gbcdDeltas[2]);
            // find symmetric poles using the first symmetry operator
            MatrixMath::Multiply3x3with3x1(sym1, vec, rotNormal);
            // get coordinates in square projection of crystal normal parallel to boundary normal
            nhCheck = getSquareCoord(rotNormal, sqCoord);
            // Note the switch to have theta in the 4 slot and cos(Phi) int he 3 slot
            int32_t location4 = int32_t((sqCoord[0] - gbcdLimits[3]) / gbcdDeltas[3]);
            int32_t location5 = int32_t((sqCoord[1] - gbcdLimits[4]) / gbcdDeltas[4]);
            if (location1 >= 0 && location2 >= 0 && location3 >= 0 && location4 >= 0 && location5 >= 0 &&
                location1 < gbcdSizes[0] && location2 < gbcdSizes[1] && location3 < gbcdSizes[2] && location4 < gbcdSizes[3] && location5 < gbcdSizes[4])
            {
              hemisphere = 0;
              if (nhCheck == false) { hemisphere = 1; }
              sum += m_GBCD[(m_PhaseOfInterest * totalGBCDBins) + 2 * ((location5 * shift4) + (location4 * shift3) + (location3 * shift2) + (location2 * shift1) + location1) + hemisphere];
              count++;
            }
          }

          // again in second crystal reference frame
          // calculate symmetric misorientation
          MatrixMath::Multiply3x3with3x3(dgt, sym2, dg1);
          MatrixMath::Multiply3x3with3x3(sym1, dg1, dg2);
          // convert to euler angle
          FOrientTransformsType::om2eu(FOrientArrayType(dg2), mEuler);
          if (mis_euler1[0] < SIMPLib::Constants::k_PiOver2 && mis_euler1[1] < SIMPLib::Constants::k_PiOver2 && mis_euler1[2] < SIMPLib::Constants::k_PiOver2)
          {
            mis_euler1[1] = cosf(mis_euler1[1]);
            // find bins in GBCD
            int32_t location1 = int32_t((mis_euler1[0] - gbcdLimits[0]) / gbcdDeltas[0]);
            int32_t location2 = int32_t((mis_euler1[1] - gbcdLimits[1]) / gbcdDeltas[1]);
            int32_t location3 = int32_t((mis_euler1[2] - gbcdLimits[2]) / gbcdDeltas[2]);
            // find symmetric poles using the first symmetry operator
            MatrixMath::Multiply3x3with3x1(sym1, vec2, rotNormal2);
            // get coordinates in square projection of crystal normal parallel to boundary normal
            nhCheck = getSquareCoord(rotNormal2, sqCoord);
            // Note the switch to have theta in the 4 slot and cos(Phi) int he 3 slot
            int32_t location4 = int32_t((sqCoord[0] - gbcdLimits[3]) / gbcdDeltas[3]);
            int32_t location5 = int32_t((sqCoord[1] - gbcdLimits[4]) / gbcdDeltas[4]);
            if (location1 >= 0 && location2 >= 0 && location3 >= 0 && location4 >= 0 && location5 >= 0 &&
                location1 < gbcdSizes[0] && location2 < gbcdSizes[1] && location3 < gbcdSizes[2] && location4 < gbcdSizes[3] && location5 < gbcdSizes[4])
            {
              hemisphere = 0;
              if (nhCheck == false) { hemisphere = 1; }
              sum += m_GBCD[(m_PhaseOfInterest * totalGBCDBins) + 2 * ((location5 * shift4) + (location4 * shift3) + (location3 * shift2) + (location2 * shift1) + location1) + hemisphere];
              count++;
            }
          }
        }
      }
      gmtValues.push_back(theta);
      gmtValues.push_back((90.0f - phi));
      gmtValues.push_back(sum / float(count));
    }
  }

  FILE* f = NULL;
  f = fopen(m_OutputFile.toLatin1().data(), "wb");
  if (NULL == f)
  {
    QString ss = QObject::tr("Error opening output file '%1'").arg(m_OutputFile);
    setErrorCondition(-1);
    notifyErrorMessage(getHumanLabel(), ss, getErrorCondition());
    return;
  }

  // Remember to use the original Angle in Degrees!!!!
  fprintf(f, "%.1f %.1f %.1f %.1f\n", m_MisorientationRotation.h, m_MisorientationRotation.k, m_MisorientationRotation.l, m_MisorientationRotation.angle);
  size_t size = gmtValues.size() / 3;

  for (size_t i = 0; i < size; i++)
  {
    fprintf(f, "%f %f %f\n", gmtValues[3 * i], gmtValues[3 * i + 1], gmtValues[3 * i + 2]);
  }
  fclose(f);

  /* Let the GUI know we are done with this filter */
  notifyStatusMessage(getHumanLabel(), "Complete");
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void StatsGenODFWidget::on_m_CalculateODFBtn_clicked()
{
  int err = 0;

  QwtArray<float> e1s;
  QwtArray<float> e2s;
  QwtArray<float> e3s;
  QwtArray<float> weights;
  QwtArray<float> sigmas;
  QwtArray<float> odf;
  SGODFTableModel* tableModel = NULL;

  if(weightSpreadGroupBox->isChecked() )
  {
    tableModel = m_ODFTableModel;
  }
  else
  {
    tableModel = m_OdfBulkTableModel;
  }


  e1s = tableModel->getData(SGODFTableModel::Euler1);
  e2s = tableModel->getData(SGODFTableModel::Euler2);
  e3s = tableModel->getData(SGODFTableModel::Euler3);
  weights = tableModel->getData(SGODFTableModel::Weight);
  sigmas = tableModel->getData(SGODFTableModel::Sigma);


  // Convert from Degrees to Radians
  for(int i = 0; i < e1s.size(); i++)
  {
    e1s[i] = e1s[i] * M_PI / 180.0;
    e2s[i] = e2s[i] * M_PI / 180.0;
    e3s[i] = e3s[i] * M_PI / 180.0;
  }
  size_t numEntries = e1s.size();

  int imageSize = pfImageSize->value();
  int lamberSize = pfLambertSize->value();
  int numColors = 16;
  int npoints = pfSamplePoints->value();
  QVector<size_t> dims(1, 3);
  FloatArrayType::Pointer eulers = FloatArrayType::CreateArray(npoints, dims, "Eulers");
  PoleFigureConfiguration_t config;
  QVector<UInt8ArrayType::Pointer> figures;

  if ( Ebsd::CrystalStructure::Cubic_High == m_CrystalStructure)
  {
    // We now need to resize all the arrays here to make sure they are all allocated
    odf.resize(CubicOps::k_OdfSize);
    Texture::CalculateCubicODFData(e1s.data(), e2s.data(), e3s.data(),
                                   weights.data(), sigmas.data(), true,
                                   odf.data(), numEntries);

    err = StatsGen::GenCubicODFPlotData(odf.data(), eulers->getPointer(0), npoints);

    CubicOps ops;
    config.eulers = eulers.get();
    config.imageDim = imageSize;
    config.lambertDim = lamberSize;
    config.numColors = numColors;

    figures = ops.generatePoleFigure(config);
  }
  else if ( Ebsd::CrystalStructure::Hexagonal_High == m_CrystalStructure)
  {
    // We now need to resize all the arrays here to make sure they are all allocated
    odf.resize(HexagonalOps::k_OdfSize);
    Texture::CalculateHexODFData(e1s.data(), e2s.data(), e3s.data(),
                                 weights.data(), sigmas.data(), true,
                                 odf.data(), numEntries);

    err = StatsGen::GenHexODFPlotData(odf.data(), eulers->getPointer(0), npoints);

    HexagonalOps ops;
    config.eulers = eulers.get();
    config.imageDim = imageSize;
    config.lambertDim = lamberSize;
    config.numColors = numColors;

    figures = ops.generatePoleFigure(config);
  }
  else if ( Ebsd::CrystalStructure::OrthoRhombic == m_CrystalStructure)
  {
    //    // We now need to resize all the arrays here to make sure they are all allocated
    odf.resize(OrthoRhombicOps::k_OdfSize);
    Texture::CalculateOrthoRhombicODFData(e1s.data(), e2s.data(), e3s.data(),
                                          weights.data(), sigmas.data(), true,
                                          odf.data(), numEntries);

    err = StatsGen::GenOrthoRhombicODFPlotData(odf.data(), eulers->getPointer(0), npoints);

    OrthoRhombicOps ops;
    config.eulers = eulers.get();
    config.imageDim = imageSize;
    config.lambertDim = lamberSize;
    config.numColors = numColors;

    figures = ops.generatePoleFigure(config);
  }

  if (err == 1)
  {
    //TODO: Present Error Message
    return;
  }

  QImage image = PoleFigureImageUtilities::Create3ImagePoleFigure(figures[0].get(), figures[1].get(), figures[2].get(), config, imageLayout->currentIndex());
  m_PoleFigureLabel->setPixmap(QPixmap::fromImage(image));

  // Enable the MDF tab
  if (m_MDFWidget != NULL)
  {
    m_MDFWidget->setEnabled(true);
    m_MDFWidget->updateMDFPlot(odf);
  }
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void StatsGenODFWidget::on_loadODFTextureBtn_clicked()
{

  QString file = angleFilePath->text();
  if(true == file.isEmpty())
  {
    return;
  }

  QFileInfo fi(angleFilePath->text());
  if(fi.exists() == false)
  {
    return;
  }

  size_t count = 0;
  QVector<float> e1s(count);
  QVector<float> e2s(count);
  QVector<float> e3s(count);
  QVector<float> weights(count);
  QVector<float> sigmas(count);

  QProgressDialog progress("Loading Data ....", "Cancel", 0, 3, this);
  progress.setWindowModality(Qt::WindowModal);
  progress.setMinimumDuration(2000);

  if (fi.suffix().compare(Ebsd::Ang::FileExt) == 0)
  {
    progress.setValue(1);
    progress.setLabelText("[1/3] Reading File ...");
    AngReader loader;
    loader.setFileName(angleFilePath->text());
    int err = loader.readFile();
    if(err < 0)
    {
      QMessageBox::critical(this, "Error loading the ANG file", loader.getErrorMessage(), QMessageBox::Ok);
      return;
    }
    float* phi1 = loader.getPhi1Pointer();
    float* phi = loader.getPhiPointer();
    float* phi2 = loader.getPhi2Pointer();

    int xDim = loader.getXDimension();
    int yDim = loader.getYDimension();
    count = xDim * yDim;
    e1s.resize(count);
    e2s.resize(count);
    e3s.resize(count);
    weights.resize(count);
    sigmas.resize(count);
    for(size_t i = 0; i < count; ++i)
    {
      e1s[i] = phi1[i];
      e2s[i] = phi[i];
      e3s[i] = phi2[i];
      weights[i] = 1.0;
      sigmas[i] = 0.0;
    }
  }
  else if (fi.suffix().compare(Ebsd::Ctf::FileExt) == 0)
  {
    progress.setValue(1);
    progress.setLabelText("[1/3] Reading File ...");
    CtfReader loader;
    loader.setFileName(angleFilePath->text());
    int err = loader.readFile();
    if(err < 0)
    {
      QMessageBox::critical(this, "Error loading the CTF file", loader.getErrorMessage(), QMessageBox::Ok);
      return;
    }
    float* phi1 = loader.getEuler1Pointer();
    float* phi = loader.getEuler2Pointer();
    float* phi2 = loader.getEuler3Pointer();

    int xDim = loader.getXDimension();
    int yDim = loader.getYDimension();
    count = xDim * yDim;
    e1s.resize(count);
    e2s.resize(count);
    e3s.resize(count);
    weights.resize(count);
    sigmas.resize(count);
    for(size_t i = 0; i < count; ++i)
    {
      e1s[i] = phi1[i];
      e2s[i] = phi[i];
      e3s[i] = phi2[i];
      weights[i] = 1.0;
      sigmas[i] = 0.0;
    }
  }
  else
  {
    progress.setValue(1);
    progress.setLabelText("[1/3] Reading File ...");
    AngleFileLoader::Pointer loader = AngleFileLoader::New();
    loader->setInputFile(angleFilePath->text());
    loader->setAngleRepresentation(angleRepresentation->currentIndex());
    loader->setFileAnglesInDegrees(anglesInDegrees->isChecked());
    loader->setOutputAnglesInDegrees(true);
    QString delim;
    int index = delimiter->currentIndex();
    switch(index)
    {
      case 0:
        delim = " ";
        break;
      case 1:
        delim = "\t";
        break;
      case 2:
        delim = ",";
        break;
      case 3:
        delim = ";";
        break;
      default:
        delim = " ";

    }

    loader->setDelimiter(delim);
    FloatArrayType::Pointer data = loader->loadData();
    if (loader->getErrorCode() < 0)
    {
      QMessageBox::critical(this, "Error Loading Angle data", loader->getErrorMessage(), QMessageBox::Ok);
      return;
    }
    count = data->getNumberOfTuples();
    e1s.resize(count);
    e2s.resize(count);
    e3s.resize(count);
    weights.resize(count);
    sigmas.resize(count);
    for(size_t i = 0; i < count; ++i)
    {
      e1s[i] = data->getComponent(i, 0);
      e2s[i] = data->getComponent(i, 1);
      e3s[i] = data->getComponent(i, 2);
      weights[i] = data->getComponent(i, 3);
      sigmas[i] = data->getComponent(i, 4);
    }

  }

  progress.setValue(2);
  progress.setLabelText("[2/3] Rendering Pole Figure ...");

  m_OdfBulkTableModel->removeRows(0, m_OdfBulkTableModel->rowCount());

#if 1
  m_OdfBulkTableModel->blockSignals(true);
  m_OdfBulkTableModel->setColumnData(SGODFTableModel::Euler1, e1s);
  m_OdfBulkTableModel->setColumnData(SGODFTableModel::Euler2, e2s);
  m_OdfBulkTableModel->setColumnData(SGODFTableModel::Euler3, e3s);
  m_OdfBulkTableModel->setColumnData(SGODFTableModel::Weight, weights);
  m_OdfBulkTableModel->setColumnData(SGODFTableModel::Sigma, sigmas);
  m_OdfBulkTableModel->blockSignals(false);
#endif
  on_m_CalculateODFBtn_clicked();
  progress.setValue(3);
}
    void generate(size_t start, size_t end) const
    {

      // We want to work with the raw pointers for speed so get those pointers.
      float* m_GBCDdeltas = m_GbcdDeltasArray->getPointer(0);
      float* m_GBCDlimits = m_GbcdLimitsArray->getPointer(0);
      int* m_GBCDsizes = m_GbcdSizesArray->getPointer(0);
      int32_t* m_Bins = m_GbcdBinsArray->getPointer(0);
      bool* m_HemiCheck = m_GbcdHemiCheckArray->getPointer(0);

      int32_t* m_Labels = m_LabelsArray->getPointer(0);
      double* m_Normals = m_NormalsArray->getPointer(0);
      int32_t* m_Phases = m_PhasesArray->getPointer(0);
      float* m_Eulers = m_EulersArray->getPointer(0);
      uint32_t* m_CrystalStructures = m_CrystalStructuresArray->getPointer(0);


      int32_t j = 0;//, j4;
      int32_t k = 0;//, k4;
      int32_t m = 0;
      int32_t temp = 0;
      //bool gbcd_indices_good;
      int32_t feature1 = 0, feature2 = 0;
      int32_t inversion = 1;
      float g1ea[3] = { 0.0f, 0.0f, 0.0f }, g2ea[3] = { 0.0f, 0.0f, 0.0f };
      float g1[3][3] = { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } }, g2[3][3] = { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } };
      float g1s[3][3] = { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } }, g2s[3][3] = { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } };
      float sym1[3][3] = { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } }, sym2[3][3] = { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } };
      float g2t[3][3] = { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } }, dg[3][3] = { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } };
      float euler_mis[3] = { 0.0f, 0.0f, 0.0f };
      float normal[3] = { 0.0f, 0.0f, 0.0f };
      float xstl1_norm1[3] = { 0.0f, 0.0f, 0.0f };
      int32_t gbcd_index = 0;
      float sqCoord[2] = { 0.0f, 0.0f }, sqCoordInv[2] = { 0.0f, 0.0f };
      bool nhCheck = false, nhCheckInv = true;
      int32_t SYMcounter = 0;
      int64_t TRIcounter = static_cast<int64_t>(start - startOffset);
      int64_t TRIcounterShift = 0;

      for (size_t i = start; i < end; i++)
      {
        SYMcounter = 0;
        feature1 = m_Labels[2 * i];
        feature2 = m_Labels[2 * i + 1];
        normal[0] = m_Normals[3 * i];
        normal[1] = m_Normals[3 * i + 1];
        normal[2] = m_Normals[3 * i + 2];

        if (feature1 < 0 || feature2 < 0) { continue; }

        if (m_Phases[feature1] == m_Phases[feature2] && m_Phases[feature1] > 0)
        {
          TRIcounterShift = (TRIcounter * numEntriesPerTri);
          uint32_t cryst = m_CrystalStructures[m_Phases[feature1]];
          for (int32_t q = 0; q < 2; q++)
          {
            if (q == 1)
            {
              temp = feature1;
              feature1 = feature2;
              feature2 = temp;
              normal[0] = -normal[0];
              normal[1] = -normal[1];
              normal[2] = -normal[2];
            }
            for (m = 0; m < 3; m++)
            {
              g1ea[m] = m_Eulers[3 * feature1 + m];
              g2ea[m] = m_Eulers[3 * feature2 + m];
            }

            FOrientArrayType om(9, 0.0f);
            FOrientTransformsType::eu2om(FOrientArrayType(g1ea, 3), om);
            om.toGMatrix(g1);

            FOrientTransformsType::eu2om(FOrientArrayType(g2ea, 3), om);
            om.toGMatrix(g2);

            int32_t nsym = m_OrientationOps[cryst]->getNumSymOps();
            for (j = 0; j < nsym; j++)
            {
              // rotate g1 by symOp
              m_OrientationOps[cryst]->getMatSymOp(j, sym1);
              MatrixMath::Multiply3x3with3x3(sym1, g1, g1s);
              // get the crystal directions along the triangle normals
              MatrixMath::Multiply3x3with3x1(g1s, normal, xstl1_norm1);
              // get coordinates in square projection of crystal normal parallel to boundary normal
              nhCheck = getSquareCoord(xstl1_norm1, sqCoord);
              if (inversion == 1)
              {
                sqCoordInv[0] = -sqCoord[0];
                sqCoordInv[1] = -sqCoord[1];
                if (nhCheck == false) { nhCheckInv = true; }
                else { nhCheckInv = false; }
              }

              for (k = 0; k < nsym; k++)
              {
                // calculate the symmetric misorienation
                m_OrientationOps[cryst]->getMatSymOp(k, sym2);
                // rotate g2 by symOp
                MatrixMath::Multiply3x3with3x3(sym2, g2, g2s);
                // transpose rotated g2
                MatrixMath::Transpose3x3(g2s, g2t);
                // calculate delta g
                MatrixMath::Multiply3x3with3x3(g1s, g2t, dg);
                // translate matrix to euler angles
                FOrientArrayType om(dg);

                FOrientArrayType eu(euler_mis, 3);
                FOrientTransformsType::om2eu(om, eu);

                if (euler_mis[0] < SIMPLib::Constants::k_PiOver2 && euler_mis[1] < SIMPLib::Constants::k_PiOver2 && euler_mis[2] < SIMPLib::Constants::k_PiOver2)
                {
                  // PHI euler angle is stored in GBCD as cos(PHI)
                  euler_mis[1] = cosf(euler_mis[1]);
                  //get the indexes that this point would be in the GBCD histogram
                  gbcd_index = GBCDIndex(m_GBCDdeltas, m_GBCDsizes, m_GBCDlimits, euler_mis, sqCoord);
                  if (gbcd_index != -1)
                  {
                    m_HemiCheck[TRIcounterShift + SYMcounter] = nhCheck;
                    m_Bins[TRIcounterShift + SYMcounter] = gbcd_index;
                  }
                  SYMcounter++;
                  if (inversion == 1)
                  {
                    gbcd_index = GBCDIndex(m_GBCDdeltas, m_GBCDsizes, m_GBCDlimits, euler_mis, sqCoordInv);
                    if (gbcd_index != -1)
                    {
                      m_HemiCheck[TRIcounterShift + SYMcounter] = nhCheckInv;
                      m_Bins[TRIcounterShift + SYMcounter] = gbcd_index;
                    }
                    SYMcounter++;
                  }
                }
                else { SYMcounter += 2; }
              }
            }
          }
        }
        TRIcounter++;
      }
    }
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void VisualizeGBCDPoleFigure::execute()
{
  setErrorCondition(0);
  dataCheck();
  if(getErrorCondition() < 0) { 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
  QFileInfo fi(getOutputFile());

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

  QFile file(getOutputFile());
  if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
  {
    QString ss = QObject::tr("Error opening output file '%1'").arg(getOutputFile());
    setErrorCondition(-100);
    notifyErrorMessage(getHumanLabel(), ss, getErrorCondition());
    return;
  }

  FloatArrayType::Pointer gbcdDeltasArray = FloatArrayType::CreateArray(5, "GBCDDeltas");
  gbcdDeltasArray->initializeWithZeros();

  FloatArrayType::Pointer gbcdLimitsArray = FloatArrayType::CreateArray(10, "GBCDLimits");
  gbcdLimitsArray->initializeWithZeros();

  Int32ArrayType::Pointer gbcdSizesArray = Int32ArrayType::CreateArray(5, "GBCDSizes");
  gbcdSizesArray->initializeWithZeros();

  float* gbcdDeltas = gbcdDeltasArray->getPointer(0);
  int* gbcdSizes = gbcdSizesArray->getPointer(0);
  float* gbcdLimits = gbcdLimitsArray->getPointer(0);

  // Original Ranges from Dave R.
  //m_GBCDlimits[0] = 0.0f;
  //m_GBCDlimits[1] = cosf(1.0f*m_pi);
  //m_GBCDlimits[2] = 0.0f;
  //m_GBCDlimits[3] = 0.0f;
  //m_GBCDlimits[4] = cosf(1.0f*m_pi);
  //m_GBCDlimits[5] = 2.0f*m_pi;
  //m_GBCDlimits[6] = cosf(0.0f);
  //m_GBCDlimits[7] = 2.0f*m_pi;
  //m_GBCDlimits[8] = 2.0f*m_pi;
  //m_GBCDlimits[9] = cosf(0.0f);

  // Greg R. Ranges
  gbcdLimits[0] = 0.0f;
  gbcdLimits[1] = 0.0f;
  gbcdLimits[2] = 0.0f;
  gbcdLimits[3] = 0.0f;
  gbcdLimits[4] = 0.0f;
  gbcdLimits[5] = SIMPLib::Constants::k_PiOver2;
  gbcdLimits[6] = 1.0f;
  gbcdLimits[7] = SIMPLib::Constants::k_PiOver2;
  gbcdLimits[8] = 1.0f;
  gbcdLimits[9] = SIMPLib::Constants::k_2Pi;

  // reset the 3rd and 4th dimensions using the square grid approach
  gbcdLimits[3] = -sqrtf(SIMPLib::Constants::k_PiOver2);
  gbcdLimits[4] = -sqrtf(SIMPLib::Constants::k_PiOver2);
  gbcdLimits[8] = sqrtf(SIMPLib::Constants::k_PiOver2);
  gbcdLimits[9] = sqrtf(SIMPLib::Constants::k_PiOver2);

  // get num components of GBCD
  QVector<size_t> cDims = m_GBCDPtr.lock()->getComponentDimensions();

  gbcdSizes[0] = cDims[0];
  gbcdSizes[1] = cDims[1];
  gbcdSizes[2] = cDims[2];
  gbcdSizes[3] = cDims[3];
  gbcdSizes[4] = cDims[4];

  gbcdDeltas[0] = (gbcdLimits[5] - gbcdLimits[0]) / float(gbcdSizes[0]);
  gbcdDeltas[1] = (gbcdLimits[6] - gbcdLimits[1]) / float(gbcdSizes[1]);
  gbcdDeltas[2] = (gbcdLimits[7] - gbcdLimits[2]) / float(gbcdSizes[2]);
  gbcdDeltas[3] = (gbcdLimits[8] - gbcdLimits[3]) / float(gbcdSizes[3]);
  gbcdDeltas[4] = (gbcdLimits[9] - gbcdLimits[4]) / float(gbcdSizes[4]);

  float vec[3] = { 0.0f, 0.0f, 0.0f };
  float vec2[3] = { 0.0f, 0.0f, 0.0f };
  float rotNormal[3] = { 0.0f, 0.0f, 0.0f };
  float rotNormal2[3] = { 0.0f, 0.0f, 0.0f };
  float sqCoord[2] = { 0.0f, 0.0f };
  float dg[3][3] = { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } };
  float dgt[3][3] = { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } };
  float dg1[3][3] = { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } };
  float dg2[3][3] = { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } };
  float sym1[3][3] = { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } };
  float sym2[3][3] = { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } };
  float sym2t[3][3] = { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } };
  float mis_euler1[3] = { 0.0f, 0.0f, 0.0f };

  float misAngle = m_MisorientationRotation.angle * SIMPLib::Constants::k_PiOver180;
  float normAxis[3] = { m_MisorientationRotation.h, m_MisorientationRotation.k, m_MisorientationRotation.l };
  MatrixMath::Normalize3x1(normAxis);
  // convert axis angle to matrix representation of misorientation
  FOrientArrayType om(9, 0.0f);
  FOrientTransformsType::ax2om(FOrientArrayType(normAxis[0], normAxis[1], normAxis[2], misAngle), om);
  om.toGMatrix(dg);

  // take inverse of misorientation variable to use for switching symmetry
  MatrixMath::Transpose3x3(dg, dgt);

  // Get our SpaceGroupOps pointer for the selected crystal structure
  SpaceGroupOps::Pointer orientOps = m_OrientationOps[m_CrystalStructures[m_PhaseOfInterest]];

  // get number of symmetry operators
  int32_t n_sym = orientOps->getNumSymOps();

  int32_t xpoints = 100;
  int32_t ypoints = 100;
  int32_t zpoints = 1;
  int32_t xpointshalf = xpoints / 2;
  int32_t ypointshalf = ypoints / 2;
  float xres = 2.0f / float(xpoints);
  float yres = 2.0f / float(ypoints);
  float zres = (xres + yres) / 2.0;
  float x = 0.0f, y = 0.0f;
  float sum = 0;
  int32_t count = 0;
  bool nhCheck = false;
  int32_t hemisphere = 0;

  int32_t shift1 = gbcdSizes[0];
  int32_t shift2 = gbcdSizes[0] * gbcdSizes[1];
  int32_t shift3 = gbcdSizes[0] * gbcdSizes[1] * gbcdSizes[2];
  int32_t shift4 = gbcdSizes[0] * gbcdSizes[1] * gbcdSizes[2] * gbcdSizes[3];

  int64_t totalGBCDBins = gbcdSizes[0] * gbcdSizes[1] * gbcdSizes[2] * gbcdSizes[3] * gbcdSizes[4] * 2;

  QVector<size_t> dims(1, 1);
  DoubleArrayType::Pointer poleFigureArray = DoubleArrayType::NullPointer();
  poleFigureArray = DoubleArrayType::CreateArray(xpoints * ypoints, dims, "PoleFigure");
  poleFigureArray->initializeWithZeros();
  double* poleFigure = poleFigureArray->getPointer(0);

  for (int32_t k = 0; k < ypoints; k++)
  {
    for (int32_t l = 0; l < xpoints; l++)
    {
      // get (x,y) for stereographic projection pixel
      x = float(l - xpointshalf) * xres + (xres / 2.0);
      y = float(k - ypointshalf) * yres + (yres / 2.0);
      if ((x * x + y * y) <= 1.0)
      {
        sum = 0.0f;
        count = 0;
        vec[2] = -((x * x + y * y) - 1) / ((x * x + y * y) + 1);
        vec[0] = x * (1 + vec[2]);
        vec[1] = y * (1 + vec[2]);
        MatrixMath::Multiply3x3with3x1(dgt, vec, vec2);

        // Loop over all the symetry operators in the given cystal symmetry
        for (int32_t i = 0; i < n_sym; i++)
        {
          //get symmetry operator1
          orientOps->getMatSymOp(i, sym1);
          for (int32_t j = 0; j < n_sym; j++)
          {
            // get symmetry operator2
            orientOps->getMatSymOp(j, sym2);
            MatrixMath::Transpose3x3(sym2, sym2t);
            // calculate symmetric misorientation
            MatrixMath::Multiply3x3with3x3(dg, sym2t, dg1);
            MatrixMath::Multiply3x3with3x3(sym1, dg1, dg2);
            // convert to euler angle
            FOrientArrayType eu(mis_euler1, 3);
            FOrientTransformsType::om2eu(FOrientArrayType(dg2), eu);
            if (mis_euler1[0] < SIMPLib::Constants::k_PiOver2 && mis_euler1[1] < SIMPLib::Constants::k_PiOver2 && mis_euler1[2] < SIMPLib::Constants::k_PiOver2)
            {
              mis_euler1[1] = cosf(mis_euler1[1]);
              // find bins in GBCD
              int32_t location1 = int32_t((mis_euler1[0] - gbcdLimits[0]) / gbcdDeltas[0]);
              int32_t location2 = int32_t((mis_euler1[1] - gbcdLimits[1]) / gbcdDeltas[1]);
              int32_t location3 = int32_t((mis_euler1[2] - gbcdLimits[2]) / gbcdDeltas[2]);
              //find symmetric poles using the first symmetry operator
              MatrixMath::Multiply3x3with3x1(sym1, vec, rotNormal);
              //get coordinates in square projection of crystal normal parallel to boundary normal
              nhCheck = getSquareCoord(rotNormal, sqCoord);
              // Note the switch to have theta in the 4 slot and cos(Phi) int he 3 slot
              int32_t location4 = int32_t((sqCoord[0] - gbcdLimits[3]) / gbcdDeltas[3]);
              int32_t location5 = int32_t((sqCoord[1] - gbcdLimits[4]) / gbcdDeltas[4]);
              if (location1 >= 0 && location2 >= 0 && location3 >= 0 && location4 >= 0 && location5 >= 0 &&
                  location1 < gbcdSizes[0] && location2 < gbcdSizes[1] && location3 < gbcdSizes[2] && location4 < gbcdSizes[3] && location5 < gbcdSizes[4])
              {
                hemisphere = 0;
                if (nhCheck == false) { hemisphere = 1; }
                sum += m_GBCD[(m_PhaseOfInterest * totalGBCDBins) + 2 * ((location5 * shift4) + (location4 * shift3) + (location3 * shift2) + (location2 * shift1) + location1) + hemisphere];
                count++;
              }
            }

            // again in second crystal reference frame
            // calculate symmetric misorientation
            MatrixMath::Multiply3x3with3x3(dgt, sym2, dg1);
            MatrixMath::Multiply3x3with3x3(sym1, dg1, dg2);
            // convert to euler angle
            FOrientTransformsType::om2eu(FOrientArrayType(dg2), eu);
            if (mis_euler1[0] < SIMPLib::Constants::k_PiOver2 && mis_euler1[1] < SIMPLib::Constants::k_PiOver2 && mis_euler1[2] < SIMPLib::Constants::k_PiOver2)
            {
              mis_euler1[1] = cosf(mis_euler1[1]);
              // find bins in GBCD
              int32_t location1 = int32_t((mis_euler1[0] - gbcdLimits[0]) / gbcdDeltas[0]);
              int32_t location2 = int32_t((mis_euler1[1] - gbcdLimits[1]) / gbcdDeltas[1]);
              int32_t location3 = int32_t((mis_euler1[2] - gbcdLimits[2]) / gbcdDeltas[2]);
              // find symmetric poles using the first symmetry operator
              MatrixMath::Multiply3x3with3x1(sym1, vec2, rotNormal2);
              // get coordinates in square projection of crystal normal parallel to boundary normal
              nhCheck = getSquareCoord(rotNormal2, sqCoord);
              // Note the switch to have theta in the 4 slot and cos(Phi) int he 3 slot
              int32_t location4 = int32_t((sqCoord[0] - gbcdLimits[3]) / gbcdDeltas[3]);
              int32_t location5 = int32_t((sqCoord[1] - gbcdLimits[4]) / gbcdDeltas[4]);
              if (location1 >= 0 && location2 >= 0 && location3 >= 0 && location4 >= 0 && location5 >= 0 &&
                  location1 < gbcdSizes[0] && location2 < gbcdSizes[1] && location3 < gbcdSizes[2] && location4 < gbcdSizes[3] && location5 < gbcdSizes[4])
              {
                hemisphere = 0;
                if (nhCheck == false) { hemisphere = 1; }
                sum += m_GBCD[(m_PhaseOfInterest * totalGBCDBins) + 2 * ((location5 * shift4) + (location4 * shift3) + (location3 * shift2) + (location2 * shift1) + location1) + hemisphere];
                count++;
              }
            }
          }
        }
        if (count > 0)
        {
          poleFigure[(k * xpoints) + l] = sum / float(count);
        }
      }
    }
  }

  FILE* f = NULL;
  f = fopen(m_OutputFile.toLatin1().data(), "wb");
  if (NULL == f)
  {
    QString ss = QObject::tr("Error opening output file '%1'").arg(m_OutputFile);
    setErrorCondition(-1);
    notifyErrorMessage(getHumanLabel(), ss, getErrorCondition());
    return;
  }

  // Write the correct header
  fprintf(f, "# vtk DataFile Version 2.0\n");
  fprintf(f, "data set from DREAM3D\n");
  fprintf(f, "BINARY");
  fprintf(f, "\n");
  fprintf(f, "DATASET RECTILINEAR_GRID\n");
  fprintf(f, "DIMENSIONS %d %d %d\n", xpoints + 1, ypoints + 1, zpoints + 1);

  // Write the Coords
  writeCoords(f, "X_COORDINATES", "float", xpoints + 1, (-float(xpoints)*xres / 2.0f), xres);
  writeCoords(f, "Y_COORDINATES", "float", ypoints + 1, (-float(ypoints)*yres / 2.0f), yres);
  writeCoords(f, "Z_COORDINATES", "float", zpoints + 1, (-float(zpoints)*zres / 2.0f), zres);

  int32_t total = xpoints * ypoints * zpoints;
  fprintf(f, "CELL_DATA %d\n", total);

  fprintf(f, "SCALARS %s %s 1\n", "Intensity", "float");
  fprintf(f, "LOOKUP_TABLE default\n");
  {
    float* gn = new float[total];
    float t;
    count = 0;
    for (int32_t j = 0; j < ypoints; j++)
    {
      for (int32_t i = 0; i < xpoints; i++)
      {
        t = float(poleFigure[(j * xpoints) + i]);
        SIMPLib::Endian::FromSystemToBig::convert(t);
        gn[count] = t;
        count++;
      }
    }
    size_t totalWritten = fwrite(gn, sizeof(float), (total), f);
    delete[] gn;
    if (totalWritten != (total))
    {
      QString ss = QObject::tr("Error writing binary VTK data to file '%1'").arg(m_OutputFile);
      setErrorCondition(-1);
      notifyErrorMessage(getHumanLabel(), ss, getErrorCondition());
      fclose(f);
      return;
    }
  }
  fclose(f);

  /* Let the GUI know we are done with this filter */
  notifyStatusMessage(getHumanLabel(), "Complete");
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void ReadH5Ebsd::copyTSLArrays(H5EbsdVolumeReader* ebsdReader)
{
  float* f1 = NULL;
  float* f2 = NULL;
  float* f3 = NULL;
  int* phasePtr = NULL;

  FloatArrayType::Pointer fArray = FloatArrayType::NullPointer();
  Int32ArrayType::Pointer iArray = Int32ArrayType::NullPointer();
  VoxelDataContainer* m = getVoxelDataContainer();
  int64_t totalPoints = m->getTotalPoints();

  if (m_SelectedVoxelCellArrays.find(m_CellPhasesArrayName) != m_SelectedVoxelCellArrays.end() )
  {
    phasePtr = reinterpret_cast<int*>(ebsdReader->getPointerByName(Ebsd::Ang::PhaseData));
    iArray = Int32ArrayType::CreateArray(totalPoints, DREAM3D::CellData::Phases);
    iArray->SetNumberOfComponents(1);
    ::memcpy(iArray->GetPointer(0), phasePtr, sizeof(int32_t) * totalPoints);
    m->addCellData(DREAM3D::CellData::Phases, iArray);
  }

  if (m_SelectedVoxelCellArrays.find(m_CellEulerAnglesArrayName) != m_SelectedVoxelCellArrays.end() )
  {
    f1 = reinterpret_cast<float*>(ebsdReader->getPointerByName(Ebsd::Ang::Phi1));
    f2 = reinterpret_cast<float*>(ebsdReader->getPointerByName(Ebsd::Ang::Phi));
    f3 = reinterpret_cast<float*>(ebsdReader->getPointerByName(Ebsd::Ang::Phi2));
    fArray = FloatArrayType::CreateArray(totalPoints, 3, DREAM3D::CellData::EulerAngles);
    float* cellEulerAngles = fArray->GetPointer(0);

    for (int64_t i = 0; i < totalPoints; i++)
    {
      cellEulerAngles[3 * i] = f1[i];
      cellEulerAngles[3 * i + 1] = f2[i];
      cellEulerAngles[3 * i + 2] = f3[i];
    }
    m->addCellData(DREAM3D::CellData::EulerAngles, fArray);
  }

  if (m_SelectedVoxelCellArrays.find(Ebsd::Ang::ImageQuality) != m_SelectedVoxelCellArrays.end() )
  {
    f1 = reinterpret_cast<float*>(ebsdReader->getPointerByName(Ebsd::Ang::ImageQuality));
    fArray = FloatArrayType::CreateArray(totalPoints, Ebsd::Ang::ImageQuality);
    ::memcpy(fArray->GetPointer(0), f1, sizeof(float) * totalPoints);
    m->addCellData(Ebsd::Ang::ImageQuality, fArray);
  }

  if (m_SelectedVoxelCellArrays.find(Ebsd::Ang::ConfidenceIndex) != m_SelectedVoxelCellArrays.end() )
  {
    f1 = reinterpret_cast<float*>(ebsdReader->getPointerByName(Ebsd::Ang::ConfidenceIndex));
    fArray = FloatArrayType::CreateArray(totalPoints, Ebsd::Ang::ConfidenceIndex);
    ::memcpy(fArray->GetPointer(0), f1, sizeof(float) * totalPoints);
    m->addCellData(Ebsd::Ang::ConfidenceIndex, fArray);
  }

  if (m_SelectedVoxelCellArrays.find(Ebsd::Ang::SEMSignal) != m_SelectedVoxelCellArrays.end() )
  {
    f1 = reinterpret_cast<float*>(ebsdReader->getPointerByName(Ebsd::Ang::SEMSignal));
    fArray = FloatArrayType::CreateArray(totalPoints, Ebsd::Ang::SEMSignal);
    ::memcpy(fArray->GetPointer(0), f1, sizeof(float) * totalPoints);
    m->addCellData(Ebsd::Ang::SEMSignal, fArray);
  }

  if (m_SelectedVoxelCellArrays.find(Ebsd::Ang::Fit) != m_SelectedVoxelCellArrays.end() )
  {
    f1 = reinterpret_cast<float*>(ebsdReader->getPointerByName(Ebsd::Ang::Fit));
    fArray = FloatArrayType::CreateArray(totalPoints, Ebsd::Ang::Fit);
    ::memcpy(fArray->GetPointer(0), f1, sizeof(float) * totalPoints);
    m->addCellData(Ebsd::Ang::Fit, fArray);
  }
}
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void ReadH5Ebsd::copyHKLArrays(H5EbsdVolumeReader* ebsdReader)
{
  float* f1 = NULL;
  float* f2 = NULL;
  float* f3 = NULL;
  int* phasePtr = NULL;

  FloatArrayType::Pointer fArray = FloatArrayType::NullPointer();
  Int32ArrayType::Pointer iArray = Int32ArrayType::NullPointer();
  VoxelDataContainer* m = getVoxelDataContainer();
  int64_t totalPoints = m->getTotalPoints();

  phasePtr = reinterpret_cast<int*>(ebsdReader->getPointerByName(Ebsd::Ctf::Phase));
  iArray = Int32ArrayType::CreateArray(totalPoints, DREAM3D::CellData::Phases);
  iArray->SetNumberOfComponents(1);
  ::memcpy(iArray->GetPointer(0), phasePtr, sizeof(int32_t) * totalPoints);
  m->addCellData(DREAM3D::CellData::Phases, iArray);

  if (m_SelectedVoxelCellArrays.find(m_CellEulerAnglesArrayName) != m_SelectedVoxelCellArrays.end() )
  {
    //  radianconversion = M_PI / 180.0;
    f1 = reinterpret_cast<float*>(ebsdReader->getPointerByName(Ebsd::Ctf::Euler1));
    f2 = reinterpret_cast<float*>(ebsdReader->getPointerByName(Ebsd::Ctf::Euler2));
    f3 = reinterpret_cast<float*>(ebsdReader->getPointerByName(Ebsd::Ctf::Euler3));
    fArray = FloatArrayType::CreateArray(totalPoints * 3, DREAM3D::CellData::EulerAngles);
    fArray->SetNumberOfComponents(3);
    float* cellEulerAngles = fArray->GetPointer(0);
    int* cellPhases = iArray->GetPointer(0);

    for (int64_t i = 0; i < totalPoints; i++)
    {
      cellEulerAngles[3 * i] = f1[i];
      cellEulerAngles[3 * i + 1] = f2[i];
      cellEulerAngles[3 * i + 2] = f3[i];
      if(m_CrystalStructures[cellPhases[i]] == Ebsd::CrystalStructure::Hexagonal_High)
      {cellEulerAngles[3 * i + 2] = cellEulerAngles[3 * i + 2] + (30.0);}
    }
    m->addCellData(DREAM3D::CellData::EulerAngles, fArray);
  }

  if (m_SelectedVoxelCellArrays.find(Ebsd::Ctf::Bands) != m_SelectedVoxelCellArrays.end() )
  {
    phasePtr = reinterpret_cast<int*>(ebsdReader->getPointerByName(Ebsd::Ctf::Bands));
    iArray = Int32ArrayType::CreateArray(totalPoints, Ebsd::Ctf::Bands);
    iArray->SetNumberOfComponents(1);
    ::memcpy(iArray->GetPointer(0), phasePtr, sizeof(int32_t) * totalPoints);
    m->addCellData(Ebsd::Ctf::Bands, iArray);
  }

  if (m_SelectedVoxelCellArrays.find(Ebsd::Ctf::Error) != m_SelectedVoxelCellArrays.end() )
  {
    phasePtr = reinterpret_cast<int*>(ebsdReader->getPointerByName(Ebsd::Ctf::Error));
    iArray = Int32ArrayType::CreateArray(totalPoints, Ebsd::Ctf::Error);
    iArray->SetNumberOfComponents(1);
    ::memcpy(iArray->GetPointer(0), phasePtr, sizeof(int32_t) * totalPoints);
    m->addCellData(Ebsd::Ctf::Error, iArray);
  }

  if (m_SelectedVoxelCellArrays.find(Ebsd::Ctf::MAD) != m_SelectedVoxelCellArrays.end() )
  {
    f1 = reinterpret_cast<float*>(ebsdReader->getPointerByName(Ebsd::Ctf::MAD));
    fArray = FloatArrayType::CreateArray(totalPoints, Ebsd::Ctf::MAD);
    fArray->SetNumberOfComponents(1);
    ::memcpy(fArray->GetPointer(0), f1, sizeof(float) * totalPoints);
    m->addCellData(Ebsd::Ctf::MAD, fArray);
  }

  if (m_SelectedVoxelCellArrays.find(Ebsd::Ctf::BC) != m_SelectedVoxelCellArrays.end() )
  {
    phasePtr = reinterpret_cast<int*>(ebsdReader->getPointerByName(Ebsd::Ctf::BC));
    iArray = Int32ArrayType::CreateArray(totalPoints, Ebsd::Ctf::BC);
    iArray->SetNumberOfComponents(1);
    ::memcpy(iArray->GetPointer(0), phasePtr, sizeof(int32_t) * totalPoints);
    m->addCellData(Ebsd::Ctf::BC, iArray);
  }

  if (m_SelectedVoxelCellArrays.find(Ebsd::Ctf::BS) != m_SelectedVoxelCellArrays.end() )
  {
    phasePtr = reinterpret_cast<int*>(ebsdReader->getPointerByName(Ebsd::Ctf::BS));
    iArray = Int32ArrayType::CreateArray(totalPoints, Ebsd::Ctf::BS);
    iArray->SetNumberOfComponents(1);
    ::memcpy(iArray->GetPointer(0), phasePtr, sizeof(int32_t) * totalPoints);
    m->addCellData(Ebsd::Ctf::BS, iArray);
  }
}
Beispiel #11
0
  /**
   * @brief ConvertData Templated function that converts an IDataArray to a given primitive type
   * @param ptr IDataArray instance pointer
   * @param dims Component dimensions
   * @param m DataContainer instance pointer
   * @param scalarType Primitive type to convert to
   * @param attributeMatrixName Name of target AttributeMatrix
   * @param name Name of converted array
   */
  void ConvertData(T* ptr, QVector<size_t> dims, DataContainer::Pointer m, int32_t scalarType, const QString attributeMatrixName, const QString& name)
  {
    int voxels = ptr->getNumberOfTuples();
    size_t size = ptr->getSize();

    if (scalarType == Detail::Int8)
    {
      Int8ArrayType::Pointer p = Int8ArrayType::CreateArray(voxels, dims, name);
      m->getAttributeMatrix(attributeMatrixName)->addAttributeArray(p->getName(), p);
      for(size_t v = 0; v < size; ++v)
      {
        p->setValue(v, ptr->getValue(v) );
      }
    }
    else if (scalarType == Detail::UInt8)
    {
      UInt8ArrayType::Pointer p = UInt8ArrayType::CreateArray(voxels, dims, name);
      m->getAttributeMatrix(attributeMatrixName)->addAttributeArray(p->getName(), p);
      for(size_t v = 0; v < size; ++v)
      {
        p->setValue(v, ptr->getValue(v) );
      }
    }
    else if (scalarType == Detail::Int16)
    {
      Int16ArrayType::Pointer p = Int16ArrayType::CreateArray(voxels, dims, name);
      m->getAttributeMatrix(attributeMatrixName)->addAttributeArray(p->getName(), p);
      for(size_t v = 0; v < size; ++v)
      {
        p->setValue(v, ptr->getValue(v) );
      }
    }
    else if (scalarType == Detail::UInt16)
    {
      UInt16ArrayType::Pointer p = UInt16ArrayType::CreateArray(voxels, dims, name);
      m->getAttributeMatrix(attributeMatrixName)->addAttributeArray(p->getName(), p);
      for(size_t v = 0; v < size; ++v)
      {
        p->setValue(v, ptr->getValue(v) );
      }
    }
    else if (scalarType == Detail::Int32)
    {
      Int32ArrayType::Pointer p = Int32ArrayType::CreateArray(voxels, dims, name);
      m->getAttributeMatrix(attributeMatrixName)->addAttributeArray(p->getName(), p);
      for(size_t v = 0; v < size; ++v)
      {
        p->setValue(v, ptr->getValue(v) );
      }
    }
    else if (scalarType == Detail::UInt32)
    {
      UInt32ArrayType::Pointer p = UInt32ArrayType::CreateArray(voxels, dims, name);
      m->getAttributeMatrix(attributeMatrixName)->addAttributeArray(p->getName(), p);
      for(size_t v = 0; v < size; ++v)
      {
        p->setValue(v, ptr->getValue(v) );
      }
    }
    else if (scalarType == Detail::Int64)
    {
      Int64ArrayType::Pointer p = Int64ArrayType::CreateArray(voxels, dims, name);
      m->getAttributeMatrix(attributeMatrixName)->addAttributeArray(p->getName(), p);
      for(size_t v = 0; v < size; ++v)
      {
        p->setValue(v, ptr->getValue(v) );
      }
    }
    else if (scalarType == Detail::UInt64)
    {
      UInt64ArrayType::Pointer p = UInt64ArrayType::CreateArray(voxels, dims, name);
      m->getAttributeMatrix(attributeMatrixName)->addAttributeArray(p->getName(), p);
      for(size_t v = 0; v < size; ++v)
      {
        p->setValue(v, ptr->getValue(v) );
      }
    }
    else if (scalarType == Detail::Float)
    {
      FloatArrayType::Pointer p = FloatArrayType::CreateArray(voxels, dims, name);
      m->getAttributeMatrix(attributeMatrixName)->addAttributeArray(p->getName(), p);
      for(size_t v = 0; v < size; ++v)
      {
        p->setValue(v, ptr->getValue(v) );
      }
    }
    else if (scalarType == Detail::Double)
    {
      DoubleArrayType::Pointer p = DoubleArrayType::CreateArray(voxels, dims, name);
      m->getAttributeMatrix(attributeMatrixName)->addAttributeArray(p->getName(), p);
      for(size_t v = 0; v < size; ++v)
      {
        p->setValue(v, ptr->getValue(v) );
      }
    }
  }
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
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");
}
Beispiel #13
0
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void SampleSurfaceMesh::execute()
{
  setErrorCondition(0);
  dataCheck();
  if(getErrorCondition() < 0) { return; }

  DataContainer::Pointer sm = getDataContainerArray()->getDataContainer(m_SurfaceMeshFaceLabelsArrayPath.getDataContainerName());
  SIMPL_RANDOMNG_NEW()

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

  TriangleGeom::Pointer triangleGeom = sm->getGeometryAs<TriangleGeom>();

  // pull down faces
  int64_t numFaces = m_SurfaceMeshFaceLabelsPtr.lock()->getNumberOfTuples();

  // create array to hold bounding vertices for each face
  FloatArrayType::Pointer llPtr = FloatArrayType::CreateArray(3, "_INTERNAL_USE_ONLY_Lower_Left");
  FloatArrayType::Pointer urPtr = FloatArrayType::CreateArray(3, "_INTERNAL_USE_ONLY_Upper_Right");
  float* ll = llPtr->getPointer(0);
  float* ur = urPtr->getPointer(0);
  VertexGeom::Pointer faceBBs = VertexGeom::CreateGeometry(2 * numFaces, "_INTERNAL_USE_ONLY_faceBBs");

  // walk through faces to see how many features there are
  int32_t g1 = 0, g2 = 0;
  int32_t maxFeatureId = 0;
  for (int64_t i = 0; i < numFaces; i++)
  {
    g1 = m_SurfaceMeshFaceLabels[2 * i];
    g2 = m_SurfaceMeshFaceLabels[2 * i + 1];
    if (g1 > maxFeatureId) { maxFeatureId = g1; }
    if (g2 > maxFeatureId) { maxFeatureId = g2; }
  }
  // add one to account for feature 0
  int32_t numFeatures = maxFeatureId + 1;

  // create a dynamic list array to hold face lists
  Int32Int32DynamicListArray::Pointer faceLists = Int32Int32DynamicListArray::New();
  std::vector<int32_t> linkCount(numFeatures, 0);

  // fill out lists with number of references to cells
  typedef boost::shared_array<int32_t> SharedInt32Array_t;
  SharedInt32Array_t linkLocPtr(new int32_t[numFaces]);
  int32_t* linkLoc = linkLocPtr.get();

  ::memset(linkLoc, 0, numFaces * sizeof(int32_t));

  // traverse data to determine number of faces belonging to each feature
  for (int64_t i = 0; i < numFaces; i++)
  {
    g1 = m_SurfaceMeshFaceLabels[2 * i];
    g2 = m_SurfaceMeshFaceLabels[2 * i + 1];
    if (g1 > 0) { linkCount[g1]++; }
    if (g2 > 0) { linkCount[g2]++; }
  }

  // now allocate storage for the faces
  faceLists->allocateLists(linkCount);

  // traverse data again to get the faces belonging to each feature
  for (int64_t i = 0; i < numFaces; i++)
  {
    g1 = m_SurfaceMeshFaceLabels[2 * i];
    g2 = m_SurfaceMeshFaceLabels[2 * i + 1];
    if (g1 > 0) { faceLists->insertCellReference(g1, (linkLoc[g1])++, i); }
    if (g2 > 0) { faceLists->insertCellReference(g2, (linkLoc[g2])++, i); }
    // find bounding box for each face
    GeometryMath::FindBoundingBoxOfFace(triangleGeom, i, ll, ur);
    faceBBs->setCoords(2 * i, ll);
    faceBBs->setCoords(2 * i + 1, ur);
  }

  // generate the list of sampling points from subclass
  VertexGeom::Pointer points = generate_points();
  if(getErrorCondition() < 0 || NULL == points.get()) { return; }
  int64_t numPoints = points->getNumberOfVertices();

  // create array to hold which polyhedron (feature) each point falls in
  Int32ArrayType::Pointer iArray = Int32ArrayType::NullPointer();
  iArray = Int32ArrayType::CreateArray(numPoints, "_INTERNAL_USE_ONLY_polyhedronIds");
  iArray->initializeWithZeros();
  int32_t* polyIds = iArray->getPointer(0);

#ifdef SIMPLib_USE_PARALLEL_ALGORITHMS
  if (doParallel == true)
  {
    tbb::parallel_for(tbb::blocked_range<size_t>(0, numFeatures),
                      SampleSurfaceMeshImpl(triangleGeom, faceLists, faceBBs, points, polyIds), tbb::auto_partitioner());
  }
  else
#endif
  {
    SampleSurfaceMeshImpl serial(triangleGeom, faceLists, faceBBs, points, polyIds);
    serial.checkPoints(0, numFeatures);
  }

  assign_points(iArray);

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

  DataContainer::Pointer m = getDataContainerArray()->getDataContainer(m_FeatureIdsArrayPath.getDataContainerName());
  size_t totalPoints = m_FeatureIdsPtr.lock()->getNumberOfTuples();
  size_t totalFeatures = m_AvgCAxesPtr.lock()->getNumberOfTuples();

  int32_t avgMisoComps = 3;
  QVector<size_t> dims(1, avgMisoComps);
  FloatArrayType::Pointer avgmisoPtr = FloatArrayType::CreateArray(totalFeatures, dims, "_INTERNAL_USE_ONLY_AvgMiso_Temp");
  avgmisoPtr->initializeWithZeros();
  float* avgmiso = avgmisoPtr->getPointer(0);

  QuatF q1 = QuaternionMathF::New();
  QuatF* quats = reinterpret_cast<QuatF*>(m_Quats);

  float w = 0.0f;
  size_t udims[3] = { 0, 0, 0 };
  m->getGeometryAs<ImageGeom>()->getDimensions(udims);
#if (CMP_SIZEOF_SIZE_T == 4)
  typedef uint32_t DimType;
  uint32_t maxUInt32 = std::numeric_limits<uint32_t>::max();
  // We have more points than can be allocated on a 32 bit machine. Assert Now.
  if(totalPoints > maxUInt32)
  {
    QString ss = QObject::tr("The volume is too large for a 32 bit machine. Try reducing the input volume size. Total Voxels: %1").arg(totalPoints);
    notifyStatusMessage(getMessagePrefix(), getHumanLabel(), ss);
    return;
  }
#else
  typedef int64_t DimType;
#endif

  DimType xPoints = static_cast<DimType>(udims[0]);
  DimType yPoints = static_cast<DimType>(udims[1]);
  DimType zPoints = static_cast<DimType>(udims[2]);
  DimType point = 0;

  float g1[3][3] = { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } };
  float g1t[3][3] = { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } };
  float caxis[3] = {0.0f, 0.0f, 1.0f};
  float c1[3] = {0.0f, 0.0f, 0.0f};
  float AvgCAxis[3] = {0.0f, 0.0f, 0.0f};
  size_t index = 0;

  for (DimType col = 0; col < xPoints; col++)
  {
    for (DimType row = 0; row < yPoints; row++)
    {
      for (DimType plane = 0; plane < zPoints; plane++)
      {
        point = (plane * xPoints * yPoints) + (row * xPoints) + col;
        if (m_FeatureIds[point] > 0 && m_CellPhases[point] > 0)
        {
          QuaternionMathF::Copy(quats[point], q1);
          FOrientArrayType om(9);
          FOrientTransformsType::qu2om(FOrientArrayType(q1), om);
          om.toGMatrix(g1);
          // transpose the g matricies so when caxis is multiplied by it
          // it will give the sample direction that the caxis is along
          MatrixMath::Transpose3x3(g1, g1t);
          MatrixMath::Multiply3x3with3x1(g1t, caxis, c1);
          // normalize so that the magnitude is 1
          MatrixMath::Normalize3x1(c1);

          AvgCAxis[0] = m_AvgCAxes[3 * m_FeatureIds[point]];
          AvgCAxis[1] = m_AvgCAxes[3 * m_FeatureIds[point] + 1];
          AvgCAxis[2] = m_AvgCAxes[3 * m_FeatureIds[point] + 2];
          // normalize so that the magnitude is 1
          MatrixMath::Normalize3x1(AvgCAxis);
          w = GeometryMath::CosThetaBetweenVectors(c1, AvgCAxis);
          DREAM3DMath::boundF(w, -1, 1);
          w = acosf(w);
          w = w * DREAM3D::Constants::k_180OverPi;
          if (w > 90.0) { w = 180.0 - w; }

          m_FeatureReferenceCAxisMisorientations[point] = w;
          index = m_FeatureIds[point] * avgMisoComps;
          avgmiso[index]++;
          avgmiso[index + 1] += w;
        }
        if (m_FeatureIds[point] == 0 || m_CellPhases[point] == 0)
        {
          m_FeatureReferenceCAxisMisorientations[point] = 0;
        }
      }
    }
  }

  for (size_t i = 1; i < totalFeatures; i++)
  {
    if (i % 1000 == 0)
    {
      QString ss = QObject::tr("Working On Feature %1 of %2").arg(i).arg(totalFeatures);
      notifyStatusMessage(getMessagePrefix(), getHumanLabel(), ss);
    }
    index = i * avgMisoComps;
    m_FeatureAvgCAxisMisorientations[i] = avgmiso[index + 1] / avgmiso[index];
    if (avgmiso[index] == 0) { m_FeatureAvgCAxisMisorientations[i] = 0.0; }
  }


  int32_t gNum = 0;
  for (size_t j = 0; j < totalPoints; j++)
  {
    gNum = m_FeatureIds[j];
    avgmiso[(gNum * avgMisoComps) + 2] += ((m_FeatureReferenceCAxisMisorientations[j] - m_FeatureAvgCAxisMisorientations[gNum]) * (m_FeatureReferenceCAxisMisorientations[j] - m_FeatureAvgCAxisMisorientations[gNum]));
  }

  for (size_t i = 1; i < totalFeatures; i++)
  {
    index = i * avgMisoComps;
    m_FeatureStdevCAxisMisorientations[i] = sqrtf((1 / avgmiso[index]) * avgmiso[index + 2]);
  }

  notifyStatusMessage(getHumanLabel(), "Complete");
}
  void ConvertData(T* ptr, VoxelDataContainer* m, int32_t scalarType, const std::string &name)
  {
    int numberOfComponents = ptr->GetNumberOfComponents();
    int voxels = ptr->GetNumberOfTuples();
    size_t size = ptr->GetSize();


    if (scalarType == Detail::Int8)
    {
      Int8ArrayType::Pointer p = Int8ArrayType::CreateArray(voxels, numberOfComponents, name);
      m->addCellData(p->GetName(), p);
      for(size_t v = 0; v < size; ++v)
      {
        p->SetValue(v, ptr->GetValue(v) );
      }
    }
    else if (scalarType == Detail::UInt8)
    {
      UInt8ArrayType::Pointer p = UInt8ArrayType::CreateArray(voxels, numberOfComponents, name);
      m->addCellData(p->GetName(), p);
      for(size_t v = 0; v < size; ++v)
      {
        p->SetValue(v, ptr->GetValue(v) );
      }
    }
    else if (scalarType == Detail::Int16)
    {
      Int16ArrayType::Pointer p = Int16ArrayType::CreateArray(voxels, numberOfComponents, name);
      m->addCellData(p->GetName(), p);
      for(size_t v = 0; v < size; ++v)
      {
        p->SetValue(v, ptr->GetValue(v) );
      }
    }
    else if (scalarType == Detail::UInt16)
    {
      UInt16ArrayType::Pointer p = UInt16ArrayType::CreateArray(voxels, numberOfComponents, name);
      m->addCellData(p->GetName(), p);
      for(size_t v = 0; v < size; ++v)
      {
        p->SetValue(v, ptr->GetValue(v) );
      }
    }
    else if (scalarType == Detail::Int32)
    {
      Int32ArrayType::Pointer p = Int32ArrayType::CreateArray(voxels, numberOfComponents, name);
      m->addCellData(p->GetName(), p);
      for(size_t v = 0; v < size; ++v)
      {
        p->SetValue(v, ptr->GetValue(v) );
      }
    }
    else if (scalarType == Detail::UInt32)
    {
      UInt32ArrayType::Pointer p = UInt32ArrayType::CreateArray(voxels, numberOfComponents, name);
      m->addCellData(p->GetName(), p);
      for(size_t v = 0; v < size; ++v)
      {
        p->SetValue(v, ptr->GetValue(v) );
      }
    }
    else if (scalarType == Detail::Int64)
    {
      Int64ArrayType::Pointer p = Int64ArrayType::CreateArray(voxels, numberOfComponents, name);
      m->addCellData(p->GetName(), p);
      for(size_t v = 0; v < size; ++v)
      {
        p->SetValue(v, ptr->GetValue(v) );
      }
    }
    else if (scalarType == Detail::UInt64)
    {
      UInt64ArrayType::Pointer p = UInt64ArrayType::CreateArray(voxels, numberOfComponents, name);
      m->addCellData(p->GetName(), p);
      for(size_t v = 0; v < size; ++v)
      {
        p->SetValue(v, ptr->GetValue(v) );
      }
    }
    else if (scalarType == Detail::Float)
    {
      FloatArrayType::Pointer p = FloatArrayType::CreateArray(voxels, numberOfComponents, name);
      m->addCellData(p->GetName(), p);
    }
    else if (scalarType == Detail::Double)
    {
      DoubleArrayType::Pointer p = DoubleArrayType::CreateArray(voxels, numberOfComponents, name);
      m->addCellData(p->GetName(), p);
      for(size_t v = 0; v < size; ++v)
      {
        p->SetValue(v, ptr->GetValue(v) );
      }
    }


  }