-
Stephen A. Wood authored
Results are focal plane coordinate (transport) system, not detector system Turn on golden track selection.
Stephen A. Wood authoredResults are focal plane coordinate (transport) system, not detector system Turn on golden track selection.
THcHallCSpectrometer.cxx 7.44 KiB
//*-- Author : Stephen Wood 20-Apr-2012
//////////////////////////////////////////////////////////////////////////
//
// THcHallCSpectrometer
//
// A standard Hall C spectrometer.
// Contains no standard detectors,
// May add hodoscope
//
// The usual name of this object is either "H", "S", or "P"
// for HMS, SOS, or suPerHMS respectively
//
// Defines the functions FindVertices() and TrackCalc(), which are common
// to both the LeftHRS and the RightHRS.
//
// Special configurations of the HRS (e.g. more detectors, different
// detectors) can be supported in on e of three ways:
//
// 1. Use the AddDetector() method to include a new detector
// in this apparatus. The detector will be decoded properly,
// and its variables will be available for cuts and histograms.
// Its processing methods will also be called by the generic Reconstruct()
// algorithm implemented in THaSpectrometer::Reconstruct() and should
// be correctly handled if the detector class follows the standard
// interface design.
//
// 2. Write a derived class that creates the detector in the
// constructor. Write a new Reconstruct() method or extend the existing
// one if necessary.
//
// 3. Write a new class inheriting from THaSpectrometer, using this
// class as an example. This is appropriate if your HRS
// configuration has fewer or different detectors than the
// standard HRS. (It might not be sensible to provide a RemoveDetector()
// method since Reconstruct() relies on the presence of the
// standard detectors to some extent.)
//
// For timing calculations, S1 is treated as the scintillator at the
// 'reference distance', corresponding to the pathlength correction
// matrix.
//
//////////////////////////////////////////////////////////////////////////
#include "THcHallCSpectrometer.h"
#include "THaTrackingDetector.h"
#include "THaTrack.h"
#include "THaTrackProj.h"
#include "THaTriggerTime.h"
#include "TMath.h"
#include "TList.h"
#include "TList.h"
#include "TMath.h"
#ifdef WITH_DEBUG
#include <iostream>
#endif
using namespace std;
//_____________________________________________________________________________
THcHallCSpectrometer::THcHallCSpectrometer( const char* name, const char* description ) :
THaSpectrometer( name, description )
{
// Constructor. Defines the standard detectors for the HRS.
// AddDetector( new THaTriggerTime("trg","Trigger-based time offset"));
//sc_ref = static_cast<THaScintillator*>(GetDetector("s1"));
SetTrSorting(kTRUE);
}
//_____________________________________________________________________________
THcHallCSpectrometer::~THcHallCSpectrometer()
{
// Destructor
}
//_____________________________________________________________________________
Bool_t THcHallCSpectrometer::SetTrSorting( Bool_t set )
{
if( set )
fProperties |= kSortTracks;
else
fProperties &= ~kSortTracks;
return set;
}
//_____________________________________________________________________________
Bool_t THcHallCSpectrometer::GetTrSorting() const
{
return ((fProperties & kSortTracks) != 0);
}
//_____________________________________________________________________________
Int_t THcHallCSpectrometer::FindVertices( TClonesArray& tracks )
{
// Reconstruct target coordinates for all tracks found in the focal plane.
TIter nextTrack( fTrackingDetectors );
nextTrack.Reset();
while( THaTrackingDetector* theTrackDetector =
static_cast<THaTrackingDetector*>( nextTrack() )) {
#ifdef WITH_DEBUG
if( fDebug>1 ) cout << "Call FineTrack() for "
<< theTrackDetector->GetName() << "... ";
#endif
theTrackDetector->FindVertices( tracks );
#ifdef WITH_DEBUG
if( fDebug>1 ) cout << "done.\n";
#endif
}
// If enabled, sort the tracks by chi2/ndof
if( GetTrSorting() )
fTracks->Sort();
// Find the "Golden Track".
if( GetNTracks() > 0 ) {
// Select first track in the array. If there is more than one track
// and track sorting is enabled, then this is the best fit track
// (smallest chi2/ndof). Otherwise, it is the track with the best
// geometrical match (smallest residuals) between the U/V clusters
// in the upper and lower VDCs (old behavior).
//
// Chi2/dof is a well-defined quantity, and the track selected in this
// way is immediately physically meaningful. The geometrical match
// criterion is mathematically less well defined and not usually used
// in track reconstruction. Hence, chi2 sortiing is preferable, albeit
// obviously slower.
fGoldenTrack = static_cast<THaTrack*>( fTracks->At(0) );
fTrkIfo = *fGoldenTrack;
fTrk = fGoldenTrack;
} else
fGoldenTrack = NULL;
return 0;
}
//_____________________________________________________________________________
Int_t THcHallCSpectrometer::TrackCalc()
{
// Additioal track calculations. At present, we only calculate beta here.
return TrackTimes( fTracks );
}
//_____________________________________________________________________________
Int_t THcHallCSpectrometer::TrackTimes( TClonesArray* Tracks ) {
// Do the actual track-timing (beta) calculation.
// Use multiple scintillators to average together and get "best" time at S1.
//
// To be useful, a meaningful timing resolution should be assigned
// to each Scintillator object (part of the database).
if ( !Tracks ) return -1;
THaTrack *track=0;
Int_t ntrack = GetNTracks();
// linear regression to: t = t0 + pathl/(beta*c)
// where t0 is the time of the track at the reference plane (sc_ref).
// t0 and beta are solved for.
//
#if 0
for ( Int_t i=0; i < ntrack; i++ ) {
track = static_cast<THaTrack*>(Tracks->At(i));
THaTrackProj* tr_ref = static_cast<THaTrackProj*>
(sc_ref->GetTrackHits()->At(i));
Double_t pathlref = tr_ref->GetPathLen();
Double_t wgt_sum=0.,wx2=0.,wx=0.,wxy=0.,wy=0.;
Int_t ncnt=0;
// linear regression to get beta and time at ref.
TIter nextSc( fNonTrackingDetectors );
THaNonTrackingDetector *det;
while ( ( det = static_cast<THaNonTrackingDetector*>(nextSc()) ) ) {
THaScintillator *sc = dynamic_cast<THaScintillator*>(det);
if ( !sc ) continue;
const THaTrackProj *trh = static_cast<THaTrackProj*>(sc->GetTrackHits()->At(i));
Int_t pad = trh->GetChannel();
if (pad<0) continue;
Double_t pathl = (trh->GetPathLen()-pathlref);
Double_t time = (sc->GetTimes())[pad];
Double_t wgt = (sc->GetTuncer())[pad];
if (pathl>.5*kBig || time>.5*kBig) continue;
if (wgt>0) wgt = 1./(wgt*wgt);
else continue;
wgt_sum += wgt;
wx2 += wgt*pathl*pathl;
wx += wgt*pathl;
wxy += wgt*pathl*time;
wy += wgt*time;
ncnt++;
}
Double_t beta = kBig;
Double_t dbeta = kBig;
Double_t time = kBig;
Double_t dt = kBig;
Double_t delta = wgt_sum*wx2-wx*wx;
if (delta != 0.) {
time = (wx2*wy-wx*wxy)/delta;
dt = TMath::Sqrt(wx2/delta);
Double_t invbeta = (wgt_sum*wxy-wx*wy)/delta;
if (invbeta != 0.) {
#if ROOT_VERSION_CODE >= ROOT_VERSION(3,4,0)
Double_t c = TMath::C();
#else
Double_t c = 2.99792458e8;
#endif
beta = 1./(c*invbeta);
dbeta = TMath::Sqrt(wgt_sum/delta)/(c*invbeta*invbeta);
}
}
track->SetBeta(beta);
track->SetdBeta(dbeta);
track->SetTime(time);
track->SetdTime(dt);
}
#endif
return 0;
}
//_____________________________________________________________________________
ClassImp(THcHallCSpectrometer)