19 #include "art_root_io/TFileService.h" 20 #include "art_root_io/TFileDirectory.h" 57 fTimeCut = p.
get<
double>(
"TimeCut");
58 fDistanceCut = p.
get<
double>(
"DistanceCut");
59 fDistanceCutClu = p.
get<
double>(
"DistanceCutClu");
75 double timeoffset[3]={10.4,5.2,0.0};
79 std::vector<art::Ptr<recob::Hit> > hitsUV;
80 std::vector<art::Ptr<recob::Hit> > hitsZ;
86 std::vector< recob::Hit > DisambiguatedHits;
92 for (
unsigned int Cstat=0; Cstat < geo->
Ncryostats(); ++Cstat){
93 for (
unsigned int APA=0; APA < geo->
Cryostat(Cstat).
NTPC()/2; ++APA){
97 for (
size_t i = 0; i<OrigHits.size(); ++i){
98 if (OrigHits[i]->
WireID().Cryostat==Cstat && (OrigHits[i]->WireID().TPC==APA*2 || OrigHits[i]->WireID().TPC==APA*2+1)){
102 hitsUV.push_back(OrigHits[i]);
104 hitsZ.push_back(OrigHits[i]);
111 double origin[3]={0.0,0.0,0.0};
112 double world[3]={0.0,0.0,0.0};
115 double xbound[2]={0,2000};
116 double ybound[2]= {0.0,0.0};
117 double zbound[2]= {0.0,0.0};
128 std::vector<HitPos> InductionAll;
129 InductionAll.clear();
133 for (
unsigned int uv0=0; uv0 < hitsUV.size(); ++uv0){
134 double PeakTimeMinusUV=hitsUV[uv0]->PeakTimePlusRMS(-1.)+timeoffset[1];
135 double PeakTimeUV=hitsUV[uv0]->PeakTime()+timeoffset[1];
137 PeakTimeMinusUV+=timeoffset[1];
138 PeakTimeUV+=timeoffset[1];
142 double ChargePerNum0=hitsUV[uv0]->Integral()/hitsUV[uv0]->Multiplicity();
147 double MeanPeakTimeUV=99999;
148 unsigned int ChannelUV1=0;
149 for (
unsigned int uv1=0; uv1 < hitsUV.size(); ++uv1){
150 double PeakTimeMinusUV1=hitsUV[uv1]->PeakTimePlusRMS(-1.)+timeoffset[1];
151 double PeakTimeUV1=hitsUV[uv1]->PeakTime()+timeoffset[1];
153 PeakTimeMinusUV1+=timeoffset[1];
154 PeakTimeUV1+=timeoffset[1];
156 double rChargeUV=hitsUV[uv0]->Integral()/hitsUV[uv1]->Integral();
157 double ChargePerNum1=hitsUV[uv1]->Integral()/hitsUV[uv1]->Multiplicity();
158 if (hitsUV[uv0]->Multiplicity()>0 && hitsUV[uv1]->Integral()>0) rChargeUV=ChargePerNum0/ChargePerNum1;
160 if (hitsUV[uv0]->
View()!=hitsUV[uv1]->
View() &&
161 fabs(PeakTimeMinusUV-PeakTimeMinusUV1)<MeanPeakTimeUV &&
162 fabs(PeakTimeUV-PeakTimeUV1)<20 &&
163 (rChargeUV<rmax && rChargeUV>(1/rmax)) ){
164 MeanPeakTimeUV=fabs(PeakTimeMinusUV-PeakTimeMinusUV1);
165 ChannelUV1=hitsUV[uv1]->Channel();
170 unsigned int ChannelUV0=hitsUV[uv0]->Channel();
171 double CandPosition[3]={0.0,0.0,0.0};
172 double FinalPosition[3]={0.0,0.0,0.0};
173 unsigned int FinalWireID=0;
174 double MinVertBetUVandZ=99999;
178 std::vector<geo::WireID> wireiduv0 = geo->
ChannelToWire(ChannelUV0);
179 std::vector<geo::WireID> wireiduv1 = geo->
ChannelToWire(ChannelUV1);
184 for (
unsigned int wireid0=0; wireid0 < wireiduv0.size(); ++wireid0){
186 double MinPeakTime=99999;
190 for (
unsigned int z=0;
z < hitsZ.size(); ++
z){
191 double PeakTimeMinusZ=hitsZ[
z]->PeakTimePlusRMS(-1.);
192 double PeakTimeZ=hitsZ[
z]->PeakTime();
193 double ChargePerNumZ=hitsZ[
z]->Integral()/hitsZ[
z]->Multiplicity();
194 double rChargeZ=hitsUV[uv0]->Integral()/hitsZ[
z]->Integral();
195 if (hitsUV[uv0]->Multiplicity()>0 && hitsZ[
z]->Integral()>0) rChargeZ=ChargePerNum0/ChargePerNumZ;
196 double vert[3]={0.0,0.0,0.0};
197 std::vector<geo::WireID> wires = geo->
ChannelToWire(hitsZ[
z]->Channel());
199 if (fabs(PeakTimeMinusUV-PeakTimeMinusZ)<MinPeakTime && fabs(PeakTimeUV-PeakTimeZ)<20 &&
200 (rChargeZ<rmax && rChargeZ>(1/rmax)) &&
201 wireiduv0[wireid0].TPC==wires[0].TPC){
202 MinPeakTime=fabs(PeakTimeMinusUV-PeakTimeMinusZ);
210 double VertPosMean=0;
212 unsigned int CollectionHits=0;
213 for (
unsigned int z=0;
z < hitsZ.size(); ++
z){
214 double PeakTimeMinusZ=hitsZ[
z]->PeakTimePlusRMS(-1.);
216 double ChargePerNumZ=hitsZ[
z]->Integral()/hitsZ[
z]->Multiplicity();
217 double rChargeZ=hitsUV[uv0]->Integral()/hitsZ[
z]->Integral();
218 if (hitsUV[uv0]->Multiplicity()>0 && hitsZ[
z]->Integral()>0) rChargeZ=ChargePerNum0/ChargePerNumZ;
219 double vert[3]={0.0,0.0,0.0};
220 std::vector<geo::WireID> wires = geo->
ChannelToWire(hitsZ[
z]->Channel());
222 if (fabs(fabs(PeakTimeMinusUV-PeakTimeMinusZ)-MinPeakTime)<10 &&
224 (rChargeZ<rmax && rChargeZ>(1/rmax)) &&
225 wireiduv0[wireid0].TPC==wires[0].TPC ){
227 VertPosMean+=vert[2];
228 RMS+=(VertPos-vert[2])*(VertPos-vert[2]);
231 VertPosMean=VertPosMean/double(CollectionHits);
232 RMS=RMS/double(CollectionHits);
238 for (
unsigned int wireid1=0; wireid1 < wireiduv1.size(); ++wireid1){
239 if (
abs(
int(wireid0)-
int(wireid1))<3 && wireiduv0[wireid0].TPC==wireiduv1[wireid1].TPC){
241 wireiduv0[wireid0].
Plane, wireiduv1[wireid1].Plane,
242 wireiduv0[wireid0].Cryostat, wireiduv0[wireid0].
TPC,
243 CandPosition[1], CandPosition[2]);
245 double VertBetUVandZ=fabs(VertPos-CandPosition[2]);
246 if (CandPosition[1]>=ybound[0] && CandPosition[1]<=ybound[1] && CandPosition[2]>=zbound[0] && CandPosition[2]<=zbound[1]){
247 if (VertBetUVandZ<MinVertBetUVandZ){
248 MinVertBetUVandZ=VertBetUVandZ;
251 FinalPosition[1]=CandPosition[1];
252 FinalPosition[2]=CandPosition[2];
277 double PeakTime=hitsUV[uv0]->PeakTime();
278 if (hitsUV[uv0]->
View()==
geo::kU) PeakTime+=timeoffset[0];
279 if (hitsUV[uv0]->
View()==
geo::kV) PeakTime+=timeoffset[1];
283 h.
Channel=hitsUV[uv0]->Channel();
288 h.
RMS=hitsUV[uv0]->RMS();
298 h.
View=hitsUV[uv0]->View();
300 h.
WireID=wireiduv0[FinalWireID];
303 h.
TPC=hitsUV[uv0]->WireID().TPC;
308 InductionAll.push_back(h);
322 unsigned int CellsPerTPC=BinPerPos*BinPerPos;
323 double TotalXbin=(xbound[1]-xbound[0])/
double(BinPerPos);
324 double TotalZbin=(zbound[1]-zbound[0])/
double(BinPerPos);
327 std::vector<TH1F *> YPosXZ(CellsPerTPC,0);
328 for (
unsigned int cell=0; cell<YPosXZ.size(); cell++){
329 YPosXZ[cell]=
new TH1F(Form(
"cell%d",cell),Form(
"cell%d",cell), 40, ybound[0], ybound[1]);
333 for (
unsigned int uv0=0; uv0 < InductionAll.size(); ++uv0){
334 int XbinForHit=
int( (InductionAll[uv0].PeakTime-xbound[0])/TotalXbin );
335 int ZbinForHit=
int( (InductionAll[uv0].FinalZPos-zbound[0])/TotalZbin );
336 if (InductionAll[uv0].PeakTime>xbound[1]) XbinForHit=BinPerPos-1;
337 if (InductionAll[uv0].FinalZPos<zbound[0]){
339 }
else if (InductionAll[uv0].FinalZPos>zbound[1]){
340 ZbinForHit=BinPerPos-1;
342 int BinForHit=XbinForHit*BinPerPos+ZbinForHit;
344 YPosXZ[BinForHit]->Fill(InductionAll[uv0].FinalYPos);
351 std::vector<double> FirstPeakXmin(CellsPerTPC,0);
352 std::vector<double> FirstPeakXmax(CellsPerTPC,0);
353 std::vector<double> ShouldCorrect(CellsPerTPC,0);
354 std::vector<double> SecondPeakXmin(CellsPerTPC,0);
355 std::vector<double> SecondPeakXmax(CellsPerTPC,0);
358 for (
unsigned int cell=0; cell<CellsPerTPC; cell++){
360 double HitsInFirstPeak=0;
363 if (HitsInFirstPeak<YPosXZ[cell]->GetBinContent(
bin+1)){
364 HitsInFirstPeak=YPosXZ[cell]->GetBinContent(
bin+1);
370 double PeakBinXmin=double(FirstPeakBin)*((ybound[1]-ybound[0])/40.0)+ybound[0]-10;
371 double PeakBinXmax=double(FirstPeakBin)*((ybound[1]-ybound[0])/40.0)+ybound[0]+10;
374 TF1 *YPosFitFirstPeak =
new TF1(
"YPosFitFirstPeak",
"gaus", PeakBinXmin, PeakBinXmax);
375 YPosFitFirstPeak->SetParameter(0, 100);
376 YPosFitFirstPeak->SetParameter(1, PeakBinXmin+10);
377 YPosFitFirstPeak->SetParameter(2, 0.1);
379 YPosXZ[cell]->Fit(
"YPosFitFirstPeak",
"Q",
"", PeakBinXmin-10, PeakBinXmax+10);
381 double FirstPeakBinAll=YPosFitFirstPeak->GetParameter(0);
382 double FirstPeakBinMean=YPosFitFirstPeak->GetParameter(1);
383 double FirstPeakBinRMS=YPosFitFirstPeak->GetParameter(2);
385 FirstPeakXmin[cell]=FirstPeakBinMean-fabs(FirstPeakBinRMS)*2;
386 FirstPeakXmax[cell]=FirstPeakBinMean+fabs(FirstPeakBinRMS)*2;
392 if (FirstPeakBinMean>(ybound[0]+ybound[1])*0.5){
393 SecondPeakXmin[cell]=FirstPeakXmin[cell]-100;
394 SecondPeakXmax[cell]=FirstPeakXmax[cell]-100;
395 }
else if (FirstPeakBinMean<(ybound[0]+ybound[1])*0.5){
396 SecondPeakXmin[cell]=FirstPeakXmin[cell]+100;
397 SecondPeakXmax[cell]=FirstPeakXmax[cell]+100;
402 TF1 *YPosFitSecondPeak =
new TF1(
"YPosFitSecondPeak",
"gaus", SecondPeakXmin[cell], SecondPeakXmax[cell]);
403 YPosFitSecondPeak->SetParameter(0, 100);
404 YPosFitSecondPeak->SetParameter(1, SecondPeakXmin[cell]+10);
405 YPosFitSecondPeak->SetParameter(2, 0.1);
407 YPosXZ[cell]->Fit(
"YPosFitSecondPeak",
"Q",
"", SecondPeakXmin[cell]-20, SecondPeakXmax[cell]+20);
409 double SecondPeakBinAll=YPosFitSecondPeak->GetParameter(0);
410 double SecondPeakBinMean=YPosFitSecondPeak->GetParameter(1);
411 double SecondPeakBinRMS=YPosFitSecondPeak->GetParameter(2);
413 SecondPeakXmin[cell]=SecondPeakBinMean-fabs(SecondPeakBinRMS)*4;
414 SecondPeakXmax[cell]=SecondPeakBinMean+fabs(SecondPeakBinRMS)*4;
421 ShouldCorrect[cell]=0;
422 if (FirstPeakBinAll>SecondPeakBinAll &&
424 SecondPeakBinAll>0 && SecondPeakBinAll!=100 &&
425 SecondPeakXmin[cell]>ybound[0] && SecondPeakXmax[cell]<ybound[1]){
426 ShouldCorrect[cell]=1;
430 YPosFitFirstPeak->Delete();
431 YPosFitSecondPeak->Delete();
432 YPosXZ[cell]->Delete();
440 for (
unsigned int uv0=0; uv0 < InductionAll.size(); ++uv0){
441 int XbinForHit=
int( (InductionAll[uv0].PeakTime-xbound[0])/TotalXbin );
442 int ZbinForHit=
int( (InductionAll[uv0].FinalZPos-zbound[0])/TotalZbin );
443 if (InductionAll[uv0].PeakTime>xbound[1]) XbinForHit=BinPerPos-1;
444 if (InductionAll[uv0].FinalZPos<zbound[0]){
446 }
else if (InductionAll[uv0].FinalZPos>zbound[1]){
447 ZbinForHit=BinPerPos-1;
449 int BinForHit=XbinForHit*BinPerPos+ZbinForHit;
453 std::vector<geo::WireID> wireiduv0 = geo->
ChannelToWire(InductionAll[uv0].Channel);
454 if (ShouldCorrect[BinForHit]!=0){
455 if (InductionAll[uv0].FinalYPos>SecondPeakXmin[BinForHit] &&
456 InductionAll[uv0].FinalYPos<SecondPeakXmax[BinForHit]){
457 InductionAll[uv0].FinalYPos+=InductionAll[uv0].FinalYPos+
458 (FirstPeakXmin[BinForHit]+FirstPeakXmax[BinForHit])*0.5-(SecondPeakXmin[BinForHit]+SecondPeakXmax[BinForHit])*0.5;
460 if (InductionAll[uv0].DisambigWireID>1){
461 InductionAll[uv0].DisambigWireID=InductionAll[uv0].DisambigWireID-2;
462 }
else if (InductionAll[uv0].DisambigWireID<2 && InductionAll[uv0].DisambigWireID+2<wireiduv0.size()){
463 InductionAll[uv0].DisambigWireID=InductionAll[uv0].DisambigWireID+2;
470 InductionAll[uv0].StartTick,
471 InductionAll[uv0].EndTick,
472 InductionAll[uv0].PeakTime,
473 InductionAll[uv0].SigmaPeakTime,
474 InductionAll[uv0].RMS,
475 InductionAll[uv0].PeakAmplitude,
476 InductionAll[uv0].SigmaPeakAmplitude,
477 InductionAll[uv0].SummedADC,
478 InductionAll[uv0].Integral,
479 InductionAll[uv0].SigmaIntegral,
480 InductionAll[uv0].Multiplicity,
481 InductionAll[uv0].LocalIndex,
482 InductionAll[uv0].GoodnessOfFit,
483 InductionAll[uv0].DegreesOfFreedom,
484 InductionAll[uv0].
View,
485 InductionAll[uv0].SignalType,
486 wireiduv0[InductionAll[uv0].DisambigWireID]);
488 DisambiguatedHits.push_back(hit);
unsigned int DisambigWireID
Encapsulate the construction of a single cyostat.
AdcChannelData::View View
WireGeo const & Wire(unsigned int iwire) const
std::vector< geo::WireID > ChannelToWire(raw::ChannelID_t const channel) const
Returns a list of wires connected to the specified TPC channel.
Planes which measure Z direction.
unsigned int Ncryostats() const
Returns the number of cryostats in the detector.
double Length() const
Length is associated with z coordinate [cm].
IDparameter< geo::WireID > WireID
Member type of validated geo::WireID parameter.
virtual void reconfigure(fhicl::ParameterSet const &pset)
geo::SigType_t SignalType
T get(std::string const &key) const
unsigned int NTPC() const
Number of TPCs in this cryostat.
CryostatGeo const & Cryostat(geo::CryostatID const &cryoid) const
Returns the specified cryostat.
bool IntersectionPoint(geo::WireID const &wid1, geo::WireID const &wid2, double &y, double &z) const
Returns the intersection point of two wires.
Encapsulate the geometry of a wire.
double HalfHeight() const
Height is associated with y coordinate [cm].
Declaration of signal hit object.
Encapsulate the construction of a single detector plane.
const TPCGeo & TPC(unsigned int itpc) const
Return the itpc'th TPC in the cryostat.
QTextStream & bin(QTextStream &s)
double SigmaPeakAmplitude
Declaration of basic channel signal object.
PlaneGeo const & Plane(geo::View_t view) const
Return the plane in the tpc with View_t view.
2D representation of charge deposited in the TDC/wire plane
void GetCenter(double *xyz, double localz=0.0) const
Fills the world coordinate of a point on the wire.
recob::tracking::Plane Plane
LArSoft geometry interface.
void LocalToWorld(const double *tpc, double *world) const
Transform point from local TPC frame to world frame.
constexpr Point origin()
Returns a origin position with a point of the specified type.
unsigned int Multiplicity
Encapsulate the construction of a single detector plane.