From ed82d35ec5e88ef7df1d7a5baa882467571fe3c7 Mon Sep 17 00:00:00 2001 From: cholm Date: Mon, 28 Jul 2008 21:16:56 +0000 Subject: [PATCH] Commit of new FMD3 geometry and other geometry related issues. - The FMD3 geometry is defined as per the final drawings of that sub-detector. See also http://fmd.nbi.dk/fmd/drawings/. - No more any detectable overlaps with ITS. - Overlaps _are_ present by not found by automatic tools in ROOT. - It seems that there's a misunderstanding between ITS and FMD. The FMD3 flanges are sitting at 45, 135, 225, and 315 degrees, but ITS has stuff there. - I've put in the precision holes that aligns the FMD3 with the ITS. If the ITS will implement in their geometry similar holes or spikes, then we can use these to determine what is wrong. Also in this commit: - FMD2 moved back 2.5cm to avoid overlaps. - When I get the drawings of FMD2 I will check if this is real. --- FMD/AliFMD1.cxx | 4 +- FMD/AliFMD2.cxx | 8 +- FMD/AliFMD3.cxx | 134 ++++++++------ FMD/AliFMD3.h | 130 +++++++------- FMD/AliFMDGeometryBuilder.cxx | 327 ++++++++++++++++++++++++++++++++-- FMD/AliFMDGeometryBuilder.h | 14 ++ FMD/AliFMDRing.h | 6 +- FMD/Config.C | 11 +- FMD/DrawFMD.C | 59 ++++-- FMD/Reconstruct.C | 7 +- FMD/Simulate.C | 2 +- FMD/scripts/CheckOverlaps.C | 5 +- 12 files changed, 534 insertions(+), 173 deletions(-) diff --git a/FMD/AliFMD1.cxx b/FMD/AliFMD1.cxx index 0a5b74d9e2a..1cd9bdf5669 100644 --- a/FMD/AliFMD1.cxx +++ b/FMD/AliFMD1.cxx @@ -42,8 +42,8 @@ ClassImp(AliFMD1) AliFMD1::AliFMD1(AliFMDRing* inner) : AliFMDDetector(1, inner, 0) { -// Subtracting 0.5 cm puts the middle plane of the detector at 320 cm - SetInnerZ(320. - 0.5); + // Subtracting 0.25 cm puts the middle plane of the detector at 320 cm + SetInnerZ(320. - 0.25); } diff --git a/FMD/AliFMD2.cxx b/FMD/AliFMD2.cxx index 37b9ebb5d3c..a62546e7170 100644 --- a/FMD/AliFMD2.cxx +++ b/FMD/AliFMD2.cxx @@ -29,6 +29,7 @@ // Support will be simple compared to FMD3. // #include "AliFMD2.h" // ALIFMD2_H +#include "AliLog.h" // #include "AliFMDRing.h" // ALIFMDRING_H //==================================================================== @@ -42,8 +43,11 @@ AliFMD2::AliFMD2(AliFMDRing* inner, AliFMDRing* outer) : AliFMDDetector(2, inner, outer) { // Constructor - SetInnerZ(83.4); - SetOuterZ(75.2); + // SetInnerZ(83.4); + // SetOuterZ(75.2); + AliWarning("Z position of FMD2 rings may be wrong by 2.35cm!"); + SetInnerZ(83.4+2.35); + SetOuterZ(75.2+2.35); } diff --git a/FMD/AliFMD3.cxx b/FMD/AliFMD3.cxx index e41e113ba8a..dfa944a7cc2 100644 --- a/FMD/AliFMD3.cxx +++ b/FMD/AliFMD3.cxx @@ -35,6 +35,7 @@ #include "AliFMD3.h" // ALIFMD3_H #include "AliFMDDebug.h" // ALIFMDDEBUG_H ALILOG_H #include "AliFMDRing.h" // ALIFMDRING_H +#include //==================================================================== ClassImp(AliFMD3) @@ -45,38 +46,49 @@ ClassImp(AliFMD3) //____________________________________________________________________ AliFMD3::AliFMD3(AliFMDRing* inner, AliFMDRing* outer) : AliFMDDetector(3, inner, outer), - fNoseZ(0), - fNoseLowR(0), - fNoseHighR(0), - fNoseLength(0), - fBackLowR(0), - fBackHighR(0), - fBackLength(0), - fBeamThickness(0), - fBeamWidth(0), - fConeLength(0), - fFlangeR(0), - fZ(0), - fAlpha(0), - fNBeam(0), - fNFlange(0) + fNoseZ(16.54667), // From drawing + fFlangeDepth(0), + fFlangeHighR(49.25), // From drawing + fFlangeLength(0), + fFlangeWidth(6), // From drawing + fFiducialRadius(.25), + fConeInnerAngle(0), + fConeOuterAngle(0), + fHoleOffset(7), // From drawing + fHoleDepth(2), // What's needed + fHoleLength(0), + fHoleLowWidth(4), // What's needed + fHoleHighWidth(18), // What's needed + fBoltLength(1), // Guessed + fBoltRadius(0.15), // Estimate + fConeRadii(6), + fFiducialHoles(4) { // Constructor. - SetInnerZ(-62.8); - SetOuterZ(-75.2); - SetNoseZ(); - SetNoseLowR(); - SetNoseHighR(); - SetNoseLength(); - SetBackLowR(); - SetBackHighR(); - SetBackLength(); - SetBeamThickness(); - SetBeamWidth(); - SetConeLength(); - SetFlangeR(); - SetNBeam(); - SetNFlange(); + // SetInnerZ(-62.8); // By design + // SetOuterZ(-75.2); // By design + AliWarning("Z position of FMD3 rings may be off by 0.25cm!"); + SetInnerZ(-63.05); // Slightly off (2.5mm) from design + SetOuterZ(-75.45); // Slightly off (2.5mm) from design + + SetInnerHoneyLowR(4.18207); // From drawing + SetInnerHoneyHighR(19.74922); // From drawing + SetOuterHoneyLowR(13.4776); // From drawing + SetOuterHoneyHighR(31.01964); // From drawing + + // These are from the drawings + fConeRadii.Add(new TVector3( 0, 5.55, 6.25)); + fConeRadii.Add(new TVector3( 2.35, 5.55, 6.25)); + fConeRadii.Add(new TVector3( 2.9935, 5.55, 6.88479)); + fConeRadii.Add(new TVector3(28.9435, 31.50, 32.75850)); + fConeRadii.Add(new TVector3(29.5, 31.50, 33.4)); + fConeRadii.Add(new TVector3(30.9, 31.50, 33.4)); + + // These are from the drawings + fFiducialHoles.Add(new TVector2(29.666, 32.495)); + fFiducialHoles.Add(new TVector2(31.082, 33.910)); + fFiducialHoles.Add(new TVector2(32.674, 35.503)); + fFiducialHoles.Add(new TVector2(33.403, 34.818)); } //____________________________________________________________________ @@ -85,17 +97,22 @@ AliFMD3::Init() { // Initialize AliFMDDetector::Init(); - SetInnerHoneyHighR(GetOuterHoneyHighR()); - Double_t zdist = fConeLength; - Double_t tdist = fBackHighR - fNoseHighR; - Double_t innerZh = (fInnerZ - fInner->GetRingDepth()); - Double_t outerZh = (fOuterZ - fOuter->GetRingDepth() - - fOuter->GetHoneycombThickness()); - Double_t minZ = TMath::Min(fNoseZ - fConeLength, outerZh); - fAlpha = tdist / zdist; - fZ = fNoseZ + (minZ - fNoseZ) / 2; - fInnerHoneyHighR = ConeR(innerZh,"I"); - fOuterHoneyHighR = GetBackLowR(); + // TVector3& v0 = *(static_cast(fConeRadii.At(0))); + TVector3& v1 = *(static_cast(fConeRadii.At(1))); + TVector3& v2 = *(static_cast(fConeRadii.At(2))); + TVector3& v3 = *(static_cast(fConeRadii.At(3))); + TVector3& v4 = *(static_cast(fConeRadii.At(4))); + TVector3& v5 = *(static_cast(fConeRadii.At(5))); + + fFlangeDepth = v5.X() - v4.X(); + fFlangeLength = fFlangeHighR - v5.Y(); + + fConeInnerAngle = TMath::ATan2(v4.Z()-v1.Z(), v4.X()-v1.X()); + fConeOuterAngle = TMath::ATan2(v3.Y()-v2.Y(), v3.X()-v2.X()); + + Double_t hz1 = -fHoleOffset+fInnerZ+fNoseZ; + fHoleLength = TMath::Sqrt(TMath::Power(v4.Z()-ConeR(hz1),2) + + TMath::Power(v4.X()-fHoleOffset,2)); } //____________________________________________________________________ @@ -103,26 +120,33 @@ Double_t AliFMD3::ConeR(Double_t z, Option_t* opt) const { // Calculate the cone radius at Z - if (fAlpha < 0) { - AliWarning(Form("alpha not set: %lf", fAlpha)); - return -1; - } - if (z > fNoseZ) { - AliWarning(Form("z=%lf is before start of cone %lf", z, fNoseZ)); + // TVector3& v0 = *(static_cast(fConeRadii.At(0))); + TVector3& v1 = *(static_cast(fConeRadii.At(1))); + TVector3& v2 = *(static_cast(fConeRadii.At(2))); + TVector3& v3 = *(static_cast(fConeRadii.At(3))); + TVector3& v4 = *(static_cast(fConeRadii.At(4))); + TVector3& v5 = *(static_cast(fConeRadii.At(5))); + + if (z > fInnerZ + fNoseZ) { + AliWarning(Form("z=%lf is before start of cone %lf", z, fInnerZ + fNoseZ)); return -1; } - if (z < fOuterZ - fOuter->GetFullDepth()) { + if (z < fInnerZ + fNoseZ - v5.Z()) { AliWarning(Form("z=%lf is after end of cone %lf", z, - fOuterZ - fOuter->GetFullDepth())); + fInnerZ + fNoseZ - v5.Z())); return -1; } + Double_t rz = -(z-fInnerZ-fNoseZ); Bool_t inner = opt[0] == 'I' || opt[1] == 'i'; - Double_t off1 = (inner ? fNoseLowR : fNoseHighR); - Double_t off2 = (inner ? fBackLowR : fBackHighR); - Double_t off3 = (inner ? 0 : fBeamThickness/fAlpha); - if (z > fNoseZ - fNoseLength) return off1; - if (z < fNoseZ - fConeLength + fBackLength) return off2; - return (off1 + off3 + fAlpha * TMath::Abs(z - fNoseZ + fNoseLength)); + if (inner && rz <= v2.X()) return v2.Y(); + if (!inner && rz <= v1.X()) return v1.Z(); + if (inner && rz > v3.X()) return v3.Y(); + if (!inner && rz > v4.X()) return v4.Z(); + + rz -= (inner ? v2.X() : v1.X()); + Double_t sr = (inner ? v2.Y() : v1.Z()); + Double_t ang = (inner ? fConeInnerAngle : fConeOuterAngle); + return sr + rz * TMath::Tan(ang); } diff --git a/FMD/AliFMD3.h b/FMD/AliFMD3.h index 50a0322d2f1..78e9e91c814 100644 --- a/FMD/AliFMD3.h +++ b/FMD/AliFMD3.h @@ -15,6 +15,7 @@ #ifndef ALIFMDDETECTOR_H # include "AliFMDDetector.h" #endif +#include /** @class AliFMD3 AliFMD3.h @brief Geometry parameters of the FMD3 detector. @@ -35,65 +36,49 @@ public: /** Initialize the geometry */ virtual void Init(); - - /** @param z Z position of front of nose */ - void SetNoseZ(Double_t z=-46) { fNoseZ = z; } - /** @param r Nose inner radius */ - void SetNoseLowR(Double_t r=5.5) { fNoseLowR = r; } - /** @param r Nose outer radius */ - void SetNoseHighR(Double_t r=6.7) { fNoseHighR = r; } - /** @param l Length of nose in Z */ - void SetNoseLength(Double_t l=2.8) { fNoseLength = l; } - /** @param r Inner radius of base of cone */ - void SetBackLowR(Double_t r=61./2) { fBackLowR = r; } - /** @param r Outer radius of base of cone */ - void SetBackHighR(Double_t r=66.8/2) { fBackHighR = r; } - /** @param l Length of base of cone in Z */ - void SetBackLength(Double_t l=1.4) { fBackLength = l; } - /** @param t Thickness of support beams */ - void SetBeamThickness(Double_t t=.5) { fBeamThickness = t; } - /** @param w Width of support beams */ - void SetBeamWidth(Double_t w=5) { fBeamWidth = w; } - /** @param l Length of the cone in Z */ - void SetConeLength(Double_t l=30.9) { fConeLength = l; } - /** @param r Outer radius of flanges */ - void SetFlangeR(Double_t r=49.25) { fFlangeR = r; } - /** @param n Number of support beams */ - void SetNBeam(Int_t n=8) { fNBeam = n; } - /** @param n Number of support flanges */ - void SetNFlange(Int_t n=4) { fNFlange = n; } + /** Get the Z offset (to inner ring) */ + Double_t GetNoseZ() const { return fNoseZ; } /** @return Z position of front of nose */ - Double_t GetNoseZ() const { return fNoseZ; } + Double_t GetFlangeDepth() const { return fFlangeDepth; } /** @return Nose inner radius */ - Double_t GetNoseLowR() const { return fNoseLowR; } + Double_t GetFlangeLength() const { return fFlangeLength; } /** @return Nose outer radius */ - Double_t GetNoseHighR() const { return fNoseHighR; } + Double_t GetFlangeWidth() const { return fFlangeWidth; } + /** @return Length of nose in Z */ - Double_t GetNoseLength() const { return fNoseLength; } - /** @return Inner radius of base of cone */ - Double_t GetBackLowR() const { return fBackLowR; } - /** @return Outer radius of base of cone */ - Double_t GetBackHighR() const { return fBackHighR; } - /** @return Length of base of cone in Z */ - Double_t GetBackLength() const { return fBackLength; } - /** @return Thickness of support beams */ - Double_t GetBeamThickness() const { return fBeamThickness; } - /** @return Width of support beams */ - Double_t GetBeamWidth() const { return fBeamWidth; } - /** @return Length of the cone in Z */ - Double_t GetConeLength() const { return fConeLength; } - /** @return Outer radius of flanges */ - Double_t GetFlangeR() const { return fFlangeR; } - /** @return Midpoint of mother volume */ - Double_t GetZ() const { return fZ; } - /** @return Slope of cone */ - Double_t GetAlpha() const { return fAlpha; } - /** @return Number of support beams */ - Int_t GetNBeam() const { return fNBeam; } - /** @return Number of support flanges */ - Int_t GetNFlange() const { return fNFlange; } + Double_t GetFiducialRadius() const { return fFiducialRadius; } + + /** @return The angle of the cone on out-side */ + Double_t GetConeOuterAngle() const { return fConeOuterAngle; } + /** @return The angle of the cone on out-side */ + Double_t GetConeInnerAngle() const { return fConeInnerAngle; } + + /** @return Hole off-set from nose */ + Double_t GetHoleOffset() const { return fHoleOffset; } + /** @return Depth of holes */ + Double_t GetHoleDepth() const { return fHoleDepth; } + /** @return Length of holes */ + Double_t GetHoleLength() const { return fHoleLength; } + /** @return Lowest with of holes */ + Double_t GetHoleLowWidth() const { return fHoleLowWidth; } + /** @return Highest width of holes */ + Double_t GetHoleHighWidth() const { return fHoleHighWidth; } + /** @return Length of a bolt */ + Double_t GetBoltLength() const { return fBoltLength; } + /** @return Bolt radius */ + Double_t GetBoltRadius() const { return fBoltRadius; } + + + /** @return array of 3-vectors (z, r_low, r_high) of the cone + radii. */ + const TObjArray& ConeRadii() const { return fConeRadii; } + /** @return array of 2-vectors (x,y) of the fiducial holes in the + flanges. coordinates are in the global coordinate + system. */ + const TObjArray& FiducialHoles() const { return fFiducialHoles; } + /** Get the cone radii at @a z. @param z Point to evaulate at @param opt If @c "O" get the outer radii, if @c "I" get the @@ -103,21 +88,30 @@ public: protected: Double_t fNoseZ; // Z position of front of nose - Double_t fNoseLowR; // Nose inner radius - Double_t fNoseHighR; // Nose outer radius - Double_t fNoseLength; // Length of nose in Z - Double_t fBackLowR; // Inner radius of base of cone - Double_t fBackHighR; // Outer radius of base of cone - Double_t fBackLength; // Length of base of cone in Z - Double_t fBeamThickness; // Thickness of support beams - Double_t fBeamWidth; // Width of support beams - Double_t fConeLength; // Length of the cone in Z - Double_t fFlangeR; // Outer radius of flanges - Double_t fZ; // Midpoint of mother volume - Double_t fAlpha; // Slope of cone - Int_t fNBeam; // Number of support beams - Int_t fNFlange; // Number of support flangesy - ClassDef(AliFMD3, 1); + Double_t fFlangeDepth; // Depth of flanges + Double_t fFlangeHighR; // Outer radius of flanges. + Double_t fFlangeLength; // Length of flanges + Double_t fFlangeWidth; // Width of flanges + + Double_t fFiducialRadius; // Radius of fiducial holes. + + Double_t fConeInnerAngle; // Angle of cone on inside + Double_t fConeOuterAngle; // Angle of cone on outside + + Double_t fHoleOffset; // Offset (from nose-tip) of + // holes + Double_t fHoleDepth; // Depth of holes + Double_t fHoleLength; // Length of holes + Double_t fHoleLowWidth; // Lowest with of holes + Double_t fHoleHighWidth; // Highest width of holes + + Double_t fBoltLength; // Length of a bolt + Double_t fBoltRadius; // Bolt radius + + TObjArray fConeRadii; // Array of cone radii. + TObjArray fFiducialHoles; // Array of fiducial hole (x,y) + + ClassDef(AliFMD3, 2); }; #endif diff --git a/FMD/AliFMDGeometryBuilder.cxx b/FMD/AliFMDGeometryBuilder.cxx index 80e2598e2ff..d35a37e0e3d 100644 --- a/FMD/AliFMDGeometryBuilder.cxx +++ b/FMD/AliFMDGeometryBuilder.cxx @@ -40,9 +40,11 @@ #include // ROOT_TGeoTrd1 #include // ROOT_TGeoVolume #include // ROOT_TGeoXtru +#include // ROOT_TGeoPcon #include #include #include // ROOT_TVector2 +#include // ROOT_TVector3 //#include // ROOT_TGeoMaterial //#include // ROOT_TGeoMedium //#include // ROOT_TGeoPcon @@ -57,6 +59,7 @@ #include "AliFMD3.h" // ALIFMD3_H // #include "AliFMD.h" // ALIFMD_H #include "AliFMDDebug.h" // ALILOG_H +#include //==================================================================== ClassImp(AliFMDGeometryBuilder) @@ -460,6 +463,66 @@ AliFMDGeometryBuilder::RingGeometry(AliFMDRing* r) return 0; } +//____________________________________________________________________ +TGeoShape* +AliFMDGeometryBuilder::HoneycombShape(Int_t id, Char_t ring, + double r1, double r2, + double w, double t, double c) +{ + // Make a honey comb shape from passed parameters. + // Parameters: + // id Detector identifier (1,2, or 3) + // ring Ring identifier ('I' or 'O') + // r1 Inner radius + // r2 Outer radius + // w width + // t Thickness of material + // c Clearing from horizontal. + // Return + // Pointer to newly allocated composite shape. + TString form = Form("FMD%d%c_%%c_%%c", id, ring); + double a1 = TMath::ATan2(c, r1) * 180 / TMath::Pi(); + + TString fn = Form(form.Data(),'F','1'); + TString bn = Form(form.Data(),'B','1'); + TString cn = Form(form.Data(),'C','O'); + TString in = Form(form.Data(),'R','I'); + TString on = Form(form.Data(),'R','O'); + TString en = Form(form.Data(),'E','X'); + double y = c; + double x = r1 * TMath::Cos(TMath::Pi()*a1/180); + new TGeoTubeSeg(fn.Data(),r1,r2,t/2,0,180); + new TGeoTubeSeg(bn.Data(),r1,r2,t/2,0,180); + new TGeoBBox(cn.Data(),(r2-r1)/2,t/2,w/2); + new TGeoTubeSeg(in.Data(),r1,r1+t,w/2,0,180); + new TGeoTubeSeg(on.Data(),r2-t,r2,w/2,0,180); + new TGeoBBox(en.Data(),r2+.005,c/2+.005,w/2+.005); + + TString ftn = Form(form.Data(),'F','T'); + TString btn = Form(form.Data(),'F','B'); + TString ltn = Form(form.Data(),'C','L'); + TString rtn = Form(form.Data(),'C','R'); + TString etn = Form(form.Data(),'E','X'); + (new TGeoTranslation(ftn.Data(),0,0,+w/2-t/2))->RegisterYourself(); + (new TGeoTranslation(btn.Data(),0,0,-w/2+t/2))->RegisterYourself(); + (new TGeoTranslation(ltn.Data(),-(x+(r2-r1)/2), y+t/2,0))->RegisterYourself(); + (new TGeoTranslation(rtn.Data(),(x+(r2-r1)/2), y+t/2,0))->RegisterYourself(); + (new TGeoTranslation(etn.Data(),0, c/2,0))->RegisterYourself(); + + TString comp(Form("(%s:%s+%s:%s+%s+%s+%s:%s+%s:%s)-%s:%s", + fn.Data(),ftn.Data(), + bn.Data(),btn.Data(), + in.Data(),on.Data(), + cn.Data(),ltn.Data(), + cn.Data(),rtn.Data(), + en.Data(),etn.Data())); + TGeoCompositeShape* shape = new TGeoCompositeShape(comp.Data()); + shape->SetName(Form(fgkHCName,id,ring)); + shape->SetTitle(Form("FMD%d%c Honeycomb shape", id, ring)); + return shape; +} + + //____________________________________________________________________ TGeoVolume* AliFMDGeometryBuilder::DetectorGeometry(AliFMDDetector* d, @@ -527,22 +590,10 @@ AliFMDGeometryBuilder::DetectorGeometry(AliFMDDetector* d, topMother->AddNode(tvol, Int_t(c), new TGeoTranslation(0,0,z)); botMother->AddNode(bvol, Int_t(c), new TGeoTranslation(0,0,z)); - // Top of Honeycomb - TGeoTubeSeg* hcSha = new TGeoTubeSeg(lowr, highr, hcThick/2, 0, 180); - hcSha->SetName(Form(fgkHCName,id,c)); - hcSha->SetTitle(Form("FMD%d%c honeycomb shell", id, c)); + // Honeycomp + TGeoShape* hcSha = HoneycombShape(id, c, lowr, highr, hcThick, alThick); TGeoVolume* hcVol = new TGeoVolume(Form(fgkHCName,id,c),hcSha,fAl); hcVol->SetTitle(Form("FMD%d%c honeycomb shell", id, c)); - // Air in top of honeycomb - TGeoTubeSeg* ihcSha = new TGeoTubeSeg(lowr+alThick, highr - alThick, - (hcThick-alThick)/2, 0, 180); - ihcSha->SetName(Form(fgkIHCName,id,c)); - ihcSha->SetTitle(Form("FMD%d%c honeycomb internal", id, c)); - TGeoVolume* ihcVol = new TGeoVolume(Form(fgkIHCName,id,c),ihcSha,fAir); - ihcVol->SetTitle(Form("FMD%d%c honeycomb internal", id, c)); - hcVol->AddNode(ihcVol, 0); - hcVol->VisibleDaughters(kFALSE); - hcVol->SetVisibility(kTRUE); z += (r->GetSiThickness() + r->GetSpacing() + @@ -724,8 +775,8 @@ AliFMDGeometryBuilder::FMD2Geometry(AliFMD2* fmd2, Double_t z = fmd2->GetOuterZ(); Double_t framelr = fmd2->GetOuterHoneyHighR()+0.5; Double_t framehr = fmd2->GetOuterHoneyHighR()+1.8; - Double_t framelz = -1; - Double_t framehz = (fmd2->GetInnerZ()-z) + r->GetFullDepth() + 1; + Double_t framelz = -.5; + Double_t framehz = (fmd2->GetInnerZ()-z) + r->GetFullDepth() + .5; Double_t framel = framehz - framelz; Double_t coverlr = fmd2->GetInner()->GetLowR()+1; Double_t backth = 0.05; @@ -776,7 +827,7 @@ AliFMDGeometryBuilder::FMD2Geometry(AliFMD2* fmd2, Double_t f1l = 10; Double_t f1w = 6; - Double_t f1d = 1.2; + Double_t f1d = 1; TGeoBBox* flange1Shape = new TGeoBBox(f1l/2, f1w/2, f1d/2); TGeoVolume* flange1Volume = new TGeoVolume(Form(fgkFlangeName, fmd2->GetId()), @@ -832,6 +883,227 @@ AliFMDGeometryBuilder::FMD2Geometry(AliFMD2* fmd2, return 0; } +#if 1 +//____________________________________________________________________ +TGeoVolume* +AliFMDGeometryBuilder::FMD3Geometry(AliFMD3* fmd3, + TGeoVolume* innerTop, + TGeoVolume* innerBot, + TGeoVolume* outerTop, + TGeoVolume* outerBot) +{ + // Setup the FMD3 geometry. The FMD2 has a rather elaborate support + // structure, as the support will also support the vacuum + // beam-pipe. + // + // See also AliFMDGeometryBuilder::DetectorGeometry + // + if (!fmd3 || !innerTop || !innerBot || !outerTop || !outerBot) return 0; + + //__________________________________________________________________ + // Basic detector set-up. + TGeoVolume* fmd3TopVolume = new TGeoVolumeAssembly(Form(fgkFMDName, + fmd3->GetId(), 'T')); + TGeoVolume* fmd3BotVolume = new TGeoVolumeAssembly(Form(fgkFMDName, + fmd3->GetId(), 'B')); + fmd3TopVolume->SetTitle("FMD3 top half"); + fmd3BotVolume->SetTitle("FMD3 bottom half"); + DetectorGeometry(fmd3, fmd3TopVolume, fmd3BotVolume, fmd3->GetInnerZ(), + innerTop, innerBot, outerTop, outerBot); + + //__________________________________________________________________ + // Mother for all support material + TGeoVolumeAssembly* support = new TGeoVolumeAssembly("F3SU"); + support->SetTitle("FMD3 support"); + + //__________________________________________________________________ + // Base of cone + const TObjArray& radii = fmd3->ConeRadii(); + Int_t nRadii = radii.GetEntriesFast(); + TGeoPcon* coneBase = new TGeoPcon("FMD3_cone_base", 0., 180., nRadii); + TVector3* r5 = 0; + TVector3* r4 = 0; + for (Int_t i = 0; i < nRadii; i++) { + TVector3* v = static_cast(radii.At(i)); + coneBase->DefineSection(i, v->X(), v->Y(), v->Z()); + if (i == 5) r5 = v; + else if (i == 4) r4 = v; + } + TString coneComb("(FMD3_cone_base"); + + //__________________________________________________________________ + // Flanges + double flangeDepth = fmd3->GetFlangeDepth() / 2; + double flangeLength = fmd3->GetFlangeLength() / 2; + double flangeWidth = fmd3->GetFlangeWidth() / 2; + new TGeoBBox("FMD3_flange_base", flangeLength, flangeWidth, flangeDepth); + + // Fiducial holes + const TObjArray& fiducialHoles = fmd3->FiducialHoles(); + double fiducialRadius = fmd3->GetFiducialRadius(); + TGeoTube* fiducialShape = new TGeoTube("FMD3_fiducial_hole", 0, + fiducialRadius, + flangeDepth+.1); + Int_t nFiducialHoles = fiducialHoles.GetEntriesFast(); + double flangeAngle = TMath::Pi() / 4; + double flangeX = r5->Y()+flangeLength; + TVector2 flangeC(flangeX * TMath::Cos(flangeAngle), + flangeX * TMath::Sin(flangeAngle)); + TString flangeComb("FMD3_flange_base-("); +#if 0// For debugging geometry + TGeoVolume* fiducialVolume = new TGeoVolume("FMD3_fiducial", fiducialShape); + fiducialVolume->SetLineColor(kGreen); +#else + (void*)fiducialShape; +#endif + for (Int_t i = 0; i < nFiducialHoles; i++) { + TVector2& v = *(static_cast(fiducialHoles.At(i))); + v -= flangeC; + TVector2 r = v.Rotate(-flangeAngle); + TGeoTranslation* t1 = new TGeoTranslation(r.X(), r.Y(), 0); + TGeoTranslation* t2 = new TGeoTranslation(r.X(), -r.Y(), 0); + t1->SetName(Form("FMD3_fiducial_hole_rot%d", 2*i+0)); + t2->SetName(Form("FMD3_fiducial_hole_rot%d", 2*i+1)); + t1->RegisterYourself(); + t2->RegisterYourself(); + flangeComb.Append(Form("FMD3_fiducial_hole:FMD3_fiducial_hole_rot%d+" + "FMD3_fiducial_hole:FMD3_fiducial_hole_rot%d%c", + 2*i+0, 2*i+1, (i == nFiducialHoles-1 ? ')' : '+'))); +#if 1 // For debugging geometry + // support->AddNode(fiducialVolume, 2*i+0, t1); + // support->AddNode(fiducialVolume, 2*i+1, t2); +#endif + } + + // Final flange shape, and at to full shape + TGeoCompositeShape* flangeShape = new TGeoCompositeShape(flangeComb.Data()); + flangeShape->SetName("FMD3_flange"); + for (Int_t i = 0; i < 2; i++) { + TGeoRotation* rot = new TGeoRotation(); + rot->RotateZ((i+.5)*90); + TVector2 v(flangeX, 0); + TVector2 w = v.Rotate((i+.5) * 2 * flangeAngle); + TGeoCombiTrans* trans = new TGeoCombiTrans(w.X(),w.Y(), + r4->X()+flangeDepth, rot); + trans->SetName(Form("FMD3_flange_matrix%d", i)); + trans->RegisterYourself(); + coneComb.Append(Form("+FMD3_flange:FMD3_flange_matrix%d", i)); + } + coneComb.Append(")-("); + + //__________________________________________________________________ + // Holes + Double_t holeL = (fmd3->GetHoleLength()-1)/2; + Double_t holeD = fmd3->GetHoleDepth()/2; + Double_t holeLW = fmd3->GetHoleLowWidth()/2; + Double_t holeHW = fmd3->GetHoleHighWidth()/2; + Double_t holeA = fmd3->GetConeOuterAngle() - 1 * TMath::Pi() / 180; + Double_t holeZ = (fmd3->GetHoleOffset() + + holeL * TMath::Cos(holeA) + - holeD * TMath::Sin(holeA)); + Double_t holeX = (fmd3->ConeR(-holeZ + fmd3->GetInnerZ() + fmd3->GetNoseZ()) + - holeD * TMath::Cos(holeA)); + Double_t plateZ = (fmd3->GetHoleOffset() + + holeL * TMath::Cos(holeA) + - 0.033 * TMath::Sin(holeA)); + Double_t plateX = (fmd3->ConeR(-plateZ + fmd3->GetInnerZ()+fmd3->GetNoseZ()) + - 0.033 * TMath::Cos(holeA)); + TGeoTrd1* holeShape = new TGeoTrd1("FMD3_cone_hole", + holeLW, holeHW, holeD, holeL); + TGeoTrd1* plateShape = new TGeoTrd1("FMD3_cooling_plate", + holeLW, holeHW, .033, holeL); + TGeoRotation* holeRot = new TGeoRotation(); + holeRot->SetName("FMD3_cone_hole_rotation"); + holeRot->RotateZ(90); + holeRot->RotateY(holeA*180/TMath::Pi()); + TGeoCombiTrans* holeBaseTrans = new TGeoCombiTrans(holeX, 0, holeZ, holeRot); + holeBaseTrans->SetName("FMD3_cone_hole_base_matrix"); + TGeoCombiTrans* plateBaseTrans = new TGeoCombiTrans(plateX, 0,plateZ,holeRot); + (void*)holeShape; + TGeoVolume* plateVolume = new TGeoVolume("F3CO", plateShape, fAl); + plateShape->SetTitle("FMD3 cooling plate"); + plateVolume->SetTitle("FMD3 cooling plate"); + for (Int_t i = 0; i < 4; i++) { + Double_t ang = 360. / 8 * (i + .5); + TGeoCombiTrans* trans = new TGeoCombiTrans(*holeBaseTrans); + trans->RotateZ(ang); + trans->SetName(Form("FMD3_cone_hole_matrix%d", i)); + trans->RegisterYourself(); + trans = new TGeoCombiTrans(*plateBaseTrans); + trans->RotateZ(ang); + trans->SetName(Form("FMD3_cooling_plate_matrix%d", i)); + coneComb.Append(Form("FMD3_cone_hole:FMD3_cone_hole_matrix%d+", i)); + support->AddNode(plateVolume, i, trans); + } + + //__________________________________________________________________ + // Bolts + Double_t boltRadius = fmd3->GetBoltRadius(); + Double_t boltLength = fmd3->GetBoltLength() / 2; + Double_t boltZ1 = fmd3->GetInnerZ()+fmd3->GetNoseZ()-10; + Double_t boltZ2 = fmd3->GetInnerZ()+fmd3->GetNoseZ()-20; + Double_t boltXE = 2*boltLength*TMath::Cos(fmd3->GetConeOuterAngle()); + Double_t boltX1 = (fmd3->ConeR(boltZ1) - boltXE); + Double_t boltX2 = (fmd3->ConeR(boltZ2) - boltXE); + + new TGeoTube("FMD3_bolt_hole", 0, boltRadius, boltLength+.2); + TGeoTube* boltShape = new TGeoTube("FMD3_bolt", 0, boltRadius, boltLength); + TGeoRotation* boltRot = new TGeoRotation(); + boltRot->RotateY(-fmd3->GetConeOuterAngle()*180/TMath::Pi()); + TGeoCombiTrans* boltTrans1 = new TGeoCombiTrans(boltX1, 0, 10, boltRot); + TGeoCombiTrans* boltTrans2 = new TGeoCombiTrans(boltX2, 0, 20, boltRot); + TGeoCombiTrans* boltTrans3 = new TGeoCombiTrans(*boltTrans1); + TGeoCombiTrans* boltTrans4 = new TGeoCombiTrans(*boltTrans2); + boltTrans3->RotateZ(180); + boltTrans4->RotateZ(180); + boltTrans1->SetName("FMD3_bolt_matrix1"); + boltTrans2->SetName("FMD3_bolt_matrix2"); + boltTrans3->SetName("FMD3_bolt_matrix3"); + boltTrans4->SetName("FMD3_bolt_matrix4"); + boltTrans1->RegisterYourself(); + boltTrans2->RegisterYourself(); + boltTrans3->RegisterYourself(); + boltTrans4->RegisterYourself(); + coneComb.Append("FMD3_bolt_hole:FMD3_bolt_matrix1" + "+FMD3_bolt_hole:FMD3_bolt_matrix2" + "+FMD3_bolt_hole:FMD3_bolt_matrix3" + "+FMD3_bolt_hole:FMD3_bolt_matrix4)"); + TGeoVolume* boltVolume = new TGeoVolume("F3SB", boltShape, fSteel); + support->AddNode(boltVolume, 1, boltTrans1); + support->AddNode(boltVolume, 2, boltTrans2); + boltShape->SetTitle("FMD3 steering bolt"); + boltVolume->SetTitle("FMD3 steering bolt"); + + //__________________________________________________________________ + TGeoCompositeShape* coneShape = new TGeoCompositeShape(coneComb.Data()); + coneShape->SetName("FMD3_cone"); + coneShape->SetTitle("FMD3 cone"); + TGeoVolume* coneVolume = new TGeoVolume("F3SC", coneShape, fC); + coneVolume->SetLineColor(kRed); + support->AddNode(coneVolume, 0, new TGeoTranslation(0, 0, 0)); + + //__________________________________________________________________ + // Place support volumes in half-detector volumes + Double_t z = fmd3->GetInnerZ(); + TGeoTranslation* t1 = new TGeoTranslation(0, 0, -fmd3->GetNoseZ()); + fmd3TopVolume->AddNode(support, 1, t1); + TGeoCombiTrans* t2 = new TGeoCombiTrans(*t1); + t2->RotateZ(180); + fmd3BotVolume->AddNode(support, 2, t2); + + TGeoRotation* rot = new TGeoRotation("FMD3 rotatation"); + rot->RotateY(180); + TGeoVolume* top = gGeoManager->GetVolume("ALIC"); + TGeoMatrix* mmatrix = new TGeoCombiTrans("FMD3 trans", 0, 0, z, rot); + AliFMDDebug(5, ("Placing volumes %s and %s in ALIC at z=%f", + fmd3TopVolume->GetName(), fmd3BotVolume->GetName(), z)); + top->AddNode(fmd3TopVolume, fmd3->GetId(), mmatrix); + top->AddNode(fmd3BotVolume, fmd3->GetId(), mmatrix); + + return 0; +} + +#else //____________________________________________________________________ TGeoVolume* AliFMDGeometryBuilder::FMD3Geometry(AliFMD3* fmd3, @@ -878,6 +1150,26 @@ AliFMDGeometryBuilder::FMD3Geometry(AliFMD3* fmd3, TGeoVolumeAssembly* support = new TGeoVolumeAssembly("F3SU"); support->SetTitle("FMD3 support"); + // Cone shape + TGeoPcon* coneBase = new TGeoPcon("FMD3 cone base", 0, 180, 6); + const TObjArray& radii = fmd3.ConeRadii(); + TVector3* v1 = 0; + TVector3* v4 = 0; + for (Int_t i = 0; i < radii.GetEntriesFast(); i++) { + TVector3* v = static_cast(radii.At(i)); + coneBase->DefineSection(i, v->X(), v->Y(), v->Z()); + if (i == 1) v1 = v; + if (i == 4) v4 = v; + + } + Double_t holeL = TMath::Sqrt(TMath::Power(v4->Z()-v1->Z(),2) + + TMath::Power(v4->X()-v1->X(),2)); + + TGeoTrd1* coneHole = new TGeoTrd1("F3SC_hole",2,8,conet*3, + (conel-2-2)/2); + + + // Nose volume TGeoTubeSeg* noseShape = new TGeoTubeSeg(noser1, noser2, nlen / 2, 0, 180); TGeoVolume* noseVolume = new TGeoVolume(fgkNoseName, noseShape, fC); @@ -1001,6 +1293,7 @@ AliFMDGeometryBuilder::FMD3Geometry(AliFMD3* fmd3, return 0; } +#endif //____________________________________________________________________ void diff --git a/FMD/AliFMDGeometryBuilder.h b/FMD/AliFMDGeometryBuilder.h index cfffb172246..888a4484e8b 100644 --- a/FMD/AliFMDGeometryBuilder.h +++ b/FMD/AliFMDGeometryBuilder.h @@ -24,6 +24,7 @@ #endif class TGeoVolume; class TGeoMedium; +class TGeoShape; class AliFMD; class AliFMDRing; class AliFMDDetector; @@ -90,6 +91,19 @@ protected: @param r Ring geometry @return Ring volume */ virtual TGeoVolume* RingGeometry(AliFMDRing* r); + + /** Make a honey comb shape from passed parameters. + @param id Detector identifier (1,2, or 3) + @param ring Ring identifier ('I' or 'O') + @param r1 Inner radius + @param r2 Outer radius + @param w width + @param t Thickness of material + @param c Clearing from horizontal. + @return Pointer to newly allocated composite shape. */ + virtual TGeoShape* HoneycombShape(Int_t id, Char_t ring, + double r1, double r2, + double w, double t, double c=0.3); /** Make a detector volume @param d Detector geometry @param motherTop Mother volume (detector volume) diff --git a/FMD/AliFMDRing.h b/FMD/AliFMDRing.h index acb2a53ef4d..f05f8b7d339 100644 --- a/FMD/AliFMDRing.h +++ b/FMD/AliFMDRing.h @@ -67,13 +67,13 @@ public: /** @param x Value of How far the ring extends beyond the z value given. */ void SetRingDepth(Double_t x) { fRingDepth = x; } /** @param x Value of Radius of support legs */ - void SetLegRadius(Double_t x=.5) { fLegRadius = x; } + void SetLegRadius(Double_t x=.2) { fLegRadius = x; } /** @param x Value of Radius of support legs */ void SetLegLength(Double_t x=1) { fLegLength = x; } /** @param x Value of Radius of support legs */ void SetLegOffset(Double_t x=2) { fLegOffset = x; } /** @param x Value of Staggering offset */ - void SetModuleSpacing(Double_t x=1) { fModuleSpacing = x; } + void SetModuleSpacing(Double_t x=.6) { fModuleSpacing = x; } /** @param x Value of Thickness of print board */ void SetPrintboardThickness(Double_t x=.1) { fPrintboardThickness = x; } /** @param x Value of Thickness of copper on print board */ @@ -83,7 +83,7 @@ public: /** @param x Value of spacing between si and PCB */ void SetSpacing(Double_t x=.05) { fSpacing = x; } /** @param x Thickness of honeycomb plate */ - void SetHoneycombThickness(Double_t x=1) { fHoneycombThickness = x; } + void SetHoneycombThickness(Double_t x=0.65) { fHoneycombThickness = x; } /** @param x Thickness of aluminium of honeycomb */ void SetAlThickness(Double_t x=.1) { fAlThickness = x; } diff --git a/FMD/Config.C b/FMD/Config.C index b175e8a1b21..bde0a54d813 100644 --- a/FMD/Config.C +++ b/FMD/Config.C @@ -447,18 +447,21 @@ Config() field->SetL3ConstField(0); //Using const. field in the barrel rl->CdGAFile(); gAlice->SetField(field); + TFile* magF = TFile::Open("mag.root", "RECREATE"); + field->Write("mag"); + magF->Close(); //__________________________________________________________________ // // Used detectors // - Bool_t useABSO = kFALSE; + Bool_t useABSO = kTRUE; Bool_t useACORDE= kFALSE; Bool_t useDIPO = kFALSE; Bool_t useFMD = kTRUE; Bool_t useFRAME = kFALSE; Bool_t useHALL = kFALSE; - Bool_t useITS = kFALSE; + Bool_t useITS = kTRUE; Bool_t useMAG = kFALSE; Bool_t useMUON = kFALSE; Bool_t usePHOS = kFALSE; @@ -466,13 +469,13 @@ Config() Bool_t usePMD = kFALSE; Bool_t useHMPID = kFALSE; Bool_t useSHIL = kFALSE; - Bool_t useT0 = kFALSE; + Bool_t useT0 = kTRUE; Bool_t useTOF = kFALSE; Bool_t useTPC = kFALSE; Bool_t useTRD = kFALSE; Bool_t useZDC = kFALSE; Bool_t useEMCAL = kFALSE; - Bool_t useVZERO = kFALSE; + Bool_t useVZERO = kTRUE; cout << "\t* Creating the detectors ..." << endl; // ================= Alice BODY parameters ========================= diff --git a/FMD/DrawFMD.C b/FMD/DrawFMD.C index f4af85806dd..cbcd7d1ac9b 100644 --- a/FMD/DrawFMD.C +++ b/FMD/DrawFMD.C @@ -3,27 +3,50 @@ @date Mon Mar 27 14:18:21 2006 @brief Script to draw the FMD3 - obsolete */ -void DrawFMD() +void DrawFMD(const char* file="geometry.root", const char* option="ogl") { +#if 1 + AliGeomManager::LoadGeometry(file); + TGeoVolume* top = gGeoManager->GetTopVolume(); + top->InvisibleAll(kTRUE); + for (Int_t i = 1; i <= 3; i++) { + for (Int_t j = 0; j < 2; j++) { + TString name(Form("F%dM%c", i, (j == 0 ? 'T' : 'B'))); + TGeoVolume* v = gGeoManager->FindVolumeFast(name.Data()); + if (!v) { + std::cerr << "FMD" << i << " " + << (j == 0 ? "top" : "bottom") + << " Volume " << name << " not found" << std::endl; + continue; + } + v->InvisibleAll(kFALSE); + v->SetVisDaughters(kTRUE); + v->SetVisLeaves(kTRUE); + } + } + top->Draw(option); + +#else // gSystem->Load("/usr/lib/libshift"); // gSystem->Load("/usr/lib/libgfortran"); gSystem->Load("libgeant321"); gMC = new TGeant3TGeo; - gMC->Gsatt("*", "seen", -1); - gMC->Gsatt("alic", "seen", 0); - gROOT->LoadMacro("FMD/ViewFMD.C"); - gInterpreter->ProcessLine("ViewFMD()"); - gROOT->LoadMacro("ITS/ViewITS.C"); - gInterpreter->ProcessLine("ViewITS()"); - gMC->Gdopt("hide", "on"); - gMC->Gdopt("shad", "on"); - gMC->Gsatt("*", "fill", 7); - gMC->SetClipBox("."); - gMC->SetClipBox("*", 0, 1000, -1000, 1000, -1000, 1000); - gMC->DefaultRange(); - gMC->Gdraw("alic", 40, 30, 0, 12, 12, .055, .055); - gMC->Gdhead(1111, "Forward Multiplicity Detector"); - gMC->Gdman(16, 10, "MAN"); - gPad->Modified(); - gPad->cd(); + gMC->Gsatt("*", "seen", -1); + gMC->Gsatt("alic", "seen", 0); + gROOT->LoadMacro("FMD/ViewFMD.C"); + gInterpreter->ProcessLine("ViewFMD()"); + gROOT->LoadMacro("ITS/ViewITS.C"); + gInterpreter->ProcessLine("ViewITS()"); + gMC->Gdopt("hide", "on"); + gMC->Gdopt("shad", "on"); + gMC->Gsatt("*", "fill", 7); + gMC->SetClipBox("."); + gMC->SetClipBox("*", 0, 1000, -1000, 1000, -1000, 1000); + gMC->DefaultRange(); + gMC->Gdraw("alic", 40, 30, 0, 12, 12, .055, .055); + gMC->Gdhead(1111, "Forward Multiplicity Detector"); + gMC->Gdman(16, 10, "MAN"); + gPad->Modified(); + gPad->cd(); +#endif } diff --git a/FMD/Reconstruct.C b/FMD/Reconstruct.C index e7aa3c0eaf3..1cd8c0185f1 100644 --- a/FMD/Reconstruct.C +++ b/FMD/Reconstruct.C @@ -31,7 +31,12 @@ Reconstruct() // To reconstruct raw data from FDR-I, please enable below lines: // AliFMDParameters::Instance()->UseRcuTrailer(false); // AliFMDParameters::Instance()->UseCompleteHeader(false); - + + TFile* magF = TFile::Open("mag.root", "READ"); + AliMagF* mag = static_cast(magF->Get("mag")); + if (!mag) return; + AliTracker::SetFieldMap(mag, true); + AliReconstruction rec; rec.SetRunLocalReconstruction("FMD"); rec.SetRunVertexFinder(kFALSE); diff --git a/FMD/Simulate.C b/FMD/Simulate.C index 77e79e45f7f..af0d1efc91a 100644 --- a/FMD/Simulate.C +++ b/FMD/Simulate.C @@ -21,7 +21,7 @@ /** Script to do test the FMD digitization class. */ void -Simulate(Int_t n=3) +Simulate(Int_t n=1) { AliSimulation sim; // AliLog::SetModuleDebugLevel("FMD", 1); diff --git a/FMD/scripts/CheckOverlaps.C b/FMD/scripts/CheckOverlaps.C index d9f12bd4fe0..37f80f837fe 100644 --- a/FMD/scripts/CheckOverlaps.C +++ b/FMD/scripts/CheckOverlaps.C @@ -1,9 +1,10 @@ void -CheckOverlaps(Bool_t align=kTRUE, Bool_t sample=kTRUE) +CheckOverlaps(const char* file="geometry.root", + Bool_t align=kFALSE, Bool_t sample=kTRUE) { TObjArray* checked = new TObjArray(); - AliGeomManager::LoadGeometry("geometry.root"); + AliGeomManager::LoadGeometry(file); if (align) AliGeomManager::ApplyAlignObjsToGeom("FMDfullMisalignment.root", "FMDAlignment"); -- 2.43.0