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