1 /*
2  *
3  *  Copyright (C) 2000-2016, OFFIS e.V.
4  *  All rights reserved.  See COPYRIGHT file for details.
5  *
6  *  This software and supporting documentation were developed by
7  *
8  *    OFFIS e.V.
9  *    R&D Division Health
10  *    Escherweg 2
11  *    D-26121 Oldenburg, Germany
12  *
13  *
14  *  Module: dcmsr
15  *
16  *  Author: Joerg Riesmeier
17  *
18  *  Purpose:
19  *    classes: DSRNumericMeasurementValue
20  *
21  */
22 
23 
24 #ifndef DSRNUMVL_H
25 #define DSRNUMVL_H
26 
27 #include "dcmtk/config/osconfig.h"   /* make sure OS specific configuration is included first */
28 
29 #include "dcmtk/dcmsr/dsrcodvl.h"
30 
31 #include "dcmtk/dcmdata/dcvrfd.h"
32 #include "dcmtk/dcmdata/dcvrsl.h"
33 #include "dcmtk/dcmdata/dcvrul.h"
34 
35 
36 /*---------------------*
37  *  class declaration  *
38  *---------------------*/
39 
40 /** Class for numeric values and measurements
41  */
42 class DCMTK_DCMSR_EXPORT DSRNumericMeasurementValue
43 {
44     // allow access to getValuePtr()
45     friend class DSRContentItem;
46 
47   public:
48 
49     /** default constructor
50      */
51     DSRNumericMeasurementValue();
52 
53     /** constructor
54      ** @param  numericValue     numeric value (VR=DS, mandatory)
55      *  @param  measurementUnit  code representing the units of measurement (mandatory)
56      *  @param  check            if enabled, check 'numericValue' and 'measurementUnit' for
57      *                           validity before setting them.  See corresponding setValue()
58      *                           method for details.
59      */
60     DSRNumericMeasurementValue(const OFString &numericValue,
61                                const DSRCodedEntryValue &measurementUnit,
62                                const OFBool check = OFTrue);
63 
64     /** constructor
65      ** @param  valueQualifier  code representing the numeric value qualifier.  Used to
66      *                          specify the reason for the absence of the measured value
67      *                          sequence, i.e. why the numeric value and measurement unit
68      *                          are empty.
69      *  @param  check           if enabled, check value for validity before setting it.
70      *                          See corresponding setValue() method for details.
71      */
72     DSRNumericMeasurementValue(const DSRCodedEntryValue &valueQualifier,
73                                const OFBool check = OFTrue);
74 
75     /** constructor
76      ** @param  numericValue     numeric value (VR=DS, mandatory)
77      *  @param  measurementUnit  code representing the units of measurement (mandatory)
78      *  @param  valueQualifier   code representing the numeric value qualifier (optional).
79      *                           Can also be used to specify the reason for the absence of
80      *                           the measured value sequence (where 'numericValue' and
81      *                           'measurementUnit' are stored).
82      *  @param  check            if enabled, check values for validity before setting them.
83      *                           See corresponding setValue() method for details.
84      */
85     DSRNumericMeasurementValue(const OFString &numericValue,
86                                const DSRCodedEntryValue &measurementUnit,
87                                const DSRCodedEntryValue &valueQualifier,
88                                const OFBool check = OFTrue);
89 
90     /** copy constructor
91      ** @param  numericMeasurement  numeric measurement value to be copied (not checked !)
92      */
93     DSRNumericMeasurementValue(const DSRNumericMeasurementValue &numericMeasurement);
94 
95     /** destructor
96      */
97     virtual ~DSRNumericMeasurementValue();
98 
99     /** assignment operator
100      ** @param  numericMeasurement  numeric measurement value to be copied (not checked !)
101      ** @return reference to this numeric value after 'numericMeasurement' has been copied
102      */
103     DSRNumericMeasurementValue &operator=(const DSRNumericMeasurementValue &numericMeasurement);
104 
105     /** comparison operator "equal".
106      *  Two numeric measurement values are equal if the numeric value, the measurement unit
107      *  and the value qualifier are equal.  Other (additional) information is not used.
108      ** @param  numericMeasurement  numeric measurement value that should be compared to the
109      *                              current one
110      ** @return OFTrue if both numeric measurement values are equal, OFFalse otherwise
111      */
112     OFBool operator==(const DSRNumericMeasurementValue &numericMeasurement) const;
113 
114     /** comparison operator "not equal".
115      *  Two numeric measurement values are not equal if either the numeric value or the
116      *  measurement unit or the value qualifier are not equal.  Other (additional) information
117      *  is not used for comparison.
118      ** @param  numericMeasurement  numeric measurement value that should be compared to the
119      *                              current one
120      ** @return OFTrue if both numeric measurement values are not equal, OFFalse otherwise
121      */
122     OFBool operator!=(const DSRNumericMeasurementValue &numericMeasurement) const;
123 
124     /** clear all internal variables.
125      *  Use this method to create an empty numeric measurement value.
126      */
127     virtual void clear();
128 
129     /** check whether the current numeric measurement value is valid.
130      *  The value is valid if isEmpty() is true or both the numeric value and the measurement
131      *  unit contain a valid value, and the value qualifier is valid (see checkXXX() methods).
132      *  The possibly available additional representations of the numeric value are never
133      *  checked.
134      ** @return OFTrue if value is valid, OFFalse otherwise
135      */
136     virtual OFBool isValid() const;
137 
138     /** check whether the current numeric measurement value is empty.
139      *  Checks whether both the numeric value and the measurement are empty.  The optional
140      *  value qualifier is not checked since it might contain the reason for the absence of
141      *  the measured value sequence.
142      ** @return OFTrue if value is empty, OFFalse otherwise
143      */
144     virtual OFBool isEmpty() const;
145 
146     /** check whether the current numeric measurement value is complete, i.e.\ whether the
147      *  numeric value is non-empty and the measurement unit is complete, or whether the
148      *  value qualifier is complete.  This is just a basic check that might be useful for
149      *  "validating" input data.  See isValid() for a more sophisticated way of checking
150      *  the current numeric measurement value.
151      ** @return OFTrue if value is complete, OFFalse otherwise
152      */
153     virtual OFBool isComplete() const;
154 
155     /** print numeric measurement value.
156      *  The output of a typical numeric measurement value looks like this:
157      *  "3.5" (cm,UCUM[1.4],"centimeter").  If the value is empty, the text "empty" is printed
158      *  instead, followed by the numeric value qualifier (if present).  The possibly available
159      *  additional floating point and rational representations of the numeric value are never
160      *  printed.
161      ** @param  stream  output stream to which the numeric measurement value should be printed
162      *  @param  flags   flag used to customize the output (not used)
163      ** @return status, EC_Normal if successful, an error code otherwise
164      */
165     virtual OFCondition print(STD_NAMESPACE ostream &stream,
166                               const size_t flags) const;
167 
168     /** read numeric measurement value from XML document
169      ** @param  doc     document containing the XML file content
170      *  @param  cursor  cursor pointing to the starting node
171      *  @param  flags   flag used to customize the reading process (see DSRTypes::XF_xxx)
172      ** @return status, EC_Normal if successful, an error code otherwise
173      */
174     virtual OFCondition readXML(const DSRXMLDocument &doc,
175                                 DSRXMLCursor cursor,
176                                 const size_t flags);
177 
178     /** write numeric measurement value in XML format
179      ** @param  stream  output stream to which the XML document is written
180      *  @param  flags   flag used to customize the output (see DSRTypes::XF_xxx)
181      ** @return status, EC_Normal if successful, an error code otherwise
182      */
183     virtual OFCondition writeXML(STD_NAMESPACE ostream &stream,
184                                  const size_t flags) const;
185 
186     /** read measured value sequence and numeric value qualifier code sequence from dataset.
187      *  The number of items within the sequences is checked.  If error/warning output are
188      *  enabled, a warning message is printed if a sequence is absent or contains more than
189      *  one item.
190      ** @param  dataset  DICOM dataset from which the sequences should be read
191      *  @param  flags    flag used to customize the reading process (see DSRTypes::RF_xxx)
192      ** @return status, EC_Normal if successful, an error code otherwise
193      */
194     virtual OFCondition readSequence(DcmItem &dataset,
195                                      const size_t flags);
196 
197     /** write measured value sequence and numeric value qualifier code sequence to dataset.
198      *  The measured value sequence is always written (might be empty, though).  The numeric
199      *  value qualifier code sequence is optional and, therefore, only written if non-empty.
200      ** @param  dataset  DICOM dataset to which the sequences should be written
201      ** @return status, EC_Normal if successful, an error code otherwise
202      */
203     virtual OFCondition writeSequence(DcmItem &dataset) const;
204 
205     /** render numeric measurement value in HTML/XHTML format
206      ** @param  docStream    output stream to which the main HTML/XHTML document is written
207      *  @param  annexStream  output stream to which the HTML/XHTML document annex is written
208      *  @param  annexNumber  reference to the variable where the current annex number is stored.
209      *                       Value is increased automatically by 1 after a new entry has been added.
210      *  @param  flags        flag used to customize the output (see DSRTypes::HF_xxx)
211      ** @return status, EC_Normal if successful, an error code otherwise
212      */
213     virtual OFCondition renderHTML(STD_NAMESPACE ostream &docStream,
214                                    STD_NAMESPACE ostream &annexStream,
215                                    size_t &annexNumber,
216                                    const size_t flags) const;
217 
218     /** get reference to numeric measurement value
219      ** @return reference to numeric measurement value
220      */
getValue()221     inline const DSRNumericMeasurementValue &getValue() const
222     {
223         return *this;
224     }
225 
226     /** get copy of numeric measurement value
227      ** @param  numericMeasurement  reference to variable in which the value should be stored
228      ** @return always returns EC_Normal
229      */
230     OFCondition getValue(DSRNumericMeasurementValue &numericMeasurement) const;
231 
232     /** get numeric value
233      ** @return current numeric value (might be invalid or an empty string)
234      */
getNumericValue()235     inline const OFString &getNumericValue() const
236     {
237         return NumericValue;
238     }
239 
240     /** get measurement unit
241      ** @return reference to current measurement unit code (might be invalid or empty)
242      */
getMeasurementUnit()243     inline const DSRCodedEntryValue &getMeasurementUnit() const
244     {
245         return MeasurementUnit;
246     }
247 
248     /** get numeric value qualifier (optional)
249      ** @return reference to current numeric value qualifier code (might be invalid or empty)
250      */
getNumericValueQualifier()251     inline const DSRCodedEntryValue &getNumericValueQualifier() const
252     {
253         return ValueQualifier;
254     }
255 
256     /** get copy of measurement unit
257      ** @param  measurementUnit  reference to variable in which the code should be stored
258      ** @return always returns EC_Normal
259      */
260     OFCondition getMeasurementUnit(DSRCodedEntryValue &measurementUnit) const;
261 
262     /** get copy of numeric value qualifier (optional).
263      *  Can be used to specify the reason for the absence of the measured value sequence.
264      ** @param  valueQualifier  reference to variable in which the code should be stored
265      ** @return always returns EC_Normal
266      */
267     OFCondition getNumericValueQualifier(DSRCodedEntryValue &valueQualifier) const;
268 
269     /** get floating point representation of the numeric value (optional)
270      ** @param  floatingPoint  reference to variable in which the floating point representation
271      *                         should be stored
272      ** @return status, EC_Normal if successful, an error code otherwise.  Returns
273      *    SR_EC_RepresentationNotAvailable if floating point representation is not available.
274      */
275     OFCondition getFloatingPointRepresentation(Float64 &floatingPoint) const;
276 
277     /** get rational representation of the numeric value (optional)
278      ** @param  rationalNumerator    reference to variable in which the integer numerator of
279      *                               the rational representation should be stored
280      ** @param  rationalDenominator  reference to variable in which the integer denominator of
281      *                               the rational representation should be stored
282      ** @return status, EC_Normal if successful, an error code otherwise.  Returns
283      *    SR_EC_RepresentationNotAvailable if rational representation is not available.
284      */
285     OFCondition getRationalRepresentation(Sint32 &rationalNumerator,
286                                           Uint32 &rationalDenominator) const;
287 
288     /** set numeric measurement value.
289      *  Before setting the value, it is usually checked.  If the value is invalid, the current
290      *  value is not replaced and remains unchanged.
291      ** @param  numericMeasurement  value to be set
292      *  @param  check               if enabled, check value for validity before setting it.
293      *                              See checkXXX() methods for details.  Empty values are only
294      *                              accepted for non-mandatory attributes.
295      ** @return status, EC_Normal if successful, an error code otherwise
296      */
297     OFCondition setValue(const DSRNumericMeasurementValue &numericMeasurement,
298                          const OFBool check = OFTrue);
299 
300     /** set numeric value and measurement unit.
301      *  Before setting the values, they are usually checked.  Please note that both values
302      *  (i.e. 'numericValue' and 'measurementUnit') either have to be empty or non-empty.
303      *  If the value pair is invalid, the current value pair is not replaced and remains
304      *  unchanged.  If the value pair is replaced, the optional floating point and rational
305      *  representations are cleared, i.e. they have to be set manually if needed.
306      ** @param  numericValue     numeric value to be set (VR=DS, mandatory)
307      *  @param  measurementUnit  measurement unit to be set (mandatory)
308      *  @param  check            if enabled, check values for validity before setting them.
309      *                           See checkXXX() methods for details.
310      ** @return status, EC_Normal if successful, an error code otherwise
311      */
312     OFCondition setValue(const OFString &numericValue,
313                          const DSRCodedEntryValue &measurementUnit,
314                          const OFBool check = OFTrue);
315 
316     /** set empty numeric value and measurement unit with a numeric value qualifier.
317      *  Before setting the value, it is usually checked.  If the value is invalid, the
318      *  current numeric measurement value is not replaced and remains unchanged.
319      ** @param  valueQualifier  numeric value qualifier to be set.  Used to specify the
320      *                          reason for the absence of the measured value sequence,
321      *                          i.e. why the numeric value and measurement unit are empty.
322      *  @param  check           if enabled, check value for validity before setting it.
323      *                          See checkNumericValueQualifier() method for details.
324      ** @return status, EC_Normal if successful, an error code otherwise
325      */
326     OFCondition setValue(const DSRCodedEntryValue &valueQualifier,
327                          const OFBool check = OFTrue);
328 
329     /** set numeric value, measurement unit and numeric value qualifier.
330      *  Before setting the values, they are usually checked.  Please note that both
331      *  'numericValue' and 'measurementUnit' either have to be empty or non-empty.
332      *  If one of the three values is invalid, the current numeric measurement value is not
333      *  replaced and remains unchanged.  If the values are replaced, the optional floating
334      *  point and rational representations are cleared, i.e. they have to be set manually if
335      *  needed.
336      ** @param  numericValue     numeric value to be set (VR=DS, mandatory)
337      *  @param  measurementUnit  measurement unit to be set (mandatory)
338      *  @param  valueQualifier   numeric value qualifier to be set (optional).  Can also be
339      *                           used to specify the reason for the absence of the measured
340      *                           value sequence (where 'numericValue' and 'measurementUnit'
341      *                           are stored).  Use an empty code to remove the current value.
342      *  @param  check            if enabled, check values for validity before setting them.
343      *                           See checkXXX() methods for details.
344      ** @return status, EC_Normal if successful, an error code otherwise
345      */
346     OFCondition setValue(const OFString &numericValue,
347                          const DSRCodedEntryValue &measurementUnit,
348                          const DSRCodedEntryValue &valueQualifier,
349                          const OFBool check = OFTrue);
350 
351     /** set numeric value.
352      *  Before setting the value, it is usually checked.  If the value is invalid, the current
353      *  value is not replaced and remains unchanged.  If the value is replaced, the optional
354      *  floating point and rational representations are cleared, i.e. they have to be set
355      *  manually if needed.
356      ** @param  numericValue  numeric value to be set (VR=DS, mandatory)
357      *  @param  check         if enabled, check value for validity before setting it.
358      *                        See checkNumericValue() method for details.  An empty value is
359      *                        never accepted, use the clear() method instead.
360      ** @return status, EC_Normal if successful, an error code otherwise
361      */
362     OFCondition setNumericValue(const OFString &numericValue,
363                                 const OFBool check = OFTrue);
364 
365     /** set numeric value from element.
366      *  Before setting the value, it is usually checked.  If the value is invalid, the current
367      *  value is not replaced and remains unchanged.  If the value is replaced, the optional
368      *  floating point and rational representations are cleared, i.e. they have to be set
369      *  manually if needed.
370      ** @param  delem  DICOM element from which the numeric value should be retrieved
371      *  @param  pos    index of the value in case of multi-valued elements (0..vm-1)
372      *  @param  check  if enabled, check numeric value for validity before setting it.  See
373      *                 checkNumericValue() method for details.  An empty value is never
374      *                 accepted.
375      ** @return status, EC_Normal if successful, an error code otherwise
376      */
377     OFCondition setNumericValue(const DcmElement &delem,
378                                 const unsigned long pos = 0,
379                                 const OFBool check = OFTrue);
380 
381     /** set numeric value from dataset.
382      *  Before setting the value, it is usually checked.  If the value is invalid, the current
383      *  value is not replaced and remains unchanged.  If the value is replaced, the optional
384      *  floating point and rational representations are cleared, i.e. they have to be set
385      *  manually if needed.
386      ** @param  dataset  DICOM dataset from which the numeric value should be retrieved
387      *  @param  tagKey   DICOM tag specifying the attribute from which the value should be
388      *                   retrieved.  The search is limited to the top-level of the dataset.
389      *  @param  pos      index of the value in case of multi-valued elements (0..vm-1)
390      *  @param  check    if enabled, check numeric value for validity before setting it.
391      *                   See checkNumericValue() method for details.  An empty value is
392      *                   never accepted.
393      ** @return status, EC_Normal if successful, an error code otherwise
394      */
395     OFCondition setNumericValue(DcmItem &dataset,
396                                 const DcmTagKey &tagKey,
397                                 const unsigned long pos = 0,
398                                 const OFBool check = OFTrue);
399 
400     /** set measurement unit.
401      *  Before setting the code, it is usually checked.  If the code is invalid the current
402      *  code is not replaced and remains unchanged.
403      ** @param  measurementUnit  measurement unit to be set (mandatory)
404      *  @param  check            if enabled, check value for validity before setting it.
405      *                           See checkMeasurementUnit() method for details.  An empty
406      *                           value is never accepted, use the clear() method instead.
407      ** @return status, EC_Normal if successful, an error code otherwise
408      */
409     OFCondition setMeasurementUnit(const DSRCodedEntryValue &measurementUnit,
410                                    const OFBool check = OFTrue);
411 
412     /** set numeric value qualifier.
413      *  This optional code specifies the qualification of the Numeric Value in the Measured
414      *  Value Sequence, or the reason for the absence of the Measured Value Sequence Item.
415      *  Before setting the code, it is usually checked.  If the code is invalid the current
416      *  code is not replaced and remains unchanged.
417      ** @param  valueQualifier  numeric value qualifier to be set (optional).  Use an empty
418      *                          code to remove the current value.
419      *  @param  check           if enabled, check value for validity before setting it.
420      *                          See checkNumericValueQualifier() method for details.
421      ** @return status, EC_Normal if successful, an error code otherwise
422      */
423     OFCondition setNumericValueQualifier(const DSRCodedEntryValue &valueQualifier,
424                                          const OFBool check = OFTrue);
425 
426     /** set floating point representation of the numeric value.
427      *  According to the DICOM standard, this value is "required if the numeric value has
428      *  insufficient precision to represent the value as a string.  May be present otherwise."
429      *  Please note that it is not checked whether this representation is consistent with the
430      *  numeric value stored as a string.
431      ** @param  floatingPoint  floating point representation of the numeric value
432      *  @param  check          dummy parameter (currently not used)
433      ** @return status, EC_Normal if successful, an error code otherwise
434      */
435     OFCondition setFloatingPointRepresentation(const Float64 floatingPoint,
436                                                const OFBool check = OFTrue);
437 
438     /** set rational representation of the numeric value.
439      *  According to the DICOM standard, this value is "required if the numeric value has
440      *  insufficient precision to represent a rational value as a string.  May be present
441      *  otherwise."  Please note that it is not checked whether this representation is
442      *  consistent with the numeric value stored as a string.
443      ** @param  rationalNumerator    integer numerator of a rational representation of the
444      *                               numeric value (encoded as a signed integer value)
445      *  @param  rationalDenominator  integer denominator of a rational representation of the
446      *                               numeric value (encoded as a non-zero unsigned integer
447      *                               value)
448      *  @param  check                if enabled, check values for validity before setting them.
449      *                               See checkRationalRepresentation() method for details.
450      ** @return status, EC_Normal if successful, an error code otherwise
451      */
452     OFCondition setRationalRepresentation(const Sint32 rationalNumerator,
453                                           const Uint32 rationalDenominator,
454                                           const OFBool check = OFTrue);
455 
456     /** remove floating point representation of the numeric value (if any).
457      *  Internally, all elements that belong to this representation are cleared.
458      */
459     void removeFloatingPointRepresentation();
460 
461     /** remove rational representation of the numeric value (if any).
462      *  Internally, all elements that belong to this representation are cleared.
463      */
464     void removeRationalRepresentation();
465 
466 
467   protected:
468 
469     /** get pointer to numeric measurement value
470      ** @return pointer to numeric measurement value (never NULL)
471      */
getValuePtr()472     inline DSRNumericMeasurementValue *getValuePtr()
473     {
474         return this;
475     }
476 
477     /** read numeric measurement value from dataset
478      ** @param  dataset  DICOM dataset from which the value should be read
479      *  @param  flags    flag used to customize the reading process (see DSRTypes::RF_xxx)
480      ** @return status, EC_Normal if successful, an error code otherwise
481      */
482     virtual OFCondition readItem(DcmItem &dataset,
483                                  const size_t flags);
484 
485     /** write numeric measurement value to dataset
486      ** @param  dataset  DICOM dataset to which the value should be written
487      ** @return status, EC_Normal if successful, an error code otherwise
488      */
489     virtual OFCondition writeItem(DcmItem &dataset) const;
490 
491     /** check the specified numeric value for validity.
492      *  Currently, the only checks performed are that the string is non-empty and that the
493      *  given value conforms to the corresponding VR (DS) and VM (1).
494      ** @param  numericValue  numeric value to be checked
495      ** @return status, EC_Normal if numeric value is valid, an error code otherwise
496      */
497     virtual OFCondition checkNumericValue(const OFString &numericValue) const;
498 
499     /** check the specified measurement unit for validity.
500      *  Internally, the methods DSRCodedEntryValue::isEmpty() and
501      *  DSRCodedEntryValue::checkCurrentValue() are used for this purpose.  Conformance
502      *  with the Context Group 82 (as defined in the DICOM standard) is not yet checked.
503      ** @param  measurementUnit  measurement unit to be checked
504      ** @return status, EC_Normal if measurement unit is valid, an error code otherwise
505      */
506     virtual OFCondition checkMeasurementUnit(const DSRCodedEntryValue &measurementUnit) const;
507 
508     /** check the specified numeric value qualifier for validity.
509      *  Internally, DSRCodedEntryValue::isEmpty() and DSRCodedEntryValue::checkCurrentValue()
510      *  are used for this purpose.  Conformance with the Context Group 42 (as defined in the
511      *  DICOM standard) is not checked; see class CMR_SRNumericMeasurementValue if needed,
512      *  which supports such additional checks.
513      ** @param  valueQualifier  numeric value qualifier to be checked
514      ** @return status, EC_Normal if value qualifier is valid, an error code otherwise
515      */
516     virtual OFCondition checkNumericValueQualifier(const DSRCodedEntryValue &valueQualifier) const;
517 
518     /** check the specified rational representation for validity.
519      *  The only check that is performed is that the 'rationalDenominator' is not zero, i.e.
520      *  it is not checked whether this representation is consistent with the numeric value
521      *  stored as a string.
522      ** @param  rationalNumerator    numerator of the rational representation to be checked
523      *  @param  rationalDenominator  denominator of a rational representation to be checked
524      ** @return status, EC_Normal if rational representation is valid, an error code otherwise
525      */
526     virtual OFCondition checkRationalRepresentation(const Sint32 rationalNumerator,
527                                                     const Uint32 rationalDenominator) const;
528 
529     /** check the currently stored numeric measurement value for validity.
530      *  See above checkXXX() methods for details.
531      ** @return status, EC_Normal if current value is valid, an error code otherwise
532      */
533     virtual OFCondition checkCurrentValue() const;
534 
535 
536   private:
537 
538     /// Numeric Value (VR=DS, type 1 within a type 2 sequence)
539     OFString               NumericValue;
540     /// Measurement Unit (type 1 within a type 2 sequence)
541     DSRCodedEntryValue     MeasurementUnit;
542     /// Numeric Value Qualifier (type 3)
543     DSRCodedEntryValue     ValueQualifier;
544     /// Floating Point Value (VR=FD, type 1C)
545     DcmFloatingPointDouble FloatingPointValue;
546     /// Rational Numerator Value (VR=SL, type 1C)
547     DcmSignedLong          RationalNumeratorValue;
548     /// Rational Denominator Value (VR=UL, type 1C)
549     DcmUnsignedLong        RationalDenominatorValue;
550 };
551 
552 
553 /** output stream operator for numeric measurement values.
554  *  Internally, the DSRNumericMeasurementValue::print() method is used, i.e. the output
555  *  looks like this: "3.5" (cm,UCUM[1.4],"centimeter") or "empty" (if the value is empty)
556  *  @param  stream              output stream to which the numeric measurement value is
557  *                              printed
558  *  @param  numericMeasurement  numeric measurement value to be printed
559  *  @return reference to output stream
560  */
561 DCMTK_DCMSR_EXPORT STD_NAMESPACE ostream &operator<<(STD_NAMESPACE ostream &stream,
562                                                      const DSRNumericMeasurementValue &numericMeasurement);
563 
564 
565 #endif
566