-
Stephen A. Wood authored
THcHodoscope, a multiplane scintillator array. Make a Hall C style spectrometer (so that default Hall A detectors are not included.) Can read a Hall C data file and print out hodoscope hits where the left/right TDC/ADC are matched up per counter.
Stephen A. Wood authoredTHcHodoscope, a multiplane scintillator array. Make a Hall C style spectrometer (so that default Hall A detectors are not included.) Can read a Hall C data file and print out hodoscope hits where the left/right TDC/ADC are matched up per counter.
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(kFALSE);
}
//_____________________________________________________________________________
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)