virtual void AddNode(const TGeoVolume *vol, Int_t copy_no, TGeoMatrix *mat, Option_t* = "") { TGeoMatrix *matrix = mat; if (matrix == 0) matrix = gGeoIdentity; else matrix->RegisterYourself(); if (!vol) { this->T::Error("AddNode", "Volume is NULL"); return; } if (!vol->IsValid()) { this->T::Error("AddNode", "Won't add node with invalid shape"); printf("### invalid volume was : %s\n", vol->GetName()); return; } if (!this->T::fNodes) this->T::fNodes = new TObjArray(); if (this->T::fFinder) { // volume already divided. this->T::Error("AddNode", "Cannot add node %s_%i into divided volume %s", vol->GetName(), copy_no, this->T::GetName()); return; } TGeoNodeMatrix *node = new DD_TGeoNodeMatrix(vol, matrix); //node = new TGeoNodeMatrix(vol, matrix); node->SetMotherVolume(this); this->T::fNodes->Add(node); TString name = TString::Format("%s_%d", vol->GetName(), copy_no); if (this->T::fNodes->FindObject(name)) this->T::Warning("AddNode", "Volume %s : added node %s with same name", this->T::GetName(), name.Data()); node->SetName(name); node->SetNumber(copy_no); }
template <> void AlignmentActor<DDAlign_standard_operations::node_reset>::operator()(Nodes::value_type& n) const { TGeoPhysicalNode* p = n.second.first; //Entry* e = n.second.second; string np; if ( p->IsAligned() ) { for (Int_t i=0, nLvl=p->GetLevel(); i<=nLvl; i++) { TGeoNode* node = p->GetNode(i); TGeoMatrix* mm = node->GetMatrix(); // Node's relative matrix np += string("/")+node->GetName(); if ( !mm->IsIdentity() && i > 0 ) { // Ignore the 'world', is identity anyhow GlobalAlignment a = cache.get(np); if ( a.isValid() ) { printout(ALWAYS,"AlignmentActor<reset>","Correct path:%s leaf:%s",p->GetName(),np.c_str()); TGeoHMatrix* glob = p->GetMatrix(i-1); if ( a.isValid() && i!=nLvl ) { *mm = *(a->GetOriginalMatrix()); } else if ( i==nLvl ) { TGeoHMatrix* hm = dynamic_cast<TGeoHMatrix*>(mm); TGeoMatrix* org = p->GetOriginalMatrix(); hm->SetTranslation(org->GetTranslation()); hm->SetRotation(org->GetRotationMatrix()); } *glob *= *mm; } } } } }
void alignment_reset_dbg(const string& path, const Alignment& a) { TGeoPhysicalNode* n = a.ptr(); cout << " +++++++++++++++++++++++++++++++ " << path << endl; cout << " +++++ Misaligned physical node: " << endl; n->Print(); string np; if ( n->IsAligned() ) { for (Int_t i=0; i<=n->GetLevel(); i++) { TGeoMatrix* mm = n->GetNode(i)->GetMatrix(); np += "/"; np += n->GetNode(i)->GetName(); if ( mm->IsIdentity() ) continue; if ( i == 0 ) continue; TGeoHMatrix* glob = n->GetMatrix(i-1); NodeMap::const_iterator j=original_matrices.find(np); if ( j != original_matrices.end() && i!=n->GetLevel() ) { cout << " +++++ Patch Level: " << i << np << endl; *mm = *((*j).second); } else { if ( i==n->GetLevel() ) { cout << " +++++ Level: " << i << np << " --- Original matrix: " << endl; n->GetOriginalMatrix()->Print(); cout << " +++++ Level: " << i << np << " --- Local matrix: " << endl; mm->Print(); TGeoHMatrix* hm = dynamic_cast<TGeoHMatrix*>(mm); hm->SetTranslation(n->GetOriginalMatrix()->GetTranslation()); hm->SetRotation(n->GetOriginalMatrix()->GetRotationMatrix()); cout << " +++++ Level: " << i << np << " --- New local matrix" << endl; mm->Print(); } else { cout << " +++++ Level: " << i << np << " --- Keep matrix " << endl; mm->Print(); } } cout << " +++++ Level: " << i << np << " --- Global matrix: " << endl; glob->Print(); *glob *= *mm; cout << " +++++ Level: " << i << np << " --- New global matrix: " << endl; glob->Print(); } } cout << "\n\n\n +++++ physical node (full): " << np << endl; n->Print(); cout << " +++++ physical node (global): " << np << endl; n->GetMatrix()->Print(); }
//__________________________________________________________________________ Bool_t BuildFieldMap(const TGeoHMatrix& matrix) { // Create a Uniform Magnetic field and write it to file string filename = "runs/polarisation/guide_tube/C8=9 A +SQUIDs Coil =26_4 mA +D1=2 A + 6WS TC guide tube -100 z +80 cm.txt"; // Define shape of field TGeoShape* magFieldShape = new Box("FieldShape",0.031, 0.031, 3.0); // Define transformation that locates field in geometry TGeoMatrix* magFieldPosition = new TGeoHMatrix(matrix); magFieldPosition->Print(); MagFieldMap* field = new MagFieldMap("Field", magFieldShape, magFieldPosition); if (field->BuildMap(filename) == kFALSE) { Error("BuildFieldMap","Cannot open file: %s", filename); return kFALSE; } // Add field to magfield manager MagFieldArray* magFieldArray = new MagFieldArray(); magFieldArray->AddField(field); /* // Elec Field // Define shape of field TGeoShape* elecFieldShape = new Tube("SolenoidFieldShape",hvCellRMin, hvCellRMax, hvCellHalfZ); // Define transformation that locates field in geometry TGeoMatrix* elecFieldPosition = new TGeoHMatrix(matrix); TVector3 elecFieldStrength(hvCellEx, hvCellEy, hvCellEz); ElecField* elecField = new UniformElecField("ElectricField", elecFieldStrength, elecFieldShape, elecFieldPosition); // Add field to electric field manager ElecFieldArray* elecFieldArray = new ElecFieldArray(); elecFieldArray->AddField(elecField); */ // -- Write magfieldmanager to geometry file const char *magFileName = "geom/fields.root"; TFile *f = TFile::Open(magFileName,"recreate"); if (!f || f->IsZombie()) { Error("BuildFieldMap","Cannot open file: %s", magFileName); return kFALSE; } magFieldArray->Write(magFieldArray->GetName()); // elecFieldArray->Write(elecFieldArray->GetName()); f->ls(); f->Close(); delete magFieldArray; // delete elecFieldArray; magFieldArray = 0; // elecFieldArray = 0; return kTRUE; }
/** * 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; }