3#include "G4HCofThisEvent.hh"
5#include "G4ThreeVector.hh"
6#include "G4SDManager.hh"
7#include "G4UnitsTable.hh"
9#include "G4RunManager.hh"
10#include "ReadBoostRoot.hh"
11#include "G4Svc/IG4Svc.h"
12#include "G4Svc/G4Svc.h"
13#include "CalibDataSvc/ICalibRootSvc.h"
14#include "CalibData/Dedx/DedxCalibData.h"
15#include "CalibData/Dedx/DedxSimData.h"
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 G4double betaGamma=aStep->GetPreStepPoint()->GetBeta() * aStep->GetPreStepPoint()->GetGamma();
238 if(betaGamma<0.01)
return false;
241 G4double eCount=dedxSample(betaGamma, charge, theta);
251 newHit->
SetPos(hitPosition);
260 driftT=mdcCalPointer->
D2T(driftD);
267 if (hitPointer[layerId][cellId] == -1) {
268 hitsCollection->insert(newHit);
269 G4int NbHits = hitsCollection->entries();
270 hitPointer[layerId][cellId]=NbHits-1;
274 G4int pointer=hitPointer[layerId][cellId];
275 if (g4TrackID == trackID) {
276 G4double preDriftT=(*hitsCollection)[pointer]->GetDriftT();
279 G4double preDriftT = (*hitsCollection)[pointer]->GetDriftT();
280 if (driftT < preDriftT) {
281 (*hitsCollection)[pointer]->SetTrackID(truthID);
283 (*hitsCollection)[pointer]->SetDriftD(driftD);
284 (*hitsCollection)[pointer]->SetDriftT(driftT);
285 (*hitsCollection)[pointer]->SetPos(hitPosition);
286 (*hitsCollection)[pointer]->SetGlobalT(globalT);
287 (*hitsCollection)[pointer]->SetTheta(theta);
288 (*hitsCollection)[pointer]->SetPosFlag(posFlag);
289 (*hitsCollection)[pointer]->SetEnterAngle(enterAngle);
297 if(g4TrackID==trackID){
298 G4int pointer=truthPointer[layerId][cellId];
305 truthHit->
SetPos (hitPosition);
313 truthCollection->insert(truthHit);
314 G4int NbHits = truthCollection->entries();
315 truthPointer[layerId][cellId]=NbHits-1;
318 if(truthID == (*truthCollection)[pointer]->GetTrackID()){
319 G4double preDriftT=(*truthCollection)[pointer]->GetDriftT();
320 if(driftT<preDriftT){
321 (*truthCollection)[pointer]->SetDriftD(driftD);
322 (*truthCollection)[pointer]->SetDriftT(driftT);
323 (*truthCollection)[pointer]->SetPos(hitPosition);
324 (*truthCollection)[pointer]->SetGlobalT(globalT);
325 (*truthCollection)[pointer]->SetTheta(theta);
326 (*truthCollection)[pointer]->SetPosFlag(posFlag);
327 (*truthCollection)[pointer]->SetEnterAngle(enterAngle);
329 edepTemp=(*truthCollection)[pointer]->GetEdep();
330 (*truthCollection)[pointer]->SetEdep(edepTemp+edep);
337 truthHit->
SetPos(hitPosition);
345 truthCollection->insert(truthHit);
346 G4int NbHits = truthCollection->entries();
347 truthPointer[layerId][cellId]=NbHits-1;
361 if (verboseLevel>0) {
362 hitsCollection->PrintAllHits();
372G4double
BesMdcSD::Distance(G4int layerId, G4int cellId, G4ThreeVector pointIn, G4ThreeVector pointOut,G4ThreeVector& hitPosition,G4double& transferT)
382 G4double t1,distance,dInOut,dHitIn,dHitOut;
384 G4ThreeVector east=mdcGeomSvc->
Wire(layerId,cellId)->
Backward();
385 G4ThreeVector west=mdcGeomSvc->
Wire(layerId,cellId)->
Forward();
386 G4ThreeVector wireLine=east-west;
387 G4ThreeVector hitLine=pointOut-pointIn;
389 G4ThreeVector hitXwire=hitLine.cross(wireLine);
390 G4ThreeVector wire2hit=east-pointOut;
393 if(hitXwire.mag()==0){
394 distance=wireLine.cross(wire2hit).mag()/wireLine.mag();
397 t1=hitXwire.dot(wire2hit.cross(wireLine))/hitXwire.mag2();
398 hitPosition=pointOut+t1*hitLine;
400 dInOut=(pointOut-pointIn).mag();
401 dHitIn=(hitPosition-pointIn).mag();
402 dHitOut=(hitPosition-pointOut).mag();
403 if(dHitIn<=dInOut && dHitOut<=dInOut){
404 distance=fabs(wire2hit.dot(hitXwire)/hitXwire.mag());
405 }
else if(dHitOut>dHitIn){
406 distance=wireLine.cross(pointIn-east).mag()/wireLine.mag();
409 distance=wireLine.cross(pointOut-east).mag()/wireLine.mag();
410 hitPosition=pointOut;
415 G4double halfLayerLength=mdcGeomSvc->
Layer(layerId)->
Length()/2.;
416 G4double halfWireLength=wireLine.mag()/2.;
417 G4double transferZ=0;
419 transferZ=halfLayerLength+hitPosition.z();
421 transferZ=halfLayerLength-hitPosition.z();
424 transferT=transferZ*halfWireLength/halfLayerLength/220;
426 transferT=transferZ*halfWireLength/halfLayerLength/240;
435 dEdE_mylanfunc =
new TF1(
"dEdE_mylanfunc",
436 "[3]*TMath::Exp([2]*((x[0]-[0])/[1]+TMath::Exp(-1*((x[0]-[0])/[1]))))",
440 dEdE_mylanfunc->SetParNames(
"MPV",
"Sigma",
"constant1",
"constant2");
443G4double BesMdcSD::dedxSample(G4double betagamma, G4double charge, G4double theta)
445 G4double
x = betagamma;
446 G4double fitval = GetValDedxCurve(x, charge);
447 if(fitval <= 0)
return 0;
449 G4double random1, random2, dedx1, dedx2, de;
450 G4double standard1, standard2, beta_temp1, beta_temp2;
453 G4int range_idx, bg_idx, angle_idx, charge_idx, hist_idx;
454 range_idx = GetBetagammaIndex(betagamma);
455 angle_idx = GetAngleIndex(theta);
456 charge_idx = GetChargeIndex(charge);
463 hist_idx = bg_idx * 2 * 10 + angle_idx * 2 + charge_idx;
464 random1 = m_dedx_hists[hist_idx].GetRandom();
465 beta_temp1 = (m_bgRange[0] + m_bgRange[1]) / 2;
466 standard1 = GetValDedxCurve(beta_temp1, charge);
467 dedx = random1 + fitval - standard1;
470 else if (range_idx == m_numBg - 1)
474 bg_idx = (G4int)(range_idx / 2);
475 hist_idx = bg_idx * 2 * 10 + angle_idx * 2 + charge_idx;
476 random1 = m_dedx_hists[hist_idx].GetRandom();
477 beta_temp1 = (m_bgRange[m_numBg - 2] +
478 m_bgRange[m_numBg - 1]) / 2;
479 standard1 = GetValDedxCurve(beta_temp1, charge);
480 dedx = random1 + fitval - standard1;
486 if (range_idx % 2 == 0)
490 bg_idx = (G4int)(range_idx / 2);
491 hist_idx = bg_idx * 2 * 10 + angle_idx * 2 + charge_idx;
492 random1 = m_dedx_hists[hist_idx].GetRandom();
493 beta_temp1 = (m_bgRange[range_idx] +
494 m_bgRange[range_idx + 1]) / 2;
495 standard1 = GetValDedxCurve(beta_temp1, charge);
496 dedx1 = random1 + fitval - standard1;
507 beta_temp1 = (m_bgRange[range_idx - 1] +
508 m_bgRange[range_idx]) / 2;
509 standard1 = GetValDedxCurve(beta_temp1, charge);
512 beta_temp2 = (m_bgRange[range_idx + 1] +
513 m_bgRange[range_idx + 2]) / 2;
514 standard2 = GetValDedxCurve(beta_temp2, charge);
517 bg_idx = (G4int)(range_idx / 2);
518 hist_idx = bg_idx * 2 * 10 + angle_idx * 2 + charge_idx;
519 random1 = m_dedx_hists[hist_idx].GetRandom();
523 hist_idx = bg_idx * 2 * 10 + angle_idx * 2 + charge_idx;
524 random2 = m_dedx_hists[hist_idx].GetRandom();
527 dedx1 = random1 + fitval - standard1;
528 dedx2 = random2 + fitval - standard2;
529 dedx = (dedx2 * (
x - m_bgRange[range_idx]) +
530 dedx1 * (m_bgRange[range_idx + 1] - x)) /
531 (m_bgRange[range_idx + 1] - m_bgRange[range_idx]);
552 m_costheta =
cos(theta);
563G4double BesMdcSD::GetValDedxCurve(G4double x, G4double charge)
570 std::vector<G4double> par;
575 dedxflag = m_pDedxCurSvc->
getCurve(0);
577 for (G4int i = 1; i < size; i++) {
578 par.push_back(m_pDedxCurSvc->
getCurve(i));
588 G4double partA = par[0] * pow(sqrt(x * x + 1), par[2]) / pow(x, par[2]) *
589 (par[1] - par[5] * log(pow(1 / x, par[3]))) -
590 par[4] +
exp(par[6] + par[7] * x);
591 G4double partB = par[8] * pow(x, 3) + par[9] * pow(x, 2) + par[10] *
x + par[11];
592 G4double partC = - par[12] * log(par[15] + pow(1 / x, par[13])) + par[14];
594 val = 550 * (
A * partA +
B * partB +
C * partC);
604G4int BesMdcSD::GetBetagammaIndex(G4double
bg)
606 if (
bg < m_bgRange[0])
return -1;
607 for (G4int i = 0; i < m_numBg - 1; i++)
609 if (
bg > m_bgRange[i] &&
bg < m_bgRange[i + 1])
614 if (
bg > m_bgRange[m_numBg - 1])
615 return (m_numBg - 1);
623G4int BesMdcSD::GetAngleIndex(G4double theta)
625 if (fabs(
cos(theta)) >= 0.93)
return 9;
626 return (G4int)(fabs(
cos(theta)) * 10 / 0.93);
634G4int BesMdcSD::GetChargeIndex(G4int charge)
636 if (charge > 0)
return 0;
637 if (charge == 0)
return -1;
638 if (charge < 0)
return 1;
EvtComplex exp(const EvtComplex &c)
double cos(const BesAngle a)
G4THitsCollection< BesMdcHit > BesMdcHitsCollection
***************************************************************************************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
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)