2#include "G4HCofThisEvent.hh"
4#include "G4ThreeVector.hh"
5#include "G4SDManager.hh"
6#include "G4UnitsTable.hh"
8#include "G4RunManager.hh"
15#include "GaudiKernel/DataSvc.h"
20#include "GaudiKernel/Bootstrap.h"
21#include "GaudiKernel/IService.h"
22#include "GaudiKernel/Service.h"
23#include "GaudiKernel/SmartDataPtr.h"
31 collectionName.insert(
"BesMdcHitsCollection");
32 collectionName.insert(
"BesMdcTruthCollection");
38 StatusCode sc=Gaudi::svcLocator()->service(
"MdcGeomSvc", ISvc);
40 std::cout<<
"BesMdcSD::Could not open MdcGeomSvc"<<std::endl;
44 sc=Gaudi::svcLocator()->service(
"G4Svc", tmpSvc);
46 G4cout <<
" MdcSD::Error,could not open G4Svc"<<G4endl;
47 m_G4Svc=
dynamic_cast<G4Svc *
>(tmpSvc);
50 G4cout <<
" MdcSD: Use sampled dedx instead of Geant4 value"<<G4endl;
56 sc = Gaudi::svcLocator()->service(
"DedxSimSvc", tmp_dedxSimSvc,
true);
59 std::cout <<
"Could not get DedxSimSvc" << std::endl;
61 m_pDedxSimSvc =
dynamic_cast<DedxSimSvc*
>(tmp_dedxSimSvc);
64 sc = Gaudi::svcLocator()->service(
"DedxCurSvc", tmp_dedxCurSvc,
true);
67 std::cout <<
"Could not get DedxCurSvc"
70 m_pDedxCurSvc =
dynamic_cast<DedxCurSvc*
>(tmp_dedxCurSvc);
75 sc = m_tupleMdc->addItem(
"betaGamma",m_betaGamma);
76 sc = m_tupleMdc->addItem(
"fitval",m_fitval);
77 sc = m_tupleMdc->addItem(
"dedx",m_dedx);
78 sc = m_tupleMdc->addItem(
"de",m_de);
81 sc = m_tupleMdc->addItem(
"charge", m_charge);
82 sc = m_tupleMdc->addItem(
"costheta", m_costheta);
92 (SensitiveDetectorName,collectionName[0]);
93 static G4int HCID = -1;
95 { HCID = G4SDManager::GetSDMpointer()->GetCollectionID(collectionName[0]); }
96 HCE->AddHitsCollection( HCID, hitsCollection );
101 truthPointer[i][j]=-1;
110 (SensitiveDetectorName,collectionName[1]);
115{
static G4int HLID=-1;
118 HLID = G4SDManager::GetSDMpointer()->
119 GetCollectionID(collectionName[1]);
121 G4HCofThisEvent* HCE = evt->GetHCofThisEvent();
122 HCE->AddHitsCollection(HLID,truthCollection);
127 G4Track* gTrack = aStep->GetTrack() ;
129 G4double globalT=gTrack->GetGlobalTime();
130 if(std::isnan(globalT)){
131 G4cout<<
"MdcSD:error, globalT is nan "<<G4endl;
134 if(globalT > 2000)
return false;
137 G4int
charge = gTrack->GetDefinition()->GetPDGCharge();
138 if (
charge == 0)
return false;
141 G4double stepLength=aStep->GetStepLength();
147 G4double edep = aStep->GetTotalEnergyDeposit() / stepLength;
148 if(edep==0.)
return false;
151 G4StepPoint* prePoint = aStep->GetPreStepPoint() ;
152 G4StepPoint* postPoint = aStep->GetPostStepPoint() ;
155 G4ThreeVector pointIn = prePoint->GetPosition();
156 G4ThreeVector pointOut = postPoint->GetPosition();
159 const G4VTouchable *touchable = prePoint->GetTouchable();
160 G4VPhysicalVolume *volume = touchable->GetVolume(0);
164 G4double edepTemp = 0;
165 G4double lengthTemp = 0;
167 G4int layerId = touchable->GetVolume(1)->GetCopyNo();
168 if(volume->IsReplicated()){
169 cellId = touchable->GetReplicaNumber();
171 cellId=touchable->GetVolume(0)->GetCopyNo();
173 if(layerId==18&&(cellId==27||cellId==42))
return false;
178 if(layerId >= 36) layerId = 36 + (layerId-36)/2;
181 G4double halfLayerLength=mdcGeomSvc->
Layer(layerId)->
Length()/2.;
182 if(((fabs(pointIn.z())-halfLayerLength)>-7.)
183 &&((fabs(pointOut.z())-halfLayerLength)>-7.))
return false;
185 G4int trackID= gTrack->GetTrackID();
186 G4int truthID, g4TrackID;
189 G4double theta=gTrack->GetMomentumDirection().theta();
191 G4ThreeVector hitPosition(0,0,0);
192 G4double transferT=0;
193 driftD =
Distance(layerId,cellId,pointIn,pointOut,hitPosition,transferT);
195 G4double posPhi, wirePhi;
196 posPhi=hitPosition.phi();
197 if(posPhi<0)posPhi += 2*
pi;
198 wirePhi=mdcGeoPointer->
SignalWire(layerId,cellId).
Phi(hitPosition.z());
207 if(posPhi < 1. && wirePhi > 5.)posFlag = 1;
208 if(posPhi > 5. && wirePhi < 1.)posFlag = 0;
210 G4ThreeVector hitLine=pointOut-pointIn;
211 G4double enterAngle=hitLine.phi()-wirePhi;
212 while(enterAngle<-
pi/2.)enterAngle+=
pi;
213 while(enterAngle>
pi/2.)enterAngle-=
pi;
216 G4double betaGamma=aStep->GetPreStepPoint()->GetBeta() * aStep->GetPreStepPoint()->GetGamma();
217 if(betaGamma<0.01)
return false;
220 G4double eCount=dedxSample(betaGamma,
charge, theta);
230 newHit->
SetPos(hitPosition);
239 driftT=mdcCalPointer->
D2T(driftD);
246 if (hitPointer[layerId][cellId] == -1) {
247 hitsCollection->insert(newHit);
248 G4int NbHits = hitsCollection->entries();
249 hitPointer[layerId][cellId]=NbHits-1;
253 G4int pointer=hitPointer[layerId][cellId];
254 if (g4TrackID == trackID) {
255 G4double preDriftT=(*hitsCollection)[pointer]->GetDriftT();
258 G4double preDriftT = (*hitsCollection)[pointer]->GetDriftT();
259 if (driftT < preDriftT) {
260 (*hitsCollection)[pointer]->SetTrackID(truthID);
262 (*hitsCollection)[pointer]->SetDriftD(driftD);
263 (*hitsCollection)[pointer]->SetDriftT(driftT);
264 (*hitsCollection)[pointer]->SetPos(hitPosition);
265 (*hitsCollection)[pointer]->SetGlobalT(globalT);
266 (*hitsCollection)[pointer]->SetTheta(theta);
267 (*hitsCollection)[pointer]->SetPosFlag(posFlag);
268 (*hitsCollection)[pointer]->SetEnterAngle(enterAngle);
276 if(g4TrackID==trackID){
277 G4int pointer=truthPointer[layerId][cellId];
284 truthHit->
SetPos (hitPosition);
292 truthCollection->insert(truthHit);
293 G4int NbHits = truthCollection->entries();
294 truthPointer[layerId][cellId]=NbHits-1;
297 if(truthID == (*truthCollection)[pointer]->GetTrackID()){
298 G4double preDriftT=(*truthCollection)[pointer]->GetDriftT();
299 if(driftT<preDriftT){
300 (*truthCollection)[pointer]->SetDriftD(driftD);
301 (*truthCollection)[pointer]->SetDriftT(driftT);
302 (*truthCollection)[pointer]->SetPos(hitPosition);
303 (*truthCollection)[pointer]->SetGlobalT(globalT);
304 (*truthCollection)[pointer]->SetTheta(theta);
305 (*truthCollection)[pointer]->SetPosFlag(posFlag);
306 (*truthCollection)[pointer]->SetEnterAngle(enterAngle);
308 edepTemp=(*truthCollection)[pointer]->GetEdep();
309 (*truthCollection)[pointer]->SetEdep(edepTemp+edep);
316 truthHit->
SetPos(hitPosition);
324 truthCollection->insert(truthHit);
325 G4int NbHits = truthCollection->entries();
326 truthPointer[layerId][cellId]=NbHits-1;
340 if (verboseLevel>0) {
341 hitsCollection->PrintAllHits();
351G4double
BesMdcSD::Distance(G4int layerId, G4int cellId, G4ThreeVector pointIn, G4ThreeVector pointOut,G4ThreeVector& hitPosition,G4double& transferT)
361 G4double t1,distance,dInOut,dHitIn,dHitOut;
363 G4ThreeVector east=mdcGeomSvc->
Wire(layerId,cellId)->
Backward();
364 G4ThreeVector west=mdcGeomSvc->
Wire(layerId,cellId)->
Forward();
365 G4ThreeVector wireLine=east-west;
366 G4ThreeVector hitLine=pointOut-pointIn;
368 G4ThreeVector hitXwire=hitLine.cross(wireLine);
369 G4ThreeVector wire2hit=east-pointOut;
372 if(hitXwire.mag()==0){
373 distance=wireLine.cross(wire2hit).mag()/wireLine.mag();
376 t1=hitXwire.dot(wire2hit.cross(wireLine))/hitXwire.mag2();
377 hitPosition=pointOut+t1*hitLine;
379 dInOut=(pointOut-pointIn).mag();
380 dHitIn=(hitPosition-pointIn).mag();
381 dHitOut=(hitPosition-pointOut).mag();
382 if(dHitIn<=dInOut && dHitOut<=dInOut){
383 distance=fabs(wire2hit.dot(hitXwire)/hitXwire.mag());
384 }
else if(dHitOut>dHitIn){
385 distance=wireLine.cross(pointIn-east).mag()/wireLine.mag();
388 distance=wireLine.cross(pointOut-east).mag()/wireLine.mag();
389 hitPosition=pointOut;
394 G4double halfLayerLength=mdcGeomSvc->
Layer(layerId)->
Length()/2.;
395 G4double halfWireLength=wireLine.mag()/2.;
396 G4double transferZ=0;
398 transferZ=halfLayerLength+hitPosition.z();
400 transferZ=halfLayerLength-hitPosition.z();
403 transferT=transferZ*halfWireLength/halfLayerLength/220;
405 transferT=transferZ*halfWireLength/halfLayerLength/240;
414 dEdE_mylanfunc =
new TF1(
"dEdE_mylanfunc",
415 "[3]*TMath::Exp([2]*((x[0]-[0])/[1]+TMath::Exp(-1*((x[0]-[0])/[1]))))",
419 dEdE_mylanfunc->SetParNames(
"MPV",
"Sigma",
"constant1",
"constant2");
422G4double BesMdcSD::dedxSample(G4double betagamma, G4double
charge, G4double theta)
427 m_dedx_hists = m_pDedxSimSvc->
getHist();
428 m_bgRange = m_pDedxSimSvc->
getRange();
429 G4double
x = betagamma;
430 G4double fitval = GetValDedxCurve(x,
charge);
431 if(fitval <= 0)
return 0;
433 G4double random1, random2, dedx1, dedx2, de;
434 G4double standard1, standard2, beta_temp1, beta_temp2;
437 G4int range_idx, bg_idx, angle_idx, charge_idx, hist_idx;
438 range_idx = GetBetagammaIndex(betagamma);
439 angle_idx = GetAngleIndex(theta);
440 charge_idx = GetChargeIndex(
charge);
447 hist_idx = bg_idx * 2 * m_numTheta + angle_idx * 2 + charge_idx;
448 random1 = m_dedx_hists->at(hist_idx).GetRandom();
449 beta_temp1 = (m_bgRange->at(0) + m_bgRange->at(1)) / 2;
450 standard1 = GetValDedxCurve(beta_temp1,
charge);
451 dedx = random1 + fitval - standard1;
454 else if (range_idx == m_numBg - 1)
458 bg_idx = (G4int)(range_idx / 2);
459 hist_idx = bg_idx * 2 * m_numTheta + angle_idx * 2 + charge_idx;
460 random1 = m_dedx_hists->at(hist_idx).GetRandom();
461 beta_temp1 = (m_bgRange->at(m_numBg - 2) +
462 m_bgRange->at(m_numBg - 1)) / 2;
463 standard1 = GetValDedxCurve(beta_temp1,
charge);
464 dedx = random1 + fitval - standard1;
470 if (range_idx % 2 == 0)
474 bg_idx = (G4int)(range_idx / 2);
475 hist_idx = bg_idx * 2 * m_numTheta + angle_idx * 2 + charge_idx;
476 random1 = m_dedx_hists->at(hist_idx).GetRandom();
477 beta_temp1 = (m_bgRange->at(range_idx) +
478 m_bgRange->at(range_idx + 1)) / 2;
479 standard1 = GetValDedxCurve(beta_temp1,
charge);
480 dedx1 = random1 + fitval - standard1;
491 beta_temp1 = (m_bgRange->at(range_idx - 1) +
492 m_bgRange->at(range_idx)) / 2;
493 standard1 = GetValDedxCurve(beta_temp1,
charge);
496 beta_temp2 = (m_bgRange->at(range_idx + 1) +
497 m_bgRange->at(range_idx + 2)) / 2;
498 standard2 = GetValDedxCurve(beta_temp2,
charge);
501 bg_idx = (G4int)(range_idx / 2);
502 hist_idx = bg_idx * 2 * m_numTheta + angle_idx * 2 + charge_idx;
503 random1 = m_dedx_hists->at(hist_idx).GetRandom();
507 hist_idx = bg_idx * 2 * m_numTheta + angle_idx * 2 + charge_idx;
508 random2 = m_dedx_hists->at(hist_idx).GetRandom();
511 dedx1 = random1 + fitval - standard1;
512 dedx2 = random2 + fitval - standard2;
513 dedx = (dedx2 * (
x - m_bgRange->at(range_idx)) +
514 dedx1 * (m_bgRange->at(range_idx + 1) - x)) /
515 (m_bgRange->at(range_idx + 1) - m_bgRange->at(range_idx));
536 m_costheta =
cos(theta);
547G4double BesMdcSD::GetValDedxCurve(G4double x, G4double
charge)
554 std::vector<G4double> par;
559 dedxflag = m_pDedxCurSvc->
getCurve(0);
561 for (G4int i = 1; i < size; i++) {
562 par.push_back(m_pDedxCurSvc->
getCurve(i));
572 G4double partA = par[0] * pow(sqrt(x * x + 1), par[2]) / pow(x, par[2]) *
573 (par[1] - par[5] * log(pow(1 / x, par[3]))) -
574 par[4] +
exp(par[6] + par[7] * x);
575 G4double partB = par[8] * pow(x, 3) + par[9] * pow(x, 2) + par[10] *
x + par[11];
576 G4double partC = - par[12] * log(par[15] + pow(1 / x, par[13])) + par[14];
578 val = 550 * (
A * partA +
B * partB +
C * partC);
588G4int BesMdcSD::GetBetagammaIndex(G4double
bg)
591 for (G4int i = 0; i < m_numBg - 1; i++)
598 if (
bg > m_bgRange->at(m_numBg - 1))
599 return (m_numBg - 1);
609G4int BesMdcSD::GetAngleIndex(G4double theta)
611 if (m_version == 0) {
612 if (fabs(
cos(theta)) >= 0.93)
return 9;
613 return (G4int)(fabs(
cos(theta)) * 10 / 0.93);
616 G4double cos_min = -0.93;
617 G4double cos_max = 0.93;
618 G4int nbin = m_numTheta;
619 G4double cos_step = (cos_max - cos_min) / nbin;
621 if (
cos(theta) < cos_min)
return 0;
622 else if (cos_min <
cos(theta) &&
cos(theta) < cos_max) {
623 return (G4int)((
cos(theta) - cos_min) / cos_step);
625 else return nbin - 1;
634G4int BesMdcSD::GetChargeIndex(G4int
charge)
637 if (
charge == 0)
return -1;
double cos(const BesAngle a)
G4THitsCollection< BesMdcHit > BesMdcHitsCollection
************Class m_alfQCDMZ INTEGER m_KFfin INTEGER m_IVfin INTEGER m_ibox *COMMON c_DZface $ alphaQED at(Q^2=MZ^2) DIZET $ m_alfQCDMZ
EvtComplex exp(const EvtComplex &c)
***************************************************************************************Pseudo Class RRes *****************************************************************************************Parameters and physical constants **Maarten sept ************************************************************************DOUBLE PRECISION xsmu **************************************************************************PARTICLE DATA all others are from PDG *Only resonances with known widths into electron pairs are sept ************************************************************************C Declarations C
double D2T(double driftDNew)
void SetHitPointer(BesMdcHit *hit)
static BesMdcGeoParameter * GetGeo(void)
BesMdcWire SignalWire(int, int)
void SetEdep(G4double de)
void SetDriftT(G4double time)
void SetEnterAngle(G4double angle)
void SetCellNo(G4int cell)
void SetPos(G4ThreeVector xyz)
void SetTrackID(G4int track)
void SetLayerNo(G4int layer)
void SetTheta(G4double angle)
void SetDriftD(G4double distance)
void SetGlobalT(G4double time)
void SetPosFlag(G4int flag)
void BeginOfTruthEvent(const G4Event *)
void EndOfTruthEvent(const G4Event *)
G4double Distance(G4int, G4int, G4ThreeVector, G4ThreeVector, G4ThreeVector &, G4double &)
G4bool ProcessHits(G4Step *, G4TouchableHistory *)
void EndOfEvent(G4HCofThisEvent *)
void Initialize(G4HCofThisEvent *)
void GetCurrentTrackIndex(G4int &trackIndex, G4int &g4TrackId) const
std::vector< TH1F > * getHist()
std::vector< double > * getRange()
NTuple::Tuple * GetTupleMdc()
virtual const int getCurveSize()=0
virtual const double getCurve(int i)=0
double Length(void) const
HepPoint3D Forward(void) const
HepPoint3D Backward(void) const
const MdcGeoWire *const Wire(unsigned id)
const MdcGeoLayer *const Layer(unsigned id)