KaliVeda
Toolkit for HIC analysis
KVTrapezoidalStripDetector.cpp
1 #include "KVTrapezoidalStripDetector.h"
2 
3 
5 
6 TGeoArb8* KVTrapezoidalStripDetector::make_arb8(const TString& name, double A, double B, double C, double dZ, double dX)
7 {
8  double vert[] = {dX + C / 2, A / 2, dX + C / 2, -A / 2, dX - C / 2, -B / 2, dX - C / 2, B / 2, dX + C / 2, A / 2, dX + C / 2, -A / 2, dX - C / 2, -B / 2, dX - C / 2, B / 2};
9  return new TGeoArb8(name, dZ / 2., vert);
10 }
11 
12 
13 
15 
16 TGeoArb8* KVTrapezoidalStripDetector::make_vert_strip_arb8(const TString& name, double y_A, double y_B, double x_AB, double x_C, double x_D, double dZ, double dX)
17 {
18  double vert[] = {x_D + dX, y_A, x_C + dX, y_B, x_AB + dX, y_B, x_AB + dX, y_A, x_D + dX, y_A, x_C + dX, y_B, x_AB + dX, y_B, x_AB + dX, y_A};
19  return new TGeoArb8(name, dZ / 2., vert);
20 }
21 
22 
23 
25 
26 TGeoArb8* KVTrapezoidalStripDetector::make_hori_strip_arb8(const TString& name, double x_AB, double y_A, double x_CD, double y_D, double dZ, double dX)
27 {
28  double vert[] = {x_CD + dX, y_D, x_CD + dX, -y_D, x_AB + dX, -y_A, x_AB + dX, y_A, x_CD + dX, y_D, x_CD + dX, -y_D, x_AB + dX, -y_A, x_AB + dX, y_A};
29  return new TGeoArb8(name, dZ / 2., vert);
30 }
31 
32 
33 
37 
38 double KVTrapezoidalStripDetector::Xcoord_of_frame_bottom(double Ycoord, double A, double B, double C)
39 {
40  // for given Y coord (horizontal position) give X coord (vertical) of the 1 of the 3 sides
41  // making up the bottom of the frame. in coordinates where trapeze centre is at X=0.
42 
43  if (Ycoord < -A / 2) Ycoord = -A / 2;
44  if (Ycoord > A / 2) Ycoord = A / 2;
45  if (TMath::Abs(Ycoord) < B / 2) {
46  // on the bottom segment cc->dd
47  return -C / 2;
48  }
49  if (Ycoord <= -B / 2 && Ycoord >= -A / 2) {
50  // on left hand segment bb->cc
51  return C / 2 - 2 * C / (A - B) * (Ycoord + A / 2);
52  }
53  if (Ycoord >= B / 2 && Ycoord <= A / 2) {
54  // on right hand segment dd->aa
55  return 2 * C / (A - B) * (Ycoord - B / 2) - C / 2;
56  }
57  return 0;
58 }
59 
60 
61 
66 
67 double KVTrapezoidalStripDetector::Ycoord_of_frame_side(double Xcoord, double A, double B, double C)
68 {
69  // for a given vertical (X) position (between -C/2 and C/2) give the Y coordinate
70  // on the side frame (between A/2 and B/2). We give the positive coordinate, the reflection
71  // is given by the negative coordinate.
72 
73  return B / 2 + (A - B) / 2 / C * (Xcoord + C / 2);
74 }
75 
76 
77 
85 
86 KVTrapezoidalStripDetector::KVTrapezoidalStripDetector(const TString& name, double OF_A, double OF_B, double OF_C, double IF_A, double IF_B, double IF_C, double a, double dZ, StripDirection strip_direction, int N, double inter_strip)
87  : TGeoVolumeAssembly(Form("DET_%s", name.Data()))
88 {
89  /*
90  OF_A, OF_B, OF_C = dimensions of outer frame (PCB) in cm
91  IF_A, IF_B, IF_C = dimensions of inner frame (silicon) in cm
92  a = distance between top of outer frame (OF_A) and top of inner frame (IF_A) in cm
93  dZ = silicon thickness in cm
94  N = number of strips
95  inter_strip given in cm
96  */
97  KVMaterial si("Si"), cu("Cu"), al("Al");
98  auto OF_trap = make_arb8(Form("OF_%s", name.Data()), OF_A, OF_B, OF_C, frame_thickness);
99  // deduce b from a, OF_C and IF_C
100  auto b = OF_C - a - IF_C;
101  std::cout << "calculated b = " << b << " [cm]\n";
102  dX_IF = 0.5 * (b - a);
103  auto IF_trap = make_arb8(Form("IF_%s", name.Data()), IF_A, IF_B, IF_C, frame_thickness, dX_IF);
104  auto cs = new TGeoCompositeShape(Form("FRAME_%s", name.Data()), Form("OF_%s-IF_%s", name.Data(), name.Data()));
105  auto ofr = new TGeoVolume(Form("DEADZONE_FRAME_%s", name.Data()), cs, cu.GetGeoMedium());
106  ofr->SetTransparency((Char_t)25);
107 
108  if (strip_direction == StripDirection::vertical) {
109  // vertical strips
110  double pitch = (IF_A - (N - 1) * inter_strip) / double(N);
111  std::cout << "Strip width is " << pitch / KVUnits::um << " microns (" << inter_strip / KVUnits::um << " micron inter-strip)\n";
112  double strip_B_y = IF_A / 2;
113  double strip_A_y = strip_B_y - pitch;
114  for (int strip = 0; strip < N; ++strip) {
115  auto strip_C_x = Xcoord_of_frame_bottom(strip_B_y, IF_A, IF_B, IF_C);
116  auto strip_D_x = Xcoord_of_frame_bottom(strip_A_y, IF_A, IF_B, IF_C);
117  auto _s = make_vert_strip_arb8(Form("%s_STRIP_%d", name.Data(), strip), strip_A_y, strip_B_y, IF_C / 2, strip_C_x, strip_D_x, dZ, dX_IF);
118  auto _svol = new TGeoVolume("SUBDET", _s, si.GetGeoMedium());
119  //_svol->SetLineColor(kGray+1);
120  AddNode(_svol, strip);
121  strip_B_y -= (pitch + inter_strip);
122  strip_A_y -= (pitch + inter_strip);
123  }
124  // add interstrip deadzones
125  strip_B_y = IF_A / 2 - pitch;
126  strip_A_y = strip_B_y - inter_strip;
127  for (int strip = 1; strip < N; ++strip) {
128  auto strip_C_x = Xcoord_of_frame_bottom(strip_B_y, IF_A, IF_B, IF_C);
129  auto strip_D_x = Xcoord_of_frame_bottom(strip_A_y, IF_A, IF_B, IF_C);
130  auto _s = make_vert_strip_arb8(Form("%s_INTERSTRIP_%d", name.Data(), strip), strip_A_y, strip_B_y, IF_C / 2, strip_C_x, strip_D_x, dZ, dX_IF);
131  auto _svol = new TGeoVolume(Form("DEADZONE_%s_INTERSTRIP", name.Data()), _s, al.GetGeoMedium());
132  //_svol->SetLineColor(kBlack);
133  AddNode(_svol, strip + N);
134  strip_B_y -= (pitch + inter_strip);
135  strip_A_y -= (pitch + inter_strip);
136  }
137  }
138  else { // strip_direction==horizontal
139  // horizontal strips: numbered from bottom (short/B side) to top (long/A side)
140  double pitch = (IF_C - (N - 1) * inter_strip) / double(N);
141  std::cout << "Strip width is " << pitch / KVUnits::um << " microns (" << inter_strip / KVUnits::um << " micron inter-strip)\n";
142  double strip_AB_x = -IF_C / 2;
143  double strip_CD_x = strip_AB_x + pitch;
144  for (int strip = 0; strip < N; ++strip) {
145  auto strip_AB_y = Ycoord_of_frame_side(strip_AB_x, IF_A, IF_B, IF_C);
146  auto strip_CD_y = Ycoord_of_frame_side(strip_CD_x, IF_A, IF_B, IF_C);
147  auto _s = make_hori_strip_arb8(Form("%s_STRIP_%d", name.Data(), strip), strip_AB_x, strip_AB_y, strip_CD_x, strip_CD_y, dZ, dX_IF);
148  auto _svol = new TGeoVolume("SUBDET", _s, si.GetGeoMedium());
149  //_svol->SetLineColor(kGray+1);
150  AddNode(_svol, strip);
151  strip_AB_x += (pitch + inter_strip);
152  strip_CD_x += (pitch + inter_strip);
153  }
154  // add interstrip deadzones
155  strip_AB_x = -IF_C / 2 + pitch;
156  strip_CD_x = strip_AB_x + inter_strip;
157  for (int strip = 1; strip < N; ++strip) {
158  auto strip_AB_y = Ycoord_of_frame_side(strip_AB_x, IF_A, IF_B, IF_C);
159  auto strip_CD_y = Ycoord_of_frame_side(strip_CD_x, IF_A, IF_B, IF_C);
160  auto _s = make_hori_strip_arb8(Form("%s_INTERSTRIP_%d", name.Data(), strip), strip_AB_x, strip_AB_y, strip_CD_x, strip_CD_y, dZ, dX_IF);
161  auto _svol = new TGeoVolume(Form("DEADZONE_%s_INTERSTRIP", name.Data()), _s, al.GetGeoMedium());
162  //_svol->SetLineColor(kBlack);
163  AddNode(_svol, strip + N);
164  strip_AB_x += (pitch + inter_strip);
165  strip_CD_x += (pitch + inter_strip);
166  }
167  }
168  AddNode(ofr, 2 * N, new TGeoTranslation(0, 0, 0.5 * (dZ + frame_thickness)));
169 }
170 
171 
173 
174 
175 
char Char_t
#define N
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t b
char name[80]
char * Form(const char *fmt,...)
Description of physical materials used to construct detectors & targets; interface to range tables.
Definition: KVMaterial.h:89
virtual TGeoMedium * GetGeoMedium(const Char_t *="")
Single-sided stripped trapezoidal silicon detector.
double Ycoord_of_frame_side(double Xcoord, double A, double B, double C)
double Xcoord_of_frame_bottom(double Ycoord, double A, double B, double C)
TGeoArb8 * make_arb8(const TString &name, double A, double B, double C, double dZ, double dX=0)
TGeoArb8 * make_hori_strip_arb8(const TString &name, double x_AB, double y_A, double x_CD, double y_D, double dZ, double dX=0)
TGeoArb8 * make_vert_strip_arb8(const TString &name, double y_A, double y_B, double x_AB, double x_C, double x_D, double dZ, double dX=0)
TGeoNode * AddNode(TGeoVolume *vol, Int_t copy_no, TGeoMatrix *mat=nullptr, Option_t *option="") override
const long double um
Definition: KVUnits.h:68
constexpr Double_t C()
Double_t Abs(Double_t d)
TArc a
ClassImp(TPyArg)