00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <iostream>
00019
00020 #include "TrkExtAlg/Ext_errmx.h"
00021
00022 extern bool Ext_err_valid( bool msg, const HepSymMatrix &error,
00023 const int dimension );
00024 static const double Eps(1.0e-12);
00025 static const double Infinite(1.0e+12);
00026
00027
00028
00029 Ext_errmx::Ext_errmx() : m_err(Ndim_err,0), m_err3(3,0), m_R(3,3,0),
00030 m_err2(2), m_valid(0) {}
00031
00032
00033
00034 Ext_errmx::Ext_errmx( const Ext_errmx &err ) : m_err(err.m_err),
00035 m_err3(err.m_err3), m_R(err.m_R), m_err2(err.m_err2),
00036 m_valid(err.m_valid) {}
00037
00038 Ext_errmx::Ext_errmx( const HepSymMatrix &err ) : m_err(err),
00039 m_err3(3,0), m_R(3,3,0), m_err2(2), m_valid(1) {}
00040
00041
00042
00043
00044
00045 void Ext_errmx::put_err( const double error[] )
00046 {
00047 int ne = 0;
00048
00049 for( int i = 1; i <= m_err.num_col(); i++ ){
00050 for( int j = 1; j <= i; j++ ){
00051 m_err.fast( i, j ) = error[ ne++ ];
00052 }
00053 }
00054 m_valid = 1;
00055 }
00056
00057
00058
00059
00060 void Ext_errmx::set_plane_errs( const Hep3Vector &nx, const Hep3Vector &ny,
00061 const Hep3Vector &nz ) const
00062 {
00063
00064
00065 m_R( 1, 1 ) = nx.x();
00066 m_R( 1, 2 ) = nx.y();
00067 m_R( 1, 3 ) = nx.z();
00068 m_R( 2, 1 ) = ny.x();
00069 m_R( 2, 2 ) = ny.y();
00070 m_R( 2, 3 ) = ny.z();
00071 m_R( 3, 1 ) = nz.x();
00072 m_R( 3, 2 ) = nz.y();
00073 m_R( 3, 3 ) = nz.z();
00074
00075
00076
00077 m_err3 = (m_err.sub( 1, 3 )).similarity( m_R );
00078
00079 }
00080
00081
00082
00083
00084
00085 double Ext_errmx::get_plane_err( const Hep3Vector &np, const Hep3Vector &nr )
00086 const
00087
00088
00089
00090
00091
00092
00093
00094
00095 {
00096
00097
00098
00099 if( !(*this).valid( 0 ) ){
00100
00101
00102 }
00103
00104
00105
00106
00107
00108
00109
00110 double nr_np( nr*np );
00111 double denom( 1.0 - nr_np*nr_np );
00112 double error( 0.0 );
00113
00114 if( denom > Eps ){
00115
00116 double fac( 1.0 / sqrt( denom ) );
00117 Hep3Vector nx( ( nr - nr_np * np ) * fac );
00118 Hep3Vector ny( np.cross( nx ) );
00119
00120 (*this).set_plane_errs( nx, ny, np );
00121
00122 double sigma2( m_err3( 1, 1 ) );
00123 if( sigma2 > 0 ){
00124 error = sqrt( sigma2 ) * fac;
00125 }
00126
00127 } else {
00128
00129 error = Infinite;
00130
00131 }
00132 return( error );
00133 }
00134
00135
00136
00137
00138
00139
00140 const HepVector &Ext_errmx::get_plane_errs( const Hep3Vector &np,
00141 const Hep3Vector &nr, const Hep3Vector &nt ) const
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151 {
00152
00153
00154
00155 if( !(*this).valid( 1 ) ){
00156
00157
00158 }
00159
00160 double nr_np( nr*np );
00161 double denom_r( 1.0 - nr_np*nr_np );
00162
00163 if( denom_r > Eps ){
00164
00165 double nt_np( nt*np );
00166 double denom_t( 1.0 - nt_np*nt_np );
00167 double fac_r( 1.0 / sqrt( denom_r ) );
00168 Hep3Vector nx( ( nr - nr_np * np ) * fac_r );
00169 Hep3Vector ny( np.cross( nx ) );
00170
00171 (*this).set_plane_errs( nx, ny, np );
00172
00173 double sigma2( m_err3( 1, 1 ) );
00174 if( sigma2 > 0 ){
00175 m_err2( 1 ) = sqrt( sigma2 ) * fac_r;
00176 } else {
00177 m_err2( 1 ) = 0.0;
00178 }
00179
00180 if( denom_t > Eps ){
00181 double fac_t( 1.0 / sqrt( denom_t ) );
00182 sigma2 = m_err3( 2, 2 );
00183 if( sigma2 > 0 ){
00184 m_err2( 2 ) = sqrt( sigma2 ) * fac_t;
00185 } else {
00186 m_err2( 2 ) = 0.0;
00187 }
00188 } else {
00189 m_err2( 2 ) = (*this).get_plane_err( np, nt );
00190 }
00191 } else {
00192 m_err2( 1 ) = (*this).get_plane_err( np, nr );
00193 m_err2( 2 ) = (*this).get_plane_err( np, nt );
00194 }
00195 return( m_err2 );
00196 }
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215 const Hep3Vector * Ext_errmx::get_tvs( const int view,
00216 const Hep3Vector &pv ) const
00217
00218
00219
00220
00221 {
00222
00223 Hep3Vector np( pv.unit() );
00224 Hep3Vector nr;
00225
00226 switch( view ){
00227
00228 case 1:
00229
00230 if( np.x() != 0 || np.y() != 0 ){
00231 nr.setX( np.y() );
00232 nr.setY( -np.x() );
00233 nr = nr.unit();
00234 } else {
00235 nr.setX( 1 );
00236 }
00237 break;
00238
00239 case 2:
00240
00241 if( np.y() != 0 || np.z() != 0 ){
00242 nr.setY( -np.z() );
00243 nr.setZ( np.y() );
00244 nr = nr.unit();
00245 } else {
00246 nr.setZ( 1 );
00247 }
00248 break;
00249
00250 case 3:
00251
00252 if( np.z() != 0 || np.x() != 0 ){
00253 nr.setX( -np.z() );
00254 nr.setZ( np.x() );
00255 nr = nr.unit();
00256 } else {
00257 nr.setZ( 1 );
00258 }
00259 break;
00260 }
00261
00262 Hep3Vector nt( np.cross( nr ) );
00263 const HepVector & err_v = (*this).get_plane_errs( np, nr, nt );
00264 *m_nv = err_v[0]*nr;
00265 *(m_nv+1) = err_v[1]*nt;
00266 return( m_nv );
00267 }
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278 const Hep3Vector * Ext_errmx::get_tvs( const Hep3Vector &pv ) const
00279
00280
00281
00282 {
00283
00284 Hep3Vector np( pv.unit() );
00285 Hep3Vector nz( 0.0, 0.0, 1.0 );
00286 Hep3Vector nt( (nz.cross(np)).unit() );
00287 Hep3Vector nr( nt.cross(np) );
00288
00289 const HepVector & err_v = (*this).get_plane_errs( np, nr, nt );
00290 *m_nv = err_v[0]*nr;
00291 *(m_nv+1) = err_v[1]*nt;
00292 return( m_nv );
00293
00294 }
00295
00296
00297
00298
00299
00300 bool Ext_errmx::valid( bool msg ) const
00301 {
00302 if( m_valid ){
00303 if( Ext_err_valid( msg, m_err, 6 ) ){
00304 return 1;
00305 } else {
00306 m_valid = 0;
00307 return 0;
00308 }
00309 } else {
00310 return 0;
00311 }
00312 }
00313
00314
00315
00316 Ext_errmx &Ext_errmx::operator=( const Ext_errmx &err )
00317 {
00318 if( this != &err ){
00319 m_err = err.m_err;
00320 m_err3 = err.m_err3;
00321 m_err2 = err.m_err2;
00322 m_R = err.m_R;
00323 m_valid = err.m_valid;
00324 *m_nv = *err.m_nv;
00325 *(m_nv+1) = *(err.m_nv+1);
00326 }
00327 return *this;
00328 }
00329
00330
00331
00332
00333 std::ostream &operator<<( std::ostream &s, const Ext_errmx &err )
00334 {
00335 s << " m_valid: " << err.m_valid << '\n'
00336 << "m_err: " << err.m_err << " m_err3: " << err.m_err3
00337 << " m_R: " << err.m_R << " m_err2: " << err.m_err2
00338 << " *m_nv: " << *err.m_nv
00339 << " *(m_nv+1): " << *(err.m_nv+1)
00340 << std::endl;
00341 return s;
00342 }