/**************************************************************************
* 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$ */
/* History of cvs commits:
*
* $Log$
* Revision 1.87 2007/04/01 07:37:10 kharlov
* TGeo RS to Local RS transf matr added
*
* Revision 1.86 2007/03/06 06:55:46 kharlov
* DP:Misalignment of CPV added
*
* Revision 1.85 2007/03/01 11:37:37 kharlov
* Strip units changed from 8x1 to 8x2 (T.Pocheptsov)
*
* Revision 1.84 2006/12/20 16:56:43 kharlov
* Optional geometry without CPV
*
* Revision 1.83 2006/11/14 17:11:15 hristov
* Removing inheritances from TAttLine, TAttMarker and AliRndm in AliModule. The copy constructor and assignment operators are moved to the private part of the class and not implemented. The corresponding changes are propagated to the detectors
*
* Revision 1.82 2006/09/27 19:55:57 kharlov
* Alignment object with symbolic volume names are introduced
*
* Revision 1.81 2006/03/04 20:25:56 kharlov
* Set geom parameters from CDB
*
* Revision 1.80 2005/06/17 07:39:07 hristov
* Removing GetDebug and SetDebug from AliRun and AliModule. Using AliLog for the messages
*
* Revision 1.79 2005/05/28 14:19:05 schutz
* Compilation warnings fixed by T.P.
*
*/
//_________________________________________________________________________
// Implementation version v0 of PHOS Manager class
// An object of this class does not produce hits nor digits
// It is the one to use if you do not want to produce outputs in TREEH or TREED
//
//*-- Author: Yves Schutz (SUBATECH) & Dmitri Peressounko (RRC KI & SUBATECH)
// --- ROOT system ---
#include
PHOS in ALICE displayed by root
CPV perspective view | CPV front view |
*/ //END_HTML // Get pointer to the array containing media indexes Int_t *idtmed = fIdtmed->GetArray() - 699 ; AliPHOSGeometry * geom = GetGeometry() ; AliPHOSEMCAGeometry * emcg = geom->GetEMCAGeometry() ; // ======= Define the strip =============== gMC->Gsvolu("PSTR", "BOX ", idtmed[716], emcg->GetStripHalfSize(), 3) ; //Made of stell // --- define steel volume (cell of the strip unit) gMC->Gsvolu("PCEL", "BOX ", idtmed[716], emcg->GetSteelCellHalfSize(), 3); // --- define wrapped crystal and put it into steel cell gMC->Gsvolu("PWRA", "BOX ", idtmed[702], emcg->GetWrappedHalfSize(), 3); Float_t * pin = emcg->GetAPDHalfSize() ; Float_t * preamp = emcg->GetPreampHalfSize() ; Float_t y = (emcg->GetAirGapLed()-2*pin[1]-2*preamp[1])/2; gMC->Gspos("PWRA", 1, "PCEL", 0.0, y, 0.0, 0, "ONLY") ; // --- Define crystal and put it into wrapped crystall --- gMC->Gsvolu("PXTL", "BOX ", idtmed[699], emcg->GetCrystalHalfSize(), 3) ; gMC->Gspos("PXTL", 1, "PWRA", 0.0, 0.0, 0.0, 0, "ONLY") ; // --- define APD/PIN preamp and put it into AirCell gMC->Gsvolu("PPIN", "BOX ", idtmed[705], emcg->GetAPDHalfSize(), 3) ; Float_t * crystal = emcg->GetCrystalHalfSize() ; y = crystal[1] + emcg->GetAirGapLed() /2 - preamp[1]; gMC->Gspos("PPIN", 1, "PCEL", 0.0, y, 0.0, 0, "ONLY") ; gMC->Gsvolu("PREA", "BOX ", idtmed[711], emcg->GetPreampHalfSize(), 3) ; // Here I assumed preamp // as a printed Circuit y = crystal[1] + emcg->GetAirGapLed() /2 + pin[1] ; // May it should be changed gMC->Gspos("PREA", 1, "PCEL", 0.0, y, 0.0, 0, "ONLY") ; // to ceramics? // --- Fill strip with wrapped cristals in steel cells Float_t* splate = emcg->GetSupportPlateHalfSize(); y = -splate[1] ; Float_t* acel = emcg->GetSteelCellHalfSize() ; for(Int_t lev = 2, icel = 1; icel <= emcg->GetNCellsXInStrip()*emcg->GetNCellsZInStrip(); icel += 2, lev += 2){ Float_t x = (2*(lev / 2) - 1 - emcg->GetNCellsXInStrip())* acel[0] ; Float_t z = acel[2]; gMC->Gspos("PCEL", icel, "PSTR", x, y, +z, 0, "ONLY") ; gMC->Gspos("PCEL", icel + 1, "PSTR", x, y, -z, 0, "ONLY") ; } // --- define the support plate, hole in it and position it in strip ---- gMC->Gsvolu("PSUP", "BOX ", idtmed[701], emcg->GetSupportPlateHalfSize(), 3) ; gMC->Gsvolu("PSHO", "BOX ", idtmed[798], emcg->GetSupportPlateInHalfSize(), 3) ; Float_t z = emcg->GetSupportPlateThickness()/2 ; gMC->Gspos("PSHO", 1, "PSUP", 0.0, 0.0, z, 0, "ONLY") ; y = acel[1] ; gMC->Gspos("PSUP", 1, "PSTR", 0.0, y, 0.0, 0, "ONLY") ; // ========== Fill module with strips and put them into inner thermoinsulation============= gMC->Gsvolu("PTII", "BOX ", idtmed[706], emcg->GetInnerThermoHalfSize(), 3) ; Float_t * inthermo = emcg->GetInnerThermoHalfSize() ; Float_t * strip = emcg->GetStripHalfSize() ; y = inthermo[1] - strip[1] ; Int_t irow; Int_t nr = 1 ; Int_t icol ; for(irow = 0; irow < emcg->GetNStripX(); irow ++){ Float_t x = (2*irow + 1 - emcg->GetNStripX())* strip[0] ; for(icol = 0; icol < emcg->GetNStripZ(); icol ++){ z = (2*icol + 1 - emcg->GetNStripZ()) * strip[2] ; gMC->Gspos("PSTR", nr, "PTII", x, y, z, 0, "ONLY") ; nr++ ; } } // ------- define the air gap between thermoinsulation and cooler gMC->Gsvolu("PAGA", "BOX ", idtmed[798], emcg->GetAirGapHalfSize(), 3) ; Float_t * agap = emcg->GetAirGapHalfSize() ; y = agap[1] - inthermo[1] ; gMC->Gspos("PTII", 1, "PAGA", 0.0, y, 0.0, 0, "ONLY") ; // ------- define the Al passive cooler gMC->Gsvolu("PCOR", "BOX ", idtmed[701], emcg->GetCoolerHalfSize(), 3) ; Float_t * cooler = emcg->GetCoolerHalfSize() ; y = cooler[1] - agap[1] ; gMC->Gspos("PAGA", 1, "PCOR", 0.0, y, 0.0, 0, "ONLY") ; // ------- define the outer thermoinsulating cover gMC->Gsvolu("PTIO", "TRD1", idtmed[706], emcg->GetOuterThermoParams(), 4) ; Float_t * outparams = emcg->GetOuterThermoParams() ; Int_t idrotm[99] ; AliMatrix(idrotm[1], 90.0, 0.0, 0.0, 0.0, 90.0, 270.0) ; // Frame in outer thermoinsulation and so on: z out of beam, y along beam, x across beam z = outparams[3] - cooler[1] ; gMC->Gspos("PCOR", 1, "PTIO", 0., 0.0, z, idrotm[1], "ONLY") ; // -------- Define the outer Aluminium cover ----- gMC->Gsvolu("PCOL", "TRD1", idtmed[701], emcg->GetAlCoverParams(), 4) ; Float_t * covparams = emcg->GetAlCoverParams() ; z = covparams[3] - outparams[3] ; gMC->Gspos("PTIO", 1, "PCOL", 0., 0.0, z, 0, "ONLY") ; // --------- Define front fiberglass cover ----------- gMC->Gsvolu("PFGC", "BOX ", idtmed[717], emcg->GetFiberGlassHalfSize(), 3) ; z = - outparams[3] ; gMC->Gspos("PFGC", 1, "PCOL", 0., 0.0, z, 0, "ONLY") ; //=============This is all with cold section============== //------ Warm Section -------------- gMC->Gsvolu("PWAR", "BOX ", idtmed[701], emcg->GetWarmAlCoverHalfSize(), 3) ; Float_t * warmcov = emcg->GetWarmAlCoverHalfSize() ; // --- Define the outer thermoinsulation --- gMC->Gsvolu("PWTI", "BOX ", idtmed[706], emcg->GetWarmThermoHalfSize(), 3) ; Float_t * warmthermo = emcg->GetWarmThermoHalfSize() ; z = -warmcov[2] + warmthermo[2] ; gMC->Gspos("PWTI", 1, "PWAR", 0., 0.0, z, 0, "ONLY") ; // --- Define cables area and put in it T-supports ---- gMC->Gsvolu("PCA1", "BOX ", idtmed[718], emcg->GetTCables1HalfSize(), 3) ; Float_t * cbox = emcg->GetTCables1HalfSize() ; gMC->Gsvolu("PBE1", "BOX ", idtmed[701], emcg->GetTSupport1HalfSize(), 3) ; Float_t * beams = emcg->GetTSupport1HalfSize() ; Int_t isup ; for(isup = 0; isup < emcg->GetNTSuppots(); isup++){ Float_t x = -cbox[0] + beams[0] + (2*beams[0]+emcg->GetTSupportDist())*isup ; gMC->Gspos("PBE1", isup, "PCA1", x, 0.0, 0.0, 0, "ONLY") ; } z = -warmthermo[2] + cbox[2] ; gMC->Gspos("PCA1", 1, "PWTI", 0.0, 0.0, z, 0, "ONLY") ; gMC->Gsvolu("PCA2", "BOX ", idtmed[718], emcg->GetTCables2HalfSize(), 3) ; Float_t * cbox2 = emcg->GetTCables2HalfSize() ; gMC->Gsvolu("PBE2", "BOX ", idtmed[701], emcg->GetTSupport2HalfSize(), 3) ; for(isup = 0; isup < emcg->GetNTSuppots(); isup++){ Float_t x = -cbox[0] + beams[0] + (2*beams[0]+emcg->GetTSupportDist())*isup ; gMC->Gspos("PBE2", isup, "PCA2", x, 0.0, 0.0, 0, "ONLY") ; } z = -warmthermo[2] + 2*cbox[2] + cbox2[2]; gMC->Gspos("PCA2", 1, "PWTI", 0.0, 0.0, z, 0, "ONLY") ; // --- Define frame --- gMC->Gsvolu("PFRX", "BOX ", idtmed[716], emcg->GetFrameXHalfSize(), 3) ; Float_t * posit = emcg->GetFrameXPosition() ; gMC->Gspos("PFRX", 1, "PWTI", posit[0], posit[1], posit[2], 0, "ONLY") ; gMC->Gspos("PFRX", 2, "PWTI", posit[0], -posit[1], posit[2], 0, "ONLY") ; gMC->Gsvolu("PFRZ", "BOX ", idtmed[716], emcg->GetFrameZHalfSize(), 3) ; posit = emcg->GetFrameZPosition() ; gMC->Gspos("PFRZ", 1, "PWTI", posit[0], posit[1], posit[2], 0, "ONLY") ; gMC->Gspos("PFRZ", 2, "PWTI", -posit[0], posit[1], posit[2], 0, "ONLY") ; // --- Define Fiber Glass support --- gMC->Gsvolu("PFG1", "BOX ", idtmed[717], emcg->GetFGupXHalfSize(), 3) ; posit = emcg->GetFGupXPosition() ; gMC->Gspos("PFG1", 1, "PWTI", posit[0], posit[1], posit[2], 0, "ONLY") ; gMC->Gspos("PFG1", 2, "PWTI", posit[0], -posit[1], posit[2], 0, "ONLY") ; gMC->Gsvolu("PFG2", "BOX ", idtmed[717], emcg->GetFGupZHalfSize(), 3) ; posit = emcg->GetFGupZPosition() ; gMC->Gspos("PFG2", 1, "PWTI", posit[0], posit[1], posit[2], 0, "ONLY") ; gMC->Gspos("PFG2", 2, "PWTI", -posit[0], posit[1], posit[2], 0, "ONLY") ; gMC->Gsvolu("PFG3", "BOX ", idtmed[717], emcg->GetFGlowXHalfSize(), 3) ; posit = emcg->GetFGlowXPosition() ; gMC->Gspos("PFG3", 1, "PWTI", posit[0], posit[1], posit[2], 0, "ONLY") ; gMC->Gspos("PFG3", 2, "PWTI", posit[0], -posit[1], posit[2], 0, "ONLY") ; gMC->Gsvolu("PFG4", "BOX ", idtmed[717], emcg->GetFGlowZHalfSize(), 3) ; posit = emcg->GetFGlowZPosition() ; gMC->Gspos("PFG4", 1, "PWTI", posit[0], posit[1], posit[2], 0, "ONLY") ; gMC->Gspos("PFG4", 2, "PWTI", -posit[0], posit[1], posit[2], 0, "ONLY") ; // --- Define Air Gap for FEE electronics ----- gMC->Gsvolu("PAFE", "BOX ", idtmed[798], emcg->GetFEEAirHalfSize(), 3) ; posit = emcg->GetFEEAirPosition() ; gMC->Gspos("PAFE", 1, "PWTI", posit[0], posit[1], posit[2], 0, "ONLY") ; // Define the EMC module volume and combine Cool and Warm sections gMC->Gsvolu("PEMC", "TRD1", idtmed[798], emcg->GetEMCParams(), 4) ; z = - warmcov[2] ; gMC->Gspos("PCOL", 1, "PEMC", 0., 0., z, 0, "ONLY") ; z = covparams[3] ; gMC->Gspos("PWAR", 1, "PEMC", 0., 0., z, 0, "ONLY") ; // Put created EMC geometry into PHOS volume z = geom->GetCPVBoxSize(1) / 2. ; gMC->Gspos("PEMC", 1, "PHOS", 0., 0., z, 0, "ONLY") ; } //____________________________________________________________________________ void AliPHOSv0::CreateGeometryforCPV() { // Create the PHOS-CPV geometry for GEANT // Author: Yuri Kharlov 11 September 2000 //BEGIN_HTML /*
CPV perspective view | CPV front view |
One CPV module, perspective view | One CPV module, front view (extended in vertical direction) |
*/
//END_HTML
Float_t par[5], x0,y0,z0 ;
Int_t i,j,copy;
// Get pointer to the array containing media indexes
Int_t *idtmed = fIdtmed->GetArray() - 699 ;
AliPHOSGeometry * geom = GetGeometry() ;
// --- Dummy box containing two rails on which PHOS support moves
// --- Put these rails to the bottom of the L3 magnet
par[0] = geom->GetRailRoadSize(0) / 2.0 ;
par[1] = geom->GetRailRoadSize(1) / 2.0 ;
par[2] = geom->GetRailRoadSize(2) / 2.0 ;
gMC->Gsvolu("PRRD", "BOX ", idtmed[798], par, 3) ;
y0 = -(geom->GetRailsDistanceFromIP() - geom->GetRailRoadSize(1) / 2.0) ;
gMC->Gspos("PRRD", 1, "ALIC", 0.0, y0, 0.0, 0, "ONLY") ;
// --- Dummy box containing one rail
par[0] = geom->GetRailOuterSize(0) / 2.0 ;
par[1] = geom->GetRailOuterSize(1) / 2.0 ;
par[2] = geom->GetRailOuterSize(2) / 2.0 ;
gMC->Gsvolu("PRAI", "BOX ", idtmed[798], par, 3) ;
for (i=0; i<2; i++) {
x0 = (2*i-1) * geom->GetDistanceBetwRails() / 2.0 ;
gMC->Gspos("PRAI", i, "PRRD", x0, 0.0, 0.0, 0, "ONLY") ;
}
// --- Upper and bottom steel parts of the rail
par[0] = geom->GetRailPart1(0) / 2.0 ;
par[1] = geom->GetRailPart1(1) / 2.0 ;
par[2] = geom->GetRailPart1(2) / 2.0 ;
gMC->Gsvolu("PRP1", "BOX ", idtmed[716], par, 3) ;
y0 = - (geom->GetRailOuterSize(1) - geom->GetRailPart1(1)) / 2.0 ;
gMC->Gspos("PRP1", 1, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ;
y0 = (geom->GetRailOuterSize(1) - geom->GetRailPart1(1)) / 2.0 - geom->GetRailPart3(1);
gMC->Gspos("PRP1", 2, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ;
// --- The middle vertical steel parts of the rail
par[0] = geom->GetRailPart2(0) / 2.0 ;
par[1] = geom->GetRailPart2(1) / 2.0 ;
par[2] = geom->GetRailPart2(2) / 2.0 ;
gMC->Gsvolu("PRP2", "BOX ", idtmed[716], par, 3) ;
y0 = - geom->GetRailPart3(1) / 2.0 ;
gMC->Gspos("PRP2", 1, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ;
// --- The most upper steel parts of the rail
par[0] = geom->GetRailPart3(0) / 2.0 ;
par[1] = geom->GetRailPart3(1) / 2.0 ;
par[2] = geom->GetRailPart3(2) / 2.0 ;
gMC->Gsvolu("PRP3", "BOX ", idtmed[716], par, 3) ;
y0 = (geom->GetRailOuterSize(1) - geom->GetRailPart3(1)) / 2.0 ;
gMC->Gspos("PRP3", 1, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ;
// --- The wall of the cradle
// --- The wall is empty: steel thin walls and air inside
par[1] = TMath::Sqrt(TMath::Power((geom->GetIPtoCPVDistance() + geom->GetOuterBoxSize(3)),2) +
TMath::Power((geom->GetOuterBoxSize(1)/2),2))+10. ;
par[0] = par[1] - geom->GetCradleWall(1) ;
par[2] = geom->GetCradleWall(2) / 2.0 ;
par[3] = geom->GetCradleWall(3) ;
par[4] = geom->GetCradleWall(4) ;
gMC->Gsvolu("PCRA", "TUBS", idtmed[716], par, 5) ;
par[0] += geom->GetCradleWallThickness() ;
par[1] -= geom->GetCradleWallThickness() ;
par[2] -= geom->GetCradleWallThickness() ;
gMC->Gsvolu("PCRE", "TUBS", idtmed[798], par, 5) ;
gMC->Gspos ("PCRE", 1, "PCRA", 0.0, 0.0, 0.0, 0, "ONLY") ;
for (i=0; i<2; i++) {
z0 = (2*i-1) * (geom->GetOuterBoxSize(2) + geom->GetCradleWall(2) )/ 2.0 ;
gMC->Gspos("PCRA", i, "ALIC", 0.0, 0.0, z0, 0, "ONLY") ;
}
// --- The "wheels" of the cradle
par[0] = geom->GetCradleWheel(0) / 2;
par[1] = geom->GetCradleWheel(1) / 2;
par[2] = geom->GetCradleWheel(2) / 2;
gMC->Gsvolu("PWHE", "BOX ", idtmed[716], par, 3) ;
y0 = -(geom->GetRailsDistanceFromIP() - geom->GetRailRoadSize(1) -
geom->GetCradleWheel(1)/2) ;
for (i=0; i<2; i++) {
z0 = (2*i-1) * ((geom->GetOuterBoxSize(2) + geom->GetCradleWheel(2))/ 2.0 +
geom->GetCradleWall(2));
for (j=0; j<2; j++) {
copy = 2*i + j;
x0 = (2*j-1) * geom->GetDistanceBetwRails() / 2.0 ;
gMC->Gspos("PWHE", copy, "ALIC", x0, y0, z0, 0, "ONLY") ;
}
}
}
//_____________________________________________________________________________
void AliPHOSv0::AddAlignableVolumes() const
{
//
// Create entries for alignable volumes associating the symbolic volume
// name with the corresponding volume path. Needs to be syncronized with
// eventual changes in the geometry
// Alignable volumes are:
// 1) PHOS modules as a whole
// 2) Cradle
// 3) Cradle wheels
// 4) Strip units (group of 2x8 crystals)
TString volpath, symname;
// Alignable modules
// Volume path /ALIC_1/PHOS_ => symbolic name /PHOS/Module, =1,2,3,4,5
TString physModulePath="/ALIC_1/PHOS_";
TString symbModuleName="PHOS/Module";
Int_t nModules = GetGeometry()->GetNModules();
for(Int_t iModule=1; iModule<=nModules; iModule++){
volpath = physModulePath;
volpath += iModule;
symname = symbModuleName;
symname += iModule;
gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data());
}
//Aligning of CPV should be done for volume PCPV_1
symbModuleName="PHOS/Module";
Double_t rotMatrix[9] ;
for(Int_t iModule=1; iModule<=nModules; iModule++){
volpath = physModulePath;
volpath += iModule;
volpath += "/PCPV_1";
symname = symbModuleName;
symname += iModule;
symname += "/CPV";
gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data());
// Creates the TGeo Local to Tracking transformation matrix ...
TGeoPNEntry *alignableEntry = gGeoManager->GetAlignableEntry(symname.Data()) ;
const char *path = alignableEntry->GetTitle();
if (!gGeoManager->cd(path))
AliFatal(Form("Volume path %s not valid!",path));
TGeoHMatrix *matLtoT = new TGeoHMatrix;
matLtoT->SetDx(0.) ;
matLtoT->SetDy(0.) ;
matLtoT->SetDz(0.) ;
rotMatrix[0]= 1; rotMatrix[1]= 0; rotMatrix[2]= 0; //
rotMatrix[3]= 0; rotMatrix[4]= 0; rotMatrix[5]= 1; //
rotMatrix[6]= 0; rotMatrix[7]= 1; rotMatrix[8]= 0;
TGeoRotation rot;
rot.SetMatrix(rotMatrix);
matLtoT->MultiplyLeft(&rot);
TGeoHMatrix *matTtoL = new TGeoHMatrix(matLtoT->Inverse());
delete matLtoT;
alignableEntry->SetMatrix(matTtoL);
}
// Alignable cradle walls
// Volume path /ALIC_1/PCRA_ => symbolic name /PHOS/Cradle, =0,1
TString physCradlePath="/ALIC_1/PCRA_";
TString symbCradleName="PHOS/Cradle";
Int_t nCradles = 2;
for(Int_t iCradle=0; iCradle