38 #include <TGeoManager.h> 39 #include <TGeoPhysicalNode.h> 40 #include <TGeoMatrix.h> 55 : TNamed(Form(
"FMD%d", id),
"Forward multiplicity ring"),
111 if (&other ==
this)
return *
this;
112 SetName(other.GetName());
113 SetTitle(other.GetTitle());
150 if (!r)
return kTRUE;
152 if (!matricies)
return kTRUE;
153 if (matricies->GetEntries() == r->
GetNModules())
return kTRUE;
157 #define IS_NODE_THIS(name) \ 158 (name[0] == 'F' && name[2] == 'M' && name[1] == Char_t(48+fId) && \ 159 (name[3] == 'T' || name[3] == 'B')) 160 #define IS_NODE_SENSOR(name) \ 161 (name[0] == 'F' && (name[2] == 'B' || name[2] == 'F') && name[3] == 'H') 164 #define IS_NODE_HALF(name) \ 165 (name[0] == 'F' && name[2] == 'M' && (name[3] == 'B' || name[3] == 'T')) 166 #define HALF_FORMAT "FMD/FMD%d_%c" 167 #define SENSOR_FORMAT "FMD/FMD%d_%c/FMD%c_%02d" 193 for (
size_t ihalf = 0; ihalf < 2; ihalf++) {
194 char half = (ihalf == 0 ?
'T' :
'B');
196 TGeoPNEntry* entry =
gGeoManager->GetAlignableEntry(path.Data());
198 AliError(Form(
"Alignable entry for half-detector \"%s\" not found!",
202 TGeoPhysicalNode* pn = entry->GetPhysicalNode();
204 AliWarning(Form(
"Making physical volume for \"%s\"", path.Data()));
207 AliError(Form(
"No physical node for \"%s\"", path.Data()));
214 for (
size_t iring = 0; iring < 2; iring++) {
215 char ring = (iring == 0 ?
'I' :
'O');
222 if (!r || !trans)
continue;
225 if (nModules <= 0)
continue;
228 for (
size_t ihalf = 0; ihalf < 2; ihalf++) {
229 char half = (ihalf == 0 ?
'T' :
'B');
230 Int_t base = (half ==
'T' ? 0 : nModules / 2);
233 for (Int_t imod = 0; imod < nModules / 2; imod++) {
236 TGeoPNEntry* entry =
gGeoManager->GetAlignableEntry(path.Data());
238 AliError(Form(
"Alignable entry for sensor \"%s\" not found!",
242 TGeoPhysicalNode* pn = entry->GetPhysicalNode();
244 AliWarning(Form(
"Making physical volume for \"%s\"", path.Data()));
247 AliError(Form(
"No physical node for \"%s\"", path.Data()));
252 const TGeoMatrix* pm = pn->GetMatrix();
254 AliError(Form(
"No matrix for path \"%s\"", path.Data()));
258 TGeoMatrix* t =
new TGeoHMatrix(*pm);
259 trans->AddAt(t, base+imod);
260 AliFMDDebug(5, (
"Found matrix for path \"%s\": %p",path.Data(),pm));
267 TGeoVolume* topVolume =
gGeoManager->GetTopVolume();
269 AliFatal(
"No top-level volume defined");
273 TGeoIterator next(topVolume);
278 Bool_t thisNodeFound = kFALSE;
282 while ((node = static_cast<TGeoNode*>(next()))
283 && !(allInners && allOuters)) {
285 const Char_t* name = node->GetName();
291 AliFMDDebug(20, (
"Found detector node '%s' for FMD%d", name,
fId));
292 thisNodeFound = kTRUE;
299 Char_t ringid = name[1];
307 Bool_t& done = (ring ==
fInner ? allInners : allOuters);
309 AliFMDDebug(20, (
"Already has all module transforms for ring %c",
315 TObjArray* matricies = (ringid ==
'i' || ringid ==
'I' 320 Int_t copy = node->GetNumber();
321 if (matricies->At(copy)) {
322 AliWarning(Form(
"Have a transformation for module %d in ring %c",
328 TGeoMatrix*
trans =
new TGeoHMatrix(*(next.GetCurrentMatrix()));
329 matricies->AddAt(trans, copy);
348 TGeoVolume* topVolume =
gGeoManager->GetTopVolume();
350 AliFatal(
"No top-level volume defined");
355 TGeoIterator next(topVolume);
356 next.Reset(topVolume);
357 next.SetTopName(Form(
"/%s_1", topVolume->GetName()));
364 Bool_t thisNodeFound = kFALSE;
365 Char_t thisHalf =
'\0';
366 Int_t iInnerSensor = 0;
367 Int_t iOuterSensor = 0;
368 Bool_t hasTop =
false;
369 Bool_t hasBottom =
false;
372 while ((node = static_cast<TGeoNode*>(next()))
373 && (iInnerSensor < nInnerSensor || iOuterSensor < nOuterSensor
374 || !hasBottom || !hasTop)) {
376 const Char_t* name = node->GetName();
378 AliFMDDebug((name[0] ==
'F' ? 40 : 50), (
"Got volume %s", name));
382 AliFMDDebug(20, (
"Found detector node '%s' for FMD%d", name,
fId));
383 thisNodeFound = kTRUE;
394 Bool_t done = (thisHalf ==
'T' ? hasTop : hasBottom);
396 AliFMDDebug(20, (
"Already has all halves for detector %c",name[1]));
401 case 'T': hasTop =
true;
break;
402 case 'B': hasBottom =
true;
break;
404 AliWarning(Form(
"Unknown part '%c' of FMD%d", thisHalf,
fId));
418 Char_t ringid = name[1];
429 case 'I': done = iInnerSensor >= nInnerSensor;
break;
430 case 'O': done = iOuterSensor >= nOuterSensor;
break;
434 AliFMDDebug(20, (
"Already has all sensor volumes for ring %c",ringid));
439 Int_t copy = node->GetNumber();
445 case 'I': iInnerSensor++;
break;
446 case 'O': iOuterSensor++;
break;
449 if (!align.IsNull() && !path.IsNull()) {
450 AliFMDDebug(20, (
"Got %s -> %s", path.Data(), align.Data()));
452 gGeoManager->SetAlignableEntry(align.Data(),path.Data());
454 AliFatal(Form(
"Alignable entry %s not created. " 455 "Volume path %s not valid",
456 align.Data(),path.Data()));
457 #ifdef MAKE_ALIGNABLE_PHYSICAL 458 TGeoPhysicalNode* phys =
gGeoManager->MakeAlignablePN(entry);
460 AliWarning(Form(
"Physical node entry %s not created. " 461 "Volume path %s not valid",
462 align.Data(),path.Data()));
466 AliFMDDebug(20, (
"FMD%d: top: %d bottom: %d Inner: %d/%d Outer %d/%d",
467 fId, hasTop, hasBottom, iInnerSensor, nInnerSensor,
468 iOuterSensor, nOuterSensor));
523 UInt_t module = sector / 2;
524 TGeoMatrix* m =
static_cast<TGeoMatrix*
>(matricies->At(module));
526 AliWarning(Form(
"No matrix found for sector %d in FMD%d%c",
552 AliWarning(Form(
"No transfrmation found for FMD%d%c[%02d]",
557 Double_t phi = ((sector % 2) - .5) * r->
GetTheta();
560 Double_t modThick = (siThick
566 AliFMDDebug(30, (
"Rho %7.3f, angle %7.3f", rho, phi));
567 Double_t local[] = { rho * TMath::Cos(phi * TMath::DegToRad()),
568 rho * TMath::Sin(phi * TMath::DegToRad()),
571 AliFMDDebug(30, (
"Local (%7.3f,%7.3f,%7.3f)",local[0], local[1], local[2]));
572 m->LocalToMaster(local, master);
574 master[0],master[1],master[2]));
587 UShort_t& strip)
const 593 for (
int j = 0; j < 2; j++) {
594 rng =
GetRing(j == 0 ?
'I' :
'O');
596 Double_t ringZ =
GetRingZ(j == 0 ?
'I' :
'O');
598 if (TMath::Abs(z - ringZ) < 0.01 ||
599 TMath::Abs(z - ringZ + modSpace) < 0.01)
break;
Double_t GetOuterZ() const
#define IS_NODE_THIS(name)
Bool_t HasAllTransforms(Char_t ring) const
AliFMDRing * GetInner() const
AliFMDDetector(Int_t id, AliFMDRing *inner, AliFMDRing *outer)
Double_t GetInnerHoneyHighR() const
AliFMDRing * GetOuter() const
Double_t GetHighR() const
Double_t GetInnerZ() const
Double_t GetChipThickness() const
FMD ring geometry parameters.
Double_t GetCopperThickness() const
void Detector2XYZ(Char_t ring, UShort_t sector, UShort_t strip, Double_t &x, Double_t &y, Double_t &z) const
AliFMDRing * GetRing(Char_t id) const
Double_t GetSpacing() const
Base class for the geometry description and parameters of the FMD sub detectors FMD1, FMD2, and FMD3.
Double_t GetStripRadius(UShort_t strip) const
TObjArray * fInnerTransforms
#define AliWarning(message)
Double_t GetSiThickness() const
TGeoMatrix * FindTransform(Char_t ring, UShort_t sector) const
Double_t fInnerHoneyHighR
Double_t fOuterHoneyHighR
bool trans(const AliFMDIndex &x, const AliFMDIndex &y, const AliFMDIndex &z)
Double_t GetRingZ(Char_t id) const
void SetOuterHoneyHighR(Double_t x)
Int_t GetNModules() const
TGeoManager * gGeoManager
#define IS_NODE_HALF(name)
#define AliFMDDebug(N, A)
void SetOuterZ(Double_t x)
void SetInnerHoneyLowR(Double_t x)
Double_t GetPrintboardThickness() const
#define AliFatal(message)
AliFMDDetector & operator=(const AliFMDDetector &other)
TObjArray * fOuterTransforms
void SetOuterHoneyLowR(Double_t x)
#define IS_NODE_SENSOR(name)
void SetInnerHoneyHighR(Double_t x)
Double_t GetOuterHoneyHighR() const
Bool_t XYZ2Detector(Double_t x, Double_t y, Double_t z, Char_t &ring, UShort_t §or, UShort_t &strip) const
virtual void SetAlignableVolumes() const
Double_t GetTheta() const
Geometry description and parameters of a ring in the FMD detector.
Bool_t XYZ2Detector(Double_t x, Double_t y, Double_t z, UShort_t §or, UShort_t &strip) const
Double_t GetOuterHoneyLowR() const
#define AliError(message)
Double_t GetModuleSpacing() const
virtual void InitTransformations()
Sub-detector base class declaration.
void SetInnerZ(Double_t x)
Double_t GetInnerHoneyLowR() const