24 #include "G4ThreeVector.hh"
25 #include "G4StepPoint.hh"
28 #include "G4AffineTransform.hh"
29 #include "G4NavigationHistory.hh"
30 #include "G4VTouchable.hh"
31 #include "G4TouchableHistory.hh"
36 #include "GaudiKernel/ISvcLocator.h"
37 #include "GaudiKernel/Bootstrap.h"
51 , m_geometry(
"LArBarrelGeometry",
name)
70 ATH_MSG_DEBUG(
"LArBarrelCalculator: Beginning construction ");
72 declareProperty(
"GeometryCalculator",
m_geometry);
77 declareProperty(
"EMBdstep",
m_dstep);
78 declareProperty(
"EMBHVEnable",
m_doHV);
83 ATH_MSG_DEBUG(
"LArBarrelCalculator: Beginning initialization ");
85 const double Birks_LAr_density = 1.396;
120 +
parameters->GetValue(
"LArEMBThickElecKapton"));
137 ATH_MSG_DEBUG(
" LArBarrelCalculator: start reading of current maps");
142 ATH_MSG_DEBUG(
" LArBarrelCalculator: end of reading current maps");
156 if(
m_IflCur)
ATH_MSG_DEBUG(
" LArBarrelCalculator: Deposited Energy dE/dX Corrected ==> CURRENT Option ON");
157 else ATH_MSG_DEBUG(
" LArBarrelCalculator: Crude Deposited Energy dE/dX NO CURRENT option");
159 else ATH_MSG_DEBUG(
" LArBarrelCalculator: Ignore effect of E field around eta=0.8 ");
170 return StatusCode::SUCCESS;
177 return StatusCode::SUCCESS;
191 G4double thisStepEnergyDeposit =
step->GetTotalEnergyDeposit() *
step->GetTrack()->GetWeight();
195 ATH_MSG_DEBUG(
"****** LArBarrelCalculator: Step energy,length "
196 << thisStepEnergyDeposit <<
" " << thisStepLength);
199 if(thisStepEnergyDeposit <= 0. || thisStepLength <= 0.)
208 G4StepPoint *thisStepPoint =
step->GetPreStepPoint();
209 G4StepPoint *thisStepBackPoint =
step->GetPostStepPoint();
210 G4ThreeVector startPoint = thisStepPoint->GetPosition();
211 G4ThreeVector endPoint = thisStepBackPoint->GetPosition();
215 << startPoint.x() <<
" " << startPoint.y() <<
" " << startPoint.z());
221 const G4NavigationHistory* g4navigation = thisStepPoint->GetTouchable()->GetHistory();
222 G4int ndep = g4navigation->GetDepth();
223 for (G4int ii=0;ii<=ndep;ii++) {
224 G4VPhysicalVolume* v1 = g4navigation->GetVolume(ii);
225 G4String vname = v1->GetName();
226 if ( vname.find(
"NegPhysical") != std::string::npos) zSide=-1;
233 const G4AffineTransform transformation =
234 thisStepPoint->GetTouchable()->GetHistory()->GetTopTransform();
236 G4ThreeVector startPointinLocal =
237 transformation.TransformPoint(startPoint);
238 G4ThreeVector endPointinLocal =
239 transformation.TransformPoint (endPoint);
243 << startPointinLocal.x() <<
" " << startPointinLocal.y() <<
" "
244 << startPointinLocal.z());
246 << endPointinLocal.x() <<
" " << endPointinLocal.y() <<
" "
247 << endPointinLocal.z());
250 G4double
energy =
step->GetTotalEnergyDeposit() *
step->GetTrack()->GetWeight();
253 const double EField = 10.;
254 const double wholeStepLengthCm =
step->GetStepLength() /
CLHEP::cm;
255 energy = (*m_birksLaw)(
energy, wholeStepLengthCm, EField);
266 G4double delta=1./((
double) nsub_step);
268 ATH_MSG_DEBUG(
" nsub_step,delta " << nsub_step <<
" " << delta);
275 for (G4int
i=0;
i<nsub_step;
i++) {
279 G4double fraction=(((G4double)
i)+0.5)*delta;
280 G4ThreeVector subinLocal=startPointinLocal*(1-fraction) + endPointinLocal*fraction;
281 G4double xloc = subinLocal.x();
282 G4double yloc = subinLocal.y();
283 G4double zloc = subinLocal.z();
284 G4double etaloc = subinLocal.pseudoRapidity();
285 G4double philoc = subinLocal.phi();
286 if(philoc<0.) philoc = philoc + 2.*
M_PI;
287 G4double radloc = sqrt( xloc*xloc + yloc*yloc );
290 << xloc <<
" " << yloc <<
" " << zloc);
303 if (currentCellData.
cellID == 0)
306 ATH_MSG_DEBUG(
"LArBarrelCalculator: Invalid hit CELLID == 0 ");
307 ATH_MSG_DEBUG(
"x,y,z local " << xloc <<
" " << yloc <<
" " << zloc);
308 ATH_MSG_DEBUG(
"radius " << radloc <<
" etaloc "<< etaloc <<
" philoc " << philoc);
312 G4int region = currentCellData.
region;
315 G4int sampling = currentCellData.
sampling;
320 if( sampling == 1 && region ==0 )
325 if( sampling == 1 && region ==1 )
337 ATH_MSG_DEBUG(
" region,side,sampling,eta,phi " << region <<
" " << zSide <<
" "
341 ATH_MSG_DEBUG(
" local coordinates " << currentCellData.
x0 <<
" " << currentCellData.
y0);
347 ATH_MSG_DEBUG(
" hit in absorber or electrode radius:" << radloc);
381 G4double Current_xt1,Current_xt2;
391 G4int nfold = currentCellData.
nfold;
392 G4double x0=currentCellData.
x0;
393 G4double y0=currentCellData.
y0;
394 if (x0<1500 || x0>1960 || y0>30 || y0<-30) {
398 G4double
rr = sqrt(x0*x0+y0*y0);
401 const CurrMap* mapOfCurrent(
nullptr);
405 x0 < m_accmap->GetXmax(nfold) &&
407 y0 < m_accmap->GetYmax(nfold) &&
408 (nfold != 13 || x0 < 1957.5) &&
409 (nfold>0 || x0 < 1504.6) ) {
413 ATH_MSG_DEBUG(
" Map for fold xmap,ymap " << nfold <<
" " << xmap <<
" " << ymap);
416 G4int sampMap = currentCellData.
sampMap;
422 ATH_MSG_WARNING(
" region,sampling,eta,fold " << region <<
" " << sampMap <<
" "
423 <<
etaMap <<
" " << nfold);
429 G4int nstraight = currentCellData.
nstraight;
430 if (nstraight%2==0)
n=22;
438 xmap = currentCellData.
xl;
441 if (nstraight==0) xmap = 0.5*(xmap+1.);
443 ATH_MSG_DEBUG(
" Map for straight xl,delec " << xmap <<
" " << ymap);
447 double current0,current1,current2;
449 mapOfCurrent->
GetAll(xmap,ymap,&
gap,¤t0,¤t1,¤t2);
450 G4double gap2=std::fabs(currentCellData.
distElec)+std::fabs(currentCellData.
distAbs)
454 int ipm,ielec,ieta,iside;
457 ielec=currentCellData.
phiGap;
460 if(ielec < 0 ) ielec += 1024;
462 ieta=((
int) (etaloc*(1./0.2)));
465 if ((currentCellData.
distElec>0 && zSide==1)
466 || (currentCellData.
distElec<0 && zSide==-1) ) iside=1;
470 double hv=
m_hv[ipm][ielec][ieta][iside];
471 if (hv>1995.)
current=current0;
482 if (
gap>1
e-3 && gap2 >1
e-3) dgap=
gap/gap2-1;
493 if (!UseFold && std::fabs(currentCellData.
distElec)>2.1 && current0 < 0.1) {
496 <<
" str number " << currentCellData.
nstraight
497 <<
" sampling,eta " << sampling <<
" " <<
etaBin <<
" "
498 <<
" current/E " << current0);
509 if (fabs(etaloc-etaTrans) < 0.025) {
510 double x=std::fabs(zloc-radloc*sinh(etaTrans))/cosh(etaTrans);
511 double y=std::fabs(currentCellData.
distElec);
512 if ( x < m_etamap3->Xmax() ) {
515 Current = Current*resp;
526 double resp,xt0,xt1,xt2,deta;
530 &resp,&xt0,&xt1,&xt2);
532 ATH_MSG_DEBUG(
"hit in strip etaloc,etaBin,deta,delec,resp,xt0,xt1,xt2 "
533 << etaloc <<
" " <<
etaBin <<
" " << deta*1000 <<
" " << currentCellData.
distElec
534 <<
" " << resp <<
" " << xt0 <<
" " << xt1 <<
" " << xt2);
536 if (!InTrans) Current = Current*resp;
540 identifier_xt1.
clear();
541 identifier_xt1 << 4 << 1 << zSide << sampling << region << (
etaBin+1) <<
phiBin;
542 Current_xt1 = Current*xt1;
543 identifier_xt2.
clear();
544 identifier_xt2 << 4 << 1 << zSide << sampling << region << (
etaBin-1) <<
phiBin;
545 Current_xt2 = Current*xt2;
548 identifier_xt1.
clear();
549 identifier_xt1 << 4 << 1 << zSide << sampling << region << (
etaBin-1) <<
phiBin;
550 Current_xt1 = Current*xt1;
551 identifier_xt2.
clear();
552 identifier_xt2 << 4 << 1 << zSide << sampling << region << (
etaBin+1) <<
phiBin;
553 Current_xt2 = Current*xt2;
555 Current = Current*xt0;
558 else if (sampling==2 && !InTrans) {
563 ATH_MSG_DEBUG(
"hit in middle etaloc,etaBin,deta,delec,resp,xt0,xt1,xt2 "
564 << etaloc <<
" " <<
etaBin <<
" " << deta*1000 <<
" " << currentCellData.
distElec
567 Current = Current*resp;
578 for (
unsigned int i=0;
i<hdata.size();
i++) {
579 if (hdata[
i].
id==identifier2) {
580 hdata[
i].energy += Current;
581 hdata[
i].time +=
time*Current;
588 hdata.push_back(newdata);
592 for (
unsigned int i=0;
i<hdata.size();
i++) {
593 if (hdata[
i].
id==identifier_xt1) {
594 hdata[
i].energy += Current_xt1;
595 hdata[
i].time +=
time*Current_xt1;
601 LArHitData newdata = {identifier_xt1,
time*Current_xt1, Current_xt1};
602 hdata.push_back(newdata);
605 for (
unsigned int i=0;
i<hdata.size();
i++) {
606 if (hdata[
i].
id==identifier_xt2) {
607 hdata[
i].energy += Current_xt2;
608 hdata[
i].time +=
time*Current_xt2;
614 LArHitData newdata = {identifier_xt2,
time*Current_xt2, Current_xt2};
615 hdata.push_back(newdata);
623 ATH_MSG_DEBUG(
"Number of hits for this step " << m_nhits <<
" "
628 for (
unsigned int i=0;
i<hdata.size();
i++) {
629 if (std::fabs(hdata[
i].
energy)>1
e-6) hdata[
i].time=hdata[
i].time/hdata[
i].energy;
630 else hdata[
i].time=0.;
637 if (hdata.size()>0)
return true;
668 float defaultHvVal=2000.;
670 for (
int ipm=0;ipm<2;ipm++) {
671 for (
int ielec=0;ielec<1024;ielec++) {
672 for (
int ieta=0;ieta<7;ieta++) {
673 for (
int iside=0;iside<2;iside++) {
674 m_hv[ipm][ielec][ieta][iside] = defaultHvVal;
682 SmartIF<StoreGateSvc> pDetStore{Gaudi::svcLocator()->service(
"DetectorStore")};
684 ATH_MSG_WARNING(
"LArBarrelCalculator::InitHV() unable to get Detector Store! Use default HV values.");
690 if (pDetStore->retrieve(
manager)==StatusCode::SUCCESS) {
695 for (
unsigned int iSide=0;iSide<2;iSide++) {
697 for (
unsigned int iSector=0;iSector<2;iSector++) {
700 for (
unsigned int ielec=0;ielec<32;ielec++) {
702 unsigned jElec = ielec+32*iSector+64*
iPhi;
703 for (
unsigned int iGap=0;iGap<2;iGap++) {
704 double hv = hvdata.
voltage (electrode, iGap);
705 ATH_MSG_DEBUG(
" iSide,jElec,iEta,iGap,hv " << iSide <<
" " << jElec <<
" " <<
iEta <<
" " << iGap <<
" " << hv);
706 if (hv>-999.)
m_hv[iSide][jElec][
iEta][iGap] = hv;
734 if (std::fabs(curr1)>1
e-6) {
735 double x=curr0/curr1;
743 if (std::fabs(curr2)>1
e-6) {
744 double x=curr1/curr2;
752 if (std::fabs(curr2)>1
e-6) {