/*========================================================================= Program: wxMaracas Module: $RCSfile: marDicom.cpp,v $ Language: C++ Date: $Date: 2008/11/14 11:33:20 $ Version: $Revision: 1.2 $ Copyright: (c) 2002, 2003 License: This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ /* extern "C" { #include #include } #include "marDicom.h" #include static char* DicomTagsNames[] = { "ID_File_Name", "ID_SOP_Class_UID", "ID_SOP_Instance_UID", "ID_Study_Date", "ID_Series_Date", "ID_Acquisition_Date", "ID_Image_Date", "ID_Study_Time", "ID_Series_Time", "ID_Acquisition_Time", "ID_Image_Time", "ID_Modality", "ID_Manufacturer", "ID_Institution_Name", "ID_Study_Description", "ID_Series_Description", "ID_Admitting_Diagnoses_Description", "ID_Patient_Name", "ID_Patient_ID", "ID_Body_Part_Examined", "ID_Scanning_Sequence", "ID_Sequence_Variant", "ID_Scan_Options", "ID_MR_Acquisition_Type", "ID_Sequence_Name", "ID_Slice_Thickness", "ID_Repetition_Time", "ID_Echo_Time", "ID_Inversion_Time", "ID_Number_of_Averages", "ID_Imaging_Frequency", "ID_Imaged_Nucleus", "ID_Echo_Number", "ID_Magnetic_Field_Strength", "ID_Spacing_Between_Slices", "ID_Echo_Train_Length", "ID_Percent_Sampling", "ID_Percent_Phase_Field_of_View", "ID_Receiving_Coil", "ID_Patient_Position", "ID_Study_Instance_UID", "ID_Series_Instance_UID", "ID_Study_ID", "ID_Series_Number", "ID_Acquisition_Number", "ID_Image_Number", "ID_Patient_Orientation", "ID_Image_Position", "ID_Image_Position_Patient", "ID_Image_Orientation", "ID_Image_Orientation_Patient", "ID_Location", "ID_Frame_of_Reference_UID", "ID_Slice_Location", "ID_Image_Comments", "ID_Pixel_Spacing", "ID_Window_Center", "ID_Window_Width", }; // ------------------------------------------------------------------------- marDicom::marDicom( marParameters* p ) : marObject( p ), _actualStudy( "" ), _actualSerie( "" ), _volume( NULL ) { } // ---------------------------------------------------------------------------- wxArrayString marDicom_SelectDirs( wxString& root ) { wxArrayString ret; wxString it, tmp; tmp = root.c_str( ); tmp += "/*"; it = wxFindFirstFile( tmp, wxDIR ); while( !it.IsEmpty( ) ) { if( wxFileNameFromPath( it ).Cmp( "." ) != 0 && wxFileNameFromPath( it ).Cmp( ".." ) != 0 ) ret.Add( wxFileNameFromPath( it ) ); it = wxFindNextFile( ); } // fwhile ret.Sort( ); return( ret ); } // ------------------------------------------------------------------------- wxArrayString marDicom::getStudies( ) { return( marDicom_SelectDirs( getParameters( )->getStringParam( marParameters::e_dicom_images_directory ) ) ); } // ------------------------------------------------------------------------- wxArrayString marDicom::getSeries( ) { wxString tmp; tmp = getParameters( )->getStringParam( marParameters::e_dicom_images_directory ); tmp += '/'; tmp += _actualStudy; return( marDicom_SelectDirs( tmp ) ); } // ------------------------------------------------------------------------- wxArrayString marDicom::getStudyData( ) { int i; char** res; wxArrayString ret; wxString cad; if( _actualStudy != "" ) { cad = getParameters( )->getStringParam( marParameters::e_dicom_images_directory ); cad += '/'; cad += _actualStudy; // WARNING : Use of LibIDO to get the information. res = IdStrGetExamInfo( ( char* )cad.c_str( ), "*" ); for( i = 0; i < ID_dicom_tags_count; i++ ) { ret.Add( copystring( res[ i ] ) ); delete res[ i ]; } // rof ret[ID_File_Name] = _actualStudy; delete res; } // fi return( ret ); } // ------------------------------------------------------------------------- wxArrayString marDicom::getSerieData( ) { int i; char** res; wxArrayString ret; wxString cad; if( _actualSerie != "" ) { // WARNING : Use of LibIDO to get the information. cad = getParameters( )->getStringParam( marParameters::e_dicom_images_directory ); cad += '/'; cad += _actualStudy; cad += '/'; cad += _actualSerie; res = IdStrGetSerieInfo( ( char* )cad.c_str( ), "*" ); for( i = 0; i < ID_dicom_tags_count; i++ ) { ret.Add( copystring( res[ i ] ) ); delete res[ i ]; } // rof ret[ ID_File_Name ] = _actualSerie; delete res; } // fi return( ret ); } // ------------------------------------------------------------------------- wxArrayString marDicom_SelectFiles( wxString& root ) { wxString it, tmp; wxArrayString ret; tmp = root.c_str( ); tmp += "/*"; it = wxFindFirstFile( tmp, wxFILE ); while( !it.IsEmpty( ) ) { if( IdAcrIsAcrReadable( ( char* )it.c_str( ) ) ) // Check if DICOM ret.Add( it ); it = wxFindNextFile( ); } // fwhile ret.Sort( ); return( ret ); } // ------------------------------------------------------------------------- void marDicom::loadActualSerie( ) { wxString tmp; reset( ); tmp = getParameters( )->getStringParam( marParameters::e_dicom_images_directory ); tmp += '/'; tmp += _actualStudy; tmp += '/'; tmp += _actualSerie; _imageFileNames = marDicom_SelectFiles( tmp ); loadVolume( true ); } // ------------------------------------------------------------------------- bool marDicom_ReadAllImageData( wxString& fn, PPIMAGE_USHORT& ima, wxString& number, int& dX, int& dY, double& vX, double& vY, double& vZ ) { char** tmp; // char* stmp; // char* end; ima = ( PPIMAGE_USHORT )IdAcrReadFile( ( char* )fn.c_str( ), IMA_USHORT ); dX = IdImaDimX( ima ); dY = IdImaDimY( ima ); tmp = IdAcrInquireIRMInfo( ( char* )fn.c_str( ) ); number = tmp[ 16 ]; // printf("%s\n", tmp[20]); //stmp = strtok( tmp[ 20 ], "\\" ); //vX = strtod( stmp, &end ); //stmp = strtok( NULL, "\\" ); //vY = strtod( stmp, &end ); sscanf( tmp[ 20 ], "%lf\\%lf", &vX, &vY); //vZ = strtod( tmp[ 6 ], &end ); vZ = strtod( tmp[ 6 ], NULL ); // printf("Vx = %lf Vy = %lf Vz = %lf\n", vX, vY, vZ); //for( int i = 0; i < marDicom::ID_dicom_tags_count; i++ ) //delete tmp[ i ]; //delete tmp; return( true ); } // ------------------------------------------------------------------------- void marDicom::loadVolume( bool force ) { // //TODO: this function calls 11 534 336 to kVolume::setPixel !!!! // wxString number, tmp; int size, i, j, k, dx, dy, dz, loc; double vX, vY, vZ; PPIMAGE_USHORT ima_t; if( force || !_volume ) { freeVolume( ); _imageNumbers.Clear( ); dz = _imageFileNames.GetCount( ); if( dz > 0 ) { tmp = _imageFileNames[0 ]; marDicom_ReadAllImageData( tmp, ima_t, number, dx, dy, vX, vY, vZ ); getParameters( )->setDoubleParam( marParameters::e_voxel_x_dimension, vX ); getParameters( )->setDoubleParam( marParameters::e_voxel_y_dimension, vY ); getParameters( )->setDoubleParam( marParameters::e_voxel_z_dimension, vZ ); printf("dx = %i dy = %i dz = %i vX = %lf vY = %lf vZ = %lf\n", dx, dy, dz, vX, vY, vZ ); _volume = new kVolume( kVolume::USHORT, dx, dy, dz, vX, vY, vZ ); IdImaFree( ima_t ); // Loads real data for( k = 0; k < dz; k++ ) { tmp = _imageFileNames[ k ]; marDicom_ReadAllImageData( tmp, ima_t, number, dx, dy, vX, vY, vZ ); _imageNumbers.Add( number.c_str( ) ); for( j = 0; j < dy; j++ ) for( i = 0; i < dx; i++ ) _volume->setPixel( ima_t[ j ][ i ], i, j, k ); IdImaFree( ima_t ); } // rof } // fi } // fi } // ------------------------------------------------------------------------- void marDicom::freeVolume( ) { if( _volume ) delete _volume; _volume = NULL; } // ------------------------------------------------------------------------- bool marDicom::setActualStudy( wxString& s ) { wxString cad; if( _actualStudy != s ) { cad = getParameters( )->getStringParam( marParameters::e_dicom_images_directory ); cad += '/'; cad += s; if( wxDirExists( cad.c_str( ) ) ) { _actualStudy = s; _actualSerie = ""; return( true ); } else return( false ); } else return( true ); } // ------------------------------------------------------------------------- bool marDicom::setActualSerie( wxString& s ) { wxString cad; if( _actualSerie != s ) { cad = getParameters( )->getStringParam( marParameters::e_dicom_images_directory ); cad += '/'; cad += _actualStudy; cad += '/'; cad += s; if( wxDirExists( cad.c_str( ) ) ) { _actualSerie = s; return( true ); } else return( false ); } else return( true ); } // ------------------------------------------------------------------------- void marDicom::copyFrom( const marObject& from ) { // TODO } // ------------------------------------------------------------------------- bool marDicom::save( std::ofstream& os ) { int s; s = _actualStudy.length( ); os.write( ( const char* )&s, sizeof( int ) ); os.write( ( char* )_actualStudy.c_str( ), s * sizeof( char ) ); s = _actualSerie.length( ); os.write( ( const char* )&s, sizeof( int ) ); os.write( ( char* )_actualSerie.c_str( ), s * sizeof( char ) ); return( true ); } // ------------------------------------------------------------------------- bool marDicom::load( std::ifstream& is ) { int s; reset( ); is.read( ( char* )&s, sizeof( int ) ); _actualStudy.resize( s ); is.read( ( char* )_actualStudy.c_str( ), s * sizeof( char ) ); is.read( ( char* )&s, sizeof( int ) ); _actualSerie.resize( s ); is.read( ( char* )_actualSerie.c_str( ), s * sizeof( char ) ); return( true ); } // ---------------------------------------------------------------------------- wxArrayString marDicom::getRelationalArrayStudyData( ) { wxArrayString ret; wxArrayString inf = getStudyData( ); unsigned int i; for( i = 0; i < inf.GetCount( ); i++ ) { ret.Add( wxString( DicomTagsNames[ i ] ) ); ret.Add( wxString( inf[ i ] ) ); } // rof return( ret ); } // ---------------------------------------------------------------------------- wxArrayString marDicom::getRelationalArraySerieData( ) { wxArrayString ret; wxArrayString inf = getSerieData( ); unsigned int i; for( i = 0; i < inf.GetCount( ); i++ ) { ret.Add( wxString( DicomTagsNames[ i ] ) ); ret.Add( wxString( inf[ i ] ) ); } // rof return( ret ); } // eof - dicom.cxx */