00001 #include "TFile.h"
00002 #include "TTree.h"
00003 #include "TEveGeoNode.h"
00004 #include "TPRegexp.h"
00005 #include "TSystem.h"
00006 #include "TGeoArb8.h"
00007
00008 #include "Fireworks/Core/interface/FWGeometry.h"
00009 #include "Fireworks/Core/interface/fwLog.h"
00010 #include "DataFormats/DetId/interface/DetId.h"
00011
00012 #include <iostream>
00013 #include <cassert>
00014 #include <sstream>
00015 #include <stdexcept>
00016 #include <algorithm>
00017
00018 FWGeometry::FWGeometry( void )
00019 {}
00020
00021 FWGeometry::~FWGeometry( void )
00022 {}
00023
00024 TFile*
00025 FWGeometry::findFile( const char* fileName )
00026 {
00027 TString file;
00028 if( fileName[0] == '/' || ( fileName[0] == '.' && fileName[1] == '/' ))
00029 {
00030 file = fileName;
00031 }
00032 else
00033 {
00034 if( const char* cmspath = gSystem->Getenv( "CMSSW_BASE" ))
00035 {
00036 file += cmspath;
00037 file += "/";
00038 }
00039 file += fileName;
00040 }
00041 if( !gSystem->AccessPathName( file.Data()))
00042 {
00043 return TFile::Open( file );
00044 }
00045
00046 const char* searchpath = gSystem->Getenv( "CMSSW_SEARCH_PATH" );
00047 if( searchpath == 0 )
00048 return 0;
00049 TString paths( searchpath );
00050 TObjArray* tokens = paths.Tokenize( ":" );
00051 for( int i = 0; i < tokens->GetEntries(); ++i )
00052 {
00053 TObjString* path = (TObjString*)tokens->At( i );
00054 TString fullFileName( path->GetString());
00055 fullFileName += "/Fireworks/Geometry/data/";
00056 fullFileName += fileName;
00057 if( !gSystem->AccessPathName( fullFileName.Data()))
00058 return TFile::Open( fullFileName.Data());
00059 }
00060 return 0;
00061 }
00062
00063 void
00064 FWGeometry::loadMap( const char* fileName )
00065 {
00066 TFile* file = findFile( fileName );
00067 if( ! file )
00068 {
00069 throw std::runtime_error( "ERROR: failed to find geometry file. Initialization failed." );
00070 return;
00071 }
00072 TTree* tree = static_cast<TTree*>(file->Get( "idToGeo" ));
00073 if( ! tree )
00074 {
00075 throw std::runtime_error( "ERROR: cannot find detector id map in the file. Initialization failed." );
00076 return;
00077 }
00078
00079 unsigned int id;
00080 Float_t points[24];
00081 Float_t topology[9];
00082 Float_t shape[5];
00083 Float_t translation[3];
00084 Float_t matrix[9];
00085 bool loadPoints = tree->GetBranch( "points" ) != 0;
00086 bool loadParameters = tree->GetBranch( "topology" ) != 0;
00087 bool loadShape = tree->GetBranch( "shape" ) != 0;
00088 bool loadTranslation = tree->GetBranch( "translation" ) != 0;
00089 bool loadMatrix = tree->GetBranch( "matrix" ) != 0;
00090 tree->SetBranchAddress( "id", &id );
00091 if( loadPoints )
00092 tree->SetBranchAddress( "points", &points );
00093 if( loadParameters )
00094 tree->SetBranchAddress( "topology", &topology );
00095 if( loadShape )
00096 tree->SetBranchAddress( "shape", &shape );
00097 if( loadTranslation )
00098 tree->SetBranchAddress( "translation", &translation );
00099 if( loadMatrix )
00100 tree->SetBranchAddress( "matrix", &matrix );
00101
00102 unsigned int treeSize = tree->GetEntries();
00103 if( m_idToInfo.size() != treeSize )
00104 m_idToInfo.resize( treeSize );
00105 for( unsigned int i = 0; i < treeSize; ++i )
00106 {
00107 tree->GetEntry( i );
00108
00109 m_idToInfo[i].id = id;
00110 if( loadPoints )
00111 {
00112 for( unsigned int j = 0; j < 24; ++j )
00113 m_idToInfo[i].points[j] = points[j];
00114 }
00115 if( loadParameters )
00116 {
00117 for( unsigned int j = 0; j < 9; ++j )
00118 m_idToInfo[i].parameters[j] = topology[j];
00119 }
00120 if( loadShape )
00121 {
00122 for( unsigned int j = 0; j < 5; ++j )
00123 m_idToInfo[i].shape[j] = shape[j];
00124 }
00125 if( loadTranslation )
00126 {
00127 for( unsigned int j = 0; j < 3; ++j )
00128 m_idToInfo[i].translation[j] = translation[j];
00129 }
00130 if( loadMatrix )
00131 {
00132 for( unsigned int j = 0; j < 9; ++j )
00133 m_idToInfo[i].matrix[j] = matrix[j];
00134 }
00135 }
00136 file->Close();
00137 }
00138
00139 void
00140 FWGeometry::initMap( const FWRecoGeom::InfoMap& map )
00141 {
00142 FWRecoGeom::InfoMapItr begin = map.begin();
00143 FWRecoGeom::InfoMapItr end = map.end();
00144 unsigned int mapSize = map.size();
00145 if( m_idToInfo.size() != mapSize )
00146 m_idToInfo.resize( mapSize );
00147 unsigned int i = 0;
00148 for( FWRecoGeom::InfoMapItr it = begin;
00149 it != end; ++it, ++i )
00150 {
00151 m_idToInfo[i].id = it->id;
00152 for( unsigned int j = 0; j < 24; ++j )
00153 m_idToInfo[i].points[j] = it->points[j];
00154 for( unsigned int j = 0; j < 9; ++j )
00155 m_idToInfo[i].parameters[j] = it->topology[j];
00156 for( unsigned int j = 0; j < 5; ++j )
00157 m_idToInfo[i].shape[j] = it->shape[j];
00158 for( unsigned int j = 0; j < 3; ++j )
00159 m_idToInfo[i].translation[j] = it->translation[j];
00160 for( unsigned int j = 0; j < 9; ++j )
00161 m_idToInfo[i].matrix[j] = it->matrix[j];
00162 }
00163 }
00164
00165 const TGeoMatrix*
00166 FWGeometry::getMatrix( unsigned int id ) const
00167 {
00168 std::map<unsigned int, TGeoMatrix*>::iterator mit = m_idToMatrix.find( id );
00169 if( mit != m_idToMatrix.end()) return mit->second;
00170
00171 IdToInfoItr it = FWGeometry::find( id );
00172 if( it == m_idToInfo.end())
00173 {
00174 fwLog( fwlog::kWarning ) << "no reco geometry found for id " << id << std::endl;
00175 return 0;
00176 }
00177 else
00178 {
00179 const GeomDetInfo& info = *it;
00180 TGeoTranslation trans( info.translation[0], info.translation[1], info.translation[2] );
00181 TGeoRotation rotation;
00182 const Double_t matrix[9] = { info.matrix[0], info.matrix[1], info.matrix[2],
00183 info.matrix[3], info.matrix[4], info.matrix[5],
00184 info.matrix[6], info.matrix[7], info.matrix[8]
00185 };
00186 rotation.SetMatrix( matrix );
00187
00188 m_idToMatrix[id] = new TGeoCombiTrans( trans, rotation );
00189 return m_idToMatrix[id];
00190 }
00191 }
00192
00193 std::vector<unsigned int>
00194 FWGeometry::getMatchedIds( Detector det, SubDetector subdet ) const
00195 {
00196 std::vector<unsigned int> ids;
00197 unsigned int mask = ( det << 4 ) | ( subdet );
00198 for( IdToInfoItr it = m_idToInfo.begin(), itEnd = m_idToInfo.end();
00199 it != itEnd; ++it )
00200 {
00201 if( FWGeometry::match_id( *it, mask ))
00202 ids.push_back(( *it ).id );
00203 }
00204
00205 return ids;
00206 }
00207
00208 TGeoShape*
00209 FWGeometry::getShape( unsigned int id ) const
00210 {
00211 IdToInfoItr it = FWGeometry::find( id );
00212 if( it == m_idToInfo.end())
00213 {
00214 fwLog( fwlog::kWarning ) << "no reco geoemtry found for id " << id << std::endl;
00215 return 0;
00216 }
00217 else
00218 {
00219 return getShape( *it );
00220 }
00221 }
00222
00223 TGeoShape*
00224 FWGeometry::getShape( const GeomDetInfo& info ) const
00225 {
00226 TEveGeoManagerHolder gmgr( TEveGeoShape::GetGeoMangeur());
00227 TGeoShape* geoShape = 0;
00228 if( info.shape[0] == 1 )
00229 {
00230 geoShape = new TGeoTrap(
00231 info.shape[3],
00232 0,
00233 0,
00234 info.shape[4],
00235 info.shape[1],
00236 info.shape[2],
00237 0,
00238 info.shape[4],
00239 info.shape[1],
00240 info.shape[2],
00241 0);
00242 }
00243 else
00244 geoShape = new TGeoBBox( info.shape[1], info.shape[2], info.shape[3] );
00245
00246 return geoShape;
00247 }
00248
00249 TEveGeoShape*
00250 FWGeometry::getEveShape( unsigned int id ) const
00251 {
00252 IdToInfoItr it = FWGeometry::find( id );
00253 if( it == m_idToInfo.end())
00254 {
00255 fwLog( fwlog::kWarning ) << "no reco geoemtry found for id " << id << std::endl;
00256 return 0;
00257 }
00258 else
00259 {
00260 const GeomDetInfo& info = *it;
00261 double array[16] = { info.matrix[0], info.matrix[3], info.matrix[6], 0.,
00262 info.matrix[1], info.matrix[4], info.matrix[7], 0.,
00263 info.matrix[2], info.matrix[5], info.matrix[8], 0.,
00264 info.translation[0], info.translation[1], info.translation[2], 1.
00265 };
00266 TEveGeoManagerHolder gmgr( TEveGeoShape::GetGeoMangeur());
00267 TEveGeoShape* shape = new TEveGeoShape(TString::Format("RecoGeom Id=%u", id));
00268 TGeoShape* geoShape = getShape( info );
00269 shape->SetShape( geoShape );
00270
00271 shape->SetTransMatrix( array );
00272 return shape;
00273 }
00274 }
00275
00276 const float*
00277 FWGeometry::getCorners( unsigned int id ) const
00278 {
00279
00280 IdToInfoItr it = FWGeometry::find( id );
00281 if( it == m_idToInfo.end())
00282 {
00283 fwLog( fwlog::kWarning ) << "no reco geometry found for id " << id << std::endl;
00284 return 0;
00285 }
00286 else
00287 {
00288 return ( *it ).points;
00289 }
00290 }
00291
00292 const float*
00293 FWGeometry::getParameters( unsigned int id ) const
00294 {
00295
00296 IdToInfoItr it = FWGeometry::find( id );
00297 if( it == m_idToInfo.end())
00298 {
00299 fwLog( fwlog::kWarning ) << "no reco geometry found for id " << id << std::endl;
00300 return 0;
00301 }
00302 else
00303 {
00304 return ( *it ).parameters;
00305 }
00306 }
00307
00308 const float*
00309 FWGeometry::getShapePars( unsigned int id ) const
00310 {
00311
00312 IdToInfoItr it = FWGeometry::find( id );
00313 if( it == m_idToInfo.end())
00314 {
00315 fwLog( fwlog::kWarning ) << "no reco geometry found for id " << id << std::endl;
00316 return 0;
00317 }
00318 else
00319 {
00320 return ( *it ).shape;
00321 }
00322 }
00323
00324 void
00325 FWGeometry::localToGlobal( unsigned int id, const float* local, float* global ) const
00326 {
00327 IdToInfoItr it = FWGeometry::find( id );
00328 if( it == m_idToInfo.end())
00329 {
00330 fwLog( fwlog::kWarning ) << "no reco geometry found for id " << id << std::endl;
00331 }
00332 else
00333 {
00334 localToGlobal( *it, local, global );
00335 }
00336 }
00337
00338 void
00339 FWGeometry::localToGlobal( unsigned int id, const float* local1, float* global1, const float* local2, float* global2 ) const
00340 {
00341 IdToInfoItr it = FWGeometry::find( id );
00342 if( it == m_idToInfo.end())
00343 {
00344 fwLog( fwlog::kWarning ) << "no reco geometry found for id " << id << std::endl;
00345 }
00346 else
00347 {
00348 localToGlobal( *it, local1, global1 );
00349 localToGlobal( *it, local2, global2 );
00350 }
00351 }
00352
00353 FWGeometry::IdToInfoItr
00354 FWGeometry::find( unsigned int id ) const
00355 {
00356 FWGeometry::IdToInfoItr begin = m_idToInfo.begin();
00357 FWGeometry::IdToInfoItr end = m_idToInfo.end();
00358 return std::lower_bound( begin, end, id );
00359 }
00360
00361 void
00362 FWGeometry::localToGlobal( const GeomDetInfo& info, const float* local, float* global ) const
00363 {
00364 for( int i = 0; i < 3; ++i )
00365 {
00366 global[i] = info.translation[i]
00367 + local[0] * info.matrix[3 * i]
00368 + local[1] * info.matrix[3 * i + 1]
00369 + local[2] * info.matrix[3 * i + 2];
00370 }
00371 }