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