1 /*
2 *
3 * Copyright (C) 2016-2018, Open Connections GmbH
4 * All rights reserved. See COPYRIGHT file for details.
5 *
6 * This software and supporting documentation are maintained by
7 *
8 * OFFIS e.V.
9 * R&D Division Health
10 * Escherweg 2
11 * D-26121 Oldenburg, Germany
12 *
13 *
14 * Module: dcmtract
15 *
16 * Author: Michael Onken
17 *
18 * Purpose: Statistics from a Tractography Results IOD
19 *
20 */
21 #include "dcmtk/config/osconfig.h"
22 #include "dcmtk/dcmdata/dcuid.h"
23 #include "dcmtk/dcmiod/iodutil.h"
24 #include "dcmtk/dcmtract/trcstatistic.h"
25
26
27 // ------------------------------ class TrcTStatistic --------------------------
28
29 // default constructor (protected, instance creation via create() function)
TrcStatistic()30 TrcStatistic::TrcStatistic()
31 : IODComponent(),
32 m_Type(),
33 m_TypeModifier(),
34 m_Units(),
35 m_Values()
36 {
37 // This is an abstract class so it is enough to call resetRules() is called
38 // from derived classes
39 }
40
41
resetRules()42 void TrcStatistic::resetRules()
43 {
44 // Set rules for the attributes within this component
45 getRules()->addRule(new IODRule(DCM_ConceptNameCodeSequence, "1","1",getName(), DcmIODTypes::IE_INSTANCE), OFTrue);
46 getRules()->addRule(new IODRule(DCM_ModifierCodeSequence, "1","1", getName(), DcmIODTypes::IE_INSTANCE), OFTrue);
47 getRules()->addRule(new IODRule(DCM_MeasurementUnitsCodeSequence, "1","1", getName(), DcmIODTypes::IE_INSTANCE), OFTrue);
48 }
49
50
read(DcmItem & source,const OFBool clearOldData)51 OFCondition TrcStatistic::read(DcmItem& source,
52 const OFBool clearOldData)
53 {
54 if (clearOldData)
55 this->clearData();
56 // Read as much as possible. In order to return success at minimum the tracks
57 // must be readable.
58 IODComponent::read(source, OFFalse /* we cleared data before */);
59 DcmIODUtil::readSingleItem(source, DCM_ConceptNameCodeSequence, m_Type, getRules()->getByTag(DCM_ConceptNameCodeSequence));
60 DcmIODUtil::readSingleItem(source, DCM_MeasurementUnitsCodeSequence, m_Units, getRules()->getByTag(DCM_MeasurementUnitsCodeSequence));
61 DcmIODUtil::readSingleItem(source, DCM_ModifierCodeSequence, m_TypeModifier, getRules()->getByTag(DCM_ModifierCodeSequence));
62 return EC_Normal;
63 }
64
65
write(DcmItem & destination)66 OFCondition TrcStatistic::write(DcmItem& destination)
67 {
68 OFCondition result;
69 DcmIODUtil::writeSingleItem(result, DCM_ConceptNameCodeSequence, m_Type, getData(), getRules()->getByTag(DCM_ConceptNameCodeSequence));
70 DcmIODUtil::writeSingleItem(result, DCM_MeasurementUnitsCodeSequence, m_Units, getData(), getRules()->getByTag(DCM_MeasurementUnitsCodeSequence));
71 DcmIODUtil::writeSingleItem(result, DCM_ModifierCodeSequence, m_TypeModifier, getData(), getRules()->getByTag(DCM_ModifierCodeSequence));
72 if (result.good()) result = IODComponent::write(destination);
73 return result;
74 }
75
76
clearData()77 void TrcStatistic::clearData()
78 {
79 m_Type.clearData();
80 m_Units.clearData();
81 m_TypeModifier.clearData();
82 IODComponent::clearData();
83 }
84
get(CodeSequenceMacro & typeCode,CodeSequenceMacro & typeModifierCode,CodeSequenceMacro & unitsCode)85 OFCondition TrcStatistic::get(CodeSequenceMacro& typeCode,
86 CodeSequenceMacro& typeModifierCode,
87 CodeSequenceMacro& unitsCode)
88 {
89 typeCode = m_Type;
90 typeModifierCode = m_TypeModifier;
91 unitsCode = m_Units;
92 return EC_Normal;
93 }
94
95
setCommon(const CodeSequenceMacro & typeCode,const CodeSequenceMacro & typeModifierCode,const CodeSequenceMacro & unitsCode)96 OFCondition TrcStatistic::setCommon(const CodeSequenceMacro& typeCode,
97 const CodeSequenceMacro& typeModifierCode,
98 const CodeSequenceMacro& unitsCode)
99 {
100 OFCondition result;
101 result = OFconst_cast(CodeSequenceMacro*, &typeCode)->check(OFTrue /* quiet */);
102 if (result.good())
103 {
104 m_Type = typeCode;
105 }
106 if (result.good())
107 {
108 result = OFconst_cast(CodeSequenceMacro*, &typeModifierCode)->check(OFTrue /* quiet */);
109 if (result.good())
110 {
111 m_TypeModifier = typeModifierCode;
112 }
113 }
114 if (result.good())
115 {
116 result = OFconst_cast(CodeSequenceMacro*, &unitsCode)->check(OFTrue /* quiet */);
117 if (result.good())
118 {
119 m_Units = unitsCode;
120 }
121 }
122 return result;
123 }
124
125
~TrcStatistic()126 TrcStatistic::~TrcStatistic()
127 {
128 // nothing to do
129 }
130
131
132
133 // ----------------------------- class TrcTrackStatistic -----------------------
134
TrcTracksStatistic()135 TrcTracksStatistic::TrcTracksStatistic()
136 : TrcStatistic()
137 {
138 resetRules();
139 }
140
141
~TrcTracksStatistic()142 TrcTracksStatistic::~TrcTracksStatistic()
143 {
144 // nothing to do
145 }
146
create(const CodeSequenceMacro & typeCode,const CodeSequenceMacro & typeModifierCode,const CodeSequenceMacro & unitsCode,const Float32 * statisticValues,const size_t numValues,TrcTracksStatistic * & statistic)147 OFCondition TrcTracksStatistic::create(const CodeSequenceMacro& typeCode,
148 const CodeSequenceMacro& typeModifierCode,
149 const CodeSequenceMacro& unitsCode,
150 const Float32* statisticValues,
151 const size_t numValues,
152 TrcTracksStatistic*& statistic)
153 {
154 statistic = new TrcTracksStatistic();
155 if (!statistic)
156 return EC_MemoryExhausted;
157
158 //OFCondition result = OFstatic_cast(TrcStatistic*,statistic)->set(typeCode, typeModifierCode, unitsCode);
159 OFCondition result = statistic->TrcStatistic::setCommon(typeCode, typeModifierCode, unitsCode);
160 if (result.good())
161 {
162 result = statistic->getData().putAndInsertFloat32Array(DCM_FloatingPointValues, statisticValues, OFstatic_cast(unsigned long, numValues));
163 if (result.bad())
164 {
165 result = TRC_EC_InvalidStatisticData;
166 }
167 }
168 if (result.bad())
169 {
170 delete statistic;
171 statistic = NULL;
172 }
173 return result;
174 }
175
176
read(DcmItem & source,const OFBool clearOldData)177 OFCondition TrcTracksStatistic::read(DcmItem& source,
178 const OFBool clearOldData)
179 {
180 return TrcStatistic::read(source, clearOldData);
181 }
182
183
write(DcmItem & destination)184 OFCondition TrcTracksStatistic::write(DcmItem& destination)
185 {
186 OFCondition result;
187 result = TrcStatistic::write(destination);
188 if (result.good())
189 {
190 result = IODComponent::write(destination);
191 }
192 return result;
193 }
194
195
get(CodeSequenceMacro & typeCode,CodeSequenceMacro & typeModifierCode,CodeSequenceMacro & unitsCode,const Float32 * & statisticValues,unsigned long & numValues)196 OFCondition TrcTracksStatistic::get(CodeSequenceMacro& typeCode,
197 CodeSequenceMacro& typeModifierCode,
198 CodeSequenceMacro& unitsCode,
199 const Float32*& statisticValues,
200 unsigned long& numValues)
201 {
202 OFCondition result = TrcStatistic::get(typeCode, typeModifierCode, unitsCode);
203
204 if (result.good())
205 {
206 result = m_Item->findAndGetFloat32Array(DCM_FloatingPointValues, statisticValues, &numValues);
207 }
208 return result;
209 }
210
211
getName() const212 OFString TrcTracksStatistic::getName() const
213 {
214 return "TrackStatisticsSequenceItem";
215 }
216
217
resetRules()218 void TrcTracksStatistic::resetRules()
219 {
220 TrcStatistic::resetRules();
221 m_Rules->addRule(new IODRule(DCM_FloatingPointValues, "1","1", getName(), DcmIODTypes::IE_INSTANCE), OFTrue);
222 }
223
224
set(const CodeSequenceMacro & typeCode,const CodeSequenceMacro & typeModifierCode,const CodeSequenceMacro & unitsCode,const Float32 * statisticValues,const size_t numValues)225 OFCondition TrcTracksStatistic::set(const CodeSequenceMacro& typeCode,
226 const CodeSequenceMacro& typeModifierCode,
227 const CodeSequenceMacro& unitsCode,
228 const Float32* statisticValues,
229 const size_t numValues)
230 {
231 if ( !statisticValues || (numValues == 0))
232 {
233 return TRC_EC_InvalidStatisticData;
234 }
235 OFCondition result = TrcStatistic::setCommon(typeCode, typeModifierCode, unitsCode);
236 if (result.good())
237 {
238 result = m_Item->putAndInsertFloat32Array(DCM_FloatingPointValues, statisticValues, OFstatic_cast(unsigned long, numValues));
239 }
240 return result;
241 }
242
243
244 // --------------------------- class TrcTrackSetStatistic ----------------------
245
TrcTrackSetStatistic()246 TrcTrackSetStatistic::TrcTrackSetStatistic()
247 : TrcStatistic()
248 {
249 resetRules();
250 }
251
252
~TrcTrackSetStatistic()253 TrcTrackSetStatistic::~TrcTrackSetStatistic()
254 {
255 // nothing to do
256 }
257
258
create(const CodeSequenceMacro & typeCode,const CodeSequenceMacro & typeModifierCode,const CodeSequenceMacro & unitsCode,const Float64 statisticValue,TrcTrackSetStatistic * & statistic)259 OFCondition TrcTrackSetStatistic::create(const CodeSequenceMacro& typeCode,
260 const CodeSequenceMacro& typeModifierCode,
261 const CodeSequenceMacro& unitsCode,
262 const Float64 statisticValue,
263 TrcTrackSetStatistic *&statistic)
264 {
265 statistic = new TrcTrackSetStatistic();
266 if (!statistic)
267 return EC_MemoryExhausted;
268
269 OFCondition result = statistic->set(typeCode, typeModifierCode, unitsCode, statisticValue);
270 if (result.bad())
271 {
272 delete statistic;
273 statistic = NULL;
274 }
275 return result;
276 }
277
278
read(DcmItem & source,const OFBool clearOldData)279 OFCondition TrcTrackSetStatistic::read(DcmItem& source,
280 const OFBool clearOldData)
281 {
282 OFCondition result = IODComponent::read(source, clearOldData);
283 if (result.good())
284 {
285 TrcStatistic::read(source, clearOldData);
286 }
287 return result;
288 }
289
290
write(DcmItem & destination)291 OFCondition TrcTrackSetStatistic::write(DcmItem& destination)
292 {
293 OFCondition result;
294 result = TrcStatistic::write(destination);
295 if (result.good())
296 {
297 result = IODComponent::write(destination);
298 }
299 return result;
300 }
301
302
303
get(CodeSequenceMacro & typeCode,CodeSequenceMacro & typeModifierCode,CodeSequenceMacro & unitsCode,Float64 & statisticValue)304 OFCondition TrcTrackSetStatistic::get(CodeSequenceMacro& typeCode,
305 CodeSequenceMacro& typeModifierCode,
306 CodeSequenceMacro& unitsCode,
307 Float64& statisticValue)
308 {
309 OFCondition result = TrcStatistic::get(typeCode, typeModifierCode, unitsCode);
310 if (result.good())
311 {
312 result = m_Item->findAndGetFloat64(DCM_FloatingPointValue, statisticValue, 0);
313 if (result.bad())
314 {
315 result = TRC_EC_InvalidStatisticData;
316 }
317 }
318 return result;
319 }
320
321
getName() const322 OFString TrcTrackSetStatistic::getName() const
323 {
324 return "TrackSetStatisticsSequenceItem";
325 }
326
327
resetRules()328 void TrcTrackSetStatistic::resetRules()
329 {
330 TrcStatistic::resetRules();
331 m_Rules->addRule(new IODRule(DCM_FloatingPointValue, "1","1", getName(), DcmIODTypes::IE_INSTANCE), OFTrue);
332 }
333
334
set(const CodeSequenceMacro & typeCode,const CodeSequenceMacro & typeModifierCode,const CodeSequenceMacro & unitsCode,const Float64 statisticValue)335 OFCondition TrcTrackSetStatistic::set(const CodeSequenceMacro& typeCode,
336 const CodeSequenceMacro& typeModifierCode,
337 const CodeSequenceMacro& unitsCode,
338 const Float64 statisticValue)
339 {
340 OFCondition result = TrcStatistic::setCommon(typeCode, typeModifierCode, unitsCode);
341 if (result.good())
342 {
343 result = m_Item->putAndInsertFloat64(DCM_FloatingPointValue, statisticValue, 0);
344 if (result.bad())
345 {
346 result = TRC_EC_InvalidStatisticData;
347 }
348 }
349 return result;
350 }
351