ZSwcTree *ZNeuronConstructor::reconstruct( std::vector<Locseg_Chain*> &chainArray) { ZSwcTree *tree = NULL; if (!chainArray.empty()) { int chain_number = chainArray.size(); /* <neuronComponent> allocated */ Neuron_Component *neuronComponent = Make_Neuron_Component_Array(chain_number); for (int i = 0; i < chain_number; i++) { Set_Neuron_Component(neuronComponent + i, NEUROCOMP_TYPE_LOCSEG_CHAIN, chainArray[i]); } /* reconstruct neuron */ /* alloc <ns> */ double zscale = 1.0; Neuron_Structure *ns = Locseg_Chain_Comp_Neurostruct( neuronComponent, chain_number, m_signal, zscale, m_connWorkspace); Process_Neuron_Structure(ns); if (m_connWorkspace->crossover_test == TRUE) { Neuron_Structure_Crossover_Test(ns, zscale); } /* alloc <ns2> */ Neuron_Structure* ns2= Neuron_Structure_Locseg_Chain_To_Circle_S(ns, 1.0, 1.0); Neuron_Structure_To_Tree(ns2); tree = new ZSwcTree; tree->setData(Neuron_Structure_To_Swc_Tree_Circle_Z(ns2, 1.0, NULL)); tree->resortId(); /* free <ns2> */ Kill_Neuron_Structure(ns2); /* free <ns> */ ns->comp = NULL; Kill_Neuron_Structure(ns); /* free <neuronComponent> */ Clean_Neuron_Component_Array(neuronComponent, chain_number); free(neuronComponent); } return tree; }
std::vector<double> ZSwcLayerShollFeatureAnalyzer::computeFeature( Swc_Tree_Node *tn) { TZ_ASSERT(tn != NULL, "null pointer"); std::vector<double> featureArray(2, 0); ZSwcTree tree; tree.setDataFromNodeRoot(tn); tree.updateIterator(SWC_TREE_ITERATOR_BREADTH_FIRST); double baseZ = SwcTreeNode::z(tn); featureArray[0] = baseZ; Swc_Tree_Node *iter = tree.begin(); //while (SwcTreeNode::isRoot(iter)) { while (SwcTreeNode::isVirtual(iter)) { iter = tree.next(); } double upZ = baseZ - m_layerMargin; double downZ = baseZ + m_layerMargin; for (; iter != NULL; iter = iter->next) { Swc_Tree_Node *parent = iter->parent; double minZ = iter->node.z; double maxZ = parent->node.z; if (minZ > maxZ) { minZ = parent->node.z; maxZ = iter->node.z; } /* double r1 = SwcTreeNode::radius(iter); double r2 = SwcTreeNode::radius(parent); */ if (minZ <= downZ && maxZ >= upZ) { featureArray[1] += 1.0; } } #ifdef _DEBUG_ if (featureArray[1] == 0.0) { cout << "debug here" << endl; } #endif tree.setData(NULL, ZSwcTree::FREE_WRAPPER); return featureArray; }
ZSwcTree* ZSwcGenerator::createSwc( const ZVoxelArray &voxelArray, ZSwcGenerator::EPostProcess option) { if (option == REGION_SAMPLING) { return createSwcByRegionSampling(voxelArray); } size_t startIndex = 0; size_t endIndex = voxelArray.size() - 1; Swc_Tree *tree = New_Swc_Tree(); const std::vector<ZVoxel> &voxelData = voxelArray.getInternalData(); ZVoxel prevVoxel = voxelData[startIndex]; Swc_Tree_Node *tn = New_Swc_Tree_Node(); SwcTreeNode::setPos(tn, prevVoxel.x(), prevVoxel.y(), prevVoxel.z()); SwcTreeNode::setRadius(tn, prevVoxel.value()); Swc_Tree_Node *prevTn = tn; for (size_t i = startIndex + 1; i < endIndex; i++) { double dist = voxelData[i].distanceTo(prevVoxel); bool sampling = true; if (option == SPARSE_SAMPLING) { if (dist < prevVoxel.value()) { sampling = false; } } if (sampling) { tn = New_Swc_Tree_Node(); SwcTreeNode::setPos(tn, voxelData[i].x(), voxelData[i].y(), voxelData[i].z()); SwcTreeNode::setRadius(tn, voxelData[i].value()); Swc_Tree_Node_Set_Parent(prevTn, tn); prevTn = tn; prevVoxel = voxelData[i]; } } if (endIndex - startIndex > 0) { //last node tn = New_Swc_Tree_Node(); SwcTreeNode::setPos(tn, voxelData[endIndex].x(), voxelData[endIndex].y(), voxelData[endIndex].z()); SwcTreeNode::setRadius(tn, voxelData[endIndex].value()); Swc_Tree_Node_Set_Parent(prevTn, tn); /* if (SwcTreeNode::hasOverlap(prevTn, tn) && SwcTreeNode::hasChild(prevTn)) { SwcTreeNode::mergeToParent(prevTn); } */ } tree->root = tn; ZSwcTree *treeWrapper = new ZSwcTree; treeWrapper->setData(tree); if (option == OPTIMAL_SAMPLING) { ZSwcResampler resampler; resampler.optimalDownsample(treeWrapper); } return treeWrapper; }
vector<double> ZSwcShollFeatureAnalyzer::computeFeature(Swc_Tree_Node *tn) { vector<SwcNodePair> distanceArray; vector<double> crossingNumberArray; ZPoint center(tn->node.x, tn->node.y, tn->node.z); ZSwcTree sourceTree; sourceTree.setDataFromNodeRoot(tn); //cout << sourceTree.data()->root << endl; sourceTree.updateIterator(SWC_TREE_ITERATOR_DEPTH_FIRST, false); double maxLength = 0.0; for (Swc_Tree_Node *tn = sourceTree.begin(); tn != sourceTree.end(); tn = sourceTree.next()) { if (Swc_Tree_Node_Is_Regular(tn) && !Swc_Tree_Node_Is_Root(tn)) { //Compute the central distances of the current node and its parent SwcNodePair distancePair; ZPoint v1(Swc_Tree_Node_X(tn), Swc_Tree_Node_Y(tn), Swc_Tree_Node_Z(tn)); ZPoint v2(Swc_Tree_Node_X(tn->parent), Swc_Tree_Node_Y(tn->parent), Swc_Tree_Node_Z(tn->parent)); double d1 = v1.distanceTo(center); double d2 = v2.distanceTo(center); //Make sure that distancePair.first < distancePair.second if (d1 > d2) { distancePair.first = d2; distancePair.second = d1; distancePair.firstNode = tn->parent; distancePair.secondNode = tn; } else { distancePair.first = d1; distancePair.second = d2; distancePair.firstNode = tn; distancePair.secondNode = tn->parent; } //Calculate the distance between v1 and v2 double length = v1.distanceTo(v2); if (length > maxLength) { maxLength = length; } distanceArray.push_back(distancePair); } } sort(distanceArray.begin(), distanceArray.end(), SwcNodePairLessThan()); int startIndex = 0; int endIndex = 0; int lastIndex = int(distanceArray.size()) - 1; for (double r = m_shollStart; r <= m_shollEnd; r += m_shollRadius) { if (startIndex <= lastIndex) { //Update start index and end index while (distanceArray[startIndex].first < r - maxLength) { startIndex++; if (startIndex > lastIndex) { break; } } if (endIndex <= lastIndex) { while (distanceArray[endIndex].first < r) { endIndex++; if (endIndex > lastIndex) { break; } } } //Crossing test int crossingNumber = 0; if (startIndex <= lastIndex) { for (int i = startIndex; i < endIndex; ++i) { //If a crossing point is detected if (distanceArray[i].second >= r) { crossingNumber += 1.0; } } } crossingNumberArray.push_back(crossingNumber); } else { crossingNumberArray.push_back(0); } } //cout << sourceTree.data()->root << endl; sourceTree.setData(NULL, ZSwcTree::FREE_WRAPPER); return crossingNumberArray; }