Skip to content
Snippets Groups Projects
THcHodoscope.cxx 76.9 KiB
Newer Older
  • Learn to ignore specific revisions
  • /** \class THcHodoscope
        \ingroup Detectors
    
    
    \brief 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.
    
    */
    
    #include "TClass.h"
    #include "THaSubDetector.h"
    
    #include "THcCherenkov.h"
    #include "THcHallCSpectrometer.h"
    
    Zafar's avatar
    Zafar committed
    #include "THcHitList.h"
    #include "THcRawShowerHit.h"
    
    #include "THcScintPlaneCluster.h"
    #include "THcShower.h"
    #include "THcSignalHit.h"
    
    Zafar's avatar
    Zafar committed
    #include "math.h"
    
    #include "TClonesArray.h"
    #include "THaCutList.h"
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
    #include "THaGlobals.h"
    
    #include "THaTrack.h"
    #include "THcDetectorMap.h"
    
    #include "THcParmList.h"
    
    #include "VarDef.h"
    #include "VarType.h"
    
    
    #include "THaOutput.h"
    #include "TTree.h"
    
    
    #include "THaTrackProj.h"
    
    #include <cstdio>
    #include <cstdlib>
    
    
    #include "hcana/helpers.hxx"
    
    
    //_____________________________________________________________________________
    
    THcHodoscope::THcHodoscope(const char* name, const char* description, THaApparatus* apparatus)
        : hcana::ConfigLogging<THaNonTrackingDetector>(name, description, apparatus) {
    
      // fTrackProj = new TClonesArray( "THaTrackProj", 5 );
    
      // Construct the planes
    
      fNPlanes       = 0; // No planes until we make them
      fStartTime     = -1e5;
      fGoodStartTime = kFALSE;
    
    
    //_____________________________________________________________________________
    
    THcHodoscope::THcHodoscope() : hcana::ConfigLogging<THaNonTrackingDetector>() {
    
    //_____________________________________________________________________________
    
    void THcHodoscope::Setup(const char* name, const char* description) {
    
      /**
         Create the scintillator plane objects for the hodoscope.
    
         Uses the Xhodo_num_planes and Xhodo_plane_names to get the number of
         planes and their names.
    
         Gets a pointer to the Cherenkov named "cer" ("hgcer" in the case of the SHMS.)
    
    Eric Pooser's avatar
    Eric Pooser committed
      // fDebug = 1;  // Keep this at one while we're working on the code
    
      prefix[0] = tolower(GetApparatus()->GetName()[0]);
      prefix[1] = '\0';
    
      fSHMS = kFALSE;
      if (temp == "p")
        fSHMS = kTRUE;
      TString histname = temp + "_timehist";
      hTime            = new TH1F(histname, "", 400, 0, 200);
    
    Eric Pooser's avatar
    Eric Pooser committed
      // cout << " fSHMS = " << fSHMS << endl;
    
      string    planenamelist;
      DBRequest listextra[] = {{"hodo_num_planes", &fNPlanes, kInt},
                               {"hodo_plane_names", &planenamelist, kString},
                               {"hodo_tdcrefcut", &fTDC_RefTimeCut, kInt, 0, 1},
                               {"hodo_adcrefcut", &fADC_RefTimeCut, kInt, 0, 1},
                               {0}};
      // fNPlanes = 4; 		// Default if not defined
      fTDC_RefTimeCut = 0; // Minimum allowed reference times
    
      fADC_RefTimeCut = 0;
    
      gHcParms->LoadParmValues((DBRequest*)&listextra, prefix);
    
      _det_logger->info("Plane Name List : {}", planenamelist);
      // cout << "Plane Name List : " << planenamelist << endl;
    
    
      vector<string> plane_names = vsplit(planenamelist);
    
      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;
    
      // Save the nominal particle mass
    
      THcHallCSpectrometer* app = dynamic_cast<THcHallCSpectrometer*>(GetApparatus());
      fPartMass                 = app->GetParticleMass();
      fBetaNominal              = app->GetBetaAtPcentral();
    
    Mark Jones's avatar
    Mark Jones committed
    
      if (fSHMS) {
        fCherenkov = dynamic_cast<THcCherenkov*>(app->GetDetector("hgcer"));
      } else {
        fCherenkov = dynamic_cast<THcCherenkov*>(app->GetDetector("cer"));
      }
    
    
    }
    
    //_____________________________________________________________________________
    
    THaAnalysisObject::EStatus THcHodoscope::Init(const TDatime& date) {
    
    Eric Pooser's avatar
    Eric Pooser committed
      // cout << "In THcHodoscope::Init()" << endl;
    
      Setup(GetName(), GetTitle());
    
      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.", EngineDID );
        _det_logger->error("THcHodoscope::Init : Error filling detectormap for {}.", EngineDID);
    
      // 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.
    
      _det_logger->info("Hodo TDC and ADC ref time cut = {} {}", fTDC_RefTimeCut, fADC_RefTimeCut);
    
      // cout << " Hodo tdc ref time cut = " << fTDC_RefTimeCut << " " << fADC_RefTimeCut << endl;
    
      InitHitList(fDetMap, "THcRawHodoHit", fDetMap->GetTotNumChan() + 1, fTDC_RefTimeCut,
                  fADC_RefTimeCut);
    
      EStatus status;
      // This triggers call of ReadDatabase and DefineVariables
    
      if ((status = THaNonTrackingDetector::Init(date)))
        return fStatus = status;
    
      for (Int_t ip = 0; ip < fNPlanes; ip++) {
        if ((status = fPlanes[ip]->Init(date))) {
          return fStatus = status;
    
      fNScinHits     = new Int_t[fNPlanes];
      fGoodPlaneTime = new Bool_t[fNPlanes];
      fNPlaneTime    = new Int_t[fNPlanes];
      fSumPlaneTime  = new Double_t[fNPlanes];
    
    Zafar's avatar
    Zafar committed
    
      //  Double_t  fHitCnt4 = 0., fHitCnt3 = 0.;
    
      // fScinHit = new Double_t*[fNPlanes];
    
      // for ( m = 0; m < fNPlanes; m++ ){
      //   fScinHit[m] = new Double_t[fNPaddle[0]];
      // }
    
        fScinHitPaddle.push_back(std::vector<Int_t>(fNPaddle[ip], 0));
      }
    
    Zafar's avatar
    Zafar committed
    
    
      fPresentP        = 0;
      THaVar* vpresent = gHaVars->Find(Form("%s.present", GetApparatus()->GetName()));
      if (vpresent) {
        fPresentP = (Bool_t*)vpresent->GetValuePointer();
    
    Mark Jones's avatar
    Mark Jones committed
    
    
      return fStatus = kOK;
    }
    //_____________________________________________________________________________
    
    Int_t THcHodoscope::ReadDatabase(const TDatime& date) {
    
      /**
         Read this detector's parameters from the ThcParmlist.
    
         This function is called by THaDetectorBase::Init() once at the
         beginning of the analysis.
      */
    
      //  static const char* const here = "ReadDatabase()";
    
      char prefix[2];
      char parname[100];
    
      // 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);
    
    Eric Pooser's avatar
    Eric Pooser committed
      // cout << " readdatabse hodo fnplanes = " << fNPlanes << endl;
    
      CreateMissReportParms(Form("%sscin", prefix));
    
    Zafar Ahmed's avatar
    Zafar Ahmed committed
      fBetaNoTrkChiSq = 0.;
    
      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]);
    
        DBRequest list[] = {{Form("scin_%s_nr", fPlaneNames[i]), &fNPaddle[i], kInt}, {0}};
    
        gHcParms->LoadParmValues((DBRequest*)&list, prefix);
    
      // GN added
      // reading variables from *hodo.param
    
      fMaxScinPerPlane = fNPaddle[0];
      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];
    
      // New Time-Walk Calibration Parameters
      fHodoVelFit   = new Double_t[fMaxHodoScin];
      fHodoCableFit = new Double_t[fMaxHodoScin];
      fHodo_LCoeff  = new Double_t[fMaxHodoScin];
      fHodoPos_c1   = new Double_t[fMaxHodoScin];
      fHodoNeg_c1   = new Double_t[fMaxHodoScin];
      fHodoPos_c2   = new Double_t[fMaxHodoScin];
      fHodoNeg_c2   = new Double_t[fMaxHodoScin];
      fHodoSigmaPos = new Double_t[fMaxHodoScin];
      fHodoSigmaNeg = 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];
      fTdcOffset               = new Int_t[fNPlanes];
      fAdcTdcOffset            = new Double_t[fNPlanes];
      fHodoPosAdcTimeWindowMin = new Double_t[fMaxHodoScin];
      fHodoPosAdcTimeWindowMax = new Double_t[fMaxHodoScin];
      fHodoNegAdcTimeWindowMin = new Double_t[fMaxHodoScin];
      fHodoNegAdcTimeWindowMax = new Double_t[fMaxHodoScin];
    
      for (Int_t ip = 0; ip < fNPlanes; ip++) { // Set a large default window
        fTdcOffset[ip]    = 0;
        fAdcTdcOffset[ip] = 0.0;
    
    Zafar's avatar
    Zafar committed
    
    
      DBRequest list[] = {
          {"cosmicflag", &fCosmicFlag, kInt, 0, 1},
          {"NumPlanesBetaCalc", &fNumPlanesBetaCalc, kInt, 0, 1},
          {"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_pos_sigma", &fHodoPosSigma[0], kDouble, fMaxHodoScin, 1},
          {"hodo_neg_sigma", &fHodoNegSigma[0], kDouble, fMaxHodoScin, 1},
          {"hodo_pos_ped_limit", &fHodoPosPedLimit[0], kInt, fMaxHodoScin, 1},
          {"hodo_neg_ped_limit", &fHodoNegPedLimit[0], kInt, fMaxHodoScin, 1},
          {"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},
          {"trackeff_scint_ydiff_max", &trackeff_scint_ydiff_max, kDouble, 0, 1},
          {"trackeff_scint_xdiff_max", &trackeff_scint_xdiff_max, kDouble, 0, 1},
          {"cer_npe", &fNCerNPE, kDouble, 0, 1},
          {"normalized_energy_tot", &fNormETot, kDouble, 0, 1},
          {"hodo_slop", fHodoSlop, kDouble, (UInt_t)fNPlanes},
          {"debugprintscinraw", &fdebugprintscinraw, kInt, 0, 1},
          {"hodo_tdc_offset", fTdcOffset, kInt, (UInt_t)fNPlanes, 1},
          {"hodo_adc_tdc_offset", fAdcTdcOffset, kDouble, (UInt_t)fNPlanes, 1},
          {"hodo_PosAdcTimeWindowMin", fHodoPosAdcTimeWindowMin, kDouble, (UInt_t)fMaxHodoScin, 1},
          {"hodo_PosAdcTimeWindowMax", fHodoPosAdcTimeWindowMax, kDouble, (UInt_t)fMaxHodoScin, 1},
          {"hodo_NegAdcTimeWindowMin", fHodoNegAdcTimeWindowMin, kDouble, (UInt_t)fMaxHodoScin, 1},
          {"hodo_NegAdcTimeWindowMax", fHodoNegAdcTimeWindowMax, kDouble, (UInt_t)fMaxHodoScin, 1},
          {"dumptof", &fDumpTOF, kInt, 0, 1},
          {"TOFCalib_shtrk_lo", &fTOFCalib_shtrk_lo, kDouble, 0, 1},
          {"TOFCalib_shtrk_hi", &fTOFCalib_shtrk_hi, kDouble, 0, 1},
          {"TOFCalib_cer_lo", &fTOFCalib_cer_lo, kDouble, 0, 1},
          {"TOFCalib_beta_lo", &fTOFCalib_beta_lo, kDouble, 0, 1},
          {"TOFCalib_beta_hi", &fTOFCalib_beta_hi, kDouble, 0, 1},
          {"dumptof_filename", &fTOFDumpFile, kString, 0, 1},
          {0}};
    
    
      // Defaults if not defined in parameter file
    
    
      trackeff_scint_ydiff_max = 20.;
      trackeff_scint_xdiff_max = 20.;
      for (UInt_t ip = 0; ip < fMaxHodoScin; ip++) {
    
        fHodoPosAdcTimeWindowMin[ip] = -1000.;
        fHodoPosAdcTimeWindowMax[ip] = 1000.;
        fHodoNegAdcTimeWindowMin[ip] = -1000.;
        fHodoNegAdcTimeWindowMax[ip] = 1000.;
    
    Yero1990's avatar
    Yero1990 committed
    
        fHodoPosPedLimit[ip] = 0.0;
        fHodoNegPedLimit[ip] = 0.0;
    
        fHodoPosSigma[ip]    = 0.2;
        fHodoNegSigma[ip]    = 0.2;
    
      fTOFCalib_shtrk_lo = -kBig;
      fTOFCalib_shtrk_hi = kBig;
      fTOFCalib_cer_lo   = -kBig;
      fTOFCalib_beta_lo  = -kBig;
      fTOFCalib_beta_hi  = kBig;
      fdebugprintscinraw = 0;
      fDumpTOF           = 0;
      fTOFDumpFile       = "";
      fTofUsingInvAdc    = 1;
      fTofTolerance      = 3.0;
      fNCerNPE           = 2.0;
      fNormETot          = 0.7;
      fCosmicFlag        = 0;
      fNumPlanesBetaCalc = 4;
    
      // Gets added to each reference time corrected raw TDC value
      // to make sure valid range is all positive.
    
      gHcParms->LoadParmValues((DBRequest*)&list, prefix);
      if (fCosmicFlag == 1)
        cout << "Setup for cosmics in TOF" << endl;
    
    Eric Pooser's avatar
    Eric Pooser committed
      // cout << " cosmic flag = " << fCosmicFlag << endl;
    
        fDumpOut.open(fTOFDumpFile.c_str());
    
        if (fDumpOut.is_open()) {
          // fDumpOut << "Hodoscope Time of Flight calibration data" << endl;
    
        } else {
          fDumpTOF = 0;
          cout << "WARNING: Unable to open TOF Dump file " << fTOFDumpFile << endl;
          cout << "Data for TOF calibration not being written." << endl;
        }
      }
    
    
    Eric Pooser's avatar
    Eric Pooser committed
      // cout << " x1 lo = " << fxLoScin[0]
      //      << " x2 lo = " << fxLoScin[1]
      //      << " x1 hi = " << fxHiScin[0]
      //      << " x2 hi = " << fxHiScin[1]
      //      << endl;
    
    Eric Pooser's avatar
    Eric Pooser committed
      // cout << " y1 lo = " << fyLoScin[0]
      //      << " y2 lo = " << fyLoScin[1]
      //      << " y1 hi = " << fyHiScin[0]
      //      << " y2 hi = " << fyHiScin[1]
      //      << endl;
    
    Eric Pooser's avatar
    Eric Pooser committed
      // cout << "Hdososcope planes hits for trigger = " << fTrackEffTestNScinPlanes
      //      << " normalized energy min = " << fNormETot
      //      << " number of photo electrons = " << fNCerNPE
      //      << endl;
    
    Zafar's avatar
    Zafar committed
    
    
      // Set scin Velocity/Cable to default
      for (UInt_t i = 0; i < fMaxHodoScin; i++) {
    
        fHodoVelLight[i] = 15.0;
      }
    
    
        DBRequest list2[] = {
            {"hodo_vel_light", &fHodoVelLight[0], kDouble, fMaxHodoScin, 1},
            {"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);
    
    Yero1990's avatar
    Yero1990 committed
      /* if (!fTofUsingInvAdc) {
          DBRequest list3[]={
    
        {"hodo_vel_light",                   &fHodoVelLight[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},
    
        gHcParms->LoadParmValues((DBRequest*)&list3,prefix);
    
    Yero1990's avatar
    Yero1990 committed
      */
    
      DBRequest list4[] = {{"hodo_velFit", &fHodoVelFit[0], kDouble, fMaxHodoScin, 1},
                           {"hodo_cableFit", &fHodoCableFit[0], kDouble, fMaxHodoScin, 1},
                           {"hodo_LCoeff", &fHodo_LCoeff[0], kDouble, fMaxHodoScin, 1},
                           {"c1_Pos", &fHodoPos_c1[0], kDouble, fMaxHodoScin, 1},
                           {"c1_Neg", &fHodoNeg_c1[0], kDouble, fMaxHodoScin, 1},
                           {"c2_Pos", &fHodoPos_c2[0], kDouble, fMaxHodoScin, 1},
                           {"c2_Neg", &fHodoNeg_c2[0], kDouble, fMaxHodoScin, 1},
                           {"TDC_threshold", &fTdc_Thrs, kDouble, 0, 1},
                           {"hodo_PosSigma", &fHodoSigmaPos[0], kDouble, fMaxHodoScin, 1},
                           {"hodo_NegSigma", &fHodoSigmaNeg[0], kDouble, fMaxHodoScin, 1},
                           {0}};
    
      fTdc_Thrs = 1.0;
      // Set Default Values if NOT defined in param file
      for (UInt_t i = 0; i < fMaxHodoScin; i++) {
    
        // Turn OFF Time-Walk Correction if param file NOT found
        fHodoPos_c1[i] = 0.0;
        fHodoPos_c2[i] = 0.0;
        fHodoNeg_c1[i] = 0.0;
        fHodoNeg_c2[i] = 0.0;
      }
      for (UInt_t i = 0; i < fMaxHodoScin; i++) {
        // Set scin Velocity/Cable to default
        fHodoCableFit[i] = 0.0;
        fHodoVelFit[i]   = 15.0;
        // set time coeff between paddles to default
        fHodo_LCoeff[i] = 0.0;
      }
    
      gHcParms->LoadParmValues((DBRequest*)&list4, 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";
        for (Int_t i1 = 0; i1 < fNPlanes; i1++) {
          cout << "Plane " << i1 << endl;
          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";
        _det_logger->info("THcHodoscope: Using {} nsec window for fp no_track calculations.",
                          fTofTolerance);
      } else {
        fTofTolerance = 3.0;
        // cout << "*** USING DEFAULT 3 NSEC WINDOW FOR FP NO_TRACK CALCULATIONS!! ***\n";
        _det_logger->warn("THcHodoscope: Using default {} nsec window for fp no_track calculations.",
                          fTofTolerance);
    
      fRatio_xpfp_to_xfp = 0.00;
      TString SHMS       = "p";
      TString HMS        = "h";
      TString test       = prefix[0];
      if (test == SHMS)
        fRatio_xpfp_to_xfp = 0.0018; // SHMS
      if (test == HMS)
        fRatio_xpfp_to_xfp = 0.0011; // HMS
    
      cout << " fRatio_xpfp_to_xfp= " << fRatio_xpfp_to_xfp << endl;
    
      fIsInit = true;
      return kOK;
    }
    
    //_____________________________________________________________________________
    
    Int_t THcHodoscope::DefineVariables(EMode mode) {
    
      /**
        Initialize global variables for histograms and Root tree
      */
    
    Eric Pooser's avatar
    Eric Pooser committed
      // 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
          {"beta", "Beta including track info", "fBeta"},
          {"betanotrack", "Beta from scintillator hits", "fBetaNoTrk"},
          {"betachisqnotrack", "Chi square of beta from scintillator hits", "fBetaNoTrkChiSq"},
          {"fpHitsTime", "Time at focal plane from all hits", "fFPTimeAll"},
          {"starttime", "Hodoscope Start Time", "fStartTime"},
          {"goodstarttime", "Hodoscope Good Start Time (logical flag)", "fGoodStartTime"},
          {"goodscinhit", "Hit in fid area", "fGoodScinHits"},
          {"TimeHist_Sigma", "", "fTimeHist_Sigma"},
          {"TimeHist_Peak", "", "fTimeHist_Peak"},
          {"TimeHist_Hits", "", "fTimeHist_Hits"},
          {0}};
    
      return DefineVarsFromList(vars, mode);
    
      //  return kOK;
    
    //_____________________________________________________________________________
    
    Int_t THcHodoscope::ManualInitTree(TTree* t) {
    
      // The most direct path to the output tree!!!
      std::string app_name    = GetApparatus()->GetName();
      std::string det_name    = GetName();
      std::string branch_name = (app_name + "_" + det_name + "_data");
      if (t) {
    
        _det_logger->info("THcHodoscope::ManualInitTree : Adding branch, {}, to output tree",
                          branch_name);
    
        t->Branch(branch_name.c_str(), &_basic_data, 32000, 99);
      }
      return 0;
    }
    
    //_____________________________________________________________________________
    
      // Destructor. Remove variables from global list.
    
    
      delete[] fFPTime;
      delete[] fPlaneCenter;
      delete[] fPlaneSpacing;
    
    }
    
    //_____________________________________________________________________________
    
      // Delete member arrays. Used by destructor.
    
      // for( k = 0; k < fNPlanes; k++){
      //   delete [] fScinHit[k];
      // }
      // delete [] fScinHit;
    
      delete[] fxLoScin;
      fxLoScin = NULL;
      delete[] fxHiScin;
      fxHiScin = NULL;
      delete[] fyLoScin;
      fyLoScin = NULL;
      delete[] fyHiScin;
      fyHiScin = 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[] fHodoNegInvAdcAdc;
      fHodoNegInvAdcAdc = NULL;
      delete[] fGoodPlaneTime;
      fGoodPlaneTime = NULL;
      delete[] fNPlaneTime;
      fNPlaneTime = NULL;
      delete[] fSumPlaneTime;
      fSumPlaneTime = NULL;
      delete[] fNScinHits;
      fNScinHits = NULL;
      delete[] fTdcOffset;
      fTdcOffset = NULL;
      delete[] fAdcTdcOffset;
      fAdcTdcOffset = NULL;
      delete[] fHodoNegAdcTimeWindowMin;
      fHodoNegAdcTimeWindowMin = NULL;
      delete[] fHodoNegAdcTimeWindowMax;
      fHodoNegAdcTimeWindowMax = NULL;
      delete[] fHodoPosAdcTimeWindowMin;
      fHodoPosAdcTimeWindowMin = NULL;
      delete[] fHodoPosAdcTimeWindowMax;
      fHodoPosAdcTimeWindowMax = NULL;
    
      delete[] fHodoVelFit;
      fHodoVelFit = NULL;
      delete[] fHodoCableFit;
      fHodoCableFit = NULL;
      delete[] fHodo_LCoeff;
      fHodo_LCoeff = NULL;
      delete[] fHodoPos_c1;
      fHodoPos_c1 = NULL;
      delete[] fHodoNeg_c1;
      fHodoNeg_c1 = NULL;
      delete[] fHodoPos_c2;
      fHodoPos_c2 = NULL;
      delete[] fHodoNeg_c2;
      fHodoNeg_c2 = NULL;
      delete[] fHodoSigmaPos;
      fHodoSigmaPos = NULL;
      delete[] fHodoSigmaNeg;
      fHodoSigmaNeg = NULL;
    
    }
    
    //_____________________________________________________________________________
    
    Mark Jones's avatar
    Mark Jones committed
      /*! \brief Clears variables
       *
       *  Called by  THcHodoscope::Decode
       *
       */
    
      fTimeHist_Sigma = kBig;
      fTimeHist_Peak  = kBig;
      fTimeHist_Hits  = kBig;
    
    Zafar Ahmed's avatar
    Zafar Ahmed committed
      fBetaNoTrkChiSq = 0.0;
    
      fStartTime      = -1000.;
      fFPTimeAll      = -1000.;
      fGoodStartTime  = kFALSE;
      fGoodScinHits   = 0;
    
      if (*opt != 'I') {
        for (Int_t ip = 0; ip < fNPlanes; ip++) {
    
          fFPTime[ip]       = 0.;
          fPlaneCenter[ip]  = 0.;
          fPlaneSpacing[ip] = 0.;
          for (UInt_t iPaddle = 0; iPaddle < fNPaddle[ip]; ++iPaddle) {
            fScinHitPaddle[ip][iPaddle] = 0;
    
      fClustSize.clear();
      fClustPos.clear();
    
      fThreeScin.clear();
      fGoodScinHitsX.clear();
    
    }
    
    //_____________________________________________________________________________
    
    Int_t THcHodoscope::Decode(const THaEvData& evdata) {
      /*! \brief Decodes raw data and processes raw data into hits for each instance of
       * THcScintillatorPlane
    
    Mark Jones's avatar
    Mark Jones committed
       *
       *  - Reads raw data using THcHitList::DecodeToHitList
       *  - If one wants to subtract pedestals (assumed to be a set of data at beginning of run)
    
       *    + Must define "Pedestal_event" cut in the cuts definition file
    
    Mark Jones's avatar
    Mark Jones committed
       *    + For each "Pedestal_event" calls THcScintillatorPlane::AccumulatePedestals and returns
    
       *    + After First event which is not a  "Pedestal_event" calls
       * THcScintillatorPlane::CalculatePedestals
    
    Mark Jones's avatar
    Mark Jones committed
       *  - For each scintillator plane THcScintillatorPlane::ProcessHits
       *  - Calls THcHodoscope::EstimateFocalPlaneTime
    
    Mark Jones's avatar
    Mark Jones committed
       *
       */
    
      // Get the Hall C style hitlist (fRawHitList) for this event
    
      Bool_t present = kTRUE; // Suppress reference time warnings
      if (fPresentP) {        // if this spectrometer not part of trigger
    
        present = *fPresentP;
      }
      fNHits = DecodeToHitList(evdata, !present);
    
      //
      // 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();
    
    Zafar's avatar
    Zafar committed
    
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
        Int_t nexthit = 0;
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
          nexthit = fPlanes[ip]->AccumulatePedestals(fRawHitList, nexthit);
        }
    
        fAnalyzePedestals = 1; // Analyze pedestals first normal events
        return (0);
    
    Stephen A. Wood's avatar
    Stephen A. Wood committed
      }
    
      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
    
    
    hallc-online's avatar
    hallc-online committed
      Int_t thits = 0;
    
        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);
        thits += fPlanes[ip]->GetNScinHits();
    
    Gabriel Niculescu's avatar
    Gabriel Niculescu committed
      }
    
      fStartTime = -1000;
      if (thits > 0)
        EstimateFocalPlaneTime();
    
      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;
    
    Mark Jones's avatar
    Mark Jones committed
    
    
    //_____________________________________________________________________________
    
    void THcHodoscope::EstimateFocalPlaneTime() {
      /*! \brief Calculates the Drift Chamber start time and fBetaNoTrk (velocity determined without
       * track info)
    
    Mark Jones's avatar
    Mark Jones committed
       *
    
       *  - Called by  THcHodoscope::Decode
    
    Mark Jones's avatar
    Mark Jones committed
       *  - selects good scintillator paddle hits
    
       *     + loops through hits in each scintillator plane and fills histogram array, "timehist", with
       * corrected times for positive and negative ends of each paddle
    
       *     + Determines the peak of "timehist"
    
    Mark Jones's avatar
    Mark Jones committed
       *
       */
    
      Int_t ihit      = 0;
      Int_t nscinhits = 0; // Total # hits with at least one good tdc
    
    hallc-online's avatar
    hallc-online committed
      hTime->Reset();
      //
    
      for (Int_t ip = 0; ip < fNPlanes; ip++) {
        Int_t nphits = fPlanes[ip]->GetNScinHits();
    
        TClonesArray* hodoHits = fPlanes[ip]->GetHits();
    
        for (Int_t i = 0; i < nphits; i++) {
          THcHodoHit* hit = (THcHodoHit*)hodoHits->At(i);
          if (hit->GetHasCorrectedTimes()) {
            Double_t postime = hit->GetPosTOFCorrectedTime();
            Double_t negtime = hit->GetNegTOFCorrectedTime();
            hTime->Fill(postime);
            hTime->Fill(negtime);
    
    hallc-online's avatar
    hallc-online committed
      //
    
    hallc-online's avatar
    hallc-online committed
      //
    
      ihit                      = 0;
      Double_t fpTimeSum        = 0.0;
      fNfptimes                 = 0;
      Int_t    Ngood_hits_plane = 0;
      Double_t Plane_fptime_sum = 0.0;
      Bool_t   goodplanetime[fNPlanes];
      Bool_t   twogoodtimes[nscinhits];
      Double_t tmin               = 0.5 * hTime->GetMaximumBin();
      fTimeHist_Peak              = tmin;
      fTimeHist_Sigma             = hTime->GetRMS();
      fTimeHist_Hits              = hTime->Integral();
      _basic_data.fTimeHist_Peak  = fTimeHist_Peak;
    
      _basic_data.fTimeHist_Sigma = fTimeHist_Sigma;
    
      _basic_data.fTimeHist_Hits  = fTimeHist_Hits;
      for (Int_t ip = 0; ip < fNumPlanesBetaCalc; ip++) {
        goodplanetime[ip]      = kFALSE;
        Int_t         nphits   = fPlanes[ip]->GetNScinHits();
    
        TClonesArray* hodoHits = fPlanes[ip]->GetHits();
    
        Ngood_hits_plane       = 0;
        Plane_fptime_sum       = 0.0;
        for (Int_t i = 0; i < nphits; i++) {
          THcHodoHit* hit    = (THcHodoHit*)hodoHits->At(i);
    
          twogoodtimes[ihit] = kFALSE;
    
          if (hit->GetHasCorrectedTimes()) {
            Double_t postime = hit->GetPosTOFCorrectedTime();
            Double_t negtime = hit->GetNegTOFCorrectedTime();
            if ((postime > (tmin - fTofTolerance)) && (postime < (tmin + fTofTolerance)) &&
                (negtime > (tmin - fTofTolerance)) && (negtime < (tmin + fTofTolerance))) {
              hit->SetTwoGoodTimes(kTRUE);
              twogoodtimes[ihit] = kTRUE;                      // Both tubes fired
              Int_t    index     = hit->GetPaddleNumber() - 1; //
              Double_t fptime;
              if (fCosmicFlag == 1) {
                fptime = hit->GetScinCorrectedTime() +
                         (fPlanes[ip]->GetZpos() + (index % 2) * fPlanes[ip]->GetDzpos()) /
                             (29.979 * fBetaNominal);
              } else {
                fptime = hit->GetScinCorrectedTime() -
                         (fPlanes[ip]->GetZpos() + (index % 2) * fPlanes[ip]->GetDzpos()) /
                             (29.979 * fBetaNominal);
              }
    
              Plane_fptime_sum += fptime;
              fpTimeSum += fptime;
              fNfptimes++;
              goodplanetime[ip] = kTRUE;
            } else {
              hit->SetTwoGoodTimes(kFALSE);
            }
    
        if (Ngood_hits_plane)
          fPlanes[ip]->SetFpTime(Plane_fptime_sum / float(Ngood_hits_plane));
    
        fPlanes[ip]->SetNGoodHits(Ngood_hits_plane);
    
      if (fNfptimes > 0) {
        fStartTime     = fpTimeSum / fNfptimes;
        fGoodStartTime = kTRUE;
        fFPTimeAll     = fStartTime;
    
        fStartTime     = fStartTimeCenter;
        fGoodStartTime = kFALSE;
        fFPTimeAll     = fStartTime;
    
    hallc-online's avatar
    hallc-online committed
      hTime->Reset();
      //
    
      if ((goodplanetime[0] || goodplanetime[1]) && (goodplanetime[2] || goodplanetime[3])) {
    
        Double_t sumW  = 0.;
        Double_t sumT  = 0.;
        Double_t sumZ  = 0.;
    
    Zafar Ahmed's avatar
    Zafar Ahmed committed
        Double_t sumZZ = 0.;
    
        for (Int_t ip = 0; ip < fNumPlanesBetaCalc; ip++) {
          Int_t         nphits   = fPlanes[ip]->GetNScinHits();
    
    Zafar Ahmed's avatar
    Zafar Ahmed committed
          TClonesArray* hodoHits = fPlanes[ip]->GetHits();
    
    
          for (Int_t i = 0; i < nphits; i++) {
            Int_t index = ((THcHodoHit*)hodoHits->At(i))->GetPaddleNumber() - 1;
    
            if (twogoodtimes[ihhit]) {
    
              Double_t sigma = 0.0;
              if (fTofUsingInvAdc) {
                sigma = 0.5 * (TMath::Sqrt(TMath::Power(fHodoPosSigma[GetScinIndex(ip, index)], 2) +
                                           TMath::Power(fHodoNegSigma[GetScinIndex(ip, index)], 2)));
              } else {
                sigma = 0.5 * (TMath::Sqrt(TMath::Power(fHodoSigmaPos[GetScinIndex(ip, index)], 2) +
                                           TMath::Power(fHodoSigmaNeg[GetScinIndex(ip, index)], 2)));
              }
    
              Double_t scinWeight = 1 / TMath::Power(sigma, 2);
              Double_t zPosition  = fPlanes[ip]->GetZpos() + (index % 2) * fPlanes[ip]->GetDzpos();
              //	  cout << "hit = " << ihhit + 1 << "   zpos = " << zPosition << "   sigma = " <<
              // sigma << endl; cout << "fHodoSigma+ = " << fHodoSigmaPos[GetScinIndex(ip,index)] <<
              // endl;
              sumW += scinWeight;
              sumT += scinWeight * ((THcHodoHit*)hodoHits->At(i))->GetScinCorrectedTime();
              sumZ += scinWeight * zPosition;
              sumZZ += scinWeight * (zPosition * zPosition);
              sumTZ += scinWeight * zPosition * ((THcHodoHit*)hodoHits->At(i))->GetScinCorrectedTime();
    
            } // condition of good scin time
            ihhit++;
    
    Zafar Ahmed's avatar
    Zafar Ahmed committed
          } // loop over hits of plane
    
        Double_t tmp      = sumW * sumZZ - sumZ * sumZ;
        Double_t t0       = (sumT * sumZZ - sumZ * sumTZ) / tmp;
    
    Zafar Ahmed's avatar
    Zafar Ahmed committed
        Double_t tmpDenom = sumW * sumTZ - sumZ * sumT;
    
        if (TMath::Abs(tmpDenom) > (1 / 10000000000.0)) {
    
          for (Int_t ip = 0; ip < fNumPlanesBetaCalc; ip++) { // Loop over planes
            Int_t         nphits   = fPlanes[ip]->GetNScinHits();
            TClonesArray* hodoHits = fPlanes[ip]->GetHits();
    
            for (Int_t i = 0; i < nphits; i++) {
              Int_t index = ((THcHodoHit*)hodoHits->At(i))->GetPaddleNumber() - 1;
    
                Double_t zPosition = fPlanes[ip]->GetZpos() + (index % 2) * fPlanes[ip]->GetDzpos();
                Double_t timeDif   = (((THcHodoHit*)hodoHits->At(i))->GetScinCorrectedTime() - t0);
    
    Yero1990's avatar
    Yero1990 committed
    
    
                Double_t sigma = 0.0;
                if (fTofUsingInvAdc) {
                  sigma = 0.5 * (TMath::Sqrt(TMath::Power(fHodoPosSigma[GetScinIndex(ip, index)], 2) +
                                             TMath::Power(fHodoNegSigma[GetScinIndex(ip, index)], 2)));
                } else {
                  sigma = 0.5 * (TMath::Sqrt(TMath::Power(fHodoSigmaPos[GetScinIndex(ip, index)], 2) +
                                             TMath::Power(fHodoSigmaNeg[GetScinIndex(ip, index)], 2)));
                }
    
                fBetaNoTrkChiSq +=
                    ((zPosition / fBetaNoTrk - timeDif) * (zPosition / fBetaNoTrk - timeDif)) /
                    (sigma * sigma);