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_version = pDedxSimData->getVersion();
71 m_numDedxHists = pDedxSimData->gethistNo();
72 m_numBg = pDedxSimData->getRangeNo();
73 if (m_version == 0) m_numTheta = 10;
74 else m_numTheta = pDedxSimData->getThetaNo();
75 m_dedx_hists =
new TH1F[m_numDedxHists];
76 for (G4int i = 0; i < m_numBg; i++)
78 m_bgRange.push_back(pDedxSimData->getRange(i));
80 for (G4int i = 0; i < m_numDedxHists; i++)
82 m_dedx_hists[i] = pDedxSimData->getHist(i);
87 sc = Gaudi::svcLocator()->service(
"DedxCurSvc", tmp_dedxCurSvc,
true);
90 std::cout <<
"Could not get DedxCurSvc"
93 m_pDedxCurSvc =
dynamic_cast<DedxCurSvc*
>(tmp_dedxCurSvc);
98 sc = m_tupleMdc->addItem(
"betaGamma",m_betaGamma);
99 sc = m_tupleMdc->addItem(
"fitval",m_fitval);
100 sc = m_tupleMdc->addItem(
"dedx",m_dedx);
101 sc = m_tupleMdc->addItem(
"de",m_de);
104 sc = m_tupleMdc->addItem(
"charge", m_charge);
105 sc = m_tupleMdc->addItem(
"costheta", m_costheta);
110 delete []m_dedx_hists;
116 (SensitiveDetectorName,collectionName[0]);
117 static G4int HCID = -1;
119 { HCID = G4SDManager::GetSDMpointer()->GetCollectionID(collectionName[0]); }
120 HCE->AddHitsCollection( HCID, hitsCollection );
125 truthPointer[i][j]=-1;
134 (SensitiveDetectorName,collectionName[1]);
139{
static G4int HLID=-1;
142 HLID = G4SDManager::GetSDMpointer()->
143 GetCollectionID(collectionName[1]);
145 G4HCofThisEvent* HCE = evt->GetHCofThisEvent();
146 HCE->AddHitsCollection(HLID,truthCollection);
151 G4Track* gTrack = aStep->GetTrack() ;
153 G4double globalT=gTrack->GetGlobalTime();
155 G4cout<<
"MdcSD:error, globalT is nan "<<G4endl;
158 if(globalT > 2000)
return false;
161 G4int
charge = gTrack->GetDefinition()->GetPDGCharge();
162 if (
charge == 0)
return false;
165 G4double stepLength=aStep->GetStepLength();
171 G4double edep = aStep->GetTotalEnergyDeposit() / stepLength;
172 if(edep==0.)
return false;
175 G4StepPoint* prePoint = aStep->GetPreStepPoint() ;
176 G4StepPoint* postPoint = aStep->GetPostStepPoint() ;
179 G4ThreeVector pointIn = prePoint->GetPosition();
180 G4ThreeVector pointOut = postPoint->GetPosition();
183 const G4VTouchable *touchable = prePoint->GetTouchable();
184 G4VPhysicalVolume *volume = touchable->GetVolume(0);
188 G4double edepTemp = 0;
189 G4double lengthTemp = 0;
191 G4int layerId = touchable->GetVolume(1)->GetCopyNo();
192 if(volume->IsReplicated()){
193 cellId = touchable->GetReplicaNumber();
195 cellId=touchable->GetVolume(0)->GetCopyNo();
197 if(layerId==18&&(cellId==27||cellId==42))
return false;
202 if(layerId >= 36) layerId = 36 + (layerId-36)/2;
205 G4double halfLayerLength=mdcGeomSvc->
Layer(layerId)->
Length()/2.;
206 if(((fabs(pointIn.z())-halfLayerLength)>-7.)
207 &&((fabs(pointOut.z())-halfLayerLength)>-7.))
return false;
209 G4int trackID= gTrack->GetTrackID();
210 G4int truthID, g4TrackID;
213 G4double theta=gTrack->GetMomentumDirection().theta();
215 G4ThreeVector hitPosition=0;
216 G4double transferT=0;
217 driftD =
Distance(layerId,cellId,pointIn,pointOut,hitPosition,transferT);
219 G4double posPhi, wirePhi;
220 posPhi=hitPosition.phi();
221 if(posPhi<0)posPhi += 2*
pi;
222 wirePhi=mdcGeoPointer->
SignalWire(layerId,cellId).
Phi(hitPosition.z());
231 if(posPhi < 1. && wirePhi > 5.)posFlag = 1;
232 if(posPhi > 5. && wirePhi < 1.)posFlag = 0;
234 G4ThreeVector hitLine=pointOut-pointIn;
235 G4double enterAngle=hitLine.phi()-wirePhi;
236 while(enterAngle<-
pi/2.)enterAngle+=
pi;
237 while(enterAngle>
pi/2.)enterAngle-=
pi;
240 G4double betaGamma=aStep->GetPreStepPoint()->GetBeta() * aStep->GetPreStepPoint()->GetGamma();
241 if(betaGamma<0.01)
return false;
244 G4double eCount=dedxSample(betaGamma,
charge, theta);
254 newHit->
SetPos(hitPosition);
263 driftT=mdcCalPointer->
D2T(driftD);
270 if (hitPointer[layerId][cellId] == -1) {
271 hitsCollection->insert(newHit);
272 G4int NbHits = hitsCollection->entries();
273 hitPointer[layerId][cellId]=NbHits-1;
277 G4int pointer=hitPointer[layerId][cellId];
278 if (g4TrackID == trackID) {
279 G4double preDriftT=(*hitsCollection)[pointer]->GetDriftT();
282 G4double preDriftT = (*hitsCollection)[pointer]->GetDriftT();
283 if (driftT < preDriftT) {
284 (*hitsCollection)[pointer]->SetTrackID(truthID);
286 (*hitsCollection)[pointer]->SetDriftD(driftD);
287 (*hitsCollection)[pointer]->SetDriftT(driftT);
288 (*hitsCollection)[pointer]->SetPos(hitPosition);
289 (*hitsCollection)[pointer]->SetGlobalT(globalT);
290 (*hitsCollection)[pointer]->SetTheta(theta);
291 (*hitsCollection)[pointer]->SetPosFlag(posFlag);
292 (*hitsCollection)[pointer]->SetEnterAngle(enterAngle);
300 if(g4TrackID==trackID){
301 G4int pointer=truthPointer[layerId][cellId];
308 truthHit->
SetPos (hitPosition);
316 truthCollection->insert(truthHit);
317 G4int NbHits = truthCollection->entries();
318 truthPointer[layerId][cellId]=NbHits-1;
321 if(truthID == (*truthCollection)[pointer]->GetTrackID()){
322 G4double preDriftT=(*truthCollection)[pointer]->GetDriftT();
323 if(driftT<preDriftT){
324 (*truthCollection)[pointer]->SetDriftD(driftD);
325 (*truthCollection)[pointer]->SetDriftT(driftT);
326 (*truthCollection)[pointer]->SetPos(hitPosition);
327 (*truthCollection)[pointer]->SetGlobalT(globalT);
328 (*truthCollection)[pointer]->SetTheta(theta);
329 (*truthCollection)[pointer]->SetPosFlag(posFlag);
330 (*truthCollection)[pointer]->SetEnterAngle(enterAngle);
332 edepTemp=(*truthCollection)[pointer]->GetEdep();
333 (*truthCollection)[pointer]->SetEdep(edepTemp+edep);
340 truthHit->
SetPos(hitPosition);
348 truthCollection->insert(truthHit);
349 G4int NbHits = truthCollection->entries();
350 truthPointer[layerId][cellId]=NbHits-1;
364 if (verboseLevel>0) {
365 hitsCollection->PrintAllHits();
375G4double
BesMdcSD::Distance(G4int layerId, G4int cellId, G4ThreeVector pointIn, G4ThreeVector pointOut,G4ThreeVector& hitPosition,G4double& transferT)
385 G4double t1,distance,dInOut,dHitIn,dHitOut;
387 G4ThreeVector east=mdcGeomSvc->
Wire(layerId,cellId)->
Backward();
388 G4ThreeVector west=mdcGeomSvc->
Wire(layerId,cellId)->
Forward();
389 G4ThreeVector wireLine=east-west;
390 G4ThreeVector hitLine=pointOut-pointIn;
392 G4ThreeVector hitXwire=hitLine.cross(wireLine);
393 G4ThreeVector wire2hit=east-pointOut;
396 if(hitXwire.mag()==0){
397 distance=wireLine.cross(wire2hit).mag()/wireLine.mag();
400 t1=hitXwire.dot(wire2hit.cross(wireLine))/hitXwire.mag2();
401 hitPosition=pointOut+t1*hitLine;
403 dInOut=(pointOut-pointIn).mag();
404 dHitIn=(hitPosition-pointIn).mag();
405 dHitOut=(hitPosition-pointOut).mag();
406 if(dHitIn<=dInOut && dHitOut<=dInOut){
407 distance=fabs(wire2hit.dot(hitXwire)/hitXwire.mag());
408 }
else if(dHitOut>dHitIn){
409 distance=wireLine.cross(pointIn-east).mag()/wireLine.mag();
412 distance=wireLine.cross(pointOut-east).mag()/wireLine.mag();
413 hitPosition=pointOut;
418 G4double halfLayerLength=mdcGeomSvc->
Layer(layerId)->
Length()/2.;
419 G4double halfWireLength=wireLine.mag()/2.;
420 G4double transferZ=0;
422 transferZ=halfLayerLength+hitPosition.z();
424 transferZ=halfLayerLength-hitPosition.z();
427 transferT=transferZ*halfWireLength/halfLayerLength/220;
429 transferT=transferZ*halfWireLength/halfLayerLength/240;
438 dEdE_mylanfunc =
new TF1(
"dEdE_mylanfunc",
439 "[3]*TMath::Exp([2]*((x[0]-[0])/[1]+TMath::Exp(-1*((x[0]-[0])/[1]))))",
443 dEdE_mylanfunc->SetParNames(
"MPV",
"Sigma",
"constant1",
"constant2");
446G4double BesMdcSD::dedxSample(G4double betagamma, G4double
charge, G4double theta)
448 G4double
x = betagamma;
449 G4double fitval = GetValDedxCurve(x,
charge);
450 if(fitval <= 0)
return 0;
452 G4double random1, random2, dedx1, dedx2, de;
453 G4double standard1, standard2, beta_temp1, beta_temp2;
456 G4int range_idx, bg_idx, angle_idx, charge_idx, hist_idx;
457 range_idx = GetBetagammaIndex(betagamma);
458 angle_idx = GetAngleIndex(theta);
459 charge_idx = GetChargeIndex(
charge);
466 hist_idx = bg_idx * 2 * m_numTheta + angle_idx * 2 + charge_idx;
467 random1 = m_dedx_hists[hist_idx].GetRandom();
468 beta_temp1 = (m_bgRange[0] + m_bgRange[1]) / 2;
469 standard1 = GetValDedxCurve(beta_temp1,
charge);
470 dedx = random1 + fitval - standard1;
473 else if (range_idx == m_numBg - 1)
477 bg_idx = (G4int)(range_idx / 2);
478 hist_idx = bg_idx * 2 * m_numTheta + angle_idx * 2 + charge_idx;
479 random1 = m_dedx_hists[hist_idx].GetRandom();
480 beta_temp1 = (m_bgRange[m_numBg - 2] +
481 m_bgRange[m_numBg - 1]) / 2;
482 standard1 = GetValDedxCurve(beta_temp1,
charge);
483 dedx = random1 + fitval - standard1;
489 if (range_idx % 2 == 0)
493 bg_idx = (G4int)(range_idx / 2);
494 hist_idx = bg_idx * 2 * m_numTheta + angle_idx * 2 + charge_idx;
495 random1 = m_dedx_hists[hist_idx].GetRandom();
496 beta_temp1 = (m_bgRange[range_idx] +
497 m_bgRange[range_idx + 1]) / 2;
498 standard1 = GetValDedxCurve(beta_temp1,
charge);
499 dedx1 = random1 + fitval - standard1;
510 beta_temp1 = (m_bgRange[range_idx - 1] +
511 m_bgRange[range_idx]) / 2;
512 standard1 = GetValDedxCurve(beta_temp1,
charge);
515 beta_temp2 = (m_bgRange[range_idx + 1] +
516 m_bgRange[range_idx + 2]) / 2;
517 standard2 = GetValDedxCurve(beta_temp2,
charge);
520 bg_idx = (G4int)(range_idx / 2);
521 hist_idx = bg_idx * 2 * m_numTheta + angle_idx * 2 + charge_idx;
522 random1 = m_dedx_hists[hist_idx].GetRandom();
526 hist_idx = bg_idx * 2 * m_numTheta + angle_idx * 2 + charge_idx;
527 random2 = m_dedx_hists[hist_idx].GetRandom();
530 dedx1 = random1 + fitval - standard1;
531 dedx2 = random2 + fitval - standard2;
532 dedx = (dedx2 * (
x - m_bgRange[range_idx]) +
533 dedx1 * (m_bgRange[range_idx + 1] - x)) /
534 (m_bgRange[range_idx + 1] - m_bgRange[range_idx]);
555 m_costheta =
cos(theta);
566G4double BesMdcSD::GetValDedxCurve(G4double x, G4double
charge)
573 std::vector<G4double> par;
578 dedxflag = m_pDedxCurSvc->
getCurve(0);
580 for (G4int i = 1; i < size; i++) {
581 par.push_back(m_pDedxCurSvc->
getCurve(i));
591 G4double partA = par[0] * pow(sqrt(x * x + 1), par[2]) / pow(x, par[2]) *
592 (par[1] - par[5] * log(pow(1 / x, par[3]))) -
593 par[4] +
exp(par[6] + par[7] * x);
594 G4double partB = par[8] * pow(x, 3) + par[9] * pow(x, 2) + par[10] *
x + par[11];
595 G4double partC = - par[12] * log(par[15] + pow(1 / x, par[13])) + par[14];
597 val = 550 * (
A * partA +
B * partB +
C * partC);
607G4int BesMdcSD::GetBetagammaIndex(G4double
bg)
609 if (
bg < m_bgRange[0])
return -1;
610 for (G4int i = 0; i < m_numBg - 1; i++)
612 if (
bg > m_bgRange[i] &&
bg < m_bgRange[i + 1])
617 if (
bg > m_bgRange[m_numBg - 1])
618 return (m_numBg - 1);
628G4int BesMdcSD::GetAngleIndex(G4double theta)
630 if (m_version == 0) {
631 if (fabs(
cos(theta)) >= 0.93)
return 9;
632 return (G4int)(fabs(
cos(theta)) * 10 / 0.93);
635 G4double cos_min = -0.93;
636 G4double cos_max = 0.93;
637 G4int nbin = m_numTheta;
638 G4double cos_step = (cos_max - cos_min) / nbin;
640 if (
cos(theta) < cos_min)
return 0;
641 else if (cos_min <
cos(theta) &&
cos(theta) < cos_max) {
642 return (G4int)((
cos(theta) - cos_min) / cos_step);
644 else return nbin - 1;
653G4int BesMdcSD::GetChargeIndex(G4int
charge)
656 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)