Mercurial > hg > orthanc
comparison OrthancServer/Sources/ServerContext.cpp @ 5712:52771e1a8072 find-refactoring-clean
removed ServerContext::ExpandResource()
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 12 Jul 2024 19:05:16 +0200 |
parents | c8d21a09aae6 |
children | 593e110de3d8 |
comparison
equal
deleted
inserted
replaced
5711:31eb66eaed86 | 5712:52771e1a8072 |
---|---|
67 * locking. | 67 * locking. |
68 **/ | 68 **/ |
69 | 69 |
70 namespace Orthanc | 70 namespace Orthanc |
71 { | 71 { |
72 static void ComputeStudyTags(ExpandedResource& resource, | |
73 ServerContext& context, | |
74 const std::string& studyPublicId, | |
75 const std::set<DicomTag>& requestedTags); | |
76 | |
77 | |
78 static bool IsUncompressedTransferSyntax(DicomTransferSyntax transferSyntax) | 72 static bool IsUncompressedTransferSyntax(DicomTransferSyntax transferSyntax) |
79 { | 73 { |
80 return (transferSyntax == DicomTransferSyntax_LittleEndianImplicit || | 74 return (transferSyntax == DicomTransferSyntax_LittleEndianImplicit || |
81 transferSyntax == DicomTransferSyntax_LittleEndianExplicit || | 75 transferSyntax == DicomTransferSyntax_LittleEndianExplicit || |
82 transferSyntax == DicomTransferSyntax_BigEndianExplicit); | 76 transferSyntax == DicomTransferSyntax_BigEndianExplicit); |
1937 { | 1931 { |
1938 boost::mutex::scoped_lock lock(dynamicOptionsMutex_); | 1932 boost::mutex::scoped_lock lock(dynamicOptionsMutex_); |
1939 isUnknownSopClassAccepted_ = accepted; | 1933 isUnknownSopClassAccepted_ = accepted; |
1940 } | 1934 } |
1941 | 1935 |
1942 | |
1943 static void SerializeExpandedResource(Json::Value& target, | |
1944 const ExpandedResource& resource, | |
1945 DicomToJsonFormat format, | |
1946 const std::set<DicomTag>& requestedTags, | |
1947 ExpandResourceFlags expandFlags) | |
1948 { | |
1949 target = Json::objectValue; | |
1950 | |
1951 target["Type"] = GetResourceTypeText(resource.GetLevel(), false, true); | |
1952 target["ID"] = resource.GetPublicId(); | |
1953 | |
1954 if (!resource.parentId_.empty()) | |
1955 { | |
1956 switch (resource.GetLevel()) | |
1957 { | |
1958 case ResourceType_Patient: | |
1959 break; | |
1960 | |
1961 case ResourceType_Study: | |
1962 target["ParentPatient"] = resource.parentId_; | |
1963 break; | |
1964 | |
1965 case ResourceType_Series: | |
1966 target["ParentStudy"] = resource.parentId_; | |
1967 break; | |
1968 | |
1969 case ResourceType_Instance: | |
1970 target["ParentSeries"] = resource.parentId_; | |
1971 break; | |
1972 | |
1973 default: | |
1974 throw OrthancException(ErrorCode_InternalError); | |
1975 } | |
1976 } | |
1977 | |
1978 if ((expandFlags & ExpandResourceFlags_IncludeChildren) != 0) | |
1979 { | |
1980 switch (resource.GetLevel()) | |
1981 { | |
1982 case ResourceType_Patient: | |
1983 case ResourceType_Study: | |
1984 case ResourceType_Series: | |
1985 { | |
1986 Json::Value c = Json::arrayValue; | |
1987 | |
1988 for (std::list<std::string>::const_iterator | |
1989 it = resource.childrenIds_.begin(); it != resource.childrenIds_.end(); ++it) | |
1990 { | |
1991 c.append(*it); | |
1992 } | |
1993 | |
1994 if (resource.GetLevel() == ResourceType_Patient) | |
1995 { | |
1996 target["Studies"] = c; | |
1997 } | |
1998 else if (resource.GetLevel() == ResourceType_Study) | |
1999 { | |
2000 target["Series"] = c; | |
2001 } | |
2002 else | |
2003 { | |
2004 target["Instances"] = c; | |
2005 } | |
2006 break; | |
2007 } | |
2008 | |
2009 case ResourceType_Instance: | |
2010 break; | |
2011 | |
2012 default: | |
2013 throw OrthancException(ErrorCode_InternalError); | |
2014 } | |
2015 } | |
2016 | |
2017 if ((expandFlags & ExpandResourceFlags_IncludeMetadata) != 0) | |
2018 { | |
2019 switch (resource.GetLevel()) | |
2020 { | |
2021 case ResourceType_Patient: | |
2022 case ResourceType_Study: | |
2023 break; | |
2024 | |
2025 case ResourceType_Series: | |
2026 if (resource.expectedNumberOfInstances_ < 0) | |
2027 { | |
2028 target["ExpectedNumberOfInstances"] = Json::nullValue; | |
2029 } | |
2030 else | |
2031 { | |
2032 target["ExpectedNumberOfInstances"] = resource.expectedNumberOfInstances_; | |
2033 } | |
2034 target["Status"] = resource.status_; | |
2035 break; | |
2036 | |
2037 case ResourceType_Instance: | |
2038 { | |
2039 target["FileSize"] = static_cast<unsigned int>(resource.fileSize_); | |
2040 target["FileUuid"] = resource.fileUuid_; | |
2041 | |
2042 if (resource.indexInSeries_ < 0) | |
2043 { | |
2044 target["IndexInSeries"] = Json::nullValue; | |
2045 } | |
2046 else | |
2047 { | |
2048 target["IndexInSeries"] = resource.indexInSeries_; | |
2049 } | |
2050 | |
2051 break; | |
2052 } | |
2053 | |
2054 default: | |
2055 throw OrthancException(ErrorCode_InternalError); | |
2056 } | |
2057 | |
2058 if (!resource.anonymizedFrom_.empty()) | |
2059 { | |
2060 target["AnonymizedFrom"] = resource.anonymizedFrom_; | |
2061 } | |
2062 | |
2063 if (!resource.modifiedFrom_.empty()) | |
2064 { | |
2065 target["ModifiedFrom"] = resource.modifiedFrom_; | |
2066 } | |
2067 } | |
2068 | |
2069 if (resource.GetLevel() == ResourceType_Patient || | |
2070 resource.GetLevel() == ResourceType_Study || | |
2071 resource.GetLevel() == ResourceType_Series) | |
2072 { | |
2073 if ((expandFlags & ExpandResourceFlags_IncludeIsStable) != 0) | |
2074 { | |
2075 target["IsStable"] = resource.isStable_; | |
2076 } | |
2077 | |
2078 if (!resource.lastUpdate_.empty()) | |
2079 { | |
2080 target["LastUpdate"] = resource.lastUpdate_; | |
2081 } | |
2082 } | |
2083 | |
2084 if ((expandFlags & ExpandResourceFlags_IncludeMainDicomTags) != 0) | |
2085 { | |
2086 // serialize tags | |
2087 | |
2088 static const char* const MAIN_DICOM_TAGS = "MainDicomTags"; | |
2089 static const char* const PATIENT_MAIN_DICOM_TAGS = "PatientMainDicomTags"; | |
2090 | |
2091 DicomMap mainDicomTags; | |
2092 resource.GetMainDicomTags().ExtractResourceInformation(mainDicomTags, resource.GetLevel()); | |
2093 | |
2094 target[MAIN_DICOM_TAGS] = Json::objectValue; | |
2095 FromDcmtkBridge::ToJson(target[MAIN_DICOM_TAGS], mainDicomTags, format); | |
2096 | |
2097 if (resource.GetLevel() == ResourceType_Study) | |
2098 { | |
2099 DicomMap patientMainDicomTags; | |
2100 resource.GetMainDicomTags().ExtractPatientInformation(patientMainDicomTags); | |
2101 | |
2102 target[PATIENT_MAIN_DICOM_TAGS] = Json::objectValue; | |
2103 FromDcmtkBridge::ToJson(target[PATIENT_MAIN_DICOM_TAGS], patientMainDicomTags, format); | |
2104 } | |
2105 | |
2106 if (requestedTags.size() > 0) | |
2107 { | |
2108 static const char* const REQUESTED_TAGS = "RequestedTags"; | |
2109 | |
2110 DicomMap tags; | |
2111 resource.GetMainDicomTags().ExtractTags(tags, requestedTags); | |
2112 | |
2113 target[REQUESTED_TAGS] = Json::objectValue; | |
2114 FromDcmtkBridge::ToJson(target[REQUESTED_TAGS], tags, format); | |
2115 | |
2116 } | |
2117 } | |
2118 | |
2119 if ((expandFlags & ExpandResourceFlags_IncludeLabels) != 0) | |
2120 { | |
2121 Json::Value labels = Json::arrayValue; | |
2122 | |
2123 for (std::set<std::string>::const_iterator it = resource.labels_.begin(); it != resource.labels_.end(); ++it) | |
2124 { | |
2125 labels.append(*it); | |
2126 } | |
2127 | |
2128 target["Labels"] = labels; | |
2129 } | |
2130 | |
2131 // new in Orthanc 1.12.4 | |
2132 if ((expandFlags & ExpandResourceFlags_IncludeAllMetadata) != 0) | |
2133 { | |
2134 Json::Value metadata = Json::objectValue; | |
2135 | |
2136 for (std::map<MetadataType, std::string>::const_iterator it = resource.metadata_.begin(); it != resource.metadata_.end(); ++it) | |
2137 { | |
2138 metadata[EnumerationToString(it->first)] = it->second; | |
2139 } | |
2140 | |
2141 target["Metadata"] = metadata; | |
2142 } | |
2143 } | |
2144 | |
2145 | |
2146 static void ComputeInstanceTags(ExpandedResource& resource, | |
2147 ServerContext& context, | |
2148 const std::string& instancePublicId, | |
2149 const std::set<DicomTag>& requestedTags) | |
2150 { | |
2151 if (requestedTags.count(DICOM_TAG_INSTANCE_AVAILABILITY) > 0) | |
2152 { | |
2153 resource.GetMainDicomTags().SetValue(DICOM_TAG_INSTANCE_AVAILABILITY, "ONLINE", false); | |
2154 resource.missingRequestedTags_.erase(DICOM_TAG_INSTANCE_AVAILABILITY); | |
2155 } | |
2156 } | |
2157 | |
2158 | |
2159 static void ComputeSeriesTags(ExpandedResource& resource, | |
2160 ServerContext& context, | |
2161 const std::string& seriesPublicId, | |
2162 const std::set<DicomTag>& requestedTags) | |
2163 { | |
2164 if (requestedTags.count(DICOM_TAG_NUMBER_OF_SERIES_RELATED_INSTANCES) > 0) | |
2165 { | |
2166 ServerIndex& index = context.GetIndex(); | |
2167 std::list<std::string> instances; | |
2168 | |
2169 index.GetChildren(instances, seriesPublicId); | |
2170 | |
2171 resource.GetMainDicomTags().SetValue(DICOM_TAG_NUMBER_OF_SERIES_RELATED_INSTANCES, | |
2172 boost::lexical_cast<std::string>(instances.size()), false); | |
2173 resource.missingRequestedTags_.erase(DICOM_TAG_NUMBER_OF_SERIES_RELATED_INSTANCES); | |
2174 } | |
2175 } | |
2176 | |
2177 static void ComputeStudyTags(ExpandedResource& resource, | |
2178 ServerContext& context, | |
2179 const std::string& studyPublicId, | |
2180 const std::set<DicomTag>& requestedTags) | |
2181 { | |
2182 ServerIndex& index = context.GetIndex(); | |
2183 std::list<std::string> series; | |
2184 std::list<std::string> instances; | |
2185 | |
2186 bool hasNbRelatedSeries = requestedTags.count(DICOM_TAG_NUMBER_OF_STUDY_RELATED_SERIES) > 0; | |
2187 bool hasNbRelatedInstances = requestedTags.count(DICOM_TAG_NUMBER_OF_STUDY_RELATED_INSTANCES) > 0; | |
2188 bool hasModalitiesInStudy = requestedTags.count(DICOM_TAG_MODALITIES_IN_STUDY) > 0; | |
2189 bool hasSopClassesInStudy = requestedTags.count(DICOM_TAG_SOP_CLASSES_IN_STUDY) > 0; | |
2190 | |
2191 index.GetChildren(series, studyPublicId); | |
2192 | |
2193 if (hasModalitiesInStudy) | |
2194 { | |
2195 std::set<std::string> values; | |
2196 | |
2197 for (std::list<std::string>::const_iterator | |
2198 it = series.begin(); it != series.end(); ++it) | |
2199 { | |
2200 DicomMap tags; | |
2201 index.GetMainDicomTags(tags, *it, ResourceType_Series, ResourceType_Series); | |
2202 | |
2203 const DicomValue* value = tags.TestAndGetValue(DICOM_TAG_MODALITY); | |
2204 | |
2205 if (value != NULL && | |
2206 !value->IsNull() && | |
2207 !value->IsBinary()) | |
2208 { | |
2209 values.insert(value->GetContent()); | |
2210 } | |
2211 } | |
2212 | |
2213 std::string modalities; | |
2214 Toolbox::JoinStrings(modalities, values, "\\"); | |
2215 | |
2216 resource.GetMainDicomTags().SetValue(DICOM_TAG_MODALITIES_IN_STUDY, modalities, false); | |
2217 resource.missingRequestedTags_.erase(DICOM_TAG_MODALITIES_IN_STUDY); | |
2218 } | |
2219 | |
2220 if (hasNbRelatedSeries) | |
2221 { | |
2222 resource.GetMainDicomTags().SetValue(DICOM_TAG_NUMBER_OF_STUDY_RELATED_SERIES, | |
2223 boost::lexical_cast<std::string>(series.size()), false); | |
2224 resource.missingRequestedTags_.erase(DICOM_TAG_NUMBER_OF_STUDY_RELATED_SERIES); | |
2225 } | |
2226 | |
2227 if (hasNbRelatedInstances || hasSopClassesInStudy) | |
2228 { | |
2229 for (std::list<std::string>::const_iterator | |
2230 it = series.begin(); it != series.end(); ++it) | |
2231 { | |
2232 std::list<std::string> seriesInstancesIds; | |
2233 index.GetChildren(seriesInstancesIds, *it); | |
2234 | |
2235 instances.splice(instances.end(), seriesInstancesIds); | |
2236 } | |
2237 | |
2238 if (hasNbRelatedInstances) | |
2239 { | |
2240 resource.GetMainDicomTags().SetValue(DICOM_TAG_NUMBER_OF_STUDY_RELATED_INSTANCES, | |
2241 boost::lexical_cast<std::string>(instances.size()), false); | |
2242 resource.missingRequestedTags_.erase(DICOM_TAG_NUMBER_OF_STUDY_RELATED_INSTANCES); | |
2243 } | |
2244 | |
2245 if (hasSopClassesInStudy) | |
2246 { | |
2247 std::set<std::string> values; | |
2248 | |
2249 for (std::list<std::string>::const_iterator | |
2250 it = instances.begin(); it != instances.end(); ++it) | |
2251 { | |
2252 std::string value; | |
2253 | |
2254 if (context.LookupOrReconstructMetadata(value, *it, ResourceType_Instance, MetadataType_Instance_SopClassUid)) | |
2255 { | |
2256 values.insert(value); | |
2257 } | |
2258 } | |
2259 | |
2260 if (values.size() > 0) | |
2261 { | |
2262 std::string sopClassUids; | |
2263 Toolbox::JoinStrings(sopClassUids, values, "\\"); | |
2264 resource.GetMainDicomTags().SetValue(DICOM_TAG_SOP_CLASSES_IN_STUDY, sopClassUids, false); | |
2265 } | |
2266 | |
2267 resource.missingRequestedTags_.erase(DICOM_TAG_SOP_CLASSES_IN_STUDY); | |
2268 } | |
2269 } | |
2270 } | |
2271 | |
2272 static void ComputePatientTags(ExpandedResource& resource, | |
2273 ServerContext& context, | |
2274 const std::string& patientPublicId, | |
2275 const std::set<DicomTag>& requestedTags) | |
2276 { | |
2277 ServerIndex& index = context.GetIndex(); | |
2278 | |
2279 std::list<std::string> studies; | |
2280 std::list<std::string> series; | |
2281 std::list<std::string> instances; | |
2282 | |
2283 bool hasNbRelatedStudies = requestedTags.count(DICOM_TAG_NUMBER_OF_PATIENT_RELATED_STUDIES) > 0; | |
2284 bool hasNbRelatedSeries = requestedTags.count(DICOM_TAG_NUMBER_OF_PATIENT_RELATED_SERIES) > 0; | |
2285 bool hasNbRelatedInstances = requestedTags.count(DICOM_TAG_NUMBER_OF_PATIENT_RELATED_INSTANCES) > 0; | |
2286 | |
2287 index.GetChildren(studies, patientPublicId); | |
2288 | |
2289 if (hasNbRelatedStudies) | |
2290 { | |
2291 resource.GetMainDicomTags().SetValue(DICOM_TAG_NUMBER_OF_PATIENT_RELATED_STUDIES, | |
2292 boost::lexical_cast<std::string>(studies.size()), false); | |
2293 resource.missingRequestedTags_.erase(DICOM_TAG_NUMBER_OF_PATIENT_RELATED_STUDIES); | |
2294 } | |
2295 | |
2296 if (hasNbRelatedSeries || hasNbRelatedInstances) | |
2297 { | |
2298 for (std::list<std::string>::const_iterator | |
2299 it = studies.begin(); it != studies.end(); ++it) | |
2300 { | |
2301 std::list<std::string> thisSeriesIds; | |
2302 index.GetChildren(thisSeriesIds, *it); | |
2303 series.splice(series.end(), thisSeriesIds); | |
2304 } | |
2305 | |
2306 if (hasNbRelatedSeries) | |
2307 { | |
2308 resource.GetMainDicomTags().SetValue(DICOM_TAG_NUMBER_OF_PATIENT_RELATED_SERIES, | |
2309 boost::lexical_cast<std::string>(series.size()), false); | |
2310 resource.missingRequestedTags_.erase(DICOM_TAG_NUMBER_OF_PATIENT_RELATED_SERIES); | |
2311 } | |
2312 } | |
2313 | |
2314 if (hasNbRelatedInstances) | |
2315 { | |
2316 for (std::list<std::string>::const_iterator | |
2317 it = series.begin(); it != series.end(); ++it) | |
2318 { | |
2319 std::list<std::string> thisInstancesIds; | |
2320 index.GetChildren(thisInstancesIds, *it); | |
2321 instances.splice(instances.end(), thisInstancesIds); | |
2322 } | |
2323 | |
2324 resource.GetMainDicomTags().SetValue(DICOM_TAG_NUMBER_OF_PATIENT_RELATED_INSTANCES, | |
2325 boost::lexical_cast<std::string>(instances.size()), false); | |
2326 resource.missingRequestedTags_.erase(DICOM_TAG_NUMBER_OF_PATIENT_RELATED_INSTANCES); | |
2327 } | |
2328 } | |
2329 | |
2330 | |
2331 static void ComputeTags(ExpandedResource& resource, | |
2332 ServerContext& context, | |
2333 const std::string& resourceId, | |
2334 ResourceType level, | |
2335 const std::set<DicomTag>& requestedTags) | |
2336 { | |
2337 if (level == ResourceType_Patient | |
2338 && DicomMap::HasComputedTags(resource.missingRequestedTags_, ResourceType_Patient)) | |
2339 { | |
2340 ComputePatientTags(resource, context, resourceId, requestedTags); | |
2341 } | |
2342 | |
2343 if (level == ResourceType_Study | |
2344 && DicomMap::HasComputedTags(resource.missingRequestedTags_, ResourceType_Study)) | |
2345 { | |
2346 ComputeStudyTags(resource, context, resourceId, requestedTags); | |
2347 } | |
2348 | |
2349 if (level == ResourceType_Series | |
2350 && DicomMap::HasComputedTags(resource.missingRequestedTags_, ResourceType_Series)) | |
2351 { | |
2352 ComputeSeriesTags(resource, context, resourceId, requestedTags); | |
2353 } | |
2354 | |
2355 if (level == ResourceType_Instance | |
2356 && DicomMap::HasComputedTags(resource.missingRequestedTags_, ResourceType_Instance)) | |
2357 { | |
2358 ComputeInstanceTags(resource, context, resourceId, requestedTags); | |
2359 } | |
2360 } | |
2361 | |
2362 bool ServerContext::ExpandResource(Json::Value& target, | |
2363 const std::string& publicId, | |
2364 ResourceType level, | |
2365 DicomToJsonFormat format, | |
2366 const std::set<DicomTag>& requestedTags, | |
2367 bool allowStorageAccess) | |
2368 { | |
2369 std::string unusedInstanceId; | |
2370 Json::Value* unusedDicomAsJson = NULL; | |
2371 DicomMap unusedMainDicomTags; | |
2372 | |
2373 return ExpandResource(target, publicId, unusedMainDicomTags, unusedInstanceId, unusedDicomAsJson, level, format, requestedTags, allowStorageAccess); | |
2374 } | |
2375 | |
2376 bool ServerContext::ExpandResource(Json::Value& target, | |
2377 const std::string& publicId, | |
2378 const DicomMap& mainDicomTags, // optional: the main dicom tags for the resource (if already available) | |
2379 const std::string& instanceId, // optional: the id of an instance for the resource (if already available) | |
2380 const Json::Value* dicomAsJson, // optional: the dicom-as-json for the resource (if already available) | |
2381 ResourceType level, | |
2382 DicomToJsonFormat format, | |
2383 const std::set<DicomTag>& requestedTags, | |
2384 bool allowStorageAccess) | |
2385 { | |
2386 ExpandedResource resource; | |
2387 | |
2388 if (ExpandResource(resource, publicId, mainDicomTags, instanceId, dicomAsJson, level, requestedTags, ExpandResourceFlags_DefaultExtract, allowStorageAccess)) | |
2389 { | |
2390 SerializeExpandedResource(target, resource, format, requestedTags, ExpandResourceFlags_DefaultOutput); | |
2391 return true; | |
2392 } | |
2393 | |
2394 return false; | |
2395 } | |
2396 | |
2397 bool ServerContext::ExpandResource(ExpandedResource& resource, | |
2398 const std::string& publicId, | |
2399 const DicomMap& mainDicomTags, // optional: the main dicom tags for the resource (if already available) | |
2400 const std::string& instanceId, // optional: the id of an instance for the resource (if already available) | |
2401 const Json::Value* dicomAsJson, // optional: the dicom-as-json for the resource (if already available) | |
2402 ResourceType level, | |
2403 const std::set<DicomTag>& requestedTags, | |
2404 ExpandResourceFlags expandFlags, | |
2405 bool allowStorageAccess) | |
2406 { | |
2407 // first try to get the tags from what is already available | |
2408 | |
2409 if ((expandFlags & ExpandResourceFlags_IncludeMainDicomTags) && | |
2410 mainDicomTags.GetSize() > 0 && | |
2411 dicomAsJson != NULL) | |
2412 { | |
2413 | |
2414 resource.GetMainDicomTags().Merge(mainDicomTags); | |
2415 | |
2416 if (dicomAsJson->isObject()) | |
2417 { | |
2418 resource.GetMainDicomTags().FromDicomAsJson(*dicomAsJson); | |
2419 } | |
2420 | |
2421 std::set<DicomTag> retrievedTags; | |
2422 std::set<DicomTag> missingTags; | |
2423 resource.GetMainDicomTags().GetTags(retrievedTags); | |
2424 | |
2425 Toolbox::GetMissingsFromSet(missingTags, requestedTags, retrievedTags); | |
2426 | |
2427 // if all possible tags have been read, no need to get them from DB anymore | |
2428 if (missingTags.size() > 0 && DicomMap::HasOnlyComputedTags(missingTags)) | |
2429 { | |
2430 resource.missingRequestedTags_ = missingTags; | |
2431 ComputeTags(resource, *this, publicId, level, requestedTags); | |
2432 return true; | |
2433 } | |
2434 else if (missingTags.size() == 0) | |
2435 { | |
2436 expandFlags = static_cast<ExpandResourceFlags>(expandFlags & ~ExpandResourceFlags_IncludeMainDicomTags); | |
2437 } | |
2438 | |
2439 if (missingTags.size() == 0 && expandFlags == ExpandResourceFlags_None) // we have already retrieved anything we need | |
2440 { | |
2441 return true; | |
2442 } | |
2443 } | |
2444 | |
2445 if (expandFlags != ExpandResourceFlags_None && | |
2446 GetIndex().ExpandResource(resource, publicId, level, requestedTags, | |
2447 static_cast<ExpandResourceFlags>(expandFlags | ExpandResourceFlags_IncludeMetadata))) // we always need the metadata to get the mainDicomTagsSignature | |
2448 { | |
2449 // check the main dicom tags list has not changed since the resource was stored | |
2450 if (resource.mainDicomTagsSignature_ != DicomMap::GetMainDicomTagsSignature(resource.GetLevel())) | |
2451 { | |
2452 OrthancConfiguration::ReaderLock lock; | |
2453 if (lock.GetConfiguration().IsWarningEnabled(Warnings_002_InconsistentDicomTagsInDb)) | |
2454 { | |
2455 LOG(WARNING) << "W002: " << Orthanc::GetResourceTypeText(resource.GetLevel(), false , false) | |
2456 << " has been stored with another version of Main Dicom Tags list, you should POST to /" | |
2457 << Orthanc::GetResourceTypeText(resource.GetLevel(), true, false) | |
2458 << "/" << resource.GetPublicId() | |
2459 << "/reconstruct to update the list of tags saved in DB. Some MainDicomTags might be missing from this answer."; | |
2460 } | |
2461 } | |
2462 | |
2463 // possibly merge missing requested tags from dicom-as-json | |
2464 if (allowStorageAccess && | |
2465 !resource.missingRequestedTags_.empty() && | |
2466 !DicomMap::HasOnlyComputedTags(resource.missingRequestedTags_)) | |
2467 { | |
2468 OrthancConfiguration::ReaderLock lock; | |
2469 if (lock.GetConfiguration().IsWarningEnabled(Warnings_001_TagsBeingReadFromStorage)) | |
2470 { | |
2471 std::set<DicomTag> missingTags; | |
2472 Toolbox::AppendSets(missingTags, resource.missingRequestedTags_); | |
2473 for (std::set<DicomTag>::const_iterator it = resource.missingRequestedTags_.begin(); it != resource.missingRequestedTags_.end(); ++it) | |
2474 { | |
2475 if (DicomMap::IsComputedTag(*it)) | |
2476 { | |
2477 missingTags.erase(*it); | |
2478 } | |
2479 } | |
2480 | |
2481 std::string missings; | |
2482 FromDcmtkBridge::FormatListOfTags(missings, missingTags); | |
2483 | |
2484 LOG(WARNING) << "W001: Accessing Dicom tags from storage when accessing " | |
2485 << Orthanc::GetResourceTypeText(resource.GetLevel(), false, false) | |
2486 << " : " << missings; | |
2487 } | |
2488 | |
2489 | |
2490 std::string instanceId_ = instanceId; | |
2491 DicomMap tagsFromJson; | |
2492 | |
2493 if (dicomAsJson == NULL) | |
2494 { | |
2495 if (instanceId_.empty()) | |
2496 { | |
2497 if (level == ResourceType_Instance) | |
2498 { | |
2499 instanceId_ = publicId; | |
2500 } | |
2501 else | |
2502 { | |
2503 std::list<std::string> instancesIds; | |
2504 GetIndex().GetChildInstances(instancesIds, publicId); | |
2505 if (instancesIds.size() < 1) | |
2506 { | |
2507 throw OrthancException(ErrorCode_InternalError, "ExpandResource: no instances found"); | |
2508 } | |
2509 instanceId_ = instancesIds.front(); | |
2510 } | |
2511 } | |
2512 | |
2513 Json::Value tmpDicomAsJson; | |
2514 ReadDicomAsJson(tmpDicomAsJson, instanceId_, resource.missingRequestedTags_ /* ignoreTagLength */); // read all tags from DICOM and avoid cropping requested tags | |
2515 tagsFromJson.FromDicomAsJson(tmpDicomAsJson, false /* append */, true /* parseSequences*/); | |
2516 } | |
2517 else | |
2518 { | |
2519 tagsFromJson.FromDicomAsJson(*dicomAsJson, false /* append */, true /* parseSequences*/); | |
2520 } | |
2521 | |
2522 resource.GetMainDicomTags().Merge(tagsFromJson); | |
2523 } | |
2524 | |
2525 // compute the requested tags | |
2526 ComputeTags(resource, *this, publicId, level, requestedTags); | |
2527 } | |
2528 else | |
2529 { | |
2530 return false; | |
2531 } | |
2532 | |
2533 return true; | |
2534 } | |
2535 | |
2536 int64_t ServerContext::GetServerUpTime() const | 1936 int64_t ServerContext::GetServerUpTime() const |
2537 { | 1937 { |
2538 boost::posix_time::ptime nowUtc = boost::posix_time::second_clock::universal_time(); | 1938 boost::posix_time::ptime nowUtc = boost::posix_time::second_clock::universal_time(); |
2539 boost::posix_time::time_duration elapsed = nowUtc - serverStartTimeUtc_; | 1939 boost::posix_time::time_duration elapsed = nowUtc - serverStartTimeUtc_; |
2540 | 1940 |