// Detector.cpp #include "Detector.h" #include "LayerPtr.h" #include #include "objstream/ObjData.hpp" #include "objstream/ObjTable.hpp" #include "trfutil/trfstream.h" #include "Layer.h" using std::vector; using std::ostream; using trf::Layer; using trf::LayerPtr; using trf::ConstLayerPtr; using trf::Detector; #ifdef __KCC // Bug fix for KCC. Detector::LayerNameList::size_type max(Detector::LayerNameList::size_type sz1, Detector::LayerNameList::size_type sz2 ) { return std::max(sz1,sz2); } #endif //********************************************************************** // Free functions. //********************************************************************** namespace { //********************************************************************** // Detector subclass used to create a generic Detector. // This allows us to construct a detector and add the layers and // subdetectors. class GenericDetector : public Detector { public: typedef vector LayerList; typedef vector ConstLayerList; GenericDetector(const LayerNameList& lnames, const LayerList& layers, const DetectorList& detectors); }; GenericDetector:: GenericDetector(const LayerNameList& lnames, const LayerList& layers, const DetectorList& detectors) { assert( lnames.size() == layers.size() ); if ( lnames.size() != layers.size() ) return; LayerList::const_iterator ilyr = layers.begin(); for ( LayerNameList::const_iterator iname=lnames.begin(); iname!=lnames.end(); ++iname ) { const LayerPtr& plyr = *ilyr++; assert( plyr != 0 ); int stat = add_layer(*iname,plyr); assert( stat == 0 ); } for ( DetectorList::const_iterator idet=detectors.begin(); idet!=detectors.end(); ++idet ) { assert( *idet != 0 ); add_subdetector(*idet); } } //********************************************************************** // Creator. // Need to add list of names and list of layers. ObjPtr create(const ObjData& data) { assert( data.get_object_type() == "Detector" ); if ( data.get_object_type() != "Detector" ) return ObjPtr(0); GenericDetector::LayerNameList lnames; GenericDetector::ConstLayerList clayers; GenericDetector::DetectorList detectors; #ifdef ObjData_supports_lists // Fetch lists. data.get_string_list("layer_names",lnames); data.get_share_ptr_list("layers",clayers); data.get_share_ptr_list("subdetectors",detectors); #endif GenericDetector::LayerList layers; for ( GenericDetector::ConstLayerList::const_iterator ilyr=clayers.begin(); ilyr!=clayers.end(); ++ilyr ) { LayerPtr plyr; plyr.assign_with_const_cast(*ilyr); layers.push_back(plyr); } return ObjPtr( new GenericDetector(lnames, layers, detectors) ); } } // Flags for assertions. // If set false, assertion will fail. static bool CHECK_SIZE_MISMATCH = false; //********************************************************************** // Member functions. //********************************************************************** // Default constructor. Detector::Detector() : _check(UNCHECKED) { } //********************************************************************** // Destructor. Detector::~Detector() { } //********************************************************************** // Return the creator. ObjCreator Detector::get_creator() { return create; } //********************************************************************** // Write data object. // Note that we write out all the layers including those from // subdetectors and we do not write out any subdetectors. ObjData Detector::write_data() const { ObjData data("Detector"); #ifdef ObjData_supports_lists GenericDetector::LayerList layers; GenericDetector::DetectorList detectors; for ( LayerNameList::const_iterator iname=get_layer_names().begin(); iname!=get_layer_names().end(); ++iname ) layers.push_back( get_layer_pointer(*iname) ); data.add_string_list( "layer_names", get_layer_names() ); data.add_share_ptr_list("layers", layers); data.add_share_ptr_list("subdetectors", detectors); #endif return data; } //********************************************************************** // Add a layer. // Take no action if if name has already been used. int Detector::add_layer(LayerName name, const LayerPtr& plyr) { // Set unchecked. if ( _check == CHECKED_OK ) _check = UNCHECKED; // Check name does not already appear in map. if ( is_assigned(name) ) return 11; // Add layer. _names.push_back(name); _layermap[name] = plyr; return 0; } //********************************************************************** // Add the layers from a subdetector. // If any names are used, then add none. int Detector::add_subdetector(const DetectorPtr& psdt) { // Set unchecked. if ( _check == CHECKED_OK ) _check = UNCHECKED; // Exit if the subdetector does not check ok. if ( ! psdt->is_ok() ) return 21; // Fetch the subdetector names and layer map. const LayerNameList subnames = psdt->get_layer_names(); const LayerMap& sublayermap = psdt->get_layer_map(); // Check that the names are unique. LayerNameList::const_iterator iname; for ( iname=subnames.begin(); iname!=subnames.end(); ++iname ) if ( is_assigned(*iname) ) return 22; // Add the layers from each subdetector. _names.insert( _names.end(), subnames.begin(), subnames.end() ); _layermap.insert( sublayermap.begin(), sublayermap.end() ); // The check status will reflect that of the added layers. return 0; } //********************************************************************** // Check the detector. // This checks the detector for internal consistency and sets the // status accordingly. // Presently, the status is inherently good, so no check is needed. void Detector::check() const { // Bad check stays bad. if ( _check == CHECKED_BAD ) return; // Check the list of names and map have the same size. // There is a logic error if this fails. if ( _names.size() != _layermap.size() ) { assert( CHECK_SIZE_MISMATCH ); _check = CHECKED_BAD; } // All tests passed. _check = CHECKED_OK; } //********************************************************************** // Print the layers. void Detector::print_layers(ostream& stream) const { // Fetch list of layer names (including subdetectors) LayerNameList names = get_layer_names(); // header int size = names.size(); stream << begin_object; stream << "Detector has " << size << " layer"; if ( size != 1 ) stream << "s"; if ( size > 0 ) stream << ":"; else stream << "."; // Loop over layers. LayerNameList::const_iterator iname; for ( iname=names.begin(); iname!=names.end(); ++iname ) { LayerName name = *iname; stream << new_line; stream << name << ": " << get_layer(name); } stream << end_object; } //********************************************************************** // Return whether a name has been assigned. bool Detector::is_assigned(LayerName name) const { return _layermap.find(name) != _layermap.end(); } //********************************************************************** // return a layer by pointer. LayerPtr Detector::get_layer_pointer(LayerName name) const { LayerMap::const_iterator ilyr = _layermap.find(name); if ( ilyr == _layermap.end() ) return LayerPtr(0); else return ilyr->second; } //********************************************************************** // Return a layer by reference. // Pointer will throw exception if name did not exist. Layer& Detector::get_layer(LayerName name) const { // fetch pointer to the layer LayerPtr plyr = get_layer_pointer(name); return *plyr; } //********************************************************************** ostream& trf::operator<<(ostream& stream, const Detector& rhs) { rhs.print_layers(stream); return stream; } //********************************************************************** // Register with ObjTable. int Detector::register_with_objtable() const { // Initialize the number of failures. int nfail = 0; // Fetch layer names. const Detector::LayerNameList& names = get_layer_names(); // Loop over layers and register each. for ( LayerNameList::const_iterator iname=names.begin(); iname!=names.end(); ++iname ) { LayerPtr plyr( get_layer_pointer(*iname) ); assert( plyr != 0 ); // Replace spaces in name with underscores. ObjName oname(*iname); for ( string::size_type ich=0; ich