// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- 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 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 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"); }