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 m_dedx_hists =
new TH1F[m_numDedxHists];
74 for (G4int i = 0; i < m_numBg; i++)
76 m_bgRange.push_back(pDedxSimData->getRange(i));
78 for (G4int i = 0; i < m_numDedxHists; i++)
80 m_dedx_hists[i] = pDedxSimData->getHist(i);
85 sc = Gaudi::svcLocator()->service(
"DedxCurSvc", tmp_dedxCurSvc,
true);
88 std::cout <<
"Could not get DedxCurSvc"
91 m_pDedxCurSvc =
dynamic_cast<DedxCurSvc*
>(tmp_dedxCurSvc);
96 sc = m_tupleMdc->addItem(
"betaGamma",m_betaGamma);
97 sc = m_tupleMdc->addItem(
"fitval",m_fitval);
98 sc = m_tupleMdc->addItem(
"dedx",m_dedx);
99 sc = m_tupleMdc->addItem(
"de",m_de);
102 sc = m_tupleMdc->addItem(
"charge", m_charge);
103 sc = m_tupleMdc->addItem(
"costheta", m_costheta);
108 delete []m_dedx_hists;
114 (SensitiveDetectorName,collectionName[0]);
115 static G4int HCID = -1;
117 { HCID = G4SDManager::GetSDMpointer()->GetCollectionID(collectionName[0]); }
118 HCE->AddHitsCollection( HCID, hitsCollection );
123 truthPointer[i][j]=-1;
132 (SensitiveDetectorName,collectionName[1]);
137{
static G4int HLID=-1;
140 HLID = G4SDManager::GetSDMpointer()->
141 GetCollectionID(collectionName[1]);
143 G4HCofThisEvent* HCE = evt->GetHCofThisEvent();
144 HCE->AddHitsCollection(HLID,truthCollection);
149 G4Track* gTrack = aStep->GetTrack() ;
151 G4double globalT=gTrack->GetGlobalTime();
153 G4cout<<
"MdcSD:error, globalT is nan "<<G4endl;
156 if(globalT > 2000)
return false;
159 G4int charge = gTrack->GetDefinition()->GetPDGCharge();
160 if (charge == 0)
return false;
163 G4double stepLength=aStep->GetStepLength();
169 G4double edep = aStep->GetTotalEnergyDeposit() / stepLength;
170 if(edep==0.)
return false;
173 G4StepPoint* prePoint = aStep->GetPreStepPoint() ;
174 G4StepPoint* postPoint = aStep->GetPostStepPoint() ;
177 G4ThreeVector pointIn = prePoint->GetPosition();
178 G4ThreeVector pointOut = postPoint->GetPosition();
181 const G4VTouchable *touchable = prePoint->GetTouchable();
182 G4VPhysicalVolume *volume = touchable->GetVolume(0);
186 G4double edepTemp = 0;
187 G4double lengthTemp = 0;
189 G4int layerId = touchable->GetVolume(1)->GetCopyNo();
190 if(volume->IsReplicated()){
191 cellId = touchable->GetReplicaNumber();
193 cellId=touchable->GetVolume(0)->GetCopyNo();
195 if(layerId==18&&(cellId==27||cellId==42))
return false;
200 if(layerId >= 36) layerId = 36 + (layerId-36)/2;
203 G4double halfLayerLength=mdcGeomSvc->
Layer(layerId)->
Length()/2.;
204 if(((fabs(pointIn.z())-halfLayerLength)>-7.)
205 &&((fabs(pointOut.z())-halfLayerLength)>-7.))
return false;
207 G4int trackID= gTrack->GetTrackID();
208 G4int truthID, g4TrackID;
211 G4double theta=gTrack->GetMomentumDirection().theta();
213 G4ThreeVector hitPosition=0;
214 G4double transferT=0;
215 driftD =
Distance(layerId,cellId,pointIn,pointOut,hitPosition,transferT);
217 G4double posPhi, wirePhi;
218 posPhi=hitPosition.phi();
219 if(posPhi<0)posPhi += 2*
pi;
220 wirePhi=mdcGeoPointer->
SignalWire(layerId,cellId).
Phi(hitPosition.z());
229 if(posPhi < 1. && wirePhi > 5.)posFlag = 1;
230 if(posPhi > 5. && wirePhi < 1.)posFlag = 0;
232 G4ThreeVector hitLine=pointOut-pointIn;
233 G4double enterAngle=hitLine.phi()-wirePhi;
234 while(enterAngle<-
pi/2.)enterAngle+=
pi;
235 while(enterAngle>
pi/2.)enterAngle-=
pi;
238 G4double betaGamma=aStep->GetPreStepPoint()->GetBeta() * aStep->GetPreStepPoint()->GetGamma();
239 if(betaGamma<0.01)
return false;
242 G4double eCount=dedxSample(betaGamma, charge, theta);
252 newHit->
SetPos(hitPosition);
261 driftT=mdcCalPointer->
D2T(driftD);
268 if (hitPointer[layerId][cellId] == -1) {
269 hitsCollection->insert(newHit);
270 G4int NbHits = hitsCollection->entries();
271 hitPointer[layerId][cellId]=NbHits-1;
275 G4int pointer=hitPointer[layerId][cellId];
276 if (g4TrackID == trackID) {
277 G4double preDriftT=(*hitsCollection)[pointer]->GetDriftT();
280 G4double preDriftT = (*hitsCollection)[pointer]->GetDriftT();
281 if (driftT < preDriftT) {
282 (*hitsCollection)[pointer]->SetTrackID(truthID);
284 (*hitsCollection)[pointer]->SetDriftD(driftD);
285 (*hitsCollection)[pointer]->SetDriftT(driftT);
286 (*hitsCollection)[pointer]->SetPos(hitPosition);
287 (*hitsCollection)[pointer]->SetGlobalT(globalT);
288 (*hitsCollection)[pointer]->SetTheta(theta);
289 (*hitsCollection)[pointer]->SetPosFlag(posFlag);
290 (*hitsCollection)[pointer]->SetEnterAngle(enterAngle);
298 if(g4TrackID==trackID){
299 G4int pointer=truthPointer[layerId][cellId];
306 truthHit->
SetPos (hitPosition);
314 truthCollection->insert(truthHit);
315 G4int NbHits = truthCollection->entries();
316 truthPointer[layerId][cellId]=NbHits-1;
319 if(truthID == (*truthCollection)[pointer]->GetTrackID()){
320 G4double preDriftT=(*truthCollection)[pointer]->GetDriftT();
321 if(driftT<preDriftT){
322 (*truthCollection)[pointer]->SetDriftD(driftD);
323 (*truthCollection)[pointer]->SetDriftT(driftT);
324 (*truthCollection)[pointer]->SetPos(hitPosition);
325 (*truthCollection)[pointer]->SetGlobalT(globalT);
326 (*truthCollection)[pointer]->SetTheta(theta);
327 (*truthCollection)[pointer]->SetPosFlag(posFlag);
328 (*truthCollection)[pointer]->SetEnterAngle(enterAngle);
330 edepTemp=(*truthCollection)[pointer]->GetEdep();
331 (*truthCollection)[pointer]->SetEdep(edepTemp+edep);
338 truthHit->
SetPos(hitPosition);
346 truthCollection->insert(truthHit);
347 G4int NbHits = truthCollection->entries();
348 truthPointer[layerId][cellId]=NbHits-1;
362 if (verboseLevel>0) {
363 hitsCollection->PrintAllHits();
373G4double
BesMdcSD::Distance(G4int layerId, G4int cellId, G4ThreeVector pointIn, G4ThreeVector pointOut,G4ThreeVector& hitPosition,G4double& transferT)
383 G4double t1,distance,dInOut,dHitIn,dHitOut;
385 G4ThreeVector east=mdcGeomSvc->
Wire(layerId,cellId)->
Backward();
386 G4ThreeVector west=mdcGeomSvc->
Wire(layerId,cellId)->
Forward();
387 G4ThreeVector wireLine=east-west;
388 G4ThreeVector hitLine=pointOut-pointIn;
390 G4ThreeVector hitXwire=hitLine.cross(wireLine);
391 G4ThreeVector wire2hit=east-pointOut;
394 if(hitXwire.mag()==0){
395 distance=wireLine.cross(wire2hit).mag()/wireLine.mag();
398 t1=hitXwire.dot(wire2hit.cross(wireLine))/hitXwire.mag2();
399 hitPosition=pointOut+t1*hitLine;
401 dInOut=(pointOut-pointIn).mag();
402 dHitIn=(hitPosition-pointIn).mag();
403 dHitOut=(hitPosition-pointOut).mag();
404 if(dHitIn<=dInOut && dHitOut<=dInOut){
405 distance=fabs(wire2hit.dot(hitXwire)/hitXwire.mag());
406 }
else if(dHitOut>dHitIn){
407 distance=wireLine.cross(pointIn-east).mag()/wireLine.mag();
410 distance=wireLine.cross(pointOut-east).mag()/wireLine.mag();
411 hitPosition=pointOut;
416 G4double halfLayerLength=mdcGeomSvc->
Layer(layerId)->
Length()/2.;
417 G4double halfWireLength=wireLine.mag()/2.;
418 G4double transferZ=0;
420 transferZ=halfLayerLength+hitPosition.z();
422 transferZ=halfLayerLength-hitPosition.z();
425 transferT=transferZ*halfWireLength/halfLayerLength/220;
427 transferT=transferZ*halfWireLength/halfLayerLength/240;
436 dEdE_mylanfunc =
new TF1(
"dEdE_mylanfunc",
437 "[3]*TMath::Exp([2]*((x[0]-[0])/[1]+TMath::Exp(-1*((x[0]-[0])/[1]))))",
441 dEdE_mylanfunc->SetParNames(
"MPV",
"Sigma",
"constant1",
"constant2");
444G4double BesMdcSD::dedxSample(G4double betagamma, G4double charge, G4double theta)
446 G4double
x = betagamma;
447 G4double fitval = GetValDedxCurve(x, charge);
448 if(fitval <= 0)
return 0;
450 G4double random1, random2, dedx1, dedx2, de;
451 G4double standard1, standard2, beta_temp1, beta_temp2;
454 G4int range_idx, bg_idx, angle_idx, charge_idx, hist_idx;
455 range_idx = GetBetagammaIndex(betagamma);
456 angle_idx = GetAngleIndex(theta);
457 charge_idx = GetChargeIndex(charge);
464 hist_idx = bg_idx * 2 * 10 + angle_idx * 2 + charge_idx;
465 random1 = m_dedx_hists[hist_idx].GetRandom();
466 beta_temp1 = (m_bgRange[0] + m_bgRange[1]) / 2;
467 standard1 = GetValDedxCurve(beta_temp1, charge);
468 dedx = random1 + fitval - standard1;
471 else if (range_idx == m_numBg - 1)
475 bg_idx = (G4int)(range_idx / 2);
476 hist_idx = bg_idx * 2 * 10 + angle_idx * 2 + charge_idx;
477 random1 = m_dedx_hists[hist_idx].GetRandom();
478 beta_temp1 = (m_bgRange[m_numBg - 2] +
479 m_bgRange[m_numBg - 1]) / 2;
480 standard1 = GetValDedxCurve(beta_temp1, charge);
481 dedx = random1 + fitval - standard1;
487 if (range_idx % 2 == 0)
491 bg_idx = (G4int)(range_idx / 2);
492 hist_idx = bg_idx * 2 * 10 + angle_idx * 2 + charge_idx;
493 random1 = m_dedx_hists[hist_idx].GetRandom();
494 beta_temp1 = (m_bgRange[range_idx] +
495 m_bgRange[range_idx + 1]) / 2;
496 standard1 = GetValDedxCurve(beta_temp1, charge);
497 dedx1 = random1 + fitval - standard1;
508 beta_temp1 = (m_bgRange[range_idx - 1] +
509 m_bgRange[range_idx]) / 2;
510 standard1 = GetValDedxCurve(beta_temp1, charge);
513 beta_temp2 = (m_bgRange[range_idx + 1] +
514 m_bgRange[range_idx + 2]) / 2;
515 standard2 = GetValDedxCurve(beta_temp2, charge);
518 bg_idx = (G4int)(range_idx / 2);
519 hist_idx = bg_idx * 2 * 10 + angle_idx * 2 + charge_idx;
520 random1 = m_dedx_hists[hist_idx].GetRandom();
524 hist_idx = bg_idx * 2 * 10 + angle_idx * 2 + charge_idx;
525 random2 = m_dedx_hists[hist_idx].GetRandom();
528 dedx1 = random1 + fitval - standard1;
529 dedx2 = random2 + fitval - standard2;
530 dedx = (dedx2 * (
x - m_bgRange[range_idx]) +
531 dedx1 * (m_bgRange[range_idx + 1] - x)) /
532 (m_bgRange[range_idx + 1] - m_bgRange[range_idx]);
553 m_costheta =
cos(theta);
564G4double BesMdcSD::GetValDedxCurve(G4double x, G4double charge)
571 std::vector<G4double> par;
576 dedxflag = m_pDedxCurSvc->
getCurve(0);
578 for (G4int i = 1; i < size; i++) {
579 par.push_back(m_pDedxCurSvc->
getCurve(i));
589 G4double partA = par[0] * pow(sqrt(x * x + 1), par[2]) / pow(x, par[2]) *
590 (par[1] - par[5] * log(pow(1 / x, par[3]))) -
591 par[4] +
exp(par[6] + par[7] * x);
592 G4double partB = par[8] * pow(x, 3) + par[9] * pow(x, 2) + par[10] *
x + par[11];
593 G4double partC = - par[12] * log(par[15] + pow(1 / x, par[13])) + par[14];
595 val = 550 * (
A * partA +
B * partB +
C * partC);
605G4int BesMdcSD::GetBetagammaIndex(G4double
bg)
607 if (
bg < m_bgRange[0])
return -1;
608 for (G4int i = 0; i < m_numBg - 1; i++)
610 if (
bg > m_bgRange[i] &&
bg < m_bgRange[i + 1])
615 if (
bg > m_bgRange[m_numBg - 1])
616 return (m_numBg - 1);
625G4int BesMdcSD::GetAngleIndex(G4double theta)
627 if (m_version == 0) {
628 if (fabs(
cos(theta)) >= 0.93)
return 9;
629 return (G4int)(fabs(
cos(theta)) * 10 / 0.93);
632 double cos_min = -0.93;
633 double cos_max = 0.93;
635 double cos_step = (cos_max - cos_min) / nbin;
637 if (
cos(theta) < cos_min)
return 0;
638 else if (cos_min <
cos(theta) &&
cos(theta) < cos_max) {
639 return (
int)((
cos(theta) - cos_min) / cos_step);
641 else return nbin - 1;
650G4int BesMdcSD::GetChargeIndex(G4int charge)
652 if (charge > 0)
return 0;
653 if (charge == 0)
return -1;
654 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)