double ManualImage2ImageRegistrationWidget::getAccuracy(QString uid)
{
    DataPtr fixedData = mServices->registration()->getFixedData();
    if (!fixedData)
        return 1000.0;
    DataPtr movingData = mServices->registration()->getMovingData();
    if (!movingData)
        return 1000.0;

    Landmark masterLandmark = fixedData->getLandmarks()->getLandmarks()[uid];
    Landmark targetLandmark = movingData->getLandmarks()->getLandmarks()[uid];
    if (masterLandmark.getUid().isEmpty() || targetLandmark.getUid().isEmpty())
        return 1000.0;

    Vector3D p_master_master = masterLandmark.getCoord();
    Vector3D p_target_target = targetLandmark.getCoord();
    Transform3D rMmaster = fixedData->get_rMd();
    Transform3D rMtarget = movingData->get_rMd();

    Vector3D p_target_r = rMtarget.coord(p_target_target);
    Vector3D p_master_r = rMmaster.coord(p_master_master);

    double  targetPoint[3];
    double  masterPoint[3];
    targetPoint[0] = p_target_r[0];
    targetPoint[1] = p_target_r[1];
    targetPoint[2] = p_target_r[2];
    masterPoint[0] = p_master_r[0];
    masterPoint[1] = p_master_r[1];
    masterPoint[2] = p_master_r[2];

    return (vtkMath::Distance2BetweenPoints(targetPoint, masterPoint));
}
void RegistrationImplService::doPatientRegistration()
{
	DataPtr fixedImage = this->getFixedData();

	if(!fixedImage)
	{
	reportError("The fixed data is not set, cannot do patient registration!");
		return;
	}
	LandmarkMap fixedLandmarks = fixedImage->getLandmarks()->getLandmarks();
	LandmarkMap toolLandmarks = mPatientModelService->getPatientLandmarks()->getLandmarks();

	this->writePreLandmarkRegistration(fixedImage->getName(), fixedImage->getLandmarks()->getLandmarks());
	this->writePreLandmarkRegistration("physical", toolLandmarks);

	std::vector<QString> landmarks = this->getUsableLandmarks(fixedLandmarks, toolLandmarks);

	vtkPointsPtr p_ref = this->convertTovtkPoints(landmarks, fixedLandmarks, fixedImage->get_rMd());
	vtkPointsPtr p_pr = this->convertTovtkPoints(landmarks, toolLandmarks, Transform3D::Identity());

	// ignore if too few data.
	if (p_ref->GetNumberOfPoints() < 3)
		return;

	bool ok = false;
	Transform3D rMpr = this->performLandmarkRegistration(p_pr, p_ref, &ok);
	if (!ok)
	{
		reportError("P-I Landmark registration: Failed to register: [" + qstring_cast(p_pr->GetNumberOfPoints()) + "p]");
		return;
	}

	this->applyPatientRegistration(rMpr, "Patient Landmark");
}
void ImageLandmarksWidget::setTargetLandmark(QString uid, Vector3D p_target)
{
	DataPtr image = this->getCurrentData();
	if (!image)
		return;
	image->getLandmarks()->setLandmark(Landmark(uid, p_target));
}
void ImageLandmarksWidget::importPointMetricsToLandmarkButtonClickedSlot()
{
	DataPtr image = this->getCurrentData();
	if(!image)
		return;

	std::map<QString, DataPtr> point_metrics = mServices->patient()->getChildren(image->getUid(), "pointMetric");
	std::map<QString, DataPtr>::iterator it = point_metrics.begin();

	//Make sure we have enough landmarks
	int number_of_landmarks = mServices->patient()->getLandmarkProperties().size();
	int number_of_metrics = point_metrics.size();
	for(int i=number_of_landmarks; i<number_of_metrics; ++i)
	{
		QString uid = mServices->patient()->addLandmark();
	}

	for(; it != point_metrics.end(); ++it)
	{
		PointMetricPtr point_metric = boost::static_pointer_cast<PointMetric>(it->second);
		if(!point_metric)
			continue;

		Vector3D pos_x = point_metric->getCoordinate();
		//Transform3D d_M_x = mServices->spaceProvider()->get_toMfrom(CoordinateSystem::fromString(image->getSpace()), point_metric->getSpace());
		//Vector3D pos_d = d_M_x.coord(pos_x);
		QString point_metric_name = point_metric->getName();
		image->getLandmarks()->setLandmark(Landmark(point_metric_name, pos_x));
		this->activateLandmark(point_metric_name);
	}
}
LandmarkMap ImageLandmarksWidget::getTargetLandmarks() const
{
	DataPtr image = this->getCurrentData();
	if (!image)
		return LandmarkMap();

	return image->getLandmarks()->getLandmarks();
}
void ImageLandmarksWidget::deleteLandmarksButtonClickedSlot()
{
	DataPtr image = this->getCurrentData();
	if (!image)
		return;

	image->getLandmarks()->clear();
	this->setModified();
	mServices->patient()->deleteLandmarks();
}
void ImageLandmarksWidget::removeLandmarkButtonClickedSlot()
{
	DataPtr image = this->getCurrentData();
	if (!image)
		return;

    QString next = this->getNextLandmark();
	image->getLandmarks()->removeLandmark(mActiveLandmark);
	this->activateLandmark(next);
}
void RegistrationImplService::doFastRegistration_Translation()
{
	DataPtr fixedImage = this->getFixedData();
	if(!fixedImage)
	{
	reportError("The fixed data is not set, cannot do image registration!");
		return;
	}

	LandmarkMap fixedLandmarks = fixedImage->getLandmarks()->getLandmarks();
	LandmarkMap toolLandmarks = mPatientModelService->getPatientLandmarks()->getLandmarks();

	this->writePreLandmarkRegistration(fixedImage->getName(), fixedImage->getLandmarks()->getLandmarks());
	this->writePreLandmarkRegistration("physical", toolLandmarks);

	std::vector<QString> landmarks = this->getUsableLandmarks(fixedLandmarks, toolLandmarks);

	Transform3D rMd = fixedImage->get_rMd();
	Transform3D rMpr_old = mPatientModelService->get_rMpr();
	std::vector<Vector3D> p_pr_old = this->convertAndTransformToPoints(landmarks, fixedLandmarks, rMpr_old.inv()*rMd);
	std::vector<Vector3D> p_pr_new = this->convertAndTransformToPoints(landmarks, toolLandmarks, Transform3D::Identity());

	// ignore if too few data.
	if (p_pr_old.size() < 1)
		return;

	LandmarkTranslationRegistration landmarkTransReg;
	bool ok = false;
	Transform3D pr_oldMpr_new = landmarkTransReg.registerPoints(p_pr_old, p_pr_new, &ok);
	if (!ok)
	{
		reportError("Fast translation registration: Failed to register: [" + qstring_cast(p_pr_old.size()) + "points]");
		return;
	}

	this->applyPatientRegistration(rMpr_old*pr_oldMpr_new, "Fast Translation");
}
void ImageLandmarksWidget::editLandmarkButtonClickedSlot()
{
	PickerRepPtr PickerRep = this->getPickerRep();
	if (!PickerRep)
	{
		reportError("Need a 3D view to edit landmarks.");
		return;
	}

	DataPtr image = this->getCurrentData();
	if (!image)
		return;

	QString uid = mActiveLandmark;
	Vector3D pos_r = PickerRep->getPosition();
	Vector3D pos_d = image->get_rMd().inv().coord(pos_r);
	image->getLandmarks()->setLandmark(Landmark(uid, pos_d));

    this->activateLandmark(this->getNextLandmark());
}
double LandmarkRegistrationWidget::getAccuracy(QString uid)
{
	DataPtr fixedData = mServices->registration()->getFixedData();
	if (!fixedData)
		return 1000.0;

	Landmark masterLandmark = fixedData->getLandmarks()->getLandmarks()[uid];
	Landmark targetLandmark = this->getTargetLandmarks()[uid];
	if (masterLandmark.getUid().isEmpty() || targetLandmark.getUid().isEmpty())
		return 1000.0;

	Vector3D p_master_master = masterLandmark.getCoord();
	Vector3D p_target_target = targetLandmark.getCoord();
	Transform3D rMmaster = fixedData->get_rMd();
	Transform3D rMtarget = this->getTargetTransform();

	Vector3D p_target_r = rMtarget.coord(p_target_target);
	Vector3D p_master_r = rMmaster.coord(p_master_master);

	return (p_target_r - p_master_r).length();
}
void RegistrationImplService::doImageRegistration(bool translationOnly)
{
	//check that the fixed data is set
	DataPtr fixedImage = this->getFixedData();
	if(!fixedImage)
	{
	reportError("The fixed data is not set, cannot do landmark image registration!");
		return;
	}

	//check that the moving data is set
	DataPtr movingImage = this->getMovingData();
	if(!movingImage)
	{
	reportError("The moving data is not set, cannot do landmark image registration!");
		return;
	}

	// ignore self-registration, this gives no effect bestcase, buggy behaviour worstcase (has been observed)
	if(movingImage==fixedImage)
	{
		reportError("The moving and fixed are equal, ignoring landmark image registration!");
		return;
	}

	LandmarkMap fixedLandmarks = fixedImage->getLandmarks()->getLandmarks();
	LandmarkMap imageLandmarks = movingImage->getLandmarks()->getLandmarks();

	this->writePreLandmarkRegistration(fixedImage->getName(), fixedImage->getLandmarks()->getLandmarks());
	this->writePreLandmarkRegistration(movingImage->getName(), movingImage->getLandmarks()->getLandmarks());

	std::vector<QString> landmarks = getUsableLandmarks(fixedLandmarks, imageLandmarks);
	vtkPointsPtr p_fixed_r = convertTovtkPoints(landmarks, fixedLandmarks, fixedImage->get_rMd());
	vtkPointsPtr p_moving_r = convertTovtkPoints(landmarks, imageLandmarks, movingImage->get_rMd());

	int minNumberOfPoints = 3;
	if (translationOnly)
		minNumberOfPoints = 1;

	// ignore if too few data.
	if (p_fixed_r->GetNumberOfPoints() < minNumberOfPoints)
	{
		reportError(
			QString("Found %1 corresponding landmarks, need %2, cannot do landmark image registration!")
			.arg(p_fixed_r->GetNumberOfPoints())
			.arg(minNumberOfPoints)
			);
		return;
	}

	bool ok = false;
	QString idString;
	Transform3D delta;

	if (translationOnly)
	{
		LandmarkTranslationRegistration landmarkTransReg;
		delta = landmarkTransReg.registerPoints(convertVtkPointsToPoints(p_fixed_r), convertVtkPointsToPoints(p_moving_r), &ok);
		idString = QString("Image to Image Landmark Translation");
	}
	else
	{
		Transform3D rMd;
		delta = this->performLandmarkRegistration(p_moving_r, p_fixed_r, &ok);
		idString = QString("Image to Image Landmark");
	}

	if (!ok)
	{
		reportError("I-I Landmark registration: Failed to register: [" + qstring_cast(p_moving_r->GetNumberOfPoints()) + "p], "+ movingImage->getName());
		return;
	}

	this->applyImage2ImageRegistration(delta, idString);
}