void EUTelProcessorCoordinateTransformHits::processEvent(LCEvent* event)
{
		//Check the event type and if it is the last event.
		EUTelEventImpl* evt	= static_cast<EUTelEventImpl*>(event);				
		if( evt->getEventType() == kEORE )
		{
				streamlog_out( MESSAGE5 ) << "EORE found: nothing else to do." << std::endl;
				return;
		} 
		else if( evt->getEventType() == kUNKNOWN )
		{
				streamlog_out( WARNING2 ) << "Event number " << evt->getEventNumber() << " in run " << evt->getRunNumber()
						<< " is of unknown type. Continue considering it as a normal Data Event." << std::endl;
		}

		//Opens collection for input.
		LCCollection* inputCollection = nullptr;
		try
		{
				inputCollection = evt->getCollection(_hitCollectionNameInput);
		}
		catch (DataNotAvailableException& e)
		{
				streamlog_out( WARNING2 ) << _hitCollectionNameInput << " collection not available" << std::endl;
				return;
		}

		LCCollectionVec* outputCollection = nullptr;
		try
		{
				outputCollection  = static_cast<LCCollectionVec*> (event->getCollection( _hitCollectionNameOutput ));
		}
		catch(...)
		{
				outputCollection = new LCCollectionVec(LCIO::TRACKERHIT);
		}

		std::string encoding = inputCollection->getParameters().getStringVal( LCIO::CellIDEncoding );

		if(encoding.empty())
		{
			encoding = EUTELESCOPE::HITENCODING;
		}

		lcio::CellIDDecoder<TrackerHitImpl> hitDecoder ( encoding );
		lcio::UTIL::CellIDReencoder<TrackerHitImpl> cellReencoder( encoding, outputCollection );

		//Now get each individual hit LOOP OVER!
		for(int iHit = 0; iHit < inputCollection->getNumberOfElements(); ++iHit)
		{  
			TrackerHitImpl*	inputHit = static_cast<TrackerHitImpl*>(inputCollection->getElementAt(iHit));
			TrackerHitImpl* outputHit = new IMPL::TrackerHitImpl(); 

			//Call the local2masterHit/master2localHit function defined int EUTelGeometryTelescopeDescription
			int properties = hitDecoder(inputHit)["properties"];
			int sensorID = hitDecoder(inputHit)["sensorID"];
			
			const double* inputPos = inputHit->getPosition();
			double outputPos[3];

			if( !(properties & kHitInGlobalCoord) && !_undoAlignment )
			{
				streamlog_out(DEBUG5) << "Transforming hit from local to global!" << std::endl;
              //  std::cout<<"Local Sensor: " << sensorID << " " << inputPos[0]<< " " << inputPos[1]<< " " << inputPos[2]<<std::endl;
				geo::gGeometry().local2Master(sensorID, inputPos, outputPos);
              //  std::cout<<"Global Sensor: " << sensorID << " " << outputPos[0]<< " " << outputPos[1]<< " " << outputPos[2]<<std::endl;

			}
			else if( (properties & kHitInGlobalCoord) && _undoAlignment )
			{
				streamlog_out(DEBUG5) << "Transforming hit from global to local!" << std::endl;
				geo::gGeometry().master2Local(sensorID, inputPos, outputPos);
			}
			else
			{
				std::cout << "Properties: " << properties <<std::endl;
				std::string errMsg;
				if(!_undoAlignment) errMsg = "Provided global hit, but trying to transform into global. Something is wrong!";
				else errMsg = "Provided local hit, but trying to transform into local. Something is wrong!";
				throw InvalidGeometryException(errMsg);
			}
	
			//Fill the new outputHit with information
			outputHit->setPosition(outputPos);
			outputHit->setCovMatrix( inputHit->getCovMatrix());
			outputHit->setType( inputHit->getType() );
			outputHit->setTime( inputHit->getTime() );
			outputHit->setCellID0( inputHit->getCellID0() );
			outputHit->setCellID1( inputHit->getCellID1() );
			outputHit->setQuality( inputHit->getQuality() );
			outputHit->rawHits() = inputHit->getRawHits();

			cellReencoder.readValues(outputHit);
			//^= is a bitwise XOR i.e. we will switch the coordinate sytsem
			cellReencoder["properties"] = properties ^= kHitInGlobalCoord;
			cellReencoder.setCellID(outputHit);

			outputCollection->push_back(outputHit);
		}
	
		//Now push the hit for this event onto the collection
		try
		{	
				event->addCollection(outputCollection, _hitCollectionNameOutput );
		}
		catch(...)
		{
				streamlog_out ( WARNING5 )  << "Problem with pushing collection onto event" << std::endl;
		}
}
/** Called for every event - the working horse.
 */
void FastJetTopTagger::processEvent(LCEvent * evt){
	
  LCCollection* particleIn(NULL);
  try {
    // get the input collection if existent
    particleIn = evt->getCollection(_lcParticleInName);
    if (particleIn->getNumberOfElements() < 1){
      _statsNrSkippedEmptyEvents++;
      throw DataNotAvailableException("Collection is there, but its empty!");
    }
    
  } catch (DataNotAvailableException& e) {
    streamlog_out(WARNING) << e.what() << std::endl << "Skipping" << std::endl;

    //create dummy empty collection only in case there are processor that need the presence of them in later stages

    //create output collection and save every jet with its particles in it 
    LCCollectionVec* lccJetsOut = new LCCollectionVec(LCIO::RECONSTRUCTEDPARTICLE);

    //create output collection and save every particle which contributes to a jet
    LCCollectionVec* lccParticlesOut(NULL);
    if (_storeParticlesInJets){
      lccParticlesOut= new LCCollectionVec(LCIO::RECONSTRUCTEDPARTICLE);
      lccParticlesOut->setSubset(true);
    }
    
    evt->addCollection(lccJetsOut, _lcJetOutName);
    if (_storeParticlesInJets) evt->addCollection(lccParticlesOut, _lcParticleOutName);

    //create output collection for the top jets
    LCCollectionVec* lccTopTaggerOut = new LCCollectionVec(LCIO::RECONSTRUCTEDPARTICLE);
    LCCollectionVec* lccTopTaggerWOut = new LCCollectionVec(LCIO::RECONSTRUCTEDPARTICLE);
    LCCollectionVec* lccTopTaggerW1Out = new LCCollectionVec(LCIO::RECONSTRUCTEDPARTICLE);
    LCCollectionVec* lccTopTaggerW2Out = new LCCollectionVec(LCIO::RECONSTRUCTEDPARTICLE);
    LCCollectionVec* lccTopTaggernonWOut = new LCCollectionVec(LCIO::RECONSTRUCTEDPARTICLE);
    LCCollectionVec* lccTopTaggerCosThetaW = new LCCollectionVec(LCIO::LCGENERICOBJECT);
    
    evt->addCollection(lccTopTaggerOut, _lcTopTaggerOutName);
    evt->addCollection(lccTopTaggerWOut, _lcTopTaggerOutName+"_W");
    evt->addCollection(lccTopTaggernonWOut, _lcTopTaggerOutName+"_nonW");
    evt->addCollection(lccTopTaggerW1Out, _lcTopTaggerOutName+"_W1");
    evt->addCollection(lccTopTaggerW2Out, _lcTopTaggerOutName+"_W2");
    evt->addCollection(lccTopTaggerCosThetaW, _lcTopTaggerOutName+"_cos_theta_W");
    
    return;
  }
  
  // convert to pseudojet list
  PseudoJetList pjList = _fju->convertFromRecParticle(particleIn);
  
  //Jet finding
  PseudoJetList jets;
  try {
    // sort jets according to pt
    jets = sorted_by_pt(_fju->clusterJets(pjList, particleIn));
  } catch(SkippedFixedNrJetException& e){
    _statsNrSkippedFixedNrJets++; 
  } catch( SkippedMaxIterationException& e ) {
    jets = e._jets;
    _statsNrSkippedMaxIterations++; 
  }

  _statsNrEvents++;
  _statsFoundJets += jets.size();
  const unsigned nrJets = jets.size();
  
  // create output collection and save every jet with its particles in it
  LCCollectionVec* lccJetsOut = new LCCollectionVec(LCIO::RECONSTRUCTEDPARTICLE);
  
  // create output collection and save every particle which contributes to a jet
  LCCollectionVec* lccParticlesOut(NULL);
  if (_storeParticlesInJets){
    lccParticlesOut= new LCCollectionVec(LCIO::RECONSTRUCTEDPARTICLE);
    lccParticlesOut->setSubset(true);
  }

  //Save TopTagger info of the jets into the lcio stream
  LCCollectionVec* lccTopTaggerOut = new LCCollectionVec(LCIO::RECONSTRUCTEDPARTICLE);
  LCCollectionVec* lccTopTaggerWOut = new LCCollectionVec(LCIO::RECONSTRUCTEDPARTICLE);
  LCCollectionVec* lccTopTaggerW1Out = new LCCollectionVec(LCIO::RECONSTRUCTEDPARTICLE);
  LCCollectionVec* lccTopTaggerW2Out = new LCCollectionVec(LCIO::RECONSTRUCTEDPARTICLE);
  LCCollectionVec* lccTopTaggernonWOut = new LCCollectionVec(LCIO::RECONSTRUCTEDPARTICLE);
  
  //Save helicity information
  LCCollectionVec* lccTopTaggerCosThetaW = new LCCollectionVec(LCIO::LCGENERICOBJECT);
  LCGenericObjectImpl* lcgTopTaggerCosThetaW = new LCGenericObjectImpl(0, 0, 2);
  
  //Save substructure functions
  LCCollectionVec* lccSubStructure = new LCCollectionVec(LCIO::LCGENERICOBJECT);
  LCGenericObjectImpl* lcgSubStructureC2 = new LCGenericObjectImpl(0, 0, 2);
  LCGenericObjectImpl* lcgSubStructureD2 = new LCGenericObjectImpl(0, 0, 2);
  LCGenericObjectImpl* lcgSubStructureC3 = new LCGenericObjectImpl(0, 0, 2);
  LCGenericObjectImpl* lcgSubStructureD3 = new LCGenericObjectImpl(0, 0, 2);
  LCGenericObjectImpl* lcgSubStructureTau1 = new LCGenericObjectImpl(0, 0, 2);
  LCGenericObjectImpl* lcgSubStructureTau2 = new LCGenericObjectImpl(0, 0, 2);
  LCGenericObjectImpl* lcgSubStructureTau3 = new LCGenericObjectImpl(0, 0, 2);

  //NSubjetiness definitions
  auto axModeIt = _axesModeMap.find(_axesMode);
  auto measModeIt = _measureModeMap.find(_measureMode);
  if( axModeIt == _axesModeMap.end() ){
    throw std::runtime_error("Cannot find axesMode");
  } 
  if( measModeIt == _measureModeMap.end() ){
    throw std::runtime_error("Cannot find measureMode");
  }  
  auto const& measMode = measModeIt->second.def();
  auto const& axMode = axModeIt->second.def();
  fastjet::contrib::Nsubjettiness nSubJettiness1(1, axMode, measMode);
  fastjet::contrib::Nsubjettiness nSubJettiness2(2, axMode, measMode);
  fastjet::contrib::Nsubjettiness nSubJettiness3(3, axMode, measMode);
  
  //Loop over jets
  int index = 0;  
  PseudoJetList::iterator it;
  for(it=jets.begin(); it != jets.end(); it++, index++) {
    
    // create a reconstructed particle for this jet, and add all the containing particles to it
    ReconstructedParticle* rec = _fju->convertFromPseudoJet((*it), _fju->_cs->constituents(*it), particleIn);
    lccJetsOut->addElement( rec );
    
    if (_storeParticlesInJets) {
      for (unsigned int n = 0; n < _fju->_cs->constituents(*it).size(); ++n){
	ReconstructedParticle* p = static_cast<ReconstructedParticle*>(particleIn->getElementAt((_fju->_cs->constituents(*it))[n].user_index()));
        lccParticlesOut->addElement(p); 
      }
    }

    //Save substructure information
    if (_doSubstructure){

      //Substructure - energy correlation 
      double ECF1 = getECF(*it, 1, _energyCorrelator);
      double ECF2 = getECF(*it, 2, _energyCorrelator);   
      double ECF3 = getECF(*it, 3, _energyCorrelator);   
      double ECF4 = getECF(*it, 4, _energyCorrelator);   
      double C2 = ECF3*pow(ECF1,1)/pow(ECF2, 2); lcgSubStructureC2->setDoubleVal(index, C2); 
      double D2 = ECF3*pow(ECF1,3)/pow(ECF2, 3); lcgSubStructureD2->setDoubleVal(index, D2);
      double C3 = ECF4*pow(ECF2,1)/pow(ECF3, 2); lcgSubStructureC3->setDoubleVal(index, C3);
      double D3 = ECF4*pow(ECF2,3)/pow(ECF3, 3); lcgSubStructureD3->setDoubleVal(index, D3);
    
      //Substructure - NSubjettiness
      double tau1 = nSubJettiness1(*it); lcgSubStructureTau1->setDoubleVal(index, tau1);
      double tau2 = nSubJettiness2(*it); lcgSubStructureTau2->setDoubleVal(index, tau2);
      double tau3 = nSubJettiness3(*it); lcgSubStructureTau3->setDoubleVal(index, tau3);
    }

    //Johns-Hopkins top tagger
    
    // search for top quark like structure in jet
    fastjet::PseudoJet top_candidate = _jhtoptagger(*it);
    
    if (top_candidate == 0){ 
      
      lccTopTaggerOut->addElement(new ReconstructedParticleImpl());
      lccTopTaggerWOut->addElement(new ReconstructedParticleImpl());
      lccTopTaggernonWOut->addElement(new ReconstructedParticleImpl());
      lccTopTaggerW1Out->addElement(new ReconstructedParticleImpl());
      lccTopTaggerW2Out->addElement(new ReconstructedParticleImpl());
      lcgTopTaggerCosThetaW->setDoubleVal(index, 0.);

    } else {      
      // save top candidate
      ReconstructedParticle* t = _fju->convertFromPseudoJet(top_candidate, top_candidate.constituents(), particleIn);	    
      lccTopTaggerOut->addElement(t);

      // save W candidate
      fastjet::PseudoJet top_candidate_W = top_candidate.structure_of<fastjet::JHTopTagger>().W();
      ReconstructedParticle* W = _fju->convertFromPseudoJet(top_candidate_W, top_candidate_W.constituents(), particleIn);	    
      lccTopTaggerWOut->addElement(W);
      
      // save part 1 of W candidate
      fastjet::PseudoJet top_candidate_W1 = top_candidate.structure_of<fastjet::JHTopTagger>().W1();
      ReconstructedParticle* W1 = _fju->convertFromPseudoJet(top_candidate_W1, top_candidate_W1.constituents(), particleIn);	    
      lccTopTaggerW1Out->addElement(W1);
      
      // save part 2 of W candidate
      fastjet::PseudoJet top_candidate_W2 = top_candidate.structure_of<fastjet::JHTopTagger>().W2();
      ReconstructedParticle* W2 = _fju->convertFromPseudoJet(top_candidate_W2, top_candidate_W2.constituents(), particleIn);	    
      lccTopTaggerW2Out->addElement(W2);    

      // save non-W subjet of top candidate
      fastjet::PseudoJet top_candidate_nonW = top_candidate.structure_of<fastjet::JHTopTagger>().non_W();
      ReconstructedParticle* nonW = _fju->convertFromPseudoJet(top_candidate_nonW, top_candidate_nonW.constituents(), particleIn);	    
      lccTopTaggernonWOut->addElement(nonW);
         
      // save the polarisation angle of W
      double top_candidate_cos_theta_W = top_candidate.structure_of<fastjet::JHTopTagger>().cos_theta_W();
      lcgTopTaggerCosThetaW->setDoubleVal(index, top_candidate_cos_theta_W);

    }
  }

  evt->addCollection(lccJetsOut, _lcJetOutName);
  if (_storeParticlesInJets) evt->addCollection(lccParticlesOut, _lcParticleOutName);
  
  if (_doSubstructure){
    lccSubStructure->addElement(lcgSubStructureC2);
    lccSubStructure->addElement(lcgSubStructureD2);
    lccSubStructure->addElement(lcgSubStructureC3);
    lccSubStructure->addElement(lcgSubStructureD3);
    lccSubStructure->addElement(lcgSubStructureTau1);
    lccSubStructure->addElement(lcgSubStructureTau2);
    lccSubStructure->addElement(lcgSubStructureTau3);
    evt->addCollection(lccSubStructure, _lcSubStructureOutName);
  }

  evt->addCollection(lccTopTaggerOut, _lcTopTaggerOutName);
  evt->addCollection(lccTopTaggerWOut, _lcTopTaggerOutName+"_W");
  evt->addCollection(lccTopTaggernonWOut, _lcTopTaggerOutName+"_nonW");
  evt->addCollection(lccTopTaggerW1Out, _lcTopTaggerOutName+"_W1");
  evt->addCollection(lccTopTaggerW2Out, _lcTopTaggerOutName+"_W2");

  lccTopTaggerCosThetaW->addElement(lcgTopTaggerCosThetaW);  
  evt->addCollection(lccTopTaggerCosThetaW, _lcTopTaggerOutName+"_cos_theta_W");
  
  // special case for the exclusive jet mode: we can save the transition y_cut value
  if (_fju->_clusterMode == FJ_exclusive_nJets && jets.size() == _fju->_requestedNumberOfJets) {
    // save the dcut value for this algorithm (although it might not be meaningful)
    LCParametersImpl &lccJetParams((LCParametersImpl &)lccJetsOut->parameters());
    
    lccJetParams.setValue(std::string("d_{n-1,n}"), (float)_fju->_cs->exclusive_dmerge(nrJets-1));
    lccJetParams.setValue(std::string("d_{n,n+1}"), (float)_fju->_cs->exclusive_dmerge(nrJets));
    lccJetParams.setValue(std::string("y_{n-1,n}"), (float)_fju->_cs->exclusive_ymerge(nrJets-1));
    lccJetParams.setValue(std::string("y_{n,n+1}"), (float)_fju->_cs->exclusive_ymerge(nrJets));
  }
  
} //end processEvent
Beispiel #3
0
/* Example program for (re) fitting LCIO tracks with aidaTT.
 * 
 */
int main(int argc, char** argv)
{

  if(argc < 3) {
    std::cout << " usage: ./lcio_tracks compact.xml input_tracks.slcio [output_file.slcio]" << std::endl ;
    return 1;
  }

#ifdef AIDATT_USE_STREAMLOG
  streamlog::out.init( std::cout , "lcio_tracks" ) ;
  streamlog::logscope scope(streamlog::out) ;
  scope.setLevel<VERBOSITY>()  ;
#endif

  std::string inFile =  argv[1] ;

  const aidaTT::IGeometry& geom = aidaTT::IGeometry::instance( inFile ) ;

  const SurfaceVec& surfaces = geom.getSurfaces() ;

  // create map of surfaces
  
  for(std::vector<const aidaTT::ISurface*>::const_iterator surf = surfaces.begin() ; surf != surfaces.end() ; ++surf){
    surfMap[(*surf)->id() ] = (*surf) ;
  }
  
  //*********************************************************************
  /// lcio stuff
  std::string lcioFileName = argv[2] ;

  int counter = -1 ;

  LCReader* rdr = LCFactory::getInstance()->createLCReader() ;
  rdr->open(lcioFileName) ;
  LCWriter* wrt = LCFactory::getInstance()->createLCWriter() ;

  if(argc == 4) {
    std::string outFile = argv[3];
    wrt->open(outFile) ;

  } else {
    wrt->open("aidaTT_tracks.slcio", lcio::LCIO::WRITE_NEW ) ;
  }

  LCEvent* evt = 0 ;

  UTIL::BitField64 idDecoder(LCTrackerCellID::encoding_string()) ;

  // create the propagation object
  aidaTT::analyticalPropagation* propagation = new aidaTT::analyticalPropagation();
  //aidaTT::simplifiedPropagation* propagation = new aidaTT::simplifiedPropagation();

  // create the fitter object
  aidaTT::GBLInterface* fitter = new aidaTT::GBLInterface();
  
  
  /// event loop
  while( (evt = rdr->readNextEvent()) != 0 &&  ++counter < maxEvent ) {
    
    LCCollection* trackCollection = evt->getCollection(trackCollectionName) ;
    
    // add output track collection to the event
    LCCollectionVec* outCol = new LCCollectionVec(LCIO::TRACK) ;
    
    evt->addCollection( outCol, outColName ) ;
    
    LCFlagImpl trkFlag(0) ;
    trkFlag.setBit(LCIO::TRBIT_HITS) ;
    outCol->setFlag(trkFlag.getFlag()) ;

    int nTracks = trackCollection->getNumberOfElements();
    
    // loop over all tracks in the collection
    for( unsigned i=0 ; i<nTracks ; ++i){
      
      TrackImpl* outTrk = new TrackImpl ;
      outCol->addElement(outTrk) ;

      Track* initialTrack = (Track*) trackCollection->getElementAt(i) ;
    
      aidaTT::trackParameters iTP(  aidaTT::readLCIO( initialTrack->getTrackState( trkStateIndex ) )   );  
    
      const TrackerHitVec& initialHits = initialTrack->getTrackerHits();
      unsigned nHits = initialHits.size() ;

      if( nHits < 3) {
	
	streamlog_out( DEBUG5 ) << " less than three hits - track is dropped ..." << std::endl ;
	
	continue ;
      }


      if( compute_start_helix ) { 

	//----------------------------------------------------------------------------------------------------
	aidaTT::trackParameters startHelix ;
	
	
	//--------- get the start helix from three points
	bool backwards = false ;
	
	lcio::TrackerHit* h1 = ( backwards ?  initialHits[ nHits-1 ] : initialHits[    0    ] ) ;
	lcio::TrackerHit* h2 =  initialHits[ (nHits+1) / 2 ] ;
	lcio::TrackerHit* h3 = ( backwards ?  initialHits[    0    ] : initialHits[ nHits-1 ] ) ;
	
	const double* pos1 = h1->getPosition() ;
	const double* pos2 = h2->getPosition() ;
	const double* pos3 = h3->getPosition() ;
	
	aidaTT::Vector3D x1( pos1[0] * dd4hep::mm, pos1[1] * dd4hep::mm , pos1[2] * dd4hep::mm ) ;
	aidaTT::Vector3D x2( pos2[0] * dd4hep::mm, pos2[1] * dd4hep::mm , pos2[2] * dd4hep::mm ) ;
	aidaTT::Vector3D x3( pos3[0] * dd4hep::mm, pos3[1] * dd4hep::mm , pos3[2] * dd4hep::mm ) ;
	
	calculateStartHelix( x1, x2,  x3 , startHelix , backwards ) ;
	
	moveHelixTo( startHelix, aidaTT::Vector3D(), false  ) ; // move to origin
	
	// --- set some large errors to the covariance matrix
	startHelix.covarianceMatrix().Unit() ;
	startHelix.covarianceMatrix()( aidaTT::OMEGA, aidaTT::OMEGA ) = 1.e-2 ;
	startHelix.covarianceMatrix()( aidaTT::TANL , aidaTT::TANL  ) = 1.e2 ;
	startHelix.covarianceMatrix()( aidaTT::PHI0 , aidaTT::PHI0  ) = 1.e2 ;
	startHelix.covarianceMatrix()( aidaTT::D0   , aidaTT::D0    ) = 1.e5 ;
	startHelix.covarianceMatrix()( aidaTT::Z0   , aidaTT::Z0    ) = 1.e5 ;
	
	streamlog_out( DEBUG4 ) << "  start helix from three points : " << startHelix << std::endl ;
	
	
	// use this helix as start for the fit:
	iTP = ( run_prefit ? createPreFit( startHelix , initialHits ) : startHelix  )  ;
      }
	
      TrackStateImpl* ts;
      bool success;	      
      
      aidaTT::trajectory fitTrajectory( iTP, fitter, propagation, &geom);
      
      const aidaTT::fitResults* result = 0 ; //fitTrajectory.getFitResults();
      
      streamlog_out( DEBUG1 )  << " magnetic field at origin " 
			       << fitTrajectory.geometry()->getBField( aidaTT::Vector3D() ) 
			       << std::endl ;
      

      // copy the hits in order to get strip hits in case of spacepoints
      TrackerHitVec lcioHits ;
      for(unsigned i=0 ; i < nHits ; ++i){
	TrackerHit* trkHit = initialHits[i] ;

	outTrk->addHit( trkHit  ) ;

	if( UTIL::BitSet32( trkHit->getType() )[ UTIL::ILDTrkHitTypeBit::COMPOSITE_SPACEPOINT ]  ){
	  
	  const EVENT::LCObjectVec rawObjects = trkHit->getRawHits();                    
	  
	  for( unsigned k=0; k< rawObjects.size(); k++ ){
	    EVENT::TrackerHit* rawHit = dynamic_cast< EVENT::TrackerHit* >( rawObjects[k] );
	    
	    lcioHits.push_back( rawHit ) ;
          }
	  
	} else { // normal non composite hit

	  lcioHits.push_back( trkHit ) ;
	}
      }


      // ==== store hits in a map and in track  ===============
      std::map< int, EVENT::TrackerHit*> hitMap ;
      for(unsigned i=0 ; i < lcioHits.size() ; ++i){
	hitMap[ lcioHits[i]->getCellID0()  ] = lcioHits[i] ;
      }
      
      //==== compute _all_ surface intersections ====================== 
      const IntersectionVec* intersections = &fitTrajectory.getIntersectionsWithSurfaces( surfaces ) ;
      
      // now we have all surface intersections of the initial track seed
      // however the hits might be on neighbouring sensors really ...

      // ... to be sorted out ...

      //========= loop over all intersections =========
      int pointLabel = 0 ; 
      for( std::vector<std::pair<double, const aidaTT::ISurface*> >::const_iterator it =  
	     intersections->begin() ; it != intersections->end() ; ++it ){
	
	const aidaTT::ISurface* surf = it->second ;
	
	EVENT::TrackerHit* hit = hitMap[ surf->id() ] ;
	
	streamlog_out(DEBUG4) << "intersection - current pointLabel : " << pointLabel  
			      << ":  at s = " << it->first <<  " surface id : " 
			      << cellIDString( surf->id()  ) << std::endl ; 

	streamlog_out(DEBUG1) << aidaTT::pointAt(it->first, iTP ) << std::endl ;

	streamlog_out(DEBUG) << *surf << std::endl ;
	
	if( hit != 0 ){ //-------- we have to add a measurement   
	  
	  double hitpos[3] ;
	  std::vector<double> precision ;
	  getHitInfo( hit, hitpos, precision , surf) ;
	  
	  fitTrajectory.addMeasurement( hitpos, precision, *surf, hit , useQMS );
	  ++pointLabel ;

	  streamlog_out(DEBUG3) << "addMeasurement called for pointLabel : " << pointLabel << std::endl ;
	  
	} else  { // we just add a scatterer
	  
	  if ( useQMS ){
	    
	    // ignore virtual surface with no material (e.g. inside the beam pipe )
	    
	    if( ! ( surf->innerMaterial().density() < 1e-6  && 
		    surf->outerMaterial().density() < 1e-6 )  ) {
	      
	      fitTrajectory.addScatterer( *surf ) ;
	      ++pointLabel ;

	      streamlog_out(DEBUG3) << " addScatterer called for pointLabel : " << pointLabel << std::endl ;
	    }
	  }
	}
      }

      
      fitTrajectory.prepareForFitting();
      
      success = fitTrajectory.fit();
      
      result = fitTrajectory.getFitResults();
      
      
      //***********************************************************************************************************

      if( ! success ) {
	streamlog_out( ERROR ) << " ********** ERROR:  Fit Failed !!!!! ****" 
			       << std::endl ;
      }
      
	      
      
      streamlog_out( DEBUG ) << " End of the loop " << std::endl ;
      streamlog_out( DEBUG ) << " initial values " << std::endl;
      streamlog_out( DEBUG ) << iTP << std::endl;
      streamlog_out( DEBUG ) << " refitted values " << std::endl;
      streamlog_out( DEBUG ) << result->estimatedParameters() << std::endl;
      
      // add Track State to track:
      ts = aidaTT::createLCIO( result->estimatedParameters() );
      //DEBUG: return seed track: ts = aidaTT::createLCIO( iTP );
      
      outTrk->setChi2( result->chiSquare() ) ;
      outTrk->setNdf( result->ndf() ) ;
      outTrk->subdetectorHitNumbers().resize(10.) ;
      
      outTrk->subdetectorHitNumbers()[0] = outTrk->getTrackerHits().size() ;
      
      float ref[3] = { 0., 0. , 0. } ;
      ts->setReferencePoint(ref);	    
      ts->setLocation(lcio::TrackState::AtIP);
      
      
      // checking the covariance matrix
      //--------------------------------------------------------------------
      std::vector<float> cm  =  ts->getCovMatrix();
      trackParameters finalAidaTP = result->estimatedParameters();
      fiveByFiveMatrix  finalAidaCovMat = finalAidaTP.covarianceMatrix();
      
      //---------------------------------------------------------------------
      
      outTrk->addTrackState(ts);
      
    }

    wrt->writeEvent(evt) ;
  }
  
  streamlog_out( DEBUG ) << " counter = " << counter << std::endl ;
  
  return 0;
}