// LayerXYPlane.cpp #include "LayerXYPlane.h" #include "trfbase/CrossStat.h" #include "trfbase/ETrack.h" #include "trfbase/Propagator.h" #include "trfbase/PropStat.h" #include "spacegeom/SpacePath.h" #include "trflayer/LayerStat.h" #include "trfutil/TRFMath.h" #include "trfutil/trfstream.h" #include "objstream/ObjData.hpp" #include "objstream/ObjTable.hpp" using namespace trf; //********************************************************************** // Free functions. //********************************************************************** namespace { // Creator. ObjPtr create(const ObjData& data) { assert( data.get_object_type() == "LayerXYPlane" ); SurfXYPlanePtr psrf; data.get_share_pointer("surface",psrf); ClusterFindManagerPtr pfind_const; data.get_share_pointer("finder",pfind_const); MutableClusterFindManagerPtr pfind; pfind.assign_with_const_cast(pfind_const); return ObjPtr( new LayerXYPlane(psrf,pfind) ); } } //********************************************************************** // constructor LayerXYPlane::LayerXYPlane(const SurfXYPlanePtr& xyptr, MutableClusterFindManagerPtr pfind) : _srf(xyptr ), _pfind(pfind) { } //********************************************************************** // constructor LayerXYPlane::LayerXYPlane(const LayerXYPlane& xy) { *this = xy; } // constructor const LayerXYPlane& LayerXYPlane::operator=(const LayerXYPlane& xy) { _srf = xy._srf; _pfind = xy._pfind; return *this; } //********************************************************************** // destructor LayerXYPlane::~LayerXYPlane() { } //********************************************************************** // output stream void LayerXYPlane::ostr(ostream& stream) const { stream << begin_object ; stream << "XYPlane layer."; stream << new_line; stream << "Surfaces :" << new_line; stream<< *_srf << new_line; if ( _pfind ) stream << "Finder: " << *_pfind; else stream << "No finder."; stream << new_line; stream << "No miss defined."; stream << end_object; } //********************************************************************** // propagation to this surface void LayerXYPlane:: _propagate(const LTrack& trl0, const Propagator& prop,LTrackList& ltracks) const { // The input state should be the default one. if ( trl0.get_status().get_state() != 0 ) return; // Copy the track // Create the output track list. ltracks.push_back(trl0); LTrack& trl = ltracks[ltracks.size()-1]; ETrack& tre = trl.get_track(); VTrack trv( *((VTrack *)&tre) ); // Fetch the crossing status. CrossStat xstat = _srf->pure_status(tre); // If track is not on surface, propagate it. if ( ! xstat.at() ) { // Find the direction for propagation. Propagator::PropDir dir1 = Propagator::FORWARD; PropStat pstat1 = prop.vec_dir_prop(trv,*_srf,dir1); Propagator::PropDir dir= Propagator::FORWARD; if( !pstat1.success() ) dir= Propagator::BACKWARD; else { const SpacePath& sp = trv.space_vector(); double dy1= sp.dy(); double dx1= sp.dx(); double phi= _srf->get_parameter( SurfXYPlane::NORMPHI); double px= cos(phi); double py= sin(phi); if( px*dx1+py*dy1 >= 0) dir= Propagator::FORWARD; else dir= Propagator::BACKWARD; } // Propagate. PropStat pstat = prop.err_dir_prop(tre,*_srf,dir); // If propagation fails, exit. if ( ! pstat.success() ) {ltracks.pop_back();return ;} trl.get_prop_stat() = pstat ; } // Check the crossing status. // We could but do not check bounds. xstat = _srf->status(tre); assert( xstat.at() ); // Create the return status. // Set the state to a non-default value and set at_exit. // LayerStat lstat(*this); trl.get_status().reset(); trl.get_status().set_state(1); trl.get_status().set_at_exit(); if ( _pfind ) { trl.get_status().set_finder(*_pfind); trl.set_cluster_status(); } // Create the one return track. if(!_srf->is_pure()) { if(xstat.in_bounds() && !xstat.out_of_bounds()) trl.get_status().set_state(2); if( ! xstat.in_bounds() ) trl.get_status().set_state(3); } } //********************************************************************** Layer::SurfaceList LayerXYPlane::get_cluster_surfaces() const { Layer::SurfaceList lst; lst.push_back(_srf); return lst; } //********************************************************************** // return the list of clusters ClusterList LayerXYPlane::get_clusters() const { if ( _pfind ) return _pfind->get_clusters(); else return ClusterList(); } //********************************************************************** // Return all the clusters associated with a particular surface in // the current layer or its descendants. // Default is to return an empty list. ClusterList LayerXYPlane::get_clusters(SurfacePtr psrf) const { if( _srf!=psrf) { report_invalid_surface(psrf); return ClusterList(); } return get_clusters(); } //********************************************************************** // add a cluster int LayerXYPlane::add_cluster(const ClusterPtr& pclu) { bool ok = _srf->pure_equal( pclu->get_surface() ); //assert( ok ); //if ( ! ok ) return 1; if ( _pfind ) return _pfind->add_cluster(pclu); else return 2; } //********************************************************************** int LayerXYPlane::add_cluster(const ClusterPtr& pclu, SurfacePtr psrf) { if( _srf!=psrf) { report_invalid_surface(psrf); return 3; } return add_cluster(pclu); } //********************************************************************** // drop clusters void LayerXYPlane::drop_clusters() { if ( _pfind ) _pfind->drop_clusters(); } //********************************************************************** // Return the creator. ObjCreator LayerXYPlane::get_creator() { return create; } //********************************************************************** // Write the object data. ObjData LayerXYPlane::write_data() const { ObjData data( get_type_name() ); data.add_share_pointer( "surface", get_surface() ); data.add_share_pointer( "finder", _pfind ); return data; } //**********************************************************************