CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/Fireworks/Core/src/BuilderUtils.cc

Go to the documentation of this file.
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          // make phi continuous around jet phi
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       // Coordinates for a scaled version of the original box
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       // Coordinates for a scaled version of the original box
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       // Coordinates of a front face scaled 
00289       if( reflect )
00290       {
00291          // We know, that an ES rechit geometry in -Z needs correction. 
00292          // The back face is actually its front face.
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       // Coordinates of a front face scaled 
00337       if( reflect )
00338       {
00339          // We know, that an ES rechit geometry in -Z needs correction. 
00340          // The back face is actually its front face.
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 } // namespace fireworks