//_____________________________________________________________________________ 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; }
//_____________________________________________________________________________ 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 }