98 std::vector<int> startTimes;
99 std::vector<int> maxTimes;
100 std::vector<int> endTimes;
102 int minTimeHolder = 0;
104 bool maxFound =
false;
105 double threshold = 0.;
106 double fitWidth = 0.;
107 double minWidth = 0.;
108 std::string eqn =
"gaus(0)";
110 std::stringstream numConv;
113 for (
unsigned int wireIter = 0; wireIter < wireVecHandle->size(); wireIter++) {
119 std::vector<float> signal(wire->Signal());
124 channel = wire->Channel();
139 for (timeIter = signal.begin(); timeIter + 2 < signal.end(); timeIter++) {
141 if (*timeIter > *(timeIter + 1) && *(timeIter + 1) < *(timeIter + 2)) {
144 endTimes.push_back(time + 1);
147 minTimeHolder = time + 2;
150 minTimeHolder = time + 1;
154 else if (*timeIter < *(timeIter + 1) && *(timeIter + 1) > *(timeIter + 2) &&
155 *(timeIter + 1) > threshold) {
157 maxTimes.push_back(time + 1);
158 startTimes.push_back(minTimeHolder);
164 while (maxTimes.size() > endTimes.size())
165 endTimes.push_back(signal.size() - 1);
166 if (startTimes.size() == 0)
continue;
177 double amplitude(0), position(0), width(0);
178 double amplitudeErr(0), positionErr(0), widthErr(0);
179 double goodnessOfFit(0), chargeErr(0);
180 double minPeakHeight(0);
184 std::vector<double> hitSig;
187 while (hitIndex < (
signed)startTimes.size()) {
191 minPeakHeight = signal[maxTimes[hitIndex]];
198 while (numHits <
fMaxMultiHit && numHits + hitIndex < (
signed)endTimes.size() &&
199 signal[endTimes[hitIndex + numHits - 1]] > threshold / 2.0 &&
200 startTimes[hitIndex + numHits] - endTimes[hitIndex + numHits - 1] < 2) {
202 if (signal[maxTimes[hitIndex + numHits]] < minPeakHeight)
203 minPeakHeight = signal[maxTimes[hitIndex + numHits]];
209 startT = startTimes[hitIndex];
211 while (signal[(
int)startT] < minPeakHeight / 2.0)
215 endT = endTimes[hitIndex + numHits - 1];
217 while (signal[(
int)endT] < minPeakHeight / 2.0)
219 size = (int)(endT - startT);
220 TH1D hitSignal(
"hitSignal",
"",
size, startT, endT);
221 for (
int i = (
int)startT; i < (int)endT; ++i)
222 hitSignal.Fill(i, signal[i]);
227 for (
int i = 3; i < numHits * 3; i += 3) {
228 eqn.append(
"+gaus(");
231 eqn.append(numConv.str());
235 TF1 gSum(
"gSum", eqn.c_str(), 0,
size);
238 TArrayD data(numHits * numHits);
239 TVectorD amps(numHits);
240 for (
int i = 0; i < numHits; ++i) {
241 amps[i] = signal[maxTimes[hitIndex + i]];
242 for (
int j = 0; j < numHits; j++)
243 data[i + numHits * j] =
244 TMath::Gaus(maxTimes[hitIndex + j], maxTimes[hitIndex + i], fitWidth);
250 TMatrixD h(numHits, numHits);
251 h.Use(numHits, numHits, data.GetArray());
261 for (
int i = 0; i < numHits; ++i) {
268 amplitude = 0.5 * (threshold + signal[maxTimes[hitIndex + i]]);
269 gSum.SetParameter(3 * i, amplitude);
270 gSum.SetParameter(1 + 3 * i, maxTimes[hitIndex + i]);
271 gSum.SetParameter(2 + 3 * i, fitWidth);
272 gSum.SetParLimits(3 * i, 0.0, 3.0 * amplitude);
273 gSum.SetParLimits(1 + 3 * i, startT, endT);
274 gSum.SetParLimits(2 + 3 * i, 0.0, 10.0 * fitWidth);
278 gSum.SetParameters(signal[maxTimes[hitIndex]], maxTimes[hitIndex], fitWidth);
279 gSum.SetParLimits(0, 0.0, 1.5 * signal[maxTimes[hitIndex]]);
280 gSum.SetParLimits(1, startT, endT);
281 gSum.SetParLimits(2, 0.0, 10.0 * fitWidth);
285 hitSignal.Fit(&gSum,
"QNRW",
"", startT, endT);
286 for (
int hitNumber = 0; hitNumber < numHits; ++hitNumber) {
288 if (gSum.GetParameter(3 * hitNumber) > threshold / 2.0 &&
289 gSum.GetParameter(3 * hitNumber + 2) > minWidth) {
290 amplitude = gSum.GetParameter(3 * hitNumber);
291 position = gSum.GetParameter(3 * hitNumber + 1);
292 width = gSum.GetParameter(3 * hitNumber + 2);
293 amplitudeErr = gSum.GetParError(3 * hitNumber);
294 positionErr = gSum.GetParError(3 * hitNumber + 1);
295 widthErr = gSum.GetParError(3 * hitNumber + 2);
296 goodnessOfFit = gSum.GetChisquare() / (double)gSum.GetNDF();
297 int DoF = gSum.GetNDF();
300 chargeErr = std::sqrt(TMath::Pi()) * (amplitudeErr * width + widthErr * amplitude);
304 for (
int sigPos = 0; sigPos <
size; ++sigPos) {
305 hitSig[sigPos] = amplitude * TMath::Gaus(sigPos + startT, position, width);
306 totSig += hitSig[(int)sigPos];
310 totSig = std::sqrt(2 * TMath::Pi()) * amplitude * width /
fAreaNorms[(size_t)sigType];
313 std::vector<geo::WireID> wids = geom->
ChannelToWire(channel);
331 (signal.begin() + (int)startT, signal.begin() + (int)endT, 0.),
342 hcol.emplace_back(
hit.move(), wire, rawdigits);
double fIndMinWidth
Minimum induction hit width.
std::vector< WireID > ChannelToWire(raw::ChannelID_t const channel) const
Returns a list of wires connected to the specified TPC channel.
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
double fMinSigInd
Induction signal height threshold.
double fIndWidth
Initial width for induction fit.
int fMaxMultiHit
maximum hits for multi fit
double fColWidth
Initial width for collection fit.
std::vector< double > fAreaNorms
factors for converting area to same units as peak height
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Class managing the creation of a new recob::Hit object.
std::string fCalDataModuleLabel
constexpr ChannelID_t InvalidChannelID
ID of an invalid channel.
A class handling a collection of hits and its associations.
Signal from induction planes.
enum geo::_plane_sigtype SigType_t
Enumerate the possible plane projections.
double fColMinWidth
Minimum collection hit width.
Detector simulation of raw signals on wires.
SigType_t SignalType(PlaneID const &pid) const
Returns the type of signal on the channels of specified TPC plane.
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
double fMinSigCol
Collection signal height threshold.
int fAreaMethod
Type of area calculation.
unsigned int ChannelID_t
Type representing the ID of a readout channel.
Signal from collection planes.