/* * TrkNucleiZCut.cpp * * Created on: 10-mag-2009 * Author: Nicola Mori */ /*! @file TrkNucleiZCut.cpp The TrkNucleiZCut class implementation file */ #ifndef NO_TRKNUCLEI #include "TrkNucleiZCut.h" const float TrkNucleiZCut::_meanRigMean[] = { .992, 1.99, 3., 4., 5., 6. }; // the charge distribution peak for Z=1..6 const float TrkNucleiZCut::_sigmaRigMean[] = { 0.06, 0.1, 0.17, 0.34, 0.44, 0.59 }; // the charge-width for Z=1..6 const float TrkNucleiZCut::_meanBetaMean[] = { 1., 2., 3., 4., 5., 6. }; // the charge distribution peak for Z=1..6 const float TrkNucleiZCut::_sigmaBetaMean[] = { 0.09, 0.1, 0.17, 0.34, 0.44, 0.59 }; // the charge-width for Z=1..6 int TrkNucleiZCut::Check(PamLevel2 *event) { if (_lowZ < 1 || _lowZ > 6) { return TRKNUCLEIZ_ILLEGALLOWZ; } if ((_highZ < (int) _lowZ && _highZ != -1) || _highZ > 6) { return TRKNUCLEIZ_ILLEGALLOWZ; } /* Check if we must perform a range selection */ bool range = false; if (_highZ != -1) range = true; // ******** Check if TrkNuclei has already been initialized ******** if (_trkNuclei == NULL) _trkNuclei = new TrkNuclei(); _trkNuclei->Set(event->GetTrack(0)->GetTrkTrack()); // ******** First of all, check if the minimum number of planes is matched. ******** // NOTE: in current implementation a plane is considered valid if it is tagged as good in Tracker level 2 // routines. This should correspond to a valid charge. // TODO Check the above statement. // Prepare the valid charges counter unsigned int nValid = 0; for (unsigned int ip = 0; ip < 6; ip++) { if (_trkNuclei->GetTrkTrack()->XGood(ip) && _trkNuclei->GetTrkTrack()->XGood(ip)) nValid++; } if (nValid < _minLayers) return TRKNUCLEIZ_TOOFEWLAYERS; // ******** Check the mean charge value ******** if (_howToCheck == TRKNUCLEIZ_CHECKMEAN) { Float_t charge = 0., meanLowZ = 0., sigmaLowZ = 0., meanHighZ = 0., sigmaHighZ = 0.; ; switch (_method) { case TRKNUCLEIZ_RIG: charge = _trkNuclei->GetZ_Rigidity(); meanLowZ = _meanRigMean[_lowZ - 1]; sigmaLowZ = _sigmaRigMean[_lowZ - 1]; if (range) { meanHighZ = _meanRigMean[_highZ - 1]; sigmaHighZ = _sigmaRigMean[_highZ - 1]; } break; case TRKNUCLEIZ_BETA: charge = _trkNuclei->GetZ_Beta(event->GetTrack(0)->GetToFTrack()->beta[12]); meanLowZ = _meanBetaMean[_lowZ - 1]; sigmaLowZ = _sigmaBetaMean[_lowZ - 1]; if (range) { meanHighZ = _meanBetaMean[_highZ - 1]; sigmaHighZ = _sigmaBetaMean[_highZ - 1]; } break; } if (!range) { if ((charge > meanLowZ + _upperLimit * sigmaLowZ) || (charge < meanLowZ - _lowerLimit * sigmaLowZ)) { return TRKNUCLEIZ_OUTOFBOUNDS; } } else { if ((charge > meanHighZ + _upperLimit * sigmaHighZ) || (charge < meanLowZ - _lowerLimit * sigmaLowZ)) { return TRKNUCLEIZ_OUTOFBOUNDS; } } } // ******** Check the charge value from each plane ******** // NB. In current implementation only 2 check methods (mean and single values) are used, so an "else" statement // is sufficient. Implement an "if" cascade or a "switch" if another check method is necessary. else { Float_t charge[6] = { 0., 0., 0., 0., 0., 0. }; nValid = 0; switch (_method) { case TRKNUCLEIZ_RIG: for (int ip = 0; ip < 6; ip++) { charge[ip] = _trkNuclei->GetZ_Rigidity(ip); if (charge[ip] > 0.) { nValid++; } } break; case TRKNUCLEIZ_BETA: for (int ip = 0; ip < 6; ip++) { charge[ip] = _trkNuclei->GetZ_Beta(ip, event->GetTrack(0)->GetToFTrack()->beta[12]); if (charge[ip] > 0.) { nValid++; } } break; } for (int ip = 0; ip < 6; ip++) { if (charge[ip] > 0.) { // Check only good layers // Currently, no calibration for single layers is available. Z is used as a mean value, while for sigma // we use the standard values use for mean dE/dx Vs. beta. if (!range) { if ((charge[ip] > _lowZ + _upperLimit * _sigmaBetaMean[_lowZ - 1]) || (charge[ip] < _lowZ - _lowerLimit * _sigmaBetaMean[_lowZ - 1])) { return TRKNUCLEIZ_OUTOFBOUNDS; } } else { if ((charge[ip] > _highZ + _upperLimit * _sigmaBetaMean[_highZ - 1]) || (charge[ip] < _lowZ - _lowerLimit * _sigmaBetaMean[_lowZ - 1])) { return TRKNUCLEIZ_OUTOFBOUNDS; } } } } } return CUTOK; } #endif /* NO_TRKNUCLEI */