//
#include <TGeoManager.h> // ROOT_TGeoManager
+#include <TGeoPhysicalNode.h> // ROOT_TGeoPhysicalNode
#include <TGeoMatrix.h> // ROOT_TGeoMatrix
#include <TMath.h> // ROOT_TMath
#include "AliFMDDetector.h" // ALIFMDSUBDETECTOR_H
#include "AliFMDRing.h" // ALIFMDRING_H
-#include "AliLog.h" // ALILOG_H
+#include "AliFMDDebug.h" // ALIFMDDEBUG_H ALILOG_H
//====================================================================
ClassImp(AliFMDDetector)
fId(id),
fInnerZ(0.),
fOuterZ(0.),
- fHoneycombThickness(0.),
- fAlThickness(0.),
fInnerHoneyLowR(0.),
fInnerHoneyHighR(0.),
fOuterHoneyLowR(0.),
// INNER Inner ring geometry
// OUTER Outer ring geometry (if any)
//
- SetHoneycombThickness();
- SetAlThickness();
SetInnerHoneyLowR(0);
SetInnerHoneyHighR(0);
SetInnerZ(0);
fId(other.fId),
fInnerZ(0.),
fOuterZ(0.),
- fHoneycombThickness(0.),
- fAlThickness(0.),
fInnerHoneyLowR(0.),
fInnerHoneyHighR(0.),
fOuterHoneyLowR(0.),
fOuterTransforms(other.fOuterTransforms)
{
// Copy constructor
- SetHoneycombThickness(other.GetHoneycombThickness());
- SetAlThickness(other.GetAlThickness());
SetInnerHoneyLowR(other.GetInnerHoneyLowR());
SetInnerHoneyHighR(other.GetInnerHoneyHighR());
SetInnerZ(other.GetInnerZ());
fOuter = other.fOuter;
fInnerTransforms = other.fInnerTransforms;
fOuterTransforms = other.fOuterTransforms;
- SetHoneycombThickness(other.GetHoneycombThickness());
- SetAlThickness(other.GetAlThickness());
SetInnerHoneyLowR(other.GetInnerHoneyLowR());
SetInnerHoneyHighR(other.GetInnerHoneyHighR());
SetInnerZ(other.GetInnerZ());
#define IS_NODE_THIS(name) \
(name[0] == 'F' && name[2] == 'M' && name[1] == Char_t(48+fId) && \
(name[3] == 'T' || name[3] == 'B'))
-#define IS_NODE_SENSOR(name) \
- (name[0] == 'F' && name[2] == 'S' && name[3] == 'E')
+#define IS_NODE_SENSOR(name) \
+ (name[0] == 'F' && (name[2] == 'B' || name[2] == 'F') && name[3] == 'H')
+//#define IS_NODE_SENSOR(name)
+// (name[0] == 'F' && name[2] == 'S' && name[3] == 'E')
#define IS_NODE_HALF(name) \
(name[0] == 'F' && name[2] == 'M' && (name[3] == 'B' || name[3] == 'T'))
+#define HALF_FORMAT "FMD/FMD%d_%c"
+#define SENSOR_FORMAT "FMD/FMD%d_%c/FMD%c_%02d"
//____________________________________________________________________
void
// Find all local<->global transformations for this detector.
if ((!fInner || (fInner && fInnerTransforms)) &&
(!fOuter || (fOuter && fOuterTransforms))) {
- AliDebug(5, Form("Transforms for FMD%d already registered", fId));
+ AliFMDDebug(5, ("Transforms for FMD%d already registered", fId));
return;
}
- AliDebug(5, Form("Initializing transforms for FMD%d", fId));
+ AliFMDDebug(5, ("Initializing transforms for FMD%d", fId));
if (!gGeoManager) {
AliFatal("No TGeoManager defined");
return;
}
- TGeoVolume* topVolume = gGeoManager->GetTopVolume();
- if (!topVolume) {
- AliFatal("No top-level volume defined");
- return;
- }
+
+ // Implementation using alignable volume names.
// Make container of transforms
if (fInner && !fInnerTransforms)
fInnerTransforms = new TObjArray(fInner->GetNModules());
if (fOuter && !fOuterTransforms)
fOuterTransforms = new TObjArray(fOuter->GetNModules());
+ // Loop over rings
+ for (size_t iring = 0; iring < 2; iring++) {
+ char ring = (iring == 0 ? 'I' : 'O');
+ TObjArray* trans = 0;
+ AliFMDRing* r = 0;
+ switch (ring) {
+ case 'I': r = fInner; trans = fInnerTransforms; break;
+ case 'O': r = fOuter; trans = fOuterTransforms; break;
+ }
+ if (!r || !trans) continue;
+
+ Int_t nModules = r->GetNModules();
+ if (nModules <= 0) continue;
+
+ // Loop over bottom/top
+ for (size_t ihalf = 0; ihalf < 2; ihalf++) {
+ char half = (ihalf == 0 ? 'T' : 'B');
+ Int_t base = (half == 'T' ? 0 : nModules / 2);
+
+ // Loop over modules in this half ring
+ for (Int_t imod = 0; imod < nModules / 2; imod++) {
+ // Find physical node entry
+ TString path(Form(SENSOR_FORMAT, fId, half, ring, base+imod));
+ TGeoPNEntry* entry = gGeoManager->GetAlignableEntry(path.Data());
+ if (!entry) {
+ AliError(Form("Alignable entry for sensor \"%s\" not found!",
+ path.Data()));
+ continue;
+ }
+ TGeoPhysicalNode* pn = entry->GetPhysicalNode();
+ if (!pn) {
+ AliWarning(Form("Making physical volume for \"%s\"", path.Data()));
+ pn = gGeoManager->MakeAlignablePN(entry);
+ if (!pn) {
+ AliError(Form("No physical node for \"%s\"", path.Data()));
+ continue;
+ }
+ }
+
+ const TGeoMatrix* pm = pn->GetMatrix();
+ if (!pm) {
+ AliError(Form("No matrix for path \"%s\"", path.Data()));
+ continue;
+ }
+ // Get transformation matrix for this node, and store it.
+ TGeoMatrix* t = new TGeoHMatrix(*pm);
+ trans->AddAt(t, base+imod);
+ AliFMDDebug(5, ("Found matrix for path \"%s\": %p",path.Data(),pm));
+ }
+ }
+ }
+ if (HasAllTransforms('I') && HasAllTransforms('O')) return;
+
+ // Alternative implementation using TGeoIter.
+ TGeoVolume* topVolume = gGeoManager->GetTopVolume();
+ if (!topVolume) {
+ AliFatal("No top-level volume defined");
+ return;
+ }
// Make an iterator
TGeoIterator next(topVolume);
TGeoNode* node = 0;
// Get nodes names
const Char_t* name = node->GetName();
if (!name) continue;
- AliDebug(50, Form("Got volume %s", name));
+ AliFMDDebug(50, ("Got volume %s", name));
// Check if this node is this detector
// The base offset for numbers in the ASCII table is 48
if (IS_NODE_THIS(name)) {
- AliDebug(20, Form("Found detector node '%s' for FMD%d", name, fId));
+ AliFMDDebug(20, ("Found detector node '%s' for FMD%d", name, fId));
thisNodeFound = kTRUE;
}
// if the detector was found, then we're on that branch, and we
// check if this node represents a module in that branch.
if (thisNodeFound && IS_NODE_SENSOR(name)) {
- AliDebug(20, Form("Found sensor node '%s' for FMD%d", name, fId));
+ AliFMDDebug(20, ("Found sensor node '%s' for FMD%d", name, fId));
// Get the ring Id.
Char_t ringid = name[1];
// and if so, go on to the next node.
Bool_t& done = (ring == fInner ? allInners : allOuters);
if ((done = HasAllTransforms(ringid))) {
- AliDebug(20, Form("Already has all module transforms for ring %c",
+ AliFMDDebug(20, ("Already has all module transforms for ring %c",
ringid));
continue;
}
void
AliFMDDetector::SetAlignableVolumes() const
{
- AliDebug(10, Form("Making alignable volumes for FMD%d", fId));
+ // Set alignable volumes.
+ // This will define the alignable volumes.
+ // That is currently, the modules and the half-rings.
+
+ AliFMDDebug(10, ("Making alignable volumes for FMD%d", fId));
if (!gGeoManager) {
AliFatal("No TGeoManager defined");
return;
// Get nodes names
const Char_t* name = node->GetName();
if (!name) continue;
- AliDebug((name[0] == 'F' ? 40 : 50), Form("Got volume %s", name));
+ AliFMDDebug((name[0] == 'F' ? 40 : 50), ("Got volume %s", name));
// Check if this node is this detector
// The base offset for numbers in the ASCII table is 48
if (IS_NODE_THIS(name)) {
- AliDebug(20, Form("Found detector node '%s' for FMD%d", name, fId));
+ AliFMDDebug(20, ("Found detector node '%s' for FMD%d", name, fId));
thisNodeFound = kTRUE;
}
// if a half ring is found, then we're on that branch, and we
// check if this node represents a half ring on that branch
if (thisNodeFound && IS_NODE_HALF(name)) {
- AliDebug(30, Form("Found half node '%s' for FMD%d", name, fId));
+ AliFMDDebug(30, ("Found half node '%s' for FMD%d", name, fId));
// Get the half Id.
thisHalf = name[3];
// Check if we're done
Bool_t done = (thisHalf == 'T' ? hasTop : hasBottom);
if (done) {
- AliDebug(20,Form("Already has all halves for detector %c",name[1]));
+ AliFMDDebug(20, ("Already has all halves for detector %c",name[1]));
continue;
}
// Get the node path
next.GetPath(path);
- align = Form("FMD/FMD%d_%c", fId, thisHalf);
+ align = Form(HALF_FORMAT, fId, thisHalf);
}
// if the detector was found, then we're on that branch, and we
// check if this node represents a module in that branch.
if (thisNodeFound && thisHalf && IS_NODE_SENSOR(name)) {
- AliDebug(30, Form("Found sensor node '%s' for FMD%d", name, fId));
+ AliFMDDebug(30, ("Found sensor node '%s' for FMD%d", name, fId));
// Get the ring Id.
Char_t ringid = name[1];
default: continue;
}
if (done) {
- AliDebug(20,Form("Already has all sensor volumes for ring %c",ringid));
+ AliFMDDebug(20, ("Already has all sensor volumes for ring %c",ringid));
continue;
}
// Get the copy (module) number, and check that it hasn't
Int_t copy = node->GetNumber();
next.GetPath(path);
// path.Replace("ALIC", "/ALIC_1");
- align = Form("FMD/FMD%d_%c/FMD%c_%02d", fId, thisHalf, ringid, copy);
+ align = Form(SENSOR_FORMAT, fId, thisHalf, ringid, copy);
switch (ringid) {
case 'I': iInnerSensor++; break;
}
}
if (!align.IsNull() && !path.IsNull()) {
- AliDebug(20, Form("Got %s -> %s", path.Data(), align.Data()));
+ AliFMDDebug(20, ("Got %s -> %s", path.Data(), align.Data()));
TGeoPNEntry* entry =
gGeoManager->SetAlignableEntry(align.Data(),path.Data());
if(!entry)
#endif
align = "";
}
- AliDebug(20, Form("FMD%d: top: %d bottom: %d Inner: %d/%d Outer %d/%d",
+ AliFMDDebug(20, ("FMD%d: top: %d bottom: %d Inner: %d/%d Outer %d/%d",
fId, hasTop, hasBottom, iInnerSensor, nInnerSensor,
iOuterSensor, nOuterSensor));
}
// Translate detector coordinates (this,ring,sector,strip) into
// (x,y,z) coordinates (in global reference frame)
AliFMDRing* r = GetRing(ring);
- if (!r) return;
+ if (!r) {
+ AliWarning(Form("No such ring FMD%d%c ", fId, ring));
+ return;
+ }
TGeoMatrix* m = FindTransform(ring, sector);
- if (!m) return;
+ if (!m) {
+ AliWarning(Form("No transfrmation found for FMD%d%c[%02d]",
+ fId, ring, sector));
+ return;
+ }
Double_t rho = r->GetStripRadius(strip);
Double_t phi = ((sector % 2) - .5) * r->GetTheta();
Double_t siThick = r->GetSiThickness();
+#if 0
Double_t modThick = (siThick
+ r->GetPrintboardThickness()
+ r->GetCopperThickness()
+ r->GetChipThickness()
+ r->GetSpacing());
- AliDebug(30,Form("Rho %7.3f, angle %7.3f", rho, phi));
-# define DEGRAD TMath::Pi() / 180.
- Double_t local[] = { rho * TMath::Cos(phi * DEGRAD),
- rho * TMath::Sin(phi * DEGRAD),
- -modThick + siThick / 2 };
+#endif
+ AliFMDDebug(30, ("Rho %7.3f, angle %7.3f", rho, phi));
+ Double_t local[] = { rho * TMath::Cos(phi * TMath::DegToRad()),
+ rho * TMath::Sin(phi * TMath::DegToRad()),
+ /* -modThick + */ siThick / 2 };
Double_t master[3];
- AliDebug(30, Form("Local (%7.3f,%7.3f,%7.3f)",local[0], local[1], local[2]));
+ AliFMDDebug(30, ("Local (%7.3f,%7.3f,%7.3f)",local[0], local[1], local[2]));
m->LocalToMaster(local, master);
- AliDebug(30, Form("Master (%7.3f,%7.3f,%7.3f)",
+ AliFMDDebug(30, ("Master (%7.3f,%7.3f,%7.3f)",
master[0],master[1],master[2]));
x = master[0];
y = master[1];