LCOV - code coverage report
Current view: top level - FMD/FMDbase - AliFMDRing.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 115 180 63.9 %
Date: 2016-06-14 17:26:59 Functions: 9 15 60.0 %

          Line data    Source code
       1             : /**************************************************************************
       2             :  * Copyright(c) 2004, 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             : /* $Id$ */
      16             : /** @file    AliFMDRing.cxx
      17             :     @author  Christian Holm Christensen <cholm@nbi.dk>
      18             :     @date    Mon Mar 27 12:47:43 2006
      19             :     @brief   FMD ring geometry parameters 
      20             : */
      21             : //__________________________________________________________________
      22             : //
      23             : // Utility class to help implement collection of FMD modules into
      24             : // rings.  This is used by AliFMDDetector and AliFMDGeometry.
      25             : // The AliFMDGeometry object owns the AliFMDRing objects, and the
      26             : // AliFMDDetector objects reference these.  That is, the AliFMDRing
      27             : // objects are share amoung the AliFMDDetector objects.
      28             : //
      29             : // Latest changes by Christian Holm Christensen
      30             : //
      31             : 
      32             : #include <TMath.h>                // ROOT_TMath
      33             : #include <TVector2.h>             // ROOT_TVector2
      34             : 
      35             : // #include <AliLog.h>            // ALILOG_H
      36             : #include "AliFMDRing.h"               // ALIFMDRING_H
      37             : 
      38             : //====================================================================
      39          12 : ClassImp(AliFMDRing)
      40             : #if 0
      41             :   ; // This is here to keep Emacs for indenting the next line
      42             : #endif
      43             : 
      44             : //____________________________________________________________________
      45             : AliFMDRing::AliFMDRing(Char_t id) 
      46           6 :   : TNamed(Form("FMD%c", id), "Forward multiplicity ring"), 
      47           6 :     fId(id), 
      48           6 :     fBondingWidth(0),
      49           6 :     fWaferRadius(0),
      50           6 :     fSiThickness(0),
      51           6 :     fLowR(0),
      52           6 :     fHighR(0),
      53           6 :     fMinR(0),
      54           6 :     fMaxR(0),
      55           6 :     fTheta(0),
      56           6 :     fNStrips(0),
      57           6 :     fRingDepth(0),
      58           6 :     fLegRadius(0),
      59           6 :     fLegLength(0),
      60           6 :     fLegOffset(0),
      61           6 :     fModuleSpacing(0),
      62           6 :     fPrintboardThickness(0),
      63           6 :     fCopperThickness(0),
      64           6 :     fChipThickness(0),
      65           6 :     fSpacing(0),
      66           6 :     fHoneycombThickness(0.),
      67           6 :     fAlThickness(0.),
      68           6 :     fVerticies(0), 
      69           6 :     fSensorVerticies(0),
      70           6 :     fHybridVerticies(0),
      71           6 :     fFeetPositions(0)
      72          30 : {
      73             :   // Constructor 
      74             :   // 
      75             :   // Parameters: 
      76             :   //    id      Type of ring (either 'I' or 'O') 
      77             :   // 
      78           6 :   SetBondingWidth();
      79           6 :   SetWaferRadius();
      80           6 :   SetSiThickness();
      81           6 :   SetLegRadius();
      82           6 :   SetLegLength();
      83           6 :   SetLegOffset();
      84           6 :   SetModuleSpacing();
      85           6 :   SetPrintboardThickness();
      86           6 :   SetCopperThickness();
      87           6 :   SetChipThickness();
      88           6 :   SetSpacing();
      89           6 :   SetHoneycombThickness();
      90           6 :   SetAlThickness();
      91             :   
      92           9 :   if (fId == 'I' || fId == 'i') {
      93           3 :     SetLowR(4.3);
      94           3 :     SetHighR(17.2);
      95           3 :     SetTheta(36/2);
      96           3 :     SetNStrips(512);
      97             :     Double_t base = 0; // 4.1915;
      98           9 :     fFeetPositions.Add(new TVector2( 0.0551687, 8.0534-base));
      99           9 :     fFeetPositions.Add(new TVector2( 2.9993,   12.9457-base));
     100           9 :     fFeetPositions.Add(new TVector2(-2.9062,   12.9508-base));
     101             :     
     102           9 :     fHybridVerticies.Add(new TVector2(0.0000,  4.1700));
     103           9 :     fHybridVerticies.Add(new TVector2(1.0574,  4.1700));
     104           9 :     fHybridVerticies.Add(new TVector2(4.6614, 15.2622));
     105           9 :     fHybridVerticies.Add(new TVector2(0.9643, 17.4000));
     106           9 :     fHybridVerticies.Add(new TVector2(0.0000, 17.4000));
     107             : 
     108           9 :     fSensorVerticies.Add(new TVector2(0.0000,  4.1915));
     109           9 :     fSensorVerticies.Add(new TVector2(1.5793,  4.1915));
     110           9 :     fSensorVerticies.Add(new TVector2(5.2293, 15.4251));
     111           9 :     fSensorVerticies.Add(new TVector2(1.9807, 17.3035));
     112           9 :     fSensorVerticies.Add(new TVector2(0.0000, 17.3035));
     113             : 
     114           9 :     fVerticies.Add(new TVector2(0.0000,  4.3000));
     115           9 :     fVerticies.Add(new TVector2(1.3972,  4.3000));
     116           9 :     fVerticies.Add(new TVector2(4.9895, 15.3560));
     117           9 :     fVerticies.Add(new TVector2(1.8007, 17.2000));
     118           9 :     fVerticies.Add(new TVector2(0.0000, 17.2000));
     119           3 :   }
     120           3 :   else if (fId == 'O' || fId == 'o') {
     121           3 :     SetLowR(15.6);
     122           3 :     SetHighR(28.0);
     123           3 :     SetTheta(18/2);
     124           3 :     SetNStrips(256);
     125             :     Double_t base = 0; // 14.9104;
     126           9 :     fFeetPositions.Add(new TVector2(-1.72540000, 20.6267-base));
     127           9 :     fFeetPositions.Add(new TVector2( 1.72900000, 20.6267-base));
     128           9 :     fFeetPositions.Add(new TVector2( 0.00177616, 26.6007-base));
     129             : 
     130           9 :     fHybridVerticies.Add(new TVector2(0.0000, 14.9104));
     131           9 :     fHybridVerticies.Add(new TVector2(2.0783, 14.9104));
     132           9 :     fHybridVerticies.Add(new TVector2(3.9202, 26.5395));
     133           9 :     fHybridVerticies.Add(new TVector2(0.6784, 28.2500));
     134           9 :     fHybridVerticies.Add(new TVector2(0.0000, 28.2500));
     135             : 
     136           9 :     fSensorVerticies.Add(new TVector2(0.0000, 15.0104));
     137           9 :     fSensorVerticies.Add(new TVector2(2.5799, 15.0104));
     138           9 :     fSensorVerticies.Add(new TVector2(4.4439, 26.7766));
     139           9 :     fSensorVerticies.Add(new TVector2(1.8350, 28.1500));
     140           9 :     fSensorVerticies.Add(new TVector2(0.0000, 28.1500));
     141             : 
     142           9 :     fVerticies.Add(new TVector2(0.0000, 15.2104));
     143           9 :     fVerticies.Add(new TVector2(2.4091, 15.2104));
     144           9 :     fVerticies.Add(new TVector2(4.2231, 26.6638));
     145           9 :     fVerticies.Add(new TVector2(1.8357, 27.9500));
     146           9 :     fVerticies.Add(new TVector2(0.0000, 27.9500));
     147           3 :   }
     148          12 : }
     149             : 
     150             : //____________________________________________________________________
     151             : void
     152             : AliFMDRing::Init()
     153             : {
     154             :   // Initialize 
     155             :   // 
     156             :   // All derived quantities are calculated here. 
     157             :   // 
     158             : #if 0
     159             :   Double_t tanTheta  = TMath::Tan(fTheta * TMath::Pi() / 180.);
     160             :   Double_t tanTheta2 = TMath::Power(tanTheta,2);
     161             :   Double_t r2        = TMath::Power(fWaferRadius,2);
     162             :   Double_t yA        = tanTheta * fLowR;
     163             :   Double_t lr2       = TMath::Power(fLowR, 2);
     164             :   Double_t hr2       = TMath::Power(fHighR,2);
     165             :   Double_t xD        = fLowR + TMath::Sqrt(r2 - tanTheta2 * lr2);
     166             :   Double_t xD2       = TMath::Power(xD,2);
     167             :   Double_t yB        = TMath::Sqrt(r2 - hr2 + 2 * fHighR * xD - xD2);
     168             :   Double_t xC        = ((xD + TMath::Sqrt(-tanTheta2 * xD2 + r2
     169             :                                           + r2 * tanTheta2)) 
     170             :                         / (1 + tanTheta2));
     171             :   Double_t yC        = tanTheta * xC;
     172             :   
     173             :   fVerticies.Expand(6);
     174             :   fVerticies.AddAt(new TVector2(fLowR,  -yA), 0);
     175             :   fVerticies.AddAt(new TVector2(xC,     -yC), 1);
     176             :   fVerticies.AddAt(new TVector2(fHighR, -yB), 2);
     177             :   fVerticies.AddAt(new TVector2(fHighR,  yB), 3);
     178             :   fVerticies.AddAt(new TVector2(xC,      yC), 4);
     179             :   fVerticies.AddAt(new TVector2(fLowR,   yA), 5);  
     180             : #endif
     181             : 
     182             :   // A's length. Corresponds to distance from nominal beam line to the
     183             :   // cornor of the active silicon element. 
     184          44 :   fMinR = GetVertex(1)->Mod(); // GetVertex(5)->Mod();
     185             :   // A's length. Corresponds to distance from nominal beam line to the
     186             :   // cornor of the active silicon element. 
     187          22 :   fMaxR = fHighR;
     188             : 
     189          44 :   fRingDepth = (fSiThickness + fPrintboardThickness 
     190          22 :                 + fCopperThickness + fChipThickness 
     191          22 :                 + fLegLength + fModuleSpacing + fSpacing);
     192          22 : }
     193             : 
     194             : //____________________________________________________________________
     195             : TVector2*
     196             : AliFMDRing::GetVertex(Int_t i) const
     197             : {
     198             :   // Get the i'th vertex of polygon shape
     199             :   // 
     200             :   // the polygon shape describes the shape of the rings' sensors
     201             :   // 
     202             :   // Parameters: 
     203             :   //     i    The vertex number to get (from 0 to 5)
     204          44 :   return static_cast<TVector2*>(fVerticies.At(i));
     205             : }
     206             : 
     207             : //____________________________________________________________________
     208             : TVector2*
     209             : AliFMDRing::GetSensorVertex(Int_t i) const
     210             : {
     211             :   // Get the i'th vertex of polygon shape
     212             :   // 
     213             :   // the polygon shape describes the shape of the rings' sensors
     214             :   // 
     215             :   // Parameters: 
     216             :   //     i    The vertex number to get (from 0 to 5)
     217           0 :   return static_cast<TVector2*>(fSensorVerticies.At(i));
     218             : }
     219             : 
     220             : //____________________________________________________________________
     221             : TVector2*
     222             : AliFMDRing::GetHybridVertex(Int_t i) const
     223             : {
     224             :   // Get the i'th vertex of polygon shape
     225             :   // 
     226             :   // the polygon shape describes the shape of the rings' hybrid cards
     227             :   // 
     228             :   // Parameters: 
     229             :   //     i    The vertex number to get (from 0 to 5)
     230           0 :   return static_cast<TVector2*>(fHybridVerticies.At(i));
     231             : }
     232             : 
     233             : //____________________________________________________________________
     234             : TVector2*
     235             : AliFMDRing::GetFootPosition(Int_t i) const
     236             : {
     237             :   // Get the i'th vertex of polygon shape
     238             :   // 
     239             :   // The feet are attached to the hybrid cards
     240             :   // 
     241             :   // Parameters: 
     242             :   //     i    The foot number to get (from 0 to 2)
     243          12 :   return static_cast<TVector2*>(fFeetPositions.At(i));
     244             : }
     245             : 
     246             : //____________________________________________________________________
     247             : Double_t
     248             : AliFMDRing::GetStripRadius(UShort_t strip) const
     249             : {
     250             :   // Return the nominal strip radius 
     251             :   // 
     252             :   // Parameter 
     253             :   //   strip    Strip number (0-511 for inners, 0-255 for outers)
     254      884736 :   Double_t rmax     = GetMaxR();
     255      442368 :   Double_t stripoff = GetMinR();
     256      442368 :   Double_t dstrip   = (rmax - stripoff) / GetNStrips();
     257      442368 :   return (strip + .5) * dstrip + stripoff; // fLowR
     258             : }
     259             :  
     260             : //____________________________________________________________________
     261             : Double_t
     262             : AliFMDRing::GetModuleDepth() const
     263             : {
     264             :   // Get the total depth of a module (sensor + hybrid card) 
     265             :   // 
     266             :   // The depth is the sum of 
     267             :   // 
     268             :   //   The silicon thickness 
     269             :   //   The thickness of spacers between the silicon and hybrid
     270             :   //   The thickness of the hybrid PCB
     271             :   //   The thickness of the copper layer in the PCB
     272             :   //   The thickness of the chip layer in the PCB
     273             :   //   The height of the legs
     274          36 :   return (GetSiThickness() 
     275          12 :           + GetSpacing() 
     276          12 :           + GetPrintboardThickness()
     277          12 :           + GetCopperThickness()
     278          12 :           + GetChipThickness()
     279          12 :           + GetLegLength());
     280             :   
     281             : }
     282             : 
     283             : //____________________________________________________________________
     284             : Double_t
     285             : AliFMDRing::GetFullDepth() const
     286             : {
     287             :   // Get the full depth of this ring, including the honeycomb, 
     288             :   // digitizer and card. 
     289           6 :   return (GetModuleDepth() 
     290           2 :           + GetModuleSpacing()
     291           2 :           + GetHoneycombThickness()
     292           2 :           + GetFMDDPrintboardThickness()
     293           2 :           + GetFMDDCopperThickness()
     294           2 :           + GetFMDDChipThickness() 
     295           2 :           + 0.5);
     296             : }
     297             : 
     298             : //____________________________________________________________________
     299             : void
     300             : AliFMDRing::Detector2XYZ(UShort_t sector,
     301             :                          UShort_t strip, 
     302             :                          Double_t& x, 
     303             :                          Double_t& y, 
     304             :                          Double_t& z) const
     305             : {
     306             :   // Translate detector coordinates (this,sector,strip) to global
     307             :   // coordinates (x,y,z)
     308             :   // 
     309             :   // Parameters 
     310             :   //    sector        Sector number in this ring 
     311             :   //    strip         Strip number in this ring 
     312             :   //    x             On return, the global X coordinate
     313             :   //    y             On return, the global Y coordinate 
     314             :   //    z             On return, the z coordinate in the ring plane 
     315             :   //
     316             :   // The ring plane is the plane half way between the two sensor
     317             :   // layers. 
     318           0 :   if (sector >= GetNSectors()) {
     319           0 :     Error("Detector2XYZ", "Invalid sector number %d (>=%d) in ring %c", 
     320           0 :           sector, GetNSectors(), fId);
     321           0 :     return;
     322             :   }
     323           0 :   if (strip >= GetNStrips()) {
     324           0 :     Error("Detector2XYZ", "Invalid strip number %d (>=%d) for ring type '%c'", 
     325           0 :           strip, GetNStrips(), fId);
     326           0 :     return;
     327             :   }
     328           0 :   Double_t phi = Float_t(sector + .5) / GetNSectors() * 2 * TMath::Pi();
     329           0 :   Double_t r   = Float_t(strip + .5) / GetNStrips() * (fHighR - fLowR) + fLowR;
     330           0 :   x = r * TMath::Cos(phi);
     331           0 :   y = r * TMath::Sin(phi);
     332           0 :   if (((sector / 2) % 2) == 1) 
     333           0 :     z += TMath::Sign(fModuleSpacing, z);
     334           0 : }
     335             : 
     336             : //____________________________________________________________________
     337             : Bool_t
     338             : AliFMDRing::XYZ2Detector(Double_t  x, 
     339             :                          Double_t  y, 
     340             :                          Double_t  z,
     341             :                          UShort_t& sector,
     342             :                          UShort_t& strip) const
     343             : {
     344             :   // Translate global coordinates (x,y,z) to detector coordinates
     345             :   // (this,sector,strip)
     346             :   // 
     347             :   //  Parameters: 
     348             :   //     x       Global x coordinate 
     349             :   //     y       Global y coordinate
     350             :   //     z       Global y coordinate
     351             :   //     sector  On return, the sector number in this ring
     352             :   //     strip   On return, the strip number in this ring
     353             :   // 
     354           0 :   sector = strip = 0;
     355           0 :   Double_t r = TMath::Sqrt(x * x + y * y);
     356           0 :   Int_t str = Int_t((r - fMinR) / GetPitch());
     357           0 :   if (str < 0 || str >= GetNStrips()) return kFALSE;
     358             : 
     359           0 :   Double_t phi = TMath::ATan2(y, x) * 180. / TMath::Pi();
     360           0 :   if (phi < 0) phi = 360. + phi;
     361           0 :   Int_t sec = Int_t(phi / fTheta);
     362           0 :   if (sec < 0 || sec >= GetNSectors()) return kFALSE;
     363           0 :   if ((sec / 2) % 2 == 1) {
     364           0 :     if (TMath::Abs(z - TMath::Sign(fModuleSpacing, z)) >= 0.01)
     365           0 :       return kFALSE;
     366             :   }
     367           0 :   else if (TMath::Abs(z) >= 0.01) return kFALSE;
     368             : 
     369           0 :   strip  = str;
     370           0 :   sector = sec;
     371           0 :   return kTRUE;
     372           0 : }
     373             : //____________________________________________________________________
     374             : Float_t 
     375             : AliFMDRing::GetStripLength(UShort_t strip) const 
     376             : {
     377             :   // Get the length of a strip 
     378             :   // 
     379             :   // Parameters:
     380             :   //   strip     Strip number (0-511 for inners, 0-255 for outers)
     381             :   // 
     382           0 :   if(strip >= GetNStrips())
     383           0 :     Error("GetStripLength", "Invalid strip number %d (>=%d) for ring type %c", 
     384           0 :           strip, GetNStrips(), fId);
     385             :   
     386           0 :   Float_t rad        = GetMaxR()-GetMinR();
     387             :   
     388           0 :   Float_t segment    = rad / GetNStrips();
     389             :   
     390           0 :   TVector2* corner1  = GetVertex(2);  
     391           0 :   TVector2* corner2  = GetVertex(3);
     392             :   
     393           0 :   Float_t slope      = ((corner1->Y() - corner2->Y()) / 
     394           0 :                         (corner1->X() - corner2->X()));
     395           0 :   Float_t constant   = ((corner2->Y() * corner1->X() - 
     396           0 :                          (corner2->X()*corner1->Y())) / 
     397           0 :                         (corner1->X() - corner2->X()));
     398           0 :   Float_t radius     = GetMinR() + strip*segment;
     399             :   
     400           0 :   Float_t d          = (TMath::Power(TMath::Abs(radius*slope),2) + 
     401           0 :                         TMath::Power(radius,2) - TMath::Power(constant,2));
     402             :   
     403           0 :   Float_t arclength  = GetBaseStripLength(strip);
     404           0 :   if(d>0) {
     405           0 :     Float_t x        = ((-1 * TMath::Sqrt(d) -slope*constant) / 
     406           0 :                         (1 + TMath::Power(slope,2)));
     407           0 :     Float_t y        = slope*x + constant;
     408           0 :     Float_t theta    = TMath::ATan2(x,y);
     409             :     
     410           0 :     if(x < corner1->X() && y > corner1->Y()) {
     411             :       //One sector since theta is by definition half-hybrid
     412           0 :       arclength = radius*theta;
     413           0 :     }
     414           0 :   }
     415             :   
     416           0 :   return arclength;
     417             :   
     418             :   
     419             : }
     420             : //____________________________________________________________________
     421             : Float_t 
     422             : AliFMDRing::GetBaseStripLength(UShort_t strip) const 
     423             : {  
     424             :   // Get the basic strip length 
     425             :   // 
     426             :   // Parameters:
     427             :   //   strip    Strip number
     428           0 :   Float_t rad             = GetMaxR()-GetMinR();
     429           0 :   Float_t segment         = rad / GetNStrips();
     430           0 :   Float_t basearc         = 2*TMath::Pi() / (0.5*GetNSectors()); 
     431           0 :   Float_t radius          = GetMinR() + strip*segment;
     432           0 :   Float_t basearclength   = 0.5*basearc * radius;                
     433             :   
     434           0 :   return basearclength;
     435             : }
     436             : //
     437             : // EOF
     438             : //

Generated by: LCOV version 1.11