30 #include "art_root_io/TFileService.h" 48 const std::vector<sim::SimEnergyDeposit> & dep_vec,
49 const sim::ParticleList & plist);
53 const sim::ParticleList & plist);
56 return (KE + part->
Mass())/part->
Mass();
60 return sqrt(1. - 1./(
gamma(KE, part)*
gamma(KE, part)));
68 double dedx = (rho*K*Z/
A);
69 dedx /= (
beta(KE, part)*
beta(KE, part));
70 double post_factor = .5*log(2*me*(
beta(KE, part)*
beta(KE, part))*(
gamma(KE, part)*
gamma(KE, part))*
Tmax(KE, part)/(I*I));
71 post_factor -=
beta(KE, part)*
beta(KE, part);
77 return (K/2)*(Z/
A)*(p*rho/(
beta(KE, part)*
beta(KE, part)))*(log(2*me*
beta(KE, part)*
beta(KE, part)*
gamma(KE, part)*
gamma(KE, part)/I) + log((K/2)*(Z/A)*p*rho/(
beta(KE, part)*
beta(KE, part)*I)) + .2 -
beta(KE, part)*
beta(KE, part));
90 E0 -=
MPV(E0 - 1.e3*part->
Mass(),
p, part);
98 const std::vector<sim::SimEnergyDeposit> & dep_vec,
99 const sim::ParticleList & plist) {
104 std::map<size_t, double> results;
105 for (
size_t i = 0; i < traj.
size() - 1; ++i) {
109 std::map<size_t, std::vector<int>> daughters_by_traj
114 if (dep.TrackID() == id) {
115 for (
size_t i = 1; i < traj.
size(); ++i) {
116 if (traj.
Z(i-1) <= dep.MidPointZ() && traj.
Z(i) > dep.MidPointZ()) {
117 results[i-1] += dep.Energy();
123 for (
auto it = daughters_by_traj.begin();
124 it != daughters_by_traj.end(); ++it) {
125 for (
size_t i = 0; i < it->second.size(); ++i) {
126 if (it->second[i] == dep.TrackID()) {
127 results[it->first] += dep.Energy();
138 const sim::ParticleList & plist) {
141 std::map<size_t, std::vector<int>> results;
145 auto daughter = plist[id];
148 if ((process.find(
"Ioni") == std::string::npos) &&
149 (process.find(
"Brem") == std::string::npos) &&
150 (process.find(
"annihil") == std::string::npos)) {
154 for (
size_t j = 1; j < traj.
size(); ++j) {
155 if (traj.
Z(j-1) < daughter->Position().Z() &&
156 daughter->Position().Z() < traj.
Z(j)) {
158 std::deque<int> downstream;
159 downstream.push_back(
id);
162 while (!downstream.empty()) {
163 int d_id = downstream.front();
164 auto d_part = plist[d_id];
165 results[j-1].push_back(d_id);
166 for (
int k = 0;
k < d_part->NumberDaughters(); ++
k) {
167 downstream.push_back(d_part->Daughter(
k));
169 downstream.pop_front();
222 fView(
p.get<
int>(
"View")),
232 const sim::ParticleList & plist = pi_serv->
ParticleList();
237 if (!true_beam_particle)
return;
247 int true_beam_ID = true_beam_particle->
TrackId();
254 double total_d_edep = 0.;
256 std::deque<int> to_check;
257 std::vector<const sim::IDE *> daughter_IDEs;
259 int id = true_beam_particle->
Daughter(i);
260 auto part = plist[id];
262 if ((process.find(
"Ioni") == std::string::npos) &&
263 (process.find(
"Brem") == std::string::npos) &&
264 (process.find(
"annihil") == std::string::npos)) {
265 std::cout <<
"Skipping " << process <<
std::endl;
269 to_check.push_back(
id);
272 while (!to_check.empty()) {
273 const int id = to_check.front();
274 to_check.pop_front();
276 std::vector<const sim::IDE *> ides
278 daughter_IDEs.insert(daughter_IDEs.end(), ides.begin(), ides.end());
280 for (
size_t i = 0; i < ides.size(); ++i) {
281 total_d_edep += ides[i]->energy;
285 auto part = plist[id];
286 std::cout <<
id <<
" Has daughters: ";
287 for (
int i = 0; i < part->NumberDaughters(); ++i) {
288 to_check.push_back(part->Daughter(i));
289 std::cout << part->Daughter(i) <<
" ";
305 std::sort(view2_IDEs.begin(), view2_IDEs.end(),
308 double ide_z = (view2_IDEs.size() ? view2_IDEs[0]->z : -999.);
310 std::cout <<
"First IDE: " << ide_z <<
std::endl;
312 for (
size_t i = 0; i < view2_IDEs.size(); ++i) {
313 std::cout << i <<
" " << view2_IDEs[i]->z <<
std::endl;
316 std::sort(daughter_IDEs.begin(), daughter_IDEs.end(),
318 if (daughter_IDEs.size())
319 std::cout <<
"First daughter IDE: " << daughter_IDEs[0]->
z << std::endl;
322 std::map<size_t, unsigned char> proc_map(true_beam_procs.begin(),
323 true_beam_procs.end());
325 size_t first_point_in_TPC = 0;
326 for (
size_t i = 1; i < true_beam_trajectory.
size(); ++i) {
327 double z0 = true_beam_trajectory.
Z(i-1);
328 double x0 = true_beam_trajectory.
X(i-1);
329 double y0 = true_beam_trajectory.
Y(i-1);
331 const TGeoMaterial * mat = geom->Material(test_point);
332 std::cout <<
"Point " << i-1 <<
" (" << x0 <<
", " << y0 <<
333 ", " << z0 <<
") Material " << mat->GetName() <<
" " <<
334 (proc_map.find(i-1) != proc_map.end() ?
336 "") <<
" " << 1.e3*true_beam_trajectory.
E(i-1) <<
339 (proc_map.find(i-1) != proc_map.end() ?
343 if (mat_name ==
"LAr" && proc_name ==
"Transportation") {
344 first_point_in_TPC = i-1;
345 std::cout <<
"Found first point " << first_point_in_TPC <<
std::endl;
347 if (view2_IDEs.size()) {
348 double z1 = true_beam_trajectory.
Z(i);
349 double x1 = true_beam_trajectory.
X(i);
350 double y1 = true_beam_trajectory.
Y(i);
351 if (z0 < ide_z && z1 > ide_z) {
353 const TGeoMaterial * mat1 = geom->Material(test_point_1);
354 init_KE = 1.e3 * true_beam_trajectory.
E(i-1);
355 std::cout <<
"Found matching position " << z0 <<
" " << ide_z <<
356 " " << z1 <<
" Material " << mat1->GetName() <<
std::endl;
357 std::cout <<
"init KE: " << init_KE <<
std::endl;
360 std::cout <<
"energies: " << 1.e3 * true_beam_trajectory.
E(i-1) <<
361 " " << 1.e3 * true_beam_trajectory.
E(i) <<
std::endl;
362 std::cout <<
"Second to last, last point -- (Z, E): " <<
"(" <<
363 true_beam_trajectory.
Z(true_beam_trajectory.
size()-2) <<
", " <<
364 1.e3*true_beam_trajectory.
E(true_beam_trajectory.
size()-2) <<
"), (" <<
365 true_beam_trajectory.
Z(true_beam_trajectory.
size()-1) <<
", " <<
366 1.e3*true_beam_trajectory.
E(true_beam_trajectory.
size()-1) <<
")" <<
376 true_beam_trajectory.
E(true_beam_trajectory.
size() - 2));
381 for (
size_t i = 0; i < true_beam_trajectory.
size(); ++i) {
382 std::cout <<
"Z, E: " << true_beam_trajectory.
Z(i) <<
" " <<
389 if (view2_IDEs.size()) {
391 double total_edep = 0.;
392 for (
size_t i = 0; i < view2_IDEs.size(); ++i) {
393 total_edep += view2_IDEs[i]->energy;
399 std::cout <<
"Total edep: " << total_edep <<
std::endl;
400 std::cout <<
"From daughters: " << total_d_edep <<
std::endl;
401 std::cout <<
"Combined: " << total_edep + total_d_edep <<
std::endl;
403 std::cout <<
"DeltaE: " << init_KE - (1.e3*true_beam_trajectory.
E(true_beam_trajectory.
size()-2)) <<
std::endl;
404 std::cout <<
"IDE - traj: " << total_edep + total_d_edep - (init_KE - (1.e3*true_beam_trajectory.
E(true_beam_trajectory.
size()-2))) << std::endl;
405 std::cout <<
"Energies: " << (1.e3*true_beam_trajectory.
E(0)) <<
" " << init_KE <<
" " <<
406 (1.e3*true_beam_trajectory.
E(true_beam_trajectory.
size()-2)) <<
" " << (1.e3*true_beam_trajectory.
E(true_beam_trajectory.
size()-1))
412 for (
auto it = true_beam_procs.begin();
413 it != true_beam_procs.end(); ++it) {
414 if (true_beam_trajectory.
KeyToProcess(it->second) ==
"hadElastic") {
418 std::cout <<
"N Elastics " << n_elast <<
std::endl;
424 double total_sim_edep = 0.;
427 if (dep.TrackID() != true_beam_ID)
continue;
428 total_sim_edep += dep.Energy();
429 if (dep.MidPointZ() < dep_min_z) dep_min_z = dep.StartZ();
431 std::cout <<
"Min dep z: " << dep_min_z <<
std::endl;
435 int id = true_beam_particle->
Daughter(i);
436 auto part = plist[id];
438 if ((process.find(
"Ioni") == std::string::npos) &&
439 (process.find(
"Brem") == std::string::npos) &&
440 (process.find(
"annihil") == std::string::npos)) {
441 std::cout <<
"Skipping " << process <<
std::endl;
444 to_check.push_back(
id);
447 while (!to_check.empty()) {
448 const int id = to_check.front();
449 to_check.pop_front();
452 if (dep.TrackID() != id)
continue;
453 total_sim_edep += dep.Energy();
457 auto part = plist[id];
458 for (
int i = 0; i < part->NumberDaughters(); ++i) {
459 to_check.push_back(part->Daughter(i));
464 size_t first_point = 0;
465 for (
size_t i = 1; i < true_beam_trajectory.
size(); ++i) {
466 double z0 = true_beam_trajectory.
Z(i-1);
467 double x0 = true_beam_trajectory.
X(i-1);
468 double y0 = true_beam_trajectory.
Y(i-1);
470 const TGeoMaterial * mat = geom->Material(test_point);
471 double z1 = true_beam_trajectory.
Z(i);
472 std::cout <<
"checking " << z0 <<
" " << dep_min_z <<
" " << z1 <<
" " <<
473 1.e3*(true_beam_trajectory.
E(i-1) -
474 true_beam_trajectory.
E(true_beam_trajectory.
size()-2)) <<
476 if (z0 <= dep_min_z && z1 > dep_min_z) {
478 init_KE = 1.e3 * true_beam_trajectory.
E(i-1);
479 std::cout <<
"Found matching position " << z0 <<
" " << dep_min_z <<
480 " " << z1 <<
" " << mat->GetName() <<
std::endl;
481 std::cout <<
"init KE: " << init_KE <<
std::endl;
484 std::cout <<
"energies: " << 1.e3 * true_beam_trajectory.
E(i-1) <<
485 " " << 1.e3 * true_beam_trajectory.
E(i) <<
std::endl;
486 std::cout <<
"Second to last, last point -- (Z, E): " <<
"(" <<
487 true_beam_trajectory.
Z(true_beam_trajectory.
size()-2) <<
", " <<
488 1.e3*true_beam_trajectory.
E(true_beam_trajectory.
size()-2) <<
"), (" <<
489 true_beam_trajectory.
Z(true_beam_trajectory.
size()-1) <<
", " <<
490 1.e3*true_beam_trajectory.
E(true_beam_trajectory.
size()-1) <<
")" <<
495 std::cout <<
"SimEDep Delta E: " << init_KE - 1.e3*true_beam_trajectory.
E(true_beam_trajectory.
size()-2) << std::endl;
496 std::cout <<
"SimEDep Diff: " <<
497 total_sim_edep - (init_KE - 1.e3*true_beam_trajectory.
E(true_beam_trajectory.
size()-2)) <<
" " <<
498 (total_sim_edep - (init_KE - 1.e3*true_beam_trajectory.
E(true_beam_trajectory.
size()-2)))/total_sim_edep << std::endl;
500 std::map<size_t, double> edep_by_traj
501 =
GetEDepByTraj(true_beam_particle, true_beam_ID, (*sim_edep_vec), plist);
502 for (
auto it = edep_by_traj.begin(); it != edep_by_traj.end(); ++it) {
503 if (it->second == 0.)
continue;
504 std::cout << it->second <<
" " <<
505 1.e3*(true_beam_trajectory.
E(it->first) -
506 true_beam_trajectory.
E(it->first + 1)) << std::endl;
509 std::cout <<
"First Point: " << first_point <<
" " <<
510 true_beam_trajectory.
Z(first_point) <<
std::endl;
512 for (
size_t i = first_point; i < true_beam_trajectory.
size() - 2; ++i) {
513 std::cout << (true_beam_trajectory.
Position(i+1) -
515 total += (true_beam_trajectory.
Position(i+1) -
516 true_beam_trajectory.
Position(i)).Vect().Mag();
518 std::cout <<
"Total len in LAr: " << total <<
std::endl;
520 double pitch = geom->WirePitch( 2, 1, 0);
523 1.e3*true_beam_trajectory.
E(first_point),
524 1.e3*true_beam_trajectory.
E(true_beam_trajectory.
size() - 2),
527 std::cout <<
"Slices: " << slices.size() <<
" " << slices.size() * pitch <<
532 std::cout <<
"can't get sim edep. Moving on" <<
std::endl;
561 fTree = tfs->make<TTree>(
"beamana",
"beam analysis tree");
art::InputTag fSimEDepTag
double Z(const size_type i) const
double X(const size_type i) const
float z
z position of ionization [cm]
double beta(double KE, const simb::MCParticle *part)
const simb::MCParticle * GetGeantGoodParticle(const simb::MCTruth &genTruth, const art::Event &evt) const
std::map< size_t, double > GetEDepByTraj(const simb::MCParticle *part, int id, const std::vector< sim::SimEnergyDeposit > &dep_vec, const sim::ParticleList &plist)
const TLorentzVector & EndPosition() const
double E(const size_type i) const
enum geo::_plane_proj View_t
Enumerate the possible plane projections.
const simb::MCTrajectory & Trajectory() const
TruthAnalyzer(fhicl::ParameterSet const &p)
std::string KeyToProcess(unsigned char const &key) const
std::map< size_t, std::vector< int > > GetEMDaughterByTraj(const simb::MCParticle *part, const sim::ParticleList &plist)
double MPV(double KE, double p, const simb::MCParticle *part)
std::vector< const sim::IDE * > TrackIdToSimIDEs_Ps(int const &id) const
EDAnalyzer(fhicl::ParameterSet const &pset)
std::vector< double > true_traj_Y
int NumberDaughters() const
double dEdX(double KE, const simb::MCParticle *part)
art framework interface to geometry description
int Daughter(const int i) const
std::vector< double > true_traj_X
double Y(const size_type i) const
art::InputTag fGeneratorTag
#define DEFINE_ART_MODULE(klass)
std::string EndProcess() const
Ionization at a point of the TPC sensitive volume.
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
SubRunNumber_t subRun() const
TruthAnalyzer & operator=(TruthAnalyzer const &)=delete
static int max(int a, int b)
double gamma(double KE, const simb::MCParticle *part)
const TLorentzVector & Position(const size_type) const
The accessor methods described above.
ProcessMap const & TrajectoryProcesses() const
std::vector< TCSlice > slices
void analyze(art::Event const &e) override
const sim::ParticleList & ParticleList() const
std::vector< double > true_traj_Z
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
contains information for a single step in the detector simulation
Energy deposition in the active material.
EventNumber_t event() const
std::vector< int > MakeSlices(double E0, double Ef, double p, const simb::MCParticle *part)
std::vector< double > true_traj_E
double Tmax(double KE, const simb::MCParticle *part)
cet::coded_exception< error, detail::translate > exception
QTextStream & endl(QTextStream &s)
Event finding and building.