comparison OrthancServer/ServerJobs/SplitStudyJob.cpp @ 3941:771dbd9eb3bd transcoding

class CleaningInstancesJob to share cleaning code by merge/split jobs
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 18 May 2020 18:20:19 +0200
parents 3661e2a72482
children
comparison
equal deleted inserted replaced
3940:3661e2a72482 3941:771dbd9eb3bd
79 79
80 std::unique_ptr<ParsedDicomFile> modified; 80 std::unique_ptr<ParsedDicomFile> modified;
81 81
82 try 82 try
83 { 83 {
84 ServerContext::DicomCacheLocker locker(context_, instance); 84 ServerContext::DicomCacheLocker locker(GetContext(), instance);
85 modified.reset(locker.GetDicom().Clone(true)); 85 modified.reset(locker.GetDicom().Clone(true));
86 } 86 }
87 catch (OrthancException&) 87 catch (OrthancException&)
88 { 88 {
89 LOG(WARNING) << "An instance was removed after the job was issued: " << instance; 89 LOG(WARNING) << "An instance was removed after the job was issued: " << instance;
142 DicomInstanceToStore toStore; 142 DicomInstanceToStore toStore;
143 toStore.SetOrigin(origin_); 143 toStore.SetOrigin(origin_);
144 toStore.SetParsedDicomFile(*modified); 144 toStore.SetParsedDicomFile(*modified);
145 145
146 std::string modifiedInstance; 146 std::string modifiedInstance;
147 if (context_.Store(modifiedInstance, toStore, 147 if (GetContext().Store(modifiedInstance, toStore,
148 StoreInstanceMode_Default) != StoreStatus_Success) 148 StoreInstanceMode_Default) != StoreStatus_Success)
149 { 149 {
150 LOG(ERROR) << "Error while storing a modified instance " << instance; 150 LOG(ERROR) << "Error while storing a modified instance " << instance;
151 return false; 151 return false;
152 }
153
154 return true;
155 }
156
157
158 bool SplitStudyJob::HandleTrailingStep()
159 {
160 if (!keepSource_)
161 {
162 const size_t n = GetInstancesCount();
163
164 for (size_t i = 0; i < n; i++)
165 {
166 Json::Value tmp;
167 context_.DeleteResource(tmp, GetInstance(i), ResourceType_Instance);
168 }
169 } 152 }
170 153
171 return true; 154 return true;
172 } 155 }
173 156
174 157
175 SplitStudyJob::SplitStudyJob(ServerContext& context, 158 SplitStudyJob::SplitStudyJob(ServerContext& context,
176 const std::string& sourceStudy) : 159 const std::string& sourceStudy) :
177 context_(context), 160 CleaningInstancesJob(context, false /* by default, remove source instances */),
178 keepSource_(false),
179 sourceStudy_(sourceStudy), 161 sourceStudy_(sourceStudy),
180 targetStudyUid_(FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Study)) 162 targetStudyUid_(FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Study))
181 { 163 {
182 Setup(); 164 Setup();
183 165
184 ResourceType type; 166 ResourceType type;
185 167
186 if (!context_.GetIndex().LookupResourceType(type, sourceStudy) || 168 if (!GetContext().GetIndex().LookupResourceType(type, sourceStudy) ||
187 type != ResourceType_Study) 169 type != ResourceType_Study)
188 { 170 {
189 throw OrthancException(ErrorCode_UnknownResource, 171 throw OrthancException(ErrorCode_UnknownResource,
190 "Cannot split unknown study " + sourceStudy); 172 "Cannot split unknown study " + sourceStudy);
191 } 173 }
217 199
218 if (IsStarted()) 200 if (IsStarted())
219 { 201 {
220 throw OrthancException(ErrorCode_BadSequenceOfCalls); 202 throw OrthancException(ErrorCode_BadSequenceOfCalls);
221 } 203 }
222 else if (!context_.GetIndex().LookupParent(parent, series, ResourceType_Study) || 204 else if (!GetContext().GetIndex().LookupParent(parent, series, ResourceType_Study) ||
223 parent != sourceStudy_) 205 parent != sourceStudy_)
224 { 206 {
225 throw OrthancException(ErrorCode_UnknownResource, 207 throw OrthancException(ErrorCode_UnknownResource,
226 "This series does not belong to the study to be split: " + series); 208 "This series does not belong to the study to be split: " + series);
227 } 209 }
230 // Generate a target SeriesInstanceUID for this series 212 // Generate a target SeriesInstanceUID for this series
231 seriesUidMap_[series] = FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Series); 213 seriesUidMap_[series] = FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Series);
232 214
233 // Add all the instances of the series as to be processed 215 // Add all the instances of the series as to be processed
234 std::list<std::string> instances; 216 std::list<std::string> instances;
235 context_.GetIndex().GetChildren(instances, series); 217 GetContext().GetIndex().GetChildren(instances, series);
236 218
237 for (std::list<std::string>::const_iterator 219 for (std::list<std::string>::const_iterator
238 it = instances.begin(); it != instances.end(); ++it) 220 it = instances.begin(); it != instances.end(); ++it)
239 { 221 {
240 AddInstance(*it); 222 AddInstance(*it);
241 } 223 }
242 } 224 }
243 } 225 }
244 226
245 227
246 void SplitStudyJob::SetKeepSource(bool keep)
247 {
248 if (IsStarted())
249 {
250 throw OrthancException(ErrorCode_BadSequenceOfCalls);
251 }
252
253 keepSource_ = keep;
254 }
255
256
257 bool SplitStudyJob::LookupTargetSeriesUid(std::string& uid, 228 bool SplitStudyJob::LookupTargetSeriesUid(std::string& uid,
258 const std::string& series) const 229 const std::string& series) const
259 { 230 {
260 SeriesUidMap::const_iterator found = seriesUidMap_.find(series); 231 SeriesUidMap::const_iterator found = seriesUidMap_.find(series);
261 232
313 } 284 }
314 285
315 286
316 void SplitStudyJob::GetPublicContent(Json::Value& value) 287 void SplitStudyJob::GetPublicContent(Json::Value& value)
317 { 288 {
318 SetOfInstancesJob::GetPublicContent(value); 289 CleaningInstancesJob::GetPublicContent(value);
319 290
320 if (!targetStudy_.empty()) 291 if (!targetStudy_.empty())
321 { 292 {
322 value["TargetStudy"] = targetStudy_; 293 value["TargetStudy"] = targetStudy_;
323 } 294 }
324 295
325 value["TargetStudyUID"] = targetStudyUid_; 296 value["TargetStudyUID"] = targetStudyUid_;
326 } 297 }
327 298
328 299
329 static const char* KEEP_SOURCE = "KeepSource";
330 static const char* SOURCE_STUDY = "SourceStudy"; 300 static const char* SOURCE_STUDY = "SourceStudy";
331 static const char* TARGET_STUDY = "TargetStudy"; 301 static const char* TARGET_STUDY = "TargetStudy";
332 static const char* TARGET_STUDY_UID = "TargetStudyUID"; 302 static const char* TARGET_STUDY_UID = "TargetStudyUID";
333 static const char* SERIES_UID_MAP = "SeriesUIDMap"; 303 static const char* SERIES_UID_MAP = "SeriesUIDMap";
334 static const char* ORIGIN = "Origin"; 304 static const char* ORIGIN = "Origin";
336 static const char* REMOVALS = "Removals"; 306 static const char* REMOVALS = "Removals";
337 307
338 308
339 SplitStudyJob::SplitStudyJob(ServerContext& context, 309 SplitStudyJob::SplitStudyJob(ServerContext& context,
340 const Json::Value& serialized) : 310 const Json::Value& serialized) :
341 SetOfInstancesJob(serialized), // (*) 311 CleaningInstancesJob(context, serialized,
342 context_(context) 312 false /* by default, remove source instances */) // (*)
343 { 313 {
344 if (!HasTrailingStep()) 314 if (!HasTrailingStep())
345 { 315 {
346 // Should have been set by (*) 316 // Should have been set by (*)
347 throw OrthancException(ErrorCode_InternalError); 317 throw OrthancException(ErrorCode_InternalError);
348 } 318 }
349 319
350 Setup(); 320 Setup();
351 321
352 keepSource_ = SerializationToolbox::ReadBoolean(serialized, KEEP_SOURCE);
353 sourceStudy_ = SerializationToolbox::ReadString(serialized, SOURCE_STUDY); 322 sourceStudy_ = SerializationToolbox::ReadString(serialized, SOURCE_STUDY);
354 targetStudy_ = SerializationToolbox::ReadString(serialized, TARGET_STUDY); 323 targetStudy_ = SerializationToolbox::ReadString(serialized, TARGET_STUDY);
355 targetStudyUid_ = SerializationToolbox::ReadString(serialized, TARGET_STUDY_UID); 324 targetStudyUid_ = SerializationToolbox::ReadString(serialized, TARGET_STUDY_UID);
356 SerializationToolbox::ReadMapOfStrings(seriesUidMap_, serialized, SERIES_UID_MAP); 325 SerializationToolbox::ReadMapOfStrings(seriesUidMap_, serialized, SERIES_UID_MAP);
357 origin_ = DicomInstanceOrigin(serialized[ORIGIN]); 326 origin_ = DicomInstanceOrigin(serialized[ORIGIN]);
360 } 329 }
361 330
362 331
363 bool SplitStudyJob::Serialize(Json::Value& target) 332 bool SplitStudyJob::Serialize(Json::Value& target)
364 { 333 {
365 if (!SetOfInstancesJob::Serialize(target)) 334 if (!CleaningInstancesJob::Serialize(target))
366 { 335 {
367 return false; 336 return false;
368 } 337 }
369 else 338 else
370 { 339 {
371 target[KEEP_SOURCE] = keepSource_;
372 target[SOURCE_STUDY] = sourceStudy_; 340 target[SOURCE_STUDY] = sourceStudy_;
373 target[TARGET_STUDY] = targetStudy_; 341 target[TARGET_STUDY] = targetStudy_;
374 target[TARGET_STUDY_UID] = targetStudyUid_; 342 target[TARGET_STUDY_UID] = targetStudyUid_;
375 SerializationToolbox::WriteMapOfStrings(target, seriesUidMap_, SERIES_UID_MAP); 343 SerializationToolbox::WriteMapOfStrings(target, seriesUidMap_, SERIES_UID_MAP);
376 origin_.Serialize(target[ORIGIN]); 344 origin_.Serialize(target[ORIGIN]);