void nest::cg_connect( nest::ConnectionGeneratorDatum& cg, IntVectorDatum& sources, IntVectorDatum& targets, const DictionaryDatum& params_map, const Name& synmodel_name ) { const Token synmodel = kernel().model_manager.get_synapsedict()->lookup( synmodel_name ); if ( synmodel.empty() ) throw UnknownSynapseType( synmodel_name.toString() ); const index synmodel_id = static_cast< index >( synmodel ); RangeSet source_ranges; cg_get_ranges( source_ranges, ( *sources ) ); RangeSet target_ranges; cg_get_ranges( target_ranges, ( *targets ) ); cg_connect( cg, source_ranges, ( *sources ), target_ranges, ( *targets ), params_map, synmodel_id ); }
void nest::cg_connect( nest::ConnectionGeneratorDatum& cg, const index source_id, const index target_id, const DictionaryDatum& params_map, const Name& synmodel_name ) { Subnet* sources = dynamic_cast< Subnet* >( kernel().node_manager.get_node( source_id ) ); if ( sources == NULL ) { LOG( M_ERROR, "CGConnect_cg_i_i_D_l", "sources must be a subnet." ); throw SubnetExpected(); } if ( !sources->is_homogeneous() ) { LOG( M_ERROR, "CGConnect_cg_i_i_D_l", "sources must be a homogeneous subnet." ); throw BadProperty(); } if ( dynamic_cast< Subnet* >( *sources->local_begin() ) ) { LOG( M_ERROR, "CGConnect_cg_i_i_D_l", "Only 1-dim subnets are supported as sources." ); throw BadProperty(); } Subnet* targets = dynamic_cast< Subnet* >( kernel().node_manager.get_node( target_id ) ); if ( targets == NULL ) { LOG( M_ERROR, "CGConnect_cg_i_i_D_l", "targets must be a subnet." ); throw SubnetExpected(); } if ( !targets->is_homogeneous() ) { LOG( M_ERROR, "CGConnect_cg_i_i_D_l", "targets must be a homogeneous subnet." ); throw BadProperty(); } if ( dynamic_cast< Subnet* >( *targets->local_begin() ) ) { LOG( M_ERROR, "CGConnect_cg_i_i_D_l", "Only 1-dim subnets are supported as targets." ); throw BadProperty(); } const Token synmodel = kernel().model_manager.get_synapsedict()->lookup( synmodel_name ); if ( synmodel.empty() ) throw UnknownSynapseType( synmodel_name.toString() ); const index synmodel_id = static_cast< index >( synmodel ); const modelrange source_range = kernel().modelrange_manager.get_contiguous_gid_range( ( *sources->local_begin() )->get_gid() ); index source_offset = source_range.get_first_gid(); RangeSet source_ranges; source_ranges.push_back( Range( source_range.get_first_gid(), source_range.get_last_gid() ) ); const modelrange target_range = kernel().modelrange_manager.get_contiguous_gid_range( ( *targets->local_begin() )->get_gid() ); index target_offset = target_range.get_first_gid(); RangeSet target_ranges; target_ranges.push_back( Range( target_range.get_first_gid(), target_range.get_last_gid() ) ); cg_connect( cg, source_ranges, source_offset, target_ranges, target_offset, params_map, synmodel_id ); }
nest::ConnBuilder::ConnBuilder( const GIDCollection& sources, const GIDCollection& targets, const DictionaryDatum& conn_spec, const DictionaryDatum& syn_spec ) : sources_( &sources ) , targets_( &targets ) , autapses_( true ) , multapses_( true ) , symmetric_( false ) , exceptions_raised_( kernel().vp_manager.get_num_threads() ) , synapse_model_( kernel().model_manager.get_synapsedict()->lookup( "static_synapse" ) ) , weight_( 0 ) , delay_( 0 ) , param_dicts_() , parameters_requiring_skipping_() { // read out rule-related parameters ------------------------- // - /rule has been taken care of above // - rule-specific params are handled by subclass c'tor updateValue< bool >( conn_spec, names::autapses, autapses_ ); updateValue< bool >( conn_spec, names::multapses, multapses_ ); updateValue< bool >( conn_spec, names::symmetric, symmetric_ ); // read out synapse-related parameters ---------------------- if ( !syn_spec->known( names::model ) ) throw BadProperty( "Synapse spec must contain synapse model." ); const std::string syn_name = ( *syn_spec )[ names::model ]; if ( not kernel().model_manager.get_synapsedict()->known( syn_name ) ) throw UnknownSynapseType( syn_name ); // if another synapse than static_synapse is defined we need to make // sure that Connect can process all parameter specified if ( syn_name != "static_synapse" ) check_synapse_params_( syn_name, syn_spec ); synapse_model_ = kernel().model_manager.get_synapsedict()->lookup( syn_name ); DictionaryDatum syn_defaults = kernel().model_manager.get_connector_defaults( synapse_model_ ); // All synapse models have the possibility to set the delay (see // SynIdDelay), but some have homogeneous weights, hence it should // be possible to set the delay without the weight. default_weight_ = !syn_spec->known( names::weight ); default_delay_ = !syn_spec->known( names::delay ); // If neither weight nor delay are given in the dict, we handle this // separately. Important for hom_w synapses, on which weight cannot // be set. However, we use default weight and delay for _all_ types // of synapses. default_weight_and_delay_ = ( default_weight_ && default_delay_ ); #ifdef HAVE_MUSIC // We allow music_channel as alias for receptor_type during // connection setup ( *syn_defaults )[ names::music_channel ] = 0; #endif if ( !default_weight_and_delay_ ) { weight_ = syn_spec->known( names::weight ) ? ConnParameter::create( ( *syn_spec )[ names::weight ], kernel().vp_manager.get_num_threads() ) : ConnParameter::create( ( *syn_defaults )[ names::weight ], kernel().vp_manager.get_num_threads() ); register_parameters_requiring_skipping_( *weight_ ); delay_ = syn_spec->known( names::delay ) ? ConnParameter::create( ( *syn_spec )[ names::delay ], kernel().vp_manager.get_num_threads() ) : ConnParameter::create( ( *syn_defaults )[ names::delay ], kernel().vp_manager.get_num_threads() ); } else if ( default_weight_ ) { delay_ = syn_spec->known( names::delay ) ? ConnParameter::create( ( *syn_spec )[ names::delay ], kernel().vp_manager.get_num_threads() ) : ConnParameter::create( ( *syn_defaults )[ names::delay ], kernel().vp_manager.get_num_threads() ); } register_parameters_requiring_skipping_( *delay_ ); // Structural plasticity parameters // Check if both pre and post synaptic element are provided if ( syn_spec->known( names::pre_synaptic_element ) && syn_spec->known( names::post_synaptic_element ) ) { pre_synaptic_element_name = getValue< std::string >( syn_spec, names::pre_synaptic_element ); post_synaptic_element_name = getValue< std::string >( syn_spec, names::post_synaptic_element ); } else { if ( syn_spec->known( names::pre_synaptic_element ) || syn_spec->known( names::post_synaptic_element ) ) { throw BadProperty( "In order to use structural plasticity, both a pre and post synaptic " "element must be specified" ); } pre_synaptic_element_name = ""; post_synaptic_element_name = ""; } // synapse-specific parameters // TODO: Can we create this set once and for all? // Should not be done as static initialization, since // that might conflict with static initialization of // Name system. std::set< Name > skip_set; skip_set.insert( names::weight ); skip_set.insert( names::delay ); skip_set.insert( Name( "min_delay" ) ); skip_set.insert( Name( "max_delay" ) ); skip_set.insert( Name( "num_connections" ) ); skip_set.insert( Name( "num_connectors" ) ); skip_set.insert( Name( "property_object" ) ); skip_set.insert( Name( "synapsemodel" ) ); for ( Dictionary::const_iterator default_it = syn_defaults->begin(); default_it != syn_defaults->end(); ++default_it ) { const Name param_name = default_it->first; if ( skip_set.find( param_name ) != skip_set.end() ) continue; // weight, delay or not-settable parameter if ( syn_spec->known( param_name ) ) { synapse_params_[ param_name ] = ConnParameter::create( ( *syn_spec )[ param_name ], kernel().vp_manager.get_num_threads() ); register_parameters_requiring_skipping_( *synapse_params_[ param_name ] ); } } // Now create dictionary with dummy values that we will use // to pass settings to the synapses created. We create it here // once to avoid re-creating the object over and over again. if ( synapse_params_.size() > 0 ) { for ( index t = 0; t < kernel().vp_manager.get_num_threads(); ++t ) { param_dicts_.push_back( new Dictionary() ); for ( ConnParameterMap::const_iterator it = synapse_params_.begin(); it != synapse_params_.end(); ++it ) { if ( it->first == names::receptor_type || it->first == names::music_channel || it->first == names::synapse_label ) ( *param_dicts_[ t ] )[ it->first ] = Token( new IntegerDatum( 0 ) ); else ( *param_dicts_[ t ] )[ it->first ] = Token( new DoubleDatum( 0.0 ) ); } } } // If symmetric_ is requested call reset on all parameters in order // to check if all parameters support symmetric connections if ( symmetric_ ) { if ( weight_ ) { weight_->reset(); } if ( delay_ ) { delay_->reset(); } for ( ConnParameterMap::const_iterator it = synapse_params_.begin(); it != synapse_params_.end(); ++it ) { it->second->reset(); } } }
ConnectionCreator::ConnectionCreator( DictionaryDatum dict ) : allow_autapses_( true ) , allow_multapses_( true ) , source_filter_() , target_filter_() , number_of_connections_( 0 ) , mask_() , kernel_() , synapse_model_( kernel().model_manager.get_synapsedict()->lookup( "static_synapse" ) ) , weight_() , delay_() { Name connection_type; for ( Dictionary::iterator dit = dict->begin(); dit != dict->end(); ++dit ) { if ( dit->first == names::connection_type ) { connection_type = getValue< std::string >( dit->second ); } else if ( dit->first == names::allow_autapses ) { allow_autapses_ = getValue< bool >( dit->second ); } else if ( dit->first == names::allow_multapses ) { allow_multapses_ = getValue< bool >( dit->second ); } else if ( dit->first == names::allow_oversized_mask ) { allow_oversized_ = getValue< bool >( dit->second ); } else if ( dit->first == names::number_of_connections ) { number_of_connections_ = getValue< long_t >( dit->second ); } else if ( dit->first == names::mask ) { mask_ = TopologyModule::create_mask( dit->second ); } else if ( dit->first == names::kernel ) { kernel_ = TopologyModule::create_parameter( dit->second ); } else if ( dit->first == names::synapse_model ) { const std::string syn_name = getValue< std::string >( dit->second ); const Token synmodel = kernel().model_manager.get_synapsedict()->lookup( syn_name ); if ( synmodel.empty() ) throw UnknownSynapseType( syn_name ); synapse_model_ = static_cast< index >( synmodel ); } else if ( dit->first == names::targets ) { target_filter_ = getValue< DictionaryDatum >( dit->second ); } else if ( dit->first == names::sources ) { source_filter_ = getValue< DictionaryDatum >( dit->second ); } else if ( dit->first == names::weights ) { weight_ = TopologyModule::create_parameter( dit->second ); } else if ( dit->first == names::delays ) { delay_ = TopologyModule::create_parameter( dit->second ); } else { throw BadProperty( "ConnectLayers cannot handle parameter '" + dit->first.toString() + "'." ); } } // Set default weight and delay if not given explicitly DictionaryDatum syn_defaults = kernel().model_manager.get_connector_defaults( synapse_model_ ); if ( not weight_.valid() ) weight_ = TopologyModule::create_parameter( ( *syn_defaults )[ names::weight ] ); if ( not delay_.valid() ) delay_ = TopologyModule::create_parameter( ( *syn_defaults )[ names::delay ] ); if ( connection_type == names::convergent ) { if ( number_of_connections_ ) { type_ = Convergent; } else { type_ = Target_driven; } } else if ( connection_type == names::divergent ) { if ( number_of_connections_ ) { type_ = Divergent; } else { type_ = Source_driven; } } else { throw BadProperty( "Unknown connection type." ); } }