3#include "G4HCofThisEvent.hh"
5#include "G4ThreeVector.hh"
6#include "G4SDManager.hh"
7#include "G4UnitsTable.hh"
9#include "G4RunManager.hh"
16#include "GaudiKernel/DataSvc.h"
21#include "GaudiKernel/Bootstrap.h"
22#include "GaudiKernel/IService.h"
23#include "GaudiKernel/Service.h"
24#include "GaudiKernel/SmartDataPtr.h"
32 collectionName.insert(
"BesMdcHitsCollection");
33 collectionName.insert(
"BesMdcTruthCollection");
39 StatusCode sc=Gaudi::svcLocator()->service(
"MdcGeomSvc", ISvc);
41 std::cout<<
"BesMdcSD::Could not open MdcGeomSvc"<<std::endl;
45 sc=Gaudi::svcLocator()->service(
"G4Svc", tmpSvc);
47 G4cout <<
" MdcSD::Error,could not open G4Svc"<<G4endl;
48 m_G4Svc=
dynamic_cast<G4Svc *
>(tmpSvc);
51 G4cout <<
" MdcSD: Use sampled dedx instead of Geant4 value"<<G4endl;
58 std::string dedxTDSPath =
"/Calib/DedxSim";
59 IDataProviderSvc* pCalibDataSvc;
60 sc = Gaudi::svcLocator()->service(
"CalibDataSvc", pCalibDataSvc,
true);
62 std::cout <<
"BesMdcSD::Could not open CalibDataSvc" << std::endl;
63 m_calibDataSvc =
dynamic_cast<CalibDataSvc*
>(pCalibDataSvc);
66 std::cout <<
"Could not get CalibDataSvc"
69 SmartDataPtr<CalibData::DedxSimData> pDedxSimData(m_calibDataSvc, dedxTDSPath);
70 m_numDedxHists = pDedxSimData->gethistNo();
71 m_numBg = pDedxSimData->getRangeNo();
72 m_dedx_hists =
new TH1F[m_numDedxHists];
73 for (G4int i = 0; i < m_numBg; i++)
75 m_bgRange.push_back(pDedxSimData->getRange(i));
77 for (G4int i = 0; i < m_numDedxHists; i++)
79 m_dedx_hists[i] = pDedxSimData->getHist(i);
84 sc = Gaudi::svcLocator()->service(
"DedxCurSvc", tmp_dedxCurSvc,
true);
87 std::cout <<
"Could not get DedxCurSvc"
90 m_pDedxCurSvc =
dynamic_cast<DedxCurSvc*
>(tmp_dedxCurSvc);
95 sc = m_tupleMdc->addItem(
"betaGamma",m_betaGamma);
96 sc = m_tupleMdc->addItem(
"fitval",m_fitval);
97 sc = m_tupleMdc->addItem(
"dedx",m_dedx);
98 sc = m_tupleMdc->addItem(
"de",m_de);
101 sc = m_tupleMdc->addItem(
"charge", m_charge);
102 sc = m_tupleMdc->addItem(
"costheta", m_costheta);
107 delete []m_dedx_hists;
113 (SensitiveDetectorName,collectionName[0]);
114 static G4int HCID = -1;
116 { HCID = G4SDManager::GetSDMpointer()->GetCollectionID(collectionName[0]); }
117 HCE->AddHitsCollection( HCID, hitsCollection );
122 truthPointer[i][j]=-1;
131 (SensitiveDetectorName,collectionName[1]);
136{
static G4int HLID=-1;
139 HLID = G4SDManager::GetSDMpointer()->
140 GetCollectionID(collectionName[1]);
142 G4HCofThisEvent* HCE = evt->GetHCofThisEvent();
143 HCE->AddHitsCollection(HLID,truthCollection);
148 G4Track* gTrack = aStep->GetTrack() ;
150 G4double globalT=gTrack->GetGlobalTime();
152 G4cout<<
"MdcSD:error, globalT is nan "<<G4endl;
155 if(globalT > 2000)
return false;
158 G4int charge = gTrack->GetDefinition()->GetPDGCharge();
159 if (charge == 0)
return false;
162 G4double stepLength=aStep->GetStepLength();
168 G4double edep = aStep->GetTotalEnergyDeposit() / stepLength;
169 if(edep==0.)
return false;
172 G4StepPoint* prePoint = aStep->GetPreStepPoint() ;
173 G4StepPoint* postPoint = aStep->GetPostStepPoint() ;
176 G4ThreeVector pointIn = prePoint->GetPosition();
177 G4ThreeVector pointOut = postPoint->GetPosition();
180 const G4VTouchable *touchable = prePoint->GetTouchable();
181 G4VPhysicalVolume *volume = touchable->GetVolume(0);
185 G4double edepTemp = 0;
186 G4double lengthTemp = 0;
188 G4int layerId = touchable->GetVolume(1)->GetCopyNo();
189 if(volume->IsReplicated()){
190 cellId = touchable->GetReplicaNumber();
192 cellId=touchable->GetVolume(0)->GetCopyNo();
194 if(layerId==18&&(cellId==27||cellId==42))
return false;
199 if(layerId >= 36) layerId = 36 + (layerId-36)/2;
202 G4double halfLayerLength=mdcGeomSvc->
Layer(layerId)->
Length()/2.;
203 if(((fabs(pointIn.z())-halfLayerLength)>-7.)
204 &&((fabs(pointOut.z())-halfLayerLength)>-7.))
return false;
206 G4int trackID= gTrack->GetTrackID();
207 G4int truthID, g4TrackID;
210 G4double theta=gTrack->GetMomentumDirection().theta();
212 G4ThreeVector hitPosition=0;
213 G4double transferT=0;
214 driftD =
Distance(layerId,cellId,pointIn,pointOut,hitPosition,transferT);
216 G4double posPhi, wirePhi;
217 posPhi=hitPosition.phi();
218 if(posPhi<0)posPhi += 2*
pi;
219 wirePhi=mdcGeoPointer->
SignalWire(layerId,cellId).
Phi(hitPosition.z());
228 if(posPhi < 1. && wirePhi > 5.)posFlag = 1;
229 if(posPhi > 5. && wirePhi < 1.)posFlag = 0;
231 G4ThreeVector hitLine=pointOut-pointIn;
232 G4double enterAngle=hitLine.phi()-wirePhi;
233 while(enterAngle<-
pi/2.)enterAngle+=
pi;
234 while(enterAngle>
pi/2.)enterAngle-=
pi;
237 G4int pdg_code = gTrack->GetDefinition()->GetPDGEncoding();
238 G4String process_name=
"Generator";
239 if(NULL != gTrack->GetCreatorProcess()) process_name = gTrack->GetCreatorProcess()->GetProcessName();
240 G4double trkLen = gTrack->GetTrackLength();
241 G4int isSecondary = (trackID==g4TrackID)? 0:1;
242 G4ThreeVector p3_pre = prePoint->GetMomentum();
243 G4ThreeVector p3_post = postPoint->GetMomentum();
244 G4ThreeVector p3_hit = 0.5*(p3_pre+p3_post);
248 G4double betaGamma=aStep->GetPreStepPoint()->GetBeta() * aStep->GetPreStepPoint()->GetGamma();
249 if(betaGamma<0.01)
return false;
252 G4double eCount=dedxSample(betaGamma, charge, theta);
262 newHit->
SetPos(hitPosition);
277 driftT=mdcCalPointer->
D2T(driftD);
284 if (hitPointer[layerId][cellId] == -1) {
285 hitsCollection->insert(newHit);
286 G4int NbHits = hitsCollection->entries();
287 hitPointer[layerId][cellId]=NbHits-1;
291 G4int pointer=hitPointer[layerId][cellId];
292 if (g4TrackID == trackID) {
293 G4double preDriftT=(*hitsCollection)[pointer]->GetDriftT();
296 G4double preDriftT = (*hitsCollection)[pointer]->GetDriftT();
297 if (driftT < preDriftT) {
309 *((*hitsCollection)[pointer])=*newHit;
317 if(g4TrackID==trackID){
318 G4int pointer=truthPointer[layerId][cellId];
325 truthHit->
SetPos (hitPosition);
333 truthCollection->insert(truthHit);
334 G4int NbHits = truthCollection->entries();
335 truthPointer[layerId][cellId]=NbHits-1;
338 if(truthID == (*truthCollection)[pointer]->GetTrackID()){
339 G4double preDriftT=(*truthCollection)[pointer]->GetDriftT();
340 if(driftT<preDriftT){
341 (*truthCollection)[pointer]->SetDriftD(driftD);
342 (*truthCollection)[pointer]->SetDriftT(driftT);
343 (*truthCollection)[pointer]->SetPos(hitPosition);
344 (*truthCollection)[pointer]->SetGlobalT(globalT);
345 (*truthCollection)[pointer]->SetTheta(theta);
346 (*truthCollection)[pointer]->SetPosFlag(posFlag);
347 (*truthCollection)[pointer]->SetEnterAngle(enterAngle);
349 edepTemp=(*truthCollection)[pointer]->GetEdep();
350 (*truthCollection)[pointer]->SetEdep(edepTemp+edep);
357 truthHit->
SetPos(hitPosition);
365 truthCollection->insert(truthHit);
366 G4int NbHits = truthCollection->entries();
367 truthPointer[layerId][cellId]=NbHits-1;
381 if (verboseLevel>0) {
382 hitsCollection->PrintAllHits();
392G4double
BesMdcSD::Distance(G4int layerId, G4int cellId, G4ThreeVector pointIn, G4ThreeVector pointOut,G4ThreeVector& hitPosition,G4double& transferT)
402 G4double t1,distance,dInOut,dHitIn,dHitOut;
404 G4ThreeVector east=mdcGeomSvc->
Wire(layerId,cellId)->
Backward();
405 G4ThreeVector west=mdcGeomSvc->
Wire(layerId,cellId)->
Forward();
406 G4ThreeVector wireLine=east-west;
407 G4ThreeVector hitLine=pointOut-pointIn;
409 G4ThreeVector hitXwire=hitLine.cross(wireLine);
410 G4ThreeVector wire2hit=east-pointOut;
413 if(hitXwire.mag()==0){
414 distance=wireLine.cross(wire2hit).mag()/wireLine.mag();
417 t1=hitXwire.dot(wire2hit.cross(wireLine))/hitXwire.mag2();
418 hitPosition=pointOut+t1*hitLine;
420 dInOut=(pointOut-pointIn).mag();
421 dHitIn=(hitPosition-pointIn).mag();
422 dHitOut=(hitPosition-pointOut).mag();
423 if(dHitIn<=dInOut && dHitOut<=dInOut){
424 distance=fabs(wire2hit.dot(hitXwire)/hitXwire.mag());
425 }
else if(dHitOut>dHitIn){
426 distance=wireLine.cross(pointIn-east).mag()/wireLine.mag();
429 distance=wireLine.cross(pointOut-east).mag()/wireLine.mag();
430 hitPosition=pointOut;
435 G4double halfLayerLength=mdcGeomSvc->
Layer(layerId)->
Length()/2.;
436 G4double halfWireLength=wireLine.mag()/2.;
437 G4double transferZ=0;
439 transferZ=halfLayerLength+hitPosition.z();
441 transferZ=halfLayerLength-hitPosition.z();
444 transferT=transferZ*halfWireLength/halfLayerLength/220;
446 transferT=transferZ*halfWireLength/halfLayerLength/240;
455 dEdE_mylanfunc =
new TF1(
"dEdE_mylanfunc",
456 "[3]*TMath::Exp([2]*((x[0]-[0])/[1]+TMath::Exp(-1*((x[0]-[0])/[1]))))",
460 dEdE_mylanfunc->SetParNames(
"MPV",
"Sigma",
"constant1",
"constant2");
463G4double BesMdcSD::dedxSample(G4double betagamma, G4double charge, G4double theta)
465 G4double
x = betagamma;
466 G4double fitval = GetValDedxCurve(x, charge);
467 if(fitval <= 0)
return 0;
469 G4double random1, random2, dedx1, dedx2, de;
470 G4double standard1, standard2, beta_temp1, beta_temp2;
473 G4int range_idx, bg_idx, angle_idx, charge_idx, hist_idx;
474 range_idx = GetBetagammaIndex(betagamma);
475 angle_idx = GetAngleIndex(theta);
476 charge_idx = GetChargeIndex(charge);
483 hist_idx = bg_idx * 2 * 10 + angle_idx * 2 + charge_idx;
484 random1 = m_dedx_hists[hist_idx].GetRandom();
485 beta_temp1 = (m_bgRange[0] + m_bgRange[1]) / 2;
486 standard1 = GetValDedxCurve(beta_temp1, charge);
487 dedx = random1 + fitval - standard1;
490 else if (range_idx == m_numBg - 1)
494 bg_idx = (G4int)(range_idx / 2);
495 hist_idx = bg_idx * 2 * 10 + angle_idx * 2 + charge_idx;
496 random1 = m_dedx_hists[hist_idx].GetRandom();
497 beta_temp1 = (m_bgRange[m_numBg - 2] +
498 m_bgRange[m_numBg - 1]) / 2;
499 standard1 = GetValDedxCurve(beta_temp1, charge);
500 dedx = random1 + fitval - standard1;
506 if (range_idx % 2 == 0)
510 bg_idx = (G4int)(range_idx / 2);
511 hist_idx = bg_idx * 2 * 10 + angle_idx * 2 + charge_idx;
512 random1 = m_dedx_hists[hist_idx].GetRandom();
513 beta_temp1 = (m_bgRange[range_idx] +
514 m_bgRange[range_idx + 1]) / 2;
515 standard1 = GetValDedxCurve(beta_temp1, charge);
516 dedx1 = random1 + fitval - standard1;
527 beta_temp1 = (m_bgRange[range_idx - 1] +
528 m_bgRange[range_idx]) / 2;
529 standard1 = GetValDedxCurve(beta_temp1, charge);
532 beta_temp2 = (m_bgRange[range_idx + 1] +
533 m_bgRange[range_idx + 2]) / 2;
534 standard2 = GetValDedxCurve(beta_temp2, charge);
537 bg_idx = (G4int)(range_idx / 2);
538 hist_idx = bg_idx * 2 * 10 + angle_idx * 2 + charge_idx;
539 random1 = m_dedx_hists[hist_idx].GetRandom();
543 hist_idx = bg_idx * 2 * 10 + angle_idx * 2 + charge_idx;
544 random2 = m_dedx_hists[hist_idx].GetRandom();
547 dedx1 = random1 + fitval - standard1;
548 dedx2 = random2 + fitval - standard2;
549 dedx = (dedx2 * (
x - m_bgRange[range_idx]) +
550 dedx1 * (m_bgRange[range_idx + 1] - x)) /
551 (m_bgRange[range_idx + 1] - m_bgRange[range_idx]);
572 m_costheta =
cos(theta);
583G4double BesMdcSD::GetValDedxCurve(G4double x, G4double charge)
590 std::vector<G4double> par;
595 dedxflag = m_pDedxCurSvc->
getCurve(0);
597 for (G4int i = 1; i < size; i++) {
598 par.push_back(m_pDedxCurSvc->
getCurve(i));
608 G4double partA = par[0] * pow(sqrt(x * x + 1), par[2]) / pow(x, par[2]) *
609 (par[1] - par[5] * log(pow(1 / x, par[3]))) -
610 par[4] +
exp(par[6] + par[7] * x);
611 G4double partB = par[8] * pow(x, 3) + par[9] * pow(x, 2) + par[10] *
x + par[11];
612 G4double partC = - par[12] * log(par[15] + pow(1 / x, par[13])) + par[14];
614 val = 550 * (
A * partA +
B * partB +
C * partC);
624G4int BesMdcSD::GetBetagammaIndex(G4double
bg)
626 if (
bg < m_bgRange[0])
return -1;
627 for (G4int i = 0; i < m_numBg - 1; i++)
629 if (
bg > m_bgRange[i] &&
bg < m_bgRange[i + 1])
634 if (
bg > m_bgRange[m_numBg - 1])
635 return (m_numBg - 1);
643G4int BesMdcSD::GetAngleIndex(G4double theta)
645 if (fabs(
cos(theta)) >= 0.93)
return 9;
646 return (G4int)(fabs(
cos(theta)) * 10 / 0.93);
654G4int BesMdcSD::GetChargeIndex(G4int charge)
656 if (charge > 0)
return 0;
657 if (charge == 0)
return -1;
658 if (charge < 0)
return 1;
double cos(const BesAngle a)
G4THitsCollection< BesMdcHit > BesMdcHitsCollection
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 SetPDGCode(G4int code)
void SetDriftT(G4double time)
void SetEnterAngle(G4double angle)
void SetIsSecondary(G4int isSec)
void SetCellNo(G4int cell)
void SetCreatorProcess(G4String proName)
void SetPos(G4ThreeVector xyz)
void SetTrackID(G4int track)
void SetLayerNo(G4int layer)
void SetTheta(G4double angle)
void SetDriftD(G4double distance)
void SetMomentum(G4ThreeVector xyz)
void SetGlobalT(G4double time)
void SetPosFlag(G4int flag)
void SetFlightLength(G4double len)
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
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)