26 #include "GaudiKernel/IToolSvc.h"
32 #include "G4Version.hh"
42 using CLHEP::Hep3Vector;
71 if (
first->position().mag2() <
second->position().mag2())
return true;
73 }
else if (
type ==
R) {
74 if (
first->position().perp2() <
second->position().perp2())
return true;
76 }
else if (
type ==
Z) {
77 if (
first->position().z() <
second->position().z())
return true;
85 :
AthAlgorithm(
name, pSvcLocator), m_stat_numshowers(0), m_stat_valid(0), m_stat_invalid(0), m_stat_nolib(0)
88 "max distance squared after which the hits will be truncated");
90 "energy border, that truncation won't cross");
92 "maximal radius squared until two hits will be combined");
94 "energy fraction that will be inside containment borders");
96 "List of files to read library structures from");
98 "the allowed amount of energy that can be deposited outside calorimeter region ");
109 std::vector< std::string >::const_iterator nameiter;
118 if (library ==
nullptr) {
119 ATH_MSG_WARNING (
"Library structure file " << (*nameiter) <<
" doesn't describe a valid library" );
123 std::stringstream location;
130 ATH_MSG_VERBOSE (
"Library named " << (*nameiter)+
".root" <<
"is stored at the location " << location.str() );
135 ATH_MSG_ERROR (
"No valid library structure files found. Further execution is pointless." );
136 return StatusCode::FAILURE;
141 return StatusCode::SUCCESS;
151 return StatusCode::FAILURE;
156 double fraction = eventStepsES->
invalid_energy/theParticle->momentum().e();
158 ATH_MSG_WARNING (
"Shower deposited too much energy outside the calorimeter region (" << (
int)(fraction*100) <<
"%), ignoring" );
160 return StatusCode::SUCCESS;
167 if (eventStepsES->
size()>500) {
174 for (ShowerLib::StepInfoList::const_iterator iter = eventSteps->begin();iter != eventSteps->end();++iter) {
175 etot += (*iter)->dep();
178 std::stringstream location;
180 location << eventStepsES->
detector <<
"/" << theParticle->pdg_id();
190 return StatusCode::SUCCESS;
193 Hep3Vector origin(theParticle->production_vertex()->position().x(),
194 theParticle->production_vertex()->position().y(),
195 theParticle->production_vertex()->position().z());
199 Hep3Vector DirectionShower(theParticle->momentum().px(),
200 theParticle->momentum().py(),
201 theParticle->momentum().pz());
202 DirectionShower /= DirectionShower.mag();
203 Hep3Vector OrthoShower = DirectionShower.orthogonal();
204 OrthoShower /= OrthoShower.mag();
205 Hep3Vector CrossShower = DirectionShower.cross(OrthoShower);
206 CrossShower /= CrossShower.mag();
210 Hep3Vector HitDir = (*i)->position() - origin;
212 (*i)->setX(HitDir*OrthoShower);
213 (*i)->setY(HitDir*CrossShower);
214 (*i)->setZ(HitDir*DirectionShower);
221 ATH_MSG_VERBOSE (
"Size after clusterization: " << eventSteps->size() );
223 if (eventSteps->size() > 10) {
228 double maxZ = 0, maxR = 0;
235 ShowerLib::StepInfoList::const_iterator iter = eventSteps->begin();
236 for (;(iter != eventSteps->end()) && (edep < containmentEnergy);++iter) {
237 edep += (*iter)->dep();
238 maxR = (*iter)->position().r();
244 iter = eventSteps->begin();
245 for (;(iter != eventSteps->end()) && (edep < containmentEnergy);++iter) {
246 edep += (*iter)->dep();
247 maxZ = (*iter)->position().z();
263 if ((*
m_libraries.find(location.str())).second->storeShower(theParticle, shower)) {
266 ATH_MSG_WARNING (
"Wasn't able to store shower (" << location.str() <<
")" );
272 return StatusCode::SUCCESS;
283 return !mcEvent->
at(0)->particles().empty() ? mcEvent->
at(0)->particles().back() :
nullptr;
285 return ( * (* mcEvent->
begin())->particles_end());
294 if (
evtStore()->
retrieve(eventStepsES,
"EventSteps").isFailure())
return nullptr;
307 rez->push_back(
copy);
317 const double dsame = 1.;
329 if ( (i1)->diff2(*i2) < dsame) {
344 typedef std::multimap<double,Dist> distMap;
351 for (ShowerLib::StepInfoList::reverse_iterator i_h2(stepinfo->rbegin()); (*i_h2) != (*i_h1); ++i_h2) {
352 distances.insert(distMap::value_type((*i_h1)->diff2(**i_h2),
Dist(*i_h1, *i_h2)));
358 int cursize = stepinfo->size();
361 while (cursize > 1) {
363 while ( !( (*iter).second.h1->valid() && (*iter).second.h2->valid() ) ) {
364 distances.erase(iter++);
367 if ((*iter).first > rmin )
break;
372 if ((*i_h1)->valid()){
373 distances.insert(distMap::value_type((*i_h1)->diff2(*mergedHit),
Dist(*i_h1, mergedHit)));
377 stepinfo->push_back(mergedHit);
387 i = stepinfo->erase(
i);
398 for (ShowerLib::StepInfoList::const_iterator
i(stepinfo->begin());
i != stepinfo->end(); ++
i) {
406 for (iterCut = stepinfo->begin(); (iterCut != stepinfo->end()) && (((*iterCut)->position().mag2() <
m_maxDistance) || (rsum < minEnergy));++iterCut) {
407 rsum += (*iterCut)->dep();
410 if (iterCut == stepinfo->end()) {
414 stepinfo->erase(iterCut,stepinfo->end());
420 const double inv_rsum = 1. / rsum;
421 for (iterCut = stepinfo->begin(); iterCut != stepinfo->end(); ++iterCut){
422 (*iterCut)->setE((*iterCut)->dep() * etot*inv_rsum);
429 char* atlasProject =
getenv(
"AtlasProject");
430 char* atlasVersion =
getenv(
"AtlasVersion");
431 std::string atlasReleaseTag = (atlasProject? std::string(atlasProject)+std::string(
"-") : std::string(
"Unknown-"));
433 atlasReleaseTag += std::string(atlasVersion);
436 atlasReleaseTag += std::string(
"Unknown");
442 (*itr).second->release(atlasReleaseTag);
446 (*itr).second->geometry(geoModelSvc->atlasVersion());
452 std::string g4Version = G4Version;
453 size_t pos = g4Version.find(
"$Name: ");
454 if (
pos != std::string::npos) {
455 g4Version.erase(
pos, 7);
457 pos = g4Version.find(
" $");
458 if (
pos != std::string::npos) {
459 g4Version.erase(
pos, 2);
461 (*itr).second->geantVersion(g4Version);
474 ATH_MSG_DEBUG (
"Writing shower library to file " << (*itr).first );
476 TFile libr((*itr).first.c_str(),
"RECREATE");
478 if (!(*itr).second->writeToROOT(&libr)) {
479 ATH_MSG_ERROR (
"Wasn't able to write " << (*itr).first <<
". Probably empty lib." );
485 ATH_MSG_DEBUG (
"********Statistics for GenShowerLib********" );
490 ATH_MSG_DEBUG (
"*******************************************" );
491 std::stringstream
ss((*itr).second->statistics());
496 ATH_MSG_DEBUG (
"*******************************************" );
501 return StatusCode::SUCCESS;
506 double&
weights,
double& xavfra,
double& yavfra,
double& ravfra)
509 double xav(0.), yav(0.), xav2(0.), yav2(0.);
512 escal += (*i)->dep();
513 xav += (*i)->x()*(*i)->dep();
514 yav += (*i)->y()*(*i)->dep();
515 xav2 += (*i)->x()*(*i)->x()*(*i)->dep();
516 yav2 += (*i)->y()*(*i)->y()*(*i)->dep();
522 const double inv_escal = 1. / escal;
523 xavfra = xav*inv_escal;
524 yavfra = yav*inv_escal;
526 ravfra = std::sqrt(std::abs((xav2*inv_escal-xavfra*xavfra) +
527 (yav2*inv_escal-yavfra*yavfra)));