1 /*
2 * music_rate_in_handler.cpp
3 *
4 * This file is part of NEST.
5 *
6 * Copyright (C) 2004 The NEST Initiative
7 *
8 * NEST is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * NEST is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with NEST. If not, see <http://www.gnu.org/licenses/>.
20 *
21 */
22
23 #include "music_rate_in_handler.h"
24
25 #ifdef HAVE_MUSIC
26
27 // Includes from libnestutil:
28 #include "compose.hpp"
29 #include "logging.h"
30
31 // Includes from nestkernel:
32 #include "event.h"
33 #include "kernel_manager.h"
34 #include "nest_types.h"
35
36 namespace nest
37 {
MusicRateInHandler()38 MusicRateInHandler::MusicRateInHandler()
39 : MP_( 0 )
40 , published_( false )
41 , port_name_( "" )
42 {
43 }
44
MusicRateInHandler(std::string portname)45 MusicRateInHandler::MusicRateInHandler( std::string portname )
46 : MP_( 0 )
47 , published_( false )
48 , port_name_( portname )
49 {
50 }
51
~MusicRateInHandler()52 MusicRateInHandler::~MusicRateInHandler()
53 {
54 if ( published_ )
55 {
56 if ( MP_ != 0 )
57 {
58 delete MP_;
59 }
60 }
61 }
62
63 void
register_channel(int channel,nest::Node * mp)64 MusicRateInHandler::register_channel( int channel, nest::Node* mp )
65 {
66 if ( static_cast< size_t >( channel ) >= channelmap_.size() )
67 {
68 // all entries not explicitly set will be 0
69 channelmap_.resize( channel + 1, 0 );
70 }
71
72 if ( channelmap_[ channel ] != 0 )
73 {
74 throw MUSICChannelAlreadyMapped( "MusicRateInHandler", port_name_, channel );
75 }
76
77 channelmap_[ channel ] = mp;
78 }
79
80 void
publish_port()81 MusicRateInHandler::publish_port()
82 {
83
84 if ( not published_ )
85 {
86 MUSIC::Setup* s = kernel().music_manager.get_music_setup();
87 if ( s == 0 )
88 {
89 throw MUSICSimulationHasRun( "" );
90 }
91
92 MP_ = s->publishContInput( port_name_ );
93
94 if ( not MP_->isConnected() )
95 {
96 throw MUSICPortUnconnected( "", port_name_ );
97 }
98
99 if ( not MP_->hasWidth() )
100 {
101 throw MUSICPortHasNoWidth( "", port_name_ );
102 }
103
104 port_width_ = MP_->width();
105
106 data_ = std::vector< double >( port_width_ );
107
108 for ( std::vector< double >::iterator it = data_.begin(); it != data_.end(); ++it )
109 {
110 *it = 0;
111 }
112
113 MUSIC::ArrayData data_map( static_cast< void* >( &( data_[ 0 ] ) ), MPI::DOUBLE, 0, port_width_ );
114
115 MP_->map( &data_map );
116 published_ = true;
117
118 std::string msg = String::compose( "Mapping MUSIC input port '%1' with width=%2.", port_name_, port_width_ );
119 LOG( M_INFO, "music_rate_in_handler::publish_port()", msg.c_str() );
120 }
121 }
122
123
124 void
update(Time const &,const long,const long)125 MusicRateInHandler::update( Time const&, const long, const long )
126 {
127 const size_t buffer_size = kernel().connection_manager.get_min_delay();
128 std::vector< double > new_rates( buffer_size, 0.0 );
129
130 for ( size_t channel = 0; channel < channelmap_.size(); ++channel )
131 {
132 if ( channelmap_[ channel ] != 0 )
133 {
134 std::fill( new_rates.begin(), new_rates.end(), data_[ channel ] );
135
136 InstantaneousRateConnectionEvent rate_event;
137 rate_event.set_coeffarray( new_rates );
138 channelmap_[ channel ]->handle( rate_event );
139 }
140 }
141 }
142
143 } // namespace nest
144
145 #endif // #ifdef HAVE_MUSIC
146