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);
}
// Support will be simple compared to FMD3.
//
#include "AliFMD2.h" // ALIFMD2_H
+#include "AliLog.h"
// #include "AliFMDRing.h" // ALIFMDRING_H
//====================================================================
: 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);
}
#include "AliFMD3.h" // ALIFMD3_H
#include "AliFMDDebug.h" // ALIFMDDEBUG_H ALILOG_H
#include "AliFMDRing.h" // ALIFMDRING_H
+#include <TVector3.h>
//====================================================================
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));
}
//____________________________________________________________________
{
// 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<TVector3*>(fConeRadii.At(0)));
+ TVector3& v1 = *(static_cast<TVector3*>(fConeRadii.At(1)));
+ TVector3& v2 = *(static_cast<TVector3*>(fConeRadii.At(2)));
+ TVector3& v3 = *(static_cast<TVector3*>(fConeRadii.At(3)));
+ TVector3& v4 = *(static_cast<TVector3*>(fConeRadii.At(4)));
+ TVector3& v5 = *(static_cast<TVector3*>(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));
}
//____________________________________________________________________
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<TVector3*>(fConeRadii.At(0)));
+ TVector3& v1 = *(static_cast<TVector3*>(fConeRadii.At(1)));
+ TVector3& v2 = *(static_cast<TVector3*>(fConeRadii.At(2)));
+ TVector3& v3 = *(static_cast<TVector3*>(fConeRadii.At(3)));
+ TVector3& v4 = *(static_cast<TVector3*>(fConeRadii.At(4)));
+ TVector3& v5 = *(static_cast<TVector3*>(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);
}
#ifndef ALIFMDDETECTOR_H
# include "AliFMDDetector.h"
#endif
+#include <TObjArray.h>
/** @class AliFMD3 AliFMD3.h <FMD/AliFMD3.h>
@brief Geometry parameters of the FMD3 detector.
/** 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
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
#include <TGeoCone.h> // ROOT_TGeoTrd1
#include <TGeoVolume.h> // ROOT_TGeoVolume
#include <TGeoXtru.h> // ROOT_TGeoXtru
+#include <TGeoPcon.h> // ROOT_TGeoPcon
#include <TGeoCompositeShape.h>
#include <TMath.h>
#include <TVector2.h> // ROOT_TVector2
+#include <TVector3.h> // ROOT_TVector3
//#include <TGeoMaterial.h> // ROOT_TGeoMaterial
//#include <TGeoMedium.h> // ROOT_TGeoMedium
//#include <TGeoPcon.h> // ROOT_TGeoPcon
#include "AliFMD3.h" // ALIFMD3_H
// #include "AliFMD.h" // ALIFMD_H
#include "AliFMDDebug.h" // ALILOG_H
+#include <iostream>
//====================================================================
ClassImp(AliFMDGeometryBuilder)
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,
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() +
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;
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()),
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<TVector3*>(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<TVector2*>(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,
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<TVector3*>(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);
return 0;
}
+#endif
//____________________________________________________________________
void
#endif
class TGeoVolume;
class TGeoMedium;
+class TGeoShape;
class AliFMD;
class AliFMDRing;
class AliFMDDetector;
@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)
/** @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 */
/** @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; }
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;
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 =========================
@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
}
// 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<AliMagF*>(magF->Get("mag"));
+ if (!mag) return;
+ AliTracker::SetFieldMap(mag, true);
+
AliReconstruction rec;
rec.SetRunLocalReconstruction("FMD");
rec.SetRunVertexFinder(kFALSE);
/** 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);
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");