diff --git a/Modules/IGT/IGTFilters/mitkNavigationDataRecorder.cpp b/Modules/IGT/IGTFilters/mitkNavigationDataRecorder.cpp index 8d272ae661..b1c1764a09 100644 --- a/Modules/IGT/IGTFilters/mitkNavigationDataRecorder.cpp +++ b/Modules/IGT/IGTFilters/mitkNavigationDataRecorder.cpp @@ -1,261 +1,262 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2007-12-11 14:46:19 +0100 (Di, 11 Dez 2007) $ Version: $Revision: 13129 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkNavigationDataRecorder.h" #include #include #include #include mitk::NavigationDataRecorder::NavigationDataRecorder() { m_NumberOfInputs = 0; m_RecordingMode = NormalFile; m_Recording = false; m_NumberOfRecordedFiles = 0; m_Stream = NULL; m_FileName = ""; m_SystemTimeClock = RealTimeClock::New(); + m_OutputFormatMember = mitk::NavigationDataRecorder::xml; //To get a start time mitk::TimeStamp::GetInstance()->Start(this); } mitk::NavigationDataRecorder::~NavigationDataRecorder() { } void mitk::NavigationDataRecorder::GenerateData() { } void mitk::NavigationDataRecorder::AddNavigationData( const NavigationData* nd ) { // Process object is not const-correct so the const_cast is required here this->SetNthInput(m_NumberOfInputs, const_cast< mitk::NavigationData * >( nd ) ); m_NumberOfInputs++; this->Modified(); } void mitk::NavigationDataRecorder::SetRecordingMode( RecordingMode mode ) { m_RecordingMode = mode; this->Modified(); } void mitk::NavigationDataRecorder::Update() { if (m_Recording) { DataObjectPointerArray inputs = this->GetInputs(); //get all inputs mitk::NavigationData::TimeStampType timestamp=0.0; // timestamp for mitk time timestamp = mitk::TimeStamp::GetInstance()->GetElapsed(); mitk::NavigationData::TimeStampType sysTimestamp = 0.0; // timestamp for system time sysTimestamp = m_SystemTimeClock->GetCurrentStamp(); // cast system time double value to stringstream to avoid low precision rounding std::ostringstream strs; strs.precision(15); // rounding precision for system time double value strs << sysTimestamp; std::string sysTimeStr = strs.str(); for (unsigned int index = 0; index < inputs.size(); index++) { mitk::NavigationData* nd = dynamic_cast(inputs[index].GetPointer()); nd->Update(); // call update to propagate update to previous filters mitk::NavigationData::PositionType position; mitk::NavigationData::OrientationType orientation(0.0, 0.0, 0.0, 0.0); mitk::NavigationData::CovarianceMatrixType matrix; bool hasPosition = true; bool hasOrientation = true; bool dataValid = false; position.Fill(0.0); matrix.SetIdentity(); position = nd->GetPosition(); orientation = nd->GetOrientation(); matrix = nd->GetCovErrorMatrix(); hasPosition = nd->GetHasPosition(); hasOrientation = nd->GetHasOrientation(); dataValid = nd->IsDataValid(); //use this one if you want the timestamps of the source //timestamp = nd->GetTimeStamp(); //a timestamp is never < 0! this case happens only if you are using the timestamp of the nd object instead of getting a new one if (timestamp >= 0) { TiXmlElement* elem = new TiXmlElement("ND"); elem->SetDoubleAttribute("Time", timestamp); elem->SetAttribute("SystemTime", sysTimeStr); // tag for system time elem->SetDoubleAttribute("Tool", index); elem->SetDoubleAttribute("X", position[0]); elem->SetDoubleAttribute("Y", position[1]); elem->SetDoubleAttribute("Z", position[2]); elem->SetDoubleAttribute("QX", orientation[0]); elem->SetDoubleAttribute("QY", orientation[1]); elem->SetDoubleAttribute("QZ", orientation[2]); elem->SetDoubleAttribute("QR", orientation[3]); elem->SetDoubleAttribute("C00", matrix[0][0]); elem->SetDoubleAttribute("C01", matrix[0][1]); elem->SetDoubleAttribute("C02", matrix[0][2]); elem->SetDoubleAttribute("C03", matrix[0][3]); elem->SetDoubleAttribute("C04", matrix[0][4]); elem->SetDoubleAttribute("C05", matrix[0][5]); elem->SetDoubleAttribute("C10", matrix[1][0]); elem->SetDoubleAttribute("C11", matrix[1][1]); elem->SetDoubleAttribute("C12", matrix[1][2]); elem->SetDoubleAttribute("C13", matrix[1][3]); elem->SetDoubleAttribute("C14", matrix[1][4]); elem->SetDoubleAttribute("C15", matrix[1][5]); if (dataValid) elem->SetAttribute("Valid",1); else elem->SetAttribute("Valid",0); if (hasOrientation) elem->SetAttribute("hO",1); else elem->SetAttribute("hO",0); if (hasPosition) elem->SetAttribute("hP",1); else elem->SetAttribute("hP",0); *m_Stream << " " << *elem << std::endl; delete elem; } } } } void mitk::NavigationDataRecorder::StartRecording() { if (m_Recording) { std::cout << "Already recording please stop before start new recording session" << std::endl; return; } if (m_Stream == NULL) { std::stringstream ss; std::ostream* stream; //An existing extension will be cut and replaced with .xml std::string tmpPath = itksys::SystemTools::GetFilenamePath(m_FileName); m_FileName = itksys::SystemTools::GetFilenameWithoutExtension(m_FileName); ss << tmpPath << "/" << m_FileName << "-" << m_NumberOfRecordedFiles << ".xml"; switch(m_RecordingMode) { case Console: stream = &std::cout; break; case NormalFile: //Check if there is a file name and path if (m_FileName == "") { stream = &std::cout; std::cout << "No file name or file path set the output is redirected to the console"; } else { stream = new std::ofstream(ss.str().c_str()); } break; case ZipFile: stream = &std::cout; std::cout << "Sorry no ZipFile support yet"; break; default: stream = &std::cout; break; } StartRecording(stream); } } void mitk::NavigationDataRecorder::StartRecording(std::ostream* stream) { if (m_Recording) { std::cout << "Already recording please stop before start new recording session" << std::endl; return; } m_Stream = stream; m_Stream->precision(10); //TODO store date and GMT time if (m_Stream) { *m_Stream << "" << std::endl; /**m_Stream << "" << std::endl;*/ // should be a generic version, meaning a member variable, which has the actual version *m_Stream << " " << "" << std::endl; m_Recording = true; } } void mitk::NavigationDataRecorder::StopRecording() { if (!m_Recording) { std::cout << "You have to start a recording first" << std::endl; return; } if (m_Stream) { *m_Stream << "" << std::endl; } m_NumberOfRecordedFiles++; m_Stream = NULL; m_Recording = false; } \ No newline at end of file diff --git a/Modules/IGT/IGTFilters/mitkNavigationDataRecorder.h b/Modules/IGT/IGTFilters/mitkNavigationDataRecorder.h index 5aed2f8037..7352a88df7 100644 --- a/Modules/IGT/IGTFilters/mitkNavigationDataRecorder.h +++ b/Modules/IGT/IGTFilters/mitkNavigationDataRecorder.h @@ -1,150 +1,170 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2008-02-08 13:23:19 +0100 (Fr, 08 Feb 2008) $ Version: $Revision: 13561 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _MITK_NavigationDataRecorder_H #define _MITK_NavigationDataRecorder_H #include #include "mitkNavigationData.h" #include #include namespace mitk { /**Documentation * \brief This class records NavigationData objects. * * The output of this class is formated as a XML document. * * Internal this class uses streams for recording NavigationData objects. Therefore different types of output are possible * and can be set with the SetOutputMode() method. The default output is directed to the console. If you want to save into a * file you have to set a file name and the path. The recording is started with the call of the method StartRecording(). Now * every Update() stores the current state of the added NavigationDatas. With StopRecording() the stream is stopped. With * another call of StartRecording() the output is written to a new file with incremented filename counter. * * \warning At the moment there is no check if the file is already existing and this class will override existing files. * \ingroup IGT */ class MitkIGT_EXPORT NavigationDataRecorder : public itk::ProcessObject { public: mitkClassMacro( NavigationDataRecorder, itk::ProcessObject ); itkNewMacro( Self ); /** * \brief sets the file name for the OutputMode NormalFile and ZipFile * * Any extensions will be cut * \warning existing files will be overridden * \warning do not use "." in file names at the end */ itkSetStringMacro(FileName); /** * \brief Returns the file name of the recording file (in OutputMode NormalFile and ZipFile) */ itkGetStringMacro(FileName); /** * \brief Returns whether the NavigationDataRecorder is recording or not */ itkGetMacro(Recording,bool); /** * \brief Adds the input NavigationDatas */ virtual void AddNavigationData(const NavigationData* nd); /**Documentation * \brief Starts the recording with the presetted OutputMode * this method calls StartRecording(std::ostream*) */ void StartRecording(); /**Documentation * \brief Starts the recording with an own preinitialized stream */ void StartRecording(std::ostream* stream); /**Documentation * \brief Stops the recording and closes the stream */ void StopRecording(); /**Documentation * \brief Every call of update causes one line for each added NavigationData in the output if the recording was started */ virtual void Update(); /**Documentation * \brief Determines where the output is directed to * * Console: std::cout * NormalFile: std::ofstream * ZipFile: Not supported yet -> std::cout */ enum RecordingMode { Console, NormalFile, ZipFile }; + /**Documentation + * \brief Determines the output format + * + * xml: XML format, also default, can be read by NavigationDataPlayer + * csv: use to export in excel, matlab, etc. + */ + enum OutputFormat + { + xml, + csv + }; + /**Documentation * \brief Sets the recording mode which causes different types of output streams * see enum RecordingMode */ void SetRecordingMode(RecordingMode mode); + /**Documentation + * \brief Sets the output format which causes different formats of output streams. The XML format is default. + * Also see enum OutputFormat for more information. + */ + itkSetMacro(OutputFormatMember,mitk::NavigationDataRecorder::OutputFormat); + protected: /**Documentation * \brief filter execute method here it is not used * */ virtual void GenerateData(); NavigationDataRecorder(); virtual ~NavigationDataRecorder(); std::string m_FileName; ///< stores the file name and path unsigned int m_NumberOfInputs; ///< counts the numbers of added input NavigationDatas std::ostream* m_Stream; ///< the output stream RecordingMode m_RecordingMode; ///< stores the mode see enum RecordingMode + OutputFormat m_OutputFormatMember; ///< stores the output format; see enum OutputFormat + bool m_Recording; ///< indicates whether the recording is started or not unsigned int m_NumberOfRecordedFiles; ///< necessary for the naming of the file if there is more than one start-stop cycle mitk::RealTimeClock::Pointer m_SystemTimeClock; ///< system time clock for system time tag in output xml file }; } #endif // #define _MITK_POINT_SET_SOURCE_H