virtual void work() { Random random; unsigned delta=0; for(unsigned pos=0; pos<Total ;setCurrent(++pos)) { if( getCancel() ) { setResult("test cancelled"); return; } unsigned sy=random.select(1,10000); unsigned sx=sy+random.select(10000); Replace_max(delta,test1(sx,sy)); } char temp[TextBufLen]; PrintBuf out(Range(temp)); Printf(out,"delta = #;",delta); setResult(out.close()); }
virtual void work() { Random random; for(unsigned pos=0; pos<Total ;setCurrent(++pos)) { if( getCancel() ) { setResult("test cancelled"); return; } unsigned sy=random.select(1,1000); unsigned sx=sy+random.select(10000); test1(sx,sy); test2(sx,sy,random.select(1,1000),random.select(1,1000)); test3((uCoord)sx,(uCoord)sy); } setResult("test ok"); }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void MultiEmmpmFilter::execute() { setErrorCondition(0); dataCheck(); if (getErrorCondition() < 0) { return; } DataArrayPath inputAMPath = DataArrayPath::GetAttributeMatrixPath(getInputDataArrayVector()); QList<QString> arrayNames = DataArrayPath::GetDataArrayNames(getInputDataArrayVector()); QListIterator<QString> iter(arrayNames); QString msgPrefix = getMessagePrefix(); int32_t i = 1; // This is the routine that sets up the EM/MPM to segment the image while (iter.hasNext()) { DataArrayPath arrayPath = inputAMPath; QString name = iter.next(); arrayPath.setDataArrayName(name); setInputDataArrayPath(arrayPath); // Change the output AttributeMatrix arrayPath.setAttributeMatrixName(getOutputAttributeMatrixName()); QString outName = getOutputArrayPrefix() + arrayPath.getDataArrayName(); arrayPath.setDataArrayName(outName); // Remove the array if it already exists ; this would be very strange but check for it anyway getDataContainerArray()->getAttributeMatrix(arrayPath)->removeAttributeArray(outName); setOutputDataArrayPath(arrayPath); QString prefix = QObject::tr("%1 (Array %2 of %3)").arg(msgPrefix).arg(i).arg(arrayNames.size()); setMessagePrefix(prefix); if ( i == 2 && getUsePreviousMuSigma()) { setEmmpmInitType(EMMPM_ManualInit); } else { setEmmpmInitType(EMMPM_Basic); } EMMPMFilter::execute(); if (getErrorCondition() < 0) { break; } i++; if (getCancel()) { break; } } if (getErrorCondition() < 0) { QString ss = QObject::tr("Error occurred running the EM/MPM algorithm"); setErrorCondition(-60009); notifyErrorMessage(getHumanLabel(), ss, getErrorCondition()); return; } /* Let the GUI know we are done with this filter */ notifyStatusMessage(getHumanLabel(), "Complete"); }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void CreateDataContainer::execute() { setErrorCondition(0); dataCheck(); if(getErrorCondition() < 0) { return; } if (getCancel() == true) { return; } if (getErrorCondition() < 0) { QString ss = QObject::tr("Some error message"); setErrorCondition(-99999999); notifyErrorMessage(getHumanLabel(), ss, getErrorCondition()); return; } notifyStatusMessage(getHumanLabel(), "Complete"); }
void RtKeyboard::EnableExtKey(void) { m_pExtTimer->stop(); signalMapper->blockSignals(true); //Delete the Select Key, if it is exist. if(m_pSelectKey) { delete m_pSelectKey; m_pSelectKey = NULL; } QWidget *parent = (QWidget*)this->parent(); if(parent == NULL) parent = this; EnableKeyButton(false); if(m_pExtKey){ delete m_pExtKey; m_pExtKey = NULL; } m_pExtKey = new RtExtKey(parent,m_strExtKey); connect(m_pExtKey, SIGNAL(keySelected(const QString&)), this, SIGNAL(keySelected(const QString&))); connect(m_pExtKey, SIGNAL(getCancel()), this, SIGNAL(keySelected(const QString&))); m_pExtKey->setModal(true); m_pExtKey->setEnabled(true); m_pExtKey->exec(); signalMapper->blockSignals(false); EnableKeyButton(true); m_pExtKey = NULL; /* //m_strExtKey QMessageBox::warning(this, tr("My test"), tr("Ext button.\n" "Test Test!!!"), QMessageBox::Ok , QMessageBox::Ok); */ }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void GenerateNodeTriangleConnectivity::generateConnectivity() { // Get our Reference counted Array of Triangle Structures StructArray<SurfaceMesh::DataStructures::Face_t>::Pointer trianglesPtr = getSurfaceMeshDataContainer()->getTriangles(); if(NULL == trianglesPtr.get()) { setErrorCondition(-556); notifyErrorMessage("The SurfaceMesh DataContainer Does NOT contain Triangles", -556); return; } int ntri = trianglesPtr->GetNumberOfTuples(); NodeTrianglesMap_t m_Node2Triangle; notifyStatusMessage("Creating the Mapping of Triangles to Node"); // get the triangle definitions - use the pointer to the start of the Struct Array Triangle* triangles = trianglesPtr->GetPointer(0); // Generate the map of node_id -> Triangles that include that node_id value for(int i = 0; i < ntri; ++i) { Triangle& tri = triangles[i]; m_Node2Triangle[tri.node_id[0]].insert(i); m_Node2Triangle[tri.node_id[1]].insert(i); m_Node2Triangle[tri.node_id[2]].insert(i); } if (getCancel() == true) { return; } ManagedPointerArray<int>::Pointer nodeTriangleArray = ManagedPointerArray<int>::CreateArray(m_Node2Triangle.size(), DREAM3D::CellData::SurfaceMeshNodeTriangles); float progIndex = 0.0; float curPercent = 0.0; float total = static_cast<float>(m_Node2Triangle.size()); std::stringstream ss; // Loop over each entry in the map for(NodeTrianglesMap_t::iterator iter = m_Node2Triangle.begin(); iter != m_Node2Triangle.end(); ++iter) { if ( progIndex/total * 100.0f > (curPercent) ) { ss.str(""); ss << (progIndex/total * 100.0f) << "% Complete"; notifyStatusMessage(ss.str()); curPercent += 5.0f; } progIndex++; if (getCancel() == true) { return; } int nodeId = (*iter).first; ManagedPointerArray<int>::Data_t& entry = *(nodeTriangleArray->GetPointer(nodeId)); UniqueTriangleIds_t& triangles = (*iter).second; // Allocate enough memory to hold the list of triangles entry.count = triangles.size(); if (entry.count > 0) { entry.data = (int*)(malloc(sizeof(int) * entry.count)); int index = 0; for(UniqueTriangleIds_t::iterator tIter = triangles.begin(); tIter != triangles.end(); ++tIter) { entry.data[index++] = *tIter; // Copy the value from the triangle Ids set into the ManagedPointer } } } getSurfaceMeshDataContainer()->addCellData(nodeTriangleArray->GetName(), nodeTriangleArray); return; }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void SegmentGrains::execute() { setErrorCondition(0); VoxelDataContainer* m = getVoxelDataContainer(); std::stringstream ss; if(NULL == m) { setErrorCondition(-1); ss << " DataContainer was NULL"; addErrorMessage(getHumanLabel(), ss.str(), -1); return; } size_t udims[3] = { 0, 0, 0 }; m->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]), }; size_t gnum = 1; int seed = 0; int neighbor; bool good = 0; DimType col, row, plane; size_t size = 0; size_t initialVoxelsListSize = 1000; std::vector<int> voxelslist(initialVoxelsListSize, -1); DimType neighpoints[6]; neighpoints[0] = -(dims[0] * dims[1]); neighpoints[1] = -dims[0]; neighpoints[2] = -1; neighpoints[3] = 1; neighpoints[4] = dims[0]; neighpoints[5] = (dims[0] * dims[1]); // Burn volume with tight orientation tolerance to simulate simultaneous growth/aglomeration while (seed >= 0) { seed = getSeed(gnum); if(seed >= 0) { size = 0; voxelslist[size] = seed; size++; for (size_t j = 0; j < size; ++j) { // Get the current Voxel size_t currentpoint = voxelslist[j]; // Figure out the Row, Col & Plane the voxel is located in col = currentpoint % dims[0]; row = (currentpoint / dims[0]) % dims[1]; plane = currentpoint / (dims[0] * dims[1]); // Now loop over its 6 neighbors for (int i = 0; i < 6; i++) { good = true; neighbor = currentpoint + neighpoints[i]; // Make sure we have a valid neighbor taking into account the edges of the volume if(i == 0 && plane == 0) good = false; if(i == 5 && plane == (dims[2] - 1)) good = false; if(i == 1 && row == 0) good = false; if(i == 4 && row == (dims[1] - 1)) good = false; if(i == 2 && col == 0) good = false; if(i == 3 && col == (dims[0] - 1)) good = false; if(good == true) { // We got a good voxel to check so check to see if it can be grouped with this point if(determineGrouping(currentpoint, neighbor, gnum) == true) { // The voxel can be grouped with this voxel so add it to the list of voxels for this grain voxelslist[size] = neighbor; // Increment the size of the list which affects the "j" loop size++; // Sanity check the size of the voxelslist vector. If it is not large enough, double the size of the vector if(size >= voxelslist.size()) { voxelslist.resize(size + size, -1); // The resize is a hit but the doubling mitigates the penalty somewhat } } } } } voxelslist.clear(); voxelslist.resize(initialVoxelsListSize, -1); gnum++; ss.str(""); ss << "Total Grains: " << gnum; if(gnum%100 == 0) notifyStatusMessage(ss.str()); if (getCancel() == true) { setErrorCondition(-1); break; } } } // If there is an error set this to something negative and also set a message notifyStatusMessage("Completed"); }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- int32_t LaplacianSmoothing::edgeBasedSmoothing() { int32_t err = 0; DataContainer::Pointer sm = getDataContainerArray()->getDataContainer(getSurfaceDataContainerName()); IGeometry2D::Pointer surfaceMesh = sm->getGeometryAs<IGeometry2D>(); float* verts = surfaceMesh->getVertexPointer(0); int64_t nvert = surfaceMesh->getNumberOfVertices(); // Generate the Lambda Array err = generateLambdaArray(); if (err < 0) { setErrorCondition(-557); notifyErrorMessage(getHumanLabel(), "Error generating the lambda array", getErrorCondition()); return err; } // Get a Pointer to the Lambda array for conveneince DataArray<float>::Pointer lambdas = getLambdaArray(); float* lambda = lambdas->getPointer(0); // Generate the Unique Edges if (NULL == surfaceMesh->getEdges().get()) { err = surfaceMesh->findEdges(); } if (err < 0) { setErrorCondition(-560); notifyErrorMessage(getHumanLabel(), "Error retrieving the shared edge list", getErrorCondition()); return getErrorCondition(); } int64_t* uedges = surfaceMesh->getEdgePointer(0); int64_t nedges = surfaceMesh->getNumberOfEdges(); DataArray<int32_t>::Pointer numConnections = DataArray<int32_t>::CreateArray(nvert, "_INTERNAL_USE_ONLY_Laplacian_Smoothing_NumberConnections_Array"); numConnections->initializeWithZeros(); int32_t* ncon = numConnections->getPointer(0); QVector<size_t> cDims(1, 3); DataArray<double>::Pointer deltaArray = DataArray<double>::CreateArray(nvert, cDims, "_INTERNAL_USE_ONLY_Laplacian_Smoothing_Delta_Array"); deltaArray->initializeWithZeros(); double* delta = deltaArray->getPointer(0); double dlta = 0.0; for (int32_t q = 0; q < m_IterationSteps; q++) { if (getCancel() == true) { return -1; } QString ss = QObject::tr("Iteration %1").arg(q); notifyStatusMessage(getMessagePrefix(), getHumanLabel(), ss); for (int64_t i = 0; i < nedges; i++) { int64_t in1 = uedges[2 * i]; // row of the first vertex int64_t in2 = uedges[2 * i + 1]; // row the second vertex for (int32_t j = 0; j < 3; j++) { BOOST_ASSERT( static_cast<size_t>(3 * in1 + j) < static_cast<size_t>(nvert * 3) ); BOOST_ASSERT( static_cast<size_t>(3 * in2 + j) < static_cast<size_t>(nvert * 3) ); dlta = verts[3 * in2 + j] - verts[3 * in1 + j]; delta[3 * in1 + j] += dlta; delta[3 * in2 + j] += -1.0 * dlta; } ncon[in1] += 1; ncon[in2] += 1; } float ll = 0.0f; for (int64_t i = 0; i < nvert; i++) { for (int32_t j = 0; j < 3; j++) { int64_t in0 = 3 * i + j; dlta = delta[in0] / ncon[i]; ll = lambda[i]; verts[3 * i + j] += ll * dlta; delta[in0] = 0.0; // reset for next iteration } ncon[i] = 0; // reset for next iteration } } return err; }
// ----------------------------------------------------------------------------- // Updates the voxels specified in the list for homogenous update. For non homgenous // update computes the list. Calls the parallel update of voxels routine // ----------------------------------------------------------------------------- uint8_t BFReconstructionEngine::updateVoxels(int16_t OuterIter, int16_t Iter, std::vector<AMatrixCol::Pointer>& TempCol, RealVolumeType::Pointer ErrorSino, std::vector<AMatrixCol::Pointer>& VoxelLineResponse, CostData::Pointer cost, QGGMRF::QGGMRF_Values* BFQGGMRF_values, RealImageType::Pointer magUpdateMap, RealImageType::Pointer filtMagUpdateMap, UInt8Image_t::Pointer magUpdateMask, UInt8Image_t::Pointer m_VisitCount, Real_t PrevMagSum, uint32_t EffIterCount) { #if ROI //variables used to stop the process Real_t AverageUpdate = 0; Real_t AverageMagnitudeOfRecon = 0; #endif unsigned int updateType = MBIR::VoxelUpdateType::RegularRandomOrderUpdate; VoxelUpdateList::Pointer NHList;//non homogenous list of voxels to update #ifdef NHICD if(0 == EffIterCount % 2) { updateType = MBIR::VoxelUpdateType::HomogeniousUpdate; } else { updateType = MBIR::VoxelUpdateType::NonHomogeniousUpdate; } #endif//NHICD end if #if defined (OpenMBIR_USE_PARALLEL_ALGORITHMS) tbb::task_scheduler_init init; int m_NumThreads = init.default_num_threads(); #else int m_NumThreads = 1; #endif //Parallel algorithms std::stringstream ss; uint8_t exit_status = 1; //Indicates normal exit ; else indicates to stop inner iterations uint16_t subIterations = 1; std::string indent(" "); uint8_t err = 0; if(updateType == MBIR::VoxelUpdateType::RegularRandomOrderUpdate) { ss << indent << "Regular Random Order update of Voxels" << std::endl; } else if(updateType == MBIR::VoxelUpdateType::HomogeniousUpdate) { ss << indent << "Homogenous update of voxels" << std::endl; } else if(updateType == MBIR::VoxelUpdateType::NonHomogeniousUpdate) { ss << indent << "Non Homogenous update of voxels" << std::endl; subIterations = SUB_ITER; } else { ss << indent << "Unknown Voxel Update Type. Returning Now" << std::endl; notify(ss.str(), 0, Observable::UpdateErrorMessage); return exit_status; } if(getVerbose()) { std::cout << ss.str() << std::endl; } Real_t NH_Threshold = 0.0; int totalLoops = m_TomoInputs->NumOuterIter * m_TomoInputs->NumIter; #ifdef DEBUG if (getVeryVerbose()) { std::cout << "Max of list in ReconEngineExtra = " << std::endl; m_VoxelIdxList->printMaxList(std::cout); } #endif //DEBUG for (uint16_t NH_Iter = 0; NH_Iter < subIterations; ++NH_Iter) //This can be varied //so each iterations of the voxels has multiple passes over the voxels //but generally its set to 1 { ss.str(" "); ss << "Outer Iteration: " << OuterIter << " of " << m_TomoInputs->NumOuterIter; ss << " Inner Iteration: " << Iter << " of " << m_TomoInputs->NumIter; ss << " SubLoop: " << NH_Iter << " of " << subIterations; float currentLoop = static_cast<float>(OuterIter * m_TomoInputs->NumIter + Iter); notify(ss.str(), currentLoop / totalLoops * 100.0f, Observable::UpdateProgressValueAndMessage); if(updateType == MBIR::VoxelUpdateType::NonHomogeniousUpdate) { #ifdef DEBUG Real_t TempSum = 0; for (int32_t j = 0; j < m_Geometry->N_z; j++) { for (int32_t k = 0; k < m_Geometry->N_x; k++) { TempSum += magUpdateMap->getValue(j, k); } } if (getVeryVerbose()) { std::cout << "**********************************************" << std::endl; std::cout << "Average mag Prior to VSC" << TempSum / (m_Geometry->N_z * m_Geometry->N_x) << std::endl; std::cout << "**********************************************" << std::endl; } #endif //debug //Compute a filtered version of the magnitude update map ComputeVSC(magUpdateMap, filtMagUpdateMap); #ifdef DEBUG TempSum = 0; for (int32_t j = 0; j < m_Geometry->N_z; j++) { for (int32_t k = 0; k < m_Geometry->N_x; k++) { TempSum += magUpdateMap->getValue(j, k); } } if (getVeryVerbose()) { std::cout << "**********************************************" << std::endl; std::cout << "Average mag Prior to NH Thresh" << TempSum / (m_Geometry->N_z * m_Geometry->N_x) << std::endl; std::cout << "**********************************************" << std::endl; } #endif //debug START_TIMER; NH_Threshold = SetNonHomThreshold(filtMagUpdateMap); STOP_TIMER; PRINT_TIME(" SetNonHomThreshold"); if(getVerbose()) { std::cout << indent << "NHICD Threshold: " << NH_Threshold << std::endl; } //Generate a new List based on the NH_threshold m_VoxelIdxList = GenNonHomList(NH_Threshold, filtMagUpdateMap); } START_TIMER; #if defined (OpenMBIR_USE_PARALLEL_ALGORITHMS) std::vector<int> yCount(m_NumThreads, 0); int t = 0; for (int y = 0; y < m_Geometry->N_y; ++y) { yCount[t]++; ++t; if(t == m_NumThreads) { t = 0; } } //Checking which voxels are going to be visited and setting their magnitude value to zero for(int32_t tmpiter = 0; tmpiter < m_VoxelIdxList->numElements(); tmpiter++) { // m_VisitCount->setValue(1, m_VoxelIdxList.Array[tmpiter].zidx, m_VoxelIdxList.Array[tmpiter].xidx); m_VisitCount->setValue(1, m_VoxelIdxList->zIdx(tmpiter), m_VoxelIdxList->xIdx(tmpiter)); // magUpdateMap->setValue(0, m_VoxelIdxList.Array[tmpiter].zidx, m_VoxelIdxList.Array[tmpiter].xidx); magUpdateMap->setValue(0, m_VoxelIdxList->zIdx(tmpiter), m_VoxelIdxList->xIdx(tmpiter)); } uint16_t yStart = 0; uint16_t yStop = 0; tbb::task_list taskList; //Variables to maintain stopping criteria for regular type ICD boost::shared_array<Real_t> averageUpdate(new Real_t[m_NumThreads]); ::memset(averageUpdate.get(), 0, sizeof(Real_t) * m_NumThreads); boost::shared_array<Real_t> averageMagnitudeOfRecon(new Real_t[m_NumThreads]); ::memset(averageMagnitudeOfRecon.get(), 0, sizeof(Real_t) * m_NumThreads); size_t dims[3]; //Initialize individual magnitude maps for the separate threads dims[0] = m_Geometry->N_z; //height dims[1] = m_Geometry->N_x; //width std::vector<RealImageType::Pointer> magUpdateMaps; std::vector<VoxelUpdateList::Pointer> NewList(m_NumThreads); int16_t EffCoresUsed = 0; if(getVerbose()) { std::cout << " Starting multicore allocation with " << m_NumThreads << " threads.." << std::endl; } for (int t = 0; t < m_NumThreads; ++t) { yStart = yStop; yStop = yStart + yCount[t]; if (getVeryVerbose()) { std::cout << "Thread :" << t << "(" << yStart << "," << yStop << ")" << std::endl; } if(yStart == yStop) { continue; } // Processor has NO tasks to run because we have less Y's than cores else { EffCoresUsed++; } RealImageType::Pointer _magUpdateMap = RealImageType::New(dims, "Mag Update Map"); _magUpdateMap->initializeWithZeros(); magUpdateMaps.push_back(_magUpdateMap); //NewList[t] = m_VoxelIdxList; NewList[t] = VoxelUpdateList::GenRandList(m_VoxelIdxList); BFUpdateYSlice& a = *new (tbb::task::allocate_root()) BFUpdateYSlice(yStart, yStop, m_Geometry, OuterIter, Iter, m_Sinogram, TempCol, ErrorSino, VoxelLineResponse, m_ForwardModel.get(), magUpdateMask, _magUpdateMap, magUpdateMask, updateType, averageUpdate.get() + t, averageMagnitudeOfRecon.get() + t, m_AdvParams->ZERO_SKIPPING, BFQGGMRF_values, NewList[t] ); taskList.push_back(a); } tbb::task::spawn_root_and_wait(taskList); if(getVerbose()) { std::cout << " Voxel update complete using " << EffCoresUsed << " threads" << std::endl; } // Now sum up magnitude update map values //TODO: replace by a TBB reduce operation for (int t = 0; t < m_NumThreads; ++t) { #ifdef DEBUG if(getVeryVerbose()) //TODO: Change variable name averageUpdate to totalUpdate { std::cout << "Total Update for thread " << t << ":" << averageUpdate[t] << std::endl; std::cout << "Total Magnitude for thread " << t << ":" << averageMagnitudeOfRecon[t] << std::endl; } #endif //Debug AverageUpdate += averageUpdate[t]; AverageMagnitudeOfRecon += averageMagnitudeOfRecon[t]; } averageUpdate.reset(); // We are forcing the array to be deallocated, we could wait till the current scope terminates then the arrays would be automatically cleaned up averageMagnitudeOfRecon.reset(); // We are forcing the array to be deallocated, we could wait till the current scope terminates then the arrays would be automatically cleaned up NewList.resize(0); // Frees all the pointers //From individual threads update the magnitude map if(getVerbose()) { std::cout << " Magnitude Map Update.." << std::endl; } RealImageType::Pointer TempPointer; for(int32_t tmpiter = 0; tmpiter < m_VoxelIdxList->numElements(); tmpiter++) { Real_t TempSum = 0; for (uint16_t t = 0; t < magUpdateMaps.size(); ++t) { TempPointer = magUpdateMaps[t]; TempSum += TempPointer->getValue(m_VoxelIdxList->zIdx(tmpiter), m_VoxelIdxList->xIdx(tmpiter)); } //Set the overall magnitude update map magUpdateMap->setValue(TempSum, m_VoxelIdxList->zIdx(tmpiter), m_VoxelIdxList->xIdx(tmpiter)); } #else //TODO modify the single thread code to handle the list based iterations uint16_t yStop = m_Geometry->N_y; uint16_t yStart = 0; boost::shared_array<Real_t> averageUpdate(new Real_t[m_NumThreads]); ::memset(averageUpdate.get(), 0, sizeof(Real_t) * m_NumThreads); boost::shared_array<Real_t> averageMagnitudeOfRecon(new Real_t[m_NumThreads]); ::memset(averageMagnitudeOfRecon.get(), 0, sizeof(Real_t) * m_NumThreads); size_t dims[3]; //Initialize individual magnitude maps for the separate threads dims[0] = m_Geometry->N_z; //height dims[1] = m_Geometry->N_x; //width RealImageType::Pointer _magUpdateMap = RealImageType::New(dims, "Mag Update Map"); _magUpdateMap->initializeWithZeros(); struct List NewList = m_VoxelIdxList; NewList = GenRandList(NewList); BFUpdateYSlice yVoxelUpdate = BFUpdateYSlice(yStart, yStop, m_Geometry, OuterIter, Iter, m_Sinogram, TempCol, ErrorSino, VoxelLineResponse, m_ForwardModel.get(), magUpdateMask, _magUpdateMap, magUpdateMask, updateType, averageUpdate, averageMagnitudeOfRecon, m_AdvParams->ZERO_SKIPPING, BFQGGMRF_values, NewList); /*BFUpdateYSlice(yStart, yStop, m_Geometry, OuterIter, Iter, m_Sinogram, TempCol, ErrorSino, VoxelLineResponse, m_ForwardModel.get(), mask, magUpdateMap, magUpdateMask, updateType, NH_Threshold, averageUpdate, averageMagnitudeOfRecon , m_AdvParams->ZERO_SKIPPING, BFQGGMRF_values, m_VoxelIdxList);*/ yVoxelUpdate.execute(); // AverageUpdate += averageUpdate[0]; // AverageMagnitudeOfRecon += averageMagnitudeOfRecon[0]; averageUpdate.reset(); // We are forcing the array to be deallocated, we could wait till the current scope terminates then the arrays would be automatically cleaned up averageMagnitudeOfRecon.reset(); // We are forcing the array to be deallocated, we could wait till the current scope terminates then the arrays would be automatically cleaned up #endif //Parallel algorithms /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */STOP_TIMER; ss.str(""); ss << "Inner Iter: " << Iter << " Voxel Update"; PRINT_TIME(ss.str()); if(getVerbose()) { std::cout << "Total Update " << AverageUpdate << std::endl; std::cout << "Total Mag " << AverageMagnitudeOfRecon << std::endl; } if(getCancel() == true) { setErrorCondition(err); return exit_status; } } //Stopping criteria code exit_status = stopCriteria(magUpdateMap, magUpdateMask, PrevMagSum, EffIterCount); #ifdef WRITE_INTERMEDIATE_RESULTS if(Iter == NumOfWrites * WriteCount) { WriteCount++; sprintf(buffer, "%d", Iter); sprintf(Filename, "ReconstructedObjectAfterIter"); strcat(Filename, buffer); strcat(Filename, ".bin"); Fp3 = fopen(Filename, "w"); TempPointer = geometry->Object; NumOfBytesWritten = fwrite(&(geometry->Object->d[0][0][0]), sizeof(Real_t), geometry->N_x * geometry->N_y * geometry->N_z, Fp3); printf("%d\n", NumOfBytesWritten); fclose(Fp3); } #endif //write Intermediate results #ifdef NHICD /* NHList will go out of scope at the end of this function which will cause its destructor to be called and the memory automatically cleaned up */ // if(updateType == MBIR::VoxelUpdateType::NonHomogeniousUpdate && NHList.Array != NULL) // { // free(NHList.Array); // std::cout<<"Freeing memory allocated to non-homogenous List"<<std::endl; // } #endif //NHICD if(getVerbose()) { std::cout << "exiting voxel update routine" << std::endl; } return exit_status; }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void FindGBCD::execute() { setErrorCondition(0); dataCheckVoxel(); if(getErrorCondition() < 0) { return; } // order here matters...because we are going to use the size of the crystal structures out of the dataCheckVoxel to size the faceAttrMat in dataCheckSurfaceMesh dataCheckSurfaceMesh(); if(getErrorCondition() < 0) { return; } #ifdef SIMPLib_USE_PARALLEL_ALGORITHMS tbb::task_scheduler_init init; bool doParallel = true; #endif size_t totalPhases = m_CrystalStructuresPtr.lock()->getNumberOfTuples(); size_t totalFaces = m_SurfaceMeshFaceLabelsPtr.lock()->getNumberOfTuples(); size_t faceChunkSize = 50000; size_t numMisoReps = 576 * 4; if (totalFaces < faceChunkSize) { faceChunkSize = totalFaces; } // call the sizeGBCD function with proper chunkSize and numMisoReps to get Bins array set up properly sizeGBCD(faceChunkSize, numMisoReps); int32_t totalGBCDBins = m_GbcdSizes[0] * m_GbcdSizes[1] * m_GbcdSizes[2] * m_GbcdSizes[3] * m_GbcdSizes[4] * 2; uint64_t millis = QDateTime::currentMSecsSinceEpoch(); uint64_t currentMillis = millis; uint64_t startMillis = millis; uint64_t estimatedTime = 0; float timeDiff = 0.0f; startMillis = QDateTime::currentMSecsSinceEpoch(); int32_t hemisphere = 0; //create an array to hold the total face area for each phase and initialize the array to 0.0 DoubleArrayType::Pointer totalFaceAreaPtr = DoubleArrayType::CreateArray(totalPhases, "totalFaceArea"); totalFaceAreaPtr->initializeWithValue(0.0); double* totalFaceArea = totalFaceAreaPtr->getPointer(0); QString ss = QObject::tr("Calculating GBCD || 0/%1 Completed").arg(totalFaces); for (size_t i = 0; i < totalFaces; i = i + faceChunkSize) { if(getCancel() == true) { return; } if (i + faceChunkSize >= totalFaces) { faceChunkSize = totalFaces - i; } m_GbcdBinsArray->initializeWithValue(-1); #ifdef SIMPLib_USE_PARALLEL_ALGORITHMS if (doParallel == true) { tbb::parallel_for(tbb::blocked_range<size_t>(i, i + faceChunkSize), CalculateGBCDImpl(i, numMisoReps, m_SurfaceMeshFaceLabelsPtr.lock(), m_SurfaceMeshFaceNormalsPtr.lock(), m_FeatureEulerAnglesPtr.lock(), m_FeaturePhasesPtr.lock(), m_CrystalStructuresPtr.lock(), m_GbcdBinsArray, m_GbcdHemiCheckArray, m_GbcdDeltasArray, m_GbcdSizesArray, m_GbcdLimitsArray), tbb::auto_partitioner()); } else #endif { CalculateGBCDImpl serial(i, numMisoReps, m_SurfaceMeshFaceLabelsPtr.lock(), m_SurfaceMeshFaceNormalsPtr.lock(), m_FeatureEulerAnglesPtr.lock(), m_FeaturePhasesPtr.lock(), m_CrystalStructuresPtr.lock(), m_GbcdBinsArray, m_GbcdHemiCheckArray, m_GbcdDeltasArray, m_GbcdSizesArray, m_GbcdLimitsArray); serial.generate(i, i + faceChunkSize); } currentMillis = QDateTime::currentMSecsSinceEpoch(); if (currentMillis - millis > 1000) { QString ss = QObject::tr("Calculating GBCD || Triangles %1/%2 Completed").arg(i).arg(totalFaces); timeDiff = ((float)i / (float)(currentMillis - startMillis)); estimatedTime = (float)(totalFaces - i) / timeDiff; ss = ss + QObject::tr(" || Est. Time Remain: %1").arg(DREAM3D::convertMillisToHrsMinSecs(estimatedTime)); millis = QDateTime::currentMSecsSinceEpoch(); notifyStatusMessage(getMessagePrefix(), getHumanLabel(), ss); } if(getCancel() == true) { return; } int32_t phase = 0; int32_t feature = 0; double area = 0.0; for (size_t j = 0; j < faceChunkSize; j++) { area = m_SurfaceMeshFaceAreas[i + j]; feature = m_SurfaceMeshFaceLabels[2 * (i + j)]; phase = m_FeaturePhases[feature]; for (size_t k = 0; k < numMisoReps; k++) { if (m_GbcdBins[(j * numMisoReps) + (k)] >= 0) { hemisphere = 0; if (m_HemiCheck[(j * numMisoReps) + k] == false) { hemisphere = 1; } m_GBCD[(phase * totalGBCDBins) + (2 * m_GbcdBins[(j * numMisoReps) + (k)] + hemisphere)] += area; totalFaceArea[phase] += area; } } } } ss = QObject::tr("Starting GBCD Normalization"); notifyStatusMessage(getMessagePrefix(), getHumanLabel(), ss); for (int32_t i = 0; i < totalPhases; i++) { size_t phaseShift = i * totalGBCDBins; double MRDfactor = double(totalGBCDBins) / totalFaceArea[i]; for (int32_t j = 0; j < totalGBCDBins; j++) { m_GBCD[phaseShift + j] *= MRDfactor; } } /* Let the GUI know we are done with this filter */ notifyStatusMessage(getHumanLabel(), "Complete"); }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void EbsdToH5Ebsd::execute() { std::stringstream ss; herr_t err = 0; hid_t fileId = -1; if(m_OutputFile.empty() == true) { std::string s("EbsdToH5Ebsd Error: The output file was not set correctly or is empty. The current value is '"); s.append("'. Please set the output file before running the importer. "); ss << "EbsdToH5Ebsd input filename was empty"; addErrorMessage(getHumanLabel(), ss.str(), err); setErrorCondition(-1); return; } // Make sure any directory path is also available as the user may have just typed // in a path without actually creating the full path std::string parentPath = MXAFileInfo::parentPath(m_OutputFile); if(!MXADir::mkdir(parentPath, true)) { std::stringstream ss; PipelineMessage em (getHumanLabel(), ss.str(), -1); addErrorMessage(em); setErrorCondition(-1); return; } // Create File fileId = H5Utilities::createFile(m_OutputFile); if(fileId < 0) { err = -1; ss.str(""); ss << "The Output HDF5 file could not be created. Check Permissions, if the File is in use by another program."; addErrorMessage(getHumanLabel(), ss.str(), err); setErrorCondition(-1); return; } HDF5ScopedFileSentinel sentinel(&fileId, true); err = H5Lite::writeScalarDataset(fileId, Ebsd::H5::ZResolution, m_ZResolution); if(err < 0) { ss.str(""); ss << "Could not write the Z Resolution Scalar to the HDF5 File"; addErrorMessage(getHumanLabel(), ss.str(), err); setErrorCondition(-1); } unsigned int ui = static_cast<unsigned int>(m_RefFrameZDir); err = H5Lite::writeScalarDataset(fileId, Ebsd::H5::StackingOrder, ui); if(err < 0) { ss.str(""); ss << "Could not write the Stacking Order Scalar to the HDF5 File"; addErrorMessage(getHumanLabel(), ss.str(), err); setErrorCondition(-1); } std::string s = Ebsd::StackingOrder::Utils::getStringForEnum(m_RefFrameZDir); err = H5Lite::writeStringAttribute(fileId, Ebsd::H5::StackingOrder, "Name", s); if(err < 0) { ss.str(""); ss << "Could not write the Stacking Order Name Attribute to the HDF5 File"; addErrorMessage(getHumanLabel(), ss.str(), err); setErrorCondition(-1); } err = H5Lite::writeScalarDataset(fileId, Ebsd::H5::SampleTransformationAngle, m_SampleTransformationAngle); if(err < 0) { ss.str(""); ss << "Could not write the Sample Transformation Angle to the HDF5 File"; addErrorMessage(getHumanLabel(), ss.str(), err); setErrorCondition(-1); } std::vector<hsize_t> dims(1,3); err = H5Lite::writeVectorDataset(fileId, Ebsd::H5::SampleTransformationAxis, dims, m_SampleTransformationAxis); if(err < 0) { ss.str(""); ss << "Could not write the Sample Transformation Axis to the HDF5 File"; addErrorMessage(getHumanLabel(), ss.str(), err); setErrorCondition(-1); } err = H5Lite::writeScalarDataset(fileId, Ebsd::H5::EulerTransformationAngle, m_EulerTransformationAngle); if(err < 0) { ss.str(""); ss << "Could not write the Euler Transformation Angle to the HDF5 File"; addErrorMessage(getHumanLabel(), ss.str(), err); setErrorCondition(-1); } err = H5Lite::writeVectorDataset(fileId, Ebsd::H5::EulerTransformationAxis, dims, m_EulerTransformationAxis); if(err < 0) { ss.str(""); ss << "Could not write the Euler Transformation Axis to the HDF5 File"; addErrorMessage(getHumanLabel(), ss.str(), err); setErrorCondition(-1); } EbsdImporter::Pointer fileImporter; // Write the Manufacturer of the OIM file here // This list will grow to be the number of EBSD file formats we support std::string ext = MXAFileInfo::extension(m_EbsdFileList.front()); if(ext.compare(Ebsd::Ang::FileExt) == 0) { err = H5Lite::writeStringDataset(fileId, Ebsd::H5::Manufacturer, Ebsd::Ang::Manufacturer); if(err < 0) { ss.str(""); ss << "Could not write the Manufacturer Data to the HDF5 File"; addErrorMessage(getHumanLabel(), ss.str(), err); setErrorCondition(-1); } fileImporter = H5AngImporter::New(); } else if(ext.compare(Ebsd::Ctf::FileExt) == 0) { err = H5Lite::writeStringDataset(fileId, Ebsd::H5::Manufacturer, Ebsd::Ctf::Manufacturer); if(err < 0) { ss.str(""); ss << "Could not write the Manufacturer Data to the HDF5 File"; addErrorMessage(getHumanLabel(), ss.str(), err); setErrorCondition(-1); } fileImporter = H5CtfImporter::New(); } else if(ext.compare(Ebsd::Mic::FileExt) == 0) { err = H5Lite::writeStringDataset(fileId, Ebsd::H5::Manufacturer, Ebsd::Mic::Manufacturer); if(err < 0) { ss.str(""); ss << "Could not write the Manufacturer Data to the HDF5 File"; addErrorMessage(getHumanLabel(), ss.str(), err); setErrorCondition(-1); } fileImporter = H5MicImporter::New(); } else { err = -1; ss.str(""); ss << "The File extension was not detected correctly"; addErrorMessage(getHumanLabel(), ss.str(), err); setErrorCondition(-1); return; } std::vector<int> indices; // Loop on Each EBSD File float total = static_cast<float>( m_ZEndIndex - m_ZStartIndex ); int progress = 0; int64_t z = m_ZStartIndex; int64_t xDim = 0, yDim = 0; float xRes = 0.0f, yRes = 0.0f; /* There is a frailness about the z index and the file list. The programmer * using this code MUST ensure that the list of files that is sent into this * class is in the appropriate order to match up with the z index (slice index) * otherwise the import will have subtle errors. The programmer is urged NOT to * simply gather a list from the file system as those lists are sorted in such * a way that if the number of digits appearing in the filename are NOT the same * then the list will be wrong, ie, this example: * * slice_1.ang * slice_2.ang * .... * slice_10.ang * * Most, if not ALL C++ libraries when asked for that list will return the list * sorted like the following: * * slice_1.ang * slice_10.ang * slice_2.ang * * which is going to cause problems because the data is going to be placed * into the HDF5 file at the wrong index. YOU HAVE BEEN WARNED. */ int64_t biggestxDim = 0; int64_t biggestyDim = 0; int totalSlicesImported = 0; for (std::vector<std::string>::iterator filepath = m_EbsdFileList.begin(); filepath != m_EbsdFileList.end(); ++filepath) { std::string ebsdFName = *filepath; progress = static_cast<int>( z - m_ZStartIndex ); progress = (int)(100.0f * (float)(progress) / total); std::string msg = "Converting File: " + ebsdFName; ss.str(""); notifyStatusMessage(msg.c_str()); err = fileImporter->importFile(fileId, z, ebsdFName); if (err < 0) { if (err != -600) { setErrorCondition(fileImporter->getErrorCondition()); notifyErrorMessage(fileImporter->getPipelineMessage(), getErrorCondition()); return; } else { notifyWarningMessage(fileImporter->getPipelineMessage(), fileImporter->getErrorCondition() ); //setErrorCondition(fileImporter->getErrorCondition() ); err = 0; } } totalSlicesImported = totalSlicesImported + fileImporter->numberOfSlicesImported(); fileImporter->getDims(xDim, yDim); fileImporter->getResolution(xRes, yRes); if(xDim > biggestxDim) biggestxDim = xDim; if(yDim > biggestyDim) biggestyDim = yDim; indices.push_back( static_cast<int>(z) ); ++z; if(getCancel() == true) { notifyStatusMessage("Conversion was Canceled"); return; } } // Write Z index start, Z index end and Z Resolution to the HDF5 file err = H5Lite::writeScalarDataset(fileId, Ebsd::H5::ZStartIndex, m_ZStartIndex); if(err < 0) { ss.str(""); ss << "Could not write the Z Start Index Scalar to the HDF5 File"; addErrorMessage(getHumanLabel(), ss.str(), err); setErrorCondition(-1); } m_ZEndIndex = m_ZStartIndex + totalSlicesImported - 1; err = H5Lite::writeScalarDataset(fileId, Ebsd::H5::ZEndIndex, m_ZEndIndex); if(err < 0) { ss.str(""); ss << "Could not write the Z End Index Scalar to the HDF5 File"; addErrorMessage(getHumanLabel(), ss.str(), err); setErrorCondition(-1); } err = H5Lite::writeScalarDataset(fileId, Ebsd::H5::XPoints, biggestxDim); if(err < 0) { ss.str(""); ss << "Could not write the XPoints Scalar to HDF5 file"; addErrorMessage(getHumanLabel(), ss.str(), err); setErrorCondition(-1); } err = H5Lite::writeScalarDataset(fileId, Ebsd::H5::YPoints, biggestyDim); if(err < 0) { ss.str(""); ss << "Could not write the YPoints Scalar to HDF5 file"; addErrorMessage(getHumanLabel(), ss.str(), err); setErrorCondition(-1); } err = H5Lite::writeScalarDataset(fileId, Ebsd::H5::XResolution, xRes); if(err < 0) { ss.str(""); ss << "Could not write the XResolution Scalar to HDF5 file"; addErrorMessage(getHumanLabel(), ss.str(), err); setErrorCondition(-1); } err = H5Lite::writeScalarDataset(fileId, Ebsd::H5::YResolution, yRes); if(err < 0) { ss.str(""); ss << "Could not write the YResolution Scalar to HDF5 file"; addErrorMessage(getHumanLabel(), ss.str(), err); setErrorCondition(-1); } if(false == getCancel()) { // Write an Index data set which contains all the z index values which // should help speed up the reading side of this file std::vector<hsize_t> dims(1, indices.size()); err = H5Lite::writeVectorDataset(fileId, Ebsd::H5::Index, dims, indices); } err = H5Utilities::closeFile(fileId); fileId = -1; notifyStatusMessage("Import Complete"); }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void ImportR3DStack::execute() { int err = 0; setErrorCondition(err); dataCheck(false,1,1,1); if (getErrorCondition() < 0) { notifyErrorMessage("There is a problem with the data check", getErrorCondition()); } VoxelDataContainer* m = getVoxelDataContainer(); if(NULL == m) { setErrorCondition(-999); notifyErrorMessage("The DataContainer Object was NULL", -999); return; } setErrorCondition(0); std::stringstream ss; m->setResolution(m_Resolution.x, m_Resolution.y, m_Resolution.z); m->setOrigin(m_Origin.x, m_Origin.y, m_Origin.z); int x = 0; int y = 0; readXYSize(x, y); if (x < 1 || y < 1) { setErrorCondition(-1000); notifyErrorMessage("At least one dimension is less than 1", getErrorCondition()); } size_t numSlices = m_ZEndIndex - m_ZStartIndex + 1; size_t totalVoxels = numSlices * x * y; // Create a new array, eventually substituting this into the DataContainer later on. Int32ArrayType::Pointer grainIdsPtr = Int32ArrayType::CreateArray(totalVoxels, 1, DREAM3D::CellData::GrainIds); grainIdsPtr->initializeWithZeros(); m_GrainIds = grainIdsPtr->GetPointer(0); // Get the pointer to the front of the array int32_t* currentPositionPtr = m_GrainIds; bool ok = false; int pixelBytes = 0; int totalPixels = 0; int height = 0; int width = 0; size_t index = 0; int64_t z = m_ZStartIndex; m->setDimensions(x,y,numSlices); for (std::vector<std::string>::iterator filepath = m_R3DFileList.begin(); filepath != m_R3DFileList.end(); ++filepath) { QString R3DFName = QString::fromStdString(*filepath); ss.str(""); ss << "Importing file " << R3DFName.toStdString(); notifyStatusMessage(ss.str()); QByteArray buf; QFile in(R3DFName); if (!in.open(QIODevice::ReadOnly | QIODevice::Text)) { QString msg = QString("R3D file could not be opened: ") + R3DFName; setErrorCondition(-14000); notifyErrorMessage(msg.toStdString(), getErrorCondition()); } buf = in.readLine(); // Read first line which is the x and y sizes QList<QByteArray> tokens = buf.split(','); width = tokens.at(0).toInt(); height = tokens.at(1).toInt(); int32_t value = 0; for(qint32 i = 0; i < height; ++i) { buf = in.readLine(); tokens = buf.split(','); if (tokens.size() != width+2) { notifyStatusMessage("A file did not have the correct width partilcuar line"); break; } for(int j = 1; j < width+1; j++) { currentPositionPtr[index] = tokens[j].toInt(&ok, 10); ++index; if (!ok) { setErrorCondition(-2004); notifyErrorMessage("Width dimension entry was not an integer", getErrorCondition()); break; } } if (in.atEnd() == true && i < height - 2) { notifyStatusMessage("A file did not have the correct height"); break; } } ++z; if(getCancel() == true) { notifyStatusMessage("Conversion was Canceled"); return; } } // OVer write any GrainIds array that is already in the DataContainer getVoxelDataContainer()->addCellData(DREAM3D::CellData::GrainIds, grainIdsPtr); /* Let the GUI know we are done with this filter */ notifyStatusMessage("Complete"); }
// ----------------------------------------------------------------------------- // Main ICD reconstruction // ----------------------------------------------------------------------------- void BFReconstructionEngine::execute() { uint64_t totalTime = EIMTOMO_getMilliSeconds(); int32_t err = 0; std::stringstream ss; // int16_t i,j,k,Idx; size_t dims[3]; uint16_t maxNumberOfDetectorElts; uint8_t status; //set to 1 if ICD has converged Real_t checksum = 0, temp; RealImageType::Pointer voxelProfile; RealVolumeType::Pointer detectorResponse; RealVolumeType::Pointer h_t; RealVolumeType::Pointer y_Est; //Estimated Sinogram RealVolumeType::Pointer finalSinogram; //To store and write the final sinogram resulting from our reconstruction RealVolumeType::Pointer errorSino; //Error Sinogram std::string indent(""); //#ifdef COST_CALCULATE //Commented out because if not the code fails to run. std::string filepath(m_TomoInputs->tempDir); filepath = filepath.append(MXADir::getSeparator()).append(MBIR::Defaults::CostFunctionFile); CostData::Pointer cost = CostData::New(); cost->initOutputFile(filepath); //#endif #if OpenMBIR_USE_PARALLEL_ALGORITHMS tbb::task_scheduler_init init; #endif // Initialize the Sinogram if(m_TomoInputs == NULL) { setErrorCondition(-1); notify("Error: The TomoInput Structure was NULL. The proper API is to supply this class with that structure,", 100, Observable::UpdateErrorMessage); return; } //Based on the inputs , calculate the "other" variables in the structure definition if(m_Sinogram == NULL) { setErrorCondition(-1); notify("Error: The Sinogram Structure was NULL. The proper API is to supply this class with that structure,", 100, Observable::UpdateErrorMessage); return; } if(m_Geometry == NULL) { setErrorCondition(-1); notify("Error: The Geometry Structure was NULL. The proper API is to supply this class with that structure,", 100, Observable::UpdateErrorMessage); return; } if (m_ForwardModel.get() == NULL) { setErrorCondition(-1); notify("Error: The forward model was not set.", 100, Observable::UpdateErrorMessage); return; } // Read the Input data from the supplied data file - reconstruction from previous resolution ? err = readInputData(); if(err < 0) { return; } if (getCancel() == true) { setErrorCondition(-999); return; } if (getCancel() == true) { setErrorCondition(-999); return; } //Additional parameters associated with the system err = m_ForwardModel->createNuisanceParameters(m_Sinogram); if(err < 0) { return; } //Periodically checking if user has sent a cancel signal from the GUI if (getCancel() == true) { setErrorCondition(-999); return; } m_ForwardModel->printNuisanceParameters(m_Sinogram); //Take log of the input data after subtracting offset m_ForwardModel->processRawCounts(m_Sinogram); // Initialize the Geometry data from a rough reconstruction err = initializeRoughReconstructionData(); if(err < 0) { return; } if (getCancel() == true) { setErrorCondition(-999); return; } // Get the actual boundaries in the X Direction since we "Extend Object" which makes // the output mrc file much wider than they really need to be. uint16_t cropStart = 0; uint16_t cropEnd = m_Geometry->N_x; computeOriginalXDims(cropStart, cropEnd); // std::cout << "Crop Start: " << cropStart << std::endl; // std::cout << "Crop End: " << cropEnd << std::endl; m_ForwardModel->allocateNuisanceParameters(m_Sinogram); //#ifdef COST_CALCULATE // dims[0] = (m_TomoInputs->NumIter+1)*m_TomoInputs->NumOuterIter*3; //#endif dims[0] = m_Sinogram->N_theta; dims[1] = m_Sinogram->N_r; dims[2] = m_Sinogram->N_t; y_Est = RealVolumeType::New(dims, "y_Est");//y_Est = A*x_{initial} errorSino = RealVolumeType::New(dims, "ErrorSino");// y - y_est m_ForwardModel->weightInitialization(dims); //Initialize the \lambda matrix finalSinogram = RealVolumeType::New(dims, "Final Sinogram"); //Debug variable to store the final A*x_{Final} /*************** Computation of partial Amatrix *************/ //calculate the trapezoidal voxel profile for each angle.Also the angles in the Sinogram // Structure are converted to radians voxelProfile = calculateVoxelProfile(); //This is used for computation of the partial A matrix //Pre compute sine and cos theta to speed up computations DetectorParameters::Pointer haadfParameters = DetectorParameters::New(); haadfParameters->setOffsetR ( ((m_TomoInputs->delta_xz / sqrt(3.0)) + m_Sinogram->delta_r / 2) / m_AdvParams->DETECTOR_RESPONSE_BINS); haadfParameters->setOffsetT ( ((m_TomoInputs->delta_xz / 2) + m_Sinogram->delta_t / 2) / m_AdvParams->DETECTOR_RESPONSE_BINS); haadfParameters->setBeamWidth(m_Sinogram->delta_r); haadfParameters->calculateSinCos(m_Sinogram); //Initialize the e-beam haadfParameters->initializeBeamProfile(m_Sinogram, m_AdvParams); //The shape of the averaging kernel for the detector if (getCancel() == true) { setErrorCondition(-999); return; } //calculate sine and cosine of all angles and store in the global arrays sine and cosine DetectorResponse::Pointer dResponseFilter = DetectorResponse::New(); dResponseFilter->setTomoInputs(m_TomoInputs); dResponseFilter->setSinogram(m_Sinogram); dResponseFilter->setAdvParams(m_AdvParams); dResponseFilter->setDetectorParameters(haadfParameters); dResponseFilter->setVoxelProfile(voxelProfile); dResponseFilter->setObservers(getObservers()); dResponseFilter->setVerbose(getVerbose()); dResponseFilter->setVeryVerbose(getVeryVerbose()); dResponseFilter->execute(); if(dResponseFilter->getErrorCondition() < 0) { ss.str(""); ss << "Error Calling function detectorResponse in file " << __FILE__ << "(" << __LINE__ << ")" << std::endl; setErrorCondition(-2); notify(ss.str(), 100, Observable::UpdateErrorMessage); return; } detectorResponse = dResponseFilter->getResponse(); // Writer the Detector Response to an output file DetectorResponseWriter::Pointer responseWriter = DetectorResponseWriter::New(); responseWriter->setTomoInputs(m_TomoInputs); responseWriter->setSinogram(m_Sinogram); responseWriter->setAdvParams(m_AdvParams); responseWriter->setObservers(getObservers()); responseWriter->setResponse(detectorResponse); responseWriter->setVerbose(getVerbose()); responseWriter->setVeryVerbose(getVeryVerbose()); responseWriter->execute(); if(responseWriter->getErrorCondition() < 0) { ss.str(""); ss << __FILE__ << "(" << __LINE__ << ") " << "Error writing detector response to file." << std::endl; setErrorCondition(-3); notify(ss.str(), 100, Observable::UpdateErrorMessage); return; } if (getCancel() == true) { setErrorCondition(-999); return; } // Initialize H_t volume dims[0] = 1; dims[1] = m_Sinogram->N_theta; dims[2] = m_AdvParams->DETECTOR_RESPONSE_BINS; h_t = RealVolumeType::New(dims, "h_t"); initializeHt(h_t, haadfParameters->getOffsetT() ); checksum = 0; ss.str(""); ss << "Calculating A Matrix...."; notify(ss.str(), 0, Observable::UpdateProgressMessage); std::vector<AMatrixCol::Pointer> voxelLineResponse(m_Geometry->N_y); maxNumberOfDetectorElts = (uint16_t)((m_TomoInputs->delta_xy / m_Sinogram->delta_t) + 2); dims[0] = maxNumberOfDetectorElts; for (uint16_t i = 0; i < m_Geometry->N_y; i++) { AMatrixCol::Pointer vlr = AMatrixCol::New(dims, 0); voxelLineResponse[i] = vlr; } //Calculating A-Matrix one column at a time //For each entry the idea is to initially allocate space for Sinogram.N_theta * Sinogram.N_x // And then store only the non zero entries by allocating a new array of the desired size std::vector<AMatrixCol::Pointer> tempCol(m_Geometry->N_x * m_Geometry->N_z); checksum = 0; temp = 0; uint32_t voxel_count = 0; for (uint16_t z = 0; z < m_Geometry->N_z; z++) { for (uint16_t x = 0; x < m_Geometry->N_x; x++) { tempCol[voxel_count] = AMatrixCol::calculateAMatrixColumnPartial(m_Sinogram, m_Geometry, m_TomoInputs, m_AdvParams, z, x, 0, detectorResponse, haadfParameters); temp += tempCol[voxel_count]->count; if(0 == tempCol[voxel_count]->count ) { //If this line is never hit and the Object is badly initialized //set it to zero for (uint16_t y = 0; y < m_Geometry->N_y; y++) { m_Geometry->Object->setValue(0.0, z, x, y); } } voxel_count++; } } storeVoxelResponse(h_t, voxelLineResponse, haadfParameters); if (getCancel() == true) { setErrorCondition(-999); return; } if(getVerbose()) { printf("Number of non zero entries of the forward projector is %lf\n", temp); printf("Geometry-Z %d\n", m_Geometry->N_z); } /************ End of A matrix partial computations **********************/ //Gain and Offset Parameters Initialization of the forward model m_ForwardModel->gainAndOffsetInitialization(m_Sinogram->N_theta); initializeVolume(y_Est, 0.0); if (getCancel() == true) { setErrorCondition(-999); return; } //Forward Project Geometry->Object one slice at a time and compute the Sinogram for each slice // Forward Project using the Forward Model err = m_ForwardModel->forwardProject(m_Sinogram, m_Geometry, tempCol, voxelLineResponse, y_Est , errorSino); if (err < 0) { return; } if (getCancel() == true) { setErrorCondition(-999); return; } #ifdef FORWARD_PROJECT_MODE return 0; //exit the program once we finish forward projecting the object #endif//Forward Project mode // Initialize the Prior Model parameters - here we are using a QGGMRF Prior Model QGGMRF::QGGMRF_Values QGGMRF_values; QGGMRF::initializePriorModel(m_TomoInputs, &QGGMRF_values, NULL); #ifdef COST_CALCULATE err = calculateCost(cost, m_Sinogram, m_Geometry, errorSino, &QGGMRF_values); #endif //Cost calculation endif Real_t TempBraggValue, DesBraggValue; #ifdef BRAGG_CORRECTION if(m_TomoInputs->NumIter > 1) { //Get the value of the Bragg threshold from the User Interface the first time DesBraggValue = m_ForwardModel->getBraggThreshold(); if (getVeryVerbose()) {std::cout << "Desired Bragg threshold =" << DesBraggValue << std::endl;} TempBraggValue = DefBraggThreshold;//m_ForwardModel->getBraggThreshold(); m_ForwardModel->setBraggThreshold(TempBraggValue); //setting the Threshold T of \beta_{T,\delta} //the \delta value is set in BFMultiResolutionReconstruction.cpp } else { TempBraggValue = m_ForwardModel->getBraggThreshold(); m_ForwardModel->setBraggThreshold(TempBraggValue); } #endif //Bragg correction if (getVeryVerbose()) {std::cout << "Bragg threshold =" << TempBraggValue << std::endl;} //Generate a List if (getVeryVerbose()) {std::cout << "Generating a list of voxels to update" << std::endl;} //Takes all the voxels along x-z slice and forms a list m_VoxelIdxList = VoxelUpdateList::GenRegularList(m_Geometry->N_z, m_Geometry->N_x); //Randomize the list of voxels m_VoxelIdxList = VoxelUpdateList::GenRandList(m_VoxelIdxList); if(getVerbose()) { std::cout << "Initial random order list .." << std::endl; m_VoxelIdxList->printMaxList(std::cout); } // Create a copy of the Voxel Update List because we are going to adjust the VoxelUpdateList instance variable // with values for the array pointer and number of elements based on the iteration VoxelUpdateList::Pointer TempList = VoxelUpdateList::New(m_VoxelIdxList->numElements(), m_VoxelIdxList->getArray() ); uint32_t listselector = 0; //For the homogenous updates this cycles through the random list one sublist at a time //Initialize the update magnitude arrays (for NHICD mainly) & stopping criteria dims[0] = m_Geometry->N_z; //height dims[1] = m_Geometry->N_x; //width dims[2] = 0; RealImageType::Pointer magUpdateMap = RealImageType::New(dims, "Update Map for voxel lines"); RealImageType::Pointer filtMagUpdateMap = RealImageType::New(dims, "Filter Update Map for voxel lines"); UInt8Image_t::Pointer magUpdateMask = UInt8Image_t::New(dims, "Update Mask for selecting voxel lines NHICD");//TODO: Remove this variable. Under the new formulation not needed Real_t PrevMagSum = 0; magUpdateMap->initializeWithZeros(); filtMagUpdateMap->initializeWithZeros(); #if ROI //A mask to check the stopping criteria for the algorithm initializeROIMask(magUpdateMask); #endif //Debugging variable to check if all voxels are visited dims[0] = m_Geometry->N_z; dims[1] = m_Geometry->N_x; dims[2] = 0; UInt8Image_t::Pointer m_VisitCount = UInt8Image_t::New(dims, "VisitCount"); uint32_t EffIterCount = 0; //Maintains number of calls to updatevoxelroutine //Loop through every voxel updating it by solving a cost function for (int16_t reconOuterIter = 0; reconOuterIter < m_TomoInputs->NumOuterIter; reconOuterIter++) { ss.str(""); // Clear the string stream indent = ""; //The first time we may need to update voxels multiple times and then on //just optimize over I,d,sigma,f once each outer loop; //Each outer loop after the first outer iter updates a subset of the voxels //followed by other parameters if needed if(reconOuterIter > 0) { m_TomoInputs->NumIter = 1;//Inner iterations m_ForwardModel->setBraggThreshold(TempBraggValue); } for (int16_t reconInnerIter = 0; reconInnerIter < m_TomoInputs->NumIter; reconInnerIter++) { // If at the inner most loops at the coarsest resolution donot apply Bragg // Only at the coarsest scale the NumIter > 1 if(m_TomoInputs->NumIter > 1 && reconInnerIter == 0) { m_ForwardModel->setBraggThreshold(DefBraggThreshold); } #ifdef DEBUG //Prints the ratio of the sinogram entries selected m_ForwardModel->printRatioSelected(m_Sinogram); #endif //DEBUG ss.str(""); ss << "Outer Iterations: " << reconOuterIter << "/" << m_TomoInputs->NumOuterIter << " Inner Iterations: " << reconInnerIter << "/" << m_TomoInputs->NumIter << std::endl; indent = " "; #ifdef DEBUG // This is all done PRIOR to calling what will become a method if (getVeryVerbose()) {std::cout << "Bragg Threshold =" << m_ForwardModel->getBraggThreshold() << std::endl;} #endif //DEBUG // This could contain multiple Subloops also - voxel update /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */ #ifdef NHICD //NHICD alternates between updating a fixed subset of voxels and a //list created on the fly based on the previous iterations // Creating a sublist of voxels for the Homogenous // iterations - cycle through the partial sub lists if(EffIterCount % 2 == 0) //Even iterations == Homogenous update { listselector %= MBIR::Constants::k_NumHomogeniousIter;// A variable to cycle through the randmoized list of voxels int32_t nElements = floor((Real_t)TempList->numElements() / MBIR::Constants::k_NumHomogeniousIter); //If the number of voxels is NOT exactly divisible by NUM_NON .. then compensate and make the last of the lists longer if(listselector == MBIR::Constants::k_NumHomogeniousIter - 1) { nElements += (TempList->numElements() - nElements * MBIR::Constants::k_NumHomogeniousIter); if(getVeryVerbose()) { std::cout << "**********Adjusted number of voxel lines for last iter**************" << std::endl; std::cout << nElements << std::endl; std::cout << "**********************************" << std::endl; } } //Set the list array for updating voxels int32_t start = (uint32_t)(floor(((Real_t)TempList->numElements() / MBIR::Constants::k_NumHomogeniousIter)) * listselector); m_VoxelIdxList = TempList->subList(nElements, start); //m_VoxelIdxList.Array = &(TempList.Array[]); if (getVeryVerbose()) { std::cout << "Partial random order list for homogenous ICD .." << std::endl; m_VoxelIdxList->printMaxList(std::cout); } listselector++; //printList(m_VoxelIdxList); } #endif //NHICD #ifdef DEBUG Real_t TempSum = 0; for (int32_t j = 0; j < m_Geometry->N_z; j++) { for (int32_t k = 0; k < m_Geometry->N_x; k++) { TempSum += magUpdateMap->getValue(j, k); } } if (getVeryVerbose()) { std::cout << "**********************************************" << std::endl; std::cout << "Average mag prior to calling update voxel = " << TempSum / (m_Geometry->N_z * m_Geometry->N_x) << std::endl; std::cout << "**********************************************" << std::endl; } #endif //debug status = updateVoxels(reconOuterIter, reconInnerIter, tempCol, errorSino, voxelLineResponse, cost, &QGGMRF_values, magUpdateMap, filtMagUpdateMap, magUpdateMask, m_VisitCount, PrevMagSum, EffIterCount); #ifdef NHICD if(EffIterCount % MBIR::Constants::k_NumNonHomogeniousIter == 0) // At the end of half an //equivalent iteration compute average Magnitude of recon to test //stopping criteria { PrevMagSum = roiVolumeSum(magUpdateMask); if (getVeryVerbose()) {std::cout << " Previous Magnitude of the Recon = " << PrevMagSum << std::endl;} } #else PrevMagSum = roiVolumeSum(magUpdateMask); std::cout << " Previous Magnitude of the Recon = " << PrevMagSum << std::endl; #endif //NHICD //Debugging information to test if every voxel is getting touched #ifdef NHICD //Debug every equivalent iteration if(EffIterCount % (2 * MBIR::Constants::k_NumNonHomogeniousIter) == 0 && EffIterCount > 0) #endif //NHICD { for (int16_t j = 0; j < m_Geometry->N_z; j++) { for (int16_t k = 0; k < m_Geometry->N_x; k++) { if(m_VisitCount->getValue(j, k) == 0) { printf("Pixel (%d %d) not visited\n", j, k); } } } //Reset the visit counter once we have cycled through //all voxels once via the homogenous updates for (int16_t j = 0; j < m_Geometry->N_z; j++) { for (int16_t k = 0; k < m_Geometry->N_x; k++) { m_VisitCount->setValue(0, j, k); } } } //end of debug EffIterCount++; //cycles between the two types of voxel updates /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */ if(status == 0) { break; //stop inner loop if we have hit the threshold value for x } // Check to see if we are canceled. if (getCancel() == true) { setErrorCondition(-999); return; } // Write out the MRC File ; If NHICD only after half an equit do a write #ifdef NHICD if(EffIterCount % (MBIR::Constants::k_NumNonHomogeniousIter) == 0) #endif //NHICD { ss.str(""); ss << m_TomoInputs->tempDir << MXADir::getSeparator() << reconOuterIter << "_" << reconInnerIter << "_" << MBIR::Defaults::ReconstructedMrcFile; writeMRCFile(ss.str(), cropStart, cropEnd); notify(ss.str(), 0, Observable::UpdateIntermediateImage); m_TomoInputs->tempFiles.push_back(ss.str()); } #ifdef COST_CALCULATE //typically run only for debugging /*********************Cost Calculation*************************************/ int16_t err = calculateCost(cost, m_Sinogram, m_Geometry, errorSino, &QGGMRF_values); if(err < 0) { std::cout << "Cost went up after voxel update" << std::endl; return; // break; } /**************************************************************************/ #endif //Cost calculation endif #ifdef BRAGG_CORRECTION //If at the last iteration of the inner loops at coarsest resolution adjust parameters if(reconInnerIter == m_TomoInputs->NumIter - 1 && reconInnerIter != 0) { //The first time at the coarsest resolution at the end of // inner iterations set the Bragg Threshold TempBraggValue = DesBraggValue;//threshold; m_ForwardModel->setBraggThreshold(TempBraggValue); } #endif //Bragg correction } /* ++++++++++ END Inner Iteration Loop +++++++++++++++ */ if(0 == status && reconOuterIter >= 1) //if stopping criteria is met and //number of iterations is greater than 1 { if (getVeryVerbose()) {std::cout << "Exiting the code because status =0" << std::endl;} break; } if(getVeryVerbose()) { std::cout << " Starting nuisance parameter estimation" << std::endl; } if(m_TomoInputs->NumOuterIter > 1) //Dont update any parameters if we just have one outer iteration { if(m_AdvParams->JOINT_ESTIMATION) { m_ForwardModel->jointEstimation(m_Sinogram, errorSino, y_Est, cost); m_ForwardModel->updateSelector(m_Sinogram, errorSino); #ifdef COST_CALCULATE //Debug info int16_t err = calculateCost(cost, m_Sinogram, m_Geometry, errorSino, &QGGMRF_values); if(err < 0) { std::cout << "Cost went up after offset update" << std::endl; break; } #endif//cost } //Joint estimation endif if(m_AdvParams->NOISE_ESTIMATION) { m_ForwardModel->updateWeights(m_Sinogram, errorSino); m_ForwardModel->updateSelector(m_Sinogram, errorSino); #ifdef COST_CALCULATE //err = calculateCost(cost, Weight, errorSino); err = calculateCost(cost, m_Sinogram, m_Geometry, errorSino, &QGGMRF_values); if (err < 0 && reconOuterIter > 1) { std::cout << "Cost went up after variance update" << std::endl; std::cout << "Effective iterations =" << EffIterCount << std::endl; return; //break; } #endif//cost } if(getVeryVerbose()) { std::cout << " Ending nuisance parameter estimation" << std::endl; } } }/* ++++++++++ END Outer Iteration Loop +++++++++++++++ */ indent = ""; #if DEBUG_COSTS cost->printCosts(std::cout); #endif #ifdef FORWARD_PROJECT_MODE int fileError = 0; FILE* Fp6; MAKE_OUTPUT_FILE(Fp6, fileError, m_TomoInputs->tempDir, MBIR::Defaults::BFForwardProjectedObjectFile); if (fileError == 1) { } #endif if (getCancel() == true) { setErrorCondition(-999); return; } /* Write the Gains,Offsets and variance to an output file */ m_ForwardModel->writeNuisanceParameters(m_Sinogram); //Compute final value of Ax_{final} Real_t temp_final = 0.0; for (uint16_t i_theta = 0; i_theta < m_Sinogram->N_theta; i_theta++) { for (uint16_t i_r = 0; i_r < m_Sinogram->N_r; i_r++) { for (uint16_t i_t = 0; i_t < m_Sinogram->N_t; i_t++) { temp_final = m_Sinogram->counts->getValue(i_theta, i_r, i_t) - errorSino->getValue(i_theta, i_r, i_t); finalSinogram->setValue(temp_final, i_theta, i_r, i_t); } } } // This is writing the "ReconstructedSinogram.bin" file m_ForwardModel->writeSinogramFile(m_Sinogram, finalSinogram); // Writes the sinogram to a file if (getCancel() == true) { setErrorCondition(-999); return; } // Writes ReconstructedObject.bin file for next resolution { std::stringstream ss; ss << m_TomoInputs->tempDir << MXADir::getSeparator() << MBIR::Defaults::ReconstructedObjectFile; writeReconstructionFile(ss.str()); } // Write out the VTK file if (m_TomoInputs->vtkOutputFile.empty() == false) { writeVtkFile(m_TomoInputs->vtkOutputFile, cropStart, cropEnd); } // Write out the MRC File if (m_TomoInputs->mrcOutputFile.empty() == false) { writeMRCFile(m_TomoInputs->mrcOutputFile, cropStart, cropEnd); } //Write out avizo fire file if (m_TomoInputs->avizoOutputFile.empty() == false) { writeAvizoFile(m_TomoInputs->avizoOutputFile, cropStart, cropEnd); } //Debug : Writing out the selector array as an MRC file m_ForwardModel->writeSelectorMrc(m_TomoInputs->braggSelectorFile, m_Sinogram, m_Geometry, errorSino); if (getVerbose()) { std::cout << "Final Dimensions of Object: " << std::endl; std::cout << " Nx = " << m_Geometry->N_x << std::endl; std::cout << " Ny = " << m_Geometry->N_y << std::endl; std::cout << " Nz = " << m_Geometry->N_z << std::endl; #ifdef NHICD std::cout << "Number of equivalet iterations taken =" << EffIterCount / MBIR::Constants::k_NumNonHomogeniousIter << std::endl; #else std::cout << "Number of equivalet iterations taken =" << EffIterCount / MBIR::Constants::k_NumHomogeniousIter << std::endl; #endif //NHICD } notify("Reconstruction Complete", 100, Observable::UpdateProgressValueAndMessage); setErrorCondition(0); if (getVerbose()) {std::cout << "Total Running Time for Execute: " << (EIMTOMO_getMilliSeconds() - totalTime) / 1000 << std::endl;} return; }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void AlignSections::execute() { setErrorCondition(0); dataCheck(); if(getErrorCondition() < 0) { return; } DataContainer::Pointer m = getDataContainerArray()->getDataContainer(getDataContainerName()); 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]), }; DimType slice = 0; DimType xspot = 0, yspot = 0; DimType newPosition = 0; DimType currentPosition = 0; std::vector<int64_t> xshifts(dims[2], 0); std::vector<int64_t> yshifts(dims[2], 0); find_shifts(xshifts, yshifts); if (getSubtractBackground()) { /**fit x and y shifts to lines * * y = mx + b * * m = (n*sum(x_i * y_i) - sum(x_i) * sum(y_i)) / (n*sum(x_i^2)-sum(x_i)^2 * * b = (sum(y_i)-m*sum(x_i))/n * */ // same for both double sumX = 0.0; // sum(x_i) double sumX_2 = 0.0; // sum(x_i^2) // x shift line double x_sumY = 0.0; // sum(y_i) double x_sumXY = 0.0; // sum(x_i * y_i) // y shift line double y_sumY = 0.0; // sum(y_i) double y_sumXY = 0.0; // sum(x_i * y_i) for (DimType iter = 0; iter < dims[2]; iter++) { slice = static_cast<DimType>( (dims[2] - 1) - iter ); sumX = static_cast<double>(sumX + iter); sumX_2 = static_cast<double>(sumX_2 + iter * iter); x_sumY = static_cast<double>(x_sumY + xshifts[iter]); x_sumXY = static_cast<double>(x_sumXY + iter * xshifts[iter]); y_sumY = static_cast<double>(y_sumY + yshifts[iter]); y_sumXY = static_cast<double>(y_sumXY + iter * yshifts[iter]); } double mx = static_cast<double>((dims[2] * x_sumXY - x_sumXY) / (dims[2] * sumX_2 - sumX)); double my = static_cast<double>((dims[2] * y_sumXY - y_sumXY) / (dims[2] * sumX_2 - sumX)); // adjust shifts so that fit line has 0 slope (~ends of the sample are fixed) for (DimType iter = 1; iter < dims[2]; iter++) { slice = (dims[2] - 1) - iter; xshifts[iter] = static_cast<int64_t>(xshifts[iter] - iter * mx); yshifts[iter] = static_cast<int64_t>(yshifts[iter] - iter * my); } } QList<QString> voxelArrayNames = m->getAttributeMatrix(getCellAttributeMatrixName())->getAttributeArrayNames(); DimType progIncrement = dims[2] / 100; DimType prog = 1; DimType progressInt = 0; for (DimType i = 1; i < dims[2]; i++) { if (i > prog) { progressInt = ((float)i / dims[2]) * 100.0f; QString ss = QObject::tr("Transferring Cell Data || %1% Complete").arg(progressInt); notifyStatusMessage(getMessagePrefix(), getHumanLabel(), ss); prog = prog + progIncrement; } if (getCancel() == true) { return; } slice = (dims[2] - 1) - i; for (DimType l = 0; l < dims[1]; l++) { for (DimType n = 0; n < dims[0]; n++) { if (yshifts[i] >= 0) { yspot = l; } else if (yshifts[i] < 0) { yspot = dims[1] - 1 - l; } if (xshifts[i] >= 0) { xspot = n; } else if (xshifts[i] < 0) { xspot = dims[0] - 1 - n; } newPosition = (slice * dims[0] * dims[1]) + (yspot * dims[0]) + xspot; currentPosition = (slice * dims[0] * dims[1]) + ((yspot + yshifts[i]) * dims[0]) + (xspot + xshifts[i]); if ((yspot + yshifts[i]) >= 0 && (yspot + yshifts[i]) <= dims[1] - 1 && (xspot + xshifts[i]) >= 0 && (xspot + xshifts[i]) <= dims[0] - 1) { for (QList<QString>::iterator iter = voxelArrayNames.begin(); iter != voxelArrayNames.end(); ++iter) { IDataArray::Pointer p = m->getAttributeMatrix(getCellAttributeMatrixName())->getAttributeArray(*iter); p->copyTuple(currentPosition, newPosition); } } if ((yspot + yshifts[i]) < 0 || (yspot + yshifts[i]) > dims[1] - 1 || (xspot + xshifts[i]) < 0 || (xspot + xshifts[i]) > dims[0] - 1) { for (QList<QString>::iterator iter = voxelArrayNames.begin(); iter != voxelArrayNames.end(); ++iter) { IDataArray::Pointer p = m->getAttributeMatrix(getCellAttributeMatrixName())->getAttributeArray(*iter); p->initializeTuple(newPosition, 0); } } } } } // If there is an error set this to something negative and also set a message notifyStatusMessage(getHumanLabel(), "Complete"); }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void AdaptiveAlignmentMutualInformation::find_shifts(std::vector<int64_t>& xshifts, std::vector<int64_t>& yshifts, std::vector<float>& xneedshifts, std::vector<float>& yneedshifts) { DataContainer::Pointer m = getDataContainerArray()->getDataContainer(getDataContainerName()); int64_t totalPoints = m->getAttributeMatrix(getCellAttributeMatrixName())->getNumTuples(); m_MIFeaturesPtr = Int32ArrayType::CreateArray((totalPoints * 1), "_INTERNAL_USE_ONLY_MIFeatureIds"); m_MIFeaturesPtr->initializeWithZeros(); int32_t* miFeatureIds = m_MIFeaturesPtr->getPointer(0); size_t udims[3] = { 0, 0, 0 }; m->getGeometryAs<ImageGeom>()->getDimensions(udims); uint64_t dims[3] = { static_cast<uint64_t>(udims[0]), static_cast<uint64_t>(udims[1]), static_cast<uint64_t>(udims[2]), }; uint64_t maxstoredshifts = 1; if (xneedshifts.size() > 0) maxstoredshifts = 20; float disorientation = 0.0f; std::vector<std::vector<int64_t>> newxshift(dims[2]); std::vector<std::vector<int64_t>> newyshift(dims[2]); std::vector<std::vector<float>> mindisorientation(dims[2]); for (uint64_t a = 1; a < dims[2]; a++) { newxshift[a].resize(maxstoredshifts, 0); newyshift[a].resize(maxstoredshifts, 0); mindisorientation[a].resize(maxstoredshifts, std::numeric_limits<float>::max()); } float** mutualinfo12 = NULL; float* mutualinfo1 = NULL; float* mutualinfo2 = NULL; int32_t featurecount1 = 0, featurecount2 = 0; int64_t oldxshift = 0; int64_t oldyshift = 0; float count = 0.0f; uint64_t slice = 0; int32_t refgnum = 0, curgnum = 0; uint64_t refposition = 0; uint64_t curposition = 0; form_features_sections(); // Allocate a 2D Array which will be reused from slice to slice // second dimension is assigned in each cycle separately std::vector<std::vector<bool> > misorients(dims[0]); const uint64_t halfDim0 = static_cast<uint64_t>(dims[0] * 0.5f); const uint64_t halfDim1 = static_cast<uint64_t>(dims[1] * 0.5f); uint64_t progInt = 0; for (uint64_t iter = 1; iter < dims[2]; iter++) { progInt = static_cast<uint64_t>(iter * 100 / static_cast<float>(dims[2])); QString ss = QObject::tr("Aligning Anisotropic Sections || Determining Shifts || %1% Complete").arg(progInt); notifyStatusMessage(getMessagePrefix(), getHumanLabel(), ss); slice = (dims[2] - 1) - iter; featurecount1 = featurecounts[slice]; featurecount2 = featurecounts[slice + 1]; mutualinfo12 = new float *[featurecount1]; mutualinfo1 = new float[featurecount1]; mutualinfo2 = new float[featurecount2]; for (int32_t a = 0; a < featurecount1; a++) { mutualinfo1[a] = 0.0f; mutualinfo12[a] = new float[featurecount2]; for (int32_t b = 0; b < featurecount2; b++) { mutualinfo12[a][b] = 0.0f; mutualinfo2[b] = 0.0f; } } oldxshift = -1; oldyshift = -1; for (uint64_t i = 0; i < dims[0]; i++) { misorients[i].assign(dims[1], false); } while (newxshift[iter][0] != oldxshift || newyshift[iter][0] != oldyshift) { oldxshift = newxshift[iter][0]; oldyshift = newyshift[iter][0]; for (int32_t j = -3; j < 4; j++) { for (int32_t k = -3; k < 4; k++) { disorientation = 0; count = 0; if (llabs(k + oldxshift) < halfDim0 && llabs(j + oldyshift) < halfDim1 && misorients[k + oldxshift + halfDim0][j + oldyshift + halfDim1] == false) { for (uint64_t l = 0; l < dims[1]; l = l + 4) { for (uint64_t n = 0; n < dims[0]; n = n + 4) { if ((l + j + oldyshift) >= 0 && (l + j + oldyshift) < dims[1] && (n + k + oldxshift) >= 0 && (n + k + oldxshift) < dims[0]) { refposition = ((slice + 1) * dims[0] * dims[1]) + (l * dims[0]) + n; curposition = (slice * dims[0] * dims[1]) + ((l + j + oldyshift) * dims[0]) + (n + k + oldxshift); refgnum = miFeatureIds[refposition]; curgnum = miFeatureIds[curposition]; if (curgnum >= 0 && refgnum >= 0) { mutualinfo12[curgnum][refgnum]++; mutualinfo1[curgnum]++; mutualinfo2[refgnum]++; count++; } } else { mutualinfo12[0][0]++; mutualinfo1[0]++; mutualinfo2[0]++; } } } float ha = 0.0f; float hb = 0.0f; float hab = 0.0f; for (int32_t b = 0; b < featurecount1; b++) { mutualinfo1[b] = mutualinfo1[b] / count; if (mutualinfo1[b] != 0) { ha = ha + mutualinfo1[b] * logf(mutualinfo1[b]); } } for (int32_t c = 0; c < featurecount2; c++) { mutualinfo2[c] = mutualinfo2[c] / float(count); if (mutualinfo2[c] != 0) { hb = hb + mutualinfo2[c] * logf(mutualinfo2[c]); } } for (int32_t b = 0; b < featurecount1; b++) { for (int32_t c = 0; c < featurecount2; c++) { mutualinfo12[b][c] = mutualinfo12[b][c] / count; if (mutualinfo12[b][c] != 0) { hab = hab + mutualinfo12[b][c] * logf(mutualinfo12[b][c]); } float value = 0.0f; if (mutualinfo1[b] > 0 && mutualinfo2[c] > 0) { value = (mutualinfo12[b][c] / (mutualinfo1[b] * mutualinfo2[c])); } if (value != 0) { disorientation = disorientation + (mutualinfo12[b][c] * logf(value)); } } } for (int32_t b = 0; b < featurecount1; b++) { for (int32_t c = 0; c < featurecount2; c++) { mutualinfo12[b][c] = 0.0f; mutualinfo1[b] = 0.0f; mutualinfo2[c] = 0.0f; } } disorientation = 1.0f / disorientation; misorients[k + oldxshift + halfDim0][j + oldyshift + halfDim1] = true; // compare the new shift with currently stored ones int64_t s = maxstoredshifts; while (s - 1 >= 0 && disorientation < mindisorientation[iter][s - 1]) { s--; } // new shift is stored with index 's' in the arrays if (s < maxstoredshifts) { // lag the shifts already stored for (int64_t t = maxstoredshifts - 1; t > s; t--) { newxshift[iter][t] = newxshift[iter][t - 1]; newyshift[iter][t] = newyshift[iter][t - 1]; mindisorientation[iter][t] = mindisorientation[iter][t - 1]; } // store the new shift newxshift[iter][s] = k + oldxshift; newyshift[iter][s] = j + oldyshift; mindisorientation[iter][s] = disorientation; } } } } } xshifts[iter] = xshifts[iter - 1] + newxshift[iter][0]; yshifts[iter] = yshifts[iter - 1] + newyshift[iter][0]; delete[] mutualinfo1; delete[] mutualinfo2; for (int32_t i = 0; i < featurecount1; i++) { delete mutualinfo12[i]; } delete[] mutualinfo12; mutualinfo1 = NULL; mutualinfo2 = NULL; mutualinfo12 = NULL; } std::vector<uint64_t> curindex(dims[2], 0); // find corrected shifts if (xneedshifts.size() > 0) { QString ss = QObject::tr("Aligning Anisotropic Sections || Correcting shifts"); notifyStatusMessage(getMessagePrefix(), getHumanLabel(), ss); std::vector<float> changedisorientation(dims[2], 0); std::vector<uint64_t> changeindex(dims[2], 0); std::vector<float> changeerror(dims[2], 0); std::vector<float> xshiftsest; // cumulative x-shifts estimated from SEM images std::vector<float> yshiftsest; // cumulative y-shifts estimated from SEM images float curerror = 0; float tolerance = 1.0f / static_cast<float>(dims[2]); // evaluate error between current shifts and desired shifts if (xneedshifts.size() == 1) // error is computed as misagreement between slopes { curerror = compute_error1(dims[2], 0, xneedshifts[0], yneedshifts[0], newxshift, newyshift, curindex); } else if (xneedshifts.size() > 1) // error is computed as misagreement with shifts estimated from SEM images { xshiftsest.resize(dims[2], 0); yshiftsest.resize(dims[2], 0); for (uint64_t iter = 1; iter < dims[2]; iter++) { xshiftsest[iter] = xshiftsest[iter - 1] + xneedshifts[iter - 1]; yshiftsest[iter] = yshiftsest[iter - 1] + yneedshifts[iter - 1]; } curerror = compute_error2(dims[2], 0, xshiftsest, yshiftsest, newxshift, newyshift, curindex); } // iterative selection of a candidate shift, recomputing of current candidates, evaluation of error if (curerror > tolerance) { float minchangedisorientation = 0; float minchangeerror = 0; int64_t minchangeindex = 0; int64_t minchangeiter = 0; float olderror = 0; float newerror = 0; uint64_t progInt = 0; do { QString ss = QObject::tr("Aligning Anisotropic Sections || Correcting Shifts || Iteration %1").arg(++progInt);; notifyStatusMessage(getMessagePrefix(), getHumanLabel(), ss); if (getCancel() == true) { return; } olderror = curerror; for (uint64_t iter = 1; iter < dims[2]; iter++) { float newminerror = std::numeric_limits<float>::max(); float newmindisorientation = std::numeric_limits<float>::max(); uint64_t newminindex = 0; for (uint64_t index = curindex[iter] + 1; index < maxstoredshifts; index++) { // recompute error for the configuration with this candidate changed if (xneedshifts.size() == 1) { newerror = compute_error1(iter, index, xneedshifts[0], yneedshifts[0], newxshift, newyshift, curindex); } else if (xneedshifts.size() > 1) { newerror = compute_error2(iter, index, xshiftsest, yshiftsest, newxshift, newyshift, curindex); } // compare the new error with the best current error if (newerror < curerror && mindisorientation[iter][index] / mindisorientation[iter][0] < newmindisorientation) { newminerror = newerror; newminindex = index; newmindisorientation = mindisorientation[iter][index] / mindisorientation[iter][0]; } } // assign best error, corresponding index and disorientation value for this slice changeerror[iter] = newminerror; changeindex[iter] = newminindex; changedisorientation[iter] = newmindisorientation; } // among all slices, find the best candidate (with minimum disorientation change) minchangedisorientation = std::numeric_limits<float>::max() - 1; minchangeerror = std::numeric_limits<float>::max(); minchangeindex = 0; minchangeiter = 0; for (uint64_t iter = 1; iter < dims[2]; iter++) { if (changeerror[iter] < curerror && (changedisorientation[iter] < minchangedisorientation || (changedisorientation[iter] == minchangedisorientation && llabs(newxshift[iter][changeindex[iter]]) + llabs(newyshift[iter][changeindex[iter]]) < llabs(newxshift[iter][minchangeindex]) + llabs(newyshift[iter][minchangeindex])))) { minchangeiter = iter; minchangeindex = changeindex[iter]; minchangedisorientation = changedisorientation[iter]; minchangeerror = changeerror[iter]; } } if (minchangeerror < curerror && minchangeerror >= tolerance) { // assign the best candidate changedisorientation[minchangeiter] = minchangedisorientation; curindex[minchangeiter] = minchangeindex; // reassign current error curerror = minchangeerror; } } while (minchangedisorientation < std::numeric_limits<float>::max() - 1 && curerror < olderror && curerror > tolerance); } } if (getWriteAlignmentShifts() == true) { std::ofstream outFile; outFile.open(getAlignmentShiftFileName().toLatin1().data()); for (uint64_t iter = 1; iter < dims[2]; iter++) { slice = (dims[2] - 1) - iter; xshifts[iter] = xshifts[iter - 1] + newxshift[iter][curindex[iter]]; yshifts[iter] = yshifts[iter - 1] + newyshift[iter][curindex[iter]]; outFile << slice << " " << slice + 1 << " " << newxshift[iter][curindex[iter]] << " " << newyshift[iter][curindex[iter]] << " " << xshifts[iter] << " " << yshifts[iter] << "\n"; } outFile.close(); } m->getAttributeMatrix(getCellAttributeMatrixName())->removeAttributeArray(DREAM3D::CellData::FeatureIds); }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void AlignSections::execute() { setErrorCondition(0); VoxelDataContainer* m = getVoxelDataContainer(); if (NULL == m) { setErrorCondition(-1); std::stringstream ss; ss << " DataContainer was NULL"; notifyErrorMessage(ss.str(), -1); return; } int64_t totalPoints = m->getTotalPoints(); size_t numgrains = m->getNumFieldTuples(); size_t numensembles = m->getNumEnsembleTuples(); dataCheck(false, totalPoints, numgrains, numensembles); if (getErrorCondition() < 0) { return; } size_t udims[3] = {0,0,0}; m->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]), }; int slice; int xspot, yspot; DimType newPosition; DimType currentPosition; // unsigned int phase2; std::vector<int> xshifts; std::vector<int> yshifts; xshifts.resize(dims[2],0); yshifts.resize(dims[2],0); find_shifts(xshifts, yshifts); std::list<std::string> voxelArrayNames = m->getCellArrayNameList(); DimType progIncrement = dims[2]/100; DimType prog = 1; int progressInt = 0; std::stringstream ss; for (DimType i = 1; i < dims[2]; i++) { if (i > prog) { ss.str(""); progressInt = ((float)i/dims[2])*100.0; ss << "Transferring Cell Data - " << progressInt << "% Complete"; notifyStatusMessage(ss.str()); prog = prog + progIncrement; } if (getCancel() == true) { return; } slice = static_cast<int>( (dims[2] - 1) - i ); for (DimType l = 0; l < dims[1]; l++) { for (DimType n = 0; n < dims[0]; n++) { if(yshifts[i] >= 0) yspot = static_cast<int>(l); else if(yshifts[i] < 0) yspot = static_cast<int>( dims[1] - 1 - l ); if(xshifts[i] >= 0) xspot = static_cast<int>(n); else if(xshifts[i] < 0) xspot = static_cast<int>( dims[0] - 1 - n ); newPosition = (slice * dims[0] * dims[1]) + (yspot * dims[0]) + xspot; currentPosition = (slice * dims[0] * dims[1]) + ((yspot + yshifts[i]) * dims[0]) + (xspot + xshifts[i]); if((yspot + yshifts[i]) >= 0 && (yspot + yshifts[i]) <= dims[1] - 1 && (xspot + xshifts[i]) >= 0 && (xspot + xshifts[i]) <= dims[0] - 1) { for(std::list<std::string>::iterator iter = voxelArrayNames.begin(); iter != voxelArrayNames.end(); ++iter) { std::string name = *iter; IDataArray::Pointer p = m->getCellData(*iter); p->CopyTuple(currentPosition, newPosition); } } if((yspot + yshifts[i]) < 0 || (yspot + yshifts[i]) > dims[1] - 1 || (xspot + xshifts[i]) < 0 || (xspot + xshifts[i]) > dims[0] - 1) { for(std::list<std::string>::iterator iter = voxelArrayNames.begin(); iter != voxelArrayNames.end(); ++iter) { std::string name = *iter; IDataArray::Pointer p = m->getCellData(*iter); p->InitializeTuple(newPosition, 0.0); } } } } } // If there is an error set this to something negative and also set a message notifyStatusMessage("Complete"); }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void AlignSections::execute() { setErrorCondition(0); dataCheck(); if(getErrorCondition() < 0) { return; } DataContainer::Pointer m = getDataContainerArray()->getDataContainer(getDataContainerName()); size_t dims[3] = { 0, 0, 0 }; m->getGeometryAs<ImageGeom>()->getDimensions(dims); int64_t xspot = 0, yspot = 0; int64_t newPosition = 0; int64_t currentPosition = 0; std::vector<int64_t> xshifts(dims[2], 0); std::vector<int64_t> yshifts(dims[2], 0); find_shifts(xshifts, yshifts); QList<QString> voxelArrayNames = m->getAttributeMatrix(getCellAttributeMatrixName())->getAttributeArrayNames(); size_t progIncrement = dims[2] / 100; size_t prog = 1; size_t progressInt = 0; size_t slice = 0; for (size_t i = 1; i < dims[2]; i++) { if (i > prog) { progressInt = ((float)i / dims[2]) * 100.0f; QString ss = QObject::tr("Transferring Cell Data || %1% Complete").arg(progressInt); notifyStatusMessage(getMessagePrefix(), getHumanLabel(), ss); prog = prog + progIncrement; } if (getCancel() == true) { return; } slice = (dims[2] - 1) - i; for (size_t l = 0; l < dims[1]; l++) { for (size_t n = 0; n < dims[0]; n++) { if (yshifts[i] >= 0) { yspot = l; } else if (yshifts[i] < 0) { yspot = dims[1] - 1 - l; } if (xshifts[i] >= 0) { xspot = n; } else if (xshifts[i] < 0) { xspot = dims[0] - 1 - n; } newPosition = (slice * dims[0] * dims[1]) + (yspot * dims[0]) + xspot; currentPosition = (slice * dims[0] * dims[1]) + ((yspot + yshifts[i]) * dims[0]) + (xspot + xshifts[i]); if ((yspot + yshifts[i]) >= 0 && (yspot + yshifts[i]) <= static_cast<int64_t>(dims[1]) - 1 && (xspot + xshifts[i]) >= 0 && (xspot + xshifts[i]) <= static_cast<int64_t>(dims[0]) - 1) { for (QList<QString>::iterator iter = voxelArrayNames.begin(); iter != voxelArrayNames.end(); ++iter) { IDataArray::Pointer p = m->getAttributeMatrix(getCellAttributeMatrixName())->getAttributeArray(*iter); p->copyTuple( static_cast<size_t>(currentPosition), static_cast<size_t>(newPosition)); } } if ((yspot + yshifts[i]) < 0 || (yspot + yshifts[i]) > static_cast<int64_t>(dims[1] - 1) || (xspot + xshifts[i]) < 0 || (xspot + xshifts[i]) > static_cast<int64_t>(dims[0]) - 1) { for (QList<QString>::iterator iter = voxelArrayNames.begin(); iter != voxelArrayNames.end(); ++iter) { IDataArray::Pointer p = m->getAttributeMatrix(getCellAttributeMatrixName())->getAttributeArray(*iter); EXECUTE_FUNCTION_TEMPLATE(this, initializeArrayValues, p, p, newPosition) } } } } } // If there is an error set this to something negative and also set a message notifyStatusMessage(getHumanLabel(), "Complete"); }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void FindNeighbors::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_NumNeighborsPtr.lock()->getNumberOfTuples(); 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]), }; DimType neighpoints[6] = { 0, 0, 0, 0, 0, 0 }; neighpoints[0] = -dims[0] * dims[1]; neighpoints[1] = -dims[0]; neighpoints[2] = -1; neighpoints[3] = 1; neighpoints[4] = dims[0]; neighpoints[5] = dims[0] * dims[1]; DimType column = 0, row = 0, plane = 0; int32_t feature = 0; int32_t nnum = 0; int8_t onsurf = 0; bool good = false; DimType neighbor = 0; std::vector<std::vector<int32_t> > neighborlist; std::vector<std::vector<float> > neighborsurfacearealist; int32_t nListSize = 100; neighborlist.resize(totalFeatures); neighborsurfacearealist.resize(totalFeatures); uint64_t millis = QDateTime::currentMSecsSinceEpoch(); uint64_t currentMillis = millis; for (size_t i = 1; i < totalFeatures; i++) { currentMillis = QDateTime::currentMSecsSinceEpoch(); if (currentMillis - millis > 1000) { QString ss = QObject::tr("Finding Neighbors || Initializing Neighbor Lists || %1% Complete").arg((static_cast<float>(i) / totalFeatures) * 100); notifyStatusMessage(getMessagePrefix(), getHumanLabel(), ss); millis = QDateTime::currentMSecsSinceEpoch(); } if (getCancel() == true) { return; } m_NumNeighbors[i] = 0; neighborlist[i].resize(nListSize); neighborsurfacearealist[i].assign(nListSize, -1.0f); if (m_StoreSurfaceFeatures == true) { m_SurfaceFeatures[i] = false; } } for (size_t j = 0; j < totalPoints; j++) { currentMillis = QDateTime::currentMSecsSinceEpoch(); if (currentMillis - millis > 1000) { QString ss = QObject::tr("Finding Neighbors || Determining Neighbor Lists || %1% Complete").arg((static_cast<float>(j) / totalPoints) * 100); notifyStatusMessage(getMessagePrefix(), getHumanLabel(), ss); millis = QDateTime::currentMSecsSinceEpoch(); } if (getCancel() == true) { return; } onsurf = 0; feature = m_FeatureIds[j]; if (feature > 0) { column = static_cast<DimType>( j % m->getGeometryAs<ImageGeom>()->getXPoints() ); row = static_cast<DimType>( (j / m->getGeometryAs<ImageGeom>()->getXPoints()) % m->getGeometryAs<ImageGeom>()->getYPoints() ); plane = static_cast<DimType>( j / (m->getGeometryAs<ImageGeom>()->getXPoints() * m->getGeometryAs<ImageGeom>()->getYPoints()) ); if (m_StoreSurfaceFeatures == true) { if ((column == 0 || column == DimType((m->getGeometryAs<ImageGeom>()->getXPoints() - 1)) || row == 0 || row == DimType((m->getGeometryAs<ImageGeom>()->getYPoints()) - 1) || plane == 0 || plane == DimType((m->getGeometryAs<ImageGeom>()->getZPoints() - 1))) && m->getGeometryAs<ImageGeom>()->getZPoints() != 1) { m_SurfaceFeatures[feature] = true; } if ((column == 0 || column == DimType((m->getGeometryAs<ImageGeom>()->getXPoints() - 1)) || row == 0 || row == DimType((m->getGeometryAs<ImageGeom>()->getYPoints() - 1))) && m->getGeometryAs<ImageGeom>()->getZPoints() == 1) { m_SurfaceFeatures[feature] = true; } } for (int32_t k = 0; k < 6; k++) { good = true; neighbor = static_cast<DimType>( j + neighpoints[k] ); if (k == 0 && plane == 0) { good = false; } if (k == 5 && plane == (m->getGeometryAs<ImageGeom>()->getZPoints() - 1)) { good = false; } if (k == 1 && row == 0) { good = false; } if (k == 4 && row == (m->getGeometryAs<ImageGeom>()->getYPoints() - 1)) { good = false; } if (k == 2 && column == 0) { good = false; } if (k == 3 && column == (m->getGeometryAs<ImageGeom>()->getXPoints() - 1)) { good = false; } if (good == true && m_FeatureIds[neighbor] != feature && m_FeatureIds[neighbor] > 0) { onsurf++; nnum = m_NumNeighbors[feature]; neighborlist[feature].push_back(m_FeatureIds[neighbor]); nnum++; m_NumNeighbors[feature] = nnum; } } } if (m_StoreBoundaryCells == true) { m_BoundaryCells[j] = onsurf; } } // We do this to create new set of NeighborList objects for (size_t i = 1; i < totalFeatures; i++) { currentMillis = QDateTime::currentMSecsSinceEpoch(); if (currentMillis - millis > 1000) { QString ss = QObject::tr("Finding Neighbors || Calculating Surface Areas || %1% Complete").arg(((float)i / totalFeatures) * 100); notifyStatusMessage(getMessagePrefix(), getHumanLabel(), ss); millis = QDateTime::currentMSecsSinceEpoch(); } if(getCancel() == true) { return; } QMap<int32_t, int32_t> neighToCount; int32_t numneighs = static_cast<int32_t>( neighborlist[i].size() ); // this increments the voxel counts for each feature for (int32_t j = 0; j < numneighs; j++) { neighToCount[neighborlist[i][j]]++; } QMap<int32_t, int32_t>::Iterator neighiter = neighToCount.find(0); neighToCount.erase(neighiter); neighiter = neighToCount.find(-1); neighToCount.erase(neighiter); // Resize the features neighbor list to zero neighborlist[i].resize(0); neighborsurfacearealist[i].resize(0); for (QMap<int32_t, int32_t>::iterator iter = neighToCount.begin(); iter != neighToCount.end(); ++iter) { int32_t neigh = iter.key(); // get the neighbor feature int32_t number = iter.value(); // get the number of voxels float area = float(number) * m->getGeometryAs<ImageGeom>()->getXRes() * m->getGeometryAs<ImageGeom>()->getYRes(); // Push the neighbor feature id back onto the list so we stay synced up neighborlist[i].push_back(neigh); neighborsurfacearealist[i].push_back(area); } m_NumNeighbors[i] = int32_t(neighborlist[i].size()); // Set the vector for each list into the NeighborList Object NeighborList<int32_t>::SharedVectorType sharedNeiLst(new std::vector<int32_t>); sharedNeiLst->assign(neighborlist[i].begin(), neighborlist[i].end()); m_NeighborList.lock()->setList(static_cast<int32_t>(i), sharedNeiLst); NeighborList<float>::SharedVectorType sharedSAL(new std::vector<float>); sharedSAL->assign(neighborsurfacearealist[i].begin(), neighborsurfacearealist[i].end()); m_SharedSurfaceAreaList.lock()->setList(static_cast<int32_t>(i), sharedSAL); } notifyStatusMessage(getHumanLabel(), "Complete"); }