void ZSwcNodeObjsModel::setupModelData(ZObjsItem *parent) { QList<QVariant> data; m_typeToRow.clear(); m_swcTreeNodeToRow.clear(); m_swcTreeNodeToType.clear(); m_typeToRow[SwcTreeNode::TERMINAL] = 0; m_typeToRow[SwcTreeNode::BRANCH_POINT] = 1; data.clear(); data << "Termini" << "id" << "type" << "radius" << "x" << "y" << "z" << "label"; ZObjsItem *terminalItem = new ZObjsItem(data, NULL, parent); terminalItem->setCheckState(Qt::Checked); parent->appendChild(terminalItem); data.clear(); data << "Branch Points" << "id" << "type" << "radius" << "x" << "y" << "z" << "label"; ZObjsItem *branchPointItem = new ZObjsItem(data, NULL, parent); branchPointItem->setCheckState(Qt::Checked); parent->appendChild(branchPointItem); int terminalRow = 0; int branchPointRow = 0; QList<ZSwcTree*> swcList = m_doc->getSwcList(); for (int i=0; i<swcList.size(); i++) { data.clear(); ZSwcTree *swcTree = swcList.at(i); //ZObjsItem *nodeParent = new ZObjsItem(data, swcTree, parent); //nodeParent->setCheckState(swcTree->isVisible() ? Qt::Checked : Qt::Unchecked); //nodeParent->setToolTip(QString("source: %1").arg(QString::fromStdString(swcTree->source()))); //parent->appendChild(nodeParent); swcTree->updateIterator(SWC_TREE_ITERATOR_DEPTH_FIRST); //depth first for (Swc_Tree_Node *tn = swcTree->begin(); tn != swcTree->end(); tn = swcTree->next()) { if (!SwcTreeNode::isVirtual(tn)) { data.clear(); data << "" << tn->node.id << tn->node.type << tn->node.d << tn->node.x << tn->node.y << tn->node.z << tn->node.label << ""; if (SwcTreeNode::isBranchPoint(tn)) { m_swcTreeNodeToType[tn] = SwcTreeNode::BRANCH_POINT; m_swcTreeNodeToRow[tn] = branchPointRow++; ZObjsItem *node = new ZObjsItem(data, tn, branchPointItem); branchPointItem->appendChild(node); } else if (SwcTreeNode::isRoot(tn) || SwcTreeNode::isLeaf(tn)) { m_swcTreeNodeToType[tn] = SwcTreeNode::TERMINAL; m_swcTreeNodeToRow[tn] = terminalRow++; ZObjsItem *node = new ZObjsItem(data, tn, terminalItem); terminalItem->appendChild(node); } } } } }
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; }