mitk::SemanticRelationsDataStorageAccess::DataNodeVector mitk::SemanticRelationsDataStorageAccess::GetAllSegmentationsOfLesion(const SemanticTypes::CaseID& caseID, const SemanticTypes::Lesion& lesion) const { if (SemanticRelationsInference::InstanceExists(caseID, lesion)) { // lesion exists, retrieve all case segmentations from the storage DataNodeVector allSegmentationsOfLesion = GetAllSegmentationsOfCase(caseID); // filter all segmentations: check for semantic relation with the given lesion using a lambda function auto lambda = [&lesion, this](DataNode::Pointer segmentation) { try { SemanticTypes::Lesion representedLesion = SemanticRelationsInference::GetLesionOfSegmentation(segmentation); return lesion.UID != representedLesion.UID; } catch (const SemanticRelationException&) { return true; } }; allSegmentationsOfLesion.erase(std::remove_if(allSegmentationsOfLesion.begin(), allSegmentationsOfLesion.end(), lambda), allSegmentationsOfLesion.end()); return allSegmentationsOfLesion; } else { mitkThrowException(SemanticRelationException) << "Could not find an existing lesion instance for the given caseID " << caseID << " and lesion " << lesion.UID << "."; } }
mitk::SemanticRelationsDataStorageAccess::DataNodeVector mitk::SemanticRelationsDataStorageAccess::GetAllSpecificImages(const SemanticTypes::CaseID& caseID, const SemanticTypes::ControlPoint& controlPoint, const SemanticTypes::InformationType& informationType) const { if (SemanticRelationsInference::InstanceExists(caseID, controlPoint)) { if (SemanticRelationsInference::InstanceExists(caseID, informationType)) { // control point exists, information type exists, retrieve all images from the storage DataNodeVector allImagesOfCase = GetAllImagesOfCase(caseID); // filter all images to remove the ones with a different control point and information type using a lambda function auto lambda = [&controlPoint, &informationType, this](DataNode::Pointer imageNode) { return (informationType != SemanticRelationsInference::GetInformationTypeOfImage(imageNode)) || (controlPoint.date != SemanticRelationsInference::GetControlPointOfImage(imageNode).date); }; allImagesOfCase.erase(std::remove_if(allImagesOfCase.begin(), allImagesOfCase.end(), lambda), allImagesOfCase.end()); return allImagesOfCase; } else { mitkThrowException(SemanticRelationException) << "Could not find an existing information type for the given caseID " << caseID << " and information type " << informationType; } } else { mitkThrowException(SemanticRelationException) << "Could not find an existing control point for the given caseID " << caseID << " and control point " << controlPoint.UID; } }
mitk::SemanticRelationsDataStorageAccess::DataNodeVector mitk::SemanticRelationsDataStorageAccess::GetAllImagesOfLesion(const SemanticTypes::CaseID& caseID, const SemanticTypes::Lesion& lesion) const { if (m_DataStorage.IsExpired()) { mitkThrowException(SemanticRelationException) << "Not a valid data storage."; } DataNodeVector allImagesOfLesion; // 1. get all segmentations that define the lesion // 2. retrieve the parent node (source) of the found segmentation node DataNodeVector allSegmentationsOfLesion = GetAllSegmentationsOfLesion(caseID, lesion); for (const auto& segmentationNode : allSegmentationsOfLesion) { // get parent node of the current segmentation node with the node predicate DataStorage::SetOfObjects::ConstPointer parentNodes = m_DataStorage.Lock()->GetSources(segmentationNode, NodePredicates::GetImagePredicate(), false); for (auto it = parentNodes->Begin(); it != parentNodes->End(); ++it) { DataNode::Pointer dataNode = it->Value(); allImagesOfLesion.push_back(it->Value()); } } std::sort(allImagesOfLesion.begin(), allImagesOfLesion.end()); allImagesOfLesion.erase(std::unique(allImagesOfLesion.begin(), allImagesOfLesion.end()), allImagesOfLesion.end()); return allImagesOfLesion; }
mitk::SemanticRelationsDataStorageAccess::DataNodeVector mitk::SemanticRelationsDataStorageAccess::GetAllSpecificSegmentations(const SemanticTypes::CaseID& caseID, const SemanticTypes::ControlPoint& controlPoint, const SemanticTypes::InformationType& informationType) const { if (m_DataStorage.IsExpired()) { mitkThrow() << "Not a valid data storage."; } DataNodeVector allSpecificImages = GetAllSpecificImages(caseID, controlPoint, informationType); DataNodeVector allSpecificSegmentations; for (const auto& imageNode : allSpecificImages) { DataStorage::SetOfObjects::ConstPointer segmentationNodes = m_DataStorage.Lock()->GetDerivations(imageNode, NodePredicates::GetSegmentationPredicate(), false); for (auto it = segmentationNodes->Begin(); it != segmentationNodes->End(); ++it) { allSpecificSegmentations.push_back(it->Value()); } } return allSpecificSegmentations; }
bool mitk::SceneReaderV1::LoadScene( TiXmlDocument& document, const std::string& workingDirectory, DataStorage* storage ) { assert(storage); bool error(false); // TODO prepare to detect errors (such as cycles) from wrongly written or edited xml files //Get number of elements to initialze progress bar // 1. if there is a <data type="..." file="..."> element, // - construct a name for the appropriate serializer // - try to instantiate this serializer via itk object factory // - if serializer could be created, use it to read the file into a BaseData object // - if successful, call the new node's SetData(..) // create a node for the tag "data" and test if node was created typedef std::vector<mitk::DataNode::Pointer> DataNodeVector; DataNodeVector DataNodes; unsigned int listSize = 0; for( TiXmlElement* element = document.FirstChildElement("node"); element != NULL; element = element->NextSiblingElement("node") ) { ++listSize; } ProgressBar::GetInstance()->AddStepsToDo(listSize * 2); for (TiXmlElement* element = document.FirstChildElement("node"); element != NULL; element = element->NextSiblingElement("node")) { DataNodes.push_back(LoadBaseDataFromDataTag(element->FirstChildElement("data"), workingDirectory, error)); ProgressBar::GetInstance()->Progress(); } // iterate all nodes // first level nodes should be <node> elements DataNodeVector::iterator nit = DataNodes.begin(); for( TiXmlElement* element = document.FirstChildElement("node"); element != NULL || nit != DataNodes.end(); element = element->NextSiblingElement("node"), ++nit ) { mitk::DataNode::Pointer node = *nit; // in case dataXmlElement is valid test whether it containts the "properties" child tag // and process further if and only if yes TiXmlElement *dataXmlElement = element->FirstChildElement("data"); if( dataXmlElement && dataXmlElement->FirstChildElement("properties") ) { TiXmlElement *baseDataElement = dataXmlElement->FirstChildElement("properties"); if ( node->GetData() ) { DecorateBaseDataWithProperties( node->GetData(), baseDataElement, workingDirectory); } else { MITK_WARN << "BaseData properties stored in scene file, but BaseData could not be read" << std::endl; } } // 2. check child nodes const char* uida = element->Attribute("UID"); std::string uid(""); if (uida) { uid = uida; m_NodeForID[uid] = node.GetPointer(); m_IDForNode[ node.GetPointer() ] = uid; } else { MITK_ERROR << "No UID found for current node. Node will have no parents."; error = true; } // 3. if there are <properties> nodes, // - instantiate the appropriate PropertyListDeSerializer // - use them to construct PropertyList objects // - add these properties to the node (if necessary, use renderwindow name) bool success = DecorateNodeWithProperties(node, element, workingDirectory); if (!success) { MITK_ERROR << "Could not load properties for node."; error = true; } // remember node for later adding to DataStorage m_OrderedNodePairs.push_back( std::make_pair( node, std::list<std::string>() ) ); // 4. if there are <source> elements, remember parent objects for( TiXmlElement* source = element->FirstChildElement("source"); source != NULL; source = source->NextSiblingElement("source") ) { const char* sourceUID = source->Attribute("UID"); if (sourceUID) { m_OrderedNodePairs.back().second.push_back( std::string(sourceUID) ); } } ProgressBar::GetInstance()->Progress(); } // end for all <node> // sort our nodes by their "layer" property // (to be inserted in that order) m_OrderedNodePairs.sort( &NodeSortByLayerIsLessThan ); // remove all unknown parent UIDs for (OrderedNodesList::iterator nodesIter = m_OrderedNodePairs.begin(); nodesIter != m_OrderedNodePairs.end(); ++nodesIter) { for (std::list<std::string>::iterator parentsIter = nodesIter->second.begin(); parentsIter != nodesIter->second.end();) { if (m_NodeForID.find( *parentsIter ) == m_NodeForID.end()) { parentsIter = nodesIter->second.erase( parentsIter ); MITK_WARN << "Found a DataNode with unknown parents. Will add it to DataStorage without any parent objects."; error = true; } else { ++parentsIter; } } } // repeat the following loop ... // ... for all created nodes unsigned int lastMapSize(0); while ( lastMapSize != m_OrderedNodePairs.size()) // this is to prevent infinite loops; each iteration must at least add one node to DataStorage { lastMapSize = m_OrderedNodePairs.size(); // iterate (layer) ordered nodes backwards // we insert the highest layers first for (OrderedNodesList::iterator nodesIter = m_OrderedNodePairs.begin(); nodesIter != m_OrderedNodePairs.end(); ++nodesIter) { bool addThisNode(true); // if any parent node is not yet in DataStorage, skip node for now and check later for (std::list<std::string>::iterator parentsIter = nodesIter->second.begin(); parentsIter != nodesIter->second.end(); ++parentsIter) { if ( !storage->Exists( m_NodeForID[ *parentsIter ] ) ) { addThisNode = false; break; } } if (addThisNode) { DataStorage::SetOfObjects::Pointer parents = DataStorage::SetOfObjects::New(); for ( std::list<std::string>::iterator parentsIter = nodesIter->second.begin(); parentsIter != nodesIter->second.end(); ++parentsIter ) { parents->push_back(m_NodeForID[*parentsIter]); } // if all parents are found in datastorage (or are unknown), add node to DataStorage storage->Add(nodesIter->first, parents); // remove this node from m_OrderedNodePairs m_OrderedNodePairs.erase( nodesIter ); // break this for loop because iterators are probably invalid break; } } } // All nodes that are still in m_OrderedNodePairs at this point are not part of a proper directed graph structure. We'll add such nodes without any parent information. for (OrderedNodesList::iterator nodesIter = m_OrderedNodePairs.begin(); nodesIter != m_OrderedNodePairs.end(); ++nodesIter) { storage->Add( nodesIter->first ); MITK_WARN << "Encountered node that is not part of a directed graph structure. Will be added to DataStorage without parents."; error = true; } return !error; }