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