comparison OrthancServer/ServerToolbox.cpp @ 3083:683d572424b6 db-changes

IDatabaseWrapper::SetResourcesContent
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 04 Jan 2019 15:52:19 +0100
parents ce272138f15e
children c829758b9ca0
comparison
equal deleted inserted replaced
3082:847a0ed92654 3083:683d572424b6
33 33
34 #include "PrecompiledHeadersServer.h" 34 #include "PrecompiledHeadersServer.h"
35 #include "ServerToolbox.h" 35 #include "ServerToolbox.h"
36 36
37 #include "../Core/DicomFormat/DicomArray.h" 37 #include "../Core/DicomFormat/DicomArray.h"
38 #include "../Core/DicomParsing/ParsedDicomFile.h"
38 #include "../Core/FileStorage/StorageAccessor.h" 39 #include "../Core/FileStorage/StorageAccessor.h"
39 #include "../Core/Logging.h" 40 #include "../Core/Logging.h"
40 #include "../Core/OrthancException.h" 41 #include "../Core/OrthancException.h"
42 #include "IDatabaseWrapper.h"
43 #include "ServerContext.h"
41 44
42 #include <cassert> 45 #include <cassert>
43 46
44 namespace Orthanc 47 namespace Orthanc
45 { 48 {
49 static const DicomTag PATIENT_IDENTIFIERS[] =
50 {
51 DICOM_TAG_PATIENT_ID,
52 DICOM_TAG_PATIENT_NAME,
53 DICOM_TAG_PATIENT_BIRTH_DATE
54 };
55
56 static const DicomTag STUDY_IDENTIFIERS[] =
57 {
58 DICOM_TAG_PATIENT_ID,
59 DICOM_TAG_PATIENT_NAME,
60 DICOM_TAG_PATIENT_BIRTH_DATE,
61 DICOM_TAG_STUDY_INSTANCE_UID,
62 DICOM_TAG_ACCESSION_NUMBER,
63 DICOM_TAG_STUDY_DESCRIPTION,
64 DICOM_TAG_STUDY_DATE
65 };
66
67 static const DicomTag SERIES_IDENTIFIERS[] =
68 {
69 DICOM_TAG_SERIES_INSTANCE_UID
70 };
71
72 static const DicomTag INSTANCE_IDENTIFIERS[] =
73 {
74 DICOM_TAG_SOP_INSTANCE_UID
75 };
76
77
78 void ResourcesContent::Store(Compatibility::ISetResourcesContent& compatibility) const
79 {
80 for (std::list<TagValue>::const_iterator
81 it = tags_.begin(); it != tags_.end(); ++it)
82 {
83 if (it->isIdentifier_)
84 {
85 compatibility.SetIdentifierTag(it->resourceId_, it->tag_, it->value_);
86 }
87 else
88 {
89 compatibility.SetMainDicomTag(it->resourceId_, it->tag_, it->value_);
90 }
91 }
92
93 for (std::list<Metadata>::const_iterator
94 it = metadata_.begin(); it != metadata_.end(); ++it)
95 {
96 compatibility.SetMetadata(it->resourceId_, it->metadata_, it->value_);
97 }
98 }
99
100
101 static void StoreMainDicomTagsInternal(ResourcesContent& target,
102 int64_t resource,
103 const DicomMap& tags)
104 {
105 DicomArray flattened(tags);
106
107 for (size_t i = 0; i < flattened.GetSize(); i++)
108 {
109 const DicomElement& element = flattened.GetElement(i);
110 const DicomTag& tag = element.GetTag();
111 const DicomValue& value = element.GetValue();
112 if (!value.IsNull() &&
113 !value.IsBinary())
114 {
115 target.AddMainDicomTag(resource, tag, element.GetValue().GetContent());
116 }
117 }
118 }
119
120
121 static void StoreIdentifiers(ResourcesContent& target,
122 int64_t resource,
123 ResourceType level,
124 const DicomMap& map)
125 {
126 const DicomTag* tags;
127 size_t size;
128
129 ServerToolbox::LoadIdentifiers(tags, size, level);
130
131 for (size_t i = 0; i < size; i++)
132 {
133 // The identifiers tags are a subset of the main DICOM tags
134 assert(DicomMap::IsMainDicomTag(tags[i]));
135
136 const DicomValue* value = map.TestAndGetValue(tags[i]);
137 if (value != NULL &&
138 !value->IsNull() &&
139 !value->IsBinary())
140 {
141 std::string s = ServerToolbox::NormalizeIdentifier(value->GetContent());
142 target.AddIdentifierTag(resource, tags[i], s);
143 }
144 }
145 }
146
147
148 void ResourcesContent::AddResource(int64_t resource,
149 ResourceType level,
150 const DicomMap& dicomSummary)
151 {
152 StoreIdentifiers(*this, resource, level, dicomSummary);
153
154 DicomMap tags;
155
156 switch (level)
157 {
158 case ResourceType_Patient:
159 dicomSummary.ExtractPatientInformation(tags);
160 break;
161
162 case ResourceType_Study:
163 // Duplicate the patient tags at the study level (new in Orthanc 0.9.5 - db v6)
164 dicomSummary.ExtractPatientInformation(tags);
165 StoreMainDicomTagsInternal(*this, resource, tags);
166
167 dicomSummary.ExtractStudyInformation(tags);
168 break;
169
170 case ResourceType_Series:
171 dicomSummary.ExtractSeriesInformation(tags);
172 break;
173
174 case ResourceType_Instance:
175 dicomSummary.ExtractInstanceInformation(tags);
176 break;
177
178 default:
179 throw OrthancException(ErrorCode_InternalError);
180 }
181
182 StoreMainDicomTagsInternal(*this, resource, tags);
183 }
184
185
46 namespace ServerToolbox 186 namespace ServerToolbox
47 { 187 {
48 static const DicomTag patientIdentifiers[] =
49 {
50 DICOM_TAG_PATIENT_ID,
51 DICOM_TAG_PATIENT_NAME,
52 DICOM_TAG_PATIENT_BIRTH_DATE
53 };
54
55 static const DicomTag studyIdentifiers[] =
56 {
57 DICOM_TAG_PATIENT_ID,
58 DICOM_TAG_PATIENT_NAME,
59 DICOM_TAG_PATIENT_BIRTH_DATE,
60 DICOM_TAG_STUDY_INSTANCE_UID,
61 DICOM_TAG_ACCESSION_NUMBER,
62 DICOM_TAG_STUDY_DESCRIPTION,
63 DICOM_TAG_STUDY_DATE
64 };
65
66 static const DicomTag seriesIdentifiers[] =
67 {
68 DICOM_TAG_SERIES_INSTANCE_UID
69 };
70
71 static const DicomTag instanceIdentifiers[] =
72 {
73 DICOM_TAG_SOP_INSTANCE_UID
74 };
75
76
77 void SimplifyTags(Json::Value& target, 188 void SimplifyTags(Json::Value& target,
78 const Json::Value& source, 189 const Json::Value& source,
79 DicomToJsonFormat format) 190 DicomToJsonFormat format)
80 { 191 {
81 if (!source.isObject()) 192 if (!source.isObject())
136 } 247 }
137 } 248 }
138 } 249 }
139 250
140 251
141 static void StoreMainDicomTagsInternal(IDatabaseWrapper& database,
142 int64_t resource,
143 const DicomMap& tags)
144 {
145 DicomArray flattened(tags);
146
147 for (size_t i = 0; i < flattened.GetSize(); i++)
148 {
149 const DicomElement& element = flattened.GetElement(i);
150 const DicomTag& tag = element.GetTag();
151 const DicomValue& value = element.GetValue();
152 if (!value.IsNull() &&
153 !value.IsBinary())
154 {
155 database.SetMainDicomTag(resource, tag, element.GetValue().GetContent());
156 }
157 }
158 }
159
160
161 static void StoreIdentifiers(IDatabaseWrapper& database,
162 int64_t resource,
163 ResourceType level,
164 const DicomMap& map)
165 {
166 const DicomTag* tags;
167 size_t size;
168
169 LoadIdentifiers(tags, size, level);
170
171 for (size_t i = 0; i < size; i++)
172 {
173 // The identifiers tags are a subset of the main DICOM tags
174 assert(DicomMap::IsMainDicomTag(tags[i]));
175
176 const DicomValue* value = map.TestAndGetValue(tags[i]);
177 if (value != NULL &&
178 !value->IsNull() &&
179 !value->IsBinary())
180 {
181 std::string s = NormalizeIdentifier(value->GetContent());
182 database.SetIdentifierTag(resource, tags[i], s);
183 }
184 }
185 }
186
187
188 void StoreMainDicomTags(IDatabaseWrapper& database,
189 int64_t resource,
190 ResourceType level,
191 const DicomMap& dicomSummary)
192 {
193 // WARNING: The database should be locked with a transaction!
194
195 StoreIdentifiers(database, resource, level, dicomSummary);
196
197 DicomMap tags;
198
199 switch (level)
200 {
201 case ResourceType_Patient:
202 dicomSummary.ExtractPatientInformation(tags);
203 break;
204
205 case ResourceType_Study:
206 // Duplicate the patient tags at the study level (new in Orthanc 0.9.5 - db v6)
207 dicomSummary.ExtractPatientInformation(tags);
208 StoreMainDicomTagsInternal(database, resource, tags);
209
210 dicomSummary.ExtractStudyInformation(tags);
211 break;
212
213 case ResourceType_Series:
214 dicomSummary.ExtractSeriesInformation(tags);
215 break;
216
217 case ResourceType_Instance:
218 dicomSummary.ExtractInstanceInformation(tags);
219 break;
220
221 default:
222 throw OrthancException(ErrorCode_InternalError);
223 }
224
225 StoreMainDicomTagsInternal(database, resource, tags);
226 }
227
228
229 bool FindOneChildInstance(int64_t& result, 252 bool FindOneChildInstance(int64_t& result,
230 IDatabaseWrapper& database, 253 IDatabaseWrapper& database,
231 int64_t resource, 254 int64_t resource,
232 ResourceType type) 255 ResourceType type)
233 { 256 {
333 // Update the tags of this resource 356 // Update the tags of this resource
334 DicomMap dicomSummary; 357 DicomMap dicomSummary;
335 dicom.ExtractDicomSummary(dicomSummary); 358 dicom.ExtractDicomSummary(dicomSummary);
336 359
337 database.ClearMainDicomTags(resource); 360 database.ClearMainDicomTags(resource);
338 StoreMainDicomTags(database, resource, level, dicomSummary); 361
362 ResourcesContent tags;
363 tags.AddResource(resource, level, dicomSummary);
364 database.SetResourcesContent(tags);
339 } 365 }
340 catch (OrthancException&) 366 catch (OrthancException&)
341 { 367 {
342 LOG(ERROR) << "Cannot decode the DICOM file with UUID " << attachment.GetUuid() 368 LOG(ERROR) << "Cannot decode the DICOM file with UUID " << attachment.GetUuid()
343 << " associated with instance " << database.GetPublicId(instance); 369 << " associated with instance " << database.GetPublicId(instance);
352 ResourceType level) 378 ResourceType level)
353 { 379 {
354 switch (level) 380 switch (level)
355 { 381 {
356 case ResourceType_Patient: 382 case ResourceType_Patient:
357 tags = patientIdentifiers; 383 tags = PATIENT_IDENTIFIERS;
358 size = sizeof(patientIdentifiers) / sizeof(DicomTag); 384 size = sizeof(PATIENT_IDENTIFIERS) / sizeof(DicomTag);
359 break; 385 break;
360 386
361 case ResourceType_Study: 387 case ResourceType_Study:
362 tags = studyIdentifiers; 388 tags = STUDY_IDENTIFIERS;
363 size = sizeof(studyIdentifiers) / sizeof(DicomTag); 389 size = sizeof(STUDY_IDENTIFIERS) / sizeof(DicomTag);
364 break; 390 break;
365 391
366 case ResourceType_Series: 392 case ResourceType_Series:
367 tags = seriesIdentifiers; 393 tags = SERIES_IDENTIFIERS;
368 size = sizeof(seriesIdentifiers) / sizeof(DicomTag); 394 size = sizeof(SERIES_IDENTIFIERS) / sizeof(DicomTag);
369 break; 395 break;
370 396
371 case ResourceType_Instance: 397 case ResourceType_Instance:
372 tags = instanceIdentifiers; 398 tags = INSTANCE_IDENTIFIERS;
373 size = sizeof(instanceIdentifiers) / sizeof(DicomTag); 399 size = sizeof(INSTANCE_IDENTIFIERS) / sizeof(DicomTag);
374 break; 400 break;
375 401
376 default: 402 default:
377 throw OrthancException(ErrorCode_ParameterOutOfRange); 403 throw OrthancException(ErrorCode_ParameterOutOfRange);
378 } 404 }