comparison Framework/Loaders/DicomStructureSetLoader.cpp @ 981:c20dbaab360c

Ability to cope with empty "Referenced SOP Instance UID" (dicom path (3006,0039)[i] / (0x3006, 0x0040)[0] / (0x3006, 0x0016)[0] / (0x0008, 0x1155)) + better logs + code formating
author Benjamin Golinvaux <bgo@osimis.io>
date Fri, 06 Sep 2019 09:38:18 +0200
parents 262a0244e9b2
children 50e5acf5553b
comparison
equal deleted inserted replaced
978:0e21ecafcc23 981:c20dbaab360c
62 { 62 {
63 } 63 }
64 64
65 virtual void Handle(const OrthancRestApiCommand::SuccessMessage& message) 65 virtual void Handle(const OrthancRestApiCommand::SuccessMessage& message)
66 { 66 {
67 #if 0
68 if (logbgo115)
69 LOG(TRACE) << "DicomStructureSetLoader::AddReferencedInstance::Handle() (SUCCESS)";
70 #endif
71 Json::Value tags; 67 Json::Value tags;
72 message.ParseJsonBody(tags); 68 message.ParseJsonBody(tags);
73 69
74 Orthanc::DicomMap dicom; 70 Orthanc::DicomMap dicom;
75 dicom.FromDicomAsJson(tags); 71 dicom.FromDicomAsJson(tags);
76 72
77 DicomStructureSetLoader& loader = GetLoader<DicomStructureSetLoader>(); 73 DicomStructureSetLoader& loader = GetLoader<DicomStructureSetLoader>();
78
79 #if 0
80 {
81 std::stringstream ss;
82 //DumpDicomMap(ss, dicom);
83 std::string dicomMapStr = ss.str();
84 if (logbgo115)
85 LOG(TRACE) << " DicomStructureSetLoader::AddReferencedInstance::Handle() about to call AddReferencedSlice on dicom = " << dicomMapStr;
86 }
87 #endif
88
89 74
90 loader.content_->AddReferencedSlice(dicom); 75 loader.content_->AddReferencedSlice(dicom);
91 76
92 loader.countProcessedInstances_ ++; 77 loader.countProcessedInstances_ ++;
93 assert(loader.countProcessedInstances_ <= loader.countReferencedInstances_); 78 assert(loader.countProcessedInstances_ <= loader.countReferencedInstances_);
148 } 133 }
149 134
150 const std::string instanceId = lookup[0]["ID"].asString(); 135 const std::string instanceId = lookup[0]["ID"].asString();
151 136
152 { 137 {
153 #if 0
154 if(logbgo115)
155 LOG(TRACE) << "DicomStructureSetLoader::LookupInstance::Handle() (SUCCESS)";
156 #endif
157 std::auto_ptr<OrthancRestApiCommand> command(new OrthancRestApiCommand); 138 std::auto_ptr<OrthancRestApiCommand> command(new OrthancRestApiCommand);
158 command->SetHttpHeader("Accept-Encoding", "gzip"); 139 command->SetHttpHeader("Accept-Encoding", "gzip");
159 std::string uri = "/instances/" + instanceId + "/tags"; 140 std::string uri = "/instances/" + instanceId + "/tags";
160 command->SetUri(uri); 141 command->SetUri(uri);
161 command->SetPayload(new AddReferencedInstance(loader, instanceId)); 142 command->SetPayload(new AddReferencedInstance(loader, instanceId));
162 #if 0
163 if (logbgo115)
164 LOG(TRACE) << " DicomStructureSetLoader::LookupInstance::Handle() about to schedule request with AddReferencedInstance subsequent command on uri \"" << uri << "\"";
165 #endif
166 Schedule(command.release()); 143 Schedule(command.release());
167 #if 0
168 if (logbgo115)
169 LOG(TRACE) << " DicomStructureSetLoader::LookupInstance::Handle() request+command scheduled";
170 #endif
171 } 144 }
172 } 145 }
173 }; 146 };
174 147
175 148
193 { 166 {
194 OrthancPlugins::FullOrthancDataset dicom(message.GetAnswer()); 167 OrthancPlugins::FullOrthancDataset dicom(message.GetAnswer());
195 loader.content_.reset(new DicomStructureSet(dicom)); 168 loader.content_.reset(new DicomStructureSet(dicom));
196 } 169 }
197 170
171 // Some (admittedly invalid) Dicom files have empty values in the
172 // 0008,1155 tag. We try our best to cope with this.
198 std::set<std::string> instances; 173 std::set<std::string> instances;
174 std::set<std::string> nonEmptyInstances;
199 loader.content_->GetReferencedInstances(instances); 175 loader.content_->GetReferencedInstances(instances);
200
201 loader.countReferencedInstances_ = static_cast<unsigned int>(instances.size());
202
203 for (std::set<std::string>::const_iterator 176 for (std::set<std::string>::const_iterator
204 it = instances.begin(); it != instances.end(); ++it) 177 it = instances.begin(); it != instances.end(); ++it)
178 {
179 std::string instance = Orthanc::Toolbox::StripSpaces(*it);
180 if(instance != "")
181 nonEmptyInstances.insert(instance);
182 }
183
184 loader.countReferencedInstances_ =
185 static_cast<unsigned int>(nonEmptyInstances.size());
186
187 for (std::set<std::string>::const_iterator
188 it = nonEmptyInstances.begin(); it != nonEmptyInstances.end(); ++it)
205 { 189 {
206 std::auto_ptr<OrthancRestApiCommand> command(new OrthancRestApiCommand); 190 std::auto_ptr<OrthancRestApiCommand> command(new OrthancRestApiCommand);
207 command->SetUri("/tools/lookup"); 191 command->SetUri("/tools/lookup");
208 command->SetMethod(Orthanc::HttpMethod_Post); 192 command->SetMethod(Orthanc::HttpMethod_Post);
209 command->SetBody(*it); 193 command->SetBody(*it);
210
211 // The following headers have been commented out because
212 // they were causing issues in the reverse proxy in a dev scenario.
213 // They should NOT be required for POST requests
214 //command->SetHttpHeader("pragma", "no-cache");
215 //command->SetHttpHeader("cache-control", "no-cache");
216
217 command->SetPayload(new LookupInstance(loader, *it)); 194 command->SetPayload(new LookupInstance(loader, *it));
218 //LOG(TRACE) << "About to schedule a /tools/lookup POST request. URI = " << command->GetUri() << " Body size = " << (*it).size() << " Body = " << (*it) << "\n";
219 Schedule(command.release()); 195 Schedule(command.release());
220 } 196 }
221 } 197 }
222 }; 198 };
223 199
265 241
266 for (size_t i = 0; i < content_.GetStructuresCount(); i++) 242 for (size_t i = 0; i < content_.GetStructuresCount(); i++)
267 { 243 {
268 const Color& color = content_.GetStructureColor(i); 244 const Color& color = content_.GetStructureColor(i);
269 245
270 std::vector< std::vector<DicomStructureSet::PolygonPoint> > polygons; 246 std::vector< std::vector<DicomStructureSet::PolygonPoint2D> > polygons;
271 247
272 if (content_.ProjectStructure(polygons, i, cuttingPlane)) 248 if (content_.ProjectStructure(polygons, i, cuttingPlane))
273 { 249 {
274 for (size_t j = 0; j < polygons.size(); j++) 250 for (size_t j = 0; j < polygons.size(); j++)
275 { 251 {
317 { 293 {
318 std::auto_ptr<OrthancRestApiCommand> command(new OrthancRestApiCommand); 294 std::auto_ptr<OrthancRestApiCommand> command(new OrthancRestApiCommand);
319 command->SetHttpHeader("Accept-Encoding", "gzip"); 295 command->SetHttpHeader("Accept-Encoding", "gzip");
320 296
321 std::string uri = "/instances/" + instanceId + "/tags?ignore-length=3006-0050"; 297 std::string uri = "/instances/" + instanceId + "/tags?ignore-length=3006-0050";
322 #if 0 298
323 if (logbgo115)
324 LOG(TRACE) << "DicomStructureSetLoader::LoadInstance() instanceId = " << instanceId << " | uri = \"" << uri << "\"";
325 #endif
326 command->SetUri(uri); 299 command->SetUri(uri);
327 command->SetPayload(new LoadStructure(*this)); 300 command->SetPayload(new LoadStructure(*this));
328 Schedule(command.release()); 301 Schedule(command.release());
329 #if 0
330 if (logbgo115)
331 LOG(TRACE) << "DicomStructureSetLoader::LoadInstance() command (with LoadStructure) scheduled.";
332 #endif
333 } 302 }
334 } 303 }
335 304
336 305
337 IVolumeSlicer::IExtractedSlice* DicomStructureSetLoader::ExtractSlice(const CoordinateSystem3D& cuttingPlane) 306 IVolumeSlicer::IExtractedSlice* DicomStructureSetLoader::ExtractSlice(const CoordinateSystem3D& cuttingPlane)