25 #include "AliCodeTimer.h"
27 #include "TGeoManager.h"
28 #include "TGeoVolume.h"
29 #include "TGeoMatrix.h"
30 #include "TVirtualMC.h"
31 #include "TClonesArray.h"
32 #include "TGeoGlobalMagField.h"
34 #include "AliLoader.h"
35 #include "AliDetector.h"
42 #include "AliTrackReference.h"
48 #include "TObjArray.h"
61 fRecPointsPerPlane(0),
65 fChargeDispersion(25.e-4),
66 fSingleStepForChargeDispersion(0),
67 fNStepForChargeDispersion(4),
68 fDensitySupportOverSi(0.036),
69 fFileNameForUnderyingEvent(0),
70 fFileNameForPileUpEvents(0),
72 fUnderlyingEventID(-1)
85 AliDetector(name, title),
90 fRecPointsPerPlane(0),
94 fChargeDispersion(25.e-4),
95 fSingleStepForChargeDispersion(0),
96 fNStepForChargeDispersion(4),
97 fDensitySupportOverSi(0.036),
98 fFileNameForUnderyingEvent(0),
99 fFileNameForPileUpEvents(0),
101 fUnderlyingEventID(-1)
117 AliDetector(name, title),
122 fRecPointsPerPlane(0),
126 fChargeDispersion(25.e-4),
127 fSingleStepForChargeDispersion(0),
128 fNStepForChargeDispersion(4),
129 fDensitySupportOverSi(0.036),
130 fFileNameForUnderyingEvent(0),
131 fFileNameForPileUpEvents(0),
133 fUnderlyingEventID(-1)
165 AliDebug(1,
"Start MFT materials");
169 Float_t aSi = 28.085 , zSi = 14. , dSi = 2.329 , radSi = 21.82/dSi , absSi = 108.4/dSi ;
170 Float_t aCarb = 12.01 , zCarb = 6. , dCarb = 2.265 , radCarb = 18.8 , absCarb = 49.9 ;
171 Float_t aAlu = 26.98 , zAlu = 13. , dAlu = 2.70 , radAlu = 8.897 , absAlu = 39.70 ;
172 Float_t aBe = 9.012182 , zBe = 4. , dBe = 1.85 , radBe = 65.19/dBe , absBe = 77.8/dBe ;
173 Float_t aCu = 63.546 , zCu = 29. , dCu = 8.96 , radCu = 1.436 , absCu = 15.32 ;
176 const Int_t nAir = 4;
177 Float_t aAir[nAir] = {12, 14, 16, 36} , zAir[nAir] = {6, 7, 8, 18} , wAir[nAir]={0.000124, 0.755267, 0.231781, 0.012827} , dAir=0.00120479, dAirVacuum=0.00120479e-4;
180 const Int_t nWater = 2;
181 Float_t aWater[nWater] = {1.00794, 15.9994} , zWater[nWater] = {1, 8} , wWater[nWater] = {0.111894, 0.888106} , dWater=1.;
184 const Int_t nSiO2 = 2;
185 Float_t aSiO2[nSiO2] = {15.9994, 28.0855} , zSiO2[nSiO2] = {8., 14.} , wSiO2[nSiO2] = {0.532565, 0.467435} , dSiO2 = 2.20;
188 const Int_t nInox = 9;
189 Float_t aInox[nInox] = {12.0107, 54.9380, 28.0855, 30.9738, 32.0660, 58.6928, 51.9961, 95.9400, 55.8450} ;
190 Float_t zInox[nInox] = { 6, 25, 14, 15, 16, 28, 24, 42, 26 } ;
191 Float_t wInox[nInox] = {0.0003, 0.02, 0.01, 0.00045, 0.0003, 0.12, 0.17, 0.025, 0.65395} ;
192 Float_t dInox = 8.03;
195 Float_t aKapton[4]={1.00794,12.0107, 14.010,15.9994};
196 Float_t zKapton[4]={1.,6.,7.,8.};
197 Float_t wKapton[4]={0.026362,0.69113,0.07327,0.209235};
198 Float_t dKapton = 1.42;
201 Float_t aEpoxy[3] = {15.9994, 1.00794, 12.0107} ;
202 Float_t zEpoxy[3] = { 8., 1., 6.} ;
203 Float_t wEpoxy[3] = { 3., 19., 18.} ;
204 Float_t dEpoxy = 1.8 ;
207 Float_t aCM55J[4]={12.0107,14.0067,15.9994,1.00794};
208 Float_t zCM55J[4]={6.,7.,8.,1.};
209 Float_t wCM55J[4]={0.908508078,0.010387573,0.055957585,0.025146765};
210 Float_t dCM55J = 1.8;
213 const Int_t nRohacell = 3;
214 Float_t aRohacell[nRohacell] = {1.00794, 12.0107, 15.9994};
215 Float_t zRohacell[nRohacell] = {1., 6., 8.};
216 Float_t wRohacell[nRohacell] = {0.0858, 0.5964, 0.3178};
217 Float_t dRohacell = 0.075;
220 const Int_t nPolyimide = 4;
221 Float_t aPolyimide[nPolyimide] = {1.00794, 12.0107, 14.0067, 15.9994};
222 Float_t zPolyimide[nPolyimide] = {1, 6, 7, 8};
223 Float_t wPolyimide[nPolyimide] = {0.00942, 0.56089, 0.13082, 0.29887};
224 Float_t dPolyimide = 1.4;
227 const Int_t nPEEK = 3;
228 Float_t aPEEK[nPEEK] = {1.00794, 12.0107, 15.9994} ;
229 Float_t zPEEK[nPEEK] = {1, 6, 8} ;
230 Float_t wPEEK[nPEEK] = {0.06713, 0.40001, 0.53285} ;
231 Float_t dPEEK = 1.32;
234 const Int_t nFR4 = 5;
235 Float_t aFR4[nFR4] = {1.00794, 12.0107, 15.9994, 28.0855, 79.904} ;
236 Float_t zFR4[nFR4] = {1, 6, 8, 14, 35} ;
237 Float_t wFR4[nFR4] = {0.0684428, 0.278042,0.405633, 0.180774, 0.0671091} ;
242 Int_t unsens = 0, sens=1;
246 Float_t tmaxfd = -10.0;
247 Float_t stemax = 0.001;
248 Float_t deemax = -0.2;
249 Float_t epsil = 0.001;
250 Float_t stmin = -0.001;
252 Float_t tmaxfdSi = 0.1;
253 Float_t stemaxSi = 5.0e-4;
254 Float_t deemaxSi = 0.1;
255 Float_t epsilSi = 0.5e-4;
256 Float_t stminSi = -0.001;
258 Int_t fieldType = ((AliMagF*)TGeoGlobalMagField::Instance()->GetField())->Integ();
259 Double_t maxField = ((AliMagF*)TGeoGlobalMagField::Instance()->GetField())->Max();
261 AliMixture(
kAir,
"Air$", aAir, zAir, dAir, nAir, wAir);
262 AliMedium(
kAir,
"Air$",
kAir, unsens, fieldType, maxField, tmaxfd, stemax, deemax, epsil, stmin);
265 AliMixture(
kVacuum,
"Vacuum$", aAir, zAir, dAirVacuum, nAir, wAir);
266 AliMedium(
kVacuum,
"Vacuum$",
kVacuum, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);
268 AliMaterial(++matId,
"Si$", aSi, zSi, dSi, radSi, absSi);
269 AliMedium(
kSi,
"Si$", matId, sens, fieldType, maxField, tmaxfdSi, stemaxSi, deemaxSi, epsilSi, stminSi);
271 AliMaterial(++matId,
"Readout$", aSi, zSi, dSi, radSi, absSi);
272 AliMedium(
kReadout,
"Readout$", matId, unsens, fieldType, maxField, tmaxfdSi, stemaxSi, deemaxSi, epsilSi, stminSi);
274 AliMaterial(++matId,
"Support$", aSi, zSi, dSi*
fDensitySupportOverSi, radSi/fDensitySupportOverSi, absSi/fDensitySupportOverSi);
275 AliMedium(
kSupport,
"Support$", matId, unsens, fieldType, maxField, tmaxfdSi, stemaxSi, deemaxSi, epsilSi, stminSi);
277 Double_t maxBending = 0;
278 Double_t maxStepSize = 0.001;
279 Double_t maxEnergyLoss = 1;
280 Double_t precision = 0.001;
281 Double_t minStepSize = 0.001;
292 AliMaterial(matId,
"Carbon$", aCarb, zCarb, dCarb, radCarb, absCarb);
293 AliMedium(
kCarbon,
"Carbon$", matId,0,fieldType,maxField,maxBending,
294 maxStepSize,maxEnergyLoss,precision,minStepSize);
299 AliMaterial(++matId,
"Be$", aBe, zBe, dBe, radBe, absBe );
300 AliMedium(
kBe,
"Be$", matId, unsens, fieldType, maxField, tmaxfd, stemax, deemax, epsil, stmin);
302 AliMaterial(++matId,
"Alu$", aAlu, zAlu, dAlu, radAlu, absAlu);
303 AliMedium(
kAlu,
"Alu$", matId, unsens, fieldType, maxField, tmaxfd, stemax, deemax, epsil, stmin);
306 AliMixture(++matId,
"Water$", aWater, zWater, dWater, nWater, wWater);
307 AliMedium(
kWater,
"Water$", matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);
309 AliMixture(++matId,
"SiO2$", aSiO2, zSiO2, dSiO2, nSiO2, wSiO2);
310 AliMedium(
kSiO2,
"SiO2$", matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);
312 AliMixture(++matId,
"Inox$", aInox, zInox, dInox, nInox, wInox);
313 AliMedium(
kInox,
"Inox$", matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);
315 AliMixture(++matId,
"Kapton$", aKapton, zKapton, dKapton, 4, wKapton);
316 AliMedium(
kKapton,
"Kapton$", matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);
318 AliMixture(++matId,
"Epoxy$", aEpoxy, zEpoxy, dEpoxy, -3, wEpoxy);
319 AliMedium(
kEpoxy,
"Epoxy$", matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);
321 AliMixture(++matId,
"C (M55J)$",aCM55J,zCM55J,dCM55J,4,wCM55J);
322 AliMedium(
kCarbonEpoxy,
"CarbonFiber$", matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);
324 AliMixture(++matId,
"Rohacell", aRohacell, zRohacell, dRohacell, nRohacell, wRohacell);
325 AliMedium(
kRohacell,
"Rohacell", matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);
327 AliMixture(++matId,
"Polyimide", aPolyimide, zPolyimide, dPolyimide, nPolyimide, wPolyimide);
328 AliMedium(
kPolyimide,
"Polyimide", matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);
330 AliMixture(++matId,
"PEEK$", aPEEK, zPEEK, dPEEK, nPEEK, wPEEK);
331 AliMedium(
kPEEK,
"PEEK$", matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);
333 AliMixture(++matId,
"FR4$", aFR4, zFR4, dFR4, nFR4, wFR4);
334 AliMedium(
kFR4,
"FR4$", matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);
336 AliMaterial(++matId,
"Cu$", aCu, zCu, dCu, radCu, absCu);
337 AliMedium(
kCu,
"Cu$", matId, unsens, itgfld, maxfld, tmaxfd, stemax, deemax, epsil, stmin);
339 AliDebug(1,
"End MFT materials");
349 if(!TVirtualMC::GetMC()->IsRootGeometrySupported())
return;
367 TString sysName =
"MFT";
368 TString volPath =
"/ALIC_1/MFT_0";
370 if (!gGeoManager->SetAlignableEntry(sysName.Data(),volPath.Data())) {
371 AliFatal(Form(
"Alignable entry %s not created. Volume path %s not valid", sysName.Data(), volPath.Data()));
381 if (!(this->IsActive()))
return;
385 if (!seg) AliFatal(
"No segmentation available");
387 TVirtualMC* mc = TVirtualMC::GetMC();
389 Double_t absQ = TMath::Abs(mc->TrackCharge());
390 if (absQ <= 0)
return;
396 int chipId=-1,ladderId=-1,diskId=-1,halfId=-1,level=0;
397 mc->CurrentVolOffID(++level,chipId);
398 mc->CurrentVolOffID(++level,ladderId);
399 mc->CurrentVolOffID(++level,diskId);
400 mc->CurrentVolOffID(++level,halfId);
402 AliDebug(1,Form(
"Found hit into half = %d; disk = %d; ladder = %d; chip = %d",halfId,diskId,ladderId,chipId));
404 if (mc->IsTrackExiting()) {
405 AddTrackReference(
gAlice->GetMCApp()->GetCurrentTrackNumber(), AliTrackReference::kMFT);
408 static TLorentzVector position, momentum;
414 if (mc->IsTrackInside()) status += 0x1<<0;
415 if (mc->IsTrackEntering()) status += 0x1<<1;
416 if (mc->IsTrackExiting()) status += 0x1<<2;
417 if (mc->IsTrackOut()) status += 0x1<<3;
418 if (mc->IsTrackDisappeared()) status += 0x1<<4;
419 if (mc->IsTrackStop()) status += 0x1<<5;
420 if (mc->IsTrackAlive()) status += 0x1<<6;
426 hit.SetTrack(
gAlice->GetMCApp()->GetCurrentTrackNumber());
428 mc->TrackPosition(position);
429 mc->TrackMomentum(momentum);
431 AliDebug(1, Form(
" %s Hit #%06d (x=%f, y=%f, z=%f) belongs to track %02d",
432 mc->CurrentVolName(), fNhits, position.X(), position.Y(), position.Z(),
gAlice->GetMCApp()->GetCurrentTrackNumber()));
435 hit.
SetTOF(mc->TrackTime());
465 AliCodeTimerAuto(
"",0);
467 AliDebug(1,
"Start Hits2SDigits.");
471 if (!seg) AliFatal(
"No segmentation available");
473 if (!fLoader->TreeH()) fLoader->LoadHits();
475 if (!fLoader->TreeS()) {
477 for (Int_t iEvt=0;iEvt<fLoader->GetRunLoader()->GetNumberOfEvents(); iEvt++) {
479 fLoader->GetRunLoader()->GetEvent(iEvt);
480 fLoader->MakeTree(
"S");
484 AliDebug(1, Form(
"Event %03d: fLoader->TreeH()->GetEntries() = %2d", iEvt, Int_t(fLoader->TreeH()->GetEntries())));
486 for (Int_t iTrack=0; iTrack<fLoader->TreeH()->GetEntries(); iTrack++) {
487 fLoader->TreeH()->GetEntry(iTrack);
491 fLoader->TreeS()->Fill();
492 fLoader->WriteSDigits(
"OVERWRITE");
498 fLoader->UnloadHits();
499 fLoader->UnloadSDigits();
501 AliDebug(1,
"Stop Hits2SDigits.");
511 AliDebug(1,
"Entering Hits2SDigitsLocal");
516 pSDigList[iPlane] = (TClonesArray*) (*pSDig)[iPlane];
517 AliDebug(1,Form(
"Entries of pSDigList %3d; plane: %02d,",pSDigList[iPlane]->GetEntries(),iPlane));
518 if (!track && pSDigList[iPlane]->GetEntries()!=0) AliErrorClass(
"Some of sdigits lists is not empty");
521 for (Int_t iHit=0; iHit<hits->GetEntries(); iHit++) {
538 AliDebug(2,Form(
"Hit at x,y,z = %f %f %f ",hit->X(), hit->Y(), hit->Z()));
540 mainSDigit->
SetPixID(xPixel, yPixel, 0);
542 Double_t xCenter, yCenter, zCenter;
546 AliDebug(2, Form(
"Created new sdigit (%f, %f, %f) from hit (%f, %f, %f)",
549 AliDebug(1,Form(
"Hit outside active area : hit x,y,z = %f ; %f ; %f --> Pixel %d ; %d ",hit->X(), hit->Y(), hit->Z(),xPixel,yPixel));
556 Double_t pi4 = TMath::Pi()/4.;
559 for (Int_t iAngle=0; iAngle<8; iAngle++) {
560 Double_t shiftX = shift*TMath::Cos(iAngle*pi4);
561 Double_t shiftY = shift*TMath::Sin(iAngle*pi4);
562 if (mftGeom->
Hit2PixelID(hit->X()+shiftX, hit->Y()+shiftY, hit->Z(), mainSDigit->
GetDetElemID(), xPixel, yPixel) ){
563 Bool_t digitExists = kFALSE;
564 for (Int_t iSideDigit=0; iSideDigit<
fSideDigits->GetEntries(); iSideDigit++) {
578 sideSDigit->
SetPixID(xPixel, yPixel, 0);
580 Double_t xCenter, yCenter, zCenter;
592 for (Int_t iSDigit=0; iSDigit<
fSideDigits->GetEntries(); iSDigit++) {
596 AliDebug(1,Form(
"Created new side sdigit (%f, %f, %f) from hit (%f, %f, %f)",
606 AliDebug(1,
"Exiting Hits2SDigitsLocal");
615 AliDebug(1, Form(
"Start with option= %s.",option));
617 const Int_t kBufSize = 4000;
619 const Char_t *cH = strstr(option,
"H");
620 const Char_t *cD = strstr(option,
"D");
621 const Char_t *cS = strstr(option,
"S");
623 if (cH && fLoader->TreeH()) {
625 MakeBranchInTree(fLoader->TreeH(),
"MFT", &fHits, kBufSize, 0);
628 if (cS && fLoader->TreeS()) {
631 Form(
"Plane_%02d",iPlane),
632 &((*fSDigitsPerPlane)[iPlane]),
636 if (cD && fLoader->TreeD()) {
639 Form(
"Plane_%02d",iPlane),
640 &((*fDigitsPerPlane)[iPlane]),
654 AliDebug(1,
"Start.");
656 AliDebug(1, Form(
"AliMFT::SetTreeAddress Hits fLoader->TreeH() = %p\n", fLoader->TreeH()));
657 if (fLoader->TreeH() && fLoader->TreeH()->GetBranch(
"MFT")) {
659 fLoader->TreeH()->SetBranchAddress(
"MFT", &fHits);
662 AliDebug(1, Form(
"AliMFT::SetTreeAddress SDigits fLoader->TreeS() = %p\n", fLoader->TreeS()));
663 if (fLoader->TreeS() && fLoader->TreeS()->GetBranch(
"Plane_00")) {
666 fLoader->TreeS()->SetBranchAddress(Form(
"Plane_%02d",iPlane), &((*
fSDigitsPerPlane)[iPlane]));
670 AliDebug(1, Form(
"AliMFT::SetTreeAddress Digits fLoader->TreeD() = %p\n", fLoader->TreeD()));
671 if (fLoader->TreeD() && fLoader->TreeD()->GetBranch(
"Plane_00")) {
674 fLoader->TreeD()->SetBranchAddress(Form(
"Plane_%02d",iPlane), &((*
fDigitsPerPlane)[iPlane]));
678 AliDebug(1, Form(
"AliMFT::SetTreeAddress RecPoints fLoader->TreeR() = %p\n", fLoader->TreeR()));
679 if (fLoader->TreeR() && fLoader->TreeR()->GetBranch(
"Plane_00")) {
682 fLoader->TreeR()->SetBranchAddress(Form(
"Plane_%02d",iPlane), &((*
fRecPointsPerPlane)[iPlane]));
710 AliDebug(1,
"AliMFT::CreateHits()");
713 fHits =
new TClonesArray(
"AliMFTHit");
723 AliDebug(1,
"AliMFT::CreateSDigits()");
739 AliDebug(1,
"AliMFT::CreateDigits()");
753 AliDebug(1,
"AliMFT::CreateRecPoints()");
Double_t fDensitySupportOverSi
Bool_t Hit2PixelID(Double_t xHit, Double_t yHit, Double_t zHit, Int_t detElemID, Int_t &xPixel, Int_t &yPixel) const
Returns the pixel ID corresponding to a hit at (x,y,z) in the ALICE global frame. ...
Double_t fSingleStepForChargeDispersion
static const Double_t kYPixelPitch
Pixel pitch along Y.
Int_t GetDetElemID() const
TObjArray * GetSDigitsList() const
void SetDetElemID(Int_t detElemID)
void SetEloss(Double_t sig)
virtual Int_t GetPlane() const
void AddAlignableVolumes()
virtual void SetDetElemID(Int_t detElemID)
void Hits2SDigitsLocal(TClonesArray *hits, const TObjArray *pSDig, Int_t track)
UInt_t GetObjectID(ObjectTypes type, Int_t half=0, Int_t disk=0, Int_t ladder=0, Int_t chip=0) const
Returns the object Unique ID.
Double_t fChargeDispersion
static const Double_t kSensorThickness
CMOS Sensor Thickness.
AliMFTSegmentation * GetSegmentation() const
Returns pointer to the segmentation.
static const Double_t kXPixelPitch
Pixel pitch along X.
Short_t fPileUpEventsIDs[AliMFTConstants::fNMaxPileUpEvents]
void GetPixelCenter(Int_t xPixel, Int_t yPixel, Int_t detElemID, Double_t &xCenter, Double_t &yCenter, Double_t &zCenter) const
Returns the center of the pixel position in the ALICE global frame.
void Build()
Builf both the Virtual segmentation and the real volumes Real part is delegates to AliMFTGeometryBuil...
Double_t GetPixelCenterX() const
virtual void SetPlane(Int_t plane)
Double_t GetPixelCenterY() const
void SetPixWidth(Double_t pixelWidthX, Double_t pixelWidthY, Double_t pixelWidthZ)
Int_t fNStepForChargeDispersion
void SetPlane(Int_t plane)
virtual void SetTOF(Double_t time)
virtual void SetEloss(Double_t energy)
static AliMFTGeometry * Instance()
Retuns MFT Geometry singleton object.
virtual void SetPosition(TLorentzVector &x)
void AddMCLabel(Int_t label)
TClonesArray * fSideDigits
TObjArray * fDigitsPerPlane
void SetPixCenter(Double_t pixelCenterX, Double_t pixelCenterY, Double_t pixelCenterZ)
Double_t GetPixelCenterZ() const
virtual void SetStatus(Int_t status)
virtual Double_t GetEloss() const
Class for the virtual segmentation of the ALICE Muon Forward Tracker.
static const Int_t fNMaxPileUpEvents
TObjArray * fSDigitsPerPlane
static const Int_t kNDisks
Number of Disk.
void SetPixID(Int_t pixelX, Int_t pixelY, Int_t pixelZ)
void MakeBranch(Option_t *option="")
virtual void SetMomentum(TLorentzVector &p)
virtual Int_t GetDetElemID() const
Class Handling both Virutal Segmentation and Real Volumes.
Int_t GetSensorVolumeID() const
Returns TGeo ID of the volume describing the sensors.
TObjArray * fRecPointsPerPlane