comparison OrthancServer/ServerJobs/SplitStudyJob.cpp @ 2846:d386abc18133

simplification in SplitStudyJob, fix possible memory leak
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 28 Sep 2018 18:36:20 +0200
parents 218e2c864d1d
children 2da68edacab6
comparison
equal deleted inserted replaced
2845:218e2c864d1d 2846:d386abc18133
83 83
84 84
85 /** 85 /**
86 * Chose the target UIDs 86 * Chose the target UIDs
87 **/ 87 **/
88 88
89 std::string series; 89 assert(modified->GetHasher().HashStudy() == sourceStudy_);
90 if (!modified->GetTagValue(series, DICOM_TAG_SERIES_INSTANCE_UID)) 90
91 std::string series = modified->GetHasher().HashSeries();
92
93 SeriesUidMap::const_iterator targetSeriesUid = seriesUidMap_.find(series);
94
95 if (targetSeriesUid == seriesUidMap_.end())
91 { 96 {
92 throw OrthancException(ErrorCode_BadFileFormat); // Should never happen 97 throw OrthancException(ErrorCode_BadFileFormat); // Should never happen
93 }
94
95 std::string targetSeriesUid;
96 SeriesUidMap::const_iterator found = targetSeries_.find(series);
97
98 if (found == targetSeries_.end())
99 {
100 // Choose a random SeriesInstanceUID for this series
101 targetSeriesUid = FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Series);
102 targetSeries_[series] = targetSeriesUid;
103 }
104 else
105 {
106 targetSeriesUid = found->second;
107 } 98 }
108 99
109 100
110 /** 101 /**
111 * Apply user-specified modifications 102 * Apply user-specified modifications
127 /** 118 /**
128 * Store the new instance into Orthanc 119 * Store the new instance into Orthanc
129 **/ 120 **/
130 121
131 modified->ReplacePlainString(DICOM_TAG_STUDY_INSTANCE_UID, targetStudyUid_); 122 modified->ReplacePlainString(DICOM_TAG_STUDY_INSTANCE_UID, targetStudyUid_);
132 modified->ReplacePlainString(DICOM_TAG_SERIES_INSTANCE_UID, targetSeriesUid); 123 modified->ReplacePlainString(DICOM_TAG_SERIES_INSTANCE_UID, targetSeriesUid->second);
133 124
134 if (targetStudy_.empty()) 125 if (targetStudy_.empty())
135 { 126 {
136 targetStudy_ = modified->GetHasher().HashStudy(); 127 targetStudy_ = modified->GetHasher().HashStudy();
137 } 128 }
184 type != ResourceType_Study) 175 type != ResourceType_Study)
185 { 176 {
186 LOG(ERROR) << "Cannot split unknown study: " << sourceStudy; 177 LOG(ERROR) << "Cannot split unknown study: " << sourceStudy;
187 throw OrthancException(ErrorCode_UnknownResource); 178 throw OrthancException(ErrorCode_UnknownResource);
188 } 179 }
189
190 std::list<std::string> children;
191 context_.GetIndex().GetChildren(children, sourceStudy);
192
193 for (std::list<std::string>::const_iterator
194 it = children.begin(); it != children.end(); ++it)
195 {
196 sourceSeries_.insert(*it);
197 }
198 } 180 }
199 181
200 182
201 void SplitStudyJob::SetOrigin(const DicomInstanceOrigin& origin) 183 void SplitStudyJob::SetOrigin(const DicomInstanceOrigin& origin)
202 { 184 {
217 } 199 }
218 200
219 201
220 void SplitStudyJob::AddSourceSeries(const std::string& series) 202 void SplitStudyJob::AddSourceSeries(const std::string& series)
221 { 203 {
222 if (IsStarted()) 204 std::string parent;
223 { 205
224 throw OrthancException(ErrorCode_BadSequenceOfCalls); 206 if (IsStarted())
225 } 207 {
226 else if (sourceSeries_.find(series) == sourceSeries_.end()) 208 throw OrthancException(ErrorCode_BadSequenceOfCalls);
209 }
210 else if (!context_.GetIndex().LookupParent(parent, series, ResourceType_Study) ||
211 parent != sourceStudy_)
227 { 212 {
228 LOG(ERROR) << "This series does not belong to the study to be split: " << series; 213 LOG(ERROR) << "This series does not belong to the study to be split: " << series;
229 throw OrthancException(ErrorCode_UnknownResource); 214 throw OrthancException(ErrorCode_UnknownResource);
230 } 215 }
231 else 216 else
232 { 217 {
218 // Generate a target SeriesInstanceUID for this series
219 seriesUidMap_[series] = FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Series);
220
233 // Add all the instances of the series as to be processed 221 // Add all the instances of the series as to be processed
234 std::list<std::string> instances; 222 std::list<std::string> instances;
235 context_.GetIndex().GetChildren(instances, series); 223 context_.GetIndex().GetChildren(instances, series);
236 224
237 for (std::list<std::string>::const_iterator 225 for (std::list<std::string>::const_iterator
290 278
291 value["TargetStudyUID"] = targetStudyUid_; 279 value["TargetStudyUID"] = targetStudyUid_;
292 } 280 }
293 281
294 282
283 static const char* KEEP_SOURCE = "KeepSource";
295 static const char* SOURCE_STUDY = "SourceStudy"; 284 static const char* SOURCE_STUDY = "SourceStudy";
296 static const char* SOURCE_SERIES = "SourceSeries";
297 static const char* KEEP_SOURCE = "KeepSource";
298 static const char* TARGET_STUDY = "TargetStudy"; 285 static const char* TARGET_STUDY = "TargetStudy";
299 static const char* TARGET_STUDY_UID = "TargetStudyUID"; 286 static const char* TARGET_STUDY_UID = "TargetStudyUID";
300 static const char* TARGET_SERIES = "TargetSeries"; 287 static const char* SERIES_UID_MAP = "SeriesUIDMap";
301 static const char* ORIGIN = "Origin"; 288 static const char* ORIGIN = "Origin";
302 static const char* REPLACEMENTS = "Replacements"; 289 static const char* REPLACEMENTS = "Replacements";
303 static const char* REMOVALS = "Removals"; 290 static const char* REMOVALS = "Removals";
304 291
305 292
316 303
317 Setup(); 304 Setup();
318 305
319 keepSource_ = SerializationToolbox::ReadBoolean(serialized, KEEP_SOURCE); 306 keepSource_ = SerializationToolbox::ReadBoolean(serialized, KEEP_SOURCE);
320 sourceStudy_ = SerializationToolbox::ReadString(serialized, SOURCE_STUDY); 307 sourceStudy_ = SerializationToolbox::ReadString(serialized, SOURCE_STUDY);
321 SerializationToolbox::ReadSetOfStrings(sourceSeries_, serialized, SOURCE_SERIES);
322 targetStudy_ = SerializationToolbox::ReadString(serialized, TARGET_STUDY); 308 targetStudy_ = SerializationToolbox::ReadString(serialized, TARGET_STUDY);
323 targetStudyUid_ = SerializationToolbox::ReadString(serialized, TARGET_STUDY_UID); 309 targetStudyUid_ = SerializationToolbox::ReadString(serialized, TARGET_STUDY_UID);
324 SerializationToolbox::ReadMapOfStrings(targetSeries_, serialized, TARGET_SERIES); 310 SerializationToolbox::ReadMapOfStrings(seriesUidMap_, serialized, SERIES_UID_MAP);
325 origin_ = DicomInstanceOrigin(serialized[ORIGIN]); 311 origin_ = DicomInstanceOrigin(serialized[ORIGIN]);
326 SerializationToolbox::ReadMapOfTags(replacements_, serialized, REPLACEMENTS); 312 SerializationToolbox::ReadMapOfTags(replacements_, serialized, REPLACEMENTS);
327 SerializationToolbox::ReadSetOfTags(removals_, serialized, REMOVALS); 313 SerializationToolbox::ReadSetOfTags(removals_, serialized, REMOVALS);
328 } 314 }
329 315
336 } 322 }
337 else 323 else
338 { 324 {
339 target[KEEP_SOURCE] = keepSource_; 325 target[KEEP_SOURCE] = keepSource_;
340 target[SOURCE_STUDY] = sourceStudy_; 326 target[SOURCE_STUDY] = sourceStudy_;
341 SerializationToolbox::WriteSetOfStrings(target, sourceSeries_, SOURCE_SERIES);
342 target[TARGET_STUDY] = targetStudy_; 327 target[TARGET_STUDY] = targetStudy_;
343 target[TARGET_STUDY_UID] = targetStudyUid_; 328 target[TARGET_STUDY_UID] = targetStudyUid_;
344 SerializationToolbox::WriteMapOfStrings(target, targetSeries_, TARGET_SERIES); 329 SerializationToolbox::WriteMapOfStrings(target, seriesUidMap_, SERIES_UID_MAP);
345 origin_.Serialize(target[ORIGIN]); 330 origin_.Serialize(target[ORIGIN]);
346 SerializationToolbox::WriteMapOfTags(target, replacements_, REPLACEMENTS); 331 SerializationToolbox::WriteMapOfTags(target, replacements_, REPLACEMENTS);
347 SerializationToolbox::WriteSetOfTags(target, removals_, REMOVALS); 332 SerializationToolbox::WriteSetOfTags(target, removals_, REMOVALS);
348 333
349 return true; 334 return true;