// LayerZPlane.cpp #include "LayerZPlane.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 "trfbase/Miss.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() == "LayerZPlane" ); SurfZPlanePtr 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 LayerZPlane(psrf,pfind) ); } } //********************************************************************** // constructor LayerZPlane::LayerZPlane(const SurfZPlanePtr& zptr, MutableClusterFindManagerPtr pfind) : _srf(zptr), _pfind(pfind) { } //********************************************************************** LayerZPlane::LayerZPlane(const LayerZPlane& z) { *this = z; } //********************************************************************** const LayerZPlane& LayerZPlane::operator=(const LayerZPlane& z) { _srf = z._srf; _pfind = z._pfind; return *this; } //********************************************************************** // destructor LayerZPlane::~LayerZPlane() { } //********************************************************************** // output stream void LayerZPlane::ostr(ostream& stream) const { stream << begin_object ; stream << "ZPlane 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 LayerZPlane:: _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. ltracks.push_back(trl0); LTrack& trl = ltracks[ltracks.size()-1]; ETrack& tre = trl.get_track(); // 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 dir = Propagator::BACKWARD; double dz= tre.space_vector().dz(); double tz= tre.space_point().z(); double sz= _srf->get_z(); double dz_p=sz-tz; if( dz_p*dz > 0. ) dir = Propagator::FORWARD; // 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(); } // Put the track on the list and return. 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 LayerZPlane::get_cluster_surfaces() const { Layer::SurfaceList lst; lst.push_back(_srf); return lst; } //********************************************************************** // return the list of clusters ClusterList LayerZPlane::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 LayerZPlane::get_clusters(SurfacePtr psrf) const { if( _srf!=psrf) { report_invalid_surface(psrf); return ClusterList(); } return get_clusters(); } //********************************************************************** // add a cluster int LayerZPlane::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 LayerZPlane::add_cluster(const ClusterPtr& pclu, SurfacePtr psrf) { if( _srf!=psrf) { report_invalid_surface(psrf); return 3; } return add_cluster(pclu); } //********************************************************************** // drop clusters void LayerZPlane::drop_clusters() { if ( _pfind ) _pfind->drop_clusters(); } //********************************************************************** // Return the creator. ObjCreator LayerZPlane::get_creator() { return create; } //********************************************************************** // Write the object data. ObjData LayerZPlane::write_data() const { ObjData data( get_type_name() ); data.add_share_pointer( "surface", get_surface() ); data.add_share_pointer( "finder", get_finder() ); return data; } //**********************************************************************