#include <TBrowser.h> // ROOT_TBrowser
#include <TMath.h> // ROOT_TMath
#include <TVirtualMC.h> // ROOT_TVirtualMC
+#include <TVector2.h>
+#include <TVector3.h>
+#include <TMarker3DBox.h>
#include <AliRunDigitizer.h> // ALIRUNDIGITIZER_H
#include <AliLoader.h> // ALILOADER_H
#include "AliFMDDetector.h" // ALIFMDDETECTOR_H
#include "AliFMDRing.h" // ALIFMDRING_H
#include "AliFMDDigitizer.h" // ALIFMDDIGITIZER_H
-#ifdef USE_PRE_MOVE
-#include "AliFMDSimulator.h" // ALIFMDSIMULATOR_H
-#include "AliFMDG3Simulator.h" // ALIFMDG3SIMULATOR_H
-#include "AliFMDGeoSimulator.h" // ALIFMDGEOSIMULATOR_H
-#include "AliFMDG3OldSimulator.h" // ALIFMDG3OLDSIMULATOR_H
-#include "AliFMDGeoOldSimulator.h" // ALIFMDGEOOLDSIMULATOR_H
-#else
-#include "AliFMDGeometryBuilderSimple.h"
-#endif
+#include "AliPoints.h" // ALIPOINTS_H
+#include "AliFMDGeometryBuilder.h"
#include "AliFMDRawWriter.h" // ALIFMDRAWWRITER_H
-#include <TVector2.h>
+
+
+class AliFMDPoints : public AliPoints
+{
+public:
+ AliFMDPoints(AliFMDHit* hit, UInt_t color)
+ : AliPoints(1), fMarker(0)
+ {
+ if (!hit) return;
+ Float_t size = TMath::Min(TMath::Max(hit->Edep() * .1, .1), 1.);
+ TVector3 p(hit->Px(), hit->Py(), hit->Pz());
+ fMarker = new TMarker3DBox(hit->X(), hit->Y(), hit->Z(), size, size, size,
+ p.Theta(), p.Phi());
+ fMarker->SetLineColor(color);
+ fMarker->SetRefObject(this);
+ fP[0] = hit->X();
+ fP[1] = hit->Y();
+ fP[2] = hit->Z();
+ }
+ ~AliFMDPoints()
+ {
+ // if (fMarker) delete fMarker;
+ }
+ void SetXYZ(Double_t x, Double_t y, Double_t z)
+ {
+ if (fMarker) fMarker->SetPosition(x, y, z);
+ }
+ Int_t DistancetoPrimitive(Int_t px, Int_t py)
+ {
+ return fMarker->DistancetoPrimitive(px, py);
+ }
+ void Draw(Option_t* option)
+ {
+ if (fMarker) fMarker->Draw(option);
+ }
+ void Paint(Option_t* option)
+ {
+ if (fMarker) fMarker->Paint(option);
+ }
+ void SetMarkerColor(Color_t colour)
+ {
+ if (fMarker) fMarker->SetLineColor(colour);
+ }
+private:
+ TMarker3DBox* fMarker;
+};
+
//____________________________________________________________________
ClassImp(AliFMD)
fSDigits(0),
fNsdigits(0),
fDetailed(kTRUE),
-#ifdef USE_PRE_MOVE
- fSimulator(0),
-#endif
fBad(0)
{
//
fSDigits(other.fSDigits),
fNsdigits(other.fNsdigits),
fDetailed(other.fDetailed),
-#ifdef USE_PRE_MOVE
- fSimulator(other.fSimulator),
-#endif
fBad(other.fBad)
{
// Copy constructor
fSDigits(0),
fNsdigits(0),
fDetailed(kTRUE),
-#ifdef USE_PRE_MOVE
- fSimulator(0),
-#endif
fBad(0)
{
//
fSDigits = other.fSDigits;
fNsdigits = other.fNsdigits;
fDetailed = other.fDetailed;
-#ifdef USE_PRE_MOVE
- fSimulator = other.fSimulator;
-#endif
fBad = other.fBad;
return *this;
}
// AliFMDSubDetector::Geomtry();
// END FOR
//
-#ifndef USE_PRE_MOVE
AliFMDGeometry* fmd = AliFMDGeometry::Instance();
- if (fUseOld) fmd->SetBuilder(new AliFMDGeometryBuilderSimple(fDetailed));
fmd->SetDetailed(fDetailed);
fmd->UseAssembly(fUseAssembly);
fmd->Build();
-#else
- if (!fSimulator) {
- AliFatal("Simulator object not made yet!");
- return;
- }
- fSimulator->DefineGeometry();
-#endif
}
//____________________________________________________________________
return;
}
#endif
-#ifndef USE_PRE_MOVE
Int_t id;
Double_t a = 0;
Double_t z = 0;
AliMedium(kPlasticId, "Plastic$", id,0,fieldType,maxField,maxBending,
maxStepSize,maxEnergyLoss,precision,minStepSize);
}
-#else
- AliDebug(10, "\tCreating materials");
-
- if (fSimulator) {
- AliFatal("Simulator object already instantised!");
- return;
- }
- TVirtualMC* mc = TVirtualMC::GetMC();
-
- Bool_t geo = mc->IsRootGeometrySupported();
- if (geo) {
- if (fUseOld)
- fSimulator = new AliFMDGeoOldSimulator(this, fDetailed);
- else
- fSimulator = new AliFMDGeoSimulator(this, fDetailed);
- }
- else {
- if (fUseOld)
- fSimulator = new AliFMDG3OldSimulator(this, fDetailed);
- else
- fSimulator = new AliFMDG3Simulator(this, fDetailed);
- }
- AliDebug(1, Form("using a %s as simulation backend",
- fSimulator->IsA()->GetName()));
- fSimulator->SetDetailed(fDetailed);
- fSimulator->UseAssembly(fUseAssembly);
- fSimulator->DefineMaterials();
-#endif
}
//____________________________________________________________________
void
AliFMD::Init()
-{}
+{
+ AliDebug(1, "Initialising FMD detector object");
+ AliFMDGeometry* fmd = AliFMDGeometry::Instance();
+ fmd->InitTransformations();
+}
//____________________________________________________________________
void
AliFMD::FinishEvent()
{
-#ifndef USE_PRE_MOVE
+ 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<AliFMDHit*>(next())))
- hit->Print("D");
+ while ((hit = static_cast<AliFMDHit*>(next()))) hit->Print("D");
fBad->Clear();
}
-#else
- if (fSimulator) fSimulator->EndEvent();
-#endif
}
} // for (Int_t i = 1 ; ...)
}
+//____________________________________________________________________
+void
+AliFMD::LoadPoints(Int_t /* track */)
+{
+ //
+ // Store x, y, z of all hits in memory
+ //
+ if (!fHits) {
+ AliError(Form("fHits == 0. Name is %s",GetName()));
+ return;
+ }
+ Int_t nHits = fHits->GetEntriesFast();
+ if (nHits == 0) {
+ return;
+ }
+ Int_t tracks = gAlice->GetMCApp()->GetNtrack();
+ if (fPoints == 0) fPoints = new TObjArray(2 * tracks);
+
+ // Get geometry
+ AliFMDGeometry* geom = AliFMDGeometry::Instance();
+ geom->Init();
+ geom->InitTransformations();
+
+ // Now make markers for each hit
+ // AliInfo(Form("Drawing %d hits (have %d points) for track %d",
+ // nHits, fPoints->GetEntriesFast(), track));
+ for (Int_t ihit = 0; ihit < nHits; ihit++) {
+ AliFMDHit* hit = static_cast<AliFMDHit*>(fHits->At(ihit));
+ if (!hit) continue;
+ Double_t edep = hit->Edep();
+ Double_t m = hit->M();
+ Double_t poverm = (m == 0 ? 0 : hit->P());
+ Double_t absQ = TMath::Abs(hit->Q());
+ Bool_t bad = kFALSE;
+ // This `if' is to debug abnormal energy depositions. We trigger on
+ // p/m approx larger than or equal to a MIP, and a large edep - more
+ // than 1 keV - a MIP is 100 eV.
+ if (edep > absQ * absQ && poverm > 1) bad = kTRUE;
+
+ AliFMDPoints* p1 = new AliFMDPoints(hit, GetMarkerColor());
+ // AliPoints* p1 = new AliPoints();
+ // p1->SetMarkerColor(GetMarkerColor());
+ // p1->SetMarkerSize(GetMarkerSize());
+ // p1->SetPoint(0, hit->X(), hit->Y(), hit->Z());
+ p1->SetDetector(this);
+ p1->SetParticle(hit->GetTrack());
+ fPoints->AddAt(p1, hit->GetTrack());
+ if (bad) {
+ p1->SetMarkerColor(4);
+ // p1->SetMarkerSize(2 * GetMarkerSize());
+ }
+
+ Double_t x, y, z;
+ geom->Detector2XYZ(hit->Detector(), hit->Ring(), hit->Sector(),
+ hit->Strip(), x, y, z);
+ AliFMDPoints* p = new AliFMDPoints(hit, 3);
+ // AliPoints* p = new AliPoints();
+ // p->SetMarkerColor(3);
+ // p->SetMarkerSize(GetMarkerSize());
+ // p->SetPoint(0, x, y, z);
+ p->SetDetector(this);
+ p->SetParticle(hit->GetTrack());
+ p->SetXYZ(x, y, z);
+ p->SetMarkerColor(3);
+ fPoints->AddAt(p, tracks+hit->GetTrack());
+ if (bad) {
+ p->SetMarkerColor(5);
+ // p->SetMarkerSize(2 * GetMarkerSize());
+ }
+ // AliInfo(Form("Adding point at %d", tracks+hit->GetTrack()));
+ }
+}
+
//____________________________________________________________________
void
AliFMD::DrawDetector()
//
AliDebug(30, "\tBrowsing the FMD");
AliDetector::Browse(b);
-#ifdef USE_PRE_MOVE
- if (fSimulator) b->Add(fSimulator);
-#endif
b->Add(AliFMDGeometry::Instance());
}
class TBranch;
class TClonesArray;
class TBrowser;
+class TMarker3DBox;
class AliDigitizer;
-#ifdef USE_PRE_MOVE
-class AliFMDSimulator;
-#endif
class AliFMDHit;
//____________________________________________________________________
virtual void BuildGeometry();
virtual void DrawDetector();
virtual Int_t DistanceToPrimitive(Int_t px, Int_t py);
-
+ virtual void LoadPoints(Int_t track);
+
// Hit and digit management
virtual void MakeBranch(Option_t *opt=" ");
virtual void SetHitsAddressBranch(TBranch *b);
kKaptonId // ID index of Kapton Medium
};
-#ifdef USE_PRE_MOVE
- AliFMDSimulator* fSimulator; // Simulator task
-#endif
TObjArray* fBad; //! debugging - bad hits
ClassDef(AliFMD,11) // Base class FMD entry point
+++ /dev/null
-/**************************************************************************
- * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
- * *
- * Author: The ALICE Off-line Project. *
- * Contributors are mentioned in the code where appropriate. *
- * *
- * Permission to use, copy, modify and distribute this software and its *
- * documentation strictly for non-commercial purposes is hereby granted *
- * without fee, provided that the above copyright notice appears in all *
- * copies and that both the copyright notice and this permission notice *
- * appear in the supporting documentation. The authors make no claims *
- * about the suitability of this software for any purpose. It is *
- * provided "as is" without express or implied warranty. *
- **************************************************************************/
-
-/* $Id$ */
-
-/////////////////////////////////////////////////////////////////////
-// //
-// Forward Multiplicity detector based on Silicon version 0 //
-//
-//Begin Html
-/*
- <img src="gif/AliFMDv0Class.gif">
-*/
-//End Html
-// //
-// //
-//////////////////////////////////////////////////////////////////////
-
-#include <Riostream.h>
-#include <stdlib.h>
-
-#include <TClonesArray.h>
-#include <TDirectory.h>
-#include <TFile.h>
-#include <TGeometry.h>
-#include <TLorentzVector.h>
-#include <TMath.h>
-#include <TNode.h>
-#include <TTUBE.h>
-#include <TTree.h>
-#include <TVirtualMC.h>
-#include <TDatabasePDG.h>
-#include <AliFMDHit.h>
-#include "AliFMDv0.h"
-#include "AliFMDAlla.h"
-#include "AliFMDDigitizerAlla.h"
-#include "AliMagF.h"
-#include "AliRun.h"
-#include "AliMC.h"
-
-ClassImp(AliFMDAlla)
-#if 0
- ;
-#endif
-
-//--------------------------------------------------------------------
-AliFMDAlla::AliFMDAlla(const char *name, const char *title)
- : AliFMD(name,title)
-{
- //
- // Standart constructor for Forward Multiplicity Detector version 0
- //
- fIdSens1=0;
- fIdSens2=0;
- fIdSens3=0;
- fIdSens4=0;
- fIdSens5=0;
- // setBufferSize(128000);
-}
-//-------------------------------------------------------------------------
-void
-AliFMDAlla::CreateGeometry()
-{
- //
- // Create the geometry of Forward Multiplicity Detector version 0
- //
- //Detector consists of 6 volumes:
- // 1st covered pseudorapidity interval from 3.3 to 2.0
- // and placed on 65cm in Z-direction;
- // 2nd - from 2.0 to 1.6 and Z=85 cm;
- // 3d - the same pseudorapidity interval as the 1st
- // but on the other side from the interaction point z=-65cm;
- // 4th - simmetricaly with the 2nd :
- // pseudorapidity from 2.0 to 1.6, Z=-85cm
- // 5th - from 3.6 to 4.7, Z=-270cm
- // 6th - from 4.5 to 5.5 , Z=-630cm.
- // Each part has 400mkm Si (sensetive area, detector itself),
- // 0.75cm of plastic simulated electronics material,
- // Al support ring 2cm thickness and 1cm width placed on
- // the outer radius of each Si disk;
- //
- // begin Html
- /*
- <img src="gif/AliFMDv0.gif">
- */
- //
-
-
-
- Int_t *idtmed = fIdtmed->GetArray();
-
- Int_t ifmd;
- Int_t idrotm[999];
- Float_t zFMD;
- Float_t par[3];
- Float_t ppcon[15];
- Float_t z[5] = {-62.8, -75.2, 83.4, 75.2, 340.};
- Float_t NylonTube[3] = {0.2,0.6,0.45};
- Float_t zPCB = 0.12;
- Float_t zHoneyComb = 0.5;
- Float_t zSi = 0.03;
- Float_t rin[5] = {4.2,15.4,4.2,15.4,4.2};
- Float_t rout[5] = {17.4,28.4,17.4,28.4,17.4};
- Float_t RinHoneyComb[5] = { 5.15,16.4, 5.15,16.4, 5.15};
- Float_t RoutHoneyComb[5] = {20.63,34.92,22.3, 32.02,20.63};
- Float_t zInside;
- Float_t zCooper = 0.01;
- Float_t zChips = 0.01;
- Float_t yNylonTube[5] = {10,20,10,20,10};
-
- char nameFMD[5];
- char nameSi[5];
- char nameSector[5];
- char nameRing[5];
- Char_t nameHoney[5];
- char nameHoneyIn[5];
- char nameHoneyOut[5];
- Char_t namePCB[5];
- char nameCopper[5];
- char nameChips[5];
- char nameG10[5];
- Char_t nameLPCB[5];
- char nameLCopper[5];
- char nameLChips[5];
- char nameGL10[5];
-
- AliMatrix(idrotm[901], 90, 0, 90, 90, 180, 0);
-
-
- // Nylon tubes
- gMC->Gsvolu("GNYL","TUBE", idtmed[1], NylonTube, 3); //support nylon tube
- Float_t wideSupport=zSi+3*zPCB+2*NylonTube[2]+zHoneyComb;
- AliDebug(1, Form("Support width: %f", wideSupport));
-
- for (ifmd=0; ifmd<5; ifmd++) {
- sprintf(nameFMD,"FMD%d",ifmd+1);
- ppcon[0]=0;
- ppcon[1]=360;
- ppcon[2]=4;
-
- ppcon[3]=-wideSupport;
- ppcon[4]=rin[ifmd]-0.1;
- ppcon[5]=rout[ifmd]+0.1;
-
- ppcon[6]=ppcon[3]+2*zSi+2*zPCB+2*NylonTube[2];
- ppcon[7]=rin[ifmd]-0.1;
- ppcon[8]=rout[ifmd]+0.1;
-
- ppcon[9]=ppcon[6];
- ppcon[10]=RinHoneyComb[ifmd]-0.1;
- ppcon[11]=RoutHoneyComb[ifmd]+0.1;
-
- ppcon[12]=ppcon[9]+2*zHoneyComb+zPCB;
- ppcon[13]=RinHoneyComb[ifmd]-0.1;
- ppcon[14]=RoutHoneyComb[ifmd]+0.1;
- gMC->Gsvolu(nameFMD,"PCON",idtmed[0],ppcon,15);
- if (z[ifmd] >0){
- zFMD=z[ifmd]+wideSupport;
- gMC->Gspos(nameFMD,1,"ALIC",0,0,zFMD,0, "ONLY");}
- else {
- zFMD=z[ifmd]-wideSupport;
- gMC->Gspos(nameFMD,1,"ALIC",0,0,zFMD,idrotm[901], "ONLY");}
-
- //silicon
- sprintf(nameSi,"GSI%d",ifmd+1);
- sprintf(nameSector,"GSC%d",ifmd+1);
- sprintf(nameRing,"GRN%d",ifmd+1);
-
- //honeycomb support
- sprintf(nameHoney,"GSU%d",ifmd+1);
- gMC->Gsvolu(nameHoney,"TUBE", idtmed[0], par, 0); //honeycomb
- sprintf(nameHoneyIn,"GHI%d",ifmd+1);
- gMC->Gsvolu(nameHoneyIn,"TUBE", idtmed[7], par, 0); //honey comb inside
- sprintf(nameHoneyOut,"GHO%d",ifmd+1);
- gMC->Gsvolu(nameHoneyOut,"TUBE", idtmed[6], par, 0); //honey comb skin
-
- //PCB
- sprintf(namePCB,"GPC%d",ifmd+1);
- gMC->Gsvolu(namePCB,"TUBE", idtmed[0], par, 0); //PCB
- sprintf(nameCopper,"GCO%d",ifmd+1);
- gMC->Gsvolu(nameCopper,"TUBE", idtmed[3], par, 0); // Cooper
- sprintf(nameChips,"GCH%d",ifmd+1);
- gMC->Gsvolu(nameChips,"TUBE", idtmed[5], par, 0); // Si chips
- sprintf(nameG10,"G10%d",ifmd+1);
- gMC->Gsvolu(nameG10,"TUBE", idtmed[2], par, 0); //G10 plate
-
- //last PCB
- sprintf(nameLPCB,"GPL%d",ifmd+1);
- gMC->Gsvolu(nameLPCB,"TUBE", idtmed[0], par, 0); //PCB
- sprintf(nameLCopper,"GCL%d",ifmd+1);
- gMC->Gsvolu(nameLCopper,"TUBE", idtmed[3], par, 0); // Cooper
- sprintf(nameLChips,"GHL%d",ifmd+1);
- gMC->Gsvolu(nameLChips,"TUBE", idtmed[5], par, 0); // Si chips
- sprintf(nameGL10,"G1L%d",ifmd+1);
- gMC->Gsvolu(nameGL10,"TUBE", idtmed[2], par, 0); // Last G10
- par[0]=rin[ifmd]; // pipe size
- par[1]=rout[ifmd];
- par[2]=zSi/2;
- gMC->Gsvolu(nameSi,"TUBE", idtmed[4], par, 3);
- zInside=ppcon[3]+par[2];
- gMC->Gspos(nameSi,ifmd+1,nameFMD,0,0,zInside,0, "ONLY");
-
- //PCB 1
- zInside += par[2]+zPCB/2;
- par[2]=zPCB/2;
- gMC->Gsposp(namePCB,1,nameFMD,0,0,zInside,0, "ONLY",par,3);
- zInside += zPCB;
- gMC->Gsposp(namePCB,2,nameFMD,0,0,zInside,0, "ONLY",par,3);
- Float_t NulonTubeBegin=zInside+2.5*zPCB;
- par[2]=zPCB/2-0.02;
- Float_t zInPCB = -zPCB/2+par[2];
- gMC->Gsposp(nameG10,1,namePCB,0,0,zInPCB,0, "ONLY",par,3);
- zInPCB+=par[2]+zCooper/2 ;
- par[2]=zCooper/2;
- gMC->Gsposp(nameCopper,1,namePCB,0,0,zInPCB,0, "ONLY",par,3);
- zInPCB += zCooper/2 + zChips/2;
- par[2]=zChips/2;
- gMC->Gsposp(nameChips,1,namePCB,0,0,zInPCB,0, "ONLY",par,3);
-
- //HoneyComb
- zHoneyComb=0.8;
- par[0] = RinHoneyComb[ifmd];
- par[1] = RoutHoneyComb[ifmd];
- par[2] = zHoneyComb/2;
- zInside += 2*NylonTube[2]+par[2];
- gMC->Gsposp(nameHoney,1,nameFMD,0,0,zInside,0, "ONLY",par,3);
- par[2]=0.1/2;
- Float_t zHoney=-zHoneyComb/2+par[2];
- gMC->Gsposp(nameHoneyOut,1,nameHoney,0,0,zHoney,0,
- "ONLY",par,3); //shkurki
- zHoney=zHoneyComb/2-par[2];
- gMC->Gsposp(nameHoneyOut,2,nameHoney,0,0,zHoney,0, "ONLY",par,3);
- par[2]=(zHoneyComb-2.*0.1)/2; //soty vnutri
- gMC->Gsposp(nameHoneyIn,1,nameHoney,0,0,0,0, "ONLY",par,3);
-
- gMC->Gspos("GNYL",1,nameFMD,0,yNylonTube[ifmd],
- NulonTubeBegin+NylonTube[2]/2.,0, "ONLY");
- gMC->Gspos("GNYL",2,nameFMD,0,-yNylonTube[ifmd],
- NulonTubeBegin+NylonTube[2]/2.,0, "ONLY");
-
- //last PCB
- par[0]=RoutHoneyComb[ifmd]-9;
- par[1]=RoutHoneyComb[ifmd];
- par[2]=zPCB/2;
- zInside += zHoneyComb/2+par[2];
- gMC->Gsposp(nameLPCB,1,nameFMD,0,0,zInside,0, "ONLY",par,3);
-
- par[2]=zPCB/2-0.02;
- zInPCB = -zPCB/2+par[2];
- gMC->Gsposp(nameGL10,1,nameLPCB,0,0,zInPCB,0, "ONLY",par,3);
- zInPCB+=par[2]+zCooper/2 ;
- par[2]=zCooper/2;
- gMC->Gsposp(nameLCopper,1,nameLPCB,0,0,zInPCB,0, "ONLY",par,3);
- zInPCB += zCooper/2 + zChips/2;
- par[2]=zChips/2;
- gMC->Gsposp(nameLChips,1,nameLPCB,0,0,zInPCB,0, "ONLY",par,3);
-
-
- //Granularity
- fSectorsSi1 = 20;
- fRingsSi1 = 256 * 2;
- // fRingsSi1=3; // for drawing only
- fSectorsSi2 = 40;
- fRingsSi2 = 128 * 2;
- // fRingsSi2=3; //for drawing onl
- if(ifmd==1||ifmd==3) {
- gMC->Gsdvn(nameSector, nameSi , fSectorsSi2, 2);
- gMC->Gsdvn(nameRing, nameSector, fRingsSi2, 1);
- }
- else {
- gMC->Gsdvn(nameSector, nameSi , fSectorsSi1, 2);
- gMC->Gsdvn(nameRing, nameSector , fRingsSi1, 1);
- }
- }
-}
-
-
-//------------------------------------------------------------------------
-void
-AliFMDAlla::CreateMaterials()
-{
- Int_t isxfld = gAlice->Field()->Integ();
- Float_t sxmgmx = gAlice->Field()->Max();
-
- // Plastic CH
- Float_t aPlastic[2]={1.01,12.01};
- Float_t zPlastic[2]={1,6};
- Float_t wPlastic[2]={1,1};
- Float_t denPlastic=1.03;
- //
- // 60% SiO2 , 40% G10FR4
- // PC board
- Float_t apcb[3] = { 28.0855,15.9994,17.749 };
- Float_t zpcb[3] = { 14.,8.,8.875 };
- Float_t wpcb[3] = { .28,.32,.4 };
- Float_t denspcb = 1.8;
- //
- // AIR
- Float_t aAir[4] = {12.0107,14.0067,15.9994,39.948};
- Float_t zAir[4] = {6.,7.,8.,18.};
- Float_t wAir[4] = {0.000124,0.755267,0.231781,0.012827};
- Float_t dAir = 1.20479E-3;
- //*** Definition Of avaible FMD materials ***
- AliMixture(0, "FMD Air$", aAir, zAir, dAir, 4,wAir);
- AliMixture(1, "Plastic$",aPlastic,zPlastic,denPlastic,-2,wPlastic);
- AliMixture(2, "SSD PCB$", apcb, zpcb, denspcb, 3, wpcb);
- AliMaterial(3, "SSD Copper$", 63.546, 29., 8.96, 1.43, 999.);
- AliMaterial(4, "SSD Si$", 28.0855, 14., 2.33, 9.36, 999.);
- AliMaterial(5, "SSD Si chip$", 28.0855, 14., 2.33, 9.36, 999.);
- AliMaterial(6, "SSD C$", 12.011, 6., 2.265,18.8, 999.);
- AliMaterial(7, "SSD Kapton$", 12.011, 6., 0.01, 31.27, 999.);//honeycomb
- AliMaterial(8, "SSD G10FR4$", 17.749, 8.875, 1.8, 21.822, 999.);
-
-
- //**
- AliMedium(0, "FMD air$", 0, 0, isxfld, sxmgmx, 1., .001, 1., .001, .001);
- AliMedium(1, "Plastic$", 1, 0,isxfld, sxmgmx, 10., .01, 1., .003, .003);
- AliMedium(2, "SSD PCB$", 2, 0, isxfld, sxmgmx, 1., .001, 1., .001, .001);
- AliMedium(3, "SSD Copper$", 3, 0,isxfld, sxmgmx, 10., .01, 1., .003, .003);
- AliMedium(4, "SSD Si$", 4, 1, isxfld, sxmgmx, 1., .001, 1., .001, .001);
- AliMedium(5, "SSD Si chip$", 5, 0,isxfld, sxmgmx, 10., .01, 1., .003, .003);
- AliMedium(6, "SSD C$", 6, 0,isxfld, sxmgmx, 10., .01, 1., .003, .003);
- AliMedium(7, "SSD Kapton$", 7, 0, isxfld, sxmgmx, 1., .001, 1., .001, .001);
- AliMedium(8, "SSD G10FR4$", 8, 0,isxfld, sxmgmx, 10., .01, 1., .003, .003);
-
-
-
-}
-//---------------------------------------------------------------------
-void
-AliFMDAlla::DrawDetector()
-{
- //
- // Draw a shaded view of the Forward multiplicity detector version 0
- //
-
- //Set ALIC mother transparent
- gMC->Gsatt("ALIC","SEEN",0);
- //
- //Set volumes visible
- gMC->Gsatt("FMD1","SEEN",1);
- gMC->Gsatt("FMD2","SEEN",1);
- gMC->Gsatt("FMD3","SEEN",1);
- gMC->Gsatt("FMD4","SEEN",1);
- gMC->Gsatt("FMD5","SEEN",1);
-
- //
- gMC->Gdopt("hide","on");
- gMC->Gdopt("shad","on");
- gMC->SetClipBox(".");
- gMC->SetClipBox("*",0,1000,-1000,1000,-1000,1000);
- gMC->DefaultRange();
- gMC->Gdraw("alic",40,30,0,12,9.5,.2,0.2);
- gMC->Gdhead(1111,"Forward multiplicity detector");
- gMC->Gdopt("hide","off");
-}
-//-------------------------------------------------------------------
-void
-AliFMDAlla::Init()
-{
- // Initialises version 0 of the Forward Multiplicity Detector
- //
- AliFMD::Init();
- fIdSens1=gMC->VolId("GRN1");
- fIdSens2=gMC->VolId("GRN2");
- fIdSens3=gMC->VolId("GRN3");
- fIdSens4=gMC->VolId("GRN4");
- fIdSens5=gMC->VolId("GRN5");
- printf("*** FMD version 1 initialized ***\n");
-}
-
-//-------------------------------------------------------------------
-void
-AliFMDAlla::StepManager()
-{
- //
- // Called for every step in the Forward Multiplicity Detector
- //
- Int_t id,copy,copy1,copy2;
- static Float_t hits[9];
- static Int_t vol[3];
- static Float_t de;
- static TLorentzVector pos;
- static TLorentzVector mom;
- static Int_t iPart;
-
- TClonesArray &lhits = *fHits;
- if(!gMC->IsTrackAlive()) return; // particle has disappeared
-
- Float_t charge = gMC->TrackCharge();
- if(TMath::Abs(charge)<=0.) return; //take only charged particles
-
- // printf(" in StepManeger \n");
- id=gMC->CurrentVolID(copy);
- //((TGeant3*)gMC)->Gpcxyz();
-
- // Check the sensetive volume
- if(id==fIdSens1||id==fIdSens2||id==fIdSens3||id==fIdSens4||id==fIdSens5) {
-
- if(gMC->IsTrackEntering()) {
- vol[2]=copy-1;
- gMC->CurrentVolOffID(1,copy1);
- vol[1]=copy1;
- gMC->CurrentVolOffID(2,copy2);
- vol[0]=copy2;
-
- gMC->TrackPosition(pos);
- hits[0]=pos[0];
- hits[1]=pos[1];
- hits[2]=pos[2];
-
- gMC->TrackMomentum(mom);
- hits[3]=mom[0];
- hits[4]=mom[1];
- hits[5]=mom[2];
-
- iPart= gMC->TrackPid();
- Int_t partId=gMC->IdFromPDG(iPart);
- hits[7]=partId;
- hits[8]=1e9*gMC->TrackTime();
- de=0.;
- }
- Float_t edep = 1000 * gMC->Edep();
- Float_t p = mom.P();
- TParticlePDG* pdg = TDatabasePDG::Instance()->GetParticle(iPart);
- Float_t mass = pdg ? pdg->Mass() : 1;
- if (edep > 1 && p/mass > 1) {
- TArrayI procs;
- gMC->StepProcesses(procs);
- TString processes;
- for (Int_t ip = 0; ip < procs.fN; ip++) {
- if (ip != 0) processes.Append(",");
- processes.Append(TMCProcessName[procs.fArray[ip]]);
- }
- TString what;
- if (gMC->IsTrackEntering()) what.Append("entering ");
- if (gMC->IsTrackExiting()) what.Append("exiting ");
- if (gMC->IsTrackInside()) what.Append("inside ");
- if (gMC->IsTrackDisappeared()) what.Append("disappeared ");
- if (gMC->IsTrackStop()) what.Append("stopped ");
- if (gMC->IsNewTrack()) what.Append("new ");
- if (gMC->IsTrackAlive()) what.Append("alive ");
- if (gMC->IsTrackOut()) what.Append("out ");
- Int_t trackno = gAlice->GetMCApp()->GetCurrentTrackNumber();
- Int_t mother = gAlice->GetMCApp()->GetPrimary(trackno);
- Warning("StepManager", "Track # %5d deposits a lot of energy\n"
- " Volume: %s\n"
- " Momentum: (%7.4f,%7.4f,%7.4f)\n"
- " PDG: %d (%s)\n"
- " Edep: %-14.7f keV (mother %d)\n"
- " p/m: %-7.4f/%-7.4f = %-14.7f\n"
- " Processes: %s\n"
- " What: %s\n",
- trackno, gMC->CurrentVolPath(), mom.X(), mom.Y(), mom.Z(),
- iPart, (pdg ? pdg->GetName() : ""), edep, mother, mom.P(), mass,
- mom.P()/mass, processes.Data(), what.Data());
- }
-
- if(gMC->IsTrackInside()) de=de+1000.*gMC->Edep();
-
- if(gMC->IsTrackExiting() ||gMC->IsTrackDisappeared()|| gMC->IsTrackStop()){
- hits[6]=de+1000.*gMC->Edep();
- UShort_t detector = vol[0] / 2 + 1;
- Char_t ring = (vol[0] % 2) == 0 ? 'I' : 'O';
- UShort_t sector = vol[1];
- UShort_t strip = vol[2];
- gMC->TrackPosition(pos);
- TVector3 cur(pos.Vect());
- TVector3 old(hits[0], hits[1], hits[2]);
- cur -= old;
- Double_t len = cur.Mag();
- AliFMDHit* h = new(lhits[fNhits++])
- AliFMDHit(fIshunt,
- gAlice->GetMCApp()->GetCurrentTrackNumber(),
- detector, ring, sector, strip,
- hits[0], hits[1], hits[2], hits[3], hits[4], hits[5],
- hits[6], iPart, hits[8], len,
- gMC->IsTrackDisappeared()||gMC->IsTrackStop());
- if (hits[6] > 1 && p/mass > 1) fBad->Add(h);
- } // IsTrackExiting()
- }
-}
-//--------------------------------------------------------------------------
-void
-AliFMDAlla::Response(Float_t Edep)
-{
- Float_t I=1.664*0.04*2.33/22400; // = 0.69e-6;
- Float_t chargeOnly=Edep/I;
- //Add noise ~500electrons
- Int_t charge=500;
- if (Edep>0)
- charge=Int_t(gRandom->Gaus(chargeOnly,500));
-}
-
-//____________________________________________________________________
-AliDigitizer*
-AliFMDAlla::CreateDigitizer(AliRunDigitizer* manager) const
-{
- // Create a digitizer object
- AliFMDDigitizerAlla* digitizer = new AliFMDDigitizerAlla(manager);
- return digitizer;
-}
-//--------------------------------------------------------------------------
-//
-// EOF
-//
-
-
-
-
-
+++ /dev/null
-#ifndef ALIFMDALLA_H
-#define ALIFMDALLA_H
-/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
- * See cxx source for full Copyright notice */
-
-///////////////////////////////////////////////
-// Manager and hits classes for set:FMD //
-////////////////////////////////////////////////
-
-#include "AliFMD.h"
-
-class AliFMDAlla : public AliFMD {
-
-public:
- AliFMDAlla() {};
- AliFMDAlla(const char *name, const char *title);
- virtual ~AliFMDAlla() {}
- virtual void CreateGeometry();
- virtual void CreateMaterials();
- virtual void DrawDetector();
- virtual void Init();
- virtual Int_t IsVersion() const {return 1;}
- virtual void StepManager();
- // virtual void Hit2Digits(Int_t bgrEvent, Option_t *opt1=" ",
- // Option_t *opt2=" ",Text_t *name=" "); // hit to digit for v1 :test
- virtual void Response( Float_t Edep);
- //private:
- //Int_t fCharge;
- AliDigitizer* CreateDigitizer(AliRunDigitizer* manager) const;
-protected:
- Int_t fIdSens1; // Sensetive volume in FMD
- Int_t fIdSens2; // Sensetive volume in FMD
- Int_t fIdSens3; // Sensetive volume in FMD
- Int_t fIdSens4; // Sensetive volume in FMD
- Int_t fIdSens5; // Sensetive volume in FMD
- Int_t fSectorsSi1;
- Int_t fSectorsSi2;
- Int_t fRingsSi1;
- Int_t fRingsSi2;
-
-
-// Background event for event mixing
-
- ClassDef(AliFMDAlla,2) //Class for FMD version 0
-};
-
-#endif
-//
-// Local Variables:
-// mode: C++
-// End:
-//
-
//
#include "AliFMDDetector.h" // ALIFMDSUBDETECTOR_H
#include "AliFMDRing.h" // ALIFMDRING_H
+#include "AliLog.h" // ALILOG_H
+#include <TGeoManager.h> // ROOT_TGeoManager
+#include <TGeoMatrix.h> // ROOT_TGeoMatrix
+#include <TMath.h> // ROOT_TMath
//====================================================================
ClassImp(AliFMDDetector)
: TNamed(Form("FMD%d", id), "Forward multiplicity ring"),
fId(id),
fInner(inner),
- fOuter(outer)
+ fOuter(outer),
+ fInnerTransforms(0),
+ fOuterTransforms(0)
{
// Constructor
//
: TNamed(other),
fId(other.fId),
fInner(other.fInner),
- fOuter(other.fOuter)
+ fOuter(other.fOuter),
+ fInnerTransforms(other.fInnerTransforms),
+ fOuterTransforms(other.fOuterTransforms)
{
// Copy constructor
SetHoneycombThickness(other.GetHoneycombThickness());
// Assignment operator
SetName(other.GetName());
SetTitle(other.GetTitle());
- fId = other.fId;
- fInner = other.fInner;
- fOuter = other.fOuter;
+ fId = other.fId;
+ fInner = other.fInner;
+ fOuter = other.fOuter;
+ fInnerTransforms = other.fInnerTransforms;
+ fOuterTransforms = other.fOuterTransforms;
SetHoneycombThickness(other.GetHoneycombThickness());
SetAlThickness(other.GetAlThickness());
SetInnerHoneyLowR(other.GetInnerHoneyLowR());
if (fOuter) {
SetOuterHoneyLowR(fOuter->GetLowR() + 1.);
SetOuterHoneyHighR(fOuter->GetHighR() + 1.);
+ }
+}
+
+//____________________________________________________________________
+Bool_t
+AliFMDDetector::HasAllTransforms(Char_t ring) const
+{
+ AliFMDRing* r = GetRing(ring);
+ if (!r) return kTRUE;
+ TObjArray* matricies = (r == fInner ? fInnerTransforms : fOuterTransforms);
+ if (!matricies) return kTRUE;
+ if (matricies->GetEntries() == r->GetNModules()) return kTRUE;
+ return kFALSE;
+}
+
+#define IS_NODE_THIS(name) \
+ (name[0] == 'F' && name[2] == 'M' && name[1] == Char_t(48+fId) && \
+ (name[3] == 'T' || name[3] == 'B'))
+#define IS_NODE_SENSOR(name) \
+ (name[0] == 'F' && name[2] == 'S' && name[3] == 'E')
+
+//____________________________________________________________________
+void
+AliFMDDetector::InitTransformations()
+{
+ if ((!fInner || (fInner && fInnerTransforms)) &&
+ (!fOuter || (fOuter && fOuterTransforms))) {
+ AliDebug(5, Form("Transforms for FMD%d already registered", fId));
+ return;
+ }
+ AliDebug(5, Form("Initializing transforms for FMD%d", fId));
+ if (!gGeoManager) {
+ AliFatal("No TGeoManager defined");
+ return;
+ }
+ TGeoVolume* topVolume = gGeoManager->GetTopVolume();
+ if (!topVolume) {
+ AliFatal("No top-level volume defined");
+ return;
+ }
+ // Make container of transforms
+ if (fInner && !fInnerTransforms)
+ fInnerTransforms = new TObjArray(fInner->GetNModules());
+ if (fOuter && !fOuterTransforms)
+ fOuterTransforms = new TObjArray(fOuter->GetNModules());
+
+ // Make an iterator
+ TGeoIterator next(topVolume);
+ TGeoNode* node = 0;
+
+ // Find the node corresponding to this detector, and then find the
+ // sensor volumes
+ Bool_t thisNodeFound = kFALSE;
+ Bool_t allInners = HasAllTransforms('I');
+ Bool_t allOuters = HasAllTransforms('O');
+
+ while ((node = static_cast<TGeoNode*>(next()))
+ && !(allInners && allOuters)) {
+ // Get nodes names
+ const Char_t* name = node->GetName();
+ if (!name) continue;
+ AliDebug(50, Form("Got volume %s", name));
+ // Check if this node is this detector
+ // The base offset for numbers in the ASCII table is 48
+ if (IS_NODE_THIS(name)) {
+ AliDebug(20, Form("Found detector node '%s' for FMD%d", name, fId));
+ thisNodeFound = kTRUE;
+ }
+ // if the detector was found, then we're on that branch, and we
+ // check if this node represents a module in that branch.
+ if (thisNodeFound && IS_NODE_SENSOR(name)) {
+ AliDebug(20, Form("Found sensor node '%s' for FMD%d", name, fId));
+ // Get the ring Id.
+ Char_t ringid = name[1];
+
+ // Get the approprate ring
+ AliFMDRing* ring = GetRing(ringid);
+ if (!ring) continue;
+
+ // Check whether we have all the modules we need for this ring,
+ // and if so, go on to the next node.
+ Bool_t& done = (ring == fInner ? allInners : allOuters);
+ if ((done = HasAllTransforms(ringid))) {
+ AliDebug(20, Form("Already has all module transforms for ring %c",
+ ringid));
+ continue;
+ }
+
+ // Get the approprate container
+ TObjArray* matricies = (ringid == 'i' || ringid == 'I'
+ ? fInnerTransforms : fOuterTransforms);
+
+ // Get the copy (module) number, and check that it hasn't
+ // already been added to the container.
+ Int_t copy = node->GetNumber();
+ if (matricies->At(copy)) {
+ AliWarning(Form("Have a transformation for module %d in ring %c",
+ copy, ringid));
+ continue;
+ }
+
+ // Get the global transformation matrix, and store it.
+ TGeoMatrix* trans = new TGeoHMatrix(*(next.GetCurrentMatrix()));
+ matricies->AddAt(trans, copy);
+
+ }
}
-
}
//____________________________________________________________________
}
return 0;
}
+
+//____________________________________________________________________
+TGeoMatrix*
+AliFMDDetector::FindTransform(Char_t ring, UShort_t sector) const
+{
+ // Find the transformation that corresponds to sector sector in ring
+ // ring.
+ TObjArray* matricies = 0;
+ switch (ring) {
+ case 'i': case 'I': matricies = fInnerTransforms; break;
+ case 'o': case 'O': matricies = fOuterTransforms; break;
+ }
+ if (!matricies) {
+ AliWarning(Form("Unknown ring %c of FMD%d", ring, fId));
+ return 0;
+ }
+ UInt_t module = sector / 2;
+ TGeoMatrix* m = static_cast<TGeoMatrix*>(matricies->At(module));
+ if (!m) {
+ AliWarning(Form("No matrix found for sector %d in FMD%d%c",
+ sector, fId, ring));
+ return 0;
+ }
+ return m;
+}
+
+
//____________________________________________________________________
void
-AliFMDDetector::Detector2XYZ(Char_t ring,
+AliFMDDetector::Detector2XYZ(Char_t ring,
UShort_t sector,
UShort_t strip,
Double_t& x,
// (x,y,z) coordinates (in global reference frame)
AliFMDRing* r = GetRing(ring);
if (!r) return;
+#if 1
+ TGeoMatrix* m = FindTransform(ring, sector);
+ if (!m) return;
+ Double_t rho = r->GetStripRadius(strip);
+ Double_t phi = ((sector % 2) - .5) * r->GetTheta();
+ Double_t siThick = r->GetSiThickness();
+ Double_t modThick = (siThick
+ + r->GetPrintboardThickness()
+ + r->GetCopperThickness()
+ + r->GetChipThickness()
+ + r->GetSpacing());
+ AliDebug(10,Form("Rho %7.3f, angle %7.3f", rho, phi));
+# define DEGRAD TMath::Pi() / 180.
+ Double_t local[] = { rho * TMath::Cos(phi * DEGRAD),
+ rho * TMath::Sin(phi * DEGRAD),
+ -modThick + siThick / 2 };
+ Double_t master[3];
+ AliDebug(10, Form("Local (%7.3f,%7.3f,%7.3f)",local[0], local[1], local[2]));
+ m->LocalToMaster(local, master);
+ AliDebug(10, Form("Master (%7.3f,%7.3f,%7.3f)",
+ master[0],master[1],master[2]));
+ x = master[0];
+ y = master[1];
+ z = master[2];
+#else
z = GetRingZ(ring);
r->Detector2XYZ(sector, strip, x, y, z);
+#endif
}
//____________________________________________________________________
# include <TNamed.h>
#endif
class AliFMDRing;
+class TGeoMatrix;
//__________________________________________________________________
virtual ~AliFMDDetector() {}
/** Initialize the geometry */
virtual void Init();
-
+ /** Find the transformations that correspond to modules of this
+ detector, and store them in the arrays. */
+ virtual void InitTransformations();
+
/** @param x Detector number */
void SetId(Int_t x) { fId = x; }
/** @param x Position of outer ring along z */
Bool_t XYZ2Detector(Double_t x, Double_t y, Double_t z,
Char_t& ring, UShort_t& sector, UShort_t& strip) const;
protected:
+ Bool_t HasAllTransforms(Char_t ring) const;
+ TGeoMatrix* FindTransform(Char_t ring, UShort_t sector) const;
Int_t fId; // Detector number
Double_t fInnerZ; // Position of outer ring along z
Double_t fOuterZ; // Position of outer ring along z
Double_t fOuterHoneyHighR; // Outer radius of outer honeycomb
AliFMDRing* fInner; // Pointer to inner ring information
AliFMDRing* fOuter; // Pointer to outer ring information
-
+ TObjArray* fInnerTransforms; // List of inner module <-> global
+ TObjArray* fOuterTransforms; // List of outer module <-> global
+
ClassDef(AliFMDDetector, 1); //
};
const char*
AliFMDBaseDigit::GetName() const
{
- return Form("FMD%d%c[%2d,%3d]", fDetector, fRing, fSector, fStrip);
+ static TString n;
+ n = Form("FMD%d%c[%2d,%3d]", fDetector, fRing, fSector, fStrip);
+ return n.Data();
}
//====================================================================
// count3 ADC count (a 10-bit word) -1 if not used
}
+//____________________________________________________________________
+const char*
+AliFMDDigit::GetTitle() const
+{
+ static TString t;
+ t = Form("ADC: %d", Counts());
+ return t.Data();
+}
+
//____________________________________________________________________
void
AliFMDDigit::Print(Option_t* /* option*/) const
Short_t Count3() const { return fCount3; }
UShort_t Counts() const;
void Print(Option_t* opt="") const;
+ const char* GetTitle() const;
protected:
UShort_t fCount1; // Digital signal
Short_t fCount2; // Digital signal (-1 if not used)
+++ /dev/null
- /**************************************************************************
- * Copyright(c) 1998-2000, ALICE Experiment at CERN, All rights reserved. *
- * *
- * Author: The ALICE Off-line Project. *
- * Contributors are mentioned in the code where appropriate. *
- * *
- * Permission to use, copy, modify and distribute this software and its *
- * documentation strictly for non-commercial purposes is hereby granted *
- * without fee, provided that the above copyright notice appears in all *
- * copies and that both the copyright notice and this permission notice *
- * appear in the supporting documentation. The authors make no claims *
- * about the suitability of this software for any purpose. It is *
- * provided "as is" without express or implied warranty. *
- **************************************************************************/
-
- //////////////////////////////////////////////////////////////////////////////
-// //
-// Forward Multiplicity Detector based on Silicon plates //
-// This class contains the procedures simulation ADC signal for //
-// the Forward Multiplicity detector : hits -> digits //
-// ADC signal consists //
-// - number of detector; //
-// - number of ring; //
-// - number of sector; //
-// - ADC signal in this channel //
-// //
- //////////////////////////////////////////////////////////////////////////////
-
-#include <TTree.h>
-#include <TVector.h>
-#include <TObjArray.h>
-#include <TFile.h>
-#include <TDirectory.h>
-#include <TRandom.h>
-#include "AliLog.h"
-#include "AliFMDDigitizerAlla.h"
-#include "AliFMD.h"
-#include "AliFMDHit.h"
-#include "AliFMDDigit.h"
-#include "AliRunDigitizer.h"
-#include "AliRun.h"
-#include "AliLoader.h"
-#include "AliRunLoader.h"
-#include <stdlib.h>
-#include <Riostream.h>
-
-ClassImp(AliFMDDigitizerAlla)
-#if 0
- ;
-#endif
-
-//___________________________________________
-AliFMDDigitizerAlla::AliFMDDigitizerAlla()
- : AliDigitizer()
-{
- // Default ctor - don't use it
-}
-
-//___________________________________________
-AliFMDDigitizerAlla::AliFMDDigitizerAlla(AliRunDigitizer* manager)
- : AliDigitizer(manager)
-{
- // ctor which should be used
- // fDebug =0;
- AliDebug(1," processed");
-}
-
-//------------------------------------------------------------------------
-AliFMDDigitizerAlla::~AliFMDDigitizerAlla()
-{
- // Destructor
-}
-
- //------------------------------------------------------------------------
-Bool_t AliFMDDigitizerAlla::Init()
-{
- // Initialization
- // cout<<"AliFMDDigitizerAlla::Init"<<endl;
- return kTRUE;
-}
-
-
-//---------------------------------------------------------------------
-
-void AliFMDDigitizerAlla::Exec(Option_t * /*option*/)
-{
-
- // Conver hits to digits:
- // - number of detector;
- // - number of ring;
- // - number of sector;
- // - ADC signal in this channel
- AliDebug(1," start...");
- Float_t de[3][2][50][520];
- for (Int_t i=0; i<3; i++)
- for(Int_t j=0; j<2; j++)
- for(Int_t k=0; k < 50; k++)
- for (Int_t l=0; l < 520; l++)
- de[i][j][k][l]=0;
- Int_t nstrips[] = { 512, 256 };
- Int_t nsectors[] = { 20, 40 };
-
- AliRunLoader* outRL =
- AliRunLoader::GetRunLoader(fManager->GetOutputFolderName());
- AliLoader* pOutFMD = outRL->GetLoader("FMDLoader");
-
- AliRunLoader* inRL =
- AliRunLoader::GetRunLoader(fManager->GetInputFolderName(0));
-
- if (!inRL) {
- AliError("Can not find Run Loader for input stream 0");
- return;
- }
- if (!inRL->GetAliRun()) inRL->LoadgAlice();
-
- AliFMD * fFMD = static_cast<AliFMD*>(inRL->GetAliRun()->GetDetector("FMD"));
- if (!fFMD) {
- AliError("Can not get FMD from gAlice");
- return;
- }
-
- // Loop over files to digitize
- Int_t nFiles = GetManager()->GetNinputs();
- for (Int_t inputFile=0; inputFile < nFiles; inputFile++) {
- AliDebug(1,Form("Digitizing event number %d",
- fManager->GetOutputEventNr()));
- if (fFMD) {
- AliRunLoader* inRL =
- AliRunLoader::GetRunLoader(fManager->GetInputFolderName(inputFile));
- AliLoader* pInFMD = inRL->GetLoader("FMDLoader");
- pInFMD->LoadHits("READ");
-
-
- TTree* tH = pInFMD->TreeH();
- if (!tH) {
- pInFMD->LoadHits("read");
- tH = pInFMD->TreeH();
- }
- TBranch* brHits = tH->GetBranch("FMD");
- if (brHits) fFMD->SetHitsAddressBranch(brHits);
- else AliFatal("Branch FMD hit not found");
- TClonesArray *fFMDhits = fFMD->Hits ();
-
- Int_t ntracks = tH->GetEntries();
- for (Int_t track = 0; track < ntracks; track++) {
- brHits->GetEntry(track);
- Int_t nhits = fFMDhits->GetEntries ();
- for (Int_t hit = 0; hit < nhits; hit++) {
- AliFMDHit* fmdHit =
- static_cast<AliFMDHit*>(fFMDhits->UncheckedAt(hit));
- Int_t detector = fmdHit->Detector();
- Int_t iring = fmdHit->Ring() == 'I' ? 0 : 1;
- Int_t sector = fmdHit->Sector();
- Int_t strip = fmdHit->Strip();
- de[detector-1][iring][sector][strip] += fmdHit->Edep();
- } //hit loop
- } //track loop
- } //if FMD
- }
-
-
- // Put noise and make ADC signal
- Float_t mipI = 1.664 * 0.04 * 2.33 / 22400; // = 6.923e-6;
- for (Int_t detector = 1; detector <= 3; detector++){
- for (Int_t iring = 0; iring < 2; iring++) {
- if (detector == 1 && iring == 1) continue;
- char ring = (iring == 0 ? 'I' : 'O');
- for (Int_t sector = 0; sector < nsectors[iring]; sector++) {
- for (Int_t strip = 0; strip < nstrips[iring]; strip++) {
- Int_t signal = Int_t(de[detector-1][iring][sector][strip] / mipI);
- Int_t pedestal = Int_t(gRandom->Gaus(500,250));
- Int_t charge = signal + pedestal;
- if(charge <= 500) charge = 500;
- //dynamic range from MIP(0.155MeV) to 30MIP(4.65MeV)
- //1024 ADC channels
- Float_t channelWidth = (22400 * 50) / 1024;
- Int_t adc = Int_t(charge / channelWidth);
- if (adc > 1023) adc = 1023;
- fFMD->AddDigitByFields(detector, ring, sector, strip, adc);
- } //strip
- } //sector
- } //iring
- } // detector
-
- pOutFMD->LoadDigits("update");
- TTree* treeD = pOutFMD->TreeD();
- if (!treeD) {
- pOutFMD->MakeTree("D");
- treeD = pOutFMD->TreeD();
- }
-
- treeD->Reset();
- TClonesArray* digits = fFMD->Digits();
- fFMD->MakeBranchInTree(treeD, fFMD->GetName(), &(digits), 4000, 0);
- if (!treeD->GetBranch("FMD")) AliFatal("No branch for FMD digits");
- treeD->Fill();
- pOutFMD->WriteDigits("OVERWRITE");
- pOutFMD->UnloadHits();
- pOutFMD->UnloadDigits();
- fFMD->ResetDigits();
-}
-
-//____________________________________________________________________
-//
-// EOF
-//
-
-
-
-
-
+++ /dev/null
-#ifndef ALIFMDDIGITIZERALLA_H
-#define ALIFMDDIGITIZERALLA_H
-/* Copyright(c) 1998-2000, ALICE Experiment at CERN, All rights reserved. *
- * See cxx source for full Copyright notice */
-//
-// Resurection of Alla's old digitizer
-// This is to investigate the changes we've seen in the reconstructed
-// particle multiplicity
-//
-#include <AliDigitizer.h>
-#include <AliRunDigitizer.h>
-class TClonesArray;
-
-class AliFMDDigitizerAlla : public AliDigitizer
-{
-public:
- AliFMDDigitizerAlla();
- AliFMDDigitizerAlla(AliRunDigitizer * manager);
- virtual ~AliFMDDigitizerAlla();
- virtual Bool_t Init();
- // Do the main work
- void Exec(Option_t* option=0) ;
- Int_t PutNoise(Int_t charge) {return (Int_t)(gRandom->Gaus(charge,500));}
- TClonesArray *Digits() const {return fDigits;}
- TClonesArray *Hits() const {return fHits;}
- enum {kBgTag = -1};
-private:
- TClonesArray *fDigits; // ! array with digits
- TClonesArray *fHits; // List of hits
- AliRunDigitizer* GetManager(){return fManager;}
- ClassDef(AliFMDDigitizerAlla,0)
-};
-#endif
-//
-// Local Variables:
-// mode: C++
-// End:
-//
-
-
-
-
--- /dev/null
+/**************************************************************************
+ * Copyright(c) 2004, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+/* $Id$ */
+
+//___________________________________________________________________
+//
+// The classes defined here, are utility classes for reading in data
+// for the FMD. They are put in a seperate library to not polute the
+// normal libraries. The classes are intended to be used as base
+// classes for customized class that do some sort of analysis on the
+// various types of data produced by the FMD.
+//
+// Latest changes by Christian Holm Christensen
+//
+#include "AliFMDDisplay.h" // ALIFMDDISPLAY_H
+#include "AliFMDHit.h" // ALIFMDHIT_H
+#include "AliFMDDigit.h" // ALIFMDDIGIT_H
+#include "AliFMDRecPoint.h" // ALIFMDRECPOINT_H
+#include "AliFMDGeometry.h" // ALIFMDGEOMETRY_H
+#include "AliFMDParameters.h" // ALIFMDPARAMETERS_H
+#include <AliESDFMD.h> // ALIESDFMD_H
+#include <AliLog.h>
+#include <TStyle.h>
+#include <TArrayF.h>
+#include <TMarker3DBox.h>
+#include <TGeoManager.h>
+#include <TMath.h>
+#include <TApplication.h>
+#include <TButton.h>
+#include <TParticle.h>
+#include <TCanvas.h>
+#include <TView.h>
+#include <TVirtualX.h>
+
+//____________________________________________________________________
+ClassImp(AliFMDDisplay)
+#if 0
+ ; // This is here to keep Emacs for indenting the next line
+#endif
+
+//____________________________________________________________________
+AliFMDDisplay* AliFMDDisplay::fgInstance = 0;
+
+//____________________________________________________________________
+AliFMDDisplay*
+AliFMDDisplay::Instance()
+{
+ return fgInstance;
+}
+
+//____________________________________________________________________
+AliFMDDisplay::AliFMDDisplay(const char* gAliceFile)
+ : AliFMDInput(gAliceFile),
+ fWait(kFALSE),
+ fCanvas(0),
+ fPad(0),
+ fButton(0),
+ fZoom(0),
+ fPick(0),
+ fZoomMode(kFALSE)
+{
+ // Constructor of an FMD display object.
+ AddLoad(kGeometry);
+ fMarkers = new TObjArray;
+ fHits = new TObjArray;
+ fMarkers->SetOwner(kTRUE);
+ fHits->SetOwner(kFALSE);
+ fgInstance = this;
+}
+
+//____________________________________________________________________
+void
+AliFMDDisplay::ExecuteEvent(Int_t event, Int_t px, Int_t py)
+{
+ AliInfo(Form("Event %d, at (%d,%d)", px, py));
+ if (px == 0 && py == 0) return;
+ if (!fZoomMode && fPad->GetView()) {
+ fPad->GetView()->ExecuteRotateView(event, px, py);
+ return;
+ }
+ fPad->SetCursor(kCross);
+ switch (event) {
+ case kButton1Down:
+ fPad->TAttLine::Modify();
+ fX0 = fPad->AbsPixeltoX(px);
+ fY0 = fPad->AbsPixeltoY(py);
+ fXPixel = fOldXPixel = px;
+ fYPixel = fOldYPixel = py;
+ fLineDrawn = kFALSE;
+ return;
+ case kButton1Motion:
+ if (fLineDrawn)
+ gVirtualX->DrawBox(fXPixel, fYPixel, fOldXPixel, fOldYPixel,
+ TVirtualX::kHollow);
+ fOldXPixel = px;
+ fOldYPixel = py;
+ fLineDrawn = kTRUE;
+ gVirtualX->DrawBox(fXPixel, fYPixel, fOldXPixel, fOldYPixel,
+ TVirtualX::kHollow);
+ return;
+ case kButton1Up:
+ fPad->GetCanvas()->FeedbackMode(kFALSE);
+ if (px == fXPixel || py == fYPixel) return;
+ fX1 = fPad->AbsPixeltoX(px);
+ fY1 = fPad->AbsPixeltoY(py);
+ if (fX1 < fX0) std::swap(fX0, fX1);
+ if (fY1 < fY0) std::swap(fY0, fY1);
+ fPad->Range(fX0, fY0, fX1, fY1);
+ fPad->Modified();
+ return;
+ }
+}
+
+//____________________________________________________________________
+Int_t
+AliFMDDisplay::DistanceToPrimitive(Int_t px, Int_t py)
+{
+ AliInfo(Form("@ (%d,%d)", px, py));
+ fPad->SetCursor(kCross);
+ Float_t xmin = fPad->GetX1();
+ Float_t xmax = fPad->GetX2();
+ Float_t dx = .02 * (xmax - xmin);
+ Float_t x = fPad->AbsPixeltoX(px);
+ if (x < xmin + dx || x > xmax - dx) return 9999;
+ return (fZoomMode ? 0 : 7);
+}
+//____________________________________________________________________
+Bool_t
+AliFMDDisplay::Init()
+{
+ if (!AliFMDInput::Init()) return kFALSE;
+ AliFMDGeometry* geom = AliFMDGeometry::Instance();
+ geom->Init();
+ geom->InitTransformations();
+ // AliFMDParameters* parm = AliFMDParameters::Instance();
+ // parm->Init();
+ return kTRUE;
+}
+//____________________________________________________________________
+Bool_t
+AliFMDDisplay::Begin(Int_t event)
+{
+ if (!fCanvas) {
+ gStyle->SetPalette(1);
+ fCanvas = new TCanvas("display", "Display", 700, 700);
+ fCanvas->SetFillColor(1);
+ fCanvas->ToggleEventStatus();
+ fPad = new TPad("view3D", "3DView", 0.0, 0.05, 1.0, 1.0, 1, 0, 0);
+ fCanvas->cd();
+ fPad->Draw();
+ }
+ if (!fButton) {
+ fCanvas->cd();
+ fButton = new TButton("Continue", "AliFMDDisplay::Instance()->Continue()",
+ 0, 0, .5, .05);
+ fButton->Draw();
+ fZoom = new TButton("Zoom", "AliFMDDisplay::Instance()->Zoom()",
+ .5, 0, .75, .05);
+ fZoom->Draw();
+ fPick = new TButton("Pick", "AliFMDDisplay::Instance()->Pick()",
+ .75, 0, 1, .05);
+ fPick->Draw();
+ }
+ AliInfo("Clearing canvas");
+ // fCanvas->Clear();
+ if (!fGeoManager) {
+ Warning("End", "No geometry manager");
+ return kFALSE;
+ }
+ AliInfo("Drawing geometry");
+ fPad->cd();
+ fGeoManager->GetTopVolume()->Draw();
+ AliInfo("Adjusting view");
+ Int_t irep;
+ if (fPad->GetView()) {
+ fPad->GetView()->SetView(-200, -40, 80, irep);
+ fPad->GetView()->Zoom();
+ fPad->Modified();
+ fPad->cd();
+ }
+ return AliFMDInput::Begin(event);
+}
+
+//____________________________________________________________________
+Bool_t
+AliFMDDisplay::End()
+{
+ fPad->cd();
+ fMarkers->Draw();
+ AppendPad();
+ fPad->Update();
+ fPad->cd();
+ fCanvas->Modified(kTRUE);
+ fCanvas->Update();
+ fCanvas->cd();
+ fWait = kTRUE;
+ while (fWait) {
+ gApplication->StartIdleing();
+ gSystem->InnerLoop();
+ gApplication->StopIdleing();
+ }
+ AliInfo("After idle loop");
+ fMarkers->Delete();
+ fHits->Clear();
+ AliInfo("After clearing caches");
+ return AliFMDInput::End();
+}
+
+//____________________________________________________________________
+Int_t
+AliFMDDisplay::LookupColor(Float_t x, Float_t max) const
+{
+ Int_t idx = Int_t(x / max * gStyle->GetNumberOfColors());
+ return gStyle->GetColorPalette(idx);
+}
+
+
+//____________________________________________________________________
+Bool_t
+AliFMDDisplay::ProcessHit(AliFMDHit* hit, TParticle* p)
+{
+ if (!hit) { AliError("No hit"); return kFALSE; }
+ if (!p) { AliError("No track"); return kFALSE; }
+
+ fHits->Add(hit);
+ Float_t size = .1;
+ Float_t pt = TMath::Sqrt(hit->Py()*hit->Py()+hit->Px()*hit->Px());
+ Float_t theta = TMath::ATan2(pt, hit->Pz());
+ Float_t phi = TMath::ATan2(hit->Py(), hit->Px());
+ TMarker3DBox* marker = new TMarker3DBox(hit->X(), hit->Y(), hit->Z(),
+ size, size, size, theta, phi);
+ marker->SetLineColor(LookupColor(hit->Edep(), 1));
+ marker->SetRefObject(hit);
+ fMarkers->Add(marker);
+ return kTRUE;
+}
+
+//____________________________________________________________________
+Bool_t
+AliFMDDisplay::ProcessDigit(AliFMDDigit* digit)
+{
+ if (!digit) { AliError("No digit"); return kFALSE; }
+
+ Double_t x, y, z;
+ AliFMDGeometry* geom = AliFMDGeometry::Instance();
+ AliFMDParameters* parm = AliFMDParameters::Instance();
+ Double_t threshold = (parm->GetPedestal(digit->Detector(),
+ digit->Ring(),
+ digit->Sector(),
+ digit->Strip())
+ + 4 * parm->GetPedestalWidth(digit->Detector(),
+ digit->Ring(),
+ digit->Sector(),
+ digit->Strip()));
+ if (digit->Counts() < threshold) return kTRUE;
+ fHits->Add(digit);
+ geom->Detector2XYZ(digit->Detector(), digit->Ring(), digit->Sector(),
+ digit->Strip(), x, y, z);
+ Float_t size = .1;
+ Float_t r = TMath::Sqrt(x * x + y * y);
+ Float_t theta = TMath::ATan2(r, z);
+ Float_t phi = TMath::ATan2(y, x);
+ TMarker3DBox* marker = new TMarker3DBox(x,y,z,size,size,size,theta,phi);
+ marker->SetRefObject(digit);
+ marker->SetLineColor(LookupColor(digit->Counts(), 1024));
+ fMarkers->Add(marker);
+ return kTRUE;
+}
+
+//____________________________________________________________________
+Bool_t
+AliFMDDisplay::ProcessRecPoint(AliFMDRecPoint* recpoint)
+{
+ if (!recpoint) { AliError("No recpoint"); return kFALSE; }
+ if (recpoint->Particles() < .1) return kTRUE;
+ fHits->Add(recpoint);
+ Double_t x, y, z;
+ AliFMDGeometry* geom = AliFMDGeometry::Instance();
+ geom->Detector2XYZ(recpoint->Detector(), recpoint->Ring(),
+ recpoint->Sector(), recpoint->Strip(), x, y, z);
+
+ Float_t size = .1;
+ Float_t r = TMath::Sqrt(x * x + y * y);
+ Float_t theta = TMath::ATan2(r, z);
+ Float_t phi = TMath::ATan2(y, x);
+ TMarker3DBox* marker = new TMarker3DBox(x,y,z,size,size,size,theta,phi);
+ marker->SetRefObject(recpoint);
+ marker->SetLineColor(LookupColor(recpoint->Particles(), 20));
+ fMarkers->Add(marker);
+ return kTRUE;
+}
+
+//____________________________________________________________________
+//
+// EOF
+//
--- /dev/null
+#ifndef AliFMDDISPLAY_H
+#define AliFMDDISPLAY_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights
+ * reserved.
+ *
+ * See cxx source for full Copyright notice
+ */
+//___________________________________________________________________
+//
+// The classes defined here, are utility classes for reading in data
+// for the FMD. They are put in a seperate library to not polute the
+// normal libraries. The classes are intended to be used as base
+// classes for customized class that do some sort of analysis on the
+// various types of data produced by the FMD.
+//
+#include "AliFMDInput.h"
+class TObjArray;
+class TCanvas;
+class TPad;
+class TButton;
+
+//___________________________________________________________________
+class AliFMDDisplay : public AliFMDInput
+{
+public:
+ AliFMDDisplay(const char* gAliceFile="galice.root");
+ virtual ~AliFMDDisplay() {}
+ static AliFMDDisplay* Instance();
+
+ void Continue() { fWait = kFALSE; }
+ void Zoom() { fZoomMode = kTRUE; }
+ void Pick() { fZoomMode = kFALSE; }
+ void ExecuteEvent(Int_t event, Int_t px, Int_t py);
+ Int_t DistanceToPrimitive(Int_t px, Int_t py);
+
+
+ virtual Bool_t Init();
+ virtual Bool_t Begin(Int_t event);
+ virtual Bool_t End();
+ virtual Bool_t ProcessHit(AliFMDHit* hit, TParticle* p);
+ virtual Bool_t ProcessDigit(AliFMDDigit* digit);
+ virtual Bool_t ProcessRecPoint(AliFMDRecPoint* recpoint);
+ virtual Int_t LookupColor(Float_t x, Float_t max) const;
+protected:
+ static AliFMDDisplay* fgInstance; // Static instance
+ Bool_t fWait; // Wait until user presses `Continue'
+ TObjArray* fMarkers; // Cache of markers
+ TObjArray* fHits; // Cache of `hits'
+ TCanvas* fCanvas; // Canvas to draw in
+ TPad* fPad; // View pad.
+ TButton* fButton; // Continue button
+ TButton* fZoom; // Zoom button
+ TButton* fPick; // Pick button
+ Bool_t fZoomMode; // Whether we're in Zoom mode
+ Float_t fX0; // X at lower left corner or range
+ Float_t fY0; // Y at lower left corner or range
+ Float_t fX1; // X at upper right corner or range
+ Float_t fY1; // Y at upper right corner or range
+ Int_t fXPixel; // X pixel of mark
+ Int_t fYPixel; // Y pixel of mark
+ Int_t fOldXPixel; // Old x pixel of mark
+ Int_t fOldYPixel; // Old y pixel of mark
+ Bool_t fLineDrawn; // Whether we're drawing a box
+ ClassDef(AliFMDDisplay,0) // FMD specialised event display
+};
+
+#endif
+//____________________________________________________________________
+//
+// Local Variables:
+// mode: C++
+// End:
+//
+// EOF
+//
+++ /dev/null
-/**************************************************************************
- * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
- * *
- * Author: The ALICE Off-line Project. *
- * Contributors are mentioned in the code where appropriate. *
- * *
- * Permission to use, copy, modify and distribute this software and its *
- * documentation strictly for non-commercial purposes is hereby granted *
- * without fee, provided that the above copyright notice appears in all *
- * copies and that both the copyright notice and this permission notice *
- * appear in the supporting documentation. The authors make no claims *
- * about the suitability of this software for any purpose. It is *
- * provided "as is" without express or implied warranty. *
- **************************************************************************/
-
-/* $Id$ */
-
-//____________________________________________________________________
-//
-// 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.
-//
-// 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 simulation
-//
-// +--------+ 1 +-----------------+
-// | AliFMD |<>-----| AliFMDSimulator |
-// +--------+ +-----------------+
-// ^
-// |
-// +-------------+-------------+
-// | |
-// +--------------------+ +-------------------+
-// | AliFMDGeoSimulator | | AliFMDG3Simulator |
-// +--------------------+ +-------------------+
-// ^
-// |
-// +----------------------+
-// | AliFMDG3OldSimulator |
-// +----------------------+
-//
-//
-// * AliFMD
-// This defines the interface for the various parts of AliROOT that
-// uses the FMD, like AliFMDSimulator, AliFMDDigitizer,
-// AliFMDReconstructor, and so on.
-//
-// * AliFMDSimulator
-// This is the base class for the FMD simulation tasks. The
-// 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. This defines the active
-// volume as an ONLY XTRU shape with a divided MANY TUBS shape
-// inside to implement the particular shape of the silicon
-// sensors.
-//
-// * AliFMDG3OldSimulator
-// This is a concrete implementation of the AliFMDSimulator that
-// uses the TVirtualMC interface with GEANT 3.21-like messages.
-// This implements the active volume as a divided TUBS shape. Hits
-// in the corners should be cut away at run time (but currently
-// isn't).
-//
-#include <math.h>
-#include "AliFMDG3OldSimulator.h" // ALIFMDG3OLDSIMULATOR_H
-#include "AliFMDGeometry.h" // ALIFMDGEOMETRY_H
-#include "AliFMDDetector.h" // ALIFMDDETECTOR_H
-#include "AliFMDRing.h" // ALIFMDRING_H
-#include "AliFMD1.h" // ALIFMD1_H
-#include "AliFMD2.h" // ALIFMD2_H
-#include "AliFMD3.h" // ALIFMD3_H
-#include "AliFMD.h" // ALIFMD_H
-#include <AliLog.h> // ALILOG_H
-#include <TVector2.h> // ROOT_TVector2
-#include <TVirtualMC.h> // ROOT_TVirtualMC
-#include <TArrayI.h> // ROOT_TArrayI
-
-//====================================================================
-ClassImp(AliFMDG3OldSimulator)
-#if 0
- ; // This is here to keep Emacs for indenting the next line
-#endif
-
-//____________________________________________________________________
-AliFMDG3OldSimulator::AliFMDG3OldSimulator()
-{
- // Default constructor
- fSectorOff = 1;
- fModuleOff = -1;
- fRingOff = 3;
- fDetectorOff = 4;
- fUseDivided = kTRUE;
-}
-
-//____________________________________________________________________
-AliFMDG3OldSimulator::AliFMDG3OldSimulator(AliFMD* fmd, Bool_t detailed)
- : AliFMDG3Simulator(fmd, detailed)
-{
- // Normal constructor
- //
- // Parameters:
- //
- // fmd Pointer to AliFMD object
- // detailed Whether to make a detailed simulation or not
- //
- fSectorOff = 1;
- fModuleOff = -1;
- fRingOff = 3;
- fDetectorOff = 4;
- fUseDivided = detailed;
-}
-
-//____________________________________________________________________
-Bool_t
-AliFMDG3OldSimulator::RingGeometry(AliFMDRing* r)
-{
- // Setup the geometry of a ring. The defined TGeoVolume is
- // returned, and should be used when setting up the rest of the
- // volumes.
- //
- // Parameters:
- //
- // r Pointer to ring geometry object
- //
- // Returns:
- // true on success
- //
- if (!r) {
- AliError("Didn't get a ring object");
- return kFALSE;
- }
- Char_t id = r->GetId();
- Double_t siThick = r->GetSiThickness();
- // const Int_t nv = r->GetNVerticies();
- //TVector2* a = r->GetVertex(5);
- TVector2* b = r->GetVertex(3);
- //TVector2* c = r->GetVertex(4);
- Double_t theta = r->GetTheta();
- //Double_t off = (TMath::Tan(TMath::Pi() * theta / 180)
- // * r->GetBondingWidth());
- Double_t rmax = b->Mod();
- Double_t rmin = r->GetLowR();
- Double_t pcbThick = r->GetPrintboardThickness();
- Double_t copperThick = r->GetCopperThickness(); // .01;
- Double_t chipThick = r->GetChipThickness(); // .01;
- //Double_t modSpace = r->GetModuleSpacing();
- //Double_t legr = r->GetLegRadius();
- //Double_t legl = r->GetLegLength();
- //Double_t legoff = r->GetLegOffset();
- Int_t ns = r->GetNStrips();
- Double_t space = r->GetSpacing();
- Int_t nsec = Int_t(360 / theta);
- //Double_t stripoff = a->Mod();
- //Double_t dstrip = (rmax - stripoff) / ns;
- Double_t par[10];
- TString name;
- TString name2;
- TVirtualMC* mc = TVirtualMC::GetMC();
-
- Int_t siId = fFMD->GetIdtmed()->At(kSiId);
- Int_t airId = fFMD->GetIdtmed()->At(kAirId);
- Int_t pcbId = fFMD->GetIdtmed()->At(kPcbId);
- //Int_t plaId = fFMD->GetIdtmed()->At(kPlasticId);
- Int_t copId = fFMD->GetIdtmed()->At(kCopperId);
- Int_t chiId = fFMD->GetIdtmed()->At(kSiChipId);
-
- Double_t ringWidth = (siThick + 2 * (pcbThick + copperThick + chipThick));
- // Virtual volume shape to divide - This volume is only defined if
- // the geometry is set to be detailed.
- // Ring mother volume
- par[0] = rmin;
- par[1] = rmax;
- par[2] = ringWidth / 2;
- name = Form(fgkRingName, id);
- mc->Gsvolu(name.Data(), "TUBE", airId, par, 3);
-
- par[2] = siThick / 2;
- name2 = name;
- name = Form(fgkActiveName, id);
- Double_t z = - ringWidth / 2 + siThick / 2;
- mc->Gsvolu(name.Data(), "TUBE", siId, par, 3);
- mc->Gspos(name.Data(), 1, name2.Data(), 0, 0, z, 0);
-
- Int_t sid = mc->VolId(name.Data());
- if (fUseDivided) {
- name2 = name;
- name = Form(fgkSectorName, id);
- mc->Gsdvn(name.Data(), name2.Data(), nsec, 2);
-
- name2 = name;
- name = Form(fgkStripName, id);
- mc->Gsdvn(name.Data(), name2.Data(), ns, 1);
- sid = mc->VolId(name.Data());
- AliDebug(10, Form("Got volume id %d for volume %s", sid, name.Data()));
- }
-
- switch (id) {
- case 'i':
- case 'I': fActiveId[0] = sid; break;
- case 'o':
- case 'O': fActiveId[2] = sid; break;
- }
-
- // Shape of Printed circuit Board
- Double_t boardThick = (pcbThick + copperThick + chipThick);
- par[0] = rmin + .1;
- par[1] = rmax - .1;
- par[2] = boardThick / 2;
- name2 = Form(fgkRingName, id);
- name = Form(fgkPCBName, id, 'B');
- z += siThick / 2 + space + boardThick / 2;
- mc->Gsvolu(name.Data(), "TUBE", pcbId, par, 3);
- mc->Gspos(name.Data(), 1, name2.Data(), 0, 0, z, 0);
- mc->Gspos(name.Data(), 2, name2.Data(), 0, 0, z + boardThick, 0);
- mc->Gsatt(name.Data(), "seen", -2);
- // PCB
- par[2] = pcbThick / 2;
- name2 = name;
- name = Form("F%cPC", id);
- z = -boardThick / 2 + pcbThick / 2;
- mc->Gsvolu(name.Data(), "TUBE", pcbId, par, 3);
- mc->Gspos(name.Data(), 1, name2.Data(), 0, 0, z, 0);
- // Copper
- par[2] = copperThick / 2;
- name = Form("F%cCO", id);
- z += pcbThick / 2 + copperThick / 2;
- mc->Gsvolu(name.Data(), "TUBE", copId, par, 3);
- mc->Gspos(name.Data(), 1, name2.Data(), 0, 0, z, 0);
- // Chip
- par[2] = chipThick / 2;
- name = Form("F%cCH", id);
- z += copperThick / 2 + chipThick / 2;
- mc->Gsvolu(name.Data(), "TUBE", chiId, par, 3);
- mc->Gspos(name.Data(), 1, name2.Data(), 0, 0, z, 0);
-
- return kTRUE;
-}
-
-//____________________________________________________________________
-//
-// EOF
-//
+++ /dev/null
-#ifndef ALIFMDG3OLDSIMULATOR_H
-#define ALIFMDG3OLDSIMULATOR_H
-/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights
- * reserved.
- *
- * Latest changes by Christian Holm Christensen <cholm@nbi.dk>
- *
- * See cxx source for full Copyright notice
- */
-#ifndef ALIFMDG3SIMULATOR
-# include <AliFMDG3Simulator.h>
-#endif
-class AliFMD;
-class AliFMDRing;
-class AliFMDDetector;
-class AliFMD1;
-class AliFMD2;
-class AliFMD3;
-
-//____________________________________________________________________
-class AliFMDG3OldSimulator : public AliFMDG3Simulator
-{
-public:
- AliFMDG3OldSimulator();
- /** CTOR */
- AliFMDG3OldSimulator(AliFMD* fmd, Bool_t detailed=kTRUE);
- virtual ~AliFMDG3OldSimulator() {}
- virtual void UseDivided(Bool_t) { fUseDivided = kTRUE; }
-protected:
- /** Make a ring volume
- @param r Ring geometry
- @return Ring volume */
- Bool_t RingGeometry(AliFMDRing* r);
- ClassDef(AliFMDG3OldSimulator,1);
-};
-
-
-#endif
-//____________________________________________________________________
-//
-// Local Variables:
-// mode: C++
-// End:
-//
-// EOF
-//
-
+++ /dev/null
-/**************************************************************************
- * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
- * *
- * Author: The ALICE Off-line Project. *
- * Contributors are mentioned in the code where appropriate. *
- * *
- * Permission to use, copy, modify and distribute this software and its *
- * documentation strictly for non-commercial purposes is hereby granted *
- * without fee, provided that the above copyright notice appears in all *
- * copies and that both the copyright notice and this permission notice *
- * appear in the supporting documentation. The authors make no claims *
- * about the suitability of this software for any purpose. It is *
- * provided "as is" without express or implied warranty. *
- **************************************************************************/
-
-/* $Id$ */
-
-//____________________________________________________________________
-//
-// 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.
-//
-// 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 simulation
-//
-// +--------+ 1 +-----------------+
-// | AliFMD |<>-----| AliFMDSimulator |
-// +--------+ +-----------------+
-// ^
-// |
-// +-------------+-------------+
-// | |
-// +--------------------+ +-------------------+
-// | AliFMDGeoSimulator | | AliFMDG3Simulator |
-// +--------------------+ +-------------------+
-// ^
-// |
-// +--------------------+
-// | AliFMDOldSimulator |
-// +--------------------+
-//
-// * AliFMD
-// This defines the interface for the various parts of AliROOT that
-// uses the FMD, like AliFMDSimulator, AliFMDDigitizer,
-// AliFMDReconstructor, and so on.
-//
-// * AliFMDSimulator
-// This is the base class for the FMD simulation tasks. The
-// 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. This defines the active
-// volume as an ONLY XTRU shape with a divided MANY TUBS shape
-// inside to implement the particular shape of the silicon
-// sensors.
-//
-// * AliFMDG3Simulator
-// This is a concrete implementation of the AliFMDSimulator that
-// uses the TVirtualMC interface with GEANT 3.21-like messages.
-// This implements the active volume as a divided TUBS shape. Hits
-// in the corners should be cut away at run time (but currently
-// isn't).
-//
-// * AliFMDOldSimulator
-// This is a concrete implementation of AliFMDSimulator. It
-// approximates the of the rings as segmented disks.
-//
-#include <math.h>
-#include "AliFMDG3Simulator.h" // ALIFMDG3SIMULATOR_H
-#include "AliFMDGeometry.h" // ALIFMDGEOMETRY_H
-#include "AliFMDDetector.h" // ALIFMDDETECTOR_H
-#include "AliFMDRing.h" // ALIFMDRING_H
-#include "AliFMD1.h" // ALIFMD1_H
-#include "AliFMD2.h" // ALIFMD2_H
-#include "AliFMD3.h" // ALIFMD3_H
-#include "AliFMD.h" // ALIFMD_H
-#include <AliLog.h> // ALILOG_H
-#include <TVector2.h> // ROOT_TVector2
-#include <TVirtualMC.h> // ROOT_TVirtualMC
-#include <TArrayI.h> // ROOT_TArrayI
-
-//====================================================================
-ClassImp(AliFMDG3Simulator)
-#if 0
- ; // This is here to keep Emacs for indenting the next line
-#endif
-
-//____________________________________________________________________
-AliFMDG3Simulator::AliFMDG3Simulator()
-{
- // Default constructor
- fSectorOff = 1;
- fModuleOff = 3;
- fRingOff = 4;
- fDetectorOff = 5;
-}
-
-//____________________________________________________________________
-AliFMDG3Simulator::AliFMDG3Simulator(AliFMD* fmd, Bool_t detailed)
- : AliFMDSimulator(fmd, detailed)
-{
- // Normal constructor
- //
- // Parameters:
- //
- // fmd Pointer to AliFMD object
- // detailed Whether to make a detailed simulation or not
- //
- fSectorOff = 1;
- fModuleOff = 3;
- fRingOff = 4;
- fDetectorOff = 5;
-}
-
-//____________________________________________________________________
-Bool_t
-AliFMDG3Simulator::RingGeometry(AliFMDRing* r)
-{
- // Setup the geometry of a ring. The defined TGeoVolume is
- // returned, and should be used when setting up the rest of the
- // volumes.
- //
- // Parameters:
- //
- // r Pointer to ring geometry object
- //
- // Returns:
- // true on success
- //
- if (!r) {
- AliError("Didn't get a ring object");
- return kFALSE;
- }
- Char_t id = r->GetId();
- Double_t siThick = r->GetSiThickness();
- // const Int_t nv = r->GetNVerticies();
- TVector2* a = r->GetVertex(5);
- TVector2* b = r->GetVertex(3);
- TVector2* c = r->GetVertex(4);
- Double_t theta = r->GetTheta();
- Double_t off = (TMath::Tan(TMath::Pi() * theta / 180)
- * r->GetBondingWidth());
- Double_t rmax = b->Mod();
- Double_t rmin = r->GetLowR();
- Double_t pcbThick = r->GetPrintboardThickness();
- Double_t modSpace = r->GetModuleSpacing();
- Double_t legr = r->GetLegRadius();
- Double_t legl = r->GetLegLength();
- Double_t legoff = r->GetLegOffset();
- Int_t ns = r->GetNStrips();
- Double_t space = r->GetSpacing();
- Double_t stripoff = a->Mod();
- Double_t dstrip = (rmax - stripoff) / ns;
- Double_t par[10];
- TString name;
- TString name2;
- TVirtualMC* mc = TVirtualMC::GetMC();
-
- Int_t siId = fFMD->GetIdtmed()->At(kSiId);
- Int_t airId = fFMD->GetIdtmed()->At(kAirId);
- Int_t pcbId = fFMD->GetIdtmed()->At(kPcbId);
- Int_t plaId = fFMD->GetIdtmed()->At(kPlasticId);
- // Int_t copId = fFMD->GetIdtmed()->At(kCopperId);
- // Int_t chiId = fFMD->GetIdtmed()->At(kSiChipId);
-
- Double_t ringWidth = r->GetRingDepth();
- Double_t x = 0;
- Double_t y = 0;
- Double_t z = 0;
- Double_t backWidth = siThick + pcbThick + legl + space;
- Double_t frontWidth = backWidth + modSpace;
-
- // Ring mother volume
- par[0] = rmin;
- par[1] = rmax;
- par[2] = ringWidth / 2;
- name = Form(fgkRingName, id);
- mc->Gsvolu(name.Data(), "TUBE", airId, par, 3);
-
- // Back container volume
- par[0] = rmin;
- par[1] = rmax;
- par[2] = backWidth / 2;
- par[3] = -theta;
- par[4] = +theta;
- TString backName(Form(fgkBackVName, id));
- mc->Gsvolu(backName.Data(), "TUBS", airId, par, 5);
-
- // Front container volume
- par[2] = frontWidth / 2;
- TString frontName(Form(fgkFrontVName, id));
- mc->Gsvolu(frontName.Data(), "TUBS", airId, par, 5);
-
- Double_t topL = (b->X() - c->X());
- Double_t botL = (c->X() - a->X());
- Int_t rot;
- mc->Matrix(rot, 90, 90, 0, 90, 90, 0);
-
- Double_t zFront = - frontWidth / 2 + siThick / 2;
- Double_t zBack = - backWidth / 2 + siThick / 2;
- if (fUseDivided) {
- fSectorOff = 1;
- fModuleOff = 3;
- fRingOff = 4;
- fDetectorOff = 5;
-
- // Virtual volume shape to divide - This volume is only defined if
- // the geometry is set to be detailed.
- par[0] = rmin;
- par[1] = rmax;
- par[2] = siThick / 2;
- par[3] = -theta;
- par[4] = theta;
- name = Form(fgkActiveName, id);
- mc->Gsvolu(name.Data(), "TUBS", (fDetailed ? airId : siId), par, 5);
-
- mc->Gspos(name.Data(), 0, backName.Data(), x, y, zBack, 0, "ONLY");
- mc->Gspos(name.Data(), 0, frontName.Data(), x, y, zFront, 0, "ONLY");
-
- Int_t sid = -1;
- if (fDetailed) {
- // Divide the volume into sectors
- name2 = name;
- name = Form(fgkSectorName, id);
- mc->Gsdvn2(name.Data(), name2.Data(), 2, 2, -theta, siId);
-
- // Divide the volume into strips
- name2 = name;
- name = Form(fgkStripName, id);
- mc->Gsdvt2(name.Data(), name2.Data(), dstrip, 1, stripoff, siId, ns);
- sid = mc->VolId(name.Data());
- AliDebug(10, Form("Got volume id %d for volume %s", sid, name.Data()));
- }
-
- switch (id) {
- case 'i': case 'I': fActiveId[0] = sid; break;
- case 'o': case 'O': fActiveId[2] = sid; break;
- }
- }
- else {
- fSectorOff = -1;
- fModuleOff = 1;
- fRingOff = 2;
- fDetectorOff = 3;
-
- // Create top of module shape
- par[0] = c->Y();
- par[1] = b->Y();
- par[2] = siThick / 2;
- par[3] = topL / 2;
- name = Form(fgkModuleName, id);
- name[3] = 'T';
- mc->Gsvolu(name.Data(), "TRD1", siId, par, 4);
- Int_t tid = mc->VolId(name.Data());
- x = rmin + botL + topL / 2;
- mc->Gspos(name.Data(), 0, backName.Data(), x, y, zBack, rot, "ONLY");
- mc->Gspos(name.Data(), 0, frontName.Data(), x, y, zFront, rot, "ONLY");
-
-
- // Create bottom of module shape
- par[0] = a->Y();
- par[1] = c->Y();
- par[3] = botL / 2;
- name = Form(fgkModuleName, id);
- name[3] = 'B';
- mc->Gsvolu(name.Data(), "TRD1", siId, par, 4);
- Int_t bid = mc->VolId(name.Data());
- x = rmin + botL / 2;
- z = - backWidth / 2 + siThick / 2;
- mc->Gspos(name.Data(), 0, backName.Data(), x, y, zBack, rot, "ONLY");
- mc->Gspos(name.Data(), 0, frontName.Data(), x, y, zFront, rot, "ONLY");
-
- switch (id) {
- case 'i': case 'I': fActiveId[0] = tid; fActiveId[1] = bid; break;
- case 'o': case 'O': fActiveId[2] = tid; fActiveId[3] = bid; break;
- }
- }
-
-
- // Shape of Printed circuit Board
- // Top
- par[0] = c->Y() - off;
- par[1] = b->Y() - off;
- par[2] = pcbThick / 2;
- par[3] = topL / 2;
- x = rmin + botL + topL / 2;
- zBack += siThick / 2 + space + pcbThick / 2;
- zFront += siThick / 2 + space + pcbThick / 2;
- name = Form(fgkPCBName, id, 'T');
- mc->Gsvolu(name.Data(), "TRD1", pcbId, par, 4);
- mc->Gspos(name.Data(), 0, backName.Data(), x, y, zBack, rot, "ONLY");
- mc->Gspos(name.Data(), 0, frontName.Data(), x, y, zFront, rot, "ONLY");
-
- // Bottom
- par[0] = a->Y() - off;
- par[1] = c->Y() - off;
- par[3] = botL / 2;
- name = Form(fgkPCBName, id, 'B');
- x = rmin + botL / 2;
- mc->Gsvolu(name.Data(), "TRD1", pcbId, par, 4);
- mc->Gspos(name.Data(), 0, backName.Data(), x, y, zBack, rot, "ONLY");
- mc->Gspos(name.Data(), 0, frontName.Data(), x, y, zFront, rot, "ONLY");
-
- Double_t x1, y1;
- // Short leg volume
- par[0] = legr - .1;
- par[1] = legr;
- par[2] = legl / 2;
- x = a->X() + legoff + legr;
- x1 = c->X();
- y1 = c->Y() - legoff - legr - off;
- zBack += pcbThick / 2 + legl / 2;
- zFront += pcbThick / 2 + legl / 2 + modSpace / 2;
- name = Form(fgkShortLegName, id);
- mc->Gsvolu(name.Data(), "TUBE", plaId, par, 3);
- mc->Gspos(name.Data(), 0, backName.Data(), x, y, zBack, 0, "ONLY");
- mc->Gspos(name.Data(), 1, backName.Data(), x1, y1, zBack, 0, "ONLY");
- mc->Gspos(name.Data(), 2, backName.Data(), x1, -y1, zBack, 0, "ONLY");
-
- // Long leg volume
- par[2] += modSpace / 2;
- name = Form(fgkLongLegName, id);
- mc->Gsvolu(name.Data(), "TUBE", plaId, par, 3);
- mc->Gspos(name.Data(), 0, frontName.Data(), x, y, zFront, 0, "ONLY");
- mc->Gspos(name.Data(), 1, frontName.Data(), x1, y1, zFront, 0, "ONLY");
- mc->Gspos(name.Data(), 2, frontName.Data(), x1, -y1, zFront, 0, "ONLY");
-
- // Place modules+pcb+legs in ring volume
- Int_t nmod = r->GetNModules();
- name2 = Form(fgkRingName, id);
- AliDebug(10, Form("making %d modules in ring %c", nmod, id));
- for (Int_t i = 0; i < nmod; i++) {
- Double_t th = (i + .5) * 2 * theta;
- Bool_t isFront = (i % 2 == 0);
- name = (isFront ? frontName : backName);
- z = (isFront ? 0 : modSpace) / 2;
- mc->Matrix(rot, 90, th, 90, fmod(90 + th, 360), 0, 0);
- mc->Gspos(name.Data(), i, name2.Data(), 0, 0, z, rot, "ONLY");
- }
-
- return kTRUE;
-}
-
-//____________________________________________________________________
-Bool_t
-AliFMDG3Simulator::DetectorGeometry(AliFMDDetector* d, Double_t zmother)
-{
- // Common stuff for setting up the FMD1, FMD2, and FMD3 geometries.
- // This includes putting the Honeycomb support plates and the rings
- // into the mother volumes.
- //
- // Parameeters:
- // d The detector geometry to use
- // zmother The midpoint in global coordinates of detector vol.
- //
- // Returns:
- // true on success
- //
- if (!d) return kFALSE;
-
- TString name;
- TString name2;
- TVirtualMC* mc = TVirtualMC::GetMC();
-
- // Loop over the defined rings
- for (int i = 0; i < 2; i++) {
- AliFMDRing* r = 0;
- Double_t lowr = 0;
- Double_t highr = 0;
- Double_t rz = 0;
- switch (i) {
- case 0:
- r = d->GetInner();
- lowr = d->GetInnerHoneyLowR();
- highr = d->GetInnerHoneyHighR();
- rz = d->GetInnerZ();
- break;
- case 1:
- r = d->GetOuter();
- lowr = d->GetOuterHoneyLowR();
- highr = d->GetOuterHoneyHighR();
- rz = d->GetOuterZ();
- break;
- }
- if (!r) continue;
- Char_t c = r->GetId();
- Int_t id = d->GetId();
- Int_t airId = (fFMD->GetIdtmed()->At(kAirId));
- Int_t alId = (fFMD->GetIdtmed()->At(kAlId));
- Double_t hcThick = d->GetHoneycombThickness();
- Double_t alThick = d->GetAlThickness();
- Double_t par[10];
- Double_t z;
- // Place ring in mother volume
- if (zmother > 0) z = rz - zmother + r->GetRingDepth() / 2;
- else z = zmother - rz + r->GetRingDepth() / 2;
- name = Form(fgkRingName, c);
- name2 = d->GetName();
- mc->Gspos(name.Data(), Int_t(c), name2.Data(), 0, 0, z, 0, "ONLY");
-
- // Place Top Honeycomb in mother volume
- z += + r->GetRingDepth() / 2 + hcThick / 2;
- // Top of Honeycomb
- par[0] = lowr;
- par[1] = highr;
- par[2] = hcThick / 2;
- par[3] = 0;
- par[4] = 180;
- name = Form(fgkTopHCName, id, c);
- mc->Gsvolu(name.Data(), "TUBS", alId, par, 5);
- mc->Gspos(name.Data(), 0, name2.Data(), 0, 0, z, 0, "ONLY");
-
- par[0] += alThick;
- par[1] -= alThick;
- par[2] -= alThick / 2;
- name2 = name;
- name = Form(fgkTopIHCName, id, c);
- mc->Gsvolu(name.Data(), "TUBS", airId, par, 5);
- mc->Gspos(name.Data(), 0, name2.Data(), 0, 0, 0, 0, "ONLY");
-
- // Bot of Honeycomb
- par[0] = lowr;
- par[1] = highr;
- par[2] = hcThick / 2;
- par[3] = 180;
- par[4] = 360;
- name2 = d->GetName();
- name = Form(fgkBotHCName, id, c);
- mc->Gsvolu(name.Data(), "TUBS", alId, par, 5);
- mc->Gspos(name.Data(), 0, name2.Data(), 0, 0, z, 0, "ONLY");
-
- par[0] += alThick;
- par[1] -= alThick;
- par[2] -= alThick / 2;
- name2 = name;
- name = Form(fgkBotIHCName, id, c);
- mc->Gsvolu(name.Data(), "TUBS", airId, par, 5);
- mc->Gspos(name.Data(), 0, name2.Data(), 0, 0, 0, 0, "ONLY");
- }
- return kTRUE;
-}
-
-//____________________________________________________________________
-Bool_t
-AliFMDG3Simulator::FMD1Geometry(AliFMD1* fmd1)
-{
- // Setup the FMD1 geometry. The FMD1 only has one ring, and no
- // special support as it is at the momement.
- //
- // See also AliFMDG3Simulator::DetectorGeometry
- //
- if (!fmd1) return kFALSE;
- Double_t rmin = fmd1->GetInner()->GetLowR();
- Double_t rmax = fmd1->GetInnerHoneyHighR();
- Double_t hcThick = fmd1->GetHoneycombThickness();
- Double_t w = fmd1->GetInner()->GetRingDepth() + hcThick;
- Double_t z = fmd1->GetInnerZ() + w / 2;
- TVirtualMC* mc = TVirtualMC::GetMC();
- Int_t airId = (fFMD->GetIdtmed()->At(kAirId));
-
- Double_t par[3];
- par[0] = rmin;
- par[1] = rmax;
- par[2] = w / 2;
- mc->Gsvolu(fmd1->GetName(), "TUBE", airId, par, 3);
- mc->Gspos(fmd1->GetName(), fmd1->GetId(), "ALIC", 0, 0, z, 0, "ONLY");
-
- return DetectorGeometry(fmd1, z);
-}
-
-//____________________________________________________________________
-Bool_t
-AliFMDG3Simulator::FMD2Geometry(AliFMD2* fmd2)
-{
- // Setup the FMD2 geometry. The FMD2 has no
- // special support as it is at the momement.
- //
- // See also AliFMDG3Simulator::DetectorGeometry
- //
- if (!fmd2) return kFALSE;
- Double_t rmin = fmd2->GetInner()->GetLowR();
- Double_t rmax = fmd2->GetOuterHoneyHighR();
- Double_t hcThick = fmd2->GetHoneycombThickness();
- Double_t ow = fmd2->GetInner()->GetRingDepth();
- Double_t iz = fmd2->GetInnerZ();
- Double_t oz = fmd2->GetOuterZ();
- Double_t w = TMath::Abs(oz - iz) + ow + hcThick;
- Double_t z = oz + w / 2;
-
- TVirtualMC* mc = TVirtualMC::GetMC();
- Int_t airId = (fFMD->GetIdtmed()->At(kAirId));
-
- Double_t par[3];
- par[0] = rmin;
- par[1] = rmax;
- par[2] = w / 2;
- mc->Gsvolu(fmd2->GetName(), "TUBE", airId, par, 3);
- mc->Gspos(fmd2->GetName(), fmd2->GetId(), "ALIC", 0, 0, z, 0, "ONLY");
-
- return DetectorGeometry(fmd2, z);
-}
-
-//____________________________________________________________________
-Bool_t
-AliFMDG3Simulator::FMD3Geometry(AliFMD3* fmd3)
-{
- // Setup the FMD3 geometry. The FMD2 has a rather elaborate support
- // structure, as the support will also support the vacuum
- // beam-pipe.
- //
- // See also AliFMDG3Simulator::DetectorGeometry
- //
- if (!fmd3) return kFALSE;
- Double_t nlen = fmd3->GetNoseLength();
- Double_t nz = fmd3->GetNoseZ();
- Double_t noser1 = fmd3->GetNoseLowR();
- Double_t noser2 = fmd3->GetNoseHighR();
- Double_t conel = fmd3->GetConeLength();
- Double_t backl = fmd3->GetBackLength();
- Double_t backr1 = fmd3->GetBackLowR();
- Double_t backr2 = fmd3->GetBackHighR();
- Double_t zdist = conel - backl - nlen;
- Double_t tdist = backr2 - noser2;
- Double_t beaml = TMath::Sqrt(zdist * zdist + tdist * tdist);
- Double_t theta = -180. * TMath::ATan2(tdist, zdist) / TMath::Pi();
- Double_t innerZ = fmd3->GetInnerZ();
- Double_t innerZh = (innerZ - fmd3->GetInner()->GetRingDepth()
- - fmd3->GetHoneycombThickness());
- Double_t outerZ = fmd3->GetOuterZ();
- Double_t outerZh = (outerZ - fmd3->GetOuter()->GetRingDepth()
- - fmd3->GetHoneycombThickness());
- Double_t innerr1 = fmd3->GetInner()->GetLowR();
- // Double_t innerr2 = fmd3->GetInner()->GetHighR();
- Double_t outerr1 = fmd3->GetOuter()->GetLowR();
- // Double_t outerr2 = fmd3->GetOuter()->GetHighR();
- Double_t flanger = fmd3->GetFlangeR();
- Double_t minZ = TMath::Min(nz - conel, outerZh);
- Double_t z = fmd3->GetZ();
- Double_t zi;
- TVirtualMC* mc = TVirtualMC::GetMC();
- Int_t airId = (fFMD->GetIdtmed()->At(kAirId));
- Int_t cId = (fFMD->GetIdtmed()->At(kCarbonId));
- Double_t par[27];
-
- // FMD3 volume
- par[0] = 0;
- par[1] = 360;
- par[2] = 8;
- // First
- par[3] = z - nz;
- par[4] = noser1;
- par[5] = noser2;
- // Second
- par[6] = z - (nz - nlen);
- par[7] = noser1;
- par[8] = fmd3->ConeR(z - par[6])+.15;
- // Third
- par[9] = z - innerZ;
- par[10] = innerr1;
- par[11] = fmd3->ConeR(z - par[9])+.15;
- // Fourth
- par[12] = z - innerZh;
- par[13] = innerr1;
- par[14] = fmd3->ConeR(z - par[12])+.15;
- // Fifth
- par[15] = par[12];
- par[16] = outerr1;
- par[17] = fmd3->ConeR(z - par[15])+.15;
- // Sixth
- par[18] = z - nz + zdist + nlen;
- par[19] = outerr1;
- par[20] = fmd3->ConeR(z - par[18])+.15;
- // Seventh
- par[21] = z - nz + nlen + zdist;
- par[22] = outerr1;
- par[23] = flanger+1.5;
- // Eight
- par[24] = z - minZ;
- par[25] = outerr1;
- par[26] = flanger+1.5;
- mc->Gsvolu(fmd3->GetName(), "PCON", airId, par, 27);
-
- Int_t id;
- mc->Matrix(id, 270, 180, 90, 90, 180, 0);
- mc->Gspos(fmd3->GetName(), fmd3->GetId(), "ALIC", 0, 0, z, id, "ONLY");
-
- // Nose volume
- par[0] = noser1;
- par[1] = noser2;
- par[2] = nlen / 2;
- zi = z - nz + nlen / 2;
- mc->Gsvolu(fgkNoseName, "TUBE", cId, par, 3);
- mc->Gspos(fgkNoseName, 0, fmd3->GetName(), 0, 0, zi, 0, "MANY");
-
- // Back
- par[0] = backr1;
- par[1] = backr2;
- par[2] = backl / 2;
- zi = z - nz + conel - backl / 2;
- mc->Gsvolu(fgkBackName, "TUBE", cId, par, 3);
- mc->Gspos(fgkBackName, 0, fmd3->GetName(), 0, 0, zi, 0, "ONLY");
-
- Int_t n;
- Double_t r;
- // The flanges
- par[0] = (flanger - backr2) / 2;
- par[1] = fmd3->GetBeamWidth() / 2;
- par[2] = backl / 2;
- mc->Gsvolu(fgkFlangeName, "BOX", cId, par, 3);
- n = fmd3->GetNFlange();
- r = backr2 + (flanger - backr2) / 2;
- for (Int_t i = 0; i < n; i++) {
- Double_t phi = 360. / n * i + 180. / n;
- Double_t x = r * TMath::Cos(TMath::Pi() / 180 * phi);
- Double_t y = r * TMath::Sin(TMath::Pi() / 180 * phi);
- Int_t id;
- mc->Matrix(id, 90, phi, 90, 90 + phi, 0, 0);
- mc->Gspos(fgkFlangeName, i, fmd3->GetName(), x, y, zi, id, "ONLY");
- }
-
- // The Beams
- par[0] = fmd3->GetBeamThickness() / 2;
- par[1] = fmd3->GetBeamWidth() / 2;
- par[2] = beaml / 2;
- mc->Gsvolu(fgkBeamName, "BOX", cId, par, 3);
- n = fmd3->GetNBeam();
- r = noser2 + tdist / 2;
- zi = z - nz + nlen + zdist / 2;
- for (Int_t i = 0; i < n; i++) {
- Double_t phi = 360. / n * i;
- Double_t x = r * TMath::Cos(TMath::Pi() / 180 * phi);
- Double_t y = r * TMath::Sin(TMath::Pi() / 180 * phi);
- Int_t id;
- (void)theta;
- mc->Matrix(id, 90-theta, phi, 90, 90 + phi, 360 - theta, phi);
- mc->Gspos(fgkBeamName, i, fmd3->GetName(), x, y, zi, id, "MANY");
- }
-
- return DetectorGeometry(fmd3, z);
-}
-
-//____________________________________________________________________
-void
-AliFMDG3Simulator::DefineGeometry()
-{
- // Setup up the FMD geometry.
- AliDebug(10, "Setting up volume");
-
- AliFMDGeometry* fmd = AliFMDGeometry::Instance();
- if (!RingGeometry(fmd->GetInner())) {
- AliError("Failed to create inner ring volume");
- return;
- }
- if (!RingGeometry(fmd->GetOuter())) {
- AliError("Failed to create outer ring volume");
- return;
- }
- FMD1Geometry(fmd->GetFMD1());
- FMD2Geometry(fmd->GetFMD2());
- FMD3Geometry(fmd->GetFMD3());
-}
-
-//____________________________________________________________________
-//
-// EOF
-//
+++ /dev/null
-#ifndef ALIFMDG3SIMULATOR_H
-#define ALIFMDG3SIMULATOR_H
-/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights
- * reserved.
- *
- * Latest changes by Christian Holm Christensen <cholm@nbi.dk>
- *
- * See cxx source for full Copyright notice
- */
-#ifndef ALIFMDSIMULATOR
-# include <AliFMDSimulator.h>
-#endif
-class AliFMD;
-class AliFMDRing;
-class AliFMDDetector;
-class AliFMD1;
-class AliFMD2;
-class AliFMD3;
-
-//____________________________________________________________________
-class AliFMDG3Simulator : public AliFMDSimulator
-{
-public:
- AliFMDG3Simulator();
- /** CTOR */
- AliFMDG3Simulator(AliFMD* fmd, Bool_t detailed=kTRUE);
- virtual ~AliFMDG3Simulator() {}
- /** Register */
- virtual void DefineGeometry();
-protected:
- /** Make a ring volume
- @param r Ring geometry
- @return Ring volume */
- virtual Bool_t RingGeometry(AliFMDRing* r);
- /** Make a detector volume
- @param d Detector geometry
- @param mother Mother volume (detector volume)
- @param zmother Z position of mother
- @param inner Inner ring volume
- @param outer Outer ring volume
- @return Detector volume */
- virtual Bool_t DetectorGeometry(AliFMDDetector* d, Double_t zmother);
- /** Make FMD1 volume
- @param d Detector geometry
- @param inner Inner ring volume
- @return FMD1 volume */
- virtual Bool_t FMD1Geometry(AliFMD1* d);
- /** Make FMD2 volume
- @param d Detector geometry
- @param inner Inner ring volume
- @param outer Outer ring volume
- @return FMD2 volume */
- virtual Bool_t FMD2Geometry(AliFMD2* d);
- /** Make FMD3 volume
- @param d Detector geometry
- @param inner Inner ring volume
- @param outer Outer ring volume
- @return FMD3 volume */
- virtual Bool_t FMD3Geometry(AliFMD3* d);
-
- ClassDef(AliFMDG3Simulator,1);
-};
-
-
-#endif
-//____________________________________________________________________
-//
-// Local Variables:
-// mode: C++
-// End:
-//
-// EOF
-//
-
+++ /dev/null
-/**************************************************************************
- * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
- * *
- * Author: The ALICE Off-line Project. *
- * Contributors are mentioned in the code where appropriate. *
- * *
- * Permission to use, copy, modify and distribute this software and its *
- * documentation strictly for non-commercial purposes is hereby granted *
- * without fee, provided that the above copyright notice appears in all *
- * copies and that both the copyright notice and this permission notice *
- * appear in the supporting documentation. The authors make no claims *
- * about the suitability of this software for any purpose. It is *
- * provided "as is" without express or implied warranty. *
- **************************************************************************/
-
-/* $Id$ */
-
-//____________________________________________________________________
-//
-// 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.
-//
-// 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 simulation
-//
-// +--------+ 1 +-----------------+
-// | AliFMD |<>-----| AliFMDSimulator |
-// +--------+ +-----------------+
-// ^
-// |
-// +-------------+-------------+
-// | |
-// +--------------------+ +-------------------+
-// | AliFMDGeoSimulator | | AliFMDG3Simulator |
-// +--------------------+ +-------------------+
-// ^
-// |
-// +----------------------+
-// | AliFMDG3OldSimulator |
-// +----------------------+
-//
-//
-// * AliFMD
-// This defines the interface for the various parts of AliROOT that
-// uses the FMD, like AliFMDSimulator, AliFMDDigitizer,
-// AliFMDReconstructor, and so on.
-//
-// * AliFMDSimulator
-// This is the base class for the FMD simulation tasks. The
-// 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. This defines the active
-// volume as an ONLY XTRU shape with a divided MANY TUBS shape
-// inside to implement the particular shape of the silicon
-// sensors.
-//
-// * AliFMDG3OldSimulator
-// This is a concrete implementation of the AliFMDSimulator that
-// uses the TVirtualMC interface with GEANT 3.21-like messages.
-// This implements the active volume as a divided TUBS shape. Hits
-// in the corners should be cut away at run time (but currently
-// isn't).
-//
-#include <math.h>
-#include "AliFMDGeoOldSimulator.h" // ALIFMDG3OLDSIMULATOR_H
-#include "AliFMDGeometry.h" // ALIFMDGEOMETRY_H
-#include "AliFMDDetector.h" // ALIFMDDETECTOR_H
-#include "AliFMDRing.h" // ALIFMDRING_H
-#include "AliFMD1.h" // ALIFMD1_H
-#include "AliFMD2.h" // ALIFMD2_H
-#include "AliFMD3.h" // ALIFMD3_H
-#include "AliFMD.h" // ALIFMD_H
-#include <AliLog.h> // ALILOG_H
-#include <TVector2.h> // ROOT_TVector2
-#include <TVirtualMC.h> // ROOT_TVirtualMC
-#include <TArrayI.h> // ROOT_TArrayI
-#include <TGeoVolume.h> // ROOT_TGeoVolume
-#include <TGeoTube.h> // ROOT_TGeoTube
-#include <TGeoMatrix.h> // ROOT_TGeoMatrix
-
-//====================================================================
-ClassImp(AliFMDGeoOldSimulator)
-#if 0
- ; // This is here to keep Emacs for indenting the next line
-#endif
-
-//____________________________________________________________________
-AliFMDGeoOldSimulator::AliFMDGeoOldSimulator()
-{
- // Default constructor
- fSectorOff = 1;
- fModuleOff = -1;
- fRingOff = 3;
- fDetectorOff = 4;
- fUseDivided = kTRUE;
-}
-
-//____________________________________________________________________
-AliFMDGeoOldSimulator::AliFMDGeoOldSimulator(AliFMD* fmd, Bool_t detailed)
- : AliFMDGeoSimulator(fmd, detailed)
-{
- // Normal constructor
- //
- // Parameters:
- //
- // fmd Pointer to AliFMD object
- // detailed Whether to make a detailed simulation or not
- //
- fSectorOff = 1;
- fModuleOff = -1;
- fRingOff = 3;
- fDetectorOff = 4;
- fUseDivided = kTRUE;
-}
-
-//____________________________________________________________________
-TGeoVolume*
-AliFMDGeoOldSimulator::RingGeometry(AliFMDRing* r)
-{
- // Setup the geometry of a ring. The defined TGeoVolume is
- // returned, and should be used when setting up the rest of the
- // volumes.
- //
- // Parameters:
- //
- // r Pointer to ring geometry object
- //
- // Returns:
- // true on success
- //
- if (!r) {
- AliError("Didn't get a ring object");
- return 0x0;
- }
- Char_t id = r->GetId();
- Double_t siThick = r->GetSiThickness();
- // const Int_t nv = r->GetNVerticies();
- //TVector2* a = r->GetVertex(5);
- TVector2* b = r->GetVertex(3);
- //TVector2* c = r->GetVertex(4);
- Double_t theta = r->GetTheta();
- //Double_t off = (TMath::Tan(TMath::Pi() * theta / 180)
- // * r->GetBondingWidth());
- Double_t rmax = b->Mod();
- Double_t rmin = r->GetLowR();
- Double_t pcbThick = r->GetPrintboardThickness();
- Double_t copperThick = r->GetCopperThickness(); // .01;
- Double_t chipThick = r->GetChipThickness(); // .01;
- //Double_t modSpace = r->GetModuleSpacing();
- //Double_t legr = r->GetLegRadius();
- //Double_t legl = r->GetLegLength();
- //Double_t legoff = r->GetLegOffset();
- Int_t ns = r->GetNStrips();
- Int_t nsec = Int_t(360 / theta);
- Double_t space = r->GetSpacing();
- //Double_t stripoff = a->Mod();
- //Double_t dstrip = (rmax - stripoff) / ns;
- TString name;
- TString name2;
-
- Double_t ringWidth = (siThick + 2 * (pcbThick + copperThick + chipThick));
- // Virtual volume shape to divide - This volume is only defined if
- // the geometry is set to be detailed.
- // Ring mother volume
- TGeoShape* ringShape = new TGeoTube(rmin, rmax, ringWidth / 2);
- name = Form(fgkRingName, id);
- TGeoVolume* ringVolume = new TGeoVolume(name.Data(), ringShape, fAir);
-
- TGeoShape* activeShape = new TGeoTube(rmin, rmax, siThick / 2);
- name = Form(fgkActiveName, id);
- Double_t z = - ringWidth / 2 + siThick / 2;
- TGeoVolume* activeVolume = new TGeoVolume(name.Data(), activeShape, fSi);
- ringVolume->AddNode(activeVolume, 1, new TGeoTranslation(0, 0, z));
-
- Int_t sid = activeVolume->GetNumber();
- if (fUseDivided) {
- name = Form(fgkSectorName, id);
- TGeoVolume* sectorVolume = activeVolume->Divide(name.Data(), 2, nsec,
- 0, 0, 0, "N");
-
- name = Form(fgkStripName, id);
- TGeoVolume* stripVolume = sectorVolume->Divide(name.Data(), 1, ns,
- 0, 0, 0, "N");
- sid = stripVolume->GetNumber();
- AliDebug(10, Form("Got volume id %d for volume %s", sid, name.Data()));
- }
- switch (id) {
- case 'i':
- case 'I': fActiveId[0] = sid; break;
- case 'o':
- case 'O': fActiveId[2] = sid; break;
- }
-
- // Shape of Printed circuit Board
- Double_t boardThick = (pcbThick + copperThick + chipThick);
- TGeoShape* boardShape = new TGeoTube(rmin+.1, rmax-.1, boardThick/ 2);
- name = Form(fgkPCBName, id, 'B');
- TGeoVolume* boardVolume = new TGeoVolume(name.Data(), boardShape, fAir);
- z += siThick / 2 + space + boardThick / 2;
- ringVolume->AddNode(boardVolume, 0, new TGeoTranslation(0, 0, z));
- ringVolume->AddNode(boardVolume, 1, new TGeoTranslation(0,0,z+boardThick));
-
- // PCB
- TGeoShape* pcbShape = new TGeoTube(rmin+.1,rmax-.1, pcbThick / 2);
- name = Form("F%cPC", id);
- z = -boardThick / 2 + pcbThick / 2;
- TGeoVolume* pcbVolume = new TGeoVolume(name.Data(), pcbShape, fPCB);
- boardVolume->AddNode(pcbVolume, 0, new TGeoTranslation(0, 0, z));
-
- // Copper
- TGeoShape* cuShape = new TGeoTube(rmin+.1, rmax-.1, copperThick / 2);
- name = Form("F%cCO", id);
- z += pcbThick / 2 + copperThick / 2;
- TGeoVolume* cuVolume = new TGeoVolume(name.Data(), cuShape, fCopper);
- boardVolume->AddNode(cuVolume, 0, new TGeoTranslation(0, 0, z));
-
- // Chip
- TGeoShape* chipShape = new TGeoTube(rmin+.1, rmax-.1, chipThick / 2);
- name = Form("F%cCH", id);
- z += copperThick / 2 + chipThick / 2;
- TGeoVolume* chipVolume = new TGeoVolume(name.Data(), chipShape, fChip);
- boardVolume->AddNode(chipVolume, 0, new TGeoTranslation(0, 0, z));
-
- return ringVolume;
-}
-
-//____________________________________________________________________
-//
-// EOF
-//
+++ /dev/null
-#ifndef ALIFMDGEOOLDSIMULATOR_H
-#define ALIFMDGEOOLDSIMULATOR_H
-/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights
- * reserved.
- *
- * Latest changes by Christian Holm Christensen <cholm@nbi.dk>
- *
- * See cxx source for full Copyright notice
- */
-#ifndef ALIFMDGEOSIMULATOR
-# include <AliFMDGeoSimulator.h>
-#endif
-class AliFMD;
-class AliFMDRing;
-class AliFMDDetector;
-class AliFMD1;
-class AliFMD2;
-class AliFMD3;
-
-//____________________________________________________________________
-class AliFMDGeoOldSimulator : public AliFMDGeoSimulator
-{
-public:
- AliFMDGeoOldSimulator();
- /** CTOR */
- AliFMDGeoOldSimulator(AliFMD* fmd, Bool_t detailed=kTRUE);
- virtual ~AliFMDGeoOldSimulator() {}
- virtual void UseDivided(Bool_t) { fUseDivided = kTRUE; }
-protected:
- /** Make a ring volume
- @param r Ring geometry
- @return Ring volume */
- TGeoVolume* RingGeometry(AliFMDRing* r);
- ClassDef(AliFMDGeoOldSimulator,1);
-};
-
-
-#endif
-//____________________________________________________________________
-//
-// Local Variables:
-// mode: C++
-// End:
-//
-// EOF
-//
-
+++ /dev/null
-/**************************************************************************
- * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
- * *
- * Author: The ALICE Off-line Project. *
- * Contributors are mentioned in the code where appropriate. *
- * *
- * Permission to use, copy, modify and distribute this software and its *
- * documentation strictly for non-commercial purposes is hereby granted *
- * without fee, provided that the above copyright notice appears in all *
- * copies and that both the copyright notice and this permission notice *
- * appear in the supporting documentation. The authors make no claims *
- * about the suitability of this software for any purpose. It is *
- * provided "as is" without express or implied warranty. *
- **************************************************************************/
-
-/* $Id$ */
-
-//____________________________________________________________________
-//
-// 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.
-//
-// 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 simulation
-//
-// +--------+ 1 +-----------------+
-// | AliFMD |<>-----| AliFMDSimulator |
-// +--------+ +-----------------+
-// ^
-// |
-// +-------------+-------------+
-// | |
-// +--------------------+ +-------------------+
-// | AliFMDGeoSimulator | | AliFMDG3Simulator |
-// +--------------------+ +---------+---------+
-// ^
-// |
-// +--------------------+
-// | AliFMDOldSimulator |
-// +--------------------+
-//
-// * AliFMD
-// This defines the interface for the various parts of AliROOT that
-// uses the FMD, like AliFMDSimulator, AliFMDDigitizer,
-// AliFMDReconstructor, and so on.
-//
-// * AliFMDSimulator
-// This is the base class for the FMD simulation tasks. The
-// 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. This defines the active
-// volume as an ONLY XTRU shape with a divided MANY TUBS shape
-// inside to implement the particular shape of the silicon
-// sensors.
-//
-// * AliFMDG3Simulator
-// This is a concrete implementation of the AliFMDSimulator that
-// uses the TVirtualMC interface with GEANT 3.21-like messages.
-// This implements the active volume as a divided TUBS shape. Hits
-// in the corners should be cut away at run time (but currently
-// isn't).
-//
-// * AliFMDOldSimulator
-// This is a concrete implementation of AliFMDSimulator. It
-// approximates the of the rings as segmented disks.
-//
-#include "AliFMDGeoSimulator.h" // ALIFMDGEOSIMULATOR_H
-#include "AliFMDGeometry.h" // ALIFMDGEOMETRY_H
-#include "AliFMDDetector.h" // ALIFMDDETECTOR_H
-#include "AliFMDRing.h" // ALIFMDRING_H
-#include "AliFMD1.h" // ALIFMD1_H
-#include "AliFMD2.h" // ALIFMD2_H
-#include "AliFMD3.h" // ALIFMD3_H
-#include "AliFMD.h" // ALIFMD_H
-#include "AliLog.h" // ALILOG_H
-#include <TGeoVolume.h> // ROOT_TGeoVolume
-#include <TGeoTube.h> // ROOT_TGeoTube
-#include <TGeoPcon.h> // ROOT_TGeoPcon
-#include <TGeoMaterial.h> // ROOT_TGeoMaterial
-#include <TGeoMedium.h> // ROOT_TGeoMedium
-#include <TGeoXtru.h> // ROOT_TGeoXtru
-#include <TGeoPolygon.h> // ROOT_TGeoPolygon
-#include <TGeoTube.h> // ROOT_TGeoTube
-#include <TGeoManager.h> // ROOT_TGeoManager
-#include <TVector2.h> // ROOT_TVector2
-#include <TArrayD.h> // ROOT_TArrayD
-
-//====================================================================
-ClassImp(AliFMDGeoSimulator)
-#if 0
- ; // This is here to keep Emacs for indenting the next line
-#endif
-
-//____________________________________________________________________
-AliFMDGeoSimulator::AliFMDGeoSimulator()
- : fSi(0),
- fC(0),
- fAl(0),
- fPCB(0),
- fChip(0),
- fPlastic(0)
-{
- // Default constructor
- fSectorOff = 1;
- fModuleOff = 4;
- fRingOff = 5;
- fDetectorOff = 6;
-}
-
-//____________________________________________________________________
-AliFMDGeoSimulator::AliFMDGeoSimulator(AliFMD* fmd, Bool_t detailed)
- : AliFMDSimulator(fmd, detailed),
- fSi(0),
- fC(0),
- fAl(0),
- fPCB(0),
- fChip(0),
- fPlastic(0)
-{
- // Normal constructor
- //
- // Parameters:
- //
- // fmd Pointer to AliFMD object
- // detailed Whether to make a detailed simulation or not
- //
- fSectorOff = 1;
- fModuleOff = 4;
- fRingOff = 5;
- fDetectorOff = 6;
-}
-
-//____________________________________________________________________
-void
-AliFMDGeoSimulator::DefineMaterials()
-{
- // 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
- //
- // 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_ALICE)
- // FMD Chip$ Electronics chips (currently not used)
- // FMD Air$ Air (Air in the FMD)
- // FMD Plastic$ Plastic (Support legs for the hybrid cards)
- //
- // Pointers to TGeoMedium objects are retrived from the TGeoManager
- // singleton. These pointers are later used when setting up the
- // geometry
- AliDebug(10, "\tCreating materials");
-
- if (!gGeoManager) {
- AliFatal("No TGeoManager defined");
- return;
- }
- AliFMDSimulator::DefineMaterials();
- fSi = gGeoManager->GetMedium("FMD_Si$");
- fC = gGeoManager->GetMedium("FMD_Carbon$");
- fAl = gGeoManager->GetMedium("FMD_Aluminum$");
- fChip = gGeoManager->GetMedium("FMD_Si Chip$");
- fAir = gGeoManager->GetMedium("FMD_Air$");
- fPCB = gGeoManager->GetMedium("FMD_PCB$");
- fPlastic = gGeoManager->GetMedium("FMD_Plastic$");
- fCopper = gGeoManager->GetMedium("FMD_Copper$");
-}
-
-//____________________________________________________________________
-TGeoVolume*
-AliFMDGeoSimulator::RingGeometry(AliFMDRing* r)
-{
- // Setup the geometry of a ring. The defined TGeoVolume is
- // returned, and should be used when setting up the rest of the
- // volumes.
- //
- //
- // Parameters:
- //
- // r Pointer to ring geometry object
- //
- // Returns:
- // pointer to ring volume
- //
- if (!r) {
- AliError("Didn't get a ring object");
- return 0;
- }
- Char_t id = r->GetId();
- Double_t siThick = r->GetSiThickness();
- const Int_t nv = r->GetNVerticies();
- TVector2* a = r->GetVertex(5);
- TVector2* b = r->GetVertex(3);
- TVector2* c = r->GetVertex(4);
- Double_t theta = r->GetTheta();
- Double_t off = (TMath::Tan(TMath::Pi() * theta / 180)
- * r->GetBondingWidth());
- Double_t rmax = b->Mod();
- Double_t rmin = r->GetLowR();
- Double_t pcbThick = r->GetPrintboardThickness();
- Double_t modSpace = r->GetModuleSpacing();
- Double_t legr = r->GetLegRadius();
- Double_t legl = r->GetLegLength();
- Double_t legoff = r->GetLegOffset();
- Int_t ns = r->GetNStrips();
- Double_t stripoff = a->Mod();
- Double_t dstrip = (rmax - stripoff) / ns;
- Double_t space = r->GetSpacing();
- TArrayD xs(nv);
- TArrayD ys(nv);
- for (Int_t i = 0; i < nv; i++) {
- // Reverse the order
- TVector2* vv = r->GetVertex(nv - 1 - i);
- if (!vv) {
- AliError(Form("Failed to get vertex # %d", nv - 1 - i));
- continue;
- }
- xs[i] = vv->X();
- ys[i] = vv->Y();
- }
-
- // Shape of actual sensor
- TGeoXtru* moduleShape = new TGeoXtru(2);
- moduleShape->DefinePolygon(nv, xs.fArray, ys.fArray);
- moduleShape->DefineSection(0, - siThick/2);
- moduleShape->DefineSection(1, siThick/2);
- TGeoVolume* moduleVolume = new TGeoVolume(Form(fgkModuleName, id),
- moduleShape, fSi);
- Int_t sid = moduleVolume->GetNumber();
- fSectorOff = -1;
- fModuleOff = 1;
- fRingOff = 2;
- fDetectorOff = 3;
- if (fUseDivided) {
- fSectorOff = 1;
- fModuleOff = 4;
- fRingOff = 5;
- fDetectorOff = 6;
- // Virtual volume shape to divide - This volume is only defined if
- // the geometry is set to be detailed.
- TGeoVolume* activeVolume = 0;
- if (fDetailed) {
- TGeoTubeSeg* activeShape =
- new TGeoTubeSeg(rmin, rmax, siThick/2, - theta, theta);
- activeVolume = new TGeoVolume(Form(fgkActiveName, id),activeShape,fSi);
- TGeoVolume* sectorVolume = activeVolume->Divide(Form(fgkSectorName,id),
- 2, 2, -theta,0,0,"N");
- TGeoVolume* stripVolume = sectorVolume->Divide(Form(fgkStripName, id),
- 1, ns, stripoff, dstrip,
- 0, "SX");
- sid = stripVolume->GetNumber();
- }
- // Add divived MANY volume to the true shape of the module, but only
- // if a detailed simulation is reguested.
- if (activeVolume) moduleVolume->AddNodeOverlap(activeVolume, 0);
- }
-
- switch (id) {
- case 'i':
- case 'I': fActiveId[0] = sid; break;
- case 'o':
- case 'O': fActiveId[2] = sid; break;
- }
-
- // Shape of Printed circuit Board
- TGeoXtru* pcbShape = new TGeoXtru(2);
- for (Int_t i = 0; i < nv / 2; i++) ys[i] -= off;
- for (Int_t i = nv / 2; i < nv; i++) ys[i] += off;
- pcbShape->DefinePolygon(nv, xs.fArray, ys.fArray);
- pcbShape->DefineSection(0, - pcbThick/2);
- pcbShape->DefineSection(1, pcbThick/2);
- TGeoVolume* pcbVolume = new TGeoVolume(Form(fgkPCBName, id, 'B'),
- pcbShape, fPCB);
-
- // Short leg shape
- TGeoTube* shortLegShape = new TGeoTube(0, legr, legl / 2);
- TGeoVolume* shortLegVolume = new TGeoVolume(Form(fgkShortLegName, id),
- shortLegShape, fPlastic);
-
- // Long leg shape
- TGeoTube* longLegShape = new TGeoTube(0, legr, (legl + modSpace) / 2);
- TGeoVolume* longLegVolume = new TGeoVolume(Form(fgkLongLegName, id),
- longLegShape, fPlastic);
-
- TGeoMatrix* matrix = 0;
- // Back container volume
- Double_t contThick = siThick + pcbThick + legl + space;
- TGeoTubeSeg* backShape = new TGeoTubeSeg(rmin, rmax, contThick/2,
- - theta, theta);
- TGeoVolume* backVolume = new TGeoVolume(Form(fgkBackVName, id),
- backShape, fAir);
- Double_t x = 0;
- Double_t y = 0;
- Double_t z = -contThick / 2 + siThick / 2;
- matrix = new TGeoTranslation(Form("FMD Ring %c mod 1 transform", id),
- x, y, z);
- backVolume->AddNode(moduleVolume, 0, matrix);
- z += siThick / 2 + space + pcbThick / 2;
- matrix = new TGeoTranslation(Form("FMD Ring %c pcb 1 transfrom", id),
- x, y, z);
- backVolume->AddNode(pcbVolume, 0, matrix);
- x = a->X() + legoff + legr;
- y = 0;
- z += pcbThick / 2 + legl / 2;
- matrix = new TGeoTranslation(Form("FMD Ring %c leg 1 transfrom", id),
- x, y, z);
- backVolume->AddNode(shortLegVolume, 0, matrix);
- x = c->X();
- y = c->Y() - legoff - legr - off;
- matrix = new TGeoTranslation(Form("FMD Ring %c leg 2 transfrom", id),
- x, y, z);
- backVolume->AddNode(shortLegVolume, 1, matrix);
- y = -y;
- matrix = new TGeoTranslation(Form("FMD Ring %c leg 3 transfrom", id),
- x, y, z);
- backVolume->AddNode(shortLegVolume, 2, matrix);
- // backVolume->SetVisibility(kFALSE);
- // backVolume->VisibleDaughters(kTRUE);
-
- // Front container volume
- contThick += modSpace;
- TGeoTubeSeg* frontShape = new TGeoTubeSeg(rmin, rmax, contThick/2,
- -theta, theta);
- TGeoVolume* frontVolume = new TGeoVolume(Form(fgkFrontVName, id),
- frontShape, fAir);
- x = 0;
- y = 0;
- z = -contThick / 2 + siThick / 2 ;
- matrix = new TGeoTranslation(Form("FMD Ring %c mod 2 transfrom", id),
- 0, 0, z);
- frontVolume->AddNode(moduleVolume, 1, matrix);
- z += siThick / 2 + space + pcbThick / 2;
- matrix = new TGeoTranslation(Form("FMD Ring %c pcb 2 transfrom", id),
- x, y, z);
- frontVolume->AddNode(pcbVolume, 1, matrix);
- x = a->X() + legoff + legr;
- y = 0;
- z += pcbThick / 2 + (legl + modSpace)/ 2;
- matrix = new TGeoTranslation(Form("FMD Ring %c leg 4 transfrom", id),
- x, y, z);
- frontVolume->AddNode(longLegVolume, 0, matrix);
- x = c->X();
- y = c->Y() - legoff - legr - off;
- matrix = new TGeoTranslation(Form("FMD Ring %c leg 4 transfrom", id),
- x, y, z);
- frontVolume->AddNode(longLegVolume, 1, matrix);
- y = -y;
- matrix = new TGeoTranslation(Form("FMD Ring %c leg 4 transfrom", id),
- x, y, z);
- frontVolume->AddNode(longLegVolume, 2, matrix);
- // frontVolume->SetVisibility(kFALSE);
- // frontVolume->VisibleDaughters(kTRUE);
-
- // Ring mother volume
- TGeoTube* ringShape = new TGeoTube(rmin, rmax, contThick / 2);
- TGeoVolume* ringVolume = new TGeoVolume(Form(fgkRingName,id),
- ringShape,fAir);
-
- Int_t nmod = r->GetNModules();
- AliDebug(10, Form("making %d modules in ring %c", nmod, id));
- for (Int_t i = 0; i < nmod; i++) {
- Bool_t isFront = (i % 2 == 0);
- TGeoVolume* vol = (isFront ? frontVolume : backVolume);
- TGeoRotation* rot =new TGeoRotation(Form("FMD Ring %c rotation %d",id,i));
- rot->RotateZ((i + .5) * 2 * theta);
- Double_t z = (isFront ? 0 : modSpace) / 2;
- matrix = new TGeoCombiTrans(Form("FMD Ring %c transform %d", id, i),
- 0, 0, z, rot);
- ringVolume->AddNode(vol, i, matrix);
- }
-
- ringVolume->SetVisibility(kFALSE);
- ringVolume->VisibleDaughters(kTRUE);
- return ringVolume;
-}
-
-//____________________________________________________________________
-TGeoVolume*
-AliFMDGeoSimulator::DetectorGeometry(AliFMDDetector* d,
- TGeoVolume* mother,
- Double_t zmother,
- TGeoVolume* inner,
- TGeoVolume* outer)
-{
- // Common stuff for setting up the FMD1, FMD2, and FMD3 geometries.
- // This includes putting the Honeycomb support plates and the rings
- // into the mother volumes.
- //
- // Parameeters:
- // d The detector geometry to use
- // mother The mother volume of the detector
- // zmother The midpoint in global coordinates of detector vol.
- // inner Pointer to inner ring volume
- // outer Pointer to outer ring volume
- //
- // Returns:
- // Pointer to mother (detector volume)
- //
- if (!d) return 0;
- // Loop over the defined rings
- for (int i = 0; i < 2; i++) {
- AliFMDRing* r = 0;
- Double_t lowr = 0;
- Double_t highr = 0;
- Double_t rz = 0;
- TGeoVolume* rvol = 0;
- switch (i) {
- case 0:
- r = d->GetInner();
- lowr = d->GetInnerHoneyLowR();
- highr = d->GetInnerHoneyHighR();
- rz = d->GetInnerZ();
- rvol = inner;
- break;
- case 1:
- r = d->GetOuter();
- lowr = d->GetOuterHoneyLowR();
- highr = d->GetOuterHoneyHighR();
- rz = d->GetOuterZ();
- rvol = outer;
- break;
- }
- if (!r) continue;
- Char_t c = r->GetId();
- Int_t id = d->GetId();
- Double_t hcThick = d->GetHoneycombThickness();
- Double_t alThick = d->GetAlThickness();
- Double_t z;
- if (zmother > 0) z = rz - zmother + r->GetRingDepth() / 2;
- else z = zmother - rz + r->GetRingDepth() / 2;
- // Place ring in mother volume
- mother->AddNode(rvol, Int_t(c),
- new TGeoTranslation(Form("FMD%d%c transform", id, c),
- 0, 0, z));
-
- z += r->GetRingDepth() / 2 + hcThick / 2;
- // Top of Honeycomb
- TGeoTubeSeg* topHCShape = new TGeoTubeSeg(lowr, highr, hcThick/2, 0, 180);
- TGeoVolume* topHCVolume = new TGeoVolume(Form(fgkTopHCName, id, c),
- topHCShape, fAl);
- TGeoMatrix* topHCMatrix =
- new TGeoTranslation(Form("FMD%d%c top HC transform", id, c), 0, 0, z);
- mother->AddNode(topHCVolume, 0, topHCMatrix);
-
- // Air in top of honeycomb
- TGeoTubeSeg* topIHCShape = new TGeoTubeSeg(lowr+alThick, highr - alThick,
- (hcThick-alThick)/2, 0, 180);
- TGeoVolume* topIHCVolume = new TGeoVolume(Form(fgkTopIHCName, id, c),
- topIHCShape, fAir);
- topHCVolume->AddNode(topIHCVolume, 0);
- topHCVolume->VisibleDaughters(kFALSE);
- topHCVolume->SetVisibility(kTRUE);
-
-
- // Bottom of Honeycomb
- TGeoTubeSeg* botHCShape = new TGeoTubeSeg(lowr, highr, hcThick/2,
- 180, 360);
- TGeoVolume* botHCVolume = new TGeoVolume(Form(fgkBotHCName, id, c),
- botHCShape, fAl);
- TGeoMatrix* botHCMatrix =
- new TGeoTranslation(Form("FMD%d%c bottom HC transform", id, c), 0, 0, z);
- mother->AddNode(botHCVolume, 0, botHCMatrix);
-
- // Air in bot of honeycomb
- TGeoTubeSeg* botIHCShape = new TGeoTubeSeg(lowr+alThick, highr - alThick,
- (hcThick-alThick)/2, 180, 360);
- TGeoVolume* botIHCVolume = new TGeoVolume(Form(fgkBotIHCName, id, c),
- botIHCShape, fAir);
- botHCVolume->AddNode(botIHCVolume, 0);
- botHCVolume->VisibleDaughters(kFALSE);
- botHCVolume->SetVisibility(kTRUE);
- }
- mother->SetVisibility(kFALSE);
- mother->VisibleDaughters(kTRUE);
- return mother;
-}
-
-//____________________________________________________________________
-TGeoVolume*
-AliFMDGeoSimulator::FMD1Geometry(AliFMD1* fmd1, TGeoVolume* inner)
-{
- // Setup the FMD1 geometry. The FMD1 only has one ring, and no
- // special support as it is at the momement.
- //
- // See also AliFMDGeoSimulator::DetectorGeometry
- //
- if (!fmd1 || !inner) return 0;
- Double_t rmin = fmd1->GetInner()->GetLowR();
- Double_t rmax = fmd1->GetInnerHoneyHighR();
- Double_t hcThick = fmd1->GetHoneycombThickness();
- Double_t w = fmd1->GetInner()->GetRingDepth() + hcThick;
- Double_t z = fmd1->GetInnerZ() + w / 2;
-
- TGeoVolume* fmd1Volume = 0;
- if (!fUseAssembly) {
- TGeoTube* fmd1Shape = new TGeoTube(rmin, rmax, w / 2);
- fmd1Volume = new TGeoVolume(fmd1->GetName(), fmd1Shape, fAir);
- }
- else
- fmd1Volume = new TGeoVolumeAssembly(fmd1->GetName());
-
- TGeoVolume* top = gGeoManager->GetVolume("ALIC");
- TGeoMatrix* matrix = new TGeoTranslation("FMD1 transform", 0, 0, z);
- top->AddNode(fmd1Volume, fmd1->GetId(), matrix);
-
- return DetectorGeometry(fmd1, fmd1Volume, z, inner, 0);
-}
-
-//____________________________________________________________________
-TGeoVolume*
-AliFMDGeoSimulator::FMD2Geometry(AliFMD2* fmd2,
- TGeoVolume* inner,
- TGeoVolume* outer)
-{
- // Setup the FMD2 geometry. The FMD2 has no
- // special support as it is at the momement.
- //
- // See also AliFMDGeoSimulator::DetectorGeometry
- //
- if (!fmd2 || !inner || !outer) return 0;
- Double_t rmin = fmd2->GetInner()->GetLowR();
- Double_t rmax = fmd2->GetOuterHoneyHighR();
- Double_t hcThick = fmd2->GetHoneycombThickness();
- Double_t ow = fmd2->GetInner()->GetRingDepth();
- Double_t iz = fmd2->GetInnerZ();
- Double_t oz = fmd2->GetOuterZ();
- Double_t w = TMath::Abs(oz - iz) + ow + hcThick;
- Double_t z = oz + w / 2;
-
- TGeoVolume* fmd2Volume = 0;
- if (!fUseAssembly) {
- TGeoTube* fmd2Shape = new TGeoTube(rmin, rmax, w / 2);
- fmd2Volume = new TGeoVolume(fmd2->GetName(), fmd2Shape, fAir);
- }
- else
- fmd2Volume = new TGeoVolumeAssembly(fmd2->GetName());
-
- TGeoVolume* top = gGeoManager->GetVolume("ALIC");
- TGeoMatrix* matrix = new TGeoTranslation("FMD2 transform", 0, 0, z);
- top->AddNode(fmd2Volume, fmd2->GetId(), matrix);
-
- return DetectorGeometry(fmd2, fmd2Volume, z, inner, outer);
-}
-
-//____________________________________________________________________
-TGeoVolume*
-AliFMDGeoSimulator::FMD3Geometry(AliFMD3* fmd3,
- TGeoVolume* inner,
- TGeoVolume* outer)
-{
- // Setup the FMD3 geometry. The FMD2 has a rather elaborate support
- // structure, as the support will also support the vacuum
- // beam-pipe.
- //
- // See also AliFMDGeoSimulator::DetectorGeometry
- //
- if (!fmd3 || !inner || !outer) return 0;
- Double_t nlen = fmd3->GetNoseLength();
- Double_t nz = fmd3->GetNoseZ();
- Double_t noser1 = fmd3->GetNoseLowR();
- Double_t noser2 = fmd3->GetNoseHighR();
- Double_t conel = fmd3->GetConeLength();
- Double_t backl = fmd3->GetBackLength();
- Double_t backr1 = fmd3->GetBackLowR();
- Double_t backr2 = fmd3->GetBackHighR();
- Double_t zdist = conel - backl - nlen;
- Double_t tdist = backr2 - noser2;
- Double_t beaml = TMath::Sqrt(zdist * zdist + tdist * tdist);
- Double_t theta = -180. * TMath::ATan2(tdist, zdist) / TMath::Pi();
- Double_t innerZ = fmd3->GetInnerZ();
- Double_t innerZh = (innerZ - fmd3->GetInner()->GetRingDepth()
- - fmd3->GetHoneycombThickness());
- Double_t outerZ = fmd3->GetOuterZ();
- Double_t outerZh = (outerZ - fmd3->GetOuter()->GetRingDepth()
- - fmd3->GetHoneycombThickness());
- Double_t innerr1 = fmd3->GetInner()->GetLowR();
- // Double_t innerr2 = fmd3->GetInner()->GetHighR();
- Double_t outerr1 = fmd3->GetOuter()->GetLowR();
- // Double_t outerr2 = fmd3->GetOuter()->GetHighR();
- Double_t flanger = fmd3->GetFlangeR();
- Double_t minZ = TMath::Min(nz - conel, outerZh);
- Double_t z = fmd3->GetZ();
- Double_t zi;
-
- // FMD3 volume
- TGeoVolume* fmd3Volume = 0;
- if (!fUseAssembly) {
- TGeoPcon* fmd3Shape = new TGeoPcon(0, 360, 8);
- zi = z - nz;
- fmd3Shape->DefineSection(0, zi, noser1, noser2);
- zi = z - (nz - nlen);
- fmd3Shape->DefineSection(1, zi, noser1, fmd3->ConeR(z - zi)+.15);
- zi = z - innerZ;
- fmd3Shape->DefineSection(2, zi, innerr1, fmd3->ConeR(z - zi)+.15);
- zi = z - innerZh;
- fmd3Shape->DefineSection(3, zi, innerr1, fmd3->ConeR(z - zi)+.15);
- fmd3Shape->DefineSection(4, zi, outerr1, fmd3->ConeR(z - zi)+.15);
- zi = z - nz + zdist + nlen;
- fmd3Shape->DefineSection(5, zi, outerr1, fmd3->ConeR(z - zi)+.15);
- zi = z - nz + nlen + zdist;
- fmd3Shape->DefineSection(6, zi, outerr1, flanger+1.5);
- zi = z - minZ;
- fmd3Shape->DefineSection(7, zi, outerr1, flanger+1.5);
- fmd3Volume = new TGeoVolume(fmd3->GetName(), fmd3Shape, fAir);
- }
- else
- fmd3Volume = new TGeoVolumeAssembly(fmd3->GetName());
-
- TGeoRotation* rot = new TGeoRotation("FMD3 rotatation");
- rot->RotateY(180);
- TGeoVolume* top = gGeoManager->GetVolume("ALIC");
- TGeoMatrix* mmatrix = new TGeoCombiTrans("FMD3 transform", 0, 0, z, rot);
- top->AddNode(fmd3Volume, fmd3->GetId(), mmatrix);
-
- // Nose volume
- TGeoTube* noseShape = new TGeoTube(noser1, noser2, nlen / 2);
- TGeoVolume* noseVolume = new TGeoVolume(fgkNoseName, noseShape, fC);
- zi = z - nz + nlen / 2;
- TGeoMatrix* nmatrix = new TGeoTranslation("FMD3 Nose translation", 0, 0, zi);
- // fmd3Volume->AddNodeOverlap(noseVolume, 0, nmatrix);
- fmd3Volume->AddNode(noseVolume, 0, nmatrix);
-
- // Back
- TGeoTube* backShape = new TGeoTube(backr1, backr2, backl / 2);
- TGeoVolume* backVolume = new TGeoVolume(fgkBackName, backShape, fC);
- zi = z - nz + conel - backl / 2;
- TGeoMatrix* bmatrix = new TGeoTranslation("FMD3 Back translation", 0, 0, zi);
- fmd3Volume->AddNode(backVolume, 0, bmatrix);
-
- Int_t n;
- Double_t r;
- // The flanges
- TGeoBBox* flangeShape = new TGeoBBox((flanger - backr2) / 2,
- fmd3->GetBeamWidth() / 2,
- backl / 2);
- TGeoVolume* flangeVolume = new TGeoVolume(fgkFlangeName, flangeShape, fC);
- n = fmd3->GetNFlange();
- r = backr2 + (flanger - backr2) / 2;
- for (Int_t i = 0; i < n; i++) {
- Double_t phi = 360. / n * i + 180. / n;
- Double_t x = r * TMath::Cos(TMath::Pi() / 180 * phi);
- Double_t y = r * TMath::Sin(TMath::Pi() / 180 * phi);
- TGeoRotation* rot = new TGeoRotation(Form("FMD3 Flange rotation %d", i));
- rot->RotateZ(phi);
- TGeoMatrix* matrix = new TGeoCombiTrans(Form("FMD3 flange transform %d",
- i), x, y, zi, rot);
- // fmd3Volume->AddNodeOverlap(flangeVolume, i, matrix);
- fmd3Volume->AddNode(flangeVolume, i, matrix);
-
- }
-
- // The Beams
- TGeoBBox* beamShape = new TGeoBBox(fmd3->GetBeamThickness() / 2,
- fmd3->GetBeamWidth() / 2 - .1,
- beaml / 2);
- TGeoVolume* beamVolume = new TGeoVolume(fgkBeamName, beamShape, fC);
- n = fmd3->GetNBeam();
- r = noser2 + tdist / 2;
- zi = z - nz + nlen + zdist / 2;
- for (Int_t i = 0; i < n; i++) {
- Double_t phi = 360. / n * i;
- Double_t x = r * TMath::Cos(TMath::Pi() / 180 * phi);
- Double_t y = r * TMath::Sin(TMath::Pi() / 180 * phi);
- TGeoRotation* rot = new TGeoRotation(Form("FMD3 beam rotation %d", i));
- // Order is important
- rot->RotateY(-theta);
- rot->RotateZ(phi);
- TGeoMatrix* matrix = new TGeoCombiTrans(Form("FMD3 beam transform %d", i),
- x, y, zi, rot);
- fmd3Volume->AddNode(beamVolume, i, matrix);
- }
-
-
- return DetectorGeometry(fmd3, fmd3Volume, z, inner, outer);
-}
-
-//____________________________________________________________________
-void
-AliFMDGeoSimulator::DefineGeometry()
-{
- // Setup up the FMD geometry.
- AliDebug(1, "Setting up volumes, with ");
-
- AliFMDGeometry* fmd = AliFMDGeometry::Instance();
- TGeoVolume* inner = RingGeometry(fmd->GetInner());
- TGeoVolume* outer = RingGeometry(fmd->GetOuter());
-
- if (!inner || !outer) {
- AliError("Failed to create one of the ring volumes");
- return;
- }
- FMD1Geometry(fmd->GetFMD1(), inner);
- FMD2Geometry(fmd->GetFMD2(), inner, outer);
- FMD3Geometry(fmd->GetFMD3(), inner, outer);
-}
-
-
-//____________________________________________________________________
-//
-// EOF
-//
+++ /dev/null
-#ifndef ALIFMDGEOSIMULATOR_H
-#define ALIFMDGEOSIMULATOR_H
-/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights
- * reserved.
- *
- * Latest changes by Christian Holm Christensen <cholm@nbi.dk>
- *
- * See cxx source for full Copyright notice
- */
-#ifndef ALIFMDSIMULATOR
-# include <AliFMDSimulator.h>
-#endif
-class TGeoVolume;
-class TGeoMedium;
-class AliFMD;
-class AliFMDRing;
-class AliFMDDetector;
-class AliFMD1;
-class AliFMD2;
-class AliFMD3;
-
-//____________________________________________________________________
-class AliFMDGeoSimulator : public AliFMDSimulator
-{
-public:
- AliFMDGeoSimulator();
- /** CTOR */
- AliFMDGeoSimulator(AliFMD* fmd, Bool_t detailed=kTRUE);
- virtual ~AliFMDGeoSimulator() {}
- /** Initialize */
- virtual void DefineMaterials();
- /** Register */
- virtual void DefineGeometry();
-protected:
- /** Make a ring volume
- @param r Ring geometry
- @return Ring volume */
- virtual TGeoVolume* RingGeometry(AliFMDRing* r);
- /** Make a detector volume
- @param d Detector geometry
- @param mother Mother volume (detector volume)
- @param zmother Z position of mother
- @param inner Inner ring volume
- @param outer Outer ring volume
- @return Detector volume */
- virtual TGeoVolume* DetectorGeometry(AliFMDDetector* d,
- TGeoVolume* mother,
- Double_t zmother,
- TGeoVolume* inner,
- TGeoVolume* outer=0);
- /** Make FMD1 volume
- @param d Detector geometry
- @param inner Inner ring volume
- @return FMD1 volume */
- virtual TGeoVolume* FMD1Geometry(AliFMD1* d, TGeoVolume* inner);
- /** Make FMD2 volume
- @param d Detector geometry
- @param inner Inner ring volume
- @param outer Outer ring volume
- @return FMD2 volume */
- virtual TGeoVolume* FMD2Geometry(AliFMD2* d, TGeoVolume* inner,
- TGeoVolume* outer);
- /** Make FMD3 volume
- @param d Detector geometry
- @param inner Inner ring volume
- @param outer Outer ring volume
- @return FMD3 volume */
- virtual TGeoVolume* FMD3Geometry(AliFMD3* d, TGeoVolume* inner,
- TGeoVolume* outer);
- TGeoMedium* fSi; //! Si Medium
- TGeoMedium* fC; //! C Medium
- TGeoMedium* fAl; //! Al Medium
- TGeoMedium* fPCB; //! PCB Medium
- TGeoMedium* fChip; //! Chip Medium
- TGeoMedium* fAir; //! Air Medium
- TGeoMedium* fPlastic; //! Plastic Medium
- TGeoMedium* fCopper; //! Copper Medium
-
- ClassDef(AliFMDGeoSimulator,1)
-};
-
-#endif
-//____________________________________________________________________
-//
-// Local Variables:
-// mode: C++
-// End:
-//
-// EOF
-//
-
#include <TMatrix.h> // ROOT_TMatrix
#include <TParticle.h> // ROOT_TParticle
#include <Riostream.h>
-#ifndef USE_PRE_MOVE
#include "AliFMDGeometryBuilder.h"
#include <TArrayI.h>
#include <TGeoManager.h>
#include <TGeoVolume.h>
#include <TGeoNode.h>
static Int_t FindNodeDepth(const char* name, const char* volname);
-#endif
//====================================================================
fUseFMD1 = kTRUE;
fUseFMD2 = kTRUE;
fUseFMD3 = kTRUE;
-#ifndef USE_PRE_MOVE
fDetailed = kTRUE;
fUseAssembly = kTRUE;
-#endif
fInner = new AliFMDRing('I');
fOuter = new AliFMDRing('O');
fFMD1 = new AliFMD1(fInner);
fFMD2 = new AliFMD2(fInner, fOuter);
fFMD3 = new AliFMD3(fInner, fOuter);
fIsInitialized = kFALSE;
- // fActive.Set(4);
-#ifndef USE_PRE_MOVE
fActive.Reset(-1);
-#endif
}
//____________________________________________________________________
fFMD3(other.fFMD3),
fUseFMD1(other.fUseFMD1),
fUseFMD2(other.fUseFMD2),
- fUseFMD3(other.fUseFMD3)
-#ifndef USE_PRE_MOVE
- , fActive(other.fActive),
+ fUseFMD3(other.fUseFMD3),
+ fActive(other.fActive),
fDetailed(other.fDetailed),
fUseAssembly(other.fUseAssembly)
-#endif
{
// PROTECTED
// Copy constructor
fFMD3->Init();
}
-#ifndef USE_PRE_MOVE
+//____________________________________________________________________
+void
+AliFMDGeometry::InitTransformations()
+{
+ if (!gGeoManager) {
+ AliError("No TGeoManager defined");
+ return;
+ }
+ AliDebug(0, "Initialising transforms for FMD geometry");
+ if (fFMD1) fFMD1->InitTransformations();
+ if (fFMD2) fFMD2->InitTransformations();
+ if (fFMD3) fFMD3->InitTransformations();
+}
+
//____________________________________________________________________
void
AliFMDGeometry::Build()
if (fActive[i] == vol) return kTRUE;
return kFALSE;
}
-
-#endif
//____________________________________________________________________
AliFMDDetector*
// spatial coordinates (x, y, z) in the master reference frame of
// ALICE.
AliFMDDetector* det = GetDetector(detector);
- if (!det) return;
+ if (!det) {
+ AliWarning(Form("Unknown detector %d", detector));
+ return;
+ }
det->Detector2XYZ(ring, sector, strip, x, y, z);
}
return kFALSE;
}
-#ifndef USE_PRE_MOVE
//____________________________________________________________________
void
AliFMDGeometry::ExtractGeomInfo()
if (CheckNodes(node, name, lvl) >= 0) return lvl;
return -1;
}
-#endif
//____________________________________________________________________
//
class AliFMD1;
class AliFMD2;
class AliFMD3;
-#ifndef USE_PRE_MOVE
#ifndef ROOT_TArrayI
# include <TArrayI.h>
#endif
class AliFMDGeometryBuilder;
-class TArrayI;
-#endif
//__________________________________________________________________
public:
static AliFMDGeometry* Instance();
virtual void Init();
+ virtual void InitTransformations();
AliFMDRing* GetInner() const { return fInner; }
AliFMDRing* GetOuter() const { return fOuter; }
AliFMD1* GetFMD1() const { return (fUseFMD1 ? fFMD1 : 0); }
Bool_t XYZ2Detector(Double_t x, Double_t y, Double_t z,
UShort_t& detector, Char_t& ring,
UShort_t& sector, UShort_t& strip) const;
-#ifndef USE_PRE_MOVE
void Build();
Int_t GetDetectorOff() const { return fDetectorOff; }
Int_t GetModuleOff() const { return fModuleOff; }
void SetDetailed(Bool_t det) { fDetailed = det; }
Bool_t IsDetailed() const { return fDetailed; }
void UseAssembly(Bool_t ass) { fUseAssembly = ass; }
-#endif
// AliGeometry member functions
virtual void GetGlobal(const AliRecPoint* p, TVector3& pos,
AliFMDGeometry& operator=(const AliFMDGeometry& other);
virtual ~AliFMDGeometry() {}
-#ifndef USE_PRE_MOVE
AliFMDGeometryBuilder* fBuilder;
Int_t fDetectorOff;
Int_t fModuleOff;
TArrayI fActive;
Bool_t fDetailed;
Bool_t fUseAssembly;
-#endif
ClassDef(AliFMDGeometry,1); //
};
//____________________________________________________________________
const Char_t* AliFMDGeometryBuilder::fgkActiveName = "F%cAC";
-const Char_t* AliFMDGeometryBuilder::fgkSectorName = "F%cSE";
+const Char_t* AliFMDGeometryBuilder::fgkSectorName = "F%cSC";
const Char_t* AliFMDGeometryBuilder::fgkStripName = "F%cST";
-const Char_t* AliFMDGeometryBuilder::fgkModuleName = "F%cMO";
-const Char_t* AliFMDGeometryBuilder::fgkPCBName = "F%cP%c";
+const Char_t* AliFMDGeometryBuilder::fgkSensorName = "F%cSE";
+const Char_t* AliFMDGeometryBuilder::fgkPCBName = "F%cPB";
+const Char_t* AliFMDGeometryBuilder::fgkCuName = "F%cCU";
+const Char_t* AliFMDGeometryBuilder::fgkChipName = "F%cCH";
const Char_t* AliFMDGeometryBuilder::fgkLongLegName = "F%cLL";
const Char_t* AliFMDGeometryBuilder::fgkShortLegName = "F%cSL";
-const Char_t* AliFMDGeometryBuilder::fgkFrontVName = "F%cFV";
-const Char_t* AliFMDGeometryBuilder::fgkBackVName = "F%cBV";
-const Char_t* AliFMDGeometryBuilder::fgkRingName = "FMD%c";
-const Char_t* AliFMDGeometryBuilder::fgkTopHCName = "F%d%cI";
-const Char_t* AliFMDGeometryBuilder::fgkBotHCName = "F%d%cJ";
-const Char_t* AliFMDGeometryBuilder::fgkTopIHCName = "F%d%cK";
-const Char_t* AliFMDGeometryBuilder::fgkBotIHCName = "F%d%cL";
+const Char_t* AliFMDGeometryBuilder::fgkFrontVName = "F%cFH";
+const Char_t* AliFMDGeometryBuilder::fgkBackVName = "F%cBH";
+const Char_t* AliFMDGeometryBuilder::fgkRingTopName = "F%cTV";
+const Char_t* AliFMDGeometryBuilder::fgkRingBotName = "F%cBV";
+const Char_t* AliFMDGeometryBuilder::fgkHCName = "F%dH%c";
+const Char_t* AliFMDGeometryBuilder::fgkIHCName = "F%dI%c";
const Char_t* AliFMDGeometryBuilder::fgkNoseName = "F3SN";
const Char_t* AliFMDGeometryBuilder::fgkBackName = "F3SB";
const Char_t* AliFMDGeometryBuilder::fgkBeamName = "F3SL";
const Char_t* AliFMDGeometryBuilder::fgkFlangeName = "F3SF";
+const Char_t* AliFMDGeometryBuilder::fgkFMDName = "F%dM%c";
//____________________________________________________________________
AliFMDGeometryBuilder::AliFMDGeometryBuilder()
Double_t rmax = b->Mod();
Double_t rmin = r->GetLowR();
Double_t pcbThick = r->GetPrintboardThickness();
+ Double_t cuThick = r->GetCopperThickness();
+ Double_t chipThick= r->GetChipThickness();
Double_t modSpace = r->GetModuleSpacing();
Double_t legr = r->GetLegRadius();
Double_t legl = r->GetLegLength();
}
// Shape of actual sensor
- TGeoXtru* moduleShape = new TGeoXtru(2);
- moduleShape->DefinePolygon(nv, xs.fArray, ys.fArray);
- moduleShape->DefineSection(0, - siThick/2);
- moduleShape->DefineSection(1, siThick/2);
- TGeoVolume* moduleVolume = new TGeoVolume(Form(fgkModuleName, id),
- moduleShape, fSi);
- Int_t sid = moduleVolume->GetNumber();
+ TGeoXtru* sensorShape = new TGeoXtru(2);
+ sensorShape->DefinePolygon(nv, xs.fArray, ys.fArray);
+ sensorShape->DefineSection(0, - siThick/2);
+ sensorShape->DefineSection(1, siThick/2);
+ TGeoVolume* sensorVolume = new TGeoVolume(Form(fgkSensorName, id),
+ sensorShape, fSi);
+ sensorVolume->VisibleDaughters(kFALSE);
+ Int_t sid = sensorVolume->GetNumber();
fSectorOff = -1;
fModuleOff = 1;
fRingOff = 2;
fDetectorOff = 3;
if (fDetailed) {
fSectorOff = 1;
- fModuleOff = 4;
- fRingOff = 5;
- fDetectorOff = 6;
+ fModuleOff = 3;
+ fRingOff = 4;
+ fDetectorOff = 5;
// Virtual volume shape to divide - This volume is only defined if
// the geometry is set to be detailed.
- TGeoTubeSeg* activeShape =
- new TGeoTubeSeg(rmin, rmax, siThick/2, - theta, theta);
+ TGeoTubeSeg* activeShape = new TGeoTubeSeg(rmin, rmax, siThick/2,
+ - theta, theta);
TGeoVolume* activeVolume = new TGeoVolume(Form(fgkActiveName, id),
activeShape,fSi);
TGeoVolume* sectorVolume = activeVolume->Divide(Form(fgkSectorName,id),
1, ns, stripoff, dstrip,
0, "SX");
sid = stripVolume->GetNumber();
- moduleVolume->AddNodeOverlap(activeVolume, 0);
+ sensorVolume->AddNodeOverlap(activeVolume, 0);
}
switch (id) {
- case 'i':
- case 'I': fActiveId[0] = sid; break;
- case 'o':
- case 'O': fActiveId[1] = sid; break;
+ case 'i': case 'I': fActiveId[0] = sid; break;
+ case 'o': case 'O': fActiveId[1] = sid; break;
}
// Shape of Printed circuit Board
- TGeoXtru* pcbShape = new TGeoXtru(2);
for (Int_t i = 0; i < nv / 2; i++) ys[i] -= off;
for (Int_t i = nv / 2; i < nv; i++) ys[i] += off;
+ TGeoXtru* pcbShape = new TGeoXtru(2);
pcbShape->DefinePolygon(nv, xs.fArray, ys.fArray);
pcbShape->DefineSection(0, - pcbThick/2);
pcbShape->DefineSection(1, pcbThick/2);
- TGeoVolume* pcbVolume = new TGeoVolume(Form(fgkPCBName, id, 'B'),
- pcbShape, fPCB);
+ TGeoVolume* pcbVolume = new TGeoVolume(Form(fgkPCBName, id),
+ pcbShape, fPCB);
+
+ // Copper layer
+ TGeoXtru* cuShape = new TGeoXtru(2);
+ cuShape->DefinePolygon(6, xs.fArray, ys.fArray);
+ cuShape->DefineSection(0, - cuThick/2);
+ cuShape->DefineSection(1, cuThick/2);
+ TGeoVolume* cuVolume = new TGeoVolume(Form(fgkCuName,id),cuShape,fCopper);
+
+ // Chip layer
+ TGeoXtru* chipShape = new TGeoXtru(2);
+ chipShape->DefinePolygon(6, xs.fArray, ys.fArray);
+ chipShape->DefineSection(0, - chipThick/2);
+ chipShape->DefineSection(1, chipThick/2);
+ TGeoVolume* chipVolume = new TGeoVolume(Form(fgkChipName,id),
+ chipShape,fChip);
// Short leg shape
TGeoTube* shortLegShape = new TGeoTube(0, legr, legl / 2);
TGeoVolume* longLegVolume = new TGeoVolume(Form(fgkLongLegName, id),
longLegShape, fPlastic);
- TGeoMatrix* matrix = 0;
+
// Back container volume
- Double_t contThick = siThick + pcbThick + legl + space;
- TGeoTubeSeg* backShape = new TGeoTubeSeg(rmin, rmax, contThick/2,
- - theta, theta);
- TGeoVolume* backVolume = new TGeoVolume(Form(fgkBackVName, id),
- backShape, fAir);
+ TGeoVolume* backVolume = new TGeoVolumeAssembly(Form(fgkBackVName, id));
Double_t x = 0;
Double_t y = 0;
- Double_t z = -contThick / 2 + siThick / 2;
- matrix = new TGeoTranslation(Form("FMD Ring %c mod 1 transform", id),
- x, y, z);
- backVolume->AddNode(moduleVolume, 0, matrix);
- z += siThick / 2 + space + pcbThick / 2;
- matrix = new TGeoTranslation(Form("FMD Ring %c pcb 1 transfrom", id),
- x, y, z);
- backVolume->AddNode(pcbVolume, 0, matrix);
+ Double_t z = pcbThick / 2;
+ backVolume->AddNode(pcbVolume, 0, new TGeoTranslation(x,y,z));
+ z += (pcbThick + cuThick) / 2;
+ backVolume->AddNode(cuVolume, 0, new TGeoTranslation(0, 0, z));
+ z += (cuThick + chipThick) / 2;
+ backVolume->AddNode(chipVolume, 0, new TGeoTranslation(0, 0, z));
x = a->X() + legoff + legr;
y = 0;
z += pcbThick / 2 + legl / 2;
- matrix = new TGeoTranslation(Form("FMD Ring %c leg 1 transfrom", id),
- x, y, z);
- backVolume->AddNode(shortLegVolume, 0, matrix);
+ backVolume->AddNode(shortLegVolume, 0, new TGeoTranslation(x,y,z));
x = c->X();
y = c->Y() - legoff - legr - off;
- matrix = new TGeoTranslation(Form("FMD Ring %c leg 2 transfrom", id),
- x, y, z);
- backVolume->AddNode(shortLegVolume, 1, matrix);
+ backVolume->AddNode(shortLegVolume, 1, new TGeoTranslation(x,y,z));
y = -y;
- matrix = new TGeoTranslation(Form("FMD Ring %c leg 3 transfrom", id),
- x, y, z);
- backVolume->AddNode(shortLegVolume, 2, matrix);
- // backVolume->SetVisibility(kFALSE);
- // backVolume->VisibleDaughters(kTRUE);
+ backVolume->AddNode(shortLegVolume, 2, new TGeoTranslation(x,y,z));
// Front container volume
- contThick += modSpace;
- TGeoTubeSeg* frontShape = new TGeoTubeSeg(rmin, rmax, contThick/2,
- -theta, theta);
- TGeoVolume* frontVolume = new TGeoVolume(Form(fgkFrontVName, id),
- frontShape, fAir);
+ TGeoVolume* frontVolume = new TGeoVolumeAssembly(Form(fgkFrontVName, id));
x = 0;
y = 0;
- z = -contThick / 2 + siThick / 2 ;
- matrix = new TGeoTranslation(Form("FMD Ring %c mod 2 transfrom", id),
- 0, 0, z);
- frontVolume->AddNode(moduleVolume, 1, matrix);
- z += siThick / 2 + space + pcbThick / 2;
- matrix = new TGeoTranslation(Form("FMD Ring %c pcb 2 transfrom", id),
- x, y, z);
- frontVolume->AddNode(pcbVolume, 1, matrix);
+ z = pcbThick / 2;
+ frontVolume->AddNode(pcbVolume, 1, new TGeoTranslation(x,y,z));
+ z += (pcbThick + cuThick) / 2;
+ frontVolume->AddNode(cuVolume, 0, new TGeoTranslation(0, 0, z));
+ z += (cuThick + chipThick) / 2;
+ frontVolume->AddNode(chipVolume, 0, new TGeoTranslation(0, 0, z));
x = a->X() + legoff + legr;
y = 0;
z += pcbThick / 2 + (legl + modSpace)/ 2;
- matrix = new TGeoTranslation(Form("FMD Ring %c leg 4 transfrom", id),
- x, y, z);
- frontVolume->AddNode(longLegVolume, 0, matrix);
+ frontVolume->AddNode(longLegVolume, 0, new TGeoTranslation(x,y,z));
x = c->X();
y = c->Y() - legoff - legr - off;
- matrix = new TGeoTranslation(Form("FMD Ring %c leg 4 transfrom", id),
- x, y, z);
- frontVolume->AddNode(longLegVolume, 1, matrix);
+ frontVolume->AddNode(longLegVolume, 1, new TGeoTranslation(x,y,z));
y = -y;
- matrix = new TGeoTranslation(Form("FMD Ring %c leg 4 transfrom", id),
- x, y, z);
- frontVolume->AddNode(longLegVolume, 2, matrix);
- // frontVolume->SetVisibility(kFALSE);
- // frontVolume->VisibleDaughters(kTRUE);
+ frontVolume->AddNode(longLegVolume, 2, new TGeoTranslation(x,y,z));
- // Ring mother volume
- TGeoTube* ringShape = new TGeoTube(rmin, rmax, contThick / 2);
- TGeoVolume* ringVolume = new TGeoVolume(Form(fgkRingName,id),
- ringShape,fAir);
+ // Half ring mother volumes.
+ TGeoVolume* ringTopVolume = new TGeoVolumeAssembly(Form(fgkRingTopName,id));
+ TGeoVolume* ringBotVolume = new TGeoVolumeAssembly(Form(fgkRingBotName,id));
+ TGeoVolume* halfRing = ringTopVolume;
- Int_t nmod = r->GetNModules();
+ // Adding modules to half-rings
+ Int_t nmod = r->GetNModules();
AliDebug(10, Form("making %d modules in ring %c", nmod, id));
for (Int_t i = 0; i < nmod; i++) {
- Bool_t isFront = (i % 2 == 0);
- TGeoVolume* vol = (isFront ? frontVolume : backVolume);
- TGeoRotation* rot =new TGeoRotation(Form("FMD Ring %c rotation %d",id,i));
- rot->RotateZ((i + .5) * 2 * theta);
- Double_t z = (isFront ? 0 : modSpace) / 2;
- matrix = new TGeoCombiTrans(Form("FMD Ring %c transform %d", id, i),
- 0, 0, z, rot);
- ringVolume->AddNode(vol, i, matrix);
+ if (i == nmod / 2) halfRing = ringBotVolume;
+ Bool_t front = (i % 2 == 0);
+ Double_t z1 = siThick / 2 + (i % 2) * modSpace;
+ Double_t z2 = z1 + siThick / 2 + space;
+ Double_t th = (2 * i + 1) * theta;
+ TGeoVolume* vol = (front ? frontVolume : backVolume);
+ AliDebug(20, Form("Placing copy %d of %s and %s in %s at z=%f and %f, "
+ "and theta=%f", i, sensorVolume->GetName(),
+ vol->GetName(), halfRing->GetName(), z1, z2, th));
+ TGeoMatrix* mat1 = new TGeoCombiTrans(0,0,z1,0);
+ mat1->RotateZ(th);
+ halfRing->AddNode(sensorVolume, i, mat1);
+ TGeoMatrix* mat2 = new TGeoCombiTrans(0,0,z2,0);
+ mat2->RotateZ(th);
+ halfRing->AddNode(vol, i, mat2);
}
- ringVolume->SetVisibility(kFALSE);
- ringVolume->VisibleDaughters(kTRUE);
- return ringVolume;
+ return 0;
}
//____________________________________________________________________
TGeoVolume*
AliFMDGeometryBuilder::DetectorGeometry(AliFMDDetector* d,
- TGeoVolume* mother,
- Double_t zmother,
- TGeoVolume* inner,
- TGeoVolume* outer)
+ TGeoVolume* topMother,
+ TGeoVolume* botMother,
+ Double_t zMother,
+ TGeoVolume* innerTop,
+ TGeoVolume* innerBot,
+ TGeoVolume* outerTop,
+ TGeoVolume* outerBot)
{
// Common stuff for setting up the FMD1, FMD2, and FMD3 geometries.
// This includes putting the Honeycomb support plates and the rings
Double_t lowr = 0;
Double_t highr = 0;
Double_t rz = 0;
- TGeoVolume* rvol = 0;
+ TGeoVolume* tvol = 0;
+ TGeoVolume* bvol = 0;
switch (i) {
case 0:
r = d->GetInner();
lowr = d->GetInnerHoneyLowR();
highr = d->GetInnerHoneyHighR();
rz = d->GetInnerZ();
- rvol = inner;
+ tvol = innerTop;
+ bvol = innerBot;
break;
case 1:
r = d->GetOuter();
lowr = d->GetOuterHoneyLowR();
highr = d->GetOuterHoneyHighR();
rz = d->GetOuterZ();
- rvol = outer;
+ tvol = outerTop;
+ bvol = outerBot;
break;
}
if (!r) continue;
Int_t id = d->GetId();
Double_t hcThick = d->GetHoneycombThickness();
Double_t alThick = d->GetAlThickness();
- Double_t z;
- if (zmother > 0) z = rz - zmother + r->GetRingDepth() / 2;
- else z = zmother - rz + r->GetRingDepth() / 2;
+ Double_t z = TMath::Abs(rz - zMother);
+
// Place ring in mother volume
- mother->AddNode(rvol, Int_t(c),
- new TGeoTranslation(Form("FMD%d%c transform", id, c),
- 0, 0, z));
+ // TGeoMatrix*matrix=new TGeoTranslation(Form("FMD%d%c trans",id,c),0,0,0);
+ AliDebug(5, Form("Placing volumes %s and %s in %s and %s at z=%f",
+ tvol->GetName(), bvol->GetName(),
+ topMother->GetName(), botMother->GetName(), z));
+ topMother->AddNode(tvol, Int_t(c), new TGeoTranslation(0,0,z));
+ botMother->AddNode(bvol, Int_t(c), new TGeoTranslation(0,0,z));
- z += r->GetRingDepth() / 2 + hcThick / 2;
// Top of Honeycomb
- TGeoTubeSeg* topHCShape = new TGeoTubeSeg(lowr, highr, hcThick/2, 0, 180);
- TGeoVolume* topHCVolume = new TGeoVolume(Form(fgkTopHCName, id, c),
- topHCShape, fAl);
- TGeoMatrix* topHCMatrix =
- new TGeoTranslation(Form("FMD%d%c top HC transform", id, c), 0, 0, z);
- mother->AddNode(topHCVolume, 0, topHCMatrix);
-
+ TGeoTubeSeg* hcSha = new TGeoTubeSeg(lowr, highr, hcThick/2, 0, 180);
+ TGeoVolume* hcVol = new TGeoVolume(Form(fgkHCName,id,c),hcSha,fAl);
// Air in top of honeycomb
- TGeoTubeSeg* topIHCShape = new TGeoTubeSeg(lowr+alThick, highr - alThick,
- (hcThick-alThick)/2, 0, 180);
- TGeoVolume* topIHCVolume = new TGeoVolume(Form(fgkTopIHCName, id, c),
- topIHCShape, fAir);
- topHCVolume->AddNode(topIHCVolume, 0);
- topHCVolume->VisibleDaughters(kFALSE);
- topHCVolume->SetVisibility(kTRUE);
-
-
- // Bottom of Honeycomb
- TGeoTubeSeg* botHCShape = new TGeoTubeSeg(lowr, highr, hcThick/2,
- 180, 360);
- TGeoVolume* botHCVolume = new TGeoVolume(Form(fgkBotHCName, id, c),
- botHCShape, fAl);
- TGeoMatrix* botHCMatrix =
- new TGeoTranslation(Form("FMD%d%c bottom HC transform", id, c), 0, 0, z);
- mother->AddNode(botHCVolume, 0, botHCMatrix);
-
- // Air in bot of honeycomb
- TGeoTubeSeg* botIHCShape = new TGeoTubeSeg(lowr+alThick, highr - alThick,
- (hcThick-alThick)/2, 180, 360);
- TGeoVolume* botIHCVolume = new TGeoVolume(Form(fgkBotIHCName, id, c),
- botIHCShape, fAir);
- botHCVolume->AddNode(botIHCVolume, 0);
- botHCVolume->VisibleDaughters(kFALSE);
- botHCVolume->SetVisibility(kTRUE);
+ TGeoTubeSeg* ihcSha = new TGeoTubeSeg(lowr+alThick, highr - alThick,
+ (hcThick-alThick)/2, 0, 180);
+ TGeoVolume* ihcVol = new TGeoVolume(Form(fgkIHCName,id,c),ihcSha,fAir);
+ hcVol->AddNode(ihcVol, 0);
+ hcVol->VisibleDaughters(kFALSE);
+ hcVol->SetVisibility(kTRUE);
+
+ z += (r->GetSiThickness() +
+ r->GetSpacing() +
+ r->GetPrintboardThickness() +
+ r->GetCopperThickness() +
+ r->GetChipThickness() +
+ r->GetModuleSpacing() +
+ r->GetLegLength() +
+ hcThick / 2);
+
+ AliDebug(15, Form("Placing a copy of %s in %s and %s at z=%f",
+ hcVol->GetName(), topMother->GetName(),
+ botMother->GetName(), z));
+ // Add to top
+ topMother->AddNode(hcVol, 0, new TGeoTranslation(0, 0, z));
+
+ // Add to bottom
+ TGeoMatrix* bhcMatrix = new TGeoCombiTrans(0,0,z,0);
+ bhcMatrix->RotateZ(180);
+ botMother->AddNode(hcVol, 1, bhcMatrix);
}
- mother->SetVisibility(kFALSE);
- mother->VisibleDaughters(kTRUE);
- return mother;
+ return 0;
}
//____________________________________________________________________
TGeoVolume*
-AliFMDGeometryBuilder::FMD1Geometry(AliFMD1* fmd1, TGeoVolume* inner)
+AliFMDGeometryBuilder::FMD1Geometry(AliFMD1* fmd1,
+ TGeoVolume* innerTop,
+ TGeoVolume* innerBot)
{
// Setup the FMD1 geometry. The FMD1 only has one ring, and no
// special support as it is at the momement.
//
// See also AliFMDGeometryBuilder::DetectorGeometry
//
- if (!fmd1 || !inner) return 0;
- Double_t rmin = fmd1->GetInner()->GetLowR();
- Double_t rmax = fmd1->GetInnerHoneyHighR();
- Double_t hcThick = fmd1->GetHoneycombThickness();
- Double_t w = fmd1->GetInner()->GetRingDepth() + hcThick;
- Double_t z = fmd1->GetInnerZ() + w / 2;
-
- TGeoVolume* fmd1Volume = 0;
- if (!fUseAssembly) {
- TGeoTube* fmd1Shape = new TGeoTube(rmin, rmax, w / 2);
- fmd1Volume = new TGeoVolume(fmd1->GetName(), fmd1Shape, fAir);
- }
- else
- fmd1Volume = new TGeoVolumeAssembly(fmd1->GetName());
+ if (!fmd1 || !innerTop || !innerBot) return 0;
+ Double_t z = fmd1->GetInnerZ();
+ TGeoVolume* fmd1TopVolume = new TGeoVolumeAssembly(Form(fgkFMDName,
+ fmd1->GetId(), 'T'));
+ TGeoVolume* fmd1BotVolume = new TGeoVolumeAssembly(Form(fgkFMDName,
+ fmd1->GetId(), 'B'));
- TGeoVolume* top = gGeoManager->GetVolume("ALIC");
- TGeoMatrix* matrix = new TGeoTranslation("FMD1 transform", 0, 0, z);
- top->AddNode(fmd1Volume, fmd1->GetId(), matrix);
-
- return DetectorGeometry(fmd1, fmd1Volume, z, inner, 0);
+ // Basic detector geometry
+ DetectorGeometry(fmd1, fmd1TopVolume, fmd1BotVolume, z,
+ innerTop, innerBot, 0, 0);
+
+ // Must add this after filling the assembly.
+ TGeoVolume* top = gGeoManager->GetVolume("ALIC");
+ TGeoMatrix* matrix = new TGeoTranslation("FMD1 trans", 0, 0, z);
+ AliDebug(5, Form("Placing volumes %s and %s in ALIC at z=%f",
+ fmd1TopVolume->GetName(), fmd1BotVolume->GetName(), z));
+ top->AddNode(fmd1TopVolume, fmd1->GetId(), matrix);
+ top->AddNode(fmd1BotVolume, fmd1->GetId(), matrix);
+
+ return 0;
}
//____________________________________________________________________
TGeoVolume*
AliFMDGeometryBuilder::FMD2Geometry(AliFMD2* fmd2,
- TGeoVolume* inner,
- TGeoVolume* outer)
+ TGeoVolume* innerTop,
+ TGeoVolume* innerBot,
+ TGeoVolume* outerTop,
+ TGeoVolume* outerBot)
{
// Setup the FMD2 geometry. The FMD2 has no
// special support as it is at the momement.
//
// See also AliFMDGeometryBuilder::DetectorGeometry
//
- if (!fmd2 || !inner || !outer) return 0;
- Double_t rmin = fmd2->GetInner()->GetLowR();
- Double_t rmax = fmd2->GetOuterHoneyHighR();
- Double_t hcThick = fmd2->GetHoneycombThickness();
- Double_t ow = fmd2->GetInner()->GetRingDepth();
- Double_t iz = fmd2->GetInnerZ();
- Double_t oz = fmd2->GetOuterZ();
- Double_t w = TMath::Abs(oz - iz) + ow + hcThick;
- Double_t z = oz + w / 2;
-
- TGeoVolume* fmd2Volume = 0;
- if (!fUseAssembly) {
- TGeoTube* fmd2Shape = new TGeoTube(rmin, rmax, w / 2);
- fmd2Volume = new TGeoVolume(fmd2->GetName(), fmd2Shape, fAir);
- }
- else
- fmd2Volume = new TGeoVolumeAssembly(fmd2->GetName());
+ if (!fmd2 || !innerTop || !innerBot || !outerTop || !outerBot) return 0;
+ Double_t z = fmd2->GetOuterZ();
+ TGeoVolume* fmd2TopVolume = new TGeoVolumeAssembly(Form(fgkFMDName,
+ fmd2->GetId(), 'T'));
+ TGeoVolume* fmd2BotVolume = new TGeoVolumeAssembly(Form(fgkFMDName,
+ fmd2->GetId(), 'B'));
+ DetectorGeometry(fmd2, fmd2TopVolume, fmd2BotVolume, z,
+ innerTop, innerBot, outerTop, outerBot);
+
+ // Must be done after filling the assemblies
TGeoVolume* top = gGeoManager->GetVolume("ALIC");
- TGeoMatrix* matrix = new TGeoTranslation("FMD2 transform", 0, 0, z);
- top->AddNode(fmd2Volume, fmd2->GetId(), matrix);
+ TGeoMatrix* matrix = new TGeoTranslation("FMD2 trans", 0, 0, z);
+ AliDebug(5, Form("Placing volumes %s and %s in ALIC at z=%f",
+ fmd2TopVolume->GetName(), fmd2BotVolume->GetName(), z));
+ top->AddNode(fmd2TopVolume, fmd2->GetId(), matrix);
+ top->AddNode(fmd2BotVolume, fmd2->GetId(), matrix);
- return DetectorGeometry(fmd2, fmd2Volume, z, inner, outer);
+ return 0;
}
//____________________________________________________________________
TGeoVolume*
AliFMDGeometryBuilder::FMD3Geometry(AliFMD3* fmd3,
- TGeoVolume* inner,
- TGeoVolume* outer)
+ TGeoVolume* innerTop,
+ TGeoVolume* innerBot,
+ TGeoVolume* outerTop,
+ TGeoVolume* outerBot)
{
// Setup the FMD3 geometry. The FMD2 has a rather elaborate support
// structure, as the support will also support the vacuum
//
// See also AliFMDGeometryBuilder::DetectorGeometry
//
- if (!fmd3 || !inner || !outer) return 0;
+ if (!fmd3 || !innerTop || !innerBot || !outerTop || !outerBot) return 0;
Double_t nlen = fmd3->GetNoseLength();
Double_t nz = fmd3->GetNoseZ();
Double_t noser1 = fmd3->GetNoseLowR();
Double_t tdist = backr2 - noser2;
Double_t beaml = TMath::Sqrt(zdist * zdist + tdist * tdist);
Double_t theta = -180. * TMath::ATan2(tdist, zdist) / TMath::Pi();
- Double_t innerZ = fmd3->GetInnerZ();
- Double_t innerZh = (innerZ - fmd3->GetInner()->GetRingDepth()
- - fmd3->GetHoneycombThickness());
- Double_t outerZ = fmd3->GetOuterZ();
- Double_t outerZh = (outerZ - fmd3->GetOuter()->GetRingDepth()
- - fmd3->GetHoneycombThickness());
- Double_t innerr1 = fmd3->GetInner()->GetLowR();
- // Double_t innerr2 = fmd3->GetInner()->GetHighR();
- Double_t outerr1 = fmd3->GetOuter()->GetLowR();
- // Double_t outerr2 = fmd3->GetOuter()->GetHighR();
Double_t flanger = fmd3->GetFlangeR();
- Double_t minZ = TMath::Min(nz - conel, outerZh);
- Double_t z = fmd3->GetZ();
+ Double_t z = fmd3->GetInnerZ(); // fmd3->GetZ();
Double_t zi;
- // FMD3 volume
- TGeoVolume* fmd3Volume = 0;
- if (!fUseAssembly) {
- TGeoPcon* fmd3Shape = new TGeoPcon(0, 360, 8);
- zi = z - nz;
- fmd3Shape->DefineSection(0, zi, noser1, noser2);
- zi = z - (nz - nlen);
- fmd3Shape->DefineSection(1, zi, noser1, fmd3->ConeR(z - zi)+.15);
- zi = z - innerZ;
- fmd3Shape->DefineSection(2, zi, innerr1, fmd3->ConeR(z - zi)+.15);
- zi = z - innerZh;
- fmd3Shape->DefineSection(3, zi, innerr1, fmd3->ConeR(z - zi)+.15);
- fmd3Shape->DefineSection(4, zi, outerr1, fmd3->ConeR(z - zi)+.15);
- zi = z - nz + zdist + nlen;
- fmd3Shape->DefineSection(5, zi, outerr1, fmd3->ConeR(z - zi)+.15);
- zi = z - nz + nlen + zdist;
- fmd3Shape->DefineSection(6, zi, outerr1, flanger+1.5);
- zi = z - minZ;
- fmd3Shape->DefineSection(7, zi, outerr1, flanger+1.5);
- fmd3Volume = new TGeoVolume(fmd3->GetName(), fmd3Shape, fAir);
- }
- else
- fmd3Volume = new TGeoVolumeAssembly(fmd3->GetName());
-
- TGeoRotation* rot = new TGeoRotation("FMD3 rotatation");
- rot->RotateY(180);
- TGeoVolume* top = gGeoManager->GetVolume("ALIC");
- TGeoMatrix* mmatrix = new TGeoCombiTrans("FMD3 transform", 0, 0, z, rot);
- top->AddNode(fmd3Volume, fmd3->GetId(), mmatrix);
+ TGeoVolume* fmd3TopVolume = new TGeoVolumeAssembly(Form(fgkFMDName,
+ fmd3->GetId(), 'T'));
+ TGeoVolume* fmd3BotVolume = new TGeoVolumeAssembly(Form(fgkFMDName,
+ fmd3->GetId(), 'B'));
+
+ DetectorGeometry(fmd3, fmd3TopVolume, fmd3BotVolume, z,
+ innerTop, innerBot, outerTop, outerBot);
+
+
// Nose volume
- TGeoTube* noseShape = new TGeoTube(noser1, noser2, nlen / 2);
+ TGeoTubeSeg* noseShape = new TGeoTubeSeg(noser1, noser2, nlen / 2, 0, 180);
TGeoVolume* noseVolume = new TGeoVolume(fgkNoseName, noseShape, fC);
- zi = z - nz + nlen / 2;
- TGeoMatrix* nmatrix = new TGeoTranslation("FMD3 Nose translation", 0, 0, zi);
- // fmd3Volume->AddNodeOverlap(noseVolume, 0, nmatrix);
- fmd3Volume->AddNode(noseVolume, 0, nmatrix);
+ zi = -nz + nlen / 2 + z;
+
+ fmd3TopVolume->AddNode(noseVolume, 0, new TGeoTranslation(0, 0, zi));
+ TGeoMatrix* nmatrix = new TGeoCombiTrans(0, 0, zi, 0);
+ nmatrix->RotateZ(180);
+ fmd3BotVolume->AddNode(noseVolume, 1, nmatrix);
// Back
- TGeoTube* backShape = new TGeoTube(backr1, backr2, backl / 2);
+ TGeoTubeSeg* backShape = new TGeoTubeSeg(backr1, backr2, backl / 2, 0, 180);
TGeoVolume* backVolume = new TGeoVolume(fgkBackName, backShape, fC);
- zi = z - nz + conel - backl / 2;
- TGeoMatrix* bmatrix = new TGeoTranslation("FMD3 Back translation", 0, 0, zi);
- fmd3Volume->AddNode(backVolume, 0, bmatrix);
+ zi = -nz + conel - backl / 2 + z;
+ fmd3TopVolume->AddNode(backVolume, 0, new TGeoTranslation(0, 0, zi));
+ TGeoMatrix* bmatrix = new TGeoCombiTrans(0, 0, zi, 0);
+ bmatrix->RotateZ(180);
+ fmd3BotVolume->AddNode(backVolume, 1, bmatrix);
+
Int_t n;
Double_t r;
fmd3->GetBeamWidth() / 2,
backl / 2);
TGeoVolume* flangeVolume = new TGeoVolume(fgkFlangeName, flangeShape, fC);
- n = fmd3->GetNFlange();
- r = backr2 + (flanger - backr2) / 2;
+ n = fmd3->GetNFlange();
+ r = backr2 + (flanger - backr2) / 2;
+ TGeoVolume* mother = fmd3TopVolume;
for (Int_t i = 0; i < n; i++) {
- Double_t phi = 360. / n * i + 180. / n;
- Double_t x = r * TMath::Cos(TMath::Pi() / 180 * phi);
- Double_t y = r * TMath::Sin(TMath::Pi() / 180 * phi);
- TGeoRotation* rot = new TGeoRotation(Form("FMD3 Flange rotation %d", i));
+ if (i >= n / 2) mother = fmd3BotVolume;
+ Double_t phi = 360. / n * i + 180. / n;
+ Double_t x = r * TMath::Cos(TMath::Pi() / 180 * phi);
+ Double_t y = r * TMath::Sin(TMath::Pi() / 180 * phi);
+ AliDebug(15, Form("Placing flange %d in %s at (%f,%f,%f) r=%f, phi=%f",
+ i, mother->GetName(), x, y, zi, r, phi));
+ TGeoRotation* rot = new TGeoRotation;
rot->RotateZ(phi);
- TGeoMatrix* matrix = new TGeoCombiTrans(Form("FMD3 flange transform %d",
- i), x, y, zi, rot);
- // fmd3Volume->AddNodeOverlap(flangeVolume, i, matrix);
- fmd3Volume->AddNode(flangeVolume, i, matrix);
-
+ TGeoMatrix* matrix = new TGeoCombiTrans(x, y, zi, rot);
+ mother->AddNode(flangeVolume, i, matrix);
}
// The Beams
fmd3->GetBeamWidth() / 2 - .1,
beaml / 2);
TGeoVolume* beamVolume = new TGeoVolume(fgkBeamName, beamShape, fC);
- n = fmd3->GetNBeam();
- r = noser2 + tdist / 2;
- zi = z - nz + nlen + zdist / 2;
+ n = fmd3->GetNBeam();
+ r = noser2 + tdist / 2;
+ zi = - nz + nlen + zdist / 2 + z;
+ mother = fmd3TopVolume;
for (Int_t i = 0; i < n; i++) {
- Double_t phi = 360. / n * i;
- Double_t x = r * TMath::Cos(TMath::Pi() / 180 * phi);
- Double_t y = r * TMath::Sin(TMath::Pi() / 180 * phi);
+ if (i >= n / 2) mother = fmd3BotVolume;
+ Double_t phi = 360. / n * i;
+ Double_t x = r * TMath::Cos(TMath::Pi() / 180 * phi);
+ Double_t y = r * TMath::Sin(TMath::Pi() / 180 * phi);
TGeoRotation* rot = new TGeoRotation(Form("FMD3 beam rotation %d", i));
// Order is important
rot->RotateY(-theta);
rot->RotateZ(phi);
- TGeoMatrix* matrix = new TGeoCombiTrans(Form("FMD3 beam transform %d", i),
+ TGeoMatrix* matrix = new TGeoCombiTrans(Form("FMD3 beam trans %d", i),
x, y, zi, rot);
- fmd3Volume->AddNode(beamVolume, i, matrix);
+ mother->AddNode(beamVolume, i, matrix);
}
-
- return DetectorGeometry(fmd3, fmd3Volume, z, inner, outer);
+ z = fmd3->GetInnerZ();
+ TGeoRotation* rot = new TGeoRotation("FMD3 rotatation");
+ rot->RotateY(180);
+ TGeoVolume* top = gGeoManager->GetVolume("ALIC");
+ TGeoMatrix* mmatrix = new TGeoCombiTrans("FMD3 trans", 0, 0, z, rot);
+ AliDebug(5, Form("Placing volumes %s and %s in ALIC at z=%f",
+ fmd3TopVolume->GetName(), fmd3BotVolume->GetName(), z));
+ top->AddNode(fmd3TopVolume, fmd3->GetId(), mmatrix);
+ top->AddNode(fmd3BotVolume, fmd3->GetId(), mmatrix);
+
+ return 0;
}
//____________________________________________________________________
AliFMDGeometryBuilder::Exec(Option_t*)
{
// Setup up the FMD geometry.
- AliDebug(1, Form("\tGeometry options: %s, %s",
- (fDetailed ? "divided into strips" : "one volume"),
- (fUseAssembly ? "within assemblies" : "in real volumes")));
+ AliDebug(1, Form("\tGeometry options: %s",
+ (fDetailed ? "divided into strips" : "one volume")));
if (!gGeoManager) {
AliFatal("No TGeoManager defined");
return;
return;
}
AliFMDGeometry* fmd = AliFMDGeometry::Instance();
- TGeoVolume* inner = RingGeometry(fmd->GetInner());
- TGeoVolume* outer = RingGeometry(fmd->GetOuter());
- if (!inner || !outer) {
- AliError("Failed to create one of the ring volumes");
- return;
- }
- FMD1Geometry(fmd->GetFMD1(), inner);
- FMD2Geometry(fmd->GetFMD2(), inner, outer);
- FMD3Geometry(fmd->GetFMD3(), inner, outer);
+ AliFMDRing* inner = fmd->GetInner();
+ AliFMDRing* outer = fmd->GetOuter();
+ RingGeometry(inner);
+ RingGeometry(outer);
+ TGeoVolume* innerTop = gGeoManager->GetVolume(Form(fgkRingTopName,
+ inner->GetId()));
+ TGeoVolume* innerBot = gGeoManager->GetVolume(Form(fgkRingBotName,
+ inner->GetId()));
+ TGeoVolume* outerTop = gGeoManager->GetVolume(Form(fgkRingTopName,
+ outer->GetId()));
+ TGeoVolume* outerBot = gGeoManager->GetVolume(Form(fgkRingBotName,
+ outer->GetId()));
+
+ FMD1Geometry(fmd->GetFMD1(), innerTop, innerBot);
+ FMD2Geometry(fmd->GetFMD2(), innerTop, innerBot, outerTop, outerBot);
+ FMD3Geometry(fmd->GetFMD3(), innerTop, innerBot, outerTop, outerBot);
#ifndef USE_PRE_MOVE
fmd->SetSectorOff(fSectorOff);
fmd->SetModuleOff(fModuleOff);
@param outer Outer ring volume
@return Detector volume */
virtual TGeoVolume* DetectorGeometry(AliFMDDetector* d,
- TGeoVolume* mother,
- Double_t zmother,
- TGeoVolume* inner,
- TGeoVolume* outer=0);
+ TGeoVolume* motherTop,
+ TGeoVolume* motherBot,
+ Double_t zmother,
+ TGeoVolume* innerTop,
+ TGeoVolume* innerBot,
+ TGeoVolume* outerTop=0,
+ TGeoVolume* outerBot=0);
/** Make FMD1 volume
@param d Detector geometry
@param inner Inner ring volume
@return FMD1 volume */
- virtual TGeoVolume* FMD1Geometry(AliFMD1* d, TGeoVolume* inner);
+ virtual TGeoVolume* FMD1Geometry(AliFMD1* d,
+ TGeoVolume* innerTop,
+ TGeoVolume* innerBot);
/** Make FMD2 volume
@param d Detector geometry
@param inner Inner ring volume
@param outer Outer ring volume
@return FMD2 volume */
- virtual TGeoVolume* FMD2Geometry(AliFMD2* d, TGeoVolume* inner,
- TGeoVolume* outer);
+ virtual TGeoVolume* FMD2Geometry(AliFMD2* d,
+ TGeoVolume* innerTop,
+ TGeoVolume* innerBot,
+ TGeoVolume* outerTop,
+ TGeoVolume* outerBot);
/** Make FMD3 volume
@param d Detector geometry
@param inner Inner ring volume
@param outer Outer ring volume
@return FMD3 volume */
- virtual TGeoVolume* FMD3Geometry(AliFMD3* d, TGeoVolume* inner,
- TGeoVolume* outer);
+ virtual TGeoVolume* FMD3Geometry(AliFMD3* d,
+ TGeoVolume* innerTop,
+ TGeoVolume* innerBot,
+ TGeoVolume* outerTop,
+ TGeoVolume* outerBot);
TArrayI fActiveId; //! Active volume ID's
static const Char_t* fgkActiveName; // Name of Active volumes
static const Char_t* fgkSectorName; // Name of Sector volumes
static const Char_t* fgkStripName; // Name of Strip volumes
- static const Char_t* fgkModuleName; // Name of Module volumes
+ static const Char_t* fgkSensorName; // Name of Sensor volumes
static const Char_t* fgkPCBName; // Name of PCB volumes
+ static const Char_t* fgkCuName; // Name of copper volumes
+ static const Char_t* fgkChipName; // Name of chip volumes
static const Char_t* fgkLongLegName; // Name of LongLeg volumes
static const Char_t* fgkShortLegName; // Name of ShortLeg volumes
static const Char_t* fgkFrontVName; // Name of Front volumes
static const Char_t* fgkBackVName; // Name of Back volumes
- static const Char_t* fgkRingName; // Name of Ring volumes
- static const Char_t* fgkTopHCName; // Name of TopHC volumes
- static const Char_t* fgkBotHCName; // Name of BotHC volumes
- static const Char_t* fgkTopIHCName; // Name of TopIHC volumes
- static const Char_t* fgkBotIHCName; // Name of BotIHC volumes
+ static const Char_t* fgkRingTopName; // Name of Top ring volumes
+ static const Char_t* fgkRingBotName; // Name of Bottom ring volumes
+ static const Char_t* fgkHCName; // Name of Honeycomb volumes
+ static const Char_t* fgkIHCName; // Name of Inner honeycomb volumes
static const Char_t* fgkNoseName; // Name of Nose volumes
static const Char_t* fgkBackName; // Name of Back volumes
static const Char_t* fgkBeamName; // Name of Beam volumes
static const Char_t* fgkFlangeName; // Name of Flange volumes
+ static const Char_t* fgkFMDName; // Name of Half FMD volumes
ClassDef(AliFMDGeometryBuilder,1)
};
+++ /dev/null
-/**************************************************************************
- * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
- * *
- * Author: The ALICE Off-line Project. *
- * Contributors are mentioned in the code where appropriate. *
- * *
- * Permission to use, copy, modify and distribute this software and its *
- * documentation strictly for non-commercial purposes is hereby granted *
- * without fee, provided that the above copyright notice appears in all *
- * copies and that both the copyright notice and this permission notice *
- * appear in the supporting documentation. The authors make no claims *
- * about the suitability of this software for any purpose. It is *
- * provided "as is" without express or implied warranty. *
- **************************************************************************/
-
-/* $Id$ */
-
-//____________________________________________________________________
-//
-// 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.
-//
-// 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 simulation
-//
-// +--------+ 1 +-----------------------+
-// | AliFMD |<>-----| AliFMDGeometryBuilder |
-// +--------+ +-----------------------+
-// ^
-// |
-// +-----------------------------+
-// | AliFMDGeometryBuilderSimple |
-// +-----------------------------+
-//
-//
-// * AliFMD
-// This defines the interface for the various parts of AliROOT that
-// uses the FMD, AliFMDDigitizer, AliFMDReconstructor, and so on.
-//
-// * AliFMDGeometryBuilder
-// This is the base class for the FMD geometry builder tasks. The
-// builder tasks are responsible to implment the geoemtry. This
-// defines the active volume as an ONLY XTRU shape with a divided
-// MANY TUBS shape inside to implement the particular shape of the
-// silicon sensors.
-//
-// * AliFMDGeometryBuilderSimple
-// This is a concrete implementation of the AliFMDGeometryBuilder,
-// that defines the active elements as sections of a TUBE.
-//
-#include "AliFMDGeometryBuilderSimple.h" // ALIFMDG3OLDSIMULATOR_H
-#include "AliFMDGeometry.h" // ALIFMDGEOMETRY_H
-#include "AliFMDDetector.h" // ALIFMDDETECTOR_H
-#include "AliFMDRing.h" // ALIFMDRING_H
-#include "AliFMD1.h" // ALIFMD1_H
-#include "AliFMD2.h" // ALIFMD2_H
-#include "AliFMD3.h" // ALIFMD3_H
-#include "AliFMD.h" // ALIFMD_H
-#include <AliLog.h> // ALILOG_H
-#include <TVector2.h> // ROOT_TVector2
-#include <TVirtualMC.h> // ROOT_TVirtualMC
-#include <TArrayI.h> // ROOT_TArrayI
-#include <TGeoVolume.h> // ROOT_TGeoVolume
-#include <TGeoTube.h> // ROOT_TGeoTube
-#include <TGeoMatrix.h> // ROOT_TGeoMatrix
-#include <cmath> // __CMATH__
-
-//====================================================================
-ClassImp(AliFMDGeometryBuilderSimple)
-#if 0
- ; // This is here to keep Emacs for indenting the next line
-#endif
-
-//____________________________________________________________________
-AliFMDGeometryBuilderSimple::AliFMDGeometryBuilderSimple()
-{
- // Default constructor
-}
-
-//____________________________________________________________________
-AliFMDGeometryBuilderSimple::AliFMDGeometryBuilderSimple(Bool_t detailed)
- : AliFMDGeometryBuilder(detailed)
-{
- // Normal constructor
- //
- // Parameters:
- //
- // fmd Pointer to AliFMD object
- // detailed Whether to make a detailed simulation or not
- //
-}
-
-//____________________________________________________________________
-TGeoVolume*
-AliFMDGeometryBuilderSimple::RingGeometry(AliFMDRing* r)
-{
- // Setup the geometry of a ring. The defined TGeoVolume is
- // returned, and should be used when setting up the rest of the
- // volumes.
- //
- // Parameters:
- //
- // r Pointer to ring geometry object
- //
- // Returns:
- // true on success
- //
- if (!r) {
- AliError("Didn't get a ring object");
- return 0;
- }
- Char_t id = r->GetId();
- Double_t siThick = r->GetSiThickness();
- // const Int_t nv = r->GetNVerticies();
- //TVector2* a = r->GetVertex(5);
- TVector2* b = r->GetVertex(3);
- //TVector2* c = r->GetVertex(4);
- Double_t theta = r->GetTheta();
- //Double_t off = (TMath::Tan(TMath::Pi() * theta / 180)
- // * r->GetBondingWidth());
- Double_t rmax = b->Mod();
- Double_t rmin = r->GetLowR();
- Double_t pcbThick = r->GetPrintboardThickness();
- Double_t copperThick = r->GetCopperThickness(); // .01;
- Double_t chipThick = r->GetChipThickness(); // .01;
- //Double_t modSpace = r->GetModuleSpacing();
- //Double_t legr = r->GetLegRadius();
- //Double_t legl = r->GetLegLength();
- //Double_t legoff = r->GetLegOffset();
- Int_t ns = r->GetNStrips();
- Int_t nsec = Int_t(360 / theta);
- Double_t space = r->GetSpacing();
- //Double_t stripoff = a->Mod();
- //Double_t dstrip = (rmax - stripoff) / ns;
- TString name;
- TString name2;
-
- Double_t ringWidth = (siThick + 2 * (pcbThick + copperThick + chipThick));
- // Virtual volume shape to divide - This volume is only defined if
- // the geometry is set to be detailed.
- // Ring mother volume
- TGeoShape* ringShape = new TGeoTube(rmin, rmax, ringWidth / 2);
- name = Form(fgkRingName, id);
- TGeoVolume* ringVolume = new TGeoVolume(name.Data(), ringShape, fAir);
-
- TGeoShape* activeShape = new TGeoTube(rmin, rmax, siThick / 2);
- name = Form(fgkActiveName, id);
- Double_t z = - ringWidth / 2 + siThick / 2;
- TGeoVolume* activeVolume = new TGeoVolume(name.Data(), activeShape, fSi);
- ringVolume->AddNode(activeVolume, 1, new TGeoTranslation(0, 0, z));
-
- fSectorOff = -1;
- fModuleOff = -1;
- fRingOff = 1;
- fDetectorOff = 2;
- Int_t sid = activeVolume->GetNumber();
- if (fDetailed) {
- fSectorOff = 1;
- fRingOff = 3;
- fDetectorOff = 4;
- name = Form(fgkSectorName, id);
- TGeoVolume* sectorVolume = activeVolume->Divide(name.Data(), 2, nsec,
- 0, 0, 0, "N");
-
- name = Form(fgkStripName, id);
- TGeoVolume* stripVolume = sectorVolume->Divide(name.Data(), 1, ns,
- 0, 0, 0, "N");
- sid = stripVolume->GetNumber();
- AliDebug(10, Form("Got volume id %d for volume %s", sid, name.Data()));
- }
- switch (id) {
- case 'i':
- case 'I': fActiveId[0] = sid; break;
- case 'o':
- case 'O': fActiveId[1] = sid; break;
- }
-
- // Shape of Printed circuit Board
- Double_t boardThick = (pcbThick + copperThick + chipThick);
- TGeoShape* boardShape = new TGeoTube(rmin+.1, rmax-.1, boardThick/ 2);
- name = Form(fgkPCBName, id, 'B');
- TGeoVolume* boardVolume = new TGeoVolume(name.Data(), boardShape, fAir);
- z += siThick / 2 + space + boardThick / 2;
- ringVolume->AddNode(boardVolume, 0, new TGeoTranslation(0, 0, z));
- ringVolume->AddNode(boardVolume, 1, new TGeoTranslation(0,0,z+boardThick));
-
- // PCB
- TGeoShape* pcbShape = new TGeoTube(rmin+.1,rmax-.1, pcbThick / 2);
- name = Form("F%cPC", id);
- z = -boardThick / 2 + pcbThick / 2;
- TGeoVolume* pcbVolume = new TGeoVolume(name.Data(), pcbShape, fPCB);
- boardVolume->AddNode(pcbVolume, 0, new TGeoTranslation(0, 0, z));
-
- // Copper
- TGeoShape* cuShape = new TGeoTube(rmin+.1, rmax-.1, copperThick / 2);
- name = Form("F%cCO", id);
- z += pcbThick / 2 + copperThick / 2;
- TGeoVolume* cuVolume = new TGeoVolume(name.Data(), cuShape, fCopper);
- boardVolume->AddNode(cuVolume, 0, new TGeoTranslation(0, 0, z));
-
- // Chip
- TGeoShape* chipShape = new TGeoTube(rmin+.1, rmax-.1, chipThick / 2);
- name = Form("F%cCH", id);
- z += copperThick / 2 + chipThick / 2;
- TGeoVolume* chipVolume = new TGeoVolume(name.Data(), chipShape, fChip);
- boardVolume->AddNode(chipVolume, 0, new TGeoTranslation(0, 0, z));
-
- return ringVolume;
-}
-
-//____________________________________________________________________
-//
-// EOF
-//
+++ /dev/null
-#ifndef ALIFMDGEOMETRYBUILDERSIMPLE_H
-#define ALIFMDGEOMETRYBUILDERSIMPLE_H
-/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights
- * reserved.
- *
- * Latest changes by Christian Holm Christensen <cholm@nbi.dk>
- *
- * See cxx source for full Copyright notice
- */
-#ifndef ALIFMDGEOMETRYBUILDER
-# include <AliFMDGeometryBuilder.h>
-#endif
-class AliFMDRing;
-
-//____________________________________________________________________
-class AliFMDGeometryBuilderSimple : public AliFMDGeometryBuilder
-{
-public:
- AliFMDGeometryBuilderSimple();
- /** CTOR */
- AliFMDGeometryBuilderSimple(Bool_t detailed);
- virtual ~AliFMDGeometryBuilderSimple() {}
-protected:
- /** Make a ring volume
- @param r Ring geometry
- @return Ring volume */
- TGeoVolume* RingGeometry(AliFMDRing* r);
- ClassDef(AliFMDGeometryBuilderSimple,1);
-};
-
-
-#endif
-//____________________________________________________________________
-//
-// Local Variables:
-// mode: C++
-// End:
-//
-// EOF
-//
-
fZ = z;
}
+//____________________________________________________________________
+const char*
+AliFMDHit::GetName() const
+{
+ static TString n;
+ n = Form("FMD%d%c[%2d,%3d]", fDetector,fRing,fSector,fStrip);
+ return n.Data();
+}
+
+//____________________________________________________________________
+const char*
+AliFMDHit::GetTitle() const
+{
+ static TString t;
+ TDatabasePDG* pdgDB = TDatabasePDG::Instance();
+ TParticlePDG* pdg = pdgDB->GetParticle(fPdg);
+ t = Form("%s (%d): %f MeV / %f cm", (pdg ? pdg->GetName() : "?"),
+ fTrack, fEdep, fLength);
+ return t.Data();
+}
+
//____________________________________________________________________
Float_t
AliFMDHit::P() const
Float_t l=0,
Bool_t stop=kFALSE);
virtual ~AliFMDHit() {}
-
+
UShort_t Detector() const { return fDetector; }
Char_t Ring() const { return fRing; }
UShort_t Sector() const { return fSector; }
Float_t Time() const { return fTime; }
Float_t Length() const { return fLength; }
Bool_t IsStop() const { return fStop; }
- void Print(Option_t* opt="") const;
+
+ void Print(Option_t* opt="") const;
+ const char* GetName() const;
+ const char* GetTitle() const;
void SetEdep(Float_t edep) { fEdep = edep; }
protected:
#include "AliFMD.h" // ALIFMD_H
#include "AliFMDHit.h" // ALIFMDHIT_H
#include "AliFMDDigit.h" // ALIFMDDigit_H
-#include "AliFMDMultStrip.h" // ALIFMDMultStrip_H
-#include "AliFMDMultRegion.h" // ALIFMDMultRegion_H
+#include "AliFMDRecPoint.h" // ALIFMDRECPOINT_H
+#include <AliESD.h>
+#include <AliESDFMD.h>
#include <TTree.h> // ROOT_TTree
+#include <TChain.h> // ROOT_TChain
#include <TParticle.h> // ROOT_TParticle
#include <TString.h> // ROOT_TString
#include <TDatabasePDG.h> // ROOT_TDatabasePDG
#include <TMath.h> // ROOT_TMath
#include <TGeoManager.h> // ROOT_TGeoManager
+#include <TSystemDirectory.h> // ROOT_TSystemDirectory
#include <Riostream.h> // ROOT_Riostream
//____________________________________________________________________
fStack(0),
fFMDLoader(0),
fFMD(0),
+ fMainESD(0),
+ fESD(0),
fTreeE(0),
fTreeH(0),
fTreeD(0),
fTreeS(0),
fTreeR(0),
+ fChainE(0),
fArrayE(0),
fArrayH(0),
fArrayD(0),
fArrayS(0),
- fArrayN(0),
- fArrayP(0),
+ fArrayR(0),
fTreeMask(0),
fIsInit(kFALSE)
{
fStack(0),
fFMDLoader(0),
fFMD(0),
+ fMainESD(0),
+ fESD(0),
fTreeE(0),
fTreeH(0),
fTreeD(0),
fTreeS(0),
fTreeR(0),
+ fChainE(0),
fArrayE(0),
fArrayH(0),
fArrayD(0),
fArrayS(0),
- fArrayN(0),
- fArrayP(0),
+ fArrayR(0),
fTreeMask(0),
fIsInit(kFALSE)
{
}
fTreeE = fLoader->TreeE();
+ // Optionally, get the ESD files
+ if (TESTBIT(fTreeMask, kESD)) {
+ fChainE = new TChain("esdTree");
+ TSystemDirectory dir;
+ TList* files = dir.GetListOfFiles();
+ TSystemFile* file;
+ files->Sort();
+ TIter next(files);
+ while ((file = static_cast<TSystemFile*>(next()))) {
+ TString fname(file->GetName());
+ if (fname.Contains("AliESDs")) fChainE->AddFile(fname.Data());
+ }
+ fChainE->SetBranchAddress("ESD", &fMainESD);
+ }
+
// Optionally, get the geometry
if (TESTBIT(fTreeMask, kGeometry)) {
TString fname(fRun->GetGeometryFileName());
return kFALSE;
}
}
+
fIsInit = kTRUE;
return fIsInit;
AliInfo("Getting FMD reconstructed points");
if (fFMDLoader->LoadRecPoints()) return kFALSE;
fTreeR = fFMDLoader->TreeR();
- if (!fArrayN) fArrayN = new TClonesArray("AliFMDMultStrip");
- // if (!fArrayP) fArrayP = new TClonesArray("AliFMDMultRegion");
- fTreeR->SetBranchAddress("FMD", &fArrayN);
- // fTreeR->SetBranchAddress("FMDPoisson", &fArrayP);
+ if (!fArrayR) fArrayR = new TClonesArray("AliFMDRecPoint");
+ fTreeR->SetBranchAddress("FMD", &fArrayR);
+ }
+
+ // Possibly load FMD ESD information
+ if (TESTBIT(fTreeMask, kESD)) {
+ AliInfo("Getting FMD event summary data");
+ Int_t read = fChainE->GetEntry(event);
+ if (read <= 0) return kFALSE;
+ fESD = fMainESD->GetFMDData();
+ if (!fESD) return kFALSE;
+ }
+
+ return kTRUE;
+}
+
+
+//____________________________________________________________________
+Bool_t
+AliFMDInput::Event()
+{
+ // Process one event. The default implementation one or more of
+ //
+ // - ProcessHits if the hits are loaded.
+ // - ProcessDigits if the digits are loaded.
+ // - ProcessSDigits if the sumbable digits are loaded.
+ // - ProcessRecPoints if the reconstructed points are loaded.
+ // - ProcessESD if the event summary data is loaded
+ //
+ if (TESTBIT(fTreeMask, kHits))
+ if (!ProcessHits()) return kFALSE;
+ if (TESTBIT(fTreeMask, kDigits))
+ if (!ProcessDigits()) return kFALSE;
+ if (TESTBIT(fTreeMask, kSDigits))
+ if (!ProcessSDigits()) return kFALSE;
+ if (TESTBIT(fTreeMask, kRecPoints))
+ if (!ProcessRecPoints()) return kFALSE;
+ if (TESTBIT(fTreeMask, kESD))
+ if (!ProcessESD(fESD)) return kFALSE;
+
+ return kTRUE;
+}
+
+//____________________________________________________________________
+Bool_t
+AliFMDInput::ProcessHits()
+{
+ if (!fTreeH) {
+ AliError("No hit tree defined");
+ return kFALSE;
+ }
+ Int_t nTracks = fTreeH->GetEntries();
+ for (Int_t i = 0; i < nTracks; i++) {
+ Int_t hitRead = fTreeH->GetEntry(i);
+ if (hitRead <= 0) continue;
+ if (!fArrayH) {
+ AliError("No hit array defined");
+ return kFALSE;
+ }
+ Int_t nHit = fArrayH->GetEntries();
+ if (nHit <= 0) continue;
+ for (Int_t j = 0; j < nHit; j++) {
+ AliFMDHit* hit = static_cast<AliFMDHit*>(fArrayH->At(j));
+ if (!hit) continue;
+ TParticle* track = 0;
+ if (TESTBIT(fTreeMask, kKinematics) && fStack) {
+ Int_t trackno = hit->Track();
+ track = fStack->Particle(trackno);
+ }
+ if (!ProcessHit(hit, track)) return kFALSE;
+ }
+ }
+ return kTRUE;
+}
+
+//____________________________________________________________________
+Bool_t
+AliFMDInput::ProcessDigits()
+{
+ // Read the digit tree, and pass each digit to the member function
+ // ProcessDigit.
+ Int_t nEv = fTreeD->GetEntries();
+ for (Int_t i = 0; i < nEv; i++) {
+ Int_t digitRead = fTreeD->GetEntry(i);
+ if (digitRead <= 0) continue;
+ Int_t nDigit = fArrayD->GetEntries();
+ if (nDigit <= 0) continue;
+ for (Int_t j = 0; j < nDigit; j++) {
+ AliFMDDigit* digit = static_cast<AliFMDDigit*>(fArrayD->At(j));
+ if (!digit) continue;
+ if (!ProcessDigit(digit)) return kFALSE;
+ }
+ }
+ return kTRUE;
+}
+
+//____________________________________________________________________
+Bool_t
+AliFMDInput::ProcessSDigits()
+{
+ // Read the summable digit tree, and pass each sumable digit to the
+ // member function ProcessSdigit.
+ Int_t nEv = fTreeD->GetEntries();
+ for (Int_t i = 0; i < nEv; i++) {
+ Int_t sdigitRead = fTreeS->GetEntry(i);
+ if (sdigitRead <= 0) continue;
+ Int_t nSdigit = fArrayS->GetEntries();
+ if (nSdigit <= 0) continue;
+ for (Int_t j = 0; j < nSdigit; j++) {
+ AliFMDSDigit* sdigit = static_cast<AliFMDSDigit*>(fArrayS->At(j));
+ if (!sdigit) continue;
+ if (!ProcessSDigit(sdigit)) return kFALSE;
+ }
+ }
+ return kTRUE;
+}
+
+//____________________________________________________________________
+Bool_t
+AliFMDInput::ProcessRecPoints()
+{
+ // Read the reconstrcted points tree, and pass each reconstruction
+ // object (AliFMDRecPoint) to either ProcessRecPoint.
+ Int_t nEv = fTreeR->GetEntries();
+ for (Int_t i = 0; i < nEv; i++) {
+ Int_t recRead = fTreeR->GetEntry(i);
+ if (recRead <= 0) continue;
+ Int_t nRecPoint = fArrayR->GetEntries();
+ for (Int_t j = 0; j < nRecPoint; j++) {
+ AliFMDRecPoint* recPoint = static_cast<AliFMDRecPoint*>(fArrayR->At(j));
+ if (!recPoint) continue;
+ if (!ProcessRecPoint(recPoint)) return kFALSE;
+ }
}
return kTRUE;
}
;
#endif
-Bool_t
-AliFMDInputHits::Event()
-{
- // Read the hit tree, and pass each hit to the member function
- // ProcessHit. Optionally, if the user said `AddLoad(kKinematics)'
- // the track corresponding to the hit will also be passed to the
- // ProcessHit member function of the derived class.
- if (!fTreeH) {
- AliError("No hit tree defined");
- return kFALSE;
- }
- Int_t nTracks = fTreeH->GetEntries();
- for (Int_t i = 0; i < nTracks; i++) {
- Int_t hitRead = fTreeH->GetEntry(i);
- if (hitRead <= 0) continue;
- if (!fArrayH) {
- AliError("No hit array defined");
- return kFALSE;
- }
- Int_t nHit = fArrayH->GetEntries();
- if (nHit <= 0) continue;
- for (Int_t j = 0; j < nHit; j++) {
- AliFMDHit* hit = static_cast<AliFMDHit*>(fArrayH->At(j));
- if (!hit) continue;
- TParticle* track = 0;
- if (TESTBIT(fTreeMask, kKinematics) && fStack) {
- Int_t trackno = hit->Track();
- track = fStack->Particle(trackno);
- }
- if (!ProcessHit(hit, track)) return kFALSE;
- }
- }
- return kTRUE;
-}
//====================================================================
ClassImp(AliFMDInputDigits)
;
#endif
-Bool_t
-AliFMDInputDigits::Event()
-{
- // Read the digit tree, and pass each digit to the member function
- // ProcessDigit.
- Int_t nEv = fTreeD->GetEntries();
- for (Int_t i = 0; i < nEv; i++) {
- Int_t digitRead = fTreeD->GetEntry(i);
- if (digitRead <= 0) continue;
- Int_t nDigit = fArrayD->GetEntries();
- if (nDigit <= 0) continue;
- for (Int_t j = 0; j < nDigit; j++) {
- AliFMDDigit* digit = static_cast<AliFMDDigit*>(fArrayD->At(j));
- if (!digit) continue;
- if (!ProcessDigit(digit)) return kFALSE;
- }
- }
- return kTRUE;
-}
-
//====================================================================
ClassImp(AliFMDInputSDigits)
#if 0
;
#endif
-Bool_t
-AliFMDInputSDigits::Event()
-{
- // Read the summable digit tree, and pass each sumable digit to the
- // member function ProcessSdigit.
- Int_t nEv = fTreeD->GetEntries();
- for (Int_t i = 0; i < nEv; i++) {
- Int_t sdigitRead = fTreeS->GetEntry(i);
- if (sdigitRead <= 0) continue;
- Int_t nSdigit = fArrayS->GetEntries();
- if (nSdigit <= 0) continue;
- for (Int_t j = 0; j < nSdigit; j++) {
- AliFMDSDigit* sdigit = static_cast<AliFMDSDigit*>(fArrayS->At(j));
- if (!sdigit) continue;
- if (!ProcessSDigit(sdigit)) return kFALSE;
- }
- }
- return kTRUE;
-}
-
//====================================================================
ClassImp(AliFMDInputRecPoints)
#if 0
;
#endif
-Bool_t
-AliFMDInputRecPoints::Event()
-{
- // Read the reconstrcted points tree, and pass each reconstruction
- // object to either ProcessStrip (for AliFMDMultStrip objects), or
- // ProcessRegion (for AliFMDMultRegion objects).
- Int_t nEv = fTreeR->GetEntries();
- for (Int_t i = 0; i < nEv; i++) {
- Int_t recRead = fTreeR->GetEntry(i);
- if (recRead <= 0) continue;
- Int_t nRecStrip = fArrayN->GetEntries();
- for (Int_t j = 0; j < nRecStrip; j++) {
- AliFMDMultStrip* strip = static_cast<AliFMDMultStrip*>(fArrayN->At(j));
- if (!strip) continue;
- if (!ProcessStrip(strip)) return kFALSE;
- }
- Int_t nRecRegion = fArrayP->GetEntries();
- for (Int_t j = 0; j < nRecRegion; j++) {
- AliFMDMultRegion* region =static_cast<AliFMDMultRegion*>(fArrayP->At(j));
- if (!region) continue;
- if (!ProcessRegion(region)) return kFALSE;
- }
- }
- return kTRUE;
-}
-
-
-
//____________________________________________________________________
//
// EOF
class AliRun;
class AliFMD;
class AliFMDHit;
+class AliFMDDigit;
+class AliFMDSDigit;
+class AliFMDRecPoint;
+class AliESD;
+class AliESDFMD;
class TString;
class TClonesArray;
class TTree;
class TGeoManager;
class TParticle;
-
+class TChain;
//___________________________________________________________________
class AliFMDInput : public TObject
kSDigits, // Summable digits
kHeader, // Header information
kRecPoints, // Reconstructed points
+ kESD, // Load ESD's
kGeometry // Not really a tree
};
AliFMDInput();
virtual Bool_t Init();
virtual Bool_t Begin(Int_t event);
- virtual Bool_t Event() = 0;
+ virtual Bool_t Event();
virtual Bool_t End();
virtual Bool_t Finish() { return kTRUE; }
virtual Bool_t Run();
+
+ virtual Bool_t ProcessHits();
+ virtual Bool_t ProcessDigits();
+ virtual Bool_t ProcessSDigits();
+ virtual Bool_t ProcessRecPoints();
+
+ virtual Bool_t ProcessHit(AliFMDHit*, TParticle*) { return kTRUE; }
+ virtual Bool_t ProcessDigit(AliFMDDigit*) { return kTRUE; }
+ virtual Bool_t ProcessSDigit(AliFMDSDigit*) { return kTRUE; }
+ virtual Bool_t ProcessRecPoint(AliFMDRecPoint*) { return kTRUE; }
+ virtual Bool_t ProcessESD(AliESDFMD*) { return kTRUE; }
+
protected:
TString fGAliceFile; // File name of gAlice file
AliRunLoader* fLoader; // Loader of FMD data
AliStack* fStack; // Stack of particles
AliLoader* fFMDLoader; // Loader of FMD data
AliFMD* fFMD; // FMD object
+ AliESD* fMainESD; // ESD Object
+ AliESDFMD* fESD; // FMD ESD data
TTree* fTreeE; // Header tree
TTree* fTreeH; // Hits tree
TTree* fTreeD; // Digit tree
TTree* fTreeS; // SDigit tree
TTree* fTreeR; // RecPoint tree
+ TChain* fChainE; // Chain of ESD's
TClonesArray* fArrayE; // Event info array
TClonesArray* fArrayH; // Hit info array
TClonesArray* fArrayD; // Digit info array
TClonesArray* fArrayS; // SDigit info array
- TClonesArray* fArrayN; // Mult (single) info array
- TClonesArray* fArrayP; // Mult (region) info array
+ TClonesArray* fArrayR; // Mult (single) info array
TGeoManager* fGeoManager; // Geometry manager
Int_t fTreeMask; // Which tree's to load
Bool_t fIsInit;
public:
AliFMDInputHits(const char* file="galice.root")
: AliFMDInput(file) { AddLoad(kHits); }
- virtual Bool_t Event();
- virtual Bool_t ProcessHit(AliFMDHit* hit, TParticle* track) = 0;
ClassDef(AliFMDInputHits, 0);
};
public:
AliFMDInputDigits(const char* file="galice.root")
: AliFMDInput(file) { AddLoad(kDigits); }
- virtual Bool_t Event();
- virtual Bool_t ProcessDigit(AliFMDDigit* digit) = 0;
ClassDef(AliFMDInputDigits, 0);
};
public:
AliFMDInputSDigits(const char* file="galice.root")
: AliFMDInput(file) { AddLoad(kSDigits); }
- virtual Bool_t Event();
- virtual Bool_t ProcessSDigit(AliFMDSDigit* sdigit) = 0;
ClassDef(AliFMDInputSDigits, 0);
};
//____________________________________________________________________
-class AliFMDMultStrip;
-class AliFMDMultRegion;
+class AliFMDRecPoint;
class AliFMDInputRecPoints : public AliFMDInput
{
public:
AliFMDInputRecPoints(const char* file="galice.root")
: AliFMDInput(file) { AddLoad(kRecPoints); }
- virtual Bool_t Event();
- virtual Bool_t ProcessStrip(AliFMDMultStrip* mult) = 0;
- virtual Bool_t ProcessRegion(AliFMDMultRegion* mult) = 0;
ClassDef(AliFMDInputRecPoints, 0);
};
+++ /dev/null
-/**************************************************************************
- * Copyright(c) 2004, ALICE Experiment at CERN, All rights reserved. *
- * *
- * Author: The ALICE Off-line Project. *
- * Contributors are mentioned in the code where appropriate. *
- * *
- * Permission to use, copy, modify and distribute this software and its *
- * documentation strictly for non-commercial purposes is hereby granted *
- * without fee, provided that the above copyright notice appears in all *
- * copies and that both the copyright notice and this permission notice *
- * appear in the supporting documentation. The authors make no claims *
- * about the suitability of this software for any purpose. It is *
- * provided "as is" without express or implied warranty. *
- **************************************************************************/
-
-/* $Id$ */
-
-//____________________________________________________________________
-//
-// Base class for reconstructed charged particle multiplicty in the
-// FMD.
-// The class contains the field fMethod which is a flag set by
-// the AliFMDMultAlgorithm that created the object. The flag tells us
-// which algorithm was used to create the data stored in the object.
-//
-#include "AliFMDMult.h" // ALIFMDMULT_H
-#include <TString.h> // ROOT_TString
-#include <Riostream.h> // ROOT_Riostream
-
-//____________________________________________________________________
-ClassImp(AliFMDMult)
-#if 0
- ; // This is here to keep Emacs for indenting the next line
-#endif
-
-//____________________________________________________________________
-AliFMDMult::AliFMDMult(Float_t particles, UShort_t method)
- : fParticles(particles),
- fMethod(method)
-{
- // Constructor
- switch (fMethod) {
- case kPoission:
- case kIterative:
- case kNaiive:
- break;
- default:
- Warning("AliFMDMult", "unknown method: %d", method);
- break;
- }
-}
-
-
-//____________________________________________________________________
-void
-AliFMDMult::Print(Option_t* option) const
-{
- // Print information
- //
- // Options:
- //
- // V Be verbose
- //
- TString opt(option);
- if (!opt.Contains("v", TString::kIgnoreCase)) return;
- cout << " Method: " << flush;
- switch (fMethod) {
- case kPoission: cout << "Poission" << endl; break;
- case kIterative: cout << "Iterative" << endl; break;
- case kNaiive: cout << "Naive" << endl; break;
- default: cout << "Unknown" << endl; break;
- }
-}
-
-
-//____________________________________________________________________
-//
-// EOF
-//
+++ /dev/null
-#ifndef ALIFMDMULT_H
-#define ALIFMDMULT_H
-
-// Reconstracted Particles Class: has number of reconstructed
-// particles in sectors from NumOfMinSector to NumberOfMaxSector()
-// rings from NumOfMinRing to NumOfMaxRing for each FMDvolume
-//
-#ifndef ROOT_TObject
-# include <TObject.h>
-#endif
-
-class AliFMDMult: public TObject
-{
-public:
- enum EMethod {
- kPoission,
- kIterative,
- kNaiive
- };
- AliFMDMult(Float_t particles=0, UShort_t method=kNaiive);
- virtual ~AliFMDMult() {};
-
- Float_t Particles() const { return fParticles; }
- UShort_t Method() const { return fMethod; }
- virtual Float_t Eta() const = 0;
- virtual Float_t Phi() const = 0;
- virtual void Print(Option_t* opt="") const;
-protected:
- Float_t fParticles; // Number of particles
- UShort_t fMethod; // Method use to get fParticles
-
- ClassDef(AliFMDMult,1) // Base class for multiplicity data
-};
-#endif
-//____________________________________________________________________
-//
-// Local Variables:
-// mode: C++
-// End:
-//
-// EOF
-//
+++ /dev/null
-/**************************************************************************
- * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
- * *
- * Author: The ALICE Off-line Project. *
- * Contributors are mentioned in the code where appropriate. *
- * *
- * Permission to use, copy, modify and distribute this software and its *
- * documentation strictly for non-commercial purposes is hereby granted *
- * without fee, provided that the above copyright notice appears in all *
- * copies and that both the copyright notice and this permission notice *
- * appear in the supporting documentation. The authors make no claims *
- * about the suitability of this software for any purpose. It is *
- * provided "as is" without express or implied warranty. *
- **************************************************************************/
-
-/* $Id$ */
-
-//____________________________________________________________________
-//
-// Base class for FMD reconstruction algorithms.
-//
-// Derived classes will implement various ways of reconstructing the
-// charge particle multiplicity in the FMD.
-//
-// +---------------------+ +---------------------+
-// | AliFMDReconstructor |<>-----| AliFMDMultAlgorithm |
-// +---------------------+ +---------------------+
-// ^
-// |
-// +-----------+---------+
-// | |
-// +-------------------+ +------------------+
-// | AliFMDMultPoisson | | AliFMDMultNaiive |
-// +-------------------+ +------------------+
-//
-// AliFMDReconstructor acts as a manager class. It contains a list of
-// AliFMDMultAlgorithm objects. The call graph looks something like
-//
-//
-// +----------------------+ +----------------------+
-// | :AliFMDReconstructor | | :AliFMDMultAlgorithm |
-// +----------------------+ +----------------------+
-// | |
-// Reconstruct +-+ |
-// ------------>| | PreRun +-+
-// | |------------------------------->| |
-// | | +-+
-// | |-----+ (for each event) |
-// | | | *ProcessEvent |
-// |+-+ | |
-// || |<---+ PreEvent +-+
-// || |------------------------------>| |
-// || | +-+
-// || |-----+ |
-// || | | ProcessDigits |
-// ||+-+ | |
-// ||| |<---+ |
-// ||| | *ProcessDigit(digit) +-+
-// ||| |----------------------------->| |
-// ||| | +-+
-// ||+-+ |
-// || | PostEvent +-+
-// || |------------------------------>| |
-// || | +-+
-// |+-+ |
-// | | PostRun +-+
-// | |------------------------------->| |
-// | | +-+
-// +-+ |
-// | |
-//
-//
-#include "AliFMDMultAlgorithm.h" // ALIFMDMULTALGORITHM_H
-#include "AliFMDDigit.h" // ALIFMDDIGIT_H
-#include <TClonesArray.h> // ROOT_TClonesArray
-
-//____________________________________________________________________
-ClassImp(AliFMDMultAlgorithm)
-#if 0
- ; // This is here to keep Emacs for indenting the next line
-#endif
-
-//____________________________________________________________________
-AliFMDMultAlgorithm::AliFMDMultAlgorithm(const char* name, const char* title)
- : TNamed(name, title),
- fTreeR(0),
- fMult(0),
- fFMD(0)
-{
- // Default CTOR
-}
-
-//____________________________________________________________________
-AliFMDMultAlgorithm::~AliFMDMultAlgorithm()
-{
- // DTOR
- if (fMult) {
- fMult->Delete();
- delete fMult;
- }
-}
-
-
-//____________________________________________________________________
-void
-AliFMDMultAlgorithm::PreEvent(TTree* treeR, Float_t /* ipZ */)
-{
- // Executed before each event.
- if (fMult) fMult->Clear();
- fNMult = 0;
- fTreeR = treeR;
-}
-
-
-
-//____________________________________________________________________
-//
-// EOF
-//
+++ /dev/null
-#ifndef ALIFMDMULTALGORITHM_H
-#define ALIFMDMULTALGORITHM_H
-/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights
- * reserved.
- *
- * Latest changes by Christian Holm Christensen <cholm@nbi.dk>
- *
- * See cxx source for full Copyright notice
- */
-/* $Id$ */
-
-//____________________________________________________________________
-//
-// Base class for FMD reconstruction algorithms.
-// Derived classes will implement various ways of reconstructing the
-// charge particle multiplicity in the FMD.
-//
-
-#ifndef ROOT_TTask
-# include <TTask.h>
-#endif
-
-//____________________________________________________________________
-class AliFMDDigit;
-class TTree;
-class AliFMD;
-class TClonesArray;
-
-//____________________________________________________________________
-class AliFMDMultAlgorithm : public TNamed
-{
-public:
- AliFMDMultAlgorithm(const char* name, const char* title);
- virtual ~AliFMDMultAlgorithm();
-
- virtual void PreRun(AliFMD* fmd) { fFMD = fmd; }
- virtual void PreEvent(TTree* treeR, Float_t ipZ);
- virtual void ProcessDigit(AliFMDDigit* digit,
- Float_t eta,
- Float_t phi,
- UShort_t counts) = 0;
- virtual void PostEvent() {}
- virtual void PostRun() {}
-protected:
- TTree* fTreeR; //! Reconstruction tree
- TClonesArray* fMult; //! Reconstructed multiplicities
- Int_t fNMult; //! Number of reconstructed multiplicities
- AliFMD* fFMD; //! Detector information
-
- ClassDef(AliFMDMultAlgorithm, 0) // Base class for algorithms
-};
-
-#endif
-//____________________________________________________________________
-//
-// Local Variables:
-// mode: C++
-// End:
-//
-// EOF
-//
+++ /dev/null
-/**************************************************************************
- * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
- * *
- * Author: The ALICE Off-line Project. *
- * Contributors are mentioned in the code where appropriate. *
- * *
- * Permission to use, copy, modify and distribute this software and its *
- * documentation strictly for non-commercial purposes is hereby granted *
- * without fee, provided that the above copyright notice appears in all *
- * copies and that both the copyright notice and this permission notice *
- * appear in the supporting documentation. The authors make no claims *
- * about the suitability of this software for any purpose. It is *
- * provided "as is" without express or implied warranty. *
- **************************************************************************/
-
-/* $Id$ */
-
-//____________________________________________________________________
-//
-// Reconstruct charged particle multiplicity in the FMD
-//
-// [See also the AliFMDReconstructor class]
-//
-// This class reconstructs the multiplicity based on the assumption
-// that all particles are minimum ionizing.
-// Hence, the name `naiive'
-//
-#include "AliFMD.h" // ALIFMD_H
-#include "AliFMDMultNaiive.h" // ALIFMDMULTNAIIVE_H
-#include "AliFMDParameters.h" // ALIFMDPARAMETERS_H
-#include "AliFMDMultStrip.h" // ALIFMDMULTNAIIVE_H
-#include "AliFMDDigit.h" // ALIFMDDIGIT_H
-#include <TClonesArray.h> // ROOT_TClonesArray
-#include <TTree.h> // ROOT_TTree
-
-//____________________________________________________________________
-ClassImp(AliFMDMultNaiive)
-#if 0
- ; // This is here to keep Emacs for indenting the next line
-#endif
-
-//____________________________________________________________________
-AliFMDMultNaiive::AliFMDMultNaiive()
- : AliFMDMultAlgorithm("Naiive", "Naiive")
-{
- // Default CTOR
- fMult = new TClonesArray("AliFMDMultStrip", 1000);
-}
-
-//____________________________________________________________________
-void
-AliFMDMultNaiive::PreRun(AliFMD* fmd)
-{
- // Initialise before a run
- AliFMDMultAlgorithm::PreRun(fmd);
- AliFMDParameters* pars = AliFMDParameters::Instance();
- fEdepMip = pars->GetEdepMip();
- fGain = (Float_t(pars->GetVA1MipRange()) / pars->GetAltroChannelSize()
- * fEdepMip);
-}
-
-//____________________________________________________________________
-void
-AliFMDMultNaiive::PreEvent(TTree* treeR, Float_t ipZ)
-{
- // Reset internal data
- AliFMDMultAlgorithm::PreEvent(treeR, ipZ);
- fTreeR->Branch("FMDNaiive", &fMult);
-}
-
-//____________________________________________________________________
-void
-AliFMDMultNaiive::ProcessDigit(AliFMDDigit* digit,
- Float_t eta,
- Float_t phi,
- UShort_t count)
-{
- // Process one digit.
- //
- // Parameters:
- //
- // digit Digit to process
- // eta Pseudo-rapidity of digit
- // phi Azimuthal angle of digit
- // count ADC (corrected for the pedestal)
- //
- // This calculates the energy deposited and the number of MIPs that
- // this energy deposition corresponds to
- //
- // EnergyDeposited = cos(theta) * gain * count
- // Multiplicity = EnergyDeposited / EnergyDepositedPerMIP
- //
- // where gain is a conversion factor from number of counts to an
- // energy:
- // Pre_Amp_MIP_Range 1
- // gain = ----------------- * ---------------------
- // ADC_channel_size EnergyDepositedPerMip
- //
- // and theta is the particles incident angle on the strip, given by
- //
- // theta = 2 * atan(exp(-eta))
- //
- // The cos(theta) factor corrects for the fact that the particle may
- // traverse the strip at an angle, and therefor have a longer flight
- // length, leading to a larger energy deposition.
- //
- if (!digit) return;
- Double_t edep = Adc2Energy(digit, eta, count);
- Double_t mult = Energy2Multiplicity(digit, edep);
-
- AliFMDMultStrip* m =
- new ((*fMult)[fNMult]) AliFMDMultStrip(digit->Detector(),
- digit->Ring(),
- digit->Sector(),
- digit->Strip(),
- eta, phi,
- edep, mult,
- AliFMDMult::kNaiive);
- (void)m;
- fNMult++;
-}
-//____________________________________________________________________
-Float_t
-AliFMDMultNaiive::Adc2Energy(AliFMDDigit* /* digit */,
- Float_t eta,
- UShort_t count)
-{
- // Converts number of ADC counts to energy deposited.
- // Note, that this member function can be overloaded by derived
- // classes to do strip-specific look-ups in databases or the like,
- // to find the proper gain for a strip.
- //
- // In this simple version, we calculate the energy deposited as
- //
- // EnergyDeposited = cos(theta) * gain * count
- //
- // where
- //
- // Pre_amp_MIP_Range
- // gain = ----------------- * Energy_deposited_per_MIP
- // ADC_channel_size
- //
- // is constant and the same for all strips.
- Double_t theta = 2 * TMath::ATan(TMath::Exp(-eta));
- Double_t edep = TMath::Abs(TMath::Cos(theta)) * fGain * count;
- return edep;
-}
-
-//____________________________________________________________________
-Float_t
-AliFMDMultNaiive::Energy2Multiplicity(AliFMDDigit* /* digit */,
- Float_t edep)
-{
- // Converts an energy signal to number of particles.
- // Note, that this member function can be overloaded by derived
- // classes to do strip-specific look-ups in databases or the like,
- // to find the proper gain for a strip.
- //
- // In this simple version, we calculate the multiplicity as
- //
- // multiplicity = Energy_deposited / Energy_deposited_per_MIP
- //
- // where
- //
- // Energy_deposited_per_MIP = 1.664 * SI_density * SI_thickness
- //
- // is constant and the same for all strips
- return edep / fEdepMip;
-}
-
-
-
-//____________________________________________________________________
-//
-// EOF
-//
+++ /dev/null
-#ifndef ALIFMDMULTNAIIVE_H
-#define ALIFMDMULTNAIIVE_H
-/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights
- * reserved.
- *
- * Latest changes by Christian Holm Christensen <cholm@nbi.dk>
- *
- * See cxx source for full Copyright notice
- */
-/* $Id$ */
-//____________________________________________________________________
-//
-// Class to do multiplicity reconstruction using the Naiive method.
-// That is, we count the number of empty strips in a region, and
-// derive the charge particle multiplicity from that number.
-//
-
-#ifndef ALIFMDMULTALGORITHM_H
-# include "AliFMDMultAlgorithm.h"
-#endif
-
-//____________________________________________________________________
-class AliFMDMultNaiive : public AliFMDMultAlgorithm
-{
-public:
- AliFMDMultNaiive();
- virtual ~AliFMDMultNaiive() {}
-
- virtual void PreRun(AliFMD* fmd);
- virtual void PreEvent(TTree* treeR, Float_t ipZ);
- virtual void ProcessDigit(AliFMDDigit* digit,
- Float_t eta,
- Float_t phi,
- UShort_t counts);
- void SetGain(Float_t g) { fGain = g; }
- void SetEdepMip(Float_t e) { fEdepMip = e; }
- Float_t GetGain() const { return fGain; }
- Float_t GetEdepMip() const { return fEdepMip; }
-protected:
- Float_t Adc2Energy(AliFMDDigit* digit, Float_t eta, UShort_t count);
- Float_t Energy2Multiplicity(AliFMDDigit* digit, Float_t edep);
- Float_t fGain; // GeV per ADC count
- Float_t fEdepMip; // Energy deposited per MIP
-
- ClassDef(AliFMDMultNaiive, 0) // Naiive algorithm
-};
-
-#endif
-//____________________________________________________________________
-//
-// Local Variables:
-// mode: C++
-// End:
-//
-// EOF
-//
+++ /dev/null
-/**************************************************************************
- * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
- * *
- * Author: The ALICE Off-line Project. *
- * Contributors are mentioned in the code where appropriate. *
- * *
- * Permission to use, copy, modify and distribute this software and its *
- * documentation strictly for non-commercial purposes is hereby granted *
- * without fee, provided that the above copyright notice appears in all *
- * copies and that both the copyright notice and this permission notice *
- * appear in the supporting documentation. The authors make no claims *
- * about the suitability of this software for any purpose. It is *
- * provided "as is" without express or implied warranty. *
- **************************************************************************/
-
-/* $Id$ */
-
-//____________________________________________________________________
-//
-// Reconstruct charged particle multiplicity in the FMD
-//
-// [See also the AliFMDReconstructor class]
-//
-// This class reconstructs the muliplicity in regions based on the
-// ratio of empty to full strips.
-// Hence the name `poisson'
-//
-#include "AliFMD.h" // ALIFMD_H
-#include "AliFMDGeometry.h" // ALIFMDGEOMETRY_H
-#include "AliFMDDetector.h" // ALIFMDDETECTOR_H
-#include "AliFMDRing.h" // ALIFMDRING_H
-#include "AliFMDMultPoisson.h" // ALIFMDMULTPOISSON_H
-#include "AliFMDMultRegion.h" // ALIFMDMULTREGION_H
-#include "AliFMDDigit.h" // ALIFMDDIGIT_H
-#include "AliLog.h" // ALILOG_H
-#include <TClonesArray.h> // ROOT_TClonesArray
-#include <TTree.h> // ROOT_TTree
-
-//____________________________________________________________________
-ClassImp(AliFMDMultPoisson)
-#if 0
- ; // This is here to keep Emacs for indenting the next line
-#endif
-
-//____________________________________________________________________
-AliFMDMultPoisson::AliFMDMultPoisson()
- : AliFMDMultAlgorithm("Poisson", "Poisson"),
- fDeltaEta(0),
- fDeltaPhi(0),
- fThreshold(0)
-{
- // CTOR
- SetDeltaEta();
- SetDeltaPhi();
- SetThreshold();
- fMult = new TClonesArray("AliFMDMultRegion", 1000);
-}
-
-//____________________________________________________________________
-void
-AliFMDMultPoisson::PreEvent(TTree* tree, Float_t ipZ)
-{
- // Reset internal data
- AliDebug(30, Form("before event with vertex %f", ipZ));
- AliFMDMultAlgorithm::PreEvent(tree, ipZ);
- fCurrentVertexZ = ipZ;
- fEmpty.Reset(kFALSE);
-
- // Make a branch in the reconstruction tree.
- const Int_t kBufferSize = 16000;
- fTreeR->Branch("FMDPoisson", &fMult, kBufferSize);
-
-}
-
-//____________________________________________________________________
-void
-AliFMDMultPoisson::ProcessDigit(AliFMDDigit* digit,
- Float_t /* eta */,
- Float_t /* phi */,
- UShort_t count)
-{
- // Process one digit.
- //
- // Parameters:
- //
- // digit Digit to process
- // ipZ Z--coordinate of the primary interaction
- // vertex of this event
- //
- if (!digit) return;
- AliDebug(30, Form("Processing digit %s (%s)", digit->GetName(),
- count < fThreshold ? "empty" : "hit"));
- if (count < fThreshold) fEmpty(digit->Detector(),
- digit->Ring(),
- digit->Sector(),
- digit->Strip()) = kTRUE;
-}
-
-//____________________________________________________________________
-void
-AliFMDMultPoisson::PostEvent()
-{
- // Fill the branch
- // Based on the information in the cache, do the reconstruction.
-
- // Loop over the detectors
- for (Int_t i = 1; i <= 3; i++) {
- AliFMDGeometry* fmd = AliFMDGeometry::Instance();
- AliFMDDetector* sub = fmd->GetDetector(i);
- if (!sub) continue;
-
- // Loop over the rings in the detector
- for (Int_t j = 0; j < 2; j++) {
- AliFMDRing* r = sub->GetRing((j == 0 ? 'I' : 'O'));
- Float_t rZ = sub->GetRingZ((j == 0 ? 'I' : 'O'));
- if (!r) continue;
-
- // Calculate low/high theta and eta
- // FIXME: Is this right?
- Float_t realZ = fCurrentVertexZ + rZ;
- Float_t thetaOut = TMath::ATan2(r->GetHighR(), realZ);
- Float_t thetaIn = TMath::ATan2(r->GetLowR(), realZ);
- Float_t etaOut = - TMath::Log(TMath::Tan(thetaOut / 2));
- Float_t etaIn = - TMath::Log(TMath::Tan(thetaIn / 2));
- if (TMath::Abs(etaOut) > TMath::Abs(etaIn)) {
- Float_t tmp = etaIn;
- etaIn = etaOut;
- etaOut = tmp;
- }
-
- //-------------------------------------------------------------
- //
- // Here starts poisson method
- //
- // Calculate eta step per strip, number of eta steps, number of
- // phi steps, and check the sign of the eta increment
- Float_t stripEta = (Float_t(r->GetNStrips()) / (etaIn - etaOut));
- Int_t nEta = Int_t(TMath::Abs(etaIn - etaOut) / fDeltaEta);
- Int_t nPhi = Int_t(360. / fDeltaPhi);
- Float_t sign = TMath::Sign(Float_t(1.), etaIn);
-
- AliDebug(10, Form("FMD%d%c Eta range: %f, %f %d Phi steps",
- sub->GetId(), r->GetId(), etaOut, etaIn, nPhi));
-
- // Loop over relevant phi values
- for (Int_t p = 0; p < nPhi; p++) {
- Float_t minPhi = p * fDeltaPhi;
- Float_t maxPhi = minPhi + fDeltaPhi;
- UShort_t minSector = UShort_t(minPhi / 360) * r->GetNSectors();
- UShort_t maxSector = UShort_t(maxPhi / 360) * r->GetNSectors();
-
- // AliDebug(10, Form(" Now in phi range %f, %f (sectors %d,%d)",
- // minPhi, maxPhi, minSector, maxSector));
- // Loop over relevant eta values
- for (Int_t e = nEta; e >= 0; --e) {
- Float_t maxEta = etaIn - sign * e * fDeltaEta;
- Float_t minEta = maxEta - sign * fDeltaEta;
- if (sign > 0) minEta = TMath::Max(minEta, etaOut);
- else minEta = TMath::Min(minEta, etaOut);
- Float_t theta1 = 2 * TMath::ATan(TMath::Exp(-minEta));
- Float_t theta2 = 2 * TMath::ATan(TMath::Exp(-maxEta));
- Float_t minR = TMath::Abs(realZ * TMath::Tan(theta2));
- Float_t maxR = TMath::Abs(realZ * TMath::Tan(theta1));
- // Calculate the weighted mean eta of the region
- Float_t minW2 = TMath::Power(minR * 2 * TMath::Pi() *
- ((maxPhi - minPhi)/360),2);
- Float_t maxW2 = TMath::Power(minR * 2 * TMath::Pi() *
- ((maxPhi - minPhi)/360), 2);
- Float_t meanEta = ((minEta / minW2 + maxEta / maxW2) /
- (1 / (minW2 + maxW2)));
- //UShort_t minStrip = UShort_t((etaIn - maxEta) * stripEta + 0.5);
- // UShort_t maxStrip = UShort_t((etaIn - minEta) * stripEta + 0.5);
-
- UShort_t minStrip = UShort_t(r->GetNStrips() -
- (etaIn - minEta) * stripEta + 0.5);
- UShort_t maxStrip = UShort_t(r->GetNStrips() -
- (etaIn - maxEta) * stripEta + 0.5);
-
- AliDebug(10, Form(" Now in eta range %f, %f (strips %d, %d)\n"
- " [radii %f, %f, thetas %f, %f, sign %d]",
- minEta, maxEta, minStrip, maxStrip,
- minR, maxR, theta1, theta2, sign));
-
- // Count number of empty strips
- Int_t emptyStrips = 0;
- for (Int_t sector = minSector; sector < maxSector; sector++)
- for (Int_t strip = minStrip; strip < maxStrip; strip++)
- if (fEmpty(sub->GetId(), r->GetId(), sector, strip))
- emptyStrips++;
-
- // The total number of strips
- Float_t nTotal = (maxSector - minSector) * (maxStrip - minStrip);
- // Log ratio of empty to total number of strips
-
- Double_t lambda = (emptyStrips > 0 ?
- - TMath::Log(Double_t(emptyStrips) / nTotal) :
- 1);
-
- // The reconstructed number of particles is then given by
- Int_t reconstructed = Int_t(lambda * nTotal + 0.5);
- AliDebug(10, Form("Lambda= %d / %f = %f particles %d",
- emptyStrips, nTotal,
- Float_t(emptyStrips) / nTotal , reconstructed));
-
- // Add a AliFMDMultRegion to the reconstruction tree.
- AliFMDMultRegion* m = new((*fMult)[fNMult])
- AliFMDMultRegion(sub->GetId(), r->GetId(),
- minSector, maxSector, minStrip, maxStrip,
- minEta, maxEta, meanEta, minPhi, maxPhi,
- reconstructed, AliFMDMultRegion::kPoission);
- (void)m;
- fNMult++;
- } // phi
- } // eta
- } // ring
- } // detector
-}
-
-
-//____________________________________________________________________
-//
-// EOF
-//
+++ /dev/null
-#ifndef ALIFMDMULTPOISSON_H
-#define ALIFMDMULTPOISSON_H
-/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights
- * reserved.
- *
- * Latest changes by Christian Holm Christensen <cholm@nbi.dk>
- *
- * See cxx source for full Copyright notice
- */
-/* $Id$ */
-//____________________________________________________________________
-//
-// Class to do multiplicity reconstruction using the Poisson method.
-// That is, we count the number of empty strips in a region, and
-// derive the charge particle multiplicity from that number.
-//
-
-#ifndef ALIFMDMULTALGORITHM_H
-# include "AliFMDMultAlgorithm.h"
-#endif
-#ifndef ALIFMDBOOLMAP_H
-# include "AliFMDBoolMap.h"
-#endif
-
-//____________________________________________________________________
-class AliFMDMultPoisson : public AliFMDMultAlgorithm
-{
-public:
- AliFMDMultPoisson();
- virtual ~AliFMDMultPoisson() {}
-
- virtual void PreEvent(TTree* treeR, Float_t ipZ);
- virtual void ProcessDigit(AliFMDDigit* digit,
- Float_t eta,
- Float_t phi,
- UShort_t counts);
- virtual void PostEvent();
-
- void SetDeltaEta(Float_t deta=.1) { fDeltaEta = deta; }
- void SetDeltaPhi(Float_t dphi=360) { fDeltaPhi = dphi; }
- void SetThreshold(UShort_t t=6) { fThreshold = t; }
-protected:
- AliFMDBoolMap fEmpty; //! Map of empty channels
- Float_t fCurrentVertexZ; //! Current IP's Z-coordinate
- Float_t fDeltaEta; // Bin size in eta
- Float_t fDeltaPhi; // Bin size in phi
- UShort_t fThreshold; // Threshold for Poisson recon.
-
- ClassDef(AliFMDMultPoisson, 0) // Poisson algorithm
-};
-
-#endif
-//____________________________________________________________________
-//
-// Local Variables:
-// mode: C++
-// End:
-//
-// EOF
-//
+++ /dev/null
-/**************************************************************************
- * Copyright(c) 2004, ALICE Experiment at CERN, All rights reserved. *
- * *
- * Author: The ALICE Off-line Project. *
- * Contributors are mentioned in the code where appropriate. *
- * *
- * Permission to use, copy, modify and distribute this software and its *
- * documentation strictly for non-commercial purposes is hereby granted *
- * without fee, provided that the above copyright notice appears in all *
- * copies and that both the copyright notice and this permission notice *
- * appear in the supporting documentation. The authors make no claims *
- * about the suitability of this software for any purpose. It is *
- * provided "as is" without express or implied warranty. *
- **************************************************************************/
-
-/* $Id$ */
-
-//____________________________________________________________________
-//
-// FMD reconstructed multiplicity in a region of a ring. The region
-// is identified by (strip_min,sector_min)x(strip_max,sector_max) or
-// by (eta_max,phi_min),(eta_min,phi_max). It's also possible to
-// get the peudorapidity of the center-of-mass of the region, as well
-// as the mean azimuthal angle.
-//
-// [Note, that minStrip corresponds to maxEta, and maxStrip
-// corresponds to minEta]
-//
-// These objects are usually created by the Poisson reconstruction
-// method.
-//
-#include "AliFMDMultRegion.h" // ALIFMDPARTICLES_H
-#include <TString.h> // ROOT_TString
-#include <Riostream.h> // ROOT_Riostream
-
-//____________________________________________________________________
-ClassImp(AliFMDMultRegion)
-#if 0
- ; // This is here to keep Emacs for indenting the next line
-#endif
-
-
-//____________________________________________________________________
-AliFMDMultRegion::AliFMDMultRegion()
- : fDetector(0),
- fRing('\0'),
- fMinSector(0),
- fMaxSector(0),
- fMinStrip(0),
- fMaxStrip(0),
- fMinEta(0),
- fMaxEta(0),
- fMinPhi(0),
- fMaxPhi(0)
-{}
-
-//____________________________________________________________________
-AliFMDMultRegion::AliFMDMultRegion(UShort_t detector, Char_t ring,
- UShort_t minSector, UShort_t maxSector,
- UShort_t minStrip, UShort_t maxStrip,
- Float_t minEta, Float_t maxEta,
- Float_t meanEta,
- Float_t minPhi, Float_t maxPhi,
- Float_t particles, UShort_t method)
- : AliFMDMult(particles, method),
- fDetector(detector),
- fRing(ring),
- fMinSector(minSector),
- fMaxSector(maxSector),
- fMinStrip(minStrip),
- fMaxStrip(maxStrip),
- fMinEta(minEta),
- fMaxEta(maxEta),
- fMeanEta(meanEta),
- fMinPhi(minPhi),
- fMaxPhi(maxPhi)
-{}
-
-#if 0
-//____________________________________________________________________
-Float_t
-AliFMDMultRegion::Eta() const
-{
- // Return the center-of-mass eta of the region. This is calculated
- // as the weighted mean of min and max eta, where the weights are
- // the length of the arcs of the upper and lower edge of the region:
- //
- // (maxPhi - minPhi)
- // f = -----------------
- // 360
- //
- // w_max = ds*minStrip*2*pi*f
- //
- // w_min = ds*maxStrip*2*pi*f
- //
- // 1/w^2 = 1/w_max^2 + 1/w_min^2
- //
- // 1 1
- // = ---------------------- + ----------------------
- // (ds*minStrip*2*pi*f)^2 (ds*maxStrip*2*pi*f)^2
- //
- // (ds*maxStrip*2*pi*f)^2 + (ds*minStrip*2*pi*f)^2
- // = -----------------------------------------------
- // (ds*maxStrip*2*pi*f)^2 * (ds*minStrip*2*pi*f)^2
- //
- //
- // 4 * pi^2 * ds^2 * f^2 (maxStrip^2 + minStrip^2)
- // = -------------------------------------------------
- // 16 * pi^4 * ds^4 * f^4 minStrip^2 * maxStrip^2
- //
- // (maxStrip^2 + minStrip^2)
- // = -------------------------------------------------
- // 4 * pi^2 * ds^2 * f^2 minStrip^2 * maxStrip^2
- //
- // <eta> = (maxEta/w_max^2 + minEta /w_min^2) / (1/w^2)
- //
- // w_min^2 * maxEta + w_max^2 * minEta
- // = ------------------------------------ / (1/w^2)
- // w_max^2 * w_min^2
- //
- // 4*pi^2*ds^2*(maxStrip*maxEta + minStrip*minEta)
- // = ----------------------------------------------- / (1/w^2)
- // 16*pi^4*ds^4*f^4*minStrip^2*maxStrip^2
- //
- // maxStrip * maxEta + minStrip * minEta
- // = -------------------------------------
- // 4*pi^2*ds^2*f^2*minStrip^2*maxStrip^2
- //
- // 4*pi^2*ds^2*f^2*minStrip^2*maxStrip^2
- // * -------------------------------------
- // maxStrip^2+minStrip^2
- //
- // maxStrip * maxEta + minStrip * minEta
- // = -------------------------------------
- // maxStrip^2 + minStrip^2
- // _
- // |_|
- //
- Float_t eta = (fMaxStrip * fMaxEta + fMinStrip * fMinEta)
- / (fMaxStrip * fMaxStrip + fMinStrip * fMinStrip);
- return eta;
-}
-#endif
-
-//____________________________________________________________________
-void
-AliFMDMultRegion::Print(Option_t* option) const
-{
- // Print information
- //
- // Options:
- // D: Detector (default)
- // S: Sector range
- // T: Strip range
- // E: Eta range (default)
- // P: Phi range (default)
- //
- TString opt(option);
- cout << "FMD Multiplicity in a region: " << fParticles << endl;
- if (opt.Contains("D", TString::kIgnoreCase))
- cout << " Detector: FMD" << fDetector << fRing
- << "[" << fMinSector << "-" << fMaxSector
- << "," << fMinStrip << "-" << fMaxStrip << "]" << endl;
- if (opt.Contains("E", TString::kIgnoreCase))
- cout << " Eta range: [" << fMinEta << "," << fMaxEta << endl;
- if (opt.Contains("P", TString::kIgnoreCase))
- cout << " Phi range: [" << fMinPhi << "," << fMaxPhi << endl;
- AliFMDMult::Print(option);
-}
-
-
-//____________________________________________________________________
-//
-// EOF
-//
+++ /dev/null
-#ifndef ALIFMDMULTREGION_H
-#define ALIFMDMULTREGION_H
-
-// Reconstracted Particles Class: has number of reconstructed
-// particles in sectors from NumOfMinSector to NumberOfMaxSector()
-// rings from NumOfMinRing to NumOfMaxRing for each FMDvolume
-//
-#ifndef ALIFMDMULT_H
-# include "AliFMDMult.h"
-#endif
-
-class AliFMDMultRegion: public AliFMDMult
-{
-public:
- AliFMDMultRegion();
- AliFMDMultRegion (UShort_t detector, Char_t ring,
- UShort_t minSector, UShort_t maxSector,
- UShort_t minStrip, UShort_t maxStrip,
- Float_t minEta, Float_t maxEta,
- Float_t meanEta,
- Float_t minPhi, Float_t maxPhi,
- Float_t particles, UShort_t method);
- virtual ~AliFMDMultRegion(){};
-
- UShort_t Detector() const { return fDetector; }
- Char_t Ring() const { return fRing; }
- Float_t Eta() const { return fMeanEta; }
- Float_t Phi() const { return (fMaxPhi + fMinPhi) / 2; }
- UShort_t MinSector() const { return fMinSector; }
- UShort_t MaxSector() const { return fMaxSector; }
- UShort_t MinStrip() const { return fMinStrip; }
- UShort_t MaxStrip() const { return fMaxStrip; }
- Float_t MinEta() const { return fMinEta; }
- Float_t MaxEta() const { return fMaxEta; }
- Float_t MinPhi() const { return fMinPhi; }
- Float_t MaxPhi() const { return fMaxPhi; }
- virtual void Print(Option_t* opt="EP") const;
-protected:
- UShort_t fDetector; // Detector #
- Char_t fRing; // Ring ID
- UShort_t fMinSector; // !First sector of this region
- UShort_t fMaxSector; // !Last sector of this region
- UShort_t fMinStrip; // !First strip of this region
- UShort_t fMaxStrip; // !Second strip of this region
- Float_t fMinEta; // Least eta covered
- Float_t fMaxEta; // Largest eta covered
- Float_t fMeanEta; // Scaled average Eta in the region
- Float_t fMinPhi; // Least phi covered
- Float_t fMaxPhi; // Largest phi covered
-
- ClassDef(AliFMDMultRegion,2) // Rec. Multiplicity in a eta,phi region
-};
-#endif
-//____________________________________________________________________
-//
-// Local Variables:
-// mode: C++
-// End:
-//
-// EOF
-//
return fEdepMip;
}
+//__________________________________________________________________
+Bool_t
+AliFMDParameters::Hardware2Detector(UInt_t ddl, UInt_t addr, UShort_t& det,
+ Char_t& ring, UShort_t& sec,
+ UShort_t& str) const
+{
+ // Translate a hardware address to detector coordinates.
+ // The detector is simply
+ //
+ // ddl - kBaseDDL + 1
+ //
+ // The ring number, sector, and strip number is given by the addr
+ // argument. The address argument, has the following format
+ //
+ // 12 7 4 0
+ // +-------------+----------+----------+
+ // | Board | ALTRO | Channel |
+ // +-------------+----------+----------+
+ //
+ // The board number identifier among other things the ring. There's
+ // up to 4 boards per DDL, and the two first (0 and 1) corresponds
+ // to the inner rings, while the two last (2 and 3) corresponds to
+ // the outer rings.
+ //
+ // The board number and ALTRO number together identifies the sensor,
+ // and hence. The lower board number (0 or 2) are the first N / 2
+ // sensors (where N is the number of sensors in the ring).
+ //
+ // There are 3 ALTRO's per card, and each ALTRO serves up to 4
+ // sensors. Which of sensor is determined by the channel number.
+ // For the inner rings, the map is
+ //
+ // ALTRO 0, Channel 0 to 7 -> Sensor 0 or 5
+ // ALTRO 0, Channel 8 to 15 -> Sensor 1 or 6
+ // ALTRO 1, Channel 0 to 7 -> Sensor 2 or 7
+ // ALTRO 2, Channel 0 to 7 -> Sensor 3 or 8
+ // ALTRO 2, Channel 8 to 15 -> Sensor 4 or 9
+ //
+ // For the outer rings, the map is
+ //
+ // ALTRO 0, Channel 0 to 3 -> Sensor 0 or 10
+ // ALTRO 0, Channel 4 to 7 -> Sensor 1 or 11
+ // ALTRO 0, Channel 8 to 11 -> Sensor 2 or 12
+ // ALTRO 0, Channel 12 to 15 -> Sensor 3 or 13
+ // ALTRO 1, Channel 0 to 3 -> Sensor 4 or 14
+ // ALTRO 1, Channel 4 to 7 -> Sensor 5 or 15
+ // ALTRO 2, Channel 0 to 3 -> Sensor 6 or 16
+ // ALTRO 2, Channel 4 to 7 -> Sensor 7 or 17
+ // ALTRO 2, Channel 8 to 11 -> Sensor 8 or 18
+ // ALTRO 2, Channel 12 to 15 -> Sensor 9 or 19
+ //
+ // Which divison of the sensor we're in, depends on the channel
+ // number only. For the inner rings, the map is
+ //
+ // Channel 0 -> Sector 0, strips 0-127
+ // Channel 1 -> Sector 1, strips 0-127
+ // Channel 3 -> Sector 0, strips 128-255
+ // Channel 4 -> Sector 1, strips 128-255
+ // Channel 5 -> Sector 0, strips 256-383
+ // Channel 6 -> Sector 1, strips 256-383
+ // Channel 7 -> Sector 0, strips 384-511
+ // Channel 8 -> Sector 1, strips 384-511
+ //
+ // There are only half as many strips in the outer sensors, so there
+ // only 4 channels are used for a full sensor. The map is
+ //
+ // Channel 0 -> Sector 0, strips 0-127
+ // Channel 1 -> Sector 1, strips 0-127
+ // Channel 3 -> Sector 0, strips 128-255
+ // Channel 4 -> Sector 1, strips 128-255
+ //
+ // With this information, we can decode the hardware address to give
+ // us detector coordinates, unique at least up a 128 strips. We
+ // return the first strip in the given range.
+ //
+ det = (ddl - kBaseDDL) + 1;
+ UInt_t board = (addr >> 7) & 0x1F;
+ UInt_t altro = (addr >> 4) & 0x7;
+ UInt_t chan = (addr & 0xf);
+ if (board > 3) {
+ AliError(Form("Invalid board address %d for the FMD", board));
+ return kFALSE;
+ }
+ if (altro > 2) {
+ AliError(Form("Invalid ALTRO address %d for the FMD digitizer %d",
+ altro, board));
+ return kFALSE;
+ }
+ ring = (board > 1 ? 'O' : 'I');
+ UInt_t nsen = (ring == 'I' ? 10 : 20);
+ UInt_t nsa = (ring == 'I' ? 2 : 4); // Sensors per ALTRO
+ UInt_t ncs = (ring == 'I' ? 8 : 4); // Channels per sensor
+ UInt_t sen = (board % 2) * nsen / 2; // Base for half-ring
+ sen += chan / ncs + (altro == 0 ? 0 :
+ altro == 1 ? nsa : UInt_t(1.5 * nsa));
+ sec = 2 * sen + (chan % 2);
+ str = (chan % ncs) / 2 * 128;
+ return kTRUE;
+}
+
+//__________________________________________________________________
+Bool_t
+AliFMDParameters::Detector2Hardware(UShort_t det, Char_t ring, UShort_t sec,
+ UShort_t str, UInt_t& ddl, UInt_t& addr)
+ const
+{
+ // Translate detector coordinates to a hardware address.
+ // The ddl is simply
+ //
+ // kBaseDDL + (det - 1)
+ //
+ // The ring number, sector, and strip number must be encoded into a
+ // hardware address. The address argument, will have the following
+ // format on output
+ //
+ // 12 7 4 0
+ // +-------------+----------+----------+
+ // | Board | ALTRO | Channel |
+ // +-------------+----------+----------+
+ //
+ // The board number is given by the ring and sector. The inner
+ // rings board 0 and 1, while the outer are 2 and 3. Which of these
+ // depends on the sector. The map is
+ //
+ // Ring I, sector 0- 9 -> board 0
+ // Ring I, sector 10-19 -> board 1
+ // Ring O, sector 0-19 -> board 2
+ // Ring O, sector 20-39 -> board 3
+ //
+ // There are 3 ALTRO's per board. The ALTRO number is given by the
+ // sector number. For the inner rings, these are given by
+ //
+ // Sector 0- 3 or 10-13 -> ALTRO 0
+ // Sector 4- 5 or 14-15 -> ALTRO 1
+ // Sector 6- 9 or 16-19 -> ALTRO 2
+ //
+ // For the outers, it's given by
+ //
+ // Sector 0- 7 or 20-27 -> ALTRO 0
+ // Sector 8-11 or 28-31 -> ALTRO 1
+ // Sector 12-19 or 32-39 -> ALTRO 2
+ //
+ // The channel number is given by the sector and strip number. For
+ // the inners, the map is
+ //
+ // Sector 0, strips 0-127 -> Channel 0
+ // Sector 0, strips 128-255 -> Channel 2
+ // Sector 0, strips 256-383 -> Channel 4
+ // Sector 0, strips 384-511 -> Channel 6
+ // Sector 1, strips 0-127 -> Channel 1
+ // Sector 1, strips 128-255 -> Channel 3
+ // Sector 1, strips 256-383 -> Channel 5
+ // Sector 1, strips 384-511 -> Channel 7
+ // Sector 2, strips 0-127 -> Channel 8
+ // Sector 2, strips 128-255 -> Channel 10
+ // Sector 2, strips 256-383 -> Channel 12
+ // Sector 2, strips 384-511 -> Channel 14
+ // Sector 3, strips 0-127 -> Channel 9
+ // Sector 3, strips 128-255 -> Channel 11
+ // Sector 3, strips 256-383 -> Channel 13
+ // Sector 3, strips 384-511 -> Channel 15
+ //
+ // and so on, up to sector 19. For the outer, the map is
+ //
+ // Sector 0, strips 0-127 -> Channel 0
+ // Sector 0, strips 128-255 -> Channel 2
+ // Sector 1, strips 0-127 -> Channel 1
+ // Sector 1, strips 128-255 -> Channel 3
+ // Sector 2, strips 0-127 -> Channel 4
+ // Sector 2, strips 128-255 -> Channel 6
+ // Sector 3, strips 0-127 -> Channel 5
+ // Sector 3, strips 128-255 -> Channel 7
+ // Sector 4, strips 0-127 -> Channel 8
+ // Sector 4, strips 128-255 -> Channel 10
+ // Sector 5, strips 0-127 -> Channel 9
+ // Sector 5, strips 128-255 -> Channel 11
+ // Sector 6, strips 0-127 -> Channel 12
+ // Sector 6, strips 128-255 -> Channel 14
+ // Sector 7, strips 0-127 -> Channel 13
+ // Sector 7, strips 128-255 -> Channel 15
+ //
+ // and so on upto sector 40.
+ //
+ // With this information, we can decode the detector coordinates to
+ // give us a unique hardware address
+ //
+ ddl = kBaseDDL + (det - 1);
+ UInt_t nsen = (ring == 'I' ? 10 : 20);
+ UInt_t nsa = (ring == 'I' ? 2 : 4); // Sensors per ALTRO
+ UInt_t ncs = (ring == 'I' ? 8 : 4); // Channels per sensor
+ UInt_t bbase = (ring == 'I' ? 0 : 2);
+ UInt_t board = bbase + sec / nsen;
+ UInt_t lsen = (sec - (board - bbase) * nsen);
+ UInt_t altro = (lsen < 2 * nsa ? 0 : (lsen < 3 * nsa ? 1 : 2));
+ UInt_t sbase = (lsen < 2 * nsa ? 0 : (lsen < 3 * nsa ? 2*nsa : 3*nsa));
+ UInt_t chan = (sec % 2) + (lsen-sbase) / 2 * ncs + 2 * str / 128;
+ AliDebug(40, Form("\n"
+ " chan = (%d %% 2) + (%d-%d) / %d * %d + 2 * %d / 128\n"
+ " = %d + %d + %d = %d",
+ sec, lsen, sbase, 2, ncs, str,
+ (sec % 2), (lsen - sbase) / 2 * ncs,
+ 2 * str / 128, chan));
+ addr = chan + (altro << 4) + (board << 7);
+
+ return kTRUE;
+}
+
+
+
+
//____________________________________________________________________
//
// EOF
UShort_t strip) const;
UShort_t GetSampleRate(UShort_t ddl) const;
+ Bool_t Hardware2Detector(UInt_t ddl, UInt_t addr, UShort_t& det,
+ Char_t& ring, UShort_t& sec, UShort_t& str) const;
+ Bool_t Detector2Hardware(UShort_t det, Char_t ring, UShort_t sec,
+ UShort_t str, UInt_t& ddl, UInt_t& addr) const;
enum {
kBaseDDL = 0x1000 // DDL offset for the FMD
};
//____________________________________________________________________
//
-// FMD reconstructed multiplicity in a strip. It contains the
-// information of which strip in what sector of what ring, in which
-// detector the information belongs, as well as the pseudo-rapidity,
-// and azimuthal angle the strip had in the event. Note, that this
-// may change when the interaction points z--coordinate changes
-// (which it probably will - experience from RHIC says so). Also,
-// the reconstructed energy deposited is stored.
+// Base class for reconstructed charged particle multiplicty in the
+// FMD.
+// The class contains the field fMethod which is a flag set by
+// the AliFMDRecPointAlgorithm that created the object. The flag tells us
+// which algorithm was used to create the data stored in the object.
//
-//
-#include "AliFMDMultStrip.h" // ALIFMDMULTSTRIP_H
-#include <TString.h> // ROOT_TString
+#include "AliFMDRecPoint.h" // ALIFMDRECPOINT_H
+#include <TString.h> // ROOT_TString
#include <Riostream.h> // ROOT_Riostream
//____________________________________________________________________
-ClassImp(AliFMDMultStrip)
+ClassImp(AliFMDRecPoint)
#if 0
; // This is here to keep Emacs for indenting the next line
#endif
-
//____________________________________________________________________
-AliFMDMultStrip::AliFMDMultStrip()
+AliFMDRecPoint::AliFMDRecPoint()
: fDetector(0),
fRing('\0'),
fSector(0),
{}
//____________________________________________________________________
-AliFMDMultStrip::AliFMDMultStrip(UShort_t detector, Char_t ring,
- UShort_t sector, UShort_t strip,
- Float_t eta, Float_t phi,
- Float_t edep, Float_t particles,
- UShort_t method)
- : AliFMDMult(particles, method),
- fDetector(detector),
+AliFMDRecPoint::AliFMDRecPoint(UShort_t detector, Char_t ring,
+ UShort_t sector, UShort_t strip,
+ Float_t eta, Float_t phi,
+ Float_t edep, Float_t particles)
+ : fDetector(detector),
fRing(ring),
fSector(sector),
fStrip(strip),
fEta(eta),
fPhi(phi),
- fEdep(edep)
-{}
+ fEdep(edep),
+ fParticles(particles)
+{
+}
+//____________________________________________________________________
+const char*
+AliFMDRecPoint::GetName() const
+{
+ static TString n;
+ n = Form("FMD%d%c[%2d,%3d]", fDetector,fRing,fSector,fStrip);
+ return n.Data();
+}
+
+//____________________________________________________________________
+const char*
+AliFMDRecPoint::GetTitle() const
+{
+ static TString t;
+ t = Form("%f (%f,%f)", fParticles, fEta, fPhi);
+ return t.Data();
+}
//____________________________________________________________________
void
-AliFMDMultStrip::Print(Option_t* option) const
+AliFMDRecPoint::Print(Option_t* option) const
{
// Print information
//
// P: Phi range (default)
//
TString opt(option);
- cout << "FMD Multiplicity in a strip: " << fParticles << endl;
+ cout << "FMD RecPoint in a strip: " << fParticles << endl;
if (opt.Contains("D", TString::kIgnoreCase))
cout << " Detector: FMD" << fDetector << fRing
<< "[" << fSector << "," << fStrip << "]" << endl;
cout << " Eta range: " << fEta << endl;
if (opt.Contains("P", TString::kIgnoreCase))
cout << " Phi range: " << fPhi << endl;
- AliFMDMult::Print(option);
}
-#ifndef ALIFMDMULTSTRIP_H
-#define ALIFMDMULTSTRIP_H
+#ifndef ALIFMDRECPOINT_H
+#define ALIFMDRECPOINT_H
// Reconstracted Particles Class: has number of reconstructed
// particles in sectors from NumOfMinSector to NumberOfMaxSector()
-// rings from NumOfMinRing to NumOfMaxRing for each FMDvolume
+// rings from NumOfMinRing to NumOfMaxRing for each FMDvolume
//
-#ifndef ALIFMDMULT_H
-# include "AliFMDMult.h"
+#ifndef ROOT_TObject
+# include <TObject.h>
#endif
-class AliFMDMultStrip: public AliFMDMult
+class AliFMDRecPoint: public TObject
{
public:
- AliFMDMultStrip();
- AliFMDMultStrip (UShort_t detector, Char_t ring,
- UShort_t sector, UShort_t strip,
- Float_t eta, Float_t phi,
- Float_t edep, Float_t particles,
- UShort_t method);
- virtual ~AliFMDMultStrip(){};
+ AliFMDRecPoint();
+ AliFMDRecPoint(UShort_t detector, Char_t ring,
+ UShort_t sector, UShort_t strip,
+ Float_t eta, Float_t phi,
+ Float_t edep, Float_t particles);
+ virtual ~AliFMDRecPoint() {};
UShort_t Detector() const { return fDetector; }
Char_t Ring() const { return fRing; }
Float_t Eta() const { return fEta; }
Float_t Phi() const { return fPhi; }
Float_t Edep() const { return fEdep; }
+ Float_t Particles() const { return fParticles; }
virtual void Print(Option_t* opt="D") const;
+ const char* GetName() const;
+ const char* GetTitle() const;
protected:
UShort_t fDetector; // Detector #
Char_t fRing; // Ring ID
Float_t fEta; // Eta value
Float_t fPhi; // Phi value
Float_t fEdep; // Energy deposited
+ Float_t fParticles; // Quasi-number of particles
- ClassDef(AliFMDMultStrip,1) // Rec. Multiplicity in a strip
+ ClassDef(AliFMDRecPoint,1) // Base class for multiplicity data
};
#endif
//____________________________________________________________________
#include "AliFMDReconstructor.h" // ALIFMDRECONSTRUCTOR_H
#include "AliFMDRawStream.h" // ALIFMDRAWSTREAM_H
#include "AliFMDRawReader.h" // ALIFMDRAWREADER_H
-#include "AliFMDMultStrip.h" // ALIFMDMULTNAIIVE_H
+#include "AliFMDRecPoint.h" // ALIFMDMULTNAIIVE_H
#include "AliESD.h" // ALIESD_H
#include <AliESDFMD.h> // ALIESDFMD_H
#include <TFile.h>
{
// Initialize the reconstructor
AliDebug(1, Form("Init called with runloader 0x%x", runLoader));
+ // Initialize the geometry
+ AliFMDGeometry* fmd = AliFMDGeometry::Instance();
+ fmd->Init();
+ fmd->InitTransformations();
+
// Current vertex position
fCurrentVertex = 0;
// Create array of reconstructed strip multiplicities
- fMult = new TClonesArray("AliFMDMultStrip", 51200);
+ fMult = new TClonesArray("AliFMDRecPoint", 51200);
// Create ESD output object
fESDObj = new AliESDFMD;
digit->Strip(), digit->Counts(), counts, edep, mult));
// Create a `RecPoint' on the output branch.
- AliFMDMultStrip* m =
- new ((*fMult)[fNMult]) AliFMDMultStrip(digit->Detector(),
- digit->Ring(),
- digit->Sector(),
- digit->Strip(),
- eta, phi,
- edep, mult,
- AliFMDMult::kNaiive);
+ AliFMDRecPoint* m =
+ new ((*fMult)[fNMult]) AliFMDRecPoint(digit->Detector(),
+ digit->Ring(),
+ digit->Sector(),
+ digit->Strip(),
+ eta, phi,
+ edep, mult);
(void)m; // Suppress warnings about unused variables.
fNMult++;
//
// Get geometry.
AliFMDGeometry* fmd = AliFMDGeometry::Instance();
+#if 0
AliFMDDetector* subDetector = fmd->GetDetector(digit->Detector());
if (!subDetector) {
Warning("ProcessDigits", "Unknown detector: FMD%d" , digit->Detector());
digit->Ring());
return;
}
-
- // Correct for vertex offset.
Float_t realZ = fCurrentVertex + ringZ;
Float_t stripR = ((ring->GetHighR() - ring->GetLowR())
/ ring->GetNStrips() * (digit->Strip() + .5)
+ ring->GetLowR());
Float_t theta = TMath::ATan2(stripR, realZ);
- phi = (2 * TMath::Pi() / ring->GetNSectors()
- * (digit->Sector() + .5));
- eta = -TMath::Log(TMath::Tan(theta / 2));
+#endif
+ Double_t x, y, z, r, theta;
+ fmd->Detector2XYZ(digit->Detector(), digit->Ring(), digit->Sector(),
+ digit->Strip(), x, y, z);
+ // Correct for vertex offset.
+ z += fCurrentVertex;
+ phi = TMath::ATan2(y, x);
+ r = TMath::Sqrt(y * y + x * x);
+ theta = TMath::ATan2(r, z);
+ eta = -TMath::Log(TMath::Tan(theta / 2));
}
return static_cast<TVector2*>(fVerticies.At(i));
}
+//____________________________________________________________________
+Double_t
+AliFMDRing::GetStripRadius(UShort_t strip) const
+{
+ // Return the nominal strip radius
+ Double_t rmax = GetMaxR();
+ Double_t stripoff = GetMinR();
+ Double_t dstrip = (rmax - stripoff) / GetNStrips();
+ return (strip + .5) * dstrip + stripoff; // fLowR
+}
+
//____________________________________________________________________
void
AliFMDRing::Detector2XYZ(UShort_t sector,
Double_t GetSpacing() const { return fSpacing; }
/** @return The strip pitch */
Double_t GetPitch() const { return (fMaxR - fMinR) / fNStrips; }
-
+ /** @return Radius (in cm) correspondig to strip @a strip */
+ Double_t GetStripRadius(UShort_t strip) const;
+
/** @return List of verticies */
const TObjArray& GetVerticies() const { return fVerticies; }
/** @return Number of verticies */
+++ /dev/null
-/**************************************************************************
- * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
- * *
- * Author: The ALICE Off-line Project. *
- * Contributors are mentioned in the code where appropriate. *
- * *
- * Permission to use, copy, modify and distribute this software and its *
- * documentation strictly for non-commercial purposes is hereby granted *
- * without fee, provided that the above copyright notice appears in all *
- * copies and that both the copyright notice and this permission notice *
- * appear in the supporting documentation. The authors make no claims *
- * about the suitability of this software for any purpose. It is *
- * provided "as is" without express or implied warranty. *
- **************************************************************************/
-
-/* $Id$ */
-
-//____________________________________________________________________
-//
-// 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.
-//
-// 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 simulation
-//
-// +--------+ 1 +-----------------+
-// | AliFMD |<>-----| AliFMDSimulator |
-// +--------+ +-----------------+
-// ^
-// |
-// +-------------+-------------+
-// | |
-// +--------------------+ +-------------------+
-// | AliFMDGeoSimulator | | AliFMDG3Simulator |
-// +--------------------+ +-------------------+
-// ^
-// |
-// +----------------------+
-// | AliFMDG3OldSimulator |
-// +----------------------+
-//
-// * AliFMD
-// This defines the interface for the various parts of AliROOT that
-// uses the FMD, like AliFMDSimulator, AliFMDDigitizer,
-// AliFMDReconstructor, and so on.
-//
-// * AliFMDSimulator
-// This is the base class for the FMD simulation tasks. The
-// 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. This defines the active
-// volume as an ONLY XTRU shape with a divided MANY TUBS shape
-// inside to implement the particular shape of the silicon
-// sensors.
-//
-// * AliFMDG3Simulator
-// This is a concrete implementation of the AliFMDSimulator that
-// uses the TVirtualMC interface with GEANT 3.21-like messages.
-// This implements the active volume as a divided TUBS shape. Hits
-// in the corners should be cut away at run time (but currently
-// isn't).
-//
-// * AliFMDG3OldSimulator
-// This is a concrete implementation of AliFMDSimulator. It
-// approximates the of the rings as segmented disks.
-//
-#include "AliFMDSimulator.h" // ALIFMDSIMULATOR_H
-#include "AliFMDGeometry.h" // ALIFMDGEOMETRY_H
-#include "AliFMDDetector.h" // ALIFMDDETECTOR_H
-#include "AliFMDRing.h" // ALIFMDRING_H
-#include "AliFMD1.h" // ALIFMD1_H
-#include "AliFMD2.h" // ALIFMD2_H
-#include "AliFMD3.h" // ALIFMD3_H
-#include "AliFMD.h" // ALIFMD_H
-#include "AliFMDHit.h" // ALIFMDHIT_H
-#include <AliRun.h> // ALIRUN_H
-#include <AliMC.h> // ALIMC_H
-#include <AliMagF.h> // ALIMAGF_H
-#include <AliLog.h> // ALILOG_H
-#include <TGeoVolume.h> // ROOT_TGeoVolume
-#include <TGeoTube.h> // ROOT_TGeoTube
-#include <TGeoPcon.h> // ROOT_TGeoPcon
-#include <TGeoMaterial.h> // ROOT_TGeoMaterial
-#include <TGeoMedium.h> // ROOT_TGeoMedium
-#include <TGeoXtru.h> // ROOT_TGeoXtru
-#include <TGeoPolygon.h> // ROOT_TGeoPolygon
-#include <TGeoTube.h> // ROOT_TGeoTube
-#include <TGeoManager.h> // ROOT_TGeoManager
-#include <TTree.h> // ROOT_TTree
-#include <TParticle.h> // ROOT_TParticle
-#include <TLorentzVector.h> // ROOT_TLorentzVector
-#include <TVector2.h> // ROOT_TVector2
-#include <TVector3.h> // ROOT_TVector3
-#include <TVirtualMC.h> // ROOT_TVirtualMC
-#include <TArrayD.h> // ROOT_TArrayD
-
-
-//====================================================================
-ClassImp(AliFMDSimulator)
-#if 0
- ; // This is here to keep Emacs for indenting the next line
-#endif
-
-//____________________________________________________________________
-const Char_t* AliFMDSimulator::fgkActiveName = "F%cAC";
-const Char_t* AliFMDSimulator::fgkSectorName = "F%cSE";
-const Char_t* AliFMDSimulator::fgkStripName = "F%cST";
-const Char_t* AliFMDSimulator::fgkModuleName = "F%cMO";
-const Char_t* AliFMDSimulator::fgkPCBName = "F%cP%c";
-const Char_t* AliFMDSimulator::fgkLongLegName = "F%cLL";
-const Char_t* AliFMDSimulator::fgkShortLegName = "F%cSL";
-const Char_t* AliFMDSimulator::fgkFrontVName = "F%cFV";
-const Char_t* AliFMDSimulator::fgkBackVName = "F%cBV";
-const Char_t* AliFMDSimulator::fgkRingName = "FMD%c";
-const Char_t* AliFMDSimulator::fgkTopHCName = "F%d%cI";
-const Char_t* AliFMDSimulator::fgkBotHCName = "F%d%cJ";
-const Char_t* AliFMDSimulator::fgkTopIHCName = "F%d%cK";
-const Char_t* AliFMDSimulator::fgkBotIHCName = "F%d%cL";
-const Char_t* AliFMDSimulator::fgkNoseName = "F3SN";
-const Char_t* AliFMDSimulator::fgkBackName = "F3SB";
-const Char_t* AliFMDSimulator::fgkBeamName = "F3SL";
-const Char_t* AliFMDSimulator::fgkFlangeName = "F3SF";
-
-//____________________________________________________________________
-AliFMDSimulator::AliFMDSimulator()
- : fFMD(0),
- fActiveId(4),
- fDetailed(kFALSE),
- fUseDivided(kFALSE),
- fUseAssembly(kTRUE),
- fBad(0)
-{
- // Default constructor
-}
-
-//____________________________________________________________________
-AliFMDSimulator::AliFMDSimulator(AliFMD* fmd, Bool_t detailed)
- : TTask("FMDSimulator", "Forward Multiplicity Detector Simulator"),
- fFMD(fmd),
- fActiveId(4),
- fDetailed(detailed),
- fUseDivided(kFALSE),
- fUseAssembly(kTRUE),
- fBad(0)
-{
- // Normal constructor
- //
- // Parameters:
- //
- // fmd Pointer to AliFMD object
- // detailed Whether to make a detailed simulation or not
- //
- fBad = new TClonesArray("AliFMDHit");
-}
-
-
-//____________________________________________________________________
-void
-AliFMDSimulator::DefineMaterials()
-{
- // 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
- //
- // 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)
- //
- // Pointers to TGeoMedium objects are retrived from the TGeoManager
- // singleton. These pointers are later used when setting up the
- // geometry
- AliDebug(10, "\tCreating materials");
- AliDebug(1, Form("\tGeometry options: %s, %s, %s",
- (fDetailed ? "detailed" : "coarse"),
- (fUseDivided ? "divided into strips" : "one volume"),
- (fUseAssembly ? "within assemblies" : "in real volumes")));
- // Get pointer to geometry singleton object.
- AliFMDGeometry* geometry = AliFMDGeometry::Instance();
- geometry->Init();
-
- 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.
- 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;
- fFMD->AliMaterial(id, "Si$",
- a, z, density, radiationLength, absorbtionLength);
- fFMD->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;
- fFMD->AliMaterial(id, "Carbon$",
- a, z, density, radiationLength, absorbtionLength);
- fFMD->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;
- fFMD->AliMaterial(id, "Aluminum$",
- a, z, density, radiationLength, absorbtionLength);
- fFMD->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;
- fFMD->AliMaterial(id, "Copper$",
- a, z, density, radiationLength, absorbtionLength);
- fFMD->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;
- fFMD->AliMixture(id, "Si Chip$", as, zs, density, 6, ws);
- fFMD->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;
- fFMD->AliMixture(id, "Kaption$", as, zs, density, 4, ws);
- fFMD->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;
- fFMD->AliMixture(id, "Air$", as, zs, density, 4, ws);
- fFMD->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;
- fFMD->AliMixture(id, "PCB$", as, zs, density, 14, ws);
- fFMD->AliMedium(kPcbId, "PCB$",
- 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;
- fFMD->AliMixture(id, "Plastic$", as, zs, density, -2, ws);
- fFMD->AliMedium(kPlasticId, "Plastic$",
- id,0,fieldType,maxField,maxBending,
- maxStepSize,maxEnergyLoss,precision,minStepSize);
- }
-}
-
-//____________________________________________________________________
-Bool_t
-AliFMDSimulator::IsActive(Int_t volId) const
-{
- for (Int_t i = 0; i < fActiveId.fN; i++)
- if (volId == fActiveId[i]) return kTRUE;
- return kFALSE;
-}
-
-//____________________________________________________________________
-Bool_t
-AliFMDSimulator::VMC2FMD(TLorentzVector& v, UShort_t& detector,
- Char_t& ring, UShort_t& sector, UShort_t& strip)
-{
- TVirtualMC* mc = TVirtualMC::GetMC();
-
- // Get track position
- mc->TrackPosition(v);
- Int_t moduleno; mc->CurrentVolOffID(fModuleOff, moduleno);
- Int_t iring; mc->CurrentVolOffID(fRingOff, iring); ring = Char_t(iring);
- Int_t det; mc->CurrentVolOffID(fDetectorOff, det); detector = det;
-
-
- // Get the ring geometry
- AliFMDGeometry* fmd = AliFMDGeometry::Instance();
- //Int_t nsec = fmd->GetDetector(detector)->GetRing(ring)->GetNSectors();
- Int_t nstr = fmd->GetDetector(detector)->GetRing(ring)->GetNStrips();
- Double_t lowr = fmd->GetDetector(detector)->GetRing(ring)->GetLowR();
- Double_t highr= fmd->GetDetector(detector)-&