/* $Id$ */
-//////////////////////////////////////////////////////////////////////////////
+//____________________________________________________________________
//
// Forward Multiplicity Detector based on Silicon wafers. This class
// contains the base procedures for the Forward Multiplicity detector
// Many modifications by Christian Holm Christensen <cholm@nbi.dk>
//
-#ifndef ROOT_TClonesArray
-#include <TClonesArray.h>
-#endif
-#ifndef ROOT_TGeomtry
-# include <TGeometry.h>
-#endif
-#ifndef ROOT_TNode
-# include <TNode.h>
-#endif
-#ifndef ROOT_TTUBE
-# include <TTUBE.h>
-#endif
-#ifndef ROOT_TTree
-# include <TTree.h>
-#endif
-#ifndef ROOT_TVirtualMC
-# include <TVirtualMC.h>
-#endif
-#ifndef ROOT_TBrowser
-# include <TBrowser.h>
-#endif
-#ifndef ROOT_TMath
-# include <TMath.h>
-#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 <TClonesArray.h> // ROOT_TClonesArray
+#include <TGeometry.h> // ROOT_TGeomtry
+#include <TNode.h> // ROOT_TNode
+#include <TTUBE.h> // ROOT_TTUBE
+#include <TTree.h> // ROOT_TTree
+#include <TVirtualMC.h> // ROOT_TVirtualMC
+#include <TBrowser.h> // ROOT_TBrowser
+#include <TMath.h> // ROOT_TMath
+
+#include <AliRunDigitizer.h> // ALIRUNDIGITIZER_H
+#include <AliLoader.h> // ALILOADER_H
+#include <AliRun.h> // ALIRUN_H
+#include <AliMC.h> // ALIMC_H
+#include <AliLog.h> // ALILOG_H
+#include <AliMagF.h> // ALIMAGF_H
+#include "AliFMD.h" // ALIFMD_H
+#include "AliFMDDigit.h" // ALIFMDDIGIG_H
+#include "AliFMDHit.h" // ALIFMDHIT_H
+#include "AliFMDDigitizer.h" // ALIFMDDIGITIZER_H
+#include "AliFMD1.h" // ALIFMD1_H
+#include "AliFMD2.h" // ALIFMD2_H
+#include "AliFMD3.h" // ALIFMD3_H
+#include "AliFMDRawWriter.h" // ALIFMDRAWWRITER_H
//____________________________________________________________________
ClassImp(AliFMD);
fOuter(0),
fFMD1(0),
fFMD2(0),
- fFMD3(0)
+ fFMD3(0),
+ fSDigits(0),
+ fNsdigits(0),
+ fPrintboardRotationId(0),
+ fIdentityRotationId(0),
+ fShortLegId(0),
+ fLongLegId(0),
+ fLegLength(0),
+ fLegRadius(0),
+ fModuleSpacing(0),
+ fSiDensity(0),
+ fSiThickness(0),
+ fSiDeDxMip(1.664),
+ fVA1MipRange(0),
+ fAltroChannelSize(0),
+ fSampleRate(0)
{
//
// Default constructor for class AliFMD
AliDebug(0, "Default CTOR");
fHits = 0;
fDigits = 0;
- fSDigits = 0;
- fNsdigits = 0;
fIshunt = 0;
}
+//____________________________________________________________________
+AliFMD::AliFMD(const AliFMD& other)
+ : AliDetector(other),
+ fInner(other.fInner),
+ fOuter(other.fOuter),
+ fFMD1(other.fFMD1),
+ fFMD2(other.fFMD2),
+ fFMD3(other.fFMD3),
+ fSDigits(other.fSDigits),
+ fNsdigits(other.fNsdigits),
+ fPrintboardRotationId(other.fPrintboardRotationId),
+ fIdentityRotationId(other.fIdentityRotationId),
+ fShortLegId(other.fShortLegId),
+ fLongLegId(other.fLongLegId),
+ fLegLength(other.fLegLength),
+ fLegRadius(other.fLegRadius),
+ fModuleSpacing(other.fModuleSpacing),
+ fSiDensity(other.fSiDensity),
+ fSiThickness(other.fSiThickness),
+ fSiDeDxMip(other.fSiDeDxMip),
+ fVA1MipRange(other.fVA1MipRange),
+ fAltroChannelSize(other.fAltroChannelSize),
+ fSampleRate(other.fSampleRate)
+{
+ // Copy constructor
+}
+
//____________________________________________________________________
AliFMD::AliFMD(const char *name, const char *title, bool detailed)
: AliDetector (name, title),
fOuter(0),
fFMD1(0),
fFMD2(0),
- fFMD3(0)
+ fFMD3(0),
+ fSDigits(0),
+ fNsdigits(0),
+ fPrintboardRotationId(0),
+ fIdentityRotationId(0),
+ fShortLegId(0),
+ fLongLegId(0),
+ fLegLength(0),
+ fLegRadius(0),
+ fModuleSpacing(0),
+ fSiDensity(0),
+ fSiThickness(0),
+ fSiDeDxMip(1.664),
+ fVA1MipRange(0),
+ fAltroChannelSize(0),
+ fSampleRate(0)
{
//
// Standard constructor for Forward Multiplicity Detector
SetLegRadius();
SetLegOffset();
SetModuleSpacing();
+ SetSiThickness();
+ SetSiDensity();
+ SetVA1MipRange();
+ SetAltroChannelSize();
+ SetSampleRate();
fInner->SetLowR(4.3);
fInner->SetHighR(17.2);
fInner->SetWaferRadius(13.4/2);
fInner->SetTheta(36/2);
fInner->SetNStrips(512);
- fInner->SetSiThickness(.03);
+ fInner->SetSiThickness(fSiThickness);
fInner->SetPrintboardThickness(.11);
fInner->SetBondingWidth(.5);
fOuter->SetHighR(28.0);
fOuter->SetWaferRadius(13.4/2);
fOuter->SetTheta(18/2);
- fOuter->SetNStrips( 256);
- fOuter->SetSiThickness(.03);
+ fOuter->SetNStrips(256);
+ fOuter->SetSiThickness(fSiThickness);
fOuter->SetPrintboardThickness(.1);
fOuter->SetBondingWidth(.5);
}
}
+//____________________________________________________________________
+AliFMD&
+AliFMD::operator=(const AliFMD& other)
+{
+ AliDetector::operator=(other);
+ fInner = other.fInner;
+ fOuter = other.fOuter;
+ fFMD1 = other.fFMD1;
+ fFMD2 = other.fFMD2;
+ fFMD3 = other.fFMD3;
+ fSDigits = other.fSDigits;
+ fNsdigits = other.fNsdigits;
+ fSiDensity = other.fSiDensity;
+ fPrintboardRotationId = other.fPrintboardRotationId;
+ fIdentityRotationId = other.fIdentityRotationId;
+ fShortLegId = other.fShortLegId;
+ fLongLegId = other.fLongLegId;
+ fLegLength = other.fLegLength;
+ fLegRadius = other.fLegRadius;
+ fModuleSpacing = other.fModuleSpacing;
+ fSiDensity = other.fSiDensity;
+ fSiThickness = other.fSiThickness;
+ fVA1MipRange = other.fVA1MipRange;
+ fAltroChannelSize = other.fAltroChannelSize;
+ fSampleRate = other.fSampleRate;
+
+ return *this;
+}
+
//====================================================================
//
// GEometry ANd Traking
par[0] = fLegRadius - .1;
par[1] = fLegRadius;
par[2] = fLegLength / 2;
- name = "SLEG";
+ name = "FSL";
fShortLegId = gMC->Gsvolu(name.Data(),"TUBE",(*fIdtmed)[kPlasticId],par,3);
par[2] += fModuleSpacing / 2;
- name = "LLEG";
+ name = "FLL";
fLongLegId = gMC->Gsvolu(name.Data(),"TUBE",(*fIdtmed)[kPlasticId],par,3);
fInner->SetupGeometry((*fIdtmed)[kAirId],
fPrintboardRotationId,
fIdentityRotationId);
- fFMD1->SetupGeometry((*fIdtmed)[kAirId], (*fIdtmed)[kKaptionId]);
- fFMD2->SetupGeometry((*fIdtmed)[kAirId], (*fIdtmed)[kKaptionId]);
- fFMD3->SetupGeometry((*fIdtmed)[kAirId], (*fIdtmed)[kKaptionId]);
+ fFMD1->SetupGeometry((*fIdtmed)[kAirId], (*fIdtmed)[kAlId]);
+ fFMD2->SetupGeometry((*fIdtmed)[kAirId], (*fIdtmed)[kAlId]);
+ fFMD3->SetupGeometry((*fIdtmed)[kAirId], (*fIdtmed)[kAlId]);
fFMD1->Geometry("ALIC", fPrintboardRotationId, fIdentityRotationId);
fFMD2->Geometry("ALIC", fPrintboardRotationId, fIdentityRotationId);
AliMedium(kCarbonId, "FMD 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, "FMD Aluminum$", a, z, density, radiationLength,
+ absorbtionLength);
+ AliMedium(kAlId, "FMD Aluminum$", id, 0, fieldType, maxField, maxBending,
+ maxStepSize, maxEnergyLoss, precision, minStepSize);
+
+
// Silicon chip
{
Float_t as[] = { 12.0107, 14.0067, 15.9994,
maxBending, maxStepSize, maxEnergyLoss, precision, minStepSize);
}
-
- // Kaption
+#if 0
+ // Kaption
{
Float_t as[] = { 1.00794, 12.0107, 14.010, 15.9994};
Float_t zs[] = { 1., 6., 7., 8.};
maxStepSize = .001;
precision = .001;
minStepSize = .001;
- id = kKaptionId;
+ id = KaptionId;
AliMixture(id, "FMD Kaption$", as, zs, density, 4, ws);
- AliMedium(kKaptionId, "FMD Kaption$",id,0,fieldType,maxField,maxBending,
+ AliMedium(kAlId, "FMD Kaption$",id,0,fieldType,maxField,maxBending,
maxStepSize,maxEnergyLoss,precision,minStepSize);
}
-
+#endif
+
// Air
{
Float_t as[] = { 12.0107, 14.0067, 15.9994, 39.948 };
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;
+ 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++) std::cout << "*";
- std::cout << std::endl;
+ for (i = 0; i < 80; i++) cout << "*";
+ cout << endl;
}
//
//
}
//____________________________________________________________________
-const Int_t
+Int_t
AliFMD::DistanceToPrimitive(Int_t, Int_t)
{
//
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();
// 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("");
+ AliFMDSDigitizer* digitizer = new AliFMDSDigitizer("galice.root");
+ digitizer->SetSampleRate(fSampleRate);
+ digitizer->SetVA1MipRange(fVA1MipRange);
+ digitizer->SetAltroChannelSize(fAltroChannelSize);
+ digitizer->Exec("");
}
AliFMD::CreateDigitizer(AliRunDigitizer* manager) const
{
// Create a digitizer object
- return new AliFMDDigitizer(manager);
+ AliFMDDigitizer* digitizer = new AliFMDDigitizer(manager);
+ digitizer->SetSampleRate(fSampleRate);
+ digitizer->SetVA1MipRange(fVA1MipRange);
+ digitizer->SetAltroChannelSize(fAltroChannelSize);
+ return digitizer;
}
//====================================================================
{
// 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<AliFMD*>(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<AliFMDDigit*>(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.SetSampleRate(fSampleRate);
+ writer.Exec();
}
//==================================================================