00001 #include <stdexcept>
00002 #include "StDbUtilities/StGlobalCoordinate.hh"
00003 #include "StDbUtilities/StSvtLocalCoordinate.hh"
00004 #include "StDbUtilities/StSvtCoordinateTransform.hh"
00005 #include "StiSvtDetectorBuilder.h"
00006 #include "StSvtClassLibrary/StSvtConfig.hh"
00007 #include "StSvtClassLibrary/StSvtGeometry.hh"
00008 #include "StSvtClassLibrary/StSvtWaferGeometry.hh"
00009 #include "StSvtDbMaker/StSvtDbMaker.h"
00010 #include "StDbUtilities/St_svtRDOstrippedC.h"
00011 #include "Sti/Base/Factory.h"
00012 #include "Sti/StiPlanarShape.h"
00013 #include "Sti/StiMaterial.h"
00014 #include "Sti/StiPlacement.h"
00015 #include "Sti/StiDetector.h"
00016 #include "Sti/StiToolkit.h"
00017 #include "Sti/StiNeverActiveFunctor.h"
00018 #include "StiIsSvtActiveFunctor.h"
00019 #include "Sti/StiElossCalculator.h"
00020 #include "StDetectorDbMaker/StiSvtHitErrorCalculator.h"
00021 #include <stdio.h>
00022 #include "tables/St_HitError_Table.h"
00023 #include "StiSvtLayerLadder.h"
00024 #include "StThreeVectorD.hh"
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
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 static Int_t _debug = 0;
00105 StiSvtDetectorBuilder::StiSvtDetectorBuilder(bool active, const string & inputFile)
00106 : StiDetectorBuilder("Svt",active,inputFile), _siMat(0), _hybridMat(0){}
00107
00108 StiSvtDetectorBuilder::~StiSvtDetectorBuilder() {}
00109
00110 void StiSvtDetectorBuilder::buildDetectors(StMaker & source)
00111 {
00112 char name[50];
00113 int nRows;
00114 cout << "StiSvtDetectorBuilder::buildDetectors() -I- Started" << endl;
00115
00116 St_DataSet *dataSet = NULL;
00117 dataSet = source.GetDataSet("StSvtConfig");
00118 if (!dataSet) throw runtime_error("StiSvtDetectorBuilder::loadDb() -E- dataSet==0 while getting StSvtConfig");
00119 _config = static_cast<StSvtConfig*>(dataSet->GetObject());
00120 if (!_config) throw runtime_error("StiSvtDetectorBuilder::loadDb() -E- _config==0");
00121
00122 dataSet = source.GetDataSet("StSvtGeometry");
00123 if (!dataSet) throw runtime_error("StiSvtDetectorBuilder::loadDb() -E- dataSet==0 while getting StSvtGeometry");
00124 _geometry = static_cast<StSvtGeometry*>(dataSet->GetObject());
00125 if (!_geometry) throw runtime_error("StiSvtDetectorBuilder::loadDb() -E- _geometry==0");
00126 nRows = 2* _config->getNumberOfBarrels();
00127 setNRows(nRows);
00128
00129 cout << "SVT Number of Rows : "<<2* _config->getNumberOfBarrels()<<endl
00130 << " Layer# numberOfLadders Radius" << endl;
00131 cout << "StiSvtDetectorBuilder::buildDetectors() -I- Define Svt Materials" << endl;
00132 if (! _gasMat)
00133 _gasMat = add(new StiMaterial("Air",7.3, 14.61, 0.001205, 30420.*0.001205, 7.3*12.e-9));
00134 if (! _siMat)
00135 _siMat = add(new StiMaterial("Si", 14., 28.0855, 2.33, 21.82, 14.*12.*1e-9) );
00136 if (! _hybridMat)
00137 _hybridMat = add(new StiMaterial("Hybrid", 14., 28.0855, 2.33, 21.82, 14.*12.*1e-9) );
00138 cout << "StiSvtDetectorBuilder::buildDetectors() -I- Define Svt Shapes" << endl;
00139
00140 double ionization = _siMat->getIonization();
00141 StiElossCalculator * siElossCalculator =
00142 new StiElossCalculator(_siMat->getZOverA(), ionization*ionization, _siMat->getA(), _siMat->getZ(), _siMat->getDensity());
00143 for (int layer=0;layer<nRows;layer++) {
00144 cout << " "<<layer<<" "<<_config->getNumberOfLadders(1+layer/2)/2 << " "
00145 << _geometry->getBarrelRadius(layer+1) << endl;
00146 Int_t svtLayer = layer+1;
00147 Int_t svtBarrel = getSvtBarrel(svtLayer);
00148 int nWafers = _config->getNumberOfWafers(svtBarrel);
00149
00150 sprintf(name, "Svt/Layer_%d/Wafers", layer);
00151 _waferShape[layer] = new StiPlanarShape(name,
00152 nWafers*3.15,
00153 2.*_geometry->getWaferThickness(),
00154 3.15);
00155 add(_waferShape[layer]);
00156 int nSectors = _config->getNumberOfLadders(svtBarrel)/2;
00157 setNSectors(layer,nSectors);
00158
00159
00160
00161
00162
00163 float fLadderRadius = _geometry->getBarrelRadius(svtLayer);
00164 if (fLadderRadius<=0) throw runtime_error("StiSvtDetectorBuilder::buildDetectors() - FATAL - fLadderRadius<=0");
00165 StSvtWaferGeometry* waferGeom;
00166 Int_t index1, index2;
00167 StSvtWaferGeometry* waferGeom2;
00168 for(unsigned int ladder = 0; ladder<getNSectors(layer); ladder++) {
00169 Int_t svtLadder = 2*(ladder+1) - (svtLayer-1)%2;
00170 Int_t wafer = nWafers/2+1;
00171 index1 = _geometry->getWaferIndex(svtBarrel,svtLadder,wafer);
00172 assert (index1 >= 0);
00173 waferGeom = (StSvtWaferGeometry*) _geometry->at(index1);
00174 if (_debug) waferGeom->print();
00175 StThreeVectorD centerVector(waferGeom->x(0), waferGeom->x(1), waferGeom->x(2) );
00176 if ( nWafers%2 == 0) {
00177 index2 = _geometry->getWaferIndex(svtBarrel,svtLadder,wafer-1);
00178 assert(index2 >= 0);
00179 waferGeom2 = (StSvtWaferGeometry*) _geometry->at(index2);
00180 StThreeVectorD centerVector2(waferGeom2->x(0), waferGeom2->x(1), waferGeom2->x(2) );
00181 if (_debug) waferGeom2->print();
00182 centerVector += centerVector2;
00183 centerVector *= 0.5;
00184 }
00185 StThreeVectorD normalVector(waferGeom->n(0), waferGeom->n(1), waferGeom->n(2) );
00186 Double_t prod = centerVector.x()*normalVector.x() + centerVector.y()*normalVector.y();
00187 if (prod < 0) normalVector *= -1;
00188 double phi = centerVector.phi();
00189 double phiD = normalVector.phi();
00190 double r = centerVector.perp();
00191 cout <<"Det Id = "<<waferGeom->getID()<<"\tcv\t:"<<centerVector<<"\tphi:\t"<<phi<<"\tr:\t"<<r<<"\tz:\t" << centerVector.z() << endl;
00192 StiPlacement *pPlacement = new StiPlacement;
00193 pPlacement->setZcenter(centerVector.z());
00194 pPlacement->setLayerRadius(r);
00195 pPlacement->setLayerAngle(phi);
00196 pPlacement->setRegion(StiPlacement::kMidRapidity);
00197 pPlacement->setNormalRep(phiD, r*TMath::Cos(phi-phiD), r*TMath::Sin(phi-phiD));
00198 sprintf(name, "Svt/Layer_%d/Ladder_%d/Wafers", layer, ladder);
00199 StiDetector *pLadder = _detectorFactory->getInstance();
00200 pLadder->setName(name);
00201 pLadder->setIsOn(true);
00202 pLadder->setIsActive(new StiIsSvtActiveFunctor(svtBarrel,svtLadder, nWafers, _geometry->getWaferWidth(), _geometry->getWaferLength(), _active));
00203 pLadder->setIsContinuousMedium(true);
00204 pLadder->setIsDiscreteScatterer(true);
00205 pLadder->setGas(_gasMat);
00206 pLadder->setMaterial(_siMat);
00207 pLadder->setShape(_waferShape[layer]);
00208 pLadder->setPlacement(pPlacement);
00209 pLadder->setHitErrorCalculator(StiSvtHitErrorCalculator::instance());
00210 pLadder->setKey(1,layer);
00211 pLadder->setKey(2,ladder);
00212 pLadder->setElossCalculator(siElossCalculator);
00213 add(layer,ladder,pLadder);
00214 }
00215 }
00216 if (StiVMCToolKit::GetVMC()) {useVMCGeometry();}
00217 if (debug()) {
00218 cout << "StiSvtDetectorBuilder::buildDetectors list of built detectors" << endl;
00219 Int_t nlayers = _detectors.size();
00220 for (Int_t layer = 0; layer < nlayers; layer++) {
00221 Int_t nLadders = _detectors[layer].size();
00222 for (Int_t ladder = 0; ladder < nLadders; ladder++) {
00223 cout << "layer " << layer << "\tladder = " << ladder << "\t" << _detectors[layer][ladder]->getName() << endl;
00224 }
00225 }
00226 }
00227 }
00228
00229 void StiSvtDetectorBuilder::useVMCGeometry() {
00230 cout << "StiSvtDetectorBuilder::buildDetectors() -I- Use VMC geometry" << endl;
00231 SetCurrentDetectorBuilder(this);
00232 struct Material_t {
00233 const Char_t *name;
00234 StiMaterial **p;
00235 };
00236 Material_t map[] = {
00237 {"AIR", &_gasMat},
00238 {"SILICON", &_siMat},
00239 {"SILICON", &_hybridMat}
00240 };
00241 Int_t M = sizeof(map)/sizeof(Material_t);
00242 for (Int_t i = 0; i < M; i++) {
00243 const TGeoMaterial *mat = gGeoManager->GetMaterial(map[i].name);
00244 if (! mat) continue;
00245 Double_t PotI = StiVMCToolKit::GetPotI(mat);
00246 *map[i].p = add(new StiMaterial(mat->GetName(),
00247 mat->GetZ(),
00248 mat->GetA(),
00249 mat->GetDensity(),
00250 mat->GetDensity()*mat->GetRadLen(),
00251 PotI));
00252 }
00253 const VolumeMap_t SvtVolumes[] = {
00254 {"SOUM", "Outer shileding structure","HALL_1/CAVE_1/SVTT_1/SOUM_1/*","",""},
00255 {"SXRL", "Circular water feeds","HALL_1/CAVE_1/SVTT_1/SXRL_1-2/*","",""},
00256 {"SXR1", "Circular water feeds","HALL_1/CAVE_1/SVTT_1/SXR1_3-4/*","",""},
00257 {"SXR2", "Circular water feeds","HALL_1/CAVE_1/SVTT_1/SXR2_5-6/*","",""},
00258
00259 {"SCBL", "The bundles of cables connecting PCBs with the transition boards","HALL_1/CAVE_1/SVTT_1/SCBM_1-2/SCBL_1","",""},
00260 {"SCB1", "The bundles of cables connecting PCBs with the transition boards","HALL_1/CAVE_1/SVTT_1/SCBM_1-2/SCB1_2","",""},
00261 {"SCB2", "The bundles of cables connecting PCBs with the transition boards","HALL_1/CAVE_1/SVTT_1/SCBM_1-2/SCB2_3","",""},
00262 {"SCB3", "The bundles of cables connecting PCBs with the transition boards","HALL_1/CAVE_1/SVTT_1/SCBM_1-2/SCB3_4","",""},
00263 {"SFED", "bundles of water pipes","HALL_1/CAVE_1/SVTT_1/SCBM_1-2/SFED_1","",""},
00264 {"SFE1", "bundles of water pipes","HALL_1/CAVE_1/SVTT_1/SCBM_1-2/SFE1_2","",""},
00265 {"SFE2", "bundles of water pipes","HALL_1/CAVE_1/SVTT_1/SCBM_1-2/SFE2_3","",""},
00266 {"SPLS", "plastic of the water pipes","HALL_1/CAVE_1/SVTT_1/SCBM_1-2/SPLS_1","",""},
00267 {"SPL1", "plastic of the water pipes","HALL_1/CAVE_1/SVTT_1/SCBM_1-2/SPL1_2","",""},
00268 {"SPL2", "plastic of the water pipes","HALL_1/CAVE_1/SVTT_1/SCBM_1-2/SPL2_3","",""},
00269 {"SALM", "aluminum shield mesh","HALL_1/CAVE_1/SVTT_1/SALM_1-2","",""},
00270 {"SOSH", "SVT outer shield","HALL_1/CAVE_1/SVTT_1/SOSH_1","",""},
00271 {"SISH", "SVT inner shield","HALL_1/CAVE_1/SVTT_1/SISH_1","",""},
00272
00273
00274
00275
00276
00277
00278 {"SELE","electronics mother volume","HALL_1/CAVE_1/SVTT_1/SLYD_1/SLSD_1/SELE_1","",""},
00279 #if 1
00280 {"SEL1","electronics mother volume","HALL_1/CAVE_1/SVTT_1/SLYD_2/SLSD_1/SELE_1","",""},
00281 {"SEL2","electronics mother volume","HALL_1/CAVE_1/SVTT_1/SLYD_3/SLSD_1/SELE_1","",""},
00282 {"SEL3","electronics mother volume","HALL_1/CAVE_1/SVTT_1/SLYD_4/SLSD_1/SELE_1","",""},
00283 {"SEL4","electronics mother volume","HALL_1/CAVE_1/SVTT_1/SLYD_5/SLSD_1/SELE_1","",""},
00284 {"SEL5","electronics mother volume","HALL_1/CAVE_1/SVTT_1/SLYD_6/SLSD_1/SELE_1","",""},
00285 #endif
00286
00287 {"SBWC", "water manifold to support cone bracket mother","HALL_1/CAVE_1/SVTT_1/SBWC_1-2/*","",""},
00288 {"SWMM", "water manifold mother","HALL_1/CAVE_1/SVTT_1/SWMM_1-2/*","",""},
00289 {"SIES", "Volume to hold inner endring screws","HALL_1/CAVE_1/SVTT_1/SIES_1-2/*","",""},
00290 {"SOES", "Volume to hold outer endring screws","HALL_1/CAVE_1/SVTT_1/SOES_1-2/*","",""},
00291 {"SBRG", "Bracket joining the end rungs","HALL_1/CAVE_1/SVTT_1/SBRG_1-2/*","",""},
00292 {"SOER", "outer end ring","HALL_1/CAVE_1/SVTT_1/SOER_1-2/*","",""},
00293 {"SIRT", "inner end ring tube piece ","HALL_1/CAVE_1/SVTT_1/SIRT_1-2","",""},
00294 {"SIRP", "inner end ring polygon piece ","HALL_1/CAVE_1/SVTT_1/SIRP_1-2","",""}
00295
00296
00297 };
00298 Int_t NoSvtVols = sizeof(SvtVolumes)/sizeof(VolumeMap_t);
00299 TString pathT("HALL_1/CAVE_1");
00300 TString path("");
00301 for (Int_t i = 0; i < NoSvtVols; i++) {
00302 gGeoManager->RestoreMasterVolume();
00303 gGeoManager->CdTop();
00304 gGeoManager->cd(pathT); path = pathT;
00305 TGeoNode *nodeT = gGeoManager->GetCurrentNode();
00306 if (! nodeT) continue;
00307 StiVMCToolKit::LoopOverNodes(nodeT, path, SvtVolumes[i].name, MakeAverageVolume);
00308 }
00309 }