]> Creatis software - gdcm.git/blob - gdcmSerieHelper.h
519255c8b0592efb312d6f0ec30c81dba36ef54f
[gdcm.git] / gdcmSerieHelper.h
1 /*=========================================================================
2                                                                                 
3   Program:   gdcm
4   Module:    $RCSfile: gdcmSerieHelper.h,v $
5   Language:  C++
6   Date:      $Date: 2005/11/28 15:20:34 $
7   Version:   $Revision: 1.31 $
8                                                                                 
9   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
10   l'Image). All rights reserved. See Doc/License.txt or
11   http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details.
12                                                                                 
13      This software is distributed WITHOUT ANY WARRANTY; without even
14      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15      PURPOSE.  See the above copyright notices for more information.
16                                                                                 
17 =========================================================================*/
18
19 #ifndef GDCMSERIEHELPER_H
20 #define GDCMSERIEHELPER_H
21
22 #include "gdcmCommon.h" 
23 #include "gdcmTagKey.h" 
24 #include "gdcmDebug.h"  // for LEGACY
25 #include "gdcmCommandManager.h"
26  
27 #include <vector>
28 #include <iostream>
29 #include <map>
30
31 namespace gdcm 
32 {
33 class File;
34
35    typedef std::vector<File* > FileList;
36    
37    /// \brief XCoherent stands for 'Extra Coherent', 
38    ///        (The name 'Coherent' would be enough but it was used before;
39    ///        I don't want to put a bomb in the code)
40    ///        Any 'better name' is welcome !
41    typedef std::map<std::string, FileList *> XCoherentFileSetmap; 
42       
43    typedef bool (*BOOL_FUNCTION_PFILE_PFILE_POINTER)(File *, File *);
44
45 //-----------------------------------------------------------------------------
46 /**
47  * \brief  
48  *  This class should be used for a stack of 2D dicom images.
49  *
50  *   - It allows to explore (recursively or not) a directory and 
51  *   makes a set of 'Single SerieUID Filesets' 
52  *   - It allows :
53  *   - - to sort any of the 'Single SerieUID Fileset' on the image position.
54  *   - - to split any of the Single SerieUID Filesets (better use this name than
55  *   'CoherentFileList' : it's NOT a std::list, files are NOT coherent ...)
56  *    into several XCoherent Filesets 
57  *   XCoherent stands for 'Extra Coherent' (same orientation, or same position)
58  */
59 class GDCM_EXPORT SerieHelper  : public CommandManager
60 {
61    gdcmTypeMacro(SerieHelper);
62    
63 public:
64    /// SingleSerieUIDFileSetmap replaces the former CoherentFileListmap
65    /// ( List were actually std::vectors, and wher no coherent at all :
66    ///   They were only Single SeriesInstanceUID File sets)
67    typedef std::map<std::string, FileList *> SingleSerieUIDFileSetmap;
68
69    typedef std::vector<File* > FileVector;
70
71 /// \brief Constructs a SerieHelper with a RefCounter
72     static SerieHelper *New() {return new SerieHelper();}
73      
74    virtual ~SerieHelper();
75    void Print(std::ostream &os = std::cout, std::string const &indent = "" );
76
77    /// \todo should return bool or throw error ?
78    void AddFileName(std::string const &filename);
79    void AddGdcmFile(File *header);
80
81    void SetDirectory(std::string const &dir, bool recursive=false);
82    bool IsCoherent(FileList *fileSet);
83    void OrderFileList(FileList *fileSet);
84    
85    /// \brief Gets the FIRST Single SerieUID Fileset.
86    ///        Deprecated; kept not to break the API
87    /// \note Caller must call OrderFileList first
88    /// @return the (first) Single SerieUID Fileset
89    const FileList &GetFileList()
90                            { return *SingleSerieUIDFileSetHT.begin()->second; }
91   
92    GDCM_LEGACY(   FileList *GetFirstCoherentFileList()  );
93    GDCM_LEGACY(   FileList *GetNextCoherentFileList()   );
94    GDCM_LEGACY(   FileList *GetCoherentFileList(std::string serieUID)  );
95
96    FileList *GetFirstSingleSerieUIDFileSet();
97    FileList *GetNextSingleSerieUIDFileSet();
98    FileList *GetSingleSerieUIDFileSet(std::string serieUID);
99    /// brief returns the 'Series Instance UID' Single SerieUID FileSet
100    std::string GetCurrentSerieUIDFileSetUID()
101                              { return  (*ItFileSetHt).first; }
102    /// All the following allow user to restrict DICOM file to be part
103    /// of a particular serie
104    void AddRestriction(TagKey const &key, std::string const &value, int op);
105
106    /// \brief Use additional series information such as ProtocolName
107    ///        and SeriesName to identify when a single SeriesUID contains
108    ///        multiple 3D volumes - as can occur with perfusion and DTI imaging
109    void SetUseSeriesDetails( bool useSeriesDetails )
110                                    { m_UseSeriesDetails = useSeriesDetails;}
111    bool GetUseSeriesDetails( ){ return m_UseSeriesDetails; }
112
113    // \brief Create a string that uniquely identifies a series.   By default
114    //         uses the SeriesUID.   If UseSeriesDetails(true) has been called,
115    //         then additional identifying information is used.
116    std::string CreateUniqueSeriesIdentifier( File * inFile );
117
118  
119 /**
120  * \brief Sets the LoadMode as a boolean string. 
121  *        LD_NOSEQ, LD_NOSHADOW, LD_NOSHADOWSEQ
122  *        ... (nothing more, right now)
123  *        WARNING : before using LD_NOSHADOW, be sure *all* your files
124  *        contain accurate values in the 0x0000 element (if any) 
125  *        of *each* Shadow Group. The parser will fail if the size is wrong !
126  * @param   mode Load mode to be used    
127  */
128    void SetLoadMode (int mode) { LoadMode = mode; }
129
130 /// Brief User wants the files to be sorted Direct Order (default value)
131    void SetSortOrderToDirect()  { DirectOrder = true;  }
132
133 /// Brief User wants the files to be sorted Reverse Order 
134    void SetSortOrderToReverse() { DirectOrder = false; }
135
136    /// to allow user to give is own comparison function
137    void SetUserLessThanFunction( BOOL_FUNCTION_PFILE_PFILE_POINTER userFunc ) 
138                         { UserLessThanFunction = userFunc; }  
139
140    XCoherentFileSetmap SplitOnOrientation(FileList *fileSet); 
141    XCoherentFileSetmap SplitOnPosition(FileList *fileSet); 
142    XCoherentFileSetmap SplitOnTagValue(FileList *fileSet,
143                                                uint16_t group, uint16_t elem);
144 protected :
145    SerieHelper();
146    
147 private:
148    void ClearAll();
149    bool UserOrdering(FileList *fileSet);
150    bool ImagePositionPatientOrdering(FileList *fileSet);
151    bool ImageNumberOrdering(FileList *fileSet);
152    bool FileNameOrdering(FileList *fileSet);
153    
154    static bool ImageNumberLessThan(File *file1, File *file2);
155    static bool ImageNumberGreaterThan(File *file1, File *file2);
156    static bool FileNameLessThan(File *file1, File *file2);
157    static bool FileNameGreaterThan(File *file1, File *file2);
158
159 //Attributes:
160    
161    SingleSerieUIDFileSetmap SingleSerieUIDFileSetHT;
162    SingleSerieUIDFileSetmap::iterator ItFileSetHt;
163    
164    typedef std::pair<TagKey, std::string> Rule;
165    typedef std::vector<Rule> SerieRestrictions;
166    SerieRestrictions Restrictions;
167    
168    // New style for (extented) Rules (Moreover old one doesn't compile)
169    typedef struct {
170       uint16_t group;
171       uint16_t elem;
172       std::string value;
173       int op;
174    } ExRule;
175    typedef std::vector<ExRule> SerieExRestrictions;
176    SerieExRestrictions ExRestrictions;
177    bool m_UseSeriesDetails;
178    
179    /// \brief Bit string integer (each one considered as a boolean)
180    ///        Bit 0 : Skip Sequences,    if possible
181    ///        Bit 1 : Skip Shadow Groups if possible
182    ///        Probabely, some more to add
183    int LoadMode;
184
185    /// \brief whether we want to sort in direct order or not (reverse order).
186    ///        To be used by aware user only
187    bool DirectOrder;
188
189    /// \brief If user knows more about his images than gdcm does,
190    ///        he may supply his own comparison function.
191     BOOL_FUNCTION_PFILE_PFILE_POINTER UserLessThanFunction;
192
193 };
194
195 } // end namespace gdcm
196
197 //-----------------------------------------------------------------------------
198 #endif