// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- int32_t MergeColonies::getSeed(int32_t newFid) { setErrorCondition(0); int32_t numfeatures = static_cast<int32_t>(m_FeaturePhasesPtr.lock()->getNumberOfTuples()); SIMPL_RANDOMNG_NEW() int32_t seed = -1; int32_t randfeature = 0; // Precalculate some constants int32_t totalFMinus1 = numfeatures - 1; size_t counter = 0; randfeature = int32_t(float(rg.genrand_res53()) * float(totalFMinus1)); while (seed == -1 && counter < numfeatures) { if (randfeature > totalFMinus1) { randfeature = randfeature - numfeatures; } if (m_FeatureParentIds[randfeature] == -1) { seed = randfeature; } randfeature++; counter++; } if (seed >= 0) { m_FeatureParentIds[seed] = newFid; QVector<size_t> tDims(1, newFid + 1); getDataContainerArray()->getDataContainer(m_FeatureIdsArrayPath.getDataContainerName())->getAttributeMatrix(getNewCellFeatureAttributeMatrixName())->resizeAttributeArrays(tDims); updateFeatureInstancePointers(); } return seed; }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void PrimaryRolledPreset::initializeCOverATableModel(StatsGenPlotWidget* plot, QVector<float> binNumbers) { // Make sure the distribution is set correctly plot->setDistributionType(SIMPL::DistributionType::Beta, false); // This line basically makes sure we have the distribution type we are looking for SGBetaTableModel* model = qobject_cast<SGBetaTableModel*> (plot->tableModel()); if (NULL == model) { return; } qint32 count = binNumbers.count(); // Remove all the current rows in the table model model->removeRows(0, model->rowCount()); float alpha, beta; SIMPL_RANDOMNG_NEW() QVector<float> alphas; QVector<float> betas; QVector<QColor> colors = GenerateColors(count, 160, 255); for (qint32 i = 0; i < count; ++i) { alpha = (0 * i) + (1.1 + (28.9 * (1.0 / m_AspectRatio2))) + (rg.genrand_res53()); beta = (0 * i) + (30 - (28.9 * (1.0 / m_AspectRatio2))) + (rg.genrand_res53()); alphas.push_back(alpha); betas.push_back(beta); } QVector<QVector<float> > data; data.push_back(alphas); data.push_back(betas); model->setTableData(binNumbers, data, colors); }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- int32_t GroupMicroTextureRegions::getSeed(int32_t newFid) { setErrorCondition(0); int32_t numfeatures = static_cast<int32_t>(m_FeaturePhasesPtr.lock()->getNumberOfTuples()); float c1[3] = { 0.0f, 0.0f, 0.0f }; uint32_t phase1 = 0; QuatF* avgQuats = reinterpret_cast<QuatF*>(m_AvgQuats); float caxis[3] = { 0.0f, 0.0f, 1.0f }; QuatF q1 = QuaternionMathF::New(); 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 } }; SIMPL_RANDOMNG_NEW() int32_t seed = -1; int32_t randfeature = 0; // Precalculate some constants int32_t totalFMinus1 = numfeatures - 1; size_t counter = 0; randfeature = int32_t(float(rg.genrand_res53()) * float(totalFMinus1)); while (seed == -1 && counter < numfeatures) { if (randfeature > totalFMinus1) { randfeature = randfeature - numfeatures; } if (m_FeatureParentIds[randfeature] == -1) { seed = randfeature; } randfeature++; counter++; } if (seed >= 0) { m_FeatureParentIds[seed] = newFid; QVector<size_t> tDims(1, newFid + 1); getDataContainerArray()->getDataContainer(m_FeatureIdsArrayPath.getDataContainerName())->getAttributeMatrix(getNewCellFeatureAttributeMatrixName())->resizeAttributeArrays(tDims); updateFeatureInstancePointers(); if (m_UseRunningAverage == true) { QuaternionMathF::Copy(avgQuats[seed], q1); phase1 = m_CrystalStructures[m_FeaturePhases[seed]]; FOrientArrayType om(9); FOrientTransformsType::qu2om(FOrientArrayType(q1), om); om.toGMatrix(g1); // transpose the g matrix 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 dot product can be taken below without // dividing by the magnitudes (they would be 1) MatrixMath::Normalize3x1(c1); MatrixMath::Copy3x1(c1, avgCaxes); MatrixMath::Multiply3x1withConstant(avgCaxes, m_Volumes[seed]); } } return seed; }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void RegularGridSampleSurfaceMesh::execute() { setErrorCondition(0); dataCheck(); if(getErrorCondition() < 0) { return; } SIMPL_RANDOMNG_NEW() DataContainer::Pointer m = getDataContainerArray()->getDataContainer(getDataContainerName()); m->getGeometryAs<ImageGeom>()->setDimensions(m_XPoints, m_YPoints, m_ZPoints); m->getGeometryAs<ImageGeom>()->setOrigin(m_Origin.x, m_Origin.y, m_Origin.z); m->getGeometryAs<ImageGeom>()->setResolution(m_Resolution.x, m_Resolution.y, m_Resolution.z); SampleSurfaceMesh::execute(); notifyStatusMessage(getHumanLabel(), "Complete"); }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void PrimaryEquiaxedPreset::initializeNeighborTableModel(StatsGenPlotWidget* plot, QVector<float> binNumbers) { // Make sure the distribution is set correctly plot->setDistributionType(DREAM3D::DistributionType::LogNormal, false); // This line basically makes sure we have the distribution type we are looking for SGLogNormalTableModel* model = qobject_cast<SGLogNormalTableModel*> (plot->tableModel()); if (NULL == model) { return; } qint32 count = binNumbers.count(); // Remove all the current rows in the table model model->removeRows(0, model->rowCount()); float mu, sigma; SIMPL_RANDOMNG_NEW() QVector<float> mus; QVector<float> sigmas; QVector<QString> colors; QStringList colorNames = QColor::colorNames(); qint32 colorOffset = 21; int middlebin = count / 2; for (qint32 i = 0; i < count; ++i) { mu = log(14.0 + (2.0 * float(i - middlebin))); sigma = 0.3 + (float(middlebin - i) / float(middlebin * 10)); mus.push_back(mu); sigmas.push_back(sigma); colors.push_back(colorNames[colorOffset++]); if (colorOffset == colorNames.size()) { colorOffset = 21; } } QVector<QVector<float> > data; data.push_back(mus); data.push_back(sigmas); model->setTableData(binNumbers, data, colors); }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void PrimaryEquiaxedPreset::initializeOmega3TableModel(StatsGenPlotWidget* plot, QVector<float> binNumbers) { // Make sure the distribution is set correctly plot->setDistributionType(DREAM3D::DistributionType::Beta, false); // This line basically makes sure we have the distribution type we are looking for SGBetaTableModel* model = qobject_cast<SGBetaTableModel*>(plot->tableModel()); if (NULL == model) { return; } qint32 count = binNumbers.count(); // Remove all the current rows in the table model // model->removeRows(0, model->rowCount()); float alpha, beta; SIMPL_RANDOMNG_NEW() QVector<float> alphas; QVector<float> betas; QVector<QString> colors; QStringList colorNames = QColor::colorNames(); qint32 colorOffset = 21; for (qint32 i = 0; i < count; ++i) { alpha = (0 * i) + 10.0 + rg.genrand_res53(); beta = (0 * i) + 1.5 + (0.5 * rg.genrand_res53()); alphas.push_back(alpha); betas.push_back(beta); colors.push_back(colorNames[colorOffset++]); if (colorOffset == colorNames.size()) { colorOffset = 21; } } QVector<QVector<float> > data; data.push_back(alphas); data.push_back(betas); model->setTableData(binNumbers, data, colors); }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void PrimaryRolledPreset::initializeNeighborTableModel(StatsGenPlotWidget* plot, QVector<float> binNumbers) { // Make sure the distribution is set correctly plot->setDistributionType(SIMPL::DistributionType::LogNormal, false); // This line basically makes sure we have the distribution type we are looking for SGLogNormalTableModel* model = qobject_cast<SGLogNormalTableModel*> (plot->tableModel()); if (NULL == model) { return; } qint32 count = binNumbers.count(); // Remove all the current rows in the table model model->removeRows(0, model->rowCount()); float mu, sigma; SIMPL_RANDOMNG_NEW() QVector<float> mus; QVector<float> sigmas; QVector<QColor> colors = GenerateColors(count, 160, 255); int middlebin = count / 2; for (qint32 i = 0; i < count; ++i) { mu = log(8.0 + (1.0 * float(i - middlebin))); sigma = 0.3 + (float(middlebin - i) / float(middlebin * 10)); mus.push_back(mu); sigmas.push_back(sigma); } QVector<QVector<float> > data; data.push_back(mus); data.push_back(sigmas); model->setTableData(binNumbers, data, colors); }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- 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"); }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- QString InitializeSyntheticVolume::estimateNumFeatures(IntVec3_t dims, FloatVec3_t res) { float totalvol = 0.0f; int32_t phase = 0; totalvol = (dims.x * res.x) * (dims.y * res.y) * (dims.z * res.z); if (totalvol == 0.0) { return "-1"; } DataContainerArray::Pointer dca = getDataContainerArray(); // Get the PhaseTypes - Remember there is a Dummy PhaseType in the first slot of the array QVector<size_t> cDims(1, 1); // This states that we are looking for an array with a single component UInt32ArrayType::Pointer phaseType = dca->getPrereqArrayFromPath<UInt32ArrayType, AbstractFilter>(NULL, getInputPhaseTypesArrayPath(), cDims); if (phaseType.get() == NULL) { QString ss = QObject::tr("Phase types array could not be downcast using std::dynamic_pointer_cast<T> when estimating the number of grains. The path is %1").arg(getInputPhaseTypesArrayPath().serialize()); setErrorCondition(-11002); notifyErrorMessage(getHumanLabel(), ss, getErrorCondition()); return "0"; } QVector<size_t> statsDims(1, 1); StatsDataArray::Pointer statsPtr = dca->getPrereqArrayFromPath<StatsDataArray, AbstractFilter>(this, getInputStatsArrayPath(), statsDims); if (statsPtr.get() == NULL) { QString ss = QObject::tr("Statistics array could not be downcast using std::dynamic_pointer_cast<T> when estimating the number of grains. The path is %1").arg(getInputStatsArrayPath().serialize()); notifyErrorMessage(getHumanLabel(), ss, -11001); return "0"; } if (!phaseType->isAllocated()) { if (getInputStatsFile().isEmpty()) { QString ss = QObject::tr("Phase types array has not been allocated and the input statistics file is empty"); setErrorCondition(-1000); notifyWarningMessage(getHumanLabel(), ss, getErrorCondition()); return "-1"; } QFileInfo fi(getInputStatsFile()); if (fi.exists() == false) { QString ss = QObject::tr("Phase types array has not been allocated and the input statistics file does not exist at '%1'").arg(fi.absoluteFilePath()); setErrorCondition(-1001); notifyWarningMessage(getHumanLabel(), ss, getErrorCondition()); return "-1"; } hid_t fileId = -1; herr_t err = 0; // open the file fileId = H5Utilities::openFile(getInputStatsFile().toLatin1().constData(), true); // This will make sure if we return early from this method that the HDF5 File is properly closed. HDF5ScopedFileSentinel scopedFileSentinel(&fileId, true); DataArrayPath dap = getInputPhaseTypesArrayPath(); // Generate the path to the AttributeMatrix QString hPath = DREAM3D::StringConstants::DataContainerGroupName + "/" + dap.getDataContainerName() + "/" + dap.getAttributeMatrixName(); // Open the AttributeMatrix Group hid_t amGid = H5Gopen(fileId, hPath.toLatin1().data(), H5P_DEFAULT ); scopedFileSentinel.addGroupId(&amGid); err = phaseType->readH5Data(amGid); if (err < 0) { QString ss = QObject::tr("Error reading phase type data"); setErrorCondition(-1003); notifyWarningMessage(getHumanLabel(), ss, getErrorCondition()); return "-1"; } if (!phaseType->isAllocated()) { QString ss = QObject::tr("Phase types Array was not allocated due to an error reading the data from the statistics file %1").arg(fi.absoluteFilePath()); setErrorCondition(-1002); notifyWarningMessage(getHumanLabel(), ss, getErrorCondition()); return "-1"; } } // Create a Reference Variable so we can use the [] syntax StatsDataArray& statsDataArray = *(statsPtr.get()); std::vector<int32_t> primaryphases; std::vector<double> primaryphasefractions; double totalprimaryfractions = 0.0; // find which phases are primary phases for (size_t i = 1; i < phaseType->getNumberOfTuples(); ++i) { if (phaseType->getValue(i) == DREAM3D::PhaseType::PrimaryPhase) { PrimaryStatsData* pp = PrimaryStatsData::SafePointerDownCast(statsDataArray[i].get()); primaryphases.push_back(i); primaryphasefractions.push_back(pp->getPhaseFraction()); totalprimaryfractions = totalprimaryfractions + pp->getPhaseFraction(); } } // scale the primary phase fractions to total to 1 for (int32_t i = 0; i < primaryphasefractions.size(); i++) { primaryphasefractions[i] = primaryphasefractions[i] / totalprimaryfractions; } SIMPL_RANDOMNG_NEW() // generate the Features int32_t gid = 1; float currentvol = 0.0f; float vol = 0.0f; float diam = 0.0f; bool volgood = false; for (int32_t j = 0; j < primaryphases.size(); ++j) { float curphasetotalvol = totalvol * primaryphasefractions[j]; while (currentvol < curphasetotalvol) { volgood = false; phase = primaryphases[j]; PrimaryStatsData* pp = PrimaryStatsData::SafePointerDownCast(statsDataArray[phase].get()); if (NULL == pp) { QString ss = QObject::tr("Tried to cast a statsDataArray[%1].get() to a PrimaryStatsData* " "pointer but this resulted in a NULL pointer.\n") .arg(phase).arg(phase); setErrorCondition(-666); notifyErrorMessage(getHumanLabel(), ss, getErrorCondition()); return "-1"; } while (volgood == false) { volgood = true; if (pp->getFeatureSize_DistType() == DREAM3D::DistributionType::LogNormal) { float avgdiam = pp->getFeatureSizeDistribution().at(0)->getValue(0); float sddiam = pp->getFeatureSizeDistribution().at(1)->getValue(0); diam = rg.genrand_norm(avgdiam, sddiam); diam = expf(diam); if (diam >= pp->getMaxFeatureDiameter()) { volgood = false; } if (diam < pp->getMinFeatureDiameter()) { volgood = false; } vol = (4.0f / 3.0f) * (M_PI) * ((diam * 0.5f) * (diam * 0.5f) * (diam * 0.5f)); } } currentvol = currentvol + vol; gid++; } } return QString::number(gid); }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void AdaptiveAlignmentMutualInformation::form_features_sections() { SIMPL_RANDOMNG_NEW() DataContainer::Pointer m = getDataContainerArray()->getDataContainer(getDataContainerName()); size_t udims[3] = { 0, 0, 0 }; m->getGeometryAs<ImageGeom>()->getDimensions(udims); int64_t dims[3] = { static_cast<int64_t>(udims[0]), static_cast<int64_t>(udims[1]), static_cast<int64_t>(udims[2]), }; int64_t point = 0; int64_t seed = 0; bool noseeds = false; int32_t featurecount = 1; int64_t neighbor = 0; QuatF q1 = QuaternionMathF::New(); QuatF q2 = QuaternionMathF::New(); QuatF* quats = reinterpret_cast<QuatF*>(m_Quats); float w = 0.0f; float n1 = 0.0f; float n2 = 0.0f; float n3 = 0.0f; int64_t randx = 0; int64_t randy = 0; bool good = false; int64_t x = 0, y = 0, z = 0; int64_t col = 0, row = 0; size_t size = 0; size_t initialVoxelsListSize = 1000; m_FeatureCounts->resize(dims[2]); featurecounts = m_FeatureCounts->getPointer(0); int32_t* miFeatureIds = m_MIFeaturesPtr->getPointer(0); std::vector<int64_t> voxelslist(initialVoxelsListSize, -1); int64_t neighpoints[4] = { 0, 0, 0, 0 }; neighpoints[0] = -dims[0]; neighpoints[1] = -1; neighpoints[2] = 1; neighpoints[3] = dims[0]; uint32_t phase1 = 0, phase2 = 0; for (int64_t slice = 0; slice < dims[2]; slice++) { float prog = ((float)slice / dims[2]) * 100; QString ss = QObject::tr("Aligning Sections || Identifying Features on Sections || %1% Complete").arg(QString::number(prog, 'f', 0)); notifyStatusMessage(getMessagePrefix(), getHumanLabel(), ss); featurecount = 1; noseeds = false; while (noseeds == false) { seed = -1; randx = int64_t(float(rg.genrand_res53()) * float(dims[0])); randy = int64_t(float(rg.genrand_res53()) * float(dims[1])); for (int64_t j = 0; j < dims[1]; ++j) { for (int64_t i = 0; i < dims[0]; ++i) { x = randx + i; y = randy + j; z = slice; if (x > dims[0] - 1) { x = x - dims[0]; } if (y > dims[1] - 1) { y = y - dims[1]; } point = (z * dims[0] * dims[1]) + (y * dims[0]) + x; if ((m_UseGoodVoxels == false || m_GoodVoxels[point] == true) && miFeatureIds[point] == 0 && m_CellPhases[point] > 0) { seed = point; } if (seed > -1) { break; } } if (seed > -1) { break; } } if (seed == -1) { noseeds = true; } if (seed >= 0) { size = 0; miFeatureIds[seed] = featurecount; voxelslist[size] = seed; size++; for (size_t j = 0; j < size; ++j) { int64_t currentpoint = voxelslist[j]; col = currentpoint % dims[0]; row = (currentpoint / dims[0]) % dims[1]; QuaternionMathF::Copy(quats[currentpoint], q1); phase1 = m_CrystalStructures[m_CellPhases[currentpoint]]; for (int32_t i = 0; i < 4; i++) { good = true; neighbor = currentpoint + neighpoints[i]; if ((i == 0) && row == 0) { good = false; } if ((i == 3) && row == (dims[1] - 1)) { good = false; } if ((i == 1) && col == 0) { good = false; } if ((i == 2) && col == (dims[0] - 1)) { good = false; } if (good == true && miFeatureIds[neighbor] <= 0 && m_CellPhases[neighbor] > 0) { w = std::numeric_limits<float>::max(); QuaternionMathF::Copy(quats[neighbor], q2); phase2 = m_CrystalStructures[m_CellPhases[neighbor]]; if (phase1 == phase2) { w = m_OrientationOps[phase1]->getMisoQuat(q1, q2, n1, n2, n3); } if (w < m_MisorientationTolerance) { miFeatureIds[neighbor] = featurecount; voxelslist[size] = neighbor; size++; if (std::vector<int64_t>::size_type(size) >= voxelslist.size()) { size = voxelslist.size(); voxelslist.resize(size + initialVoxelsListSize); for (std::vector<int64_t>::size_type v = size; v < voxelslist.size(); ++v) { voxelslist[v] = -1; } } } } } } voxelslist.erase(std::remove(voxelslist.begin(), voxelslist.end(), -1), voxelslist.end()); featurecount++; voxelslist.assign(initialVoxelsListSize, -1); } } featurecounts[slice] = featurecount; } }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void EstablishMatrixPhase::establish_matrix() { notifyStatusMessage(getHumanLabel(), "Establishing Matrix"); SIMPL_RANDOMNG_NEW() DataContainer::Pointer m = getDataContainerArray()->getDataContainer(getOutputCellAttributeMatrixPath().getDataContainerName()); StatsDataArray& statsDataArray = *(m_StatsDataArray.lock()); size_t udims[3] = { 0, 0, 0 }; m->getGeometryAs<ImageGeom>()->getDimensions(udims); #if (CMP_SIZEOF_SIZE_T == 4) typedef int32_t DimType; #else typedef int64_t DimType; #endif DimType dims[3] = { static_cast<DimType>(udims[0]), static_cast<DimType>(udims[1]), static_cast<DimType>(udims[2]), }; sizex = dims[0] * m->getGeometryAs<ImageGeom>()->getXRes(); sizey = dims[1] * m->getGeometryAs<ImageGeom>()->getYRes(); sizez = dims[2] * m->getGeometryAs<ImageGeom>()->getZRes(); totalvol = sizex * sizey * sizez; size_t totalPoints = m_FeatureIdsPtr.lock()->getNumberOfTuples(); size_t currentnumfeatures = m_FeaturePhasesPtr.lock()->getNumberOfTuples(); size_t numensembles = m_PhaseTypesPtr.lock()->getNumberOfTuples(); QVector<size_t> tDims(1, 1); if (currentnumfeatures == 0) { m->getAttributeMatrix(m_OutputCellFeatureAttributeMatrixName)->resizeAttributeArrays(tDims); updateFeatureInstancePointers(); currentnumfeatures = 1; } firstMatrixFeature = currentnumfeatures; float random = 0.0f; float totalmatrixfractions = 0.0f; for (size_t i = 1; i < numensembles; ++i) { if (m_PhaseTypes[i] == DREAM3D::PhaseType::MatrixPhase) { MatrixStatsData* mp = MatrixStatsData::SafePointerDownCast(statsDataArray[i].get()); if (NULL == mp) { QString ss = QObject::tr("Tried to cast a statsDataArray[%1].get() to a MatrixStatsData* " "pointer but this resulted in a NULL pointer. The value at m_PhaseTypes[%2] = %3 does not match up " "with the type of pointer stored in the StatsDataArray (MatrixStatsData)\n") .arg(i).arg(i).arg(m_PhaseTypes[i]); notifyErrorMessage(getHumanLabel(), ss, -666); setErrorCondition(-666); return; } matrixphases.push_back(i); matrixphasefractions.push_back(mp->getPhaseFraction()); totalmatrixfractions = totalmatrixfractions + mp->getPhaseFraction(); } } for (int32_t i = 0; i < matrixphases.size(); i++) { matrixphasefractions[i] = matrixphasefractions[i] / totalmatrixfractions; if (i > 0) { matrixphasefractions[i] = matrixphasefractions[i] + matrixphasefractions[i - 1]; } } size_t j = 0; for (size_t i = 0; i < totalPoints; ++i) { if ((m_UseMask == false && m_FeatureIds[i] <= 0) || (m_UseMask == true && m_Mask[i] == true && m_FeatureIds[i] <= 0)) { random = static_cast<float>( rg.genrand_res53() ); j = 0; while (random > matrixphasefractions[j]) { j++; } if (m->getAttributeMatrix(m_OutputCellFeatureAttributeMatrixName)->getNumTuples() <= (firstMatrixFeature + j)) { tDims[0] = (firstMatrixFeature + j) + 1; m->getAttributeMatrix(m_OutputCellFeatureAttributeMatrixName)->resizeAttributeArrays(tDims); updateFeatureInstancePointers(); m_NumFeatures[j] = 1; } m_FeatureIds[i] = (firstMatrixFeature + j); m_CellPhases[i] = matrixphases[j]; m_FeaturePhases[(firstMatrixFeature + j)] = matrixphases[j]; } else if (m_UseMask == true && m_Mask[i] == false) { m_FeatureIds[i] = 0; m_CellPhases[i] = 0; } } }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- std::vector<float> RadialDistributionFunction::GenerateRandomDistribution(float minDistance, float maxDistance, int numBins, std::vector<float> boxdims, std::vector<float> boxres) { std::vector<float> freq(numBins, 0); std::vector<float> randomCentroids; std::vector<std::vector<float> > distancelist; int32_t largeNumber = 1000; int32_t numDistances = largeNumber * (largeNumber - 1); // boxdims are the dimensions of the box in microns // boxres is the resoultion of the box in microns int32_t xpoints = boxdims[0] / boxres[0]; int32_t ypoints = boxdims[1] / boxres[1]; int32_t zpoints = boxdims[2] / boxres[2]; int32_t bin; int32_t totalpoints = xpoints * ypoints * zpoints; float x, y, z; float xn, yn, zn; float xc, yc, zc; float r; size_t featureOwnerIdx = 0; size_t column, row, plane; float stepsize = (maxDistance - minDistance) / numBins; float maxBoxDistance = sqrtf((boxdims[0] * boxdims[0]) + (boxdims[1] * boxdims[1]) + (boxdims[2] * boxdims[2])); int32_t current_num_bins = ceil((maxBoxDistance - minDistance) / (stepsize)); freq.resize(current_num_bins + 1); SIMPL_RANDOMNG_NEW(); randomCentroids.resize(largeNumber * 3); //Generating all of the random points and storing their coordinates in randomCentroids for (int32_t i = 0; i < largeNumber; i++) { featureOwnerIdx = static_cast<size_t>(rg.genrand_res53() * totalpoints); column = featureOwnerIdx % xpoints; row = int(featureOwnerIdx / xpoints) % ypoints; plane = featureOwnerIdx / (xpoints * ypoints); xc = static_cast<float>(column * boxres[0]) ; yc = static_cast<float>(row * boxres[1]); zc = static_cast<float>(plane * boxres[2]); randomCentroids[3 * i] = xc; randomCentroids[3 * i + 1] = yc; randomCentroids[3 * i + 2] = zc; } distancelist.resize(largeNumber); //Calculating all of the distances and storing them in the distnace list for (int32_t i = 1; i < largeNumber; i++) { x = randomCentroids[3 * i]; y = randomCentroids[3 * i + 1]; z = randomCentroids[3 * i + 2]; for (int32_t j = i + 1; j < largeNumber; j++) { xn = randomCentroids[3 * j]; yn = randomCentroids[3 * j + 1]; zn = randomCentroids[3 * j + 2]; r = sqrtf((x - xn) * (x - xn) + (y - yn) * (y - yn) + (z - zn) * (z - zn)); distancelist[i].push_back(r); distancelist[j].push_back(r); } } //bin up the distance list for (int32_t i = 0; i < largeNumber; i++) { for (size_t j = 0; j < distancelist[i].size(); j++) { bin = (distancelist[i][j] - minDistance) / stepsize; if (distancelist[i][j] < minDistance) { bin = -1; } freq[bin + 1]++; } } for (int32_t i = 0; i < current_num_bins + 1; i++) { freq[i] = freq[i] / (numDistances); } return freq; }
static void CalculateCubicODFData(T* e1s, T* e2s, T* e3s, T* weights, T* sigmas, bool normalize, T* odf, size_t numEntries) { SIMPL_RANDOMNG_NEW() CubicOps ops; Int32ArrayType::Pointer textureBins = Int32ArrayType::CreateArray(numEntries, "TextureBins"); int32_t* TextureBins = textureBins->getPointer(0); float addweight = 0; float totaladdweight = 0; float totalweight = float(ops.getODFSize()); int bin, addbin; int bin1, bin2, bin3; int addbin1, addbin2, addbin3; float dist, fraction; for (size_t i = 0; i < numEntries; i++) { FOrientArrayType eu(e1s[i], e2s[i], e3s[i]); FOrientArrayType rod(4); OrientationTransforms<FOrientArrayType, float>::eu2ro(eu, rod); rod = ops.getODFFZRod(rod); bin = ops.getOdfBin(rod); TextureBins[i] = static_cast<int>(bin); } for (int i = 0; i < ops.getODFSize(); i++) { odf[i] = 0; } for (size_t i = 0; i < numEntries; i++) { bin = TextureBins[i]; bin1 = bin % 18; bin2 = (bin / 18) % 18; bin3 = bin / (18 * 18); for (int j = -sigmas[i]; j <= sigmas[i]; j++) { int jsqrd = j * j; for (int k = -sigmas[i]; k <= sigmas[i]; k++) { int ksqrd = k * k; for (int l = -sigmas[i]; l <= sigmas[i]; l++) { int lsqrd = l * l; addbin1 = bin1 + int(j); addbin2 = bin2 + int(k); addbin3 = bin3 + int(l); //if(addbin1 < 0) addbin1 = addbin1 + 18; //if(addbin1 >= 18) addbin1 = addbin1 - 18; //if(addbin2 < 0) addbin2 = addbin2 + 18; //if(addbin2 >= 18) addbin2 = addbin2 - 18; //if(addbin3 < 0) addbin3 = addbin3 + 18; //if(addbin3 >= 18) addbin3 = addbin3 - 18; int good = 1; if(addbin1 < 0) { good = 0; } if(addbin1 >= 18) { good = 0; } if(addbin2 < 0) { good = 0; } if(addbin2 >= 18) { good = 0; } if(addbin3 < 0) { good = 0; } if(addbin3 >= 18) { good = 0; } addbin = (addbin3 * 18 * 18) + (addbin2 * 18) + (addbin1); dist = powf((jsqrd + ksqrd + lsqrd), 0.5); fraction = 1.0 - (double(dist / int(sigmas[i])) * double(dist / int(sigmas[i]))); if(dist <= int(sigmas[i]) && good == 1) { addweight = (weights[i] * fraction); if(sigmas[i] == 0.0) { addweight = weights[i]; } odf[addbin] = odf[addbin] + addweight; totaladdweight = totaladdweight + addweight; } } } } } if(totaladdweight > totalweight) { float scale = (totaladdweight / totalweight); for (int i = 0; i < ops.getODFSize(); i++) { odf[i] = odf[i] / scale; } } else { float remainingweight = totalweight - totaladdweight; float background = remainingweight / static_cast<float>(ops.getODFSize()); for (int i = 0; i < ops.getODFSize(); i++) { odf[i] += background; } } if (normalize == true) { // Normalize the odf for (int i = 0; i < ops.getODFSize(); i++) { odf[i] = odf[i] / totalweight; } } }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- 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"); }