示例#1
0
//_____________________________________________________________________________
THaVDCTrackID::THaVDCTrackID( const THaVDCUVTrack* lower,
			      const THaVDCUVTrack* upper) :
  THaTrackID()
{
  // Constructor that automatically determines pivot numbers
  // from the given THaVDCUVTracks.

  THaVDCCluster* cluster;
  if( lower ) {
    if( (cluster = lower->GetUCluster()))
      fLowerU = cluster->GetPivotWireNum();
    if( (cluster = lower->GetVCluster()))
      fLowerV = cluster->GetPivotWireNum();
  }
  if( upper ) {
    if( (cluster = upper->GetUCluster()))
      fUpperU = cluster->GetPivotWireNum();
    if( (cluster = upper->GetVCluster()))
      fUpperV = cluster->GetPivotWireNum();
  }
}
示例#2
0
文件: THaVDC.C 项目: whit2333/podd
//_____________________________________________________________________________
Int_t THaVDC::ConstructTracks( TClonesArray* tracks, Int_t mode )
{
  // Construct tracks from pairs of upper and lower UV tracks and add 
  // them to 'tracks'

#ifdef WITH_DEBUG
  if( fDebug>1 ) {
    cout << "-----------------------------------------------\n";
    cout << "ConstructTracks: ";
    if( mode == 0 )
      cout << "iterating";
    if( mode == 1 )
      cout << "coarse tracking";
    if( mode == 2 )
      cout << "fine tracking";
    cout << endl;
  }
#endif
  UInt_t theStage = ( mode == 1 ) ? kCoarse : kFine;

  fUVpairs->Clear();

  Int_t nUpperTracks = fUpper->GetNUVTracks();
  Int_t nLowerTracks = fLower->GetNUVTracks();

#ifdef WITH_DEBUG
  if( fDebug>1 )
    cout << "nUpper/nLower = " << nUpperTracks << "  " << nLowerTracks << endl;
#endif

  // No tracks at all -> can't have any tracks
  if( nUpperTracks == 0 && nLowerTracks == 0 ) {
#ifdef WITH_DEBUG
    if( fDebug>1 )
      cout << "No tracks.\n";
#endif
    return 0;
  }

  Int_t nTracks = 0;  // Number of valid particle tracks through the detector
  Int_t nPairs  = 0;  // Number of UV track pairs to consider

  // One plane has no tracks, the other does 
  // -> maybe recoverable with loss of precision
  // FIXME: Only do this if missing cluster recovery flag set
  if( nUpperTracks == 0 || nLowerTracks == 0 ) {
    //FIXME: Put missing cluster recovery code here
    //For now, do nothing
#ifdef WITH_DEBUG
    if( fDebug>1 ) 
      cout << "missing cluster " << nUpperTracks << " " << nUpperTracks << endl;
#endif
    return 0;
  }

  THaVDCUVTrack *track, *partner;
  THaVDCTrackPair *thePair;

  for( int i = 0; i < nLowerTracks; i++ ) {
    track = fLower->GetUVTrack(i);
    if( !track ) 
      continue;

    for( int j = 0; j < nUpperTracks; j++ ) {
      partner = fUpper->GetUVTrack(j);
      if( !partner ) 
	continue;

      // Create new UV track pair.
      thePair = new( (*fUVpairs)[nPairs++] ) THaVDCTrackPair( track, partner );

      // Explicitly mark these UV tracks as unpartnered
      track->SetPartner( NULL );
      partner->SetPartner( NULL );

      // Compute goodness of match parameter
      thePair->Analyze( fUSpacing );
    }
  }
      
#ifdef WITH_DEBUG
  if( fDebug>1 )
    cout << nPairs << " pairs.\n";
#endif

  // Initialize some counters
  int n_exist = 0, n_mod = 0;
  int n_oops = 0;
  // How many tracks already exist in the global track array?
  if( tracks )
    n_exist = tracks->GetLast()+1;

  // Sort pairs in order of ascending goodness of match
  if( nPairs > 1 )
    fUVpairs->Sort();

  // Mark pairs as partners, starting with the best matches,
  // until all tracks are marked.
  for( int i = 0; i < nPairs; i++ ) {
    if( !(thePair = static_cast<THaVDCTrackPair*>( fUVpairs->At(i) )) )
      continue;

#ifdef WITH_DEBUG
    if( fDebug>1 ) {
      cout << "Pair " << i << ":  " 
	   << thePair->GetUpper()->GetUCluster()->GetPivotWireNum() << " "
	   << thePair->GetUpper()->GetVCluster()->GetPivotWireNum() << " "
	   << thePair->GetLower()->GetUCluster()->GetPivotWireNum() << " "
	   << thePair->GetLower()->GetVCluster()->GetPivotWireNum() << " "
	   << thePair->GetError() << endl;
    }
#endif
    // Stop if track matching error too big
    if( thePair->GetError() > fErrorCutoff )
      break;

    // Get the tracks of the pair
    track   = thePair->GetLower();
    partner = thePair->GetUpper();
    if( !track || !partner ) 
      continue;

    //FIXME: debug
#ifdef WITH_DEBUG
    if( fDebug>1 ) {
      cout << "dUpper/dLower = " 
	   << thePair->GetProjectedDistance( track,partner,fUSpacing) << "  "
	   << thePair->GetProjectedDistance( partner,track,-fUSpacing);
    }
#endif

    // Skip pairs where any of the tracks already has a partner
    if( track->GetPartner() || partner->GetPartner() ) {
#ifdef WITH_DEBUG
      if( fDebug>1 )
	cout << " ... skipped.\n";
#endif
      continue;
    }
#ifdef WITH_DEBUG
    if( fDebug>1 )
      cout << " ... good.\n";
#endif

    // Make the tracks of this pair each other's partners. This prevents
    // tracks from being associated with more than one valid pair.
    track->SetPartner( partner );
    partner->SetPartner( track );
    thePair->SetStatus(1);

    nTracks++;

    // Compute global track values and get TRANSPORT coordinates for tracks.
    // Replace local cluster slopes with global ones, 
    // which have higher precision.

    THaVDCCluster 
      *tu = track->GetUCluster(), 
      *tv = track->GetVCluster(), 
      *pu = partner->GetUCluster(),
      *pv = partner->GetVCluster();

    Double_t du = pu->GetIntercept() - tu->GetIntercept();
    Double_t dv = pv->GetIntercept() - tv->GetIntercept();
    Double_t mu = du / fUSpacing;
    Double_t mv = dv / fVSpacing;

    tu->SetSlope(mu);
    tv->SetSlope(mv);
    pu->SetSlope(mu);
    pv->SetSlope(mv);

    // Recalculate the UV track's detector coordinates using the global
    // U,V slopes.
    track->CalcDetCoords();
    partner->CalcDetCoords();

#ifdef WITH_DEBUG
    if( fDebug>2 )
      cout << "Global track parameters: " 
	   << mu << " " << mv << " " 
	   << track->GetTheta() << " " << track->GetPhi()
	   << endl;
#endif

    // If the 'tracks' array was given, add THaTracks to it 
    // (or modify existing ones).
    if (tracks) {

      // Decide whether this is a new track or an old track 
      // that is being updated
      THaVDCTrackID* thisID = new THaVDCTrackID(track,partner);
      THaTrack* theTrack = NULL;
      bool found = false;
      int t;
      for( t = 0; t < n_exist; t++ ) {
	theTrack = static_cast<THaTrack*>( tracks->At(t) );
	// This test is true if an existing track has exactly the same clusters
	// as the current one (defined by track/partner)
	if( theTrack && theTrack->GetCreator() == this &&
	    *thisID == *theTrack->GetID() ) {
	  found = true;
	  break;
	}
	// FIXME: for debugging
	n_oops++;
      }

      UInt_t flag = theStage;
      if( nPairs > 1 )
	flag |= kMultiTrack;

      if( found ) {
#ifdef WITH_DEBUG
        if( fDebug>1 )
          cout << "Track " << t << " modified.\n";
#endif
        delete thisID;
        ++n_mod;
      } else {
#ifdef WITH_DEBUG
	if( fDebug>1 )
	  cout << "Track " << tracks->GetLast()+1 << " added.\n";
#endif
	theTrack = AddTrack(*tracks, 0.0, 0.0, 0.0, 0.0, thisID );
	//	theTrack->SetID( thisID );
	//	theTrack->SetCreator( this );
	theTrack->AddCluster( track );
	theTrack->AddCluster( partner );
	if( theStage == kFine ) 
	  flag |= kReassigned;
      }
      

      theTrack->SetD(track->GetX(), track->GetY(), track->GetTheta(), 
		     track->GetPhi());
      theTrack->SetFlag( flag );
      
      Double_t chi2=0;
      Int_t nhits=0;
      track->CalcChisquare(chi2,nhits);
      partner->CalcChisquare(chi2,nhits);
      theTrack->SetChi2(chi2,nhits-4); // Nconstraints - Nparameters

      // calculate the TRANSPORT coordinates
      CalcFocalPlaneCoords(theTrack, kRotatingTransport);
    }
  }

#ifdef WITH_DEBUG
  if( fDebug>1 )
    cout << nTracks << " good tracks.\n";
#endif

  // Delete tracks that were not updated
  if( tracks && n_exist > n_mod ) {
    bool modified = false;
    for( int i = 0; i < tracks->GetLast()+1; i++ ) {
      THaTrack* theTrack = static_cast<THaTrack*>( tracks->At(i) );
      // Track created by this class and not updated?
      if( (theTrack->GetCreator() == this) &&
	  ((theTrack->GetFlag() & kStageMask) != theStage ) ) {
#ifdef WITH_DEBUG
	if( fDebug>1 )
	  cout << "Track " << i << " deleted.\n";
#endif
	tracks->RemoveAt(i);
	modified = true;
      }
    }
    // Get rid of empty slots - they may cause trouble in the Event class and
    // with global variables.
    // Note that the PIDinfo and vertices arrays are not reordered.
    // Therefore, PID and vertex information must always be retrieved from the
    // track objects, not from the PID and vertex TClonesArrays.
    // FIXME: Is this really what we want?
    if( modified )
      tracks->Compress();
  }

  return nTracks;
}
示例#3
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;
}
示例#4
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
}