BmnRoot 26.10.0-18-g4e3414f9
Software framework of the BM@N experiment
Loading...
Searching...
No Matches
BmnSiliconLayer.cxx
Go to the documentation of this file.
1#include "BmnSiliconLayer.h"
2
3#include "TMath.h"
4
5#include <iostream>
6
7using namespace TMath;
8using namespace std;
9
12
14{
15
16 Verbosity = true;
17
18 ZoneID = -1;
21
22 XMinLayer = 0.0;
23 XMaxLayer = 10.0;
24 YMinLayer = 0.0;
25 YMaxLayer = 10.0;
26
27 Pitch = 0.01; // cm
28 AngleDeg = 2.5; // in degrees from a vertical line where a plus value is clockwise
29 AngleRad = AngleDeg * Pi() / 180; // in radians
30
32
35 } else {
36 if (AngleDeg > 0.0 && AngleDeg <= 90.0) {
38 }
39 }
40
42
44}
45
47 StripLayerType layer_type,
48 Int_t first_strip_number,
49 Double_t xsize,
50 Double_t ysize,
51 Double_t xorig,
52 Double_t yorig,
53 Double_t pitch,
54 Double_t adeg)
55{
56
57 Verbosity = true;
58
59 ZoneID = zone_id;
60 LayerType = layer_type;
61 FirstStripNumber = first_strip_number;
62
63 XMinLayer = xorig;
64 XMaxLayer = xorig + xsize;
65 YMinLayer = yorig;
66 YMaxLayer = yorig + ysize;
67
68 Pitch = pitch;
69 AngleDeg = adeg; // in degrees from a vertical line where a plus value is clockwise
70 AngleRad = AngleDeg * Pi() / 180; // in radians
71
73
76 } else {
77 if (AngleDeg > 0.0 && AngleDeg <= 90.0) {
79 }
80 }
81
83
85}
86
88
90{
91 Int_t NStrips = GetNStrips();
92
93 // strips
94 Strips.clear();
95 Strips.resize(NStrips, 0.0);
96
97 // matches
100
101 // strip hits
103
106}
107
112
114{
117 Double_t n_strips = (xright_layer - xleft_layer) / Pitch;
118
119 if ((n_strips - (Int_t)n_strips) < 1E-10) {
120 return (Int_t)n_strips;
121 } else {
122 return (Int_t)(n_strips + 1);
123 }
124}
125
127{
128 Pitch = pitch;
129
131}
132
134{
135 XMinLayer = xorig;
136 XMaxLayer = xorig + xsize;
137 YMinLayer = yorig;
138 YMaxLayer = yorig + ysize;
139
141}
142
144{
145 if (Abs(deg) <= 90.0) {
146 AngleDeg = deg;
147 } else {
148 AngleDeg = 0.0;
149 if (Verbosity)
150 cerr << "WARNING: BmnSiliconLayer::SetAngleDeg(): the strip angle is incorrect and has been set to zero\n";
151 }
152
153 AngleRad = AngleDeg * Pi() / 180;
154
156}
157
159{
160 if (x_right < x_left)
161 return false;
162
167
168 ResetLayer();
169
170 return true;
171}
172
174{
175
176 if (left != LeftTop && left != LeftBottom) {
177 if (Verbosity)
178 cerr << "WARNING: SetStripNumberingBorders: left strip border point is incorrect\n";
179 return false;
180 }
181 if (right != RightTop && right != RightBottom) {
182 if (Verbosity)
183 cerr << "WARNING: SetStripNumberingBorders: right strip border point is incorrect\n";
184 return false;
185 }
186
189
190 switch (left) {
191 case LeftTop:
193 break;
194 case LeftBottom:
196 break;
197 default:
198 return false;
199 }
200
201 switch (right) {
202 case RightTop:
204 break;
205 case RightBottom:
207 break;
208 default:
209 return false;
210 }
211
212 ResetLayer();
213
214 return true;
215}
216
217Bool_t BmnSiliconLayer::SetStripNumberingOrder(StripNumberingDirection strip_direction)
218{
219 StripOrder = strip_direction;
220
221 ResetLayer();
222
223 return true;
224}
225
227{
228 DeadZoneOfStripLayer dead_zone;
229 Bool_t status = dead_zone.SetDeadZone(n_points, x_points, y_points);
230 if (status == true) {
231 DeadZones.push_back(dead_zone);
232 return true;
233 } else {
234 return false;
235 }
236}
237
239{
240 if (dead_zone.GetNPoints() > 2) {
241 DeadZones.push_back(dead_zone);
242 return true;
243 } else {
244 return false;
245 }
246}
247
249{
250 for (size_t izone = 0; izone < DeadZones.size(); ++izone)
251 if (DeadZones[izone].IsInside(x, y))
252 return true;
253
254 return false;
255}
256
258{
259 if (x >= XMinLayer && x <= XMaxLayer && y >= YMinLayer && y <= YMaxLayer && !IsPointInsideDeadZones(x, y))
260 return true;
261 else
262 return false;
263}
264
266{
267 if (strip_num >= FirstStripNumber && strip_num < ((Int_t)Strips.size() + FirstStripNumber)) {
268 Strips[strip_num - FirstStripNumber] = signal;
269 return true;
270 } else
271 return false;
272}
273
275{
276 if (strip_num >= FirstStripNumber && strip_num < ((Int_t)Strips.size() + FirstStripNumber)) {
277 Strips[strip_num - FirstStripNumber] += signal;
278 return true;
279 } else
280 return false;
281}
282
284{
285 if (strip_num >= FirstStripNumber && strip_num < ((Int_t)Strips.size() + FirstStripNumber))
286 return Strips[strip_num - FirstStripNumber];
287 else
288 return -1;
289}
290
292{
293 if (strip_num >= FirstStripNumber && strip_num < ((Int_t)StripMatches.size() + FirstStripNumber)) {
294 StripMatches[strip_num - FirstStripNumber] = mc_match;
295 return true;
296 } else
297 return false;
298}
299
301{
302 if (strip_num >= FirstStripNumber && strip_num < ((Int_t)StripMatches.size() + FirstStripNumber)) {
303 StripMatches[strip_num - FirstStripNumber].AddLink(weight, mc_num);
304 return true;
305 } else
306 return false;
307}
308
310{
311 if (strip_num >= FirstStripNumber && strip_num < ((Int_t)StripDigitNumberMatches.size() + FirstStripNumber)) {
312 StripDigitNumberMatches[strip_num - FirstStripNumber] = digit_num_match;
313 return true;
314 } else
315 return false;
316}
317
319{
320 if (strip_num >= FirstStripNumber && strip_num < ((Int_t)StripDigitNumberMatches.size() + FirstStripNumber)) {
321 StripDigitNumberMatches[strip_num - FirstStripNumber].AddLink(weight, digit_num);
322 return true;
323 } else
324 return false;
325}
326
328{
329 if (strip_num >= FirstStripNumber && strip_num < ((Int_t)StripMatches.size() + FirstStripNumber))
330 return StripMatches[strip_num - FirstStripNumber];
331 else
332 return BmnMatch(); // return an empty match
333}
334
336{
337 if (strip_num >= FirstStripNumber && strip_num < ((Int_t)StripDigitNumberMatches.size() + FirstStripNumber))
338 return StripDigitNumberMatches[strip_num - FirstStripNumber];
339 else
340 return BmnMatch(); // return an empty match
341}
342
344{
345 Int_t NStrips = GetNStrips();
346
347 StripMatches.clear();
348 StripMatches.resize(NStrips, BmnMatch());
349}
350
352{
353 Int_t NStrips = GetNStrips();
354
356 StripDigitNumberMatches.resize(NStrips, BmnMatch());
357}
358
360{
361 if (num >= 0 && num < (Int_t)StripHits.size())
362 return StripHits[num];
363
364 return -1.0;
365}
366
368{
369 if (num >= 0 && num < (Int_t)StripHitsTotalSignal.size())
370 return StripHitsTotalSignal[num];
371
372 return -1.0;
373}
374
376{
377 if (num >= 0 && num < (Int_t)StripHitsErrors.size())
378 return StripHitsErrors[num];
379
380 return -1.0;
381}
382
384{
385 if (num >= 0 && num < (Int_t)StripHitsClusterSize.size())
386 return StripHitsClusterSize[num];
387
388 return -1.0;
389}
390
392{
393 StripHits.clear();
394 StripHitsTotalSignal.clear();
395 StripHitsErrors.clear();
396 StripHitsClusterSize.clear();
397 StripClusters.clear();
398}
399
401{
402 Double_t XRotationCenter;
403 Double_t YRotationCenter;
404
405 if (StripOrder == LeftToRight) {
406 XRotationCenter = XLeftPointOfStripNumbering;
407 YRotationCenter = YLeftPointOfStripNumbering;
408 } else {
409 if (StripOrder == RightToLeft) {
410 XRotationCenter = XRightPointOfStripNumbering;
411 YRotationCenter = YRightPointOfStripNumbering;
412 }
413 }
414 Double_t StripX =
415 (x - XRotationCenter) * Cos(-AngleRad) + (y - YRotationCenter) * Sin(-AngleRad) + XRotationCenter; // see
416 return StripX;
417}
418
420{
421 Double_t XRotationCenter;
422 Double_t YRotationCenter;
423
424 if (StripOrder == LeftToRight) {
425 XRotationCenter = XLeftPointOfStripNumbering;
426 YRotationCenter = YLeftPointOfStripNumbering;
427 } else {
428 if (StripOrder == RightToLeft) {
429 XRotationCenter = XRightPointOfStripNumbering;
430 YRotationCenter = YRightPointOfStripNumbering;
431 }
432 }
433 Double_t StripY =
434 -(x - XRotationCenter) * Sin(-AngleRad) + (y - YRotationCenter) * Cos(-AngleRad) + YRotationCenter; // see
435 return StripY;
436}
437
439{
440 // This function returns real(double) value,
441 // where integer part - number of a strip, fractional part - position on this strip (as ratio from begin)
442
443 if (StripOrder == LeftToRight) {
445 } else {
446 if (StripOrder == RightToLeft) {
448 }
449 }
450
451 return -1;
452}
453
455{
456
457 Double_t b;
458
459 if (Abs(AngleDeg) != 90.0) { // case: y=a*x+b
460 Double_t x_strip_shift = ((strip_pos - FirstStripNumber) * Pitch) / Cos(Abs(AngleRad));
461 Double_t xcoord;
462
463 if (StripOrder == LeftToRight) {
464 xcoord = XLeftPointOfStripNumbering + x_strip_shift;
466 } else {
467 if (StripOrder == RightToLeft) {
468 xcoord = XRightPointOfStripNumbering - x_strip_shift;
470 }
471 }
472 } else { // case: y=b
473 Double_t y_strip_shift = (strip_pos - FirstStripNumber) * Pitch * Sin(AngleRad);
474
475 if (StripOrder == LeftToRight) {
476 b = YLeftPointOfStripNumbering - y_strip_shift;
477 } else {
478 if (StripOrder == RightToLeft) {
479 b = YRightPointOfStripNumbering + y_strip_shift;
480 }
481 }
482 }
483
484 return b;
485}
486
488{
489
491
493 // Double_t threshold = 500.0;
494
495 StripCluster cluster;
496
497 Bool_t ascent = false;
498 Bool_t descent = false;
499
500 // Processing strips
501 vector<Double_t> AnalyzableStrips = Strips;
502
503 // Smooth strip signal ------------------------------------------------------
504 // if(Pitch > 0.079) SmoothStripSignal(AnalyzableStrips, 1, 1, 1.0);
505 // else SmoothStripSignal(AnalyzableStrips, 2, 1, 1.0);
506 //--------------------------------------------------------------------------
507
508 for (Int_t is = 0; is < (Int_t)AnalyzableStrips.size(); is++) {
509 if (AnalyzableStrips.at(is) <= threshold) {
510 if (descent || ascent) {
511 descent = false;
512 ascent = false;
513 // make strip hit
514 MakeStripHit(cluster, AnalyzableStrips, is);
515 }
516 continue;
517 }
518
519 if (cluster.GetClusterSize() > 0) {
520 if (AnalyzableStrips.at(is) >= (cluster.Signals.at(cluster.GetClusterSize() - 1))) {
521 if (descent) {
522 ascent = false;
523 descent = false;
524 // make strip hit
525 MakeStripHit(cluster, AnalyzableStrips, is);
526 // continue;
527 }
528 ascent = true;
529 descent = false;
530 } else {
531 ascent = false;
532 descent = true;
533 }
534 } else {
535 ascent = true;
536 descent = false;
537 }
538
539 cluster.AddStrip(is, AnalyzableStrips.at(is));
540 }
541
542 if (cluster.GetClusterSize() != 0) {
543 // make strip hit
544 Int_t lastnum = AnalyzableStrips.size() - 1;
545 MakeStripHit(cluster, AnalyzableStrips, lastnum);
546 }
547}
548
549void BmnSiliconLayer::MakeStripHit(StripCluster& cluster, vector<Double_t>& AnalyzableStrips, Int_t& curcnt)
550{
551
552 Double_t mean_strip_position = 0.0;
553 Double_t total_cluster_signal = 0.0;
554 Double_t cluster_rms = 0.0;
555
556 Int_t NStripsInCluster = cluster.GetClusterSize();
557
558 // Share the common strip signal of two adjacent clusters in half
559 if (true) {
560 if (AnalyzableStrips.at(curcnt) >= AnalyzableStrips.at(curcnt - 1)) {
561 cluster.Signals.at(cluster.Signals.size() - 1) *= 0.5;
562 AnalyzableStrips.at(curcnt - 1) *= 0.5;
563 }
564 }
565
566 // mean position and cluster signal -----------------------------------------
567 for (Int_t i = 0; i < NStripsInCluster; ++i) {
568 Double_t strip_num = cluster.Strips.at(i) + FirstStripNumber;
569 Double_t signal = cluster.Signals.at(i);
570 total_cluster_signal += signal;
571 mean_strip_position += (strip_num + 0.5) * signal;
572 }
573 mean_strip_position /= total_cluster_signal;
574
575 if (mean_strip_position < FirstStripNumber)
576 mean_strip_position = FirstStripNumber;
577 if (mean_strip_position >= AnalyzableStrips.size() + FirstStripNumber)
578 mean_strip_position = AnalyzableStrips.size() - 0.001;
579 //--------------------------------------------------------------------------
580
581 // cluster standard deviation (sigma): RMS ----------------------------------
582 // if(NStripsInCluster > 1) {
583 // for(Int_t i = 0; i < NStripsInCluster; ++i) {
584 // Double_t strip_num = cluster.Strips.at(i) + FirstStripNumber;
585 // Double_t signal = cluster.Signals.at(i);
586 // Double_t residual = (strip_num+0.5) - mean_strip_position;
587 // cluster_rms += residual*residual*signal;
588 // }
589 // cluster_rms /= total_cluster_signal;
590 // cluster_rms = TMath::Sqrt(cluster_rms);
591 // }
592 // else {
593 // cluster_rms = 1.0/TMath::Sqrt(12.0);
594 // }
595 //
596
597 // AZ, STS, method2
598 Double_t sumW = total_cluster_signal;
599 Double_t sumWX = 0.;
600 Double_t sumWX2 = 0.;
601 if (NStripsInCluster > 1) {
602 for (Int_t i = 0; i < NStripsInCluster; ++i) {
603 Double_t strip_num = cluster.Strips.at(i) + FirstStripNumber;
604 Double_t signal = cluster.Signals.at(i);
605 sumWX += strip_num * signal;
606 sumWX2 += strip_num * strip_num * signal;
607 }
608 cluster_rms = (sumWX2 - sumWX * sumWX / sumW) / sumW;
609 }
610
611 else
612 {
613 cluster_rms = 1.0 / TMath::Sqrt(12.0);
614 }
615
616 //--------------------------------------------------------------------------
617
618 StripHits.push_back(mean_strip_position);
619 StripHitsTotalSignal.push_back(total_cluster_signal);
620 StripHitsErrors.push_back(cluster_rms);
621 StripHitsClusterSize.push_back(NStripsInCluster);
622
623 cluster.MeanPosition = mean_strip_position;
624 cluster.TotalSignal = total_cluster_signal;
625 cluster.SetWidth(NStripsInCluster);
626 cluster.Error = cluster_rms;
627 if (LayerType == LowerStripLayer) {
628 cluster.SetType(0);
629 cluster.SetUniqueID(fUniqueIdL++);
630 } else {
631 cluster.SetType(1);
632 cluster.SetUniqueID(fUniqueIdU++);
633 }
634
635 /* Update strip numbers in the local cluster according to
636 * the FirstStripNumber shift before we can use it in the outer code
637 */
638 for (Int_t i = 0; i < NStripsInCluster; ++i) {
639 cluster.Strips.at(i) += FirstStripNumber;
640 }
641
642 StripClusters.push_back(cluster);
643
644 // return to a previous strip
645 curcnt--;
646 if (curcnt < 0)
647 curcnt = 0;
648
649 cluster.Clear();
650}
651
652void BmnSiliconLayer::SmoothStripSignal(vector<Double_t>& AnalyzableStrips,
653 Int_t NIterations,
654 Int_t SmoothWindow,
655 Double_t Weight)
656{
657 // It's the Simple Moving Average (SMA) method
658 // AnalyzableStrips - analyzable strip layer (ref)
659 // NIterations - number of smooth iterations (usually 1)
660 // SmoothWindow - number of strips on the left-right of the current strip (usually 1)
661 // Weight - weight of the current strip (usually 1.0 - for simplicity, greater - for weighted value))
662
663 SmoothStrips.clear();
664 Int_t NStrips = AnalyzableStrips.size();
665
666 for (Int_t iteration = 0; iteration < NIterations; ++iteration) {
667 SmoothStrips.clear();
668 for (Int_t istrip = 0; istrip < NStrips; ++istrip) {
669 Double_t mean_value = 0.0;
670 for (Int_t iw = istrip - SmoothWindow; iw <= istrip + SmoothWindow; ++iw) {
671 if (iw >= 0 && iw < NStrips) {
672 if (iw == istrip)
673 mean_value += AnalyzableStrips[iw] * Weight;
674 else
675 mean_value += AnalyzableStrips[iw];
676 }
677 }
678 mean_value /= 2.0 * SmoothWindow + Weight;
679 SmoothStrips.push_back(mean_value);
680 }
681 AnalyzableStrips = SmoothStrips;
682 }
683
684 return;
685}
int i
Definition P4_F32vec4.h:22
bool Bool_t
int Int_t
double Double_t
StripBorderPoint
@ LeftTop
@ RightBottom
@ LeftBottom
@ RightTop
@ RightToLeft
@ LeftToRight
@ LowerStripLayer
Bool_t AddDeadZone(Int_t n_points, Double_t *x_points, Double_t *y_points)
Double_t CalculateStripEquationB(Double_t strip_pos)
Bool_t IsPointInsideStripLayer(Double_t x, Double_t y)
Double_t GetStripSignal(Int_t strip_num)
Bool_t SetStripDigitNumberMatch(Int_t strip_num, BmnMatch digit_num_match)
vector< Double_t > SmoothStrips
void MakeStripHit(StripCluster &cluster, vector< Double_t > &AnalyzableStrips, Int_t &curcnt)
Double_t ClusterFindingThreshold
BmnMatch GetStripMatch(Int_t strip_num)
StripNumberingDirection StripOrder
vector< Double_t > StripHitsErrors
Bool_t SetStripMatch(Int_t strip_num, BmnMatch mc_match)
void SmoothStripSignal(vector< Double_t > &AnalyzableStrips, Int_t NIterations, Int_t SmoothWindow, Double_t Weight)
Bool_t AddStripSignal(Int_t strip_num, Double_t signal)
Bool_t SetStripSignal(Int_t strip_num, Double_t signal)
vector< Int_t > StripHitsClusterSize
void SetAngleDeg(Double_t deg)
Double_t XRightPointOfStripNumbering
Bool_t IsPointInsideDeadZones(Double_t x, Double_t y)
Bool_t AddLinkToStripMatch(Int_t strip_num, Double_t weight, Int_t mc_num)
void ResetStripDigitNumberMatches()
static Int_t fUniqueIdL
Bool_t SetStripNumberingBorders(Double_t x_left, Double_t y_left, Double_t x_right, Double_t y_right)
BmnMatch GetStripDigitNumberMatch(Int_t strip_num)
Double_t GetStripHitPos(Int_t num)
vector< Double_t > StripHitsTotalSignal
Double_t XLeftPointOfStripNumbering
Bool_t SetStripNumberingOrder(StripNumberingDirection strip_direction)
Double_t ConvertNormalPointToStripY(Double_t x, Double_t y)
vector< StripCluster > StripClusters
Double_t GetStripHitError(Int_t num)
Int_t GetStripHitClusterSize(Int_t num)
void SetPitch(Double_t pitch)
Bool_t AddLinkToStripDigitNumberMatch(Int_t strip_num, Double_t weight, Int_t digit_num)
vector< Double_t > Strips
vector< Double_t > StripHits
vector< BmnMatch > StripMatches
void SetLayerSizes(Double_t xsize, Double_t ysize, Double_t xorig=0.0, Double_t yorig=0.0)
Double_t ConvertNormalPointToStripX(Double_t x, Double_t y)
Double_t ConvertPointToStripPosition(Double_t x, Double_t y)
Double_t GetStripHitTotalSignal(Int_t num)
Double_t YRightPointOfStripNumbering
vector< BmnMatch > StripDigitNumberMatches
StripLayerType LayerType
vector< DeadZoneOfStripLayer > DeadZones
virtual ~BmnSiliconLayer()
Double_t YLeftPointOfStripNumbering
static Int_t fUniqueIdU
Bool_t SetDeadZone(Int_t n_points, Double_t *xpoints, Double_t *ypoints)
Double_t TotalSignal
Int_t GetClusterSize()
Double_t MeanPosition
Double_t Error
void SetWidth(Int_t w)
void AddStrip(Int_t strip_num, Double_t strip_signal)
void SetType(Int_t type)
vector< Int_t > Strips
vector< Double_t > Signals
virtual void SetUniqueID(UInt_t uid)
Bool_t IsInside(T xp, T yp, Int_t np, T *x, T *y)
constexpr Double_t PiOver2()
constexpr Double_t E()
Double_t Sqrt(Double_t x)
Double_t Cos(Double_t)
constexpr Double_t Pi()
Double_t Abs(Double_t d)
Double_t Sin(Double_t)
Double_t Tan(Double_t)
Definition json.hpp:4446