Edges edgesToUnlink(const PFBlock& block) { Edges toUnlink; Ids ids = block.elementIds(); if (ids.size() > 1) { Ids linkedIds; bool firstHCAL; double minDist = -1; for (auto id : ids) { if (IdCoder::isTrack(id)) { linkedIds = block.linkedIds(id, Edge::EdgeType::kHcalTrack); if (linkedIds.size() > 0) { firstHCAL = true; for (auto elem : linkedIds) { // find minimum distance between track and Hcals if (firstHCAL) { minDist = block.edge(id, elem).distance(); firstHCAL = false; } else { minDist = fmin(minDist, block.edge(id, elem).distance()); } } // unlink anything that is greater than minimum distance for (auto elem : linkedIds) { auto key = Edge::makeKey(id, elem); auto& edge = block.edge(id, elem); if (edge.distance() > minDist) { // (could be more than one at zero distance) toUnlink[key] = edge; // should toUnlink be list of keys rather than edges } } } } } } return toUnlink; // move }
static void output_once_( const boost::posix_time::ptime& t ) { std::pair< boost::posix_time::ptime, cv::Mat > output; if( polar ) { static unsigned int polar_size = ( row_size + offset_from_center ) * 2 + 1; static unsigned int type = output_options.get_header().type; static cv::Mat polar_image( polar_size, polar_size * ids.size(), type ); ::memset( const_cast< unsigned char* >( polar_image.datastart ), 0, polar_image.dataend - polar_image.datastart ); for( unsigned int i = 0; i < ids.size(); ++i ) { unsigned int offset = row_size * i; unsigned int polar_offset = polar_size * i; for( unsigned int row = 0; row < block_size; ++row ) { double x_step = sin_cos[row].second; double y_step = sin_cos[row].first * sign; double x = row_size + offset_from_center + polar_offset; double y = row_size + offset_from_center; x += sin_cos[row].second * offset_from_center; y += sin_cos[row].first * sign * offset_from_center; for( unsigned int column = 0; column < row_size; ++column, x += x_step, y += y_step ) { ::memcpy( const_cast< unsigned char* >( polar_image.datastart ) + ( int( y ) * ( polar_image.cols ) + int( x ) ) * pixel_size , image.datastart + ( int( row ) * image.cols + offset + column ) * pixel_size , pixel_size ); } } } output.second = polar_image; } else { output.second = image; } output.first = t; serialization->write( std::cout, output ); }
void PFReconstructor::reconstructBlock(const PFBlock& block) { /// see class description for summary of reconstruction approach Ids ids = block.elementIds(); #if WITHSORT std::sort(ids.begin(), ids.end()); #endif for (auto id : ids) { m_locked[id] = false; } if (ids.size() == 1) { //#TODO WARNING!!! LOTS OF MISSING CASES IdType id = ids[0]; if (Id::isEcal(id)) { insertParticle(block, reconstructCluster(m_pfEvent.ECALCluster(id), papas::Layer::kEcal)); } else if (Id::isHcal(id)) { insertParticle(block, reconstructCluster(m_pfEvent.HCALCluster(id), papas::Layer::kHcal)); } else if (Id::isTrack(id)) { insertParticle(block, reconstructTrack(m_pfEvent.track(id))); } else { // ask Colin about energy balance - what happened to the associated clusters that one would expect? // TODO } } else { for (auto id : ids) { if (Id::isHcal(id)) { reconstructHcal(block, id); } } for (auto id : ids) { if (Id::isTrack(id) && !m_locked[id]) { /* unused tracks, so not linked to HCAL # reconstructing charged hadrons. # ELECTRONS TO BE DEALT WITH.*/ insertParticle(block, reconstructTrack(m_pfEvent.track(id))); for (auto idlink : block.linkedIds(id, Edge::EdgeType::kEcalTrack)) { // TODO ask colin what happened to possible photons here: // TODO add in extra photons but decide where they should go? m_locked[idlink] = true; } } } } for (auto& id : ids) { if (!m_locked[id]) { m_unused.push_back(id); } } }
int main( int ac, char** av ) { int result = 0; try { comma::command_line_options options( ac, av ); if( options.exists( "--help,-h" ) ) { usage(); } verbose = options.exists( "--verbose,-v" ); csv = comma::csv::options( options, "values" ); csv.full_xpath = true; row_number_offset = options.value( "--row-number-offset,--offset", 0 ); polar = options.exists( "--polar" ); as_radians = !options.exists( "--degrees" ); clockwise = options.exists( "--clockwise" ); offset_from_center = options.value( "--offset-from-center", 0 ); // quick and dirty z_up = options.value< std::string >( "--z", "up" ) == "up"; sign = ( z_up && !clockwise ) || ( !z_up && clockwise ) ? 1 : -1; if( options.exists( "--fps" ) ) { dial_size = options.value( "--dial-size,--dial", 0 ); } std::string s = options.value< std::string >( "--size" ); std::vector< std::string > v = comma::split( s, ',' ); if( v.size() != 2 && v.size() != 3 ) { std::cerr << "image-accumulate: expected --size=<value>; got \"" << s << "\"" << std::endl; return 1; } block_size = boost::lexical_cast< unsigned int >( v[0] ); row_size = boost::lexical_cast< unsigned int >( v[1] ); scale = comma::csv::ascii< std::pair< double, double > >().get( options.value< std::string >( "--scale", "0,255" ) ); scaled< unsigned char > scaled( scale ); fps = options.optional< double >( "--fps" ); sin_cos = precomputed_sin_cos_(); channel::options default_channel_options( options ); std::vector< channel::options > channel_options; if( csv.has_field( "id" ) ) { const std::vector< std::string >& v = options.values< std::string >( "--id" ); if( v.empty() ) { std::cerr << "image-accumulate: 'id' field given, please specify at least one --id" << std::endl; return 1; } for( unsigned int i = 0; i < v.size(); ++i ) { channel_options.push_back( comma::name_value::parser( ';', '=' ).get< channel::options >( v[i], default_channel_options ) ); ids[ boost::lexical_cast< unsigned int >( comma::split( v[i], ';' )[0] ) ] = i; } } else { ids[0] = 0; channel_options.push_back( default_channel_options ); } in.values.resize( row_size ); has_block = csv.has_field( "block" ); has_row = csv.has_field( "row" ); has_angle = csv.has_field( "angle" ); if( has_row && has_angle ) { std::cerr << "image-accumulate: in input fields, expected either 'row' or 'angle'; got both" << std::endl; return 1; } comma::csv::input_stream< input > istream( std::cin, csv, in ); // todo: watch performance! std::string default_output_options = "no-header;rows=" + boost::lexical_cast< std::string >( polar ? row_size * 2 + 1 : block_size ) + ";cols=" + boost::lexical_cast< std::string >( polar ? ( row_size * 2 + 1 ) * ids.size() : row_size * ids.size() ) + ";type=3ub"; std::string output_options_string = options.value( "--output", default_output_options ); output_options = comma::name_value::parser( ';', '=' ).get< snark::cv_mat::serialization::options >( output_options_string ); if( options.exists( "--output-options" ) ) { std::cout << comma::name_value::parser( ';', '=' ).put< snark::cv_mat::serialization::options >( output_options ) << std::endl; return 0; } serialization.reset( new snark::cv_mat::serialization( output_options ) ); image = cv::Mat::zeros( block_size, row_size * ids.size(), output_options.get_header().type ); pixel_size = output_options.get_header().type == CV_8UC3 ? 3 : 1; // quick and dirty boost::ptr_vector< channel > channels; for( unsigned int i = 0; i < ids.size(); ++i ) { channels.push_back( new channel( i, channel_options[i] ) ); } if( fps ) { output_thread.reset( new boost::thread( &output_ ) ); } while( !is_shutdown && std::cin.good() && !std::cin.eof() ) { const input* p = istream.read(); if( p ) { Ids::const_iterator it = ids.find( p->id ); if( it == ids.end() ) { continue; } if( !channels[ it->second ].draw( p ) ) { break; } } else { for( Ids::const_iterator it = ids.begin(); it != ids.end(); ++it ) { channels[ it->second ].draw( p ); } break; } } } catch( std::exception& ex ) { std::cerr << "image-accumulate: " << ex.what() << std::endl; result = 1; } catch( ... ) { std::cerr << "image-accumulate: unknown exception" << std::endl; result = 1; } done = true; if( fps ) { output_thread->join(); } return result; }
Blocks PFReconstructor::simplifyBlock(IdType id) { /* Block: a block which contains list of element ids and set of edges that connect them history_nodes: optional dictionary of Nodes with element identifiers in each node returns None or a dictionary of new split blocks The goal is to remove, if needed, some links from the block so that each track links to at most one hcal within a block. In some cases this may separate a block into smaller blocks (splitblocks). The BlockSplitter is used to return the new smaller blocks. If history_nodes are provided then the history will be updated. Split blocks will have the tracks and cluster elements as parents, and also the original block as a parent */ Blocks splitBlocks; auto& block = m_blocks.at(id); Ids ids = block.elementIds(); if (ids.size() <= 1) { // if block is just one element therer are no links to remove return splitBlocks; } /* work out any links that need to be removed - for tracks unink all hcals except the closest hcal - for ecals unlink hcals */ Edges toUnlink; // TODO think about copy std::vector<Edge::EdgeKey> linkedEdgeKeys; bool firstHCAL; double minDist = -1; for (auto id : ids) { if (Id::isTrack(id)) { linkedEdgeKeys = block.linkedEdgeKeys(id, Edge::EdgeType::kHcalTrack); if (linkedEdgeKeys.size() > 0) { firstHCAL = true; // find minimum distance for (auto elem : linkedEdgeKeys) { if (firstHCAL) { minDist = block.findEdge(elem).distance(); firstHCAL = false; } else { minDist = fmin(minDist, block.findEdge(elem).distance()); } } // unlink anything that is greater than minimum distance for (auto elem : linkedEdgeKeys) { if (block.findEdge(elem).distance() > minDist) { // (could be more than one at zero distance) toUnlink[elem] = block.findEdge(elem); // should toUnlink be list of keys rather than edges } } } } else if (Id::isEcal(id)) { // this is now handled elsewhere in Ruler::distance and so could be removed // remove all ecal-hcal links. ecal linked to hcal give rise to a photon anyway. linkedEdgeKeys = block.linkedEdgeKeys(id, Edge::EdgeType::kEcalHcal); //"ecal_hcal") for (auto elem : linkedEdgeKeys) { toUnlink[elem] = block.findEdge(elem); } } } // if there is something to unlink then use the BlockSplitter if (toUnlink.size() > 0) { splitBlocks = BlockSplitter(toUnlink, block, m_historyNodes).blocks(); } return splitBlocks; // moves }