/** * Method rewrites Reco Signal to Phys Signal. * Time of Signal set to time of the Leading Signal Channel at the lowest threshold. * Other fields are set to -1, quality fields set to 0. */ JPetPhysSignal SignalTransformer::createPhysSignal(const JPetRecoSignal& recoSignal) { JPetPhysSignal physSignal; physSignal.setRecoSignal(recoSignal); physSignal.setPhe(-1.0); physSignal.setQualityOfPhe(0.0); physSignal.setQualityOfTime(0.0); physSignal.setRecoFlag(recoSignal.getRecoFlag()); std::vector<JPetSigCh> leadingSigChVec = recoSignal.getRawSignal().getPoints( JPetSigCh::Leading, JPetRawSignal::ByThrValue ); physSignal.setTime(leadingSigChVec.at(0).getValue()); return physSignal; }
vector<JPetHit> TaskC::createHits(const vector<JPetRawSignal>& signals) { vector<JPetHit> hits; for (auto i = signals.begin(); i != signals.end(); ++i) { for (auto j = i; ++j != signals.end();) { if (i->getPM().getScin() == j->getPM().getScin()) { // found 2 signals from the same scintillator // wrap the RawSignal objects into RecoSignal and PhysSignal // for now this is just wrapping opne object into another // in the future analyses it will involve more logic like // reconstructing the signal's shape, charge, amplitude etc. JPetRecoSignal recoSignalA; JPetRecoSignal recoSignalB; JPetPhysSignal physSignalA; JPetPhysSignal physSignalB; // assign sides A and B properly if ( (i->getPM().getSide() == JPetPM::SideA) && (j->getPM().getSide() == JPetPM::SideB) ) { recoSignalA.setRawSignal(*i); recoSignalB.setRawSignal(*j); } else if ( (j->getPM().getSide() == JPetPM::SideA) && (i->getPM().getSide() == JPetPM::SideB) ) { recoSignalA.setRawSignal(*j); recoSignalB.setRawSignal(*i); } else { // if two hits on the same side, ignore WARNING("TWO hits on the same scintillator side we ignore it"); continue; } if ( recoSignalA.getRawSignal().getNumberOfPoints(JPetSigCh::Leading) < 4 ) continue; if ( recoSignalB.getRawSignal().getNumberOfPoints(JPetSigCh::Leading) < 4 ) continue; bool thresholds_ok = true; for (int i = 1; i <= 4; ++i) { if ( recoSignalA.getRawSignal().getTimesVsThresholdNumber(JPetSigCh::Leading).count(i) < 1 ) { thresholds_ok = false; } if ( recoSignalB.getRawSignal().getTimesVsThresholdNumber(JPetSigCh::Leading).count(i) < 1 ) { thresholds_ok = false; } } if (thresholds_ok == false) { continue; } physSignalA.setRecoSignal(recoSignalA); physSignalB.setRecoSignal(recoSignalB); auto leading_points_a = physSignalA.getRecoSignal().getRawSignal().getTimesVsThresholdNumber(JPetSigCh::Leading); auto leading_points_b = physSignalB.getRecoSignal().getRawSignal().getTimesVsThresholdNumber(JPetSigCh::Leading); //skip signals with no information on 1st threshold // if(leading_points_a.count(1) == 0) continue; // if(leading_points_b.count(1) == 0) continue; physSignalA.setTime(leading_points_a.at(1)); physSignalB.setTime(leading_points_b.at(1)); JPetHit hit; hit.setSignalA(physSignalA); hit.setSignalB(physSignalB); hit.setScintillator(i->getPM().getScin()); hit.setBarrelSlot(i->getPM().getScin().getBarrelSlot()); physSignalA.setTime(physSignalA.getRecoSignal().getRawSignal().getTimesVsThresholdNumber(JPetSigCh::Leading).at(1)); physSignalB.setTime(physSignalB.getRecoSignal().getRawSignal().getTimesVsThresholdNumber(JPetSigCh::Leading).at(1)); hit.setTime( 0.5 * ( hit.getSignalA().getTime() + hit.getSignalB().getTime()) ); hits.push_back(hit); getStatistics().getCounter("No. found hits")++; } } } return hits; }
JPetPhysSignal JPetSimplePhysSignalReco::createPhysSignal(JPetRecoSignal& recoSignal) { // create a Phys Signal JPetPhysSignal physSignal; // use the values from Reco Signal to set the physical properties of signal // here, a dummy example - much more sophisticated procedures should go here physSignal.setPhe( recoSignal.getCharge() * 1.0 + 0.0 ); physSignal.setQualityOfPhe(1.0); // in the previous module (C2) we have reconstructed one time at arbitrary // threshold - now we retrieve it by getting a map of times vs. thresholds, // and taking its first (and only) element by the begin() iterator. We get // an std::pair, where first is the threshold value, and second is time. double time = recoSignal.getRecoTimesAtThreshold().begin()->second; // ----------------------------------------------------------- // // Estimate the time of the signal based on raw signal samples JPetRawSignal rawSignal = recoSignal.getRawSignal(); if (rawSignal.getNumberOfPoints(JPetSigCh::Leading) >= 2 && rawSignal.getNumberOfPoints(JPetSigCh::Trailing) >= 2) { // get number of points on leading edge int iNumPoints = rawSignal.getNumberOfPoints(JPetSigCh::Leading); std::vector<JPetSigCh> leadingPoints = rawSignal.getPoints( JPetSigCh::Leading, JPetRawSignal::ByThrValue); // create vectors vector<float> vecTime(iNumPoints); vector<float> vecVolt(iNumPoints); for (int j = 0; j < iNumPoints; j++) { vecTime(j) = leadingPoints.at(j).getValue(); vecVolt(j) = leadingPoints.at(j).getThreshold(); } // To evaluate time below parameters should be specified: // the parameter alfa of the below expression need to be specified: // vecVolt = a(t - vecTime)^(alfa); // Here alfa is fixed for the linear case. // Caution! alfa has to be an integer and positive value, negative values are ignored. int alfa = getAlpha(); // thr_sel specifies the threshold level to read the time value, // and with thr_sel the below equation may be solved: // thr_sel = a(t - time)^(alfa); // Caution! thr_sel has to negative, and for positive values the program will set thr_sel equal to 0. float thr_sel = getThresholdSel(); // The evaluation of time based on alfa and thr_sel assert(thr_sel < 0); assert(alfa > 0); time = static_cast<double>(polynomialFit(vecTime, vecVolt, alfa, thr_sel)); } // ------------------------------------------------------------ physSignal.setTime(time); physSignal.setQualityOfTime(1.0); // store the original JPetRecoSignal in the PhysSignal as a processing history physSignal.setRecoSignal(recoSignal); return physSignal; }