// LayerCylinder.cpp #include "LayerCylinder.h" #include "objstream/ObjData.hpp" #include "objstream/ObjTable.hpp" #include "trfutil/trfstream.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" using namespace trf; //********************************************************************** // Free functions. //********************************************************************** namespace { // Creator. ObjPtr create(const ObjData& data) { assert( data.get_object_type() == "LayerCylinder" ); Ptr 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 LayerCylinder(psrf,pfind) ); } } //********************************************************************** // Member functions. //********************************************************************** // constructor LayerCylinder::LayerCylinder(double r, double zmin, double zmax, const MutableClusterFindManagerPtr& pfind, const MissPtr& pmiss) : _psrf( new BSurfCylinder(r,zmin,zmax) ), _pfind(pfind), _pmiss(pmiss) { } //********************************************************************** // Constructor from a SurfCylinder. // Set pfind = 0 if no clusters are associated with layer. LayerCylinder:: LayerCylinder(const Ptr& psrf, const MutableClusterFindManagerPtr& pfind, const MissPtr& pmiss) : _psrf(psrf), _pfind(pfind), _pmiss(pmiss) { } //********************************************************************** // destructor LayerCylinder::~LayerCylinder() { } //********************************************************************** // Return the creator. ObjCreator LayerCylinder::get_creator() { return create; } //********************************************************************** // Write the object data. ObjData LayerCylinder::write_data() const { ObjData data( get_type_name() ); data.add_share_pointer( "surface", get_surface() ); data.add_share_pointer( "finder", get_finder() ); return data; } //********************************************************************** // output stream void LayerCylinder::ostr(ostream& stream) const { stream << begin_object; stream << "Cylinder layer."; stream << new_line; stream << "Surface: " << *_psrf; stream << 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 LayerCylinder::_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 ) { ltracks.erase(ltracks.begin(), ltracks.end()); return; } // Copy the track. LTrack trl = trl0; // Access the kinematic track. ETrack& tre = trl.get_track(); // Fetch the crossing status. CrossStat xstat = _psrf->status(tre); // Find the direction for propagation. // If the track is at the surface, we jump to the crossing on the // opposite side. Propagator::PropDir dir = Propagator::NEAREST; SpacePath svec = tre.space_vector(); if ( ! xstat.at() ) { if ( xstat.inside() ) { assert( ! xstat.outside() ); if ( svec.drxy() > 0.0 ) dir = Propagator::FORWARD; if ( svec.drxy() < 0.0 ) dir = Propagator::BACKWARD; } else if ( xstat.outside() ) { if ( svec.drxy() < 0.0 ) dir = Propagator::FORWARD; if ( svec.drxy() > 0.0 ) dir = Propagator::BACKWARD; } else if ( xstat.on() ) { dir = Propagator::NEAREST; } else { assert(false); } } else { if ( svec.drxy() < 0.0 ) dir = Propagator::FORWARD_MOVE; if ( svec.drxy() > 0.0 ) dir = Propagator::BACKWARD_MOVE; } // Propagate. trl.get_prop_stat() = prop.err_dir_prop(tre,*_psrf,dir); // If propagation fails, exit. if ( ! trl.get_prop_stat().success() ) { return; } // Check the crossing status. // We could but do not check bounds. xstat = _psrf->status(tre); assert( xstat.at() ); // Modify the return status. // Set the state to a non-default value and set at_exit. 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(); } if ( _pmiss ) { Miss* pmiss = _pmiss->new_copy(); pmiss->update(tre); trl.get_status().set_miss(*pmiss); delete pmiss; } // Update the propagtor return status. // Put the track on the list and return. ltracks.push_back(trl); return; } //********************************************************************** // Return the list of surfaces. LayerCylinder::SurfaceList LayerCylinder::get_cluster_surfaces() const { SurfaceList surfaces; surfaces.push_back(_psrf); return surfaces; } //********************************************************************** // return the list of clusters ClusterList LayerCylinder::get_clusters() const { if ( _pfind ) return _pfind->get_clusters(); else return ClusterList(); } //********************************************************************** // return the list of clusters associated with a surface ClusterList LayerCylinder::get_clusters(SurfacePtr psrf) const { // If the surfaces is wrong, return an empty list. if ( psrf != _psrf ) { report_invalid_surface(psrf); return ClusterList(); } return get_clusters(); } //********************************************************************** // add a cluster int LayerCylinder::add_cluster(const ClusterPtr& pclu) { // Temporarily drop requirement that cluster and layer surfaces are // the same. CFT does not quite satisfy this. //bool ok = _psrf->pure_equal( pclu->get_surface() ); //assert( ok ); //if ( ! ok ) return 1; if ( _pfind ) return _pfind->add_cluster(pclu); else return 2; } //********************************************************************** // add a cluster associated with a surface int LayerCylinder::add_cluster(const ClusterPtr& pclu, SurfacePtr psrf) { // If the surface is wrong, return an error if ( psrf != _psrf ) { report_invalid_surface(psrf); return 3; } return add_cluster(pclu); } //********************************************************************** // drop clusters void LayerCylinder::drop_clusters() { if ( _pfind ) _pfind->drop_clusters(); } //**********************************************************************