Line data Source code
1 : /**************************************************************************
2 : * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 : * *
4 : * Author: The ALICE Off-line Project. *
5 : * Contributors are mentioned in the code where appropriate. *
6 : * *
7 : * Permission to use, copy, modify and distribute this software and its *
8 : * documentation strictly for non-commercial purposes is hereby granted *
9 : * without fee, provided that the above copyright notice appears in all *
10 : * copies and that both the copyright notice and this permission notice *
11 : * appear in the supporting documentation. The authors make no claims *
12 : * about the suitability of this software for any purpose. It is *
13 : * provided "as is" without express or implied warranty. *
14 : **************************************************************************/
15 :
16 : // $Id$
17 :
18 : //*************************************************************************
19 : // Class for flat cables
20 : //
21 : // Ludovic Gaudichet gaudichet@to.infn.it
22 : //*************************************************************************
23 :
24 :
25 :
26 : // General Root includes
27 : //#include <Riostream.h>
28 : #include <TMath.h>
29 : #include <TVectorD.h>
30 :
31 : // Root Geometry includes
32 : #include <TGeoManager.h>
33 : #include <TGeoVolume.h>
34 : #include <TGeoArb8.h>
35 : #include <TGeoTube.h>
36 : #include <TGeoMatrix.h>
37 : #include <TGeoNode.h>
38 :
39 : #include "AliITSv11GeomCableFlat.h"
40 :
41 :
42 116 : ClassImp(AliITSv11GeomCableFlat)
43 :
44 : //________________________________________________________________________
45 : AliITSv11GeomCableFlat::AliITSv11GeomCableFlat():
46 44 : AliITSv11GeomCable(),
47 44 : fWidth(0),
48 44 : fThick(0),
49 44 : fNlayer(0)
50 220 : {
51 : // constructor
52 1408 : for (Int_t i=0; i<fgkCableMaxLayer ; i++) {
53 660 : fLayThickness[i] = 0;
54 660 : fTranslation[i] = 0;
55 660 : fLayColor[i] = 0;
56 660 : fLayMedia[i] = 0;
57 : };
58 352 : for(Int_t i=0;i<3;i++)fPreviousX[i]=0.;
59 88 : }
60 :
61 : //________________________________________________________________________
62 : AliITSv11GeomCableFlat::
63 : AliITSv11GeomCableFlat(const char* name, Double_t width, Double_t thick) :
64 41 : AliITSv11GeomCable(name),
65 41 : fWidth(width),
66 41 : fThick(thick),
67 41 : fNlayer(0)
68 205 : {
69 : // standard constructor
70 1312 : for (Int_t i=0; i<fgkCableMaxLayer ; i++) {
71 615 : fLayThickness[i] = 0;
72 615 : fTranslation[i] = 0;
73 615 : fLayColor[i] = 0;
74 615 : fLayMedia[i] = 0;
75 : };
76 328 : for(Int_t i=0;i<3;i++)fPreviousX[i]=0.;
77 82 : }
78 : /*
79 : //________________________________________________________________________
80 : AliITSv11GeomCableFlat::AliITSv11GeomCableFlat(const AliITSv11GeomCableFlat &s) :
81 : AliITSv11GeomCable(s),fWidth(s.fWidth),fThick(s.fThick),fNlayer(s.fNlayer)
82 : {
83 : // Copy Constructor
84 : for (Int_t i=0; i<s.fNlayer; i++) {
85 : fLayThickness[i] = s.fLayThickness[i];
86 : fTranslation[i] = s.fTranslation[i];
87 : fLayMedia[i] = s.fLayMedia[i];
88 : fLayColor[i] = s.fLayColor[i];
89 : }
90 : for(Int_t i=0;i<3;i++)fPreviousX[i]=s.fPreviousX[i];
91 :
92 : }
93 :
94 : //________________________________________________________________________
95 : AliITSv11GeomCableFlat& AliITSv11GeomCableFlat::
96 : operator=(const AliITSv11GeomCableFlat &s) {
97 : // Assignment operator
98 : // Not fully inplemented yet !!!
99 :
100 : if(&s == this) return *this;
101 : *this = s;
102 : fWidth = s.fWidth;
103 : fThick = s.fThick;
104 : fNlayer = s.fNlayer;
105 : for (Int_t i=0; i<s.fNlayer; i++) {
106 : fLayThickness[i] = s.fLayThickness[i];
107 : fTranslation[i] = s.fTranslation[i];
108 : fLayMedia[i] = s.fLayMedia[i];
109 : fLayColor[i] = s.fLayColor[i];
110 : };
111 : return *this;
112 : }
113 : */
114 : //________________________________________________________________________
115 : Int_t AliITSv11GeomCableFlat::GetPoint( Int_t iCheckPt, Double_t *coord)
116 : const {
117 : // Get the correct point #iCheckPt
118 696 : TVectorD *coordVector =(TVectorD *)fPointArray.At(2*iCheckPt);
119 348 : if (coordVector) {
120 : #if ROOT_VERSION_CODE < ROOT_VERSION(4,0,0)
121 : CopyFrom(coord, coordVector->GetElements());
122 : #else
123 348 : CopyFrom(coord, coordVector->GetMatrixArray());
124 : #endif
125 348 : return kTRUE;
126 : } else {
127 0 : return kFALSE;
128 : };
129 348 : }
130 :
131 : //________________________________________________________________________
132 : Int_t AliITSv11GeomCableFlat::GetVect( Int_t iCheckPt, Double_t *coord)
133 : const {
134 : // Get the correct vect corresponding to point #iCheckPt
135 :
136 616 : TVectorD *coordVector =(TVectorD *)fPointArray.At(2*iCheckPt+1);
137 308 : if (coordVector) {
138 : #if ROOT_VERSION_CODE < ROOT_VERSION(4,0,0)
139 : CopyFrom(coord, coordVector->GetElements());
140 : #else
141 308 : CopyFrom(coord, coordVector->GetMatrixArray());
142 : #endif
143 308 : return kTRUE;
144 : } else {
145 0 : return kFALSE;
146 : };
147 308 : }
148 :
149 : //________________________________________________________________________
150 : void AliITSv11GeomCableFlat::AddCheckPoint( TGeoVolume *vol, Int_t iCheckPt,
151 : Double_t *coord, Double_t *orthVect)
152 : {
153 : //
154 : // Add a check point. In the fPointArray, the point is at i and its vector
155 : // is at i+1.
156 : //
157 :
158 : // if (iCheckPt>=fVolumeArray.GetEntriesFast()) {
159 : // fVolumeArray.AddLast(vol);
160 : // TVectorD *point = new TVectorD(3,coord);
161 : // TVectorD *vect = new TVectorD(3,orthVect);
162 : // fPointArray.AddLast(point);
163 : // fPointArray.AddLast(vect);
164 :
165 : // } else if ((iCheckPt >= 0)&&(iCheckPt < fVolumeArray.GetEntriesFast())) {
166 : // fVolumeArray.AddAt(vol, iCheckPt);
167 : // TVectorD *point = new TVectorD(3,coord);
168 : // TVectorD *vect = new TVectorD(3,orthVect);
169 : // fPointArray.AddAt(point, iCheckPt*2 );
170 : // fPointArray.AddAt(vect, iCheckPt*2+1);
171 : // };
172 516 : fVolumeArray.AddAtAndExpand(vol, iCheckPt);
173 258 : TVectorD *point = new TVectorD(3,coord);
174 258 : TVectorD *vect = new TVectorD(3,orthVect);
175 258 : fPointArray.AddAtAndExpand(point, iCheckPt*2 );
176 258 : fPointArray.AddAtAndExpand(vect, iCheckPt*2+1);
177 258 : }
178 :
179 : //________________________________________________________________________
180 : void AliITSv11GeomCableFlat::PrintCheckPoints() const {
181 : // print all check points of the cable
182 0 : printf(" ---\n Printing all check points of the flat cable\n");
183 0 : for (Int_t i = 0; i<fVolumeArray.GetEntriesFast(); i++) {
184 0 : Double_t coord[3];
185 0 : if (GetPoint( i, coord))
186 0 : printf(" ( %.2f, %.2f, %.2f )\n", coord[0], coord[1], coord[2]);
187 0 : };
188 0 : }
189 :
190 : //________________________________________________________________________
191 : TGeoVolume* AliITSv11GeomCableFlat::CreateAndInsertCableSegment(Int_t p2,
192 : Double_t rotation,
193 : TGeoCombiTrans** ct)
194 : {
195 : // Creates a cable segment between points p1 and p2.
196 : // Rotation is the eventual rotation of the flat cable
197 : // along its length axis
198 : //
199 : // The segment volume is created inside the volume containing point2
200 : // Therefore this segment should be defined in this volume only.
201 : // I mean here that, if the previous point is in another volume,
202 : // it should be just at the border between the 2 volumes. Also the
203 : // orientation vector of the previous point should be orthogonal to
204 : // the surface between the 2 volumes.
205 :
206 : TGeoNode *mainNode;
207 158 : if (fInitialNode==0) {
208 0 : TObjArray *nodes = gGeoManager->GetListOfNodes();
209 0 : if (nodes->GetEntriesFast()==0) return 0;
210 0 : mainNode = (TGeoNode *) nodes->UncheckedAt(0);
211 0 : } else {
212 : mainNode = fInitialNode;
213 : };
214 :
215 79 : Int_t p1 = p2 - 1;
216 79 : TGeoVolume *p2Vol = GetVolume(p2);
217 79 : TGeoVolume *p1Vol = GetVolume(p1);
218 :
219 79 : ResetCheckDaughter();
220 79 : fCurrentVol = p1Vol;
221 79 : if (! CheckDaughter(mainNode)) {
222 0 : printf("Error::volume containing point is not visible in node tree!\n");
223 0 : return 0;
224 : };
225 :
226 79 : Double_t coord1[3], coord2[3], vect1[3], vect2[3];
227 : //=================================================
228 : // Get p1 position in the systeme of p2
229 79 : if (p1Vol!=p2Vol) {
230 :
231 36 : Int_t p1nodeInd[fgkCableMaxNodeLevel];
232 3672 : for (Int_t i=0; i<fgkCableMaxNodeLevel; i++) p1nodeInd[i]=fNodeInd[i];
233 : Int_t p1volLevel = 0;
234 144 : while (p1nodeInd[p1volLevel]!=-1) p1volLevel++;
235 36 : p1volLevel--;
236 :
237 36 : ResetCheckDaughter();
238 36 : fCurrentVol = p2Vol;
239 36 : if (! CheckDaughter(mainNode)) {
240 0 : printf("Error::volume containing point is not visible in node tree!\n");
241 0 : return 0;
242 : };
243 36 : Int_t p2nodeInd[fgkCableMaxNodeLevel];
244 3672 : for (Int_t i=0; i<fgkCableMaxNodeLevel; i++) p2nodeInd[i]=fNodeInd[i];
245 : Int_t commonMotherLevel = 0;
246 72 : while (p1nodeInd[commonMotherLevel]==fNodeInd[commonMotherLevel])
247 0 : commonMotherLevel++;
248 36 : commonMotherLevel--;
249 : Int_t p2volLevel = 0;
250 144 : while (fNodeInd[p2volLevel]!=-1) p2volLevel++;
251 36 : p2volLevel--;
252 :
253 : // Get coord and vect of p1 in the common mother reference system
254 36 : if (! GetCheckPoint(p1, 0, p1volLevel-commonMotherLevel, coord1) )
255 0 : return 0;
256 36 : if (! GetCheckVect( p1, 0, p1volLevel-commonMotherLevel, vect1) )
257 0 : return 0;
258 :
259 : // Translate them in the reference system of the volume containing p2
260 36 : TGeoNode *pathNode[fgkCableMaxNodeLevel];
261 36 : pathNode[0] = mainNode;
262 144 : for (Int_t i=0; i<=p2volLevel; i++) {
263 36 : pathNode[i+1] = pathNode[i]->GetDaughter(p2nodeInd[i]);
264 : };
265 36 : Double_t globalCoord1[3] = {coord1[0], coord1[1], coord1[2]};
266 36 : Double_t globalVect1[3] = {vect1[0], vect1[1], vect1[2]};
267 :
268 144 : for (Int_t i = commonMotherLevel+1; i <= p2volLevel; i++) {
269 36 : pathNode[i+1]->GetMatrix()->MasterToLocal(globalCoord1, coord1);
270 36 : pathNode[i+1]->GetMatrix()->MasterToLocalVect(globalVect1, vect1);
271 36 : CopyFrom(globalCoord1, coord1);
272 36 : CopyFrom(globalVect1, vect1);
273 : };
274 108 : } else {
275 43 : if (! GetCheckPoint(p1, 0, 0, coord1) ) return 0;
276 43 : if (! GetCheckVect(p1, 0, 0, vect1) ) return 0;
277 : };
278 :
279 : //=================================================
280 : // Get p2 position in the systeme of p2
281 79 : if (! GetCheckPoint(p2, 0, 0, coord2) ) return 0;
282 79 : if (! GetCheckVect(p2, 0, 0, vect2) ) return 0;
283 :
284 79 : Double_t cx = (coord1[0]+coord2[0])/2;
285 79 : Double_t cy = (coord1[1]+coord2[1])/2;
286 79 : Double_t cz = (coord1[2]+coord2[2])/2;
287 79 : Double_t dx = coord2[0]-coord1[0];
288 79 : Double_t dy = coord2[1]-coord1[1];
289 79 : Double_t dz = coord2[2]-coord1[2];
290 :
291 : //=================================================
292 : // Positionning of the segment between the 2 points
293 93 : if (TMath::Abs(dy)<1e-231) dy = 1e-231;
294 79 : if (TMath::Abs(dz)<1e-231) dz = 1e-231;
295 : //Double_t angleRot1 = -TMath::ATan(dx/dy);
296 : //Double_t planDiagL = -TMath::Sqrt(dy*dy+dx*dx);
297 : //if (dy<0) planDiagL = -planDiagL;
298 : //Double_t angleRotDiag = TMath::ATan(planDiagL/dz);
299 :
300 79 : Double_t angleRot1 = -TMath::ATan2(dx,dy);
301 79 : Double_t planDiagL = TMath::Sqrt(dy*dy+dx*dx);
302 79 : Double_t angleRotDiag = -TMath::ATan2(planDiagL,dz);
303 : //--- (Calculate rotation of segment on the Z axis)
304 : //-- Here I'm trying to calculate the rotation to be applied in
305 : //-- order to match as closer as possible this segment and the
306 : //-- previous one.
307 : //-- It seems that some times it doesn't work ...
308 158 : TGeoRotation rotTemp("",angleRot1*TMath::RadToDeg(),
309 79 : angleRotDiag*TMath::RadToDeg(), rotation);
310 79 : Double_t localX[3] = {0,1,0};
311 79 : Double_t globalX[3];
312 79 : rotTemp.LocalToMasterVect(localX, globalX);
313 79 : CopyFrom(localX, globalX);
314 79 : GetCheckVect(localX, p2Vol, 0, fgkCableMaxNodeLevel+1, globalX);
315 79 : Double_t orthVect[3];
316 79 : GetCheckVect(vect1, p2Vol, 0, fgkCableMaxNodeLevel+1, orthVect);
317 : // Double_t angleRotZ = 0;
318 : // if (p2>1) {
319 : // Double_t orthVectNorm2 = ScalProd(orthVect,orthVect);
320 : // Double_t alpha1 = ScalProd(fPreviousX,orthVect)/orthVectNorm2;
321 : // Double_t alpha2 = ScalProd(globalX,orthVect)/orthVectNorm2;
322 : // Double_t globalX1p[3], globalX2p[3];
323 : // globalX1p[0] = fPreviousX[0] - alpha1*orthVect[0];
324 : // globalX1p[1] = fPreviousX[1] - alpha1*orthVect[1];
325 : // globalX1p[2] = fPreviousX[2] - alpha1*orthVect[2];
326 : // globalX2p[0] = globalX[0] - alpha2*orthVect[0];
327 : // globalX2p[1] = globalX[1] - alpha2*orthVect[1];
328 : // globalX2p[2] = globalX[2] - alpha2*orthVect[2];
329 : // //-- now I'm searching the 3th vect which makes an orthogonal base
330 : // //-- with orthVect and globalX1p ...
331 : // Double_t nulVect[3] = {0,0,0};
332 : // Double_t axis3[3];
333 : // TMath::Normal2Plane(nulVect, orthVect, globalX1p, axis3);
334 : // Double_t globalX1pNorm2 = ScalProd(globalX1p, globalX1p);
335 : // Double_t beta = ScalProd(globalX2p, globalX1p)/globalX1pNorm2;
336 : // Double_t gamma = ScalProd(globalX2p, axis3);
337 : // angleRotZ = (TMath::ATan2(1,0) - TMath::ATan2(beta, gamma))
338 : // *TMath::RadToDeg();
339 : // };
340 : // cout << "!!!!!!!!!!!!!!!!!!! angle = " <<angleRotZ << endl;
341 79 : CopyFrom(fPreviousX, globalX);
342 : //---
343 79 : Double_t localVect1[3], localVect2[3];
344 158 : TGeoRotation rot("",angleRot1*TMath::RadToDeg(),
345 79 : angleRotDiag*TMath::RadToDeg(),
346 : rotation);
347 : // rotation-angleRotZ);
348 : // since angleRotZ doesn't always work, I won't use it ...
349 :
350 79 : rot.MasterToLocalVect(vect1, localVect1);
351 79 : rot.MasterToLocalVect(vect2, localVect2);
352 :
353 : //=================================================
354 : // Create the segment and add it to the mother volume
355 79 : TGeoVolume *vCableSegB = CreateSegment(coord1, coord2,
356 : localVect1, localVect2);
357 79 : TGeoRotation rotArbSeg("", 0, 90, 0);
358 79 : rotArbSeg.MultiplyBy(&rot, kFALSE);
359 79 : TGeoTranslation trans("",cx, cy, cz);
360 158 : TGeoCombiTrans *combiB = new TGeoCombiTrans(trans, rotArbSeg);
361 79 : p2Vol->AddNode(vCableSegB, p2, combiB);
362 : //=================================================;
363 :
364 79 : if (fDebug) {
365 0 : printf("---\n Cable segment points : ");
366 0 : printf("%f, %f, %f\n",coord1[0], coord1[1], coord1[2]);
367 0 : printf("%f, %f, %f\n",coord2[0], coord2[1], coord2[2]);
368 : };
369 :
370 : // #include <TGeoSphere.h>
371 : // TGeoMedium *airSDD = gGeoManager->GetMedium("ITS_AIR$");
372 : // TGeoSphere *sphere = new TGeoSphere(0, 0.05);
373 : // TGeoVolume *vSphere = new TGeoVolume("", sphere, airSDD);
374 : // TGeoTranslation *trC = new TGeoTranslation("", cx, cy, cz);
375 : // TGeoTranslation *tr1 = new TGeoTranslation("",coord1[0],
376 : // coord1[1],coord1[2]);
377 : // TGeoTranslation *tr2 = new TGeoTranslation("",coord2[0],
378 : // coord2[1],coord2[2]);
379 : // p2Vol->AddNode(vSphere, p2*3-2, trC);
380 : // p2Vol->AddNode(vSphere, p2*3-1, tr1);
381 : // p2Vol->AddNode(vSphere, p2*3 , tr2);
382 79 : if (ct) *ct = combiB;
383 : return vCableSegB;
384 237 : }
385 :
386 : //________________________________________________________________________
387 : TGeoVolume* AliITSv11GeomCableFlat::CreateAndInsertBoxCableSegment(Int_t p2,
388 : Double_t rotation,
389 : TGeoCombiTrans** ct)
390 : {
391 : // This function is to be use only when the segment has the shape
392 : // of a simple box, i.e. the normal vector to its end is perpendicular
393 : // to the segment own axis
394 : // Creates a cable segment between points p1 and p2.
395 : // Rotation is the eventual rotation of the flat cable
396 : // along its length axis
397 : //
398 : // The segment volume is created inside the volume containing point2
399 : // Therefore this segment should be defined in this volume only.
400 : // I mean here that, if the previous point is in another volume,
401 : // it should be just at the border between the 2 volumes. Also the
402 : // orientation vector of the previous point should be orthogonal to
403 : // the surface between the 2 volumes.
404 :
405 : TGeoNode *mainNode;
406 122 : if (fInitialNode==0) {
407 0 : TObjArray *nodes = gGeoManager->GetListOfNodes();
408 0 : if (nodes->GetEntriesFast()==0) return 0;
409 0 : mainNode = (TGeoNode *) nodes->UncheckedAt(0);
410 0 : } else {
411 : mainNode = fInitialNode;
412 : };
413 :
414 61 : Int_t p1 = p2 - 1;
415 61 : TGeoVolume *p2Vol = GetVolume(p2);
416 61 : TGeoVolume *p1Vol = GetVolume(p1);
417 :
418 61 : ResetCheckDaughter();
419 61 : fCurrentVol = p1Vol;
420 61 : if (! CheckDaughter(mainNode)) {
421 0 : printf("Error::volume containing point is not visible in node tree!\n");
422 0 : return 0;
423 : };
424 :
425 61 : Double_t coord1[3], coord2[3], vect1[3], vect2[3];
426 : //=================================================
427 : // Get p1 position in the systeme of p2
428 61 : if (p1Vol!=p2Vol) {
429 :
430 0 : Int_t p1nodeInd[fgkCableMaxNodeLevel];
431 0 : for (Int_t i=0; i<fgkCableMaxNodeLevel; i++) p1nodeInd[i]=fNodeInd[i];
432 : Int_t p1volLevel = 0;
433 0 : while (p1nodeInd[p1volLevel]!=-1) p1volLevel++;
434 0 : p1volLevel--;
435 :
436 0 : ResetCheckDaughter();
437 0 : fCurrentVol = p2Vol;
438 0 : if (! CheckDaughter(mainNode)) {
439 0 : printf("Error::volume containing point is not visible in node tree!\n");
440 0 : return 0;
441 : };
442 0 : Int_t p2nodeInd[fgkCableMaxNodeLevel];
443 0 : for (Int_t i=0; i<fgkCableMaxNodeLevel; i++) p2nodeInd[i]=fNodeInd[i];
444 : Int_t commonMotherLevel = 0;
445 0 : while (p1nodeInd[commonMotherLevel]==fNodeInd[commonMotherLevel])
446 0 : commonMotherLevel++;
447 0 : commonMotherLevel--;
448 : Int_t p2volLevel = 0;
449 0 : while (fNodeInd[p2volLevel]!=-1) p2volLevel++;
450 0 : p2volLevel--;
451 :
452 : // Get coord and vect of p1 in the common mother reference system
453 0 : if (! GetCheckPoint(p1, 0, p1volLevel-commonMotherLevel, coord1) )
454 0 : return 0;
455 0 : if (! GetCheckVect( p1, 0, p1volLevel-commonMotherLevel, vect1) )
456 0 : return 0;
457 :
458 : // Translate them in the reference system of the volume containing p2
459 0 : TGeoNode *pathNode[fgkCableMaxNodeLevel];
460 0 : pathNode[0] = mainNode;
461 0 : for (Int_t i=0; i<=p2volLevel; i++) {
462 0 : pathNode[i+1] = pathNode[i]->GetDaughter(p2nodeInd[i]);
463 : };
464 0 : Double_t globalCoord1[3] = {coord1[0], coord1[1], coord1[2]};
465 0 : Double_t globalVect1[3] = {vect1[0], vect1[1], vect1[2]};
466 :
467 0 : for (Int_t i = commonMotherLevel+1; i <= p2volLevel; i++) {
468 0 : pathNode[i+1]->GetMatrix()->MasterToLocal(globalCoord1, coord1);
469 0 : pathNode[i+1]->GetMatrix()->MasterToLocalVect(globalVect1, vect1);
470 0 : CopyFrom(globalCoord1, coord1);
471 0 : CopyFrom(globalVect1, vect1);
472 : };
473 0 : } else {
474 61 : if (! GetCheckPoint(p1, 0, 0, coord1) ) return 0;
475 61 : if (! GetCheckVect(p1, 0, 0, vect1) ) return 0;
476 : };
477 :
478 : //=================================================
479 : // Get p2 position in the systeme of p2
480 61 : if (! GetCheckPoint(p2, 0, 0, coord2) ) return 0;
481 61 : if (! GetCheckVect(p2, 0, 0, vect2) ) return 0;
482 :
483 61 : Double_t cx = (coord1[0]+coord2[0])/2;
484 61 : Double_t cy = (coord1[1]+coord2[1])/2;
485 61 : Double_t cz = (coord1[2]+coord2[2])/2;
486 61 : Double_t dx = coord2[0]-coord1[0];
487 61 : Double_t dy = coord2[1]-coord1[1];
488 61 : Double_t dz = coord2[2]-coord1[2];
489 :
490 : //=================================================
491 : // Positionning of the segment between the 2 points
492 122 : if (TMath::Abs(dy)<1e-231) dy = 1e-231;
493 104 : if (TMath::Abs(dz)<1e-231) dz = 1e-231;
494 : //Double_t angleRot1 = -TMath::ATan(dx/dy);
495 : //Double_t planDiagL = -TMath::Sqrt(dy*dy+dx*dx);
496 : //if (dy<0) planDiagL = -planDiagL;
497 : //Double_t angleRotDiag = TMath::ATan(planDiagL/dz);
498 :
499 61 : Double_t angleRot1 = -TMath::ATan2(dx,dy);
500 61 : Double_t planDiagL = TMath::Sqrt(dy*dy+dx*dx);
501 61 : Double_t angleRotDiag = -TMath::ATan2(planDiagL,dz);
502 : //--- (Calculate rotation of segment on the Z axis)
503 : //-- Here I'm trying to calculate the rotation to be applied in
504 : //-- order to match as closer as possible this segment and the
505 : //-- previous one.
506 : //-- It seems that some times it doesn't work ...
507 122 : TGeoRotation rotTemp("",angleRot1*TMath::RadToDeg(),
508 61 : angleRotDiag*TMath::RadToDeg(), rotation);
509 61 : Double_t localX[3] = {0,1,0};
510 61 : Double_t globalX[3];
511 61 : rotTemp.LocalToMasterVect(localX, globalX);
512 61 : CopyFrom(localX, globalX);
513 61 : GetCheckVect(localX, p2Vol, 0, fgkCableMaxNodeLevel+1, globalX);
514 61 : Double_t orthVect[3];
515 61 : GetCheckVect(vect1, p2Vol, 0, fgkCableMaxNodeLevel+1, orthVect);
516 : // Double_t angleRotZ = 0;
517 : // if (p2>1) {
518 : // Double_t orthVectNorm2 = ScalProd(orthVect,orthVect);
519 : // Double_t alpha1 = ScalProd(fPreviousX,orthVect)/orthVectNorm2;
520 : // Double_t alpha2 = ScalProd(globalX,orthVect)/orthVectNorm2;
521 : // Double_t globalX1p[3], globalX2p[3];
522 : // globalX1p[0] = fPreviousX[0] - alpha1*orthVect[0];
523 : // globalX1p[1] = fPreviousX[1] - alpha1*orthVect[1];
524 : // globalX1p[2] = fPreviousX[2] - alpha1*orthVect[2];
525 : // globalX2p[0] = globalX[0] - alpha2*orthVect[0];
526 : // globalX2p[1] = globalX[1] - alpha2*orthVect[1];
527 : // globalX2p[2] = globalX[2] - alpha2*orthVect[2];
528 : // //-- now I'm searching the 3th vect which makes an orthogonal base
529 : // //-- with orthVect and globalX1p ...
530 : // Double_t nulVect[3] = {0,0,0};
531 : // Double_t axis3[3];
532 : // TMath::Normal2Plane(nulVect, orthVect, globalX1p, axis3);
533 : // Double_t globalX1pNorm2 = ScalProd(globalX1p, globalX1p);
534 : // Double_t beta = ScalProd(globalX2p, globalX1p)/globalX1pNorm2;
535 : // Double_t gamma = ScalProd(globalX2p, axis3);
536 : // angleRotZ = (TMath::ATan2(1,0) - TMath::ATan2(beta, gamma))
537 : // *TMath::RadToDeg();
538 : // };
539 61 : CopyFrom(fPreviousX, globalX);
540 : //---
541 61 : Double_t localVect1[3], localVect2[3];
542 122 : TGeoRotation rot("",angleRot1*TMath::RadToDeg(),
543 61 : angleRotDiag*TMath::RadToDeg(),
544 : rotation);
545 : // rotation-angleRotZ);
546 : // since angleRotZ doesn't always work, I won't use it ...
547 :
548 61 : rot.MasterToLocalVect(vect1, localVect1);
549 61 : rot.MasterToLocalVect(vect2, localVect2);
550 :
551 : //=================================================
552 : // Create the segment and add it to the mother volume
553 61 : TGeoVolume *vCableSegB = CreateBoxSegment(coord1, coord2);
554 :
555 61 : TGeoRotation rotArbSeg("", 0, 90, 0);
556 61 : rotArbSeg.MultiplyBy(&rot, kFALSE);
557 61 : TGeoTranslation trans("",cx, cy, cz);
558 122 : TGeoCombiTrans *combiB = new TGeoCombiTrans(trans, rotArbSeg);
559 61 : p2Vol->AddNode(vCableSegB, p2, combiB);
560 : //=================================================;
561 :
562 61 : if (fDebug) {
563 0 : printf("---\n Cable segment points : ");
564 0 : printf("%f, %f, %f\n",coord1[0], coord1[1], coord1[2]);
565 0 : printf("%f, %f, %f\n",coord2[0], coord2[1], coord2[2]);
566 : };
567 :
568 65 : if (ct) *ct = combiB;
569 : return vCableSegB;
570 183 : }
571 :
572 : //________________________________________________________________________
573 : TGeoVolume* AliITSv11GeomCableFlat::CreateAndInsertCableCylSegment(Int_t p2,
574 : Double_t rotation,
575 : TGeoCombiTrans** ct)
576 : {
577 : // Create a flat cable segment with a curvature between points p1 and p2.
578 : // The radius and position of the curve is defined by the
579 : // perpendicular vector of point p2 (the orientation of this vector
580 : // and the position of the 2 check points are enough to completely
581 : // define the curve)
582 : // Rotation is the eventual rotation of the flat cable
583 : // along its length axis
584 : //
585 :
586 : TGeoNode *mainNode;
587 28 : if (fInitialNode==0) {
588 0 : TObjArray *nodes = gGeoManager->GetListOfNodes();
589 0 : if (nodes->GetEntriesFast()==0) return 0;
590 0 : mainNode = (TGeoNode *) nodes->UncheckedAt(0);
591 0 : } else {
592 : mainNode = fInitialNode;
593 : };
594 :
595 14 : Int_t p1 = p2 - 1;
596 14 : TGeoVolume *p1Vol = GetVolume(p1);
597 14 : TGeoVolume *p2Vol = GetVolume(p2);
598 :
599 14 : ResetCheckDaughter();
600 14 : fCurrentVol = p1Vol;
601 14 : if (! CheckDaughter(mainNode)) {
602 0 : printf("Error::volume containing point is not visible in node tree!\n");
603 0 : return 0;
604 : };
605 :
606 14 : Double_t coord1[3], coord2[3], vect1[3], vect2[3];
607 : //=================================================
608 : // Get p1 position in the systeme of p2
609 14 : if (p1Vol!=p2Vol) {
610 :
611 0 : Int_t p1nodeInd[fgkCableMaxNodeLevel];
612 0 : for (Int_t i=0; i<fgkCableMaxNodeLevel; i++) p1nodeInd[i]=fNodeInd[i];
613 : Int_t p1volLevel = 0;
614 0 : while (p1nodeInd[p1volLevel]!=-1) p1volLevel++;
615 0 : p1volLevel--;
616 :
617 0 : ResetCheckDaughter();
618 0 : fCurrentVol = p2Vol;
619 0 : if (! CheckDaughter(mainNode)) {
620 0 : printf("Error::volume containing point is not visible in node tree!\n");
621 0 : return 0;
622 : };
623 0 : Int_t p2nodeInd[fgkCableMaxNodeLevel];
624 0 : for (Int_t i=0; i<fgkCableMaxNodeLevel; i++) p2nodeInd[i]=fNodeInd[i];
625 : Int_t commonMotherLevel = 0;
626 0 : while (p1nodeInd[commonMotherLevel]==fNodeInd[commonMotherLevel])
627 0 : commonMotherLevel++;
628 0 : commonMotherLevel--;
629 : Int_t p2volLevel = 0;
630 0 : while (fNodeInd[p2volLevel]!=-1) p2volLevel++;
631 0 : p2volLevel--;
632 :
633 : // Get coord and vect of p1 in the common mother reference system
634 0 : GetCheckPoint(p1, 0, p1volLevel-commonMotherLevel, coord1);
635 0 : GetCheckVect( p1, 0, p1volLevel-commonMotherLevel, vect1);
636 : // Translate them in the reference system of the volume containing p2
637 0 : TGeoNode *pathNode[fgkCableMaxNodeLevel];
638 0 : pathNode[0] = mainNode;
639 0 : for (Int_t i=0; i<=p2volLevel; i++) {
640 0 : pathNode[i+1] = pathNode[i]->GetDaughter(p2nodeInd[i]);
641 : };
642 0 : Double_t globalCoord1[3] = {coord1[0], coord1[1], coord1[2]};
643 0 : Double_t globalVect1[3] = {vect1[0], vect1[1], vect1[2]};
644 :
645 0 : for (Int_t i = commonMotherLevel+1; i<=p2volLevel; i++) {
646 0 : pathNode[i+1]->GetMatrix()->MasterToLocal(globalCoord1, coord1);
647 0 : pathNode[i+1]->GetMatrix()->MasterToLocalVect(globalVect1, vect1);
648 0 : CopyFrom(globalCoord1, coord1);
649 0 : CopyFrom(globalVect1, vect1);
650 : };
651 0 : } else {
652 14 : GetCheckPoint(p1, 0, 0, coord1);
653 14 : GetCheckVect(p1, 0, 0, vect1);
654 : };
655 :
656 : //=================================================
657 : // Get p2 position in the systeme of p2
658 14 : GetCheckPoint(p2, 0, 0, coord2);
659 14 : GetCheckVect(p2, 0, 0, vect2);
660 :
661 14 : Double_t cx = (coord1[0]+coord2[0])/2;
662 14 : Double_t cy = (coord1[1]+coord2[1])/2;
663 14 : Double_t cz = (coord1[2]+coord2[2])/2;
664 14 : Double_t dx = coord2[0]-coord1[0];
665 14 : Double_t dy = coord2[1]-coord1[1];
666 14 : Double_t dz = coord2[2]-coord1[2];
667 14 : Double_t length = TMath::Sqrt(dx*dx+dy*dy+dz*dz);
668 :
669 : //=================================================
670 : // Positionning of the segment between the 2 points
671 14 : if ((dy<1e-31)&&(dy>0)) dy = 1e-31;
672 14 : if ((dz<1e-31)&&(dz>0)) dz = 1e-31;
673 14 : if ((dy>-1e-31)&&(dy<0)) dy = -1e-31;
674 14 : if ((dz>-1e-31)&&(dz<0)) dz = -1e-31;
675 :
676 14 : Double_t angleRot1 = -TMath::ATan2(dx,dy);
677 14 : Double_t planDiagL = TMath::Sqrt(dy*dy+dx*dx);
678 14 : Double_t angleRotDiag = -TMath::ATan2(planDiagL,dz);
679 :
680 28 : TGeoRotation rotTorusTemp("",angleRot1*TMath::RadToDeg(),
681 14 : angleRotDiag*TMath::RadToDeg(),0);
682 14 : TGeoRotation rotTorusToZ("",0,90,0);
683 14 : rotTorusTemp.MultiplyBy(&rotTorusToZ, kTRUE);
684 14 : Double_t localVect2[3];
685 14 : rotTorusTemp.MasterToLocalVect(vect2, localVect2);
686 14 : if (localVect2[1]<0) {
687 7 : localVect2[0] = -localVect2[0];
688 7 : localVect2[1] = -localVect2[1];
689 7 : localVect2[2] = -localVect2[2];
690 7 : };
691 42 : Double_t normVect2 = TMath::Sqrt(localVect2[0]*localVect2[0]+
692 28 : localVect2[1]*localVect2[1]+
693 14 : localVect2[2]*localVect2[2]);
694 : Double_t axisX[3] = {1,0,0};
695 28 : Double_t cosangleTorusSeg = (localVect2[0]*axisX[0]+
696 28 : localVect2[1]*axisX[1]+
697 28 : localVect2[2]*axisX[2])/normVect2;
698 14 : Double_t angleTorusSeg = TMath::ACos(cosangleTorusSeg)*TMath::RadToDeg();
699 28 : TGeoRotation rotTorus("",angleRot1*TMath::RadToDeg(),
700 14 : angleRotDiag*TMath::RadToDeg(),
701 14 : 45-angleTorusSeg+rotation);
702 : //180-angleTorusSeg+rotation);
703 14 : rotTorus.MultiplyBy(&rotTorusToZ, kTRUE);
704 14 : rotTorus.MasterToLocalVect(vect2, localVect2);
705 14 : if (localVect2[1]<0) {
706 7 : localVect2[0] = -localVect2[0];
707 7 : localVect2[1] = -localVect2[1];
708 7 : localVect2[2] = -localVect2[2];
709 7 : };
710 42 : normVect2 = TMath::Sqrt(localVect2[0]*localVect2[0]+
711 28 : localVect2[1]*localVect2[1]+
712 14 : localVect2[2]*localVect2[2]);
713 : Double_t axisY[3] = {0,1,0};
714 28 : Double_t cosPhi = (localVect2[0]*axisY[0]+localVect2[1]*axisY[1]+
715 28 : localVect2[2]*axisY[2])/normVect2;
716 14 : Double_t torusPhi1 = TMath::ACos(cosPhi);
717 14 : Double_t torusR = (length/2)/TMath::Sin(torusPhi1);
718 14 : torusPhi1 = torusPhi1*TMath::RadToDeg();
719 14 : Double_t perpLength = TMath::Sqrt((torusR-0.5*length)*(torusR+0.5*length));
720 14 : Double_t localTransT[3] = {-perpLength,0,0};
721 14 : Double_t globalTransT[3];
722 14 : rotTorus.LocalToMasterVect(localTransT, globalTransT);
723 28 : TGeoTranslation transTorus("",cx+globalTransT[0],cy+globalTransT[1],
724 14 : cz+globalTransT[2]);
725 :
726 28 : TGeoCombiTrans *combiTorus = new TGeoCombiTrans(transTorus, rotTorus);
727 :
728 : //=================================================
729 : // Create the segment and add it to the mother volume
730 14 : TGeoVolume *vCableSegT = CreateCylSegment(torusPhi1, torusR);
731 14 : p2Vol->AddNode(vCableSegT, p2, combiTorus);
732 :
733 14 : if (fDebug) {
734 0 : printf("---\n Cable segment points : ");
735 0 : printf("%f, %f, %f\n",coord1[0], coord1[1], coord1[2]);
736 0 : printf("%f, %f, %f\n",coord2[0], coord2[1], coord2[2]);
737 : };
738 :
739 14 : if (ct) *ct = combiTorus;
740 : return vCableSegT;
741 42 : }
742 :
743 : //________________________________________________________________________
744 : TGeoVolume *AliITSv11GeomCableFlat::CreateSegment( const Double_t *coord1,
745 : const Double_t *coord2,
746 : const Double_t *localVect1,
747 : const Double_t *localVect2 )
748 : {
749 : // Create a segment with arbitrary vertices (general case)
750 : //=================================================
751 : // Calculate segment "deformation"
752 158 : Double_t dx = coord2[0]-coord1[0];
753 79 : Double_t dy = coord2[1]-coord1[1];
754 79 : Double_t dz = coord2[2]-coord1[2];
755 79 : Double_t length = TMath::Sqrt(dx*dx+dy*dy+dz*dz);
756 :
757 158 : Double_t cosTheta1 = -1./TMath::Sqrt( 1 + localVect1[0]*localVect1[0]
758 79 : /localVect1[2]/localVect1[2] );
759 158 : Double_t cosTheta2 = 1./TMath::Sqrt( 1 + localVect2[0]*localVect2[0]
760 79 : /localVect2[2]/localVect2[2] );
761 111 : if (localVect1[2]<0) cosTheta1 = -cosTheta1;
762 111 : if (localVect2[2]<0) cosTheta2 = -cosTheta2;
763 :
764 79 : Double_t dL1 = 0.5*fWidth*TMath::Tan(TMath::ACos(cosTheta1));
765 79 : Double_t dL2 = 0.5*fWidth*TMath::Tan(TMath::ACos(cosTheta2));
766 94 : if (localVect1[0]<0) dL1 = - dL1;
767 94 : if (localVect2[0]<0) dL2 = - dL2;
768 : //---
769 158 : Double_t cosPhi1 = -1./TMath::Sqrt( 1 + localVect1[1]*localVect1[1]
770 79 : /localVect1[2]/localVect1[2] );
771 158 : Double_t cosPhi2 = 1./TMath::Sqrt( 1 + localVect2[1]*localVect2[1]
772 79 : /localVect2[2]/localVect2[2] );
773 111 : if (localVect1[2]<0) cosPhi1 = -cosPhi1;
774 111 : if (localVect2[2]<0) cosPhi2 = -cosPhi2;
775 :
776 79 : Double_t tanACosCosPhi1 = TMath::Tan(TMath::ACos(cosPhi1));
777 79 : Double_t tanACosCosPhi2 = TMath::Tan(TMath::ACos(cosPhi2));
778 150 : if (localVect1[1]<0) tanACosCosPhi1 = -tanACosCosPhi1;
779 150 : if (localVect2[1]<0) tanACosCosPhi2 = -tanACosCosPhi2;
780 :
781 79 : Double_t dl1 = 0.5*fThick*tanACosCosPhi1*0.99999999999999;
782 79 : Double_t dl2 = 0.5*fThick*tanACosCosPhi2*0.99999999999999;
783 : // 0.9999999999999 is for correcting problems in TGeo...
784 : //=================================================
785 : // Create the segment
786 79 : TGeoArb8 *cableSeg = new TGeoArb8(fThick/2);
787 79 : cableSeg->SetVertex( 0, -fWidth/2, -length/2 - dL1 + dl1);
788 79 : cableSeg->SetVertex( 1, -fWidth/2, length/2 + dL2 - dl2);
789 79 : cableSeg->SetVertex( 2, fWidth/2, length/2 - dL2 - dl2);
790 79 : cableSeg->SetVertex( 3, fWidth/2, -length/2 + dL1 + dl1);
791 79 : cableSeg->SetVertex( 4, -fWidth/2, -length/2 - dL1 - dl1);
792 79 : cableSeg->SetVertex( 5, -fWidth/2, length/2 + dL2 + dl2);
793 79 : cableSeg->SetVertex( 6, fWidth/2, length/2 - dL2 + dl2);
794 79 : cableSeg->SetVertex( 7, fWidth/2, -length/2 + dL1 - dl1);
795 :
796 158 : TGeoVolume *vCableSeg = new TGeoVolume(GetName(), cableSeg, fLayMedia[fNlayer-1]);
797 79 : vCableSeg->SetLineColor(fLayColor[fNlayer-1]);
798 :
799 : // add all cable layers but the last
800 354 : for (Int_t iLay=0; iLay<fNlayer-1; iLay++) {
801 :
802 98 : Double_t dl1Lay = 0.5*fLayThickness[iLay]*tanACosCosPhi1;
803 98 : Double_t dl2Lay = 0.5*fLayThickness[iLay]*tanACosCosPhi2;
804 :
805 98 : Double_t ztr = -fThick/2;
806 246 : for (Int_t i=0;i<iLay; i++) ztr+= fLayThickness[i];
807 98 : ztr+= fLayThickness[iLay]/2;
808 :
809 98 : Double_t dl1LayS = ztr*tanACosCosPhi1;
810 98 : Double_t dl2LayS = ztr*tanACosCosPhi2;
811 :
812 98 : TGeoArb8 *lay = new TGeoArb8(fLayThickness[iLay]/2);
813 98 : lay->SetVertex( 0, -fWidth/2, -length/2 - dL1 + dl1Lay - dl1LayS);
814 98 : lay->SetVertex( 1, -fWidth/2, length/2 + dL2 - dl2Lay + dl2LayS);
815 98 : lay->SetVertex( 2, fWidth/2, length/2 - dL2 - dl2Lay + dl2LayS);
816 98 : lay->SetVertex( 3, fWidth/2, -length/2 + dL1 + dl1Lay - dl1LayS);
817 98 : lay->SetVertex( 4, -fWidth/2, -length/2 - dL1 - dl1Lay - dl1LayS);
818 98 : lay->SetVertex( 5, -fWidth/2, length/2 + dL2 + dl2Lay + dl2LayS);
819 98 : lay->SetVertex( 6, fWidth/2, length/2 - dL2 + dl2Lay + dl2LayS);
820 98 : lay->SetVertex( 7, fWidth/2, -length/2 + dL1 - dl1Lay - dl1LayS);
821 98 : TGeoVolume *vLay = new TGeoVolume("vCableSegLay", lay, fLayMedia[iLay]);
822 98 : vLay->SetLineColor(fLayColor[iLay]);
823 :
824 98 : if (fTranslation[iLay]==0)
825 124 : fTranslation[iLay] = new TGeoTranslation(0, 0, ztr);
826 98 : vCableSeg->AddNode(vLay, iLay+1, fTranslation[iLay]);
827 : };
828 :
829 : //vCableSeg->SetVisibility(kFALSE);
830 79 : return vCableSeg;
831 0 : }
832 :
833 : //________________________________________________________________________
834 : TGeoVolume *AliITSv11GeomCableFlat::CreateCylSegment(const Double_t &phi,
835 : const Double_t &r)
836 : {
837 : // Create a segment in shape of a cylinder, allows to represent
838 : // a folded flat cable
839 :
840 28 : Double_t phi1 = 360-phi;
841 14 : Double_t phi2 = 360+phi;
842 :
843 14 : Double_t rMin = r-fThick/2;
844 14 : Double_t rMax = r+fThick/2;
845 : //=================================================
846 : // Create the segment
847 :
848 14 : TGeoTubeSeg *cableSeg = new TGeoTubeSeg(rMin, rMax, fWidth/2,
849 : phi1, phi2);
850 28 : TGeoVolume *vCableSeg = new TGeoVolume(GetName(), cableSeg, fLayMedia[fNlayer-1]);
851 14 : vCableSeg->SetLineColor(fLayColor[fNlayer-1]);
852 :
853 : // add all cable layers but the last
854 56 : for (Int_t iLay=0; iLay<fNlayer-1; iLay++) {
855 :
856 14 : Double_t ztr = -fThick/2;
857 28 : for (Int_t i=0;i<iLay; i++) ztr+= fLayThickness[i];
858 :
859 14 : rMin = r + ztr;
860 14 : rMax = r + ztr + fLayThickness[iLay];
861 14 : TGeoTubeSeg *lay = new TGeoTubeSeg(rMin, rMax, fWidth/2,
862 : phi1, phi2);
863 :
864 14 : TGeoVolume *vLay = new TGeoVolume("vCableSegLay", lay, fLayMedia[iLay]);
865 14 : vLay->SetLineColor(fLayColor[iLay]);
866 :
867 14 : vCableSeg->AddNode(vLay, iLay+1, 0);
868 : };
869 :
870 : //vCableSeg->SetVisibility(kFALSE);
871 14 : return vCableSeg;
872 0 : }
873 :
874 : //________________________________________________________________________
875 : TGeoVolume *AliITSv11GeomCableFlat::CreateBoxSegment( const Double_t *coord1,
876 : const Double_t *coord2)
877 : {
878 : // Create a segment for the case it is a simple box
879 : //=================================================
880 122 : Double_t dx = coord2[0]-coord1[0];
881 61 : Double_t dy = coord2[1]-coord1[1];
882 61 : Double_t dz = coord2[2]-coord1[2];
883 61 : Double_t length = TMath::Sqrt(dx*dx+dy*dy+dz*dz);
884 :
885 61 : TGeoBBox *cableSeg = new TGeoBBox(fWidth/2, length/2, fThick/2);
886 122 : TGeoVolume *vCableSeg = new TGeoVolume(GetName(), cableSeg, fLayMedia[fNlayer-1]);
887 61 : vCableSeg->SetLineColor(fLayColor[fNlayer-1]);
888 : // This volume is the cable container. It codes also the material for the
889 : // last layer
890 :
891 : // add all cable layers but the last one
892 292 : for (Int_t iLay=0; iLay<fNlayer-1; iLay++) {
893 :
894 85 : Double_t ztr = -fThick/2;
895 266 : for (Int_t i=0;i<iLay; i++) ztr+= fLayThickness[i];
896 85 : ztr+= fLayThickness[iLay]/2;
897 :
898 85 : TGeoBBox *lay = new TGeoBBox(fWidth/2, length/2, fLayThickness[iLay]/2);
899 :
900 85 : TGeoVolume *vLay = new TGeoVolume("vCableSegLay", lay, fLayMedia[iLay]);
901 85 : vLay->SetLineColor(fLayColor[iLay]);
902 :
903 85 : if (fTranslation[iLay]==0)
904 86 : fTranslation[iLay] = new TGeoTranslation(0, 0, ztr);
905 85 : vCableSeg->AddNode(vLay, iLay+1, fTranslation[iLay]);
906 : };
907 :
908 : //vCableSeg->SetVisibility(kFALSE);
909 61 : return vCableSeg;
910 0 : }
911 :
912 : //________________________________________________________________________
913 : void AliITSv11GeomCableFlat::SetNLayers(Int_t nLayers) {
914 : // Set the number of layers
915 166 : if((nLayers>0) &&(nLayers<=fgkCableMaxLayer)) {
916 :
917 83 : fNlayer = nLayers;
918 2656 : for (Int_t i=0; i<fgkCableMaxLayer ; i++) {
919 1245 : fLayThickness[i] = 0;
920 1245 : fTranslation[i] = 0;
921 1245 : fLayColor[i] = 0;
922 1245 : fLayMedia[i] = 0;
923 : };
924 83 : };
925 83 : }
926 :
927 : //________________________________________________________________________
928 : Int_t AliITSv11GeomCableFlat::SetLayer(Int_t nLayer, Double_t thick,
929 : TGeoMedium *medium, Int_t color) {
930 : // Set the layer number nLayer
931 573 : if ((nLayer<0)||(nLayer>=fNlayer)) {
932 0 : printf("Set wrong layer number of the cable\n");
933 0 : return kFALSE;
934 : };
935 191 : if (nLayer>0)
936 108 : if (fLayThickness[nLayer-1]<=0) {
937 0 : printf("AliITSv11GeomCableFlat::SetLayer():"
938 : " You must define cable layer %i first !",nLayer-1);
939 0 : return kFALSE;
940 : };
941 :
942 : Double_t thickTot = 0;
943 660 : for (Int_t i=0; i<nLayer; i++) thickTot += fLayThickness[i];
944 191 : thickTot += thick;
945 191 : if (thickTot-1e-10>fThick) {
946 0 : printf("Can't add this layer, cable thickness would be higher than total\n");
947 0 : return kFALSE;
948 : };
949 :
950 191 : fLayThickness[nLayer] = thick;
951 191 : fLayMedia[nLayer] = medium;
952 191 : fLayColor[nLayer] = color;
953 191 : fTranslation[nLayer] = 0;
954 191 : return kTRUE;
955 191 : }
|