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 }
std::vector<Id::Type> PFBlock::linkedIds(IdType uniqueid, Edge::EdgeType edgetype) const { /// Returns list of all linked ids of a given edge type that are connected to a given id - /// TODO think about sorting Ids linkedIds; for (auto key : linkedEdgeKeys(uniqueid, edgetype)) { auto found = m_edges.find(key); if (found == m_edges.end()) throw std::range_error("Required EdgeKey is missing from Linked Edges collection"); linkedIds.push_back(found->second.otherid(uniqueid)); } // std::sort(linkedIds.begin(), linkedIds.end(), [this, uniqueid](IdType a, IdType b) -> bool // { return this->compareEdges(a, b, uniqueid); } ); return linkedIds; }
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); } } }
/* * function members */ TSP(Dmatrix _costs) : dist(_costs), n(_costs.size()) { iorder.resize(n); jorder.resize(n); maxd = dist.max(); /* * identity_permutations */ std::iota(std::begin(iorder), std::end(iorder), 0); #if 0 for (auto &e : iorder) { e = i; } #endif /* * best order */ border = iorder; bestCost = dist.pathCost(border); }
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 ); }
SearchContext(const Point* points_begin, const Point* points_end) { auto start_time = std::chrono::system_clock::now(); auto objects = points_end - points_begin; if (objects > std::numeric_limits<int32_t>::max()) return; auto points_count = (int32_t)objects; coordinates.xs.resize(points_count); coordinates.ys.resize(points_count); ids.resize(points_count); ordered_points.resize(points_count); auto ranks = Ranks(points_count, END_OF_DATA); auto points = std::vector<Point>(points_count); for (auto it = points_begin; it != points_end; ++it) { auto idx = it->rank; if (idx < 0 || idx >= points_count || ranks[idx] != END_OF_DATA) return; coordinates.xs[idx] = it->x; coordinates.ys[idx] = it->y; ids[idx] = it->id; ranks[idx] = idx; points[idx] = *it; ordered_points[idx] = *it; } Mappings mappings(points_count, coordinates, ids); concurrency::parallel_sort(points.begin(), points.end(), [](const Point& a, const Point& b) { return a.x < b.x; }); for (auto i = 0; i < points_count; ++i) { mappings.x_sorted_rank_idxes[i] = points[i].rank; mappings.rank_idx_to_x_sorted_idxes[points[i].rank] = i; } concurrency::parallel_sort(points.begin(), points.end(), [](const Point& a, const Point& b) { return a.y < b.y; }); for (auto i = 0; i < points_count; ++i) { mappings.y_sorted_rank_idxes[i] = points[i].rank; mappings.rank_idx_to_y_sorted_idxes[points[i].rank] = i; } top = surface_factory(mappings, ranks, 0, false, false); }
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 }
void PFReconstructor::reconstructHcal(const PFBlock& block, IdType hcalId) { /* block: element ids and edges hcalid: id of the hcal being processed her has hcal and has a track -> add up all connected tracks, turn each track into a charged hadron -> add up all ecal energies -> if track energies is greater than hcal energy then turn the missing energies into an ecal (photon) NB this links the photon to the hcal rather than the ecals -> if track energies are less than hcal then make a neutral hadron with rest of hcal energy and turn all ecals into photons has hcal but no track (nb by design there will be no attached ecals because hcal ecal links have been removed) -> make a neutral hadron has hcals -> each hcal is treated using rules above */ // hcal used to make ecal_in has a couple of possible issues // m_pfEvent.HCALCluster(hcalId); // TODO assert(len(block.linked_ids(hcalid, "hcal_hcal"))==0 ) // TODO sorting Ids trackids = block.sort_distance_energy(hcalid, block.linked_ids(hcalid, "hcal_track") ) Ids ecalIds; Ids trackIds = block.linkedIds(hcalId, Edge::EdgeType::kHcalTrack); #if WITHSORT std::sort(trackIds.begin(), trackIds.end()); #endif for (auto trackId : trackIds) { for (auto ecalId : block.linkedIds(trackId, Edge::EdgeType::kEcalTrack)) { /*the ecals get all grouped together for all tracks in the block # Maybe we want to link ecals to their closest track etc? # this might help with history work # ask colin.*/ if (!m_locked[ecalId]) { ecalIds.push_back(ecalId); m_locked[ecalId] = true; } } } #if WITHSORT std::sort(trackIds.begin(), trackIds.end()); std::sort(ecalIds.begin(), ecalIds.end()); #endif // hcal should be the only remaining linked hcal cluster (closest one) const Cluster& hcal = m_pfEvent.HCALCluster(hcalId); double hcalEnergy = hcal.energy(); double ecalEnergy = 0.; double trackEnergy = 0.; if (!trackIds.empty()) { for (auto id : trackIds) { const Track& track = m_pfEvent.tracks().at(id); insertParticle(block, reconstructTrack(track)); trackEnergy += track.energy(); } for (auto id : ecalIds) { ecalEnergy += m_pfEvent.ECALCluster(id).energy(); } double deltaERel = (hcalEnergy + ecalEnergy) / trackEnergy - 1.; double caloERes = neutralHadronEnergyResolution(hcal); /*self.log.info( 'dE/p, res = {derel}, {res} '.format( derel = delta_e_rel, res = calo_eres ))*/ if (deltaERel > nsigmaHcal(hcal) * caloERes) { //# approx means hcal energy + ecal energies > track energies double excess = deltaERel * trackEnergy; // energy in excess of track energies // print( 'excess = {excess:5.2f}, ecal_E = {ecal_e:5.2f}, diff = {diff:5.2f}'.format( // excess=excess, ecal_e = ecal_energy, diff=excess-ecal_energy)) if (excess <= ecalEnergy) { /* # approx means hcal energy > track energies # Make a photon from the ecal energy # We make only one photon using only the combined ecal energies*/ insertParticle(block, reconstructCluster(hcal, papas::Layer::kEcal, excess)); } else { // approx means that hcal energy>track energies so we must have a neutral hadron // excess-ecal_energy is approximately hcal energy - track energies insertParticle(block, reconstructCluster(hcal, papas::Layer::kHcal, excess - ecalEnergy)); if (ecalEnergy) { // make a photon from the remaining ecal energies // again history is confusingbecause hcal is used to provide direction // be better to make several smaller photons one per ecal? insertParticle(block, reconstructCluster(hcal, papas::Layer::kEcal, ecalEnergy)); } } } } else { // # case whether there are no tracks make a neutral hadron for each hcal //# note that hcal-ecal links have been removed so hcal should only be linked to //# other hcals insertParticle(block, reconstructCluster(hcal, papas::Layer::kHcal)); } m_locked[hcalId] = true; }