Quaternionfs getRotations( const GIDSet& gids ) const final { const float deg2rad = float( M_PI ) / 180.f; const brion::NeuronMatrix& data = _circuit.get( gids, brion::NEURON_ROTATION ); Quaternionfs rotations( gids.size( )); #pragma omp parallel for for( size_t i = 0; i < gids.size(); ++i ) { try { // transform rotation Y angle in degree into rotation quaternion const float angle = lexical_cast<float>( data[i][0] ) * deg2rad; rotations[i] = Quaternionf( angle, Vector3f( 0, 1, 0 )); } catch( const boost::bad_lexical_cast& ) { GIDSet::const_iterator gid = gids.begin(); std::advance( gid, i ); LBWARN << "Error parsing circuit orientation for gid " << *gid << std::endl; } } return rotations; }
Vector3fs getPositions( const GIDSet& gids ) const final { const brion::NeuronMatrix& data = _circuit.get( gids, brion::NEURON_POSITION_X | brion::NEURON_POSITION_Y | brion::NEURON_POSITION_Z ); Vector3fs positions( gids.size( )); #pragma omp parallel for for( size_t i = 0; i < gids.size(); ++i ) { try { positions[i] = brion::Vector3f( lexical_cast< float >( data[i][0] ), lexical_cast< float >( data[i][1] ), lexical_cast< float >( data[i][2] )); } catch( const boost::bad_lexical_cast& ) { GIDSet::const_iterator gid = gids.begin(); std::advance( gid, i ); LBWARN << "Error parsing circuit position for gid " << *gid << std::endl; } } return positions; }
Strings getMorphologyNames( const GIDSet& gids ) const final { Strings results( gids.size( )); const ::MVD3::Range& range = getRange( gids ); const Strings& morphos = _circuit.getMorphologies( range ); assign( range, gids, morphos, results, toString ); return results; }
Quaternionfs getRotations( const GIDSet& gids ) const final { Quaternionfs results( gids.size( )); const ::MVD3::Range& range = getRange( gids ); const ::MVD3::Rotations& rotations = _circuit.getRotations( range ); assign( range, gids, rotations, results, toQuaternion ); return results; }
Vector3fs getPositions( const GIDSet& gids ) const final { Vector3fs results( gids.size( )); const ::MVD3::Range& range = getRange( gids ); const ::MVD3::Positions& positions = _circuit.getPositions( range ); assign( range, gids, positions, results, toVector3f ); return results; }
std::vector<uint32_t> CompartmentReportCommon::_computeSubsetIndices( const GIDSet& source, const GIDSet& target) { GIDSet::iterator i = source.begin(); std::vector<uint32_t> indices; indices.reserve(target.size()); uint32_t sourceIndex = 0; for (const auto gid : target) { assert(i != source.end()); while (*i != gid) { ++i; ++sourceIndex; } indices.push_back(sourceIndex); } return indices; }
neuron::Morphologies Circuit::loadMorphologies( const GIDSet& gids, const Coordinates coords ) const { const URIs& uris = getMorphologyURIs( gids ); const auto circuitPath = // cache outside of loop, canonical does stat() which is slow on GPFS fs::canonical( _impl->getCircuitSource().getPath( )).generic_string(); // < GID, hash > Strings gidHashes; gidHashes.reserve( uris.size( )); std::set< std::string > hashes; GIDSet::const_iterator gid = gids.begin(); for( size_t i = 0; i < uris.size(); ++i, ++gid ) { auto hash = uris[i].getPath(); if( hash[0] != '/' ) // opt: don't stat abs file path (see above) hash = fs::canonical( hash ).generic_string(); if( coords == Coordinates::global ) // store circuit + GID for transformed morphology hash += circuitPath + boost::lexical_cast< std::string >( *gid ); hash = servus::make_uint128( hash ).getString(); gidHashes.push_back( hash ); hashes.insert( hash ); } CachedMorphologies cached = _impl->loadMorphologiesFromCache( hashes ); // resolve missing morphologies and put them in GID-order into result neuron::Morphologies result; result.reserve( uris.size( )); const Matrix4fs transforms = coords == Coordinates::global ? getTransforms( gids ) : Matrix4fs(); for( size_t i = 0; i < uris.size(); ++i ) { const URI& uri = uris[i]; const std::string& hash = gidHashes[i]; CachedMorphologies::const_iterator it = cached.find( hash ); if( it == cached.end( )) { neuron::MorphologyPtr morphology; const brion::Morphology raw( uri.getPath( )); if( coords == Coordinates::global ) morphology.reset( new neuron::Morphology( raw, transforms[i] )); else morphology.reset( new neuron::Morphology( raw )); cached.insert( std::make_pair( hash, morphology )); _impl->saveMorphologiesToCache( uri.getPath(), hash, morphology ); result.push_back( morphology ); } else result.push_back( it->second ); } return result; }
GIDSet CompartmentReportCommon::_computeIntersection(const GIDSet& all, const GIDSet& subset) { GIDSet intersection; std::set_intersection(subset.begin(), subset.end(), all.begin(), all.end(), std::inserter(intersection, intersection.begin())); if (intersection != subset || intersection.empty()) { LBWARN << "Requested " << subset.size() << " GIDs [" << *subset.begin() << ":" << *subset.rbegin() << "] are not a subset of the " << all.size() << " GIDs in the report [" << *all.begin() << ":" << *all.rbegin(); if (intersection.empty()) LBWARN << " with no GIDs in common" << std::endl; else LBWARN << "], using intersection size " << intersection.size() << " [" << *intersection.begin() << ":" << *intersection.rbegin() << "]" << std::endl; } return intersection; }