+
+
+//________________________________________________________________________
+TGeoPcon* AliITSv11GeometrySDD::CreateConeConstSection(Double_t r1max, Double_t z1,
+ Double_t r2max, Double_t z2,
+ Double_t section, Int_t nDiv)
+{
+ // Creates a cone along z where the section is approximately constant
+ // with z. This is for simulation of cables, because a cone with a constant
+ // radius difference would show a quantity of matter increasing with z...
+ // The max radius of the created Pcon is evolving linearly, the min radius
+ // is calculated at several steps (nDiv).
+ // z2 > z1 (required by the Pcon)
+
+ TGeoPcon *myPcon = new TGeoPcon(0, 360, 1+nDiv);
+
+ Double_t dr = (r2max-r1max)/nDiv;
+ Double_t dz = (z2-z1)/nDiv;
+ Double_t r1minI, r2minI, r1maxI, r2maxI;
+ Double_t z1I, z2I;
+
+ Double_t lZ = TMath::Sqrt((r2max-r1max)*(r2max-r1max) + (z2-z1)*(z2-z1));
+ Double_t cosAlpha = (z2-z1)/lZ;
+
+ r1minI = TMath::Sqrt(r1max*r1max-section/(TMath::Pi()*cosAlpha));
+ myPcon->DefineSection(0, z1, r1minI, r1max);
+
+ for (Int_t i=0; i<nDiv; i++) {
+
+ z1I = z1 + i*dz;
+ z2I = z1I + dz;
+ r1maxI = r1max + i*dr;
+ r2maxI = r1maxI + dr;
+
+ r2minI = TMath::Sqrt(r2maxI*r2maxI-section/(TMath::Pi()*cosAlpha));
+ myPcon->DefineSection(i+1, z2I, r2minI, r2maxI);
+ }
+ return myPcon;
+}
+
+
+//________________________________________________________________________
+Double_t AliITSv11GeometrySDD::GetConeZ(Double_t r, Double_t refR1, Double_t refR2,
+ Double_t refZ1, Double_t refZ2) {
+ // just a helping function
+ return refZ1+(refZ2-refZ1)*(r-refR1)/(refR2-refR1);
+}
+
+//________________________________________________________________________
+Int_t AliITSv11GeometrySDD::CreateAndInsetConeCablePart(TGeoVolume *mother, Double_t angle,
+ Int_t nLay3, Int_t nLay4,
+ Double_t r1, Double_t z1,
+ Double_t r2, Double_t z2) {
+
+ // Create some cables portions from SDD modules grouped
+ // and attached at the border of the SSD cone
+
+ TGeoMedium *copper = GetMedium("COPPER$");
+ TGeoMedium *plastic = GetMedium("SDDKAPTON (POLYCH2)$");
+ TGeoMedium *opticalFiber = GetMedium("SDD OPTICFIB$");
+
+ char titleCable[30];
+ sprintf(titleCable,"cableSDDport%i",(Int_t)angle);
+
+ //---
+ Double_t section = (fgkSectionCuPerMod+fgkSectionPlastPerMod+fgkSectionGlassPerMod)*(nLay3+nLay4);
+ Double_t thickness = 1.; // let's fix the thickness, then calculate the width
+ Double_t width = section/thickness;
+ Double_t thickCu = thickness*fgkSectionCuPerMod/(fgkSectionCuPerMod+fgkSectionPlastPerMod
+ +fgkSectionGlassPerMod);
+
+ Double_t thickPlast = thickness*fgkSectionPlastPerMod/(fgkSectionCuPerMod+fgkSectionPlastPerMod
+ +fgkSectionGlassPerMod);
+
+ Double_t thickGlass = thickness*fgkSectionGlassPerMod/(fgkSectionCuPerMod+fgkSectionPlastPerMod
+ +fgkSectionGlassPerMod);
+
+ Double_t hypothenus = TMath::Sqrt( (r2-r1)*(r2-r1) + (z2-z1)*(z2-z1) );
+ Double_t cosAlpha = (z2-z1)/hypothenus;
+ Double_t radius1Cable = TMath::Sqrt(r1*r1 - width*width/4) - 0.5*thickness/cosAlpha;
+ Double_t radius2Cable = TMath::Sqrt(r2*r2 - width*width/4) - 0.5*thickness/cosAlpha;
+ angle *= TMath::DegToRad();
+ Double_t x1 = radius1Cable*TMath::Cos(angle), y1 = radius1Cable*TMath::Sin(angle);
+ Double_t x2 = radius2Cable*TMath::Cos(angle), y2 = radius2Cable*TMath::Sin(angle);
+ Double_t pos1[3] = {x1,y1,z1};
+ Double_t pos2[3] = {x2,y2,z2};
+ Double_t zVect[3] = {0,0,1};
+
+ AliITSv11GeomCableFlat cable(titleCable,width,thickness);
+ cable.SetNLayers(3);
+ cable.SetLayer(0, thickPlast, plastic, kYellow);
+ cable.SetLayer(1, thickCu, copper, kRed);
+ cable.SetLayer(2, thickGlass, opticalFiber, kGreen);
+
+ cable.AddCheckPoint( mother, 0, pos1, zVect );
+ cable.AddCheckPoint( mother, 1, pos2, zVect );
+ cable.SetInitialNode(mother);
+ cable.CreateAndInsertCableSegment(1);
+
+ return kTRUE;
+}
+
+
+
+//________________________________________________________________________
+void AliITSv11GeometrySDD::SDDCables(TGeoVolume *moth)
+{
+//
+// Creates and inserts the SDD cables running on SDD and SSD cones
+//
+// Input:
+// moth : the TGeoVolume owing the volume structure
+// Output:
+//
+// Created: ??? Ludovic Gaudichet
+// Updated: 15 Mar 2008 Mario Sitta
+// Updated: 14 Apr 2008 Mario Sitta Overlap fixes
+// Updated: 09 May 2008 Mario Sitta SSD overlap fixes
+//
+
+ TGeoMedium *copper = GetMedium("COPPER$");
+ TGeoMedium *plastic = GetMedium("SDDKAPTON (POLYCH2)$");
+ TGeoMedium *opticalFiber = GetMedium("SDD OPTICFIB$");
+ TGeoMedium *airSDD = GetMedium("SDD AIR$");
+
+
+ //==================================
+ //
+ //==================================
+
+ Double_t nModLay3 = fgkLay3Nladd*fgkLay3Ndet;
+ Double_t nModLay4 = fgkLay4Nladd*fgkLay4Ndet;
+
+ Double_t sectionLay3Cu = fgkCableBendRatio*fgkSectionCuPerMod*nModLay3/2;
+ Double_t sectionLay3Plastic = fgkCableBendRatio*fgkSectionPlastPerMod*nModLay3/2;
+ Double_t sectionLay3Glass = fgkCableBendRatio*fgkSectionGlassPerMod*nModLay3/2;
+
+ Double_t sectionLay4Cu = fgkCableBendRatio*fgkSectionCuPerMod*nModLay4/2;
+ Double_t sectionLay4Plastic = fgkCableBendRatio*fgkSectionPlastPerMod*nModLay4/2;
+ Double_t sectionLay4Glass = fgkCableBendRatio*fgkSectionGlassPerMod*nModLay4/2;
+
+ // Do not use hardcoded numbers, get them from real shapes - M.S. 15/03/08
+ TGeoVolume *sddCone = gGeoManager->GetVolume("SDDCarbonFiberCone");
+ TGeoPcon *sddConeShape = (TGeoPcon*)sddCone->GetShape();
+
+ TGeoVolume *sddCylinder = gGeoManager->GetVolume("SDDCarbonFiberCylinder");
+ TGeoTube *sddCylinderShape = (TGeoTube*)sddCylinder->GetShape();
+
+ // (were fgkConeSDDr1, fgkConeSDDr2, fgkConeSDDz1, fgkConeSDDz2 hardcoded)
+ Double_t coneSDDr1 = sddConeShape->GetRmin(5);
+ Double_t coneSDDr2 = sddConeShape->GetRmin(3);
+
+ Double_t coneSDDz1 = sddConeShape->GetZ(9) - sddConeShape->GetZ(5) +
+ sddCylinderShape->GetDz();
+ Double_t coneSDDz2 = sddConeShape->GetZ(9) - sddConeShape->GetZ(3) +
+ sddCylinderShape->GetDz();
+
+ // Calculate z1, z2 thanks to R1 and R2
+ Double_t sddCableZ1 = GetConeZ(fgkSDDCableR1, coneSDDr1, coneSDDr2,
+ coneSDDz1, coneSDDz2);
+ Double_t sddCableZ2 = GetConeZ(fgkSDDCableR2, coneSDDr1, coneSDDr2,
+ coneSDDz1, coneSDDz2);
+ Double_t sddCableZ3 = GetConeZ(fgkSDDCableR3, coneSDDr1, coneSDDr2,
+ coneSDDz1, coneSDDz2);
+
+ TGeoRotation *rotCableSDD = new TGeoRotation("rotCableSDD",0,180,0);
+
+ //==================================
+ // first set of cones : cables from layer 3
+ //==================================
+
+ TGeoPcon* pcon1all = CreateConeConstSection(fgkSDDCableR1, sddCableZ1,
+ fgkSDDCableR2, sddCableZ2,
+ sectionLay3Plastic+sectionLay3Cu+sectionLay3Glass, 1);
+
+ TGeoPcon* pcon1container = new TGeoPcon(0,360,2);
+ pcon1container->DefineSection(0, sddCableZ1, pcon1all->GetRmin(0),
+ pcon1all->GetRmax(0));
+
+ Double_t drMax = pcon1all->GetRmax(0)- pcon1all->GetRmin(0);
+ pcon1container->DefineSection(1, sddCableZ2, pcon1all->GetRmax(1)-drMax,
+ pcon1all->GetRmax(1));
+
+ TGeoVolume *vpcon1container = new TGeoVolume("vpcon1container",
+ pcon1container, airSDD);
+ vpcon1container->SetVisibility(kFALSE);
+
+ TGeoPcon* pcon1plast = CreateConeConstSection(fgkSDDCableR1, sddCableZ1,
+ fgkSDDCableR2, sddCableZ2,
+ sectionLay3Plastic, 3);
+
+ TGeoVolume *vpcon1plast = new TGeoVolume("ITScablesSDDpcon1Plast",
+ pcon1plast, plastic);
+ vpcon1plast->SetLineColor(kYellow);
+ vpcon1container->AddNode(vpcon1plast, 0);
+
+ Double_t dr1a = fgkSDDCableR1 - pcon1plast->GetRmin(0);
+ TGeoPcon* pcon1Cu = CreateConeConstSection(fgkSDDCableR1 - dr1a, sddCableZ1,
+ fgkSDDCableR2 - dr1a, sddCableZ2,
+ sectionLay3Cu, 3);
+
+ TGeoVolume *vpcon1Cu = new TGeoVolume("ITScablesSDDpcon1Cu",
+ pcon1Cu, copper);
+ vpcon1Cu->SetLineColor(kRed);
+ vpcon1container->AddNode(vpcon1Cu, 0);
+
+ Double_t dr1b = pcon1Cu->GetRmax(0) - pcon1Cu->GetRmin(0);
+ TGeoPcon* pcon1glass = CreateConeConstSection(fgkSDDCableR1-dr1a-dr1b, sddCableZ1,
+ fgkSDDCableR2-dr1a-dr1b, sddCableZ2,
+ sectionLay3Glass, 3);
+
+ TGeoVolume *vpcon1glass = new TGeoVolume("ITScablesSDDpcon1glass",
+ pcon1glass, opticalFiber);
+ vpcon1glass->SetLineColor(kGreen);
+ vpcon1container->AddNode(vpcon1glass, 0);
+
+ moth->AddNode(vpcon1container, 1);
+ moth->AddNode(vpcon1container, 2, rotCableSDD);
+
+ //==================================
+ // 2nd set of cones : cables from layer 3 and layer 4
+ //==================================
+
+ TGeoPcon* pcon2all = CreateConeConstSection(fgkSDDCableR2, sddCableZ2,
+ fgkSDDCableR3, sddCableZ3,
+ sectionLay3Plastic+sectionLay4Plastic+
+ sectionLay3Cu+sectionLay4Cu+
+ sectionLay3Glass+sectionLay4Glass, 1);
+
+ TGeoPcon* pcon2container = new TGeoPcon(0,360,2);
+ pcon2container->DefineSection(0, sddCableZ2, pcon2all->GetRmin(0),
+ pcon2all->GetRmax(0));
+
+ drMax = pcon2all->GetRmax(0)- pcon2all->GetRmin(0);
+ pcon2container->DefineSection(1, sddCableZ3, pcon2all->GetRmax(1)-drMax,
+ pcon2all->GetRmax(1));
+
+
+ TGeoVolume *vpcon2container = new TGeoVolume("vpcon2container",
+ pcon2container, airSDD);
+ vpcon2container->SetVisibility(kFALSE);
+
+ TGeoPcon* pcon2plast = CreateConeConstSection(fgkSDDCableR2, sddCableZ2,
+ fgkSDDCableR3, sddCableZ3,
+ sectionLay3Plastic+
+ sectionLay4Plastic, 3);
+
+ TGeoVolume *vpcon2plast = new TGeoVolume("ITScablesSDDpcon2Plast",
+ pcon2plast, plastic);
+ vpcon2plast->SetLineColor(kYellow);
+ vpcon2container->AddNode(vpcon2plast, 0);
+
+ Double_t dr2a = fgkSDDCableR2 - pcon2plast->GetRmin(0);
+ TGeoPcon* pcon2Cu = CreateConeConstSection(fgkSDDCableR2 - dr2a, sddCableZ2,
+ fgkSDDCableR3 - dr2a, sddCableZ3,
+ sectionLay3Cu+sectionLay4Cu, 3);
+
+ TGeoVolume *vpcon2Cu = new TGeoVolume("ITScablesSDDpcon2Cu",
+ pcon2Cu, copper);
+ vpcon2Cu->SetLineColor(kRed);
+ vpcon2container->AddNode(vpcon2Cu, 0);
+
+ Double_t dr2b = pcon2Cu->GetRmax(0) - pcon2Cu->GetRmin(0);
+ TGeoPcon* pcon2glass = CreateConeConstSection(fgkSDDCableR2-dr2a-dr2b, sddCableZ2,
+ fgkSDDCableR3-dr2a-dr2b, sddCableZ3,
+ sectionLay3Glass+
+ sectionLay4Glass, 3);
+
+ TGeoVolume *vpcon2glass = new TGeoVolume("ITScablesSDDpcon2glass",
+ pcon2glass, opticalFiber);
+ vpcon2glass->SetLineColor(kGreen);
+ vpcon2container->AddNode(vpcon2glass, 0);
+
+ moth->AddNode(vpcon2container, 1);
+ moth->AddNode(vpcon2container, 2, rotCableSDD);
+
+ //==================================
+ // intermediate cylinder
+ //==================================
+
+ // (was fgkSDDCableDZint hardcoded)
+ Double_t sddCableDZint = (sddConeShape->GetZ(9) - sddConeShape->GetZ(0) +
+ sddCylinderShape->GetDz()) - sddCableZ3;
+
+ TGeoTube *interCyl = new TGeoTube("sddCableInterCyl",
+ pcon2container->GetRmin(1),
+ pcon2container->GetRmax(1),
+ sddCableDZint/2);
+
+ TGeoVolume *vInterCyl = new TGeoVolume("vSddCableInterCyl",
+ interCyl, airSDD);
+ vInterCyl->SetVisibility(kFALSE);
+
+ Double_t rmaxCylPlast = pcon2container->GetRmax(1);
+ Double_t rminCylPlast = TMath::Sqrt(rmaxCylPlast*rmaxCylPlast -
+ (sectionLay3Plastic+sectionLay4Plastic)/TMath::Pi() );
+
+ TGeoTube *interCylPlast = new TGeoTube("sddCableInterCylPlast", rminCylPlast,
+ rmaxCylPlast, sddCableDZint/2);
+
+ TGeoVolume *vInterCylPlast = new TGeoVolume("vSddCableInterCylPlast",
+ interCylPlast, plastic);
+ vInterCylPlast->SetLineColor(kYellow);
+ vInterCyl->AddNode(vInterCylPlast, 0);
+
+ Double_t rmaxCylCu = pcon2Cu->GetRmax(3);
+ Double_t rminCylCu = TMath::Sqrt(rmaxCylCu*rmaxCylCu -
+ (sectionLay3Cu+sectionLay4Cu)/TMath::Pi() );
+
+ TGeoTube *interCylCu = new TGeoTube("sddCableInterCylCu", rminCylCu,
+ rmaxCylCu, sddCableDZint/2);
+
+ TGeoVolume *vInterCylCu = new TGeoVolume("vSddCableInterCylCu",
+ interCylCu, copper);
+ vInterCylCu->SetLineColor(kRed);
+ vInterCyl->AddNode(vInterCylCu, 0);
+
+ Double_t rmaxCylGlass = pcon2glass->GetRmax(3);
+ Double_t rminCylGlass = TMath::Sqrt(rmaxCylGlass*rmaxCylGlass -
+ (sectionLay3Glass+sectionLay4Glass)/TMath::Pi() );
+
+ TGeoTube *interCylGlass = new TGeoTube("sddCableInterCylGlass", rminCylGlass,
+ rmaxCylGlass, sddCableDZint/2);
+
+ TGeoVolume *vInterCylGlass = new TGeoVolume("vSddCableInterCylGlass",
+ interCylGlass,opticalFiber);
+ vInterCylGlass->SetLineColor(kGreen);
+ vInterCyl->AddNode(vInterCylGlass, 0);
+
+ moth->AddNode(vInterCyl, 1, new TGeoTranslation(0, 0,
+ sddCableZ3+sddCableDZint/2));
+ moth->AddNode(vInterCyl, 2, new TGeoTranslation(0, 0,
+ -sddCableZ3-sddCableDZint/2));
+
+ //==================================
+ // cable cone on the SSD cone
+ //==================================
+
+ Double_t sddCableR4 = rmaxCylPlast;
+ Double_t sddCableZ4 = sddCableZ3 + sddCableDZint;
+
+ TGeoPcon* pcon3all = CreateConeConstSection(sddCableR4, sddCableZ4,
+ fgkSDDCableR5, fgkSDDCableZ5,
+ sectionLay3Plastic+
+ sectionLay4Plastic+
+ sectionLay3Cu+sectionLay4Cu+
+ sectionLay3Glass+sectionLay4Glass, 1);
+
+ TGeoPcon* pcon3container = new TGeoPcon(0,360,2);
+ pcon3container->DefineSection(0, sddCableZ4, pcon3all->GetRmin(0),
+ pcon3all->GetRmax(0));
+
+ drMax = pcon3all->GetRmax(0) - pcon3all->GetRmin(0);
+ pcon3container->DefineSection(1, fgkSDDCableZ5, pcon3all->GetRmax(1)-drMax,
+ pcon3all->GetRmax(1));
+
+
+ TGeoVolume *vpcon3container = new TGeoVolume("vpcon3container",
+ pcon3container, airSDD);
+ vpcon3container->SetVisibility(kFALSE);
+
+ TGeoPcon* pcon3plast = CreateConeConstSection(sddCableR4, sddCableZ4,
+ fgkSDDCableR5, fgkSDDCableZ5,
+ sectionLay3Plastic+
+ sectionLay4Plastic, 3);
+
+ TGeoVolume *vpcon3plast = new TGeoVolume("ITScablesSDDpcon3Plast",
+ pcon3plast, plastic);
+ vpcon3plast->SetLineColor(kYellow);
+ vpcon3container->AddNode(vpcon3plast, 0);
+
+ Double_t dr3a = sddCableR4 - pcon3plast->GetRmin(0);
+ TGeoPcon* pcon3Cu = CreateConeConstSection(sddCableR4 - dr3a, sddCableZ4,
+ fgkSDDCableR5 - dr3a, fgkSDDCableZ5,
+ sectionLay3Cu+sectionLay4Cu, 3);
+
+ TGeoVolume *vpcon3Cu = new TGeoVolume("ITScablesSDDpcon3Cu",
+ pcon3Cu, copper);
+ vpcon3Cu->SetLineColor(kRed);
+ vpcon3container->AddNode(vpcon3Cu, 0);
+
+ Double_t dr3b = pcon3Cu->GetRmax(0) - pcon3Cu->GetRmin(0);
+ TGeoPcon* pcon3glass = CreateConeConstSection(sddCableR4-dr3a-dr3b, sddCableZ4,
+ fgkSDDCableR5-dr3a-dr3b, fgkSDDCableZ5,
+ sectionLay3Glass+sectionLay4Glass, 3);
+
+ TGeoVolume *vpcon3glass = new TGeoVolume("ITScablesSDDpcon3glass",
+ pcon3glass,opticalFiber);
+ vpcon3glass->SetLineColor(kGreen);
+ vpcon3container->AddNode(vpcon3glass, 0);
+
+ moth->AddNode(vpcon3container, 1);
+ moth->AddNode(vpcon3container, 2, rotCableSDD);
+
+ //==================================
+ // cables that are grouped at the end of SSD cones
+ //==================================
+
+ Double_t fgkSDDCableR6 = fgkSDDCableR5+9;
+ Double_t fgkSDDCableZ6 = fgkSDDCableZ5+8.8;
+
+ TGeoVolumeAssembly *endConeSDDCable = new TGeoVolumeAssembly("endConeSDDCable");
+
+ // Add some hardcoded shifts to avoid overlaps with SSD pathc panels
+ CreateAndInsetConeCablePart(endConeSDDCable, 40, 1*3,2*4, fgkSDDCableR5,
+ fgkSDDCableZ5,fgkSDDCableR6+0.7,fgkSDDCableZ6);
+
+ CreateAndInsetConeCablePart(endConeSDDCable, 60, 1*3,1*4, fgkSDDCableR5,
+ fgkSDDCableZ5,fgkSDDCableR6+0.6,fgkSDDCableZ6);
+
+ CreateAndInsetConeCablePart(endConeSDDCable, 85, 2*3,1*4, fgkSDDCableR5,
+ fgkSDDCableZ5,fgkSDDCableR6,fgkSDDCableZ6);
+
+ CreateAndInsetConeCablePart(endConeSDDCable, 95, 0*3,1*4, fgkSDDCableR5,
+ fgkSDDCableZ5,fgkSDDCableR6,fgkSDDCableZ6);
+
+ CreateAndInsetConeCablePart(endConeSDDCable, 110, 2*3,3*4, fgkSDDCableR5,
+ fgkSDDCableZ5,fgkSDDCableR6+0.9,fgkSDDCableZ6);
+
+ CreateAndInsetConeCablePart(endConeSDDCable, 146, 0*3,3*4, fgkSDDCableR5,
+ fgkSDDCableZ5,fgkSDDCableR6+0.7,fgkSDDCableZ6);
+
+ CreateAndInsetConeCablePart(endConeSDDCable, 176.1, 0*3,1*4, fgkSDDCableR5,
+ fgkSDDCableZ5,fgkSDDCableR6,fgkSDDCableZ6);
+
+ CreateAndInsetConeCablePart(endConeSDDCable, 190, 2*3,0*4, fgkSDDCableR5,
+ fgkSDDCableZ5,fgkSDDCableR6,fgkSDDCableZ6);
+
+ CreateAndInsetConeCablePart(endConeSDDCable, 220, 1*3,2*4, fgkSDDCableR5,
+ fgkSDDCableZ5,fgkSDDCableR6,fgkSDDCableZ6);
+
+ CreateAndInsetConeCablePart(endConeSDDCable, 240, 1*3,2*4, fgkSDDCableR5,
+ fgkSDDCableZ5,fgkSDDCableR6,fgkSDDCableZ6);
+
+ CreateAndInsetConeCablePart(endConeSDDCable, 290.1, 2*3,2*4, fgkSDDCableR5,
+ fgkSDDCableZ5,fgkSDDCableR6,fgkSDDCableZ6);
+
+ CreateAndInsetConeCablePart(endConeSDDCable, 315, 1*3,1*4, fgkSDDCableR5,
+ fgkSDDCableZ5,fgkSDDCableR6+0.6,fgkSDDCableZ6);
+
+ CreateAndInsetConeCablePart(endConeSDDCable, 353, 1*3,3*4, fgkSDDCableR5,
+ fgkSDDCableZ5,fgkSDDCableR6,fgkSDDCableZ6);
+
+ moth->AddNode(endConeSDDCable, 1, 0);
+
+ TGeoRotation* reflect = new TGeoRotation("reflectEndConeSDDCable");
+ reflect->ReflectZ(kTRUE);
+ moth->AddNode(endConeSDDCable, 2, reflect);
+
+
+ return;
+}