int CharacterEdits::exec( TextRangeRegExp* regexp )
{
    _regexp = regexp;
    negate->setChecked( regexp->negate() );
    digit->setChecked( regexp->digit() );
    _nonDigit->setChecked( regexp->nonDigit() );
    space->setChecked( regexp->space() );
    _nonSpace->setChecked( regexp->nonSpace() );
    wordChar->setChecked( regexp->wordChar() );
    _nonWordChar->setChecked( regexp->nonWordChar() );

    bool enabled = (RegExpConverter::current()->features() & RegExpConverter::CharacterRangeNonItems);
    _nonWordChar->setEnabled( enabled );
    _nonDigit->setEnabled( enabled );
    _nonSpace->setEnabled( enabled );

    // Characters

    KMultiFormListBoxEntryList list1 = _single->elements();
    for ( TQPtrListIterator<KMultiFormListBoxEntry> it(list1); *it; ++it ) {
        SingleEntry* entry = dynamic_cast<SingleEntry*>( *it );
        if (entry)
            entry->setText( TQString::fromLocal8Bit("") );
    }
    TQStringList list2 = regexp->chars();
    for ( TQStringList::Iterator it2( list2.begin() ); ! (*it2).isNull(); ++it2 ) {
        addCharacter( *it2 );
    }

    // Ranges
    KMultiFormListBoxEntryList list3 = _range->elements();
    for ( TQPtrListIterator<KMultiFormListBoxEntry> it3(list3); *it3; ++it3 ) {
        RangeEntry* entry = dynamic_cast<RangeEntry*>( *it3 );
        if (entry) {
            entry->setFrom( TQString::fromLocal8Bit("") );
            entry->setTo( TQString::fromLocal8Bit("") );
        }
    }

    TQPtrList<StringPair> ranges = regexp->range();
    for ( TQPtrListIterator<StringPair> it4(ranges); *it4; ++it4 ) {
        TQString from = (*it4)->first();
        TQString to = (*it4)->second();
        addRange(from,to);
    }

    int res = KDialogBase::exec();
    _regexp = 0;
    return res;
}
TEST_F(test_ring_input_iterator, canEqualityCompareIterators) {
  iterator it1, it2;
  EXPECT_EQ(it1, it2);
  ring buff(5);
  iterator it3(&buff.front(), &buff.front() + buff.capacity());
  iterator it4(&buff.front(), &buff.front() + buff.capacity());
  EXPECT_NE(it1, it3);
  EXPECT_EQ(it3, it4);
  ++it3;
  EXPECT_NE(it3, it4);
  ++it3;
  ++it3;
  ++it3;
  ++it3;
  EXPECT_NE(it3, it4);
}
	TEST(RandomIterator, init) {

		int cnt;
		std::vector<int> values = {1,2,3,4,5,6};

		RandomIterator<int> it1(values, 1); it1.randomize();
		cnt = 0; for(int i : it1) {(void) i; ++cnt;} ASSERT_EQ(1, cnt);

		RandomIterator<int> it2(values, 2); it2.randomize();
		cnt = 0; for(int i: it2) {(void) i; ++cnt;} ASSERT_EQ(2, cnt);

		RandomIterator<int> it3(values, 3); it3.randomize();
		cnt = 0; for(int i: it3) {(void) i; ++cnt;} ASSERT_EQ(3, cnt);

		RandomIterator<int> it4(values, 4); it4.randomize();
		cnt = 0; for(int i: it4) {(void) i; ++cnt;} ASSERT_EQ(4, cnt);

		RandomIterator<int> it5(values, 5); it5.randomize();
		cnt = 0; for(int i: it5) {(void) i; ++cnt;} ASSERT_EQ(5, cnt);

		RandomIterator<int> it6(values, 6); it6.randomize();
		cnt = 0; for(int i: it6) {(void) i; ++cnt;} ASSERT_EQ(6, cnt);

	}
int main()
{
	InputImageType::Pointer im = readImage<InputImageType>("C:/Users/arun/Research/Farsight/exe/bin/CF_1_inverted_bg_sub.tif");
	FILE *fp = fopen("C:/Users/arun/Research/Farsight/exe/bin/seeds.txt","r");

	//IteratorType initer(im,im->GetLargestPossibleRegion());
	//initer.GoToBegin();
	//
	//for(;!initer.IsAtEnd(); ++initer)
	//{
	//	initer.Set(transfer_function1(initer.Get()));
	//}
	//
	//writeImage<InputImageType>(im,"C:/Users/arun/Research/Farsight/exe/bin/hp2_cropped2_filtered.tif");
	//
	//return 0;
	typedef itk::SymmetricSecondRankTensor<double,3> HessianType;
	typedef itk::Hessian3DToVesselnessMeasureImageFilter<float> MeasureType;
	typedef itk::Image<HessianType,3> HessianImageType;
	typedef itk::MultiScaleHessianBasedMeasureImageFilter< InputImageType, HessianImageType, FloatImageType> VesselnessFilterType;
	
	std::vector<InputImageType::RegionType> in1,in2,out1,out2;

	get_tiles(im->GetLargestPossibleRegion().GetSize(),1500,1500,1500,100,100,10,in1,in2,out1,out2);
	
	InputImageType::Pointer om;
/*
	om = InputImageType::New();
	om->SetRegions(im->GetLargestPossibleRegion());
	om->Allocate();
	for(int counter = 0; counter < in1.size(); counter++)
	{
		InputImageType::Pointer imtile = InputImageType::New();//
		imtile->SetRegions(in2[counter]);
		imtile->Allocate();

		in1[counter].Print(std::cout);
		in2[counter].Print(std::cout);
		IteratorType iter1(im,in1[counter]);
		IteratorType iter2(imtile,in2[counter]);
		for(iter1.GoToBegin(),iter2.GoToBegin();!iter1.IsAtEnd(); ++iter1,++iter2)
		{
			iter2.Set(iter1.Get());
		}

		VesselnessFilterType::Pointer vfilt = VesselnessFilterType::New();
		MeasureType::Superclass::Pointer measure = MeasureType::New();
		
		vfilt->SetInput(imtile);
		vfilt->SetHessianToMeasureFilter((VesselnessFilterType::HessianToMeasureFilterType *)measure);
		vfilt->SetSigmaMinimum(3.0);
		vfilt->SetSigmaMaximum(5.0);
		vfilt->SetNumberOfSigmaSteps(3);
		vfilt->SetSigmaStepMethod(VesselnessFilterType::EquispacedSigmaSteps);
		vfilt->Update();
		FloatImageType::Pointer omtile = vfilt->GetOutput();
		
		typedef itk::ImageRegionIterator<FloatImageType> FloatIteratorType;
		FloatIteratorType iter3;
		iter1 = IteratorType(om,out1[counter]);
		iter3 = FloatIteratorType(omtile,out2[counter]);
		for(iter1.GoToBegin(),iter3.GoToBegin();!iter1.IsAtEnd();++iter1,++iter3)
		{
			iter1.Set(iter3.Get());
		}
	}
	writeImage<InputImageType>(om,"C:/Users/arun/Research/Farsight/exe/bin/vesselnesstest.tif");
*/
	om = readImage<InputImageType>("C:/Users/arun/Research/Farsight/exe/bin/vesselnesstest.tif");
	typedef itk::BinaryBallStructuringElement<InputImageType::PixelType,3> StructElementType;
	typedef itk::GrayscaleDilateImageFilter<InputImageType,InputImageType,StructElementType> FilterType1;
	FilterType1::Pointer minfilt = FilterType1::New();
	minfilt->SetInput(om);
	FilterType1::RadiusType radius;
	radius[0] = 1;
	radius[1] = 1;
	radius[2] = 1;
	StructElementType strel;
	strel.SetRadius(radius);
	minfilt->SetKernel(strel);
	minfilt->Update();

	InputImageType::Pointer seed_out  = InputImageType::New();
	seed_out->SetRegions(om->GetLargestPossibleRegion());
	seed_out->Allocate();
	seed_out->FillBuffer(0);

	int thresh_value = 6;
	int number_of_seeds = 200;
	int tnum_seeds = 0;

	typedef itk::ImageRegionIteratorWithIndex<InputImageType> IndexIteratorType;

	IndexIteratorType it1(minfilt->GetOutput(),minfilt->GetOutput()->GetLargestPossibleRegion());
	IteratorType it2(om,om->GetLargestPossibleRegion());

	for(it2.GoToBegin();!it2.IsAtEnd(); ++it2)
	{
		if(it2.Get()>thresh_value)
			tnum_seeds++;
	}
	printf("tnum_seeds = %d\n",tnum_seeds);
	IteratorType it3(seed_out,seed_out->GetLargestPossibleRegion());
	IteratorType it4(im,im->GetLargestPossibleRegion());

	std::vector<mdl::fPoint3D> seeds;
	seeds.clear();
	/*for(it1.GoToBegin(),it2.GoToBegin(),it3.GoToBegin(),it4.GoToBegin();!it1.IsAtEnd();++it1,++it2,++it3,++it4)
	{
		if(it1.Get()==it2.Get() && it4.Get() > 150)
		{
			it3.Set(255);
			InputImageType::IndexType index = it1.GetIndex();
			mdl::fPoint3D seed1;
			seed1.x = index[0];
			seed1.y = index[1];
			seed1.z = index[2];
			seeds.push_back(seed1);
		}
	}*/

	seeds.clear();
	
	while(!feof(fp))
	{
		mdl::fPoint3D seed1;
		fscanf(fp,"%f %f %f",&seed1.x,&seed1.y,&seed1.z);
		if(feof(fp))
			break;
		seed1.x*=1;
		seed1.y*=1;
		seeds.push_back(seed1);
	}
	fclose(fp);
	printf("Seeds.size = %d\n",seeds.size());
	//scanf("%*d");
	mdl::vtkFileHandler * fhd1 = new mdl::vtkFileHandler();
	fhd1->SetNodes(&seeds);
	std::vector<mdl::pairE> nullpairs;
	fhd1->SetLines(&nullpairs);
	std::string outFilename1 = "C:/Users/arun/Research/Farsight/exe/bin/mst_input.vtk";
	fhd1->Write(outFilename1.c_str());
	delete fhd1;


	int edgeRange = 50;
	int morphStrength = 0;
	mdl::MST *mst = new mdl::MST( im );
	mst->SetDebug(false);
	mst->SetUseVoxelRounding(false);
	mst->SetEdgeRange(edgeRange);
	mst->SetPower(1);
	mst->SetSkeletonPoints( &seeds );
	// can choose different weight
	//mst->CreateGraphAndMST(1);
	mst->CreateGraphAndMST(5);
	mst->ErodeAndDialateNodeDegree(morphStrength);

	std::vector<mdl::fPoint3D> nodes = mst->GetNodes();
	std::vector<mdl::pairE> bbpairs = mst->BackboneExtract();

	delete mst;

	std::cerr << "Saving\n";

	//****************************************************************
	// TREE WRITER
	mdl::vtkFileHandler * fhd2 = new mdl::vtkFileHandler();
	fhd2->SetNodes(&nodes);
	fhd2->SetLines(&bbpairs);
	std::string outFilename2 = "C:/Users/arun/Research/Farsight/exe/bin/mst_tree.vtk";
	fhd2->Write(outFilename2.c_str());
	delete fhd2;
	scanf("%*d");

	writeImage<InputImageType>(seed_out,"C:/Users/arun/Research/Farsight/exe/bin/seedimage.tif");
		
}
void LinguisticaMainWindow::updateTreeViewSlot()
{
  // Adapted from MFC version: CMyTree::UpdateUpperTree, CMyTree::UpdateStatistics

  int     count,    // used for various counts
          index;    // mini-lexicon index
  index = 0;
  count = 0;

//  bool      add = TRUE;

  CStem* pWord;

  Q3ListViewItem  * MiscItem      = NULL,
		  * MiscItem1       = NULL,
          * LexiconItem     = NULL,
          * WordsReadItem   = NULL,
          * PrefixesItem    = NULL,
          * SuffixesItem    = NULL,
          * WordsItem       = NULL,
 		  * CompoundsItem   = NULL,
          * ComponentItem   = NULL,
		  *	STRINGEDITITEM  = NULL,
		  * CorpusWordsItem = NULL;
		  
 
  // Clear the tree
  m_treeView->clear();
  m_treeView->setFont( GetFontPreference( "Main" ) );
  m_treeView->hideColumn(1);

//**************************************************************************************
// A NOTE ON THE ORGANIZATION OF THIS FUNCTION:
// The items are inserted into the tree in reverse order respective to their group.  They
// are organized by depth here, i.e. what is connected to the root is the first group,
// then do the groups of items connected to this first group, etc.  The only items that
// get their own name are those that have children.  The rest use MiscItem
//**************************************************************************************


//======================================================================================//
  // START CONNECTED DIRECTLY TO m_treeView
//======================================================================================//


	count = GetNumberOfTokens();
	if( count >= 0 )
	{
		MiscItem = new CTreeViewItem( m_treeView,
									  "Tokens requested: " + IntToStringWithCommas( count ),
									  TOKENS_REQUESTED );
		MiscItem->setSelectable(false);
	}  

//======================================================================================//

	if( m_lexicon->GetWords() && m_lexicon->GetMiniCount() )
	{
		count = m_lexicon->GetTokenCount();
		if ( count >= 0 )
		{
			WordsReadItem = new CTreeViewItem( m_treeView,
											   "Tokens read: " + IntToStringWithCommas( count ) );
			WordsReadItem->setSelectable(false);
			WordsReadItem->setOpen(true);
		}

//======================================================================================//

		LexiconItem = new CTreeViewItem( m_treeView,
						 "Lexicon : click items to display them" );
		LexiconItem->setSelectable(false);
		LexiconItem->setOpen(true);
	}

//======================================================================================//

  if ( m_projectDirectory.length()  )
  {
    MiscItem = new CTreeViewItem( m_treeView, "Project directory: " + m_projectDirectory );
    MiscItem->setSelectable(false);
  }
  else
  {
    MiscItem = new CTreeViewItem( m_treeView, "No project directory." );
    MiscItem->setSelectable(false);
  }

//======================================================================================//

  if ( m_logging )
  {
    MiscItem = new CTreeViewItem( m_treeView, "Log file (now on) " + GetLogFileName() );
    MiscItem->setSelectable(false);
  }
  else
  {
    MiscItem = new CTreeViewItem( m_treeView, "Log file (now off) " + GetLogFileName() );
    MiscItem->setSelectable(false);
  }

//=================================================================================================
  // END CONNECTED DIRECTLY TO m_treeView
  // START CONNECTED TO LexiconItem
//=================================================================================================

	if ( LexiconItem && m_lexicon->GetHMM() )
	{		
		MiscItem = new CTreeViewItem( LexiconItem,
									   "HMM",
									   HMM_Document);
		double dl = m_lexicon->GetHMM()->GetLogProbability();
		MiscItem1 = new CTreeViewItem(MiscItem,"HMM description length: " + IntToStringWithCommas(int( dl) )
									   );		
		MiscItem1 = new CTreeViewItem(MiscItem,
									  "Iterations: " + IntToStringWithCommas( m_lexicon->GetHMM()->m_NumberOfIterations )
									   );		
		MiscItem1 = new CTreeViewItem(MiscItem,
									  "Number of states: " + IntToStringWithCommas( m_lexicon->GetHMM()->m_countOfStates )
									   );		
	}
	MiscItem->setOpen(true);

//======================================================================================//

  if( LexiconItem )
  {
	  if( m_lexicon->GetDLHistory()->count() > 0 )
	  {
		 MiscItem = new CTreeViewItem( LexiconItem,
									   "Description length history",
									   DESCRIPTION_LENGTH_HISTORY );
	  }
  }

//////////////////////////////
//// StringEdit Display

	if ((LexiconItem != NULL) && (m_Words_InitialTemplates != NULL))
	{
		if ( m_Words_InitialTemplates ->GetCount() > 0)
		{
			STRINGEDITITEM = new CTreeViewItem( LexiconItem,
										  "StringEditDistanceTemplates: " + IntToStringWithCommas( 2 ), 
										  STRINGEDITDISTANCE, -1);

			count = m_Words_Templates ->GetCount();
			if ( count != 0)
			{
				MiscItem = new CTreeViewItem( STRINGEDITITEM,
										  "StringEdit_Templates: " + IntToStringWithCommas( count ), 
										  WORKINGSTRINGEDITTEMPLATES, -1);

			}

			count = m_Words_InitialTemplates ->GetCount();
			MiscItem = new CTreeViewItem( STRINGEDITITEM,
										  "StringEdit_InitialTemplates: " + IntToStringWithCommas( count ), 
										  INITIALSTRINGEDITTEMPLATES, -1);
		}
	}

		count = 0;
		Q3DictIterator<PrefixSet> it5( *m_lexicon->GetAllPrefixes() );
		for( ; it5.current(); ++it5 )
		{
			count += it5.current()->count();
		}
		if( count > 0 )
		{
			PrefixesItem = new CTreeViewItem( LexiconItem,
											  "All Prefixes " + IntToStringWithCommas( count ),
											  ALL_PREFIXES );
			PrefixesItem->setOpen( TRUE );
		}    
//======================================================================================//
		count = 0;
		Q3DictIterator<SuffixSet> it4( *m_lexicon->GetAllSuffixes() );
		for( ; it4.current(); ++it4 )
		{
			count += it4.current()->count();
		}
		if( count > 0 )
		{
			SuffixesItem = new CTreeViewItem( LexiconItem,
											  "All Suffixes " + IntToStringWithCommas( count ),
											  ALL_SUFFIXES );
			SuffixesItem->setOpen( TRUE );
		}
//======================================================================================//
		count = 0;
		Q3DictIterator<StemSet> it1( *m_lexicon->GetAllStems() );
		for( ; it1.current(); ++it1 )
		{
			count += it1.current()->count();
		}
		if( count > 0 )
		{
			MiscItem = new CTreeViewItem( LexiconItem,
										  "All Stems " + IntToStringWithCommas( count ),
										  ALL_STEMS );
		}
 //======================================================================================//
		count = 0;
		Q3DictIterator<StemSet> it2( *m_lexicon->GetAllWords() );
		for( ; it2.current(); ++it2 )
		{
			count += it2.current()->count();
		}

		if( count > 0 )
		{
			WordsItem = new CTreeViewItem( LexiconItem,
										  "All Words " + IntToStringWithCommas( count ),
										  ALL_WORDS );
			WordsItem->setOpen( TRUE );
		}	
//======================================================================================//
	  if( m_lexicon->GetMiniCount() )
	  {
		for( index = m_lexicon->GetMiniSize() - 1; index >= 0; index-- )
		{
			if( m_lexicon->GetMiniLexicon( index ) )
				MiscItem = GetMiniLexiconSubTree( LexiconItem, index );
		}
	  }
//======================================================================================//
		count = m_lexicon->GetCompounds()->GetCount();
		if( count > 0 )
		{
			CompoundsItem = new CTreeViewItem( LexiconItem,
											   "Compounds " + IntToStringWithCommas( count ),
											   COMPOUNDS );
			CompoundsItem->setOpen( TRUE );
            int count2 = m_lexicon->GetCompounds()->GetComponents()->GetSize();
            ComponentItem = new CTreeViewItem( CompoundsItem, "Components "+ IntToStringWithCommas (count2),
                                                COMPOUND_COMPONENTS);
		}
//======================================================================================//

	  count = m_lexicon->GetWords()->GetCount();
	  if( count > 0 )
	  {
		CorpusWordsItem = new CTreeViewItem( LexiconItem,
											 "Corpus Words " + IntToStringWithCommas( count ),
											 CORPUS_WORDS );
		CorpusWordsItem->setOpen( TRUE );
	  }
//=================================================================================================
  // END CONNECTED TO LexiconItem
  // START CONNECTED TO CorpusWordsItem
//=================================================================================================

	count = 0;
	if( CorpusWordsItem )
	{

		CCorpusWord* pCorpusWord;
		CCorpusWordCollection* pWords = m_lexicon->GetWords();

		pWords->Sort( KEY );

		for( int i = 0; i < pWords->GetCount(); i++ )
		{
			pCorpusWord = pWords->GetAtSort(i);

			if( pCorpusWord->Size() > 1 )
			{
				count++;
			}
		}

		if( count > 0 )
		{
			MiscItem = new CTreeViewItem( CorpusWordsItem,
										  "Analyzed " + IntToStringWithCommas( count ),
										  ANALYZED_CORPUS_WORDS );
		}
	}
 
//=================================================================================================
  // END CONNECTED TO CorpusWordsItem
  // START CONNECTED TO WordsItem
//=================================================================================================

	count = 0;

	bool analyzed_exists;
	Q3DictIterator<StemSet> it3( *m_lexicon->GetAllWords() );
        for( ; it3.current(); ++it3 )
	{
            analyzed_exists = FALSE;
            //for( pWord = it3.current()->first(); pWord; pWord = it3.current()->next() )
            for (int z = 0; z < it3.current()->size(); z++)
            {
                pWord = it3.current()->at(z);
                if( pWord->Size() > 1 )
                {
                        analyzed_exists = TRUE;
                        count++;
                }
            }
	}

	if( count > 0 )
	{
		MiscItem = new CTreeViewItem( WordsItem,
									  "Analyzed " + IntToStringWithCommas( count ),
									  ALL_ANALYZED_WORDS );
	}

//=================================================================================================
  // END CONNECTED TO WordsItem
  // START CONNECTED TO SuffixesItem
//=================================================================================================

	count = 0;

	Q3DictIterator<SignatureSet> it7( *m_lexicon->GetAllSuffixSigs() );
	for( ; it7.current(); ++it7 )
	{
		count += it7.current()->count();
	}
	if( count > 0 )
	{
		MiscItem = new CTreeViewItem( SuffixesItem,
									  "Signatures " + IntToStringWithCommas( count ),
									  ALL_SUFFIX_SIGNATURES );
	}

//=================================================================================================
  // END CONNECTED TO SuffixesItem
  // START CONNECTED TO PrefixesItem
//=================================================================================================

	count = 0;

	Q3DictIterator<SignatureSet> it6( *m_lexicon->GetAllPrefixSigs() );
	for( ; it6.current(); ++it6 )
	{
		count += it6.current()->count();
	}
	if( count > 0 )
	{
		MiscItem = new CTreeViewItem( PrefixesItem,
									  "Signatures " + IntToStringWithCommas( count ),
									  ALL_PREFIX_SIGNATURES );
	}

//=================================================================================================
  // END CONNECTED TO PrefixesItem
  // START CONNECTED TO WordsReadItem
//=================================================================================================

	if( WordsReadItem )
	{
		if( m_lexicon->GetWords() )
		{
			count = m_lexicon->GetWords()->GetCount();
			if( count > 0 )
			{
				MiscItem = new CTreeViewItem( WordsReadItem,
											  "Distinct types read: " + IntToStringWithCommas( count ) );
				MiscItem->setSelectable(false);
			}
		} 

//======================================================================================//

		count = m_lexicon->GetCorpusCount();
		if( count >= 0 )
		{
			MiscItem = new CTreeViewItem( WordsReadItem,
										  "Tokens included: " + IntToStringWithCommas( count ) );
			MiscItem->setSelectable(false);
		} 
	}


//=================================================================================================
  // END CONNECTED TO WordsReadItem
  // START CONNECTED TO CompoundsItem
//=================================================================================================

	count = m_lexicon->GetLinkers()->GetCount();
	if( count > 0 )
	{
		MiscItem = new CTreeViewItem( CompoundsItem,
									  "Linkers " + IntToStringWithCommas( count ),
									  LINKERS, index );
	}
}
float
rich_cell::
compute_average_intensity( ImageType::Pointer intensity_image, LabelImageType::ConstPointer label_image, int dist_interior, int dist_exterior)
{
  float sum_interior = 0;
  float sum_exterior = 0;
  int count_interior = 0;
  int count_exterior = 0;

  if (dist_exterior < dist_interior) { // the entire segmented area is taken
    for (unsigned int b = 0; b<all_points_.size(); b++) {
      vnl_vector_fixed< float, 3 > const & pt = all_points_[b];
      ImageType::IndexType pos;
      pos[0] = pt[0];
      pos[1] = pt[1];
      pos[2] = pt[2];
      sum_interior += intensity_image->GetPixel(pos);
    }

    return sum_interior/all_points_.size();
  }
   
  RegionType region = bounding_box_;
  if (dist_interior < 0) { //erode the mask 
    // Generate a mask image of the cell region. Erode the region by
    // r_interior
    RegionType::SizeType size = region.GetSize();
    RegionType::IndexType start={{0,0,0}};
    ImageType::Pointer cropped_mask = ImageType::New(); 
    RegionType mask_region;
    mask_region.SetIndex( start );
    mask_region.SetSize( size );
    cropped_mask->SetRegions( mask_region );
    cropped_mask->Allocate();
    cropped_mask->FillBuffer(0);
    LabelConstRegionIteratorType it1( label_image, region);
    RegionIteratorType it2( cropped_mask, mask_region );
    for (it1.GoToBegin(), it2.GoToBegin(); !it1.IsAtEnd(); ++it1, ++it2) {
      if (it1.Get() == label_)
        it2.Set( 255 );
    }
      
    ImageType::Pointer eroded_mask;
    ErodeFilterType::Pointer f_erode = ErodeFilterType::New();
    SubFilterType::Pointer f_sub = SubFilterType::New();
    StructuringElementType  structuringElement;
    structuringElement.SetRadius( -dist_interior );
    structuringElement.CreateStructuringElement();
    f_erode->SetKernel( structuringElement );
    f_erode->SetInput(cropped_mask);
    f_sub->SetInput1( cropped_mask  );
    f_sub->SetInput2( f_erode->GetOutput() );
    try {
      f_sub->Update();
    }
    catch (itk::ExceptionObject & e) {
      std::cerr << "Exception in SubFilter: " << e << std::endl;
      exit(0);
    }
    eroded_mask = f_sub->GetOutput();
      
    // Sum the signal in the eroded region only
    ConstRegionIteratorType it3( eroded_mask, mask_region );
    ConstRegionIteratorType it4( intensity_image, region);
    for (it3.GoToBegin(), it4.GoToBegin(); !it3.IsAtEnd(); ++it1, ++it3, ++it4) {
      if (it3.Get() > 0) {
        sum_interior += it4.Get();
        count_interior ++;
      }
    }
  }
  if (dist_exterior > 0) { //dilate the mask
    // enlarge the bounding box by r on each side.
    RegionType::SizeType image_size = intensity_image->GetLargestPossibleRegion().GetSize();
    RegionType::SizeType size = region.GetSize();
    RegionType::IndexType start = region.GetIndex();
    RegionType::IndexType end;
    end[0] = vnl_math_min(start[0]+size[0]+dist_exterior, image_size[0]);
    end[1] = vnl_math_min(start[1]+size[1]+dist_exterior, image_size[1]);
    end[2] = vnl_math_min(start[2]+size[2]+dist_exterior, image_size[2]);
    start[0] = vnl_math_max(int(start[0]-dist_exterior), 0);
    start[1] = vnl_math_max(int(start[1]-dist_exterior), 0);
    start[2] = vnl_math_max(int(start[2]-dist_exterior), 0);
    
    size[0] = end[0] - start[0];
    size[1] = end[1] - start[1];
    size[2] = end[2] - start[2];
    region.SetSize( size );
    region.SetIndex( start );
    
    // Generate a mask image of the region just found. Dilate the
    // region defined by the segmentation by r. 
    ImageType::Pointer cropped_mask = ImageType::New(); 
    RegionType mask_region;
    start[0] = start[1] = start[2] = 0;
    mask_region.SetIndex( start );
    mask_region.SetSize( size );
    cropped_mask->SetRegions( mask_region );
    cropped_mask->Allocate();
    cropped_mask->FillBuffer(0);
    LabelConstRegionIteratorType it1( label_image, region);
    RegionIteratorType it2( cropped_mask, mask_region );
    for (it1.GoToBegin(), it2.GoToBegin(); !it1.IsAtEnd(); ++it1, ++it2) {
      if (it1.Get() == label_)
        it2.Set( 255 );
    }
    ImageType::Pointer dilated_mask;
    DilateFilterType::Pointer f_dilate = DilateFilterType::New();
    SubFilterType::Pointer f_sub = SubFilterType::New();
    StructuringElementType  structuringElement;
    structuringElement.SetRadius( dist_exterior );
    structuringElement.CreateStructuringElement();
    f_dilate->SetKernel( structuringElement );
    f_dilate->SetInput(cropped_mask);
    f_sub->SetInput1( f_dilate->GetOutput() );
    f_sub->SetInput2( cropped_mask );
    
    try {
      f_sub->Update();
    }
    catch (itk::ExceptionObject & e) {
      std::cerr << "Exception in SubFilter: " << e << std::endl;
      exit(0);
    }
    dilated_mask = f_sub->GetOutput();
    
    // Sum the signal in the dilated region only
    ConstRegionIteratorType it3( dilated_mask, mask_region );
    ConstRegionIteratorType it4( intensity_image, region);
    for (it3.GoToBegin(), it4.GoToBegin(); !it3.IsAtEnd(); ++it1, ++it3, ++it4) {
      if (it3.Get() > 0) {
        sum_exterior += it4.Get();
        count_exterior ++;
      }
    }
  }
  
  // average the interior and exterior signals
  return (sum_interior+sum_exterior)/float(count_interior+count_exterior);
}