TGeoVolume* KVSpectroDetector::GetGeoVolume(const Char_t* name, const Char_t* material, const Char_t* shape_name, const Char_t* params){ // Construct a TGeoVolume shape which can be used to represent // a detector in the current geometry managed by gGeoManager. // If the argument material is empty, the name of the detector is used. // Input: name - name given to the volume. // material - material of the volume. The list of available // materials can be found with // det->GetRangeTable()->GetListOfMaterials()->ls() // where det is a KVSpectroDetector or another // object inheriting from KVMaterial. // shape_name - name of the shape associated to the volum // (Box, Arb8, Cone, Sphere, ...), given // by the short name of the shape used in // the methods XXX: // TGeoManger::MakeXXX(...) TGeoMedium *med = GetGeoMedium(material); if(!med) return NULL; TString method = Form("Make%s",shape_name); TString parameters = Form("%p,%p,%s",name,med,params); Info("GetGeoVolume","Trying to run the command gGeoManager->%s(%s)",method.Data(),parameters.Data()); gGeoManager->Execute(method.Data(),parameters.Data()); TGeoVolume* vol = (TGeoVolume*)gGeoManager->GetListOfVolumes()->Last(); if(vol) vol->SetLineColor(med->GetMaterial()->GetDefaultColor()); return vol; }
double EUTelGeometryTelescopeGeoDescription::FindRad(Eigen::Vector3d const & startPt, Eigen::Vector3d const & endPt) { Eigen::Vector3d track = endPt-startPt; double length = track.norm(); track.normalize(); double snext; Eigen::Vector3d point; Eigen::Vector3d direction; double epsil = 0.00001; double rad = 0.; double propagatedDistance = 0; bool reachedEnd = false; TGeoMedium* med; gGeoManager->InitTrack(startPt(0), startPt(1), startPt(2), track(0), track(1), track(2)); TGeoNode* nextnode = gGeoManager->GetCurrentNode(); while(nextnode && !reachedEnd) { med = nullptr; if (nextnode) med = nextnode->GetVolume()->GetMedium(); nextnode = gGeoManager->FindNextBoundaryAndStep(length); snext = gGeoManager->GetStep(); if( propagatedDistance+snext >= length ) { snext = length - propagatedDistance; reachedEnd = true; } //snext gets very small at a transition into a next node, in this case we need to manually propagate a small (epsil) //step into the direction of propagation. This introduces a small systematic error, depending on the size of epsil as if(snext < 1.e-8) { const double * currDir = gGeoManager->GetCurrentDirection(); const double * currPt = gGeoManager->GetCurrentPoint(); direction(0) = currDir[0]; direction(1) = currDir[1]; direction(2) = currDir[2]; point(0) = currPt[0]; point(1) = currPt[1]; point(2) = currPt[2]; point = point + epsil*direction; gGeoManager->CdTop(); nextnode = gGeoManager->FindNode(point(0),point(1),point(2)); snext = epsil; } if(med) { //ROOT returns the rad length in cm while we use mm, therefore factor of 10 double radlen = med->GetMaterial()->GetRadLen(); if (radlen > 1.e-5 && radlen < 1.e10) { rad += snext/(radlen*10); } } propagatedDistance += snext; } return rad; }
void Run(const std::string& medName, const std::string& pdgName) { TGeant3* mc = static_cast<TGeant3*>(gMC); if (!mc) { std::cerr << "Couldn't get VMC" << std::endl; return; } TGeoMedium* medium = gGeoManager->GetMedium(medName.c_str()); if (!medium) { std::cerr << "Couldn't find medium " << medName << std::endl; return; } int medNo = medium->GetMaterial()->GetUniqueID(); TDatabasePDG* pdgDb = TDatabasePDG::Instance(); fPDG = pdgDb->GetParticle(pdgName.c_str()); if (!fPDG) { std::cerr << "Couldn't find particle " << pdgName << std::endl; return; } int pdgNo = fPDG->PdgCode(); int pidNo = mc->IdFromPDG(pdgNo); std::stringstream vars; vars << "betagamma/F"; size_t nOk = 0; // Loop over defined mechanisms for (mech_array::iterator i = fMechs.begin(); i != fMechs.end(); ++i) { if (!(*i)->Get(mc, fTKine, fCuts, medNo, pidNo, fPDG->Mass()))continue; vars << ":" << (*i)->fMech.fName; nOk ++; } std::stringstream tName; tName << medName << "_" << pdgName; TTree* tree = new TTree(tName.str().c_str(), tName.str().c_str()); float_array cache(nOk+1); tree->Branch("xsec", &(cache[0]), vars.str().c_str()); for (size_t i = 0; i < fTKine.size(); i++) { cache[0] = fTKine[i] / fPDG->Mass(); int k = 0; for (mech_array::iterator j = fMechs.begin(); j != fMechs.end(); ++j) { if (!(*j)->fStatus) continue; cache[++k] = (*j)->fValues[i]; } tree->Fill(); } tree->Write(); }
//_____________________________________________________________________________ void StarMCHits::MakeDetectorDescriptors() { if (! gGeoManager) { cout << "No gGeoManager" << endl; return; } TDataSet *Detectors = StMaker::GetChain()->GetDataBase("VmcGeometry/Index"); if (! Detectors) { cout << "No Detectors found in VmcGeometry/Index" << endl; } // Make List of sensitive volumes TObjArray *vols = gGeoManager->GetListOfVolumes(); Int_t nvol = vols->GetEntriesFast(); Int_t nSensVol = 0; Int_t nsize = 100; TArrayI Indx(nsize); Int_t *indx = Indx.GetArray(); for (Int_t i = 0; i < nvol; i++) { TGeoVolume *vol = (TGeoVolume *) vols->At(i); if (! vol) continue; TGeoMedium *med = vol->GetMedium(); if (! med) continue; Int_t isvol = (Int_t) med->GetParam(0); if (! isvol) continue; indx[nSensVol] = i; nSensVol++; if (nSensVol >= nsize) { nsize *= 2; Indx.Set(nsize); indx = Indx.GetArray(); } TString Path(MakeDetectorDescriptor(vol->GetName())); if (Detectors) { // Check consistency StarVMCDetector *det = (StarVMCDetector *) Detectors->Find(vol->GetName()); if (! det) { cout << "Detector description for " << vol->GetName() << "\t" << vol->GetTitle() << " is missing" << endl; } else { TString FMT = det->GetFMT(); cout << "Found path:\t" << Path.Data() << endl; cout << "Set path:\t" << FMT.Data(); if (Path == FMT) cout << " are the same" << endl; else cout << " are the different" << endl; } } } }
TGeoVolume* KVSpectroDetector::GetGeoVolume(const Char_t* name,const Char_t* material, TGeoShape* shape){ // Construct a TGeoVolume shape which can be used to represent // a detector in the current geometry managed by gGeoManager. // If the argument material is empty, the name of the detector is used. // Input: name - name given to the volume. // material - material of the volume. The list of available // materials can be found with // det->GetRangeTable()->GetListOfMaterials()->ls() // where det is a KVSpectroDetector or another // object inheriting from KVMaterial. // shape - shape of the volume. TGeoMedium *med = GetGeoMedium(material); if(!med) return NULL; TGeoVolume* vol = new TGeoVolume(name,shape,med); if(vol) vol->SetLineColor(med->GetMaterial()->GetDefaultColor()); return vol; }
void AliITSMaterialsTGeo(TString gfile="geometry.root"){ // Macro to print out the ITS material definitions as found // in the TGeo geometry file. // retrives geometry if(!gGeoManager) gGeoManager = new TGeoManager(); TGeoManager::Import(gfile.Data()); if (!gGeoManager) { cout<<"geometry not found\n"; return; } // end if TList *medlist=gGeoManager->GetListOfMedia(); TGeoMedium *med; TGeoMaterial *mat; Int_t imed,nmed,i; printf("imed Id Med_Name Mat_Name "); for(i=0;i<20;i++) printf(" par[%2d] ",i); printf("\n"); imed=0; do{ med = (TGeoMedium*)(medlist->At(imed)); if(!med) continue; /*if((((med->GetName())[0]=='I')&& // Only ITS. ((med->GetName())[1]=='T')&& ((med->GetName())[2]=='S')&& ((med->GetName())[3]=='_')))*/{ mat = med->GetMaterial(); if(mat) printf("%4d %4d %30s %30s",imed,med->GetId(),med->GetName(),mat->GetName()); else printf("%4d %4d %30s %30s",imed,med->GetId(),med->GetName(),"No Material"); for(i=0;i<20;i++) printf(" %12g",med->GetParam(i)); printf("\n"); imed++; } }while(med!=medlist->Last()); }
TGeoMedium* KVSpectroDetector::GetGeoMedium(const Char_t* mat_name){ // By default, return pointer to TGeoMedium corresponding to this KVMaterial. // If argument "mat_name" is given, a pointer to a medium is return for this material. // mat_name = "Vacuum" is a special case: if the "Vacuum" does not exist, we create it. // // Instance of geometry manager class TGeoManager must be created before calling this // method, otherwise 0x0 will be returned. // If the required TGeoMedium is not already available in the TGeoManager, we create // a new TGeoMedium corresponding to the material given in argument. if( !gGeoManager ) return NULL; TString medName, matName; if( !strcmp(mat_name,"") ){ // for gaseous materials, the TGeoMedium/Material name is of the form // gasname_pressure // e.g. C3F8_37.5 for C3F8 gas at 37.5 torr // each gas with different pressure has to have a separate TGeoMaterial/Medium matName = GetName(); KVIonRangeTableMaterial* irmat = KVMaterial::GetRangeTable()->GetMaterial(matName.Data()); if(irmat->IsGas()) medName.Form("%s_%f", matName.Data(), GetPressure()); else medName = GetName(); } else{ matName = mat_name; medName = mat_name; } TGeoMedium* gmed = gGeoManager->GetMedium( medName); if( gmed ) return gmed; TGeoMaterial *gmat = gGeoManager->GetMaterial( medName); if( !gmat ){ if( !strcmp(matName.Data(), "Vacuum") ){ // create material gmat = new TGeoMaterial("Vacuum",0,0,0 ); } else{ // create material gmat = GetRangeTable()->GetTGeoMaterial(matName.Data()); if(!gmat){ Error("GetGeoMedium","Material %s is nowhere to be found in %s" ,matName.Data(),GetRangeTable()->GetName()); return NULL; } gmat->SetPressure( GetPressure() ); gmat->SetTemperature( GetTemperature() ); gmat->SetTransparency(0); } } // For the moment the names of material and medium do not // depend on the temperature of the material. gmat->SetName(medName); gmat->SetTitle(matName); // create medium TGeoMedium* lastmed = (TGeoMedium*)gGeoManager->GetListOfMedia()->Last(); Int_t numed = (lastmed ? lastmed->GetId()+1 : 0); // static counter variable used to number media gmed = new TGeoMedium( medName, numed, gmat ); numed+=1; return gmed; }
TGeoMedium* KVMaterial::GetGeoMedium(const Char_t* med_name) { // By default, return pointer to TGeoMedium corresponding to this KVMaterial. // If argument "med_name" is given and corresponds to the name of an already existing // medium, we return a pointer to this medium, or 0x0 if it does not exist. // med_name = "Vacuum" is a special case: if the "Vacuum" does not exist, we create it. // // Instance of geometry manager class TGeoManager must be created before calling this // method, otherwise 0x0 will be returned. // If the required TGeoMedium is not already available in the TGeoManager, we create // a new TGeoMedium corresponding to the properties of this KVMaterial. // The name of the TGeoMedium (and associated TGeoMaterial) is the name of the KVMaterial. if (!gGeoManager) return NULL; if (strcmp(med_name, "")) { TGeoMedium* gmed = gGeoManager->GetMedium(med_name); if (gmed) return gmed; else if (!strcmp(med_name, "Vacuum")) { // create material TGeoMaterial* gmat = new TGeoMaterial("Vacuum", 0, 0, 0); gmat->SetTitle("Vacuum"); gmed = new TGeoMedium("Vacuum", 0, gmat); gmed->SetTitle("Vacuum"); return gmed; } return NULL; } // if object is a KVDetector, we return medium corresponding to the active layer if (GetActiveLayer()) return GetActiveLayer()->GetGeoMedium(); // for gaseous materials, the TGeoMedium/Material name is of the form // gasname_pressure // e.g. C3F8_37.5 for C3F8 gas at 37.5 torr // each gas with different pressure has to have a separate TGeoMaterial/Medium TString medName; if (IsGas()) medName.Form("%s_%f", GetName(), GetPressure()); else medName = GetName(); TGeoMedium* gmed = gGeoManager->GetMedium(medName); if (gmed) return gmed; TGeoMaterial* gmat = gGeoManager->GetMaterial(medName); if (!gmat) { // create material gmat = GetRangeTable()->GetTGeoMaterial(GetName()); gmat->SetPressure(GetPressure()); gmat->SetTemperature(GetTemperature()); gmat->SetTransparency(0); gmat->SetName(medName); gmat->SetTitle(GetName()); } // create medium static Int_t numed = 1; // static counter variable used to number media gmed = new TGeoMedium(medName, numed, gmat); numed += 1; return gmed; }
/** * Calculate effective radiation length traversed by particle traveling between two points * along straight line. * * Calculation is done according to the eq. (27.23) * @see http://pdg.lbl.gov/2006/reviews/passagerpp.pdf * * @param globalPosStart starting point in the global coordinate system * @param globalPosFinish ending point in the global coordinate system * @param skipBoundaryVolumes if true subtract rad length of the volumes containing start and finish points * * @return radiation length in units of X0 */ float EUTelGeometryTelescopeGeoDescription::findRadLengthIntegral( const double globalPosStart[], const double globalPosFinish[], bool skipBoundaryPonitsVolumes ) { streamlog_out(DEBUG1) << "EUTelGeometryTelescopeGeoDescription::findRadLengthIntegral()" << std::endl; float rad = 0.; // integral of radiation length in units of X0 const double mm2cm = 0.1; /* TGeo uses cm and grams as internal units e.g. in radiation length and density. Telescope/LCIO uses mm. Therefore this routine is full of annoying conversion factors */ const double stepLenght2 = ( globalPosFinish[0] - globalPosStart[0] )*( globalPosFinish[0] - globalPosStart[0] ) + ( globalPosFinish[1] - globalPosStart[1] )*( globalPosFinish[1] - globalPosStart[1] ) + ( globalPosFinish[2] - globalPosStart[2] )*( globalPosFinish[2] - globalPosStart[2] ); const double stepLenght = TMath::Sqrt( stepLenght2 ); // don't need conversion factor to for calculation of directions const double xp = ( globalPosFinish[0] - globalPosStart[0] )/stepLenght; const double yp = ( globalPosFinish[1] - globalPosStart[1] )/stepLenght; const double zp = ( globalPosFinish[2] - globalPosStart[2] )/stepLenght; streamlog_out(DEBUG0) << "Start point (x,y,z):" << globalPosStart[0] << "," << globalPosStart[1] << "," << globalPosStart[2] << std::endl; streamlog_out(DEBUG0) << "Finish point (x,y,z):" << globalPosFinish[0] << "," << globalPosFinish[1] << "," << globalPosFinish[2] << std::endl; streamlog_out(DEBUG0) << "Direction (nx,ny,nz):" << xp << "," << yp << "," << zp << std::endl; double snext; double pt[3], loc[3]; double epsil = 1.E-7; double lastrad = 0.; int ismall = 0; int nbound = 0; float length = 0.; TGeoMedium *med; TGeoShape *shape; // Get starting node gGeoManager->InitTrack( globalPosStart[0]/*mm*/, globalPosStart[1]/*mm*/, globalPosStart[2]/*mm*/, xp, yp, zp ); TGeoNode *nextnode = gGeoManager->GetCurrentNode( ); double currentStep = stepLenght /*mm*/; // Loop over all, encountered during the propagation, volumes while ( nextnode ) { med = NULL; // Check if current point is inside silicon sensor. Radiation length of silicon sensors is accounted in thin scatterers of GBL. bool isBoundaryVolume = false; if ( gGeoManager->IsSameLocation( globalPosStart[0], globalPosStart[1], globalPosStart[2] ) || gGeoManager->IsSameLocation( globalPosFinish[0], globalPosFinish[1], globalPosFinish[2] ) ) isBoundaryVolume = true; if ( nextnode ) med = nextnode->GetVolume()->GetMedium(); else return 0.; shape = nextnode->GetVolume()->GetShape(); // make a step to the next intersection point if ( currentStep > 1.e-9 /*mm*/ ) nextnode = gGeoManager->FindNextBoundaryAndStep( currentStep /*mm*/ ); else return rad; snext = gGeoManager->GetStep() /*mm*/; // Small steps treatment if ( snext < 1.e-8 /*mm*/ ) { ismall++; // Terminate calculation if too many small steps done if ( ismall > 3 ) { streamlog_out( WARNING1 ) << "ERROR: Small steps in: " << gGeoManager->GetPath() << " shape=" << shape->ClassName() << endl; return rad; } // increase step size (epsilon) and advance along the particle direction memcpy( pt, gGeoManager->GetCurrentPoint(), 3 * sizeof (double) ); const double *dir = gGeoManager->GetCurrentDirection(); for ( Int_t i = 0; i < 3; i++ ) pt[i] += epsil * dir[i]; snext = epsil; length += snext; // Ignore start and finish volumes if required if ( skipBoundaryPonitsVolumes && isBoundaryVolume ) { rad += 0.; } else { rad += lastrad*snext; } gGeoManager->CdTop( ); nextnode = gGeoManager->FindNode( pt[0], pt[1], pt[2] ); // Check if particle is crossed the boundary if ( gGeoManager->IsOutside() ) return rad; // leave if not TGeoMatrix *mat = gGeoManager->GetCurrentMatrix(); mat->MasterToLocal( pt, loc ); if ( !gGeoManager->GetCurrentVolume()->Contains( loc ) ) { gGeoManager->CdUp(); nextnode = gGeoManager->GetCurrentNode(); // move to new volume } continue; } else { ismall = 0; } // Normal steps case nbound++; length += snext; currentStep -= snext; if ( med ) { double radlen = med->GetMaterial()->GetRadLen() /*cm*/; if ( radlen > 1.e-9 && radlen < 1.e10 ) { lastrad = 1. / radlen * mm2cm; // Ignore start and finish volumes if required if ( skipBoundaryPonitsVolumes && isBoundaryVolume ) { rad += 0.; } else { rad += lastrad*snext; } } else { lastrad = 0.; } streamlog_out( DEBUG0 ) << "STEP #" << nbound << std::endl; streamlog_out( DEBUG0 ) << " step[mm]=" << snext << " length[mm]=" << length << " rad[X0]=" << snext * mm2cm / radlen << " " << med->GetName( ) << " rho[g/cm^3]=" << med->GetMaterial()->GetDensity() <<" radlen[cm]=" << radlen << " Boundary:" << (isBoundaryVolume?"yes":"no") << std::endl; } } streamlog_out(DEBUG1) << "--------EUTelGeometryTelescopeGeoDescription::findRadLengthIntegral()--------" << std::endl; return rad; }