From 8394016045848e962601613c79ed2c5d1d91dbe0 Mon Sep 17 00:00:00 2001
From: "Stephen A. Wood" <zviwood@gmail.com>
Date: Tue, 4 Oct 2016 11:02:28 -0400
Subject: [PATCH] Update hodoscope code to work with multihit tdcs needing ref
 time   THcRawHodoHit gives reference time corrected TDC values  
 THcScintillator plane adds a per plane offset to the raw tdc value   First
 positive TDC value after adding offset is used

---
 src/THcHodoHit.cxx           | 22 ----------------
 src/THcHodoHit.h             | 12 ++++++---
 src/THcHodoscope.cxx         | 12 ++++-----
 src/THcHodoscope.h           |  6 ++---
 src/THcRawHodoHit.cxx        | 19 ++++++++++----
 src/THcRawHodoHit.h          |  3 +++
 src/THcScintillatorPlane.cxx | 49 ++++++++++++++++++++++++++++--------
 src/THcScintillatorPlane.h   |  3 +++
 8 files changed, 74 insertions(+), 52 deletions(-)

diff --git a/src/THcHodoHit.cxx b/src/THcHodoHit.cxx
index eab26b0..ecf8e1a 100644
--- a/src/THcHodoHit.cxx
+++ b/src/THcHodoHit.cxx
@@ -8,28 +8,6 @@
 
 #include <iostream>
 
-using std::cout;
-using std::endl;
-
 ClassImp(THcHodoHit)
 
-THcHodoHit::THcHodoHit( THcRawHodoHit *hit, Double_t posPed, 
-			     Double_t negPed, THcScintillatorPlane* sp)
-{
-  if(hit) {
-    fPosTDC = hit->GetTDCPos();
-    fNegTDC = hit->GetTDCNeg();
-    fPosADC_Ped = hit->GetADCPos() - posPed;
-    fNegADC_Ped = hit->GetADCNeg() - negPed;
-    fPaddleNumber = hit->fCounter;
-  } else {
-    fPosTDC = -1;
-    fNegTDC = -1;
-    fPosADC_Ped = -1000.0;
-    fNegADC_Ped = -1000.0;
-    fPaddleNumber = -1;
-  }
-  fPlane = sp;
-}
-
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/src/THcHodoHit.h b/src/THcHodoHit.h
index f893706..39ea3a0 100644
--- a/src/THcHodoHit.h
+++ b/src/THcHodoHit.h
@@ -16,9 +16,12 @@
 class THcHodoHit : public TObject {
 
 public:
-  THcHodoHit( THcRawHodoHit* hit=NULL, Double_t posPed=0.0, 
-	      Double_t negPed=0.0, THcScintillatorPlane* sp=NULL);
-      
+
+  THcHodoHit(Int_t postdc, Int_t negtdc, Double_t posadc, Double_t negadc,
+	     Int_t ipad, THcScintillatorPlane* sp) :
+  fPosTDC(postdc), fNegTDC(negtdc), fPosADC_Ped(posadc), fNegADC_Ped(negadc),
+    fPaddleNumber(ipad), fPlane(sp) {};
+
   virtual ~THcHodoHit() {}
 
   Bool_t IsSortable () const { return kFALSE; }
@@ -49,11 +52,12 @@ public:
 protected:
   static const Double_t kBig;  //!
 
-  Int_t fPaddleNumber;
   Int_t fPosTDC;
   Int_t fNegTDC;
   Double_t fPosADC_Ped;		// Pedestal subtracted ADC
   Double_t fNegADC_Ped;		// Pedestal subtracted ADC
+  Int_t fPaddleNumber;
+
   Double_t fPosCorrectedTime;	// Pulse height corrected time
   Double_t fNegCorrectedTime;	// Pulse height corrected time
   Double_t fScinCorrectedTime;  // Time average corrected for position
diff --git a/src/THcHodoscope.cxx b/src/THcHodoscope.cxx
index 9405baf..7a11cc8 100644
--- a/src/THcHodoscope.cxx
+++ b/src/THcHodoscope.cxx
@@ -309,8 +309,6 @@ Int_t THcHodoscope::ReadDatabase( const TDatime& date )
   fyLoScin = new Int_t [fNHodoscopes]; 
   fyHiScin = new Int_t [fNHodoscopes]; 
   fHodoSlop = new Double_t [fNPlanes];
-  fTdcWinMin = new Int_t [fNPlanes];
-  fTdcWinMax = new Int_t [fNPlanes];
 
   DBRequest list[]={
     {"start_time_center",                &fStartTimeCenter,                      kDouble},
@@ -341,8 +339,7 @@ Int_t THcHodoscope::ReadDatabase( const TDatime& date )
     {"normalized_energy_tot",            &fNormETot,              kDouble,         0,  1},
     {"hodo_slop",                        fHodoSlop,               kDouble,  (UInt_t) fNPlanes},
     {"debugprintscinraw",                &fdebugprintscinraw,               kInt,  0,1},
-    {"hodo_tdc_min_win",                 fTdcWinMin,              kInt,     (UInt_t) fNPlanes, 1},
-    {"hodo_tdc_max_win",                 fTdcWinMax,              kInt,     (UInt_t) fNPlanes, 1},
+    {"hodo_tdc_offset",                  fTdcOffset,              kInt,     (UInt_t) fNPlanes, 1},
     {0}
   };
 
@@ -353,9 +350,11 @@ Int_t THcHodoscope::ReadDatabase( const TDatime& date )
   fTofTolerance = 3.0;
   fNCerNPE = 2.0;
   fNormETot = 0.7;
+  // Gets added to each reference time corrected raw TDC value
+  // to make sure valid range is all positive.
+  fTdcOffset = new Int_t [fNPlanes];
   for(Int_t ip=0;ip<fNPlanes;ip++) { // Set a large default window
-    fTdcWinMin[ip] = -65000;
-    fTdcWinMax[ip] = 65000;
+    fTdcOffset[ip] = 0;
   }
 
   gHcParms->LoadParmValues((DBRequest*)&list,prefix);
@@ -508,6 +507,7 @@ void THcHodoscope::DeleteArrays()
   delete [] fNPlaneTime;          fNPlaneTime = NULL;
   delete [] fSumPlaneTime;        fSumPlaneTime = NULL;
   delete [] fNScinHits;           fNScinHits = NULL;
+  delete [] fTdcOffset;           fTdcOffset = NULL;
 
 }
 
diff --git a/src/THcHodoscope.h b/src/THcHodoscope.h
index f85ea8a..f34bc36 100644
--- a/src/THcHodoscope.h
+++ b/src/THcHodoscope.h
@@ -82,8 +82,7 @@ public:
   Double_t GetHodoSlop(Int_t ip) { return fHodoSlop[ip];}
   Double_t GetPlaneCenter(Int_t ip) { return fPlaneCenter[ip];}
   Double_t GetPlaneSpacing(Int_t ip) { return fPlaneSpacing[ip];}
-  Int_t GetTdcWinMin(Int_t ip) const { return fTdcWinMin[ip];}
-  Int_t GetTdcWinMax(Int_t ip) const { return fTdcWinMax[ip];}
+  Int_t GetTdcOffset(Int_t ip) const { return fTdcOffset[ip];}
 
 
   //  Double_t GetBeta() const {return fBeta[];}
@@ -187,8 +186,7 @@ protected:
   Double_t     fNormETot;
   Double_t     fNCerNPE;
   Double_t*    fHodoSlop;
-  Int_t*       fTdcWinMin;
-  Int_t*       fTdcWinMax;
+  Int_t        *fTdcOffset;
   Int_t        fdebugprintscinraw;
   Int_t        fTestSum;
   Int_t        fTrackEffTestNScinPlanes;
diff --git a/src/THcRawHodoHit.cxx b/src/THcRawHodoHit.cxx
index 0081f65..3f3d51d 100644
--- a/src/THcRawHodoHit.cxx
+++ b/src/THcRawHodoHit.cxx
@@ -14,6 +14,7 @@ Class representing a single raw hit for a hodoscope paddle
 #include <cstdio>
 #include <cstdlib>
 #include <iostream>
+#include <cassert>
 
 #include "THcRawHodoHit.h"
 
@@ -36,7 +37,9 @@ Int_t THcRawHodoHit::GetData(Int_t signal) {
 }
 Int_t THcRawHodoHit::GetData(Int_t signal, UInt_t ihit) {
   Int_t value;
-  if(ihit>= fNRawHits[signal]) {
+  if(ihit > 0 && ihit>= fNRawHits[signal]) {
+    cout << "THcRawHodoHit::GetData(): requested hit #" << ihit << " out of range: "
+	 << fNRawHits[signal] << endl;
     return(-1);
   }
   if(signal==0) {
@@ -48,6 +51,8 @@ Int_t THcRawHodoHit::GetData(Int_t signal, UInt_t ihit) {
   } else if (signal==3) {
     value = fTDC_neg[ihit];
   } else {
+    cout << "THcRawHodoHit::GetData(): requested invalid signal #"
+	 << signal << endl;
     return(-1);			// Actually should throw an exception
   }
   // We are return -1 as a error, but reference subtracted
@@ -65,6 +70,8 @@ Int_t THcRawHodoHit::GetRawData(Int_t signal) {
 // Return a requested raw hit
 Int_t THcRawHodoHit::GetRawData(Int_t signal, UInt_t ihit) {
   if(ihit>= fNRawHits[signal]) {
+    cout << "THcRawHodoHit::GetRawData(): requested hit #" << ihit << " out of "
+	 << fNRawHits[signal] << endl;
     return(-1);
   }
   if(signal==0) {
@@ -76,6 +83,8 @@ Int_t THcRawHodoHit::GetRawData(Int_t signal, UInt_t ihit) {
   } else if (signal==3) {
     return(fTDC_neg[ihit]);
   } else {
+    cout << "THcRawHodoHit::GetData(): requested invalid signal #"
+	 << signal << endl;
     return(-1);			// Actually should throw an exception
   }
 }
@@ -109,16 +118,16 @@ THcRawHodoHit& THcRawHodoHit::operator=( const THcRawHodoHit& rhs )
       fNRawHits[is] = rhs.fNRawHits[is];
       fHasRef[is] = rhs.fHasRef[is];
     }
-    for(Int_t ih=0;ih<fNRawHits[0];ih++) {
+    for(UInt_t ih=0;ih<fNRawHits[0];ih++) {
       fADC_pos[ih] = rhs.fADC_pos[ih];
     }
-    for(Int_t ih=0;ih<fNRawHits[1];ih++) {
+    for(UInt_t ih=0;ih<fNRawHits[1];ih++) {
       fADC_neg[ih] = rhs.fADC_neg[ih];
     }
-    for(Int_t ih=0;ih<fNRawHits[2];ih++) {
+    for(UInt_t ih=0;ih<fNRawHits[2];ih++) {
       fTDC_pos[ih] = rhs.fTDC_pos[ih];
     }
-    for(Int_t ih=0;ih<fNRawHits[3];ih++) {
+    for(UInt_t ih=0;ih<fNRawHits[3];ih++) {
       fTDC_neg[ih] = rhs.fTDC_neg[ih];
     }
   }
diff --git a/src/THcRawHodoHit.h b/src/THcRawHodoHit.h
index 5c60466..9df8dc0 100644
--- a/src/THcRawHodoHit.h
+++ b/src/THcRawHodoHit.h
@@ -43,6 +43,9 @@ class THcRawHodoHit : public THcRawHit {
   Int_t GetTDCPos() {return GetData(2, 0);}
   Int_t GetTDCNeg() {return GetData(3, 0);}
 
+  Int_t GetTDCPos(UInt_t ihit) {return GetData(2, ihit);}
+  Int_t GetTDCNeg(UInt_t ihit) {return GetData(3, ihit);}
+
  protected:
   Int_t fADC_pos[MAXHITS];
   Int_t fADC_neg[MAXHITS];
diff --git a/src/THcScintillatorPlane.cxx b/src/THcScintillatorPlane.cxx
index 019551d..fa2bc92 100644
--- a/src/THcScintillatorPlane.cxx
+++ b/src/THcScintillatorPlane.cxx
@@ -155,6 +155,7 @@ Int_t THcScintillatorPlane::ReadDatabase( const TDatime& date )
   // Retrieve parameters we need from parent class
   // Common for all planes
   fHodoSlop= ((THcHodoscope*) GetParent())->GetHodoSlop(fPlaneNum-1);
+  fTdcOffset= ((THcHodoscope*) GetParent())->GetTdcOffset(fPlaneNum-1);
   fScinTdcMin=((THcHodoscope *)GetParent())->GetTdcMin();
   fScinTdcMax=((THcHodoscope *)GetParent())->GetTdcMax();
   fScinTdcToTime=((THcHodoscope *)GetParent())->GetTdcToTime();
@@ -321,6 +322,11 @@ Int_t THcScintillatorPlane::ProcessHits(TClonesArray* rawhits, Int_t nexthit)
 
   //  cout << "THcScintillatorPlane: raw htis = " << nrawhits << endl;
   
+  // A THcRawHodoHit contains all the information (tdc and adc for both
+  // pmts) for a single paddle for a single trigger.  The tdc information
+  // might include multiple hits if it uses a multihit tdc.
+  // Use "ihit" as the index over THcRawHodoHit objects.  Use
+  // "thit" to index over multiple tdc hits within an "ihit".
   while(ihit < nrawhits) {
     THcRawHodoHit* hit = (THcRawHodoHit *) rawhits->At(ihit);
     if(hit->fPlane > fPlaneNum) {
@@ -331,28 +337,49 @@ Int_t THcScintillatorPlane::ProcessHits(TClonesArray* rawhits, Int_t nexthit)
     Int_t index=padnum-1;
     // Need to be finding first hit in TDC range, not the first hit overall
     if (hit->fNRawHits[2] > 0) 
-      ((THcSignalHit*) frPosTDCHits->ConstructedAt(nrPosTDCHits++))->Set(padnum, hit->GetTDCPos());
+      ((THcSignalHit*) frPosTDCHits->ConstructedAt(nrPosTDCHits++))->Set(padnum, hit->GetTDCPos()+fTdcOffset);
     if (hit->fNRawHits[3] > 0) 
-      ((THcSignalHit*) frNegTDCHits->ConstructedAt(nrNegTDCHits++))->Set(padnum, hit->GetTDCNeg());
+      ((THcSignalHit*) frNegTDCHits->ConstructedAt(nrNegTDCHits++))->Set(padnum, hit->GetTDCNeg()+fTdcOffset);
     if ((hit->GetADCPos()-fPosPed[index]) >= 50) 
       ((THcSignalHit*) frPosADCHits->ConstructedAt(nrPosADCHits++))->Set(padnum, hit->GetADCPos()-fPosPed[index]);
     if ((hit->GetADCNeg()-fNegPed[index]) >= 50) 
       ((THcSignalHit*) frNegADCHits->ConstructedAt(nrNegADCHits++))->Set(padnum, hit->GetADCNeg()-fNegPed[index]);
-    // check TDC values
-    if (((hit->GetTDCPos() >= fScinTdcMin) && (hit->GetTDCPos() <= fScinTdcMax)) ||
-	((hit->GetTDCNeg() >= fScinTdcMin) && (hit->GetTDCNeg() <= fScinTdcMax))) {
 
-      // If TDC values are all good, transfer the raw hit to the HodoHit list
-      new( (*fHodoHits)[fNScinHits]) THcHodoHit(hit, fPosPed[index], fNegPed[index], this);
+    Bool_t tdcraw_pos=kFALSE;
+    Bool_t tdcraw_neg=kFALSE;
+    Int_t tdcpos, tdcneg;
+    // Find first in range hit from multihit tdcs
+    for(UInt_t thit=0; thit<hit->fNRawHits[2]; thit++) {
+      tdcpos = hit->GetTDCPos(thit);
+      if(tdcpos >= fScinTdcMin && tdcpos <= fScinTdcMax) {
+	tdcraw_pos = kTRUE;
+	break;
+      }
+    }
+    for(UInt_t thit=0; thit<hit->fNRawHits[3]; thit++) {
+      tdcneg = hit->GetTDCNeg(thit);
+      if(tdcneg >= fScinTdcMin && tdcneg <= fScinTdcMax) {
+	tdcraw_neg = kTRUE;
+	break;
+      }
+    }
+    // Proceed if there is a valid TDC on each end of the bar
+    if(tdcraw_pos && tdcraw_neg) {
+      Double_t adc_pos = hit->GetADCPos()-fPosPed[index];
+      Double_t adc_neg = hit->GetADCNeg()-fNegPed[index];
+
+      new( (*fHodoHits)[fNScinHits]) THcHodoHit(tdcraw_pos, tdcraw_neg,
+						adc_pos, adc_neg,
+						hit->fCounter, this);
       
       // Do the pulse height correction to the time.  (Position dependent corrections later)
-      Double_t timec_pos = hit->GetTDCPos()*fScinTdcToTime - fHodoPosPhcCoeff[index]*
+      Double_t timec_pos = tdcraw_pos*fScinTdcToTime - fHodoPosPhcCoeff[index]*
 	TMath::Sqrt(TMath::Max(0.0,
-			       (hit->GetADCPos()-fPosPed[index])/fHodoPosMinPh[index]-1.0))
+			       (adc_pos)/fHodoPosMinPh[index]-1.0))
 	- fHodoPosTimeOffset[index];
-      Double_t timec_neg = hit->GetTDCNeg()*fScinTdcToTime - fHodoNegPhcCoeff[index]*
+      Double_t timec_neg = tdcraw_neg*fScinTdcToTime - fHodoNegPhcCoeff[index]*
 	TMath::Sqrt(TMath::Max(0.0,
-			       (hit->GetADCNeg()-fNegPed[index])/fHodoNegMinPh[index]-1.0))
+			       (adc_neg)/fHodoNegMinPh[index]-1.0))
 	- fHodoNegTimeOffset[index];
 
       // Find hit position using ADCs
diff --git a/src/THcScintillatorPlane.h b/src/THcScintillatorPlane.h
index a3a1a3d..e9adbcb 100644
--- a/src/THcScintillatorPlane.h
+++ b/src/THcScintillatorPlane.h
@@ -74,6 +74,9 @@ class THcScintillatorPlane : public THaSubDetector {
 				 detector base class */
   Int_t fNScinHits;                 /* number of hits in plane (that pass min/max TDC cuts) */
   Int_t fNGoodHits;                 /* number of hits in plane (used in determining focal plane time) */
+
+  // Constants
+  Int_t fTdcOffset;		/* Overall offset to raw tdc */
   Int_t fMaxHits;               /* maximum number of hits to be considered - useful for dimensioning arrays */
   Double_t fSpacing;            /* paddle spacing */
   Double_t fSize;               /* paddle size */
-- 
GitLab