LCOV - code coverage report
Current view: top level - ITS/ITSsim - AliITSv11GeomCableFlat.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 355 467 76.0 %
Date: 2016-06-14 17:26:59 Functions: 16 17 94.1 %

          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 : }

Generated by: LCOV version 1.11