Example #1
0
int main(int argc, char **argv)
{
  get_ngram().read(argc == 2 ? argv[1] : "ngram");
  dic_init();
  warch.load("wordlist");

  int count = 0;
  while (!cin.eof()) {
    if (++count % 200 == 0) cerr << count << endl;
    Lattice l;
    cin >> l;
    WordDAG dag(&l);
    Path p;
    PFS pfs;
    pfs.search(dag,p);
    Segmentation seg;
    if (p.empty() || p.size() <= 2)
      continue;
    seg.resize(p.size()-2);
    copy(p.begin()+1,p.end()-1,seg.begin());
    seg.we = l.we;
    cout << seg << endl;
  }
  return 0;
}
Example #2
0
  KeyDetectionResult KeyFinder::keyOfChromagram(
    Workspace& workspace,
    const Parameters& params
  ) const {

    KeyDetectionResult result;

    // working copy of chromagram
    Chromagram* ch = new Chromagram(*workspace.chroma);
    ch->reduceToOneOctave();

    // get harmonic change signal and segment
    Segmentation segmenter;
    std::vector<unsigned int> segmentBoundaries = segmenter.getSegmentationBoundaries(ch, params);
    segmentBoundaries.push_back(ch->getHops()); // sentinel

    // get key estimates for each segment
    KeyClassifier classifier(
      params.getSimilarityMeasure(),
      params.getToneProfile(),
      params.getOffsetToC(),
      params.getCustomToneProfile()
    );

    std::vector<float> keyWeights(24); // TODO: not ideal using int cast of key_t enum. Hash?

    for (int s = 0; s < (signed) segmentBoundaries.size() - 1; s++) {
      KeyDetectionResultSegment segment;
      segment.firstHop = segmentBoundaries[s];
      segment.lastHop  = segmentBoundaries[s+1] - 1;
      // collapse segment's time dimension
      std::vector<float> segmentChroma(ch->getBands(), 0.0);
      for (unsigned int hop = segment.firstHop; hop <= segment.lastHop; hop++) {
        for (unsigned int band = 0; band < ch->getBands(); band++) {
          float value = ch->getMagnitude(hop, band);
          segmentChroma[band] += value;
          segment.energy += value;
        }
      }
      segment.chromaVector = segmentChroma;
      segment.key = classifier.classify(segmentChroma);
      if (segment.key != SILENCE)
        keyWeights[segment.key] += segment.energy;
      result.segments.push_back(segment);
    }

    delete ch;

    // get global key
    result.globalKeyEstimate = SILENCE;
    float mostCommonKeyWeight = 0.0;
    for (int k = 0; k < (signed)keyWeights.size(); k++) {
      if (keyWeights[k] > mostCommonKeyWeight) {
        mostCommonKeyWeight = keyWeights[k];
        result.globalKeyEstimate = (key_t)k;
      }
    }

    return result;
  }
bool ModelValidator::isValid(const Segmentation& segmentation, bool allowDefaults/* = false*/)
{
	RETURN_IF_UID_NOT_VALID(segmentation.GetSopInstanceUID(), "SOP Instance UID");
	RETURN_IF_UID_NOT_VALID(segmentation.GetSopClassUID(), "SOP Class UID");
	RETURN_IF_UID_NOT_VALID(segmentation.GetReferencedSopInstanceUID(), "Referenced SOP Instance UID");
	if (segmentation.GetImagingObservation() != NULL)
		RETURN_IF_NOT_VALID1(*segmentation.GetImagingObservation(), allowDefaults, "Segmentation's Imaging Observation is invalid");

	return true;
}
void Tools::segmentation()
{
    ImageViewer* iv = getViewer();

    if (!SupportedImageFormat(iv, QList<QImage::Format>() << QImage::Format_Indexed8
                                                          << QImage::Format_RGB32))
        return;

    Segmentation* s = new Segmentation(iv->getImage(), iv);
    s->start();
}
Example #5
0
void WFST::generate_misspelled_words(const vector<uint> &pos,int len,Segmentation &final_seg)
{
	const Lattice &words = *p_words;
	Lattice w;

	w.based_on(words);
	
	// 2. Compute the score, jump to 1. if score is too low (pruning 1)

	// create new (more compact) Lattice structure
	int i,n = words.get_word_count();
	for (i = 0;i < len;i ++) {
		const WordEntryRefs &fmap = words.get_fuzzy_map(pos[i]);
		int ii,nn = fmap.size();
		for (ii = 0;ii < nn;++ii)
			w.add(*fmap[ii]);
	}

	//cerr << w << endl;

	// 4. Create sections
	Sections sects;
	sects.construct(words);

	// 5. Call create_base_segmentation
	//Segmentation base_seg(words.we);
	//create_base_segmentation(words,sects,base_seg);


	// 6. Get the best segmentation of each section,
	// then merge to one big segment.
	n = sects.size();

	uint ii,nn;

	i = ii = 0;
	nn = words.get_word_count();
	
	final_seg.clear();
	while (ii < nn)
		if (i < n && sects[i].start == ii) {
			Segmentation seg;
			sects[i].segment_best(words,seg);
			copy(seg.begin(),
					 seg.end(),
					 back_insert_iterator< Segmentation >(final_seg));
			ii += sects[i].len;
			i ++;
		} else {
			// only word(i,*,0) exists
			final_seg.push_back(words.get_we(ii)[0]->id);
			ii += words.get_we(ii)[0]->len;
		}
}
Example #6
0
int 
main (int argc, char **argv)
{
  bool use_device = false;
  bool use_file = false;
  if (argc >= 2)
    use_device = true;
  if (argc >= 3)
    use_file = true;
  Segmentation s;
  s.run (use_device, use_file);
  return 0;
}
int 
main (int argc, char **argv)
{
  ros::init (argc, argv, "realtime_segmentation");
  ros::NodeHandle nh ("~");

  bool gui = false;
  if (command_line_param (argc, argv, "--gui"))
    gui = true;

  Segmentation s (nh, gui);
  s.run ();
  return 0;
}
long long Geant4SensitiveDetector::getCellID(G4Step* s) {
  StepHandler h(s);
  Geant4VolumeManager volMgr = Geant4Mapping::instance().volumeManager();
  VolumeID            volID  = volMgr.volumeID(h.preTouchable());
  Segmentation        seg    = m_readout.segmentation();
  if ( seg.isValid() )  {
    G4ThreeVector global = 0.5 * ( h.prePosG4()+h.postPosG4());
    G4ThreeVector local  = h.preTouchable()->GetHistory()->GetTopTransform().TransformPoint(global);
    Position loc(local.x()*MM_2_CM, local.y()*MM_2_CM, local.z()*MM_2_CM);
    Position glob(global.x()*MM_2_CM, global.y()*MM_2_CM, global.z()*MM_2_CM);
    VolumeID cID = seg.cellID(loc,glob,volID);
    return cID;
  }
  return volID;
}
 ReturnType Recognizer::getHypseg(Segmentation& seg) {
   if ((decoder == NULL) || (is_recording)) return BAD_STATE;
   seg.clear();
   int32 scoreh=0, sfh=0, efh=0;
   std::string hseg;
   ps_seg_t *itor = ps_seg_iter(decoder, &scoreh);
   while (itor) { 
     SegItem segItem;
     segItem.word = ps_seg_word(itor);
     ps_seg_frames(itor, &sfh, &efh);
     segItem.start = sfh;
     segItem.end = efh;
     seg.push_back(segItem);
     itor = ps_seg_next(itor);
   }
   return SUCCESS;
 }
Example #10
0
int main(int argc, char** argv)
{
	const std::string sourcePath = "IMG_0267.jpg";
	const std::string destPath = "test.bmp";

	// Basic procedure to use the library
	ColorimetricYCbCrAlgorithm1<NumType> algo = ColorimetricYCbCrAlgorithm1<NumType>();

	// Algorithm configuration
	algo.ApplyMedian(true);
	algo.MedianSize(3);
	algo.ApplyGrow(true);
	algo.GrowCount(20);
	algo.GrowSize(3);
	algo.ApplyShrink(true);
	algo.ShrinkCount(22);
	algo.ShrinkSize(3);
	algo.ApplyFixedGrowShrink(false);
	algo.FixedGrowShrinkCount(10);
	algo.FixedGrowShrinkSize(5);
	algo.ApplyRegionClearing(true);

    Segmentation<NumType> segm = Segmentation<NumType>(&algo);
	CImg<bool> *mask = segm.retrieveMask_asBinaryChannel(sourcePath);

	CImg<int> *distMap = segm.retrieveDistanceMapOfMask(*mask);

	CImg<unsigned char> *resImg = distanceMapToRGB(distMap);

	//CImg<int> *resImg = changeBinaryMaskToRGBImage(*mask);

	/*std::vector<BinarySeed> *skinSeeds = segm.retrieveSkinSeedsOfMask(*testImg, true, true, 30, 5);
	std::vector<BinarySeed> *nonSkinSeeds = segm.retrieveNonSkinSeedsOfMask(*testImg, true, true, 30, 5);

	addSeedsToRGBImage(resImg,skinSeeds,nonSkinSeeds);*/

	resImg->save(destPath.c_str());

	delete mask;
	delete resImg;
	delete distMap;

    return 0;
}
Example #11
0
void TonalAnalyser::finalise(TrackInfoObject* tio) {
    if(!m_bCanRun)
        return;

	CLAM::DiscontinuousSegmentation segmentation = m_ce.segmentation();

	Segmentation<QString> segs;

	for (unsigned i=0; i<segmentation.onsets().size(); i++)
	{
		unsigned chordIndex = m_ce.chordIndexes()[i];
		std::string chordName = m_ce.root(chordIndex) + " " + m_ce.mode(chordIndex);
		//segmentation.setLabel(i,chordName);
		segs.addSeg(segmentation.onsets()[i], segmentation.offsets()[i], chordName.c_str());
		//qDebug() << "Got chord " << chordName.c_str() << " at " << segmentation.onsets()[i] << " until " << segmentation.offsets()[i];
	}

	m_ce.clear();

	tio->setChordData(segs);

}
/*******************************************************************
 * Function Name: GetSegments
 * Return Type 	: int
 * Created On	: Jan 1, 2013
 * Created By 	: hrushi
 * Comments		: Gets the Segments of objects
 *******************************************************************/
ContourMap Detect::GetSegments( const ColorImg ProbeImg, const GrayImg BkImg, bool bSaveOutput, const Args& args  )
{

	fs::path iPath = ProbeImg.GetImagePath();

	fs::path OutputPath;

	OutputPath = GiveSegImgPath(iPath, "_seg");

	ContourMap Cnturs;

	for( int K = SLIC_K; K >= 1; K-- )
	{
		try
		{
			Segmentation Segm;
			Cnturs = Segm.GetSegments(ProbeImg, BkImg, OutputPath.string(), bSaveOutput, K, SLIC_M, args );
		}
		catch(int iERR)
		{
			if( iERR == ERR_SLIC )
			{
				cerr << "Calling Slick with K: " << (K - 1) << endl;
				continue;
			}
		}

		break;
	}

	if(bSaveOutput)
	{
		ColorImg Overlay = ProbeImg.Overlay(Cnturs, 1, cv::Scalar(0, 0, 255), args);
		string OverlayWrite  = GiveSegImgPath(iPath, "_Merge").string();
		Overlay.Write( OverlayWrite );
	}

	return Cnturs;
}
Example #13
0
void FireflyOptimizator::computeFirefly(Segmentation ffI, int idx_ffI, int verbose = 3)
{
    if(verbose >=1 ) {
        cout << "------------------------------" << endl;
        cout << "Starting " << idx_ffI << endl;
    }

    double rank1 = ranks[idx_ffI];
    int j = 0,idx_ffJ =0 ;

    vector<Segmentation>::iterator ffJ;


    for( ffJ = population.begin(),idx_ffJ=0; ffJ != population.end();idx_ffJ++,ffJ++) {

        if (idx_ffI == idx_ffJ) {
            j++;
            continue;
        }

        double rank2 = ranks[idx_ffJ];

        if(verbose >=2 )
            cout << "\tComparing " << idx_ffI << " with " << j << " (" << rank1 << " x " << rank2 << " ) ";

        if (rank2 > rank1) {

            double distance = getDistance(ffI, *ffJ);
            double amount = beta * exp(-gamma * distance * distance);

            if(verbose >= 3)
              cout << "  -  Dis: " << distance << " It: " << amount;

            ffI.matrixAdj = ffI.interpolateMatrix(*ffJ, amount);

            j++;

        }
        else
        {  if(verbose >=3 )
             cout<<" - "<<idx_ffI << " greater, no update.";
        }
        //cout<<endl;
    }


}
Example #14
0
double FireflyOptimizator::getDistance(Segmentation pr, Segmentation gt)
{
    double dis = 0.0;


    for(int i=0;i<pr.size;i++) {

        int top = (i-pr.width)<0?-1:i-pr.width;
        int down = (i+pr.width) >= pr.width* pr.height ? -1 : i+pr.width;
        int left = (i-1)<0?-1:i-1;
        int right = (i+1)>= pr.height*pr.width?-1:i+1;


        if (top!=-1)
        {

            dis += abs(pr.findWeight(i, top) - gt.findWeight(i, top));

        }
        if (down!=-1)
        {

            dis += abs(pr.findWeight(i, down) - gt.findWeight(i, down));

        }
        if (right!=-1)
        {

            dis += abs(pr.findWeight(i, right) - gt.findWeight(i, right));

        }
        if (left!=-1) {

            dis += abs(pr.findWeight(i, left) - gt.findWeight(i, left));

        }

    }

    return dis;
}
Example #15
0
void print_area_center(Segmentation& seg, const std::string& name, int label, Image& output) {
  int area; Coordinate center;
  seg.GetCenterAndArea(label, center, area);
  std::cout << name << " is located at " << center.GetX() << ", " << center.GetY() << " with area " << area << std::endl;
  
  Coordinate point(seg.GetLabelTopLeft(label));
  std::vector<int> freeman_code;
  seg.GetFreemanCode(label, point, freeman_code);
  seg.DrawContourFreeman(point, freeman_code, Color::red(), output);

  const float circumference = seg.GetCircumference(freeman_code);
  const float roundness = seg.GetRoundness(area, circumference);
  std::cout << "  Object has roundness of " << roundness << std::endl;
  
  if (rint(roundness) >= 45) {
    std::cout << "  Object is a tree" << std::endl;
  } else if (rint(roundness) >= 16) {
    std::cout << "  Object is a rectangle" << std::endl;
  } else {
    std::cout << "  Object is a circle" << std::endl;
  }
}
Example #16
0
    static long createGearForILD(Detector& description, int /*argc*/, char** /*argv*/) {
      
      std::cout << " **** running plugin createGearForILD ! " <<  std::endl ;
      
      
      // ===========================================================================================
      // global parameters:
      
      double crossing_angle(0.) ;
      try{ crossing_angle = description.constant<double>("ILC_Main_Crossing_Angle") ; } catch(std::runtime_error&e) {std::cerr << " >>>> " << e.what() << std::endl ;} 
      
      
      //========= TPC ==============================================================================
      try{

	DetElement tpcDE = description.detector("TPC") ;
	
	FixedPadSizeTPCData* tpc = tpcDE.extension<FixedPadSizeTPCData>() ;
	
	gear::TPCParametersImpl* gearTPC = new gear::TPCParametersImpl( tpc->driftLength /dd4hep::mm , gear::PadRowLayout2D::POLAR ) ;
	
	gearTPC->setPadLayout( new gear::FixedPadSizeDiskLayout( tpc->rMinReadout/dd4hep::mm , tpc->rMaxReadout/dd4hep::mm, tpc->padHeight/dd4hep::mm,
								 tpc->padWidth/dd4hep::mm , tpc->maxRow, tpc->padGap /dd4hep::mm  ) ) ;
	
	gearTPC->setDoubleVal("tpcInnerRadius", tpc->rMin/dd4hep::mm  )  ; // inner r of support tube
	gearTPC->setDoubleVal("tpcOuterRadius", tpc->rMax/dd4hep::mm  )  ; // outer radius of TPC
	gearTPC->setDoubleVal("tpcInnerWallThickness", tpc->innerWallThickness/dd4hep::mm  )  ;   // thickness of inner shell
	gearTPC->setDoubleVal("tpcOuterWallThickness", tpc->outerWallThickness/dd4hep::mm  )  ;   // thickness of outer shell
	
	tpcDE.addExtension< GearHandle >( new GearHandle( gearTPC, "TPCParameters" ) ) ;

      } catch( std::runtime_error& e ){  
	std::cerr << " >>>> " << e.what() << std::endl ;
      } 

      //========= VXD ==============================================================================
      
      try{
	DetElement vxdDE = description.detector("VXD") ;
	
	ZPlanarData* vxd = vxdDE.extension<ZPlanarData>() ;
	
	//      ZPlanarParametersImpl (int type, double shellInnerRadius, double shellOuterRadius, double shellHalfLength, double shellGap, double shellRadLength)
	int vxdType =  gear::ZPlanarParameters::CMOS ;
	gear::ZPlanarParametersImpl* gearVXD = new gear::ZPlanarParametersImpl( vxdType, vxd->rInnerShell/dd4hep::mm,  vxd->rOuterShell/dd4hep::mm,
										vxd->zHalfShell/dd4hep::mm , vxd->gapShell/dd4hep::mm , 0.  ) ;
	
	for(unsigned i=0,n=vxd->layers.size() ; i<n; ++i){
	  
	  const rec::ZPlanarData::LayerLayout& l = vxd->layers[i] ;
	  
	  // FIXME set rad lengths to 0 -> need to get from dd4hep ....
	  gearVXD->addLayer( l.ladderNumber, l.phi0, 
			     l.distanceSupport/dd4hep::mm,   l.offsetSupport/dd4hep::mm,   l.thicknessSupport/dd4hep::mm,   l.zHalfSupport/dd4hep::mm,   l.widthSupport/dd4hep::mm,   0. , 
			     l.distanceSensitive/dd4hep::mm, l.offsetSensitive/dd4hep::mm, l.thicknessSensitive/dd4hep::mm, l.zHalfSensitive/dd4hep::mm, l.widthSensitive/dd4hep::mm, 0. )  ;
	
	}
	
	GearHandle* handle = new GearHandle( gearVXD, "VXDParameters" )  ;
	
	// quick hack for now: add the one material that is needed by KalDet :  
	//      handle->addMaterial( "VXDSupportMaterial", 2.075865162e+01, 1.039383117e+01, 2.765900000e+02, 1.014262421e+03, 3.341388059e+03)  ; 
	
	// -------- better: get right averaged material from first ladder:  ------------------
	MaterialManager matMgr( Detector::getInstance().world().volume() ) ;
      
	const rec::ZPlanarData::LayerLayout& l = vxd->layers[0] ;
	
	Vector3D a( l.distanceSupport                      , l.phi0 , 0. ,  Vector3D::cylindrical ) ;
	Vector3D b( l.distanceSupport + l.thicknessSupport , l.phi0 , 0. ,  Vector3D::cylindrical ) ;
	
	const MaterialVec& materials = matMgr.materialsBetween( a , b  ) ;
	
	MaterialData mat = ( materials.size() > 1  ? matMgr.createAveragedMaterial( materials ) : materials[0].first  ) ;
	
	// std::cout << " ####### found materials between points : " << a << " and " << b << " : " ;
	// for( unsigned i=0,n=materials.size();i<n;++i){
	// 	std::cout <<  materials[i].first.name() << "[" <<   materials[i].second << "], " ;
	// }
	// std::cout << std::endl ;
	// std::cout << "   averaged material : " << mat << std::endl ;
	
	handle->addMaterial( "VXDSupportMaterial", mat.A(), mat.Z() , mat.density()/(dd4hep::kg/(dd4hep::g*dd4hep::m3)) , mat.radiationLength()/dd4hep::mm , mat.interactionLength()/dd4hep::mm )  ; 
	
	
	vxdDE.addExtension< GearHandle >( handle ) ;

      } catch( std::runtime_error& e ){  
	std::cerr << " >>>> " << e.what() << std::endl ;
      } 

      //========= SIT ==============================================================================
      
      try{ 

	DetElement sitDE = description.detector("SIT") ;
	
	ZPlanarData* sit = sitDE.extension<ZPlanarData>() ;
	
	//      ZPlanarParametersImpl (int type, double shellInnerRadius, double shellOuterRadius, double shellHalfLength, double shellGap, double shellRadLength)
	int sitType =  gear::ZPlanarParameters::CCD ;
	gear::ZPlanarParametersImpl* gearSIT = new gear::ZPlanarParametersImpl( sitType, sit->rInnerShell/dd4hep::mm,  sit->rOuterShell/dd4hep::mm,
										sit->zHalfShell/dd4hep::mm , sit->gapShell/dd4hep::mm , 0.  ) ;
	std::vector<int> n_sensors_per_ladder ;
	
	for(unsigned i=0,n=sit->layers.size() ; i<n; ++i){
	  
	  const rec::ZPlanarData::LayerLayout& l = sit->layers[i] ;
	  
	  // FIXME set rad lengths to 0 -> need to get from dd4hep ....
	  gearSIT->addLayer( l.ladderNumber, l.phi0, 
			     l.distanceSupport/dd4hep::mm,   l.offsetSupport/dd4hep::mm,   l. thicknessSupport/dd4hep::mm,   l.zHalfSupport/dd4hep::mm,   l.widthSupport/dd4hep::mm,   0. , 
			     l.distanceSensitive/dd4hep::mm, l.offsetSensitive/dd4hep::mm, l. thicknessSensitive/dd4hep::mm, l.zHalfSensitive/dd4hep::mm, l.widthSensitive/dd4hep::mm, 0. )  ;
	  
	  
	  n_sensors_per_ladder.push_back( l.sensorsPerLadder);
	}
	
	gearSIT->setDoubleVal("strip_width_mm"  , sit->widthStrip / dd4hep::mm ) ;
	gearSIT->setDoubleVal("strip_length_mm" , sit->lengthStrip/ dd4hep::mm ) ;
	gearSIT->setDoubleVal("strip_pitch_mm"  , sit->pitchStrip / dd4hep::mm ) ;
	gearSIT->setDoubleVal("strip_angle_deg" , sit->angleStrip / dd4hep::deg ) ;
	
	
	gearSIT->setIntVals("n_sensors_per_ladder",n_sensors_per_ladder);
	
	sitDE.addExtension< GearHandle >( new GearHandle( gearSIT, "SITParameters" ) ) ;

      } catch( std::runtime_error& e ){ 
	std::cerr << " >>>> " << e.what() << std::endl ;
      } 

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

      try {

	DetElement setDE = description.detector("SET") ;
	
	ZPlanarData* set = setDE.extension<ZPlanarData>() ;
	
	//      ZPlanarParametersImpl (int type, double shellInnerRadius, double shellOuterRadius, double shellHalfLength, double shellGap, double shellRadLength)
	int setType =  gear::ZPlanarParameters::CCD ;
	gear::ZPlanarParametersImpl* gearSET = new gear::ZPlanarParametersImpl( setType, set->rInnerShell/dd4hep::mm,  set->rOuterShell/dd4hep::mm,
										set->zHalfShell/dd4hep::mm , set->gapShell/dd4hep::mm , 0.  ) ;
	std::vector<int> n_sensors_per_ladder ;
	//n_sensors_per_ladder.clear() ;
	
	for(unsigned i=0,n=set->layers.size() ; i<n; ++i){
	  
	  const rec::ZPlanarData::LayerLayout& l = set->layers[i] ;
	  
	  // FIXME set rad lengths to 0 -> need to get from dd4hep ....
	  gearSET->addLayer( l.ladderNumber, l.phi0, 
			     l.distanceSupport/dd4hep::mm,   l.offsetSupport/dd4hep::mm,   l. thicknessSupport/dd4hep::mm,   l.zHalfSupport/dd4hep::mm,   l.widthSupport/dd4hep::mm,   0. , 
			     l.distanceSensitive/dd4hep::mm, l.offsetSensitive/dd4hep::mm, l. thicknessSensitive/dd4hep::mm, l.zHalfSensitive/dd4hep::mm, l.widthSensitive/dd4hep::mm, 0. )  ;
	  
	  
	  n_sensors_per_ladder.push_back( l.sensorsPerLadder);
	}
	
	gearSET->setDoubleVal("strip_width_mm"  , set->widthStrip / dd4hep::mm ) ;
	gearSET->setDoubleVal("strip_length_mm" , set->lengthStrip/ dd4hep::mm ) ;
	gearSET->setDoubleVal("strip_pitch_mm"  , set->pitchStrip / dd4hep::mm ) ;
	gearSET->setDoubleVal("strip_angle_deg" , set->angleStrip / dd4hep::deg ) ;

	
	gearSET->setIntVals("n_sensors_per_ladder",n_sensors_per_ladder);
	
	setDE.addExtension< GearHandle >( new GearHandle( gearSET, "SETParameters" ) ) ;

      } catch( std::runtime_error& e ){  
	std::cerr << " >>>> " << e.what() << std::endl ;
      } 
      
      //============================================================================================

      try {

	DetElement ftdDE = description.detector("FTD") ;
	
	ZDiskPetalsData* ftd = ftdDE.extension<ZDiskPetalsData>() ;
	
	gear::FTDParametersImpl* gearFTD = new gear::FTDParametersImpl();
	
	for(unsigned i=0,n=ftd->layers.size() ; i<n; ++i){
	  
	  const rec::ZDiskPetalsData::LayerLayout& l = ftd->layers[i] ;
	  
	  
	  bool isDoubleSided  = l.typeFlags[ rec::ZDiskPetalsStruct::SensorType::DoubleSided ] ;
	  
	  // avoid 'undefined reference' at link time ( if built w/o optimization ):
	  static const int PIXEL = gear::FTDParameters::PIXEL ;
	  static const int STRIP = gear::FTDParameters::STRIP ;
	  int  sensorType   = ( l.typeFlags[ rec::ZDiskPetalsStruct::SensorType::Pixel ] ? PIXEL : STRIP ) ;
	  //			      gear::FTDParameters::PIXEL :  gear::FTDParameters::STRIP ) ;
	  
	  double zoffset = fabs( l.zOffsetSupport ) ;
	  double signoffset =  l.zOffsetSupport > 0  ?  1. : -1 ;
	  
	  gearFTD->addLayer( l.petalNumber, l.sensorsPerPetal, 
			     isDoubleSided, sensorType, 
			     l.petalHalfAngle, l.phi0, l.alphaPetal, 
			     l.zPosition/dd4hep::mm, zoffset/dd4hep::mm, signoffset,
			     l.distanceSupport/dd4hep::mm, l.thicknessSupport/dd4hep::mm,
			     l.widthInnerSupport/dd4hep::mm, l.widthOuterSupport/dd4hep::mm,
			     l.lengthSupport/dd4hep::mm, 
			     0.,
			     l.distanceSensitive/dd4hep::mm, l.thicknessSensitive/dd4hep::mm,
			     l.widthInnerSensitive/dd4hep::mm, l.widthOuterSensitive/dd4hep::mm,
			     l.lengthSensitive/dd4hep::mm, 
			     0. ) ;
	  
	  
	  // FIXME set rad lengths to 0 -> need to get from dd4hep ....
	}
	
	gearFTD->setDoubleVal("strip_width_mm"  , ftd->widthStrip / dd4hep::mm ) ;
	gearFTD->setDoubleVal("strip_length_mm" , ftd->lengthStrip/ dd4hep::mm ) ;
	gearFTD->setDoubleVal("strip_pitch_mm"  , ftd->pitchStrip / dd4hep::mm ) ;
	gearFTD->setDoubleVal("strip_angle_deg" , ftd->angleStrip / dd4hep::deg ) ;
	
	
	ftdDE.addExtension< GearHandle >( new GearHandle( gearFTD, "FTDParameters" ) ) ;

      } catch( std::runtime_error& e ){  
	std::cerr << " >>>> " << e.what() << std::endl ;
      } 

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

      try {
	
	DetElement coilDE = description.detector("Coil") ;
	
	gear::GearParametersImpl* gearCOIL = new gear::GearParametersImpl();
	
	Tube coilTube = Tube( coilDE.volume().solid() )  ;
	
	gearCOIL->setDoubleVal("Coil_cryostat_inner_radius" , coilTube->GetRmin()/ dd4hep::mm ) ;
	gearCOIL->setDoubleVal("Coil_cryostat_outer_radius" , coilTube->GetRmax()/ dd4hep::mm ) ;
	gearCOIL->setDoubleVal("Coil_cryostat_half_z"       , coilTube->GetDZ()/ dd4hep::mm ) ;
	
	coilDE.addExtension< GearHandle >( new GearHandle( gearCOIL, "CoilParameters" ) ) ;
      
      } catch( std::runtime_error& e ){  
	std::cerr << " >>>> " << e.what() << std::endl ;
      } 

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

      try {

	DetElement tubeDE = description.detector("Tube") ;
	
	ConicalSupportData* tube = tubeDE.extension<ConicalSupportData>() ;
	
	gear::GearParametersImpl* gearTUBE = new gear::GearParametersImpl();
	
	tube->isSymmetricInZ = true ;
	
	unsigned n = tube->sections.size() ;
	
	std::vector<double> rInner(n) ;
	std::vector<double> rOuter(n) ;
	std::vector<double> zStart(n) ;
	
	for(unsigned i=0 ; i<n ; ++i){
	  
	  const ConicalSupportData::Section& s = tube->sections[i] ;
	  
	  rInner[i] = s.rInner/ dd4hep::mm  ; 
	  rOuter[i] = s.rOuter/ dd4hep::mm  ; 
	  zStart[i] = s.zPos  / dd4hep::mm  ; 
	  
	  // FIXME set rad lengths to 0 -> need to get from dd4hep ....
	}
	
	gearTUBE->setDoubleVals("RInner" , rInner ) ;
	gearTUBE->setDoubleVals("ROuter" , rOuter ) ;
	gearTUBE->setDoubleVals("Z"      , zStart ) ;
	
	
	tubeDE.addExtension< GearHandle >( new GearHandle( gearTUBE, "BeamPipe" ) ) ;
      
      } catch( std::runtime_error& e ){  
	std::cerr << " >>>> " << e.what() << std::endl ;
      } 

      //========= CALO ==============================================================================

      //**********************************************************
      //*  gear interface w/ LayeredCalorimeterData extension
      //**********************************************************

      std::map< std::string, std::string > caloMap ;
      caloMap["HcalBarrel"] = "HcalBarrelParameters"  ; 
      caloMap["EcalBarrel"] = "EcalBarrelParameters" ;
      caloMap["EcalEndcap"] = "EcalEndcapParameters" ;
      caloMap["EcalPlug"]   = "EcalPlugParameters" ;
      caloMap["YokeBarrel"] = "YokeBarrelParameters" ;
      caloMap["YokeEndcap"] = "YokeEndcapParameters" ;
      caloMap["YokePlug"]   = "YokePlugParameters" ;
      caloMap["HcalBarrel"] = "HcalBarrelParameters" ;
      caloMap["HcalEndcap"] = "HcalEndcapParameters" ;
      caloMap["HcalRing"]   = "HcalRingParameters" ;
      caloMap["Lcal"]	    = "LcalParameters" ;
      caloMap["LHcal"]	    = "LHcalParameters" ;
      caloMap["BeamCal"]    = "BeamCalParameters" ;
      
      for(  std::map< std::string, std::string >::const_iterator it = caloMap.begin() ; it != caloMap.end() ; ++it ){

      

	try {

	  DetElement caloDE = description.detector( it->first ) ;
	
	  LayeredCalorimeterData* calo = caloDE.extension<LayeredCalorimeterData>() ;
	  
	  gear::CalorimeterParametersImpl* gearCalo = 
	    ( calo->layoutType == LayeredCalorimeterData::BarrelLayout  ?
	      new gear::CalorimeterParametersImpl(  calo->extent[0]/dd4hep::mm, calo->extent[3]/dd4hep::mm, calo->inner_symmetry, calo->phi0 )  :
	      //CalorimeterParametersImpl (double rMin, double zMax, int symOrder=8, double phi0=0.0) - C'tor for a cylindrical (octagonal) BARREL calorimeter.
	      new gear::CalorimeterParametersImpl(  calo->extent[0]/dd4hep::mm,  calo->extent[1]/dd4hep::mm,  calo->extent[2]/dd4hep::mm, calo->outer_symmetry, calo->phi0 )   ) ;
	  //CalorimeterParametersImpl (double rMin, double rMax, double zMin, int symOrder=2, double phi0=0.0) - C'tor for a cylindrical (octagonal) ENDCAP calorimeter. 
	  
	  for( unsigned i=0, nL = calo->layers.size() ; i <nL ; ++i ){
	    
	    LayeredCalorimeterData::Layer& l = calo->layers[i] ;
	    
            //Do some arithmetic to get thicknesses and (approximate) absorber thickneses from "new" rec structures
            //The positioning should come out right, but the absorber thickness should be overestimated due to the presence of 
            //other less dense material
	    if( i == 0 ) {
	      gearCalo->layerLayout().positionLayer( l.distance/dd4hep::mm, 
						     (l.inner_thickness+l.sensitive_thickness/2.)/dd4hep::mm , 
						     l.cellSize0/dd4hep::mm, l.cellSize1/dd4hep::mm, 
						     (l.inner_thickness-l.sensitive_thickness/2.)/dd4hep::mm ) ;
	    }else{
	      gearCalo->layerLayout().addLayer( (l.inner_thickness+l.sensitive_thickness/2.+calo->layers[i-1].outer_thickness-calo->layers[i-1].sensitive_thickness/2. ) / dd4hep::mm , 
						l.cellSize0/dd4hep::mm, l.cellSize1/dd4hep::mm, (l.inner_thickness-l.sensitive_thickness/2.+calo->layers[i-1].outer_thickness-calo->layers[i-1].sensitive_thickness/2.)/dd4hep::mm) ;
	    }
	    // if( i == 0 ) {
	    //   gearCalo->layerLayout().positionLayer( l.distance/dd4hep::mm, l.thickness/dd4hep::mm , 
	    // 					     l.cellSize0/dd4hep::mm, l.cellSize1/dd4hep::mm, l.absorberThickness/dd4hep::mm ) ;
	    // }else{
	    //   gearCalo->layerLayout().addLayer(                             l.thickness/dd4hep::mm , 
	    // 								    l.cellSize0/dd4hep::mm, l.cellSize1/dd4hep::mm, l.absorberThickness/dd4hep::mm ) ;
	    // }
	    
	  }
	
	  if( it->first == "HcalBarrel" ){
	    // additional parameters needed by MarlinPandora
	    gearCalo->setIntVal("Hcal_outer_polygon_order"   ,  calo->outer_symmetry  ) ;
	    gearCalo->setDoubleVal("Hcal_outer_polygon_phi0" ,  calo->phi0 ) ;
	  }
		  
	  if( it->first == "BeamCal" ){

	    try{
	      // additional parameters needed by BCalReco
	      
	      SensitiveDetector sD = description.sensitiveDetector( it->first   )   ;
	      Readout readOut = sD.readout() ;
	      Segmentation seg = readOut.segmentation() ;
	      
	      //	    DDSegmentation::DoubleVecParameter rPar =  dynamic_cast<DDSegmentation::DoubleVecParameter>( seg.parameter("grid_r_values"));
	      DDSegmentation::DoubleVecParameter pPar =  dynamic_cast<DDSegmentation::DoubleVecParameter>( seg.parameter("grid_phi_values"));
	      DDSegmentation::DoubleParameter    oPPar=  dynamic_cast<DDSegmentation::DoubleParameter>(    seg.parameter("offset_phi"));
	      

	      //offset_phi="-180*degree+(360*degree-BCal_SpanningPhi)*0.5"
	      double offsetPhi   = oPPar->typedValue() ;
	      double spanningPhi = 360.*dd4hep::deg - 2.*( offsetPhi + 180.*dd4hep::deg ) ;  

	      gearCalo->setDoubleVals( "phi_segmentation"     , pPar->typedValue()  );
	      gearCalo->setDoubleVal(  "cylinder_starting_phi", offsetPhi  );
	      gearCalo->setDoubleVal(  "cylinder_spanning_phi", spanningPhi );
	      gearCalo->setDoubleVal(  "beam_crossing_angle"  , crossing_angle );

	      //fixme: don't know how to get these parameters at this stage ...
	      //       probably need a named parameter object at every DetElement  ....
	      gearCalo->setDoubleVal(  "dead_area_outer_r"       ,   0 );
	      gearCalo->setDoubleVal(  "pairsMonitorZ"           ,   0. );
	      gearCalo->setDoubleVal(  "FIXME_dead_area_outer_r" ,  -1. );
	      gearCalo->setDoubleVal(  "FIXME_pairsMonitorZ"     ,  -1. );
	    
	    } catch( std::runtime_error& e ){  
	      std::cerr << " >>>> BeamCal: " << e.what() << std::endl ;
	    }
	  }

	  if( it->first == "Lcal" ||  it->first == "LHcal" ){
	    gearCalo->setDoubleVal(  "beam_crossing_angle"  , crossing_angle );
	  }

	  caloDE.addExtension< GearHandle >( new GearHandle( gearCalo, it->second ) ) ;
	  
	} catch( std::runtime_error& e ){  
	  std::cerr << " >>>> " << e.what() << std::endl ;
	} 

      } // calo loop 



      //**********************************************************
      //*  test gear interface w/ LayeredExtensionImpl extension
      //**********************************************************
      
      // DetElement calo2DE = description.detector("EcalBarrel") ;
      
      // Calorimeter calo2( calo2DE ) ;
      
      // gear::CalorimeterParametersImpl* gearCalo2 = 
      // 	( calo2.isBarrel()  ?
      // 	  new gear::CalorimeterParametersImpl(  calo2.getRMin()/dd4hep::mm,                             calo2.getZMax()/dd4hep::mm, calo2.getNSides(),  0. )  :    // fixme: phi 0  is not defined ??
      // 	  new gear::CalorimeterParametersImpl(  calo2.getRMin()/dd4hep::mm, calo2.getRMax()/dd4hep::mm, calo2.getZMin()/dd4hep::mm, calo2.getNSides(),  0. ) 
      // 	  ) ;

      // for( unsigned i=0, nL = calo2.numberOfLayers() ; i <nL ; ++i ){
	    
      // 	if( i == 0 ) {
      // 	  gearCalo2->layerLayout().positionLayer( calo2.getRMin()/dd4hep::mm, calo2.thickness(i)/dd4hep::mm ,  0. /dd4hep::mm,   0. /dd4hep::mm, calo2.absorberThickness(i)/dd4hep::mm ) ;

      // 	}else{                                                                                        //     fixme:   cell sizes  not in API !? 

      // 	  gearCalo2->layerLayout().addLayer(                                  calo2.thickness(i)/dd4hep::mm ,  0. /dd4hep::mm,   0. /dd4hep::mm, calo2.absorberThickness(i)/dd4hep::mm ) ;
      // 	}


      // }

      // calo2DE.addExtension< GearHandle >( new GearHandle( gearCalo2, "EcalBarrelParameters" ) ) ;


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



      // --- Detector::apply() expects return code 1 if all went well ! ----
      return 1;
    }
Example #17
0
    /**
     * @brief execute
     * @param imgIn
     * @param imgOut
     * @return
     */
    Image *execute(Image *imgIn, Image *imgOut)
    {
        if(imgIn == NULL) {
            return NULL;
        }

        if(!imgIn->isValid()) {
            return NULL;
        }

        if(imgOut == NULL) {
            imgOut = new Image(1, imgIn->width, imgIn->height, imgIn->channels);
        }

        //compute segmentation map
        seg_map = seg.Process(imgIn, seg_map);

        /*	0 ---> Drago et al. 2003
        	1 ---> Reinhard et al. 2002
        	LumZone     = [-2, -1, 0, 1, 2, 3, 4];
        	TMOForZone =  [ 0,  0, 1, 0, 1, 0, 0];	*/

        int count[2];
        count[0] = 0;
        count[1] = 0;

        for(int i = 0; i < seg_map->size(); i++) {
            int indx = int(seg_map->data[i]);

            if((indx == 2) || (indx == 4)) {
                seg_map->data[i] = 1.0f;
                count[1]++;
            } else {
                seg_map->data[i] = 0.0f;
                count[0]++;
            }
        }

#ifdef PIC_DEBUG
        seg_map->Write("weight_map.pfm");
#endif

        //check if we have different zones
        int value = 10;

        if(count[0] > 0 && count[1] > 0) {
            value = 10;
        }

        if(count[0] > 0 && count[1] == 0) {
            value = 0;
        }

        if(count[0] == 0 && count[1] > 0) {
            value = 1;
        }

        switch(value) {
        case 0: {
            fltDragoTMO.Process(Single(imgIn), imgOut);
        }
        break;

        case 1: {
            fltReinhardTMO.Process(Single(imgIn), imgOut);
        }
        break;

        case 10: {
            //Drago TMO
            imgDrago = fltDragoTMO.Process(Single(imgIn), imgDrago);

            if(pyrA == NULL) {
                pyrA = new Pyramid(imgDrago, true);
            } else {
                pyrA->update(imgDrago);
            }

            //Reinhard TMO
            imgReinhard = fltReinhardTMO.Process(Single(imgIn), imgReinhard);

            if(pyrB == NULL) {
                pyrB = new Pyramid(imgReinhard, true);
            } else {
                pyrB->update(imgReinhard);
            }

            //compute blending weight
            if(pyrWeight == NULL) {
                pyrWeight = new Pyramid(seg_map, false);
            } else {
                pyrWeight->update(seg_map);
            }

            //blend
            pyrA->blend(pyrB, pyrWeight);
            pyrA->reconstruct(imgOut);
        }
        break;
        }

        return imgOut;
    }
Example #18
0
int main(int argc, char** argv) 
{
	pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZRGBA>);
	pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloudFiltered (new pcl::PointCloud<pcl::PointXYZRGBA>);
	
	int k=atoi(argv[1]);
	double min_mah_dist=atof(argv[2]);
	int max_gauss=atoi(argv[3]);
	
	std::vector <Gauss> gaussians_learned;

	pcl::PCDReader reader;
	reader.read (argv[4], *cloud); 
	
	pcl::console::TicToc timer;
	
	timer.tic();
	
	// Filtering
	Filtering filtering;
	cloudFiltered=filtering.filter(cloud);
	
	// Segmentation
	Segmentation segmentation;
	std::vector <Surface> surfaces=segmentation.segment (cloudFiltered);
	
	// Colour extraction from point cloud
	ExtractColour extractcolour;
	cv::Mat samples=extractcolour.pcd2colourRGB(surfaces[0].segmented_cloud);
	
	// Point cloud analysis
	ColourAnalysis colouranalysis;
	std::vector <Gauss> gaussians = colouranalysis.analyzeColourCluster(k, surfaces[0].segmented_cloud, surfaces[0].b, surfaces[0].d, samples);
	
	// Learning
	Learning learning;
	gaussians_learned=learning.learnGaussians(gaussians, gaussians_learned, max_gauss);
	
	// ROI
	ROI roi;
	std::vector<Line> lines=roi.roi(surfaces);
	std::vector<int> index=roi.extractIndex(lines);
	
	// Colour extraction from image
	std::vector<Matrix_double> colours=extractcolour.indexPCD2VectorRGB(*cloud, index);
	
	// Image analysis
	std::vector <int> pixels_labeled=colouranalysis.labelIndex(colours, k, gaussians_learned, min_mah_dist);
	
	// Map reconstruction
	Map map;
	std::vector<Matrix_double> distancesLabeled=map.mapDistances(index, surfaces[0].a ,surfaces[0].b, surfaces[0].c, surfaces[0].d);
	
	std::cout << "Part 1 finished" << std::endl;
	timer.toc_print();
	
	timer.tic();
	// Generate image
	cv::Mat environment=extractcolour.pcd2image(*cloud);
	
	// Calcule begin and end points for a line
	std::vector <LinePoint> linePoints=roi.calculeLinePoints(lines);
	
	// Draw lines
	Visualize visualize;
	environment=visualize.drawLines (environment, linePoints, "green");
	
	// Print floor
	std::vector<int> pixels=colouranalysis.labelPixel(pixels_labeled, index, colours);
	environment=visualize.drawFloor (pixels, environment, "cyan");
	
	std::vector <int> kinectIndex=roi.extractFloorIdx(surfaces[0].a, surfaces[0].b, surfaces[0].c, surfaces[0].d, cloud);
	environment=visualize.drawFloor (kinectIndex, environment, "blue");
	
	// Reconstruct kinect floor
	std::vector <int> kinect (kinectIndex.size(), 1);
	std::vector<Matrix_double> distancesKinect=map.mapDistances(kinectIndex, surfaces[0].a ,surfaces[0].b, surfaces[0].c, surfaces[0].d);
    pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloudEnhanced=map.mapEnhance(distancesLabeled, index, cloud, pixels_labeled, surfaces[0].a ,surfaces[0].b, surfaces[0].c, surfaces[0].d);
	
	// Generate map reconstruction image
	cv::Mat map_reconstruction(cv::Size(400,650),CV_8UC3);
	map_reconstruction=cv::Scalar(0,0,0);
	map_reconstruction=visualize.mapGeneration(map_reconstruction, pixels_labeled, distancesLabeled, "blue", "white");
	map_reconstruction=visualize.mapGeneration(map_reconstruction, kinect, distancesKinect, "red", "yellow");
	
	// Show images on a window
	std::string name_window="Floor window";
    visualize.visualizeImage (environment, name_window);
	name_window="Map window";
    visualize.visualizeImage (map_reconstruction, name_window);
    visualize.visualizeCloud(cloudEnhanced, "Cloud");
	
	// Save images
	Save save;
	char name[50]="map.png";
	save.saveImage(map_reconstruction, name);
	char name2[50]="environment.png";
	save.saveImage(environment, name2);
	
	// Save cloud
	std::string names= "cloud.pcd";
	save.saveCloud(surfaces[0].segmented_cloud, names);
		
	std::cout << "Part 2 finished" << std::endl;
	timer.toc_print();
	cv::waitKey();
	
	return 0;
}
void defaultExecution(SysEnv &sysEnv, std::string &metricType, RegionTemplateCollection *rtCollection,
                      std::string tuningPolicy,
                      float *perf, float *totaldiffs, float *metricPerIteration,
                      float *diceNotCoolPerIteration,
                      uint64_t *totalexecutiontimes) {
    int versionNorm = 0, versionSeg = 0;
    int segCount = 0;
    std::vector<int> segComponentIds[rtCollection->getNumRTs()];
    std::vector<int> metricComponentIds[rtCollection->getNumRTs()];
    std::vector<int> diceNotCoolComponentIds[rtCollection->getNumRTs()];
    // Build application dependency graph
    // Instantiate application dependency graph
    for (int i = 0; i < rtCollection->getNumRTs(); i++) {

        int previousSegCompId = 0;
        // CREATE NORMALIZATION STEP
        ParameterSet parSetNormalization;
        std::vector<ArgumentBase *> targetMeanOptions;
        ArgumentFloatArray *targetMeanAux = new ArgumentFloatArray(ArgumentFloat(-0.632356));
        targetMeanAux->addArgValue(ArgumentFloat(-0.0516004));
        targetMeanAux->addArgValue(ArgumentFloat(0.0376543));
        targetMeanOptions.push_back(targetMeanAux);
        parSetNormalization.addArguments(targetMeanOptions);
        parSetNormalization.resetIterator();
        std::vector<ArgumentBase *> argSetInstanceNorm = parSetNormalization.getNextArgumentSetInstance();
        NormalizationComp *norm = new NormalizationComp();
        // normalization parameters
        norm->addArgument(new ArgumentInt(versionNorm));
        norm->addArgument(argSetInstanceNorm[0]);
        norm->addRegionTemplateInstance(rtCollection->getRT(i), rtCollection->getRT(i)->getName());
        sysEnv.executeComponent(norm);


        std::cout << "BEGIN: Default Execution: ";


        std::cout << std::endl;

        // Creating segmentation component
        Segmentation *seg = new Segmentation();

        // version of the data region red. Each parameter instance in norm creates a output w/ different version
        seg->addArgument(new ArgumentInt(versionNorm));
        // version of the data region generated by the segmentation stage
        seg->addArgument(new ArgumentInt(versionSeg));


        int blue = 220;
        int green = 220;
        int red = 220;
        float T1 = 5.0;
        float T2 = 4.0;
        int G1 = 80;
        int minSize = 11;
        int maxSize = 1000;
        int G2 = 45;
        int minSizePl = 30;
        int minSizeSeg = 21;
        int maxSizeSeg = 1000;
        int fillHolesConnectivity = 4;
        int reconConnectivity = 8;
        int watershedConnectivity = 8;

        // add remaining (application specific) parameters from the argSegInstance
        seg->addArgument(new ArgumentInt(
                (int) round(blue)));
        seg->addArgument(new ArgumentInt(
                (int) round(green)));
        seg->addArgument(new ArgumentInt(
                (int) round(red)));
        seg->addArgument(
                new ArgumentFloat((float) (T1)));
        seg->addArgument(
                new ArgumentFloat((float) (T2)));
        seg->addArgument(new ArgumentInt(
                (int) round(G1)));
        seg->addArgument(new ArgumentInt(
                (int) round(G2)));
        seg->addArgument(new ArgumentInt(
                (int) round(minSize)));
        seg->addArgument(new ArgumentInt(
                (int) round(maxSize)));
        seg->addArgument(new ArgumentInt(
                (int) round(minSizePl)));
        seg->addArgument(new ArgumentInt(
                (int) round(minSizeSeg)));
        seg->addArgument(new ArgumentInt(
                (int) round(maxSizeSeg)));
        seg->addArgument(new ArgumentInt(
                (int) round(fillHolesConnectivity)));
        seg->addArgument(new ArgumentInt(
                (int) round(reconConnectivity)));
        seg->addArgument(new ArgumentInt(
                (int) round(watershedConnectivity)));


        // and region template instance that it is suppose to process
        seg->addRegionTemplateInstance(rtCollection->getRT(i), rtCollection->getRT(i)->getName());
        seg->addDependency(norm->getId());

        std::cout << "Creating DiffMask" << std::endl;

        RTPipelineComponentBase *metricComp;
        DiceNotCoolMaskComp *diceNotCoolComp;

        if (metricType.find("jaccard") != std::string::npos) metricComp = new JaccardMaskComp();
        else metricComp = new DiceMaskComp();

        if (metricType.find("dicenc") != std::string::npos) diceNotCoolComp = new DiceNotCoolMaskComp();

        // version of the data region that will be read. It is created during the segmentation.
        // region template name
        metricComp->addArgument(new ArgumentInt(versionSeg));
        metricComp->addRegionTemplateInstance(rtCollection->getRT(i), rtCollection->getRT(i)->getName());
        metricComp->addDependency(seg->getId());


        // add to the list of diff component ids.
        segComponentIds[i].push_back(seg->getId());
        metricComponentIds[i].push_back(metricComp->getId());


        sysEnv.executeComponent(seg);
        sysEnv.executeComponent(metricComp);

        if (metricType.find("dicenc") != std::string::npos) {
            diceNotCoolComp->addArgument(new ArgumentInt(versionSeg));
            diceNotCoolComp->addRegionTemplateInstance(rtCollection->getRT(i),
                                                       rtCollection->getRT(i)->getName());
            diceNotCoolComp->addDependency(metricComp->getId());
            diceNotCoolComponentIds[i].push_back(diceNotCoolComp->getId());
            sysEnv.executeComponent(diceNotCoolComp);
        }


        std::cout << "Manager CompId: " << metricComp->getId() << " fileName: " <<
        rtCollection->getRT(i)->getDataRegion(0)->getInputFileName() << std::endl;
        segCount++;
        versionSeg++;


        versionNorm++;
    }



    // End Creating Dependency Graph
    sysEnv.startupExecution();

    std::cout << std::endl << std::endl;
    //==============================================================================================
    //Fetch results from execution workflow
    //==============================================================================================
    for (int j = 0; j < rtCollection->getNumRTs(); j++) {
        float metric = 0;
        float secondaryMetric = 0;
        float diceNotCoolValue = 0;

        std::ostringstream oss;
        oss << " Default PARAMS";


        for (int i = 0; i < metricComponentIds[j].size(); i++) {
            char *metricResultData = sysEnv.getComponentResultData(metricComponentIds[j][i]);
            std::cout << "RT name: " << rtCollection->getRT(j)->getDataRegion("RAW")->getInputFileName() <<
            " - Diff Id: " << metricComponentIds[j][i];
            if (metricResultData != NULL) {
                //std::cout << "size: " << ((int *) metricResultData)[0] << " \thadoopgis-metric: " <<
                //((float *) metricResultData)[1] <<
                //" \tsecondary: " << ((float *) metricResultData)[2] << endl;

                metric += ((float *) metricResultData)[1];
                secondaryMetric += ((float *) metricResultData)[2];

                if (metricType.find("dicenc") != std::string::npos) {
                    char *diceNotCoolResultData = sysEnv.getComponentResultData(diceNotCoolComponentIds[j][i]);
//                        std::cout << " \tdiceNotCool: " <<
//                        ((float *) diceNotCoolResultData)[1] << std::endl;
                    diceNotCoolValue += ((float *) diceNotCoolResultData)[1];
                }

            } else {
                std::cout << "NULL" << std::endl;
            }
            char *segExecutionTime = sysEnv.getComponentResultData(segComponentIds[j][i]);
            if (segExecutionTime != NULL) {
                totalexecutiontimes[j] = ((int *) segExecutionTime)[1];
//                    cout << "Segmentation execution time:" <<
//                    totalexecutiontimes[j] << endl;
            }
            if (metricType.find("dicenc") != std::string::npos)
                sysEnv.eraseResultData(diceNotCoolComponentIds[j][i]);
            sysEnv.eraseResultData(metricComponentIds[j][i]);
            sysEnv.eraseResultData(segComponentIds[j][i]);
        }
        metricComponentIds[j].clear();
        segComponentIds[j].clear();
        if (metricType.find("dicenc") != std::string::npos) diceNotCoolComponentIds[j].clear();


        float diff;

        if (metricType.find("dicenc") != std::string::npos) diff = (metric + diceNotCoolValue) / 2;
        else diff = metric;

        if (diff <= 0) diff = FLT_EPSILON;


        cout << "\tDiff (average of metric and dnc): " << diff << "\tMetric:" << metric << "\tDNC:" <<
        diceNotCoolValue << " Segmentation Time: " <<
        totalexecutiontimes[j] << endl;

        totaldiffs[j] = diff;
        metricPerIteration[j] = metric;
        diceNotCoolPerIteration[j] = diceNotCoolValue;

    }

    std::cout << std::endl << std::endl;




}
void test_crosschannelregistration(UnitTest &ut) {

  ut.begin_test_set("CrossChannelRegistration");

  Segmentation<uint16> segmenter;

  EuclideanDistanceMap<uint16> edm;
  Watershed<uint16> wat;
  Invert<uint16> inv;
  NWThreshold<uint16> nwt(5,0.5,60000,NWThreshold<uint16>::mask_type_square);//0.75 beautiful

  SwiftImage<uint16> c1a_i1("./Images/smallfake2/c1_a.tif");
  cout << "Load complete" << endl;
  SwiftImage<uint16> c1a_i2 = nwt.process(c1a_i1);
  cout << "Thresholding complete" << endl;
  SwiftImage<uint16> c1a_i3 = edm.process(c1a_i2);
  cout << "EDM complete" << endl;
  SwiftImage<uint16> c1a_i4 = inv.process(c1a_i3);
  cout << "INV complete" << endl;
  SwiftImage<uint16> c1a_i5 = wat.process(c1a_i4);
  cout << "Wat complete" << endl;
  SwiftImage<uint16> c1a_i6 = c1a_i2 && c1a_i5;
  vector<SwiftImageObject<> > c1a_objs1 = segmenter.process(c1a_i6);
  
  SwiftImage<uint16> c2a_i1("./Images/smallfake2/c2_a.tif");
  cout << "Load complete" << endl;
  SwiftImage<uint16> c2a_i2 = nwt.process(c2a_i1);
  cout << "Thresholding complete" << endl;
  SwiftImage<uint16> c2a_i3 = edm.process(c2a_i2);
  cout << "EDM complete" << endl;
  SwiftImage<uint16> c2a_i4 = inv.process(c2a_i3);
  cout << "INV complete" << endl;
  SwiftImage<uint16> c2a_i5 = wat.process(c2a_i4);
  cout << "Wat complete" << endl;
  SwiftImage<uint16> c2a_i6 = c2a_i2 && c2a_i5;
  vector<SwiftImageObject<> > c2a_objs1 = segmenter.process(c2a_i6);
  
  SwiftImage<uint16> c1t_i1("./Images/smallfake2/c1_t.tif");
  cout << "Load complete" << endl;
  SwiftImage<uint16> c1t_i2 = nwt.process(c1t_i1);
  cout << "Thresholding complete" << endl;
  SwiftImage<uint16> c1t_i3 = edm.process(c1t_i2);
  cout << "EDM complete" << endl;
  SwiftImage<uint16> c1t_i4 = inv.process(c1t_i3);
  cout << "INV complete" << endl;
  SwiftImage<uint16> c1t_i5 = wat.process(c1t_i4);
  cout << "Wat complete" << endl;
  SwiftImage<uint16> c1t_i6 = c1t_i2 && c1t_i5;
  vector<SwiftImageObject<> > c1t_objs1 = segmenter.process(c1t_i6);
  
  SwiftImage<uint16> c2t_i1("./Images/smallfake2/c2_t.tif");
  cout << "Load complete" << endl;
  SwiftImage<uint16> c2t_i2 = nwt.process(c2t_i1);
  cout << "Thresholding complete" << endl;
  SwiftImage<uint16> c2t_i3 = edm.process(c2t_i2);
  cout << "EDM complete" << endl;
  SwiftImage<uint16> c2t_i4 = inv.process(c2t_i3);
  cout << "INV complete" << endl;
  SwiftImage<uint16> c2t_i5 = wat.process(c2t_i4);
  cout << "Wat complete" << endl;
  SwiftImage<uint16> c2t_i6 = c2t_i2 && c2t_i5;
  vector<SwiftImageObject<> > c2t_objs1 = segmenter.process(c2t_i6);
  
 
  // Now have c1_objs1 and c2_objs1 for registration

  vector<vector<SwiftImageObject<> > > a_cycles;
  a_cycles.push_back(c1a_objs1);
  a_cycles.push_back(c2a_objs1);
  
  vector<vector<SwiftImageObject<> > > t_cycles;
  t_cycles.push_back(c1t_objs1);
  t_cycles.push_back(c2t_objs1);

  ChannelRegistration<> chanreg(c2a_i6.image_width(),c2a_i6.image_height());
  vector<vector<SwiftImageCluster<> > > a_clusters = chanreg.process_channel_registration(a_cycles,SwiftImageCluster<>::base_a);
  vector<vector<SwiftImageCluster<> > > c_clusters = chanreg.process_channel_registration(t_cycles,SwiftImageCluster<>::base_c);
  vector<vector<SwiftImageCluster<> > > g_clusters = chanreg.process_channel_registration(a_cycles,SwiftImageCluster<>::base_g);
  vector<vector<SwiftImageCluster<> > > t_clusters = chanreg.process_channel_registration(t_cycles,SwiftImageCluster<>::base_t);
 
  CrossChannelRegistration<> crosschanreg(c2a_i6.image_width(),c2a_i6.image_height(),true,3);
  vector<vector<SwiftImageCluster<> > > all_clusters = crosschanreg.process_crosschannel_registration(a_clusters,
                                                                                                      c_clusters,
                                                                                                      g_clusters,
                                                                                                      t_clusters);


  for(int n=0;n<all_clusters.size();n++) {
    ut.test(static_cast<int>(all_clusters[n].size()),2);
  }
   
  ut.test(static_cast<int>(all_clusters.size()),5);
  
  // Cluster 1, Cycle 1
  ut.test(static_cast<int>(all_clusters[0][0].features[SwiftImageCluster<>::base_a].size()),1);
  ut.test(static_cast<int>(all_clusters[0][0].features[SwiftImageCluster<>::base_t].size()),1);
  ut.test(static_cast<int>(all_clusters[0][0].features[SwiftImageCluster<>::base_g].size()),1);
  ut.test(static_cast<int>(all_clusters[0][0].features[SwiftImageCluster<>::base_c].size()),1);

  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_a][0].pixels[0].pos.x,1);
  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_a][0].pixels[0].pos.y,1);
  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_a][0].pixels[0].length,2);
  
  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_a][0].pixels[1].pos.x,1);
  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_a][0].pixels[1].pos.y,2);
  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_a][0].pixels[1].length,2);
  

  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_t][0].pixels[0].pos.x,1);
  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_t][0].pixels[0].pos.y,1);
  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_t][0].pixels[0].length,2);
  
  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_t][0].pixels[1].pos.x,1);
  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_t][0].pixels[1].pos.y,2);
  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_t][0].pixels[1].length,2);
  

  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_g][0].pixels[0].pos.x,1);
  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_g][0].pixels[0].pos.y,1);
  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_g][0].pixels[0].length,2);
  
  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_c][0].pixels[1].pos.x,1);
  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_c][0].pixels[1].pos.y,2);
  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_c][0].pixels[1].length,2);

  
  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_c][0].pixels[0].pos.x,1);
  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_c][0].pixels[0].pos.y,1);
  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_c][0].pixels[0].length,2);
  
  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_c][0].pixels[1].pos.x,1);
  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_c][0].pixels[1].pos.y,2);
  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_c][0].pixels[1].length,2);

  // Cluster 1, Cycle 2
  ut.test(static_cast<int>(all_clusters[0][1].features[SwiftImageCluster<>::base_a].size()),1);
  ut.test(static_cast<int>(all_clusters[0][1].features[SwiftImageCluster<>::base_t].size()),1);
  ut.test(static_cast<int>(all_clusters[0][1].features[SwiftImageCluster<>::base_g].size()),1);
  ut.test(static_cast<int>(all_clusters[0][1].features[SwiftImageCluster<>::base_c].size()),1);

  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_a][0].pixels[0].pos.x,1);
  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_a][0].pixels[0].pos.y,1);
  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_a][0].pixels[0].length,2);
  
  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_a][0].pixels[1].pos.x,1);
  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_a][0].pixels[1].pos.y,2);
  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_a][0].pixels[1].length,2);
  

  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_t][0].pixels[0].pos.x,1);
  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_t][0].pixels[0].pos.y,1);
  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_t][0].pixels[0].length,2);
  
  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_t][0].pixels[1].pos.x,1);
  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_t][0].pixels[1].pos.y,2);
  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_t][0].pixels[1].length,2);
  

  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_g][0].pixels[0].pos.x,1);
  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_g][0].pixels[0].pos.y,1);
  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_g][0].pixels[0].length,2);
  
  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_c][0].pixels[1].pos.x,1);
  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_c][0].pixels[1].pos.y,2);
  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_c][0].pixels[1].length,2);

  
  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_c][0].pixels[0].pos.x,1);
  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_c][0].pixels[0].pos.y,1);
  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_c][0].pixels[0].length,2);
  
  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_c][0].pixels[1].pos.x,1);
  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_c][0].pixels[1].pos.y,2);
  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_c][0].pixels[1].length,2);

  // Cluster 2, Cycle 1
  ut.test(static_cast<int>(all_clusters[1][0].features[SwiftImageCluster<>::base_a].size()),2);
  ut.test(static_cast<int>(all_clusters[1][0].features[SwiftImageCluster<>::base_t].size()),1);
  ut.test(static_cast<int>(all_clusters[1][0].features[SwiftImageCluster<>::base_g].size()),2);
  ut.test(static_cast<int>(all_clusters[1][0].features[SwiftImageCluster<>::base_c].size()),1);
  
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_a][0].pixels[0].pos.x,1);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_a][0].pixels[0].pos.y,5);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_a][0].pixels[0].length,2);
  
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_a][0].pixels[1].pos.x,1);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_a][0].pixels[1].pos.y,6);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_a][0].pixels[1].length,2);

  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_a][1].pixels[0].pos.x,5);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_a][1].pixels[0].pos.y,5);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_a][1].pixels[0].length,2);
  
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_a][1].pixels[1].pos.x,5);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_a][1].pixels[1].pos.y,6);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_a][1].pixels[1].length,2);

  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_t][0].pixels[0].pos.x,5);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_t][0].pixels[0].pos.y,5);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_t][0].pixels[0].length,2);
  
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_t][0].pixels[1].pos.x,5);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_t][0].pixels[1].pos.y,6);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_t][0].pixels[1].length,2);

  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_g][0].pixels[0].pos.x,1);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_g][0].pixels[0].pos.y,5);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_g][0].pixels[0].length,2);
  
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_g][0].pixels[1].pos.x,1);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_g][0].pixels[1].pos.y,6);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_g][0].pixels[1].length,2);

  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_g][1].pixels[0].pos.x,5);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_g][1].pixels[0].pos.y,5);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_g][1].pixels[0].length,2);
  
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_g][1].pixels[1].pos.x,5);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_g][1].pixels[1].pos.y,6);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_g][1].pixels[1].length,2);

  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_c][0].pixels[0].pos.x,5);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_c][0].pixels[0].pos.y,5);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_c][0].pixels[0].length,2);
  
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_c][0].pixels[1].pos.x,5);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_c][0].pixels[1].pos.y,6);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_c][0].pixels[1].length,2);

  
  // Cluster 2, Cycle 2
  ut.test(static_cast<int>(all_clusters[1][1].features[SwiftImageCluster<>::base_a].size()),1);
  ut.test(static_cast<int>(all_clusters[1][1].features[SwiftImageCluster<>::base_t].size()),1);
  ut.test(static_cast<int>(all_clusters[1][1].features[SwiftImageCluster<>::base_g].size()),1);
  ut.test(static_cast<int>(all_clusters[1][1].features[SwiftImageCluster<>::base_c].size()),1);
  
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_a][0].pixels[0].pos.x,1);
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_a][0].pixels[0].pos.y,5);
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_a][0].pixels[0].length,6);
  
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_a][0].pixels[1].pos.x,1);
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_a][0].pixels[1].pos.y,6);
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_a][0].pixels[1].length,6);

  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_t][0].pixels[0].pos.x,1);
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_t][0].pixels[0].pos.y,5);
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_t][0].pixels[0].length,6);
  
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_t][0].pixels[1].pos.x,1);
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_t][0].pixels[1].pos.y,6);
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_t][0].pixels[1].length,6);
   
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_g][0].pixels[0].pos.x,1);
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_g][0].pixels[0].pos.y,5);
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_g][0].pixels[0].length,6);
  
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_g][0].pixels[1].pos.x,1);
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_g][0].pixels[1].pos.y,6);
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_g][0].pixels[1].length,6);
  
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_c][0].pixels[0].pos.x,1);
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_c][0].pixels[0].pos.y,5);
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_c][0].pixels[0].length,6);
  
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_c][0].pixels[1].pos.x,1);
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_c][0].pixels[1].pos.y,6);
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_c][0].pixels[1].length,6);
 

  // Cluster 3, Cycle 1
  ut.test(static_cast<int>(all_clusters[2][0].features[SwiftImageCluster<>::base_a].size()),1);
  ut.test(static_cast<int>(all_clusters[2][0].features[SwiftImageCluster<>::base_t].size()),1);
  ut.test(static_cast<int>(all_clusters[2][0].features[SwiftImageCluster<>::base_g].size()),1);
  ut.test(static_cast<int>(all_clusters[2][0].features[SwiftImageCluster<>::base_c].size()),1);

  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_a][0].pixels[0].pos.x,5);
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_a][0].pixels[0].pos.y,1);
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_a][0].pixels[0].length,2);
  
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_a][0].pixels[1].pos.x,5);
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_a][0].pixels[1].pos.y,2);
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_a][0].pixels[1].length,2);
  
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_t][0].pixels[0].pos.x,5);
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_t][0].pixels[0].pos.y,1);
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_t][0].pixels[0].length,2);
  
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_t][0].pixels[1].pos.x,5);
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_t][0].pixels[1].pos.y,2);
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_t][0].pixels[1].length,2);
  
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_g][0].pixels[0].pos.x,5);
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_g][0].pixels[0].pos.y,1);
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_g][0].pixels[0].length,2);
  
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_g][0].pixels[1].pos.x,5);
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_g][0].pixels[1].pos.y,2);
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_g][0].pixels[1].length,2);
  
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_c][0].pixels[0].pos.x,5);
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_c][0].pixels[0].pos.y,1);
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_c][0].pixels[0].length,2);
  
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_c][0].pixels[1].pos.x,5);
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_c][0].pixels[1].pos.y,2);
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_c][0].pixels[1].length,2);
  
  // Cluster 3, Cycle 2
  ut.test(static_cast<int>(all_clusters[2][1].features[SwiftImageCluster<>::base_a].size()),1);
  ut.test(static_cast<int>(all_clusters[2][1].features[SwiftImageCluster<>::base_t].size()),1);
  ut.test(static_cast<int>(all_clusters[2][1].features[SwiftImageCluster<>::base_g].size()),1);
  ut.test(static_cast<int>(all_clusters[2][1].features[SwiftImageCluster<>::base_c].size()),1);

  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_a][0].pixels[0].pos.x,5);
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_a][0].pixels[0].pos.y,1);
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_a][0].pixels[0].length,2);
  
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_a][0].pixels[1].pos.x,5);
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_a][0].pixels[1].pos.y,2);
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_a][0].pixels[1].length,2);
  
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_t][0].pixels[0].pos.x,5);
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_t][0].pixels[0].pos.y,1);
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_t][0].pixels[0].length,2);
  
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_t][0].pixels[1].pos.x,5);
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_t][0].pixels[1].pos.y,2);
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_t][0].pixels[1].length,2);
  
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_g][0].pixels[0].pos.x,5);
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_g][0].pixels[0].pos.y,1);
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_g][0].pixels[0].length,2);
  
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_g][0].pixels[1].pos.x,5);
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_g][0].pixels[1].pos.y,2);
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_g][0].pixels[1].length,2);
  
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_c][0].pixels[0].pos.x,5);
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_c][0].pixels[0].pos.y,1);
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_c][0].pixels[0].length,2);
  
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_c][0].pixels[1].pos.x,5);
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_c][0].pixels[1].pos.y,2);
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_c][0].pixels[1].length,2);

  // Cluster 4, Cycle 1
  ut.test(static_cast<int>(all_clusters[3][0].features[SwiftImageCluster<>::base_a].size()),1);
  ut.test(static_cast<int>(all_clusters[3][0].features[SwiftImageCluster<>::base_t].size()),1);
  ut.test(static_cast<int>(all_clusters[3][0].features[SwiftImageCluster<>::base_g].size()),1);
  ut.test(static_cast<int>(all_clusters[3][0].features[SwiftImageCluster<>::base_c].size()),1);

  ut.test(all_clusters[3][0].features[SwiftImageCluster<>::base_a][0].pixels[0].pos.x,8);
  ut.test(all_clusters[3][0].features[SwiftImageCluster<>::base_a][0].pixels[0].pos.y,5);
  ut.test(all_clusters[3][0].features[SwiftImageCluster<>::base_a][0].pixels[0].length,2);
  
  ut.test(all_clusters[3][0].features[SwiftImageCluster<>::base_a][0].pixels[1].pos.x,8);
  ut.test(all_clusters[3][0].features[SwiftImageCluster<>::base_a][0].pixels[1].pos.y,6);
  ut.test(all_clusters[3][0].features[SwiftImageCluster<>::base_a][0].pixels[1].length,2);
  
  ut.test(all_clusters[3][0].features[SwiftImageCluster<>::base_t][0].pixels[0].pos.x,8);
  ut.test(all_clusters[3][0].features[SwiftImageCluster<>::base_t][0].pixels[0].pos.y,5);
  ut.test(all_clusters[3][0].features[SwiftImageCluster<>::base_t][0].pixels[0].length,2);
  
  ut.test(all_clusters[3][0].features[SwiftImageCluster<>::base_t][0].pixels[1].pos.x,8);
  ut.test(all_clusters[3][0].features[SwiftImageCluster<>::base_t][0].pixels[1].pos.y,6);
  ut.test(all_clusters[3][0].features[SwiftImageCluster<>::base_t][0].pixels[1].length,2);
  
  ut.test(all_clusters[3][0].features[SwiftImageCluster<>::base_g][0].pixels[0].pos.x,8);
  ut.test(all_clusters[3][0].features[SwiftImageCluster<>::base_g][0].pixels[0].pos.y,5);
  ut.test(all_clusters[3][0].features[SwiftImageCluster<>::base_g][0].pixels[0].length,2);
  
  ut.test(all_clusters[3][0].features[SwiftImageCluster<>::base_g][0].pixels[1].pos.x,8);
  ut.test(all_clusters[3][0].features[SwiftImageCluster<>::base_g][0].pixels[1].pos.y,6);
  ut.test(all_clusters[3][0].features[SwiftImageCluster<>::base_g][0].pixels[1].length,2);
  
  ut.test(all_clusters[3][0].features[SwiftImageCluster<>::base_c][0].pixels[0].pos.x,8);
  ut.test(all_clusters[3][0].features[SwiftImageCluster<>::base_c][0].pixels[0].pos.y,5);
  ut.test(all_clusters[3][0].features[SwiftImageCluster<>::base_c][0].pixels[0].length,2);
  
  ut.test(all_clusters[3][0].features[SwiftImageCluster<>::base_c][0].pixels[1].pos.x,8);
  ut.test(all_clusters[3][0].features[SwiftImageCluster<>::base_c][0].pixels[1].pos.y,6);
  ut.test(all_clusters[3][0].features[SwiftImageCluster<>::base_c][0].pixels[1].length,2);
 
  // Cluster 4, Cycle 2
  ut.test(all_clusters[3][1].features[SwiftImageCluster<>::base_a][0].pixels[0].pos.x,8);
  ut.test(all_clusters[3][1].features[SwiftImageCluster<>::base_a][0].pixels[0].pos.y,5);
  ut.test(all_clusters[3][1].features[SwiftImageCluster<>::base_a][0].pixels[0].length,2);
  
  ut.test(all_clusters[3][1].features[SwiftImageCluster<>::base_a][0].pixels[1].pos.x,8);
  ut.test(all_clusters[3][1].features[SwiftImageCluster<>::base_a][0].pixels[1].pos.y,6);
  ut.test(all_clusters[3][1].features[SwiftImageCluster<>::base_a][0].pixels[1].length,2);
  
  ut.test(all_clusters[3][1].features[SwiftImageCluster<>::base_t][0].pixels[0].pos.x,8);
  ut.test(all_clusters[3][1].features[SwiftImageCluster<>::base_t][0].pixels[0].pos.y,5);
  ut.test(all_clusters[3][1].features[SwiftImageCluster<>::base_t][0].pixels[0].length,2);
  
  ut.test(all_clusters[3][1].features[SwiftImageCluster<>::base_t][0].pixels[1].pos.x,8);
  ut.test(all_clusters[3][1].features[SwiftImageCluster<>::base_t][0].pixels[1].pos.y,6);
  ut.test(all_clusters[3][1].features[SwiftImageCluster<>::base_t][0].pixels[1].length,2);
  
  ut.test(all_clusters[3][1].features[SwiftImageCluster<>::base_g][0].pixels[0].pos.x,8);
  ut.test(all_clusters[3][1].features[SwiftImageCluster<>::base_g][0].pixels[0].pos.y,5);
  ut.test(all_clusters[3][1].features[SwiftImageCluster<>::base_g][0].pixels[0].length,2);
  
  ut.test(all_clusters[3][1].features[SwiftImageCluster<>::base_g][0].pixels[1].pos.x,8);
  ut.test(all_clusters[3][1].features[SwiftImageCluster<>::base_g][0].pixels[1].pos.y,6);
  ut.test(all_clusters[3][1].features[SwiftImageCluster<>::base_g][0].pixels[1].length,2);
  
  ut.test(all_clusters[3][1].features[SwiftImageCluster<>::base_c][0].pixels[0].pos.x,8);
  ut.test(all_clusters[3][1].features[SwiftImageCluster<>::base_c][0].pixels[0].pos.y,5);
  ut.test(all_clusters[3][1].features[SwiftImageCluster<>::base_c][0].pixels[0].length,2);
  
  ut.test(all_clusters[3][1].features[SwiftImageCluster<>::base_c][0].pixels[1].pos.x,8);
  ut.test(all_clusters[3][1].features[SwiftImageCluster<>::base_c][0].pixels[1].pos.y,6);
  ut.test(all_clusters[3][1].features[SwiftImageCluster<>::base_c][0].pixels[1].length,2);
 
  
  all_clusters = crosschanreg.process_crosschannel_registration_inv(a_clusters,
                                                                    c_clusters,
                                                                    g_clusters,
                                                                    t_clusters);
  
  for(int n=0;n<all_clusters.size();n++) {
    ut.test(static_cast<int>(all_clusters[n].size()),2);
  }
   
  ut.test(static_cast<int>(all_clusters.size()),5);
  
  // Cluster 1, Cycle 1
  ut.test(static_cast<int>(all_clusters[0][0].features[SwiftImageCluster<>::base_a].size()),1);
  ut.test(static_cast<int>(all_clusters[0][0].features[SwiftImageCluster<>::base_t].size()),1);
  ut.test(static_cast<int>(all_clusters[0][0].features[SwiftImageCluster<>::base_g].size()),1);
  ut.test(static_cast<int>(all_clusters[0][0].features[SwiftImageCluster<>::base_c].size()),1);

  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_a][0].pixels[0].pos.x,1);
  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_a][0].pixels[0].pos.y,1);
  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_a][0].pixels[0].length,2);
  
  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_a][0].pixels[1].pos.x,1);
  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_a][0].pixels[1].pos.y,2);
  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_a][0].pixels[1].length,2);
  

  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_t][0].pixels[0].pos.x,1);
  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_t][0].pixels[0].pos.y,1);
  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_t][0].pixels[0].length,2);
  
  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_t][0].pixels[1].pos.x,1);
  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_t][0].pixels[1].pos.y,2);
  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_t][0].pixels[1].length,2);
  

  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_g][0].pixels[0].pos.x,1);
  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_g][0].pixels[0].pos.y,1);
  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_g][0].pixels[0].length,2);
  
  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_c][0].pixels[1].pos.x,1);
  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_c][0].pixels[1].pos.y,2);
  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_c][0].pixels[1].length,2);

  
  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_c][0].pixels[0].pos.x,1);
  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_c][0].pixels[0].pos.y,1);
  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_c][0].pixels[0].length,2);
  
  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_c][0].pixels[1].pos.x,1);
  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_c][0].pixels[1].pos.y,2);
  ut.test(all_clusters[0][0].features[SwiftImageCluster<>::base_c][0].pixels[1].length,2);

  // Cluster 1, Cycle 2
  ut.test(static_cast<int>(all_clusters[0][1].features[SwiftImageCluster<>::base_a].size()),1);
  ut.test(static_cast<int>(all_clusters[0][1].features[SwiftImageCluster<>::base_t].size()),1);
  ut.test(static_cast<int>(all_clusters[0][1].features[SwiftImageCluster<>::base_g].size()),1);
  ut.test(static_cast<int>(all_clusters[0][1].features[SwiftImageCluster<>::base_c].size()),1);

  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_a][0].pixels[0].pos.x,1);
  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_a][0].pixels[0].pos.y,1);
  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_a][0].pixels[0].length,2);
  
  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_a][0].pixels[1].pos.x,1);
  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_a][0].pixels[1].pos.y,2);
  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_a][0].pixels[1].length,2);
  

  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_t][0].pixels[0].pos.x,1);
  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_t][0].pixels[0].pos.y,1);
  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_t][0].pixels[0].length,2);
  
  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_t][0].pixels[1].pos.x,1);
  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_t][0].pixels[1].pos.y,2);
  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_t][0].pixels[1].length,2);
  

  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_g][0].pixels[0].pos.x,1);
  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_g][0].pixels[0].pos.y,1);
  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_g][0].pixels[0].length,2);
  
  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_c][0].pixels[1].pos.x,1);
  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_c][0].pixels[1].pos.y,2);
  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_c][0].pixels[1].length,2);

  
  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_c][0].pixels[0].pos.x,1);
  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_c][0].pixels[0].pos.y,1);
  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_c][0].pixels[0].length,2);
  
  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_c][0].pixels[1].pos.x,1);
  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_c][0].pixels[1].pos.y,2);
  ut.test(all_clusters[0][1].features[SwiftImageCluster<>::base_c][0].pixels[1].length,2);

  // Cluster 2, Cycle 1
  ut.test(static_cast<int>(all_clusters[1][0].features[SwiftImageCluster<>::base_a].size()),2);
  ut.test(static_cast<int>(all_clusters[1][0].features[SwiftImageCluster<>::base_t].size()),1);
  ut.test(static_cast<int>(all_clusters[1][0].features[SwiftImageCluster<>::base_g].size()),2);
  ut.test(static_cast<int>(all_clusters[1][0].features[SwiftImageCluster<>::base_c].size()),1);
  
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_a][0].pixels[0].pos.x,1);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_a][0].pixels[0].pos.y,5);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_a][0].pixels[0].length,2);
  
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_a][0].pixels[1].pos.x,1);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_a][0].pixels[1].pos.y,6);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_a][0].pixels[1].length,2);

  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_a][1].pixels[0].pos.x,5);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_a][1].pixels[0].pos.y,5);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_a][1].pixels[0].length,2);
  
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_a][1].pixels[1].pos.x,5);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_a][1].pixels[1].pos.y,6);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_a][1].pixels[1].length,2);

  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_t][0].pixels[0].pos.x,5);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_t][0].pixels[0].pos.y,5);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_t][0].pixels[0].length,2);
  
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_t][0].pixels[1].pos.x,5);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_t][0].pixels[1].pos.y,6);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_t][0].pixels[1].length,2);

  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_g][0].pixels[0].pos.x,1);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_g][0].pixels[0].pos.y,5);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_g][0].pixels[0].length,2);
  
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_g][0].pixels[1].pos.x,1);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_g][0].pixels[1].pos.y,6);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_g][0].pixels[1].length,2);

  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_g][1].pixels[0].pos.x,5);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_g][1].pixels[0].pos.y,5);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_g][1].pixels[0].length,2);
  
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_g][1].pixels[1].pos.x,5);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_g][1].pixels[1].pos.y,6);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_g][1].pixels[1].length,2);

  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_c][0].pixels[0].pos.x,5);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_c][0].pixels[0].pos.y,5);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_c][0].pixels[0].length,2);
  
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_c][0].pixels[1].pos.x,5);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_c][0].pixels[1].pos.y,6);
  ut.test(all_clusters[1][0].features[SwiftImageCluster<>::base_c][0].pixels[1].length,2);

  
  // Cluster 2, Cycle 2
  ut.test(static_cast<int>(all_clusters[1][1].features[SwiftImageCluster<>::base_a].size()),1);
  ut.test(static_cast<int>(all_clusters[1][1].features[SwiftImageCluster<>::base_t].size()),1);
  ut.test(static_cast<int>(all_clusters[1][1].features[SwiftImageCluster<>::base_g].size()),1);
  ut.test(static_cast<int>(all_clusters[1][1].features[SwiftImageCluster<>::base_c].size()),1);
  
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_a][0].pixels[0].pos.x,1);
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_a][0].pixels[0].pos.y,5);
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_a][0].pixels[0].length,6);
  
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_a][0].pixels[1].pos.x,1);
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_a][0].pixels[1].pos.y,6);
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_a][0].pixels[1].length,6);

  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_t][0].pixels[0].pos.x,1);
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_t][0].pixels[0].pos.y,5);
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_t][0].pixels[0].length,6);
  
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_t][0].pixels[1].pos.x,1);
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_t][0].pixels[1].pos.y,6);
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_t][0].pixels[1].length,6);
   
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_g][0].pixels[0].pos.x,1);
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_g][0].pixels[0].pos.y,5);
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_g][0].pixels[0].length,6);
  
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_g][0].pixels[1].pos.x,1);
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_g][0].pixels[1].pos.y,6);
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_g][0].pixels[1].length,6);
  
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_c][0].pixels[0].pos.x,1);
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_c][0].pixels[0].pos.y,5);
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_c][0].pixels[0].length,6);
  
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_c][0].pixels[1].pos.x,1);
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_c][0].pixels[1].pos.y,6);
  ut.test(all_clusters[1][1].features[SwiftImageCluster<>::base_c][0].pixels[1].length,6);
 

  // Cluster 3, Cycle 1
  ut.test(static_cast<int>(all_clusters[4][0].features[SwiftImageCluster<>::base_a].size()),1);
  ut.test(static_cast<int>(all_clusters[4][0].features[SwiftImageCluster<>::base_t].size()),1);
  ut.test(static_cast<int>(all_clusters[4][0].features[SwiftImageCluster<>::base_g].size()),1);
  ut.test(static_cast<int>(all_clusters[4][0].features[SwiftImageCluster<>::base_c].size()),1);

  ut.test(all_clusters[4][0].features[SwiftImageCluster<>::base_a][0].pixels[0].pos.x,5);
  ut.test(all_clusters[4][0].features[SwiftImageCluster<>::base_a][0].pixels[0].pos.y,1);
  ut.test(all_clusters[4][0].features[SwiftImageCluster<>::base_a][0].pixels[0].length,2);
  
  ut.test(all_clusters[4][0].features[SwiftImageCluster<>::base_a][0].pixels[1].pos.x,5);
  ut.test(all_clusters[4][0].features[SwiftImageCluster<>::base_a][0].pixels[1].pos.y,2);
  ut.test(all_clusters[4][0].features[SwiftImageCluster<>::base_a][0].pixels[1].length,2);
  
  ut.test(all_clusters[4][0].features[SwiftImageCluster<>::base_t][0].pixels[0].pos.x,5);
  ut.test(all_clusters[4][0].features[SwiftImageCluster<>::base_t][0].pixels[0].pos.y,1);
  ut.test(all_clusters[4][0].features[SwiftImageCluster<>::base_t][0].pixels[0].length,2);
  
  ut.test(all_clusters[4][0].features[SwiftImageCluster<>::base_t][0].pixels[1].pos.x,5);
  ut.test(all_clusters[4][0].features[SwiftImageCluster<>::base_t][0].pixels[1].pos.y,2);
  ut.test(all_clusters[4][0].features[SwiftImageCluster<>::base_t][0].pixels[1].length,2);
  
  ut.test(all_clusters[4][0].features[SwiftImageCluster<>::base_g][0].pixels[0].pos.x,5);
  ut.test(all_clusters[4][0].features[SwiftImageCluster<>::base_g][0].pixels[0].pos.y,1);
  ut.test(all_clusters[4][0].features[SwiftImageCluster<>::base_g][0].pixels[0].length,2);
  
  ut.test(all_clusters[4][0].features[SwiftImageCluster<>::base_g][0].pixels[1].pos.x,5);
  ut.test(all_clusters[4][0].features[SwiftImageCluster<>::base_g][0].pixels[1].pos.y,2);
  ut.test(all_clusters[4][0].features[SwiftImageCluster<>::base_g][0].pixels[1].length,2);
  
  ut.test(all_clusters[4][0].features[SwiftImageCluster<>::base_c][0].pixels[0].pos.x,5);
  ut.test(all_clusters[4][0].features[SwiftImageCluster<>::base_c][0].pixels[0].pos.y,1);
  ut.test(all_clusters[4][0].features[SwiftImageCluster<>::base_c][0].pixels[0].length,2);
  
  ut.test(all_clusters[4][0].features[SwiftImageCluster<>::base_c][0].pixels[1].pos.x,5);
  ut.test(all_clusters[4][0].features[SwiftImageCluster<>::base_c][0].pixels[1].pos.y,2);
  ut.test(all_clusters[4][0].features[SwiftImageCluster<>::base_c][0].pixels[1].length,2);
  
  // Cluster 3, Cycle 2
  ut.test(static_cast<int>(all_clusters[4][1].features[SwiftImageCluster<>::base_a].size()),1);
  ut.test(static_cast<int>(all_clusters[4][1].features[SwiftImageCluster<>::base_t].size()),1);
  ut.test(static_cast<int>(all_clusters[4][1].features[SwiftImageCluster<>::base_g].size()),1);
  ut.test(static_cast<int>(all_clusters[4][1].features[SwiftImageCluster<>::base_c].size()),1);

  ut.test(all_clusters[4][1].features[SwiftImageCluster<>::base_a][0].pixels[0].pos.x,5);
  ut.test(all_clusters[4][1].features[SwiftImageCluster<>::base_a][0].pixels[0].pos.y,1);
  ut.test(all_clusters[4][1].features[SwiftImageCluster<>::base_a][0].pixels[0].length,2);
  
  ut.test(all_clusters[4][1].features[SwiftImageCluster<>::base_a][0].pixels[1].pos.x,5);
  ut.test(all_clusters[4][1].features[SwiftImageCluster<>::base_a][0].pixels[1].pos.y,2);
  ut.test(all_clusters[4][1].features[SwiftImageCluster<>::base_a][0].pixels[1].length,2);
  
  ut.test(all_clusters[4][1].features[SwiftImageCluster<>::base_t][0].pixels[0].pos.x,5);
  ut.test(all_clusters[4][1].features[SwiftImageCluster<>::base_t][0].pixels[0].pos.y,1);
  ut.test(all_clusters[4][1].features[SwiftImageCluster<>::base_t][0].pixels[0].length,2);
  
  ut.test(all_clusters[4][1].features[SwiftImageCluster<>::base_t][0].pixels[1].pos.x,5);
  ut.test(all_clusters[4][1].features[SwiftImageCluster<>::base_t][0].pixels[1].pos.y,2);
  ut.test(all_clusters[4][1].features[SwiftImageCluster<>::base_t][0].pixels[1].length,2);
  
  ut.test(all_clusters[4][1].features[SwiftImageCluster<>::base_g][0].pixels[0].pos.x,5);
  ut.test(all_clusters[4][1].features[SwiftImageCluster<>::base_g][0].pixels[0].pos.y,1);
  ut.test(all_clusters[4][1].features[SwiftImageCluster<>::base_g][0].pixels[0].length,2);
  
  ut.test(all_clusters[4][1].features[SwiftImageCluster<>::base_g][0].pixels[1].pos.x,5);
  ut.test(all_clusters[4][1].features[SwiftImageCluster<>::base_g][0].pixels[1].pos.y,2);
  ut.test(all_clusters[4][1].features[SwiftImageCluster<>::base_g][0].pixels[1].length,2);
  
  ut.test(all_clusters[4][1].features[SwiftImageCluster<>::base_c][0].pixels[0].pos.x,5);
  ut.test(all_clusters[4][1].features[SwiftImageCluster<>::base_c][0].pixels[0].pos.y,1);
  ut.test(all_clusters[4][1].features[SwiftImageCluster<>::base_c][0].pixels[0].length,2);
  
  ut.test(all_clusters[4][1].features[SwiftImageCluster<>::base_c][0].pixels[1].pos.x,5);
  ut.test(all_clusters[4][1].features[SwiftImageCluster<>::base_c][0].pixels[1].pos.y,2);
  ut.test(all_clusters[4][1].features[SwiftImageCluster<>::base_c][0].pixels[1].length,2);

  // Cluster 4, Cycle 1
  ut.test(static_cast<int>(all_clusters[2][0].features[SwiftImageCluster<>::base_a].size()),1);
  ut.test(static_cast<int>(all_clusters[2][0].features[SwiftImageCluster<>::base_t].size()),1);
  ut.test(static_cast<int>(all_clusters[2][0].features[SwiftImageCluster<>::base_g].size()),1);
  ut.test(static_cast<int>(all_clusters[2][0].features[SwiftImageCluster<>::base_c].size()),1);

  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_a][0].pixels[0].pos.x,8);
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_a][0].pixels[0].pos.y,5);
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_a][0].pixels[0].length,2);
  
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_a][0].pixels[1].pos.x,8);
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_a][0].pixels[1].pos.y,6);
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_a][0].pixels[1].length,2);
  
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_t][0].pixels[0].pos.x,8);
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_t][0].pixels[0].pos.y,5);
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_t][0].pixels[0].length,2);
  
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_t][0].pixels[1].pos.x,8);
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_t][0].pixels[1].pos.y,6);
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_t][0].pixels[1].length,2);
  
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_g][0].pixels[0].pos.x,8);
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_g][0].pixels[0].pos.y,5);
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_g][0].pixels[0].length,2);
  
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_g][0].pixels[1].pos.x,8);
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_g][0].pixels[1].pos.y,6);
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_g][0].pixels[1].length,2);
  
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_c][0].pixels[0].pos.x,8);
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_c][0].pixels[0].pos.y,5);
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_c][0].pixels[0].length,2);
  
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_c][0].pixels[1].pos.x,8);
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_c][0].pixels[1].pos.y,6);
  ut.test(all_clusters[2][0].features[SwiftImageCluster<>::base_c][0].pixels[1].length,2);
 
  // Cluster 4, Cycle 2
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_a][0].pixels[0].pos.x,8);
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_a][0].pixels[0].pos.y,5);
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_a][0].pixels[0].length,2);
  
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_a][0].pixels[1].pos.x,8);
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_a][0].pixels[1].pos.y,6);
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_a][0].pixels[1].length,2);
  
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_t][0].pixels[0].pos.x,8);
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_t][0].pixels[0].pos.y,5);
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_t][0].pixels[0].length,2);
  
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_t][0].pixels[1].pos.x,8);
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_t][0].pixels[1].pos.y,6);
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_t][0].pixels[1].length,2);
  
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_g][0].pixels[0].pos.x,8);
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_g][0].pixels[0].pos.y,5);
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_g][0].pixels[0].length,2);
  
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_g][0].pixels[1].pos.x,8);
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_g][0].pixels[1].pos.y,6);
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_g][0].pixels[1].length,2);
  
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_c][0].pixels[0].pos.x,8);
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_c][0].pixels[0].pos.y,5);
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_c][0].pixels[0].length,2);
 
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_c][0].pixels[1].pos.x,8);
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_c][0].pixels[1].pos.y,6);
  ut.test(all_clusters[2][1].features[SwiftImageCluster<>::base_c][0].pixels[1].length,2);

  ut.end_test_set();
}
Example #21
0
static Ref_t create_detector(Detector& theDetector, xml_h element, SensitiveDetector sens)  {
  xml_det_t   x_det     = element;
  Layering    layering(x_det);
  xml_dim_t   dim         = x_det.dimensions();
  string      det_name    = x_det.nameStr();
  //unused: string      det_type    = x_det.typeStr();
  Material    air         = theDetector.air();
  Material    stavesMaterial    = theDetector.material(x_det.materialStr());
  int         numSides    = dim.numsides();

  int           det_id    = x_det.id();

  DetElement   sdet(det_name,det_id);

  PlacedVolume pVol;

  // --- create an envelope volume and position it into the world ---------------------

  Volume envelope = dd4hep::xml::createPlacedEnvelope( theDetector,  element , sdet ) ;
  
  sdet.setTypeFlag( DetType::CALORIMETER |  DetType::ENDCAP  | DetType::HADRONIC ) ;

  if( theDetector.buildType() == BUILD_ENVELOPE ) return sdet ;
  //-----------------------------------------------------------------------------------

  sens.setType("calorimeter");

  DetElement    stave_det("module0stave0",det_id);
 
  // The way to reaad constant from XML/Detector file.
  double      Hcal_radiator_thickness          = theDetector.constant<double>("Hcal_radiator_thickness");
  double      Hcal_endcap_lateral_structure_thickness = theDetector.constant<double>("Hcal_endcap_lateral_structure_thickness");
  double      Hcal_endcap_layer_air_gap        = theDetector.constant<double>("Hcal_endcap_layer_air_gap");

  //double      Hcal_cells_size                  = theDetector.constant<double>("Hcal_cells_size");
  double      HcalEndcap_inner_radius          = theDetector.constant<double>("HcalEndcap_inner_radius");
  double      HcalEndcap_outer_radius          = theDetector.constant<double>("HcalEndcap_outer_radius");
  double      HcalEndcap_min_z                 = theDetector.constant<double>("HcalEndcap_min_z");
  double      HcalEndcap_max_z                 = theDetector.constant<double>("HcalEndcap_max_z");

  double   Hcal_steel_cassette_thickness       = theDetector.constant<double>("Hcal_steel_cassette_thickness");
  double   HcalServices_outer_FR4_thickness    = theDetector.constant<double>("HcalServices_outer_FR4_thickness");
  double   HcalServices_outer_Cu_thickness     = theDetector.constant<double>("HcalServices_outer_Cu_thickness");
  double   Hcal_endcap_services_module_width   = theDetector.constant<double>("Hcal_endcap_services_module_width");

  Material  stainless_steel =  theDetector.material("stainless_steel");
  Material  PCB             =  theDetector.material("PCB");
  Material  copper          =  theDetector.material("Cu");

  std::cout <<"\n HcalEndcap_inner_radius = "
	    <<HcalEndcap_inner_radius/dd4hep::mm <<" mm"
	    <<"\n HcalEndcap_outer_radius = "
	    <<HcalEndcap_outer_radius/dd4hep::mm <<" mm"
	    <<"\n HcalEndcap_min_z = "
	    <<HcalEndcap_min_z/dd4hep::mm <<" mm"
	    <<"\n HcalEndcap_max_z = "
	    <<HcalEndcap_max_z/dd4hep::mm <<" mm"
	    <<std::endl;


  Readout readout = sens.readout();
  Segmentation seg = readout.segmentation();
  
  std::vector<double> cellSizeVector = seg.segmentation()->cellDimensions(0); //Assume uniform cell sizes, provide dummy cellID
  double cell_sizeX      = cellSizeVector[0];
  double cell_sizeY      = cellSizeVector[1];

  //========== fill data for reconstruction ============================
  LayeredCalorimeterData* caloData = new LayeredCalorimeterData ;
  caloData->layoutType = LayeredCalorimeterData::EndcapLayout ;
  caloData->inner_symmetry = 4  ; // hard code cernter box hole
  caloData->outer_symmetry = 0  ; // outer tube, or 8 for Octagun
  caloData->phi0 = 0 ;

  /// extent of the calorimeter in the r-z-plane [ rmin, rmax, zmin, zmax ] in mm.
  caloData->extent[0] = HcalEndcap_inner_radius ;
  caloData->extent[1] = HcalEndcap_outer_radius ;
  caloData->extent[2] = HcalEndcap_min_z ;
  caloData->extent[3] = HcalEndcap_max_z ;
  

  int endcapID = 0;
  for(xml_coll_t c(x_det.child(_U(dimensions)),_U(dimensions)); c; ++c) 
    {
      xml_comp_t l(c);
      
      double dim_x = l.attr<double>(_Unicode(dim_x));
      double dim_y = l.attr<double>(_Unicode(dim_y));
      double dim_z = l.attr<double>(_Unicode(dim_z));
      double pos_y = l.attr<double>(_Unicode(y_offset));
    
      // Hcal Endcap module shape
      double box_half_x= dim_x/2.0; // module width, all are same
      double box_half_y= dim_y/2.0; // total thickness, all are same
      double box_half_z= dim_z/2.0; // module length, changed, 
      
      double x_offset = box_half_x*numSides-box_half_x*endcapID*2.0-box_half_x;
      double y_offset = pos_y;
      
      Box    EndcapModule(box_half_x,box_half_y,box_half_z);
      
      // define the name of each endcap Module
      string envelopeVol_name   = det_name+_toString(endcapID,"_EndcapModule%d");
      
      Volume envelopeVol(envelopeVol_name,EndcapModule,stavesMaterial);
      
      // Set envelope volume attributes.
      envelopeVol.setAttributes(theDetector,x_det.regionStr(),x_det.limitsStr(),x_det.visStr());
      

      double FEE_half_x = box_half_x-Hcal_endcap_services_module_width/2.0;
      double FEE_half_y = box_half_y;
      double FEE_half_Z = Hcal_endcap_services_module_width/2.0;

      Box    FEEBox(FEE_half_x,FEE_half_y,FEE_half_Z);
      Volume FEEModule("Hcal_endcap_FEE",FEEBox,air);

      double FEELayer_thickness = Hcal_steel_cassette_thickness + HcalServices_outer_FR4_thickness + HcalServices_outer_Cu_thickness;
      Box    FEELayerBox(FEE_half_x,FEELayer_thickness/2.0,FEE_half_Z);
      Volume FEELayer("FEELayer",FEELayerBox,air);

      Box    FEELayerSteelBox(FEE_half_x,Hcal_steel_cassette_thickness/2.0,FEE_half_Z);
      Volume FEELayerSteel("FEELayerSteel",FEELayerSteelBox,stainless_steel);
      pVol = FEELayer.placeVolume(FEELayerSteel,
				  Position(0,
					   (-FEELayer_thickness/2.0
					    +Hcal_steel_cassette_thickness/2.0),
					   0));

      Box    FEELayerFR4Box(FEE_half_x,HcalServices_outer_FR4_thickness/2.0,FEE_half_Z);
      Volume FEELayerFR4("FEELayerFR4",FEELayerFR4Box,PCB);
      pVol = FEELayer.placeVolume(FEELayerFR4,
				  Position(0,
					   (-FEELayer_thickness/2.0+Hcal_steel_cassette_thickness
					    +HcalServices_outer_FR4_thickness/2.0),
					   0));

      Box    FEELayerCuBox(FEE_half_x,HcalServices_outer_Cu_thickness/2.0,FEE_half_Z);
      Volume FEELayerCu("FEELayerCu",FEELayerCuBox,copper);
      pVol = FEELayer.placeVolume(FEELayerCu,
				  Position(0,
					   (-FEELayer_thickness/2.0+Hcal_steel_cassette_thickness+HcalServices_outer_FR4_thickness
					    +HcalServices_outer_Cu_thickness/2.0),
					   0));


      // ========= Create Hcal Chamber (i.e. Layers) ==============================
      // It will be the sub volume for placing the slices.
      // Itself will be placed into the Hcal Endcap modules envelope.
      // ==========================================================================
      
      // create Layer (air) and place the slices (Polystyrene,Cu,FR4,air) into it. 
      // place the Layer into the Hcal Endcap Modules envelope (stavesMaterial).
      
      // First Hcal Chamber position, start after first radiator
      double layer_pos_y     = - box_half_y + Hcal_radiator_thickness;                      
      
      // Create Hcal Endcap Chamber without radiator
      // Place into the Hcal Encap module envelope, after each radiator 
      int layer_num = 1;
      for(xml_coll_t m(x_det,_U(layer)); m; ++m)  {
	xml_comp_t   x_layer = m;
	int          repeat = x_layer.repeat();          // Get number of layers.

	double layer_thickness = layering.layer(layer_num)->thickness();
	string layer_name      = envelopeVol_name+"_layer";
	DetElement  layer(stave_det,layer_name,det_id);
	
	// Active Layer box & volume
	double active_layer_dim_x = box_half_x - Hcal_endcap_lateral_structure_thickness - Hcal_endcap_layer_air_gap;
	double active_layer_dim_y = layer_thickness/2.0;
	double active_layer_dim_z = box_half_z;
	
	// Build chamber including air gap
	// The Layer will be filled with slices, 
	Volume layer_vol(layer_name, Box((active_layer_dim_x + Hcal_endcap_layer_air_gap),
					 active_layer_dim_y,active_layer_dim_z), air);

	LayeredCalorimeterData::Layer caloLayer ;
	caloLayer.cellSize0 = cell_sizeX;
	caloLayer.cellSize1 = cell_sizeY;
	
	// ========= Create sublayer slices =========================================
	// Create and place the slices into Layer
	// ==========================================================================
	
	// Create the slices (sublayers) within the Hcal Chamber.
	double slice_pos_y = -(layer_thickness / 2.0);
	int slice_number = 0;

	double nRadiationLengths=0.;
	double nInteractionLengths=0.;
	double thickness_sum=0;

	nRadiationLengths   = Hcal_radiator_thickness/(stavesMaterial.radLength());
	nInteractionLengths = Hcal_radiator_thickness/(stavesMaterial.intLength());
	thickness_sum       = Hcal_radiator_thickness;

	for(xml_coll_t k(x_layer,_U(slice)); k; ++k)  {
	  xml_comp_t x_slice = k;
	  string   slice_name      = layer_name + _toString(slice_number,"_slice%d");
	  double   slice_thickness = x_slice.thickness();
	  Material slice_material  = theDetector.material(x_slice.materialStr());
	  DetElement slice(layer,_toString(slice_number,"slice%d"),det_id);
	  
	  slice_pos_y += slice_thickness / 2.0;
	  
	  // Slice volume & box
	  Volume slice_vol(slice_name,Box(active_layer_dim_x,slice_thickness/2.0,active_layer_dim_z),slice_material);
	  
	  nRadiationLengths   += slice_thickness/(2.*slice_material.radLength());
	  nInteractionLengths += slice_thickness/(2.*slice_material.intLength());
	  thickness_sum       += slice_thickness/2;

	  if ( x_slice.isSensitive() ) {
	    sens.setType("calorimeter");
	    slice_vol.setSensitiveDetector(sens);

#if DD4HEP_VERSION_GE( 0, 15 )
	    //Store "inner" quantities
	    caloLayer.inner_nRadiationLengths = nRadiationLengths;
	    caloLayer.inner_nInteractionLengths = nInteractionLengths;
	    caloLayer.inner_thickness = thickness_sum;
	    //Store scintillator thickness
	    caloLayer.sensitive_thickness = slice_thickness;
#endif
	    //Reset counters to measure "outside" quantitites
	    nRadiationLengths=0.;
	    nInteractionLengths=0.;
	    thickness_sum = 0.;
	  }

	  nRadiationLengths += slice_thickness/(2.*slice_material.radLength());
	  nInteractionLengths += slice_thickness/(2.*slice_material.intLength());
	  thickness_sum += slice_thickness/2;

	  // Set region, limitset, and vis.
	  slice_vol.setAttributes(theDetector,x_slice.regionStr(),x_slice.limitsStr(),x_slice.visStr());
	  // slice PlacedVolume
	  PlacedVolume slice_phv = layer_vol.placeVolume(slice_vol,Position(0,slice_pos_y,0));
	  //slice_phv.addPhysVolID("slice",slice_number);
	  
	  slice.setPlacement(slice_phv);
	  // Increment Z position for next slice.
	  slice_pos_y += slice_thickness / 2.0;
	  // Increment slice number.
	  ++slice_number;             
	}
	// Set region, limitset, and vis.
	layer_vol.setAttributes(theDetector,x_layer.regionStr(),x_layer.limitsStr(),x_layer.visStr());

#if DD4HEP_VERSION_GE( 0, 15 )
	//Store "outer" quantities
	caloLayer.outer_nRadiationLengths = nRadiationLengths;
	caloLayer.outer_nInteractionLengths = nInteractionLengths;
	caloLayer.outer_thickness = thickness_sum;
#endif 	
	
	// ========= Place the Layer (i.e. Chamber) =================================
	// Place the Layer into the Hcal Endcap module envelope.
	// with the right position and rotation.
	// Registry the IDs (layer, stave, module).
	// Place the same layer 48 times into Endcap module
	// ==========================================================================
	
	for (int j = 0; j < repeat; j++)    {
	  
	  // Layer position in y within the Endcap Modules.
	  layer_pos_y += layer_thickness / 2.0;
	  
	  PlacedVolume layer_phv = envelopeVol.placeVolume(layer_vol,
							   Position(0,layer_pos_y,0));
	  // registry the ID of Layer, stave and module
	  layer_phv.addPhysVolID("layer",layer_num);

	  // then setPlacement for it.
	  layer.setPlacement(layer_phv);
	  
	  pVol = FEEModule.placeVolume(FEELayer,
				       Position(0,layer_pos_y,0));
	  //-----------------------------------------------------------------------------------------
	  if ( caloData->layers.size() < (unsigned int)repeat ) {

	    caloLayer.distance = HcalEndcap_min_z + box_half_y + layer_pos_y
	      - caloLayer.inner_thickness ; // Will be added later at "DDMarlinPandora/DDGeometryCreator.cc:226" to get center of sensitive element
	    caloLayer.absorberThickness = Hcal_radiator_thickness ;
	    
	    caloData->layers.push_back( caloLayer ) ;
	  }
	  //-----------------------------------------------------------------------------------------
	  
	  
	  // ===== Prepare for next layer (i.e. next Chamber) =========================
	  // Prepare the chamber placement position and the chamber dimension
	  // ==========================================================================
	  
	  // Increment the layer_pos_y
	  // Place Hcal Chamber after each radiator 
	  layer_pos_y += layer_thickness / 2.0;
	  layer_pos_y += Hcal_radiator_thickness;
	  ++layer_num;         
	}
	
	
      }
      
      
      // =========== Place Hcal Endcap envelope ===================================
      // Finally place the Hcal Endcap envelope into the world volume.
      // Registry the stave(up/down), module(left/right) and endcapID.
      // ==========================================================================
      
      // Acording to the number of staves and modules,
      // Place the same Hcal Endcap module volume into the world volume
      // with the right position and rotation.
      for(int stave_num=0;stave_num<2;stave_num++){
	
	double EndcapModule_pos_x = 0;
	double EndcapModule_pos_y = 0;
	double EndcapModule_pos_z = 0;
	double rot_EM = 0;

	double EndcapModule_center_pos_z = HcalEndcap_min_z + box_half_y;

	double FEEModule_pos_x = 0;
	double FEEModule_pos_y = 0;
	double FEEModule_pos_z = 0;
	double FEEModule_center_pos_z = HcalEndcap_min_z + box_half_y;
	
	switch (stave_num)
	  {
	  case 0 : 
	    EndcapModule_pos_x = x_offset;
	    EndcapModule_pos_y = y_offset;
	    FEEModule_pos_x = x_offset;
	    FEEModule_pos_y = y_offset + box_half_z + Hcal_endcap_services_module_width/2.0;
	    break;
	  case 1 : 
	    EndcapModule_pos_x = -x_offset;
	    EndcapModule_pos_y = -y_offset;
	    FEEModule_pos_x = -x_offset;
	    FEEModule_pos_y = -y_offset - box_half_z - Hcal_endcap_services_module_width/2.0;
	    break;
	  }
	
	for(int module_num=0;module_num<2;module_num++) {

	  int module_id = (module_num==0)? 0:6;
	  
	  rot_EM = (module_id==0)?(-M_PI/2.0):(M_PI/2.0);
	  
	  EndcapModule_pos_z = (module_id==0)? -EndcapModule_center_pos_z:EndcapModule_center_pos_z;

	  PlacedVolume env_phv = envelope.placeVolume(envelopeVol,
						      Transform3D(RotationX(rot_EM),
								  Translation3D(EndcapModule_pos_x,
										EndcapModule_pos_y,
										EndcapModule_pos_z)));
	  env_phv.addPhysVolID("tower",endcapID);	  
	  env_phv.addPhysVolID("stave",stave_num);   // y: up /down
	  env_phv.addPhysVolID("module",module_id); // z: -/+ 0/6
	  env_phv.addPhysVolID("system",det_id);


	  FEEModule_pos_z = (module_id==0)? -FEEModule_center_pos_z:FEEModule_center_pos_z;

	  if (!(endcapID==0))
	    env_phv = envelope.placeVolume(FEEModule,
					   Transform3D(RotationX(rot_EM),
						       Translation3D(FEEModule_pos_x,
								     FEEModule_pos_y,
								     FEEModule_pos_z)));


	  DetElement sd = (module_num==0&&stave_num==0) ? stave_det : stave_det.clone(_toString(module_id,"module%d")+_toString(stave_num,"stave%d"));	  
	  sd.setPlacement(env_phv);	  

	}
	
      }

    endcapID++;
      
    }
  
  sdet.addExtension< LayeredCalorimeterData >( caloData ) ;  
  
  return sdet;
}
Example #22
0
static Ref_t create_detector(Detector& theDetector, xml_h element, SensitiveDetector sens)  {
  static double tolerance = 0e0;

  xml_det_t     x_det     = element;
  string        det_name  = x_det.nameStr();
  Layering      layering (element);

  Material      air       = theDetector.air();
  //unused: Material      vacuum    = theDetector.vacuum();

  int           det_id    = x_det.id();
  xml_comp_t    x_staves  = x_det.staves();
  DetElement    sdet      (det_name,det_id);

  xml_comp_t    x_dim     = x_det.dimensions();
  int           nsides    = x_dim.numsides();
  double        dphi      = (2*M_PI/nsides);
  double        hphi      = dphi/2;


 // --- create an envelope volume and position it into the world ---------------------

  Volume envelope = dd4hep::xml::createPlacedEnvelope( theDetector,  element , sdet ) ;

  dd4hep::xml::setDetectorTypeFlag( element, sdet ) ;
 
  if( theDetector.buildType() == BUILD_ENVELOPE ) return sdet ;

  //-----------------------------------------------------------------------------------


  sens.setType("calorimeter");

  Material stave_material  = theDetector.material(x_staves.materialStr());

  DetElement    stave_det("module0stave0",det_id);

  Readout readout = sens.readout();
  Segmentation seg = readout.segmentation();
  
  // check if we have a WaferGridXY segmentation :
  WaferGridXY* waferSeg = 
    dynamic_cast< WaferGridXY*>( seg.segmentation() ) ;

  std::vector<double> cellSizeVector = seg.segmentation()->cellDimensions(0); //Assume uniform cell sizes, provide dummy cellID
  double cell_sizeX      = cellSizeVector[0];
  double cell_sizeY      = cellSizeVector[1];

//====================================================================
//
// Read all the constant from ILD_o1_v05.xml
// Use them to build HcalBarrel
//
//====================================================================

  int N_FIBERS_W_STRUCTURE = 2; 
  int N_FIBERS_ALVOULUS = 3;

  //  read parametere from compact.xml file
  double Ecal_Alveolus_Air_Gap              = theDetector.constant<double>("Ecal_Alveolus_Air_Gap");
  double Ecal_Slab_shielding                = theDetector.constant<double>("Ecal_Slab_shielding");
  double Ecal_Slab_copper_thickness         = theDetector.constant<double>("Ecal_Slab_copper_thickness");
  double Ecal_Slab_PCB_thickness            = theDetector.constant<double>("Ecal_Slab_PCB_thickness");
  double Ecal_Slab_glue_gap                 = theDetector.constant<double>("Ecal_Slab_glue_gap");
  double Ecal_Slab_ground_thickness         = theDetector.constant<double>("Ecal_Slab_ground_thickness");
  double Ecal_fiber_thickness               = theDetector.constant<double>("Ecal_fiber_thickness");
  double Ecal_Si_thickness                  = theDetector.constant<double>("Ecal_Si_thickness");
  
  double Ecal_inner_radius                  = theDetector.constant<double>("TPC_outer_radius") +theDetector.constant<double>("Ecal_Tpc_gap");
  double Ecal_radiator_thickness1           = theDetector.constant<double>("Ecal_radiator_layers_set1_thickness");
  double Ecal_radiator_thickness2           = theDetector.constant<double>("Ecal_radiator_layers_set2_thickness");
  double Ecal_radiator_thickness3           = theDetector.constant<double>("Ecal_radiator_layers_set3_thickness");
  double Ecal_Barrel_halfZ                  = theDetector.constant<double>("Ecal_Barrel_halfZ");
  
  double Ecal_support_thickness             = theDetector.constant<double>("Ecal_support_thickness");
  double Ecal_front_face_thickness          = theDetector.constant<double>("Ecal_front_face_thickness");
  double Ecal_lateral_face_thickness        = theDetector.constant<double>("Ecal_lateral_face_thickness");
  double Ecal_Slab_H_fiber_thickness        = theDetector.constant<double>("Ecal_Slab_H_fiber_thickness");

  double Ecal_Slab_Sc_PCB_thickness         = theDetector.constant<double>("Ecal_Slab_Sc_PCB_thickness");
  double Ecal_Sc_thickness                  = theDetector.constant<double>("Ecal_Sc_thickness");
  double Ecal_Sc_reflector_thickness        = theDetector.constant<double>("Ecal_Sc_reflector_thickness");

  int    Ecal_nlayers1                      = theDetector.constant<int>("Ecal_nlayers1");
  int    Ecal_nlayers2                      = theDetector.constant<int>("Ecal_nlayers2");
  int    Ecal_nlayers3                      = theDetector.constant<int>("Ecal_nlayers3");
  int    Ecal_barrel_number_of_towers       = theDetector.constant<int>("Ecal_barrel_number_of_towers");
  
  //double      Ecal_cells_size                  = theDetector.constant<double>("Ecal_cells_size");
  double Ecal_guard_ring_size               = theDetector.constant<double>("Ecal_guard_ring_size");
  
//====================================================================
//
// general calculated parameters
//
//====================================================================
  
  double Ecal_total_SiSlab_thickness = 
    Ecal_Slab_shielding + 
    Ecal_Slab_copper_thickness + 
    Ecal_Slab_PCB_thickness +
    Ecal_Slab_glue_gap + 
    Ecal_Si_thickness + 
    Ecal_Slab_ground_thickness +
    Ecal_Alveolus_Air_Gap / 2;
#ifdef VERBOSE
  std::cout << " Ecal_total_SiSlab_thickness = " << Ecal_total_SiSlab_thickness  << std::endl;
#endif
  
  

  double Ecal_total_ScSlab_thickness = 
    Ecal_Slab_shielding + 
    Ecal_Slab_copper_thickness + 
    Ecal_Slab_Sc_PCB_thickness +
    Ecal_Sc_thickness + 
    Ecal_Sc_reflector_thickness * 2 +
    Ecal_Alveolus_Air_Gap / 2;
#ifdef VERBOSE
  std::cout << " Ecal_total_ScSlab_thickness = " << Ecal_total_ScSlab_thickness  << std::endl;
#endif
  

    int Number_of_Si_Layers_in_Barrel = 0;
    int Number_of_Sc_Layers_in_Barrel = 0;


#ifdef VERBOSE
  std::cout << " Ecal total number of Silicon layers = " << Number_of_Si_Layers_in_Barrel  << std::endl;
  std::cout << " Ecal total number of Scintillator layers = " << Number_of_Sc_Layers_in_Barrel  << std::endl;
#endif
  
  // In this release the number of modules is fixed to 5
  double Ecal_Barrel_module_dim_z = 2 * Ecal_Barrel_halfZ / 5. ;
#ifdef VERBOSE
  std::cout << "Ecal_Barrel_module_dim_z  = " << Ecal_Barrel_module_dim_z  << std::endl;
#endif

  // The alveolus size takes in account the module Z size
  // but also 4 fiber layers for the alveoulus wall, the all
  // divided by the number of towers
  double alveolus_dim_z = 
    (Ecal_Barrel_module_dim_z - 2. * Ecal_lateral_face_thickness) /
    Ecal_barrel_number_of_towers - 
    2 * N_FIBERS_ALVOULUS  * Ecal_fiber_thickness  - 
    2 * Ecal_Slab_H_fiber_thickness -
    2 * Ecal_Slab_shielding;


#ifdef VERBOSE
  std::cout << "alveolus_dim_z = " <<  alveolus_dim_z << std::endl;
#endif

  int n_total_layers = Ecal_nlayers1 + Ecal_nlayers2 + Ecal_nlayers3;
  Number_of_Si_Layers_in_Barrel = n_total_layers+1;

  double module_thickness = 
    Ecal_nlayers1 * Ecal_radiator_thickness1 +
    Ecal_nlayers2 * Ecal_radiator_thickness2 +
    Ecal_nlayers3 * Ecal_radiator_thickness3 +
    
    int(n_total_layers/2) * // fiber around W struct layers
    (N_FIBERS_W_STRUCTURE * 2 *  Ecal_fiber_thickness) +
    
    Number_of_Si_Layers_in_Barrel * // Silicon slabs plus fiber around and inside
    (Ecal_total_SiSlab_thickness +
     (N_FIBERS_ALVOULUS + 1 ) * Ecal_fiber_thickness) +
    
    Number_of_Sc_Layers_in_Barrel * // Scintillator slabs plus fiber around and inside
    (Ecal_total_ScSlab_thickness +
     (N_FIBERS_ALVOULUS + 1 ) * Ecal_fiber_thickness) +
    
    Ecal_support_thickness + Ecal_front_face_thickness;
  
#ifdef VERBOSE
  std::cout << "For information : module_thickness = " << module_thickness  << std::endl;
#endif
  
  // module barrel key parameters
  double  bottom_dim_x = 2. * tan(M_PI/8.) * Ecal_inner_radius +
    module_thickness/sin(M_PI/4.);
  
  double top_dim_x = bottom_dim_x - 2 * module_thickness;

  //------------------------------------------------------------------------------------

  LayeredCalorimeterData::Layer caloLayer ;
  caloLayer.cellSize0 = cell_sizeX;
  caloLayer.cellSize1 = cell_sizeY;

  //== For Wafer ===  
  double cell_dim_x = caloLayer.cellSize0;
  double total_Si_dim_z = alveolus_dim_z;

  double util_SI_wafer_dim_z = 
    total_Si_dim_z/2 -  2 * Ecal_guard_ring_size;

  double cell_dim_z =  util_SI_wafer_dim_z/ 
    floor(util_SI_wafer_dim_z/
	  cell_dim_x);

  int N_cells_in_Z = int(util_SI_wafer_dim_z/cell_dim_z);
  int N_cells_in_X = N_cells_in_Z;
  
  cell_dim_x = cell_dim_z;


  
#ifdef VERBOSE
  std::cout << " bottom_dim_x = " << bottom_dim_x  << std::endl;
  std::cout << " top_dim_x = " << top_dim_x << std::endl;
  std::cout << " Ecal total number of Silicon layers = " << Number_of_Si_Layers_in_Barrel  << std::endl;
  std::cout << " Ecal total number of Scintillator layers = " << Number_of_Sc_Layers_in_Barrel  << std::endl;
#endif
  


// ========= Create Ecal Barrel stave   ====================================
//  It will be the volume for palcing the Ecal Barrel alveolus(i.e. Layers).
//  And the structure W plate.
//  Itself will be placed into the world volume.
// ==========================================================================

  // The TOP_X and BOTTOM_X is different in Mokka and DD4hep
  Trapezoid trd(top_dim_x / 2,
		bottom_dim_x / 2, 
		Ecal_Barrel_module_dim_z / 2,
		Ecal_Barrel_module_dim_z / 2,
		module_thickness/2);

  //  Volume mod_vol(det_name+"_module",trd,theDetector.material("g10"));
  Volume mod_vol(det_name+"_module",trd,theDetector.material("CarbonFiber")); // DJeans 5-sep-2016

  // We count the layers starting from IP and from 1,
  // so odd layers should be inside slabs and
  // even ones on the structure.
  // The structure W layers are here big plans, as the 
  // gap between each W plate is too small to create problems 
  // The even W layers are part of H structure placed inside
  // the alveolus.

  // ############################
  //  Dimension of radiator wLog
  //  slice provide the thickness
  // ############################


  double y_floor = 
    Ecal_front_face_thickness +
    N_FIBERS_ALVOULUS * Ecal_fiber_thickness;


  // ############################
  //  Dimension of alveolus
  //  slice provide the thickness
  // ############################
  
    // =====  build Si Slab and put into the Layer volume =====
    // =====  place the layer into the module 5 time for one full layer into the trd module ====
    // =====  build and place barrel structure into trd module ====
    // Parameters for computing the layer X dimension:
    double stave_z  =(Ecal_Barrel_module_dim_z - 2. * Ecal_lateral_face_thickness) / Ecal_barrel_number_of_towers/2.;
    double l_dim_x  = bottom_dim_x/2.;                            // Starting X dimension for the layer.
    double l_pos_z  = module_thickness/2;

    l_dim_x -= y_floor;
    l_pos_z -= y_floor;


    // ------------- create extension objects for reconstruction -----------------
    
    //========== fill data for reconstruction ============================
    LayeredCalorimeterData* caloData = new LayeredCalorimeterData ;
    caloData->layoutType = LayeredCalorimeterData::BarrelLayout ;
    caloData->inner_symmetry = nsides  ;
    //added by Thorben Quast
    caloData->outer_symmetry = nsides  ;
    caloData->phi0 = 0 ; // hardcoded 
    
    /// extent of the calorimeter in the r-z-plane [ rmin, rmax, zmin, zmax ] in mm.
    caloData->extent[0] = Ecal_inner_radius ;
    //line fixed by Thorben Quast since actual conversion is made during the drawing
    caloData->extent[1] = ( Ecal_inner_radius + module_thickness );
    //caloData->extent[1] = ( Ecal_inner_radius + module_thickness ) / cos( M_PI/8. ) ;
    caloData->extent[2] = 0. ;
    caloData->extent[3] = Ecal_Barrel_halfZ ;

    // // base vectors for surfaces:
    // dd4hep::rec::Vector3D u(1,0,0) ;
    // dd4hep::rec::Vector3D v(0,1,0) ;
    // dd4hep::rec::Vector3D n(0,0,1) ;


    //-------------------- start loop over ECAL layers ----------------------
    // Loop over the sets of layer elements in the detector.

    double nRadiationLengths   = 0. ;
    double nInteractionLengths = 0. ;
    double thickness_sum       = 0. ;

    nRadiationLengths   = Ecal_radiator_thickness1/(stave_material.radLength())
      + y_floor/air.radLength();
    nInteractionLengths = Ecal_radiator_thickness1/(stave_material.intLength())
      + y_floor/air.intLength();
    thickness_sum       = Ecal_radiator_thickness1 + y_floor;

    int l_num = 1;
    bool isFirstSens = true;
    int myLayerNum = 0 ;

    for(xml_coll_t li(x_det,_U(layer)); li; ++li)  {
      xml_comp_t x_layer = li;
      int repeat = x_layer.repeat();
      // Loop over number of repeats for this layer.
      for (int j=0; j<repeat; j++)    {
	string l_name = _toString(l_num,"layer%d");
	double l_thickness = layering.layer(l_num-1)->thickness();  // Layer's thickness.
	double xcut = (l_thickness);                     // X dimension for this layer.
	l_dim_x -= xcut;


	Box        l_box(l_dim_x-tolerance,stave_z-tolerance,l_thickness/2.0-tolerance);
	Volume     l_vol(det_name+"_"+l_name,l_box,air);

	l_vol.setVisAttributes(theDetector.visAttributes(x_layer.visStr()));

	//fg: need vector of DetElements for towers ! 
	//    DetElement layer(stave_det, l_name, det_id);
	std::vector< DetElement > layers( Ecal_barrel_number_of_towers )  ;
	
	// place layer 5 times in module. at same layer position (towers !)
	double l_pos_y = Ecal_Barrel_module_dim_z / 2. 
	  - ( Ecal_lateral_face_thickness +
	      Ecal_fiber_thickness * N_FIBERS_ALVOULUS +
	      Ecal_Slab_shielding + 
	      Ecal_Slab_H_fiber_thickness +
	      alveolus_dim_z /2.);						  
       	for (int i=0; i<Ecal_barrel_number_of_towers; i++){ // need four clone

	  layers[i] = DetElement( stave_det, l_name+_toString(i,"tower%02d") , det_id ) ;

	  Position   l_pos(0,l_pos_y,l_pos_z-l_thickness/2.);      // Position of the layer.
	  PlacedVolume layer_phv = mod_vol.placeVolume(l_vol,l_pos);
	  // layer_phv.addPhysVolID("layer", l_num);
	  layer_phv.addPhysVolID("tower", i);

	  layers[i].setPlacement(layer_phv);
	  l_pos_y -= (alveolus_dim_z + 
		      2. * Ecal_fiber_thickness * N_FIBERS_ALVOULUS +
		      2. * Ecal_Slab_H_fiber_thickness +
		      2. * Ecal_Slab_shielding);
	}




	// Loop over the sublayers or slices for this layer.
	int s_num = 1;
	double s_pos_z = l_thickness / 2.;


	//--------------------------------------------------------------------------------
	// BuildBarrelAlveolus: BuildSiliconSlab:
	//--------------------------------------------------------------------------------
	double radiator_dim_y = Ecal_radiator_thickness1; //to be updated with slice radiator thickness 

	for(xml_coll_t si(x_layer,_U(slice)); si; ++si)  {
	  xml_comp_t x_slice = si;
	  string     s_name  =  _toString(s_num,"slice%d");
	  double     s_thick = x_slice.thickness();
	  Material slice_material  = theDetector.material(x_slice.materialStr());
#ifdef VERBOSE
	  std::cout<<"Ecal_barrel_number_of_towers: "<< Ecal_barrel_number_of_towers <<std::endl;
#endif
	  double slab_dim_x = l_dim_x-tolerance;
	  double slab_dim_y = s_thick/2.;
	  double slab_dim_z = stave_z-tolerance;

	  Box        s_box(slab_dim_x,slab_dim_z,slab_dim_y);
	  Volume     s_vol(det_name+"_"+l_name+"_"+s_name,s_box,slice_material);
	  //fg: not needed          DetElement slice(layer,s_name,det_id);

	  s_vol.setVisAttributes(theDetector.visAttributes(x_slice.visStr()));
#ifdef VERBOSE
	  std::cout<<"x_slice.materialStr(): "<< x_slice.materialStr() <<std::endl;
#endif
	  if (x_slice.materialStr().compare(x_staves.materialStr()) == 0){
	    radiator_dim_y = s_thick;
	  // W StructureLayer has the same thickness as W radiator layer in the Alveolus layer
	    
#if DD4HEP_VERSION_GE( 0, 15 )
	    caloLayer.outer_nRadiationLengths   = nRadiationLengths;
	    caloLayer.outer_nInteractionLengths = nInteractionLengths;
	    caloLayer.outer_thickness           = thickness_sum;

	    if (!isFirstSens){ caloData->layers.push_back( caloLayer ) ;
#ifdef VERBOSE
	    std::cout<<" caloLayer.distance: "<< caloLayer.distance <<std::endl;

	    std::cout<<" caloLayer.inner_nRadiationLengths: "<< caloLayer.inner_nRadiationLengths <<std::endl;
	    std::cout<<" caloLayer.inner_nInteractionLengths: "<< caloLayer.inner_nInteractionLengths <<std::endl;
	    std::cout<<" caloLayer.inner_thickness: "<< caloLayer.inner_thickness <<std::endl;
	    std::cout<<" caloLayer.sensitive_thickness: "<< caloLayer.sensitive_thickness <<std::endl;

	    std::cout<<" caloLayer.outer_nRadiationLengths: "<< caloLayer.outer_nRadiationLengths <<std::endl;
	    std::cout<<" caloLayer.outer_nInteractionLengths: "<< caloLayer.outer_nInteractionLengths <<std::endl;
	    std::cout<<" caloLayer.outer_thickness: "<< caloLayer.outer_thickness <<std::endl;

	    std::cout<<" EcalBarrel[1]==>caloLayer.inner_thickness + caloLayer.outer_thickness: "
		     << caloLayer.inner_thickness + caloLayer.outer_thickness <<std::endl;
#endif
	    }
#endif
	    // Init for inner
	    nRadiationLengths   = 0. ;
	    nInteractionLengths = 0. ;
	    thickness_sum       = 0. ;	    
	    isFirstSens         = false;

	  }
	  nRadiationLengths   += s_thick/(2.*slice_material.radLength());
	  nInteractionLengths += s_thick/(2.*slice_material.intLength());
	  thickness_sum       += s_thick/2.;

          if ( x_slice.isSensitive() ) {
	    //s_vol.setSensitiveDetector(sens);

	    // Normal squared wafers
	    double wafer_dim_x = 
	      N_cells_in_X * cell_dim_x;
	    double wafer_dim_z = 
	      N_cells_in_Z * cell_dim_z;
	    Box WaferSiSolid( wafer_dim_x/2,wafer_dim_z/2,slab_dim_y);
	    //Volume WaferSiLog(det_name+"_"+l_name+"_"+s_name+"Wafer",WaferSiSolid,slice_material);
	    //WaferSiLog.setSensitiveDetector(sens);

	    double real_wafer_size_x =
	      wafer_dim_x + 2 * Ecal_guard_ring_size;
      
	    int n_wafers_x =
	      int(floor(slab_dim_x*2 / real_wafer_size_x));
      
	    double wafer_pos_x =
	      -slab_dim_x + 
	      Ecal_guard_ring_size +
	      wafer_dim_x /2 ;
	    int n_wafer_x;
	    int wafer_num = 0;
	    for (n_wafer_x = 1;
		 n_wafer_x < n_wafers_x + 1;
		 n_wafer_x++)
	      {
		double wafer_pos_z =
		  -alveolus_dim_z/2.0 + 
		  Ecal_guard_ring_size +
		  wafer_dim_z /2;
		for (int n_wafer_z = 1;
		     n_wafer_z < 3;
		     n_wafer_z++)
		  {
		    wafer_num++;
		    string Wafer_name  =  _toString(wafer_num,"wafer%d");
		    Volume WaferSiLog(det_name+"_"+l_name+"_"+s_name+"_"+Wafer_name,WaferSiSolid,slice_material);
		    WaferSiLog.setSensitiveDetector(sens);
		    //WaferSiLog.setVisAttributes(theDetector.visAttributes(x_slice.visStr()));
		    PlacedVolume wafer_phv = s_vol.placeVolume(WaferSiLog,Position(wafer_pos_x,
							  wafer_pos_z,
							  0));
		    wafer_phv.addPhysVolID("wafer", wafer_num);

		    // Normal squared wafers, this waferOffsetX is 0.0 
		    waferSeg->setWaferOffsetX(myLayerNum, wafer_num, 0.0);

		    wafer_pos_z +=
		      wafer_dim_z +
		      2 * Ecal_guard_ring_size;
		  }
		wafer_pos_x += 
		  wafer_dim_x +
		  2 * Ecal_guard_ring_size;
	      }

	    // Magic wafers to complete the slab...
	    // (wafers with variable number of cells just
	    // to complete the slab. in reality we think that
	    // we'll have just a few models of special wafers
	    // for that.
	    double resting_dim_x =
	      slab_dim_x*2 - 
	      (wafer_dim_x + 2 * Ecal_guard_ring_size) * 
	      n_wafers_x;

	    if(resting_dim_x >
	       (cell_dim_x + 2 * Ecal_guard_ring_size))
	      {
		int N_cells_x_remaining =
		  int(floor((resting_dim_x - 
			     2 * Ecal_guard_ring_size)
			    /cell_dim_x));
		
		wafer_dim_x =
		  N_cells_x_remaining *
		  cell_dim_x;
		
		Box MagicWaferSiSolid( wafer_dim_x/2,wafer_dim_z/2,slab_dim_y);
		//Volume MagicWaferSiLog(det_name+"_"+l_name+"_"+s_name+"MagicWafer",MagicWaferSiSolid,slice_material);

		// Magic wafers, this waferOffsetX has to be taken care, 0.0 or half cell size in X.
		double thisWaferOffsetX = 0.0;
		if ( N_cells_x_remaining%2 ) thisWaferOffsetX = cell_dim_x/2.0;

		wafer_pos_x =
		  -slab_dim_x +
		  n_wafers_x * real_wafer_size_x +
		  (wafer_dim_x + 2 * Ecal_guard_ring_size)/2;
	  
		real_wafer_size_x =
		  wafer_dim_x + 2 * Ecal_guard_ring_size;
	  
		double wafer_pos_z =
		  -alveolus_dim_z/2.0 + 
		  Ecal_guard_ring_size +
		  wafer_dim_z /2;

		//int MagicWafer_num = 0;
		for (int n_wafer_z = 1;
		     n_wafer_z < 3;
		     n_wafer_z++)
		  {
		    wafer_num++;
		    string MagicWafer_name  =  _toString(wafer_num,"MagicWafer%d");
		    Volume MagicWaferSiLog(det_name+"_"+l_name+"_"+s_name+"_"+MagicWafer_name,MagicWaferSiSolid,slice_material);
		    MagicWaferSiLog.setSensitiveDetector(sens);
		    //MagicWaferSiLog.setVisAttributes(theDetector.visAttributes(x_slice.visStr()));
		    PlacedVolume wafer_phv = s_vol.placeVolume(MagicWaferSiLog,Position(wafer_pos_x,
							       wafer_pos_z,
							       0));
		    wafer_phv.addPhysVolID("wafer", wafer_num);

		    // Magic wafers, set the waferOffsetX for this layer this wafer.
		    waferSeg->setWaferOffsetX(myLayerNum, wafer_num, thisWaferOffsetX);

		    wafer_pos_z +=
		      wafer_dim_z +
		      2 * Ecal_guard_ring_size;
		  }
	      }
	    

#if DD4HEP_VERSION_GE( 0, 15 )
	    //Store "inner" quantities
	    caloLayer.inner_nRadiationLengths   = nRadiationLengths ;
	    caloLayer.inner_nInteractionLengths = nInteractionLengths ;
	    caloLayer.inner_thickness           = thickness_sum ;
	    //Store sensitive slice thickness
	    caloLayer.sensitive_thickness       = s_thick ;
#ifdef VERBOSE	    
	    std::cout<<" l_num: "<<l_num <<std::endl;
	    std::cout<<" s_num: "<<s_num <<std::endl;
	    std::cout<<" Ecal_inner_radius: "<< Ecal_inner_radius <<std::endl;
	    std::cout<<" module_thickness: "<< module_thickness <<std::endl;
	    std::cout<<" l_pos_z: "<< l_pos_z <<std::endl;
	    std::cout<<" l_thickness: "<< l_thickness <<std::endl;
	    std::cout<<" s_pos_z: "<< s_pos_z <<std::endl;
	    std::cout<<" s_thick: "<< s_thick <<std::endl;
	    std::cout<<" radiator_dim_y: "<< radiator_dim_y <<std::endl;
#endif	    
	    //-----------------------------------------------------------------------------------------
	    caloLayer.distance  = Ecal_inner_radius + module_thickness/2.0 - l_pos_z + l_thickness/2. + (s_pos_z+s_thick/2.) 
	      - caloLayer.inner_thickness;
	    caloLayer.absorberThickness = radiator_dim_y ;

	    //-----------------------------------------------------------------------------------------
#endif
	    // Init for outer
	    nRadiationLengths   = 0. ;
	    nInteractionLengths = 0. ;
	    thickness_sum       = 0. ;

	  }

	  nRadiationLengths   += s_thick/(2.*slice_material.radLength());
	  nInteractionLengths += s_thick/(2.*slice_material.intLength());
	  thickness_sum       += s_thick/2;


          // Slice placement.
          PlacedVolume slice_phv = l_vol.placeVolume(s_vol,Position(0,0,s_pos_z-s_thick/2));

          if ( x_slice.isSensitive() ) {
	    slice_phv.addPhysVolID("layer", myLayerNum++ );
	    //	    slice_phv.addPhysVolID("slice",s_num);
	  }

	  //fg: not needed   slice.setPlacement(slice_phv);

          // Increment Z position of slice.
          s_pos_z -= s_thick;
                                        
          // Increment slice number.
          ++s_num;

        }        

#if DD4HEP_VERSION_GE( 0, 15 )
	caloLayer.outer_nRadiationLengths   = nRadiationLengths
	  + (Ecal_fiber_thickness * (N_FIBERS_ALVOULUS + N_FIBERS_W_STRUCTURE))/air.radLength();
	caloLayer.outer_nInteractionLengths = nInteractionLengths
	  + (Ecal_fiber_thickness * (N_FIBERS_ALVOULUS + N_FIBERS_W_STRUCTURE))/air.intLength();
	caloLayer.outer_thickness           = thickness_sum 
	  + (Ecal_fiber_thickness * (N_FIBERS_ALVOULUS + N_FIBERS_W_STRUCTURE));

	if (!isFirstSens) caloData->layers.push_back( caloLayer ) ;
#ifdef VERBOSE
	std::cout<<" caloLayer.distance: "<< caloLayer.distance <<std::endl;
	
	std::cout<<" caloLayer.inner_nRadiationLengths: "<< caloLayer.inner_nRadiationLengths <<std::endl;
	std::cout<<" caloLayer.inner_nInteractionLengths: "<< caloLayer.inner_nInteractionLengths <<std::endl;
	std::cout<<" caloLayer.inner_thickness: "<< caloLayer.inner_thickness <<std::endl;
	std::cout<<" caloLayer.sensitive_thickness: "<< caloLayer.sensitive_thickness <<std::endl;

	std::cout<<" caloLayer.outer_nRadiationLengths: "<< caloLayer.outer_nRadiationLengths <<std::endl;
	std::cout<<" caloLayer.outer_nInteractionLengths: "<< caloLayer.outer_nInteractionLengths <<std::endl;
	std::cout<<" caloLayer.outer_thickness: "<< caloLayer.outer_thickness <<std::endl;

	std::cout<<" EcalBarrel[2]==>caloLayer.inner_thickness + caloLayer.outer_thickness: "
		 << caloLayer.inner_thickness + caloLayer.outer_thickness <<std::endl;
#endif
#endif
	// Init for next double layer
	nRadiationLengths   = radiator_dim_y/(stave_material.radLength())
	  + (Ecal_fiber_thickness * (N_FIBERS_ALVOULUS + N_FIBERS_W_STRUCTURE))/air.radLength();
	nInteractionLengths = radiator_dim_y/(stave_material.intLength())
	  + (Ecal_fiber_thickness * (N_FIBERS_ALVOULUS + N_FIBERS_W_STRUCTURE))/air.intLength();
	thickness_sum       = radiator_dim_y
	  + (Ecal_fiber_thickness * (N_FIBERS_ALVOULUS + N_FIBERS_W_STRUCTURE));
	
	if(radiator_dim_y <= 0) {
	  stringstream err;
	  err << " \n ERROR: The subdetector " << x_det.nameStr() << " geometry parameter -- radiator_dim_y = " << radiator_dim_y ;
	  err << " \n Please check the radiator material name in the subdetector xml file";
	  throw runtime_error(err.str());
	}

	// #########################
	// BuildBarrelStructureLayer
	// #########################


	l_dim_x -=  (radiator_dim_y +  Ecal_fiber_thickness * (N_FIBERS_ALVOULUS + N_FIBERS_W_STRUCTURE));
	double radiator_dim_x = l_dim_x*2.;

#ifdef VERBOSE
	std::cout << "radiator_dim_x = " << radiator_dim_x << std::endl;
#endif  

	double radiator_dim_z =
	  Ecal_Barrel_module_dim_z -
	  2 * Ecal_lateral_face_thickness -
	  2 * N_FIBERS_W_STRUCTURE * Ecal_fiber_thickness;
	
	string bs_name="bs";
	Box        barrelStructureLayer_box(radiator_dim_x/2.,radiator_dim_z/2.,radiator_dim_y/2.);
	Volume     barrelStructureLayer_vol(det_name+"_"+l_name+"_"+bs_name,barrelStructureLayer_box,stave_material);

	barrelStructureLayer_vol.setVisAttributes(theDetector.visAttributes(x_layer.visStr()));	


        // Increment to next layer Z position.
        l_pos_z -= l_thickness;          

	// Without last W StructureLayer, the last part is Si SD even layer.
	// the last number of  Ecal_nlayers1, Ecal_nlayers2 and  Ecal_nlayers3 is odd.
	int even_layer = l_num*2;
	if(even_layer > Ecal_nlayers1 + Ecal_nlayers2 + Ecal_nlayers3) continue;
	//if ( Number_of_Si_Layers_in_Barrel > n_total_layers ) continue;

	double bsl_pos_z = l_pos_z - (radiator_dim_y/2. + Ecal_fiber_thickness * (N_FIBERS_ALVOULUS + N_FIBERS_W_STRUCTURE));
	l_pos_z -= (Ecal_fiber_thickness * (N_FIBERS_ALVOULUS + N_FIBERS_W_STRUCTURE));

	Position   bsl_pos(0,0,bsl_pos_z);      // Position of the layer.
	// PlacedVolume  barrelStructureLayer_phv =
	  mod_vol.placeVolume(barrelStructureLayer_vol,bsl_pos);

	l_dim_x -=  (Ecal_fiber_thickness * (N_FIBERS_ALVOULUS + N_FIBERS_W_STRUCTURE));	
	l_pos_z -= (radiator_dim_y + Ecal_fiber_thickness * (N_FIBERS_ALVOULUS + N_FIBERS_W_STRUCTURE));
	
        ++l_num;

      }
    }
  

    // Set stave visualization.
    if (x_staves)   {
      mod_vol.setVisAttributes(theDetector.visAttributes(x_staves.visStr()));
    }
    
    
    
//====================================================================
// Place ECAL Barrel stave module into the envelope volume
//====================================================================
    double X,Y;
    X = module_thickness * sin(M_PI/4.);
    Y = Ecal_inner_radius + module_thickness / 2.;
    
    for (int stave_id = 1; stave_id <= nsides ; stave_id++)
      for (int module_id = 1; module_id < 6; module_id++)
	{
	  double phirot =  (stave_id-1) * dphi - hphi*3.0;
	  double module_z_offset =  (2 * module_id-6) * Ecal_Barrel_module_dim_z/2.;
	  
	  // And the rotation in Mokka is right hand rule, and the rotation in DD4hep is clockwise rule
	  // So there is a negitive sign when port Mokka into DD4hep 
	  Transform3D tr(RotationZYX(0,phirot,M_PI*0.5),Translation3D(X*cos(phirot)-Y*sin(phirot),
								      X*sin(phirot)+Y*cos(phirot),
								      module_z_offset));
	  PlacedVolume pv = envelope.placeVolume(mod_vol,tr);
	  pv.addPhysVolID("module",module_id);
	  pv.addPhysVolID("stave",stave_id);
	  DetElement sd = (module_id==0&&stave_id==0) ? stave_det : stave_det.clone(_toString(module_id,"module%d")+_toString(stave_id,"stave%d"));
	  sd.setPlacement(pv);
	  sdet.add(sd);
	  
	}
    
    // Set envelope volume attributes.
    envelope.setAttributes(theDetector,x_det.regionStr(),x_det.limitsStr(),x_det.visStr());
    
    sdet.addExtension< LayeredCalorimeterData >( caloData ) ; 


    return sdet;
}
int main(int argc, char *argv[]) {

    //std::cout << "Running mrisegmentation.cpp..." << std::endl;
    if (argc != 12) {
        cerr << "#arguments = " << argc << endl;
        cerr <<
        "Usage: dist mrivolume.bin seeds.bin #rows #columns #layers #bands samplingdensity [a|c|f|g|m] [m|p|*] neighborhoodSize segmentation.bin" <<
        endl;
        exit(1);
    }
    // read input parameters
    char *volumeFilename, *seedsFilename, *segmentationFilename;
    char distanceMeasureType, normType;
    int nRows, nColumns, nLayers, nBands, neighborhoodSize;
    double inputDensity, outputDensity;
    volumeFilename = argv[1];
    seedsFilename = argv[2];
    nRows = atoi(argv[3]);
    nColumns = atoi(argv[4]);
    nLayers = atoi(argv[5]);
    nBands = atoi(argv[6]);
    inputDensity = atof(argv[7]);
    distanceMeasureType = *argv[8];
    normType = *argv[9];
    neighborhoodSize = atoi(argv[10]);
    segmentationFilename = argv[11];

    int nElements = nRows * nColumns * nLayers;

    // create input image
    double *volumeData;
    volumeData = readVolume(volumeFilename, nElements * nBands);
    CCLattice lattice(nRows, nColumns, nLayers, inputDensity);
    Image<double> inputImage(volumeData, lattice, nBands);

    // extract seed points
    int nLabels = 5;
    double *seedData;
    seedData = readVolume(seedsFilename, nElements * nLabels);
    Image<double> seedImage(seedData, lattice, nLabels);
    //int nPotentialSeeds = 0;
    //for (int elementIndex = 0; elementIndex < nElements; elementIndex++) {
    //    if (fabs(seedData[elementIndex]) > EPSILONT) {
    //        nPotentialSeeds++;
    //    }
    //}
    //cout << "#Potential seedpoints: " << nPotentialSeeds << endl;
    vector<vector<Seed> > seedPoints;
    vector<Seed> tmp;
    for (int label = 0; label < nLabels; label++) {
        tmp.clear();
        for (int elementIndex = 0; elementIndex < nElements; elementIndex++) {
            if (fabs(seedImage(elementIndex, label) - 1) < EPSILONT) {
                tmp.push_back(Seed(Seed(elementIndex, label)));
            }
        }
        seedPoints.push_back(tmp);
    }
    //std::cout << "Extracted seedpoints:" << std::endl;
    //std::cout << "\tlabel 1: " << seedPoints[0].size() << std::endl;
    //std::cout << "\tlabel 2: " << seedPoints[1].size() << std::endl;
    //std::cout << "\tlabel 3: " << seedPoints[2].size() << std::endl;
    //std::cout << "\tlabel 4: " << seedPoints[3].size() << std::endl;
    //std::cout << "\tlabel 5: " << seedPoints[4].size() << std::endl;

    // distance measure
    Norm<double> *norm;
    switch (normType) {
        case 'm':
            norm = new MaximumNorm<double>;
            break;
        case 'p':
            norm = new PNorm<double>(2);
            break;
        case '*':
            norm = new ProductNorm<double>;
            break;
        default:
            exit(1);
    }
    SeededDistanceMeasure<double> *distanceMeasure;
    switch (distanceMeasureType) {
        case 'a':
            distanceMeasure = new ApproximateMinimumBarrierDistance<double>(*norm);
            break;
        case 'c':
            distanceMeasure = new FuzzyConnectedness<double>(*norm);
            break;
        case 'f':
            distanceMeasure = new FuzzyDistance<double>(*norm);
            break;
        case 'g':
            distanceMeasure = new GeodesicDistance<double>;
            break;
        case 'm':
            distanceMeasure = new MinimumBarrierDistance<double>;
            break;
        default:
            exit(1);
    }

    // distance transform
    double *distanceTransformData = new double[nElements];
    Image<double> distanceImage(distanceTransformData, lattice, 1);
    int *rootData = new int[nElements];
    Image<int> rootImage(rootData, lattice, 1);
    SeededDistanceTransform seededDistanceTransform;
    seededDistanceTransform.applySingleLayer(inputImage, seedPoints, *distanceMeasure, neighborhoodSize, distanceImage, rootImage);
    writeVolume("distancetransform.bin", distanceTransformData, nElements);

    // segmentation
    Segmentation segmentation;
    double *fuzzySegmentationData = new double[nElements * nLabels];
    //double *fuzzySegmentationData = readVolume(segmentationFilename, nElements * nLabels);
    Image<double> fuzzySegmentationImage(fuzzySegmentationData, *lattice, nLabels);
    IntensityWorkset<double> fuzzySegmentation(fuzzySegmentationImage, 0, 1);
    // save segmentation
    segmentation.fuzzy(distanceImage, neighborhoodSize, fuzzySegmentation);
    writeVolume(segmentationFilename, fuzzySegmentationData, nElements * nLabels);

    ObjectSurfaceAreaFromVoronoiCellIntersection<double> surfaceAreaComputer;
    double area;
    area = surfaceAreaComputer.compute(fuzzySegmentation, 4);
    cout << "small tomato surface area: " << area << endl;
    area = surfaceAreaComputer.compute(fuzzySegmentation, 3);
    cout << "large tomato surface area: " << area << endl;
    area = surfaceAreaComputer.compute(fuzzySegmentation, 2);
    cout << "avocado surface area: " << area << endl;
    area = surfaceAreaComputer.compute(fuzzySegmentation, 1);
    cout << "margarine surface area: " << area << endl;

    ObjectVolumeFromCoverage<double> volumeComputer;
    double volume;
    volume = volumeComputer.compute(fuzzySegmentation, 4);
    cout << "small tomato volume: " << volume << endl;
    volume = volumeComputer.compute(fuzzySegmentation, 3);
    cout << "large tomato volume: " << volume << endl;
    volume = volumeComputer.compute(fuzzySegmentation, 2);
    cout << "avocado volume: " << volume << endl;
    volume = volumeComputer.compute(fuzzySegmentation, 1);
    cout << "margarine volume: " << volume << endl;

    delete seedData;
    delete volumeData;
    delete rootData;
    delete distanceTransformData;
    delete fuzzySegmentationData;
    delete norm;
    delete distanceMeasure;

    return 0;
}
Example #24
0
  KeyDetectionResult KeyFinder::findKey(const AudioData& originalAudio, const Parameters& params){

    KeyDetectionResult result;

    AudioData* workingAudio = new AudioData(originalAudio);

    workingAudio->reduceToMono();

    // TODO: there is presumably some good maths to determine filter frequencies
    float lpfCutoff = params.getLastFrequency() * 1.05;
    float dsCutoff = params.getLastFrequency() * 1.10;
    unsigned int downsampleFactor = (int)floor( workingAudio->getFrameRate() / 2 / dsCutoff );

    // get filter
    LowPassFilter* lpf = lpfFactory.getLowPassFilter(160, workingAudio->getFrameRate(), lpfCutoff, 2048);
    // feeding in the downsampleFactor for a shortcut
    lpf->filter(workingAudio, downsampleFactor);
    // note we don't delete the LPF; it's stored in the factory for reuse

    Downsampler ds;
    ds.downsample(workingAudio, downsampleFactor);

    SpectrumAnalyser* sa = new SpectrumAnalyser(workingAudio->getFrameRate(), params, &ctFactory);

    // run spectral analysis
    Chromagram* ch = sa->chromagram(workingAudio);

    delete workingAudio;
    delete sa;

    // reduce chromagram
    ch->reduceTuningBins(params);
    result.fullChromagram = Chromagram(*ch);
    ch->reduceToOneOctave(params);
    result.oneOctaveChromagram = Chromagram(*ch);

    // get harmonic change signal
    Segmentation* segmenter = Segmentation::getSegmentation(params);
    result.harmonicChangeSignal = segmenter->getRateOfChange(*ch, params);

    // get track segmentation
    std::vector<unsigned int> segmentBoundaries = segmenter->getSegments(result.harmonicChangeSignal, params);
    segmentBoundaries.push_back(ch->getHops()); // sentinel
    delete segmenter;

    // get key estimates for each segment
    KeyClassifier hc(params);
    std::vector<float> keyWeights(24); // TODO: not ideal using int cast of key_t enum. Hash?

    for (int s = 0; s < (signed)segmentBoundaries.size()-1; s++){
      KeyDetectionSegment segment;
      segment.firstHop = segmentBoundaries[s];
      segment.lastHop = segmentBoundaries[s+1] - 1;
      // collapse segment's time dimension
      std::vector<float> segmentChroma(ch->getBins());
      for (unsigned int hop = segment.firstHop; hop <= segment.lastHop; hop++) {
        for (unsigned int bin = 0; bin < ch->getBins(); bin++) {
          float value = ch->getMagnitude(hop, bin);
          segmentChroma[bin] += value;
          segment.energy += value;
        }
      }
      segment.key = hc.classify(segmentChroma);
      if(segment.key != SILENCE){
        keyWeights[segment.key] += segment.energy;
      }
      result.segments.push_back(segment);
    }

    delete ch;

    // get global key
    result.globalKeyEstimate = SILENCE;
    float mostCommonKeyWeight = 0.0;
    for (int k = 0; k < (signed)keyWeights.size(); k++){
      if(keyWeights[k] > mostCommonKeyWeight){
        mostCommonKeyWeight = keyWeights[k];
        result.globalKeyEstimate = (key_t)k;
      }
    }

    return result;

  }
static Ref_t create_detector(Detector& theDetector, xml_h e, SensitiveDetector sens)  {
    xml_det_t   x_det     = e;
    int         det_id    = x_det.id();
    string      det_name  = x_det.nameStr();
    DetElement    sdet      (det_name,det_id);
    
    // --- create an envelope volume and position it into the world ---------------------
    
    Volume envelope = dd4hep::xml::createPlacedEnvelope( theDetector,  e , sdet ) ;
    dd4hep::xml::setDetectorTypeFlag( e, sdet ) ;
    
    if( theDetector.buildType() == BUILD_ENVELOPE ) return sdet ;
    
    //-----------------------------------------------------------------------------------
    
    xml_dim_t   dim       = x_det.dimensions();
    Material    air       = theDetector.air();
    int         nsides_inner = dim.nsides_inner();
    int         nsides_outer = dim.nsides_outer();
    double      rmin      = dim.rmin();
    double      rmax      = dim.rmax(); /// FIXME: IS THIS RIGHT?
    double      zmin      = dim.zmin();
    
    double       rcutout   = dim.hasAttr(_U(rmin2)) ? dim.rmin2() : 0.;
    double       zcutout   = dim.hasAttr(_U(z2)) ? dim.z2() : 0.;
    
    Layering    layering(x_det);
    double      totalThickness = layering.totalThickness();
    Readout readout = sens.readout();
    Segmentation seg = readout.segmentation();
    
    std::vector<double> cellSizeVector = seg.segmentation()->cellDimensions(0); //Assume uniform cell sizes, provide dummy cellID
    double cell_sizeX      = cellSizeVector[0];
    double cell_sizeY      = cellSizeVector[1];
    
    
    PolyhedraRegular polyVolume(nsides_outer,rmin,rmax,totalThickness);
    Volume      endcapVol("endcap",polyVolume,air);
    
    
    if(zcutout >0. || rcutout > 0.){
        PolyhedraRegular cutoutPolyVolume(nsides_inner,0,rmin+rcutout,zcutout);
        Position cutoutPos(0,0,(zcutout-totalThickness)/2.0);
        std::cout<<"Cutout z width will be  "<<zcutout<<std::endl; 
        endcapVol=Volume("endcap",SubtractionSolid(polyVolume,cutoutPolyVolume,cutoutPos),air);
        
    }
    
    
    DetElement  endcapA(sdet,"endcap",det_id);
    Ref_t(endcapA)->SetName((det_name+"_A").c_str());
    
    int layer_num = 0;
    int layerType   = 0;
    double layerZ   = -totalThickness/2;
    
    //Create caloData object to extend driver with data required for reconstruction
    LayeredCalorimeterData* caloData = new LayeredCalorimeterData ;
    caloData->layoutType = LayeredCalorimeterData::EndcapLayout ;
    caloData->inner_symmetry = nsides_inner;
    caloData->outer_symmetry = nsides_outer; 
    
    /** NOTE: phi0=0 means lower face flat parallel to experimental floor
     *  This is achieved by rotating the modules with respect to the envelope
     *  which is assumed to be a Polyhedron and has its axes rotated with respect
     *  to the world by 180/nsides. In any other case (e.g. if you want to have
     *  a tip of the calorimeter touching the ground) this value needs to be computed
     */
    
    caloData->inner_phi0 = 0.; 
    caloData->outer_phi0 = 0.; 
    caloData->gap0 = 0.; //FIXME
    caloData->gap1 = 0.; //FIXME
    caloData->gap2 = 0.; //FIXME  
    
    
    /// extent of the calorimeter in the r-z-plane [ rmin, rmax, zmin, zmax ] in mm.
    caloData->extent[0] = rmin ;
    caloData->extent[1] = rmax ; ///FIXME: CHECK WHAT IS NEEDED (EXSCRIBED?)
    caloData->extent[2] = zmin ;
    caloData->extent[3] = zmin + totalThickness;
    
    endcapVol.setAttributes(theDetector,x_det.regionStr(),x_det.limitsStr(),x_det.visStr());
    
    for(xml_coll_t c(x_det,_U(layer)); c; ++c)  {
        xml_comp_t       x_layer  = c;
        double           layer_thick  = layering.layer(layer_num)->thickness();
        string           layer_type_name   = _toString(layerType,"layerType%d");
        int              layer_repeat = x_layer.repeat();
        double            layer_rcutout = x_layer.hasAttr(_U(gap)) ? x_layer.gap() : 0;
        
        std::cout<<"Number of layers in group "<<layerType<<" : "<<layer_repeat<<std::endl; 
        
        Volume           layer_vol(layer_type_name,PolyhedraRegular(nsides_outer,rmin+layer_rcutout,rmax,layer_thick),air);
        
        int slice_num = 0;
        double sliceZ = -layer_thick/2;
        
        //Create a caloLayer struct for thiss layer type to store copies of in the parent struct
        LayeredCalorimeterData::Layer caloLayer ;
        caloLayer.cellSize0 = cell_sizeX;
        caloLayer.cellSize1 = cell_sizeY; 
        
        double nRadiationLengths=0.;
        double nInteractionLengths=0.;
        double thickness_sum=0;
        
        for(xml_coll_t s(x_layer,_U(slice)); s; ++s)  {
            xml_comp_t x_slice = s;
            string     slice_name  = _toString(slice_num,"slice%d");
            double     slice_thickness = x_slice.thickness();
            Material   slice_material   = theDetector.material(x_slice.materialStr());
            Volume     slice_vol(slice_name,PolyhedraRegular(nsides_outer,rmin+layer_rcutout,rmax,slice_thickness),slice_material);
            
            slice_vol.setVisAttributes(theDetector.visAttributes(x_slice.visStr()));
            sliceZ += slice_thickness/2;
            layer_vol.placeVolume(slice_vol,Position(0,0,sliceZ));
            
            nRadiationLengths += slice_thickness/(2.*slice_material.radLength());
            nInteractionLengths += slice_thickness/(2.*slice_material.intLength());
            thickness_sum += slice_thickness/2;
            
            if ( x_slice.isSensitive() )  {
                sens.setType("calorimeter");
                slice_vol.setSensitiveDetector(sens);
                
#if DD4HEP_VERSION_GE( 0, 15 )
                //Store "inner" quantities
                caloLayer.inner_nRadiationLengths = nRadiationLengths;
                caloLayer.inner_nInteractionLengths = nInteractionLengths;
                caloLayer.inner_thickness = thickness_sum;
                //Store scintillator thickness
                caloLayer.sensitive_thickness = slice_thickness;
#endif
                //Reset counters to measure "outside" quantitites
                nRadiationLengths=0.;
                nInteractionLengths=0.;
                thickness_sum = 0.;
            } 
            
            nRadiationLengths += slice_thickness/(2.*slice_material.radLength());
            nInteractionLengths += slice_thickness/(2.*slice_material.intLength());
            thickness_sum += slice_thickness/2;

            sliceZ += slice_thickness/2;
            slice_num++;
        }
        
#if DD4HEP_VERSION_GE( 0, 15 )
        //Store "outer" quantities
        caloLayer.outer_nRadiationLengths = nRadiationLengths;
        caloLayer.outer_nInteractionLengths = nInteractionLengths;
        caloLayer.outer_thickness = thickness_sum;
#endif        
        layer_vol.setVisAttributes(theDetector.visAttributes(x_layer.visStr()));
        
        
        if ( layer_repeat <= 0 ) throw std::runtime_error(x_det.nameStr()+"> Invalid repeat value");
        
        for(int j=0; j<layer_repeat; ++j) {
            string phys_lay = _toString(layer_num,"layer%d");
            
            //The rest of the data is constant; only the distance needs to be updated  
            //Store the position up to the inner face of the layer
            caloLayer.distance = zmin +  totalThickness/2 + layerZ;
            //Push back a copy to the caloData structure
            caloData->layers.push_back( caloLayer );
            
            layerZ += layer_thick/2;
            DetElement    layer_elt(endcapA, phys_lay, layer_num);
            PlacedVolume  pv = endcapVol.placeVolume(layer_vol,Position(0,0,layerZ));
            pv.addPhysVolID("layer", layer_num);
            layer_elt.setPlacement(pv);
            
            layerZ += layer_thick/2;
            ++layer_num;
        }
        ++layerType;
    }
    
    double z_pos = zmin+totalThickness/2;
    PlacedVolume pv;
    // Reflect it.
    
    DetElement  endcapB = endcapA.clone(det_name+"_B",x_det.id());
    
    //Removed rotations to align with envelope
    //NOTE: If the envelope is not a polyhedron (eg. if you use a tube)
    //you may need to rotate so the axes match
    
    pv = envelope.placeVolume(endcapVol,Transform3D(RotationZYX(0,0,0),
                                                    Position(0,0,z_pos)));
    pv.addPhysVolID("side", 1);
    endcapA.setPlacement(pv);
    
    //Removed rotations
    pv = envelope.placeVolume(endcapVol,Transform3D(RotationZYX(0,M_PI,0),
                                                    Position(0,0,-z_pos)));
    pv.addPhysVolID("side", 2);
    endcapB.setPlacement(pv);
    
    sdet.add(endcapB);
    
    sdet.addExtension< LayeredCalorimeterData >( caloData ) ;
    
    return sdet;
    
}
void KeyFinderWorkerThread::run(){
	if(!haveParams){
		emit failed("No parameters.");
		return;
	}
	// initialise stream and decode file into it
	AudioStream* astrm = NULL;
  AudioFileDecoder* dec = AudioFileDecoder::getDecoder(filePath.toUtf8().data());
	try{
    astrm = dec->decodeFile(filePath.toUtf8().data());
	}catch(Exception){
		delete astrm;
		delete dec;
		emit failed("Could not decode file.");
		return;
	}
	delete dec;
	emit decoded();

	// make audio stream monaural
	astrm->reduceToMono();
	emit madeMono();

	// downsample if necessary
	if(prefs.getDFactor() > 1){
		Downsampler* ds = Downsampler::getDownsampler(prefs.getDFactor(),astrm->getFrameRate(),prefs.getLastFreq());
		try{
			astrm = ds->downsample(astrm,prefs.getDFactor());
		}catch(Exception){
			delete astrm;
			delete ds;
			emit failed("Downsampler failed.");
			return;
		}
		delete ds;
		emit downsampled();
	}

	// start spectrum analysis
	SpectrumAnalyser* sa = NULL;
  Chromagram* ch = NULL;
  sa = SpectrumAnalyserFactory::getInstance()->getSpectrumAnalyser(astrm->getFrameRate(),prefs);
  ch = sa->chromagram(astrm);
  delete astrm; // note we don't delete the spectrum analyser; it stays in the centralised factory for reuse.
  ch->reduceTuningBins(prefs);
	emit producedFullChromagram(*ch);

	// reduce chromagram
	ch->reduceToOneOctave(prefs);
	emit producedOneOctaveChromagram(*ch);

	// get energy level across track to weight segments
	std::vector<float> loudness(ch->getHops());
	for(int h=0; h<ch->getHops(); h++)
		for(int b=0; b<ch->getBins(); b++)
			loudness[h] += ch->getMagnitude(h,b);

	// get harmonic change signal
	Segmentation* hcdf = Segmentation::getSegmentation(prefs);
	std::vector<double> harmonicChangeSignal = hcdf->getRateOfChange(ch,prefs);
	emit producedHarmonicChangeSignal(harmonicChangeSignal);

	// get track segmentation
  std::vector<int> changes = hcdf->getSegments(harmonicChangeSignal,prefs);
  changes.push_back(ch->getHops()); // It used to be getHops()-1. But this doesn't crash. So we like it.

	// batch output of keychange locations for Beatles experiment
	//for(int i=1; i<changes.size(); i++) // don't want the leading zero
	//	std::cout << filePath.substr(53) << "\t" << std::fixed << std::setprecision(2) << changes[i]*(prefs.getHopSize()/(44100.0/prefs.getDFactor())) << std::endl;
	// end experiment output

	// get key estimates for segments
	KeyClassifier hc(prefs);
	std::vector<int> keys(0);
	std::vector<float> keyWeights(24);
  for(int i=0; i<(signed)changes.size()-1; i++){
    std::vector<double> chroma(ch->getBins());
		for(int j=changes[i]; j<changes[i+1]; j++)
			for(int k=0; k<ch->getBins(); k++)
        chroma[k] += ch->getMagnitude(j,k);
    int key = hc.classify(chroma);
    for(int j=changes[i]; j<changes[i+1]; j++){
			keys.push_back(key);
			if(key < 24) // ignore parts that were classified as silent
				keyWeights[key] += loudness[j];
    }
	}
	keys.push_back(keys[keys.size()-1]); // put last key on again to match length of track
	delete ch;
	emit producedKeyEstimates(keys);

	// get global key
	int mostCommonKey = 24;
	float mostCommonKeyWeight = 0.0;
	for(int i=0; i<(signed)keyWeights.size(); i++){
		if(keyWeights[i] > mostCommonKeyWeight){
			mostCommonKeyWeight = keyWeights[i];
			mostCommonKey = i;
		}
	}
	emit producedGlobalKeyEstimate(mostCommonKey);
	return;
}
Example #27
0
  KeyDetectionResult KeyFinder::findKey(const AudioData& originalAudio, const Parameters& params){

    KeyDetectionResult result;

    AudioData* workingAudio = new AudioData(originalAudio);

    workingAudio->reduceToMono();

    Downsampler ds;
    ds.downsample(workingAudio, params.getLastFreq(), &lpfFactory);

    SpectrumAnalyser* sa = new SpectrumAnalyser(workingAudio->getFrameRate(), params, &ctFactory);

    // run spectral analysis
    Chromagram* ch = sa->chromagram(workingAudio);

    delete workingAudio;
    delete sa;

    // reduce chromagram
    ch->reduceTuningBins(params);
    result.fullChromagram = Chromagram(*ch);
    ch->reduceToOneOctave(params);
    result.oneOctaveChromagram = Chromagram(*ch);

    // get harmonic change signal
    Segmentation* segmenter = Segmentation::getSegmentation(params);
    result.harmonicChangeSignal = segmenter->getRateOfChange(*ch, params);

    // get track segmentation
    std::vector<unsigned int> segmentBoundaries = segmenter->getSegments(result.harmonicChangeSignal, params);
    segmentBoundaries.push_back(ch->getHops()); // sentinel
    delete segmenter;

    // get key estimates for each segment
    KeyClassifier hc(params);
    std::vector<float> keyWeights(24); // TODO: not ideal using int cast of key_t enum. Hash?

    for (int s = 0; s < (signed)segmentBoundaries.size()-1; s++){
      KeyDetectionSegment segment;
      segment.firstWindow = segmentBoundaries[s];
      segment.lastWindow = segmentBoundaries[s+1] - 1;
      // collapse segment's time dimension, for a single chroma vector and a single energy value
      std::vector<float> segmentChroma(ch->getBins());
      // for each relevant hop of the chromagram
      for (unsigned int hop = segment.firstWindow; hop <= segment.lastWindow; hop++) {
        // for each bin
        for (unsigned int bin = 0; bin < ch->getBins(); bin++) {
          float value = ch->getMagnitude(hop, bin);
          segmentChroma[bin] += value;
          segment.energy += value;
        }
      }
      segment.key = hc.classify(segmentChroma);
      if(segment.key != SILENCE){
        keyWeights[segment.key] += segment.energy;
      }
      result.segments.push_back(segment);
    }

    delete ch;

    // get global key
    result.globalKeyEstimate = SILENCE;
    float mostCommonKeyWeight = 0.0;
    for (int k = 0; k < (signed)keyWeights.size(); k++){
      if(keyWeights[k] > mostCommonKeyWeight){
        mostCommonKeyWeight = keyWeights[k];
        result.globalKeyEstimate = (key_t)k;
      }
    }

    return result;

  }
TuningInterface *multiObjectiveTuning(int argc, char **argv, SysEnv &sysEnv, int max_number_of_tests,
                                      std::string &metricType,
                                      double metricWeight,
                                      double timeWeight,
                                      double &tSlowest, double &tFastest, RegionTemplateCollection *rtCollection,
                                      std::string tuningPolicy,
                                      float *perf, float *totaldiffs, float *metricPerIteration,
                                      float *diceNotCoolPerIteration,
                                      uint64_t *totalexecutiontimes) {

    TuningInterface *tuningClient;
    int numClients;


    //USING AH
    if (tuningPolicy.find("nm") != std::string::npos || tuningPolicy.find("NM") != std::string::npos ||
        tuningPolicy.find("pro") != std::string::npos || tuningPolicy.find("PRO") != std::string::npos ||
        tuningPolicy.find("random") != std::string::npos || tuningPolicy.find("RANDOM") != std::string::npos) {
        numClients = 1;
        tuningClient = new ActiveHarmonyTuning(tuningPolicy, max_number_of_tests, numClients);
    } else {


        //USING GA
        int max_number_of_generations = (int) floor(sqrt(max_number_of_tests));
        int mutationchance = 30;
        int crossoverrate = 50;

        int popsize = (int) ceil(sqrt(max_number_of_tests));
        if (popsize > 1 && ((popsize % 2) == 1)) {
            --popsize;
            max_number_of_generations++;
        } //Pop size must be an even number for GA.

        if (popsize <= 1) popsize++; //pop size must be at least 2.

        if (popsize * max_number_of_generations > max_number_of_tests) {
            max_number_of_generations--;
        }

        //int propagationamount = 2;
        int propagationamount = (int) ceil(popsize * 0.25); //around 25% of popsize

        if ((2 * propagationamount) >= popsize)
            propagationamount--; //Elite size(propagation amount) must be less than half the popsize.

        numClients = popsize; //popsize
        tuningClient = new GeneticAlgorithm(max_number_of_generations, popsize, mutationchance,
                                            crossoverrate,
                                            propagationamount,
                                            1);

    }

    double *totalExecutionTimesNormalized = (double *) malloc(sizeof(double) * max_number_of_tests);

    std::vector<int> segComponentIds[numClients];
    std::vector<int> metricComponentIds[numClients];
    std::vector<int> diceNotCoolComponentIds[numClients];
    std::map<std::string, double> perfDataBase; //Checks if a param has been tested already

    int versionNorm = 0, versionSeg = 0;
    resetPerf(perf, max_number_of_tests);
    bool executedAlready[numClients];
    int repeatCounter = 0;


    if (tuningClient->initialize(argc, argv) != 0) {
        fprintf(stderr, "Failed to initialize tuning session.\n");
        return NULL;
    };


    if (tuningClient->declareParam("blue", 210, 240, 10) != 0 ||
        tuningClient->declareParam("green", 210, 240, 10) != 0 ||
        tuningClient->declareParam("red", 210, 240, 10) != 0 ||
        tuningClient->declareParam("T1", 2.5, 7.5, 0.5) != 0 ||
        tuningClient->declareParam("T2", 2.5, 7.5, 0.5) != 0 ||
        tuningClient->declareParam("G1", 5, 80, 5) != 0 ||
        tuningClient->declareParam("minSize", 2, 40, 2) != 0 ||
        tuningClient->declareParam("maxSize", 900, 1500, 50) != 0 ||
        tuningClient->declareParam("G2", 2, 40, 2) != 0 ||
        tuningClient->declareParam("minSizePl", 5, 80, 5) != 0 ||
        tuningClient->declareParam("minSizeSeg", 2, 40, 2) != 0 ||
        tuningClient->declareParam("maxSizeSeg", 900, 1500, 50) != 0 ||
        tuningClient->declareParam("fillHoles", 4, 8, 4) != 0 ||
        tuningClient->declareParam("recon", 4, 8, 4) != 0 ||
        tuningClient->declareParam("watershed", 4, 8, 4) != 0) {
        fprintf(stderr, "Failed to define tuning session\n");
        return NULL;
    }

    if (tuningClient->configure() != 0) {
        fprintf(stderr, "Failed to initialize tuning session.\n");
        return NULL;
    };

    for (; !tuningClient->hasConverged();) {
        cout << "ITERATION: " << tuningClient->getIteration() << endl;


        //Get new param suggestions from the tuning client
        tuningClient->fetchParams();
        //Apply fitness function for each individual
        for (int i = 0; i < numClients; i++) {

            std::ostringstream oss;
            oss << "PARAMS";
            typedef std::map<std::string, double *>::iterator it_type;
            for (it_type iterator = tuningClient->getParamSet(i)->paramSet.begin();
                 iterator != tuningClient->getParamSet(i)->paramSet.end(); iterator++) {
                //iterator.first key
                //iterator.second value
                oss << " - " << iterator->first << ": " << *(iterator->second);
            }

            // / if not found in performance database
            if (perfDataBase.find(oss.str()) != perfDataBase.end()) {
                perf[tuningClient->getIteration() * numClients +
                     (i)] = perfDataBase.find(oss.str())->second;
                std::cout << "Parameters already tested: " << oss.str() << " perf: " << perf << std::endl;

                executedAlready[i] = true;
            } else {
                executedAlready[i] = false;
            }

        }


        int segCount = 0;
        // Build application dependency graph
        // Instantiate application dependency graph
        for (int i = 0; i < rtCollection->getNumRTs(); i++) {

            int previousSegCompId = 0;
            // CREATE NORMALIZATION STEP
            ParameterSet parSetNormalization;
            std::vector<ArgumentBase *> targetMeanOptions;
            ArgumentFloatArray *targetMeanAux = new ArgumentFloatArray(ArgumentFloat(-0.632356));
            targetMeanAux->addArgValue(ArgumentFloat(-0.0516004));
            targetMeanAux->addArgValue(ArgumentFloat(0.0376543));
            targetMeanOptions.push_back(targetMeanAux);
            parSetNormalization.addArguments(targetMeanOptions);
            parSetNormalization.resetIterator();
            std::vector<ArgumentBase *> argSetInstanceNorm = parSetNormalization.getNextArgumentSetInstance();
            NormalizationComp *norm = new NormalizationComp();
            // normalization parameters
            norm->addArgument(new ArgumentInt(versionNorm));
            norm->addArgument(argSetInstanceNorm[0]);
            norm->addRegionTemplateInstance(rtCollection->getRT(i), rtCollection->getRT(i)->getName());
            sysEnv.executeComponent(norm);

            for (int j = 0; j < numClients; j++) {

                if (executedAlready[j] == false) {

                    std::cout << "BEGIN: LoopIdx: " << tuningClient->getIteration() * numClients + (j);

                    typedef std::map<std::string, double *>::iterator it_type;
                    for (it_type iterator = tuningClient->getParamSet(j)->paramSet.begin();
                         iterator != tuningClient->getParamSet(j)->paramSet.end(); iterator++) {
                        std::cout << " - " << iterator->first << ": " << *(iterator->second);
                    }

                    std::cout << std::endl;

                    // Creating segmentation component
                    Segmentation *seg = new Segmentation();

                    // version of the data region red. Each parameter instance in norm creates a output w/ different version
                    seg->addArgument(new ArgumentInt(versionNorm));
                    // version of the data region generated by the segmentation stage
                    seg->addArgument(new ArgumentInt(versionSeg));

                    // add remaining (application specific) parameters from the argSegInstance
                    seg->addArgument(new ArgumentInt(
                            (int) round(tuningClient->getParamValue("blue", j))));
                    seg->addArgument(new ArgumentInt(
                            (int) round(tuningClient->getParamValue("green", j))));
                    seg->addArgument(new ArgumentInt(
                            (int) round(tuningClient->getParamValue("red", j))));
                    seg->addArgument(
                            new ArgumentFloat((float) (tuningClient->getParamValue("T1", j))));
                    seg->addArgument(
                            new ArgumentFloat((float) (tuningClient->getParamValue("T2", j))));
                    seg->addArgument(new ArgumentInt(
                            (int) round(tuningClient->getParamValue("G1", j))));
                    seg->addArgument(new ArgumentInt(
                            (int) round(tuningClient->getParamValue("G2", j))));
                    seg->addArgument(new ArgumentInt(
                            (int) round(tuningClient->getParamValue("minSize", j))));
                    seg->addArgument(new ArgumentInt(
                            (int) round(tuningClient->getParamValue("maxSize", j))));
                    seg->addArgument(new ArgumentInt(
                            (int) round(tuningClient->getParamValue("minSizePl", j))));
                    seg->addArgument(new ArgumentInt(
                            (int) round(tuningClient->getParamValue("minSizeSeg", j))));
                    seg->addArgument(new ArgumentInt(
                            (int) round(tuningClient->getParamValue("maxSizeSeg", j))));
                    seg->addArgument(new ArgumentInt(
                            (int) round(tuningClient->getParamValue("fillHoles", j))));
                    seg->addArgument(new ArgumentInt(
                            (int) round(tuningClient->getParamValue("recon", j))));
                    seg->addArgument(new ArgumentInt(
                            (int) round(tuningClient->getParamValue("watershed", j))));


                    // and region template instance that it is suppose to process
                    seg->addRegionTemplateInstance(rtCollection->getRT(i), rtCollection->getRT(i)->getName());
                    seg->addDependency(norm->getId());

                    std::cout << "Creating DiffMask" << std::endl;

                    RTPipelineComponentBase *metricComp;
                    DiceNotCoolMaskComp *diceNotCoolComp;

                    if (metricType.find("jaccard") != std::string::npos) metricComp = new JaccardMaskComp();
                    else metricComp = new DiceMaskComp();

                    if (metricType.find("dicenc") != std::string::npos) diceNotCoolComp = new DiceNotCoolMaskComp();

                    // version of the data region that will be read. It is created during the segmentation.
                    // region template name
                    metricComp->addArgument(new ArgumentInt(versionSeg));
                    metricComp->addRegionTemplateInstance(rtCollection->getRT(i), rtCollection->getRT(i)->getName());
                    metricComp->addDependency(seg->getId());


                    // add to the list of diff component ids.
                    segComponentIds[j].push_back(seg->getId());
                    metricComponentIds[j].push_back(metricComp->getId());


                    sysEnv.executeComponent(seg);
                    sysEnv.executeComponent(metricComp);

                    if (metricType.find("dicenc") != std::string::npos) {
                        diceNotCoolComp->addArgument(new ArgumentInt(versionSeg));
                        diceNotCoolComp->addRegionTemplateInstance(rtCollection->getRT(i),
                                                                   rtCollection->getRT(i)->getName());
                        diceNotCoolComp->addDependency(metricComp->getId());
                        diceNotCoolComponentIds[j].push_back(diceNotCoolComp->getId());
                        sysEnv.executeComponent(diceNotCoolComp);
                    }


                    std::cout << "Manager CompId: " << metricComp->getId() << " fileName: " <<
                    rtCollection->getRT(i)->getDataRegion(0)->getInputFileName() << std::endl;
                    segCount++;
                    versionSeg++;

                }
            }
            versionNorm++;
        }

        // End Creating Dependency Graph
        sysEnv.startupExecution();


        //==============================================================================================
        //Fetch results from execution workflow
        //==============================================================================================
        for (int j = 0; j < numClients; j++) {
            float metric = 0;
            float secondaryMetric = 0;
            float diceNotCoolValue = 0;

            std::ostringstream oss;
            oss << "PARAMS";
            typedef std::map<std::string, double *>::iterator it_type;
            for (it_type iterator = tuningClient->getParamSet(j)->paramSet.begin();
                 iterator != tuningClient->getParamSet(j)->paramSet.end(); iterator++) {
                oss << " - " << iterator->first << ": " << *(iterator->second);
            }

            if (executedAlready[j] == false) {
                for (int i = 0; i < metricComponentIds[j].size(); i++) {
                    char *metricResultData = sysEnv.getComponentResultData(metricComponentIds[j][i]);
                    std::cout << "Diff Id: " << metricComponentIds[j][i] << " \tmetricResultData: ";
                    if (metricResultData != NULL) {
                        std::cout << "size: " << ((int *) metricResultData)[0] << " \thadoopgis-metric: " <<
                        ((float *) metricResultData)[1] <<
                        " \tsecondary: " << ((float *) metricResultData)[2] << endl;

                        metric += ((float *) metricResultData)[1];
                        secondaryMetric += ((float *) metricResultData)[2];

                        if (metricType.find("dicenc") != std::string::npos) {
                            char *diceNotCoolResultData = sysEnv.getComponentResultData(diceNotCoolComponentIds[j][i]);
                            std::cout << " \tdiceNotCool: " <<
                            ((float *) diceNotCoolResultData)[1] << std::endl;
                            diceNotCoolValue += ((float *) diceNotCoolResultData)[1];
                        }

                    } else {
                        std::cout << "NULL" << std::endl;
                    }
                    char *segExecutionTime = sysEnv.getComponentResultData(segComponentIds[j][i]);
                    if (segExecutionTime != NULL) {
                        totalexecutiontimes[tuningClient->getIteration() * numClients +
                                            (j)] = ((int *) segExecutionTime)[1];
                        cout << "Segmentation execution time:" <<
                        totalexecutiontimes[tuningClient->getIteration() * numClients + (j)] << endl;
                    }
                    if (metricType.find("dicenc") != std::string::npos)
                        sysEnv.eraseResultData(diceNotCoolComponentIds[j][i]);
                    sysEnv.eraseResultData(metricComponentIds[j][i]);
                    sysEnv.eraseResultData(segComponentIds[j][i]);
                }
                metricComponentIds[j].clear();
                segComponentIds[j].clear();
                if (metricType.find("dicenc") != std::string::npos) diceNotCoolComponentIds[j].clear();


                //########################################################################################
                //Multi Objective Tuning
                //########################################################################################

                float diff;

                if (metricType.find("dicenc") != std::string::npos) diff = (metric + diceNotCoolValue) / 2;
                else diff = metric;

                if (diff <= 0) diff = FLT_EPSILON;

                double timeNormalized;
                if (timeWeight > 0) {
                    timeNormalized =
                            (tSlowest - (double) totalexecutiontimes[tuningClient->getIteration() * numClients + (j)]) /
                            (tSlowest - tFastest);
//                double timeNormalized = (tSlowest)/
//                        ((double) totalexecutiontimes[tuningClient->getIteration() * numClients + (j)]) ;

                }
                double weightedSumOfMetricAndTime = (double) (metricWeight * diff + timeWeight * timeNormalized);
                if ((weightedSumOfMetricAndTime > 0) && (diff > FLT_EPSILON)) {
                    perf[tuningClient->getIteration() * numClients + (j)] = (double) 1 /
                                                                            weightedSumOfMetricAndTime; //Multi Objective Tuning
                } else {
                    perf[tuningClient->getIteration() * numClients + (j)] = std::numeric_limits<double>::infinity();
                }



                totalExecutionTimesNormalized[tuningClient->getIteration() * numClients + (j)] = timeNormalized;
                if (perf[tuningClient->getIteration() * numClients + (j)] < 0)
                    perf[tuningClient->getIteration() * numClients + (j)] = -perf[
                            tuningClient->getIteration() * numClients + (j)];

                std::cout << "END: LoopIdx: " << tuningClient->getIteration() * numClients + (j);
                typedef std::map<std::string, double *>::iterator it_type;
                for (it_type iterator = tuningClient->getParamSet(j)->paramSet.begin();
                     iterator != tuningClient->getParamSet(j)->paramSet.end(); iterator++) {
                    //iterator.first key
                    //iterator.second value
                    std::cout << " - " << iterator->first << ": " << *(iterator->second);
                }

                cout << endl << endl << "\tDiff: " << diff << " Secondary Metric: " << secondaryMetric <<
                " Time Normalized: " << timeNormalized << " Segmentation Time: " <<
                totalexecutiontimes[tuningClient->getIteration() * numClients + (j)] << " Perf: " <<
                perf[tuningClient->getIteration() * numClients + (j)] << endl;

                totaldiffs[tuningClient->getIteration() * numClients + (j)] = diff;
                metricPerIteration[tuningClient->getIteration() * numClients + (j)] = metric;
                diceNotCoolPerIteration[tuningClient->getIteration() * numClients + (j)] = diceNotCoolValue;


                perfDataBase[oss.str()] = perf[tuningClient->getIteration() * numClients + (j)];
            } else {
                perf[tuningClient->getIteration() * numClients + (j)] = perfDataBase[oss.str()];

                std::cout << "ATTENTION! Param set executed already:" << std::endl;
                std::cout << "END: LoopIdx: " << tuningClient->getIteration() * numClients + (j);
                std::cout << oss.str() << endl;

                std::cout << " perf: " << perf[tuningClient->getIteration() * numClients + (j)] << std::endl;
            }

            // Report the performance we've just measured.
            tuningClient->reportScore(perf[tuningClient->getIteration() * numClients + (j)], j);
        }

        //Checks if at least one test in this iteration succeeded.
        bool shouldIterate = false;
        for (int k = 0; k < numClients; ++k) {
            shouldIterate |= !executedAlready[k];
        }
        //Iterates the tuning algorithm
        if (shouldIterate == true || (repeatCounter >= MAX_ITERATION_REPEAT)) {
            tuningClient->nextIteration();
            repeatCounter = 0;
        } else {
            repeatCounter++;
        }
        //tuningClient->nextIteration(); //Always iterate - to be fair, all 3 algorithms may repeat values.

    }
    return tuningClient;

}