X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;f=FMD%2FAliFMD.cxx;h=1bc97d3014a17d16d4deb3241a07246e4950ebe4;hb=3915b9ac5b5b5750c531a753331c04187ea9905a;hp=2dd5a4bbdbb47c03ee93c49eec12749489f5b57c;hpb=42403906a791989192b0a7f2f5fda18146e5455c;p=u%2Fmrichter%2FAliRoot.git diff --git a/FMD/AliFMD.cxx b/FMD/AliFMD.cxx index 2dd5a4bbdbb..1bc97d3014a 100644 --- a/FMD/AliFMD.cxx +++ b/FMD/AliFMD.cxx @@ -12,51 +12,52 @@ * about the suitability of this software for any purpose. It is * * provided "as is" without express or implied warranty. * **************************************************************************/ - /* $Id$ */ - -////////////////////////////////////////////////////////////////////////////// +/** @file AliFMD.cxx + @author Christian Holm Christensen + @date Sun Mar 26 17:59:18 2006 + @brief Implementation of AliFMD base class +*/ +//____________________________________________________________________ // // Forward Multiplicity Detector based on Silicon wafers. This class -// contains the base procedures for the Forward Multiplicity detector -// Detector consists of 5 Si volumes covered pseudorapidity interval -// from 1.7 to 5.1. +// is the driver for especially simulation. +// +// The Forward Multiplicity Detector consists of 3 sub-detectors FMD1, +// FMD2, and FMD3, each of which has 1 or 2 rings of silicon sensors. // // This is the base class for all FMD manager classes. // // The actual code is done by various separate classes. Below is // diagram showing the relationship between the various FMD classes -// that handles the geometry +// that handles the simulation // // // +----------+ +----------+ -// | AliFMDv1 | | AliFMDv1 | +// | AliFMDv1 | | AliFMDv0 | // +----------+ +----------+ -// | | -// +----+--------------+ -// | -// | +------------+ 1 +---------------+ -// | +- | AliFMDRing |<>--| AliFMDPolygon | -// V 2 | +------------+ +---------------+ -// +--------+<>--+ | -// | AliFMD | ^ -// +--------+<>--+ V 1..2 -// 3 | +-------------------+ -// +-| AliFMDSubDetector | -// +-------------------+ -// ^ -// | -// +-------------+-------------+ -// | | | -// +---------+ +---------+ +---------+ -// | AliFMD1 | | AliFMD2 | | AliFMD3 | -// +---------+ +---------+ +---------+ -// +// | | +-----------------+ +// +----+--------------+ +--| AliFMDDigitizer | +// | | +-----------------+ +// | +---------------------+ | +// | +--| AliFMDBaseDigitizer |<--+ +// V 1 | +---------------------+ | +// +--------+<>--+ | +------------------+ +// | AliFMD | +--| AliFMDSDigitizer | +// +--------+<>--+ +------------------+ +// 1 | +---------------------+ +// +--| AliFMDReconstructor | +// +---------------------+ // // * AliFMD // This defines the interface for the various parts of AliROOT that -// uses the FMD, like AliFMDDigitizer, AliFMDReconstructor, and so -// on. +// uses the FMD, like AliFMDSimulator, AliFMDDigitizer, +// AliFMDReconstructor, and so on. +// +// * AliFMDv0 +// This is a concrete implementation of the AliFMD interface. +// It is the responsibility of this class to create the FMD +// geometry. // // * AliFMDv1 // This is a concrete implementation of the AliFMD interface. @@ -64,142 +65,105 @@ // geometry, process hits in the FMD, and serve hits and digits to // the various clients. // -// It uses the objects of class AliFMDSubDetector to do the various -// stuff for FMD1, 2, and 3 -// -// * AliFMDRing -// This class contains all stuff needed to do with a ring. It's -// used by the AliFMDSubDetector objects to instantise inner and -// outer rings. The AliFMDRing objects are shared by the -// AliFMDSubDetector objects, and owned by the AliFMDv1 object. -// -// * AliFMDPolygon -// The code I lifted from TGeoPolygon to help with the geometry of -// the modules, as well as to decide wether a hit is actually with -// in the real module shape. The point is, that the shape of the -// various ring modules are really polygons (much like the lid of a -// coffin), but it's segmented at constant radius. That is very -// hard to implement using GEANT 3.21 shapes, so instead the -// modules are implemented as TUBS (tube sections), and in the step -// procedure we do the test whether the track was inside the real -// shape of the module. -// -// * AliFMD1, AliFMD2, and AliFMD3 -// These are specialisation of AliFMDSubDetector, that contains the -// particularities of each of the sub-detector system. It is -// envisioned that the classes should also define the support -// volumes and material for each of the detectors. +// * AliFMDSimulator +// This is the base class for the FMD simulation tasks. The +// simulator tasks are responsible to implment the geoemtry, and +// process hits. // -// The responsible person for this module is Alla Maevskaia -// . +// * AliFMDReconstructor +// This is a concrete implementation of the AliReconstructor that +// reconstructs pseudo-inclusive-multiplicities from digits (raw or +// from simulation) // -// Many modifications by Christian Holm Christensen +// Calibration and geometry parameters are managed by separate +// singleton managers. These are AliFMDGeometry and +// AliFMDParameters. Please refer to these classes for more +// information on these. // -#ifndef ROOT_TClonesArray -#include -#endif -#ifndef ROOT_TGeomtry -# include -#endif -#ifndef ROOT_TNode -# include -#endif -#ifndef ROOT_TTUBE -# include -#endif -#ifndef ROOT_TTree -# include -#endif -#ifndef ROOT_TVirtualMC -# include -#endif -#ifndef ROOT_TBrowser -# include -#endif -#ifndef ROOT_TMath -# include -#endif - -#ifndef ALIRUNDIGITIZER_H -# include "AliRunDigitizer.h" -#endif -#ifndef ALILOADER_H -# include "AliLoader.h" -#endif -#ifndef ALIRUN_H -# include "AliRun.h" -#endif -#ifndef ALIMC_H -# include "AliMC.h" -#endif -#ifndef ALILOG_H -# include "AliLog.h" -#endif -#ifndef ALIMAGF_H -# include "AliMagF.h" -#endif -#ifndef ALIFMD_H -# include "AliFMD.h" -#endif -#ifndef ALIFMDDIGIG_H -# include "AliFMDDigit.h" -#endif -#ifndef ALIFMDHIT_H -# include "AliFMDHit.h" -#endif -#ifndef ALIFMDDIGITIZER_H -# include "AliFMDDigitizer.h" -#endif -#ifndef ALIFMD1_H -# include "AliFMD1.h" -#endif -#ifndef ALIFMD2_H -# include "AliFMD2.h" -#endif -#ifndef ALIFMD3_H -# include "AliFMD3.h" -#endif -#ifndef ALIALTROBUFFER_H -# include "AliAltroBuffer.h" -#endif +// These files are not in the same directory, so there's no reason to +// ask the preprocessor to search in the current directory for these +// files by including them with `#include "..."' +#include // ROOT_TBrowser +#include // ROOT_TClonesArray +#include // ROOT_TGeoGlobalMagField +#include // ROOT_TGeoManager +#include // ROOT_TRotMatrix +#include // ROOT_TTree +#include // ROOT_TVector2 +#include // ROOT_TVirtualMC +#include // __CMATH__ + +#include // ALIRUNDIGITIZER_H +#include // ALILOADER_H +#include // ALIRUN_H +#include // ALIMC_H +#include // ALIMAGF_H +// #include // ALILOG_H +#include "AliFMDDebug.h" // Better debug macros +#include "AliFMD.h" // ALIFMD_H +#include "AliFMDDigit.h" // ALIFMDDIGIT_H +#include "AliFMDSDigit.h" // ALIFMDSDIGIT_H +#include "AliFMDHit.h" // ALIFMDHIT_H +#include "AliFMDGeometry.h" // ALIFMDGEOMETRY_H +#include "AliFMDDetector.h" // ALIFMDDETECTOR_H +#include "AliFMDRing.h" // ALIFMDRING_H +#include "AliFMDDigitizer.h" // ALIFMDDIGITIZER_H +#include "AliFMDHitDigitizer.h" // ALIFMDSDIGITIZER_H +// #define USE_SSDIGITIZER +//#ifdef USE_SSDIGITIZER +//# include "AliFMDSSDigitizer.h" // ALIFMDSDIGITIZER_H +//#endif +// #include "AliFMDGeometryBuilder.h" +#include "AliFMDRawWriter.h" // ALIFMDRAWWRITER_H +#include "AliFMDRawReader.h" // ALIFMDRAWREADER_H +#include "AliTrackReference.h" +#include "AliFMDStripIndex.h" +#include "AliFMDParameters.h" +#include "AliFMDReconstructor.h" //____________________________________________________________________ -ClassImp(AliFMD); +ClassImp(AliFMD) +#if 0 + ; // This is to keep Emacs from indenting the next line +#endif //____________________________________________________________________ AliFMD::AliFMD() - : fInner(0), - fOuter(0), - fFMD1(0), - fFMD2(0), - fFMD3(0) + : AliDetector(), + fSDigits(0), + fNsdigits(0), + fDetailed(kTRUE), + fUseOld(kFALSE), + fUseAssembly(kTRUE), + fBad(0) { // // Default constructor for class AliFMD // - AliDebug(0, "Default CTOR"); - fHits = 0; - fDigits = 0; - fSDigits = 0; - fNsdigits = 0; - fIshunt = 0; + AliFMDDebug(10, ("\tDefault CTOR")); + fHits = 0; + fDigits = 0; + fIshunt = 0; + fBad = new TClonesArray("AliFMDHit"); } //____________________________________________________________________ -AliFMD::AliFMD(const char *name, const char *title, bool detailed) +AliFMD::AliFMD(const char *name, const char *title) : AliDetector (name, title), - fInner(0), - fOuter(0), - fFMD1(0), - fFMD2(0), - fFMD3(0) + fSDigits(0), + fNsdigits(0), + fDetailed(kTRUE), + fUseOld(kFALSE), + fUseAssembly(kFALSE), + fBad(0) { // // Standard constructor for Forward Multiplicity Detector // - AliDebug(0, "Standard CTOR"); - + AliFMDDebug(10, ("\tStandard CTOR")); + fBad = new TClonesArray("AliFMDHit"); + // Initialise Hit array HitsArray(); gAlice->GetMCApp()->AddHitList(fHits); @@ -210,61 +174,8 @@ AliFMD::AliFMD(const char *name, const char *title, bool detailed) // CHC: What is this? fIshunt = 0; - SetMarkerColor(kRed); - SetLineColor(kYellow); - SetSiDensity(); - - // Create sub-volume managers - fInner = new AliFMDRing('I', detailed); - fOuter = new AliFMDRing('O', detailed); - fFMD1 = new AliFMD1(); - fFMD2 = new AliFMD2(); - fFMD3 = new AliFMD3(); - - // Specify parameters of sub-volume managers - fFMD1->SetInner(fInner); - fFMD1->SetOuter(0); - - fFMD2->SetInner(fInner); - fFMD2->SetOuter(fOuter); - - fFMD3->SetInner(fInner); - fFMD3->SetOuter(fOuter); - - SetLegLength(); - SetLegRadius(); - SetLegOffset(); - SetModuleSpacing(); - - fInner->SetLowR(4.3); - fInner->SetHighR(17.2); - fInner->SetWaferRadius(13.4/2); - fInner->SetTheta(36/2); - fInner->SetNStrips(512); - fInner->SetSiThickness(.03); - fInner->SetPrintboardThickness(.11); - fInner->SetBondingWidth(.5); - - fOuter->SetLowR(15.6); - fOuter->SetHighR(28.0); - fOuter->SetWaferRadius(13.4/2); - fOuter->SetTheta(18/2); - fOuter->SetNStrips( 256); - fOuter->SetSiThickness(.03); - fOuter->SetPrintboardThickness(.1); - fOuter->SetBondingWidth(.5); - - - fFMD1->SetHoneycombThickness(1); - fFMD1->SetInnerZ(340.0); - - fFMD2->SetHoneycombThickness(1); - fFMD2->SetInnerZ(83.4); - fFMD2->SetOuterZ(75.2); - - fFMD3->SetHoneycombThickness(1); - fFMD3->SetInnerZ(-62.8); - fFMD3->SetOuterZ(-75.2); + //PH SetMarkerColor(kRed); + //PH SetLineColor(kYellow); } //____________________________________________________________________ @@ -286,8 +197,14 @@ AliFMD::~AliFMD () delete fSDigits; fSDigits = 0; } + if (fBad) { + fBad->Delete(); + delete fBad; + fBad = 0; + } } + //==================================================================== // // GEometry ANd Traking @@ -298,96 +215,58 @@ AliFMD::CreateGeometry() { // // Create the geometry of Forward Multiplicity Detector. The actual - // construction of the geometry is delegated to the class AliFMDRing - // and AliFMDSubDetector and the relevant derived classes. + // construction of the geometry is delegated to the class + // AliFMDGeometryBuilder, invoked by the singleton manager + // AliFMDGeometry. // - // The flow of this member function is: - // - // FOR rings fInner and fOuter DO - // AliFMDRing::Init(); - // END FOR - // - // Set up hybrud card support (leg) volume shapes - // - // FOR rings fInner and fOuter DO - // AliFMDRing::SetupGeometry(); - // END FOR - // - // FOR subdetectors fFMD1, fFMD2, and fFMD3 DO - // AliFMDSubDetector::SetupGeomtry(); - // END FOR - // - // FOR subdetectors fFMD1, fFMD2, and fFMD3 DO - // AliFMDSubDetector::Geomtry(); - // END FOR - // - - // DebugGuard guard("AliFMD::CreateGeometry"); - AliDebug(10, "Creating geometry"); - - fInner->Init(); - fOuter->Init(); - - TString name; - Double_t par[3]; - - par[0] = fLegRadius - .1; - par[1] = fLegRadius; - par[2] = fLegLength / 2; - name = "FSL"; - fShortLegId = gMC->Gsvolu(name.Data(),"TUBE",(*fIdtmed)[kPlasticId],par,3); - - par[2] += fModuleSpacing / 2; - name = "FLL"; - fLongLegId = gMC->Gsvolu(name.Data(),"TUBE",(*fIdtmed)[kPlasticId],par,3); - - fInner->SetupGeometry((*fIdtmed)[kAirId], - (*fIdtmed)[kSiId], - (*fIdtmed)[kPcbId], - fPrintboardRotationId, - fIdentityRotationId); - fOuter->SetupGeometry((*fIdtmed)[kAirId], - (*fIdtmed)[kSiId], - (*fIdtmed)[kPcbId], - fPrintboardRotationId, - fIdentityRotationId); - - fFMD1->SetupGeometry((*fIdtmed)[kAirId], (*fIdtmed)[kKaptionId]); - fFMD2->SetupGeometry((*fIdtmed)[kAirId], (*fIdtmed)[kKaptionId]); - fFMD3->SetupGeometry((*fIdtmed)[kAirId], (*fIdtmed)[kKaptionId]); - - fFMD1->Geometry("ALIC", fPrintboardRotationId, fIdentityRotationId); - fFMD2->Geometry("ALIC", fPrintboardRotationId, fIdentityRotationId); - fFMD3->Geometry("ALIC", fPrintboardRotationId, fIdentityRotationId); + AliFMDGeometry* fmd = AliFMDGeometry::Instance(); + fmd->SetDetailed(fDetailed); + fmd->UseAssembly(fUseAssembly); + fmd->Build(); } //____________________________________________________________________ void AliFMD::CreateMaterials() { - // Register various materials and tracking mediums with the - // backend. + // Define the materials and tracking mediums needed by the FMD + // simulation. These mediums are made by sending the messages + // AliMaterial, AliMixture, and AliMedium to the passed AliModule + // object module. The defined mediums are // - // Currently defined materials and mediums are - // - // FMD Air Normal air - // FMD Si Active silicon of sensors - // FMD Carbon Normal carbon used in support, etc. - // FMD Kapton Carbon used in Honeycomb - // FMD PCB Printed circuit board material - // FMD Plastic Material for support legs - // - // Also defined are two rotation matricies. + // FMD Si$ Silicon (active medium in sensors) + // FMD C$ Carbon fibre (support cone for FMD3 and vacuum pipe) + // FMD Al$ Aluminium (honeycomb support plates) + // FMD PCB$ Printed Circuit Board (FEE board with VA1_3) + // FMD Chip$ Electronics chips (currently not used) + // FMD Air$ Air (Air in the FMD) + // FMD Plastic$ Plastic (Support legs for the hybrid cards) + // + // The geometry builder should really be the one that creates the + // materials, but the architecture of AliROOT makes that design + // akward. What should happen, was that the AliFMDGeometryBuilder + // made the mediums, and that this class retrives pointers from the + // TGeoManager, and registers the mediums here. Alas, it's not + // really that easy. // - // DebugGuard guard("AliFMD::CreateMaterials"); - AliDebug(10, "Creating materials"); + AliFMDDebug(10, ("\tCreating materials")); + // Get pointer to geometry singleton object. + AliFMDGeometry* geometry = AliFMDGeometry::Instance(); + geometry->Init(); +#if 0 + if (gGeoManager && gGeoManager->GetMedium("FMD Si$")) { + // We need to figure out the some stuff about the geometry + fmd->ExtractGeomInfo(); + return; + } +#endif Int_t id; Double_t a = 0; Double_t z = 0; Double_t density = 0; Double_t radiationLength = 0; Double_t absorbtionLength = 999; - Int_t fieldType = gAlice->Field()->Integ(); // Field type - Double_t maxField = gAlice->Field()->Max(); // Field max. + Int_t fieldType = ((AliMagF*)TGeoGlobalMagField::Instance()->GetField())->Integ(); // Field type + Double_t maxField = ((AliMagF*)TGeoGlobalMagField::Instance()->GetField())->Max(); // Field max. Double_t maxBending = 0; // Max Angle Double_t maxStepSize = 0.001; // Max step size Double_t maxEnergyLoss = 1; // Max Delta E @@ -397,17 +276,17 @@ void AliFMD::CreateMaterials() // Silicon a = 28.0855; z = 14.; - density = fSiDensity; + density = geometry->GetSiDensity(); radiationLength = 9.36; maxBending = 1; maxStepSize = .001; precision = .001; minStepSize = .001; id = kSiId; - AliMaterial(id, "FMD Si$", a, z, density, radiationLength, absorbtionLength); - AliMedium(kSiId, "FMD Si$",id,1,fieldType,maxField,maxBending, + AliMaterial(id, "Si$", a, z, density, radiationLength, absorbtionLength); + AliMedium(kSiId, "Si$", id,1,fieldType,maxField,maxBending, maxStepSize,maxEnergyLoss,precision,minStepSize); - + // Carbon a = 12.011; @@ -419,32 +298,53 @@ void AliFMD::CreateMaterials() precision = .003; minStepSize = .003; id = kCarbonId; - AliMaterial(id, "FMD Carbon$", a, z, density, radiationLength, - absorbtionLength); - AliMedium(kCarbonId, "FMD Carbon$",id,0,fieldType,maxField,maxBending, - maxStepSize,maxEnergyLoss,precision,minStepSize); + AliMaterial(id, "Carbon$", a, z, density, radiationLength, absorbtionLength); + AliMedium(kCarbonId, "Carbon$", id,0,fieldType,maxField,maxBending, + maxStepSize,maxEnergyLoss,precision,minStepSize); + + // Aluminum + a = 26.981539; + z = 13.; + density = 2.7; + radiationLength = 8.9; + id = kAlId; + AliMaterial(id, "Aluminum$",a,z, density, radiationLength, absorbtionLength); + AliMedium(kAlId, "Aluminum$", id, 0, fieldType, maxField, maxBending, + maxStepSize, maxEnergyLoss, precision, minStepSize); + + + // Copper + a = 63.546; + z = 29; + density = 8.96; + radiationLength = 1.43; + id = kCopperId; + AliMaterial(id, "Copper$", + a, z, density, radiationLength, absorbtionLength); + AliMedium(kCopperId, "Copper$", id, 0, fieldType, maxField, maxBending, + maxStepSize, maxEnergyLoss, precision, minStepSize); + // Silicon chip { Float_t as[] = { 12.0107, 14.0067, 15.9994, - 1.00794, 28.0855, 107.8682 }; + 1.00794, 28.0855, 107.8682 }; Float_t zs[] = { 6., 7., 8., 1., 14., 47. }; Float_t ws[] = { 0.039730642, 0.001396798, 0.01169634, 0.004367771, 0.844665, 0.09814344903 }; - density = 2.36436; + density = 2.36436; maxBending = 10; maxStepSize = .01; precision = .003; minStepSize = .003; - id = kSiChipId; - AliMixture(id, "FMD Si Chip$", as, zs, density, 6, ws); - AliMedium(kSiChipId, "FMD Si Chip$", id, 0, fieldType, maxField, - maxBending, maxStepSize, maxEnergyLoss, precision, minStepSize); + id = kSiChipId; + AliMixture(id, "Si Chip$", as, zs, density, 6, ws); + AliMedium(kSiChipId, "Si Chip$", id, 0, fieldType, maxField, maxBending, + maxStepSize, maxEnergyLoss, precision, minStepSize); } - - // Kaption + // Kaption { Float_t as[] = { 1.00794, 12.0107, 14.010, 15.9994}; Float_t zs[] = { 1., 6., 7., 8.}; @@ -454,12 +354,12 @@ void AliFMD::CreateMaterials() maxStepSize = .001; precision = .001; minStepSize = .001; - id = kKaptionId; - AliMixture(id, "FMD Kaption$", as, zs, density, 4, ws); - AliMedium(kKaptionId, "FMD Kaption$",id,0,fieldType,maxField,maxBending, + id = kKaptonId; + AliMixture(id, "Kaption$", as, zs, density, 4, ws); + AliMedium(kKaptonId, "Kaption$", id,0,fieldType,maxField,maxBending, maxStepSize,maxEnergyLoss,precision,minStepSize); } - + // Air { Float_t as[] = { 12.0107, 14.0067, 15.9994, 39.948 }; @@ -471,8 +371,8 @@ void AliFMD::CreateMaterials() precision = .001; minStepSize = .001; id = kAirId; - AliMixture(id, "FMD Air$", as, zs, density, 4, ws); - AliMedium(kAirId, "FMD Air$", id,0,fieldType,maxField,maxBending, + AliMixture(id, "Air$", as, zs, density, 4, ws); + AliMedium(kAirId, "Air$", id,0,fieldType,maxField,maxBending, maxStepSize,maxEnergyLoss,precision,minStepSize); } @@ -496,11 +396,22 @@ void AliFMD::CreateMaterials() precision = .001; minStepSize = .001; id = kPcbId; - AliMixture(id, "FMD PCB$", as, zs, density, 14, ws); - AliMedium(kPcbId, "FMD PCB$", id,1,fieldType,maxField,maxBending, + AliMixture(id, "PCB$", as, zs, density, 14, ws); + AliMedium(kPcbId, "PCB$", id,0,fieldType,maxField,maxBending, maxStepSize,maxEnergyLoss,precision,minStepSize); } + // Stainless steel + { + Float_t as[] = { 55.847, 51.9961, 58.6934, 28.0855 }; + Float_t zs[] = { 26., 24., 28., 14. }; + Float_t ws[] = { .715, .18, .1, .005 }; + density = 7.88; + id = kSteelId; + AliMixture(id, "Steel$", as, zs, density, 4, ws); + AliMedium(kSteelId, "Steel$", id, 0, fieldType, maxField, maxBending, + maxStepSize, maxEnergyLoss, precision, minStepSize); + } // Plastic { Float_t as[] = { 1.01, 12.01 }; @@ -512,104 +423,56 @@ void AliFMD::CreateMaterials() precision = .003; minStepSize = .003; id = kPlasticId; - AliMixture(id, "FMD Plastic$", as, zs, density, -2, ws); - AliMedium(kPlasticId, "FMD Plastic$", id,0,fieldType,maxField,maxBending, - maxStepSize,maxEnergyLoss,precision,minStepSize); + AliMixture(id, "Plastic$", as, zs, density, -2, ws); + AliMedium(kPlasticId, "Plastic$", id,0,fieldType,maxField,maxBending, + maxStepSize,maxEnergyLoss,precision,minStepSize); } - AliMatrix(fPrintboardRotationId, 90, 90, 0, 90, 90, 0); - AliMatrix(fIdentityRotationId, 90, 0, 90, 90, 0, 0); + } //____________________________________________________________________ void AliFMD::Init() { - // - // Initialis the FMD after it has been built - Int_t i; - // - if (fDebug) { - std::cout << "\n" << ClassName() << ": " << std::flush; - for (i = 0; i < 35; i++) std::cout << "*"; - std::cout << " FMD_INIT "; - for (i = 0; i < 35; i++) std::cout << "*"; - std::cout << "\n" << ClassName() << ": " << std::flush; - // - // Here the FMD initialisation code (if any!) - for (i = 0; i < 80; i++) std::cout << "*"; - std::cout << std::endl; + // Initialize the detector + // + AliFMDDebug(1, ("Initialising FMD detector object")); + TVirtualMC* mc = TVirtualMC::GetMC(); + AliFMDGeometry* fmd = AliFMDGeometry::Instance(); + const TArrayI& actGeo = fmd->ActiveIds(); + TArrayI actVmc(actGeo.fN); + for (Int_t i = 0; i < actGeo.fN; i++) { + TGeoVolume *sens = gGeoManager->GetVolume(actGeo[i]); + if (!sens) { + AliError(Form("No TGeo volume for sensitive volume ID=%d",actGeo[i])); + continue; + } + actVmc[i] = mc->VolId(sens->GetName()); + AliFMDDebug(1, ("Active vol id # %d: %d changed to %d", + i, actGeo[i], actVmc[i])); } - // - // + fmd->SetActive(actVmc.fArray, actVmc.fN); + // fmd->InitTransformations(); } -//==================================================================== -// -// Graphics and event display -// //____________________________________________________________________ -void -AliFMD::BuildGeometry() +void +AliFMD::FinishEvent() { - // - // Build simple ROOT TNode geometry for event display - // - // Build a simplified geometry of the FMD used for event display + // Called at the end of the an event in simulations. If the debug + // level is high enough, then the `bad' hits are printed. // - // The actual building of the TNodes is done by - // AliFMDSubDetector::SimpleGeometry. - AliDebug(10, "Creating a simplified geometry"); - - TNode* top = gAlice->GetGeometry()->GetNode("alice"); - - fFMD1->SimpleGeometry(fNodes, top, GetLineColor(), 0); - fFMD2->SimpleGeometry(fNodes, top, GetLineColor(), 0); - fFMD3->SimpleGeometry(fNodes, top, GetLineColor(), 0); + if (AliLog::GetDebugLevel("FMD", "AliFMD") < 10) return; + if (fBad && fBad->GetEntries() > 0) { + AliWarning((Form("EndEvent", "got %d 'bad' hits", fBad->GetEntries()))); + TIter next(fBad); + AliFMDHit* hit; + while ((hit = static_cast(next()))) hit->Print("D"); + fBad->Clear(); + } } -//____________________________________________________________________ -void -AliFMD::DrawDetector() -{ - // - // Draw a shaded view of the Forward multiplicity detector - // - // DebugGuard guard("AliFMD::DrawDetector"); - AliDebug(10, "Draw detector"); - - //Set ALIC mother transparent - gMC->Gsatt("ALIC","SEEN",0); - - //Set volumes visible - fFMD1->Gsatt(); - fFMD2->Gsatt(); - fFMD3->Gsatt(); - fInner->Gsatt(); - fOuter->Gsatt(); - - // - 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"); - gMC->Gdopt("hide", "off"); -} -//____________________________________________________________________ -const Int_t -AliFMD::DistanceToPrimitive(Int_t, Int_t) -{ - // - // Calculate the distance from the mouse to the FMD on the screen - // Dummy routine - // - return 9999; -} //==================================================================== // @@ -651,8 +514,7 @@ AliFMD::MakeBranch(Option_t * option) void AliFMD::SetTreeAddress() { - // Set branch address for the Hits and Digits Tree. - + // Set branch address for the Hits, Digits, and SDigits Tree. if (fLoader->TreeH()) HitsArray(); AliDetector::SetTreeAddress(); @@ -671,8 +533,6 @@ AliFMD::SetTreeAddress() } } - - //____________________________________________________________________ void AliFMD::SetHitsAddressBranch(TBranch *b) @@ -680,6 +540,13 @@ AliFMD::SetHitsAddressBranch(TBranch *b) // Set the TClonesArray to read hits into. b->SetAddress(&fHits); } +//____________________________________________________________________ +void +AliFMD::SetSDigitsAddressBranch(TBranch *b) +{ + // Set the TClonesArray to read hits into. + b->SetAddress(&fSDigits); +} //____________________________________________________________________ void @@ -706,40 +573,41 @@ AliFMD::AddHit(Int_t track, Int_t *vol, Float_t *hits) // hits[9] [Float_t ] Time when the track hit // // - AddHit(track, - UShort_t(vol[0]), // Detector # - Char_t(vol[1]), // Ring ID - UShort_t(vol[2]), // Sector # - UShort_t(vol[3]), // Strip # - hits[0], // X - hits[1], // Y - hits[2], // Z - hits[3], // Px - hits[4], // Py - hits[5], // Pz - hits[6], // Energy loss - Int_t(hits[7]), // PDG - hits[8]); // Time + AddHitByFields(track, + UShort_t(vol[0]), // Detector # + Char_t(vol[1]), // Ring ID + UShort_t(vol[2]), // Sector # + UShort_t(vol[3]), // Strip # + hits[0], // X + hits[1], // Y + hits[2], // Z + hits[3], // Px + hits[4], // Py + hits[5], // Pz + hits[6], // Energy loss + Int_t(hits[7]), // PDG + hits[8]); // Time } //____________________________________________________________________ -void -AliFMD::AddHit(Int_t track, - UShort_t detector, - Char_t ring, - UShort_t sector, - UShort_t strip, - Float_t x, - Float_t y, - Float_t z, - Float_t px, - Float_t py, - Float_t pz, - Float_t edep, - Int_t pdg, - Float_t t) +AliFMDHit* +AliFMD::AddHitByFields(Int_t track, + UShort_t detector, + Char_t ring, + UShort_t sector, + UShort_t strip, + Float_t x, + Float_t y, + Float_t z, + Float_t px, + Float_t py, + Float_t pz, + Float_t edep, + Int_t pdg, + Float_t t, + Float_t l, + Bool_t stop) { - // // Add a hit to the list // // Parameters: @@ -758,6 +626,8 @@ AliFMD::AddHit(Int_t track, // edep Energy deposited by track // pdg Track's particle Id # // t Time when the track hit + // l Track length through the material. + // stop Whether track was stopped or disappeared // TClonesArray& a = *(HitsArray()); // Search through the list of already registered hits, and see if we @@ -765,31 +635,46 @@ AliFMD::AddHit(Int_t track, // a new hit, but rather update the energy deposited in the hit. // This is done, so that a FLUKA based simulation will get the // number of hits right, not just the enerrgy deposition. + AliFMDHit* hit = 0; for (Int_t i = 0; i < fNhits; i++) { if (!a.At(i)) continue; - AliFMDHit* hit = static_cast(a.At(i)); + hit = static_cast(a.At(i)); if (hit->Detector() == detector && hit->Ring() == ring && hit->Sector() == sector && hit->Strip() == strip && hit->Track() == track) { - Warning("AddHit", "already had a hit in FMD%d%c[%2d,%3d] for track # %d," - " adding energy (%f) to that hit (%f) -> %f", - detector, ring, sector, strip, track, edep, hit->Edep(), - hit->Edep() + edep); + AliFMDDebug(1, ("already had a hit in FMD%d%c[%2d,%3d] for track # %d," + " adding energy (%f) to that hit (%f) -> %f", + detector, ring, sector, strip, track, edep, hit->Edep(), + hit->Edep() + edep)); hit->SetEdep(hit->Edep() + edep); - return; + return hit; } } // If hit wasn't already registered, do so know. - new (a[fNhits]) AliFMDHit(fIshunt, track, detector, ring, sector, strip, - x, y, z, px, py, pz, edep, pdg, t); + hit = new (a[fNhits]) AliFMDHit(fIshunt, track, detector, ring, sector, + strip, x, y, z, px, py, pz, edep, pdg, t, + l, stop); + // gMC->AddTrackReference(track, 12); fNhits++; + + //Reference track + + AliMC *mcApplication = (AliMC*)gAlice->GetMCApp(); + + AliTrackReference* trackRef = AddTrackReference(mcApplication->GetCurrentTrackNumber(), AliTrackReference::kFMD); + UInt_t stripId = AliFMDStripIndex::Pack(detector,ring,sector,strip); + trackRef->SetUserId(stripId); + + + + return hit; } //____________________________________________________________________ void -AliFMD::AddDigit(Int_t* digits) +AliFMD::AddDigit(Int_t* digits, Int_t*) { // Add a digit to the Digit tree // @@ -803,24 +688,28 @@ AliFMD::AddDigit(Int_t* digits) // digits[5] [Short_t] ADC Count, -1 if not used // digits[6] [Short_t] ADC Count, -1 if not used // - AddDigit(UShort_t(digits[0]), // Detector # - Char_t(digits[1]), // Ring ID - UShort_t(digits[2]), // Sector # - UShort_t(digits[3]), // Strip # - UShort_t(digits[4]), // ADC Count1 - Short_t(digits[5]), // ADC Count2 - Short_t(digits[6])); // ADC Count3 + AddDigitByFields(UShort_t(digits[0]), // Detector # + Char_t(digits[1]), // Ring ID + UShort_t(digits[2]), // Sector # + UShort_t(digits[3]), // Strip # + UShort_t(digits[4]), // ADC Count1 + Short_t(digits[5]), // ADC Count2 + Short_t(digits[6]), // ADC Count3 + Short_t(digits[7])); } //____________________________________________________________________ void -AliFMD::AddDigit(UShort_t detector, - Char_t ring, - UShort_t sector, - UShort_t strip, - UShort_t count1, - Short_t count2, - Short_t count3) +AliFMD::AddDigitByFields(UShort_t detector, + Char_t ring, + UShort_t sector, + UShort_t strip, + UShort_t count1, + Short_t count2, + Short_t count3, + Short_t count4, + UShort_t nrefs, + Int_t* refs) { // add a real digit - as coming from data // @@ -835,8 +724,15 @@ AliFMD::AddDigit(UShort_t detector, // count3 ADC count (a 10-bit word), or -1 if not used TClonesArray& a = *(DigitsArray()); + AliFMDDebug(15, ("Adding digit # %5d/%5d for FMD%d%c[%2d,%3d]" + "=(%d,%d,%d,%d) with %d tracks", + fNdigits-1, a.GetEntriesFast(), + detector, ring, sector, strip, + count1, count2, count3, count4, nrefs)); new (a[fNdigits++]) - AliFMDDigit(detector, ring, sector, strip, count1, count2, count3); + AliFMDDigit(detector, ring, sector, strip, + count1, count2, count3, count4, nrefs, refs); + } //____________________________________________________________________ @@ -856,26 +752,33 @@ AliFMD::AddSDigit(Int_t* digits) // digits[6] [Short_t] ADC Count, -1 if not used // digits[7] [Short_t] ADC Count, -1 if not used // - AddSDigit(UShort_t(digits[0]), // Detector # - Char_t(digits[1]), // Ring ID - UShort_t(digits[2]), // Sector # - UShort_t(digits[3]), // Strip # - Float_t(digits[4]), // Edep - UShort_t(digits[5]), // ADC Count1 - Short_t(digits[6]), // ADC Count2 - Short_t(digits[7])); // ADC Count3 + AddSDigitByFields(UShort_t(digits[0]), // Detector # + Char_t(digits[1]), // Ring ID + UShort_t(digits[2]), // Sector # + UShort_t(digits[3]), // Strip # + Float_t(digits[4]), // Edep + UShort_t(digits[5]), // ADC Count1 + Short_t(digits[6]), // ADC Count2 + Short_t(digits[7]), // ADC Count3 + Short_t(digits[8]), // ADC Count4 + UShort_t(digits[9]), // N particles + UShort_t(digits[10])); // N primaries } //____________________________________________________________________ void -AliFMD::AddSDigit(UShort_t detector, - Char_t ring, - UShort_t sector, - UShort_t strip, - Float_t edep, - UShort_t count1, - Short_t count2, - Short_t count3) +AliFMD::AddSDigitByFields(UShort_t detector, + Char_t ring, + UShort_t sector, + UShort_t strip, + Float_t edep, + UShort_t count1, + Short_t count2, + Short_t count3, + Short_t count4, + UShort_t ntot, + UShort_t nprim, + Int_t* refs) { // add a summable digit // @@ -891,17 +794,23 @@ AliFMD::AddSDigit(UShort_t detector, // count3 ADC count (a 10-bit word), or -1 if not used // TClonesArray& a = *(SDigitsArray()); + // AliFMDDebug(0, ("Adding sdigit # %d", fNsdigits)); + AliFMDDebug(15, ("Adding sdigit # %5d/%5d for FMD%d%c[%2d,%3d]" + "=(%d,%d,%d,%d) with %d tracks %d primaries %d (%p)", + fNsdigits-1, a.GetEntriesFast(), + detector, ring, sector, strip, + count1, count2, count3, count4, ntot, nprim, refs)); new (a[fNsdigits++]) - AliFMDSDigit(detector, ring, sector, strip, edep, count1, count2, count3); + AliFMDSDigit(detector, ring, sector, strip, edep, + count1, count2, count3, count4, ntot, nprim, refs); } //____________________________________________________________________ void AliFMD::ResetSDigits() { - // - // Reset number of digits and the digits array for this detector + // Reset number of digits and the digits array for this detector. // fNsdigits = 0; if (fSDigits) fSDigits->Clear(); @@ -955,12 +864,9 @@ AliFMD::Hits2Digits() // Create AliFMDDigit's from AliFMDHit's. This is done by making a // AliFMDDigitizer, and executing that code. // - AliRunDigitizer* manager = new AliRunDigitizer(1, 1); - manager->SetInputStream(0, "galice.root"); - manager->SetOutputFile("H2Dfile"); - - /* AliDigitizer* dig =*/ CreateDigitizer(manager); - manager->Exec(""); + AliFMDHitDigitizer digitizer(this, AliFMDHitDigitizer::kDigits); + digitizer.Init(); + digitizer.Exec(""); } //____________________________________________________________________ @@ -970,8 +876,9 @@ AliFMD::Hits2SDigits() // Create AliFMDSDigit's from AliFMDHit's. This is done by creating // an AliFMDSDigitizer object, and executing it. // - AliDigitizer* sdig = new AliFMDSDigitizer("galice.root"); - sdig->Exec(""); + AliFMDHitDigitizer digitizer(this, AliFMDHitDigitizer::kSDigits); + digitizer.Init(); + digitizer.Exec(""); } @@ -980,7 +887,21 @@ AliDigitizer* AliFMD::CreateDigitizer(AliRunDigitizer* manager) const { // Create a digitizer object - return new AliFMDDigitizer(manager); + + /* This is what we probably _should_ do */ + AliFMDBaseDigitizer* digitizer = 0; + +#ifdef USE_SSDIGITIZER + digitizer = new AliFMDSSDigitizer(manager); +#else + /* This is what we actually do, and will work */ +#if 0 + AliInfo("SDigit->Digit conversion not really supported, " + "doing Hit->Digit conversion instead"); +#endif + digitizer = new AliFMDDigitizer(manager); +#endif + return digitizer; } //==================================================================== @@ -993,277 +914,51 @@ AliFMD::Digits2Raw() { // Turn digits into raw data. // - // Digits are read from the Digit branch, and processed to make - // three DDL files, one for each of the sub-detectors FMD1, FMD2, - // and FMD3. - // - // The raw data files consists of a header, followed by ALTRO - // formatted blocks. - // - // +-------------+ - // | Header | - // +-------------+ - // | ALTRO Block | - // | ... | - // +-------------+ - // DDL file - // - // An ALTRO formatted block, in the FMD context, consists of a - // number of counts followed by a trailer. - // - // +------------------+ - // | Count | - // | ... | - // | possible fillers | - // +------------------+ - // | Trailer | - // +------------------+ - // ALTRO block - // - // The counts are listed backwards, that is, starting with the - // latest count, and ending in the first. - // - // Each count consist of 1 or more ADC samples of the VA1_ALICE - // pre-amp. signal. Just how many samples are used depends on - // whether the ALTRO over samples the pre-amp. Each sample is a - // 10-bit word, and the samples are grouped into 40-bit blocks - // - // +------------------------------------+ - // | S(n) | S(n-1) | S(n-2) | S(n-3) | - // | ... | ... | ... | ... | - // | S(2) | S(1) | AA | AA | - // +------------------------------------+ - // Counts + possible filler - // - // The trailer of the number of words of signales, the starting - // strip number, the sector number, and the ring ID; each 10-bit - // words, packed into 40-bits. - // - // +------------------------------------+ - // | # words | start | sector | ring | - // +------------------------------------+ - // Trailer - // - // Note, that this method assumes that the digits are ordered. - // - AliFMD* fmd = static_cast(gAlice->GetDetector(GetName())); - fLoader->LoadDigits(); - TTree* digitTree = fLoader->TreeD(); - if (!digitTree) { - Error("Digits2Raw", "no digit tree"); - return; - } - - TClonesArray* digits = new TClonesArray("AliFMDDigit", 1000); - fmd->SetTreeAddress(); - TBranch* digitBranch = digitTree->GetBranch(GetName()); - if (!digitBranch) { - Error("Digits2Raw", "no branch for %s", GetName()); - return; - } - digitBranch->SetAddress(&digits); - - Int_t nEvents = Int_t(digitTree->GetEntries()); - for (Int_t event = 0; event < nEvents; event++) { - fmd->ResetDigits(); - digitTree->GetEvent(event); - - Int_t nDigits = digits->GetEntries(); - if (nDigits < 1) continue; - - - UShort_t prevDetector = 0; - Char_t prevRing = '\0'; - UShort_t prevSector = 0; - // UShort_t prevStrip = 0; - - // The first seen strip number for a channel - UShort_t startStrip = 0; - - // Which channel number in the ALTRO channel we're at - UShort_t offset = 0; - - // How many times the ALTRO Samples one VA1_ALICE channel - Int_t sampleRate = 1; - - // A buffer to hold 1 ALTRO channel - Normally, one ALTRO channel - // holds 128 VA1_ALICE channels, sampled at a rate of `sampleRate' - TArrayI channel(128 * sampleRate); - - // The Altro buffer - AliAltroBuffer* altro = 0; - - // Loop over the digits in the event. Note, that we assume the - // the digits are in order in the branch. If they were not, we'd - // have to cache all channels before we could write the data to - // the ALTRO buffer, or we'd have to set up a map of the digits. - for (Int_t i = 0; i < nDigits; i++) { - // Get the digit - AliFMDDigit* digit = static_cast(digits->At(i)); - - UShort_t det = digit->Detector(); - Char_t ring = digit->Ring(); - UShort_t sector = digit->Sector(); - UShort_t strip = digit->Strip(); - if (det != prevDetector) { - AliDebug(10, Form("FMD: New DDL, was %d, now %d", - kBaseDDL + prevDetector - 1, - kBaseDDL + det - 1)); - // If an altro exists, delete the object, flushing the data to - // disk, and closing the file. - if (altro) { - // When the first argument is false, we write the real - // header. - AliDebug(10, Form("New altro: Write channel at %d Strip: %d " - "Sector: %d Ring: %d", - i, startStrip, prevSector, prevRing)); - // TPC to FMD translations - // - // TPC FMD - // ----------+----------- - // pad | strip - // row | sector - // sector | ring - // - altro->WriteChannel(Int_t(startStrip), - Int_t(prevSector), - Int_t((prevRing == 'I' ? 0 : 1)), - channel.fN, channel.fArray, 0); - altro->Flush(); - altro->WriteDataHeader(kFALSE, kFALSE); - delete altro; - altro = 0; - } - - prevDetector = det; - // Need to open a new DDL! - Int_t ddlId = kBaseDDL + det - 1; - TString filename(Form("%s_%d.ddl", GetName(), ddlId)); - - AliDebug(10, Form("New altro buffer with DDL file %s", - filename.Data())); - AliDebug(10, Form("New altro at %d", i)); - // Create a new altro buffer - a `1' as the second argument - // means `write mode' - altro = new AliAltroBuffer(filename.Data(), 1); - - // Write a dummy (first argument is true) header to the DDL - // file - later on, when we close the file, we write the real - // header - altro->WriteDataHeader(kTRUE, kFALSE); - - // Figure out the sample rate - if (digit->Count2() > 0) sampleRate = 2; - if (digit->Count3() > 0) sampleRate = 3; - - channel.Set(128 * sampleRate); - offset = 0; - prevRing = ring; - prevSector = sector; - startStrip = strip; - } - else if (offset == 128 - || digit->Ring() != prevRing - || digit->Sector() != prevSector) { - // Force a new Altro channel - AliDebug(10, Form("Flushing channel to disk because %s", - (offset == 128 ? "channel is full" : - (ring != prevRing ? "new ring up" : - "new sector up")))); - AliDebug(10, Form("New Channel: Write channel at %d Strip: %d " - "Sector: %d Ring: %d", - i, startStrip, prevSector, prevRing)); - altro->WriteChannel(Int_t(startStrip), - Int_t(prevSector), - Int_t((prevRing == 'I' ? 0 : 1)), - channel.fN, channel.fArray, 0); - // Reset and update channel variables - channel.Reset(0); - offset = 0; - startStrip = strip; - prevRing = ring; - prevSector = sector; - } - - // Store the counts of the ADC in the channel buffer - channel[offset * sampleRate] = digit->Count1(); - if (sampleRate > 1) - channel[offset * sampleRate + 1] = digit->Count2(); - if (sampleRate > 2) - channel[offset * sampleRate + 2] = digit->Count3(); - offset++; - } - // Finally, we need to close the final ALTRO buffer if it wasn't - // already - if (altro) { - altro->Flush(); - altro->WriteDataHeader(kFALSE, kFALSE); - delete altro; - } - } - fLoader->UnloadDigits(); + // This uses the class AliFMDRawWriter to do the job. Please refer + // to that class for more information. + AliFMDRawWriter writer(this); + writer.Exec(); } -//================================================================== +//==================================================================== // -// Various setter functions for the common paramters +// Raw data reading // - //__________________________________________________________________ -void -AliFMD::SetLegLength(Double_t length) +Bool_t +AliFMD::Raw2SDigits(AliRawReader* reader) { - // Set lenght of plastic legs that hold the hybrid (print board and - // silicon sensor) onto the honeycomp support - // - // DebugGuard guard("AliFMD::SetLegLength"); - AliDebug(10, "AliFMD::SetLegLength"); - fLegLength = length; - fInner->SetLegLength(fLegLength); - fOuter->SetLegLength(fLegLength); -} + // Turn digits into raw data. + // + // This uses the class AliFMDRawWriter to do the job. Please refer + // to that class for more information. + AliFMDParameters::Instance()->Init(); + MakeTree("S"); + MakeBranch("S"); + + TClonesArray* sdigits = SDigits(); + AliFMDReconstructor rec; + + // The two boolean arguments + // Make sdigits instead of digits + // Subtract the pedestal off the signal + rec.Digitize(reader, sdigits); + // + // Bool_t ret = fmdReader.ReadAdcs(sdigits, kTRUE, kTRUE); + // sdigits->ls(); + UShort_t ns = sdigits->GetEntriesFast(); + for (UShort_t i = 0; i < ns; i++) + sdigits->At(i)->Print("pl"); + + AliFMDDebug(1, ("Got a total of %d SDigits", ns)); -//__________________________________________________________________ -void -AliFMD::SetLegOffset(Double_t offset) -{ - // Set offset from edge of hybrid to plastic legs that hold the - // hybrid (print board and silicon sensor) onto the honeycomp - // support - // - // DebugGuard guard("AliFMD::SetLegOffset"); - AliDebug(10, "AliFMD::SetLegOffset"); - fInner->SetLegOffset(offset); - fOuter->SetLegOffset(offset); -} + fLoader->TreeS()->Fill(); + ResetSDigits(); + fLoader->WriteSDigits("OVERWRITE"); -//__________________________________________________________________ -void -AliFMD::SetLegRadius(Double_t radius) -{ - // Set the diameter of the plastic legs that hold the hybrid (print - // board and silicon sensor) onto the honeycomp support - // - // DebugGuard guard("AliFMD::SetLegRadius"); - AliDebug(10, "AliFMD::SetLegRadius"); - fLegRadius = radius; - fInner->SetLegRadius(fLegRadius); - fOuter->SetLegRadius(fLegRadius); + return kTRUE; } -//__________________________________________________________________ -void -AliFMD::SetModuleSpacing(Double_t spacing) -{ - // Set the distance between the front and back sensor modules - // (module staggering). - // - // DebugGuard guard("AliFMD::SetModuleSpacing"); - AliDebug(10, "AliFMD::SetModuleSpacing"); - fModuleSpacing = spacing; - fInner->SetModuleSpacing(fModuleSpacing); - fOuter->SetModuleSpacing(fModuleSpacing); -} //==================================================================== // @@ -1275,16 +970,58 @@ AliFMD::Browse(TBrowser* b) { // Browse this object. // - AliDebug(10, "AliFMD::Browse"); + AliFMDDebug(30, ("\tBrowsing the FMD")); AliDetector::Browse(b); - if (fInner) b->Add(fInner, "Inner Ring"); - if (fOuter) b->Add(fOuter, "Outer Ring"); - if (fFMD1) b->Add(fFMD1, "FMD1 SubDetector"); - if (fFMD2) b->Add(fFMD2, "FMD2 SubDetector"); - if (fFMD3) b->Add(fFMD3, "FMD3 SubDetector"); + b->Add(AliFMDGeometry::Instance()); } - +//____________________________________________________________________ +void +AliFMD::AddAlignableVolumes() const +{ + // + // Create entries for alignable volumes associating the symbolic volume + // name with the corresponding volume path. Needs to be syncronized with + // eventual changes in the geometry. + // + // This code was made by Raffaele Grosso . I + // (cholm) will probably want to change it. For one, I think it + // should be the job of the geometry manager to deal with this. + AliInfo("Add FMD alignable volumes"); + AliFMDGeometry::Instance()->SetAlignableVolumes(); +#if 0 + for(size_t f = 1; f <= 3; f++){ // Detector 1,2,3 + for(size_t tb = 0; tb <2 ; tb++){ // Top/Bottom + char stb = tb == 0 ? 'T' : 'B'; + unsigned min = tb == 0 ? 0 : 5; + + TString halfVol(Form("/ALIC_1/F%dM%c_%d", f, stb, f)); + TString halfSym(halfVol); + if(!gGeoManager->SetAlignableEntry(halfSym.Data(),halfVol.Data())) + AliFatal(Form("Alignable entry %s not created. " + "Volume path %s not valid", + halfSym.Data(),halfVol.Data())); + for(size_t io = 0; io < 2; io++){ // inner, outer + if (f==1 && io==1) continue; // Only one ring in FMD1 + if(tb == 1 && io==1) min=10; + char sio = (io == 0 ? 'I' : 'O'); + unsigned nio = (io == 0 ? 3 : 9); + unsigned max = (io == 0 ? 5 : 10) + min; + + for(size_t i = min; i < max; i++) { // Modules + TString modVol(Form("%s/F%c%cV_7%d/F%cSE_%d", halfVol.Data(), + sio, stb, nio, sio, i)); + TString modSym(modVol); + if(!gGeoManager->SetAlignableEntry(modSym.Data(),modVol.Data())) + AliFatal(Form("Alignable entry %s not created. " + "Volume path %s not valid", + modSym.Data(), modVol.Data())); + } + } + } + } +#endif +} //___________________________________________________________________ // // EOF