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(); }
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()); }
/** * 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; }