00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00058 #include <stdio.h>
00059 #include <assert.h>
00060 #include <map>
00061 using namespace std;
00062 #include <stdexcept>
00063 #include "StMessMgr.h"
00064 #include "StThreeVectorD.hh"
00065 #include "tables/St_ssdDimensions_Table.h"
00066 #include "tables/St_ssdConfiguration_Table.h"
00067 #include "tables/St_ssdWafersPosition_Table.h"
00068
00069 #include "Sti/Base/Factory.h"
00070 #include "Sti/StiPlanarShape.h"
00071 #include "Sti/StiCylindricalShape.h"
00072 #include "Sti/StiMaterial.h"
00073 #include "Sti/StiPlacement.h"
00074 #include "Sti/StiDetector.h"
00075 #include "Sti/StiToolkit.h"
00076 #include "Sti/StiElossCalculator.h"
00077 #include "StDetectorDbMaker/StiHitErrorCalculator.h"
00078 #include "Sti/StiIsActiveFunctor.h"
00079 #include "Sti/StiNeverActiveFunctor.h"
00080 #include "StiSsd/StiSsdIsActiveFunctor.h"
00081 #include "StiSsd/StiSsdDetectorBuilder.h"
00082 #include "StSsdUtil/StSsdBarrel.hh"
00083 #include "StDetectorDbMaker/StiSsdHitErrorCalculator.h"
00084 StiSsdDetectorBuilder::StiSsdDetectorBuilder(bool active, const string & inputFile)
00085 : StiDetectorBuilder("Ssd",active,inputFile), _siMat(0), _hybridMat(0)
00086 {
00087
00088 }
00089
00090 StiSsdDetectorBuilder::~StiSsdDetectorBuilder()
00091 {}
00092
00093
00094 void StiSsdDetectorBuilder::buildDetectors(StMaker & source)
00095 {
00096 char name[50];
00097 gMessMgr->Info() << "StiSsdDetectorBuilder::buildDetectors() - I - Started "<<endm;
00098 StSsdBarrel *mySsd = StSsdBarrel::Instance();
00099 if (! mySsd) {
00100 gMessMgr->Info() << "StiSsdDetectorBuilder::buildDetectors() - I - there is no SSD barrel - take whatever exist in GEANT" << endm;
00101 StiVMCToolKit::GetVMC();
00102 return;
00103 }
00104 int nRows = 1 ;
00105 setNRows(nRows);
00106 if (! _gasMat)
00107 _gasMat = add(new StiMaterial("SsdAir",7.3, 14.61, 0.001205, 30420.*0.001205, 7.3*12.e-9));
00108 if (! _siMat)
00109 _siMat = add(new StiMaterial("SsdSi",14., 28.0855, 2.33, 21.82, 14.*12.*1e-9));
00110 if (! _hybridMat)
00111 _hybridMat = add(new StiMaterial("SsdHyb",14., 28.0855, 2.33, 21.82, 14.*12.*1e-9));
00112
00113 double ionization = _siMat->getIonization();
00114
00115 StiElossCalculator * siElossCalculator = new StiElossCalculator(_siMat->getZOverA(), ionization*ionization, _siMat->getA(), _siMat->getZ(), _siMat->getDensity());
00116
00117
00118 cout << "StiSsdDetectorBuilder::buildMaterials() - I - Done "<<endl;
00119 ssdDimensions_st *dimensions = mySsd->getDimensions();
00120 Int_t NL = mySsd->getNumberOfLadders();
00121 Int_t NW = mySsd->getNWaferPerLadder();
00122 StSsdLadder *Ladder = mySsd->getLadder(0);
00123 assert(Ladder);
00124 StSsdWafer *Wafer1 = Ladder->getWafer(0);
00125 StSsdWafer *Wafer2 = Ladder->getWafer(NW-1);
00126 assert(Wafer1 && Wafer2);
00127 Double_t width = TMath::Abs(Wafer1->x(2) - Wafer2->x(2))/2. + 2;
00128 StiPlanarShape *ladderShape = new StiPlanarShape(name,
00129 width,
00130 0.34,
00131 dimensions->waferHalfLength );
00132 add(ladderShape);
00133 Int_t layer = 0;
00134 setNSectors(layer,NL);
00141 for (Int_t ladder = 0; ladder < NL; ladder++) {
00142 Ladder = mySsd->getLadder(ladder);
00143 if (! Ladder) continue;
00144 Wafer1 = Ladder->getWafer(0);
00145 Wafer2 = Ladder->getWafer(NW-1);
00146 if (! Wafer1 || ! Wafer2) continue;
00147 StThreeVectorD centerVector1(Wafer1->x(0),Wafer1->x(1),Wafer1->x(2));
00148 StThreeVectorD normalVector1(Wafer1->n(0),Wafer1->n(1),Wafer1->n(2));
00149 StThreeVectorD centerVector2(Wafer2->x(0),Wafer2->x(1),Wafer2->x(2));
00150 StThreeVectorD normalVector2(Wafer2->n(0),Wafer2->n(1),Wafer2->n(2));
00151 StThreeVectorD centerVector = centerVector1 + centerVector2; centerVector *= 0.5;
00152 StThreeVectorD normalVector = normalVector1 + normalVector2; normalVector *= 0.5;
00153 Double_t prod = centerVector*normalVector;
00154 if (prod < 0) normalVector *= -1;
00155 double phi = centerVector.phi();
00156 double phiD = normalVector.phi();
00157 double r = centerVector.perp();
00158 cout <<"Det Id = "<<Wafer1->getId()<<"\tcv\t:"<<centerVector<<"\tphi:\t"<<phi<<"\tr:\t"<<r<<"\tz:\t" << centerVector.z()<< endl;
00159 StiPlacement *pPlacement = new StiPlacement;
00160 pPlacement->setZcenter(centerVector.z());
00161 pPlacement->setLayerRadius(r);
00162 pPlacement->setLayerAngle(phi);
00163 pPlacement->setRegion(StiPlacement::kMidRapidity);
00164
00165 pPlacement->setNormalRep(phiD, r*TMath::Cos(phi-phiD), r*TMath::Sin(phi-phiD));
00166 sprintf(name, "Ssd/Layer_%d/Ladder_%d/Wafers", layer, ladder);
00167 StiDetector *pLadder = _detectorFactory->getInstance();
00168 pLadder->setName(name);
00169 pLadder->setIsOn(true);
00170 pLadder->setIsActive(new StiIsActiveFunctor(_active));
00171 pLadder->setIsContinuousMedium(true);
00172 pLadder->setIsDiscreteScatterer(true);
00173 pLadder->setGas(_gasMat);
00174 pLadder->setMaterial(_siMat);
00175 pLadder->setShape(ladderShape);
00176 pLadder->setPlacement(pPlacement);
00177 pLadder->setHitErrorCalculator(StiSsdHitErrorCalculator::instance());
00178 pLadder->setKey(1,0);
00179 pLadder->setKey(2,ladder-1);
00180 pLadder->setElossCalculator(siElossCalculator);
00181 add(layer,ladder,pLadder);
00182 }
00183 useVMCGeometry();
00184 }
00185
00186 void StiSsdDetectorBuilder::useVMCGeometry() {
00187 cout << "StiSsdDetectorBuilder::buildDetectors() -I- Use VMC geometry" << endl;
00188 SetCurrentDetectorBuilder(this);
00189 struct Material_t {
00190 const Char_t *name;
00191 StiMaterial **p;
00192 };
00193 Material_t map[] = {
00194 {"AIR", &_gasMat},
00195 {"SILICON", &_siMat},
00196 {"SILICON", &_hybridMat}
00197 };
00198 Int_t M = sizeof(map)/sizeof(Material_t);
00199 for (Int_t i = 0; i < M; i++) {
00200 const TGeoMaterial *mat = gGeoManager->GetMaterial(map[i].name);
00201 if (! mat) continue;
00202 Double_t PotI = StiVMCToolKit::GetPotI(mat);
00203 *map[i].p = add(new StiMaterial(mat->GetName(),
00204 mat->GetZ(),
00205 mat->GetA(),
00206 mat->GetDensity(),
00207 mat->GetDensity()*mat->GetRadLen(),
00208 PotI));
00209 }
00210 const VolumeMap_t SsdVolumes[] = {
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 {"SFLM","the mother of the ladder","HALL_1/CAVE_1/SVTT_1/SFMO_1/SFLM_1-20/*","",""}
00222
00223
00224
00225 };
00226 Int_t NoSsdVols = sizeof(SsdVolumes)/sizeof(VolumeMap_t);
00227 TString pathT("HALL_1/CAVE_1");
00228 gGeoManager->RestoreMasterVolume();
00229 gGeoManager->CdTop();
00230
00231 TString path("");
00232 for (Int_t i = 0; i < NoSsdVols; i++) {
00233 gGeoManager->RestoreMasterVolume();
00234 gGeoManager->CdTop();
00235 if (gGeoManager->cd(pathT)) {
00236 path = pathT;
00237 TGeoNode *nodeT = gGeoManager->GetCurrentNode();
00238 if (! nodeT) continue;;
00239 StiVMCToolKit::LoopOverNodes(nodeT, path, SsdVolumes[i].name, MakeAverageVolume);
00240 } else gMessMgr->Info() << "StiSsdDetectorBuilder::useVMCGeometry skip node " << pathT.Data() << endm;
00241 }
00242 }
00243
00244 ssdWafersPosition_st *StiSsdDetectorBuilder::ssdWafersPosition(Int_t Id, St_ssdWafersPosition *wafers) {
00245 Int_t N = wafers->GetNRows();
00246 ssdWafersPosition_st *wafer = wafers->GetTable();
00247 for (Int_t i = 0; i < N; i++, wafer++) if (Id == wafer->id) return wafer;
00248 return 0;
00249 }