1#include "MdcSim/BesMdcSD.hh"
2#include "CalibData/Dedx/DedxCalibData.h"
3#include "CalibData/Dedx/DedxSimData.h"
4#include "G4HCofThisEvent.hh"
5#include "G4RunManager.hh"
6#include "G4SDManager.hh"
8#include "G4Svc/IG4Svc.h"
9#include "G4ThreeVector.hh"
10#include "G4UnitsTable.hh"
12#include "GaudiKernel/DataSvc.h"
13#include "SimUtil/ReadBoostRoot.hh"
18#include "GaudiKernel/Bootstrap.h"
19#include "GaudiKernel/IService.h"
20#include "GaudiKernel/Service.h"
21#include "GaudiKernel/SmartDataPtr.h"
26 collectionName.insert(
"BesMdcHitsCollection" );
27 collectionName.insert(
"BesMdcTruthCollection" );
32 StatusCode sc = Gaudi::svcLocator()->service(
"MdcGeomSvc", mdcGeomSvc );
33 if ( !sc.isSuccess() ) std::cout <<
"BesMdcSD::Could not open MdcGeomSvc" << std::endl;
35 sc = Gaudi::svcLocator()->service(
"G4Svc", m_G4Svc );
36 if ( !sc.isSuccess() ) G4cout <<
" MdcSD::Error,could not open G4Svc" << G4endl;
38 if ( m_G4Svc->GetMdcDedxFlag() == 1 )
40 G4cout <<
" MdcSD: Use sampled dedx instead of Geant4 value" << G4endl;
45 sc = Gaudi::svcLocator()->service(
"DedxSimSvc", m_pDedxSimSvc,
true );
46 if ( !sc.isSuccess() ) { std::cout <<
"Could not get DedxSimSvc" << std::endl; }
50 sc = Gaudi::svcLocator()->service(
"DedxCurSvc", m_pDedxCurSvc,
true );
51 if ( !sc.isSuccess() ) { std::cout <<
"Could not get DedxCurSvc" << std::endl; }
53 if ( m_G4Svc->MdcRootFlag() )
55 m_tupleMdc = m_G4Svc->GetTupleMdc();
56 sc = m_tupleMdc->addItem(
"betaGamma", m_betaGamma );
57 sc = m_tupleMdc->addItem(
"fitval", m_fitval );
58 sc = m_tupleMdc->addItem(
"dedx", m_dedx );
59 sc = m_tupleMdc->addItem(
"de", m_de );
62 sc = m_tupleMdc->addItem(
"charge", m_charge );
63 sc = m_tupleMdc->addItem(
"costheta", m_costheta );
71 static G4int HCID = -1;
73 { HCID = G4SDManager::GetSDMpointer()->GetCollectionID( collectionName[0] ); }
74 HCE->AddHitsCollection( HCID, hitsCollection );
76 for ( i = 0; i < 43; i++ )
78 for ( j = 0; j < 288; j++ )
80 hitPointer[i][j] = -1;
81 truthPointer[i][j] = -1;
93 static G4int HLID = -1;
95 { HLID = G4SDManager::GetSDMpointer()->GetCollectionID( collectionName[1] ); }
96 G4HCofThisEvent* HCE = evt->GetHCofThisEvent();
97 HCE->AddHitsCollection( HLID, truthCollection );
101 G4Track* gTrack = aStep->GetTrack();
104 gTrack->GetGlobalTime();
105 if ( std::isnan( globalT ) )
107 G4cout <<
"MdcSD:error, globalT is nan " << G4endl;
110 if ( globalT > 2000 )
return false;
113 G4int charge = gTrack->GetDefinition()->GetPDGCharge();
114 if ( charge == 0 )
return false;
117 G4double stepLength = aStep->GetStepLength();
118 if ( stepLength == 0 )
124 G4double edep = aStep->GetTotalEnergyDeposit() / stepLength;
125 if ( edep == 0. )
return false;
128 G4StepPoint* prePoint = aStep->GetPreStepPoint();
129 G4StepPoint* postPoint = aStep->GetPostStepPoint();
132 G4ThreeVector pointIn = prePoint->GetPosition();
133 G4ThreeVector pointOut = postPoint->GetPosition();
136 const G4VTouchable* touchable = prePoint->GetTouchable();
137 G4VPhysicalVolume* volume = touchable->GetVolume( 0 );
141 G4double edepTemp = 0;
142 G4double lengthTemp = 0;
144 G4int layerId = touchable->GetVolume( 1 )->GetCopyNo();
145 if ( volume->IsReplicated() ) { cellId = touchable->GetReplicaNumber(); }
146 else { cellId = touchable->GetVolume( 0 )->GetCopyNo(); }
147 if ( layerId == 18 && ( cellId == 27 || cellId == 42 ) )
return false;
153 if ( layerId >= 36 ) layerId = 36 + ( layerId - 36 ) / 2;
156 G4double halfLayerLength = mdcGeomSvc->Layer( layerId )->Length() / 2.;
157 if ( ( ( fabs( pointIn.z() ) - halfLayerLength ) > -7. ) &&
158 ( ( fabs( pointOut.z() ) - halfLayerLength ) > -7. ) )
161 G4int trackID = gTrack->GetTrackID();
162 G4int truthID, g4TrackID;
165 G4double theta = gTrack->GetMomentumDirection().theta();
167 G4ThreeVector hitPosition( 0, 0, 0 );
168 G4double transferT = 0;
169 driftD =
Distance( layerId, cellId, pointIn, pointOut, hitPosition, transferT );
171 G4double posPhi, wirePhi;
172 posPhi = hitPosition.phi();
173 if ( posPhi < 0 ) posPhi += 2 *
pi;
175 mdcGeoPointer->SignalWire( layerId, cellId ).Phi( hitPosition.z() );
178 if ( posPhi <= wirePhi ) { posFlag = 0; }
179 else { posFlag = 1; }
181 if ( posPhi < 1. && wirePhi > 5. ) posFlag = 1;
182 if ( posPhi > 5. && wirePhi < 1. ) posFlag = 0;
184 G4ThreeVector hitLine = pointOut - pointIn;
185 G4double enterAngle = hitLine.phi() - wirePhi;
186 while ( enterAngle < -
pi / 2. ) enterAngle +=
pi;
187 while ( enterAngle >
pi / 2. ) enterAngle -=
pi;
189 if ( m_G4Svc->GetMdcDedxFlag() == 1 )
192 aStep->GetPreStepPoint()->GetBeta() * aStep->GetPreStepPoint()->GetGamma();
193 if ( betaGamma < 0.01 )
return false;
196 G4double eCount = dedxSample( betaGamma, charge, theta );
206 newHit->
SetPos( hitPosition );
213 mdcCalPointer->SetHitPointer( newHit );
215 driftT = mdcCalPointer->D2T( driftD );
216 globalT += transferT;
222 if ( hitPointer[layerId][cellId] == -1 )
224 hitsCollection->insert( newHit );
225 G4int NbHits = hitsCollection->entries();
226 hitPointer[layerId][cellId] = NbHits - 1;
230 G4int pointer = hitPointer[layerId][cellId];
231 if ( g4TrackID == trackID )
232 { G4double preDriftT = ( *hitsCollection )[pointer]->GetDriftT(); }
234 G4double preDriftT = ( *hitsCollection )[pointer]->GetDriftT();
235 if ( driftT < preDriftT )
237 ( *hitsCollection )[pointer]->SetTrackID( truthID );
239 ( *hitsCollection )[pointer]->SetDriftD( driftD );
240 ( *hitsCollection )[pointer]->SetDriftT( driftT );
241 ( *hitsCollection )[pointer]->SetPos( hitPosition );
242 ( *hitsCollection )[pointer]->SetGlobalT( globalT );
243 ( *hitsCollection )[pointer]->SetTheta( theta );
244 ( *hitsCollection )[pointer]->SetPosFlag( posFlag );
245 ( *hitsCollection )[pointer]->SetEnterAngle( enterAngle );
252 if ( truthCollection )
254 if ( g4TrackID == trackID )
256 G4int pointer = truthPointer[layerId][cellId];
264 truthHit->
SetPos( hitPosition );
272 truthCollection->insert( truthHit );
273 G4int NbHits = truthCollection->entries();
274 truthPointer[layerId][cellId] = NbHits - 1;
278 if ( truthID == ( *truthCollection )[pointer]->GetTrackID() )
280 G4double preDriftT = ( *truthCollection )[pointer]->GetDriftT();
281 if ( driftT < preDriftT )
283 ( *truthCollection )[pointer]->SetDriftD( driftD );
284 ( *truthCollection )[pointer]->SetDriftT( driftT );
285 ( *truthCollection )[pointer]->SetPos( hitPosition );
286 ( *truthCollection )[pointer]->SetGlobalT( globalT );
287 ( *truthCollection )[pointer]->SetTheta( theta );
288 ( *truthCollection )[pointer]->SetPosFlag( posFlag );
289 ( *truthCollection )[pointer]->SetEnterAngle( enterAngle );
291 edepTemp = ( *truthCollection )[pointer]->GetEdep();
292 ( *truthCollection )[pointer]->SetEdep( edepTemp + edep );
301 truthHit->
SetPos( hitPosition );
309 truthCollection->insert( truthHit );
310 G4int NbHits = truthCollection->entries();
311 truthPointer[layerId][cellId] = NbHits - 1;
324 if ( verboseLevel > 0 )
326 hitsCollection->PrintAllHits();
337 G4ThreeVector pointOut, G4ThreeVector& hitPosition,
338 G4double& transferT ) {
347 G4double t1, distance, dInOut, dHitIn, dHitOut;
349 G4ThreeVector east = mdcGeomSvc->Wire( layerId, cellId )->Backward();
350 G4ThreeVector west = mdcGeomSvc->Wire( layerId, cellId )->Forward();
351 G4ThreeVector wireLine = east - west;
352 G4ThreeVector hitLine = pointOut - pointIn;
354 G4ThreeVector hitXwire = hitLine.cross( wireLine );
355 G4ThreeVector wire2hit = east - pointOut;
358 if ( hitXwire.mag() == 0 )
360 distance = wireLine.cross( wire2hit ).mag() / wireLine.mag();
361 hitPosition = pointIn;
365 t1 = hitXwire.dot( wire2hit.cross( wireLine ) ) / hitXwire.mag2();
366 hitPosition = pointOut + t1 * hitLine;
368 dInOut = ( pointOut - pointIn ).mag();
369 dHitIn = ( hitPosition - pointIn ).mag();
370 dHitOut = ( hitPosition - pointOut ).mag();
371 if ( dHitIn <= dInOut && dHitOut <= dInOut )
373 distance = fabs( wire2hit.dot( hitXwire ) / hitXwire.mag() );
375 else if ( dHitOut > dHitIn )
377 distance = wireLine.cross( pointIn - east ).mag() / wireLine.mag();
378 hitPosition = pointIn;
382 distance = wireLine.cross( pointOut - east ).mag() / wireLine.mag();
383 hitPosition = pointOut;
388 G4double halfLayerLength = mdcGeomSvc->Layer( layerId )->Length() / 2.;
389 G4double halfWireLength = wireLine.mag() / 2.;
390 G4double transferZ = 0;
391 if ( layerId % 2 == 0 )
393 transferZ = halfLayerLength + hitPosition.z();
397 transferZ = halfLayerLength - hitPosition.z();
399 if ( layerId < 8 ) { transferT = transferZ * halfWireLength / halfLayerLength / 220; }
400 else { transferT = transferZ * halfWireLength / halfLayerLength / 240; }
406 dEdE_mylanfunc =
new TF1(
407 "dEdE_mylanfunc",
"[3]*TMath::Exp([2]*((x[0]-[0])/[1]+TMath::Exp(-1*((x[0]-[0])/[1]))))",
410 dEdE_mylanfunc->SetParNames(
"MPV",
"Sigma",
"constant1",
"constant2" );
413G4double BesMdcSD::dedxSample( G4double betagamma, G4double charge, G4double theta ) {
417 m_dedx_hists = m_pDedxSimSvc->
getHist();
418 m_bgRange = m_pDedxSimSvc->
getRange();
419 G4double x = betagamma;
420 G4double fitval = GetValDedxCurve( x, charge );
421 if ( fitval <= 0 )
return 0;
423 G4double random1, random2, dedx1, dedx2, de;
424 G4double standard1, standard2, beta_temp1, beta_temp2;
427 G4int range_idx, bg_idx, angle_idx, charge_idx, hist_idx;
428 range_idx = GetBetagammaIndex( betagamma );
429 angle_idx = GetAngleIndex( theta );
430 charge_idx = GetChargeIndex( charge );
432 if ( range_idx == -1 )
437 hist_idx = bg_idx * 2 * m_numTheta + angle_idx * 2 + charge_idx;
438 random1 = m_dedx_hists->at( hist_idx ).GetRandom();
439 beta_temp1 = ( m_bgRange->at( 0 ) + m_bgRange->at( 1 ) ) / 2;
440 standard1 = GetValDedxCurve( beta_temp1, charge );
441 dedx = random1 + fitval - standard1;
444 else if ( range_idx == m_numBg - 1 )
448 bg_idx = (G4int)( range_idx / 2 );
449 hist_idx = bg_idx * 2 * m_numTheta + angle_idx * 2 + charge_idx;
450 random1 = m_dedx_hists->at( hist_idx ).GetRandom();
451 beta_temp1 = ( m_bgRange->at( m_numBg - 2 ) + m_bgRange->at( m_numBg - 1 ) ) / 2;
452 standard1 = GetValDedxCurve( beta_temp1, charge );
453 dedx = random1 + fitval - standard1;
459 if ( range_idx % 2 == 0 )
463 bg_idx = (G4int)( range_idx / 2 );
464 hist_idx = bg_idx * 2 * m_numTheta + angle_idx * 2 + charge_idx;
465 random1 = m_dedx_hists->at( hist_idx ).GetRandom();
466 beta_temp1 = ( m_bgRange->at( range_idx ) + m_bgRange->at( range_idx + 1 ) ) / 2;
467 standard1 = GetValDedxCurve( beta_temp1, charge );
468 dedx1 = random1 + fitval - standard1;
479 beta_temp1 = ( m_bgRange->at( range_idx - 1 ) + m_bgRange->at( range_idx ) ) / 2;
480 standard1 = GetValDedxCurve( beta_temp1, charge );
483 beta_temp2 = ( m_bgRange->at( range_idx + 1 ) + m_bgRange->at( range_idx + 2 ) ) / 2;
484 standard2 = GetValDedxCurve( beta_temp2, charge );
487 bg_idx = (G4int)( range_idx / 2 );
488 hist_idx = bg_idx * 2 * m_numTheta + angle_idx * 2 + charge_idx;
489 random1 = m_dedx_hists->at( hist_idx ).GetRandom();
493 hist_idx = bg_idx * 2 * m_numTheta + angle_idx * 2 + charge_idx;
494 random2 = m_dedx_hists->at( hist_idx ).GetRandom();
497 dedx1 = random1 + fitval - standard1;
498 dedx2 = random2 + fitval - standard2;
499 dedx = ( dedx2 * (
x - m_bgRange->at( range_idx ) ) +
500 dedx1 * ( m_bgRange->at( range_idx + 1 ) -
x ) ) /
501 ( m_bgRange->at( range_idx + 1 ) - m_bgRange->at( range_idx ) );
509 if ( m_G4Svc->MdcRootFlag() )
521 m_costheta =
cos( theta );
532G4double BesMdcSD::GetValDedxCurve( G4double x, G4double charge ) {
538 std::vector<G4double> par;
543 dedxflag = m_pDedxCurSvc->getCurve( 0 );
544 size = m_pDedxCurSvc->getCurveSize();
545 for ( G4int i = 1; i < size; i++ ) { par.push_back( m_pDedxCurSvc->getCurve( i ) ); }
547 if (
x < 4.5 )
A = 1;
548 else if (
x < 10 )
B = 1;
551 G4double partA = par[0] * pow( sqrt(
x *
x + 1 ), par[2] ) / pow(
x, par[2] ) *
552 ( par[1] - par[5] * log( pow( 1 /
x, par[3] ) ) ) -
553 par[4] +
exp( par[6] + par[7] *
x );
554 G4double partB = par[8] * pow(
x, 3 ) + par[9] * pow(
x, 2 ) + par[10] *
x + par[11];
555 G4double partC = -par[12] * log( par[15] + pow( 1 /
x, par[13] ) ) + par[14];
557 val = 550 * (
A * partA +
B * partB +
C * partC );
566G4int BesMdcSD::GetBetagammaIndex( G4double bg ) {
567 if ( bg < m_bgRange->
at( 0 ) )
return -1;
568 for ( G4int i = 0; i < m_numBg - 1; i++ )
570 if ( bg > m_bgRange->at( i ) && bg < m_bgRange->
at( i + 1 ) ) {
return i; }
572 if ( bg > m_bgRange->at( m_numBg - 1 ) )
return ( m_numBg - 1 );
582G4int BesMdcSD::GetAngleIndex( G4double theta ) {
583 if ( m_version == 0 )
585 if ( fabs(
cos( theta ) ) >= 0.93 )
return 9;
586 return (G4int)( fabs(
cos( theta ) ) * 10 / 0.93 );
590 G4double cos_min = -0.93;
591 G4double cos_max = 0.93;
592 G4int nbin = m_numTheta;
593 G4double cos_step = ( cos_max - cos_min ) / nbin;
595 if (
cos( theta ) < cos_min )
return 0;
596 else if ( cos_min <
cos( theta ) &&
cos( theta ) < cos_max )
597 {
return (G4int)( (
cos( theta ) - cos_min ) / cos_step ); }
598 else return nbin - 1;
607G4int BesMdcSD::GetChargeIndex( G4int charge ) {
608 if ( charge > 0 )
return 0;
609 if ( charge == 0 )
return -1;
610 if ( charge < 0 )
return 1;
************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)
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
static BesMdcGeoParameter * GetGeo(void)
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
BesSensitiveDetector(const G4String name)
virtual std::vector< double > * getRange()=0
virtual std::vector< TH1F > * getHist()=0
virtual int getThetaNo()=0
virtual int getRangeNo()=0
virtual int getVersion()=0