diff --git a/Modules/IGT/IO/mitkNavigationDataRecorderDeprecated.cpp b/Modules/IGT/IO/mitkNavigationDataRecorderDeprecated.cpp new file mode 100644 index 0000000000..7eb3fe4c93 --- /dev/null +++ b/Modules/IGT/IO/mitkNavigationDataRecorderDeprecated.cpp @@ -0,0 +1,366 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "mitkNavigationDataRecorderDeprecated.h" +#include +#include +#include +#include + +//headers for exceptions +#include "mitkIGTException.h" +#include "mitkIGTIOException.h" + +mitk::NavigationDataRecorderDeprecated::NavigationDataRecorderDeprecated() +{ + //set default values + m_NumberOfInputs = 0; + m_RecordingMode = NormalFile; + m_Recording = false; + m_NumberOfRecordedFiles = 0; + m_Stream = NULL; + m_FileName = ""; + m_SystemTimeClock = RealTimeClock::New(); + m_OutputFormat = mitk::NavigationDataRecorderDeprecated::xml; + m_RecordCounter = 0; + m_RecordCountLimit = -1; + m_DoNotOverwriteFiles = false; + m_StreamMustBeDeleted = false; + + //To get a start time + mitk::IGTTimeStamp::GetInstance()->Start(this); +} + +mitk::NavigationDataRecorderDeprecated::~NavigationDataRecorderDeprecated() +{ +} + + +void mitk::NavigationDataRecorderDeprecated::GenerateData() +{ + +} + +void mitk::NavigationDataRecorderDeprecated::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::NavigationDataRecorderDeprecated::SetRecordingMode( RecordingMode mode ) +{ + m_RecordingMode = mode; + this->Modified(); +} + +void mitk::NavigationDataRecorderDeprecated::Update() +{ + if (m_Recording) + { + DataObjectPointerArray inputs = this->GetInputs(); //get all inputs + mitk::NavigationData::TimeStampType timestamp=0.0; // timestamp for mitk time + timestamp = mitk::IGTTimeStamp::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(); + + //if csv-mode: write csv header and timestamp at beginning + if (m_OutputFormat == mitk::NavigationDataRecorderDeprecated::csv) + { + //write header only when it's the first line + if (m_firstLine) + { + m_firstLine = false; + *m_Stream << "TimeStamp"; + for (unsigned int index = 0; index < inputs.size(); index++){ *m_Stream << ";Valid_Tool" << index << + ";X_Tool" << index << + ";Y_Tool" << index << + ";Z_Tool" << index << + ";QX_Tool" << index << + ";QY_Tool" << index << + ";QZ_Tool" << index << + ";QR_Tool" << index;} + *m_Stream << "\n"; + } + //write timestamp (always) + *m_Stream << timestamp; + } + + //write tool data for every tool + 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->GetIGTTimeStamp(); + + //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) + { + if (this->m_OutputFormat == mitk::NavigationDataRecorderDeprecated::xml) + { + TiXmlElement* elem = new TiXmlElement("NavigationData"); + + 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); + + // set additional attribute? + std::map >::iterator + it = m_AdditionalAttributes.find( nd ); + if( it != m_AdditionalAttributes.end() ) + { + elem->SetAttribute(it->second.first, it->second.second); + } + + *m_Stream << " " << *elem << std::endl; + + delete elem; + } + else if (this->m_OutputFormat == mitk::NavigationDataRecorderDeprecated::csv) + { + *m_Stream << ";" << dataValid << ";" << position[0] << ";" << position[1] << ";" << position[2] << ";" << orientation[0] << ";" << orientation[1] << ";" << orientation[2] << ";" << orientation[3]; + } + } + } + if (this->m_OutputFormat == mitk::NavigationDataRecorderDeprecated::csv) + { + *m_Stream << "\n"; + } + } + m_RecordCounter++; + if ((m_RecordCountLimit<=m_RecordCounter)&&(m_RecordCountLimit != -1)) {StopRecording();} +} + +void mitk::NavigationDataRecorderDeprecated::SetAdditionalAttribute(const NavigationData* nd, + const std::string& attributeName + , const std::string& attributeValue ) +{ + std::map >::iterator + it = m_AdditionalAttributes.find( nd ); + if( it == m_AdditionalAttributes.end() ) + m_AdditionalAttributes[nd] = std::pair(attributeName, attributeValue); + else + { + it->second.first = attributeName; + it->second.second = attributeValue; + } + +} + +void mitk::NavigationDataRecorderDeprecated::RemoveAdditionalAttribute( const NavigationData* nd ) +{ + std::map >::iterator + it = m_AdditionalAttributes.find( nd ); + if( it != m_AdditionalAttributes.end() ) + m_AdditionalAttributes.erase(it); +} + +void mitk::NavigationDataRecorderDeprecated::StartRecording() +{ + + if(!m_Recording) + { + 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); + std::string extension = ".xml"; + if (m_OutputFormat == mitk::NavigationDataRecorderDeprecated::csv) + extension = ".csv"; + + ss << tmpPath << "/" << m_FileName << "-" << m_NumberOfRecordedFiles << extension; + + if( m_DoNotOverwriteFiles ) + { + unsigned int index = m_NumberOfRecordedFiles+1; + while( itksys::SystemTools::FileExists( ss.str().c_str() ) ) + { + ss.str(""); + ss << tmpPath << "/" << m_FileName << "-" << index << extension; + index++; + } + } + + switch(m_RecordingMode) + { + case Console: + stream = &std::cout; + break; + + case NormalFile: + if (m_FileName == "") //Check if there is a file name and path + { + std::string message = "No file name or file path set."; + MITK_ERROR << message; + mitkThrowException(mitk::IGTException) << message; + } + else + { + stream = new std::ofstream(ss.str().c_str()); + } + break; + + case ZipFile: + stream = &std::cout; + MITK_WARN << "Sorry no ZipFile support yet"; + break; + + default: + stream = &std::cout; + break; + } + m_Stream = stream; + m_StreamMustBeDeleted = true; + m_firstLine = true; + m_RecordCounter = 0; + StartRecording(stream); + } + } +else if (m_Recording) + { + MITK_WARN << "Already recording please stop before start new recording session"; + return; + } +} + +void mitk::NavigationDataRecorderDeprecated::StartRecording(std::ostream* stream) +{ + if (m_Recording) + { + MITK_WARN << "Already recording please stop before start new recording session"; + return; + } + + m_Stream = stream; + m_Stream->precision(10); + + //TODO store date and GMT time + //cheking if the stream is good + if (m_Stream->good()) + { + if (m_OutputFormat == mitk::NavigationDataRecorderDeprecated::xml) + { + *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; + } + else + { + m_Recording = false; + mitkThrowException(mitk::IGTException)<<"The stream is not good"; + } +} + + +void mitk::NavigationDataRecorderDeprecated::StopRecording() +{ + if (!m_Recording) + { + std::cout << "You have to start a recording first" << std::endl; + return; + } + + if ((m_Stream) && (m_OutputFormat == mitk::NavigationDataRecorderDeprecated::xml)) + { + *m_Stream << "" << std::endl; + } + + m_NumberOfRecordedFiles++; + m_Recording = false; + m_Stream->flush(); + if (m_StreamMustBeDeleted) //stream must only be deleted if it was created inside this class + { + m_StreamMustBeDeleted = false; + delete m_Stream; + } + m_Stream = NULL; +} diff --git a/Modules/IGT/IO/mitkNavigationDataRecorderDeprecated.h b/Modules/IGT/IO/mitkNavigationDataRecorderDeprecated.h new file mode 100644 index 0000000000..528349553e --- /dev/null +++ b/Modules/IGT/IO/mitkNavigationDataRecorderDeprecated.h @@ -0,0 +1,212 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef _MITK_NavigationDataRecorderDeprecated_H +#define _MITK_NavigationDataRecorderDeprecated_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 NavigationDataRecorderDeprecated : public itk::ProcessObject + { + public: + mitkClassMacro( NavigationDataRecorderDeprecated, itk::ProcessObject ); + + itkNewMacro( Self ); + + /**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 OutputFormatEnum + { + xml, + csv + }; + + /** + * \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 + */ + DEPRECATED( itkSetStringMacro(FileName)); + + /** + * \brief Returns the file name of the recording file (in OutputMode NormalFile and ZipFile) + */ + DEPRECATED( itkGetStringMacro(FileName)); + + /** + * \brief If true the recorder will never overwrite a file + */ + DEPRECATED( itkSetMacro(DoNotOverwriteFiles,bool)); + + /** + * \brief Returns whether the NavigationDataRecorderDeprecated is recording or not + */ + DEPRECATED( itkGetMacro(Recording,bool)); + + /** + * \brief Returns the recording mode + */ + DEPRECATED( itkGetMacro(RecordingMode,RecordingMode)); + + /** + * \brief Returns the number of data sets / frames which were recorded by the NavigationDataRecorderDeprecated since start + */ + DEPRECATED( itkGetMacro(RecordCounter,int)); + + /** + * \brief Sets a limit of recorded data sets / frames. Recording will be stopped if the number is reached. -1 disables the limit, -1 is default value as well. + */ + DEPRECATED( itkSetMacro(RecordCountLimit,int)); + + /** + * \brief Adds the input NavigationDatas + */ + DEPRECATED( virtual void AddNavigationData(const NavigationData* nd)); + + /// + /// set an additional attribute for a specified navigation data + /// this will be written for each navigation data and may be + /// updated before calling Update() + /// + DEPRECATED( void SetAdditionalAttribute( const NavigationData* nd, const std::string& attributeName + , const std::string& attributeValue )); + DEPRECATED(void RemoveAdditionalAttribute( const NavigationData* nd )); + + /** + * Documentation + * \brief Starts the recording with the presetted OutputMode. + * This method calls StartRecording(std::ostream*). + * Does nothing if the recorder is already recording and + * the method StartRecording is called again. + * @throw mitk::IGTException Throws an exception if no file name or file path is set. + */ + DEPRECATED( void StartRecording()); + + /** + * Documentation + * \brief Starts the recording with an own preinitialized stream + * Does nothing if it is already recording and method StartRecorded is called + * @throw mitk::IGTException Throws an exception if the stream is not good. + */ + DEPRECATED( void StartRecording(std::ostream* stream)); + + /**Documentation + * \brief Stops the recording and closes the stream + */ + DEPRECATED( void StopRecording()); + + /**Documentation + * \brief Every call of update causes one line for each added NavigationData in the output if the recording was started + */ + + DEPRECATED( virtual void Update()); + + /**Documentation + * \brief Sets the recording mode which causes different types of output streams + * see enum RecordingMode + */ + DEPRECATED( 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. + */ + DEPRECATED( itkSetMacro(OutputFormat,mitk::NavigationDataRecorderDeprecated::OutputFormatEnum)); + + protected: + + /**Documentation + * \brief filter execute method here it is not used + * + */ + virtual void GenerateData(); + + NavigationDataRecorderDeprecated(); + + virtual ~NavigationDataRecorderDeprecated(); + + 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 + + bool m_StreamMustBeDeleted; + + RecordingMode m_RecordingMode; ///< stores the mode see enum RecordingMode + + OutputFormatEnum m_OutputFormat; ///< stores the output format; see enum OutputFormat + + bool m_Recording; ///< indicates whether the recording is started or not + + int m_RecordCounter; ///< counts the number of frames which are recorded since StartRecording + + int m_RecordCountLimit; ///< limits the number of frames, recording will be stopped if the limit is reached. -1 disables the limit + + bool m_firstLine; //for the csv writer to detect wether the header must be written + + 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 + + bool m_DoNotOverwriteFiles; ///< do not overwrite any files if true + + std::map > m_AdditionalAttributes; + }; +} +#endif // #define _MITK_POINT_SET_SOURCE_H diff --git a/Modules/IGT/files.cmake b/Modules/IGT/files.cmake index 2b3112756e..a23020d003 100644 --- a/Modules/IGT/files.cmake +++ b/Modules/IGT/files.cmake @@ -1,89 +1,90 @@ set(CPP_FILES TestingHelper/mitkNavigationToolStorageTestHelper.cpp Algorithms/mitkNavigationDataDelayFilter.cpp Algorithms/mitkNavigationDataDisplacementFilter.cpp Algorithms/mitkNavigationDataEvaluationFilter.cpp Algorithms/mitkNavigationDataLandmarkTransformFilter.cpp Algorithms/mitkNavigationDataReferenceTransformFilter.cpp Algorithms/mitkNavigationDataSmoothingFilter.cpp Algorithms/mitkNavigationDataToMessageFilter.cpp Algorithms/mitkNavigationDataToNavigationDataFilter.cpp Algorithms/mitkNavigationDataToPointSetFilter.cpp Algorithms/mitkNavigationDataTransformFilter.cpp Common/mitkIGTTimeStamp.cpp Common/mitkSerialCommunication.cpp Common/mitkTrackingTypes.cpp DataManagement/mitkNavigationData.cpp DataManagement/mitkNavigationDataSet.cpp DataManagement/mitkNavigationDataSource.cpp DataManagement/mitkNavigationTool.cpp DataManagement/mitkNavigationToolStorage.cpp DataManagement/mitkTrackingDeviceSourceConfigurator.cpp DataManagement/mitkTrackingDeviceSource.cpp ExceptionHandling/mitkIGTException.cpp ExceptionHandling/mitkIGTHardwareException.cpp ExceptionHandling/mitkIGTIOException.cpp IO/mitkNavigationDataPlayer.cpp IO/mitkNavigationDataPlayerBase.cpp IO/mitkNavigationDataRecorder.cpp + IO/mitkNavigationDataRecorderDeprecated.cpp IO/mitkNavigationDataSequentialPlayer.cpp IO/mitkNavigationToolReader.cpp IO/mitkNavigationToolStorageSerializer.cpp IO/mitkNavigationToolStorageDeserializer.cpp IO/mitkNavigationToolWriter.cpp IO/mitkNavigationDataReaderInterface.cpp IO/mitkNavigationDataReaderXML.cpp IO/mitkNavigationDataReaderCSV.cpp IO/mitkNavigationDataSetWriterXML.cpp IO/mitkNavigationDataSetWriterCSV.cpp Rendering/mitkCameraVisualization.cpp Rendering/mitkNavigationDataObjectVisualizationFilter.cpp TrackingDevices/mitkClaronTool.cpp TrackingDevices/mitkClaronTrackingDevice.cpp TrackingDevices/mitkInternalTrackingTool.cpp TrackingDevices/mitkNDIPassiveTool.cpp TrackingDevices/mitkNDIProtocol.cpp TrackingDevices/mitkNDITrackingDevice.cpp TrackingDevices/mitkTrackingDevice.cpp TrackingDevices/mitkTrackingTool.cpp TrackingDevices/mitkTrackingVolumeGenerator.cpp TrackingDevices/mitkVirtualTrackingDevice.cpp TrackingDevices/mitkVirtualTrackingTool.cpp TrackingDevices/mitkOptitrackErrorMessages.cpp TrackingDevices/mitkOptitrackTrackingDevice.cpp TrackingDevices/mitkOptitrackTrackingTool.cpp ) set(RESOURCE_FILES ClaronMicron.stl IntuitiveDaVinci.stl NDIAurora.stl NDIAurora_Dome.stl NDIAuroraCompactFG_Dome.stl NDIAuroraPlanarFG_Dome.stl NDIAuroraTabletopFG_Dome.stl NDIAuroraTabletopFG_Prototype_Dome.stl NDIPolarisOldModel.stl NDIPolarisSpectra.stl NDIPolarisSpectraExtendedPyramid.stl NDIPolarisVicra.stl ) if(MITK_USE_MICRON_TRACKER) set(CPP_FILES ${CPP_FILES} TrackingDevices/mitkClaronInterface.cpp) else() set(CPP_FILES ${CPP_FILES} TrackingDevices/mitkClaronInterfaceStub.cpp) endif(MITK_USE_MICRON_TRACKER) if(MITK_USE_MICROBIRD_TRACKER) set(CPP_FILES ${CPP_FILES} TrackingDevices/mitkMicroBirdTrackingDevice.cpp) endif(MITK_USE_MICROBIRD_TRACKER)