X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=lib%2Fsrc1%2Fbruker2dicom.cxx;h=34a5ea098417e34cc633ab4088edff4a4026fc0b;hb=7a849fb72c9e8d006fa69c74b24a3e12778c269f;hp=c2366e64bad6db9ed035aa2bcef69cf88e38da0b;hpb=0f985b82ed7fee7e14b9c5da54d49c4428a87c96;p=creaBruker.git diff --git a/lib/src1/bruker2dicom.cxx b/lib/src1/bruker2dicom.cxx index c2366e6..34a5ea0 100644 --- a/lib/src1/bruker2dicom.cxx +++ b/lib/src1/bruker2dicom.cxx @@ -11,7 +11,7 @@ bool Bruker2Dicom::Execute() { - // ----- Check input values ----- + // ----- Check input directory name ----- bool bigEndian = GDCM_NAME_SPACE::Util::IsCurrentProcessorBigEndian(); @@ -27,6 +27,8 @@ bool Bruker2Dicom::Execute() std::cout << "OK : [" << InputDirName << "] is a Directory." << std::endl; } + // ----- Check output directory name ----- + std::string strDirNameOut(OutputDirName); bool res=CreateDirectory(strDirNameOut); if (!res) { @@ -68,61 +70,107 @@ bool Bruker2Dicom::Execute() "subject"; if (verbose) std::cout << " Subject : [" << subject << "]" << std::endl; - canOpen =br_subject.LoadFile(subject); - + + bool subjectFound; + canOpen =br_subject.LoadFile(subject); if (!canOpen) { - std::cout << "Hopeless! no 'subject' found" << std::endl; - throw ( BrukerHopelessException ("Hopeless! no 'subject' found in root input directory ")); - //exit(0); /// \TODO throw an exception ! + //std::cout << "Hopeless! no 'subject' found" << std::endl; + //throw ( BrukerHopelessException ("Hopeless! no 'subject' found in root input directory ")); + + std::cout << "Not too much hope! no 'subject' found (Desperate try will be performed -default values- )" << std::endl; + subjectFound = false; } else { - br_subject.FillMap(); + br_subject.FillMap(); + subjectFound = true; } //br_subject.PrintSelf(); // get info for 'Study Description' - BrukerFieldData b_name=br_subject.GetFieldData("SUBJECT_name_string"); - std::string subject_name = b_name.GetStringValue()[0]; - strPatientName = subject_name; - cleanString(subject_name); - - BrukerFieldData b_entry=br_subject.GetFieldData("SUBJECT_entry"); - std::string subject_entry = b_entry.GetStringValue()[0]; - //cleanString(subject_entry); - subject_entry = subject_entry.substr(11, subject_entry.size()-11); + if (subjectFound) + { + BrukerFieldData b_name=br_subject.GetFieldData("SUBJECT_name_string"); + subject_name = b_name.GetStringValue()[0]; + strPatientName = subject_name; + cleanString(subject_name); + } + else + subject_name ="defaultPatName"; + + // creation directory : 'nom du patient' + std::string tempStringPatDir(OutputDirName); + tempStringPatDir = tempStringPatDir + GDCM_NAME_SPACE::GDCM_FILESEPARATOR + subject_name; + + res=CreateDirectory(tempStringPatDir); + if (!res) { + std::cout << "[" << tempStringPatDir << "] Directory creation failure " << std::endl; + throw ( BrukerHopelessException ("Patient directory creation failure ")); + } + + std::string subject_entry; + std::string subject_position; + std::string subject_date; + std::string subject_study_name; - BrukerFieldData b_position=br_subject.GetFieldData("SUBJECT_position"); - std::string subject_position = b_position.GetStringValue()[0]; - //cleanString(subject_position); - subject_position = subject_position.substr(9, subject_position.size()-9); + if (subjectFound) + { + BrukerFieldData b_entry=br_subject.GetFieldData("SUBJECT_entry"); + subject_entry = b_entry.GetStringValue()[0]; + //cleanString(subject_entry); + subject_entry = subject_entry.substr(11, subject_entry.size()-11); + + BrukerFieldData b_position=br_subject.GetFieldData("SUBJECT_position"); + subject_position = b_position.GetStringValue()[0]; + //cleanString(subject_position); + subject_position = subject_position.substr(9, subject_position.size()-9); - BrukerFieldData b_date=br_subject.GetFieldData("SUBJECT_date"); - std::string subject_date = b_date.GetStringValue()[0]; - strStudyTimeDate = subject_date; - cleanString(subject_date); + BrukerFieldData b_date=br_subject.GetFieldData("SUBJECT_date"); + subject_date = b_date.GetStringValue()[0]; + strStudyTimeDate = subject_date; + cleanString(subject_date); - BrukerFieldData b_study_name=br_subject.GetFieldData("SUBJECT_study_name"); - std::string subject_study_name = b_study_name.GetStringValue()[0]; - subject_study_name = subject_study_name.substr(1, subject_study_name.size()-2); - cleanString(subject_date); - - // subject_name is already in 'Patient Name' - strStudyDescr = /*subject_name + "." + */ subject_study_name + "." + subject_entry + "." + subject_position + "." + subject_date; - + BrukerFieldData b_study_name=br_subject.GetFieldData("SUBJECT_study_name"); + subject_study_name = b_study_name.GetStringValue()[0]; + subject_study_name = subject_study_name.substr(1, subject_study_name.size()-2); + cleanString(subject_study_name); + } + else // Desperate trick when file 'subject' is missing + { + subject_entry = "HeadFirst"; // Why not? + subject_position = "Supine"; // Why not? + strStudyTimeDate = "06_06_06_6_June_1666"; // Why not? + subject_date = "6_June_1666"; // Why not? + subject_study_name = "defStudyName"; // Why not? + } + // subject_name is already in 'Patient Name' + strStudyDescr = /*subject_name + "." + */ subject_study_name + "." + subject_entry + "." + subject_position + "." + subject_date; + + // creation directory : 'nom de la Study' + + std::string tempStringStudyDir(OutputDirName); + tempStringStudyDir = tempStringPatDir + GDCM_NAME_SPACE::GDCM_FILESEPARATOR + strStudyDescr; + + res=CreateDirectory(tempStringStudyDir); + if (!res) { + std::cout << "[" << tempStringStudyDir << "] Directory creation failure " << std::endl; + throw ( BrukerHopelessException ("Study directory creation failure ")); + } + char outputDirName[(unsigned int) PATH_MAX+2]; - strStudyUID = GDCM_NAME_SPACE::Util::CreateUniqueUID(); - serieNumber = 0; + strStudyUID = GDCM_NAME_SPACE::Util::CreateUniqueUID(); + serieNumber = 0; instanceNumber = 0; + // ----------------------------------------------------- // Iterate to ALL the objets(files/directories) found in the input directory // (this is level ZERO) // each Directory (name : 1, 2, 3, ...) will be a Dicom Serie // ----------------------------------------------------- - + GDCM_NAME_SPACE::DirListType::iterator it; for (it = fileNames.begin(); @@ -143,6 +191,7 @@ bool Bruker2Dicom::Execute() br_acqp.LoadFile(strAcqp); br_acqp.FillMap(); +//std::cout << "out of br_acqp.FillMap " << std::endl; std::string acqp_scan_name; std::string acqp_method; std::string acqp_protocol_location; @@ -150,26 +199,32 @@ bool Bruker2Dicom::Execute() BrukerFieldData b_protocol_location=br_acqp.GetFieldData("ACQ_protocol_location"); acqp_protocol_location = b_protocol_location.GetStringValue()[0]; cleanString(acqp_protocol_location); - + +//std::cout << "out of br_acqp.FillMap 1" << std::endl; BrukerFieldData b_scan_name=br_acqp.GetFieldData("ACQ_scan_name"); +//std::cout << "out of br_acqp.FillMap 11" << std::endl; acqp_scan_name = b_scan_name.GetStringValue()[0]; +//std::cout << "out of br_acqp.FillMap 12 [" << acqp_scan_name << "]" << std::endl; cleanString(acqp_scan_name); +//std::cout << "out of br_acqp.FillMap 2" << std::endl; + BrukerFieldData b_method=br_acqp.GetFieldData("ACQ_method"); + b_method.PrintSelf(); + acqp_method = b_method.GetStringValue()[0]; - BrukerFieldData b_method=br_acqp.GetFieldData("ACQ_method"); - acqp_method = b_method.GetStringValue()[0]; cleanString(acqp_method); - +//std::cout << "out of br_acqp.FillMap 3" << std::endl; BrukerFieldData b_list_size = br_acqp.GetFieldData("ACQ_O1_list_size"); - //b_list_size.PrintSelf(); //JP +//std::cout << "out of br_acqp.FillMap 4" << std::endl; + //b_list_size.PrintSelf(); //JP nbSlices = b_list_size.GetIntValue()[0]; - +//std::cout << "out of br_acqp.FillMap 5" << std::endl; strSerieDescr = GDCM_NAME_SPACE::Util::GetName(*it) /* + "." + acqp_protocol_location */ // always the same (in each acquisition) + "." + acqp_scan_name + "." + acqp_method.c_str(); - sprintf(outputDirName, "%s%c%s", OutputDirName.c_str(), + sprintf(outputDirName, "%s%c%s", tempStringStudyDir.c_str(), //OutputDirName.c_str(), GDCM_NAME_SPACE::GDCM_FILESEPARATOR, strSerieDescr.c_str() ); @@ -193,7 +248,6 @@ bool Bruker2Dicom::Execute() } // end of : for (GDCM_NAME_SPACE::DirListType::iterator it } - // ===================================================================== void Bruker2Dicom::DealWithNiveau1(std::string level1Directory, std::string currentOutputDirName) { @@ -286,7 +340,7 @@ void Bruker2Dicom::DealWithNiveau1(std::string level1Directory, std::string curr br_method.FillMap(); /* a recuperer : - ##$PVM_Fov (dimension) + ##$PVM_Fov (dimension) // ou plutot RECO_fov ! */ /* dans method (pour perfusion seulement?) : @@ -297,7 +351,7 @@ void Bruker2Dicom::DealWithNiveau1(std::string level1Directory, std::string curr 7 1 */ try { - DealWithNiveau2(*it,outputDirName ); + DealWithNiveau2(*it, outputDirName); } catch (BrukerHopelessException &e) { @@ -443,6 +497,7 @@ void Bruker2Dicom::DealWithNiveau3(std::string level3Directory, std::string curr fileNames = dirList.GetFilenames(); char original2dseqName [(unsigned int) PATH_MAX+2]; + char original2dseqName_XXX [(unsigned int) PATH_MAX+2]; char currentOutputMhdDirName [(unsigned int) PATH_MAX+2]; char outputMhdFileName [(unsigned int) PATH_MAX+2]; @@ -521,7 +576,6 @@ void Bruker2Dicom::DealWithNiveau3(std::string level3Directory, std::string curr //std::cout << "------------------------------------------------------------------------------------------------" << std::cout; // br_reco.PrintSelf(); // std::cout << "------------------------------------------------------------------------------------------------" << std::cout; - // -------------------end try reco @@ -549,13 +603,43 @@ void Bruker2Dicom::DealWithNiveau3(std::string level3Directory, std::string curr std::string mhdDataPixelType; int pixelSize; getImhDataType(bDPT, mhdDataPixelType, pixelSize); - + + + /* + + // See mail Denis : + // En regle generale il vaut mieux que l'on passe par RECO_* + // pour extraire les parametres de l'image + // + BrukerFieldData fov = br_method.GetFieldData("PVM_Fov"); double fovX = fov.GetDoubleValue()[0]; double fovY = fov.GetDoubleValue()[1]; if (verbose) std::cout << "FOV (ds method) " << fovX << " " << fovY << std::endl; + BrukerFieldData spatResol = br_method.GetFieldData("PVM_SpatResol"); + double spatResolX = spatResol.GetDoubleValue()[0]; + double spatResolY = spatResol.GetDoubleValue()[1]; + if (verbose) + std::cout << "SpatResol (ds method) " << spatResolX << " " << spatResolY << std::endl; +*/ + + +// Better we use 'get' accessors from BrukerImage class, as Denis wrote them + + BrukerFieldData fov = br_reco.GetFieldData("RECO_Fov"); + double fovX = fov.GetDoubleValue()[0]; + double fovY = fov.GetDoubleValue()[1]; + if (verbose) + std::cout << "FOV (ds method) " << fovX << " " << fovY << std::endl; + + BrukerFieldData spatResol = br_reco.GetFieldData("PVM_SpatResol"); + double spatResolX = spatResol.GetDoubleValue()[0]; + double spatResolY = spatResol.GetDoubleValue()[1]; + if (verbose) + std::cout << "SpatResol (ds method) " << spatResolX << " " << spatResolY << std::endl; + /// \TODO probabely a more sophisticated accessor will be necessary : /// (cf : non contiguous slices, overlapping, slice thickness, space between slices, etc) BrukerFieldData bsliceDistance = br_method.GetFieldData("PVM_SPackArrSliceDistance"); @@ -598,11 +682,19 @@ void Bruker2Dicom::DealWithNiveau3(std::string level3Directory, std::string curr fp = fopen(original2dseqName, "rb"); if (!fp) { - std::cout << "Cannot open [" << original2dseqName << "] for reading" << std::endl; - throw ( BrukerHopelessException ("Hopeless! Cannot open '2dseq'")); - //exit (0); + // try 2dseq_Angio2D ?!? + + sprintf( original2dseqName_XXX, "%s%s", original2dseqName, "_Angio2D"); + fp = fopen(original2dseqName_XXX, "rb"); + if (!fp) + { + std::cout << "Cannot open [" << original2dseqName << "] nor [" << original2dseqName_XXX << "] for reading" << std::endl; + fclose(fp); + throw ( BrukerHopelessException ("Hopeless! Cannot open '2dseq'")); + //exit (0); + } } - + unsigned char *buffer_2dseq = new unsigned char[NX*NY*pixelSize*nbSlices*nbInstants]; ///\ TODO : find a safer way to be sure to read everything! size_t lgr = fread(buffer_2dseq, 1, NX*NY*pixelSize*nbSlices*nbInstants, fp); @@ -620,7 +712,7 @@ void Bruker2Dicom::DealWithNiveau3(std::string level3Directory, std::string curr //return; throw (e); } - + serieNumber++; strSerieUID = GDCM_NAME_SPACE::Util::CreateUniqueUID(); if (nbInstants==1) // creer un seul fichier .mhd pour toutes les Slices! (images natives) @@ -646,7 +738,8 @@ void Bruker2Dicom::DealWithNiveau3(std::string level3Directory, std::string curr fprintf(fp, "BinaryDataByteOrderMSB = False\n" ); fprintf(fp, "DimSize = %d %d %d\n", NX, NY, nbSlices ); fprintf(fp, "HeaderSize = %d\n", 0); - fprintf(fp, "ElementSpacing = %lf %lf %lf\n",fovX/NY, fovY/NY, sliceDistance ); + //fprintf(fp, "ElementSpacing = %lf %lf %lf\n",fovX/NY, fovY/NY, sliceDistance ); + fprintf(fp, "ElementSpacing = %lf %lf %lf\n", spatResolX, spatResolY, sliceDistance ); fprintf(fp, "Position = 0 0 %d\n", 0 ); fprintf(fp, "Offset = 0 0 0\n" ); fprintf(fp, "CenterOfRotation = 0 0 0\n" ); @@ -675,16 +768,17 @@ void Bruker2Dicom::DealWithNiveau3(std::string level3Directory, std::string curr { sprintf(output2dseqSliceFileName, "%s%c2dseq_All_the_Slices.dcm", currentOutputDirName.c_str(), GDCM_NAME_SPACE::GDCM_FILESEPARATOR); - + /* ----------- Write Dicom Image ---------------*/ MakeDicomImage(buffer_2dseq, NX, NY, nbFrames, pixelSize, - fovX/NY, fovY/NY, sliceDistance, + //fovX/NY, fovY/NY, sliceDistance, + spatResolX, spatResolY, sliceDistance, output2dseqSliceFileName, - strPatientName, + subject_name, day, strStudyUID, strSerieUID, @@ -696,12 +790,11 @@ void Bruker2Dicom::DealWithNiveau3(std::string level3Directory, std::string curr ); } // end if dicom } // end if nbInstants = 1 - + else // more than ONE instant { // Interleaved ! // it's (slice1,slide2, ...)t1 ; (slice1,slide2, ...)t2 ; ... - unsigned char *pixelsForCurrentSlice = new unsigned char[NX*NY*pixelSize*nbInstants]; k = 0; @@ -731,8 +824,9 @@ void Bruker2Dicom::DealWithNiveau3(std::string level3Directory, std::string curr fprintf(fp, "BinaryDataByteOrderMSB = False\n" ); fprintf(fp, "DimSize = %d %d %d\n", NX, NY, nbInstants); fprintf(fp, "HeaderSize = %d\n", 0); - fprintf(fp, "ElementSpacing = %lf %lf %lf\n",fovX/NY, fovY/NY, 1.0 ); // slice distance : no meaning for temporal serie - fprintf(fp, "Position = 0 0 %d\n", sliceNb ); + //fprintf(fp, "ElementSpacing = %lf %lf %lf\n",fovX/NY, fovY/NY, 1.0 ); // + fprintf(fp, "ElementSpacing = %lf %lf %lf\n",spatResolX, spatResolY, 1.0 ); //slice distance : no meaning for temporal serie + fprintf(fp, "Position = 0 0 %d\n", sliceNb ); fprintf(fp, "Offset = 0 0 0\n" ); fprintf(fp, "CenterOfRotation = 0 0 0\n" ); fprintf(fp, "ElementNumberOfChannels = 1\n" ); @@ -815,9 +909,10 @@ void Bruker2Dicom::DealWithNiveau3(std::string level3Directory, std::string curr NY, nbInstants, pixelSize, - fovX/NY, fovY/NY, sliceDistance, + spatResolX, spatResolY, sliceDistance, + //fovX/NY, fovY/NY, sliceDistance, output2dseqSliceFileName, - strPatientName, + subject_name, day, strStudyUID, strSerieUID, @@ -838,13 +933,13 @@ void Bruker2Dicom::DealWithNiveau3(std::string level3Directory, std::string curr } // end nbInstants == 1 delete [] buffer_2dseq; /**/ - - + + // ----------------------------------------------------- // deal with MatLab-generated Carto file. // ----------------------------------------------------- - - dealWithCarto(fileNames, NX, NY, nbSlices, fovX, fovY, sliceDistance, + + dealWithCarto(fileNames, NX, NY, nbSlices, /*fovX, fovY,*/ spatResolX, spatResolY, sliceDistance, copyFile, currentOutputDirName, outputMhdFileName, output2dseqCartoName); } @@ -852,7 +947,8 @@ void Bruker2Dicom::DealWithNiveau3(std::string level3Directory, std::string curr // =========================================================================================== void Bruker2Dicom::dealWithCarto(GDCM_NAME_SPACE::DirListType &fileNames, int NX, int NY, int nbSlices, - double fovX, double fovY, double sliceDistance, + /*double fovX, double fovY, */ + double spatResolX, double spatResolY, double sliceDistance, char *copyFile, std::string ¤tOutputDirName, char *outputMhdFileName, char *output2dseqCartoName) { @@ -867,7 +963,7 @@ void Bruker2Dicom::dealWithCarto(GDCM_NAME_SPACE::DirListType &fileNames, int NX GDCM_NAME_SPACE::DirListType::iterator it; char file_name_ident[500]; FILE *fp; - + // Iterate to ALL the objets(files/directories) found in the input directory for (it = fileNames.begin(); it != fileNames.end(); @@ -879,10 +975,10 @@ void Bruker2Dicom::dealWithCarto(GDCM_NAME_SPACE::DirListType &fileNames, int NX if (verbose) std::cout << "--- [" << *it << "] is a file..." << std::endl; - icode = 0; - iseparator = 0; + icode = 0; while (code[icode][0] != 0) - { + { + iseparator = 0; while (separator[iseparator][0] != 0) { sprintf(file_name_ident, "2dseq%s%s",separator[iseparator],code[icode]); // e.g "2dseq_ADC" @@ -892,7 +988,7 @@ void Bruker2Dicom::dealWithCarto(GDCM_NAME_SPACE::DirListType &fileNames, int NX if ( loc != std::string::npos ) { - + ///\ TODO : find a safer way to be sure to read everything! unsigned char *buffer_carto = new unsigned char[NX*NY*sizeof(double)*nbSlices]; fp = fopen ( (*it).c_str(), "rb"); @@ -902,9 +998,10 @@ void Bruker2Dicom::dealWithCarto(GDCM_NAME_SPACE::DirListType &fileNames, int NX } fread(buffer_carto, NX*NY*sizeof(double), nbSlices, fp); + // ?!? sprintf(copyFile, "cp %s %s%c%s", (*it).c_str() , std::cout << "Deal with Carto file :[" <<*it << "], computed length : " << NX*NY*sizeof(double)*nbSlices << std::endl; - std::string lastFileName = GDCM_NAME_SPACE::Util::GetName((*it).c_str()); + std::string lastFileName = GDCM_NAME_SPACE::Util::GetName((*it).c_str()); if (mhd) { // Copy the data file in the new directory @@ -912,10 +1009,10 @@ void Bruker2Dicom::dealWithCarto(GDCM_NAME_SPACE::DirListType &fileNames, int NX currentOutputDirName.c_str(),GDCM_NAME_SPACE::GDCM_FILESEPARATOR, lastFileName.c_str()); system(copyFile); sprintf(outputMhdFileName, "%s%c%s%s", - currentOutputDirName.c_str(),GDCM_NAME_SPACE::GDCM_FILESEPARATOR, lastFileName.c_str(), ".mhd" ); + currentOutputDirName.c_str(),GDCM_NAME_SPACE::GDCM_FILESEPARATOR, lastFileName.c_str(), ".mhd" ); if (verbose) std::cout << "--- Output Carto MHD file [" << outputMhdFileName << "]" << std::endl; - + FILE *fp; fp=fopen(outputMhdFileName, "w"); if (!fp) @@ -929,9 +1026,8 @@ void Bruker2Dicom::dealWithCarto(GDCM_NAME_SPACE::DirListType &fileNames, int NX fprintf(fp, "BinaryData = True \n" ); fprintf(fp, "BinaryDataByteOrderMSB = False\n" ); fprintf(fp, "DimSize = %d %d %d\n", NX, NY, nbSlices); - fprintf(fp, "ElementSpacing = %lf %lf %lf\n",fovX/NY, fovY/NY, sliceDistance ); fprintf(fp, "HeaderSize = %d\n", 0 ); - fprintf(fp, "ElementSpacing = %lf %lf %lf\n",fovX/NY, fovY/NY, sliceDistance ); + fprintf(fp, "ElementSpacing = %lf %lf %lf\n",spatResolX, spatResolY, sliceDistance ); fprintf(fp, "Position = 0 0 0\n" ); fprintf(fp, "Offset = 0 0 0\n" ); fprintf(fp, "CenterOfRotation = 0 0 0\n" ); @@ -961,9 +1057,10 @@ void Bruker2Dicom::dealWithCarto(GDCM_NAME_SPACE::DirListType &fileNames, int NX NY, nbSlices, 8, // pixelSize - fovX/NY, fovY/NY, sliceDistance, + //fovX/NY, fovY/NY, sliceDistance, + spatResolX, spatResolY, sliceDistance, output2dseqCartoName, - strPatientName, + subject_name, day, strStudyUID, strSerieUID, @@ -979,14 +1076,15 @@ void Bruker2Dicom::dealWithCarto(GDCM_NAME_SPACE::DirListType &fileNames, int NX if (verbose) std::cout << "--- End writing Carto DICOM file [" << output2dseqCartoName << "]" << std::endl; break; // don't check for more ident on same file name! - } - iseparator ++; - } - icode++; - } - } - } // end iterate on files -} + + } // end deal with _ADC, -adc, etc + iseparator ++; + } // end iterate speparators + icode++; + } // end iterate code + } // end boost::filesystem::is_regular(*it) + } // end iterate on all objects (files, dir, etc) +} // end method // ========================================================================================================== @@ -1021,7 +1119,7 @@ bool Bruker2Dicom::CreateDirectory(std::string OutputDirName) else { if (verbose) - std::cout << "Output Directory [" << OutputDirName << "] already exists; Used as is." << std::endl; + std::cout << "Output Directory [" << OutputDirName << "] already exists; Used as is." << std::endl; } return 1; @@ -1361,8 +1459,8 @@ std::cout << "charImageOrientation " << fileH->Delete(); throw ( BrukerHopelessException ("Level 1 Unable to write Dicom file ")); } - if (verbose) - file->Print(); + //if (verbose) + // file->Print(); file->Delete(); fileH->Delete();