Exemple #1
0
//_____________________________________________________________________________
Int_t THaVDCPlane::FitTracks()
{
  // Fit tracks to cluster positions and drift distances.

  Int_t nClust = GetNClusters();
  for (int i = 0; i < nClust; i++) {
    THaVDCCluster* clust = static_cast<THaVDCCluster*>( (*fClusters)[i] );
    if( !clust ) continue;

    // Convert drift times to distances.
    // The conversion algorithm is determined at wire initialization time,
    // i.e. currently in the ReadDatabase() function of this class.
    // The conversion is done with the current value of fSlope in the
    // clusters, i.e. either the rough guess from
    // THaVDCCluster::EstTrackParameters or the global slope from
    // THaVDC::ConstructTracks
    clust->ConvertTimeToDist();

    // Fit drift distances to get intercept, slope.
    clust->FitTrack();

#ifdef CLUST_RAWDATA_HACK
    // HACK: write out cluster info for small-t0 clusters in u1
    if( fName == "u" && !strcmp(GetParent()->GetName(),"uv1") &&
	TMath::Abs(clust->GetT0()) < fT0Resolution/3. &&
	clust->GetSize() <= 6 ) {
      ofstream outp;
      outp.open("u1_cluster_data.out",ios_base::app);
      outp << clust->GetSize() << endl;
      for( int i=clust->GetSize()-1; i>=0; i-- ) {
	outp << clust->GetHit(i)->GetPos() << " "
	     << clust->GetHit(i)->GetDist()
	     << endl;
      }
      outp << 1./clust->GetSlope() << " "
	   << clust->GetIntercept()
	   << endl;
      outp.close();
    }
#endif
  }

  return 0;
}
Exemple #2
0
//_____________________________________________________________________________
Int_t THaVDCPlane::FindClusters()
{
  // Reconstruct clusters in a VDC plane
  // Assumes that the wires are numbered such that increasing wire numbers
  // correspond to decreasing physical position.
  // Ignores possibility of overlapping clusters

  TimeCut timecut(fVDC,this);

// #ifndef NDEBUG
//   // bugcheck
//   bool only_fastest_hit = false;
//   if( fVDC )
//     only_fastest_hit = fVDC->TestBit(THaVDC::kOnlyFastest);
// #endif

  Int_t nHits     = GetNHits();   // Number of hits in the plane
  Int_t nUsed = 0;                // Number of wires used in clustering
  Int_t nLastUsed = -1;
  Int_t nextClust = 0;            // Current cluster number
  assert( GetNClusters() == 0 );

  vector <THaVDCHit *> clushits;
  Double_t deltat;
  Bool_t falling;

  fNpass = 0;

  Int_t nwires, span;
  UInt_t j;

  //  Loop while we're making new clusters
  while( nLastUsed != nUsed ){
     fNpass++;
     nLastUsed = nUsed;
     //Loop through all TDC hits
     for( Int_t i = 0; i < nHits; ) {
       clushits.clear();
       falling = kTRUE;

       THaVDCHit* hit = GetHit(i);
       assert(hit);

       if( !timecut(hit) ) {
	       ++i;
	       continue;
       }
       if( hit->GetClsNum() != -1 )
       	  { ++i; continue; }
       // Ensures we don't use this to try and start a new
       // cluster
       hit->SetClsNum(-3);

       // Consider this hit the beginning of a potential new cluster.
       // Find the end of the cluster.
       span = 0;
       nwires = 1;
       while( ++i < nHits ) {
	  THaVDCHit* nextHit = GetHit(i);
	  assert( nextHit );    // should never happen, else bug in Decode
	  if( !timecut(nextHit) )
		  continue;
	  if(    nextHit->GetClsNum() != -1   // -1 is virgin
	      && nextHit->GetClsNum() != -3 ) // -3 was considered to start
		  			      //a clus but is not in cluster
		  continue;
	  Int_t ndif = nextHit->GetWireNum() - hit->GetWireNum();
	  // Do not consider adding hits from a wire that was already
	  // added
	  if( ndif == 0 ) { continue; }
	  assert( ndif >= 0 );
	  // The cluster ends when we encounter a gap in wire numbers.
	  // TODO: cluster should also end if
	  //  DONE (a) it is too big
	  //  DONE (b) drift times decrease again after initial fall/rise (V-shape)
	  //  DONE (c) Enforce reasonable changes in wire-to-wire V-shape

	  // Times are sorted by earliest first when on same wire
	  deltat = nextHit->GetTime() - hit->GetTime();

	  span += ndif;
	  if( ndif > fNMaxGap+1 || span > fMaxClustSpan ){
		  break;
	  }

	  // Make sure the time structure is sensible
	  // If this cluster is rising, wire with falling time
	  // should not be associated in the cluster
	  if( !falling ){
		  if( deltat < fMinTdiff*ndif ||
		      deltat > fMaxTdiff*ndif )
		  { continue; }
	  }

	  if( falling ){
		  // Step is too big, can't be associated
		  if( deltat < -fMaxTdiff*ndif ){ continue; }
		  if( deltat > 0.0 ){
			  // if rise is reasonable and we don't
			  // have a monotonically increasing cluster
			  if( deltat < fMaxTdiff*ndif && span > 1 ){
				  // now we're rising
				  falling = kFALSE;
			  } else {
				  continue;
			  }
		  }
	  }

	  nwires++;
	  if( clushits.size() == 0 ){
		  clushits.push_back(hit);
		  hit->SetClsNum(-2);
		  nUsed++;
	  }
	  clushits.push_back(nextHit);
	  nextHit->SetClsNum(-2);
	  nUsed++;
	  hit = nextHit;
       }
       assert( i <= nHits );
       // Make a new cluster if it is big enough
       // If not, the hits of this i-iteration are ignored
       // Also, make sure that we did indeed see the time
       // spectrum turn around at some point
       if( nwires >= fMinClustSize && !falling ) {
	  THaVDCCluster* clust =
	     new ( (*fClusters)[nextClust++] ) THaVDCCluster(this);

	  for( j = 0; j < clushits.size(); j++ ){
	     clushits[j]->SetClsNum(nextClust-1);
	     clust->AddHit( clushits[j] );
	  }

	  assert( clust->GetSize() > 0 && clust->GetSize() >= nwires );
	  // This is a good cluster candidate. Estimate its position/slope
	  clust->EstTrackParameters();
       } //end new cluster

     } //end loop over hits

  } // end passes over hits

  assert( GetNClusters() == nextClust );

  return nextClust;  // return the number of clusters found
}