29 #include "Geant4/G4ThreeVector.hh" 30 #include "nug4/MagneticFieldServices/MagneticFieldService.h" 31 #include "nurandom/RandomUtils/NuRandomService.h" 32 #include "CLHEP/Random/RandGauss.h" 46 #include "CoreUtils/ServiceUtil.h" 47 #include "Geometry/GeometryCore.h" 115 fSmearX =
p.get<
float>(
"SmearX",0.3);
116 fSmearY =
p.get<
float>(
"SmearY",0.3);
117 fSmearT =
p.get<
float>(
"SmearT",1.0);
118 fPECm =
p.get<
float>(
"PeCm", 50.);
119 fSmearLY =
p.get<
float>(
"SmearLY", 10.0);
120 fThrPE =
p.get<
float>(
"ThrPE", 5.0);
121 fZCut1 =
p.get<
float>(
"ZCut1",10.0);
122 fZCut2 =
p.get<
float>(
"ZCut2",0.5);
123 fRCut =
p.get<
float>(
"RCut" ,5.0);
130 consumes<std::vector<gar::sdp::CaloDeposit> >(tpcedeptag);
131 consumes<std::vector<gar::sdp::CaloDeposit> >(muidedeptag);
132 if (fUseOnlyTrueMuonHits)
136 produces<std::vector<gar::rec::Track> >();
137 produces<std::vector<gar::rec::TPCCluster> >();
138 produces< art::Assns<gar::rec::TPCCluster, gar::rec::Track> >();
140 fGeo = gar::providerFrom<gar::geo::GeometryGAr>();
141 std::string fEncoding = fGeo->GetMinervaCellIDEncoding();
143 std::string fEncodingMuID = fGeo->GetMuIDCellIDEncoding();
146 fMu2e =
new TF1(
"mu2e_pe",
"[0] + [1]*x", 0, 600);
147 fMu2e->SetParameter(0, 50.);
148 fMu2e->SetParameter(1, -0.06);
154 std::unique_ptr< std::vector<gar::rec::TPCCluster> > TPCClusterCol(
new std::vector<gar::rec::TPCCluster>);
155 std::unique_ptr< std::vector<gar::rec::Track> > trkCol(
new std::vector<gar::rec::Track>);
156 std::unique_ptr< art::Assns<gar::rec::TPCCluster,gar::rec::Track> > TPCClusterTrkAssns(new ::art::Assns<gar::rec::TPCCluster,gar::rec::Track>);
159 auto tccdHandle = e.
getValidHandle< std::vector<gar::sdp::CaloDeposit> >(tpcedeptag);
160 auto const& tccds = *tccdHandle;
166 auto const *magFieldService = gar::providerFrom<mag::MagneticFieldService>();
167 G4ThreeVector zerovec(0,0,0);
168 G4ThreeVector magfield = magFieldService->FieldAtPoint(zerovec);
171 std::unordered_map<int, const simb::MCParticle * > TrkIDMap;
178 <<
"Attempting to identify muon hits without MC particles";
180 for (
auto const &mcp : *mcphandle)
182 TrkIDMap[mcp.TrackId()] = &mcp;
189 for (
auto const& cd : tccds)
191 const int trackid = cd.TrackID();
194 auto mcpt = TrkIDMap.find(trackid);
195 if (mcpt == TrkIDMap.end())
continue;
196 if (
std::abs(mcpt->second->PdgCode()) != 13)
continue;
201 float fcpos[3] = {0., 0., 0.};
206 float covmat[6] = {0,0,0,0,0,0};
208 if(energy <= 0.)
continue;
210 TPCClusterCol->emplace_back(energy,
222 auto muIDHandle = e.
getValidHandle< std::vector<gar::sdp::CaloDeposit> >(muidedeptag);
223 auto const& muids = *muIDHandle;
225 for (
auto const& cd : muids)
228 const int trackid = cd.TrackID();
231 auto mcpt = TrkIDMap.find(trackid);
232 if (mcpt == TrkIDMap.end())
continue;
233 if (
std::abs(mcpt->second->PdgCode()) != 13)
continue;
238 float fcpos[3] = {0., 0., 0.};
243 if(energy <= 0.)
continue;
245 float covmat[6] = {0,0,0,0,0,0};
247 TPCClusterCol->emplace_back(energy,
263 std::vector<std::vector<gar::rec::TPCCluster>> TPCClusterColTime;
264 std::vector<gar::rec::TPCCluster> TPCClusterColTimeBlock;
265 std::sort(TPCClusterCol->begin(),TPCClusterCol->end(),
267 {
return a.
Time() <
b.Time(); } );
268 size_t ntpcclus = TPCClusterCol->size();
270 if (ntpcclus!=0&&debug) std::cout<<
"Time start and end: "<<TPCClusterCol->at(0).Time()<<
" "<<TPCClusterCol->at(TPCClusterCol->size()-1).Time()<<
std::endl;
275 startt=TPCClusterCol->at(0).Time();
276 for(
size_t i=0; i<ntpcclus; i++)
279 if(TPCClusterCol->at(i).Time()-startt<=
fTimeBunch)
281 TPCClusterColTimeBlock.push_back(TPCClusterCol->at(i));
285 TPCClusterColTime.push_back(TPCClusterColTimeBlock);
286 startt=TPCClusterCol->at(i).Time();
287 TPCClusterColTimeBlock.clear();
288 TPCClusterColTimeBlock.push_back(TPCClusterCol->at(i));
293 if(TPCClusterColTimeBlock.size()!=0) TPCClusterColTime.push_back(TPCClusterColTimeBlock);
299 for(
size_t c=0;
c<TPCClusterColTime.size();
c++)
302 std::cout <<
"l"<<
c<<
" = { ";
303 for (
size_t d=0;
d<TPCClusterColTime.at(c).size();
d++) {
304 std::cout << TPCClusterColTime.at(c).at(
d).Time() <<
", ";
311 for(
size_t t=0;
t<TPCClusterColTime.size();
t++)
315 std::sort(TPCClusterColTime.at(
t).begin(),TPCClusterColTime.at(
t).end(),
317 {
return a.
Position()[2] <
b.Position()[2]; } );
320 size_t ntpcclust = TPCClusterColTime.at(
t).size();
329 std::list<size_t> unusedTPC;
330 std::list<size_t> TPCplane;
331 std::vector<std::list<size_t>> unusedTPCplanes;
337 startz=TPCClusterColTime.at(
t).at(0).Position()[2];
338 for(
size_t i=0; i<ntpcclust; i++)
340 unusedTPC.push_back(i);
342 if(TPCClusterColTime.at(
t).at(i).Position()[2]-startz<=fZCut3)
344 TPCplane.push_back(i);
348 unusedTPCplanes.push_back(TPCplane);
349 startz=TPCClusterColTime.at(
t).at(i).Position()[2];
351 TPCplane.push_back(i);
356 if(TPCplane.size()!=0) unusedTPCplanes.push_back(TPCplane);
360 for(
size_t i=0; i<ntpcclust; i++)
362 unusedTPC.push_back(i);
367 std::cout <<
"Plane division: p = { ";
368 for (
size_t n : unusedTPC) {
369 std::cout << TPCClusterColTime.at(
t).at(
n).Time() <<
", ";
373 for(
size_t c=0;
c<unusedTPCplanes.size();
c++)
375 std::cout <<
"p"<<
c<<
" = { ";
376 for (
size_t n : unusedTPCplanes.at(c)) {
377 std::cout << TPCClusterColTime.at(
t).at(
n).Time() <<
", ";
389 std::vector<size_t> besttpcclusindex;
391 for (
size_t i=0; i<unusedTPCplanes.size(); ++i)
393 for (
size_t it : unusedTPCplanes.at(i))
396 for (
size_t j=i+1; j<unusedTPCplanes.size(); ++j)
398 for (
size_t jt : unusedTPCplanes.at(j))
402 for (
size_t k=j+1;
k<unusedTPCplanes.size(); ++
k)
404 for (
size_t kt : unusedTPCplanes.at(
k))
408 std::vector<gar::rec::TPCCluster> triplet;
409 triplet.push_back(TPCClusterCol->at(it));
410 triplet.push_back(TPCClusterCol->at(jt));
411 triplet.push_back(TPCClusterCol->at(kt));
417 std::vector<size_t> tpcclusindex;
421 int tpcclusindexb = -1;
426 for (
size_t kt2 : unusedTPC)
428 const float *k2pos = TPCClusterCol->at(kt2).Position();
432 if ((TMath::Abs(zcur - k2pos[2]) >
fZCut2) &&
433 (tpcclusindexb > -1) &&
436 tpcclusindex.push_back(tpcclusindexb);
438 sumr2 += dbest*dbest;
447 if (retcode != 0)
continue;
448 if (dist >
fRCut)
continue;
455 if (kt2 == *std::prev(unusedTPC.end(),1) && tpcclusindexb > -1)
457 tpcclusindex.push_back(tpcclusindexb);
458 sumr2 += dbest*dbest;
462 if (tpcclusindex.size() > bestnpts ||
463 ((tpcclusindex.size() == bestnpts) &&
464 (sumr2 < bestsumr2)))
466 bestnpts = tpcclusindex.size();
468 besttpcclusindex = tpcclusindex;
477 for(
size_t i=0;i<bestnpts;i++)
479 unusedTPC.remove(besttpcclusindex.at(i));
480 for(
size_t j=0;j<unusedTPCplanes.size();j++)
482 unusedTPCplanes.at(j).remove(besttpcclusindex.at(i));
488 std::cout<<
"bestnpts: "<<bestnpts<<
std::endl;
489 for(
size_t j=0;j<unusedTPCplanes.size();j++)
491 std::cout<<
"unusedTPCplane"<<j<<
" : "<<unusedTPCplanes.at(j).size()<<
std::endl;
493 std::cout<<
"unusedTPC: "<<unusedTPC.size()<<std::endl<<
std::endl;
500 std::vector<gar::rec::TPCCluster> tcv;
501 for (
size_t i=0;i<besttpcclusindex.size(); ++i)
503 tcv.push_back(TPCClusterCol->at(besttpcclusindex.at(i)));
509 trkCol->push_back(btt);
511 auto const trackpointer = trackPtrMaker(trkCol->size()-1);
512 for (
size_t i=0; i<besttpcclusindex.size(); ++i)
514 auto const tpccluspointer = tpcclusPtrMaker(besttpcclusindex.at(i));
515 TPCClusterTrkAssns->addSingle(tpccluspointer,trackpointer);
521 if (debug) std::cout<<
"Not able to find a new track, stop cycle, done="<<done<<
std::endl;
545 CLHEP::RandGauss GaussRand(
fEngine);
559 fcpos[0] += GaussRand.fire(0.,
fSmearX);
564 fcpos[1] += GaussRand.fire(0.,
fSmearY);
567 time += GaussRand.fire(0.,
fSmearT);
571 energy += GaussRand.fire(0.,
fSmearLY);
573 if(energy <
fThrPE) energy = 0.;
584 CLHEP::RandGauss GaussRand(
fEngine);
598 fcpos[0] += GaussRand.fire(0.,
fSmearX);
603 fcpos[1] += GaussRand.fire(0.,
fSmearY);
606 time += GaussRand.fire(0.,
fSmearT);
610 double local_distance = 0.;
611 std::array<double, 3> point = {cd.
X(), cd.
Y(), cd.
Z()};
612 std::array<double, 3> pointLocal;
615 TVector3 tpoint(point[0], point[1], point[2]);
620 local_distance = 300. - pointLocal[0];
625 local_distance = 300. - pointLocal[1];
628 energy =
fMu2e->Eval(local_distance);
634 energy += GaussRand.fire(0.,
fSmearLY);
636 if(energy <
fThrPE) energy = 0.;
655 float fSortTransWeight = 1.0;
656 int fInitialTPNTPCClusters = 100;
657 float fSortDistBack = 2.0;
660 float lengthforwards = 0;
661 std::vector<int> hlf;
662 float lengthbackwards = 0;
663 std::vector<int> hlb;
667 std::vector<float> tparbeg(6,0);
670 tparbeg[3], tparbeg[5], tparbeg[0], tparbeg[1], xother, fInitialTPNTPCClusters, fPrintLevel) != 0)
674 float chisqforwards = 0;
675 float tvpos[3] = {tparbeg[5],tparbeg[0],tparbeg[1]};
676 for (
size_t i=0; i<trackTPCClusters.size(); ++i)
679 const float *
pos = trackTPCClusters.at(i).Position();
687 std::vector<float> tparend(6,0);
689 tparend[3], tparend[5], tparend[0], tparend[1], xother, fInitialTPNTPCClusters, fPrintLevel) != 0)
693 float chisqbackwards = 0;
694 float tepos[3] = {tparend[5],tparend[0],tparend[1]};
695 for (
size_t i=0; i<trackTPCClusters.size(); ++i)
698 const float *
pos = trackTPCClusters.at(i).Position();
710 for (
size_t i=0; i<25; ++i)
void setNTPCClusters(const size_t nTPCClusters)
base_engine_t & createEngine(seed_t seed)
void setLengthForwards(const float lengthforwards)
float fZCut1
Cut to ensure TPC Clusters are on different planes.
bool WorldToLocal(std::array< double, 3 > const &world, std::array< double, 3 > &local, gar::geo::LocalTransformation< TGeoHMatrix > &trans) const
float const & Time() const
CLHEP::HepRandomEngine & fEngine
const float * TrackParBeg() const
void setCovMatBeg(const float *covmatbeg)
Handle< PROD > getHandle(SelectorBase const &) const
dayoneconverter(fhicl::ParameterSet const &p)
EDProducer(fhicl::ParameterSet const &pset)
gar::geo::BitFieldCoder * fFieldDecoderTrk
static int DistXYZ(const float *trackpar, const float *Xpoint, const float *xyz, float &retDist)
Description of geometry of one entire detector.
void setLengthBackwards(const float lengthbackwards)
bool fUseOnlyTrueMuonHits
whether to cheat and use true muon hits
float fRCut
Road in the YZ plane to add hits on a circle.
float fTimeBunch
Time bunch spread, in ns.
float fSmearY
amount by which to smear Y, in cm
std::string fInputEdepInstanceTPC
Input instance for TPC edeps.
gar::geo::BitFieldCoder * fFieldDecoderMuID
float const & Energy() const
float fSmearLY
amount by which to smear the LY
void setTrackParametersBegin(const float *tparbeg)
std::string fInputEdepLabel
Input label for edeps.
float fThrPE
threshold cut in pe
const float * Vertex() const
#define DEFINE_ART_MODULE(klass)
void digitizeCaloHitsSimple(gar::sdp::CaloDeposit cd, float *fcpos, float &energy, float &time)
void produce(art::Event &e) override
Helper class for decoding and encoding a bit field of 64bits for convenient declaration.
void setXEnd(const float xend)
void setTrackParametersEnd(const float *tparend)
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
float fSmearT
amount by which to smear T, in ns
ProductID put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
void setChisqBackwards(const float chisqbackwards)
std::string fG4ModuleLabel
Use this to get the MCParticles.
raw::CellID_t const & CellID() const
gar::rec::Track CreateTrack()
float fSmearX
amount by which to smear X, in cm
Interface to propagate a Track to the specific point.
bool fIncludeMuIDhits
Include MuID hits as TPCClusters.
General GArSoft Utilities.
std::string fInputEdepInstanceMuID
Input instance for MuID edeps.
long64 get(long64 bitfield, size_t index) const
float fPECm
conversion factor from cm step length to pe
void setCovMatEnd(const float *covmatend)
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
void sort_TPCClusters_along_track(const std::vector< gar::rec::TPCCluster > &TPCClusters, std::vector< int > &hlf, std::vector< int > &hlb, int printlevel, float &lengthforwards, float &lengthbackwards, float sorttransweight, float sortdistback)
void setXBeg(const float xbeg)
dayoneconverter & operator=(dayoneconverter const &)=delete
const std::string VolumeName(TVector3 const &point) const
Returns the name of the deepest volume containing specified point.
void setChisqForwards(const float chisqforwards)
const float * Position() const
const gar::geo::GeometryCore * fGeo
geometry information
void digitizeCaloHitsMu2e(gar::sdp::CaloDeposit cd, float *fcpos, float &energy, float &time)
int makepatrectrack(std::vector< gar::rec::TPCCluster > &trackTPCClusters, gar::rec::TrackPar &trackpar)
art framework interface to geometry description
void setTime(const double time)
float const & StepLength() const
float fZCut2
Cut to ensure TPC clusters are on the same plane.
cet::coded_exception< error, detail::translate > exception
QTextStream & endl(QTextStream &s)
int initial_trackpar_estimate(const std::vector< gar::rec::TPCCluster > &TPCClusters, std::vector< int > &TPCClusterlist, float &curvature_init, float &lambda_init, float &phi_init, float &xpos, float &ypos, float &zpos, float &x_other_end, unsigned int initialtpnTPCClusters, int printlevel)