Public Types | Public Member Functions | Protected Member Functions | Protected Attributes

mitk::FileSeriesReader Class Reference

#include <mitkFileSeriesReader.h>

Inheritance diagram for mitk::FileSeriesReader:
Inheritance graph
[legend]
Collaboration diagram for mitk::FileSeriesReader:
Collaboration graph
[legend]

List of all members.

Public Types

typedef FileSeriesReader Self
typedef FileReader Superclass
typedef itk::SmartPointer< SelfPointer
typedef itk::SmartPointer
< const Self
ConstPointer
typedef std::vector< std::string > MatchedFileNames

Public Member Functions

virtual const char * GetClassName () const
virtual MatchedFileNames GetMatchedFileNames ()

Protected Member Functions

 FileSeriesReader ()
virtual ~FileSeriesReader ()
virtual bool GenerateFileList ()

Protected Attributes

std::string m_FileName
std::string m_FilePrefix
std::string m_FilePattern
MatchedFileNames m_MatchedFileNames

Detailed Description

Provides a function which generates a list of files from a given prefix and pattern. Subclasses may use this function to load a series of files.

Definition at line 35 of file mitkFileSeriesReader.h.


Member Typedef Documentation

typedef itk::SmartPointer<const Self> mitk::FileSeriesReader::ConstPointer
typedef std::vector< std::string > mitk::FileSeriesReader::MatchedFileNames

Definition at line 38 of file mitkFileSeriesReader.h.

typedef itk::SmartPointer<Self> mitk::FileSeriesReader::Pointer

Constructor & Destructor Documentation

mitk::FileSeriesReader::FileSeriesReader (  ) [protected]

Definition at line 251 of file mitkFileSeriesReader.cpp.

  : m_FileName( "" ), m_FilePrefix( "" ), m_FilePattern( "" )
{}
mitk::FileSeriesReader::~FileSeriesReader (  ) [protected, virtual]

Definition at line 255 of file mitkFileSeriesReader.cpp.

{
}

Member Function Documentation

bool mitk::FileSeriesReader::GenerateFileList (  ) [protected, virtual]

Definition at line 27 of file mitkFileSeriesReader.cpp.

References m_FileName, m_MatchedFileNames, and MITK_INFO.

Referenced by mitk::VtkVolumeTimeSeriesReader::GenerateData(), mitk::StlVolumeTimeSeriesReader::GenerateData(), and mitk::PicVolumeTimeSeriesReader::GenerateOutputInformation().

{
    typedef std::vector<std::string> StringContainer;
    typedef std::map<unsigned int, std::string> SortedStringContainer;
    
    if ( m_FileName == "" )
    {
      throw itk::ImageFileReaderException( __FILE__, __LINE__, "FileName must be non-empty" );
    }
    //MITK_INFO << "FileName: "<< m_FileName <<", FilePrefix: "<< m_FilePrefix << ", FilePattern: "<< m_FilePattern << std::endl;
    
    // determine begin and end idexes of the last digit sequence in the 
    // filename from the sample file name
    // Therefore, walk backwards from the end of the filename until
    // a number is found. The string in front of the number is the prefix,
    // the string after the number is the extension.
    std::string basename, path;
    path = itksys::SystemTools::GetFilenamePath( m_FileName );
    basename = itksys::SystemTools::GetFilenameName( m_FileName );
    
    unsigned int digitBegin = 0;
    unsigned int digitEnd = 0;
    bool digitFound = false;
    for ( unsigned int i = basename.length() - 1; ; --i )
    {
      char character = basename[ i ];
      if ( character >= '0' && character <= '9' )
      {
        if (!digitFound)
        {
          digitEnd = i;
          digitBegin = i;  
          digitFound = true;
        } 
        else
          digitBegin = i;
      }
      else
      {
        //end of digit series found, jump out of loop!
        if (digitFound)
          break;
      }
      if ( i == 0 )
        break;
    }
    
    //
    // if there is no digit in the filename, then we have a problem
    // no matching filenames can be identified!
    // 
    if ( !digitFound )
    {
      itkWarningMacro("Filename contains no digit!");
      return false;
    }
    
    //
    // determine prefix and extension start and length
    //
    unsigned int prefixBegin = 0;
    unsigned int prefixLength = digitBegin;
    unsigned int extensionBegin = digitEnd + 1;
    unsigned int extensionLength = (digitEnd == basename.length() -1 ? 0 : basename.length() - 1 - digitEnd);    
    unsigned int numberLength = digitEnd - digitBegin + 1;
    
    //
    // extract prefix and extension
    //
    std::string prefix = "";
    if (prefixLength != 0)
      prefix = basename.substr( prefixBegin, prefixLength );
    std::string extension = "";
    if (extensionLength != 0)
      extension = basename.substr( extensionBegin, extensionLength );
    
    //
    // print debug information
    //
    /*
    MITK_INFO << "digitBegin      : " << digitBegin << std::endl;
    MITK_INFO << "digitEnd        : " << digitEnd << std::endl;
    MITK_INFO << "number of digits: " << numberLength << std::endl;
    MITK_INFO << "prefixBegin     : " << prefixBegin << std::endl;
    MITK_INFO << "prefixLength    : " << prefixLength << std::endl;
    MITK_INFO << "prefix          : " << prefix << std::endl;
    MITK_INFO << "extensionBegin  : " << extensionBegin << std::endl;
    MITK_INFO << "extensionLength : " << extensionLength << std::endl;
    MITK_INFO << "extension       : " << extension << std::endl;
    */
    if( (prefixLength + extensionLength + numberLength) != basename.length() )
    {
      throw itk::ImageFileReaderException( __FILE__, __LINE__, "prefixLength + extensionLength + numberLength != basenameLength" );
    }
    
    
    //
    // Load Directory
    //
    std::string directory = itksys::SystemTools::GetFilenamePath( m_FileName );
    itksys::Directory itkDir;
    if ( !itkDir.Load ( directory.c_str() ) )
    {
      itkWarningMacro ( << "Directory " << directory << " cannot be read!" );
      return false;
    }

    //
    // Get a list of all files in the directory
    //
    StringContainer unmatchedFiles;
    //unsigned long i;
    for ( unsigned long i = 0; i < itkDir.GetNumberOfFiles(); i++ )
    {
        // Only read files
        std::string filename = directory + "/" + itkDir.GetFile( i );
        if ( itksys::SystemTools::FileIsDirectory( filename.c_str() ) )
            continue;

        // store the filenames without path
        unmatchedFiles.push_back( itkDir.GetFile( i ) );
    }

    //
    // Match the file list against the file prefix and extension,
    // the result should be only the files that should be read
    //
    StringContainer matchedFiles;
    for ( StringContainer::iterator it = unmatchedFiles.begin() ; it != unmatchedFiles.end() ; ++it )
    {
        bool prefixMatch = false;
        bool extensionMatch = false;
        
        // check if the file prefix matches the current file
        if ( prefixLength != 0 )
          prefixMatch = ( it->find(prefix) == prefixBegin ); // check if prefix is found
        else
          prefixMatch = ( ( (*it)[0] >='0' ) && ( (*it)[0] <='9' ) ); //check if filename begins with digit
        
        // check if the file extension matches the current file
        if ( extensionLength != 0 )
          extensionMatch = ( it->find(extension) == it->length() - extensionLength ); // check if prefix is found
        else
          extensionMatch = ( ( (*it)[it->length()-1] >='0' ) && ( (*it)[it->length()-1] <='9' ) ); //check if filename ends with digit
        
        if ( prefixMatch && extensionMatch )
        {
            matchedFiles.push_back( *it );
        }
    }
    if ( matchedFiles.size() == 0 )
    {
      itkWarningMacro( << "Sorry, none of the files matched the prefix!" );
      return false;
    }

    //
    // parse the file names from back to front for digits
    // and convert them to a number. Store the filename and number
    // in a SortedStringContainer
    //
    SortedStringContainer sortedFiles;
    for ( StringContainer::iterator it = matchedFiles.begin() ; it != matchedFiles.end() ; ++it )
    {
      // parse the filename starting from pos digitBegin until we reach a non-digit
      // or the end of filename
      std::string number = "";
      std::string currentFilename(*it);
      for ( unsigned int i = digitBegin ; i < currentFilename.length() ; ++i)
      {
        char character = currentFilename[ i ];
        //do we have a digit?
        if ( character >= '0' && character <= '9' )
          number += character;
        else
          break; //end of digit series found, jump out of loop!
      }
      if ( number.length() == 0 )
      {
        // The file is not numbered, this is an error!
        // Nevertheless, we try the next files.
        itkWarningMacro( << "The filename " << *it << "does not contain a valid digit sequence but matches prefix and extension. Skipping file!" );
      }
      else
      {
        if ( ( number.length() + prefix.length() + extension.length() ) != it->length() )
        {
          itkWarningMacro("The file "<< *it <<" matches prefix and extension, but the string in beteen is not a single digit-sequence. Skipping file!");
        }
        else
        {
        // convert the number string into an integer and
        // insert the filname (including directory) into the SortedStringContainer
        unsigned int num = atoi( number.c_str() );
        sortedFiles.insert( std::make_pair( num, directory + "/" + *it ) );
        }
      }
    }
    if ( sortedFiles.size() == 0 )
    {
      itkWarningMacro( << "Sorry, no numbered files found, I can't load anything..." );
      return false;
    }

    //
    // Convert the sorted string container in a plain sorted vector of strings;
    //
    m_MatchedFileNames.clear();
    m_MatchedFileNames.resize( sortedFiles.size() );
    unsigned long index = 0;
    for ( SortedStringContainer::iterator it = sortedFiles.begin() ; it != sortedFiles.end() ; ++it, ++index )
    {
        m_MatchedFileNames[ index ] = it->second ;
        MITK_INFO << "Added " << it->second << " to the set of matched files!" << std::endl;
    }
    return true;
}
virtual const char* mitk::FileSeriesReader::GetClassName (  ) const [virtual]
mitk::FileSeriesReader::MatchedFileNames mitk::FileSeriesReader::GetMatchedFileNames (  ) [virtual]

Definition at line 246 of file mitkFileSeriesReader.cpp.

{
    return m_MatchedFileNames;
}

Member Data Documentation

std::string mitk::FileSeriesReader::m_FileName [protected]
std::string mitk::FileSeriesReader::m_FilePattern [protected]
std::string mitk::FileSeriesReader::m_FilePrefix [protected]

The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines