Skip to content
Snippets Groups Projects
THcHodoscope.cxx 50.4 KiB
Newer Older
	    } // time at focal plane condition
	  } // on track else condition
	  
	  // ** See if there are any good time measurements in the plane.
	  if ( fTOFCalc[ihhit].good_scin_time ){
	    fGoodPlaneTime[ip] = kTRUE;
	    fTOFCalc[ihhit].dedx = fdEdX[itrack][fNScinHit[itrack]-1];
	  } else {
	    fTOFCalc[ihhit].dedx = 0.0;

	  // Can this be done after looping over hits and planes?
	  if ( fGoodPlaneTime[2] )	theTrack->SetGoodPlane3( 1 );
Zafar's avatar
Zafar committed
	  if ( !fGoodPlaneTime[2] )	theTrack->SetGoodPlane3( 0 );
	  if ( fGoodPlaneTime[3] )	theTrack->SetGoodPlane4( 1 );
Zafar's avatar
Zafar committed
	  if ( !fGoodPlaneTime[3] )	theTrack->SetGoodPlane4( 0 );
	} // Second loop over hits of a scintillator plane ends here
      } // Loop over scintillator planes ends here

Zafar's avatar
Zafar committed
      //------------------------------------------------------------------------------
      //------------------------------------------------------------------------------
      //------------------------------------------------------------------------------
      //------------------------------------------------------------------------------
      //------------------------------------------------------------------------------
      //------------------------------------------------------------------------------
      //------------------------------------------------------------------------------
      //------------------------------------------------------------------------------

      // * * Fit beta if there are enough time measurements (one upper, one lower)
      if ( ( ( fGoodPlaneTime[0] ) || ( fGoodPlaneTime[1] ) ) && 
	   ( ( fGoodPlaneTime[2] ) || ( fGoodPlaneTime[3] ) ) ){	
	
Stephen A. Wood's avatar
Stephen A. Wood committed
	Double_t sumW = 0.;
	Double_t sumT = 0.;
	Double_t sumZ = 0.;
	Double_t sumZZ = 0.;
	Double_t sumTZ = 0.;
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();	  
Stephen A. Wood's avatar
Stephen A. Wood committed
	  for (Int_t iphit = 0; iphit < fNScinHits[ip]; iphit++ ){
	    if ( fTOFCalc[ihhit].good_scin_time ) {
Stephen A. Wood's avatar
Stephen A. Wood committed
	      Double_t scinWeight = 1 / ( fTOFCalc[ihhit].scin_sigma * fTOFCalc[ihhit].scin_sigma );
	      Double_t zPosition = ( fPlanes[ip]->GetZpos() + ( fTOFCalc[ihhit].hit_paddle % 2 ) * 
			     fPlanes[ip]->GetDzpos() );
Stephen A. Wood's avatar
Stephen A. Wood committed
	      sumW  += scinWeight;
	      sumT  += scinWeight * fTOFCalc[ihhit].scin_time;
	      sumZ  += scinWeight * zPosition;
	      sumZZ += scinWeight * ( zPosition * zPosition );
	      sumTZ += scinWeight * zPosition * fTOFCalc[ihhit].scin_time;
	      	      
	    } // condition of good scin time
	  } // loop over hits of plane
	} // loop over planes
Stephen A. Wood's avatar
Stephen A. Wood committed
	Double_t tmp = sumW * sumZZ - sumZ * sumZ ;
	Double_t t0 = ( sumT * sumZZ - sumZ * sumTZ ) / tmp ;
	Double_t tmpDenom = sumW * sumTZ - sumZ * sumT;
Stephen A. Wood's avatar
Stephen A. Wood committed
	if ( TMath::Abs( tmpDenom ) > ( 1 / 10000000000.0 ) ) {
Stephen A. Wood's avatar
Stephen A. Wood committed
	  beta = tmp / tmpDenom;
Stephen A. Wood's avatar
Stephen A. Wood committed
	  betaChiSq = 0.;	  
Stephen A. Wood's avatar
Stephen A. Wood committed
	  for (Int_t ip = 0; ip < fNPlanes; ip++ ){                           // Loop over planes
Zafar's avatar
Zafar committed
	    fNScinHits[ip] = fPlanes[ip]->GetNScinHits();	  
Stephen A. Wood's avatar
Stephen A. Wood committed
	    for (Int_t iphit = 0; iphit < fNScinHits[ip]; iphit++ ){                    // Loop over hits of a plane
	      if ( fTOFCalc[ihhit].good_scin_time ){
Stephen A. Wood's avatar
Stephen A. Wood committed
		Double_t zPosition = ( fPlanes[ip]->GetZpos() + ( fTOFCalc[ihhit].hit_paddle % 2 ) * 
			       fPlanes[ip]->GetDzpos() );
Stephen A. Wood's avatar
Stephen A. Wood committed
		Double_t timeDif = ( fTOFCalc[ihhit].scin_time - t0 );		
		betaChiSq += ( ( zPosition / beta - timeDif ) * 
				( zPosition / beta - timeDif ) )  / 
		              ( fTOFCalc[ihhit].scin_sigma * fTOFCalc[ihhit].scin_sigma );
		
	      } // condition for good scin time
	    } // loop over hits of a plane
	  } // loop over planes
	  
Stephen A. Wood's avatar
Stephen A. Wood committed
	  Double_t pathNorm = TMath::Sqrt( 1. + theTrack->GetTheta() * theTrack->GetTheta() + 
				       theTrack->GetPhi()   * theTrack->GetPhi() );
Stephen A. Wood's avatar
Stephen A. Wood committed
	  beta = beta / pathNorm;
Stephen A. Wood's avatar
Stephen A. Wood committed
	  beta = beta / 29.979;    // velocity / c	  
	  
	}  // condition for fTmpDenom	
Stephen A. Wood's avatar
Stephen A. Wood committed
	  beta = 0.;
	  betaChiSq = -2.;
	} // else condition for fTmpDenom
Stephen A. Wood's avatar
Stephen A. Wood committed
	beta = 0.;
	betaChiSq = -1;
Stephen A. Wood's avatar
Stephen A. Wood committed
      if ( nFPTime != 0 ){
      	timeAtFP[itrack] = ( sumFPTime / nFPTime ); 
Zafar's avatar
Zafar committed
      }
      //
      // ---------------------------------------------------------------------------
Stephen A. Wood's avatar
Stephen A. Wood committed
      Double_t FPTimeSum=0.0;
      Int_t nFPTimeSum=0;
Stephen A. Wood's avatar
Stephen A. Wood committed
      for (Int_t ip = 0; ip < fNPlanes; ip++ ){
	if ( fNPlaneTime[ip] != 0 ){
	  fFPTime[ip] = ( fSumPlaneTime[ip] / fNPlaneTime[ip] );
Stephen A. Wood's avatar
Stephen A. Wood committed
	  FPTimeSum += fSumPlaneTime[ip];
	  nFPTimeSum += fNPlaneTime[ip];
	  fFPTime[ip] = 1000. * ( ip + 1 );
Stephen A. Wood's avatar
Stephen A. Wood committed
      Double_t fptime = FPTimeSum/nFPTimeSum;
      Double_t dedx=0.0;
      for(UInt_t ih=0;ih<fTOFCalc.size();ih++) {
	if(fTOFCalc[ih].good_scin_time) {
	  dedx = fTOFCalc[ih].dedx;
	  break;
	}
      }
      theTrack->SetDedx(dedx);
Stephen A. Wood's avatar
Stephen A. Wood committed
      theTrack->SetFPTime(fptime);
      theTrack->SetBeta(beta);
      theTrack->SetBetaChi2( betaChiSq );
Stephen A. Wood's avatar
Stephen A. Wood committed
      theTrack->SetNPMT(nPmtHit[itrack]);
      theTrack->SetFPTime( timeAtFP[itrack]);
Zafar's avatar
Zafar committed

    } // Main loop over tracks ends here.

  } // If condition for at least one track

  //-----------------------------------------------------------------------
  //
  //   Trnslation of h_track_tests.f file for tracking efficiency
  //
  //-----------------------------------------------------------------------

  //************************now look at some hodoscope tests
  //  *second, we move the scintillators.  here we use scintillator cuts to see
  //  *if a track should have been found.

  for(Int_t ip = 0; ip < fNPlanes; ip++ ) {

    std::vector<Double_t> scin_temp;
    fScinHitPaddle.push_back(scin_temp); // Create array of hits per plane

    for (UInt_t ipaddle = 0; ipaddle < fNPaddle[0]; ipaddle++ ){
	  fScinHitPaddle[ip].push_back(0.0);
	  fScinHitPaddle[ip][ipaddle] = 0.0;	  
  for(Int_t ip = 0; ip < fNPlanes; ip++ ) {
    if (!fPlanes[ip])
      return -1;

    TClonesArray* hodoHits = fPlanes[ip]->GetHits();
    //    TClonesArray* scinPosTDC = fPlanes[ip]->GetPosTDC();
    //    TClonesArray* scinNegTDC = fPlanes[ip]->GetNegTDC();

    fNScinHits[ip] = fPlanes[ip]->GetNScinHits();
    for (Int_t iphit = 0; iphit < fNScinHits[ip]; iphit++ ){
      Int_t paddle = ((THcHodoHit*)hodoHits->At(iphit))->GetPaddleNumber()-1;
    }
  }

  //  *next, look for clusters of hits in a scin plane.  a cluster is a group of
  //  *adjacent scintillator hits separated by a non-firing scintillator.
  //  *Wwe count the number of three adjacent scintillators too.  (A signle track
  //  *shouldn't fire three adjacent scintillators.

  for(Int_t ip = 0; ip < fNPlanes; ip++ ) {
    // Planes ip = 0 = 1X
    // Planes ip = 2 = 2X
    if (!fPlanes[ip]) return -1;
    fNClust.push_back(0);
    fThreeScin.push_back(0);
  }

  // *look for clusters in x planes... (16 scins)  !this assume both x planes have same
  // *number of scintillators.
  Int_t icount;
  for (Int_t ip = 0; ip < 3; ip +=2 ) {
    icount = 0;
    if ( fScinHitPaddle[ip][0] == 1 )
      icount ++;

    for (Int_t ipaddle = 0; ipaddle < (Int_t) fNPaddle[0] - 1; ipaddle++ ){
      // !look for number of clusters of 1 or more hits

      if ( ( fScinHitPaddle[ip][ipaddle] == 0 ) &&
	   ( fScinHitPaddle[ip][ipaddle + 1] == 1 ) )
	icount ++;
    } // Loop over  paddles

    fNClust[ip] = icount;
    icount = 0;

    for (Int_t ipaddle = 0; ipaddle < (Int_t) fNPaddle[0] - 2; ipaddle++ ){
      // !look for three or more adjacent hits

      if ( ( fScinHitPaddle[ip][ipaddle] == 1 ) &&
	   ( fScinHitPaddle[ip][ipaddle + 1] == 1 ) &&
	   ( fScinHitPaddle[ip][ipaddle + 2] == 1 ) )
	icount ++;
    } // Second loop over paddles

    if ( icount > 0 )
      fThreeScin[ip] = 1;

  } // Loop over X plane

  // *look for clusters in y planes... (10 scins)  !this assume both y planes have same  
  // *number of scintillators.

  for (Int_t ip = 1; ip < 4; ip +=2 ) {
    // Planes ip = 1 = 1Y
    // Planes ip = 3 = 2Y
    if (!fPlanes[ip]) return -1;

    icount = 0;
    if ( fScinHitPaddle[ip][0] == 1 )
      icount ++;

    for (Int_t ipaddle = 0; ipaddle < (Int_t) fNPaddle[1] - 1; ipaddle++ ){
      //  !look for number of clusters of 1 or more hits

      if ( ( fScinHitPaddle[ip][ipaddle] == 0 ) &&
	   ( fScinHitPaddle[ip][ipaddle + 1] == 1 ) )
	icount ++;

    } // Loop over Y paddles

    fNClust[ip] = icount;
    icount = 0;

    for (Int_t ipaddle = 0; ipaddle < (Int_t) fNPaddle[1] - 2; ipaddle++ ){
      // !look for three or more adjacent hits

      if ( ( fScinHitPaddle[ip][ipaddle] == 1 ) &&
	   ( fScinHitPaddle[ip][ipaddle + 1] == 1 ) &&
	   ( fScinHitPaddle[ip][ipaddle + 2] == 1 ) )
	icount ++;

    } // Second loop over Y paddles

    if ( icount > 0 )
      fThreeScin[ip] = 1;

  }// Loop over Y planes

  // *now put some "tracking" like cuts on the hslopes, based only on scins...
  // *by "slope" here, I mean the difference in the position of scin hits in two
  // *like-planes.  For example, a track that those great straight through will 
  // *have a slope of zero.  If it moves one scin over from s1x to s2x it has an
  // *x-slope of 1...  I pick the minimum slope if there are multiple scin hits.

Stephen A. Wood's avatar
Stephen A. Wood committed
  Double_t bestXpScin = 100.0;
  Double_t bestYpScin = 100.0;

  for (Int_t ipaddle = 0; ipaddle < (Int_t) fNPaddle[0]; ipaddle++ ){
    for (Int_t ipaddle2 = 0; ipaddle2 < (Int_t) fNPaddle[0]; ipaddle2++ ){

      if ( ( fScinHitPaddle[0][ipaddle] == 1 ) &&
	   ( fScinHitPaddle[2][ipaddle2] == 1 ) ){

Stephen A. Wood's avatar
Stephen A. Wood committed
	Double_t slope = TMath::Abs(ipaddle - ipaddle2);
Stephen A. Wood's avatar
Stephen A. Wood committed
	if ( slope < bestXpScin ) {
	  bestXpScin = slope;
    }  // Second loop over X paddles
  } // First loop over X paddles

  for (Int_t ipaddle = 0; ipaddle < (Int_t) fNPaddle[1]; ipaddle++ ){
    for (Int_t ipaddle2 = 0; ipaddle2 < (Int_t) fNPaddle[1]; ipaddle2++ ){

      if ( ( fScinHitPaddle[1][ipaddle] == 1 ) &&
	   ( fScinHitPaddle[3][ipaddle2] == 1 ) ){

Stephen A. Wood's avatar
Stephen A. Wood committed
	Double_t slope = TMath::Abs(ipaddle - ipaddle2);
Stephen A. Wood's avatar
Stephen A. Wood committed
	if ( slope < bestYpScin ) {
	  bestYpScin = slope;	
    }  // Second loop over Y paddles
  } // First loop over Y paddles

  // *next we mask out the edge scintillators, and look at triggers that happened
  // *at the center of the acceptance.  To change which scins are in the mask
  // *change the values of h*loscin and h*hiscin in htracking.param

  //      fGoodScinHits = 0;
  for (Int_t ifidx = fxLoScin[0]; ifidx < (Int_t) fxHiScin[0]; ifidx ++ ){
    fGoodScinHitsX.push_back(0);
  }

  // *first x plane.  first see if there are hits inside the scin region
  for (Int_t ifidx = fxLoScin[0]-1; ifidx < fxHiScin[0]; ifidx ++ ){
    if ( fScinHitPaddle[0][ifidx] == 1 ){
      fHitSweet1X = 1;
      fSweet1XScin = ifidx + 1;
    }
  }

  // *  next make sure nothing fired outside the good region
  for (Int_t ifidx = 0; ifidx < fxLoScin[0]-1; ifidx ++ ){
    if ( fScinHitPaddle[0][ifidx] == 1 ){ fHitSweet1X = -1; }
  }
  for (Int_t ifidx = fxHiScin[0]; ifidx < (Int_t) fNPaddle[0]; ifidx ++ ){
    if ( fScinHitPaddle[0][ifidx] == 1 ){ fHitSweet1X = -1; }
  }

  // *second x plane.  first see if there are hits inside the scin region
  for (Int_t ifidx = fxLoScin[1]-1; ifidx < fxHiScin[1]; ifidx ++ ){
    if ( fScinHitPaddle[2][ifidx] == 1 ){
      fHitSweet2X = 1;
      fSweet2XScin = ifidx + 1;
    }
  }
  // *  next make sure nothing fired outside the good region
  for (Int_t ifidx = 0; ifidx < fxLoScin[1]-1; ifidx ++ ){
    if ( fScinHitPaddle[2][ifidx] == 1 ){ fHitSweet2X = -1; }
  }
  for (Int_t ifidx = fxHiScin[1]; ifidx < (Int_t) fNPaddle[2]; ifidx ++ ){
    if ( fScinHitPaddle[2][ifidx] == 1 ){ fHitSweet2X = -1; }
  }

  // *first y plane.  first see if there are hits inside the scin region
  for (Int_t ifidx = fyLoScin[0]-1; ifidx < fyHiScin[0]; ifidx ++ ){
    if ( fScinHitPaddle[1][ifidx] == 1 ){
      fHitSweet1Y = 1;
      fSweet1YScin = ifidx + 1;
    }
  }
  // *  next make sure nothing fired outside the good region
  for (Int_t ifidx = 0; ifidx < fyLoScin[0]-1; ifidx ++ ){
    if ( fScinHitPaddle[1][ifidx] == 1 ){ fHitSweet1Y = -1; }
  }
  for (Int_t ifidx = fyHiScin[0]; ifidx < (Int_t) fNPaddle[1]; ifidx ++ ){
    if ( fScinHitPaddle[1][ifidx] == 1 ){ fHitSweet1Y = -1; }
  }

  // *second y plane.  first see if there are hits inside the scin region
  for (Int_t ifidx = fyLoScin[1]-1; ifidx < fyHiScin[1]; ifidx ++ ){
    if ( fScinHitPaddle[3][ifidx] == 1 ){
      fHitSweet2Y = 1;
      fSweet2YScin = ifidx + 1;
    }
  }

  // *  next make sure nothing fired outside the good region
  for (Int_t ifidx = 0; ifidx < fyLoScin[1]-1; ifidx ++ ){
    if ( fScinHitPaddle[3][ifidx] == 1 ){ fHitSweet2Y = -1; }
  }
  for (Int_t ifidx = fyHiScin[1]; ifidx < (Int_t) fNPaddle[3]; ifidx ++ ){
    if ( fScinHitPaddle[3][ifidx] == 1 ){ fHitSweet2Y = -1; }
  }

  fTestSum = fHitSweet1X + fHitSweet2X + fHitSweet1Y + fHitSweet2Y;

  // * now define a 3/4 or 4/4 trigger of only good scintillators the value
  // * is specified in htracking.param...
  if ( fTestSum > fTrackEffTestNScinPlanes ){
    fGoodScinHits = 1;
    for (Int_t ifidx = fxLoScin[0]; ifidx < fxHiScin[0]; ifidx ++ ){
      if ( fSweet1XScin == ifidx )
	fGoodScinHitsX[ifidx] = 1;
    }
  }

  // * require front/back hodoscopes be close to each other
  if ( ( fGoodScinHits == 1 ) && ( fTrackEffTestNScinPlanes == 4 ) ){
    if ( TMath::Abs( fSweet1XScin - fSweet2XScin ) > 3 )
      fGoodScinHits = 0;
    if ( TMath::Abs( fSweet1YScin - fSweet2YScin ) > 2 )
      fGoodScinHits = 0;
  }


  if ( !fChern || !fShower ) { 
    return 0;    
  }
  
  if ( ( fGoodScinHits == 1 ) && ( fShower->GetNormETot() > fNormETot ) &&
       ( fChern->GetCerNPE() > fNCerNPE ) )
    fScinShould = 1;
  
  if ( ( fGoodScinHits == 1 ) && ( fShower->GetNormETot() > fNormETot ) &&
       ( fChern->GetCerNPE() > fNCerNPE ) && ( tracks.GetLast() + 1 > 0 ) ) {
      fScinDid = 1;
//_____________________________________________________________________________
Int_t THcHodoscope::GetScinIndex( Int_t nPlane, Int_t nPaddle ) {
  // GN: Return the index of a scintillator given the plane # and the paddle #
  // This assumes that both planes and 
  // paddles start counting from 0!
  // Result also counts from 0.
  return fNPlanes*nPaddle+nPlane;
}
//_____________________________________________________________________________
Int_t THcHodoscope::GetScinIndex( Int_t nSide, Int_t nPlane, Int_t nPaddle ) {
  return nSide*fMaxHodoScin+fNPlanes*nPaddle+nPlane-1;
}
//_____________________________________________________________________________
Double_t THcHodoscope::GetPathLengthCentral() {
  return fPathLengthCentral;
}
ClassImp(THcHodoscope)
////////////////////////////////////////////////////////////////////////////////