forked from BlueBrain/Brion
-
Notifications
You must be signed in to change notification settings - Fork 0
/
circuit.cpp
225 lines (185 loc) · 6.43 KB
/
circuit.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
/* Copyright (c) 2013-2016, EPFL/Blue Brain Project
* Juan Hernando <jhernando@fi.upm.es>
* Adrien.Devresse@epfl.ch
* Daniel.Nachbaur@epfl.ch
* Stefan.Eilemann@epfl.ch
*
* This file is part of Brion <https://github.com/BlueBrain/Brion>
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 3.0 as published
* by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "circuit.h"
#include "detail/circuit.h"
#include "synapsesStream.h"
namespace brain
{
Circuit::Impl* newImpl( const brion::BlueConfig& config )
{
const std::string circuit = config.getCircuitSource().getPath();
if( boost::algorithm::ends_with( circuit, ".mvd2" ))
return new MVD2( config );
#ifdef BRAIN_USE_MVD3
return new MVD3( config );
#else
throw std::runtime_error( "MVD3 support requires CMake 3" );
#endif
}
Circuit::Circuit( const URI& source )
: _impl( newImpl( brion::BlueConfig( source.getPath( ))))
{
}
Circuit::Circuit( const brion::BlueConfig& config )
: _impl( newImpl( config ))
{
}
Circuit::~Circuit()
{
}
GIDSet Circuit::getGIDs() const
{
return _impl->getGIDs();
}
GIDSet Circuit::getGIDs( const std::string& target ) const
{
return _impl->getGIDs( target );
}
GIDSet Circuit::getRandomGIDs( const float fraction ) const
{
return _impl->getRandomGIDs( fraction, "" );
}
GIDSet Circuit::getRandomGIDs( const float fraction,
const std::string& target ) const
{
return _impl->getRandomGIDs( fraction, target );
}
URIs Circuit::getMorphologyURIs( const GIDSet& gids ) const
{
const Strings& names = _impl->getMorphologyNames( gids );
URIs uris;
uris.reserve( names.size( ));
for( Strings::const_iterator i = names.begin(); i < names.end(); ++i )
uris.push_back( _impl->getMorphologyURI( *i ));
return uris;
}
neuron::Morphologies Circuit::loadMorphologies( const GIDSet& gids,
const Coordinates coords ) const
{
const URIs& uris = getMorphologyURIs( gids );
// < 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 )
{
std::string hash( fs::canonical( uris[i].getPath( )).generic_string( ));
if( coords == Coordinates::global )
{
// store circuit + GID for transformed morphology
hash += fs::canonical(
_impl->getCircuitSource().getPath( )).generic_string() +
boost::lexical_cast< std::string >( *gid );
hash = servus::make_uint128( hash ).getString();
}
else
hash = servus::make_uint128( hash ).getString();
gidHashes.push_back( hash );
hashes.insert( hash );
}
Loaded loaded = _impl->loadFromCache( 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];
Loaded::const_iterator it = loaded.find( hash );
if( it == loaded.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 ));
loaded.insert( std::make_pair( hash, morphology ));
_impl->saveToCache( hash, morphology );
result.push_back( morphology );
}
else
result.push_back( it->second );
}
return result;
}
Vector3fs Circuit::getPositions( const GIDSet& gids ) const
{
return _impl->getPositions( gids );
}
size_ts Circuit::getMorphologyTypes( const GIDSet& gids ) const
{
return _impl->getMTypes( gids );
}
Strings Circuit::getMorphologyNames() const
{
return _impl->getMorphologyNames();
}
size_ts Circuit::getElectrophysiologyTypes( const GIDSet& gids ) const
{
return _impl->getETypes( gids );
}
Strings Circuit::getElectrophysiologyNames() const
{
return _impl->getElectrophysiologyNames();
}
Matrix4fs Circuit::getTransforms( const GIDSet& gids ) const
{
const Vector3fs& positions = _impl->getPositions( gids );
const Quaternionfs& rotations = _impl->getRotations( gids );
if( positions.size() != rotations.size( ))
throw std::runtime_error(
"Positions not equal rotations for given GIDs" );
Matrix4fs transforms( positions.size( ));
#pragma omp parallel for
for( size_t i = 0; i < positions.size(); ++i )
transforms[i] = Matrix4f( rotations[i], positions[i] );
return transforms;
}
Quaternionfs Circuit::getRotations( const GIDSet& gids ) const
{
return _impl->getRotations( gids );
}
size_t Circuit::getNumNeurons() const
{
return _impl->getNumNeurons();
}
SynapsesStream Circuit::getAfferentSynapses( const GIDSet& gids,
const SynapsePrefetch prefetch ) const
{
return SynapsesStream( *this, gids, true, prefetch );
}
SynapsesStream Circuit::getEfferentSynapses( const GIDSet& gids,
const SynapsePrefetch prefetch ) const
{
return SynapsesStream( *this, gids, false, prefetch );
}
SynapsesStream Circuit::getProjectedSynapses( const GIDSet& preGIDs,
const GIDSet& postGIDs,
const SynapsePrefetch prefetch ) const
{
return SynapsesStream( *this, preGIDs, postGIDs, prefetch );
}
}