#include #include //for TIter #include "IFieldPlotter.hxx" #include "IFieldManager.hxx" #include #include #include #include #include #include #include #include #include #include #include #include namespace { std::ostream& operator<<(std::ostream& stream,const TVector3& vect){ stream<<"("<cd(); else if(fDirectory) fDirectory->cd(); COMET::IFieldManager* theGlobalField = COMET::IFieldManager::GetObject(); const double origin_side=fOrigin.Dot(fDirSide); const double origin_up=fOrigin.Dot(fDirUp); const double limit_side=fNSteps*fStepSide; const double limit_up=fNSteps*fStepUp; std::stringstream x_axis; x_axis<<"Distance along "<GetFieldValue(point,field_vectors); TVector3 field(field_vectors[0],field_vectors[1],field_vectors[2]); field*=1/unit::tesla; hMagnitude->Fill(dist_side,dist_up,field.Mag()); hUpwards->Fill(dist_side,dist_up,field.Dot(fDirUp)); hSideways->Fill(dist_side,dist_up,field.Dot(fDirSide)); hOutwards->Fill(dist_side,dist_up,field.Dot(fDirOut)); if(hGeometry){ const double density=GetDensity(position); hGeometry->Fill(dist_side,dist_up,density); } } } oldwd->cd(); return true; } bool COMET::IFieldPlotter::PlotPlanes(int n_planes,double plane_sep){ double start_depth=(n_planes-1)*0.5*plane_sep; int start=(n_planes-1)*0.5; int stop=start + (n_planes+1)%2; TVector3 orig_origin=fOrigin; fOrigin-=start_depth*fDirOut; for(int i_plane=-start;i_plane<=stop; ++i_plane){ // create a name for the plane std::string slice_name=Form("slice_%g_%g_%g",fOrigin.x(),fOrigin.y(),fOrigin.z()); TDirectory* dir=fDirectory->mkdir(slice_name.c_str()); COMETNamedLog("IFieldPlotter","Running on plane ("<PushPoint(); // Find the maximum density for material used in the geometry double max_density=0; TIter nextMaterial(gGeoManager->GetListOfMaterials()); TObject* object=0; while( (object = nextMaterial() ) ){ const TGeoMaterial* material=(const TGeoMaterial*) object; if(material) { const double density=material->GetDensity(); if(density>max_density) max_density=density; } } // Until we've sampled fSampleGeometry points, const double range_side=fNSteps*fStepSide; const double range_up =fNSteps*fStepUp; const double origin_side=fOrigin.Dot(fDirSide); const double origin_up=fOrigin.Dot(fDirUp); TRandom3 generator; int points_skipped=0; const int maxIteratrions=10*fSampleGeometry; for(int n_samples=0; n_samples maxIteratrions){ break; } // Choose a point const double side=generator.Uniform(-range_side,range_side); const double up=generator.Uniform(-range_up,range_up); const TVector3 point=fOrigin+side*fDirSide+up*fDirUp; const double density=GetDensity(point); if(density<0 || generator.Rndm()>density/max_density){ ++points_skipped; continue; } hGeometry->Fill(side+origin_side,up+origin_up,1.); ++n_samples; } gGeoManager->PopPoint(); } double COMET::IFieldPlotter::GetDensity(const TVector3& point){ // Factors of 10 come from units in geometry being cm, not mm as used by // field const TGeoNode* node = COMET::IOADatabase::Get().GeomId().FindNode(point); if(!node){ COMETDebug("No node, perhaps in the world volume?"); return -1; } const TGeoVolume* volume =node->GetVolume(); if(!volume){ COMETError("Node without a volume !"); return -1; } const TGeoMaterial* material =volume->GetMaterial(); return material->GetDensity(); }