X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;f=FMD%2FAliFMD.cxx;h=cd22e9b03a5e9a02f26be237a9778fb843913aae;hb=682165900cd8d41e6e9341484436fe0d02407173;hp=e87dec87be1b3b8554bdd76df80f0706c3f58696;hpb=90da4514220d6a168a0292c2f2f54d23c75c7f00;p=u%2Fmrichter%2FAliRoot.git diff --git a/FMD/AliFMD.cxx b/FMD/AliFMD.cxx index e87dec87be1..cd22e9b03a5 100644 --- a/FMD/AliFMD.cxx +++ b/FMD/AliFMD.cxx @@ -12,15 +12,19 @@ * 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 3 sub-detectors FMD1, FMD2, and FMD3, each of -// which has 1 or 2 rings of silicon sensors. +// 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. // @@ -36,22 +40,14 @@ // +----+--------------+ +--| AliFMDDigitizer | // | | +-----------------+ // | +---------------------+ | -// | +- | AliFMDBaseDigitizer |<--+ +// | +--| AliFMDBaseDigitizer |<--+ // V 1 | +---------------------+ | // +--------+<>--+ | +------------------+ // | AliFMD | +--| AliFMDSDigitizer | // +--------+<>--+ +------------------+ -// 1 | +-----------------+ -// +-| AliFMDSimulator | -// +-----------------+ -// ^ -// | -// +-------------+-------------+ -// | | -// +--------------------+ +-------------------+ -// | AliFMDGeoSimulator | | AliFMDG3Simulator | -// +--------------------+ +---------+---------+ -// +// 1 | +---------------------+ +// +--| AliFMDReconstructor | +// +---------------------+ // // * AliFMD // This defines the interface for the various parts of AliROOT that @@ -74,46 +70,57 @@ // simulator tasks are responsible to implment the geoemtry, and // process hits. // -// * AliFMDGeoSimulator -// This is a concrete implementation of the AliFMDSimulator that -// uses the TGeo classes directly only. +// * AliFMDReconstructor +// This is a concrete implementation of the AliReconstructor that +// reconstructs pseudo-inclusive-multiplicities from digits (raw or +// from simulation) // -// * AliFMDG3Simulator -// This is a concrete implementation of the AliFMDSimulator that -// uses the TVirtualMC interface with GEANT 3.21-like messages. +// 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. // // 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 // __CMATH__ +#include // ROOT_TBrowser #include // ROOT_TClonesArray -#include // ROOT_TGeomtry -#include // ROOT_TNode -#include // ROOT_TXTRU +#include // ROOT_TGeoGlobalMagField +#include // ROOT_TGeoManager #include // ROOT_TRotMatrix -#include // ROOT_TTUBE #include // ROOT_TTree -#include // ROOT_TBrowser -#include // ROOT_TMath -#include // ROOT_TVirtualMC +#include // ROOT_TVector2 +#include // ROOT_TVirtualMC +#include // __CMATH__ -#include // ALIRUNDIGITIZER_H +#include // ALIRUNDIGITIZER_H #include // ALILOADER_H #include // ALIRUN_H #include // ALIMC_H -#include // ALILOG_H +#include // ALIMAGF_H +// #include // ALILOG_H +#include "AliFMDDebug.h" // Better debug macros #include "AliFMD.h" // ALIFMD_H -#include "AliFMDDigit.h" // ALIFMDDIGIG_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 "AliFMDSimulator.h" // ALIFMDSIMULATOR_H -#include "AliFMDG3Simulator.h" // ALIFMDG3SIMULATOR_H -#include "AliFMDGeoSimulator.h" // ALIFMDGEOSIMULATOR_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) @@ -127,26 +134,18 @@ AliFMD::AliFMD() fSDigits(0), fNsdigits(0), fDetailed(kTRUE), - fSimulator(0) + fUseOld(kFALSE), + fUseAssembly(kTRUE), + fBad(0) { // // Default constructor for class AliFMD // - AliDebug(10, "\tDefault CTOR"); - fHits = 0; - fDigits = 0; - fIshunt = 0; -} - -//____________________________________________________________________ -AliFMD::AliFMD(const AliFMD& other) - : AliDetector(other), - fSDigits(other.fSDigits), - fNsdigits(other.fNsdigits), - fDetailed(other.fDetailed), - fSimulator(other.fSimulator) -{ - // Copy constructor + AliFMDDebug(10, ("\tDefault CTOR")); + fHits = 0; + fDigits = 0; + fIshunt = 0; + // fBad = new TClonesArray("AliFMDHit"); } //____________________________________________________________________ @@ -155,25 +154,28 @@ AliFMD::AliFMD(const char *name, const char *title) fSDigits(0), fNsdigits(0), fDetailed(kTRUE), - fSimulator(0) + fUseOld(kFALSE), + fUseAssembly(kFALSE), + fBad(0) { // // Standard constructor for Forward Multiplicity Detector // - AliDebug(10, "\tStandard CTOR"); - + AliFMDDebug(10, ("\tStandard CTOR")); + // fBad = new TClonesArray("AliFMDHit"); + // Initialise Hit array - HitsArray(); - gAlice->GetMCApp()->AddHitList(fHits); + // HitsArray(); + // gAlice->GetMCApp()->AddHitList(fHits); // (S)Digits for the detectors disk - DigitsArray(); - SDigitsArray(); + // DigitsArray(); + // SDigitsArray(); // CHC: What is this? fIshunt = 0; - SetMarkerColor(kRed); - SetLineColor(kYellow); + //PH SetMarkerColor(kRed); + //PH SetLineColor(kYellow); } //____________________________________________________________________ @@ -195,20 +197,13 @@ AliFMD::~AliFMD () delete fSDigits; fSDigits = 0; } + if (fBad) { + fBad->Delete(); + delete fBad; + fBad = 0; + } } -//____________________________________________________________________ -AliFMD& -AliFMD::operator=(const AliFMD& other) -{ - AliDetector::operator=(other); - fSDigits = other.fSDigits; - fNsdigits = other.fNsdigits; - fDetailed = other.fDetailed; - fSimulator = other.fSimulator; - - return *this; -} //==================================================================== // @@ -220,250 +215,337 @@ 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. - // - // 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 + // construction of the geometry is delegated to the class + // AliFMDGeometryBuilder, invoked by the singleton manager + // AliFMDGeometry. // - if (!fSimulator) { - AliFatal("Simulator object not made yet!"); - return; - } - fSimulator->DefineGeometry(); + 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 // - AliDebug(10, "\tCreating materials"); - - if (fSimulator) { - AliFatal("Simulator object already instantised!"); - return; - } + // 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. + // + AliFMDDebug(10, ("\tCreating materials")); + // Get pointer to geometry singleton object. AliFMDGeometry* geometry = AliFMDGeometry::Instance(); geometry->Init(); -// TVirtualMC* mc = TVirtualMC::GetMC(); -// Bool_t geo = mc->IsRootGeometrySupported(); -// if (geo) -// fSimulator = new AliFMDGeoSimulator(this, fDetailed); -// else - fSimulator = new AliFMDG3Simulator(this, fDetailed); +#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 = ((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 + Double_t precision = 0.001; // Precision + Double_t minStepSize = 0.001; // Minimum step size + + // Silicon + a = 28.0855; + z = 14.; + density = geometry->GetSiDensity(); + radiationLength = 9.36; + maxBending = 1; + maxStepSize = .001; + precision = .001; + minStepSize = .001; + id = kSiId; + AliMaterial(id, "Si$", a, z, density, radiationLength, absorbtionLength); + AliMedium(kSiId, "Si$", id,1,fieldType,maxField,maxBending, + maxStepSize,maxEnergyLoss,precision,minStepSize); + + + // Carbon + a = 12.011; + z = 6.; + density = 2.265; + radiationLength = 18.8; + maxBending = 10; + maxStepSize = .01; + precision = .003; + minStepSize = .003; + id = kCarbonId; + 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); + - fSimulator->DefineMaterials(); + // 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 }; + 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; + maxBending = 10; + maxStepSize = .01; + precision = .003; + minStepSize = .003; + 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 + { + Float_t as[] = { 1.00794, 12.0107, 14.010, 15.9994}; + Float_t zs[] = { 1., 6., 7., 8.}; + Float_t ws[] = { 0.026362, 0.69113, 0.07327, 0.209235}; + density = 1.42; + maxBending = 1; + maxStepSize = .001; + precision = .001; + minStepSize = .001; + 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 }; + Float_t zs[] = { 6., 7., 8., 18. }; + Float_t ws[] = { 0.000124, 0.755267, 0.231781, 0.012827 }; + density = .00120479; + maxBending = 1; + maxStepSize = .001; + precision = .001; + minStepSize = .001; + id = kAirId; + AliMixture(id, "Air$", as, zs, density, 4, ws); + AliMedium(kAirId, "Air$", id,0,fieldType,maxField,maxBending, + maxStepSize,maxEnergyLoss,precision,minStepSize); + } + + // PCB + { + Float_t zs[] = { 14., 20., 13., 12., + 5., 22., 11., 19., + 26., 9., 8., 6., + 7., 1.}; + Float_t as[] = { 28.0855, 40.078, 26.981538, 24.305, + 10.811, 47.867, 22.98977, 39.0983, + 55.845, 18.9984, 15.9994, 12.0107, + 14.0067, 1.00794}; + Float_t ws[] = { 0.15144894, 0.08147477, 0.04128158, 0.00904554, + 0.01397570, 0.00287685, 0.00445114, 0.00498089, + 0.00209828, 0.00420000, 0.36043788, 0.27529426, + 0.01415852, 0.03427566}; + density = 1.8; + maxBending = 1; + maxStepSize = .001; + precision = .001; + minStepSize = .001; + id = kPcbId; + 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 }; + Float_t zs[] = { 1., 6. }; + Float_t ws[] = { 1., 1. }; + density = 1.03; + maxBending = 10; + maxStepSize = .01; + precision = .003; + minStepSize = .003; + id = kPlasticId; + AliMixture(id, "Plastic$", as, zs, density, -2, ws); + AliMedium(kPlasticId, "Plastic$", id,0,fieldType,maxField,maxBending, + maxStepSize,maxEnergyLoss,precision,minStepSize); + } + } +#if 0 //____________________________________________________________________ void -AliFMD::Init() +AliFMD::SetTrackingParameters(Int_t imed, + Float_t gamma, + Float_t electron, + Float_t neutral_hadron, + Float_t charged_hadron, + Float_t muon, + Float_t electron_bremstrahlung, + Float_t muon__bremstrahlung, + Float_t electron_delta, + Float_t muon_delta, + Float_t muon_pair, + Int_t annihilation, + Int_t bremstrahlung, + Int_t compton_scattering, + Int_t decay, + Int_t delta_ray, + Int_t hadronic, + Int_t energy_loss, + Int_t multiple_scattering, + Int_t pair_production, + Int_t photon_production, + Int_t rayleigh_scattering) { - // - // Initialis the FMD after it has been built - Int_t i; - // - if (AliLog::GetGlobalDebugLevel()) { - cout << "\n" << ClassName() << ": " << flush; - for (i = 0; i < 35; i++) cout << "*"; - cout << " FMD_INIT "; - for (i = 0; i < 35; i++) cout << "*"; - cout << "\n" << ClassName() << ": " << flush; - // - // Here the FMD initialisation code (if any!) - for (i = 0; i < 80; i++) cout << "*"; - cout << endl; - } - // - // + // Disabled by request of FCA, kept for reference only + if (!gMC) return; + TArrayI& idtmed = *(GetIdtmed()); + Int_t iimed = idtmed[imed]; + // gMC->Gstpar(iimed, "CUTGAM", gamma); + // gMC->Gstpar(iimed, "CUTELE", electron); + // gMC->Gstpar(iimed, "CUTNEU", neutral_hadron); + // gMC->Gstpar(iimed, "CUTHAD", charged_hadron); + // gMC->Gstpar(iimed, "CUTMUO", muon); + // gMC->Gstpar(iimed, "BCUTE", electron_bremstrahlung); + // gMC->Gstpar(iimed, "BCUTM", muon__bremstrahlung); + // gMC->Gstpar(iimed, "DCUTE", electron_delta); + // gMC->Gstpar(iimed, "DCUTM", muon_delta); + // gMC->Gstpar(iimed, "PPCUTM", muon_pair); + // gMC->Gstpar(iimed, "ANNI", Float_t(annihilation)); + // gMC->Gstpar(iimed, "BREM", Float_t(bremstrahlung)); + // gMC->Gstpar(iimed, "COMP", Float_t(compton_scattering)); + // gMC->Gstpar(iimed, "DCAY", Float_t(decay)); + // gMC->Gstpar(iimed, "DRAY", Float_t(delta_ray)); + // gMC->Gstpar(iimed, "HADR", Float_t(hadronic)); + // gMC->Gstpar(iimed, "LOSS", Float_t(energy_loss)); + // gMC->Gstpar(iimed, "MULS", Float_t(multiple_scattering)); + // gMC->Gstpar(iimed, "PAIR", Float_t(pair_production)); + // gMC->Gstpar(iimed, "PHOT", Float_t(photon_production)); + // gMC->Gstpar(iimed, "RAYL", Float_t(rayleigh_scattering)); } +#endif -//==================================================================== -// -// Graphics and event display -// //____________________________________________________________________ -void -AliFMD::BuildGeometry() +void +AliFMD::Init() { - // - // Build simple ROOT TNode geometry for event display - // - // Build a simplified geometry of the FMD used for event display + // Initialize the detector // - // The actual building of the TNodes is done by - // AliFMDSubDetector::SimpleGeometry. - AliDebug(10, "\tCreating a simplified geometry"); - - AliFMDGeometry* fmd = AliFMDGeometry::Instance(); - - static TXTRU* innerShape = 0; - static TXTRU* outerShape = 0; - static TObjArray* innerRot = 0; - static TObjArray* outerRot = 0; - - if (!innerShape || !outerShape) { - // Make the shapes for the modules - for (Int_t i = 0; i < 2; i++) { - AliFMDRing* r = 0; - switch (i) { - case 0: r = fmd->GetRing('I'); break; - case 1: r = fmd->GetRing('O'); break; - } - if (!r) { - AliError(Form("no ring found for i=%d", i)); - return; - } - Double_t siThick = r->GetSiThickness(); - const Int_t nv = r->GetNVerticies(); - Double_t theta = r->GetTheta(); - Int_t nmod = r->GetNModules(); - - TXTRU* shape = new TXTRU(r->GetName(), r->GetTitle(), "void", nv, 2); - for (Int_t j = 0; j < nv; j++) { - TVector2* vv = r->GetVertex(nv - 1 - j); - shape->DefineVertex(j, vv->X(), vv->Y()); - } - shape->DefineSection(0, -siThick / 2, 1, 0, 0); - shape->DefineSection(1, +siThick / 2, 1, 0, 0); - shape->SetLineColor(GetLineColor()); - - TObjArray* rots = new TObjArray(nmod); - for (Int_t j = 0; j < nmod; j++) { - Double_t th = (j + .5) * theta * 2; - TString name(Form("FMD_ring_%c_rot_%02d", r->GetId(), j)); - TString title(Form("FMD Ring %c Rotation # %d", r->GetId(), j)); - TRotMatrix* rot = new TRotMatrix(name.Data(), title.Data(), - 90, th, 90, fmod(90+th,360), 0, 0); - rots->AddAt(rot, j); - } - - switch (r->GetId()) { - case 'i': - case 'I': innerShape = shape; innerRot = rots; break; - case 'o': - case 'O': outerShape = shape; outerRot = rots; break; + AliFMDDebug(1, ("Initialising FMD detector object")); + TVirtualMC* mc = TVirtualMC::GetMC(); + AliFMDGeometry* fmd = AliFMDGeometry::Instance(); + TArrayI actGeo = fmd->ActiveIds(); + bool valid = true; + if (actGeo.fN <= 0) valid = false; + else { + for (int i = 0; i < actGeo.fN; i++) { + if (actGeo[i] < 0) { + valid = false; + break; } } } - - TNode* top = gAlice->GetGeometry()->GetNode("alice"); - - for (Int_t i = 1; i <= 3; i++) { - AliFMDDetector* det = fmd->GetDetector(i); - if (!det) { - Warning("BuildGeometry", "FMD%d seems to be disabled", i); + if (!valid) { + AliFMDDebug(1, ("Extracting geometry info from loaded geometry")); + fmd->ExtractGeomInfo(); + actGeo = fmd->ActiveIds(); + } + TArrayI actVmc(actGeo.fN); + for (Int_t i = 0; i < actGeo.fN; i++) { + if (actGeo[i] < 0) { + AliError(Form("Invalid id: %d", actGeo[i])); continue; } - Double_t w = 0; - Double_t rh = det->GetRing('I')->GetHighR(); - Char_t id = 'I'; - if (det->GetRing('O')) { - w = TMath::Abs(det->GetRingZ('O') - det->GetRingZ('I')); - id = (TMath::Abs(det->GetRingZ('O')) - > TMath::Abs(det->GetRingZ('I')) ? 'O' : 'I'); - rh = det->GetRing('O')->GetHighR(); - } - w += (det->GetRing(id)->GetModuleSpacing() + - det->GetRing(id)->GetSiThickness()); - TShape* shape = new TTUBE(det->GetName(), det->GetTitle(), "void", - det->GetRing('I')->GetLowR(), rh, w / 2); - Double_t z = (det->GetRingZ('I') - w / 2); - if (z > 0) z += det->GetRing(id)->GetModuleSpacing(); - top->cd(); - TNode* node = new TNode(det->GetName(), det->GetTitle(), shape, - 0, 0, z, 0); - fNodes->Add(node); - - for (Int_t j = 0; j < 2; j++) { - AliFMDRing* r = 0; - TShape* rshape = 0; - TObjArray* rots = 0; - switch (j) { - case 0: - r = det->GetRing('I'); rshape = innerShape; rots = innerRot; break; - case 1: - r = det->GetRing('O'); rshape = outerShape; rots = outerRot; break; - } - if (!r) continue; - - Double_t siThick = r->GetSiThickness(); - Int_t nmod = r->GetNModules(); - Double_t modspace = r->GetModuleSpacing(); - Double_t rz = - (z - det->GetRingZ(r->GetId())); - - for (Int_t k = 0; k < nmod; k++) { - node->cd(); - Double_t offz = (k % 2 == 1 ? modspace : 0); - TRotMatrix* rot = static_cast(rots->At(k)); - TString name(Form("%s%c_module_%02d", det->GetName(), r->GetId(),k)); - TString title(Form("%s%c Module %d", det->GetName(), r->GetId(),k)); - TNode* mnod = new TNode(name.Data(), title.Data(), rshape, - 0, 0, rz - siThick / 2 - + TMath::Sign(offz,z), rot); - mnod->SetLineColor(GetLineColor()); - fNodes->Add(mnod); - } // for (Int_t k = 0 ; ...) - } // for (Int_t j = 0 ; ...) - } // for (Int_t i = 1 ; ...) + 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(); } //____________________________________________________________________ -void -AliFMD::DrawDetector() +void +AliFMD::FinishEvent() { - // - // Draw a shaded view of the Forward multiplicity detector - // - // DebugGuard guard("AliFMD::DrawDetector"); - AliDebug(10, "\tDraw detector"); - -#if 0 - //Set ALIC mother transparent - gMC->Gsatt("ALIC","SEEN",0); - // - 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"); -#endif + // Called at the end of the an event in simulations. If the debug + // level is high enough, then the `bad' hits are printed. + // + if (AliLog::GetDebugLevel("FMD", "AliFMD") < 10) return; + if (fBad && fBad->GetEntries() > 0) { + AliWarning(Form("got %d 'bad' hits", fBad->GetEntries())); + TIter next(fBad); + AliFMDHit* hit; + while ((hit = static_cast(next()))) hit->Print("D"); + fBad->Clear(); + } } -//____________________________________________________________________ -Int_t -AliFMD::DistanceToPrimitive(Int_t, Int_t) -{ - // - // Calculate the distance from the mouse to the FMD on the screen - // Dummy routine - // - return 9999; -} + //==================================================================== // @@ -524,8 +606,6 @@ AliFMD::SetTreeAddress() } } - - //____________________________________________________________________ void AliFMD::SetHitsAddressBranch(TBranch *b) @@ -533,6 +613,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 @@ -576,7 +663,7 @@ AliFMD::AddHit(Int_t track, Int_t *vol, Float_t *hits) } //____________________________________________________________________ -void +AliFMDHit* AliFMD::AddHitByFields(Int_t track, UShort_t detector, Char_t ring, @@ -590,9 +677,10 @@ AliFMD::AddHitByFields(Int_t track, Float_t pz, Float_t edep, Int_t pdg, - Float_t t) + Float_t t, + Float_t l, + Bool_t stop) { - // // Add a hit to the list // // Parameters: @@ -611,6 +699,8 @@ AliFMD::AddHitByFields(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 @@ -618,26 +708,43 @@ AliFMD::AddHitByFields(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; } //____________________________________________________________________ @@ -662,18 +769,22 @@ AliFMD::AddDigit(Int_t* digits, Int_t*) 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[6]), // ADC Count3 + Short_t(digits[7])); } //____________________________________________________________________ void -AliFMD::AddDigitByFields(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 // @@ -688,8 +799,15 @@ AliFMD::AddDigitByFields(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); + } //____________________________________________________________________ @@ -709,26 +827,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 // - 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 + 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::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) +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 // @@ -744,17 +869,23 @@ AliFMD::AddSDigitByFields(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 (%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(); @@ -769,6 +900,8 @@ AliFMD::HitsArray() if (!fHits) { fHits = new TClonesArray("AliFMDHit", 1000); fNhits = 0; + if (gAlice && gAlice->GetMCApp() && gAlice->GetMCApp()->GetHitLists()) + gAlice->GetMCApp()->AddHitList(fHits); } return fHits; } @@ -808,12 +941,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.Digitize(""); } //____________________________________________________________________ @@ -823,17 +953,31 @@ AliFMD::Hits2SDigits() // Create AliFMDSDigit's from AliFMDHit's. This is done by creating // an AliFMDSDigitizer object, and executing it. // - AliFMDSDigitizer* digitizer = new AliFMDSDigitizer("galice.root"); - digitizer->Exec(""); + AliFMDHitDigitizer digitizer(this, AliFMDHitDigitizer::kSDigits); + digitizer.Init(); + digitizer.Digitize(""); } //____________________________________________________________________ AliDigitizer* -AliFMD::CreateDigitizer(AliRunDigitizer* manager) const +AliFMD::CreateDigitizer(AliDigitizationInput* digInput) const { // Create a digitizer object - AliFMDDigitizer* digitizer = new AliFMDDigitizer(manager); + + /* This is what we probably _should_ do */ + AliFMDBaseDigitizer* digitizer = 0; + +#ifdef USE_SSDIGITIZER + digitizer = new AliFMDSSDigitizer(digInput); +#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(digInput); +#endif return digitizer; } @@ -853,6 +997,46 @@ AliFMD::Digits2Raw() writer.Exec(); } +//==================================================================== +// +// Raw data reading +// +//__________________________________________________________________ +Bool_t +AliFMD::Raw2SDigits(AliRawReader* reader) +{ + // 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(); + if (AliLog::GetDebugLevel("FMD", 0) > 5) { + for (UShort_t i = 0; i < ns; i++) + sdigits->At(i)->Print("pl"); + } + AliFMDDebug(1, ("Got a total of %d SDigits", ns)); + + fLoader->TreeS()->Fill(); + ResetSDigits(); + fLoader->WriteSDigits("OVERWRITE"); + + return kTRUE; +} + //==================================================================== // @@ -864,12 +1048,58 @@ AliFMD::Browse(TBrowser* b) { // Browse this object. // - AliDebug(30, "\tBrowsing the FMD"); + AliFMDDebug(30, ("\tBrowsing the FMD")); AliDetector::Browse(b); - if (fSimulator) b->Add(fSimulator); 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