MOOSE - Multiscale Object Oriented Simulation Environment
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
Adaptor.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 ** This program is part of 'MOOSE', the
3 ** Messaging Object Oriented Simulation Environment.
4 ** Copyright (C) 2003-2012 Upinder S. Bhalla. and NCBS
5 ** It is made available under the terms of the
6 ** GNU Lesser General Public License version 2.1
7 ** See the file COPYING.LIB for the full notice.
8 **********************************************************************/
9 
10 #include "header.h"
11 #include "Adaptor.h"
12 
18 // MsgSrc definitions
22 {
23  static SrcFinfo1< double > output( "output",
24  "Sends the output value every timestep."
25  );
26  return &output;
27 }
28 
29 /*
30 static SrcFinfo0 *requestInput()
31 {
32  static SrcFinfo0 requestInput( "requestInput",
33  "Sends out the request. Issued from the process call."
34  );
35  return &requestInput;
36 }
37 */
38 
40 {
41  static SrcFinfo1< vector< double >* > requestOut( "requestOut",
42  "Sends out a request to a field with a double or array of doubles. "
43  "Issued from the process call."
44  "Works for any number of targets."
45  );
46  return &requestOut;
47 }
48 
49 /*
50 static DestFinfo* handleInput() {
51  static DestFinfo handleInput( "handleInput",
52  "Handle the returned value, which is in a prepacked buffer.",
53  new OpFunc1< Adaptor, PrepackedBuffer >( &Adaptor::handleBufInput )
54  );
55  return &handleInput;
56 }
57 */
58 
60 {
62  // Field definitions
64  static ValueFinfo< Adaptor, double > inputOffset(
65  "inputOffset",
66  "Offset to apply to input message, before scaling",
69  );
70  static ValueFinfo< Adaptor, double > outputOffset(
71  "outputOffset",
72  "Offset to apply at output, after scaling",
75  );
76  static ValueFinfo< Adaptor, double > scale(
77  "scale",
78  "Scaling factor to apply to input",
81  );
82  static ReadOnlyValueFinfo< Adaptor, double > outputValue(
83  "outputValue",
84  "This is the linearly transformed output.",
86  );
87 
89  // MsgDest definitions
91  static DestFinfo input(
92  "input",
93  "Input message to the adaptor. If multiple inputs are "
94  "received, the system averages the inputs.",
96  );
97  /*
98  new DestFinfo( "setup",
99  Ftype4< string, double, double, double >::global(),
100  RFCAST( &Adaptor::setup ),
101  "Sets up adaptor in placeholder mode."
102  "This is done when the kinetic model is yet to be built, "
103  "so the adaptor is given the src/target molecule name as "
104  "a placeholder. Later the 'build' function will complete "
105  "setting up the adaptor.\n"
106  "Args: moleculeName, scale, inputOffset, outputOffset. "
107  "Note that the direction of the adaptor operation is given "
108  "by whether the channel/Ca is connected as input or output."
109  ),
110  new DestFinfo( "build", Ftype0::global(),
111  RFCAST( &Adaptor::build ),
112  "Completes connection to previously specified molecule "
113  "on kinetic model."
114  ),
115  */
116 
118  // Shared definitions
120  static DestFinfo process( "process",
121  "Handles 'process' call",
123  );
124  static DestFinfo reinit( "reinit",
125  "Handles 'reinit' call",
127  );
128 
129  static Finfo* processShared[] =
130  {
131  &process, &reinit
132  };
133  static SharedFinfo proc( "proc",
134  "This is a shared message to receive Process message "
135  "from the scheduler. ",
136  processShared, sizeof( processShared ) / sizeof( Finfo* )
137  );
138 
140  // Now set it all up.
142  static Finfo* adaptorFinfos[] =
143  {
144  &inputOffset, // Value
145  &outputOffset, // Value
146  &scale, // Value
147  &outputValue, // ReadOnlyValue
148  &input, // DestFinfo
149  output(), // SrcFinfo
150  requestOut(), // SrcFinfo
151  &proc, // SharedFinfo
152  };
153 
154  static string doc[] =
155  {
156  "Name", "Adaptor",
157  "Author", "Upinder S. Bhalla, 2008, NCBS",
158  "Description",
159  " This is the adaptor class. It is used in interfacing different kinds"
160  " of solver with each other, especially for electrical to chemical"
161  " signeur models."
162  " The Adaptor class is the core of the API for interfacing between"
163  " different solution engines. It is currently in use for interfacing"
164  " between chemical and electrical simulations, but could be used for other"
165  " cases such as mechanical models."
166  ""
167  ""
168  " The API for interfacing between solution engines rests on "
169  " the following capabilities of MOOSE."
170  " 1. The object-oriented interface with classes mapped to biological"
171  " and modeling concepts such as electrical and chemical compartments,"
172  " ion channels and molecular pools."
173  " 2. The invisible mapping of Solvers (Objects implementing numerical"
174  " engines) to the object-oriented interface. Solvers work behind the "
175  " scenes to update the objects."
176  " 3. The messaging interface which allows any visible field to be "
177  " accessed and updated from any other object. "
178  " 4. The clock-based scheduler which drives operations of any subset of"
179  " objects at any interval. For example, this permits the operations of"
180  " field access and update to take place at quite different timescales "
181  " from the numerical engines."
182  " 5. The implementation of Adaptor classes. These perform a linear"
183  " transformation::"
184  ""
185  " (y = scale * (x + inputOffset) + outputOffset ) "
186  ""
187  " where y is output and x is the input. The input is the average of"
188  " any number of sources (through messages) and any number of timesteps."
189  " The output goes to any number of targets, again through messages."
190  ""
191  " It is worth adding that messages can transport arbitrary data structures,"
192  " so it would also be possible to devise a complicated opaque message"
193  " directly between solvers. The implementation of Adaptors working on"
194  " visible fields does this much more transparently and gives the user "
195  " facile control over the scaling transformatoin."
196  ""
197  " These adaptors are used especially in the rdesigneur framework of MOOSE,"
198  " which enables multiscale reaction-diffusion and electrical signaling"
199  " models."
200  " As an example of this API in operation, I consider two mappings: "
201  " 1. Calcium mapped from electrical to chemical computations."
202  " 2. phosphorylation state of a channel mapped to the channel conductance."
203  ""
204  " 1. Calcium mapping."
205  " Problem statement."
206  " Calcium is computed in the electrical solver as one or more pools that"
207  " are fed by calcium currents, and is removed by an exponential "
208  " decay process. This calcium pool is non-diffusive in the current "
209  " electrical solver. It has to be mapped to chemical calcium pools at a"
210  " different spatial discretization, which do diffuse."
211  " In terms of the list of capabilities described above, this is how the"
212  " API works."
213  " 1. The electrical model is partitioned into a number of electrical"
214  " compartments, some of which have the 'electrical' calcium pool"
215  " as child object in a UNIX filesystem-like tree. Thus the "
216  " 'electrical' calcium is represented as an object with "
217  " concentration, location and so on."
218  " 2. The Solver computes the time-course of evolution of the calcium"
219  " concentration. Whenever any function queries the 'concentration'"
220  " field of the calcium object, the Solver provides this value."
221  " 3. Messaging couples the 'electrical' calcium pool concentration to"
222  " the adaptor (see point 5). This can either be a 'push' operation,"
223  " where the solver pushes out the calcium value at its internal"
224  " update rate, or a 'pull' operation where the adaptor requests"
225  " the calcium concentration."
226  " 4. The clock-based scheduler keeps the electrical and chemical solvers"
227  " ticking away, but it also can drive the operations of the adaptor."
228  " Thus the rate of updates to and from the adaptor can be controlled."
229  " 5. The adaptor averages its inputs. Say the electrical solver is"
230  " going at a timestep of 50 usec, and the chemical solver at 5000 "
231  " usec. The adaptor will take 100 samples of the electrical "
232  " concentration, and average them to compute the 'input' to the"
233  " linear scaling. Suppose that the electrical model has calcium units"
234  " of micromolar, but has a zero baseline. The chemical model has"
235  " units of millimolar and a baseline of 1e-4 millimolar. This gives:"
236  " y = 0.001x + 1e-4"
237  " At the end of this calculation, the adaptor will typically 'push'"
238  " its output to the chemical solver. Here we have similar situation"
239  " to item (1), where the chemical entities are calcium pools in"
240  " space, each with their own calcium concentration."
241  " The messaging (3) determines another aspect of the mapping here: "
242  " the fan in or fan out. In this case, a single electrical "
243  " compartment may house 10 chemical compartments. Then the output"
244  " message from the adaptor goes to update the calcium pool "
245  " concentration on the appropriate 10 objects representing calcium"
246  " in each of the compartments."
247  ""
248  " In much the same manner, the phosphorylation state can regulate"
249  " channel properties."
250  " 1. The chemical model contains spatially distributed chemical pools"
251  " that represent the unphosphorylated state of the channel, which in"
252  " this example is the conducting form. This concentration of this"
253  " unphosphorylated state is affected by the various reaction-"
254  " diffusion events handled by the chemical solver, below."
255  " 2. The chemical solver updates the concentrations"
256  " of the pool objects as per reaction-diffusion calculations."
257  " 3. Messaging couples these concentration terms to the adaptor. In this"
258  " case we have many chemical pool objects for every electrical"
259  " compartment. There would be a single adaptor for each electrical"
260  " compartment, and it would average all the input values for calcium"
261  " concentration, one for each mesh point in the chemical calculation."
262  " As before, the access to these fields could be through a 'push'"
263  " or a 'pull' operation."
264  " 4. The clock-based scheduler oeperates as above."
265  " 5. The adaptor averages the spatially distributed inputs from calcium,"
266  " and now does a different linear transform. In this case it converts"
267  " chemical concentration into the channel conductance. As before,"
268  " the 'electrical' channel is an object (point 1) with a field for "
269  " conductance, and this term is mapped into the internal data "
270  " structures of the solver (point 2) invisibly to the user."
271  ""
272  };
273 
274  static Dinfo< Adaptor > dinfo;
275  static Cinfo adaptorCinfo(
276  "Adaptor",
278  adaptorFinfos,
279  sizeof( adaptorFinfos ) / sizeof( Finfo * ),
280  &dinfo,
281  doc,
282  sizeof( doc ) / sizeof( string )
283  );
284 
285  return &adaptorCinfo;
286 }
287 
289 
291 // Here we set up Adaptor class functions
294  :
295  output_( 0.0 ),
296  inputOffset_( 0.0 ),
297  outputOffset_( 0.0 ),
298  scale_( 1.0 ),
299  molName_( "" ),
300  sum_( 0.0 ),
301  counter_( 0 ),
302  numRequestOut_( 0 )
303 {
304  ;
305 }
307 // Here we set up Adaptor value fields
309 
311 {
313 }
315 {
316  return inputOffset_;
317 }
318 
320 {
322 }
324 {
325  return outputOffset_;
326 }
327 
328 void Adaptor::setScale( double value )
329 {
330  scale_ = value;
331 }
332 double Adaptor::getScale() const
333 {
334  return scale_;
335 }
336 
337 double Adaptor::getOutput() const
338 {
339  return output_;
340 }
341 
342 
344 // Here we set up Adaptor Destination functions
346 
347 void Adaptor::input( double v )
348 {
349  sum_ += v;
350  ++counter_;
351 }
352 
353 // separated out to help with unit tests.
355 {
356  if ( counter_ == 0 ) {
358  } else {
360  scale_ * ( ( sum_ / counter_ ) - inputOffset_ );
361  }
362  sum_ = 0.0;
363  counter_ = 0;
364 }
365 
366 void Adaptor::process( const Eref& e, ProcPtr p )
367 {
368  // static FuncId fid = handleInput()->getFid();
369  if ( numRequestOut_ > 0 ) {
370  vector< double > ret;
371  requestOut()->send( e, &ret );
372  assert( ret.size() == numRequestOut_ );
373  for ( unsigned int i = 0; i < numRequestOut_; ++i ) {
374  sum_ += ret[i];
375  }
377  }
378  innerProcess();
379  output()->send( e, output_ );
380 }
381 
382 void Adaptor::reinit( const Eref& e, ProcPtr p )
383 {
385  requestOut() ).size();
386  process( e, p );
387 }
388 
Adaptor()
Definition: Adaptor.cpp:293
unsigned int numRequestOut_
Counts number of inputs received.
Definition: Adaptor.h:174
uint32_t value
Definition: moosemodule.h:42
vector< ObjId > getMsgTargets(DataId srcDataId, const SrcFinfo *finfo) const
Definition: Element.cpp:856
void reinit(const Eref &e, ProcPtr p)
Definition: Adaptor.cpp:382
Definition: Dinfo.h:60
unsigned int dataIndex() const
Definition: Eref.h:50
double inputOffset_
Definition: Adaptor.h:166
static const Cinfo * initCinfo()
Definition: Adaptor.cpp:59
Element * element() const
Definition: Eref.h:42
void innerProcess()
Definition: Adaptor.cpp:354
double getOutputOffset() const
Definition: Adaptor.cpp:323
double getInputOffset() const
Definition: Adaptor.cpp:314
void setInputOffset(double offset)
Definition: Adaptor.cpp:310
void setScale(double scale)
Definition: Adaptor.cpp:328
void setOutputOffset(double offset)
Definition: Adaptor.cpp:319
double getScale() const
Definition: Adaptor.cpp:332
static SrcFinfo1< vector< double > * > * requestOut()
Definition: Adaptor.cpp:39
double sum_
Used for placeholding in cellreader mode.
Definition: Adaptor.h:170
double outputOffset_
Definition: Adaptor.h:167
double scale_
Definition: Adaptor.h:168
unsigned int counter_
Definition: Adaptor.h:171
double getOutput() const
Definition: Adaptor.cpp:337
Definition: OpFunc.h:27
Definition: Eref.h:26
static SrcFinfo1< double > * output()
Definition: Adaptor.cpp:21
static const Cinfo * adaptorCinfo
Definition: Adaptor.cpp:288
void process(const Eref &e, ProcPtr p)
Definition: Adaptor.cpp:366
static const Cinfo * initCinfo()
Definition: Neutral.cpp:16
void input(double val)
Definition: Adaptor.cpp:347
Definition: Cinfo.h:18
double output_
Definition: Adaptor.h:165
Definition: Finfo.h:12