137 std::vector<int> startTimes;
138 std::vector<int> maxTimes;
139 std::vector<int> endTimes;
141 int minTimeHolder = 0;
143 bool maxFound =
false;
144 double threshold = 0.;
145 double fitWidth = 0.;
146 double minWidth = 0.;
147 std::string eqn =
"gaus(0)";
149 std::stringstream numConv;
153 for(
unsigned int wireIter = 0; wireIter < wireVecHandle->size(); wireIter++) {
159 std::vector<float> signal(wire->Signal());
164 channel = wire->Channel();
179 for(timeIter = signal.begin(); timeIter+2 < signal.end(); timeIter++){
181 if(*timeIter > *(timeIter+1) && *(timeIter+1) < *(timeIter+2)){
184 endTimes.push_back(time+1);
187 minTimeHolder = time+2;
189 else minTimeHolder = time+1;
193 else if(*timeIter < *(timeIter+1) &&
194 *(timeIter+1) > *(timeIter+2) &&
195 *(timeIter+1) > threshold){
197 maxTimes.push_back(time+1);
198 startTimes.push_back(minTimeHolder);
205 while(maxTimes.size()>endTimes.size())
206 endTimes.push_back(signal.size()-1);
207 if(startTimes.size() == 0)
continue;
218 double amplitude(0), position(0), width(0);
219 double amplitudeErr(0), positionErr(0), widthErr(0);
220 double goodnessOfFit(0), chargeErr(0);
221 double minPeakHeight(0);
225 std::vector<double> hitSig;
228 while(hitIndex < (
signed)startTimes.size()) {
232 minPeakHeight = signal[maxTimes[hitIndex]];
240 numHits+hitIndex < (
signed)endTimes.size() &&
241 signal[endTimes[hitIndex+numHits-1]] >threshold/2.0 &&
242 startTimes[hitIndex+numHits] - endTimes[hitIndex+numHits-1] < 2){
244 if(signal[maxTimes[hitIndex+numHits]] < minPeakHeight)
245 minPeakHeight = signal[maxTimes[hitIndex+numHits]];
251 startT = startTimes[hitIndex];
253 while(signal[(
int)startT] < minPeakHeight/2.0) ++startT;
256 endT = endTimes[hitIndex+numHits-1];
258 while(signal[(
int)endT] <minPeakHeight/2.0) --endT;
259 size = (int)(endT-startT);
260 TH1D hitSignal(
"hitSignal",
"",size,startT,endT);
261 for(
int i = (
int)startT; i < (int)endT; ++i)
262 hitSignal.Fill(i,signal[i]);
267 for(
int i = 3; i < numHits*3; i+=3) {
268 eqn.append(
"+gaus(");
271 eqn.append(numConv.str());
275 TF1 gSum(
"gSum",eqn.c_str(),0,size);
278 TArrayD data(numHits*numHits);
279 TVectorD amps(numHits);
280 for(
int i = 0; i < numHits; ++i) {
281 amps[i] = signal[maxTimes[hitIndex+i]];
282 for(
int j = 0; j < numHits;j++)
283 data[i+numHits*j] = TMath::Gaus(maxTimes[hitIndex+j],
284 maxTimes[hitIndex+i],
291 TMatrixD h(numHits,numHits);
292 h.Use(numHits,numHits,data.GetArray());
302 for(
int i = 0; i < numHits; ++i) {
306 if(amps[i] > 0 ) amplitude = amps[i];
307 else amplitude = 0.5*(threshold+signal[maxTimes[hitIndex+i]]);
308 gSum.SetParameter(3*i,amplitude);
309 gSum.SetParameter(1+3*i, maxTimes[hitIndex+i]);
310 gSum.SetParameter(2+3*i, fitWidth);
311 gSum.SetParLimits(3*i, 0.0, 3.0*amplitude);
312 gSum.SetParLimits(1+3*i, startT , endT);
313 gSum.SetParLimits(2+3*i, 0.0, 10.0*fitWidth);
317 gSum.SetParameters(signal[maxTimes[hitIndex]],maxTimes[hitIndex],fitWidth);
318 gSum.SetParLimits(0,0.0,1.5*signal[maxTimes[hitIndex]]);
319 gSum.SetParLimits(1, startT , endT);
320 gSum.SetParLimits(2,0.0,10.0*fitWidth);
324 hitSignal.Fit(&gSum,
"QNRW",
"", startT, endT);
325 for(
int hitNumber = 0; hitNumber < numHits; ++hitNumber) {
327 if(gSum.GetParameter(3*hitNumber) > threshold/2.0 &&
328 gSum.GetParameter(3*hitNumber+2) > minWidth) {
329 amplitude = gSum.GetParameter(3*hitNumber);
330 position = gSum.GetParameter(3*hitNumber+1);
331 width = gSum.GetParameter(3*hitNumber+2);
332 amplitudeErr = gSum.GetParError(3*hitNumber);
333 positionErr = gSum.GetParError(3*hitNumber+1);
334 widthErr = gSum.GetParError(3*hitNumber+2);
335 goodnessOfFit = gSum.GetChisquare()/(double)gSum.GetNDF();
336 int DoF = gSum.GetNDF();
339 chargeErr = std::sqrt(TMath::Pi())*(amplitudeErr*width+widthErr*amplitude);
343 for(
int sigPos = 0; sigPos < size; ++sigPos){
344 hitSig[sigPos] = amplitude*TMath::Gaus(sigPos+startT,position, width);
345 totSig += hitSig[(int)sigPos];
349 totSig = std::sqrt(2*TMath::Pi())*amplitude*width/
fAreaNorms[(size_t)sigType];
352 std::vector<geo::WireID> wids = geom->
ChannelToWire(channel);
371 (signal.begin() + (int) startT, signal.begin() + (int) endT, 0.),
382 hcol.emplace_back(
hit.move(), wire, rawdigits);
double fIndMinWidth
Minimum induction hit width.
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
double fMinSigInd
Induction signal height threshold.
double fIndWidth
Initial width for induction fit.
std::vector< geo::WireID > ChannelToWire(raw::ChannelID_t const channel) const
Returns a list of wires connected to the specified TPC channel.
int fMaxMultiHit
maximum hits for multi fit
double fColWidth
Initial width for collection fit.
SigType_t SignalType(geo::PlaneID const &pid) const
Returns the type of signal on the channels of specified TPC plane.
std::vector< double > fAreaNorms
factors for converting area to same units as peak height
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.
bool getByLabel(std::string const &label, std::string const &productInstanceName, 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.