p,p'p)p!p~p{p]p^p/p(pM8Y6_p:pq,q'q)qd Gd!qOk~q{qfmv9]q^q/q(q_q:qr`b,r'r)r!r~r{r]r^r/r(r_r:rjKrLrMrNrOrPrQrRrSrTrUrVrWrXrYrZr`r s.sSn+s@s#s$s%s&sv9^n*s=s@$-s;sh:>s,s'sil)s!s~s{s]s^s/s(s_s:st,t't)t!t~t{txr/i(i]t^t/t(ti=k=6sfq:l%__tP)k=:tq;i=HaB]&gXc",
+"R:7TtUtVtWtXtYtZt`tCq~t u6h.u&j+up6@ui=Qcypk=gq#uu*li=,uj&'u)uzf!u~uzew9{u+o]uZg2hMoT6^uKmZjVmWl/ujooaa35h(u_u:uwnv,v'v)v!p!v~v{v]vBt^v/v(v_v:vw,w'w(e)w!pi=K(!wO)vo@3%_k=i=;4~wk=%_8bK(~j",
+"{w]w^w/w(w;;^+4.'#g@9 _w:wykxLa9hVl[bbh,x'x>w)xws@v0qa3#kdv!x~xi=JuK({x]xJu_t#ui=M{^xtpi=fqdb",
+"/x(x_x:xycg,yZ6Fh'yLh=y@wvx2z*jLa,z)x)xP6]e'z u1sAOq,A'A)A!Atm'A~Avz{A]AYy)AqxFt1}^Aen/A(A@z_A6u:Agzzsw-y*B=B-B;B>Bds,BM{xa'BcyGz)B8spp!B*l",
+". . . . . . . . . . . + * = { 5.9 S {+L%A ~B{B@!(3>_]B^BMz/B8ply(B22_B:B=8+OB&.d.;6PBV3QBRBiySBTB_zUB 1VBWBXBYBZB`B C.C+C@C#C$C%CC,C'C)C!C~C{C]C^C/C(C_C:C+L%pCd.^zqC(3L;KzrCsCtCuCvCwCxC(ByCXBzCACM5m5[z}zq*BCi5CCDCECwAFCGCHCICJCKC54LCMC3zNCSrOCPCQCRCSCTCpu`u}wVlzz;j>A{AUCVCWCOAXCXyYCZC`CXy DYvnmFrwg5yYkDx.DN6rvkt+Dit>z@D#D$D%D&Di=*DKB=D-D;DIz&nqp>D",
+". . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . @ * = ~ H 9 Q P {+F k j d.^zqCkAV3N2rC,D'D)D!DS5qA~DyC{D]DRzFAEIl;E_p>iRa/r!^S+,E'E2q)E!5!E~E{E",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @ . . . . . . . . . . . . . . . . . . @ + * { ~ ) H a+a+R F ^.&.e.iA^z@!kAP/N2]E^E/E(E/B_EOzPz:EF+A.^._.3F;6^zjA4FP/QB5F70,D6FTB_E%67F 1N_nyXBn5;F}E+gF 1hFiFjF^.J . . @ @ @ @ . . . . . . . . . . . . . . . . . . . . . . . @ = = = J 5.9 9 Q R >+^.&.e.e.oDjA@!ZEP/N2RBLz*6'DjyTBeF_E%6S5pD",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ~ lykF<'lFmFnFoFpFqFQB@ @ . @ . . . . . . . . . . . . . . . @ . . . @ . @ . @ . . . . . . . . @ @ + { { ~ J H I a+a+>+1+F j 3Fd.oD^zrFjAg3kAP/",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . J ,DsFtFuFvFwFxF
+#include
+
+// Qmitk
+#include "QmitkIGTTrackingDataEvaluationView.h"
+#include "QmitkStdMultiWidget.h"
+
+// Qt
+#include
+#include
+
+// MITK
+#include "mitkNavigationDataCSVSequentialPlayer.h"
+#include
+#include
+#include
+
+//ITK
+#include
+
+//VNL
+#include
+
+//vtk headers
+#include
+#include
+#include
+
+
+const std::string QmitkIGTTrackingDataEvaluationView::VIEW_ID = "org.mitk.views.igttrackingdataevaluation";
+
+QmitkIGTTrackingDataEvaluationView::QmitkIGTTrackingDataEvaluationView()
+: QmitkFunctionality()
+, m_Controls( 0 )
+, m_MultiWidget( NULL )
+, m_scalingfactor(1)
+{
+m_CSVtoXMLInputFilenameVector = std::vector();
+m_CSVtoXMLOutputFilenameVector = std::vector();
+}
+
+QmitkIGTTrackingDataEvaluationView::~QmitkIGTTrackingDataEvaluationView()
+{
+}
+
+
+void QmitkIGTTrackingDataEvaluationView::CreateQtPartControl( QWidget *parent )
+{
+ // build up qt view, unless already done
+ if ( !m_Controls )
+ {
+ // create GUI widgets from the Qt Designer's .ui file
+ m_Controls = new Ui::QmitkIGTTrackingDataEvaluationViewControls;
+ m_Controls->setupUi( parent );
+
+ connect( m_Controls->m_LoadInputFileList, SIGNAL(clicked()), this, SLOT(OnLoadFileList()) );
+ connect( m_Controls->m_StartEvaluation, SIGNAL(clicked()), this, SLOT(OnEvaluateData()) );
+ connect( m_Controls->m_AddToCurrentList, SIGNAL(clicked()), this, SLOT(OnAddToCurrentList()) );
+ connect( m_Controls->m_GeneratePointSetOfMeanPositions, SIGNAL(clicked()), this, SLOT(OnGeneratePointSet()) );
+ connect( m_Controls->m_GenerateRotationLines, SIGNAL(clicked()), this, SLOT(OnGenerateRotationLines()) );
+ connect( m_Controls->m_GeneratePointSet, SIGNAL(clicked()), this, SLOT(OnGenerateGroundTruthPointSet()) );
+ connect( m_Controls->m_Convert, SIGNAL(clicked()), this, SLOT(OnConvertCSVtoXMLFile()) );
+ connect( m_Controls->m_loadCSVtoXMLInputList, SIGNAL(clicked()), this, SLOT(OnCSVtoXMLLoadInputList()) );
+ connect( m_Controls->m_loadCSVtoXMLOutputList, SIGNAL(clicked()), this, SLOT(OnCSVtoXMLLoadOutputList()) );
+ connect( m_Controls->m_OrientationCalculationGenerateReference, SIGNAL(clicked()), this, SLOT(OnOrientationCalculation_CalcRef()) );
+ connect( m_Controls->m_OrientationCalculationWriteOrientationsToFile, SIGNAL(clicked()), this, SLOT(OnOrientationCalculation_CalcOrientandWriteToFile()) );
+ connect( m_Controls->m_GeneratePointSetsOfSinglePositions, SIGNAL(clicked()), this, SLOT(OnGeneratePointSetsOfSinglePositions()) );
+ }
+}
+
+void QmitkIGTTrackingDataEvaluationView::OnOrientationCalculation_CalcRef()
+{
+if(m_FilenameVector.size() != 3)
+ {
+ MessageBox("Need exactly three points as reference, aborting!");
+ return;
+ }
+
+//start loop and iterate through all files of list
+for(int i=0; iSetFiletype(mitk::NavigationDataCSVSequentialPlayer::ManualLoggingCSV);
+ myPlayer->SetFileName(m_FilenameVector.at(i));
+
+ //check if the stream is valid and skip file if not
+ /*
+ if (!myPlayer->GetStreamValid())
+ {
+ MITK_ERROR << "Error in file " << m_FilenameVector.at(i) << ": " << myPlayer->GetErrorMessage() << " ; Skipping file!";
+ continue;
+ }
+ */
+
+ //create evaluation filter
+ mitk::NavigationDataEvaluationFilter::Pointer myEvaluationFilter = mitk::NavigationDataEvaluationFilter::New();
+
+ //connect pipeline
+ for (int j=0; jGetNumberOfOutputs(); j++) {myEvaluationFilter->SetInput(j,myPlayer->GetOutput(j));}
+
+
+ //update pipline until number of samlples is reached
+ for (int j=0; jm_NumberOfSamples->value(); j++)
+ {myEvaluationFilter->Update();}
+
+ //store mean position as reference
+ switch (i)
+ {
+ case 0:
+ m_RefPoint1 = myEvaluationFilter->GetPositionMean(0);
+ break;
+ case 1:
+ m_RefPoint2 = myEvaluationFilter->GetPositionMean(0);
+ break;
+ case 2:
+ m_RefPoint3 = myEvaluationFilter->GetPositionMean(0);
+ break;
+ }
+ }
+ MessageBox("Created Reference!");
+}
+
+void QmitkIGTTrackingDataEvaluationView::OnOrientationCalculation_CalcOrientandWriteToFile()
+{
+//start loop and iterate through all files of list
+for(int i=0; iSetFiletype(mitk::NavigationDataCSVSequentialPlayer::ManualLoggingCSV);
+ myPlayer->SetFileName(m_FilenameVector.at(i));
+
+ //check if the stream is valid and skip file if not
+ /*
+ if (!myPlayer->GetStreamValid())
+ {
+ MITK_ERROR << "Error in file " << m_FilenameVector.at(i) << ": " << myPlayer->GetErrorMessage() << " ; Skipping file!";
+ continue;
+ }
+ */
+
+
+
+ //open file header
+ QString outputname = QString(m_FilenameVector.at(i).c_str()) + "_orientationFile.csv";
+ m_CurrentWriteFile.open(outputname.toStdString().c_str(), std::ios::out);
+ if (m_CurrentWriteFile.bad())
+ {
+ MessageBox("Error: Can't open output file!");
+ return;
+ }
+
+ //write header to file
+ m_CurrentWriteFile << "Nr;Calypso_Time;Valid_Reference;MeasureTool_Measurement-Tool[x];MeasureTool_Measurement-Tool[y];MeasureTool_Measurement-Tool[z];MeasureTool_Measurement-Tool[qx];MeasureTool_Measurement-Tool[qy];MeasureTool_Measurement-Tool[qz];MeasureTool_Measurement-Tool[qr]\n";
+
+ //update pipeline until number of samples is reached
+ int step = 0;
+ mitk::Point3D point1,point2,point3;
+ mitk::Quaternion current_orientation;
+
+ for (int j=0; !myPlayer->IsAtEnd(); j++)
+ {
+ myPlayer->Update();
+ mitk::NavigationData::Pointer currentNavData = myPlayer->GetOutput(0);
+ switch (step)
+ {
+ case 0:
+ step++;
+ point1 = currentNavData->GetPosition();
+ break;
+ case 1:
+ step++;
+ point2 = currentNavData->GetPosition();
+ break;
+ case 2:
+ step=0;
+ point3 = currentNavData->GetPosition();
+
+ //compute transform from reference to current points
+ if (point1[0] == 0 &&
+ point1[1] == 0 &&
+ point1[2] == 0 &&
+ point2[0] == 0 &&
+ point2[1] == 0 &&
+ point2[2] == 0 &&
+ point3[0] == 0 &&
+ point3[1] == 0 &&
+ point3[2] == 0
+ ) current_orientation.fill(0);
+ else
+ {
+ /* Drehen um eine Achse um das "Umschlagen" zu vermeiden
+ itk::Matrix rot180degreeAroundY;
+ rot180degreeAroundY.Fill(0);
+ rot180degreeAroundY[0][0] = -1;
+ rot180degreeAroundY[1][1] = 1;
+ rot180degreeAroundY[2][2] = -1;
+ point1 = rot180degreeAroundY * point1;
+ point2 = rot180degreeAroundY * point2;
+ point3 = rot180degreeAroundY * point3;
+ */
+
+ vtkSmartPointer transform = vtkSmartPointer::New();
+ vtkSmartPointer sourcePoints = vtkSmartPointer::New();
+ double sourcepoint1[3] = {point1[0],point1[1],point1[2]};
+ double sourcepoint2[3] = {point2[0],point2[1],point2[2]};
+ double sourcepoint3[3] = {point3[0],point3[1],point3[2]};
+ sourcePoints->InsertNextPoint(sourcepoint1);
+ sourcePoints->InsertNextPoint(sourcepoint2);
+ sourcePoints->InsertNextPoint(sourcepoint3);
+ vtkSmartPointer targetPoints = vtkSmartPointer::New();
+ double targetpoint1[3] = {m_RefPoint1[0],m_RefPoint1[1],m_RefPoint1[2]};
+ double targetpoint2[3] = {m_RefPoint2[0],m_RefPoint2[1],m_RefPoint2[2]};
+ double targetpoint3[3] = {m_RefPoint3[0],m_RefPoint3[1],m_RefPoint3[2]};
+ targetPoints->InsertNextPoint(targetpoint1);
+ targetPoints->InsertNextPoint(targetpoint2);
+ targetPoints->InsertNextPoint(targetpoint3);
+
+ transform->SetSourceLandmarks(sourcePoints);
+ transform->SetTargetLandmarks(targetPoints);
+ transform->Modified();
+ transform->Update();
+
+ mitk::Transform::Pointer newTransform = mitk::Transform::New();
+ newTransform->SetMatrix(transform->GetMatrix());
+ current_orientation = newTransform->GetOrientation();
+
+ //add pointset with the three positions
+ if((j>15) && (j<18))
+ {
+ mitk::DataNode::Pointer newNode = mitk::DataNode::New();
+ mitk::PointSet::Pointer newPointSet = mitk::PointSet::New();
+ newPointSet->InsertPoint(0,point1);
+ newPointSet->InsertPoint(1,point2);
+ newPointSet->InsertPoint(2,point3);
+ QString name = QString(m_FilenameVector.at(i).c_str());
+ newNode->SetName(name.toStdString().c_str());
+ newNode->SetData(newPointSet);
+ newNode->SetFloatProperty("pointsize",0.1);
+ this->GetDataStorage()->Add(newNode);
+ }
+ }
+
+ break;
+ }
+ m_CurrentWriteFile << i << ";";
+ m_CurrentWriteFile << currentNavData->GetTimeStamp() << ";"; //IMPORTANT: change to GetIGTTimeStamp in new version!
+ m_CurrentWriteFile << "true;";
+ m_CurrentWriteFile << currentNavData->GetPosition()[0] << ";";
+ m_CurrentWriteFile << currentNavData->GetPosition()[1] << ";";
+ m_CurrentWriteFile << currentNavData->GetPosition()[2] << ";";
+ m_CurrentWriteFile << current_orientation.x() << ";";
+ m_CurrentWriteFile << current_orientation.y() << ";";
+ m_CurrentWriteFile << current_orientation.z() << ";";
+ m_CurrentWriteFile << current_orientation.r() << ";";
+ m_CurrentWriteFile << "\n";
+ }
+ //close output file
+ m_CurrentWriteFile.close();
+
+ }
+ MessageBox("Finished!");
+}
+
+void QmitkIGTTrackingDataEvaluationView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget)
+{
+ m_MultiWidget = &stdMultiWidget;
+}
+
+
+void QmitkIGTTrackingDataEvaluationView::StdMultiWidgetNotAvailable()
+{
+ m_MultiWidget = NULL;
+}
+
+void QmitkIGTTrackingDataEvaluationView::OnAddToCurrentList()
+{
+ //read in filename
+ QString filename = QFileDialog::getOpenFileName(NULL,tr("Open Measurement Filename List"), "/", tr("All Files (*.*)"));
+ if (filename.isNull()) return;
+
+ /*
+ //save old locale
+ char * oldLocale;
+ oldLocale = setlocale( LC_ALL, 0 );
+
+ //define own locale
+ std::locale C("C");
+ setlocale( LC_ALL, "C" );
+ */ //TODO: check if this is needed here, and load old locale if yes
+
+ //read file
+ std::ifstream file;
+ file.open(filename.toStdString().c_str(), std::ios::in);
+ if (file.good())
+ {
+ //read out file
+ file.seekg(0L, std::ios::beg); // move to begin of file
+ while (! file.eof())
+ {
+ std::string buffer;
+ std::getline(file,buffer); // read out file line by line
+ if (buffer.size() > 0)
+ {
+ std::string thisFilename = "";
+ if (m_Controls->m_AddPath->isChecked()) thisFilename = m_Controls->m_ListPath->text().toStdString();
+ thisFilename.append(buffer);
+ m_FilenameVector.push_back(thisFilename);
+ }
+ }
+ }
+
+ //fill list at GUI
+ m_Controls->m_FileList->clear();
+ for(unsigned int i=0; im_FileList);}
+
+}
+
+void QmitkIGTTrackingDataEvaluationView::OnLoadFileList()
+ {
+ m_FilenameVector = std::vector();
+ m_FilenameVector.clear();
+ OnAddToCurrentList();
+ }
+
+void QmitkIGTTrackingDataEvaluationView::OnEvaluateData()
+{
+
+//open output file
+m_CurrentWriteFile.open(std::string(m_Controls->m_OutputFilename->text().toUtf8()).c_str(), std::ios::out);
+if (m_CurrentWriteFile.bad())
+ {
+ MessageBox("Error: Can't open output file!");
+ return;
+ }
+
+//write output file header
+WriteHeader();
+
+//start loop and iterate through all files of list
+for(int i=0; iSetFiletype(mitk::NavigationDataCSVSequentialPlayer::ManualLoggingCSV);
+ myPlayer->SetFileName(m_FilenameVector.at(i));
+
+
+ //check if the stream is valid and skip file if not
+ /*
+ if (!myPlayer->GetStreamValid())
+ {
+ MITK_ERROR << "Error in file " << m_FilenameVector.at(i) << ": " << myPlayer->GetErrorMessage() << " ; Skipping file!";
+
+ continue;
+ }
+ */
+
+ //create evaluation filter
+ mitk::NavigationDataEvaluationFilter::Pointer myEvaluationFilter = mitk::NavigationDataEvaluationFilter::New();
+
+ //connect pipeline
+ for (int j=0; jGetNumberOfOutputs(); j++) {myEvaluationFilter->SetInput(j,myPlayer->GetOutput(j));}
+
+
+
+ //update pipline until number of samlples is reached
+ for (int j=0; jm_NumberOfSamples->value(); j++)
+ {
+ myEvaluationFilter->Update();
+ //Debug output:
+ //std::cout.precision(5);
+ //std::cout << "Euler " << j << ";" << myPlayer->GetOutput()->GetOrientation().rotation_euler_angles()[0] << ";" << myPlayer->GetOutput()->GetOrientation().rotation_euler_angles()[1] << ";" << myPlayer->GetOutput()->GetOrientation().rotation_euler_angles()[2] << "\n";
+ }
+
+ //write result to output file
+ WriteDataSet(myEvaluationFilter,m_FilenameVector.at(i));
+
+ }
+
+//close output file
+m_CurrentWriteFile.close();
+
+//calculate angles if option is on
+if(m_Controls->m_settingDifferenceAngles->isChecked() || m_Controls->m_DifferencesSLERP->isChecked()) CalculateDifferenceAngles();
+
+MessageBox("Finished!");
+
+}
+
+void QmitkIGTTrackingDataEvaluationView::OnGeneratePointSetsOfSinglePositions()
+{
+ m_scalingfactor = m_Controls->m_ScalingFactor->value();
+
+ //start loop and iterate through all files of list
+ for(int i=0; iSetFiletype(mitk::NavigationDataCSVSequentialPlayer::ManualLoggingCSV);
+ myPlayer->SetFileName(m_FilenameVector.at(i));
+
+
+ //check if the stream is valid and skip file if not
+/*
+if (!myPlayer->GetStreamValid())
+ {
+ MITK_ERROR << "Error in file " << m_FilenameVector.at(i) << ": " << myPlayer->GetErrorMessage() << " ; Skipping file!";
+
+ continue;
+ }
+*/
+
+ //update pipline until number of samlples is reached and store every single point
+ for (int j=0; jm_NumberOfSamples->value(); j++)
+ {
+ myPlayer->Update();
+ mitk::Point3D thisPoint = myPlayer->GetOutput()->GetPosition();
+ thisPoint[0] *= m_scalingfactor;
+ thisPoint[1] *= m_scalingfactor;
+ thisPoint[2] *= m_scalingfactor;
+ thisPointSet->InsertPoint(j,thisPoint);
+ }
+
+ //add point set to data storage
+ mitk::DataNode::Pointer newNode = mitk::DataNode::New();
+ QString name = this->m_Controls->m_prefix->text() + QString("PointSet_of_All_Positions_") + QString::number(i);
+ newNode->SetName(name.toStdString());
+ newNode->SetData(thisPointSet);
+ this->GetDataStorage()->Add(newNode);
+ }
+
+
+ }
+
+void QmitkIGTTrackingDataEvaluationView::OnGeneratePointSet()
+ {
+ m_scalingfactor = m_Controls->m_ScalingFactor->value();
+
+ mitk::PointSet::Pointer generatedPointSet = mitk::PointSet::New();
+
+ //start loop and iterate through all files of list
+ for(int i=0; iSetFiletype(mitk::NavigationDataCSVSequentialPlayer::ManualLoggingCSV);
+ myPlayer->SetFileName(m_FilenameVector.at(i));
+
+
+ //check if the stream is valid and skip file if not
+ /*
+ if (!myPlayer->GetStreamValid())
+ {
+ MITK_ERROR << "Error in file " << m_FilenameVector.at(i) << ": " << myPlayer->GetErrorMessage() << " ; Skipping file!";
+
+ continue;
+ }
+ */
+
+ //create evaluation filter
+ mitk::NavigationDataEvaluationFilter::Pointer myEvaluationFilter = mitk::NavigationDataEvaluationFilter::New();
+
+ //connect pipeline
+ for (int j=0; jGetNumberOfOutputs(); j++) {myEvaluationFilter->SetInput(j,myPlayer->GetOutput(j));}
+
+ //update pipline until number of samlples is reached
+ for (int j=0; jm_NumberOfSamples->value(); j++) {myEvaluationFilter->Update();}
+
+ //add mean position to point set
+ mitk::Point3D meanPos = myEvaluationFilter->GetPositionMean(0);
+ if (m_scalingfactor!=1)
+ {
+ meanPos[0] *= m_scalingfactor;
+ meanPos[1] *= m_scalingfactor;
+ meanPos[2] *= m_scalingfactor;
+ }
+ generatedPointSet->InsertPoint(i,meanPos);
+ }
+
+ //add point set to data storage
+ mitk::DataNode::Pointer newNode = mitk::DataNode::New();
+ QString name = this->m_Controls->m_prefix->text() + "PointSet_of_Mean_Positions";
+ newNode->SetName(name.toStdString());
+ newNode->SetData(generatedPointSet);
+ this->GetDataStorage()->Add(newNode);
+ }
+
+void QmitkIGTTrackingDataEvaluationView::OnGenerateRotationLines()
+ {
+ m_scalingfactor = m_Controls->m_ScalingFactor->value();
+
+ //start loop and iterate through all files of list
+ for(int i=0; iSetFiletype(mitk::NavigationDataCSVSequentialPlayer::ManualLoggingCSV);
+ myPlayer->SetFileName(m_FilenameVector.at(i));
+
+
+ //check if the stream is valid and skip file if not
+ /*
+ if (!myPlayer->GetStreamValid())
+ {
+ MITK_ERROR << "Error in file " << m_FilenameVector.at(i) << ": " << myPlayer->GetErrorMessage() << " ; Skipping file!";
+ }
+ else
+ */
+ {
+ //create evaluation filter
+ mitk::NavigationDataEvaluationFilter::Pointer myEvaluationFilter = mitk::NavigationDataEvaluationFilter::New();
+
+ //connect pipeline
+ for (int j=0; jGetNumberOfOutputs(); j++) {myEvaluationFilter->SetInput(j,myPlayer->GetOutput(j));}
+
+ //update pipline until number of samlples is reached
+ for (int j=0; jm_NumberOfSamples->value(); j++)
+ {
+ myEvaluationFilter->Update();
+ /*
+ if (!myPlayer->GetStreamValid())
+ {
+ MITK_ERROR << "Error in file " << m_FilenameVector.at(i) << ": " << myPlayer->GetErrorMessage() << " ; Skipping file!";
+ continue;
+ }
+ */
+ }
+
+ if (!myPlayer->IsAtEnd()) continue;
+
+ //create line from mean pos to a second point which lies along the sensor (1,0,0 in tool coordinates for aurora)
+ mitk::Point3D meanPos = myEvaluationFilter->GetPositionMean(0);
+ if(m_scalingfactor!=1)
+ {
+ meanPos[0] *= m_scalingfactor;
+ meanPos[1] *= m_scalingfactor;
+ meanPos[2] *= m_scalingfactor;
+ }
+ mitk::Point3D secondPoint;
+ mitk::Point3D thirdPoint;
+ mitk::Point3D fourthPoint;
+
+ mitk::FillVector3D(secondPoint,2,0,0); //X
+ vnl_vector secondPointTransformed = myEvaluationFilter->GetQuaternionMean(0).rotation_matrix_transpose().transpose() * secondPoint.Get_vnl_vector() + meanPos.Get_vnl_vector();
+ mitk::Point3D secondPointTransformedMITK;
+ mitk::FillVector3D(secondPointTransformedMITK,secondPointTransformed[0],secondPointTransformed[1],secondPointTransformed[2]);
+
+ mitk::FillVector3D(thirdPoint,0,4,0); //Y
+ vnl_vector thirdPointTransformed = myEvaluationFilter->GetQuaternionMean(0).rotation_matrix_transpose().transpose() * thirdPoint.Get_vnl_vector() + meanPos.Get_vnl_vector();
+ mitk::Point3D thirdPointTransformedMITK;
+ mitk::FillVector3D(thirdPointTransformedMITK,thirdPointTransformed[0],thirdPointTransformed[1],thirdPointTransformed[2]);
+
+ mitk::FillVector3D(fourthPoint,0,0,6); //Z
+ vnl_vector fourthPointTransformed = myEvaluationFilter->GetQuaternionMean(0).rotation_matrix_transpose().transpose() * fourthPoint.Get_vnl_vector() + meanPos.Get_vnl_vector();
+ mitk::Point3D fourthPointTransformedMITK;
+ mitk::FillVector3D(fourthPointTransformedMITK,fourthPointTransformed[0],fourthPointTransformed[1],fourthPointTransformed[2]);
+
+
+ mitk::PointSet::Pointer rotationLine = mitk::PointSet::New();
+ rotationLine->InsertPoint(0,secondPointTransformedMITK);
+ rotationLine->InsertPoint(1,meanPos);
+ rotationLine->InsertPoint(2,thirdPointTransformedMITK);
+ rotationLine->InsertPoint(3,meanPos);
+ rotationLine->InsertPoint(4,fourthPointTransformedMITK);
+
+ mitk::DataNode::Pointer newNode = mitk::DataNode::New();
+ QString nodeName = this->m_Controls->m_prefix->text() + "RotationLineNumber" + QString::number(i);
+ newNode->SetName(nodeName.toStdString());
+ newNode->SetData(rotationLine);
+ newNode->SetBoolProperty("show contour",true);
+ newNode->SetFloatProperty("pointsize",0.5);
+ this->GetDataStorage()->Add(newNode);
+ }
+ }
+
+ }
+
+void QmitkIGTTrackingDataEvaluationView::OnGenerateGroundTruthPointSet()
+ {
+ mitk::PointSet::Pointer generatedPointSet = mitk::PointSet::New();
+ int currentPointID = 0;
+ mitk::Point3D currentPoint;
+ mitk::FillVector3D(currentPoint,0,0,0);
+ for (int i=0; im_PointNumber1->value(); i++)
+ {
+ for (int j=0; jm_PointNumber2->value(); j++)
+ {
+ generatedPointSet->InsertPoint(currentPointID,currentPoint);
+ currentPointID++;
+ currentPoint[1] += m_Controls->m_PointDistance->value();
+ }
+ currentPoint[1] = 0;
+ currentPoint[2] += m_Controls->m_PointDistance->value();
+ }
+ mitk::DataNode::Pointer newNode = mitk::DataNode::New();
+ QString nodeName = "GroundTruthPointSet_" + QString::number(m_Controls->m_PointNumber1->value()) + "x" + QString::number(m_Controls->m_PointNumber2->value()) + "_(" + QString::number(m_Controls->m_PointDistance->value()) + "mm)";
+ newNode->SetName(nodeName.toStdString());
+ newNode->SetData(generatedPointSet);
+ this->GetDataStorage()->Add(newNode);
+ }
+
+void QmitkIGTTrackingDataEvaluationView::OnConvertCSVtoXMLFile()
+ {
+ if(m_Controls->m_ConvertSingleFile->isChecked())
+ { //convert one file
+
+ int lines = ConvertOneFile(this->m_Controls->m_InputCSV->text().toStdString(),this->m_Controls->m_OutputXML->text().toStdString());
+
+ QString result = "Converted one file with" + QString::number(lines) + " data sets";
+ MessageBox(result.toStdString());
+ }
+ else //converte file list
+ {
+ if(m_CSVtoXMLInputFilenameVector.empty() || m_CSVtoXMLOutputFilenameVector.empty())
+ {
+ MessageBox("Error: one list is not loaded!");
+ return;
+ }
+ else if(m_CSVtoXMLInputFilenameVector.size() != m_CSVtoXMLOutputFilenameVector.size())
+ {
+ MessageBox("Error: lists do not have the same number of files!");
+ return;
+ }
+ for(int i=0; i < m_CSVtoXMLInputFilenameVector.size(); i++)
+ {int lines = ConvertOneFile(m_CSVtoXMLInputFilenameVector.at(i),m_CSVtoXMLOutputFilenameVector.at(i));}
+ QString result = "Converted " + QString::number(m_CSVtoXMLInputFilenameVector.size()) + " files from file list!";
+ MessageBox(result.toStdString());
+ }
+ }
+
+int QmitkIGTTrackingDataEvaluationView::ConvertOneFile(std::string inputFilename, std::string outputFilename)
+ {
+ std::vector myNavigationDatas = GetNavigationDatasFromFile(inputFilename);
+ mitk::NavigationDataRecorderDeprecated::Pointer myRecorder = mitk::NavigationDataRecorderDeprecated::New();
+ myRecorder->SetFileName(outputFilename.c_str());
+ mitk::NavigationData::Pointer input = mitk::NavigationData::New();
+ if (m_Controls->m_ConvertCSV->isChecked()) myRecorder->SetOutputFormat(mitk::NavigationDataRecorderDeprecated::csv);
+ myRecorder->AddNavigationData(input);
+ myRecorder->StartRecording();
+ for (int i=0; iGraft(myNavigationDatas.at(i));
+ myRecorder->Update();
+ }
+ myRecorder->StopRecording();
+ return myNavigationDatas.size();
+ }
+
+void QmitkIGTTrackingDataEvaluationView::OnCSVtoXMLLoadInputList()
+ {
+ //read in filename
+ QString filename = QFileDialog::getOpenFileName(NULL,tr("Open Measurement Filename List"), "/", tr("All Files (*.*)"));
+ if (filename.isNull()) return;
+
+ m_CSVtoXMLInputFilenameVector = this->GetFileContentLineByLine(filename.toStdString());
+
+ m_Controls->m_labelCSVtoXMLInputList->setText("READY");
+ }
+
+void QmitkIGTTrackingDataEvaluationView::OnCSVtoXMLLoadOutputList()
+ {
+ //read in filename
+ QString filename = QFileDialog::getOpenFileName(NULL,tr("Open Measurement Filename List"), "/", tr("All Files (*.*)"));
+ if (filename.isNull()) return;
+
+ m_CSVtoXMLOutputFilenameVector = this->GetFileContentLineByLine(filename.toStdString());
+
+ m_Controls->m_labelCSVtoXMLOutputList->setText("READY");
+ }
+
+void QmitkIGTTrackingDataEvaluationView::MessageBox(std::string s)
+ {
+ QMessageBox msgBox;
+ msgBox.setText(s.c_str());
+ msgBox.exec();
+ }
+
+void QmitkIGTTrackingDataEvaluationView::WriteHeader()
+ {
+
+ m_CurrentWriteFile << "Filename;";
+ m_CurrentWriteFile << "N;";
+ m_CurrentWriteFile << "N_invalid;";
+ m_CurrentWriteFile << "Percentage_invalid;";
+
+ if(m_Controls->m_settingPosMean->isChecked())
+ {
+ m_CurrentWriteFile << "Position_Mean[x];";
+ m_CurrentWriteFile << "Position_Mean[y];";
+ m_CurrentWriteFile << "Position_Mean[z];";
+ }
+
+ if(m_Controls->m_settingPosStabw->isChecked())
+ {
+ m_CurrentWriteFile << "Position_StandDev[x];";
+ m_CurrentWriteFile << "Position_StandDev[y];";
+ m_CurrentWriteFile << "Position_StandDev[z];";
+ }
+
+ if(m_Controls->m_settingPosSampleStabw->isChecked())
+ {
+ m_CurrentWriteFile << "Position_SampleStandDev[x];";
+ m_CurrentWriteFile << "Position_SampleStandDev[y];";
+ m_CurrentWriteFile << "Position_SampleStandDev[z];";
+ }
+
+ if(m_Controls->m_settingQuaternionMean->isChecked())
+ {
+ m_CurrentWriteFile << "Quaternion_Mean[qx];";
+ m_CurrentWriteFile << "Quaternion_Mean[qy];";
+ m_CurrentWriteFile << "Quaternion_Mean[qz];";
+ m_CurrentWriteFile << "Quaternion_Mean[qr];";
+ }
+
+ if(m_Controls->m_settionQuaternionStabw->isChecked())
+ {
+ m_CurrentWriteFile << "Quaternion_StandDev[qx];";
+ m_CurrentWriteFile << "Quaternion_StandDev[qy];";
+ m_CurrentWriteFile << "Quaternion_StandDev[qz];";
+ m_CurrentWriteFile << "Quaternion_StandDev[qr];";
+ }
+
+ if(m_Controls->m_settingPosErrorMean->isChecked()) m_CurrentWriteFile << "PositionError_Mean;";
+
+ if(m_Controls->m_settingPosErrorStabw->isChecked()) m_CurrentWriteFile << "PositionError_StandDev;";
+
+ if(m_Controls->m_settingPosErrorSampleStabw->isChecked()) m_CurrentWriteFile << "PositionError_SampleStandDev;";
+
+ if(m_Controls->m_settingPosErrorRMS->isChecked()) m_CurrentWriteFile << "PositionError_RMS;";
+
+ if(m_Controls->m_settingPosErrorMedian->isChecked()) m_CurrentWriteFile << "PositionError_Median;";
+
+ if(m_Controls->m_settingPosErrorMinMax->isChecked())
+ {
+ m_CurrentWriteFile << "PositionError_Max;";
+ m_CurrentWriteFile << "PositionError_Min;";
+ }
+
+ if(m_Controls->m_settingEulerMean->isChecked())
+ {
+ m_CurrentWriteFile << "Euler_tx;";
+ m_CurrentWriteFile << "Euler_ty;";
+ m_CurrentWriteFile << "Euler_tz;";
+ }
+
+ if(m_Controls->m_settingEulerRMS->isChecked())
+ {
+ m_CurrentWriteFile << "EulerErrorRMS (rad);";
+ m_CurrentWriteFile << "EulerErrorRMS (grad);";
+ }
+
+ m_CurrentWriteFile << "\n";
+
+ }
+
+void QmitkIGTTrackingDataEvaluationView::WriteDataSet(mitk::NavigationDataEvaluationFilter::Pointer myEvaluationFilter, std::string dataSetName)
+ {
+ if (myEvaluationFilter->GetNumberOfOutputs()==0) m_CurrentWriteFile << "Error: no input \n";
+ else
+ {
+ m_CurrentWriteFile << dataSetName << ";";
+ m_CurrentWriteFile << myEvaluationFilter->GetNumberOfAnalysedNavigationData(0) << ";";
+ m_CurrentWriteFile << myEvaluationFilter->GetNumberOfInvalidSamples(0) << ";";
+ m_CurrentWriteFile << myEvaluationFilter->GetPercentageOfInvalidSamples(0) << ";";
+
+
+ if(m_Controls->m_settingPosMean->isChecked())
+ {
+ m_CurrentWriteFile << myEvaluationFilter->GetPositionMean(0)[0] << ";";
+ m_CurrentWriteFile << myEvaluationFilter->GetPositionMean(0)[1] << ";";
+ m_CurrentWriteFile << myEvaluationFilter->GetPositionMean(0)[2] << ";";
+ }
+
+ if(m_Controls->m_settingPosStabw->isChecked())
+ {
+ m_CurrentWriteFile << myEvaluationFilter->GetPositionStandardDeviation(0)[0] << ";";
+ m_CurrentWriteFile << myEvaluationFilter->GetPositionStandardDeviation(0)[1] << ";";
+ m_CurrentWriteFile << myEvaluationFilter->GetPositionStandardDeviation(0)[2] << ";";
+ }
+
+ if(m_Controls->m_settingPosSampleStabw->isChecked())
+ {
+ m_CurrentWriteFile << myEvaluationFilter->GetPositionSampleStandardDeviation(0)[0] << ";";
+ m_CurrentWriteFile << myEvaluationFilter->GetPositionSampleStandardDeviation(0)[1] << ";";
+ m_CurrentWriteFile << myEvaluationFilter->GetPositionSampleStandardDeviation(0)[2] << ";";
+ }
+
+ if(m_Controls->m_settingQuaternionMean->isChecked())
+ {
+ m_CurrentWriteFile << myEvaluationFilter->GetQuaternionMean(0).x() << ";";
+ m_CurrentWriteFile << myEvaluationFilter->GetQuaternionMean(0).y() << ";";
+ m_CurrentWriteFile << myEvaluationFilter->GetQuaternionMean(0).z() << ";";
+ m_CurrentWriteFile << myEvaluationFilter->GetQuaternionMean(0).r() << ";";
+ }
+
+ if(m_Controls->m_settionQuaternionStabw->isChecked())
+ {
+ m_CurrentWriteFile << myEvaluationFilter->GetQuaternionStandardDeviation(0).x() << ";";
+ m_CurrentWriteFile << myEvaluationFilter->GetQuaternionStandardDeviation(0).y() << ";";
+ m_CurrentWriteFile << myEvaluationFilter->GetQuaternionStandardDeviation(0).z() << ";";
+ m_CurrentWriteFile << myEvaluationFilter->GetQuaternionStandardDeviation(0).r() << ";";
+ }
+
+ if(m_Controls->m_settingPosErrorMean->isChecked()) m_CurrentWriteFile << myEvaluationFilter->GetPositionErrorMean(0) << ";";
+ if(m_Controls->m_settingPosErrorStabw->isChecked()) m_CurrentWriteFile << myEvaluationFilter->GetPositionErrorStandardDeviation(0) << ";";
+ if(m_Controls->m_settingPosErrorSampleStabw->isChecked()) m_CurrentWriteFile << myEvaluationFilter->GetPositionErrorSampleStandardDeviation(0) << ";";
+ if(m_Controls->m_settingPosErrorRMS->isChecked()) m_CurrentWriteFile << myEvaluationFilter->GetPositionErrorRMS(0) << ";";
+ if(m_Controls->m_settingPosErrorMedian->isChecked()) m_CurrentWriteFile << myEvaluationFilter->GetPositionErrorMedian(0) << ";";
+ if(m_Controls->m_settingPosErrorMinMax->isChecked())
+ {
+ m_CurrentWriteFile << myEvaluationFilter->GetPositionErrorMax(0) << ";";
+ m_CurrentWriteFile << myEvaluationFilter->GetPositionErrorMin(0) << ";";
+ }
+
+ if(m_Controls->m_settingEulerMean->isChecked())
+ {
+ m_CurrentWriteFile << myEvaluationFilter->GetEulerAnglesMean(0)[0] << ";";
+ m_CurrentWriteFile << myEvaluationFilter->GetEulerAnglesMean(0)[1] << ";";
+ m_CurrentWriteFile << myEvaluationFilter->GetEulerAnglesMean(0)[2] << ";";
+ }
+
+ if(m_Controls->m_settingEulerRMS->isChecked())
+ {
+ m_CurrentWriteFile << myEvaluationFilter->GetEulerAnglesRMS(0) << ";";
+ m_CurrentWriteFile << myEvaluationFilter->GetEulerAnglesRMSDegree(0) << ";";
+ }
+
+ m_CurrentWriteFile << "\n";
+
+ }
+
+
+ }
+
+void QmitkIGTTrackingDataEvaluationView::CalculateDifferenceAngles()
+ {
+
+ std::vector EvaluationDataCollection;
+
+ //start loop and iterate through all files of list: store the evaluation data
+ for(int i=0; iSetFiletype(mitk::NavigationDataCSVSequentialPlayer::ManualLoggingCSV);
+ myPlayer->SetFileName(m_FilenameVector.at(i));
+
+
+
+ //create evaluation filter
+ mitk::NavigationDataEvaluationFilter::Pointer myEvaluationFilter = mitk::NavigationDataEvaluationFilter::New();
+
+ //check if the stream is valid and skip file if not
+ /*
+ if (!myPlayer->GetStreamValid())
+ {
+ MITK_ERROR << "Error in file " << m_FilenameVector.at(i) << ": " << myPlayer->GetErrorMessage() << " ; Skipping file!";
+ }
+ else
+ */
+ {
+ //connect pipeline
+ for (int j=0; jGetNumberOfOutputs(); j++) {myEvaluationFilter->SetInput(j,myPlayer->GetOutput(j));}
+ //update pipline until number of samlples is reached
+ for (int j=0; jm_NumberOfSamples->value(); j++) {myEvaluationFilter->Update();}
+ }
+
+ myEvaluationFilter->SetInput(NULL);
+ myPlayer=NULL;
+ EvaluationDataCollection.push_back(myEvaluationFilter);
+ }
+
+ //calculation and writing of output data
+ //open output file
+ m_CurrentAngleDifferencesWriteFile.open(std::string((m_Controls->m_OutputFilename->text() + ".angledifferences.csv").toUtf8()).c_str(), std::ios::out);
+ if (m_CurrentAngleDifferencesWriteFile.bad())
+ {
+ MessageBox("Error: Can't open output file for angle differences calculation!");
+ return;
+ }
+ //write header
+ WriteDifferenceAnglesHeader();
+ //compute angle differences
+ QString pos1 = "invalid";
+ QString pos2 = "invalid";
+ //now iterate through all evaluation data and calculate the angles
+ for(int i=0; im_DifferencesSLERP->isChecked())
+ {
+ //compute slerp average
+ q1 = GetSLERPAverage(EvaluationDataCollection.at(i));
+ q2 = GetSLERPAverage(EvaluationDataCollection.at(j));
+ }
+ else
+ {
+ //compute arithmetic average
+ q1 = EvaluationDataCollection.at(i)->GetQuaternionMean(0);
+ q2 = EvaluationDataCollection.at(j)->GetQuaternionMean(0);
+ }
+
+
+ double AngleBetweenTwoQuaternions = GetAngleBetweenTwoQuaterions(q1,q2);
+
+ //write data set
+ WriteDifferenceAnglesDataSet(pos1.toStdString(),pos2.toStdString(),i,j,AngleBetweenTwoQuaternions);
+ }
+ }
+
+ //close output file
+ m_CurrentAngleDifferencesWriteFile.close();
+ }
+
+void QmitkIGTTrackingDataEvaluationView::WriteDifferenceAnglesHeader()
+ {
+ m_CurrentAngleDifferencesWriteFile << "Name;Idx1;Idx2;Angle [-PI..+PI]; Angle [Degree]\n";
+ }
+
+void QmitkIGTTrackingDataEvaluationView::WriteDifferenceAnglesDataSet(std::string pos1, std::string pos2, int idx1, int idx2, double angle)
+ {
+ double PI = 3.1415926535897932384626433832795;
+ double angle_degree = (angle / PI) * 180;
+ m_CurrentAngleDifferencesWriteFile << "Angle between " << pos1 << " and " << pos2 << ";" << idx1 << ";" << idx2 << ";" << angle << ";" << angle_degree << "\n";
+ }
+
+double QmitkIGTTrackingDataEvaluationView::GetAngleBetweenTwoQuaterions(mitk::Quaternion a, mitk::Quaternion b)
+ {
+ double returnValue;
+
+ /*
+ //another variant
+ mitk::Quaternion combinedRotation = b * a;
+
+ itk::Vector pt1; //caution 5D-Tools: Vector must lie in the YZ-plane for a correct result.
+ pt1[0] = 0.0;
+ pt1[1] = 0.0;
+ pt1[2] = 100000.0;
+
+ itk::Matrix rotMatrixA;
+ for(int i=0; i<3; i++) for(int j=0; j<3; j++) rotMatrixA[i][j] = combinedRotation.rotation_matrix_transpose().transpose()[i][j];
+ itk::Vector pt2 = rotMatrixA*pt1;
+
+ //compute angle between the two vectors
+ returnValue = (pt1[0]*pt2[0]+pt1[1]*pt2[1]+pt1[2]*pt2[2]) / ( sqrt(pow(pt1[0],2)+pow(pt1[1],2)+pow(pt1[2],2)) * sqrt(pow(pt2[0],2)+pow(pt2[1],2)+pow(pt2[2],2)));
+ returnValue = acos(returnValue);
+
+ */
+
+ //variant with double precision
+
+ itk::Vector point; //caution 5D-Tools: Vector must lie in the YZ-plane for a correct result.
+ //TODO: welchen Vektor hier nehmen?
+ point[0] = 0;
+ point[1] = 100000.0;
+ point[2] = 100000.0;
+
+ //OB DAS HILFT?
+ a.normalize();
+ b.normalize();
+
+ itk::Matrix rotMatrixA;
+ for(int i=0; i<3; i++) for(int j=0; j<3; j++) rotMatrixA[i][j] = a.rotation_matrix_transpose().transpose()[i][j];
+
+ itk::Matrix rotMatrixB;
+ for(int i=0; i<3; i++) for(int j=0; j<3; j++) rotMatrixB[i][j] = b.rotation_matrix_transpose().transpose()[i][j];
+
+ itk::Vector pt1 = rotMatrixA * point;
+ itk::Vector pt2 = rotMatrixB * point;
+
+ returnValue = (pt1[0]*pt2[0]+pt1[1]*pt2[1]+pt1[2]*pt2[2]) / ( sqrt(pow(pt1[0],2.0)+pow(pt1[1],2.0)+pow(pt1[2],2.0)) * sqrt(pow(pt2[0],2.0)+pow(pt2[1],2.0)+pow(pt2[2],2.0)));
+ returnValue = acos(returnValue);
+
+
+ /* same code with float precision:
+ mitk::Point3D point;
+ mitk::FillVector3D(point,0,0,100); //caution 5D-Tools: Vector must lie in the YZ-plane for a correct result.
+ vnl_vector pt1 = a.rotate(point.Get_vnl_vector());
+ vnl_vector pt2 = b.rotate(point.Get_vnl_vector());
+
+ //compute angle between the two vectors
+ returnValue = (pt1[0]*pt2[0]+pt1[1]*pt2[1]+pt1[2]*pt2[2]) / ( sqrt(pow(pt1[0],2)+pow(pt1[1],2)+pow(pt1[2],2)) * sqrt(pow(pt2[0],2)+pow(pt2[1],2)+pow(pt2[2],2)));
+ returnValue = acos(returnValue);
+ //angle(pt1,pt2);
+ */
+
+
+ return returnValue;
+ }
+
+std::vector QmitkIGTTrackingDataEvaluationView::GetNavigationDatasFromFile(std::string filename)
+{
+std::vector returnValue = std::vector();
+std::vector fileContentLineByLine = GetFileContentLineByLine(filename);
+for(int i=1; i QmitkIGTTrackingDataEvaluationView::GetFileContentLineByLine(std::string filename)
+{
+std::vector readData = std::vector();
+
+//save old locale
+char * oldLocale;
+oldLocale = setlocale( LC_ALL, 0 );
+
+//define own locale
+std::locale C("C");
+setlocale( LC_ALL, "C" );
+
+//read file
+std::ifstream file;
+file.open(filename.c_str(), std::ios::in);
+if (file.good())
+ {
+ //read out file
+ file.seekg(0L, std::ios::beg); // move to begin of file
+ while (! file.eof())
+ {
+ std::string buffer;
+ std::getline(file,buffer); // read out file line by line
+ if (buffer.size() > 0) readData.push_back(buffer);
+
+ }
+ }
+
+file.close();
+
+//switch back to old locale
+setlocale( LC_ALL, oldLocale );
+
+return readData;
+}
+
+mitk::NavigationData::Pointer QmitkIGTTrackingDataEvaluationView::GetNavigationDataOutOfOneLine(std::string line)
+{
+ mitk::NavigationData::Pointer returnValue = mitk::NavigationData::New();
+
+ QString myLine = QString(line.c_str());
+
+ QStringList myLineList = myLine.split(';');
+
+ mitk::Point3D position;
+ mitk::Quaternion orientation;
+
+ double time = myLineList.at(1).toDouble();
+
+ bool valid = false;
+ if (myLineList.at(2).toStdString() == "1") valid = true;
+
+ position[0] = myLineList.at(3).toDouble();
+ position[1] = myLineList.at(4).toDouble();
+ position[2] = myLineList.at(5).toDouble();
+
+ orientation[0] = myLineList.at(6).toDouble();
+ orientation[1] = myLineList.at(7).toDouble();
+ orientation[2] = myLineList.at(8).toDouble();
+ orientation[3] = myLineList.at(9).toDouble();
+
+ //returnValue->SetTimeStamp(time);
+ returnValue->SetDataValid(valid);
+ returnValue->SetPosition(position);
+ returnValue->SetOrientation(orientation);
+
+ return returnValue;
+}
+
+mitk::Quaternion QmitkIGTTrackingDataEvaluationView::GetSLERPAverage(mitk::NavigationDataEvaluationFilter::Pointer evaluationFilter)
+{
+ mitk::Quaternion average;
+
+
+
+ //build a vector of quaternions from the evaulation filter (caution always takes the first (0) input of the filter
+ std::vector quaternions = std::vector();
+ for(int i=0; iGetNumberOfAnalysedNavigationData(0); i++)
+ {
+
+ mitk::Quaternion currentq = evaluationFilter->GetLoggedOrientation(i,0);
+
+ quaternions.push_back(currentq);
+ }
+
+ //compute the slerp average using the quaternion averaging class
+ mitk::QuaternionAveraging::Pointer myAverager = mitk::QuaternionAveraging::New();
+ average = myAverager->CalcAverage(quaternions);
+
+
+ return average;
+
+}
diff --git a/Plugins/org.mitk.gui.qt.igt.app.hummelprotocolmeasurements/src/internal/QmitkIGTTrackingDataEvaluationView.h b/Plugins/org.mitk.gui.qt.igt.app.hummelprotocolmeasurements/src/internal/QmitkIGTTrackingDataEvaluationView.h
new file mode 100644
index 0000000000..a928c578b3
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.igt.app.hummelprotocolmeasurements/src/internal/QmitkIGTTrackingDataEvaluationView.h
@@ -0,0 +1,125 @@
+/*=========================================================================
+
+Program: Medical Imaging & Interaction Toolkit
+Language: C++
+Date: $Date$
+Version: $Revision$
+
+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 QmitkIGTTrackingDataEvaluationView_h
+#define QmitkIGTTrackingDataEvaluationView_h
+
+#include
+
+#include
+
+#include "ui_QmitkIGTTrackingDataEvaluationViewControls.h"
+
+#include
+
+
+
+/*!
+ \brief QmitkIGTTrackingDataEvaluationView
+
+ \warning This application module is not yet documented. Use "svn blame/praise/annotate" and ask the author to provide basic documentation.
+
+ \sa QmitkFunctionality
+ \ingroup Functionalities
+*/
+class QmitkIGTTrackingDataEvaluationView : public QmitkFunctionality
+{
+ // this is needed for all Qt objects that should have a Qt meta-object
+ // (everything that derives from QObject and wants to have signal/slots)
+ Q_OBJECT
+
+ public:
+
+ static const std::string VIEW_ID;
+
+ QmitkIGTTrackingDataEvaluationView();
+ virtual ~QmitkIGTTrackingDataEvaluationView();
+
+ virtual void CreateQtPartControl(QWidget *parent);
+
+ virtual void StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget);
+ virtual void StdMultiWidgetNotAvailable();
+
+ protected slots:
+
+ void OnLoadFileList();
+ void OnAddToCurrentList();
+ void OnEvaluateData();
+ void OnGeneratePointSet();
+ void OnGeneratePointSetsOfSinglePositions();
+ void OnGenerateRotationLines();
+ void OnGenerateGroundTruthPointSet();
+ void OnConvertCSVtoXMLFile();
+ void OnCSVtoXMLLoadInputList();
+ void OnCSVtoXMLLoadOutputList();
+
+ /** Reads in exactly three position files als reference. */
+ void OnOrientationCalculation_CalcRef();
+ /** Uses always three positions (1,2,3: first orientation; 4,5,6: second orientation; and so on) in every file to calcualte a orientation. */
+ void OnOrientationCalculation_CalcOrientandWriteToFile();
+
+
+ protected:
+
+ Ui::QmitkIGTTrackingDataEvaluationViewControls* m_Controls;
+
+ QmitkStdMultiWidget* m_MultiWidget;
+
+ std::vector m_FilenameVector;
+
+ void MessageBox(std::string s);
+
+ std::fstream m_CurrentWriteFile;
+ void WriteHeader();
+ void WriteDataSet(mitk::NavigationDataEvaluationFilter::Pointer evaluationFilter, std::string dataSetName);
+
+ //members for orientation calculation
+ mitk::Point3D m_RefPoint1;
+ mitk::Point3D m_RefPoint2;
+ mitk::Point3D m_RefPoint3;
+
+ double m_scalingfactor; //scaling factor for visualization, 1 by default
+
+ //angle diffrences: seperated file
+ std::fstream m_CurrentAngleDifferencesWriteFile;
+ void CalculateDifferenceAngles();
+ void WriteDifferenceAnglesHeader();
+ void WriteDifferenceAnglesDataSet(std::string pos1, std::string pos2, int idx1, int idx2, double angle);
+
+ //different help methods to read a csv logging file
+ std::vector GetNavigationDatasFromFile(std::string filename);
+ std::vector GetFileContentLineByLine(std::string filename);
+ mitk::NavigationData::Pointer GetNavigationDataOutOfOneLine(std::string line);
+
+ //CSV to XML members
+ std::vector m_CSVtoXMLInputFilenameVector;
+ std::vector m_CSVtoXMLOutputFilenameVector;
+
+ //returns the number of converted lines
+ int ConvertOneFile(std::string inputFilename, std::string outputFilename);
+
+ /** @brief calculates the angle in the plane perpendicular to the rotation axis of the two quaterions. */
+ double GetAngleBetweenTwoQuaterions(mitk::Quaternion a, mitk::Quaternion b);
+
+ /** @brief calculates the slerp average of a set of quaternions which is stored in the navigation data evaluation filter */
+ mitk::Quaternion GetSLERPAverage(mitk::NavigationDataEvaluationFilter::Pointer);
+};
+
+
+
+#endif // _QMITKIGTTRACKINGDATAEVALUATIONVIEW_H_INCLUDED
+
diff --git a/Plugins/org.mitk.gui.qt.igt.app.hummelprotocolmeasurements/src/internal/QmitkIGTTrackingDataEvaluationViewControls.ui b/Plugins/org.mitk.gui.qt.igt.app.hummelprotocolmeasurements/src/internal/QmitkIGTTrackingDataEvaluationViewControls.ui
new file mode 100644
index 0000000000..9095e6a5af
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.igt.app.hummelprotocolmeasurements/src/internal/QmitkIGTTrackingDataEvaluationViewControls.ui
@@ -0,0 +1,941 @@
+
+
+ QmitkIGTTrackingDataEvaluationViewControls
+
+
+
+ 0
+ 0
+ 378
+ 955
+
+
+
+
+ 0
+ 0
+
+
+
+ QmitkTemplate
+
+
+ -
+
+
+ 0
+
+
+
+ Evaluation
+
+
+
-
+
+
+ Input File List (recorded NavigationData / *.csv):
+
+
+
+ -
+
+
+ -
+
+
-
+
+
+ Add Path:
+
+
+
+ -
+
+
+ D:/Experimente/
+
+
+
+
+
+ -
+
+
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+<html><head><meta name="qrichtext" content="1" /><style type="text/css">
+p, li { white-space: pre-wrap; }
+</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-style:italic;">(use text files with a complete filename in every line)</span></p></body></html>
+
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 110
+ 0
+
+
+
+ Load New List
+
+
+
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 110
+ 0
+
+
+
+ Add To Current List
+
+
+
+
+
+ -
+
+
-
+
+
+ Number of samples to analyze:
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ 1000000
+
+
+ 150
+
+
+
+
+
+ -
+
+
-
+
+
+ Result CSV Filename:
+
+
+
+ -
+
+
+ D:/Experimente/output.csv
+
+
+
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 200
+ 50
+
+
+
+
+ 200
+ 50
+
+
+
+ START EVALUATION
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+ Visualization Tools:
+
+
+
+ -
+
+
+ Generate PointSet of Mean Positions
+
+
+
+ -
+
+
+ Generate PointSets of Single Positions
+
+
+
+ -
+
+
+ Generate Lines for Rotation
+
+
+
+ -
+
+
-
+
+
+ Prefix for Data Nodes:
+
+
+
+ -
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Expanding
+
+
+
+ 20
+ 220
+
+
+
+
+
+
+
+
+ Settings
+
+
+ -
+
+
+ Output Settings
+
+
+
-
+
+
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+<html><head><meta name="qrichtext" content="1" /><style type="text/css">
+p, li { white-space: pre-wrap; }
+</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-style:italic; text-decoration: underline;">Position</span></p></body></html>
+
+
+
+ -
+
+
+ Mean (x,y,z)
+
+
+
+ -
+
+
+ Standard Deviation (x,y,z)
+
+
+
+ -
+
+
+ Sample Standard Deviation (x,y,z)
+
+
+
+ -
+
+
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+<html><head><meta name="qrichtext" content="1" /><style type="text/css">
+p, li { white-space: pre-wrap; }
+</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-style:italic; text-decoration: underline;">Orientation</span></p></body></html>
+
+
+
+ -
+
+
+ Quaternion Mean (qx,qy,qz,qr)
+
+
+
+ -
+
+
+ Quaternion Mean (SLERP)
+
+
+
+ -
+
+
+ Quaternion Standard Deviation (qx,qy,qz,qr)
+
+
+
+ -
+
+
+ Euler Mean (tx,ty,tz)
+
+
+
+ -
+
+
+ Difference Angles to all other Positions
+
+
+
+ -
+
+
+ Difference Angles to all other Positions (SLERP)
+
+
+
+ -
+
+
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+<html><head><meta name="qrichtext" content="1" /><style type="text/css">
+p, li { white-space: pre-wrap; }
+</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-style:italic; text-decoration: underline;">Position Error</span></p></body></html>
+
+
+
+ -
+
+
+ Mean
+
+
+
+ -
+
+
+ Standard Deviation
+
+
+
+ -
+
+
+ Sample Standard Deviation
+
+
+
+ -
+
+
+ RMS
+
+
+
+ -
+
+
+ Median
+
+
+
+ -
+
+
+ Min/Max
+
+
+
+ -
+
+
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+<html><head><meta name="qrichtext" content="1" /><style type="text/css">
+p, li { white-space: pre-wrap; }
+</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-style:italic; text-decoration: underline;">Orientation Error</span></p></body></html>
+
+
+
+ -
+
+
+ Euler RMS
+
+
+
+
+
+
+ -
+
+
-
+
+
+ Scaling Factor for Visualization:
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ 1.000000000000000
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 344
+
+
+
+
+
+
+
+
+ Tools
+
+
+ -
+
+
+ Point Set Ground Truth Generator
+
+
+
-
+
+
-
+
+
+ Generate
+
+
+
+ -
+
+
+ 1
+
+
+ 999
+
+
+ 10
+
+
+
+ -
+
+
+ X
+
+
+
+ -
+
+
+ 1
+
+
+ 999
+
+
+ 9
+
+
+
+ -
+
+
+ Point Set
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
-
+
+
+ Inter Point Distance (in mm):
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ 1
+
+
+ 99999
+
+
+ 50
+
+
+
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Generate
+
+
+
+
+
+
+
+
+ -
+
+
+ Result CSV File to NavigationData Converter
+
+
+
-
+
+
+ Convert Single File
+
+
+ true
+
+
+
+ -
+
+
+ Input CSV Logging File:
+
+
+
+ -
+
+
+ C:/Tools/test.csv
+
+
+
+ -
+
+
+ Output Navigation Data File:
+
+
+
+ -
+
+
+ C:/Tools/testoutput.xml
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+ Convert File List
+
+
+
+ -
+
+
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+<html><head><meta name="qrichtext" content="1" /><style type="text/css">
+p, li { white-space: pre-wrap; }
+</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-style:italic;">(use text files with a complete filename in every line)</span></p></body></html>
+
+
+
+ -
+
+
-
+
+
+ not loaded
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 100
+ 0
+
+
+
+ Load Input List
+
+
+
+
+
+ -
+
+
-
+
+
+ not loaded
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 100
+ 0
+
+
+
+ Load Output List
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Output Format
+
+
+
-
+
+
+ XML
+
+
+ true
+
+
+
+ -
+
+
+ CSV
+
+
+
+
+
+
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Convert
+
+
+
+
+
+
+
+
+ -
+
+
+ Orientation Calculation (out of three positions)
+
+
+
-
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Generate Reference From Current List
+
+
+
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Write Orientation Quaternions To File
+
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 632
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Plugins/org.mitk.gui.qt.igt.app.hummelprotocolmeasurements/src/internal/QmitkIGTTrackingSemiAutomaticMeasurementView.cpp b/Plugins/org.mitk.gui.qt.igt.app.hummelprotocolmeasurements/src/internal/QmitkIGTTrackingSemiAutomaticMeasurementView.cpp
new file mode 100644
index 0000000000..9a0c25196c
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.igt.app.hummelprotocolmeasurements/src/internal/QmitkIGTTrackingSemiAutomaticMeasurementView.cpp
@@ -0,0 +1,667 @@
+/*=========================================================================
+
+Program: Medical Imaging & Interaction Toolkit
+Language: C++
+Date: $Date$
+Version: $Revision$
+
+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.
+
+=========================================================================*/
+
+// Blueberry
+#include
+#include
+
+// Qmitk
+#include "QmitkIGTTrackingSemiAutomaticMeasurementView.h"
+#include "QmitkStdMultiWidget.h"
+
+// Qt
+#include
+#include
+#include
+#include
+
+// MITK
+#include
+#include
+#include
+
+// POCO
+#include
+#include
+
+const std::string QmitkIGTTrackingSemiAutomaticMeasurementView::VIEW_ID = "org.mitk.views.igttrackingsemiautomaticmeasurement";
+
+QmitkIGTTrackingSemiAutomaticMeasurementView::QmitkIGTTrackingSemiAutomaticMeasurementView()
+ : QmitkFunctionality()
+ , m_Controls(0)
+ , m_MultiWidget(NULL)
+{
+ m_NextFile = 0;
+ m_FilenameVector = std::vector();
+ m_Timer = new QTimer(this);
+ m_logging = false;
+ m_referenceValid = true;
+ m_tracking = false;
+ m_EvaluationFilter = mitk::NavigationDataEvaluationFilter::New();
+}
+
+QmitkIGTTrackingSemiAutomaticMeasurementView::~QmitkIGTTrackingSemiAutomaticMeasurementView()
+{
+}
+
+void QmitkIGTTrackingSemiAutomaticMeasurementView::CreateResults()
+{
+ QString LogFileName = m_Controls->m_OutputPath->text() + "_results.log";
+ mitk::LoggingBackend::Unregister();
+ mitk::LoggingBackend::SetLogFile(LogFileName.toStdString().c_str());
+ mitk::LoggingBackend::Register();
+
+ double RMSmean = 0;
+ for (int i = 0; i < m_RMSValues.size(); i++)
+ {
+ MITK_INFO << "RMS at " << this->m_FilenameVector.at(i) << ": " << m_RMSValues.at(i);
+ RMSmean += m_RMSValues.at(i);
+ }
+ RMSmean /= m_RMSValues.size();
+ MITK_INFO << "RMS mean over " << m_RMSValues.size() << " values: " << RMSmean;
+
+ mitk::DataNode::Pointer newNode = mitk::DataNode::New();
+ newNode->SetName("Tracking Results");
+ newNode->SetData(this->m_MeanPoints);
+ this->GetDataStorage()->Add(newNode);
+
+ if (m_MeanPoints->GetSize() == 12)
+ {
+ MITK_INFO << "Computing distance error for Compact FG...";
+ std::vector distances;
+ mitk::Point3D test;
+ //row 1
+ distances.push_back(m_MeanPoints->GetPoint(0).EuclideanDistanceTo(m_MeanPoints->GetPoint(1))); //0
+ distances.push_back(m_MeanPoints->GetPoint(1).EuclideanDistanceTo(m_MeanPoints->GetPoint(2))); //1
+ distances.push_back(m_MeanPoints->GetPoint(2).EuclideanDistanceTo(m_MeanPoints->GetPoint(3))); //2
+ //row 2
+ distances.push_back(m_MeanPoints->GetPoint(4).EuclideanDistanceTo(m_MeanPoints->GetPoint(5))); //3
+ distances.push_back(m_MeanPoints->GetPoint(5).EuclideanDistanceTo(m_MeanPoints->GetPoint(6))); //4
+ distances.push_back(m_MeanPoints->GetPoint(6).EuclideanDistanceTo(m_MeanPoints->GetPoint(7))); //5
+ //row 3
+ distances.push_back(m_MeanPoints->GetPoint(8).EuclideanDistanceTo(m_MeanPoints->GetPoint(9))); //6
+ distances.push_back(m_MeanPoints->GetPoint(9).EuclideanDistanceTo(m_MeanPoints->GetPoint(10))); //7
+ distances.push_back(m_MeanPoints->GetPoint(10).EuclideanDistanceTo(m_MeanPoints->GetPoint(11))); //8
+ //column 1
+ distances.push_back(m_MeanPoints->GetPoint(0).EuclideanDistanceTo(m_MeanPoints->GetPoint(4))); //9
+ distances.push_back(m_MeanPoints->GetPoint(4).EuclideanDistanceTo(m_MeanPoints->GetPoint(8))); //10
+ //column 2
+ distances.push_back(m_MeanPoints->GetPoint(1).EuclideanDistanceTo(m_MeanPoints->GetPoint(5))); //11
+ distances.push_back(m_MeanPoints->GetPoint(5).EuclideanDistanceTo(m_MeanPoints->GetPoint(9))); //12
+ //column 3
+ distances.push_back(m_MeanPoints->GetPoint(2).EuclideanDistanceTo(m_MeanPoints->GetPoint(6))); //13
+ distances.push_back(m_MeanPoints->GetPoint(6).EuclideanDistanceTo(m_MeanPoints->GetPoint(10))); //14
+ //column 4
+ distances.push_back(m_MeanPoints->GetPoint(3).EuclideanDistanceTo(m_MeanPoints->GetPoint(7))); //15
+ distances.push_back(m_MeanPoints->GetPoint(7).EuclideanDistanceTo(m_MeanPoints->GetPoint(11))); //16
+
+ std::vector errors;
+ double meanError = 0;
+ for (int i = 0; i < distances.size(); i++)
+ {
+ double currentError = distances.at(i) - (double)50.0;
+ errors.push_back(currentError);
+ meanError += currentError;
+ MITK_INFO << "Error" << i << " : " << currentError;
+ }
+ meanError /= distances.size();
+ MITK_INFO << "Mean error : " << meanError;
+ }
+}
+
+void QmitkIGTTrackingSemiAutomaticMeasurementView::CreateQtPartControl(QWidget *parent)
+{
+ // build up qt view, unless already done
+ if (!m_Controls)
+ {
+ // create GUI widgets from the Qt Designer's .ui file
+ m_Controls = new Ui::QmitkIGTTrackingSemiAutomaticMeasurementViewControls;
+ m_Controls->setupUi(parent);
+
+ //buttons
+ connect(m_Controls->m_LoadMeasurementToolStorage, SIGNAL(clicked()), this, SLOT(OnLoadMeasurementStorage()));
+ connect(m_Controls->m_LoadReferenceToolStorage, SIGNAL(clicked()), this, SLOT(OnLoadReferenceStorage()));
+ connect(m_Controls->m_StartTracking, SIGNAL(clicked()), this, SLOT(OnStartTracking()));
+ connect(m_Controls->m_LoadList, SIGNAL(clicked()), this, SLOT(OnMeasurementLoadFile()));
+ connect(m_Controls->m_StartNextMeasurement, SIGNAL(clicked()), this, SLOT(StartNextMeasurement()));
+ connect(m_Controls->m_ReapeatLastMeasurement, SIGNAL(clicked()), this, SLOT(RepeatLastMeasurement()));
+ connect(m_Controls->m_SetReference, SIGNAL(clicked()), this, SLOT(OnSetReference()));
+ connect(m_Controls->m_UseReferenceTrackingSystem, SIGNAL(toggled(bool)), this, SLOT(OnUseReferenceToggled(bool)));
+ connect(m_Controls->m_CreateResults, SIGNAL(clicked()), this, SLOT(CreateResults()));
+
+ //event filter
+ qApp->installEventFilter(this);
+
+ //timers
+ connect(m_Timer, SIGNAL(timeout()), this, SLOT(UpdateTimer()));
+ }
+
+ //initialize some view
+ m_Controls->m_StopTracking->setEnabled(false);
+}
+
+void QmitkIGTTrackingSemiAutomaticMeasurementView::StdMultiWidgetAvailable(QmitkStdMultiWidget &stdMultiWidget)
+{
+ m_MultiWidget = &stdMultiWidget;
+}
+
+void QmitkIGTTrackingSemiAutomaticMeasurementView::OnUseReferenceToggled(bool state)
+{
+ if (state)
+ {
+ m_Controls->m_ReferenceBox->setEnabled(true);
+ m_Controls->m_SetReference->setEnabled(true);
+ }
+
+ else
+ {
+ m_Controls->m_ReferenceBox->setEnabled(false);
+ m_Controls->m_SetReference->setEnabled(false);
+ }
+}
+
+void QmitkIGTTrackingSemiAutomaticMeasurementView::StdMultiWidgetNotAvailable()
+{
+ m_MultiWidget = NULL;
+}
+
+mitk::NavigationToolStorage::Pointer QmitkIGTTrackingSemiAutomaticMeasurementView::ReadStorage(std::string file)
+{
+ mitk::NavigationToolStorage::Pointer returnValue;
+
+ //initialize tool storage
+ returnValue = mitk::NavigationToolStorage::New();
+
+ //read tool storage from disk
+ mitk::NavigationToolStorageDeserializer::Pointer myDeserializer = mitk::NavigationToolStorageDeserializer::New(GetDataStorage());
+ returnValue = myDeserializer->Deserialize(file);
+ if (returnValue.IsNull())
+ {
+ QMessageBox msgBox;
+ msgBox.setText(myDeserializer->GetErrorMessage().c_str());
+ msgBox.exec();
+
+ returnValue = NULL;
+ }
+
+ return returnValue;
+}
+
+void QmitkIGTTrackingSemiAutomaticMeasurementView::OnSetReference()
+{
+ //initialize reference
+ m_ReferenceStartPositions = std::vector();
+ m_ReferenceTrackingDeviceSource->Update();
+ QString Label = "Positions At Start: ";
+ for (int i = 0; i < m_ReferenceTrackingDeviceSource->GetNumberOfOutputs(); i++)
+ {
+ mitk::Point3D position = m_ReferenceTrackingDeviceSource->GetOutput(i)->GetPosition();
+ Label = Label + "Tool" + QString::number(i) + ":[" + QString::number(position[0]) + ":" + QString::number(position[1]) + ":" + QString::number(position[1]) + "] ";
+ m_ReferenceStartPositions.push_back(position);
+ }
+ m_Controls->m_ReferencePosAtStart->setText(Label);
+}
+
+void QmitkIGTTrackingSemiAutomaticMeasurementView::OnLoadMeasurementStorage()
+{
+ //read in filename
+ QString filename = QFileDialog::getOpenFileName(NULL, tr("Open Toolfile"), "/", tr("All Files (*.*)"));
+ if (filename.isNull()) return;
+
+ m_MeasurementStorage = ReadStorage(filename.toStdString());
+
+ //update label
+ Poco::Path myPath = Poco::Path(filename.toStdString()); //use this to seperate filename from path
+ QString toolLabel = QString("Tool Storage: ") + QString::number(m_MeasurementStorage->GetToolCount()) + " Tools from " + myPath.getFileName().c_str();
+ m_Controls->m_MeasurementToolStorageLabel->setText(toolLabel);
+
+ //update status widget
+ m_Controls->m_ToolStatusWidget->RemoveStatusLabels();
+ m_Controls->m_ToolStatusWidget->PreShowTools(m_MeasurementStorage);
+}
+
+void QmitkIGTTrackingSemiAutomaticMeasurementView::OnLoadReferenceStorage()
+{
+ //read in filename
+ static QString oldFile;
+ if (oldFile.isNull()) oldFile = "/";
+ QString filename = QFileDialog::getOpenFileName(NULL, tr("Open Toolfile"), oldFile, tr("All Files (*.*)"));
+ if (filename.isNull()) return;
+ oldFile = filename;
+
+ m_ReferenceStorage = ReadStorage(filename.toStdString());
+
+ //update label
+ Poco::Path myPath = Poco::Path(filename.toStdString()); //use this to seperate filename from path
+ QString toolLabel = QString("Tool Storage: ") + QString::number(m_ReferenceStorage->GetToolCount()) + " Tools from " + myPath.getFileName().c_str();
+ m_Controls->m_ReferenceToolStorageLabel->setText(toolLabel);
+}
+
+void QmitkIGTTrackingSemiAutomaticMeasurementView::OnStartTracking()
+{
+ //check if everything is ready to start tracking
+ if (m_MeasurementStorage.IsNull())
+ {
+ MessageBox("Error: No measurement tools loaded yet!");
+ return;
+ }
+ else if (m_ReferenceStorage.IsNull() && m_Controls->m_UseReferenceTrackingSystem->isChecked())
+ {
+ MessageBox("Error: No refernce tools loaded yet!");
+ return;
+ }
+ else if (m_MeasurementStorage->GetToolCount() == 0)
+ {
+ MessageBox("Error: No way to track without tools!");
+ return;
+ }
+ else if (m_Controls->m_UseReferenceTrackingSystem->isChecked() && (m_ReferenceStorage->GetToolCount() == 0))
+ {
+ MessageBox("Error: No way to track without tools!");
+ return;
+ }
+
+ //build the first IGT pipeline (MEASUREMENT)
+ mitk::TrackingDeviceSourceConfigurator::Pointer myTrackingDeviceSourceFactory1 = mitk::TrackingDeviceSourceConfigurator::New(this->m_MeasurementStorage, this->m_Controls->m_MeasurementTrackingDeviceConfigurationWidget->GetTrackingDevice());
+ m_MeasurementTrackingDeviceSource = myTrackingDeviceSourceFactory1->CreateTrackingDeviceSource(this->m_MeasurementToolVisualizationFilter);
+ if (m_MeasurementTrackingDeviceSource.IsNull())
+ {
+ MessageBox(myTrackingDeviceSourceFactory1->GetErrorMessage());
+ return;
+ }
+ //connect the tool visualization widget
+ for (int i = 0; i < m_MeasurementTrackingDeviceSource->GetNumberOfOutputs(); i++)
+ {
+ m_Controls->m_ToolStatusWidget->AddNavigationData(m_MeasurementTrackingDeviceSource->GetOutput(i));
+ m_EvaluationFilter->SetInput(i, m_MeasurementTrackingDeviceSource->GetOutput(i));
+ }
+ m_Controls->m_ToolStatusWidget->ShowStatusLabels();
+ m_Controls->m_ToolStatusWidget->SetShowPositions(true);
+ m_Controls->m_ToolStatusWidget->SetShowQuaternions(true);
+
+ //build the second IGT pipeline (REFERENCE)
+ if (m_Controls->m_UseReferenceTrackingSystem->isChecked())
+ {
+ mitk::TrackingDeviceSourceConfigurator::Pointer myTrackingDeviceSourceFactory2 = mitk::TrackingDeviceSourceConfigurator::New(this->m_ReferenceStorage, this->m_Controls->m_ReferenceDeviceConfigurationWidget->GetTrackingDevice());
+ m_ReferenceTrackingDeviceSource = myTrackingDeviceSourceFactory2->CreateTrackingDeviceSource();
+ if (m_ReferenceTrackingDeviceSource.IsNull())
+ {
+ MessageBox(myTrackingDeviceSourceFactory2->GetErrorMessage());
+ return;
+ }
+ }
+
+ //initialize tracking
+ try
+ {
+ m_MeasurementTrackingDeviceSource->Connect();
+ m_MeasurementTrackingDeviceSource->StartTracking();
+ if (m_Controls->m_UseReferenceTrackingSystem->isChecked())
+ {
+ m_ReferenceTrackingDeviceSource->Connect();
+ m_ReferenceTrackingDeviceSource->StartTracking();
+ }
+ }
+ catch (...)
+ {
+ MessageBox("Error while starting the tracking device!");
+ return;
+ }
+
+ //set reference
+ if (m_Controls->m_UseReferenceTrackingSystem->isChecked()) OnSetReference();
+
+ //start timer
+ m_Timer->start(1000 / (m_Controls->m_SamplingRate->value()));
+
+ m_Controls->m_StartTracking->setEnabled(false);
+ m_Controls->m_StartTracking->setEnabled(true);
+
+ m_tracking = true;
+}
+
+void QmitkIGTTrackingSemiAutomaticMeasurementView::OnStopTracking()
+{
+ if (this->m_logging) FinishMeasurement();
+ m_MeasurementTrackingDeviceSource->Disconnect();
+ m_MeasurementTrackingDeviceSource->StopTracking();
+ if (m_Controls->m_UseReferenceTrackingSystem->isChecked())
+ {
+ m_ReferenceTrackingDeviceSource->Disconnect();
+ m_ReferenceTrackingDeviceSource->StopTracking();
+ }
+ m_Timer->stop();
+ m_Controls->m_StartTracking->setEnabled(true);
+ m_Controls->m_StartTracking->setEnabled(false);
+ m_tracking = false;
+}
+
+void QmitkIGTTrackingSemiAutomaticMeasurementView::OnMeasurementLoadFile()
+{
+ m_FilenameVector = std::vector();
+ m_FilenameVector.clear();
+ m_NextFile = 0;
+
+ //read in filename
+ QString filename = QFileDialog::getOpenFileName(NULL, tr("Open Measurement Filename List"), "/", tr("All Files (*.*)"));
+ if (filename.isNull()) return;
+
+ //save old locale
+ char * oldLocale;
+ oldLocale = setlocale(LC_ALL, 0);
+
+ //define own locale
+ std::locale C("C");
+ setlocale(LC_ALL, "C");
+
+ //read file
+ std::ifstream file;
+ file.open(filename.toStdString().c_str(), std::ios::in);
+ if (file.good())
+ {
+ //read out file
+ file.seekg(0L, std::ios::beg); // move to begin of file
+ while (!file.eof())
+ {
+ std::string buffer;
+ std::getline(file, buffer); // read out file line by line
+ if (buffer.size() > 0) m_FilenameVector.push_back(buffer);
+ }
+ }
+
+ //fill list at GUI
+ m_Controls->m_MeasurementList->clear();
+ for (unsigned int i = 0; i < m_FilenameVector.size(); i++) { new QListWidgetItem(tr(m_FilenameVector.at(i).c_str()), m_Controls->m_MeasurementList); }
+
+ //update label next measurement
+ std::stringstream label;
+ label << "Next Measurement: " << m_FilenameVector.at(0);
+ m_Controls->m_NextMeasurement->setText(label.str().c_str());
+
+ //reset results files
+ m_MeanPoints = mitk::PointSet::New();
+ m_RMSValues = std::vector();
+ m_EvaluationFilter = mitk::NavigationDataEvaluationFilter::New();
+ if (m_MeasurementToolVisualizationFilter.IsNotNull()) m_EvaluationFilter->SetInput(0, m_MeasurementToolVisualizationFilter->GetOutput(0));
+}
+
+void QmitkIGTTrackingSemiAutomaticMeasurementView::UpdateTimer()
+{
+ if (m_EvaluationFilter.IsNotNull() && m_logging) m_EvaluationFilter->Update();
+ else m_MeasurementToolVisualizationFilter->Update();
+
+ m_Controls->m_ToolStatusWidget->Refresh();
+
+ //update reference
+ if (m_Controls->m_UseReferenceTrackingSystem->isChecked())
+ {
+ m_ReferenceTrackingDeviceSource->Update();
+ QString Label = "Current Positions: ";
+ bool distanceThresholdExceeded = false;
+ for (int i = 0; i < m_ReferenceTrackingDeviceSource->GetNumberOfOutputs(); i++)
+ {
+ mitk::Point3D position = m_ReferenceTrackingDeviceSource->GetOutput(i)->GetPosition();
+ Label = Label + "Tool" + QString::number(i) + ":[" + QString::number(position[0]) + ":" + QString::number(position[1]) + ":" + QString::number(position[1]) + "] ";
+ if (position.EuclideanDistanceTo(m_ReferenceStartPositions.at(i)) > m_Controls->m_ReferenceThreshold->value()) distanceThresholdExceeded = true;
+ }
+ m_Controls->m_ReferenceCurrentPos->setText(Label);
+ if (distanceThresholdExceeded)
+ {
+ m_Controls->m_ReferenceOK->setText("NOT OK!");
+ m_referenceValid = false;
+ }
+ else
+ {
+ m_Controls->m_ReferenceOK->setText("OK");
+ m_referenceValid = true;
+ }
+ }
+
+ //update logging
+ if (m_logging)
+ {
+ //check for missing objects
+ if (m_MeasurementLoggingFilterXML.IsNull() ||
+ m_MeasurementLoggingFilterCSV.IsNull()
+ )
+ {
+ return;
+ }
+
+ //log/measure
+ m_MeasurementLoggingFilterXML->Update();
+ m_MeasurementLoggingFilterCSV->Update();
+
+ if (m_Controls->m_UseReferenceTrackingSystem->isChecked() &&
+ m_ReferenceLoggingFilterXML.IsNotNull() &&
+ m_ReferenceLoggingFilterCSV.IsNotNull())
+ {
+ m_ReferenceLoggingFilterXML->Update();
+ m_ReferenceLoggingFilterCSV->Update();
+ }
+ m_loggedFrames++;
+ LogAdditionalCSVFile();
+
+ //check if all frames are logged ... if yes finish the measurement
+ if (m_loggedFrames > m_Controls->m_SamplesPerMeasurement->value()) { FinishMeasurement(); }
+
+ //update logging label
+ QString loggingLabel = "Collected Samples: " + QString::number(m_loggedFrames);
+ m_Controls->m_CollectedSamples->setText(loggingLabel);
+ }
+}
+
+void QmitkIGTTrackingSemiAutomaticMeasurementView::StartNextMeasurement()
+{
+ if (this->m_NextFile >= m_FilenameVector.size())
+ {
+ MessageBox("Last Measurement reached!");
+ return;
+ }
+
+ m_loggedFrames = 0;
+ m_logging = true;
+
+ //check if directory exists, if not create one
+ Poco::File myPath(std::string(m_Controls->m_OutputPath->text().toUtf8()).c_str());
+ if (!myPath.exists()) myPath.createDirectory();
+
+ QString LogFileName = m_Controls->m_OutputPath->text() + QString(m_FilenameVector.at(m_NextFile).c_str()) + ".log";
+ mitk::LoggingBackend::Unregister();
+ mitk::LoggingBackend::SetLogFile(LogFileName.toStdString().c_str());
+ mitk::LoggingBackend::Register();
+
+ //initialize logging filters
+ m_MeasurementLoggingFilterXML = mitk::NavigationDataRecorderDeprecated::New();
+ m_MeasurementLoggingFilterXML->SetRecordingMode(mitk::NavigationDataRecorderDeprecated::NormalFile);
+ m_MeasurementLoggingFilterCSV = mitk::NavigationDataRecorderDeprecated::New();
+ m_MeasurementLoggingFilterCSV->SetRecordingMode(mitk::NavigationDataRecorderDeprecated::NormalFile);
+ m_MeasurementLoggingFilterXML->SetOutputFormat(mitk::NavigationDataRecorderDeprecated::xml);
+ m_MeasurementLoggingFilterCSV->SetOutputFormat(mitk::NavigationDataRecorderDeprecated::csv);
+ QString MeasurementFilenameXML = m_Controls->m_OutputPath->text() + QString(m_FilenameVector.at(m_NextFile).c_str()) + ".xml";
+ QString MeasurementFilenameCSV = m_Controls->m_OutputPath->text() + QString(m_FilenameVector.at(m_NextFile).c_str()) + ".csv";
+ m_MeasurementLoggingFilterXML->SetFileName(MeasurementFilenameXML.toStdString());
+ m_MeasurementLoggingFilterCSV->SetFileName(MeasurementFilenameCSV.toStdString());
+ m_MeasurementLoggingFilterXML->SetRecordCountLimit(m_Controls->m_SamplesPerMeasurement->value());
+ m_MeasurementLoggingFilterCSV->SetRecordCountLimit(m_Controls->m_SamplesPerMeasurement->value());
+
+ if (m_Controls->m_UseReferenceTrackingSystem->isChecked())
+ {
+ m_ReferenceLoggingFilterXML = mitk::NavigationDataRecorderDeprecated::New();
+ m_ReferenceLoggingFilterXML->SetRecordingMode(mitk::NavigationDataRecorderDeprecated::NormalFile);
+ m_ReferenceLoggingFilterCSV = mitk::NavigationDataRecorderDeprecated::New();
+ m_ReferenceLoggingFilterCSV->SetRecordingMode(mitk::NavigationDataRecorderDeprecated::NormalFile);
+ m_ReferenceLoggingFilterXML->SetOutputFormat(mitk::NavigationDataRecorderDeprecated::xml);
+ m_ReferenceLoggingFilterCSV->SetOutputFormat(mitk::NavigationDataRecorderDeprecated::csv);
+ QString ReferenceFilenameXML = m_Controls->m_OutputPath->text() + "Reference_" + QString(m_FilenameVector.at(m_NextFile).c_str()) + ".xml";
+ QString ReferenceFilenameCSV = m_Controls->m_OutputPath->text() + "Reference_" + QString(m_FilenameVector.at(m_NextFile).c_str()) + ".csv";
+ m_ReferenceLoggingFilterXML->SetFileName(ReferenceFilenameXML.toStdString());
+ m_ReferenceLoggingFilterCSV->SetFileName(ReferenceFilenameCSV.toStdString());
+ m_ReferenceLoggingFilterXML->SetRecordCountLimit(m_Controls->m_SamplesPerMeasurement->value());
+ m_ReferenceLoggingFilterCSV->SetRecordCountLimit(m_Controls->m_SamplesPerMeasurement->value());
+ }
+
+ //start additional csv logging
+ StartLoggingAdditionalCSVFile(m_FilenameVector.at(m_NextFile));
+
+ //connect filter
+ for (int i = 0; i < m_MeasurementToolVisualizationFilter->GetNumberOfOutputs(); i++)
+ {
+ m_MeasurementLoggingFilterXML->AddNavigationData(m_MeasurementToolVisualizationFilter->GetOutput(i));
+ m_MeasurementLoggingFilterCSV->AddNavigationData(m_MeasurementToolVisualizationFilter->GetOutput(i));
+ }
+ if (m_Controls->m_UseReferenceTrackingSystem->isChecked()) for (int i = 0; i < m_ReferenceTrackingDeviceSource->GetNumberOfOutputs(); i++)
+ {
+ m_ReferenceLoggingFilterXML->AddNavigationData(m_ReferenceTrackingDeviceSource->GetOutput(i));
+ m_ReferenceLoggingFilterCSV->AddNavigationData(m_ReferenceTrackingDeviceSource->GetOutput(i));
+ }
+
+ //start filter
+ m_MeasurementLoggingFilterXML->StartRecording();
+ m_MeasurementLoggingFilterCSV->StartRecording();
+ if (m_Controls->m_UseReferenceTrackingSystem->isChecked())
+ {
+ m_ReferenceLoggingFilterXML->StartRecording();
+ m_ReferenceLoggingFilterCSV->StartRecording();
+ }
+
+ //disable all buttons
+ DisableAllButtons();
+
+ //update label next measurement
+ std::stringstream label;
+ if ((m_NextFile + 1) >= m_FilenameVector.size()) label << "Next Measurement: ";
+ else label << "Next Measurement: " << m_FilenameVector.at(m_NextFile + 1);
+ m_Controls->m_NextMeasurement->setText(label.str().c_str());
+
+ //update label last measurement
+ std::stringstream label2;
+ label2 << "Last Measurement: " << m_FilenameVector.at(m_NextFile);
+ m_Controls->m_LastMeasurement->setText(label2.str().c_str());
+
+ m_NextFile++;
+}
+
+void QmitkIGTTrackingSemiAutomaticMeasurementView::RepeatLastMeasurement()
+{
+ m_NextFile--;
+ StartNextMeasurement();
+}
+
+void QmitkIGTTrackingSemiAutomaticMeasurementView::MessageBox(std::string s)
+{
+ QMessageBox msgBox;
+ msgBox.setText(s.c_str());
+ msgBox.exec();
+}
+
+void QmitkIGTTrackingSemiAutomaticMeasurementView::DisableAllButtons()
+{
+ m_Controls->m_LoadList->setEnabled(false);
+ m_Controls->m_StartNextMeasurement->setEnabled(false);
+ m_Controls->m_ReapeatLastMeasurement->setEnabled(false);
+ m_Controls->m_SamplingRate->setEnabled(false);
+ m_Controls->m_SamplesPerMeasurement->setEnabled(false);
+ m_Controls->m_ReferenceThreshold->setEnabled(false);
+}
+
+void QmitkIGTTrackingSemiAutomaticMeasurementView::EnableAllButtons()
+{
+ m_Controls->m_LoadList->setEnabled(true);
+ m_Controls->m_StartNextMeasurement->setEnabled(true);
+ m_Controls->m_ReapeatLastMeasurement->setEnabled(true);
+ m_Controls->m_SamplingRate->setEnabled(true);
+ m_Controls->m_SamplesPerMeasurement->setEnabled(true);
+ m_Controls->m_ReferenceThreshold->setEnabled(true);
+}
+
+void QmitkIGTTrackingSemiAutomaticMeasurementView::FinishMeasurement()
+{
+ m_logging = false;
+
+ m_MeasurementLoggingFilterXML->StopRecording();
+ m_MeasurementLoggingFilterCSV->StopRecording();
+ if (m_Controls->m_UseReferenceTrackingSystem->isChecked())
+ {
+ m_ReferenceLoggingFilterXML->StopRecording();
+ m_ReferenceLoggingFilterCSV->StopRecording();
+ }
+ StopLoggingAdditionalCSVFile();
+
+ int id = m_NextFile - 1;
+ mitk::Point3D positionMean = m_EvaluationFilter->GetPositionMean(0);
+ MITK_INFO << "Evaluated " << m_EvaluationFilter->GetNumberOfAnalysedNavigationData(0) << " samples.";
+ double rms = m_EvaluationFilter->GetPositionErrorRMS(0);
+ MITK_INFO << "RMS: " << rms;
+ MITK_INFO << "Position Mean: " << positionMean;
+ m_MeanPoints->SetPoint(id, positionMean);
+ if (m_RMSValues.size() <= id) m_RMSValues.push_back(rms);
+ else m_RMSValues[id] = rms;
+
+ m_EvaluationFilter->ResetStatistic();
+
+ EnableAllButtons();
+}
+
+void QmitkIGTTrackingSemiAutomaticMeasurementView::StartLoggingAdditionalCSVFile(std::string filePostfix)
+{
+ //write logfile header
+ QString header = "Nr;MITK_Time;Valid_Reference;";
+ QString tool = QString("MeasureTool_") + QString(m_MeasurementTrackingDeviceSource->GetOutput(0)->GetName());
+ header = header + tool + "[x];" + tool + "[y];" + tool + "[z];" + tool + "[qx];" + tool + "[qy];" + tool + "[qz];" + tool + "[qr]\n";
+
+ //open logfile and write header
+ m_logFileCSV.open(std::string(m_Controls->m_OutputPath->text().toUtf8()).append("/LogFileCombined").append(filePostfix.c_str()).append(".csv").c_str(), std::ios::out);
+ m_logFileCSV << header.toStdString().c_str();
+}
+
+void QmitkIGTTrackingSemiAutomaticMeasurementView::LogAdditionalCSVFile()
+{
+ mitk::Point3D pos = m_MeasurementTrackingDeviceSource->GetOutput(0)->GetPosition();
+ mitk::Quaternion rot = m_MeasurementTrackingDeviceSource->GetOutput(0)->GetOrientation();
+ std::string valid = "";
+ if (m_referenceValid) valid = "true";
+ else valid = "false";
+ std::stringstream timestamp;
+ timestamp << m_MeasurementTrackingDeviceSource->GetOutput(0)->GetTimeStamp();
+ QString dataSet = QString::number(m_loggedFrames) + ";" + QString(timestamp.str().c_str()) + ";" + QString(valid.c_str()) + ";" + QString::number(pos[0]) + ";" + QString::number(pos[1]) + ";" + QString::number(pos[2]) + ";" + QString::number(rot.x()) + ";" + QString::number(rot.y()) + ";" + QString::number(rot.z()) + ";" + QString::number(rot.r()) + "\n";
+ m_logFileCSV << dataSet.toStdString();
+}
+
+void QmitkIGTTrackingSemiAutomaticMeasurementView::StopLoggingAdditionalCSVFile()
+{
+ m_logFileCSV.close();
+}
+
+bool QmitkIGTTrackingSemiAutomaticMeasurementView::eventFilter(QObject *obj, QEvent *ev)
+{
+ if (ev->type() == QEvent::KeyPress)
+ {
+ QKeyEvent *k = (QKeyEvent *)ev;
+ bool up = false;
+ bool down = false;
+ if (k->key() == 16777238) up = true; //page up
+ else if (k->key() == 16777239) down = true; //page down
+
+ if (down && m_tracking && !m_logging)
+ {
+ StartNextMeasurement();
+ }
+ }
+
+ return false;
+}
diff --git a/Plugins/org.mitk.gui.qt.igt.app.hummelprotocolmeasurements/src/internal/QmitkIGTTrackingSemiAutomaticMeasurementView.h b/Plugins/org.mitk.gui.qt.igt.app.hummelprotocolmeasurements/src/internal/QmitkIGTTrackingSemiAutomaticMeasurementView.h
new file mode 100644
index 0000000000..85fe08d498
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.igt.app.hummelprotocolmeasurements/src/internal/QmitkIGTTrackingSemiAutomaticMeasurementView.h
@@ -0,0 +1,133 @@
+/*=========================================================================
+
+Program: Medical Imaging & Interaction Toolkit
+Language: C++
+Date: $Date$
+Version: $Revision$
+
+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 QmitkIGTTrackingSemiAutomaticMeasurementView_h
+#define QmitkIGTTrackingSemiAutomaticMeasurementView_h
+
+#include
+
+#include
+
+//QT
+#include
+
+//MITK
+#include
+#include
+#include
+#include
+#include
+
+#include "ui_QmitkIGTTrackingSemiAutomaticMeasurementViewControls.h"
+
+/*!
+ \brief QmitkIGTTrackingSemiAutomaticMeasurementView
+
+ \warning This application module is not yet documented. Use "svn blame/praise/annotate" and ask the author to provide basic documentation.
+
+ \sa QmitkFunctionality
+ \ingroup Functionalities
+ */
+class QmitkIGTTrackingSemiAutomaticMeasurementView : public QmitkFunctionality
+{
+ // this is needed for all Qt objects that should have a Qt meta-object
+ // (everything that derives from QObject and wants to have signal/slots)
+ Q_OBJECT
+
+public:
+
+ static const std::string VIEW_ID;
+
+ QmitkIGTTrackingSemiAutomaticMeasurementView();
+ virtual ~QmitkIGTTrackingSemiAutomaticMeasurementView();
+
+ virtual void CreateQtPartControl(QWidget *parent);
+
+ virtual void StdMultiWidgetAvailable(QmitkStdMultiWidget &stdMultiWidget);
+ virtual void StdMultiWidgetNotAvailable();
+
+ protected slots:
+
+ void OnLoadMeasurementStorage();
+ void OnLoadReferenceStorage();
+ void OnStartTracking();
+ void OnStopTracking();
+ void OnMeasurementLoadFile();
+ void OnSetReference();
+ void StartNextMeasurement();
+ void RepeatLastMeasurement();
+ void UpdateTimer();
+ void CreateResults();
+ void OnUseReferenceToggled(bool state);
+
+protected:
+
+ Ui::QmitkIGTTrackingSemiAutomaticMeasurementViewControls* m_Controls;
+
+ QmitkStdMultiWidget* m_MultiWidget;
+
+ //the tool storages
+ mitk::NavigationToolStorage::Pointer m_MeasurementStorage;
+ mitk::NavigationToolStorage::Pointer m_ReferenceStorage;
+
+ //members for the filter pipeline
+ mitk::TrackingDeviceSource::Pointer m_MeasurementTrackingDeviceSource;
+ mitk::NavigationDataObjectVisualizationFilter::Pointer m_MeasurementToolVisualizationFilter;
+ mitk::NavigationDataRecorderDeprecated::Pointer m_MeasurementLoggingFilterXML;
+ mitk::NavigationDataRecorderDeprecated::Pointer m_MeasurementLoggingFilterCSV;
+ mitk::TrackingDeviceSource::Pointer m_ReferenceTrackingDeviceSource;
+ mitk::NavigationDataRecorderDeprecated::Pointer m_ReferenceLoggingFilterXML;
+ mitk::NavigationDataRecorderDeprecated::Pointer m_ReferenceLoggingFilterCSV;
+
+ //members for file name list
+ std::vector m_FilenameVector;
+ int m_NextFile;
+
+ //help methods
+ mitk::NavigationToolStorage::Pointer ReadStorage(std::string file);
+ void MessageBox(std::string s);
+ void DisableAllButtons();
+ void EnableAllButtons();
+ void FinishMeasurement();
+ void StartLoggingAdditionalCSVFile(std::string filePostfix);
+ void LogAdditionalCSVFile();
+ void StopLoggingAdditionalCSVFile();
+
+ //timer
+ QTimer* m_Timer;
+
+ //memebers for reference checking
+ std::vector m_ReferenceStartPositions;
+ bool m_referenceValid;
+
+ //logging members
+ int m_loggedFrames;
+ bool m_logging;
+ std::fstream m_logFileCSV;
+
+ //event filter for key presses
+ bool eventFilter(QObject *obj, QEvent *ev);
+
+ //results members
+ mitk::PointSet::Pointer m_MeanPoints;
+ std::vector m_RMSValues;
+ mitk::NavigationDataEvaluationFilter::Pointer m_EvaluationFilter;
+
+ bool m_tracking;
+};
+
+#endif // _QMITKIGTTRACKINGSEMIAUTOMATICMEASUREMENTVIEW_H_INCLUDED
diff --git a/Plugins/org.mitk.gui.qt.igt.app.hummelprotocolmeasurements/src/internal/QmitkIGTTrackingSemiAutomaticMeasurementViewControls.ui b/Plugins/org.mitk.gui.qt.igt.app.hummelprotocolmeasurements/src/internal/QmitkIGTTrackingSemiAutomaticMeasurementViewControls.ui
new file mode 100644
index 0000000000..50168cb767
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.igt.app.hummelprotocolmeasurements/src/internal/QmitkIGTTrackingSemiAutomaticMeasurementViewControls.ui
@@ -0,0 +1,555 @@
+
+
+ QmitkIGTTrackingSemiAutomaticMeasurementViewControls
+
+
+
+ 0
+ 0
+ 419
+ 931
+
+
+
+
+ 0
+ 0
+
+
+
+ QmitkTemplate
+
+
+ -
+
+
+ 0
+
+
+
+ Tracking Initialization
+
+
+
-
+
+
+ Measurement Tracking System
+
+
+
-
+
+
+ -
+
+
-
+
+
+ Tool Storage: <none>
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Load Tool Storage
+
+
+
+
+
+
+
+
+ -
+
+
+ Reference Trackingsystem
+
+
+
-
+
+
+ -
+
+
-
+
+
+ Tool Storage: <none>
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Load Tool Storage
+
+
+
+
+
+
+
+
+ -
+
+
+ Start Tracking
+
+
+
+ -
+
+
+ Stop Tracking
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+ Measurement
+
+
+ -
+
+
+ Measurement List:
+
+
+
+ -
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Load List
+
+
+
+
+
+ -
+
+
-
+
+
+ Output Path:
+
+
+
+ -
+
+
+ C:/temp/
+
+
+
+
+
+ -
+
+
+ Last Measurement: <none>
+
+
+
+ -
+
+
+ Next Measurement: <none>
+
+
+
+ -
+
+
+ Collected Samples: <none>
+
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 200
+ 0
+
+
+
+ Start Next Measurement
+
+
+
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 200
+ 0
+
+
+
+ Repeat Last Measurement
+
+
+
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 200
+ 0
+
+
+
+ Create Results
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 281
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+<html><head><meta name="qrichtext" content="1" /><style type="text/css">
+p, li { white-space: pre-wrap; }
+</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600; text-decoration: underline;">Measurement Sensors:</span></p></body></html>
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ -
+
+
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+<html><head><meta name="qrichtext" content="1" /><style type="text/css">
+p, li { white-space: pre-wrap; }
+</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt; font-weight:600; text-decoration: underline;">Reference Sensors:</span></p></body></html>
+
+
+
+ -
+
+
+ Set Reference
+
+
+
+ -
+
+
+ Reference Postion: <none>
+
+
+
+ -
+
+
+ Current Positions: <none>
+
+
+
+ -
+
+
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+<html><head><meta name="qrichtext" content="1" /><style type="text/css">
+p, li { white-space: pre-wrap; }
+</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:28pt; font-weight:600;">OK</span></p></body></html>
+
+
+ Qt::AlignCenter
+
+
+
+
+
+
+
+ Settings
+
+
+ -
+
+
-
+
+
+ Sampling Rate (Times Per Second):
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ 999.000000000000000
+
+
+ 15.000000000000000
+
+
+
+
+
+ -
+
+
-
+
+
+ Samples Per Measurement:
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ 1000
+
+
+ 150
+
+
+
+
+
+ -
+
+
-
+
+
+ Threshold For Reference Tools:
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ 1.000000000000000
+
+
+
+
+
+ -
+
+
+ Use Reference Tracking System
+
+
+ true
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+
+
+
+
+
+ QmitkToolTrackingStatusWidget
+ QWidget
+ QmitkToolTrackingStatusWidget.h
+ 1
+
+
+ QmitkTrackingDeviceConfigurationWidget
+ QWidget
+ QmitkTrackingDeviceConfigurationWidget.h
+ 1
+
+
+
+
+
diff --git a/Plugins/org.mitk.gui.qt.igt.app.hummelprotocolmeasurements/src/internal/mitkNavigationDataCSVSequentialPlayer.cpp b/Plugins/org.mitk.gui.qt.igt.app.hummelprotocolmeasurements/src/internal/mitkNavigationDataCSVSequentialPlayer.cpp
new file mode 100644
index 0000000000..66f36f2fda
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.igt.app.hummelprotocolmeasurements/src/internal/mitkNavigationDataCSVSequentialPlayer.cpp
@@ -0,0 +1,214 @@
+/*=========================================================================
+
+Program: Medical Imaging & Interaction Toolkit
+Language: C++
+Date: $Date: 2009-02-10 18:08:54 +0100 (Di, 10 Feb 2009) $
+Version: $Revision: 16228 $
+
+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 "mitkNavigationDataCSVSequentialPlayer.h"
+#include
+#include
+#include
+#include
+
+
+mitk::NavigationDataCSVSequentialPlayer::NavigationDataCSVSequentialPlayer()
+ : mitk::NavigationDataPlayerBase()
+{
+m_NavigationDatas = std::vector();
+m_CurrentPos = 0;
+m_Filetype = mitk::NavigationDataCSVSequentialPlayer::NavigationDataCSV;
+}
+
+
+mitk::NavigationDataCSVSequentialPlayer::~NavigationDataCSVSequentialPlayer()
+{
+
+}
+
+bool mitk::NavigationDataCSVSequentialPlayer::IsAtEnd()
+{
+ if (m_CurrentPos >= m_NavigationDatas.size()) return true;
+ else return false;
+}
+
+void mitk::NavigationDataCSVSequentialPlayer::
+ SetFileName(const std::string& fileName)
+{
+ this->SetNumberOfOutputs(1);
+ FillOutputEmpty(0);
+
+ MITK_INFO << "Reading file: " << fileName;
+ m_NavigationDatas = GetNavigationDatasFromFile(fileName);
+
+ this->Modified();
+}
+
+void mitk::NavigationDataCSVSequentialPlayer::FillOutputEmpty(int number)
+ {
+ this->SetNthOutput(number,GetEmptyNavigationData());
+ }
+
+mitk::NavigationData::Pointer mitk::NavigationDataCSVSequentialPlayer::GetEmptyNavigationData()
+ {
+ mitk::NavigationData::Pointer emptyNd = mitk::NavigationData::New();
+ mitk::NavigationData::PositionType position;
+ mitk::NavigationData::OrientationType orientation(0.0,0.0,0.0,0.0);
+ position.Fill(0.0);
+
+ emptyNd->SetPosition(position);
+ emptyNd->SetOrientation(orientation);
+ emptyNd->SetDataValid(false);
+ return emptyNd;
+ }
+
+void mitk::NavigationDataCSVSequentialPlayer::GenerateData()
+{
+
+ for (unsigned int index = 0; index < this->GetNumberOfOutputs(); index++)
+ {
+
+ mitk::NavigationData* output = this->GetOutput(index);
+
+ if (m_CurrentPos > m_NavigationDatas.size())
+ {
+ FillOutputEmpty(index);
+ return;
+ }
+
+ output->Graft(this->m_NavigationDatas.at(m_CurrentPos));
+ m_CurrentPos++;
+
+ }
+}
+
+void mitk::NavigationDataCSVSequentialPlayer::UpdateOutputInformation()
+{
+ this->Modified(); // make sure that we need to be updated
+ Superclass::UpdateOutputInformation();
+}
+
+std::vector mitk::NavigationDataCSVSequentialPlayer::GetNavigationDatasFromFile(std::string filename)
+{
+std::vector returnValue = std::vector();
+std::vector fileContentLineByLine = GetFileContentLineByLine(filename);
+for(int i=1; (i mitk::NavigationDataCSVSequentialPlayer::GetFileContentLineByLine(std::string filename)
+{
+std::vector readData = std::vector();
+
+//save old locale
+char * oldLocale;
+oldLocale = setlocale( LC_ALL, 0 );
+
+//define own locale
+std::locale C("C");
+setlocale( LC_ALL, "C" );
+
+//read file
+std::ifstream file;
+file.open(filename.c_str(), std::ios::in);
+if (file.good())
+ {
+ //read out file
+ file.seekg(0L, std::ios::beg); // move to begin of file
+ while (! file.eof())
+ {
+ std::string buffer;
+ std::getline(file,buffer); // read out file line by line
+ if (buffer.size() > 0) readData.push_back(buffer);
+
+ }
+ }
+
+file.close();
+
+//switch back to old locale
+setlocale( LC_ALL, oldLocale );
+
+return readData;
+}
+
+mitk::NavigationData::Pointer mitk::NavigationDataCSVSequentialPlayer::GetNavigationDataOutOfOneLine(std::string line)
+{
+ mitk::NavigationData::Pointer returnValue = mitk::NavigationData::New();
+
+ QString myLine = QString(line.c_str());
+
+ QStringList myLineList = myLine.split(';');
+
+ mitk::Point3D position;
+ mitk::Quaternion orientation;
+ bool valid = false;
+ double time;
+
+ if (m_Filetype = mitk::NavigationDataCSVSequentialPlayer::NavigationDataCSV)
+ {
+
+ if (myLineList.size() < 10)
+ {
+ MITK_ERROR << "Error: cannot read line: only found " << myLineList.size() << " fields. Last field: " << myLineList.at(myLineList.size()-1).toStdString() ;
+ returnValue = GetEmptyNavigationData();
+ return returnValue;
+ }
+
+ time = myLineList.at(1).toDouble();
+
+ if (myLineList.at(2).toStdString() == "1") valid = true;
+
+ position[0] = myLineList.at(3).toDouble();
+ position[1] = myLineList.at(4).toDouble();
+ position[2] = myLineList.at(5).toDouble();
+
+ orientation[0] = myLineList.at(6).toDouble();
+ orientation[1] = myLineList.at(7).toDouble();
+ orientation[2] = myLineList.at(8).toDouble();
+ orientation[3] = myLineList.at(9).toDouble();
+ }
+ else
+ {
+ if (myLineList.size() < 10)
+ {
+ MITK_ERROR << "Error: cannot read line: only found " << myLineList.size() << " fields. Last field: " << myLineList.at(myLineList.size()-1).toStdString() ;
+ returnValue = GetEmptyNavigationData();
+ return returnValue;
+ }
+
+ time = myLineList.at(1).toDouble();
+
+ //if (myLineList.at(2).toStdString() == "true")
+ //valid-flag wurde hier nicht gespeichert
+ valid = true;
+
+ position[0] = myLineList.at(3).toDouble();
+ position[1] = myLineList.at(4).toDouble();
+ position[2] = myLineList.at(5).toDouble();
+
+ orientation[0] = myLineList.at(6).toDouble();
+ orientation[1] = myLineList.at(7).toDouble();
+ orientation[2] = myLineList.at(8).toDouble();
+ orientation[3] = myLineList.at(9).toDouble();
+ }
+
+ //returnValue->SetTimeStamp(time); //DOES NOT WORK ANY MORE... CANNOT SET TIME TO itk::timestamp CLASS
+ returnValue->SetDataValid(valid);
+ returnValue->SetPosition(position);
+ returnValue->SetOrientation(orientation);
+
+ return returnValue;
+}
diff --git a/Plugins/org.mitk.gui.qt.igt.app.hummelprotocolmeasurements/src/internal/mitkNavigationDataCSVSequentialPlayer.h b/Plugins/org.mitk.gui.qt.igt.app.hummelprotocolmeasurements/src/internal/mitkNavigationDataCSVSequentialPlayer.h
new file mode 100644
index 0000000000..50bb773d18
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.igt.app.hummelprotocolmeasurements/src/internal/mitkNavigationDataCSVSequentialPlayer.h
@@ -0,0 +1,98 @@
+/*=========================================================================
+
+Program: Medical Imaging & Interaction Toolkit
+Language: C++
+Date: $Date: 2009-02-10 18:08:54 +0100 (Di, 10 Feb 2009) $
+Version: $Revision: 16228 $
+
+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 MITKNavigationDataCSVSequentialPlayer_H_HEADER_INCLUDED_
+#define MITKNavigationDataCSVSequentialPlayer_H_HEADER_INCLUDED_
+
+#include
+#include "tinyxml.h"
+
+
+namespace mitk
+{
+
+ /**Documentation
+ * \brief This class is a NavigationDataPlayer which can play CSV formatted
+ * files in sequential order, which means it doesn't
+ * care about timestamps and just
+ * outputs the navigationdatas in their sequential order
+ *
+ * \ingroup IGT
+ */
+ class NavigationDataCSVSequentialPlayer
+ : public NavigationDataPlayerBase
+ {
+ public:
+
+ enum Filetype
+ {
+ NavigationDataCSV,
+ ManualLoggingCSV
+ };
+
+ mitkClassMacro(NavigationDataCSVSequentialPlayer, NavigationDataPlayerBase);
+ itkNewMacro(Self);
+
+ /**
+ * \brief sets the file name and path (if XMLString is set, this is neglected)
+ */
+ void SetFileName(const std::string& _FileName);
+
+ /**
+ * \brief returns the file name and path
+ */
+ itkGetStringMacro(FileName);
+
+ itkSetMacro(Filetype,Filetype);
+
+ bool IsAtEnd();
+
+ /**
+ * \brief Used for pipeline update just to tell the pipeline
+ * that we always have to update
+ */
+ virtual void UpdateOutputInformation();
+
+ protected:
+ NavigationDataCSVSequentialPlayer();
+ virtual ~NavigationDataCSVSequentialPlayer();
+
+ ///
+ /// do the work here
+ ///
+ virtual void GenerateData();
+
+ std::string m_FileName;
+
+ int m_CurrentPos;
+ Filetype m_Filetype;
+
+ //member for the navigation datas which were read (only one output is supported at the moment)
+ std::vector m_NavigationDatas;
+
+ std::vector GetNavigationDatasFromFile(std::string filename);
+ std::vector GetFileContentLineByLine(std::string filename);
+ mitk::NavigationData::Pointer GetNavigationDataOutOfOneLine(std::string line);
+
+ void FillOutputEmpty(int number);
+ mitk::NavigationData::Pointer GetEmptyNavigationData();
+
+ };
+} // namespace mitk
+
+#endif /* MITKNavigationDataCSVSequentialPlayer_H_HEADER_INCLUDED_ */
\ No newline at end of file
diff --git a/Plugins/org.mitk.gui.qt.igt.app.hummelprotocolmeasurements/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.gui.qt.igt.app.hummelprotocolmeasurements/src/internal/mitkPluginActivator.cpp
new file mode 100644
index 0000000000..b1ca328364
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.igt.app.hummelprotocolmeasurements/src/internal/mitkPluginActivator.cpp
@@ -0,0 +1,38 @@
+/*=========================================================================
+
+Program: Medical Imaging & Interaction Toolkit
+Language: C++
+Date: $Date$
+Version: $Revision$
+
+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 "mitkPluginActivator.h"
+
+#include
+
+#include "QmitkIGTTrackingSemiAutomaticMeasurementView.h"
+
+namespace mitk {
+ void PluginActivator::start(ctkPluginContext* context)
+ {
+ BERRY_REGISTER_EXTENSION_CLASS(QmitkIGTTrackingSemiAutomaticMeasurementView, context)
+ }
+
+ void PluginActivator::stop(ctkPluginContext* context)
+ {
+ Q_UNUSED(context)
+ }
+}
+
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+Q_EXPORT_PLUGIN2(org_mitk_gui_qt_igttrackingsemiautomaticmeasurement, mitk::PluginActivator)
+#endif
\ No newline at end of file
diff --git a/Plugins/org.mitk.gui.qt.igt.app.hummelprotocolmeasurements/src/internal/mitkPluginActivator.h b/Plugins/org.mitk.gui.qt.igt.app.hummelprotocolmeasurements/src/internal/mitkPluginActivator.h
new file mode 100644
index 0000000000..ecf559f1d4
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.igt.app.hummelprotocolmeasurements/src/internal/mitkPluginActivator.h
@@ -0,0 +1,44 @@
+/*=========================================================================
+
+Program: Medical Imaging & Interaction Toolkit
+Language: C++
+Date: $Date$
+Version: $Revision$
+
+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 MITKPLUGINACTIVATOR_H
+#define MITKPLUGINACTIVATOR_H
+
+#include
+
+namespace mitk {
+
+class PluginActivator :
+ public QObject, public ctkPluginActivator
+{
+ Q_OBJECT
+ #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_igtapphummelprotocolmeasurements")
+ #endif
+ Q_INTERFACES(ctkPluginActivator)
+
+public:
+
+ void start(ctkPluginContext* context);
+ void stop(ctkPluginContext* context);
+
+}; // PluginActivator
+
+}
+
+#endif // MITKPLUGINACTIVATOR_H