void QmitkUSNavigationStepTumourSelection::OnSettingsChanged(const itk::SmartPointer<mitk::DataNode> settingsNode)
{
  if (settingsNode.IsNull()) { return; }

  float securityDistance;
  if (settingsNode->GetFloatProperty("settings.security-distance", securityDistance))
  {
    m_SecurityDistance = securityDistance;
  }

  std::string stateMachineFilename;
  if (settingsNode->GetStringProperty("settings.interaction-concept", stateMachineFilename) && stateMachineFilename != m_StateMachineFilename)
  {
    m_StateMachineFilename = stateMachineFilename;
    m_Interactor->LoadStateMachine(stateMachineFilename, us::ModuleRegistry::GetModule("MitkUS"));
  }

  std::string referenceSensorName;
  if (settingsNode->GetStringProperty("settings.reference-name-selected", referenceSensorName))
  {
    m_ReferenceSensorName = referenceSensorName;
  }

  this->UpdateReferenceSensorName();
}
void QmitkUSNavigationStepMarkerIntervention::OnSettingsChanged(const itk::SmartPointer<mitk::DataNode> settingsNode)
{
  if (settingsNode.IsNull())
  {
    return;
  }

  int numberOfTargets;
  if (settingsNode->GetIntProperty("settings.number-of-targets", numberOfTargets))
  {
    m_NumberOfTargets = numberOfTargets;
    m_TargetUpdateFilter->SetNumberOfTargets(numberOfTargets);

    m_PlacementQualityCalculator->SetOptimalAngle(m_TargetUpdateFilter->GetOptimalAngle());
  }

  std::string referenceSensorName;
  if (settingsNode->GetStringProperty("settings.reference-name-selected", referenceSensorName))
  {
    m_ReferenceSensorName = referenceSensorName;
  }

  std::string needleSensorName;
  if (settingsNode->GetStringProperty("settings.needle-name-selected", needleSensorName))
  {
    m_NeedleSensorName = needleSensorName;
  }

  this->UpdateSensorsNames();
}
void QmitkUSNavigationZoneDistancesWidget::AddZone(itk::SmartPointer<mitk::DataNode> zoneNode)
{
  m_ZoneNodes.append(zoneNode);
  QmitkZoneProgressBar* progressBar =
    new QmitkZoneProgressBar(QString::fromStdString(zoneNode->GetName())+QString(": %1 mm"), 60, 25, this);

  float color[3] = {1, 0, 0};
  progressBar->SetWarnColor(color);

  zoneNode->GetColor(color);
  progressBar->SetColor(color);

  m_ZoneProgressBars.append(progressBar);
  this->layout()->addWidget(progressBar);
}
void mitk::USNavigationTargetIntersectionFilter::SetLine(itk::SmartPointer<mitk::PointSet> line)
{
  if ( line.IsNull() || line->GetSize() != 2 )
  {
    mitkThrow() << "Line must consist of exact two points.";
  }

  // copy points from the PointSet to arrays
  m_LinePoint1[0] = line->GetPoint(0)[0];
  m_LinePoint1[1] = line->GetPoint(0)[1];
  m_LinePoint1[2] = line->GetPoint(0)[2];
  m_LinePoint2[0] = line->GetPoint(1)[0];
  m_LinePoint2[1] = line->GetPoint(1)[1];
  m_LinePoint2[2] = line->GetPoint(1)[2];
}
void QmitkUSNavigationStepZoneMarking::OnSettingsChanged(const itk::SmartPointer<mitk::DataNode> settingsNode)
{
  if ( settingsNode.IsNull() ) { return; }

  std::string stateMachineFilename;
  if ( settingsNode->GetStringProperty("settings.interaction-concept", stateMachineFilename) && stateMachineFilename != m_StateMachineFilename )
  {
    m_StateMachineFilename = stateMachineFilename;
    ui->zonesWidget->SetStateMachineFilename(stateMachineFilename);
  }

  std::string referenceSensorName;
  if ( settingsNode->GetStringProperty("settings.reference-name-selected", referenceSensorName) )
  {
    m_ReferenceSensorName = referenceSensorName;
  }

  this->UpdateReferenceSensorName();
}
void QmitkUSNavigationProcessWidget::SetDataStorage(itk::SmartPointer<mitk::DataStorage> dataStorage)
{
  m_DataStorage = dataStorage;

  if ( dataStorage.IsNull() )
  {
    mitkThrow() << "Data Storage must not be null for QmitkUSNavigationProcessWidget.";
  }

  // test if base node is already in the data storage and add it if not
  m_BaseNode = dataStorage->GetNamedNode(QmitkUSAbstractNavigationStep::DATANAME_BASENODE);
  if ( m_BaseNode.IsNull() )
  {
    m_BaseNode = mitk::DataNode::New();
    m_BaseNode->SetName(QmitkUSAbstractNavigationStep::DATANAME_BASENODE);
    dataStorage->Add(m_BaseNode);
  }

  // base node and image stream node may be the same node
  if ( strcmp(QmitkUSAbstractNavigationStep::DATANAME_BASENODE, QmitkUSAbstractNavigationStep::DATANAME_IMAGESTREAM) != 0)
  {
    m_ImageStreamNode = dataStorage->GetNamedNode(QmitkUSAbstractNavigationStep::DATANAME_IMAGESTREAM);
    if (m_ImageStreamNode.IsNull())
    {
      // Create Node for US Stream
      m_ImageStreamNode = mitk::DataNode::New();
      m_ImageStreamNode->SetName(QmitkUSAbstractNavigationStep::DATANAME_IMAGESTREAM);
      dataStorage->Add(m_ImageStreamNode);
    }
  }
  else
  {
    m_ImageStreamNode = m_BaseNode;
  }


  m_SettingsNode =
    dataStorage->GetNamedDerivedNode(QmitkUSAbstractNavigationStep::DATANAME_SETTINGS, m_BaseNode);

  if ( m_SettingsNode.IsNull() )
  {
    m_SettingsNode = mitk::DataNode::New();
    m_SettingsNode->SetName(QmitkUSAbstractNavigationStep::DATANAME_SETTINGS);
    dataStorage->Add(m_SettingsNode, m_BaseNode);
  }

  if (m_SettingsWidget) { m_SettingsWidget->SetSettingsNode(m_SettingsNode); }

}
void QmitkUSNavigationStepPunctuationIntervention::OnSettingsChanged(const itk::SmartPointer<mitk::DataNode> settingsNode)
{
  if ( settingsNode.IsNull() ) { return; }
}
/* use this function to compute one associative measurement */
float NuclearAssociationRules::ComputeOneAssocMeasurement(itk::SmartPointer<TargImageType> trgIm, int ruleID, int objID)
{	
	//fisrt, get the bounding box around the object
	//The bounding box is defined by the area around the object such that the object+outerdistance are included	
	int imBounds[6] = {0,x_Size,0,y_Size,0,z_Size};
	LabelGeometryType::BoundingBoxType bbox = labGeometryFilter->GetBoundingBox(objID);
	//make sure the object exists
	int valid = 0;
	for(int dim=0; dim < imDim*2; ++dim)
	{
		if(bbox[dim] > 0)
			valid = 1;
	}
	if(valid == 0)
		return -1;

	std::vector< int > retBbox(0);
	int dist, val;
	dist = assocRulesList[ruleID].GetOutDistance();
	for(int dim=0; dim < imDim*2; ++dim)
	{  
		if(dim%2 == 0) //even
		{			
			val = int(bbox[dim])-dist-1;
			if(val<imBounds[dim])
				val=imBounds[dim];
		}
		else //odd
		{
			val = int(bbox[dim])+dist+1;
			if(val>=imBounds[dim])
				val=imBounds[dim]-1;
		}
		retBbox.push_back( val );
	}

	//the bounding box defines the region of interest we need (from both segmentation and target images)
	//so, use it to get sub images
	DistImageType::Pointer subSegImg = DistImageType::New();
	
	LabImageType::IndexType start;
    start[0] =   0;  // first index on X
    start[1] =   0;  // first index on Y    
	start[2] =   0;  // first index on Z    
	
    LabImageType::SizeType  size;
    size[0]  = retBbox[1]-retBbox[0]+1;  // size along X
    size[1]  = retBbox[3]-retBbox[2]+1;  // size along Y
	if(imDim == 3)
		size[2]  = retBbox[5]-retBbox[4]+1;  // size along Z
	else
		size[2] = 1;
  
    LabImageType::RegionType region;
    region.SetSize( size );
    region.SetIndex( start );
	subSegImg->SetRegions( region );	
    subSegImg->Allocate();
    subSegImg->FillBuffer(0);
	subSegImg->Update();	
	

	LabImageType::IndexType start2;
    start2[0] =   retBbox[0];  // first index on X
    start2[1] =   retBbox[2];  // first index on Y    
	if(imDim == 3)
		start2[2] =   retBbox[4];  // first index on Z   
	else
		start2[2] = 0;
	LabImageType::RegionType region2;
    region2.SetSize( size );
    region2.SetIndex( start2 );
	labImage->SetRequestedRegion(region2);
	trgIm->SetRequestedRegion(region2);

	typedef itk::ImageRegionIteratorWithIndex< LabImageType > IteratorType;	
	IteratorType iterator1(labImage, labImage->GetRequestedRegion());
	typedef itk::ImageRegionIteratorWithIndex< DistImageType > IteratorType2;	
	IteratorType2 iterator2(subSegImg, subSegImg->GetRequestedRegion());

	//in the sub-segmentation image, we need to mask out any pixel from another object	
	int counter = 0;
	while ( ! iterator1.IsAtEnd())
	{		
		int V = iterator1.Get();
		if(V == objID)
		{
			iterator2.Set(255.0);
			counter++; //just for debuging purposes,, will be removed
		}
		else
			iterator2.Set(0.0);
		++iterator1;
		++iterator2;		
	}	
	//Let's try this (for debugging): save the binary mask
	/*	typedef itk::Image< unsigned short, 3 > OutputImageType;
		typedef itk::CastImageFilter< DistImageType, OutputImageType > CastType; 
		CastType::Pointer cast = CastType::New(); 
		cast->SetInput( subSegImg ); 
		cast->Update(); 

		typedef itk::ImageFileWriter< OutputImageType > WriterType; 
		WriterType::Pointer writer = WriterType::New( ); 
		writer->SetInput( cast->GetOutput() ); 
		writer->SetFileName( "c:/bin_mask.tif" ); 
		writer->Update(); */

	//Compute the distance transform in the sub-segmentation image region	
	DTFilter::Pointer dt_obj= DTFilter::New() ;
	dt_obj->SetInput(subSegImg) ;
	//dt_obj->SetInsideValue(255.0);
	//dt_obj->SetOutsideValue(0.0);	
	try{
		dt_obj->Update() ;
	}
	catch( itk::ExceptionObject & err ){
		std::cout << "Error in Distance Transform: " << err << std::endl; 
		return 0;	
	}

	//Let's try this (for debugging): save the distance map
		////typedef itk::Image< unsigned short, 3 > OutputImageType;
		////typedef itk::CastImageFilter< DistImageType, OutputImageType > CastType; 
		////CastType::Pointer cast = CastType::New(); 
		//cast->SetInput( dt_obj->GetOutput() ); 
		//cast->Update(); 

		////typedef itk::ImageFileWriter< OutputImageType > WriterType; 
		////WriterType::Pointer writer = WriterType::New( ); 
		//writer->SetInput( cast->GetOutput() ); 
		//writer->SetFileName( "c:/dist_map.tif" ); 
		//writer->Update(); 
	
	//now, mask out all the pixels (in the sub-seg image) that are not in the region of interest as defined by the association rule and get the intensities of the needed pixels from the target image. The intensities are saved into an std vector
	IteratorType2 iterator3(dt_obj->GetOutput(), dt_obj->GetOutput()->GetRequestedRegion());
	IteratorType iterator4(trgIm, trgIm->GetRequestedRegion());
	std::vector<int> trgInt;
	int counter_in = 0;
	int counter_at = 0;
	int counter_ot = 0;
	while ( ! iterator3.IsAtEnd())
	{
		int V = (int)iterator3.Get();
		if(V<0)
			counter_in++;
		if(V==0)
			counter_at++;
		if(V>0)
			counter_ot++;
		//if it is outside with distance less than outDistance away
		if(V>0 && V<=assocRulesList[ruleID].GetOutDistance())
			trgInt.push_back(iterator4.Get());
		//if it is inside and the whole cell is used
		else if(V<=0 && assocRulesList[ruleID].IsUseWholeObject())
			trgInt.push_back(iterator4.Get());
		//if it is inside with distance less than in Distance
		else if(V<=0 && abs(V)<=assocRulesList[ruleID].GetInDistance())
			trgInt.push_back(iterator4.Get());

		++iterator3;
		++iterator4;
	}
	if(!trgInt.size())
		return 0;
	
	//Finally, given the list of intensities compute the associative measrement based on the type defined by the association rule
	switch(assocRulesList[ruleID].GetAssocType())
	{
		case ASSOC_MIN:
			return FindMin(trgInt);
			break;
		case ASSOC_MAX:
			return FindMax(trgInt);
			break;
		case ASSOC_TOTAL:
			return ComputeTotal(trgInt);
			break;
		case ASSOC_AVERAGE:
			return ComputeAverage(trgInt);
			break;
		default:
			return ComputeAverage(trgInt);
	}	
  //we will never go here, just silencing a compiler warning
  return 0.0;
}
mitk::USVideoDeviceCustomControls::USVideoDeviceCustomControls(itk::SmartPointer<USVideoDevice> device)
  : mitk::USAbstractControlInterface(device.GetPointer()), m_IsActive(false)
{
  m_ImageSource = dynamic_cast<mitk::USImageVideoSource*>(m_Device->GetUSImageSource().GetPointer());
}
void QmitkUSNavigationCombinedSettingsWidget::OnSetSettingsNode(itk::SmartPointer<mitk::DataNode> settingsNode, bool overwriteValues)
{
  if ( overwriteValues )
  {
    settingsNode->SetStringProperty("settings.application", ui->applicationComboBox->currentText().toStdString().c_str());
    settingsNode->SetStringProperty("settings.interaction-concept", this->InteractionNameToFile(ui->interactionConceptComboBox->currentText()).toStdString().c_str());
    settingsNode->SetBoolProperty("settings.experiment-mode", ui->experimentModeCheckBox->isChecked());
    settingsNode->SetStringProperty("settings.experiment-results-directory", ui->experimentResultsPathButton->directory().toStdString().c_str());

    settingsNode->SetFloatProperty("settings.security-distance", ui->securityDistanceSpinBox->value());
    settingsNode->SetIntProperty("settings.number-of-targets", ui->numberOfTargetsSpinBox->value());
    settingsNode->SetBoolProperty("settings.use-planning-step", ui->planningStepUsageCheckBox->isChecked());

    settingsNode->SetStringProperty("settings.needle-name-selected", ui->needleNameComboBox->currentText().toStdString().c_str());
    settingsNode->SetStringProperty("settings.reference-name-selected", ui->referenceNameComboBox->currentText().toStdString().c_str());
  }
  else
  {
    std::string stringProperty;
    float floatProperty;
    bool boolProperty;

    // load state of application setting combo box
    if ( ! settingsNode->GetStringProperty("settings.application", stringProperty) ) { stringProperty = ""; }
    int lastIndex = ui->applicationComboBox->findText(QString::fromStdString(stringProperty));
    if (lastIndex == -1) { lastIndex = 0; }
    ui->applicationComboBox->setCurrentIndex(lastIndex);
    this->OnApplicationChanged(lastIndex);

    // load state of interaction concept setting combo box
    if ( ! settingsNode->GetStringProperty("settings.interaction-concept", stringProperty) ) { stringProperty = ""; }
    lastIndex = ui->interactionConceptComboBox->findText(QString::fromStdString(stringProperty));
    if (lastIndex == -1) { lastIndex = 0; }
    ui->interactionConceptComboBox->setCurrentIndex(lastIndex);

    if ( ! settingsNode->GetBoolProperty("settings.experiment-mode", boolProperty) ) { boolProperty = false; }
    ui->experimentModeCheckBox->setChecked(boolProperty);

    if ( ! settingsNode->GetStringProperty("settings.experiment-results-directory", stringProperty) ) { stringProperty = ""; }
    ui->experimentResultsPathButton->setDirectory(QString::fromStdString(stringProperty));

    if ( ! settingsNode->GetFloatProperty("settings.security-distance", floatProperty) ) { floatProperty = 2.0; }
    ui->securityDistanceSpinBox->setValue(floatProperty);

    if ( ! settingsNode->GetFloatProperty("settings.number-of-targets", floatProperty) ) { floatProperty = 3; }
    ui->numberOfTargetsSpinBox->setValue(static_cast<int>(floatProperty));

    if ( ! settingsNode->GetBoolProperty("settings.use-planning-step", boolProperty) ) { boolProperty = true; }
    ui->planningStepUsageCheckBox->setChecked(boolProperty);

    if ( ! settingsNode->GetStringProperty("settings.needle-names", stringProperty) ) { stringProperty = ""; }
    QString needleNames = QString::fromStdString(stringProperty);

    ui->needleNameComboBox->clear();
    ui->needleNameComboBox->addItems(needleNames.split(";", QString::SkipEmptyParts));

    if ( ! settingsNode->GetStringProperty("settings.needle-name-selected", stringProperty) ) { stringProperty = ""; }
    int index = ui->needleNameComboBox->findText(QString::fromStdString(stringProperty));
    if (index == -1)
    {
      ui->needleNameComboBox->addItem(QString::fromStdString(stringProperty));
      ui->needleNameComboBox->setCurrentIndex(ui->needleNameComboBox->count()-1);
    }
    else
    {
      ui->needleNameComboBox->setCurrentIndex(index);
    }

    if ( ! settingsNode->GetStringProperty("settings.reference-names", stringProperty) ) { stringProperty = ""; }
    QString referenceNames = QString::fromStdString(stringProperty);

    ui->referenceNameComboBox->clear();
    ui->referenceNameComboBox->addItems(referenceNames.split(";", QString::SkipEmptyParts));

    if ( ! settingsNode->GetStringProperty("settings.reference-name-selected", stringProperty) ) { stringProperty = ""; }
    index = ui->referenceNameComboBox->findText(QString::fromStdString(stringProperty));
    if (index == -1)
    {
      ui->referenceNameComboBox->addItem(QString::fromStdString(stringProperty));
      ui->referenceNameComboBox->setCurrentIndex(ui->referenceNameComboBox->count()-1);
    }
    else
    {
      ui->referenceNameComboBox->setCurrentIndex(index);
    }
  }
}
USImageType::PixelType returnthresh( itk::SmartPointer<USImageType> input_image,
			     int num_bin_levs, int num_in_fg ){
	//Instantiate the different image and filter types that will be used
	typedef itk::ImageRegionConstIterator< USImageType > ConstIteratorType;
	typedef itk::Statistics::Histogram< float > HistogramType;
	typedef itk::OtsuMultipleThresholdsCalculator< HistogramType > CalculatorType;

	std::cout<<"Starting threshold computation\n";

	//Create a temporary histogram container:
	const int numBins = itk::NumericTraits<USImageType::PixelType>::max();
	double *tempHist;
	tempHist = (double*) malloc( sizeof(double) * numBins );
	for(USImageType::PixelType i=0; i<numBins; ++i)
		tempHist[i] = 0;

	USImageType::PixelType maxval = itk::NumericTraits<USImageType::PixelType>::ZeroValue();
	USImageType::PixelType minval = itk::NumericTraits<USImageType::PixelType>::max();
	//Populate the histogram (assume pixel type is actually is some integer type):
	ConstIteratorType it( input_image, input_image->GetRequestedRegion() );
	for ( it.GoToBegin(); !it.IsAtEnd(); ++it ){
		USImageType::PixelType pix = it.Get();
		++tempHist[pix];
		if( pix > maxval ) maxval = pix;
		if( pix < minval ) minval = pix;
	}
	//return max of type if there is no variation in the staining
	if( (maxval-minval)<3 ) return itk::NumericTraits<USImageType::PixelType>::max(); 
	const USImageType::PixelType numBinsPresent = maxval+1;
	
	//Find max value in the histogram
	double floatIntegerMax = itk::NumericTraits<USImageType::PixelType>::max();
	double max = 0.0;
	for(USImageType::PixelType i=0; i<numBinsPresent; ++i)
		if( tempHist[i] > max )
			max = tempHist[i];

	double scaleFactor = 1;
	if(max >= floatIntegerMax)
		scaleFactor = floatIntegerMax / max;

	HistogramType::Pointer histogram = HistogramType::New() ;
	// initialize histogram
	HistogramType::SizeType size;
	HistogramType::MeasurementVectorType lowerBound;
	HistogramType::MeasurementVectorType upperBound;

	lowerBound.SetSize(1);
	upperBound.SetSize(1);
	size.SetSize(1);

	lowerBound.Fill(0.0);
	upperBound.Fill((double)maxval);
	size.Fill(numBinsPresent);

	histogram->SetMeasurementVectorSize(1);
	histogram->Initialize(size, lowerBound, upperBound ) ;

	USImageType::PixelType i=0;
	for (HistogramType::Iterator iter = histogram->Begin(); iter != histogram->End(); ++iter ){
		float norm_freq = (float)(tempHist[i] * scaleFactor);
		iter.SetFrequency(norm_freq);
		++i;
	}

	std::cout<<"Histogram computed\n";

	CalculatorType::Pointer calculator = CalculatorType::New();
	calculator->SetNumberOfThresholds( num_bin_levs );
	calculator->SetInputHistogram( histogram );
	calculator->Update();
	const CalculatorType::OutputType &thresholdVector = calculator->GetOutput(); 
	CalculatorType::OutputType::const_iterator itNum = thresholdVector.begin();

	float thresh;

	for(USImageType::PixelType i=0; i < num_in_fg; ++itNum, ++i)
		thresh = (static_cast<float>(*itNum));

	std::cout<<"Threshold computed: "<<thresh<<std::endl;

	return (USImageType::PixelType)(thresh+0.5);
}