#include #include #include #include #include #include #include #include #include #include #include using namespace RAT; using namespace RAT::Methods; using namespace RAT::DS; void DirectionLikelihood::DefaultSeed() { FitVertex vertex; //Initialise the FitResult vertex.SetPosition( TVector3( 0.0, 0.0, 0.0), false, true); vertex.SetDirection( TVector3( 1.0, 0.0, 0.0 ), false, true ); vertex.SetDirectionErrors( TVector3( 1.0, 1.0, 1.0 ), false, true ); fSeedResult.SetVertex( 0, vertex ); } FitResult DirectionLikelihood::GetBestFit() { fFitResult.Reset(); if( fPMTData.empty() ) throw MethodFailError( "DirectionLikelihood: No hits to fit" ); CopySeedToResult(); SelectPMTData( fFitResult.GetVertex( 0 ) ); fFitResult.SetFOM( "SelectedNHit", static_cast( fSelectedPMTData.size() ) ); if( fSelectedPMTData.empty() ) throw MethodFailError( "DirectionLikelihood: No hits in selected PMT data" ); fOptimiser->SetComponent( this ); // Call the designated optimiser to fit and save the fom const double logL = fOptimiser->Maximise(); fFitResult.SetFOM( "LogL", logL ); // Now save the optimised values SetParams( fOptimiser->GetParams() ); SetPositiveErrors( fOptimiser->GetPositiveErrors() ); SetPositiveErrors( fOptimiser->GetNegativeErrors() ); // The direction should be a unit vector and the errors // should be scaled accordingly. // This is not performed in SetParams as the optimiser adjusts and // uses via that function; the method should not force the optimisers decisions. FitVertex vertex = fFitResult.GetVertex( 0 ); double scaling = vertex.GetDirection().Mag(); vertex.SetDirection( vertex.GetDirection().Unit(), fOptimiser->GetValid() ); vertex.SetPositiveDirectionError( TVector3( vertex.GetPositiveDirectionError().X() / scaling, vertex.GetPositiveDirectionError().Y() / scaling, vertex.GetPositiveDirectionError().Z() / scaling ), fOptimiser->GetValid() ); vertex.SetNegativeDirectionError( TVector3( vertex.GetNegativeDirectionError().X() / scaling, vertex.GetNegativeDirectionError().Y() / scaling, vertex.GetNegativeDirectionError().Z() / scaling ), fOptimiser->GetValid() ); fFitResult.SetVertex( 0, vertex ); return fFitResult; } double DirectionLikelihood::operator()( const std::vector& params ) { SetParams( params ); double logLike = 0.0; // loglike sum from pdf for( std::vector::const_iterator iPMT = fSelectedPMTData.begin(); iPMT != fSelectedPMTData.end(); ++iPMT ) logLike += log( fPDF->GetProbability( *iPMT, fFitResult.GetVertex(0) ) ); return logLike; } std::vector DirectionLikelihood::GetParams() const { std::vector params; FitVertex vertex = fFitResult.GetVertex(0); params.push_back( vertex.GetDirection().x() ); params.push_back( vertex.GetDirection().y() ); params.push_back( vertex.GetDirection().z() ); return params; } std::vector DirectionLikelihood::GetPositiveErrors() const { std::vector errors; FitVertex vertex = fFitResult.GetVertex(0); errors.push_back( vertex.GetPositiveDirectionError().x() ); errors.push_back( vertex.GetPositiveDirectionError().y() ); errors.push_back( vertex.GetPositiveDirectionError().z() ); return errors; } std::vector DirectionLikelihood::GetNegativeErrors() const { std::vector errors; FitVertex vertex = fFitResult.GetVertex(0); errors.push_back( vertex.GetNegativeDirectionError().x() ); errors.push_back( vertex.GetNegativeDirectionError().y() ); errors.push_back( vertex.GetNegativeDirectionError().z() ); return errors; } void DirectionLikelihood::SetParams( const std::vector& params ) { FitVertex vertex = fFitResult.GetVertex(0); vertex.SetDirection( TVector3( params[0], params[1], params[2] ), fOptimiser->GetValid() ); fFitResult.SetVertex( 0, vertex ); } void DirectionLikelihood::SetPositiveErrors( const std::vector& errors ) { FitVertex vertex = fFitResult.GetVertex(0); vertex.SetPositiveDirectionError( TVector3( errors[0], errors[1], errors[2] ), fOptimiser->GetValid() ); fFitResult.SetVertex( 0, vertex ); } void DirectionLikelihood::SetNegativeErrors( const std::vector& errors ) { FitVertex vertex = fFitResult.GetVertex(0); vertex.SetNegativeDirectionError( TVector3( errors[0], errors[1], errors[2] ), fOptimiser->GetValid() ); fFitResult.SetVertex( 0, vertex ); }