BmnRoot
Loading...
Searching...
No Matches
BmnGemStripModule.cxx
Go to the documentation of this file.
1#include "BmnGemStripModule.h"
2
3#include "BmnGemStripDigitizer.h" //AZ-110124
4#include "CbmMCTrack.h" //AZ-110124
5#include "CbmStsPoint.h" //AZ-110124
6#include "FairRunSim.h" //AZ-110124
7#include "TF1.h"
8#include "TH1F.h"
9#include "TRandom.h"
10
11#include <TDatabasePDG.h> //AZ-110124
12#include <TParticlePDG.h> //AZ-110124
13
15{
16
17 Verbosity = true;
18
19 ZStartModulePosition = 0.0;
20
21 DriftGapThickness = 0.3; // cm
22 FirstTransferGapThickness = 0.25; // cm
23 SecondTransferGapThickness = 0.2; // cm
24 InductionGapThickness = 0.15; // cm
25 ModuleThickness =
26 DriftGapThickness + FirstTransferGapThickness + SecondTransferGapThickness + InductionGapThickness; // cm
27
28 ElectronDriftDirection = ForwardZAxisEDrift;
29
30 XMinModule = 0.0;
31 XMaxModule = 0.0;
32 YMinModule = 0.0;
33 YMaxModule = 0.0;
34
35 AvalancheGenerationSeed = 0;
36 AvalancheRadius = 0.10; // cm
37 Gain = 1.0; // gain level (for each electron signal - in RealPointFull or for strip signal - in RealPointFullOne)
38}
39
41 ElectronDriftDirectionInModule edrift_direction,
42 Double_t DriftGap,
43 Double_t FTransferGap,
44 Double_t STransferGap,
45 Double_t InductionGap)
46{
47
48 Verbosity = true;
49
50 ZStartModulePosition = z_start_pos;
51
52 DriftGapThickness = DriftGap; // cm
53 FirstTransferGapThickness = FTransferGap; // cm
54 SecondTransferGapThickness = STransferGap; // cm
55 InductionGapThickness = InductionGap; // cm
56 ModuleThickness =
57 DriftGapThickness + FirstTransferGapThickness + SecondTransferGapThickness + InductionGapThickness; // cm
58
59 ElectronDriftDirection = edrift_direction;
60
61 XMinModule = 0.0;
62 XMaxModule = 0.0;
63 YMinModule = 0.0;
64 YMaxModule = 0.0;
65
66 AvalancheGenerationSeed = 0;
67 AvalancheRadius = 0.10; // cm
68 Gain = 1.0;
69}
70
72
74{
75 if (ElectronDriftDirection == ForwardZAxisEDrift) {
76 return ZStartModulePosition + DriftGapThickness * 0.5;
77 } else {
78 return ZStartModulePosition + ModuleThickness - DriftGapThickness * 0.5;
79 }
80}
81
83{
84 StripLayers.push_back(strip_layer);
85
86 DefineModuleBorders();
87}
88
89Bool_t BmnGemStripModule::SetStripSignalInLayer(Int_t layer_num, Int_t strip_num, Double_t signal)
90{
91 if (layer_num >= 0 && layer_num < (int)StripLayers.size()) {
92 return StripLayers[layer_num].SetStripSignal(strip_num, signal);
93 }
94 return false;
95}
96
97Bool_t BmnGemStripModule::AddStripSignalInLayer(Int_t layer_num, Int_t strip_num, Double_t signal)
98{
99 if (layer_num >= 0 && layer_num < (int)StripLayers.size()) {
100 return StripLayers[layer_num].AddStripSignal(strip_num, signal);
101 }
102 return false;
103}
104
105Bool_t BmnGemStripModule::SetStripMatchInLayer(Int_t layer_num, Int_t strip_num, BmnMatch mc_match)
106{
107 if (layer_num >= 0 && layer_num < (int)StripLayers.size()) {
108 return StripLayers[layer_num].SetStripMatch(strip_num, mc_match);
109 }
110 return false;
111}
112
113Bool_t BmnGemStripModule::SetStripDigitNumberMatchInLayer(Int_t layer_num, Int_t strip_num, BmnMatch digit_num_match)
114{
115 if (layer_num >= 0 && layer_num < (int)StripLayers.size()) {
116 return StripLayers[layer_num].SetStripDigitNumberMatch(strip_num, digit_num_match);
117 }
118 return false;
119}
120
121Double_t BmnGemStripModule::GetStripSignalInLayer(Int_t layer_num, Int_t strip_num)
122{
123 if (layer_num >= 0 && layer_num < (int)StripLayers.size()) {
124 return StripLayers[layer_num].GetStripSignal(strip_num);
125 }
126 return -1;
127}
128
129BmnMatch BmnGemStripModule::GetStripMatchInLayer(Int_t layer_num, Int_t strip_num)
130{
131 if (layer_num >= 0 && layer_num < (int)StripLayers.size()) {
132 return StripLayers[layer_num].GetStripMatch(strip_num);
133 }
134 return BmnMatch();
135}
136
138{
139 if (layer_num >= 0 && layer_num < (int)StripLayers.size()) {
140 return StripLayers[layer_num].GetStripDigitNumberMatch(strip_num);
141 }
142 return BmnMatch();
143}
144
146{
147 for (size_t ilayer = 0; ilayer < StripLayers.size(); ++ilayer) {
148 StripLayers[ilayer].ResetLayer();
149 }
150
151 DefineModuleBorders();
152
156
158}
159
160Bool_t BmnGemStripModule::IsPointInsideModule(Double_t x, Double_t y)
161{
162 for (size_t ilayer = 0; ilayer < StripLayers.size(); ++ilayer) {
163 if (StripLayers[ilayer].IsPointInsideStripLayer(x, y))
164 return true;
165 }
166 return false;
167}
168
169Bool_t BmnGemStripModule::IsPointInsideModule(Double_t x, Double_t y, Double_t z)
170{
171 // old condition: if( z >= ZStartModulePosition && z <= (ZStartModulePosition+ModuleThickness) )
172 Double_t coord_eps = 0.01; // 100 um
173 if (((z > ZStartModulePosition) || (fabs(z - ZStartModulePosition) < coord_eps))
174 && ((z < (ZStartModulePosition + ModuleThickness))
175 || (fabs(z - (ZStartModulePosition + ModuleThickness))) < coord_eps))
176 {
177 if (IsPointInsideModule(x, y))
178 return true;
179 }
180 return false;
181}
182
184{
185 Double_t coord_eps = 0.01; // 100 um
186 if (((z > ZStartModulePosition) || (fabs(z - ZStartModulePosition) < coord_eps))
187 && ((z < (ZStartModulePosition + ModuleThickness))
188 || (fabs(z - (ZStartModulePosition + ModuleThickness))) < coord_eps))
189 {
190 return true;
191 }
192 return false;
193}
194
195// Add point with full realistic behaviour (tracking through the module, avalanche effects)
197 Double_t y,
198 Double_t z,
199 Double_t px,
200 Double_t py,
201 Double_t pz,
202 Double_t signal,
203 Int_t refID)
204{
205
206 // Condition: a start point is inside the module and outside its dead zone (in strip layers)
207 if (IsPointInsideModule(x, y)) {
208
209 // AZ-260322 gRandom->SetSeed(AvalancheGenerationSeed);
210
211 // AZ-110124 - simulation of ionization clusters
212 BmnGemStripDigitizer* digi = (BmnGemStripDigitizer*)FairRunSim::Instance()->GetTask("GemDigitizer");
213 TClonesArray* points = digi->GetMCPoints();
214 TClonesArray* mctracks = digi->GetMCTracks();
215 CbmStsPoint* point = (CbmStsPoint*)points->UncheckedAt(refID);
216 TVector3 mom;
217 point->Momentum(mom);
218 CbmMCTrack* mcTr = (CbmMCTrack*)mctracks->UncheckedAt(point->GetTrackID());
219 TParticlePDG* part = TDatabasePDG::Instance()->GetParticle(mcTr->GetPdgCode());
220 Double_t mnoc = 1.0, mass = 3.7283999; // He4
221 if (part)
222 mass = part->Mass();
223 if (mass > 0.0001) {
224 TLorentzVector lorv;
225 lorv.SetVectM(mom, mass);
226 Double_t beta = lorv.Beta();
227 Double_t gamma = lorv.Gamma();
228 Double_t charge = (part) ? part->Charge() / 3 : 1;
229 mnoc = GetNumberOfClusters(beta, gamma, charge, 1.787, 12.33);
230 if (mnoc < 0.5)
231 return kFALSE;
232 // cout << " ***clus*** " << mass << " " << beta << " " << gamma << " " << mnoc << endl;
233 }
234 // AZ
235
236 // Distance from entry point (x,y,z) to exit point (along z-axis)
237 Double_t z_distance_from_in_to_out;
238
239 // Condition: track direction along z-axis
240 if (pz > 0.0) {
241 z_distance_from_in_to_out = ModuleThickness - (z - ZStartModulePosition);
242 } else {
243 z_distance_from_in_to_out = z - ZStartModulePosition;
244 }
245
246 // Condition: track distance along z-axis must be not zero
247 if (z_distance_from_in_to_out <= 0.0) {
248 if (Verbosity)
249 cerr << "WARNING: BmnGemStripModule::AddRealPointFull(): Point (" << x << " : " << y << " : " << z
250 << ") has a track with an incorrect length\n";
251 return false;
252 }
253
254 // Scale coefficient of the track vector (the path from entry point to exit point)
255 Double_t vector_coeff = fabs(z_distance_from_in_to_out / pz);
256
257 // Components of the track vector
258 Double_t x_vec_from_in_to_out = vector_coeff * px;
259 Double_t y_vec_from_in_to_out = vector_coeff * py;
260 Double_t z_vec_from_in_to_out = vector_coeff * pz;
261
262 // Exit point coordinates (x_out, y_out, z_out)
263 Double_t x_out = x + x_vec_from_in_to_out;
264 Double_t y_out = y + y_vec_from_in_to_out;
265 // Double_t z_out = z + z_vec_from_in_to_out;
266
267 // Check if the exit point is outside the module then calculate new x_out, y_out, z_out values
268 // Condition: x-coordinate of the exit point is inside the module
269 if (x_out < XMinModule || x_out > XMaxModule) {
270 if (x_out < XMinModule)
271 x_out = XMinModule;
272 if (x_out > XMaxModule)
273 x_out = XMaxModule;
274
275 x_vec_from_in_to_out = x_out - x;
276 vector_coeff = x_vec_from_in_to_out / px;
277
278 y_vec_from_in_to_out = vector_coeff * py;
279 z_vec_from_in_to_out = vector_coeff * pz;
280
281 y_out = y + y_vec_from_in_to_out;
282 // z_out = z + z_vec_from_in_to_out;
283 }
284 // Condition: y-coordinate of the exit point is inside the module
285 if (y_out < YMinModule || y_out > YMaxModule) {
286 if (y_out < YMinModule)
287 y_out = YMinModule;
288 if (y_out > YMaxModule)
289 y_out = YMaxModule;
290
291 y_vec_from_in_to_out = y_out - y;
292 vector_coeff = y_vec_from_in_to_out / py;
293
294 x_vec_from_in_to_out = vector_coeff * px;
295 z_vec_from_in_to_out = vector_coeff * pz;
296
297 x_out = x + x_vec_from_in_to_out;
298 // z_out = z + z_vec_from_in_to_out;
299 }
300 //----------------------------------------------------------------------
301
302 // Common track length (Fix: a square root!)
303 Double_t track_length =
304 std::sqrt((x_vec_from_in_to_out) * (x_vec_from_in_to_out) + (y_vec_from_in_to_out) * (y_vec_from_in_to_out)
305 + (z_vec_from_in_to_out) * (z_vec_from_in_to_out));
306
307 Double_t current_length = 0.0; // traversed length (counter)
308 Double_t current_length_ratio = 0.0; // ratio of the traversed length to common track length (counter)
309
310 // Int_t collisions_cnt = 0; //total collision counter
311 Double_t current_step = 0.0; // current distance between two collision points
312
313 // Collection of collision points
314 std::vector<CollPoint> collision_points;
315
316 while (current_length < track_length) {
317
318 // Reading the MCD value (mean collision distance = mean free flight path) [cm]
320 MCD = 1 / mnoc; // AZ-110124
321
322 current_step = gRandom->Exp(MCD);
323 current_length += current_step;
324
325 if (current_length > track_length)
326 break;
327
328 current_length_ratio = current_length / track_length;
329
330 Double_t current_x = x + current_length_ratio * x_vec_from_in_to_out;
331 Double_t current_y = y + current_length_ratio * y_vec_from_in_to_out;
332 Double_t current_z = z + current_length_ratio * z_vec_from_in_to_out;
333
334 collision_points.push_back(CollPoint(current_x, current_y, current_z));
335
336 // collisions_cnt++;
337 }
338
339 // Each level - distance to the readout plane
340 Double_t level1 = InductionGapThickness;
341 Double_t level2 = InductionGapThickness + SecondTransferGapThickness;
342 Double_t level3 = InductionGapThickness + SecondTransferGapThickness + FirstTransferGapThickness;
343 // Double_t level4 =
344 // InductionGapThickness+SecondTransferGapThickness+FirstTransferGapThickness+DriftGapThickness; // not used yet
345
346 // Mean electron shift along x-axis (under the influence of the Lorentz force)
347 Double_t xmean; // the dependence fitted by polynomial: f(x) = (p0 + p1*x + p2*x^2 + p3*x^3)
348
349 // Sigma electron smearing
350 Double_t sigma; // the dependence fitted by polynomial: f(x) = (p0 + p1*x + p2*x^2 + p3*x^3+ p4*x^4 + p5*x^5)
351
352 // cout << "$$$ BmnGemStripMedium::GetInstance().NameOfCurrentMedium = " <<
353 // BmnGemStripMedium::GetInstance().NameOfCurrentMedium << "\n"; //test cout
354
355 // Reading the medium configuration -------------------------------------
356 Double_t p0_xmean = BmnGemStripMedium::GetInstance().p0_xmean;
357 Double_t p1_xmean = BmnGemStripMedium::GetInstance().p1_xmean;
358 Double_t p2_xmean = BmnGemStripMedium::GetInstance().p2_xmean;
359 Double_t p3_xmean = BmnGemStripMedium::GetInstance().p3_xmean;
360
361 Double_t p0_sigma = BmnGemStripMedium::GetInstance().p0_sigma;
362 Double_t p1_sigma = BmnGemStripMedium::GetInstance().p1_sigma;
363 Double_t p2_sigma = BmnGemStripMedium::GetInstance().p2_sigma;
364 Double_t p3_sigma = BmnGemStripMedium::GetInstance().p3_sigma;
365 Double_t p4_sigma = BmnGemStripMedium::GetInstance().p4_sigma;
366 Double_t p5_sigma = BmnGemStripMedium::GetInstance().p5_sigma;
367 //----------------------------------------------------------------------
368
369 // Strip cluster in each strip layer
370 Int_t n_strip_layers = StripLayers.size();
371 vector<StripCluster> cluster_layers(n_strip_layers, StripCluster());
372
373 // ouble_t signal_coeff = signal*1E-5;
374
375 // Electron avalanche producing for each collision point at the track
376 for (size_t icoll = 0; icoll < collision_points.size(); ++icoll) {
377
378 Double_t xcoll = collision_points[icoll].x;
379 Double_t ycoll = collision_points[icoll].y;
380 Double_t zcoll = collision_points[icoll].z;
381
382 Double_t zdist; // current z-distance to the readout
383
384 // Find z-distance to the readout depending on the electron drift direction
385 if (ElectronDriftDirection == ForwardZAxisEDrift) {
386 zdist = (ModuleThickness + ZStartModulePosition) - zcoll;
387 } else {
388 zdist = zcoll - ZStartModulePosition;
389 }
390 //------------------------------------------------------------------
391
392 // polynomials
393 xmean = p0_xmean + p1_xmean * zdist + p2_xmean * zdist * zdist + p3_xmean * zdist * zdist * zdist;
394 sigma = p0_sigma + p1_sigma * zdist + p2_sigma * zdist * zdist + p3_sigma * zdist * zdist * zdist
395 + p4_sigma * zdist * zdist * zdist * zdist + p5_sigma * zdist * zdist * zdist * zdist * zdist;
396
397 // Number of electrons in the current collision
398 Int_t n_electrons_cluster = gRandom->Landau(1.027, 0.11);
399 if (n_electrons_cluster < 1)
400 n_electrons_cluster = 1; // min
401 if (n_electrons_cluster > 6)
402 n_electrons_cluster = 6; // max
403
404 for (Int_t ielectron = 0; ielectron < n_electrons_cluster; ++ielectron) {
405
406 // Electron gain in each GEM cascade
407 // Polya distribution is better, but Exponential is good too in our case
408 Double_t gain_gem1 =
409 gRandom->Exp(15); //...->Exp(V), where V is the mean value of the exponential distribution
410 Double_t gain_gem2 = gRandom->Exp(15);
411 Double_t gain_gem3 = gRandom->Exp(15);
412
413 if (gain_gem1 < 1.0)
414 gain_gem1 = 1.0;
415 if (gain_gem2 < 1.0)
416 gain_gem2 = 1.0;
417 if (gain_gem3 < 1.0)
418 gain_gem3 = 1.0;
419
420 int total_gain = 0;
421
422 if (zdist < level1) {
423 total_gain = 1.0;
424 }
425 if (zdist >= level1 && zdist < level2) {
426 total_gain = gain_gem3;
427 }
428 if (zdist >= level2 && zdist < level3) {
429 total_gain = gain_gem3 * gain_gem2;
430 }
431 if (zdist >= level3) {
432 total_gain = gain_gem3 * gain_gem2 * gain_gem1;
433 }
434
435 // Projection of the current electron on the readout (x,y-coordinates)
436 double x_readout, y_readout;
437
438 for (int igain = 0; igain < total_gain; ++igain) {
439
440 // x-shift of the electon depends on the electron drift direction
441 if (ElectronDriftDirection == ForwardZAxisEDrift) {
442 x_readout = gRandom->Gaus(xcoll + xmean, sigma);
443 } else {
444 x_readout = gRandom->Gaus(xcoll - xmean, sigma);
445 }
446
447 y_readout = gRandom->Gaus(ycoll, sigma);
448
449 for (Int_t ilayer = 0; ilayer < n_strip_layers; ++ilayer) {
450 // Condition: end electron position must be inside the layer
451 if (!StripLayers[ilayer].IsPointInsideStripLayer(x_readout, y_readout))
452 continue;
453
454 Double_t strip_pos = StripLayers[ilayer].ConvertPointToStripPosition(x_readout, y_readout);
455 // AZ-100124 - account for strip width
456 Double_t dstrip = strip_pos - (int)strip_pos;
457 if (TMath::Abs(StripLayers[ilayer].GetAngleDeg()) < 1.0) {
458 // Vertical strips
459 // if (strip_pos - (int)strip_pos > 0.2) continue; // strip width 0.16 mm
460 if (dstrip >= 0.4 && dstrip < 0.6)
461 continue; //
462 } else {
463 // Rotated strips
464 // if (strip_pos - (int)strip_pos > 0.85) continue; // strip width 0.68 mm
465 if (dstrip >= 0.3 && dstrip < 0.7)
466 continue; //
467 }
468 // AZ
469
470 // Add strips with signals to lower and upper clusters
471 // StripLayers[ilayer].AddStripSignal((Int_t)strip_pos, 1.0); //Instead of 1.0 we can use Gain
472 // in future
473 cluster_layers[ilayer].AddStrip((Int_t)strip_pos, 1.0);
474 // cluster_layers[ilayer].AddStrip((Int_t)strip_pos, Gain*signal_coeff);
475 }
476 /*
477 //Electron points on the readout (testing) -------------------------------------
478 XElectronPos.push_back(x_readout);
479 YElectronPos.push_back(y_readout);
480 ElectronSignal.push_back(1.0);
481 //------------------------------------------------------------------------------
482 */
483 }
484 }
485 }
486
487 // Calculate cluster parameters -----------------------------------------
488 vector<Double_t> cluster_mean_position(n_strip_layers, 0.0);
489 vector<Double_t> cluster_total_signal(n_strip_layers, 0.0);
490
491 for (Int_t ilayer = 0; ilayer < n_strip_layers; ++ilayer) {
492
493 if (cluster_layers[ilayer].GetClusterSize() > 0) {
494 for (int i = 0; i < cluster_layers[ilayer].GetClusterSize(); ++i) {
495 cluster_mean_position[ilayer] += (cluster_layers[ilayer].Strips[i] + 0.5)
496 * cluster_layers[ilayer].Signals[i]; // as sum of all positions
497 cluster_total_signal[ilayer] += cluster_layers[ilayer].Signals[i];
498 }
499 cluster_mean_position[ilayer] /= cluster_total_signal[ilayer];
500 }
501
502 cluster_layers[ilayer].MeanPosition = cluster_mean_position[ilayer]; // mean cluster position
503 cluster_layers[ilayer].TotalSignal = cluster_total_signal[ilayer]; // total signal of the cluster
504 }
505
506 if (ElectronDriftDirection == ForwardZAxisEDrift) {
507 if (pz > 0.0) {
508 for (Int_t ilayer = 0; ilayer < n_strip_layers; ++ilayer) {
509 cluster_layers[ilayer].OriginPosition = StripLayers[ilayer].ConvertPointToStripPosition(x, y);
510 }
511 } else {
512 for (Int_t ilayer = 0; ilayer < n_strip_layers; ++ilayer) {
513 cluster_layers[ilayer].OriginPosition =
514 StripLayers[ilayer].ConvertPointToStripPosition(x_out, y_out);
515 }
516 }
517 } else {
518 if (pz > 0.0) {
519 for (Int_t ilayer = 0; ilayer < n_strip_layers; ++ilayer) {
520 cluster_layers[ilayer].OriginPosition =
521 StripLayers[ilayer].ConvertPointToStripPosition(x_out, y_out);
522 }
523 } else {
524 for (Int_t ilayer = 0; ilayer < n_strip_layers; ++ilayer) {
525 cluster_layers[ilayer].OriginPosition = StripLayers[ilayer].ConvertPointToStripPosition(x, y);
526 }
527 }
528 }
529
530 for (Int_t ilayer = 0; ilayer < n_strip_layers; ++ilayer) {
531 cluster_layers[ilayer].PositionResidual =
532 cluster_layers[ilayer].MeanPosition - cluster_layers[ilayer].OriginPosition;
533 }
534 //----------------------------------------------------------------------
535 /*
536 //Testing ----------------------------------------------------------------------
537 if(AddedClusters.size() == 0) {
538 for(Int_t ilayer = 0; ilayer < n_strip_layers; ++ilayer) {
539 AddedClusters.push_back(vector<StripCluster>());
540 }
541 }
542
543 for(Int_t ilayer = 0; ilayer < n_strip_layers; ++ilayer) {
544 AddedClusters[ilayer].push_back(cluster_layers[ilayer]);
545 }
546 //------------------------------------------------------------------------------
547 */
548 // Add the correct clusters to the strip layers -------------------------
549 for (Int_t ilayer = 0; ilayer < n_strip_layers; ++ilayer) {
550 for (size_t ielement = 0; ielement < cluster_layers[ilayer].Strips.size(); ++ielement) {
551 Int_t strip_num = cluster_layers[ilayer].Strips.at(ielement);
552 Double_t strip_signal = cluster_layers[ilayer].Signals.at(ielement);
553 StripLayers[ilayer].AddStripSignal(strip_num, strip_signal);
554 }
555 }
556 //----------------------------------------------------------------------
557
558 // Fill strip matches ---------------------------------------------------
559 for (Int_t ilayer = 0; ilayer < n_strip_layers; ++ilayer) {
560 for (size_t ielement = 0; ielement < cluster_layers[ilayer].Strips.size(); ++ielement) {
561 Int_t strip_num = cluster_layers[ilayer].Strips.at(ielement);
562 Double_t strip_signal = cluster_layers[ilayer].Signals.at(ielement);
563 StripLayers[ilayer].AddLinkToStripMatch(strip_num, strip_signal / cluster_layers[ilayer].TotalSignal,
564 refID);
565 }
566 }
567 //----------------------------------------------------------------------
568
569 RealPointsX.push_back(x);
570 RealPointsY.push_back(y);
571 RealPointsMC.push_back(refID);
572
573 return true;
574 } else {
575 if (Verbosity)
576 cerr << "WARNING: BmnGemStripModule::AddRealPointFull(): Point (" << x << " : " << y << " : " << z
577 << ") is out of the readout plane or inside a dead zone\n";
578 return false;
579 }
580}
581
582// Add single point with Gaussian smearing
584 Double_t y,
585 Double_t z,
586 Double_t px,
587 Double_t py,
588 Double_t pz,
589 Double_t signal,
590 Int_t refID)
591{
592
593 if (IsPointInsideModule(x, y)) {
594
595 if (signal <= 0.0)
596 signal = 1e-16;
597
598 Double_t radius = AvalancheRadius;
599 if (radius <= 0.0)
600 return false;
601
602 Int_t cycle_cnt = 0;
603 while (true) {
604 radius = gRandom->Gaus(AvalancheRadius, 0.02);
605 if (radius > AvalancheRadius / 2.0 && radius < AvalancheRadius * 2.0 && radius > 0.0)
606 break;
607 cycle_cnt++;
608
609 if (cycle_cnt > 5) {
610 radius = AvalancheRadius;
611 break;
612 }
613 }
614
615 // Make strip cluster in each strip layer -------------------------------
616 Int_t n_strip_layers = StripLayers.size();
617 vector<StripCluster> cluster_layers(n_strip_layers, StripCluster());
618
619 for (Int_t ilayer = 0; ilayer < n_strip_layers; ++ilayer) {
620 if (!StripLayers[ilayer].IsPointInsideStripLayer(x, y))
621 continue;
622 cluster_layers[ilayer] = MakeCluster(ilayer, x, y, signal, radius);
623 }
624 //----------------------------------------------------------------------
625
626 // Testing ----------------------------------------------------------------------
627 /*if(AddedClusters.size() == 0) {
628 for(Int_t ilayer = 0; ilayer < n_strip_layers; ++ilayer) {
629 AddedClusters.push_back(vector<StripCluster>());
630 }
631 }
632
633 for(Int_t ilayer = 0; ilayer < n_strip_layers; ++ilayer) {
634 AddedClusters[ilayer].push_back(cluster_layers[ilayer]);
635 }*/
636 //------------------------------------------------------------------------------
637
638 // Add the correct clusters to the strip layers -------------------------
639 for (Int_t ilayer = 0; ilayer < n_strip_layers; ++ilayer) {
640 for (size_t ielement = 0; ielement < cluster_layers[ilayer].Strips.size(); ++ielement) {
641 Int_t strip_num = cluster_layers[ilayer].Strips.at(ielement);
642 Double_t strip_signal = cluster_layers[ilayer].Signals.at(ielement);
643 StripLayers[ilayer].AddStripSignal(strip_num, strip_signal);
644 }
645 }
646 //----------------------------------------------------------------------
647
648 // Fill strip matches ---------------------------------------------------
649 for (Int_t ilayer = 0; ilayer < n_strip_layers; ++ilayer) {
650 for (size_t ielement = 0; ielement < cluster_layers[ilayer].Strips.size(); ++ielement) {
651 Int_t strip_num = cluster_layers[ilayer].Strips.at(ielement);
652 Double_t strip_signal = cluster_layers[ilayer].Signals.at(ielement);
653 StripLayers[ilayer].AddLinkToStripMatch(strip_num, strip_signal / cluster_layers[ilayer].TotalSignal,
654 refID);
655 }
656 }
657 //----------------------------------------------------------------------
658
659 RealPointsX.push_back(x);
660 RealPointsY.push_back(y);
661 RealPointsMC.push_back(refID);
662
663 return true;
664 } else {
665 if (Verbosity)
666 cerr << "WARNING: BmnGemStripModule::AddRealPointFullOne(): Point (" << x << " : " << y << " : " << z
667 << ") is out of the readout plane or inside a dead zone\n";
668 return false;
669 }
670}
671
672// Add single point without smearing and avalanch effects
674 Double_t y,
675 Double_t z,
676 Double_t px,
677 Double_t py,
678 Double_t pz,
679 Double_t signal,
680 Int_t refID)
681{
682
683 if (IsPointInsideModule(x, y)) {
684
685 Int_t n_strip_layers = StripLayers.size();
686
687 // Add a signal to the strips layers ------------------------------------
688 for (Int_t ilayer = 0; ilayer < n_strip_layers; ++ilayer) {
689
690 if (!StripLayers[ilayer].IsPointInsideStripLayer(x, y))
691 continue;
692
693 Double_t strip_pos = StripLayers[ilayer].ConvertPointToStripPosition(x, y);
694 StripLayers[ilayer].AddStripSignal((Int_t)strip_pos, signal);
695
696 // strip match
697 StripLayers[ilayer].AddLinkToStripMatch((Int_t)strip_pos, 1.0, refID);
698 }
699 //----------------------------------------------------------------------
700
701 RealPointsX.push_back(x);
702 RealPointsY.push_back(y);
703 RealPointsMC.push_back(refID);
704
705 return true;
706 } else {
707 if (Verbosity)
708 cerr << "WARNING: BmnGemStripModule::AddRealPointSimple(): Point (" << x << " : " << y
709 << ") is out of the readout plane or inside a dead zone\n";
710 return false;
711 }
712}
713
715 Double_t xcoord,
716 Double_t ycoord,
717 Double_t signal,
718 Double_t radius)
719{
720
721 Double_t ClusterDistortion = 0.0; // signal variation (0.1 is 10%)
722
723 StripCluster cluster;
724
725 if (radius <= 0.0)
726 return cluster;
727
728 Double_t Pitch = StripLayers[layer_num].GetPitch();
729
730 Double_t RadiusInZones = radius / Pitch;
731 Double_t Sigma = RadiusInZones / 3.33;
732
733 TF1 gausF("gausF", "gaus", -4 * Sigma, 4 * Sigma);
734 gausF.SetParameter(0, 1.0); // constant (altitude)
735 gausF.SetParameter(1, 0.0); // mean (center position)
736 gausF.SetParameter(2, Sigma); // sigma
737
738 Double_t SCluster = gausF.Integral(-4 * Sigma, 4 * Sigma); // square of the one side distribution (more exactly)
739
740 TRandom rand(0);
741 Double_t var_level = ClusterDistortion; // signal variation (0.1 is 10%)
742
743 Int_t NStripsInLayer = StripLayers[layer_num].GetNStrips();
744
745 if (NStripsInLayer == 0)
746 return cluster;
747
748 Double_t CenterZonePos = StripLayers[layer_num].ConvertPointToStripPosition(xcoord, ycoord);
749
750 if (CenterZonePos < 0.0 || CenterZonePos >= NStripsInLayer)
751 return cluster;
752
753 gausF.SetParameter(1, CenterZonePos);
754 Double_t total_signal = 0.0;
755
756 Double_t LeftZonePos = CenterZonePos - RadiusInZones;
757 Double_t RightZonePos = CenterZonePos + RadiusInZones;
758 Double_t OutLeftBorder = 0.0;
759 Double_t OutRightBorder = 0.0;
760
761 if (LeftZonePos < 0.0) {
762 OutLeftBorder = LeftZonePos;
763 LeftZonePos = 0.0;
764 }
765 if (RightZonePos < 0.0) {
766 OutRightBorder = RightZonePos;
767 RightZonePos = 0.0;
768 }
769 if (LeftZonePos >= NStripsInLayer) {
770 OutLeftBorder = LeftZonePos;
771 LeftZonePos = NStripsInLayer - 0.001;
772 }
773 if (RightZonePos >= NStripsInLayer) {
774 OutRightBorder = RightZonePos;
775 RightZonePos = NStripsInLayer - 0.001;
776 }
777
778 Double_t h = 0.0;
779 Double_t dist = 0.0;
780
781 // avalanche is inside of the one strip
782 if ((Int_t)LeftZonePos == (Int_t)RightZonePos) {
783
784 Int_t NumCurrentZone = (Int_t)LeftZonePos;
785
786 h = RightZonePos - LeftZonePos;
787 if (h < 0.0)
788 h = 0.0;
789
790 Double_t xp = LeftZonePos + dist;
791 Double_t S = gausF.Integral(xp, xp + h);
792 Double_t Energy = (signal * Gain) * (S / SCluster);
793 Energy += rand.Gaus(0.0, var_level * Energy);
794 if (Energy < 0.0)
795 Energy = 0.0;
796
797 if (NumCurrentZone >= 0 && NumCurrentZone < NStripsInLayer && Energy > 0.0) {
798 cluster.AddStrip(NumCurrentZone, Energy);
799 total_signal += Energy;
800 }
801
802 dist += h;
803
804 } else {
805 // left border strip
806 Int_t NumCurrentZone = (Int_t)LeftZonePos;
807
808 h = ((Int_t)LeftZonePos + 1) - LeftZonePos;
809 if (h < 0.0)
810 h = 0.0;
811
812 Double_t xp = LeftZonePos + dist;
813 Double_t S = gausF.Integral(xp, xp + h);
814 Double_t Energy = (signal * Gain) * (S / SCluster);
815 Energy += rand.Gaus(0.0, var_level * Energy);
816 if (Energy < 0.0)
817 Energy = 0.0;
818
819 if (NumCurrentZone >= 0 && NumCurrentZone < NStripsInLayer && Energy > 0.0) {
820 cluster.AddStrip(NumCurrentZone, Energy);
821 total_signal += Energy;
822 }
823
824 dist += h;
825
826 // inner strips
827 for (Int_t i = (Int_t)LeftZonePos + 1; i < (Int_t)RightZonePos; ++i) {
828
829 NumCurrentZone = i;
830
831 h = 1.0;
832
833 xp = LeftZonePos + dist;
834 S = gausF.Integral(xp, xp + h);
835 Energy = (signal * Gain) * (S / SCluster);
836 Energy += rand.Gaus(0.0, var_level * Energy);
837 if (Energy < 0.0)
838 Energy = 0.0;
839
840 if (NumCurrentZone >= 0 && NumCurrentZone < NStripsInLayer && Energy > 0.0) {
841 cluster.AddStrip(NumCurrentZone, Energy);
842 total_signal += Energy;
843 }
844
845 dist += h;
846 }
847 // right border strip
848 NumCurrentZone = (Int_t)RightZonePos;
849
850 h = RightZonePos - (Int_t)RightZonePos;
851 if (h < 0.0)
852 h = 0.0;
853
854 xp = LeftZonePos + dist;
855 S = gausF.Integral(xp, xp + h);
856 Energy = (signal * Gain) * (S / SCluster);
857 Energy += rand.Gaus(0.0, var_level * Energy);
858 if (Energy < 0.0)
859 Energy = 0.0;
860
861 if (NumCurrentZone >= 0 && NumCurrentZone < NStripsInLayer && Energy > 0.0) {
862 cluster.AddStrip(NumCurrentZone, Energy);
863 total_signal += Energy;
864 }
865
866 dist += h;
867 }
868
869 if (cluster.GetClusterSize() <= 0) {
870 return cluster;
871 }
872
873 // find the mean value of the avalanche position (fitting by gaus function)
874 Double_t mean_fit_pos = 0.0;
875
876 Int_t NOutLeftBins = 0;
877 Int_t NOutRightBins = 0;
878 if (OutLeftBorder != 0.0) {
879 NOutLeftBins = (Int_t)(fabs(OutLeftBorder)) + 1;
880 }
881 if (OutRightBorder != 0.0) {
882 NOutRightBins = (Int_t)(OutRightBorder - RightZonePos) + 1;
883 }
884
885 Int_t begin_strip_num = cluster.Strips.at(0);
886 Int_t last_strip_num = cluster.Strips.at(cluster.GetClusterSize() - 1);
887 Int_t nstrips = last_strip_num - begin_strip_num + 1;
888
889 TH1F hist("hist_for_fit", "hist_for_fit", nstrips + NOutLeftBins + NOutRightBins, begin_strip_num - NOutLeftBins,
890 last_strip_num + 1 + NOutRightBins);
891 Int_t hist_index = 0;
892
893 for (Int_t i = 0; i < cluster.GetClusterSize(); ++i) {
894 Double_t value = cluster.Signals.at(i);
895 hist.SetBinContent(hist_index + 1 + NOutLeftBins, value);
896 hist_index++;
897 }
898
899 // on the left border
900 if (NOutLeftBins > 0.0) {
901 Double_t first = OutLeftBorder;
902 Double_t last = (Int_t)OutLeftBorder;
903 Double_t S = gausF.Integral(first, last);
904 Double_t Energy = (signal * Gain) * (S / SCluster);
905 Energy += rand.Gaus(0.0, var_level * Energy);
906 if (Energy < 0.0)
907 Energy = 0.0;
908 Double_t value = Energy;
909 hist.SetBinContent(1, value);
910 dist = 0.0;
911
912 for (Int_t i = 1; i < NOutLeftBins; ++i) {
913 h = 1.0;
914 first = (Int_t)OutLeftBorder + dist;
915 last = first + h;
916 S = gausF.Integral(first, last);
917 Energy = (signal * Gain) * (S / SCluster);
918 Energy += rand.Gaus(0.0, var_level * Energy);
919 if (Energy < 0.0)
920 Energy = 0.0;
921 value = Energy;
922 hist.SetBinContent(1 + i, value);
923 dist += h;
924 }
925 }
926
927 // on the right border
928 if (NOutRightBins > 0.0) {
929 dist = 0.0;
930 for (Int_t i = hist_index; i < hist_index + NOutRightBins - 1; ++i) {
931 h = 1.0;
932 Double_t first = NStripsInLayer + dist;
933 Double_t last = first + h;
934 Double_t S = gausF.Integral(first, last);
935 Double_t Energy = (signal * Gain) * (S / SCluster);
936 Energy += rand.Gaus(0.0, var_level * Energy);
937 if (Energy < 0.0)
938 Energy = 0.0;
939 Double_t value = Energy;
940 hist.SetBinContent(1 + i, value);
941 dist += h;
942 }
943
944 Double_t first = (Int_t)OutRightBorder;
945 Double_t last = first + (OutRightBorder - (Int_t)OutRightBorder);
946 Double_t S = gausF.Integral(first, last);
947 Double_t Energy = (signal * Gain) * (S / SCluster);
948 Energy += rand.Gaus(0.0, var_level * Energy);
949 if (Energy < 0.0)
950 Energy = 0.0;
951 Double_t value = Energy;
952 hist.SetBinContent(hist_index + NOutRightBins, value);
953 }
954
955 TF1* gausFitFunction = 0;
956 TString fit_params = "WQ0";
957
958#ifdef DRAW_REAL_CLUSTER_HISTOGRAMS
959 fit_params = "WQ";
960#endif
961
962 if (nstrips > 1) {
963 hist.Fit("gaus", fit_params); // Q - quit mode (without information on the screen); 0 - not draw
964 gausFitFunction = hist.GetFunction("gaus");
965 if (gausFitFunction) {
966 mean_fit_pos = gausFitFunction->GetParameter(1);
967 } else {
968 mean_fit_pos = hist.GetMean();
969 }
970 } else {
971 mean_fit_pos = hist.GetMean();
972 }
973
974 cluster.MeanPosition = mean_fit_pos;
975 cluster.TotalSignal = total_signal;
976 cluster.PositionResidual = mean_fit_pos - CenterZonePos; // residual between mean and origin positions (lower
977 // cluster): residual = finded(current) - orig(average)
978
979 cluster.IsCorrect = true; // set correct status of the cluster
980 return cluster;
981}
982
984{
985 if (aval_radius >= 0.0)
986 AvalancheRadius = aval_radius;
987 else {
988 if (Verbosity)
989 cerr << "WARNING: BmnGemStripModule::SetAvalancheRadius(): incorrect value for AvalancheRadius! It'll be "
990 "set by default!\n";
991 AvalancheRadius = 0.1; // default
992 }
993}
994
996{
997 return AvalancheRadius;
998}
999
1001{
1002
1005
1006 Int_t n_strip_layers = StripLayers.size();
1007
1008 // Find strip clusters and hits in the strip layers -------------------------
1009 for (Int_t ilayer = 0; ilayer < n_strip_layers; ++ilayer) {
1010 StripLayers[ilayer].FindClustersAndStripHits();
1011 }
1012 //--------------------------------------------------------------------------
1013
1014 map<Int_t, Bool_t> UsageStatus_LowerClusters;
1015 map<Int_t, Bool_t> UsageStatus_UpperClusters;
1016
1017 // Saving all unique id marks of clusters in a module
1018 for (Int_t ilayer = 0; ilayer < n_strip_layers; ++ilayer) {
1019 for (Int_t i_strip_hit = 0; i_strip_hit < StripLayers[ilayer].GetNStripHits(); ++i_strip_hit) {
1020 StripCluster cluster = StripLayers[ilayer].GetStripClusters()[i_strip_hit];
1021 if (cluster.GetType() == LowerStripLayer) {
1022 UsageStatus_LowerClusters[cluster.GetUniqueID()] = false;
1023 }
1024 if (cluster.GetType() == UpperStripLayer) {
1025 UsageStatus_UpperClusters[cluster.GetUniqueID()] = false;
1026 }
1027 }
1028 }
1029
1030 for (Int_t ilayer = 0; ilayer < n_strip_layers; ++ilayer) {
1031 for (Int_t jlayer = ilayer + 1; jlayer < n_strip_layers; ++jlayer) {
1032 // cout << "(i-layer : j-layer) = ( " << ilayer << " : " << jlayer << " )\n";
1033
1034 if (StripLayers[ilayer].GetType() == StripLayers[jlayer].GetType())
1035 continue;
1036
1037 Double_t iAngleRad = StripLayers[ilayer].GetAngleRad();
1038 Double_t jAngleRad = StripLayers[jlayer].GetAngleRad();
1039
1040 if (Abs(iAngleRad - jAngleRad) < 0.01)
1041 continue;
1042
1043 Double_t i_PiOver2MinusAngleRad = PiOver2() - iAngleRad;
1044 Double_t j_PiOver2MinusAngleRad = PiOver2() - jAngleRad;
1045
1046 for (Int_t i_strip_hit = 0; i_strip_hit < StripLayers[ilayer].GetNStripHits(); ++i_strip_hit) {
1047 for (Int_t j_strip_hit = 0; j_strip_hit < StripLayers[jlayer].GetNStripHits(); ++j_strip_hit) {
1048
1049 Double_t iStripHitPos = StripLayers[ilayer].GetStripHitPos(i_strip_hit);
1050 Double_t jStripHitPos = StripLayers[jlayer].GetStripHitPos(j_strip_hit);
1051
1052 Double_t iStripHitError = StripLayers[ilayer].GetStripHitError(i_strip_hit);
1053 Double_t jStripHitError = StripLayers[jlayer].GetStripHitError(j_strip_hit);
1054
1055 Double_t xcoord;
1056 Double_t ycoord;
1057
1058 if (Abs(iAngleRad) >= 0.01 && Abs(jAngleRad) >= 0.01) {
1059
1060 Double_t iB = StripLayers[ilayer].CalculateStripEquationB(iStripHitPos);
1061 Double_t jB = StripLayers[jlayer].CalculateStripEquationB(jStripHitPos);
1062
1063 xcoord = (jB - iB) / (Tan(i_PiOver2MinusAngleRad) - Tan(j_PiOver2MinusAngleRad));
1064 ycoord = Tan(i_PiOver2MinusAngleRad) * xcoord + iB;
1065 } else {
1066
1067 if (Abs(iAngleRad) < 0.01) {
1068
1069 if (StripLayers[ilayer].GetStripNumberingOrder() == LeftToRight) {
1070 xcoord = StripLayers[ilayer].GetXLeftStripBorderPoint()
1071 + iStripHitPos * StripLayers[ilayer].GetPitch();
1072 } else {
1073 xcoord = StripLayers[ilayer].GetXRightStripBorderPoint()
1074 - iStripHitPos * StripLayers[ilayer].GetPitch();
1075 }
1076
1077 Double_t jB = StripLayers[jlayer].CalculateStripEquationB(jStripHitPos);
1078 ycoord = Tan(j_PiOver2MinusAngleRad) * xcoord + jB;
1079 }
1080
1081 if (Abs(jAngleRad) < 0.01) {
1082
1083 if (StripLayers[jlayer].GetStripNumberingOrder() == LeftToRight) {
1084 xcoord = StripLayers[jlayer].GetXLeftStripBorderPoint()
1085 + jStripHitPos * StripLayers[jlayer].GetPitch();
1086 } else {
1087 xcoord = StripLayers[jlayer].GetXRightStripBorderPoint()
1088 - jStripHitPos * StripLayers[jlayer].GetPitch();
1089 }
1090
1091 Double_t iB = StripLayers[ilayer].CalculateStripEquationB(iStripHitPos);
1092 ycoord = Tan(i_PiOver2MinusAngleRad) * xcoord + iB;
1093 }
1094 }
1095
1096 // check: a point belongs to both strip layers together
1097 if (StripLayers[ilayer].IsPointInsideStripLayer(xcoord, ycoord)
1098 && StripLayers[jlayer].IsPointInsideStripLayer(xcoord, ycoord))
1099 {
1100
1101 IntersectionPointsX.push_back(xcoord);
1102 IntersectionPointsY.push_back(ycoord);
1103
1104 // Intersection (x,y)-errors from the strip-errors ------
1105 Double_t AngleIntersecRad = Abs(iAngleRad - jAngleRad);
1106
1107 // a rhomb zone is the intersection of the strip errors
1108 Double_t RhombSide1 = (iStripHitError * StripLayers[ilayer].GetPitch()) / Sin(AngleIntersecRad);
1109 Double_t RhombSide2 = (jStripHitError * StripLayers[jlayer].GetPitch()) / Sin(AngleIntersecRad);
1110
1111 // x-strip error
1112 Double_t xerr1 = Sin(Abs(jAngleRad)) * RhombSide1;
1113 Double_t xerr2 = Sin(Abs(iAngleRad)) * RhombSide2;
1114 Double_t xcoord_err = xerr1 + xerr2;
1115
1116 // y-strip error
1117 Double_t yerr1 = Cos(Abs(jAngleRad)) * RhombSide1;
1118 Double_t yerr2 = Cos(Abs(iAngleRad)) * RhombSide2;
1119 Double_t ycoord_err = yerr1 + yerr2;
1120
1121 IntersectionPointsXErrors.push_back(xcoord_err);
1122 IntersectionPointsYErrors.push_back(ycoord_err);
1123 //------------------------------------------------------
1124
1125 // intersection MC-matching -----------------------------
1126 BmnMatch iStripMatch = StripLayers[ilayer].GetStripMatch((Int_t)iStripHitPos);
1127 BmnMatch jStripMatch = StripLayers[jlayer].GetStripMatch((Int_t)jStripHitPos);
1128
1129 BmnMatch intersection_match;
1130 intersection_match.AddLink(iStripMatch);
1131 intersection_match.AddLink(jStripMatch);
1132
1133 IntersectionPointMatches.push_back(intersection_match);
1134 //------------------------------------------------------
1135
1136 // intersection digit number matching -------------------
1137 BmnMatch iStripDigitNumberMatch =
1138 StripLayers[ilayer].GetStripDigitNumberMatch((Int_t)iStripHitPos);
1139 BmnMatch jStripDigitNumberMatch =
1140 StripLayers[jlayer].GetStripDigitNumberMatch((Int_t)jStripHitPos);
1141
1142 BmnMatch intersection_digit_num_match;
1143 intersection_digit_num_match.AddLink(iStripDigitNumberMatch);
1144 intersection_digit_num_match.AddLink(jStripDigitNumberMatch);
1145
1146 IntersectionPointDigitNumberMatches.push_back(intersection_digit_num_match);
1147 //------------------------------------------------------
1148
1149 // Additional information about the intersection ------------
1150 // cluster size (number strips) in both strip layers for each intersection
1151 Int_t iLayerClusterSize = StripLayers[ilayer].GetStripHitClusterSize(i_strip_hit);
1152 Int_t jLayerClusterSize = StripLayers[jlayer].GetStripHitClusterSize(j_strip_hit);
1153
1154 // strip position in both strip layers for each intersection
1155 Double_t iLayerStripPosition = StripLayers[ilayer].ConvertPointToStripPosition(xcoord, ycoord);
1156 Double_t jLayerStripPosition = StripLayers[jlayer].ConvertPointToStripPosition(xcoord, ycoord);
1157
1158 if (StripLayers[ilayer].GetType() == LowerStripLayer) {
1159 IntersectionPoints_LowerLayerClusterSize.push_back(iLayerClusterSize);
1160 IntersectionPoints_UpperLayerClusterSize.push_back(jLayerClusterSize);
1161 IntersectionPoints_LowerLayerStripPosition.push_back(iLayerStripPosition);
1162 IntersectionPoints_UpperLayerStripPosition.push_back(jLayerStripPosition);
1163 IntersectionPoints_LowerLayerStripTotalSignal.push_back(
1164 StripLayers[ilayer].GetStripHitTotalSignal(i_strip_hit));
1165 IntersectionPoints_UpperLayerStripTotalSignal.push_back(
1166 StripLayers[jlayer].GetStripHitTotalSignal(j_strip_hit));
1167 LowerClusters.push_back(StripLayers[ilayer].GetStripClusters().at(i_strip_hit));
1168 UpperClusters.push_back(StripLayers[jlayer].GetStripClusters().at(j_strip_hit));
1169 UsageStatus_LowerClusters
1170 [StripLayers[ilayer].GetStripClusters()[i_strip_hit].GetUniqueID()] = true;
1171 UsageStatus_UpperClusters
1172 [StripLayers[jlayer].GetStripClusters()[j_strip_hit].GetUniqueID()] = true;
1173 } else {
1174 IntersectionPoints_LowerLayerClusterSize.push_back(jLayerClusterSize);
1175 IntersectionPoints_UpperLayerClusterSize.push_back(iLayerClusterSize);
1176 IntersectionPoints_LowerLayerStripPosition.push_back(jLayerStripPosition);
1177 IntersectionPoints_UpperLayerStripPosition.push_back(iLayerStripPosition);
1178 IntersectionPoints_LowerLayerStripTotalSignal.push_back(
1179 StripLayers[jlayer].GetStripHitTotalSignal(j_strip_hit));
1180 IntersectionPoints_UpperLayerStripTotalSignal.push_back(
1181 StripLayers[ilayer].GetStripHitTotalSignal(i_strip_hit));
1182 LowerClusters.push_back(StripLayers[jlayer].GetStripClusters().at(j_strip_hit));
1183 UpperClusters.push_back(StripLayers[ilayer].GetStripClusters().at(i_strip_hit));
1184 UsageStatus_LowerClusters
1185 [StripLayers[jlayer].GetStripClusters()[j_strip_hit].GetUniqueID()] = true;
1186 UsageStatus_UpperClusters
1187 [StripLayers[ilayer].GetStripClusters()[i_strip_hit].GetUniqueID()] = true;
1188 }
1189 //------------------------------------------------------
1190 }
1191 }
1192 }
1193 }
1194 }
1195 /*
1196 for(auto it : UsageStatus_UpperClusters) {
1197 if(it.second == false) cout << " upper_cluster[" << it.first << "] = " << it.second << "\n";
1198 }
1199 */
1200 for (auto it : UsageStatus_LowerClusters) {
1201
1202 // if(it.second == false) cout << " lower_cluster[" << it.first << "] = " << it.second << "\n";
1203
1204 if (it.second == false) {
1205
1206 for (Int_t ilayer = 0; ilayer < n_strip_layers; ++ilayer) {
1207
1208 if (StripLayers[ilayer].GetType() != LowerStripLayer)
1209 continue;
1210
1211 for (size_t icluster = 0; icluster < StripLayers[ilayer].GetStripClusters().size(); ++icluster) {
1212 StripCluster cluster = StripLayers[ilayer].GetStripClusters()[icluster];
1213
1214 if ((int)cluster.GetUniqueID() != it.first)
1215 continue;
1216
1217 Double_t xcoord;
1218 Double_t ycoord;
1219
1220 if (StripLayers[ilayer].GetStripNumberingOrder() == LeftToRight) {
1221 xcoord = StripLayers[ilayer].GetXLeftStripBorderPoint()
1222 + cluster.MeanPosition * StripLayers[ilayer].GetPitch();
1223 } else {
1224 xcoord = StripLayers[ilayer].GetXRightStripBorderPoint()
1225 - cluster.MeanPosition * StripLayers[ilayer].GetPitch();
1226 }
1227
1228 ycoord = (StripLayers[ilayer].GetYMinLayer() + StripLayers[ilayer].GetYMaxLayer()) * 0.5;
1229
1230 Double_t xerr = cluster.Error * StripLayers[ilayer].GetPitch();
1231 Double_t yerr = StripLayers[ilayer].GetYSize() * 0.5;
1232
1233 // cout << " low_cluster[" << icluster << "]:\n";
1234 // cout << " ID = " << cluster.GetUniqueID() << "\n";
1235 // cout << " xcoord = " << xcoord << "\n";
1236 // cout << " xmin = " << StripLayers[ilayer].GetXMinLayer() << ", xmax = " <<
1237 // StripLayers[ilayer].GetXMaxLayer() << "\n"; cout << " ycoord = " << ycoord << "\n"; cout << "
1238 // ymin = " << StripLayers[ilayer].GetYMinLayer() << ", ymax = " <<
1239 // StripLayers[ilayer].GetYMaxLayer() << "\n"; cout << " xerr = " << xerr << "\n"; cout << " yerr
1240 // = " << yerr << "\n"; cout << "\n";
1241
1242 PseudoIntersectionsX.push_back(xcoord);
1243 PseudoIntersectionsY.push_back(ycoord);
1244
1245 PseudoIntersectionsXErrors.push_back(xerr);
1246 PseudoIntersectionsYErrors.push_back(yerr);
1247
1248 PseudoIntersections_LowerLayerClusterSize.push_back(cluster.Width);
1249 PseudoIntersections_UpperLayerClusterSize.push_back(0);
1250
1251 PseudoIntersections_LowerLayerStripPosition.push_back(
1252 StripLayers[ilayer].ConvertPointToStripPosition(xcoord, ycoord));
1253 PseudoIntersections_UpperLayerStripPosition.push_back(0);
1254
1255 PseudoIntersections_LowerLayerStripTotalSignal.push_back(cluster.TotalSignal);
1256 PseudoIntersections_UpperLayerStripTotalSignal.push_back(0);
1257
1258 PseudoIntersectionMatches.push_back(
1259 StripLayers[ilayer].GetStripMatch((Int_t)cluster.MeanPosition)); // mc-match
1260 PseudoIntersectionDigitNumberMatches.push_back(StripLayers[ilayer].GetStripDigitNumberMatch(
1261 (Int_t)cluster.MeanPosition)); // digit number matches
1262
1263 LowerClusters_PseudoIntersections.push_back(cluster);
1264 UpperClusters_PseudoIntersections.push_back(
1265 StripCluster()); // empty cluster with default parameters
1266 }
1267 }
1268 }
1269 }
1270}
1271
1272// need for a separated test (find x,y intersection coords from strip positions)
1274 Double_t& y,
1275 Double_t strip_pos_layerA,
1276 Double_t strip_pos_layerB,
1277 Int_t layerA_index,
1278 Int_t layerB_index)
1279{
1280
1281 Int_t ilayer = layerA_index;
1282 Int_t jlayer = layerB_index;
1283
1284 if (StripLayers[ilayer].GetType() == StripLayers[jlayer].GetType())
1285 return false;
1286
1287 Double_t iAngleRad = StripLayers[ilayer].GetAngleRad();
1288 Double_t jAngleRad = StripLayers[jlayer].GetAngleRad();
1289
1290 if (Abs(iAngleRad - jAngleRad) < 0.01)
1291 return false;
1292
1293 Double_t i_PiOver2MinusAngleRad = PiOver2() - iAngleRad;
1294 Double_t j_PiOver2MinusAngleRad = PiOver2() - jAngleRad;
1295
1296 Double_t iStripHitPos = strip_pos_layerA;
1297 Double_t jStripHitPos = strip_pos_layerB;
1298
1299 Double_t xcoord;
1300 Double_t ycoord;
1301
1302 if (Abs(iAngleRad) >= 0.01 && Abs(jAngleRad) >= 0.01) {
1303
1304 Double_t iB = StripLayers[ilayer].CalculateStripEquationB(iStripHitPos);
1305 Double_t jB = StripLayers[jlayer].CalculateStripEquationB(jStripHitPos);
1306
1307 xcoord = (jB - iB) / (Tan(i_PiOver2MinusAngleRad) - Tan(j_PiOver2MinusAngleRad));
1308 ycoord = Tan(i_PiOver2MinusAngleRad) * xcoord + iB;
1309 } else {
1310
1311 if (Abs(iAngleRad) < 0.01) {
1312
1313 if (StripLayers[ilayer].GetStripNumberingOrder() == LeftToRight) {
1314 xcoord = StripLayers[ilayer].GetXLeftStripBorderPoint() + iStripHitPos * StripLayers[ilayer].GetPitch();
1315 } else {
1316 xcoord =
1317 StripLayers[ilayer].GetXRightStripBorderPoint() - iStripHitPos * StripLayers[ilayer].GetPitch();
1318 }
1319
1320 Double_t jB = StripLayers[jlayer].CalculateStripEquationB(jStripHitPos);
1321 ycoord = Tan(j_PiOver2MinusAngleRad) * xcoord + jB;
1322 }
1323
1324 if (Abs(jAngleRad) < 0.01) {
1325
1326 if (StripLayers[jlayer].GetStripNumberingOrder() == LeftToRight) {
1327 xcoord = StripLayers[jlayer].GetXLeftStripBorderPoint() + jStripHitPos * StripLayers[jlayer].GetPitch();
1328 } else {
1329 xcoord =
1330 StripLayers[jlayer].GetXRightStripBorderPoint() - jStripHitPos * StripLayers[jlayer].GetPitch();
1331 }
1332
1333 Double_t iB = StripLayers[ilayer].CalculateStripEquationB(iStripHitPos);
1334 ycoord = Tan(i_PiOver2MinusAngleRad) * xcoord + iB;
1335 }
1336 }
1337
1338 x = xcoord;
1339 y = ycoord;
1340
1341 // check: a point belongs to both strip layers together
1342 if (StripLayers[ilayer].IsPointInsideStripLayer(xcoord, ycoord)
1343 && StripLayers[jlayer].IsPointInsideStripLayer(xcoord, ycoord))
1344 {
1345 return true;
1346 }
1347
1348 return false;
1349}
1350
1352{
1353 IntersectionPointsX.clear();
1354 IntersectionPointsY.clear();
1355 IntersectionPointsXErrors.clear();
1356 IntersectionPointsYErrors.clear();
1357 IntersectionPoints_LowerLayerClusterSize.clear();
1358 IntersectionPoints_UpperLayerClusterSize.clear();
1359 IntersectionPoints_LowerLayerStripPosition.clear();
1360 IntersectionPoints_UpperLayerStripPosition.clear();
1361 IntersectionPoints_LowerLayerStripTotalSignal.clear();
1362 IntersectionPoints_UpperLayerStripTotalSignal.clear();
1363 IntersectionPointMatches.clear();
1364 IntersectionPointDigitNumberMatches.clear();
1365 UpperClusters.clear();
1366 LowerClusters.clear();
1367}
1368
1370{
1371 PseudoIntersectionsX.clear();
1372 PseudoIntersectionsY.clear();
1373 PseudoIntersectionsXErrors.clear();
1374 PseudoIntersectionsYErrors.clear();
1375 PseudoIntersections_LowerLayerClusterSize.clear();
1376 PseudoIntersections_UpperLayerClusterSize.clear();
1377 PseudoIntersections_LowerLayerStripPosition.clear();
1378 PseudoIntersections_UpperLayerStripPosition.clear();
1379 PseudoIntersections_LowerLayerStripTotalSignal.clear();
1380 PseudoIntersections_UpperLayerStripTotalSignal.clear();
1381 PseudoIntersectionMatches.clear();
1382 PseudoIntersectionDigitNumberMatches.clear();
1383 UpperClusters_PseudoIntersections.clear();
1384 LowerClusters_PseudoIntersections.clear();
1385}
1386
1387void BmnGemStripModule::DefineModuleBorders()
1388{
1389
1390 if (StripLayers.size() == 0)
1391 return;
1392
1393 XMinModule = 1.0E+10;
1394 XMaxModule = -1.0E+10;
1395 YMinModule = 1.0E+10;
1396 YMaxModule = -1.0E+10;
1397
1398 for (size_t ilayer = 0; ilayer < StripLayers.size(); ++ilayer) {
1399 if (StripLayers[ilayer].GetXMinLayer() < XMinModule)
1400 XMinModule = StripLayers[ilayer].GetXMinLayer();
1401 if (StripLayers[ilayer].GetXMaxLayer() > XMaxModule)
1402 XMaxModule = StripLayers[ilayer].GetXMaxLayer();
1403 if (StripLayers[ilayer].GetYMinLayer() < YMinModule)
1404 YMinModule = StripLayers[ilayer].GetYMinLayer();
1405 if (StripLayers[ilayer].GetYMaxLayer() > YMaxModule)
1406 YMaxModule = StripLayers[ilayer].GetYMaxLayer();
1407 }
1408 return;
1409}
1410
1411// -------------------------------------------------------------------------
1412
1413Double_t BmnGemStripModule::GetNumberOfClusters(Double_t beta,
1414 Double_t gamma,
1415 Double_t charge,
1416 Double_t p0,
1417 Double_t p1)
1418{
1419 // AZ-110124 - compute number of ionization clusters
1420
1421 Double_t beta2 = beta * beta;
1422 Double_t gamma2 = gamma * gamma;
1423 Double_t val = p0 / beta2 * (p1 + TMath::Log(beta2 * gamma2) - beta2);
1424 return TMath::Min(val * charge * charge, 20000.);
1425}
vector< Double_t > dist(vector< Double_t > qp, Double_t mu)
Definition BmnMath.cxx:869
Double_t Sigma(vector< Double_t > dist, vector< Double_t > w)
Definition BmnMath.cxx:890
friend F32vec4 fabs(const F32vec4 &a)
Definition P4_F32vec4.h:52
int i
Definition P4_F32vec4.h:22
@ LeftToRight
@ UpperStripLayer
@ LowerStripLayer
TClonesArray * GetMCTracks()
TClonesArray * GetMCPoints()
static BmnGemStripMedium & GetInstance()
BmnMatch GetStripMatchInLayer(Int_t layer_num, Int_t strip_num)
void SetAvalancheRadius(Double_t aval_radius)
BmnMatch GetStripDigitNumberMatchInLayer(Int_t layer_num, Int_t strip_num)
Bool_t AddRealPointFull(Double_t x, Double_t y, Double_t z, Double_t px, Double_t py, Double_t pz, Double_t signal, Int_t refID)
Double_t GetStripSignalInLayer(Int_t layer_num, Int_t strip_num)
Bool_t AddRealPointSimple(Double_t x, Double_t y, Double_t z, Double_t px, Double_t py, Double_t pz, Double_t signal, Int_t refID)
Bool_t SetStripSignalInLayer(Int_t layer_num, Int_t strip_num, Double_t signal)
Bool_t IsPointInsideModule(Double_t x, Double_t y)
Bool_t AddStripSignalInLayer(Int_t layer_num, Int_t strip_num, Double_t signal)
Bool_t AddRealPointFullOne(Double_t x, Double_t y, Double_t z, Double_t px, Double_t py, Double_t pz, Double_t signal, Int_t refID)
Bool_t SetStripMatchInLayer(Int_t layer_num, Int_t strip_num, BmnMatch mc_match)
StripCluster MakeCluster(Int_t layer_num, Double_t xcoord, Double_t ycoord, Double_t signal, Double_t radius)
void ResetElectronPointsAndClusters()
Bool_t IsPointInsideZThickness(Double_t z)
Bool_t SearchIntersectionPoint(Double_t &x, Double_t &y, Double_t strip_pos_layerA, Double_t strip_pos_layerB, Int_t layerA_index, Int_t layerB_index)
Double_t GetZPositionRegistered()
void AddStripLayer(BmnGemStripLayer strip_layer)
Bool_t SetStripDigitNumberMatchInLayer(Int_t layer_num, Int_t strip_num, BmnMatch digit_num_match)
void AddLink(const BmnMatch &match)
Definition BmnMatch.cxx:43
Int_t GetPdgCode() const
Definition CbmMCTrack.h:56
Double_t TotalSignal
Int_t GetClusterSize()
Int_t GetType()
Double_t MeanPosition
Double_t Error
void AddStrip(Int_t strip_num, Double_t strip_signal)
Double_t PositionResidual
vector< Int_t > Strips
vector< Double_t > Signals
ElectronDriftDirectionInModule
@ ForwardZAxisEDrift