// HitCylPhiZ.cpp #include "HitCylPhiZ.h" #include "objstream/ObjData.hpp" #include "objstream/ObjTable.hpp" #include "trfutil/trfstream.h" #include "trfbase/ETrack.h" #include "trfutil/TRFMath.h" using namespace trf; //********************************************************************** // Free functions. //********************************************************************** namespace { // Creator. ObjPtr create_cluster(const ObjData& data) { assert( data.get_object_type() == "ClusCylPhiZ" ); double radius = data.get_double("radius"); double phi = data.get_double("phiz"); double dphi = data.get_double("dphiz"); double stereo = data.get_double("stereo"); McIdList mcids; #ifdef ObjData_supports_lists data.get_int_list("mcids",mcids); #endif return ObjPtr( new ClusCylPhiZ(radius,phi,dphi,stereo,mcids) ); } ObjPtr create_hit(const ObjData& data) { assert(false); abort(); return ObjPtr(0); } } //********************************************************************** // ClusCylPhiZ //********************************************************************** // output stream void ClusCylPhiZ::ostr(ostream& stream) const { stream << begin_object; stream << "Hit at " << _scy << " with mixing " << _stereo << ": phiz = " << _phi << " +/- " << _dphi; stream << " MC ID's:"; const McIdList& mcids = get_mc_ids(); for ( McIdList::const_iterator imc=mcids.begin(); imc!=mcids.end(); ++imc ) stream << " " << *imc; stream << end_object; } //********************************************************************** // equality bool ClusCylPhiZ::equal(const Cluster& clus) const { assert( this->get_type() == clus.get_type() ); const ClusCylPhiZ& ccp = (const ClusCylPhiZ&) clus; return ( _phi == ccp._phi ) && ( _dphi == ccp._dphi ) && ( _stereo == ccp._stereo ) && ( _scy == ccp._scy ); } //********************************************************************** // constructor ClusCylPhiZ::ClusCylPhiZ(double radius, double phi, double dphi, double stereo) : _scy(radius), _phi(phi), _dphi(dphi), _stereo(stereo) { assert( _dphi >= 0.0 ); } //********************************************************************** // constructor with MC ID's ClusCylPhiZ::ClusCylPhiZ(double radius, double phi, double dphi, double stereo, const McIdList& mcids) : McCluster(mcids), _scy(radius), _phi(phi), _dphi(dphi), _stereo(stereo) { assert( _dphi >= 0.0 ); } //********************************************************************** // copy constructor ClusCylPhiZ::ClusCylPhiZ(const ClusCylPhiZ& rhs) : McCluster(rhs), _scy(rhs._scy), _phi(rhs._phi), _dphi(rhs._dphi), _stereo(rhs._stereo) { } //********************************************************************** // destructor ClusCylPhiZ::~ClusCylPhiZ( ) { } //********************************************************************** // Return the creator. ObjCreator ClusCylPhiZ::get_creator() { return create_cluster; } //********************************************************************** // Write the object data. ObjData ClusCylPhiZ::write_data() const { ObjData data( get_type_name() ); data.add_double( "radius", get_radius() ); data.add_double( "phiz", get_phiz() ); data.add_double( "dphiz", get_dphiz() ); data.add_double( "stereo", get_stereo() ); #ifdef ObjData_supports_lists data.add_int_list( "mcids", get_mc_ids() ); #endif return data; } //********************************************************************** // generate hits from a track HitList ClusCylPhiZ::_predict(const ETrack& tre) const { HitList hits; double phiz = tre.get_vector()(0) + _stereo*tre.get_vector()(1); double epp = tre.get_error()(0,0) + 2.0*_stereo*tre.get_error()(0,1) + _stereo*_stereo*tre.get_error()(1,1); hits.push_back( HitPtr(new HitCylPhiZ( phiz, epp )) ); return hits; } //********************************************************************** // HitCylPhi //********************************************************************** // output stream void HitCylPhiZ::ostr(ostream& stream) const { stream << "hit from "; stream << *_pclus; } //********************************************************************** // equality // Hits are equal if they have the same parent cluster. bool HitCylPhiZ::equal(const Hit& hit) const { assert( this->get_type() == hit.get_type() ); return get_cluster() == hit.get_cluster(); } //********************************************************************** // constructor HitCylPhiZ::HitCylPhiZ(double phi, double ephi) : _phi_pre(phi), _ephi_pre(ephi) { } //********************************************************************** // copy constructor HitCylPhiZ::HitCylPhiZ(const HitCylPhiZ& lhs) : Hit(lhs), _phi_pre(lhs._phi_pre), _ephi_pre(lhs._ephi_pre) { } //********************************************************************** // destructor HitCylPhiZ::~HitCylPhiZ() { } //********************************************************************** // Return the creator. ObjCreator HitCylPhiZ::get_creator() { return create_hit; } //********************************************************************** // Write the object data. ObjData HitCylPhiZ::write_data() const { ObjData data( get_type_name() ); return data; } //********************************************************************** // return the measured hit vector HitVector HitCylPhiZ::measured_vector() const { return HitVector( get_full_cluster().get_phiz() ); } //********************************************************************** // return the measured hit error HitError HitCylPhiZ::measured_error() const { double dphi = get_full_cluster().get_dphiz(); return HitError( dphi*dphi ); } //********************************************************************** // return the predicted hit vector HitVector HitCylPhiZ::predicted_vector() const { return HitVector( _phi_pre ); } //********************************************************************** // return the predicted hit error HitError HitCylPhiZ::predicted_error() const { return HitError( _ephi_pre ); } //********************************************************************** // return the derivative HitDerivative HitCylPhiZ::dhit_dtrack() const { double values[] = { 1.0, 0.0, 0.0, 0.0, 0.0 }; values[1] = get_full_cluster().get_stereo(); HitDerivative deriv(1,values); return deriv; } //********************************************************************** // return the difference between prediction and measurement. HitVector HitCylPhiZ::difference_vector() const { return HitVector( fmod2(_phi_pre-get_full_cluster().get_phiz(), TWOPI) ); } //********************************************************************** // update the hit prediction (measurement and derivative do not change) void HitCylPhiZ::update( const ETrack& tre) { double stereo = get_full_cluster().get_stereo(); _phi_pre = tre.get_vector()(0) + stereo*tre.get_vector()(1); _ephi_pre = tre.get_error()(0,0) + 2.0*stereo*tre.get_error()(0,1) + stereo*stereo*tre.get_error()(1,1); } //**********************************************************************