neuron::Morphologies Circuit::loadMorphologies( const GIDSet& gids, const Coordinates coords ) const { const URIs& uris = getMorphologyURIs( gids ); neuron::Morphologies result; result.reserve( uris.size( )); if( coords == COORDINATES_GLOBAL ) { const Matrix4fs& transforms = getTransforms( gids ); for( size_t i = 0; i < uris.size(); ++i ) { const URI& uri = uris[i]; const brion::Morphology raw( uri.getPath( )); result.push_back( neuron::MorphologyPtr( new neuron::Morphology( raw, transforms[i] ))); } return result; } std::map< std::string, neuron::MorphologyPtr > loaded; for( size_t i = 0; i < uris.size(); ++i ) { const URI& uri = uris[i]; neuron::MorphologyPtr& morphology = loaded[uri.getPath()]; if( !morphology ) { const brion::Morphology raw( uri.getPath( )); morphology.reset( new neuron::Morphology( raw )); } result.push_back( morphology ); } return result; }
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; }