// ------------------------------------------------------------------------- // ----- CbmLitEnvironment source file ----- // ----- Created 16/07/07 by A. Lebedev ----- // ------------------------------------------------------------------------- #include "CbmLitEnvironment.h" #include "CbmRunAna.h" #include "CbmBaseParSet.h" #include "CbmRuntimeDb.h" #include "CbmDetector.h" #include "CbmGeoStsPar.h" #include "CbmGeoRichPar.h" #include "CbmGeoTrdPar.h" #include "CbmGeoPassivePar.h" #include "CbmGeoMuchPar.h" #include CbmLitEnvironment* CbmLitEnvironment::fInstance = NULL; // constructors CbmLitEnvironment::CbmLitEnvironment(): fThickWall(5.), fField(NULL), fNofStations(0), fNofLayers(0) { fvMaterials.clear(); fNofLayersPerStation.clear();; } // destructor CbmLitEnvironment::~CbmLitEnvironment() { if (fInstance != NULL) delete fInstance; for (std::vector::iterator i = fvMaterials.begin(); i != fvMaterials.end(); i++) delete (*i); fvMaterials.clear(); } // CbmLitEnvironment* CbmLitEnvironment::Instance() { if (fInstance == NULL) { fInstance = new CbmLitEnvironment(); } return fInstance; } // Initialization void CbmLitEnvironment::Init() { } // Field CbmField* CbmLitEnvironment::GetField() { if (fField == NULL) { CbmRunAna *Run = CbmRunAna::Instance(); if(NULL == Run) { std::cout << "-E- CbmLitEnvironment::GetField : " << "Run Ana is not instantiated" << std::endl; return NULL; } std::cout << "-I- CbmLitEnvironment::GetField : " << "Reading Magnetic Field " << std::endl; fField = (CbmField*) Run->GetField(); } return fField; } // void CbmLitEnvironment::GetMuchLayout(Int_t &nofStations, Int_t &nofLayers, std::vector &nofLayersPerStation, std::vector &layersZPos) { CbmRunAna *Run = CbmRunAna::Instance(); CbmRuntimeDb *RunDB = Run->GetRuntimeDb(); CbmGeoMuchPar *MuchPar = (CbmGeoMuchPar*) (RunDB->findContainer("CbmGeoMuchPar")); std::set zPosSet; if( MuchPar ){ TObjArray* Nodes = MuchPar->GetGeoSensitiveNodes(); for( Int_t i=0;iGetEntries(); i++){ CbmGeoNode *node = dynamic_cast (Nodes->At(i)); TArrayD *P = node->getParameters(); CbmGeoVector nodeV = node->getLabTransform()->getTranslation(); //in cm CbmGeoVector centerV = node->getCenterPosition().getTranslation(); Double_t zPos = nodeV.Z()+centerV.Z(); Int_t NP = node->getShapePointer()->getNumParam(); Int_t Nz = (NP-3)/3; double Z = -100000,z = 100000; for (Int_t i = 0; i < Nz; i++) { double z1 = P->At(3+i*3+0); if( z1Z ) Z = z1; } zPos += Double_t(z+Z)/2.; zPosSet.insert(zPos); } } else { TObject::Fatal("CbmLitEnvironment", "Can't load CbmGeoMuchPar"); } nofLayersPerStation.clear(); layersZPos.clear(); nofLayers = zPosSet.size(); nofStations = 0; Int_t layers = 0; Double_t prev; Int_t cnt = 0; for (std::set::iterator i = zPosSet.begin(); i != zPosSet.end(); i++) { if (i != zPosSet.begin()) { std::cout << "(prev - *i)" << (prev - *i) << std:: endl; if ((*i - prev) > 20.) { nofStations++; nofLayersPerStation.push_back(layers); layers = 0; } if (cnt == nofLayers-1) { nofStations++; nofLayersPerStation.push_back(++layers); } } layers++; cnt++; prev = *i; } layersZPos.reserve(nofLayers); for (std::set::iterator i = zPosSet.begin(); i != zPosSet.end(); i++) { layersZPos.push_back(*i); } std::cout << "----->MuCh geometry<-----" << std::endl; std::cout << " number of layers: " << nofLayers << std::endl; std::cout << " number of stations: " << nofStations << std::endl; std::cout << " number of layers per station: "; for (int i=0; i < nofStations; i++) std::cout << " " << nofLayersPerStation[i] << ","; std::cout << std::endl; std::cout << " layers z positions: "; for (int i=0; i < nofLayers; i++) std::cout << " " << layersZPos[i] << ","; std::cout << std::endl; } // void CbmLitEnvironment::GetTrdLayout(Int_t &nofStations, Int_t &nofLayers, std::vector &nofLayersPerStation, std::vector &layersZPos) { /* if (nofStations == 0 || nofLayers == 0 || nofLayersPerStation.empty()) { // Get the pointer to the CbmRunAna object CbmRunAna* ana = CbmRunAna::Instance(); if(NULL == ana) { std::cout << "-E- CbmLitEnvironment::ReadTrdLayoutt :" << " no CbmRunAna object!" << std::endl; return; } // Get the pointer to run-time data base CbmRuntimeDb* rtdb = ana->GetRuntimeDb(); if(NULL == rtdb) { std::cout << "-E- CbmLitEnvironment::ReadTrdLayout :" << " no runtime database!" << std::endl; return; } // Get the pointer to container of base parameters CbmBaseParSet* baseParSet = (CbmBaseParSet*) rtdb->getContainer("CbmBaseParSet"); if(NULL == baseParSet) { std::cout << "-E- CbmLitEnvironment::ReadTrdLayout :" << " no container of base parameters!" << std::endl; return; } // Get the pointer to detector list TObjArray *detList = baseParSet->GetDetList(); if(NULL == detList) { std::cout << "-E- CbmLitEnvironment::ReadTrdLayout :" << " no detector list!" << std::endl; return; } // Find TRD detector CbmDetector* trd = (CbmDetector*) detList->FindObject("TRD"); if(NULL == trd) { std::cout << "-E- CbmLitEnvironment::ReadTrdLayout :" << " no TRD detector!" << std::endl; return; } // Determine the geometry version TString name = trd->GetGeometryFileName(); if(name.Contains("9") || name.Contains("3-3-3")) { std::cout << "-I- CbmLitEnvironment::ReadTrdLayout :" << " TRD geometry : 3x3." << std::endl; fNofStations = 3; fNofLayersPerStation.resize(3); for (Int_t i = 0; i < 3; i++) fNofLayersPerStation[i] = 3; fNofLayers = 9; } else if(name.Contains("12") || name.Contains("standard") || name.Contains("segmented") || name.Contains("4-4-4")) { std::cout << "-I- CbmLitEnvironment::ReadTrdLayout :" << " TRD geometry : 3x4." << std::endl; fNofStations = 3; fNofLayersPerStation.resize(3); for (Int_t i = 0; i < 3; i++) fNofLayersPerStation[i] = 4; fNofLayers = 12; } else if(name.Contains("6x2")) { std::cout << "-I- CbmLitEnvironment::ReadTrdLayout :" << " TRD geometry : 6x2." << std::endl; fNofStations = 6; fNofLayersPerStation.resize(6); for (Int_t i = 0; i < 6; i++) fNofLayersPerStation[i] = 2; fNofLayers = 12; } else if(name.Contains("4-3-3")) { std::cout << "-I- CbmLitEnvironment::ReadTrdLayout :" << " TRD geometry : 4-3-3." << std::endl; fNofStations = 3; fNofLayersPerStation.resize(3); fNofLayersPerStation[0] = 4; fNofLayersPerStation[1] = 3; fNofLayersPerStation[2] = 3; fNofLayers = 10; } else if(name.Contains("trd-4-2-2")) { std::cout << "-I- CbmLitEnvironment::ReadTrdLayout :" << " TRD geometry : 4-2-2." << std::endl; fNofStations = 3; fNofLayersPerStation.resize(3); fNofLayersPerStation[0] = 4; fNofLayersPerStation[1] = 2; fNofLayersPerStation[2] = 2; fNofLayers = 8; } else if(name.Contains("trd-2-2-2")) { std::cout << "-I- CbmLitEnvironment::ReadTrdLayout :" << " TRD geometry : 2-2-2." << std::endl; fNofStations = 3; fNofLayersPerStation.resize(3); for (Int_t i = 0; i < 3; i++) fNofLayersPerStation[i] = 2; fNofLayers = 6; } } nofStations = fNofStations; nofLayers = fNofLayers; nofLayersPerStation = fNofLayersPerStation; */ CbmRunAna *Run = CbmRunAna::Instance(); CbmRuntimeDb *RunDB = Run->GetRuntimeDb(); CbmGeoTrdPar *trdPar = (CbmGeoTrdPar*) (RunDB->findContainer("CbmGeoTrdPar")); std::set zPosSet; if( trdPar ){ TObjArray* Nodes = trdPar->GetGeoSensitiveNodes(); for( Int_t i = 0; i < Nodes->GetEntries(); i++){ CbmGeoNode *node = dynamic_cast (Nodes->At(i)); TArrayD *P = node->getParameters(); TString shapeName = node->getShapePointer()->GetName(); CbmGeoVector nodeV = node->getLabTransform()->getTranslation(); CbmGeoVector centerV = node->getCenterPosition().getTranslation(); if (shapeName.Contains("PGON")) { Double_t zPos = nodeV.Z() + centerV.Z() + ( 1 * P->At(4)); zPosSet.insert(zPos); } else { TObject::Fatal("CbmLitEnvironment", "Unrecognized shape..."); } } } else { TObject::Fatal("CbmLitEnvironment", "Can't load CbmGeoMuchPar"); } nofLayersPerStation.clear(); layersZPos.clear(); nofLayers = zPosSet.size(); nofStations = 0; Int_t layers = 0; Double_t prev; Int_t cnt = 0; for (std::set::iterator i = zPosSet.begin(); i != zPosSet.end(); i++) { if (i != zPosSet.begin()) { std::cout << "(prev - *i)" << (prev - *i) << std:: endl; if ((*i - prev) > 20.) { nofStations++; nofLayersPerStation.push_back(layers); layers = 0; } if (cnt == nofLayers-1) { nofStations++; nofLayersPerStation.push_back(++layers); } } layers++; cnt++; prev = *i; } layersZPos.reserve(nofLayers); for (std::set::iterator i = zPosSet.begin(); i != zPosSet.end(); i++) { layersZPos.push_back(*i); } std::cout << "----->TRD geometry<-----" << std::endl; std::cout << " number of layers: " << nofLayers << std::endl; std::cout << " number of stations: " << nofStations << std::endl; std::cout << " number of layers per station: "; for (int i=0; i < nofStations; i++) std::cout << " " << nofLayersPerStation[i] << ","; std::cout << std::endl; std::cout << " layers z positions: "; for (int i=0; i < nofLayers; i++) std::cout << " " << layersZPos[i] << ","; std::cout << std::endl; } // void CbmLitEnvironment::GetStsLayout() { } // const std::vector & CbmLitEnvironment::GetMaterials() { if (fvMaterials.empty()) { fvMaterials.clear(); //ReadStsMaterials(); ReadRichMaterials(); ReadTrdMaterials(); ReadMuchMaterials(); sort(fvMaterials.begin(), fvMaterials.end(), CbmLitMaterial::CmpUp); std::cout << "-I- CbmLitEnvironment::ReadMaterials(): " << std::endl; std::cout << " Material : [ Name, Z, Thickness, RadLength, Density, Zeff/Aeff, Rmin, Rmax" << std::endl; std::cout.precision(5); for (UInt_t i = 0; i < fvMaterials.size(); i++) { std::cout << " Material : [ " << fvMaterials[i]->GetName() << ", " << fvMaterials[i]->GetZ() << ", " << fvMaterials[i]->GetThickness() << ", " << fvMaterials[i]->GetRadLength() << ", " << fvMaterials[i]->GetDensity() << ", " << fvMaterials[i]->GetZeff() / fvMaterials[i]->GetAeff() << "] " << std::endl; } std::cout << "-I- CbmLitEnvironment::ReadMaterials(): " << "materials initialized." << std::endl; } return fvMaterials; } void CbmLitEnvironment::ReadStsMaterials(TObjArray *Nodes) { } void CbmLitEnvironment::ReadStsMaterials() { } void CbmLitEnvironment::ReadTrdMaterials(TObjArray *Nodes) { for(Int_t i = 0; i < Nodes->GetEntries(); i++){ CbmGeoNode *node = dynamic_cast (Nodes->At(i)); if (!node) continue; CbmLitCircleMaterial* mat = new CbmLitCircleMaterial(); if (0 == ReadRichNode(mat, node)) fvMaterials.push_back(mat); else delete mat; } } void CbmLitEnvironment::ReadTrdMaterials() { std::cout << "CbmLitEnvironment::ReadTrdMaterials: " << std::endl; std::cout << " reading TRD materials..." << std::endl; CbmRunAna *Run = CbmRunAna::Instance(); CbmRuntimeDb *RunDB = Run->GetRuntimeDb(); CbmGeoTrdPar *TrdPar = (CbmGeoTrdPar*) (RunDB->getContainer("CbmGeoTrdPar")); TObjArray *NodesActive = TrdPar->GetGeoSensitiveNodes(); TObjArray *NodesPassive = TrdPar->GetGeoPassiveNodes(); std::cout << " TRD Active Nodes:" << std::endl; if (NodesActive) ReadTrdMaterials(NodesActive); std::cout << " TRD Passive Nodes:" << std::endl; if (NodesPassive) ReadTrdMaterials(NodesPassive); } void CbmLitEnvironment::ReadRichMaterials() { std::cout << "CbmLitEnvironment::ReadRichMaterials: " << std::endl; CbmRunAna *Run = CbmRunAna::Instance(); CbmRuntimeDb *RunDB = Run->GetRuntimeDb(); CbmGeoRichPar *RichPar = (CbmGeoRichPar*) (RunDB->getContainer("CbmGeoRichPar")); if( RichPar ) { std::cout << "CbmLitEnvironment::ReadRichMaterials" << std::endl; CbmGeoNode* rich1entrance = NULL; // entrance window CbmGeoNode* rich1exit = NULL; // exit window CbmGeoNode* rich1gas = NULL; CbmGeoNode* rich1mgl = NULL; TObjArray *NodesActive = RichPar->GetGeoSensitiveNodes(); TObjArray *NodesPassive = RichPar->GetGeoPassiveNodes(); std::cout << " RICH active nodes:" << std::endl; for (Int_t i = 0; i < NodesActive->GetEntries(); i++) { CbmGeoNode *node = dynamic_cast (NodesActive->At(i)); if ( !node ) continue; TString name = node->getName(); std::cout << name << std::endl; if(name == "rich1mgl#1") { // RICH mirror (currently sensitive! - will change soon!) rich1mgl = node; } } std::cout << " RICH passive nodes:" << std::endl; for (Int_t i = 0; i < NodesPassive->GetEntries(); i++) { CbmGeoNode *node = dynamic_cast (NodesPassive->At(i)); if ( !node ) continue; TString name = node->getName(); std::cout << name << std::endl; if(name == "rich1entrance") { // RICH entrance window rich1entrance = node; } else if(name == "rich1mgl#1") { // RICH mirror (see above) rich1mgl = node; } else if(name == "rich1gas1") { // RICH gas rich1gas = node; } else if(name == "rich1exit") { // RICH exit window rich1exit = node; } } if(rich1entrance && rich1gas && rich1mgl && rich1exit ) { CbmLitCircleMaterial* kapton1 = new CbmLitCircleMaterial(); if (0 == ReadRichNode( kapton1, rich1entrance)) fvMaterials.push_back(kapton1); CbmLitCircleMaterial* kapton2 = new CbmLitCircleMaterial(); if (0 == ReadRichNode( kapton2, rich1exit)) fvMaterials.push_back(kapton2); CbmLitCircleMaterial* mirror = new CbmLitCircleMaterial(); if (0 == ReadRichNode( mirror, rich1mgl)) fvMaterials.push_back(mirror);; CbmLitCircleMaterial* gas1 = new CbmLitCircleMaterial(); if ( 0 == ReadRichNode( gas1, rich1gas)) { CbmLitCircleMaterial *gas2 = new CbmLitCircleMaterial(*gas1); gas1->SetZ( 0.5*( (kapton1->GetZ() + kapton1->GetThickness()/2.) + (mirror->GetZ() - mirror->GetThickness()/2.) ) ); gas1->SetThickness( (mirror->GetZ() - mirror->GetThickness()/2.) - (kapton1->GetZ() + kapton1->GetThickness()/2.)); gas2->SetZ( 0.5*( (mirror->GetZ() + mirror->GetThickness()/2.) + (kapton2->GetZ() - kapton2->GetThickness()/2.) ) ); gas2->SetThickness( (kapton2->GetZ() - kapton2->GetThickness()/2.) - (mirror->GetZ() + mirror->GetThickness()/2.) ); fvMaterials.push_back(gas1); fvMaterials.push_back(gas2); } } } } void CbmLitEnvironment::ReadMuchMaterials() { CbmRunAna *run = CbmRunAna::Instance(); CbmRuntimeDb *runDB = run->GetRuntimeDb(); CbmGeoMuchPar *muchPar = (CbmGeoMuchPar*) (runDB->findContainer("CbmGeoMuchPar")); if (muchPar) { std::cout << "CbmLitEnvironment::ReadMuchMaterials: " << std::endl; std::cout << " MUCH passive nodes:" << std::endl; TObjArray *nodes = muchPar->GetGeoPassiveNodes(); for (Int_t i = 0; i < nodes->GetEntries(); i++) { CbmGeoNode *node = dynamic_cast (nodes->At(i)); CbmLitCircleMaterial* mat = new CbmLitCircleMaterial(); if (0 == ReadRichNode(mat, node)) fvMaterials.push_back(mat); else delete mat; } std::cout << " MUCH sensitive nodes:" << std::endl; nodes = muchPar->GetGeoSensitiveNodes(); for (Int_t i = 0; i < nodes->GetEntries(); i++){ CbmGeoNode *node = dynamic_cast (nodes->At(i)); CbmLitCircleMaterial* mat = new CbmLitCircleMaterial(); if (0 == ReadRichNode( mat, node)) fvMaterials.push_back(mat); else delete mat; } } } Int_t CbmLitEnvironment::ReadRichNode(CbmLitCircleMaterial *mat, CbmGeoNode *node) { if (!node) return 1; //TString nodeName = node->getName(); CbmGeoVector nodeV = node->getLabTransform()->getTranslation(); CbmGeoVector centerV = nodeV + node->getCenterPosition().getTranslation(); CbmGeoMedium *medium = node->getMedium(); medium->calcRadiationLength(); mat->SetRadLength(medium->getRadiationLength()); // mat->SetZ(nodeV.Z() + centerV.Z()); TString shapeName = node->getShapePointer()->GetName(); TArrayD *P = node->getParameters(); //Int_t NP = node->getShapePointer()->getNumParam(); Int_t nofComponents = medium->getNComponents(); Double_t Zeff = 0.; Double_t Aeff = 0.; Double_t W = 0.; for (Int_t iComp = 0; iComp < nofComponents; iComp++) { Double_t p[3]; medium->getComponent(iComp, p); W += p[2]; } for (Int_t iComp = 0; iComp < nofComponents; iComp++) { Double_t p[3]; medium->getComponent(iComp, p); Aeff += p[0] * p[2]; Zeff += p[1] * p[2]; } Aeff /= W; Zeff /= W; mat->SetDensity(medium->getDensity()); mat->SetAeff(Aeff); mat->SetZeff(Zeff); mat->SetName(shapeName); Int_t result = 1; if (shapeName.Contains("TRAP")) { // for the RICH mat->SetInnerRadius(0.); mat->SetOuterRadius(1000.); mat->SetXCenter(0.); mat->SetYCenter(0.); mat->SetThickness(2. * P->At(0)); //if (mat->GetThickness() > fThickWall) mat->SetZ(centerV.Z() + mat->GetThickness()/2.); //else mat->SetZ(centerV.Z()); std::cout << " shape is : " << shapeName << std::endl; result = 0; } else if (shapeName.Contains("SPHE")) { // for the RICH mat->SetInnerRadius(0.); mat->SetOuterRadius(1000.); mat->SetXCenter(0.); mat->SetYCenter(0.); mat->SetThickness(P->At(1) - P->At(0)); mat->SetZ(centerV.Z() + 0.5 * (P->At(0) + P->At(1))); std::cout << " shape is : " << shapeName << std::endl; result = 0; } else if (shapeName.Contains("PCON")) { // for the MUCH Int_t np = node->getShapePointer()->getNumParam(); Int_t nz = (np - 3) / 3; Double_t Z = -100000, R = -100000, z = 100000, r = 100000; for (Int_t i = 0; i < nz; i++) { Double_t z1 = P->At(3 + i * 3 + 0); Double_t r1 = P->At(3 + i * 3 + 1); Double_t R1 = P->At(3 + i * 3 + 2); if (r1 < r) r = r1; if (R1 > R) R = R1; if (z1 < z) z = z1; if (z1 > Z) Z = z1; } mat->SetInnerRadius(r); mat->SetOuterRadius(R); mat->SetXCenter(centerV.X()); mat->SetYCenter(centerV.Y()); mat->SetThickness(Z-z); if (mat->GetThickness() > fThickWall) mat->SetZ(centerV.Z() + Double_t(z+Z)/2. + mat->GetThickness() / 2.); else mat->SetZ(centerV.Z() + Double_t(z+Z)/2.); std::cout << " shape is : " << shapeName << std::endl; result = 0; } else if (shapeName.Contains("PGON")) { // for the TRD Int_t np = node->getShapePointer()->getNumParam(); Int_t nz = (np - 4) / 3; Double_t Z = -100000, R = -100000, z = 100000, r = 100000; for (Int_t i = 0; i < nz; i++) { Double_t z1 = P->At(4 + i * 3 + 0); Double_t r1 = P->At(4 + i * 3 + 1); Double_t R1 = P->At(4 + i * 3 + 2); if (r1 < r) r = r1; if (R1 > R) R = R1; if (z1 < z) z = z1; if (z1 > Z) Z = z1; } mat->SetInnerRadius(r); mat->SetOuterRadius(R); mat->SetXCenter(centerV.X()); mat->SetYCenter(centerV.Y()); mat->SetThickness(Z-z); if (mat->GetThickness() > fThickWall) mat->SetZ(centerV.Z() + mat->GetThickness()/2.); else mat->SetZ(centerV.Z()); std::cout << " shape is : " << shapeName << std::endl; result = 0; } else { std::cout <<" unknown shape : "<< shapeName << std::endl; result = 1; } if (result){ std::cout.precision(6); std::cout << " -----> material : [ " << mat->GetName() << ", " << mat->GetZ() << ", " << mat->GetThickness() << ", " << mat->GetRadLength() << ", " << mat->GetDensity() << ", " << mat->GetZeff() / mat->GetAeff() << ", " << mat->GetInnerRadius() << ", " << mat->GetOuterRadius() << "] " << std::endl; } return result; } ClassImp(CbmLitEnvironment)