25 fDx(0.), fDy(0.), fDz(0.), fIsSet(kFALSE)
35 for (Int_t side = 0; side < 2; side++) {
44 (1. - ctcoeff ) * qCurrent + ctcoeff *
fStripCharge[side][1];
47 for (Int_t strip = 1; strip < nStrips - 1; strip++) {
52 ( 1. - 2. * ctcoeff ) * qCurrent;
59 ctcoeff * qLeft + ( 1. - ctcoeff ) * qCurrent;
70 TClonesArray* hitArray,
BmnEvent* event,
77 Int_t nClusters = clusters.size();
83 vector<Int_t> frontClusters;
84 vector<Int_t> backClusters;
86 for (Int_t iCluster = 0; iCluster < nClusters; iCluster++) {
91 frontClusters.push_back(iCluster);
94 else if ( side == 1 ) {
95 backClusters.push_back(iCluster);
99 LOG(fatal) << GetName() <<
": Illegal side qualifier "
102 LOG(debug3) << GetName() <<
": " << nClusters <<
" clusters (front "
103 << frontClusters.size() <<
", back " << backClusters.size()
107 for (Int_t iClusterF = 0; iClusterF < nClustersF; iClusterF++) {
108 BmnSsdCluster* clusterF = clusters[frontClusters[iClusterF]];
109 for (Int_t iClusterB = 0; iClusterB < nClustersB; iClusterB++) {
118 LOG(debug4) << GetName() <<
": Cluster front " << iClusterF
119 <<
", cluster back " << iClusterB
120 <<
", intersections " << nOfHits;
127 LOG(debug3) << GetName() <<
": Clusters " << nClusters <<
" ( "
128 << nClustersF <<
" / " << nClustersB <<
" ), hits: "
144 Int_t iChannel = Int_t(centre);
145 Double_t xDif = centre - Double_t(iChannel);
150 iStrip = stripSide.first;
151 side = stripSide.second;
155 xCluster = (Double_t(iStrip) + xDif + 0.5 ) *
GetPitch(side);
172 LOG(debug4) << GetName() <<
": Cluster centre " << centre
173 <<
", sensor index " <<
GetIndex() <<
", side "
174 << side <<
", cluster position " << xCluster
184 if ( x < -
fDx/2. )
return kFALSE;
185 if ( x >
fDx/2. )
return kFALSE;
186 if ( y < -
fDy/2. )
return kFALSE;
187 if ( y >
fDy/2. )
return kFALSE;
200 Double_t driftZ = 0.;
201 if ( chargeType == 0 ) driftZ =
fDz / 2. - z;
202 else if ( chargeType == 1 ) driftZ =
fDz / 2. + z;
204 LOG(error) << GetName() <<
": illegal charge type " << chargeType
226 Double_t shift = muHall * bY * driftZ * 1.e-4;
227 LOG(debug4) << GetName() <<
": Drift " << driftZ
228 <<
" cm, mobility " << muHall
229 <<
" cm**2/(Vs), field " << bY
230 <<
" T, shift " << shift <<
" cm";
242 LOG(info) << GetName() <<
": Charge status: \n";
243 for (Int_t side = 0; side < 2; side++) {
244 for (Int_t strip = 0; strip <
GetNofStrips(side); strip++) {
246 LOG(info) <<
" " << (side ?
"Back " :
"Front ") <<
"strip "
247 << strip <<
" charge " <<
fStripCharge[side][strip] <<
"\n";
250 LOG(info) <<
" Total: front side "
263 LOG(fatal) << fName <<
": sensor is not initialised!"
270 LOG(debug3) << GetName() <<
": Processing point " << point->
ToString()
285 if ( FairLogger::GetLogger()->IsLogNeeded(DEBUG4) ) {
286 LOG(debug4) << GetName() <<
": Status before cross talk"
291 LOG(debug4) << GetName() <<
": Cross-talk coefficient is "
297 if ( FairLogger::GetLogger()->IsLogNeeded(DEBUG3) )
304 Int_t nCharges[2] = { 0, 0 };
305 for (Int_t side = 0; side < 2; side ++) {
307 for (Int_t strip = 0; strip <
GetNofStrips(side); strip++) {
318 nSignals = 1000 * nCharges[0] + nCharges[1];
330 Double_t chargeTotal =
336 Double_t xP = 0.5 * ( point->
GetX1() + point->
GetX2() );
337 Double_t yP = 0.5 * ( point->
GetY1() + point->
GetY2() );
338 Double_t zP = 0.5 * ( point->
GetZ1() + point->
GetZ2() );
346 Double_t eKin = TMath::Sqrt( point->
GetP() * point->
GetP() + mass * mass )
350 Double_t trajLx = point->
GetX2() - point->
GetX1();
351 Double_t trajLy = point->
GetY2() - point->
GetY1();
352 Double_t trajLz = point->
GetZ2() - point->
GetZ1();
353 Double_t trajLength = TMath::Sqrt( trajLx*trajLx +
359 Double_t stepSizeTarget = 3.e-4;
360 Int_t nSteps = TMath::Nint( trajLength / stepSizeTarget );
361 if ( nSteps == 0 ) nSteps = 1;
362 Double_t stepSize = trajLength / nSteps;
363 Double_t stepSizeX = trajLx / nSteps;
364 Double_t stepSizeY = trajLy / nSteps;
365 Double_t stepSizeZ = trajLz / nSteps;
368 Double_t chargePerStep = chargeTotal / nSteps;
369 LOG(debug3) << GetName() <<
": Trajectory length " << trajLength
370 <<
" cm, steps " << nSteps <<
", step size " << stepSize * 1.e4
371 <<
" mu, charge per step " << chargePerStep;
379 Double_t chargeSum = 0.;
380 Double_t xStep = point->
GetX1() - 0.5 * stepSizeX;
381 Double_t yStep = point->
GetY1() - 0.5 * stepSizeY;
382 Double_t zStep = point->
GetZ1() - 0.5 * stepSizeZ;
383 for (Int_t iStep = 0; iStep < nSteps; iStep++ ) {
389 Double_t chargeInStep = chargePerStep;
393 chargeSum += chargeInStep;
409 for (Int_t side = 0; side < 2; side++) {
410 for (Int_t strip = 0; strip <
GetNofStrips(side); strip++)
411 fStripCharge[side][strip] *= ( chargeTotal / chargeSum );
423 Double_t time)
const {
427 LOG(error) << GetName() <<
": No module connected to sensor "
428 << GetName() <<
", side " << side <<
", strip "
429 << strip <<
", time " << time <<
", charge " << charge
438 LOG(debug4) << fName <<
": Registering charge: side " << side
439 <<
", strip " << strip <<
", time " << time
440 <<
", charge " << charge
441 <<
" to channel " << channel
442 <<
" of module " <<
GetModule()->GetName()
466 for (Int_t sensorId = 0; sensorId < 3; sensorId++ ) {
467 for (Int_t side = 0; side < 2; side ++ ) {
468 for (Int_t strip = 0; strip <
GetNofStrips(side); strip++ ) {
470 pair<Int_t, Int_t> test =
GetStrip(channel, sensorId);
471 if ( test.first != strip || test.second != side ) {
472 LOG(error) << fName <<
"Self test failed! Sensor " << sensorId
473 <<
" side " << side <<
" strip " << strip
474 <<
" gives channel " << channel <<
" gives strip "
475 << test.first <<
" side " << test.second
friend F32vec4 fabs(const F32vec4 &a)
Class characterising one event by a collection of links (indices) to data objects,...
Data class for SSD clusters.
Double_t GetPosition() const
Cluster position @value Cluster position in channel number units.
Double_t GetTime() const
Get cluster time.
Double_t GetTimeError() const
Get error of cluster time.
Class representing an element of the SSD setup.
void AddSignal(UShort_t channel, Double_t time, Double_t charge, Int_t index=0, Int_t entry=0, Int_t file=0)
static Double_t ParticleMass(Int_t pid)
Double_t StoppingPower(Double_t eKin, Int_t pid)
static Double_t ElectricField(Double_t vBias, Double_t vFd, Double_t dZ, Double_t z)
Double_t EnergyLoss(Double_t dz, Double_t mass, Double_t eKin, Double_t dedx) const
static Double_t PairCreationEnergy()
static BmnSsdPhysics * Instance()
Double_t GetVbias() const
Double_t GetCrossTalk() const
Double_t GetMeanLorentzShift(Int_t side) const
Double_t HallMobility(Double_t eField, Int_t chargeType) const
virtual Int_t FindHits(std::vector< BmnSsdCluster * > &clusters, TClonesArray *hitArray, BmnEvent *event, Double_t dTime)
Find hits from clusters.
Double_t fDz
Thickness in z [cm].
virtual Int_t GetNofStrips(Int_t side) const =0
Number of strips on front and back side.
void RegisterCharge(Int_t side, Int_t strip, Double_t charge, Double_t time) const
Register the produced charge in one strip to the module.
virtual Int_t IntersectClusters(BmnSsdCluster *clusterF, BmnSsdCluster *clusterB)=0
virtual Double_t GetPitch(Int_t side) const =0
Strip pitch on front and back side.
void PrintChargeStatus() const
Bool_t fIsSet
Flag whether sensor is properly initialised.
BmnSsdSensorDssd(Int_t address=0, TGeoPhysicalNode *node=nullptr, BmnSsdElement *mother=nullptr)
Double_t fDx
Dimension of active area in x [cm].
Double_t fDy
Dimension of active area in y [cm].
virtual void PropagateCharge(Double_t x, Double_t y, Double_t z, Double_t charge, Double_t bY, Int_t side)=0
Int_t GetSide(Double_t channel) const
virtual std::string ToString() const =0
virtual Int_t GetModuleChannel(Int_t strip, Int_t side, Int_t sensorId) const =0
Get the readout channel in the module for a given strip.
Double_t LorentzShift(Double_t z, Int_t chargeType, Double_t bY) const
Lorentz shift in the x coordinate.
void GetClusterPosition(Double_t ClusterCentre, Double_t &xCluster, Int_t &side)
virtual Int_t CalculateResponse(BmnSsdSensorPoint *point)
Analogue response to a track in the sensor.
void ProduceCharge(BmnSsdSensorPoint *point)
Generate charge as response to a sensor point.
virtual std::pair< Int_t, Int_t > GetStrip(Int_t channel, Int_t sensorId) const =0
void CrossTalk(Double_t ctcoeff)
Bool_t IsInside(Double_t x, Double_t y)
Container class for a local point in a SSD sensor.
Double_t GetTime() const
Time [ns].
Double_t GetZ2() const
Exit z coordinate [cm].
Double_t GetX2() const
Exit x coordinate [cm].
std::string ToString() const
Double_t GetZ1() const
Entry z coordinate [cm].
Double_t GetY2() const
Exit y coordinate [cm].
Int_t GetPid() const
Particle ID [PDG].
Double_t GetX1() const
Entry x coordinate [cm].
Double_t GetBy() const
By-Field at midpoint [T].
Double_t GetY1() const
Entry y coordinate [cm].
Double_t GetELoss() const
Energy loss [GeV].
Double_t GetP() const
Momentum magnitude.
Class representing an instance of a sensor in the BMN-SSD.
BmnLink * GetCurrentLink() const
TClonesArray * fHits
Output array for hits. Used in hit finding.
const BmnSsdSensorConditions * GetConditions() const
Int_t GetSensorId() const
BmnSsdModule * GetModule() const
static BmnSsdSetup * Instance()