Skip to content
Snippets Groups Projects
THcHodoscope.cxx 53.9 KiB
Newer Older
  • Learn to ignore specific revisions
  • ///////////////////////////////////////////////////////////////////////////////
    //                                                                           //
    // THcHodoscope                                                              //
    //                                                                           //
    // Class for a generic hodoscope consisting of multiple                      //
    // planes with multiple paddles with phototubes on both ends.                //
    // This differs from Hall A scintillator class in that it is the whole       //
    // hodoscope array, not just one plane.                                      //
    //                                                                           //
    
    // Date July 8 2014:                                                         //
    // Zafr Ahmed                                                                //
    // Beta and chis square are calculated for each of the hodoscope track.      //
    // Two new variables are added. fBeta and fBetaChisq                         //
    //                                                                           //
    
    ///////////////////////////////////////////////////////////////////////////////
    
    
    #include "THcSignalHit.h"
    
    Zafar's avatar
    Zafar committed
    #include "THcShower.h"
    
    #include "THcCherenkov.h"
    #include "THcHallCSpectrometer.h"
    
    Zafar's avatar
    Zafar committed
    
    #include "THcHitList.h"
    #include "THcRawShowerHit.h"
    #include "TClass.h"
    #include "math.h"
    #include "THaSubDetector.h"
    
    #include "THcHodoscope.h"
    #include "THaEvData.h"
    #include "THaDetMap.h"
    #include "THcDetectorMap.h"
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
    #include "THaGlobals.h"
    #include "THaCutList.h"
    
    #include "THcGlobals.h"
    #include "THcParmList.h"
    #include "VarDef.h"
    #include "VarType.h"
    #include "THaTrack.h"
    #include "TClonesArray.h"
    #include "TMath.h"
    
    #include "THaTrackProj.h"
    
    
    #include <cstring>
    #include <cstdio>
    #include <cstdlib>
    #include <iostream>
    
    
    //_____________________________________________________________________________
    THcHodoscope::THcHodoscope( const char* name, const char* description,
    				  THaApparatus* apparatus ) :
      THaNonTrackingDetector(name,description,apparatus)
    {
      // Constructor
    
    
      //fTrackProj = new TClonesArray( "THaTrackProj", 5 );
      // Construct the planes
    
      fNPlanes = 0;			// No planes until we make them
    
    Gabriel Niculescu's avatar
    Gabriel Niculescu committed
      fStartTime=-1e5;
      fGoodStartTime=kFALSE;
    
    
    //_____________________________________________________________________________
    THcHodoscope::THcHodoscope( ) :
      THaNonTrackingDetector()
    {
      // Constructor
    }
    
    
    //_____________________________________________________________________________
    void THcHodoscope::Setup(const char* name, const char* description)
    {
    
    
      //  static const char* const here = "Setup()";
      //  static const char* const message = 
      //    "Must construct %s detector with valid name! Object construction failed.";
    
      cout << "In THcHodoscope::Setup()" << endl;
    
      // Base class constructor failed?
      if( IsZombie()) return;
    
    
      fDebug   = 1;  // Keep this at one while we're working on the code    
    
      char prefix[2];
    
      prefix[0]=tolower(GetApparatus()->GetName()[0]);
      prefix[1]='\0';
    
    
      string planenamelist;
    
      DBRequest listextra[]={
        {"hodo_num_planes", &fNPlanes, kInt},
    
        {"hodo_plane_names",&planenamelist, kString},
    
      //fNPlanes = 4; 		// Default if not defined
    
      gHcParms->LoadParmValues((DBRequest*)&listextra,prefix);
      
    
      cout << "Plane Name List : " << planenamelist << endl;
    
      vector<string> plane_names = vsplit(planenamelist);
      // Plane names  
      if(plane_names.size() != (UInt_t) fNPlanes) {
        cout << "ERROR: Number of planes " << fNPlanes << " doesn't agree with number of plane names " << plane_names.size() << endl;
        // Should quit.  Is there an official way to quit?
      }
    
      fPlaneNames = new char* [fNPlanes];
    
      for(Int_t i=0;i<fNPlanes;i++) {
    
        fPlaneNames[i] = new char[plane_names[i].length()+1];
    
        strcpy(fPlaneNames[i], plane_names[i].c_str());
      }
    
    Zafar's avatar
    Zafar committed
    
    
      // Probably shouldn't assume that description is defined
    
      char* desc = new char[strlen(description)+100];
    
      fPlanes = new THcScintillatorPlane* [fNPlanes];
    
      for(Int_t i=0;i < fNPlanes;i++) {
    
        strcpy(desc, description);
    
        strcat(desc, " Plane ");
    
        strcat(desc, fPlaneNames[i]);
    
        fPlanes[i] = new THcScintillatorPlane(fPlaneNames[i], desc, i+1, this); // Number planes starting from zero!!
    
        cout << "Created Scintillator Plane " << fPlaneNames[i] << ", " << desc << endl;
    
    
      // --------------- To get energy from THcShower ----------------------
      const char* shower_detector_name = "cal";  
      //  THaApparatus* app;
      THcHallCSpectrometer *app = dynamic_cast<THcHallCSpectrometer*>(GetApparatus());
      THaDetector* det = app->GetDetector( shower_detector_name );
    
      if( dynamic_cast<THcShower*>(det) ) {
        fShower = dynamic_cast<THcShower*>(det);
      }
      else if( !dynamic_cast<THcShower*>(det) ) {
        cout << "Warining: calorimeter analysis module " 
    	 << shower_detector_name << " not loaded for spectrometer "
    	 << prefix << endl;
        
        fShower = NULL;
      }
      
      // --------------- To get energy from THcShower ----------------------
    
      // --------------- To get NPEs from THcCherenkov -------------------
      const char* chern_detector_name = "cher";
      THaDetector* detc = app->GetDetector( chern_detector_name );
      
      if( dynamic_cast<THcCherenkov*>(detc) ) {
        fChern = dynamic_cast<THcCherenkov*>(detc);  
      }
      else if( !dynamic_cast<THcCherenkov*>(detc) ) {
        cout << "Warining: Cherenkov detector analysis module " 
    	 << chern_detector_name << " not loaded for spectrometer "
    	 << prefix << endl;
        
        fChern = NULL;
      }
      
      // --------------- To get NPEs from THcCherenkov -------------------
    
      fScinShould = 0;
      fScinDid = 0;
      gHcParms->Define(Form("%shodo_did",prefix),"Total hodo tracks",fScinDid);
      gHcParms->Define(Form("%shodo_should",prefix),"Total hodo triggers",fScinShould);
    
    
      // Save the nominal particle mass
      fPartMass = app->GetParticleMass();
      fBetaNominal = app->GetBetaAtPcentral();
    
    
    }
    
    //_____________________________________________________________________________
    THaAnalysisObject::EStatus THcHodoscope::Init( const TDatime& date )
    {
    
      cout << "In THcHodoscope::Init()" << endl;
      Setup(GetName(), GetTitle());
    
      // Should probably put this in ReadDatabase as we will know the
      // maximum number of hits after setting up the detector map
      // But it needs to happen before the sub detectors are initialized
      // so that they can get the pointer to the hitlist.
    
    
    Zafar's avatar
    Zafar committed
    
    
      InitHitList(fDetMap, "THcRawHodoHit", 100);
    
      EStatus status;
      // This triggers call of ReadDatabase and DefineVariables
    
      if( (status = THaNonTrackingDetector::Init( date )) )
    
      for(Int_t ip=0;ip<fNPlanes;ip++) {
    
        if((status = fPlanes[ip]->Init( date ))) {
    
    
      // Replace with what we need for Hall C
      //  const DataDest tmp[NDEST] = {
      //    { &fRTNhit, &fRANhit, fRT, fRT_c, fRA, fRA_p, fRA_c, fROff, fRPed, fRGain },
      //    { &fLTNhit, &fLANhit, fLT, fLT_c, fLA, fLA_p, fLA_c, fLOff, fLPed, fLGain }
      //  };
      //  memcpy( fDataDest, tmp, NDEST*sizeof(DataDest) );
    
    
      char EngineDID[]="xSCIN";
      EngineDID[0] = toupper(GetApparatus()->GetName()[0]);
      if( gHcDetectorMap->FillMap(fDetMap, EngineDID) < 0 ) {
    
        static const char* const here = "Init()";
    
        Error( Here(here), "Error filling detectormap for %s.", 
    
    Zafar's avatar
    Zafar committed
      fNScinHits     = new Int_t [fNPlanes];
      fGoodPlaneTime = new Bool_t [fNPlanes];
      fNPlaneTime    = new Int_t [fNPlanes];
      fSumPlaneTime  = new Double_t [fNPlanes];
    
      //  Double_t  fHitCnt4 = 0., fHitCnt3 = 0.;
      
    
      // Int_t m = 0;
      // fScinHit = new Double_t*[fNPlanes];         
      // for ( m = 0; m < fNPlanes; m++ ){
      //   fScinHit[m] = new Double_t[fNPaddle[0]];
      // }
    
    Zafar's avatar
    Zafar committed
      
    
    
    //_____________________________________________________________________________
    Double_t THcHodoscope::DefineDoubleVariable(const char* fName)
    {
      // Define a variale of type double by looking it up in the THcParmList
      char prefix[2];
      char parname[100];
      Double_t tmpvar=-1e6;
      prefix[0]=tolower(GetApparatus()->GetName()[0]);
      prefix[1]='\0';
      strcpy(parname,prefix);
      strcat(parname,fName);
      if (gHcParms->Find(parname)) {
        tmpvar=*(Double_t *)gHcParms->Find(parname)->GetValuePointer();
        if (fDebug>=1)  cout << parname << " "<< tmpvar << endl;
      } else {
        cout << "*** ERROR!!! Could not find " << parname << " in the list of variables! ***" << endl;
      }
      return tmpvar;
    }
    
    //_____________________________________________________________________________
    Int_t THcHodoscope::DefineIntVariable(const char* fName)
    {
      // Define a variale of type int by looking it up in the THcParmList
      char prefix[2];
      char parname[100];
      Int_t tmpvar=-100000;
      prefix[0]=tolower(GetApparatus()->GetName()[0]);
      prefix[1]='\0';
      strcpy(parname,prefix);
      strcat(parname,fName);
      if (gHcParms->Find(parname)) {
        tmpvar=*(Int_t *)gHcParms->Find(parname)->GetValuePointer();
        if (fDebug>=1)  cout << parname << " "<< tmpvar << endl;
      } else {
        cout << "*** ERROR!!! Could not find " << parname << " in the list of variables! ***" << endl;
      }
      return tmpvar;
    }
    
    //_____________________________________________________________________________
    void THcHodoscope::DefineArray(const char* fName, const Int_t index, Double_t *myArray)
    {
      char prefix[2];
      char parname[100];
      //  Int_t tmpvar=-100000;
       prefix[0]=tolower(GetApparatus()->GetName()[0]);
      prefix[1]='\0';
      strcpy(parname,prefix);
      strcat(parname,fName);
      if (gHcParms->Find(parname)) {
        if (fDebug >=1) cout <<parname;
        Double_t* p = (Double_t *)gHcParms->Find(parname)->GetValuePointer();
        for(Int_t i=0;i<index;i++) {
          myArray[i] = p[i];
          if (fDebug>=1)    cout << " " << myArray[i];
        }
        if (fDebug>=1)  cout << endl;
    
      }
      else {
        cout <<" Could not find "<<parname<<" in the DataBase!!!\n";
      }
    }
    
    //_____________________________________________________________________________
    void THcHodoscope::DefineArray(const char* fName, char** Suffix, const Int_t index, Double_t *myArray)
    {
      // Try to read an array made up of what used to be (in the f77 days) a number of variables
      // example: hscin_1x_center, hscin_1y_center, hscin_2x_center, hscin_2y_center will become scin_center
      //
      char prefix[2];
      char parname[100],parname2[100];
      //  
      prefix[0]=tolower(GetApparatus()->GetName()[0]);
      prefix[1]='\0';
      strcpy(parname,prefix);
      strcat(parname,fName);
      for(Int_t i=0;i<index;i++) {
        strcpy(parname2,Form(parname,Suffix[i]));
        if (gHcParms->Find(parname2)) {
          if (fDebug >=1) cout <<parname2;
          myArray[i] = *(Double_t *)gHcParms->Find(parname2)->GetValuePointer();
          if (fDebug>=1)    cout << " " << myArray[i];
        }
        if (fDebug>=1)  cout << endl;
        else {
          cout <<" Could not find "<<parname2<<" in the DataBase!!!\n";
        }
      }
    }
    
    //_____________________________________________________________________________
    void THcHodoscope::DefineArray(const char* fName, char** Suffix, const Int_t index, Int_t *myArray)
    {
      // Try to read an array made up of what used to be (in the f77 days) a number of variables
      // example: hscin_1x_center, hscin_1y_center, hscin_2x_center, hscin_2y_center will become scin_center
      //
      char prefix[2];
      char parname[100],parname2[100];
      //  
      prefix[0]=tolower(GetApparatus()->GetName()[0]);
      prefix[1]='\0';
      strcpy(parname,prefix);
      strcat(parname,fName);
      for(Int_t i=0;i<index;i++) {
        strcpy(parname2,Form(parname,Suffix[i]));
        if (gHcParms->Find(parname2)) {
          if (fDebug >=1) cout <<parname2;
          myArray[i] = *(Int_t *)gHcParms->Find(parname2)->GetValuePointer();
          if (fDebug>=1)    cout << " " << myArray[i];
        }
        if (fDebug>=1)  cout << endl;
        else {
          cout <<" Could not find "<<parname2<<" in the DataBase!!!\n";
        }
      }
    }
    
    
    //_____________________________________________________________________________
    Int_t THcHodoscope::ReadDatabase( const TDatime& date )
    {
    
      // Read this detector's parameters from the database file 'fi'.
      // This function is called by THaDetectorBase::Init() once at the
      // beginning of the analysis.
      // 'date' contains the date/time of the run being analyzed.
    
      //  static const char* const here = "ReadDatabase()";
    
      char prefix[2];
      char parname[100];
    
    
      // Read data from database 
      // Pull values from the THcParmList instead of reading a database
      // file like Hall A does.
    
      // Will need to determine which spectrometer in order to construct
      // the parameter names (e.g. hscin_1x_nr vs. sscin_1x_nr)
    
    
      prefix[0]=tolower(GetApparatus()->GetName()[0]);
    
      prefix[1]='\0';
      strcpy(parname,prefix);
      strcat(parname,"scin_");
    
      //  Int_t plen=strlen(parname);
    
      cout << " readdatabse hodo fnplanes = " << fNPlanes << endl;
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
      fNPaddle = new UInt_t [fNPlanes];
    
      fFPTime = new Double_t [fNPlanes];
    
      fPlaneCenter = new Double_t[fNPlanes];
      fPlaneSpacing = new Double_t[fNPlanes];
    
      prefix[0]=tolower(GetApparatus()->GetName()[0]);
      //
      prefix[1]='\0';
    
      for(Int_t i=0;i<fNPlanes;i++) {
    
        
        DBRequest list[]={
          {Form("scin_%s_nr",fPlaneNames[i]), &fNPaddle[i], kInt},
          {0}
        };
        gHcParms->LoadParmValues((DBRequest*)&list,prefix);
    
      // GN added
      // reading variables from *hodo.param
    
      for (Int_t i=1;i<fNPlanes;i++) {
    
        fMaxScinPerPlane=(fMaxScinPerPlane > fNPaddle[i])? fMaxScinPerPlane : fNPaddle[i];
      }
    // need this for "padded arrays" i.e. 4x16 lists of parameters (GN)
      fMaxHodoScin=fMaxScinPerPlane*fNPlanes; 
      if (fDebug>=1)  cout <<"fMaxScinPerPlane = "<<fMaxScinPerPlane<<" fMaxHodoScin = "<<fMaxHodoScin<<endl;
    
      
      fHodoVelLight=new Double_t [fMaxHodoScin];
      fHodoPosSigma=new Double_t [fMaxHodoScin];
      fHodoNegSigma=new Double_t [fMaxHodoScin];
      fHodoPosMinPh=new Double_t [fMaxHodoScin];
      fHodoNegMinPh=new Double_t [fMaxHodoScin];
      fHodoPosPhcCoeff=new Double_t [fMaxHodoScin];
      fHodoNegPhcCoeff=new Double_t [fMaxHodoScin];
      fHodoPosTimeOffset=new Double_t [fMaxHodoScin];
      fHodoNegTimeOffset=new Double_t [fMaxHodoScin];
      fHodoPosPedLimit=new Int_t [fMaxHodoScin];
      fHodoNegPedLimit=new Int_t [fMaxHodoScin];
      fHodoPosInvAdcOffset=new Double_t [fMaxHodoScin];
      fHodoNegInvAdcOffset=new Double_t [fMaxHodoScin];
      fHodoPosInvAdcLinear=new Double_t [fMaxHodoScin];
      fHodoNegInvAdcLinear=new Double_t [fMaxHodoScin];
      fHodoPosInvAdcAdc=new Double_t [fMaxHodoScin];
      fHodoNegInvAdcAdc=new Double_t [fMaxHodoScin];
      
    
      fNHodoscopes = 2;
      fxLoScin = new Int_t [fNHodoscopes]; 
      fxHiScin = new Int_t [fNHodoscopes]; 
      fyLoScin = new Int_t [fNHodoscopes]; 
      fyHiScin = new Int_t [fNHodoscopes]; 
    
      fHodoSlop = new Double_t [fNPlanes];
    
    Zafar's avatar
    Zafar committed
    
    
        {"start_time_center",                &fStartTimeCenter,                      kDouble},
        {"start_time_slop",                  &fStartTimeSlop,                        kDouble},
        {"scin_tdc_to_time",                 &fScinTdcToTime,                        kDouble},
        {"scin_tdc_min",                     &fScinTdcMin,                           kDouble},
        {"scin_tdc_max",                     &fScinTdcMax,                           kDouble},
        {"tof_tolerance",                    &fTofTolerance,          kDouble,         0,  1},
        {"pathlength_central",               &fPathLengthCentral,                    kDouble},
        {"hodo_vel_light",                   &fHodoVelLight[0],       kDouble,  fMaxHodoScin},
        {"hodo_pos_sigma",                   &fHodoPosSigma[0],       kDouble,  fMaxHodoScin},
        {"hodo_neg_sigma",                   &fHodoNegSigma[0],       kDouble,  fMaxHodoScin},
        {"hodo_pos_minph",                   &fHodoPosMinPh[0],       kDouble,  fMaxHodoScin},
        {"hodo_neg_minph",                   &fHodoNegMinPh[0],       kDouble,  fMaxHodoScin},
        {"hodo_pos_phc_coeff",               &fHodoPosPhcCoeff[0],    kDouble,  fMaxHodoScin},
        {"hodo_neg_phc_coeff",               &fHodoNegPhcCoeff[0],    kDouble,  fMaxHodoScin},
        {"hodo_pos_time_offset",             &fHodoPosTimeOffset[0],  kDouble,  fMaxHodoScin},
        {"hodo_neg_time_offset",             &fHodoNegTimeOffset[0],  kDouble,  fMaxHodoScin},
        {"hodo_pos_ped_limit",               &fHodoPosPedLimit[0],    kInt,     fMaxHodoScin},
        {"hodo_neg_ped_limit",               &fHodoNegPedLimit[0],    kInt,     fMaxHodoScin},
        {"tofusinginvadc",                   &fTofUsingInvAdc,        kInt,            0,  1},       
        {"xloscin",                          &fxLoScin[0],            kInt,     (UInt_t) fNHodoscopes},
        {"xhiscin",                          &fxHiScin[0],            kInt,     (UInt_t) fNHodoscopes},
        {"yloscin",                          &fyLoScin[0],            kInt,     (UInt_t) fNHodoscopes},
        {"yhiscin",                          &fyHiScin[0],            kInt,     (UInt_t) fNHodoscopes},
        {"track_eff_test_num_scin_planes",   &fTrackEffTestNScinPlanes,                 kInt},
        {"cer_npe",                          &fNCerNPE,               kDouble,         0,  1},
        {"normalized_energy_tot",            &fNormETot,              kDouble,         0,  1},
    
        {"hodo_slop",                        fHodoSlop,               kDouble,  fNPlanes},
    
        {"debugprintscinraw",                &fdebugprintscinraw,               kInt,  0,1},
    
      fTofUsingInvAdc = 0;		// Default if not defined
    
      fTofTolerance = 3.0;		// Default if not defined
    
      fNCerNPE = 2.0;
      fNormETot = 0.7;
    
    
      gHcParms->LoadParmValues((DBRequest*)&list,prefix);
    
    Zafar's avatar
    Zafar committed
    
    
      cout << " x1 lo = " << fxLoScin[0] 
           << " x2 lo = " << fxLoScin[1] 
           << " x1 hi = " << fxHiScin[0] 
           << " x2 hi = " << fxHiScin[1] 
           << endl;
    
      cout << " y1 lo = " << fyLoScin[0] 
           << " y2 lo = " << fyLoScin[1] 
           << " y1 hi = " << fyHiScin[0] 
           << " y2 hi = " << fyHiScin[1] 
           << endl;
    
    
      cout << "Hdososcope planes hits for trigger = " << fTrackEffTestNScinPlanes 
           << " normalized energy min = " << fNormETot
           << " number of photo electrons = " << fNCerNPE
           << endl;
    
    Zafar's avatar
    Zafar committed
    
    
        DBRequest list2[]={
          {"hodo_pos_invadc_offset",&fHodoPosInvAdcOffset[0],kDouble,fMaxHodoScin},
          {"hodo_neg_invadc_offset",&fHodoNegInvAdcOffset[0],kDouble,fMaxHodoScin},
          {"hodo_pos_invadc_linear",&fHodoPosInvAdcLinear[0],kDouble,fMaxHodoScin},
          {"hodo_neg_invadc_linear",&fHodoNegInvAdcLinear[0],kDouble,fMaxHodoScin},
          {"hodo_pos_invadc_adc",&fHodoPosInvAdcAdc[0],kDouble,fMaxHodoScin},
          {"hodo_neg_invadc_adc",&fHodoNegInvAdcAdc[0],kDouble,fMaxHodoScin},
          {0}
        };
        gHcParms->LoadParmValues((DBRequest*)&list2,prefix);
    
      if (fDebug >=1) {
        cout <<"******* Testing Hodoscope Parameter Reading ***\n";
        cout<<"StarTimeCenter = "<<fStartTimeCenter<<endl;
        cout<<"StartTimeSlop = "<<fStartTimeSlop<<endl;
        cout <<"ScintTdcToTime = "<<fScinTdcToTime<<endl;
        cout <<"TdcMin = "<<fScinTdcMin<<" TdcMax = "<<fScinTdcMax<<endl;
        cout <<"TofTolerance = "<<fTofTolerance<<endl;
        cout <<"*** VelLight ***\n";
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
        for (Int_t i1=0;i1<fNPlanes;i1++) {
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
          for (UInt_t i2=0;i2<fMaxScinPerPlane;i2++) {
    
    	cout<<fHodoVelLight[GetScinIndex(i1,i2)]<<" ";
    
        // check fHodoPosPhcCoeff
        /*
        cout <<"fHodoPosPhcCoeff = ";
        for (int i1=0;i1<fMaxHodoScin;i1++) {
          cout<<this->GetHodoPosPhcCoeff(i1)<<" ";
        }
        cout<<endl;
        */
      }
      //
      if ((fTofTolerance > 0.5) && (fTofTolerance < 10000.)) {
        cout << "USING "<<fTofTolerance<<" NSEC WINDOW FOR FP NO_TRACK CALCULATIONS.\n";
      }
      else {
        fTofTolerance= 3.0;
        cout << "*** USING DEFAULT 3 NSEC WINDOW FOR FP NO_TRACK CALCULATIONS!! ***\n";
    
      fIsInit = true;
      return kOK;
    }
    
    //_____________________________________________________________________________
    Int_t THcHodoscope::DefineVariables( EMode mode )
    {
      // Initialize global variables and lookup table for decoder
    
      cout << "THcHodoscope::DefineVariables called " << GetName() << endl;
    
      if( mode == kDefine && fIsSetup ) return kOK;
      fIsSetup = ( mode == kDefine );
    
      // Register variables in global list
    
    
      RVarDef vars[] = {
    
        // Move these into THcHallCSpectrometer using track fTracks
    
        {"fpHitsTime",      "Time at focal plane from all hits",         "fFPTime"},
        {"starttime",       "Hodoscope Start Time",                      "fStartTime"},
        {"goodstarttime",   "Hodoscope Good Start Time",                 "fGoodStartTime"},
        {"goodscinhit",     "Hit in fid area",                           "fGoodScinHits"},
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
        //    {"goodscinhitx",    "Hit in fid x range",                        "fGoodScinHitsX"},
    
        {"scinshould",      "Total scin Hits in fid area",               "fScinShould"},
        {"scindid",         "Total scin Hits in fid area with a track",  "fScinDid"},
    
      return DefineVarsFromList( vars, mode );
      //  return kOK;
    
    }
    
    //_____________________________________________________________________________
    THcHodoscope::~THcHodoscope()
    {
      // Destructor. Remove variables from global list.
    
    
      delete [] fFPTime;
    
      delete [] fPlaneCenter;
      delete [] fPlaneSpacing;
    
      if( fIsSetup )
        RemoveVariables();
      if( fIsInit )
        DeleteArrays();
      if (fTrackProj) {
        fTrackProj->Clear();
        delete fTrackProj; fTrackProj = 0;
      }
    }
    
    //_____________________________________________________________________________
    void THcHodoscope::DeleteArrays()
    {
      // Delete member arrays. Used by destructor.
    
      // Int_t k;  
      // for( k = 0; k < fNPlanes; k++){
      //   delete [] fScinHit[k];
      // }
      // delete [] fScinHit;
    
    Zafar's avatar
    Zafar committed
      
    
      delete [] fxLoScin;             fxLoScin = NULL;
      delete [] fxHiScin;             fxHiScin = NULL;
    
      delete [] fHodoSlop;            fHodoSlop = NULL;
    
      delete [] fNPaddle;             fNPaddle = NULL;
      delete [] fHodoVelLight;        fHodoVelLight = NULL;
      delete [] fHodoPosSigma;        fHodoPosSigma = NULL;
      delete [] fHodoNegSigma;        fHodoNegSigma = NULL;
      delete [] fHodoPosMinPh;        fHodoPosMinPh = NULL;
      delete [] fHodoNegMinPh;        fHodoNegMinPh = NULL;
      delete [] fHodoPosPhcCoeff;     fHodoPosPhcCoeff = NULL;
      delete [] fHodoNegPhcCoeff;     fHodoNegPhcCoeff = NULL;
      delete [] fHodoPosTimeOffset;   fHodoPosTimeOffset = NULL;
      delete [] fHodoNegTimeOffset;   fHodoNegTimeOffset = NULL;
      delete [] fHodoPosPedLimit;     fHodoPosPedLimit = NULL;
      delete [] fHodoNegPedLimit;     fHodoNegPedLimit = NULL;
      delete [] fHodoPosInvAdcOffset; fHodoPosInvAdcOffset = NULL;
      delete [] fHodoNegInvAdcOffset; fHodoNegInvAdcOffset = NULL;
      delete [] fHodoPosInvAdcLinear; fHodoPosInvAdcLinear = NULL;
      delete [] fHodoNegInvAdcLinear; fHodoNegInvAdcLinear = NULL;
      delete [] fHodoPosInvAdcAdc;    fHodoPosInvAdcAdc = NULL;
    
      delete [] fGoodPlaneTime;       fGoodPlaneTime = NULL;
      delete [] fNPlaneTime;          fNPlaneTime = NULL;
      delete [] fSumPlaneTime;        fSumPlaneTime = NULL;
      delete [] fNScinHits;           fNScinHits = NULL;
    
    }
    
    //_____________________________________________________________________________
    inline 
    
    void THcHodoscope::ClearEvent()
    
      //  for ( Int_t imaxhit = 0; imaxhit < MAXHODHITS; imaxhit++ ){
      //    fBeta[imaxhit] = 0.;
      //    fBetaChisq[imaxhit] = 0.;
      //  }
    
      for(Int_t ip=0;ip<fNPlanes;ip++) {
    
        fPlaneCenter[ip]=0.;
        fPlaneSpacing[ip]=0.;
    
      fScinHitPaddle.clear();
    
      fNClust.clear();
      fThreeScin.clear();
      fGoodScinHitsX.clear();
    
    }
    
    //_____________________________________________________________________________
    Int_t THcHodoscope::Decode( const THaEvData& evdata )
    {
    
      // Get the Hall C style hitlist (fRawHitList) for this event
    
      //
      // GN: print event number so we can cross-check with engine
    
      // if (evdata.GetEvNum()>1000) 
    
    Zafar's avatar
    Zafar committed
      //   cout <<"\nhcana_event " << evdata.GetEvNum()<<endl;
    
      fCheckEvent = evdata.GetEvNum();
    
      fEventType =  evdata.GetEvType();
    
    Zafar's avatar
    Zafar committed
    
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
      if(gHaCuts->Result("Pedestal_event")) {
        Int_t nexthit = 0;
    
        for(Int_t ip=0;ip<fNPlanes;ip++) {
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
          nexthit = fPlanes[ip]->AccumulatePedestals(fRawHitList, nexthit);
        }
        fAnalyzePedestals = 1;	// Analyze pedestals first normal events
        return(0);
      }
      if(fAnalyzePedestals) {
    
        for(Int_t ip=0;ip<fNPlanes;ip++) {
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
          fPlanes[ip]->CalculatePedestals();
        }
        fAnalyzePedestals = 0;	// Don't analyze pedestals next event
      }
    
    
      // Let each plane get its hits
      Int_t nexthit = 0;
    
    Gabriel Niculescu's avatar
    Gabriel Niculescu committed
    
    
      for(Int_t ip=0;ip<fNPlanes;ip++) {
    
        fPlaneCenter[ip] = fPlanes[ip]->GetPosCenter(0) + fPlanes[ip]->GetPosOffset();
        fPlaneSpacing[ip] = fPlanes[ip]->GetSpacing();
    
        //    nexthit = fPlanes[ip]->ProcessHits(fRawHitList, nexthit);
        // GN: select only events that have reasonable TDC values to start with
        // as per the Engine h_strip_scin.f
    
        nexthit = fPlanes[ip]->ProcessHits(fRawHitList,nexthit);
    
         if (fPlanes[ip]->GetNScinHits()>0) {
    
          fPlanes[ip]->PulseHeightCorrection();
    
          // GN: allow for more than one fptime per plane!!
          for (Int_t i=0;i<fPlanes[ip]->GetNScinGoodHits();i++) {
    	if (TMath::Abs(fPlanes[ip]->GetFpTime(i)-fStartTimeCenter)<=fStartTimeSlop) {
    	  fStartTime=fStartTime+fPlanes[ip]->GetFpTime(i);
    	  fNfptimes++;
    	}
    
    Gabriel Niculescu's avatar
    Gabriel Niculescu committed
        }
    
      if (fNfptimes>0) {
        fStartTime=fStartTime/fNfptimes;
    
    Gabriel Niculescu's avatar
    Gabriel Niculescu committed
        fGoodStartTime=kTRUE;
      } else {
        fGoodStartTime=kFALSE;
        fStartTime=fStartTimeCenter;
      }
    
      if (fdebugprintscinraw == 1) {
      for(UInt_t ihit = 0; ihit < fNRawHits ; ihit++) {
    
        THcRawHodoHit* hit = (THcRawHodoHit *) fRawHitList->At(ihit);
    
        cout << ihit << " : " << hit->fPlane << ":" << hit->fCounter << " : "
    	 << hit->fADC_pos << " " << hit->fADC_neg << " "  <<  hit->fTDC_pos
    	 << " " <<  hit->fTDC_neg << endl;
      }
      cout << endl;
    
    Gabriel Niculescu's avatar
    Gabriel Niculescu committed
      ///  fStartTime = 500;		// Drift Chamber will need this
    
      return nhits;
    }
    
    //_____________________________________________________________________________
    Int_t THcHodoscope::ApplyCorrections( void )
    {
      return(0);
    }
    //_____________________________________________________________________________
    Double_t THcHodoscope::TimeWalkCorrection(const Int_t& paddle,
    					     const ESide side)
    {
      return(0.0);
    }
    
    //_____________________________________________________________________________
    
    Int_t THcHodoscope::CoarseProcess( TClonesArray&  tracks  )
    
    Zafar's avatar
    Zafar committed
    {
    
      ApplyCorrections();
     
      return 0;
    }
    
    //_____________________________________________________________________________
    Int_t THcHodoscope::FineProcess( TClonesArray& tracks )
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
      Int_t ntracks = tracks.GetLast()+1; // Number of reconstructed tracks
      Int_t timehist[200];
    
      // -------------------------------------------------
    
    
      fGoodScinHits = 0;
    
      fScinShould = 0; fScinDid = 0;
    
      if (tracks.GetLast()+1 > 0 ) {
    
    
        // **MAIN LOOP: Loop over all tracks and get corrected time, tof, beta...
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
        Double_t* nPmtHit = new Double_t [ntracks];
        Double_t* timeAtFP = new Double_t [ntracks];
        for ( Int_t itrack = 0; itrack < ntracks; itrack++ ) { // Line 133
          nPmtHit[itrack]=0;
          timeAtFP[itrack]=0;
    
          THaTrack* theTrack = dynamic_cast<THaTrack*>( tracks.At(itrack) );
          if (!theTrack) return -1;
          
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
          for (Int_t ip = 0; ip < fNPlanes; ip++ ){ 
    
    Zafar's avatar
    Zafar committed
    	fGoodPlaneTime[ip] = kFALSE; 
    	fNScinHits[ip] = 0;
    
    	fNPlaneTime[ip] = 0;
    	fSumPlaneTime[ip] = 0.;
    
    Zafar's avatar
    Zafar committed
          }
    
          std::vector<Double_t> dedx_temp;
          fdEdX.push_back(dedx_temp); // Create array of dedx per hit
          
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
          Int_t nFPTime = 0;
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
          Double_t betaChiSq = -3;
          Double_t beta = 0;
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
          //      timeAtFP[itrack] = 0.;
          Double_t sumFPTime = 0.; // Line 138
    
          Double_t p = theTrack->GetP(); // Line 142 
          Double_t betaP = p/( TMath::Sqrt( p * p + fPartMass * fPartMass) );
    
          
          //! Calculate all corrected hit times and histogram
          //! This uses a copy of code below. Results are save in time_pos,neg
          //! including the z-pos. correction assuming nominal value of betap
          //! Code is currently hard-wired to look for a peak in the
          //! range of 0 to 100 nsec, with a group of times that all
          //! agree withing a time_tolerance of time_tolerance nsec. The normal
          //! peak position appears to be around 35 nsec.
          //! NOTE: if want to find farticles with beta different than
          //! reference particle, need to make sure this is big enough
          //! to accomodate difference in TOF for other particles
          //! Default value in case user hasnt definedd something reasonable
          // Line 162 to 171 is already done above in ReadDatabase
          
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
          for (Int_t j=0; j<200; j++) { timehist[j]=0; } // Line 176
    
          
          // Loop over scintillator planes.
          // In ENGINE, its loop over good scintillator hits.
    
          fTOFCalc.clear();
          Int_t ihhit = 0;		// Hit # overall
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
          for(Int_t ip = 0; ip < fNPlanes; ip++ ) {
    
    Zafar's avatar
    Zafar committed
    	fNScinHits[ip] = fPlanes[ip]->GetNScinHits();
    
    	TClonesArray* hodoHits = fPlanes[ip]->GetHits();
    
    	// first loop over hits with in a single plane
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
    	for (Int_t iphit = 0; iphit < fNScinHits[ip]; iphit++ ){
    
    	  // iphit is hit # within a plane
    
    	  fTOFPInfo.push_back(TOFPInfo());
    	  // Can remove these as we will initialize in the constructor
    	  fTOFPInfo[iphit].time_pos = -99.0;
    	  fTOFPInfo[iphit].time_neg = -99.0;
    	  fTOFPInfo[iphit].keep_pos = kFALSE;
    	  fTOFPInfo[iphit].keep_neg = kFALSE;
    	  fTOFPInfo[iphit].scin_pos_time = 0.0;
    	  fTOFPInfo[iphit].scin_neg_time = 0.0;
    
    	  Int_t paddle = ((THcHodoHit*)hodoHits->At(iphit))->GetPaddleNumber()-1;
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
    	  Double_t xHitCoord = theTrack->GetX() + theTrack->GetTheta() *
    
    	    ( fPlanes[ip]->GetZpos() +
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
    	      ( paddle % 2 ) * fPlanes[ip]->GetDzpos() ); // Line 183
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
    	  Double_t yHitCoord = theTrack->GetY() + theTrack->GetPhi() *
    
    	    ( fPlanes[ip]->GetZpos() +
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
    	      ( paddle % 2 ) * fPlanes[ip]->GetDzpos() ); // Line 184
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
    	  Double_t scinTrnsCoord, scinLongCoord;
    
    	  if ( ( ip == 0 ) || ( ip == 2 ) ){ // !x plane. Line 185
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
    	    scinTrnsCoord = xHitCoord;
    	    scinLongCoord = yHitCoord;
    
    	  }
    	  
    	  else if ( ( ip == 1 ) || ( ip == 3 ) ){ // !y plane. Line 188
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
    	    scinTrnsCoord = yHitCoord;
    	    scinLongCoord = xHitCoord;
    
    	  }
    	  else { return -1; } // Line 195
    	  
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
    	  Double_t scinCenter = fPlanes[ip]->GetPosCenter(paddle) + fPlanes[ip]->GetPosOffset();
    
    
    	  // Index to access the 2d arrays of paddle/scintillator properties
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
    	  Int_t fPIndex = fNPlanes * paddle + ip;
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
    	  if ( TMath::Abs( scinCenter - scinTrnsCoord ) <
    
    	       ( fPlanes[ip]->GetSize() * 0.5 + fPlanes[ip]->GetHodoSlop() ) ){ // Line 293
    
    	    Double_t adcPhp = ((THcHodoHit*)hodoHits->At(iphit))->GetPosADC();
    	    Double_t pathp = fPlanes[ip]->GetPosLeft() - scinLongCoord;
    	    Double_t timep = ((THcHodoHit*)hodoHits->At(iphit))->GetPosTDC() * fScinTdcToTime;
    	    timep = timep - fHodoPosPhcCoeff[fPIndex] *
    	      TMath::Sqrt( TMath::Max( 0., ( ( adcPhp / fHodoPosMinPh[fPIndex] ) - 1 ) ) );
    	    timep = timep - ( pathp / fHodoVelLight[fPIndex] ) - ( fPlanes[ip]->GetZpos() +  
    								( paddle % 2 ) * fPlanes[ip]->GetDzpos() ) / ( 29.979 * betaP ) *
    	      TMath::Sqrt( 1. + theTrack->GetTheta() * theTrack->GetTheta() +
    			   theTrack->GetPhi() * theTrack->GetPhi() );
    	    timep = timep - fHodoPosTimeOffset[fPIndex];
    	    fTOFPInfo[iphit].time_pos = timep;
    
    	    for ( Int_t k = 0; k < 200; k++ ){ // Line 211
    	      Double_t tmin = 0.5 * ( k + 1 ) ;
    	      if ( ( timep > tmin ) && ( timep < ( tmin + fTofTolerance ) ) )
    		timehist[k] ++;
    	    }
    
    	    Double_t adcPhn = ((THcHodoHit*)hodoHits->At(iphit))->GetNegADC();
    	    Double_t pathn =  scinLongCoord - fPlanes[ip]->GetPosRight();
    	    Double_t timen = ((THcHodoHit*)hodoHits->At(iphit))->GetNegTDC() * fScinTdcToTime;
    	    timen =timen - fHodoNegPhcCoeff[fPIndex] * 
    	      TMath::Sqrt( TMath::Max( 0., ( ( adcPhn / fHodoNegMinPh[fPIndex] ) - 1 ) ) );
    	    timen = timen - ( pathn / fHodoVelLight[fPIndex] ) - ( fPlanes[ip]->GetZpos() +
    								( paddle % 2 ) * fPlanes[ip]->GetDzpos() ) / ( 29.979 * betaP ) *
    	      TMath::Sqrt( 1. + theTrack->GetTheta() * theTrack->GetTheta() +
    			   theTrack->GetPhi() * theTrack->GetPhi() );
    	    timen = timen - fHodoNegTimeOffset[fPIndex];
    	    fTOFPInfo[iphit].time_neg = timen;
    
    	    for ( Int_t k = 0; k < 200; k++ ){ // Line 230
    	      Double_t tmin = 0.5 * ( k + 1 );
    	      if ( ( timen > tmin ) && ( timen < ( tmin + fTofTolerance ) ) )
    		timehist[k] ++;
    	    }
    
    	  } // condition for cenetr on a paddle
    
    	} // First loop over hits in a plane <---------
    
    	//-----------------------------------------------------------------------------------------------
    
    	//------------- First large loop over scintillator hits in a plane ends here --------------------
    
    	//-----------------------------------------------------------------------------------------------
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
    	Int_t jmax = 0; // Line 240
    	Int_t maxhit = 0;
    
    	for ( Int_t k = 0; k < 200; k++ ){
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
    	  if ( timehist[k] > maxhit ){
    	    jmax = k+1;
    	    maxhit = timehist[k];
    
    	Double_t tmin = 0.5 * jmax;
    	for(Int_t iphit = 0; iphit < fNScinHits[ip]; iphit++) { // Loop over sinc. hits. in plane
    	  if ( ( fTOFPInfo[iphit].time_pos > tmin ) && ( fTOFPInfo[iphit].time_pos < ( tmin + fTofTolerance ) ) ) {
    	    fTOFPInfo[iphit].keep_pos=kTRUE;
    	  }	
    	  if ( ( fTOFPInfo[iphit].time_neg > tmin ) && ( fTOFPInfo[iphit].time_neg < ( tmin + fTofTolerance ) ) ){
    	    fTOFPInfo[iphit].keep_neg=kTRUE;
    	  }	
    	}
    
    	//---------------------------------------------------------------------------------------------	
    	// ---------------------- Scond loop over scint. hits in a plane ------------------------------
    
    	//---------------------------------------------------------------------------------------------
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
    	for (Int_t iphit = 0; iphit < fNScinHits[ip]; iphit++ ){
    
    	  fTOFCalc.push_back(TOFCalc());
    	  // Do we set back to false for each track, or just once per event?
    	  fTOFCalc[ihhit].good_scin_time = kFALSE;
    	  // These need a track index too to calculate efficiencies
    	  fTOFCalc[ihhit].good_tdc_pos = kFALSE;
    	  fTOFCalc[ihhit].good_tdc_neg = kFALSE;
    
    	  fTOFCalc[ihhit].pindex = ip;
    
    
    	  //	  ihhit ++;
    	  //	  fRawIndex ++;   // Is fRawIndex ever different from ihhit
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
    	  Int_t rawindex = ihhit;
    
    	  Int_t paddle = ((THcHodoHit*)hodoHits->At(iphit))->GetPaddleNumber()-1;
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
    	  fTOFCalc[ihhit].hit_paddle = paddle;
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
    	  fTOFCalc[rawindex].good_raw_pad = paddle;
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
    	  Double_t xHitCoord = theTrack->GetX() + theTrack->GetTheta() *
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
    	    ( fPlanes[ip]->GetZpos() + ( paddle % 2 ) * fPlanes[ip]->GetDzpos() ); // Line 277
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
    	  Double_t yHitCoord = theTrack->GetY() + theTrack->GetPhi() *
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
    	    ( fPlanes[ip]->GetZpos() + ( paddle % 2 ) * fPlanes[ip]->GetDzpos() ); // Line 278
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
    	  Double_t scinTrnsCoord, scinLongCoord;
    
    	  if ( ( ip == 0 ) || ( ip == 2 ) ){ // !x plane. Line 278
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
    	    scinTrnsCoord = xHitCoord;
    	    scinLongCoord = yHitCoord;
    
    	  }
    	  else if ( ( ip == 1 ) || ( ip == 3 ) ){ // !y plane. Line 281
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
    	    scinTrnsCoord = yHitCoord;
    	    scinLongCoord = xHitCoord;
    
    	  }
    	  else { return -1; } // Line 288
    	  
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
    	  Double_t scinCenter = fPlanes[ip]->GetPosCenter(paddle) + fPlanes[ip]->GetPosOffset();
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
    	  Int_t fPIndex = fNPlanes * paddle + ip;
    
    	  
    	  // ** Check if scin is on track
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
    	  if ( TMath::Abs( scinCenter - scinTrnsCoord ) >
    
    	       ( fPlanes[ip]->GetSize() * 0.5 + fPlanes[ip]->GetHodoSlop() ) ){ // Line 293
    
    	    if ( fTOFPInfo[iphit].keep_pos ) { // 301
    
    	      
    	      // ** Calculate time for each tube with a good tdc. 'pos' side first.
    
    	      fTOFCalc[ihhit].good_tdc_pos = kTRUE;
    
    	      Double_t adcPh = ((THcHodoHit*)hodoHits->At(iphit))->GetPosADC();
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
    	      Double_t path = fPlanes[ip]->GetPosLeft() - scinLongCoord;
    
    	      // * Convert TDC value to time, do pulse height correction, correction for
    
    	      // * propogation of light thru scintillator, and offset.	      
    
    	      Double_t time = ((THcHodoHit*)hodoHits->At(iphit))->GetPosTDC() * fScinTdcToTime;
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
    	      time = time - ( fHodoPosPhcCoeff[fPIndex] * TMath::Sqrt( TMath::Max( 0. , 
    					( ( adcPh / fHodoPosMinPh[fPIndex] ) - 1 ) ) ) );
    	      time = time - ( path / fHodoVelLight[fPIndex] );
    	      fTOFPInfo[iphit].scin_pos_time = time - fHodoPosTimeOffset[fPIndex];
    
    	      
    	    } // check for good pos TDC condition
    	    
    
    	    if ( fTOFPInfo[iphit].keep_neg ) { //
    
    	      
    	      // ** Calculate time for each tube with a good tdc. 'pos' side first.
    
    	      fTOFCalc[ihhit].good_tdc_neg = kTRUE;
    
    	      Double_t adcPh = ((THcHodoHit*)hodoHits->At(iphit))->GetNegADC();
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
    	      //	      Double_t path = fPlanes[ip]->GetPosRight() - scinLongCoord;
    	      Double_t path = scinLongCoord - fPlanes[ip]->GetPosRight();
    
    	      // * Convert TDC value to time, do pulse height correction, correction for
    	      // * propogation of light thru scintillator, and offset.
    
    	      Double_t time = ((THcHodoHit*)hodoHits->At(iphit))->GetNegTDC() * fScinTdcToTime;
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
    	      time = time - ( fHodoNegPhcCoeff[fPIndex] *
    			   TMath::Sqrt( TMath::Max( 0. , ( ( adcPh / fHodoNegMinPh[fPIndex] ) - 1 ) ) ) );
    	      time = time - ( path / fHodoVelLight[fPIndex] );
    	      fTOFPInfo[iphit].scin_neg_time = time - fHodoNegTimeOffset[fPIndex];
    
    	    } // check for good neg TDC condition