// : Aleksei Pavlinov (WSU) SHASHLYK
// --- ROOT system ---
+#include <cassert>
#include <TNode.h>
#include <TBRIK.h>
#include <TPGON.h>
#include <TTUBS.h>
#include <TGeometry.h>
+#include <TGeoPhysicalNode.h>
+#include <TGeoManager.h>
+#include <TGeoMatrix.h>
#include <TVirtualMC.h>
#include <TArrayI.h>
#include <TROOT.h>
#include <TList.h>
#include <TVector2.h>
+#include <cassert>
#include "AliEMCALShishKebabModule.h"
#include "AliEMCALShishKebabTrd1Module.h"
fSampleWidth(0),fSmodPar0(0),fSmodPar1(0),fSmodPar2(0)
{
// ctor : title is used to identify the layout
- // Apr 25, 2006
+ // Apr 25, 2006
+ // Nov 22, 2006 - case of 1X1
TString ntmp(GetTitle());
ntmp.ToUpper();
if(ntmp == "TRD1") { // TRD1 is alias for SHISH_77_TRD1_2X2_FINAL_110DEG NL=69
fShishKebabModules = geom->GetShishKebabTrd1Modules();
}
-//______________________________________________________________________
-AliEMCALv0::AliEMCALv0(const AliEMCALv0 & emcal)
- : AliEMCAL(emcal),
- fShishKebabModules(emcal.fShishKebabModules),
- fEnvelop1(emcal.fEnvelop1),
- fIdRotm(emcal.fIdRotm),
- fIdTmedArr(emcal.fIdTmedArr),
- fSampleWidth(emcal.fSampleWidth),
- fSmodPar0(emcal.fSmodPar0),
- fSmodPar1(emcal.fSmodPar1),
- fSmodPar2(emcal.fSmodPar2)
-{
- //copy ctor
- for(Int_t i = 0; i < 5; i++) fParEMOD[i] = emcal.fParEMOD[i];
-
-}
//______________________________________________________________________
void AliEMCALv0::BuildGeometry()
{
TPGON *pgon = new TPGON(envn, "PGON that contains arm 1", "void",
geom->GetArm1PhiMin(),geom->GetArm1PhiMax()-geom->GetArm1PhiMin(),geom->GetNPhiSuperModule(), 2);
// define section
+ if (fEnvelop1.GetSize()<8) {
+ fEnvelop1.Set(10);
+ fEnvelop1[0] = geom->GetArm1PhiMin(); // minimum phi angle
+ fEnvelop1[1] = geom->GetArm1PhiMax() - geom->GetArm1PhiMin(); // angular range in phi
+ fEnvelop1[2] = geom->GetNPhi(); // number of sections in phi
+ fEnvelop1[3] = 2; // 2 z coordinates
+ fEnvelop1[4] = -350.;
+ fEnvelop1[5] = geom->GetEnvelop(0) ; // rmin at z1
+ fEnvelop1[6] = geom->GetEnvelop(1) ; // rmax at z1
+ fEnvelop1[7] = 350.;
+ fEnvelop1[8] = fEnvelop1[5] ; // radii are the same.
+ fEnvelop1[9] = fEnvelop1[6] ; // radii are the same.
+
+ if(gn.Contains("SHISH"))
+ fEnvelop1[2] = geom->GetNPhiSuperModule();
+ }
pgon->DefineSection(0, fEnvelop1[4], fEnvelop1[5], fEnvelop1[6]);
pgon->DefineSection(1, fEnvelop1[7], fEnvelop1[5], fEnvelop1[6]);
top->cd();
void AliEMCALv0::Init(void)
{
// Just prints an information message
-
+ AliEMCAL::Init();
if(AliLog::GetGlobalDebugLevel()>0) {
TString message("\n") ;
message += "*****************************************\n" ;
CreateEmod("SMOD","EMOD"); // 18-may-05
- if(gn.Contains("110DEG")) CreateEmod("SM10","EMOD"); // 12-oct-05
+ if(g->GetKey110DEG()) CreateEmod("SM10","EMOD"); // Nov 1,2006
// Sensitive SC (2x2 tiles)
- double parSCM0[5], *dummy = 0, parTRAP[11];
+ double parSCM0[5]={0,0,0,0}, *dummy = 0, parTRAP[11];
Double_t trd1Angle = g->GetTrd1Angle()*TMath::DegToRad(), tanTmp = TMath::Tan(trd1Angle/2.);
if(!gn.Contains("TRD")) { // standard module
par[0] = (g->GetECPbRadThick()+g->GetECScintThick())*g->GetNECLayers()/2.;
gMC->Gsvolu("SCM0", "TRD1", fIdTmedArr[kIdAIR], parSCM0, 4);
gMC->Gspos("SCM0", 1, "EMOD", 0., 0., dzTmp/2., 0, "ONLY") ;
} else { // before MAY 2005
- double wallThickness = g->GetPhiModuleSize()/2. - g->GetPhiTileSize(); // Need check
+ // double wallThickness = g->GetPhiModuleSize()/2. - g->GetPhiTileSize(); // Need check
+ double wallThickness = g->GetPhiModuleSize()/g->GetNPHIdiv() - g->GetPhiTileSize();
for(int i=0; i<3; i++) parSCM0[i] = fParEMOD[i] - wallThickness;
parSCM0[3] = fParEMOD[3];
gMC->Gsvolu("SCM0", "TRD1", fIdTmedArr[kIdAIR], parSCM0, 4);
AliDebug(2,Form(" Number of Pb tiles in SCMX %i \n", nr));
}
} else if(g->GetNPHIdiv()==3 && g->GetNETAdiv()==3) {
+ printf(" before AliEMCALv0::Trd1Tower3X3() : parSCM0");
+ for(int i=0; i<4; i++) printf(" %7.4f ", parSCM0[i]);
+ printf("\n");
Trd1Tower3X3(parSCM0);
+ } else if(g->GetNPHIdiv()==1 && g->GetNETAdiv()==1) {
+ // no division in SCM0
+ Trd1Tower1X1(parSCM0);
} else if(g->GetNPHIdiv()==4 && g->GetNETAdiv()==4) {
Trd1Tower4X4();
}
} else if(gn.Contains("TRD2")) { // TRD2 - 14-jan-05
// Scm0InTrd2(g, fParEMOD, parSCM0); // First dessin
- PbmoInTrd2(g, fParEMOD, parSCM0); // Second dessin
+ PbmoInTrd2(g, fParEMOD, parSCM0); // Second design
}
}
int nphism = g->GetNumberOfSuperModules()/2; // 20-may-05
if(nphism>0) {
dphi = (g->GetArm1PhiMax() - g->GetArm1PhiMin())/nphism;
- // if(gn.Contains("110DEG")) dphi = (g->GetArm1PhiMax() - g->GetArm1PhiMin())/(nphism-1);
+ // if(g->GetKey110DEG()) dphi = (g->GetArm1PhiMax() - g->GetArm1PhiMin())/(nphism-1);
rpos = (g->GetEnvelop(0) + g->GetEnvelop(1))/2.;
AliDebug(2,Form(" rpos %8.2f : dphi %6.1f degree \n", rpos, dphi));
}
fIdTmedArr[kIdAIR], par[0],par[1],par[2]));
fSmodPar0 = par[0];
fSmodPar2 = par[2];
- if(gn.Contains("110DEG")) { // 12-oct-05
+ if(g->GetKey110DEG()) { // 12-oct-05
par1C = par[1];
par[1] /= 2.;
gMC->Gsvolu("SM10", "BOX", fIdTmedArr[kIdAIR], par, 3);
nr++;
} else { // TRD1
TString smName("SMOD"); // 12-oct-05
- if(i==5 && gn.Contains("110DEG")) {
+ if(i==5 && g->GetKey110DEG()) {
smName = "SM10";
nrsmod = nr;
nr = 0;
xpos = rpos * TMath::Cos(phiRad);
ypos = rpos * TMath::Sin(phiRad);
zpos = fSmodPar2; // 21-sep-04
- if(i==5 && gn.Contains("110DEG")) {
+ if(i==5 && g->GetKey110DEG()) {
xpos += (par1C/2. * TMath::Sin(phiRad));
ypos -= (par1C/2. * TMath::Cos(phiRad));
}
fParEMOD[2] = g->GetPhiModuleSize()/2.;; // dy
fParEMOD[3] = g->GetLongModuleSize()/2.; // dz
gMC->Gsvolu(child, "TRD1", fIdTmedArr[kIdSTEEL], fParEMOD, 4);
- if(gn.Contains("WSUC") || gn.Contains("MAY05")){
+ // if(gn.Contains("WSUC") || gn.Contains("MAY05")){
+ if(0){ // Jul 12 - should be checked
parSCPA[0] = g->GetEtaModuleSize()/2. + tanTrd1*g->GetFrontSteelStrip(); // dx1
parSCPA[1] = parSCPA[0] + tanTrd1*g->GetPassiveScintThick(); // dx2
parSCPA[2] = g->GetPhiModuleSize()/2.; // dy
zpos = mod->GetPosZ() - fSmodPar2;
int iyMax = g->GetNPhi();
- if(strcmp(mother,"SMOD") && gn.Contains("110DEG")) {
+ if(strcmp(mother,"SMOD") && g->GetKey110DEG()) {
iyMax /= 2;
}
for(int iy=0; iy<iyMax; iy++) { // flat in phi
}
}
}
- AliDebug(2,Form(" Number of modules in Super Module %i \n", nr));
+ AliDebug(2,Form(" Number of modules in Super Module(%s) %i \n", mother, nr));
}
-// 8-dec-04 by PAI
-void AliEMCALv0::Trd1Tower3X3(const double parSCM0[4])
+void AliEMCALv0::Trd1Tower3X3(const double *parSCM0)
{
- // PB should be for whole SCM0 - ?
+ // Started Dec 8,2004 by PAI
+ // Fixed Nov 13,2006
+ printf(" AliEMCALv0::Trd1Tower3X3() : parSCM0");
+ for(int i=0; i<4; i++) printf(" %7.4f ", parSCM0[i]);
+ printf("\n");
+ // Nov 10, 2006 - different name of SCMX
double parTRAP[11], *dummy=0;
AliEMCALGeometry * g = GetGeometry();
TString gn(g->GetName()), scmx;
double ndiv=3., xpos=0.0;
// should be defined once
gMC->Gsvolu("PBTI", "BOX", fIdTmedArr[kIdPB], dummy, 0);
- if(gn.Contains("TEST")==0) { // one name for all trapesoid
- scmx = "SCMX";
- gMC->Gsvolu(scmx.Data(), "TRAP", fIdTmedArr[kIdSC], dummy, 0);
- }
-
-
for(int ix=1; ix<=3; ix++) { // 3X3
+ scmx = "SCX"; // Nov 10,2006
// ix=1
parTRAP[0] = dz;
- parTRAP[1] = TMath::ATan2((dx2-dx1)/2.,2.*dz)*TMath::RadToDeg(); // theta
+ double xCentBot = 2.*dx1/3.;
+ double xCentTop = 2.*(dx2/4. + dx1/12.);
+ parTRAP[1] = TMath::ATan2((xCentTop-xCentBot),2.*dz)*TMath::RadToDeg(); // theta
parTRAP[2] = 0.; // phi
// bottom
parTRAP[3] = dy/ndiv; // H1
parTRAP[6] = 0.0; // ALP1
// top
parTRAP[7] = dy/ndiv; // H2
- parTRAP[8] = dx2/ndiv; // BL2
+ parTRAP[8] = dx2/2 - dx1/6.;// BL2
parTRAP[9] = parTRAP[8]; // TL2
parTRAP[10]= 0.0; // ALP2
- xpos = +(dx1+dx2)/3.; // 6 or 3
+ xpos = (xCentBot+xCentTop)/2.;
if (ix==3) {
parTRAP[1] = -parTRAP[1];
}
AliDebug(2,Form(" ** TRAP ** xpos %9.3f\n", xpos));
for(int i=0; i<11; i++) AliDebug(2,Form(" par[%2.2i] %9.4f\n", i, parTRAP[i]));
- if(gn.Contains("TEST")){
- scmx = "SCX"; scmx += ix;
- gMC->Gsvolu(scmx.Data(), "TRAP", fIdTmedArr[kIdSC], parTRAP, 11);
- gMC->Gspos(scmx.Data(), 1, "SCMY", xpos, 0.0, 0.0, 0, "ONLY") ;
- } else {
- gMC->Gsposp(scmx.Data(), ix, "SCMY", xpos, 0.0, 0.0, 0, "ONLY", parTRAP, 11) ;
- }
+
+ scmx += ix;
+ gMC->Gsvolu(scmx.Data(), "TRAP", fIdTmedArr[kIdSC], parTRAP, 11);
+ gMC->Gspos(scmx.Data(), 1, "SCMY", xpos, 0.0, 0.0, 0, "ONLY") ;
+
PbInTrap(parTRAP, scmx);
}
AliDebug(2,Form("Trd1Tower3X3()", "Ver. 1.0 : was tested."));
{
// Not ready yet
}
+
+void AliEMCALv0::Trd1Tower1X1(double *parSCM0)
+{
+ // Started Nov 22,2006 by PAI
+ AliDebug(1," AliEMCALv0::Trd1Tower1X1() : parSCM0");
+ for(int i=0; i<4; i++) printf(" %7.4f ", parSCM0[i]);
+ printf("\n");
+
+ // No division - keeping the same volume logic
+ // and as consequence the same abs is scheme
+ AliDebug(2,"Trd1Tower1X1() : Create SCMX(SCMY) as SCM0");
+
+ gMC->Gsvolu("SCMY", "TRD1", fIdTmedArr[kIdAIR], parSCM0, 4);
+ gMC->Gspos("SCMY", 1, "SCM0", 0.0, 0.0, 0.0, 0, "ONLY");
+ gMC->Gsvolu("SCMX", "TRD1", fIdTmedArr[kIdSC], parSCM0, 4);
+ gMC->Gspos("SCMX", 1, "SCMY", 0.0, 0.0, 0.0, 0, "ONLY");
+
+ // should be defined once
+ double *dummy=0;
+ gMC->Gsvolu("PBTI", "BOX", fIdTmedArr[kIdPB], dummy, 0);
+
+ PbInTrd1(parSCM0, "SCMX");
+
+ AliDebug(1,"Trd1Tower1X1() : Ver. 0.1 : was tested.");
+}
+
+void AliEMCALv0::PbInTrd1(double *parTrd1, TString n)
+{
+ // see PbInTrap(const double parTrd1[11], TString n)
+ static int nr=0, ndeb=2;
+ AliDebug(ndeb,Form(" Pb tiles : nrstart %i\n", nr));
+ AliEMCALGeometry * g = GetGeometry();
+
+ double par[3];
+ // double fSampleWidth = double(g->GetECPbRadThick()+g->GetECScintThick());
+ double xpos = 0.0, ypos = 0.0;
+ double zpos = -fSampleWidth*g->GetNECLayers()/2. + g->GetECPbRadThick()/2.;
+ double coef = (parTrd1[1] - parTrd1[0]) / (2.*parTrd1[3]);
+
+ par[1] = parTrd1[2]; // y
+ par[2] = g->GetECPbRadThick()/2.; // z
+
+ for(int iz=0; iz<g->GetNECLayers(); iz++){
+ par[0] = parTrd1[0] + coef*fSampleWidth*iz;
+ gMC->Gsposp("PBTI", ++nr, n.Data(), xpos, ypos, zpos, 0, "ONLY", par, 3) ;
+ AliDebug(2,Form(" %i xpos %9.3f zpos %9.3f par[0] %9.3f |", iz+1, xpos, zpos, par[0]));
+ zpos += fSampleWidth;
+ if(iz%2>0) printf("\n");
+ }
+ AliDebug(ndeb,Form(" Number of Pb tiles in SCMX %i coef %9.7f ", nr, coef));
+ AliDebug(ndeb,Form(" PbInTrd1 Ver. 0.1 : was tested."));
+}
+
// 3-feb-05
void AliEMCALv0::Scm0InTrd2(const AliEMCALGeometry * g, const Double_t emodPar[5], Double_t parSCM0[5])
{
//_____________________________________________________________________________
void AliEMCALv0::AddAlignableVolumes() const
+{
+ TString ntmp(GetTitle()); // name of EMCAL geometry
+
+ if(ntmp.Contains("WSUC")) {
+ AddAlignableVolumesInWSUC(); // WSUC case
+ } else {
+ AddAlignableVolumesInALICE(); // ALICE case
+ }
+}
+
+void AliEMCALv0::AddAlignableVolumesInALICE() const
{
//
// Create entries for alignable volumes associating the symbolic volume
// eventual changes in the geometry.
//
- TString vpstr1 = "ALIC_1/XEN1_1/SMOD_";
- TString snstr1 = "EMCAL/FullSupermodule";
+ Float_t * pars = GetGeometry()->GetSuperModulesPars();
+ double rpos = (GetGeometry()->GetEnvelop(0) + GetGeometry()->GetEnvelop(1))/2.;
+ double phi, phiRad, xpos, ypos, zpos;
+
TString volpath, symname;
- //Int_t nSMod = ((AliEMCALGeometry*)GetGeometry())->GetNumberOfSuperModules();
- //could use this, but what happens if it is > 10?
+ Int_t nSMod = ((AliEMCALGeometry*)GetGeometry())->GetNumberOfSuperModules();
+ for (Int_t smodnum=0; smodnum < nSMod; smodnum++) {
+ volpath = "ALIC_1/XEN1_1/SMOD_";
+ volpath += (smodnum+1);
+ symname = "EMCAL/FullSupermodule";
+ symname += (smodnum+1);
+
+ if(GetGeometry()->GetKey110DEG() && smodnum>=10) {
+ volpath = "ALIC_1/XEN1_1/SM10_";
+ volpath += (smodnum-10+1);
+ symname = "EMCAL/HalfSupermodule";
+ symname += (smodnum-10+1);
+ }
- try{
- for (Int_t smodnum=0; smodnum < 10; smodnum++) {
- symname = snstr1;
- symname += (smodnum+1);
- volpath = vpstr1;
- volpath += (smodnum+1);
- gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data());
+ if(!gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data()))
+ AliFatal("AliEMCALv0::Unable to set alignable entry!!");
+
+ // Creates the Tracking to Local transformation matrix for EMCAL
+ // modules
+ TGeoPNEntry *alignableEntry = gGeoManager->GetAlignableEntry(symname.Data()) ;
+ const char *path = alignableEntry->GetTitle();
+ if (!gGeoManager->cd(path))
+ AliFatal(Form("Volume path %s not valid!",path));
+
+ phi = GetGeometry()->GetPhiCenterOfSM(smodnum);
+ phiRad = phi*TMath::Pi()/180.;
+ xpos = rpos * TMath::Cos(phiRad);
+ ypos = rpos * TMath::Sin(phiRad);
+ zpos = pars[2];
+ if(GetGeometry()->GetKey110DEG() && smodnum >= 10) {
+ xpos += (pars[1]/2. * TMath::Sin(phiRad));
+ ypos -= (pars[1]/2. * TMath::Cos(phiRad));
}
- } catch (TString) {
- AliFatal("Trying to set alignable entry with open geometry");
- }
- TString gn( ((AliEMCALGeometry*)GetGeometry())->GetName() );
- gn.ToUpper();
- if(gn.Contains("110DEG")) {
- TString vpstr2 = "ALIC_1/XEN1_1/SM10_";
- TString snstr2 = "EMCAL/HalfSupermodule";
- try{
- for (Int_t smodnum=0; smodnum < 2; smodnum++) {
- symname = snstr2;
- symname += (smodnum+1);
- volpath = vpstr2;
- volpath += (smodnum+1);
- gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data());
- }
- } catch (TString) {
- AliFatal("Trying to set alignable entry with open geometry");
+ TGeoHMatrix *matTtoL;
+ TGeoHMatrix* globMatrix = gGeoManager->GetCurrentMatrix();
+
+ if(smodnum%2 == 0) {
+ // pozitive z
+ TGeoTranslation geoTran0(xpos,ypos, zpos);
+ TGeoRotation geoRot0("geoRot0", 90.0, phi, 90.0, 90.0+phi, 0.0, 0.0);
+ TGeoCombiTrans mat0(geoTran0, geoRot0);
+ matTtoL = new TGeoHMatrix(mat0);
+
+ matTtoL->MultiplyLeft(&(globMatrix->Inverse()));
+ alignableEntry->SetMatrix(matTtoL);
+
+ } else {
+ // negative z
+ double phiy = 90. + phi + 180.;
+ if(phiy>=360.) phiy -= 360.;
+ TGeoTranslation geoTran1(xpos,ypos,-zpos);
+ TGeoRotation geoRot1("geoRot1", 90.0, phi, 90.0, phiy, 180.0, 0.0);
+ TGeoCombiTrans mat1(geoTran1, geoRot1);
+ matTtoL = new TGeoHMatrix(mat1);
+
+ matTtoL->MultiplyLeft(&(globMatrix->Inverse()));
+ alignableEntry->SetMatrix(matTtoL);
+
}
+
}
+
}
+void AliEMCALv0::AddAlignableVolumesInWSUC() const
+{
+ //
+ // Create entries for alignable volumes associating the symbolic volume
+ // name with the corresponding volume path. Needs to be synchronized with
+ // eventual changes in the geometry.
+ //
+
+ TString vpstr1 = "WSUC_1/XEN1_1/SMOD_";
+ TString snstr1 = "EMCAL/CosmicTestSupermodule";
+ TString volpath, symname;
+
+ // #SM is just one
+ for (Int_t smodnum=0; smodnum < 1; smodnum++) {
+ symname = snstr1;
+ symname += (smodnum+1);
+ volpath = vpstr1;
+ volpath += (smodnum+1);
+ if(!gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data()))
+ AliFatal("Unable to set alignable entry!!");
+ }
+}