00001 #include "Fireworks/Core/interface/BuilderUtils.h"
00002 #include "Fireworks/Core/interface/Context.h"
00003 #include "Fireworks/Core/interface/FWProxyBuilderBase.h"
00004
00005 #include "FWCore/Common/interface/EventBase.h"
00006
00007 #include "TGeoBBox.h"
00008 #include "TColor.h"
00009 #include "TROOT.h"
00010 #include "TEveBox.h"
00011 #include "TEveScalableStraightLineSet.h"
00012 #include "TEveStraightLineSet.h"
00013 #include "TEveTrans.h"
00014 #include "TEveGeoNode.h"
00015
00016 #include <math.h>
00017 #include <time.h>
00018
00019 namespace fireworks
00020 {
00021 std::pair<double,double> getPhiRange( const std::vector<double>& phis, double phi )
00022 {
00023 double min = 100;
00024 double max = -100;
00025
00026 for( std::vector<double>::const_iterator i = phis.begin();
00027 i != phis.end(); ++i )
00028 {
00029 double aphi = *i;
00030
00031 if( aphi - phi > M_PI ) aphi -= 2*M_PI;
00032 if( phi - aphi > M_PI ) aphi += 2*M_PI;
00033 if( aphi > max ) max = aphi;
00034 if( aphi < min ) min = aphi;
00035 }
00036
00037 if( min > max ) return std::pair<double,double>( 0, 0 );
00038
00039 return std::pair<double,double>( min, max );
00040 }
00041
00042 TEveGeoShape* getShape( const char* name,
00043 TGeoBBox* shape,
00044 Color_t color )
00045 {
00046 TEveGeoShape* egs = new TEveGeoShape( name );
00047 TColor* c = gROOT->GetColor( color );
00048 Float_t rgba[4] = { 1, 0, 0, 1 };
00049 if( c )
00050 {
00051 rgba[0] = c->GetRed();
00052 rgba[1] = c->GetGreen();
00053 rgba[2] = c->GetBlue();
00054 }
00055 egs->SetMainColorRGB( rgba[0], rgba[1], rgba[2] );
00056 egs->SetShape( shape );
00057 return egs;
00058 }
00059
00060 void addRhoZEnergyProjection( FWProxyBuilderBase* pb, TEveElement* container,
00061 double r_ecal, double z_ecal,
00062 double theta_min, double theta_max,
00063 double phi )
00064 {
00065 TEveGeoManagerHolder gmgr( TEveGeoShape::GetGeoMangeur());
00066 double z1 = r_ecal / tan( theta_min );
00067 if( z1 > z_ecal ) z1 = z_ecal;
00068 if( z1 < -z_ecal ) z1 = -z_ecal;
00069 double z2 = r_ecal / tan( theta_max );
00070 if( z2 > z_ecal ) z2 = z_ecal;
00071 if( z2 < -z_ecal ) z2 = -z_ecal;
00072 double r1 = z_ecal * fabs( tan( theta_min ));
00073 if( r1 > r_ecal ) r1 = r_ecal;
00074 if( phi < 0 ) r1 = -r1;
00075 double r2 = z_ecal * fabs( tan( theta_max ));
00076 if( r2 > r_ecal ) r2 = r_ecal;
00077 if( phi < 0 ) r2 = -r2;
00078
00079 if( fabs(r2 - r1) > 1 )
00080 {
00081 TGeoBBox *sc_box = new TGeoBBox( 0., fabs( r2 - r1 ) / 2, 1 );
00082 TEveGeoShape *element = new TEveGeoShape("r-segment");
00083 element->SetShape(sc_box);
00084 TEveTrans &t = element->RefMainTrans();
00085 t(1,4) = 0;
00086 t(2,4) = (r2+r1)/2;
00087 t(3,4) = fabs(z2)>fabs(z1) ? z2 : z1;
00088 pb->setupAddElement(element, container);
00089 }
00090 if( fabs(z2 - z1) > 1 )
00091 {
00092 TGeoBBox *sc_box = new TGeoBBox( 0., 1, ( z2 - z1 ) / 2 );
00093 TEveGeoShape *element = new TEveGeoShape("z-segment");
00094 element->SetShape( sc_box );
00095 TEveTrans &t = element->RefMainTrans();
00096 t(1,4) = 0;
00097 t(2,4) = fabs(r2)>fabs(r1) ? r2 : r1;
00098 t(3,4) = (z2+z1)/2;
00099 pb->setupAddElement(element, container);
00100 }
00101 }
00102
00103 std::string getTimeGMT( const edm::EventBase& event )
00104 {
00105 time_t t( event.time().value() >> 32 );
00106 std::string text( asctime( gmtime( &t ) ) );
00107 size_t pos = text.find( '\n' );
00108 if( pos != std::string::npos ) text = text.substr( 0, pos );
00109 text += " GMT";
00110 return text;
00111 }
00112
00113 std::string getLocalTime( const edm::EventBase& event )
00114 {
00115 time_t t( event.time().value() >> 32 );
00116 std::string text( asctime( localtime( &t ) ) );
00117 size_t pos = text.find('\n');
00118 if( pos != std::string::npos ) text = text.substr( 0, pos );
00119 text += " ";
00120 if( daylight )
00121 text += tzname[1];
00122 else
00123 text += tzname[0];
00124 return text;
00125 }
00126
00127 void invertBox( std::vector<float> &corners )
00128 {
00129 std::swap( corners[0], corners[9] );
00130 std::swap( corners[1], corners[10] );
00131 std::swap( corners[2], corners[11] );
00132
00133 std::swap( corners[3], corners[6] );
00134 std::swap( corners[4], corners[7] );
00135 std::swap( corners[5], corners[8] );
00136
00137 std::swap( corners[12], corners[21] );
00138 std::swap( corners[13], corners[22] );
00139 std::swap( corners[14], corners[23] );
00140
00141 std::swap( corners[15], corners[18] );
00142 std::swap( corners[16], corners[19] );
00143 std::swap( corners[17], corners[20] );
00144 }
00145
00146 void addBox( const std::vector<float> &corners, TEveElement* comp, FWProxyBuilderBase* pb )
00147 {
00148 TEveBox* eveBox = new TEveBox( "Box" );
00149 eveBox->SetDrawFrame( false );
00150 eveBox->SetPickable( true );
00151 eveBox->SetVertices( &corners[0] );
00152
00153 pb->setupAddElement( eveBox, comp );
00154 }
00155
00156 void addCircle( double eta, double phi, double radius, const unsigned int nLineSegments, TEveElement* comp, FWProxyBuilderBase* pb )
00157 {
00158 TEveStraightLineSet* container = new TEveStraightLineSet;
00159
00160 for( unsigned int iphi = 0; iphi < nLineSegments; ++iphi )
00161 {
00162 container->AddLine( eta + radius * cos( 2 * M_PI / nLineSegments * iphi ),
00163 phi + radius * sin( 2 * M_PI / nLineSegments * iphi ),
00164 0.01,
00165 eta + radius * cos( 2 * M_PI / nLineSegments * ( iphi + 1 )),
00166 phi + radius * sin( 2 * M_PI / nLineSegments * ( iphi + 1 )),
00167 0.01 );
00168 }
00169 pb->setupAddElement( container, comp );
00170 }
00171
00172 void addDashedArrow( double phi, double size, TEveElement* comp, FWProxyBuilderBase* pb )
00173 {
00174 TEveScalableStraightLineSet* marker = new TEveScalableStraightLineSet;
00175 marker->SetLineWidth( 1 );
00176 marker->SetLineStyle( 2 );
00177 marker->AddLine( 0, 0, 0, size * cos( phi ), size * sin( phi ), 0 );
00178 marker->AddLine( size * 0.9 * cos( phi + 0.03 ), size * 0.9 * sin( phi + 0.03 ), 0, size * cos( phi ), size * sin( phi ), 0 );
00179 marker->AddLine( size * 0.9 * cos( phi - 0.03 ), size * 0.9 * sin( phi - 0.03 ), 0, size * cos( phi ), size * sin( phi ), 0 );
00180 pb->setupAddElement( marker, comp );
00181 }
00182
00183 void addDashedLine( double phi, double theta, double size, TEveElement* comp, FWProxyBuilderBase* pb )
00184 {
00185 double r( 0 );
00186 if( theta < pb->context().caloTransAngle() || M_PI - theta < pb->context().caloTransAngle())
00187 r = pb->context().caloZ2() / fabs( cos( theta ));
00188 else
00189 r = pb->context().caloR1() / sin( theta );
00190
00191 TEveStraightLineSet* marker = new TEveStraightLineSet;
00192 marker->SetLineWidth( 2 );
00193 marker->SetLineStyle( 2 );
00194 marker->AddLine( r * cos( phi ) * sin( theta ), r * sin( phi ) * sin( theta ), r * cos( theta ),
00195 ( r + size ) * cos( phi ) * sin( theta ), ( r + size ) * sin( phi ) * sin( theta ), ( r + size ) * cos( theta ));
00196 pb->setupAddElement( marker, comp );
00197 }
00198
00199 void addDoubleLines( double phi, TEveElement* comp, FWProxyBuilderBase* pb )
00200 {
00201 TEveStraightLineSet* mainLine = new TEveStraightLineSet;
00202 mainLine->AddLine( -5.191, phi, 0.01, 5.191, phi, 0.01 );
00203 pb->setupAddElement( mainLine, comp );
00204
00205 phi = phi > 0 ? phi - M_PI : phi + M_PI;
00206 TEveStraightLineSet* secondLine = new TEveStraightLineSet;
00207 secondLine->SetLineStyle( 7 );
00208 secondLine->AddLine( -5.191, phi, 0.01, 5.191, phi, 0.01 );
00209 pb->setupAddElement( secondLine, comp );
00210 }
00211
00212
00213 void energyScaledBox3DCorners( const float* corners, float scale, std::vector<float>& scaledCorners, bool invert)
00214 {
00215 std::vector<float> centre( 3, 0 );
00216
00217 for( unsigned int i = 0; i < 24; i += 3 )
00218 {
00219 centre[0] += corners[i];
00220 centre[1] += corners[i + 1];
00221 centre[2] += corners[i + 2];
00222 }
00223
00224 for( unsigned int i = 0; i < 3; ++i )
00225 centre[i] *= 1.0f / 8.0f;
00226
00227
00228 for( unsigned int i = 0; i < 24; i += 3 )
00229 {
00230 scaledCorners[i] = centre[0] + ( corners[i] - centre[0] ) * scale;
00231 scaledCorners[i + 1] = centre[1] + ( corners[i + 1] - centre[1] ) * scale;
00232 scaledCorners[i + 2] = centre[2] + ( corners[i + 2] - centre[2] ) * scale;
00233 }
00234
00235 if( invert )
00236 invertBox( scaledCorners );
00237 }
00238
00239 void drawEnergyScaledBox3D( const float* corners, float scale, TEveElement* comp, FWProxyBuilderBase* pb, bool invert )
00240 {
00241 std::vector<float> scaledCorners( 24 );
00242 energyScaledBox3DCorners(corners, scale, scaledCorners, invert);
00243 addBox( scaledCorners, comp, pb );
00244 }
00245
00246
00247 void etScaledBox3DCorners( const float* corners, float energy, float maxEnergy, std::vector<float>& scaledCorners, bool invert)
00248 {
00249 std::vector<float> centre( 3, 0 );
00250
00251 for( unsigned int i = 0; i < 24; i += 3 )
00252 {
00253 centre[0] += corners[i];
00254 centre[1] += corners[i + 1];
00255 centre[2] += corners[i + 2];
00256 }
00257
00258 for( unsigned int i = 0; i < 3; ++i )
00259 centre[i] *= 1.0f / 8.0f;
00260
00261 TEveVector c( centre[0], centre[1], centre[2] );
00262 float scale = energy / maxEnergy * sin( c.Theta());
00263
00264
00265 for( unsigned int i = 0; i < 24; i += 3 )
00266 {
00267 scaledCorners[i] = centre[0] + ( corners[i] - centre[0] ) * scale;
00268 scaledCorners[i + 1] = centre[1] + ( corners[i + 1] - centre[1] ) * scale;
00269 scaledCorners[i + 2] = centre[2] + ( corners[i + 2] - centre[2] ) * scale;
00270 }
00271
00272 if( invert )
00273 invertBox( scaledCorners );
00274 }
00275
00276 void drawEtScaledBox3D( const float* corners, float energy, float maxEnergy, TEveElement* comp, FWProxyBuilderBase* pb, bool invert )
00277 {
00278 std::vector<float> scaledCorners( 24 );
00279 etScaledBox3DCorners(corners, energy, maxEnergy, scaledCorners, invert);
00280 addBox( scaledCorners, comp, pb );
00281 }
00282
00283
00284 void energyTower3DCorners( const float* corners, float scale, std::vector<float>& scaledCorners, bool reflect)
00285 {
00286 for( int i = 0; i < 24; ++i )
00287 scaledCorners[i] = corners[i];
00288
00289 if( reflect )
00290 {
00291
00292
00293 for( unsigned int i = 0; i < 12; i += 3 )
00294 {
00295 TEveVector diff( corners[i] - corners[i + 12], corners[i + 1] - corners[i + 13], corners[i + 2] - corners[i + 14] );
00296 diff.Normalize();
00297 diff *= scale;
00298
00299 scaledCorners[i] = corners[i] + diff.fX;
00300 scaledCorners[i + 1] = corners[i + 1] + diff.fY;
00301 scaledCorners[i + 2] = corners[i + 2] + diff.fZ;
00302 }
00303 }
00304 else
00305 {
00306 for( unsigned int i = 0; i < 12; i += 3 )
00307 {
00308 TEveVector diff( corners[i + 12] - corners[i], corners[i + 13] - corners[i + 1], corners[i + 14] - corners[i + 2] );
00309 diff.Normalize();
00310 diff *= scale;
00311
00312 scaledCorners[i] = corners[i + 12];
00313 scaledCorners[i + 1] = corners[i + 13];
00314 scaledCorners[i + 2] = corners[i + 14];
00315
00316 scaledCorners[i + 12] = corners[i + 12] + diff.fX;
00317 scaledCorners[i + 13] = corners[i + 13] + diff.fY;
00318 scaledCorners[i + 14] = corners[i + 14] + diff.fZ;
00319 }
00320 }
00321 }
00322
00323 void drawEnergyTower3D( const float* corners, float scale, TEveElement* comp, FWProxyBuilderBase* pb, bool reflect )
00324 {
00325 std::vector<float> scaledCorners( 24 );
00326 energyTower3DCorners(corners, scale, scaledCorners, reflect);
00327 addBox( scaledCorners, comp, pb );
00328 }
00329
00330
00331
00332 void etTower3DCorners( const float* corners, float scale, std::vector<float>& scaledCorners, bool reflect)
00333 {
00334 for( int i = 0; i < 24; ++i )
00335 scaledCorners[i] = corners[i];
00336
00337 if( reflect )
00338 {
00339
00340
00341 for( unsigned int i = 0; i < 12; i += 3 )
00342 {
00343 TEveVector diff( corners[i] - corners[i + 12], corners[i + 1] - corners[i + 13], corners[i + 2] - corners[i + 14] );
00344 diff.Normalize();
00345 diff *= ( scale * sin( diff.Theta()));
00346
00347 scaledCorners[i] = corners[i] + diff.fX;
00348 scaledCorners[i + 1] = corners[i + 1] + diff.fY;
00349 scaledCorners[i + 2] = corners[i + 2] + diff.fZ;
00350 }
00351 }
00352 else
00353 {
00354 for( unsigned int i = 0; i < 12; i += 3 )
00355 {
00356 TEveVector diff( corners[i + 12] - corners[i], corners[i + 13] - corners[i + 1], corners[i + 14] - corners[i + 2] );
00357 diff.Normalize();
00358 diff *= ( scale * sin( diff.Theta()));
00359
00360 scaledCorners[i] = corners[i + 12];
00361 scaledCorners[i + 1] = corners[i + 13];
00362 scaledCorners[i + 2] = corners[i + 14];
00363
00364 scaledCorners[i + 12] = corners[i + 12] + diff.fX;
00365 scaledCorners[i + 13] = corners[i + 13] + diff.fY;
00366 scaledCorners[i + 14] = corners[i + 14] + diff.fZ;
00367 }
00368 }
00369 }
00370
00371
00372 void drawEtTower3D( const float* corners, float scale, TEveElement* comp, FWProxyBuilderBase* pb, bool reflect )
00373 {
00374 std::vector<float> scaledCorners( 24 );
00375 etTower3DCorners(corners, scale, scaledCorners, reflect);
00376 addBox( scaledCorners, comp, pb );
00377 }
00378
00379
00380 }