CARMA C++
monitor_stream.h
1 #ifndef monitor_stream_h
2 #define monitor_stream_h
3 
4 #include <string>
5 
6 #include "carma/szaarrayutils/arraymap.h"
7 #include "carma/szaarrayutils/regset.h"
8 #include "carma/szaarrayutils/regcal.h"
9 #include "carma/szaarrayutils/regdata.h"
10 
11 #include "carma/szautil/Complex.h"
12 #include "carma/szautil/RegDate.h"
14 #include "carma/szautil/RegCal.h"
15 
16 namespace sza {
17  namespace util {
18  class DataType;
19  class RegAxisRange;
20  }
21 }
22 
23 /*.......................................................................
24  * The following method is called upon to read all or part of the
25  * next frame of registers. It should behave like its generic
26  * counterpart described above.
27  */
28 #define MS_READ_FRAME(fn) \
29 sza::array::MsReadState (fn)(sza::array::MonitorStream *ms, int dowait)
30 
31 /*.......................................................................
32  * Where provided, the following optional method is called upon to
33  * send part or all of the most recently packed output message.
34  */
35 #define MS_SEND_MSG(fn) \
36 sza::array::MsSendState (fn)(sza::array::MonitorStream *ms, int dowait)
37 
38 /*.......................................................................
39  * Where provided the following optional method is called whenever the
40  * current selection of registers in ms->regset is changed. This allows
41  * for the register set to be packed for transmission to a remote
42  * register supplier. If calls to the MS_SEND_MSG() method will be
43  * needed to complete the transaction, MS_SEND_AGAIN should be returned.
44  */
45 #define MS_QUEUE_REGSET(fn) \
46 sza::array::MsSendState (fn)(sza::array::MonitorStream *ms)
47 
48 /*.......................................................................
49  * Where provided the following optional method is called whenever the
50  * current sampling interval [ms_get_interval()] is changed. This allows
51  * for the interval to be packed for transmission to a remote
52  * register supplier. If calls to the MS_SEND_MSG() method will be
53  * needed to complete the transaction, MS_SEND_AGAIN should be returned.
54  */
55 #define MS_QUEUE_INTERVAL(fn) \
56 sza::array::MsSendState (fn)(sza::array::MonitorStream *ms)
57 
58 /*.......................................................................
59  * Where pertinent, the following optional method requests that a stream
60  * be "rewound" to its beginning. If this requires a message to be sent
61  * to the supplier, then this function should pack the message in
62  * preparation for subsequent calls to ms_send_msg(), and return
63  * MS_SEND_AGAIN. Otherwise it should rewind the stream and return
64  * MS_SEND_DONE.
65  */
66 #define MS_QUEUE_REWIND(fn) \
67 sza::array::MsSendState (fn)(sza::array::MonitorStream *ms)
68 
69 /*.......................................................................
70  * The following method returns a file descriptor for use in select() to
71  * see when the stream is ready for reading or writing. Note that the
72  * select() user is expected to call this before each use of select().
73  * This allows the fd to change with time (for example, the file
74  * monitor will read across file boundaries, so the fd may well change).
75  */
76 #define MS_SELECT_FD(fn) int (fn)(sza::array::MonitorStream *ms)
77 
78 /*.......................................................................
79  * The following method is called to delete the stream-specific
80  * implementation context.
81  */
82 #define MS_DESTRUCTOR(fn) void *(fn)(void *context)
83 
84 /*.......................................................................
85  * Return the current array map of the stream.
86  */
87 #define MS_ARRAYMAP(fn) ArrayMap *(fn)(sza::array::MonitorStream *ms)
88 
89 /*.......................................................................
90  * Return the current register map of the stream.
91  */
92 #define MS_REGMAP(fn) RegMap *(fn)(sza::array::MonitorStream *ms)
93 
94 namespace sza {
95  namespace array {
96 
97  /*
98  * The function that reads data from the supplier can be told to wait
99  * for a complete record to be received, or to read as much as possible
100  * without blocking, then return with an indication that a future call
101  * will be necessary to retrieve the remaining data. The following
102  * values are returned by said function to indicate the state of the
103  * read operation.
104  *
105  * Special note should be taken of the MS_READ_REGMAP return value.
106  * This is a warning that the next call will return registers that may
107  * occupy different slots and have different dimensions than before.
108  * Furthermore some registers that existed in the previous register
109  * map may not exist in the new register map, and some new ones may
110  * now be available.
111  *
112  * Note that when MS_READ_REGMAP is returned, the previous register
113  * map and all of the objects returned by previous calls to
114  * ms_RegMap(), ms_RegCalData(), ms_RegRawData(), ms_RegSet(), and
115  * ms_prep_RegSet() will have been destroyed, and thus should not be
116  * used. At this point you should destroy any of your own objects
117  * who's constructors took the return value of a previous call to
118  * ms_RegMap(), then create them anew using the return value of a new
119  * call to ms_RegMap().
120  *
121  * In order to give one a chance to finish up any defered work that
122  * involved the previous register map, ms_read_frame() returns
123  * MS_READ_BREAK whenever it encounters a point in the stream beyond
124  * which a new register map *might* change. For example, in multi-file
125  * file-input streams this occurs at the end of each file.
126  */
127  typedef enum { /* Frame-reader read status */
128  MS_READ_ENDED, /* The end of the stream has been reached */
129  MS_READ_AGAIN, /* The read operation is incomplete (dowait=0) */
130  MS_READ_BREAK, /* The end of one part of a multi-segment
131  stream has been */
132  /* reached. On the next call the register map may change, */
133  /* in which case MS_READ_REGMAP will be returned. */
134  /* This forewarning allows the caller to finish up any */
135  /* defered operations that involve the old register map */
136  /* before it gets destroyed. */
137  MS_READ_REGMAP, /* A new incompatible register map has been
138  encountered */
139  /* (see above for details). */
140  MS_READ_DONE /* A new frame of selected registers has been read */
141  } MsReadState;
142 
143  /*
144  * When sending a control message to the supplier, one first submits
145  * the message to be packed for transmission by calling the
146  * appropriate submittal function, then calls ms_send_msg() to
147  * transmit the message. When calling ms_send_msg() one can ask to have
148  * the message sent in its entirety before returning, or to have as much
149  * as possible sent without blocking. In the latter case, completion
150  * of the send operation must be completed by subsequent calls to
151  * ms_send_msg().
152  *
153  * Note that while a send operation is incomplete the values submitted
154  * via intervening calls to ms_queue_regset() and/or ms_queue_interval()
155  * will be queued for re-submision when the current send
156  * completes. ms_send_msg() will not return MS_SEND_DONE until all
157  * such transactions have been completed.
158  *
159  * The following values are returned by ms_send_msg() to indicate the
160  * state of the send operation.
161  */
162  typedef enum { /* Frame-reader write status */
163  MS_SEND_ERROR, /* An unrecoverable error occurred */
164  MS_SEND_AGAIN, /* The send operation is incomplete (dowait=0) */
165  MS_SEND_DONE /* The message has been sent */
166  } MsSendState;
167 
168  /*-----------------------------------------------------------------------
169  * This module provides a generic stream interface for reading monitor
170  * data from a variety of sources. Supported sources include a network
171  * connection to the control program, and sequential archive files on
172  * disk.
173  *
174  * The internals of a stream are logically split into two parts, a
175  * local consumer and a potentially remote supplier. Given that the
176  * supplier can be in a separate process, messaging via either
177  * non-blocking or blocking I/O is used to dispatch control messages
178  * to, and receive data from a given supplier. The only time that
179  * non-blocking I/O is not an option is when the stream makes a
180  * connection to a new supplier. At this time, information, such as
181  * the register map of the supplier and buffer size information is
182  * read from the supplier using blocking I/O.
183  *
184  * The following datatype provides an opaque handle for all stream
185  * types. Its internals are private to monitor_stream.c.
186  */
187  /*
188  * Define the contents of a generic monitor stream.
189  */
190  typedef struct MonitorStream {
191  void *context; // The context of the current
192  // data-source
193  MS_DESTRUCTOR(*del_fn); // The 'context' destructor
194  // function
195  MS_READ_FRAME(*read_fn); // The method used to read the
196  // next frame
197  MS_SEND_MSG(*send_fn); // The method that is called to
198  // send queued requests to the
199  // supplier.
200  MS_QUEUE_REGSET(*regset_fn); // The method that is called to
201  // queue a new register
202  // selection.
203  MS_QUEUE_INTERVAL(*interval_fn);// The method that is called to
204  // queue a new sub-sampling
205  // interval.
206  MS_QUEUE_REWIND(*rewind_fn); // The method that is called to
207  // queue a rewind request.
208  MS_SELECT_FD(*fd_fn); // The method that returns the current fd
209  MS_ARRAYMAP(*arraymap_fn); // The method that returns the
210  // current register map.
211 
212  bool archivedOnly_; // This flag affects the
213  // interpretation of all of the
214  // following:
215 
216  ArrayMap *arraymap; // The register map of the monitor supplier
217 
218  // The register set in which applications submit new register
219  // selections
220 
221  sza::util::RegisterSet* prepRegSet;
222 
223  // The established selection of registers
224 
225  sza::util::RegisterSet* regSet;
226 
227  // The register calibration object
228 
229  sza::util::RegCal* regCal;
230 
231  RegRawData *raw; // The latest array of
232  // un-calibrated registers
233  RegCalData *cal; // The latest array of calibrated registers
234  unsigned interval; // The sampling interval. The
235  // supplier should drop all but
236  // one of every 'interval'
237  // frames.
238  int sending; // True while an ongoing send
239  // operation is incomplete.
240 
241  // If a request to send a regset or interval request to the
242  // supplier is received before a previous request has been
243  // completely dispatched, set the corresponding flag below to
244  // have the request dispatched as soon as the previous
245  // transaction is completed.
246 
247  int send_interval; // True to queue an update from 'interval'
248  int send_regset; // True to queue an update from
249  // 'prep_regset'
250  int send_rewind; // True to queue a rewind-stream message
251 
252  } MonitorStream;
253  }
254 }
255 /*
256  * The following is an example of the simplest usage of a monitor
257  * stream.
258  *
259  * |* Start by defining indexes for the registers that you are interested *|
260  * |* in retrieving. *|
261  *
262  * typedef enum {
263  * FRAME_MJD, |* The frame.mjd register *|
264  * FRAME_UTC, |* The frame.utc register *|
265  * CORR0_VIS, |* The corr0.vis[] register *|
266  * NUM_MY_REGS |* The number of register selections - this must be last *|
267  * } MyRegIndex;
268  *
269  *
270  * |* Now in the same order as the above enumeration, associate each *|
271  * |* enumerator with the register-map name of the corresponding register. *|
272  *
273  * static MonitorSelection my_sel[NUM_MY_REGS] = {
274  * {FRAME_MJD, "frame", "mjd"},
275  * {FRAME_UTC, "frame", "utc"},
276  * {CORR0_VIS, "corr0", "vis"},
277  * };
278  *
279  * ...
280  * MonitorStream *ms; |* The monitor stream to be created *|
281  *
282  * |* The following array will be filled in below by ms_select_regs() *|
283  *
284  * ArrRegMapReg my_regs[NUM_MY_REGS]; |* The array of selected registers *|
285  *
286  * |* Create a monitor stream for all the files of a disk based archive *|
287  *
288  * ms = new_FileMonitorStream("/scr/archive", 0.0, 0.0);
289  * if(!ms)
290  * return error;
291  *
292  * |* Tell the monitor stream about the registers that we are interested in. *|
293  * |* Details of each of the selected registers are recorded in my_regs[] *|
294  * |* These details change from register map to register map, so later *|
295  * |* we are careful to reselect then if a new register map is encountered *|
296  *
297  * if(ms_select_regs(ms, 1, 0, my_sel, NUM_MY_REGS, &my_regs) != MS_SEND_DONE)
298  * return error...
299  *
300  * |* Load the calibration parameters of the initial register map. *|
301  *
302  * if(ms_load_cal_file(ms, "", calfile))
303  * return error...
304  *
305  * |* Read successive register samples, stopping at the end of the stream *|
306  *
307  * while(1) {
308  * switch(ms_read_frame(ms, 1)) {
309  * case MS_READ_AGAIN: |* We should never get this when the dowait *|
310  * |* argument of ms_read_frame() is 1 *|
311  * case MS_READ_BREAK: |* We have reached a point beyond which a *|
312  * |* new register map may be encountered. *|
313  * break;
314  * case MS_READ_ENDED: |* We have reached the end of the stream *|
315  * printf("End of stream reached.\n");
316  * return ok;
317  * break;
318  * case MS_READ_DONE: |* We received a new frame of registers *|
319  * if(ms_get_double(ms, my_regs + FRAME_MJD, 0, 1, &mjd) ||
320  * ms_get_double(ms, my_regs + FRAME_UTC, 0, 2, &utc) ||
321  * ms_get_float(ms, my_regs + CORR0_VIS, 0, 156 , &vis))
322  * return error;
323  * ....process the visibility data in vis[]....;
324  * break;
325  * case MS_READ_REGMAP: |* An incompatible register map was encountered *|
326  * |* Reselect our registers in the new register map *|
327  *
328  * if(ms_select_regs(ms, 1, 0, my_sel, NUM_MY_REGS, &my_regs)!=MS_SEND_DONE)
329  * return error...
330  * |* Load the calibration parameters of the new *|
331  * |* register map. *|
332  *
333  * if(ms_load_cal_file(ms, "", calfile))
334  * return error...
335  * break;
336  * };
337  * };
338  *
339  */
340 
341 
342 /*
343  * Create a new MonitorStream object and attach it to a control
344  * program on a given host. The host argument should contain
345  * the name or internet address of the computer on which the
346  * control program is running.
347  *
348  * When successful this function returns the new MonitorStream
349  * object. On failure it returns NULL.
350  */
351 sza::array::MonitorStream *new_NetMonitorStream(char *host);
352 
353 /*
354  * Create a new MonitorStream object and attach it to a time-ordered
355  * sequence of disk files in the directory named by 'dir'. Note that
356  * expansion of ~/ and ~user/ is supported within directory names.
357  * The ta and tb arguments can be used to limit the time range over which
358  * data should be retrieved. They are UTC's, expressed as Modified
359  * Julian Dates. If ta <= 0, the earliest time available in the directory
360  * will be substituted. If tb <= 0, the latest time available will be
361  * substituted. So to retrieve all of the data in a given directory,
362  * irrespective of its time range, pass both ta and tb as 0.0.
363  *
364  * When successful this function returns the new MonitorStream
365  * object. On failure it returns NULL.
366  */
367 sza::array::MonitorStream *new_FileMonitorStream(char *dir, double ta, double tb);
368 
369 /*
370  * The following function closes and deletes a monitor stream.
371  * Note that del_MonitorStream() is idempotent (ie. it returns NULL
372  * to represent a deleted stream, and can safely take NULL as an
373  * argument).
374  */
375 sza::array::MonitorStream *del_MonitorStream(sza::array::MonitorStream *ms);
376 
377 /*-----------------------------------------------------------------------
378  * Stream method functions.
379  *
380  * The following functions should only be used while a stream is
381  * connected to a supplier.
382  *---------------------------------------------------------------------*/
383 
384 /*
385  * Incrementally read the next set of the selected registers from
386  * the established data supplier. If dowait==0, retrieval of each
387  * frame may require multiple calls to this function. In such cases
388  * select() can be used to wait for the arrival of more data. See
389  * ms_select_fd() below for details.
390  */
391 sza::array::MsReadState ms_read_frame(sza::array::MonitorStream *ms, int dowait);
392 sza::array::MsReadState ms_count_frame(sza::array::MonitorStream *ms, int dowait);
393 
394 /*
395  * After reading new register values with ms_read_frame() the
396  * following functions can be used to copy the returned values
397  * into local arrays. The reg argument of each function should
398  * be one of the register-range specifications that was used to
399  * select registers to be monitored. The index and n arguments
400  * should select subsets of these ranges, and the output data
401  * arrays must have room for at least n elements. Each of these
402  * functions returns non-zero on error. Note that zeroes will be
403  * substituted for any of the selected registers that aren't in the
404  * archive (see the documentation of the pedantic argument of
405  * ms_select_regs() above).
406  */
407 int ms_get_float(sza::array::MonitorStream *ms, sza::util::RegDescription* desc,
408  float *data, sza::util::CoordRange* range=0);
409 int ms_get_double(sza::array::MonitorStream *ms, sza::util::RegDescription* desc,
410  double* data, sza::util::CoordRange* range=0);
411 int ms_get_uint(sza::array::MonitorStream *ms, sza::util::RegDescription* desc,
412  unsigned* data, sza::util::CoordRange* range=0);
413 int ms_get_int(sza::array::MonitorStream *ms, sza::util::RegDescription* desc,
414  int* data, sza::util::CoordRange* range=0);
415 int ms_get_uchar(sza::array::MonitorStream *ms, sza::util::RegDescription* desc,
416  unsigned char* data, sza::util::CoordRange* range=0);
417 int ms_get_char(sza::array::MonitorStream *ms, sza::util::RegDescription* desc,
418  char* data, sza::util::CoordRange* range=0);
419 int ms_get_ulong(sza::array::MonitorStream *ms, sza::util::RegDescription* desc,
420  unsigned long* data, sza::util::CoordRange* range=0);
421 int ms_get_long(sza::array::MonitorStream *ms, sza::util::RegDescription* desc,
422  long* data, sza::util::CoordRange* range=0);
423 
424 int ms_get_date(sza::array::MonitorStream *ms, sza::util::RegDescription* desc,
425  sza::util::RegDate::Data* data, sza::util::CoordRange* range=0);
426 
427 int ms_get_complex_float(sza::array::MonitorStream *ms,
428  sza::util::RegDescription* desc,
429  sza::util::Complex<float>::Data* data,
430  sza::util::CoordRange* range=0);
431 
432 
433 int ms_get_float(sza::array::MonitorStream *ms, sza::util::RegDescription* desc,
434  sza::util::MonitorDataType* data, sza::util::RegAxisRange& range);
435 
436 int ms_get_double(sza::array::MonitorStream *ms, sza::util::RegDescription* desc,
437  sza::util::MonitorDataType* data, sza::util::RegAxisRange& range);
438 
439 int ms_get_uint(sza::array::MonitorStream *ms, sza::util::RegDescription* desc,
440  sza::util::MonitorDataType* data, sza::util::RegAxisRange& range);
441 
442 int ms_get_int(sza::array::MonitorStream *ms, sza::util::RegDescription* desc,
443  sza::util::MonitorDataType* data, sza::util::RegAxisRange& range);
444 
445 int ms_get_uchar(sza::array::MonitorStream *ms, sza::util::RegDescription* desc,
446  sza::util::MonitorDataType* data, sza::util::RegAxisRange& range);
447 
448 int ms_get_char(sza::array::MonitorStream *ms, sza::util::RegDescription* desc,
449  sza::util::MonitorDataType* data, sza::util::RegAxisRange& range);
450 
451 int ms_get_ulong(sza::array::MonitorStream *ms, sza::util::RegDescription* desc,
452  sza::util::MonitorDataType* data, sza::util::RegAxisRange& range);
453 
454 int ms_get_long(sza::array::MonitorStream *ms, sza::util::RegDescription* desc,
455  sza::util::MonitorDataType* data, sza::util::RegAxisRange& range);
456 
457 int ms_get_date(sza::array::MonitorStream *ms, sza::util::RegDescription* desc,
458  sza::util::MonitorDataType* data, sza::util::RegAxisRange& range);
459 
460 int ms_get_complex_float(sza::array::MonitorStream *ms, sza::util::RegDescription* desc,
461  sza::util::MonitorDataType* data, sza::util::RegAxisRange& range);
462 
463 /*
464  * Unpack a string from a string register. The *reg argument must refer
465  * to the whole of the register. Up to nc-1 characters of the string
466  * will be returned in string[], which must be an array of at least nc
467  * characters. If the string won't fit within nc-1 characters, it will
468  * be terminated by placing a '\0' terminator in string[nc-1]. Otherwise
469  * the string will be terminated with a '\0' at the natural end of the
470  * string. On error non-zero is returned. Note that an empty string will be
471  * substituted if the register isn't in the archive (see the documentation
472  * of the pedantic argument of ms_select_regs() above).
473  */
474 int ms_get_string(sza::array::MonitorStream *ms, sza::util::RegDescription *reg, unsigned nc, char *string);
475 
476 /*
477  * Incrementally send a message, previously submitted via a
478  * call to ms_queue_interval(), ms_queue_regset() or ms_queue_rewind,
479  * to the supplier. Multiple calls to this function may be required if
480  * dowait==0. In such cases select() can be used to wait for the
481  * output channel to free up. See ms_select_fd() for details.
482  */
483 sza::array::MsSendState ms_send_msg(sza::array::MonitorStream *ms, int dowait);
484 
485 /*
486  * You probably won't need to use this function directly, because
487  * ms_select_regs() calls it for you (see later).
488  *
489  * Submit a modified register selection to be subsequently sent to the
490  * supplier via one or more calls to ms_send_msg(). The modified
491  * register set should be composed in the preparation register set
492  * that is returned by a call to ms_prep_RegSet(). If subsequent
493  * calls to ms_send_msg() will not be required, ms_queue_regset()
494  * returns MS_SEND_DONE.
495  */
496 sza::array::MsSendState ms_queue_regset(sza::array::MonitorStream *ms);
497 
498 /*
499  * Submit a new subsampling interval to be sent to the
500  * data supplier. If MsSendState is MS_SEND_AGAIN then subsequent
501  * calls to ms_send_msg() will be needed to complete the transaction.
502  *
503  * Note that an interval of 2 means "supply every second record".
504  * At startup the interval is initialized to 1.
505  */
506 sza::array::MsSendState ms_queue_interval(sza::array::MonitorStream *ms, unsigned interval);
507 
508 /*
509  * If the stream can be rewound, submit a rewind request to
510  * be sent to the supplier, otherwise do nothing more than return
511  * MS_SEND_DONE. If the return code is MS_SEND_AGAIN, subsequent
512  * calls to ms_send_msg() will be needed to complete the transaction.
513  */
514 sza::array::MsSendState ms_queue_rewind(sza::array::MonitorStream *ms);
515 
516 /*
517  * Return true if the data source of the specified stream can be rewound.
518  */
519 int ms_can_be_rewound(sza::array::MonitorStream *ms);
520 
521 /*
522  * Return a file descriptor that can be used with select() to
523  * determine when more data is available, or when the output
524  * channel to the supplier is ready to accept more data. If the
525  * stream isn't connected, -1 will be returned.
526  *
527  * WARNING: This file descriptor may change after any call to
528  * ms_read_frame(), so be sure to call ms_select_fd()
529  * before every call to select().
530  */
531 int ms_select_fd(sza::array::MonitorStream *ms);
532 
533 /*
534  * Load new calibration parameters from a calibration file. Note that
535  * the contents of the dir[] and name[] arguments of ms_load_cal_file()
536  * will be concatenated to form the path name of the calibration file,
537  * so if desired the directory part of the path name can be passed via
538  * the dir[] argument, and the file name can be passed via the name[]
539  * argument. Alternatively, if you want to specify the path name of
540  * the file as a single string, pass this string via the name[]
541  * argument and set the dir[] argument to "". The return value of
542  * ms_load_cal_file() is non-zero on failure.
543  */
544 int ms_load_cal_file(sza::array::MonitorStream *ms, char *dir, char *name);
545 
546 /*
547  * Load calibration parameters from a text input stream.
548  * See input.h to see how to create input streams.
549  */
550 int ms_load_cal_stream(sza::array::MonitorStream *ms, InputStream *stream);
551 
552 /*
553  * Reset all calibration parameters to unit scale factors, and
554  * zero offsets.
555  */
556 int ms_reset_cal(sza::array::MonitorStream *ms);
557 
558 /*
559  * An array of 'nsel' elements of the following type of container
560  * is what you pass to ms_select_regs() to tell it which register
561  * ranges to select.
562  */
563 struct MonitorSelection {
564  int id_; // The index of this MonitorSelection in its parent array
565  char *regMapName_; // The name of the target board in the register map
566  char *boardName_; // The name of the target board in the register map
567  char *blockName_; // The name of the target block on the above board
568  std::string regMapStr_;
569  std::string boardStr_;
570  std::string blockStr_;
571 
572  // The range of indices to select
573 
574  sza::util::CoordRange* range_;
575 
576  // Leave this as NULL if you always want to select all of the
577  // elements of the register.
578 
579  // Initialize internals of this object
580 
581  void initialize(int id, std::string regMapName, std::string boardName,
582  std::string blockName, sza::util::CoordRange* range);
583 
584  // Constructor
585 
586  MonitorSelection(int id, std::string regMapName, std::string boardName,
587  std::string blockName, sza::util::CoordRange* range=0);
588 
589  // Copy constructor
590 
591  MonitorSelection(const MonitorSelection& selection);
592 
593  // Destructor
594 
595  ~MonitorSelection();
596 };
597 
598 /*
599  * Tell a monitor stream which registers you are interested in
600  * receiving in subsequent calls to ms_read_frame().
601  *
602  * Input:
603  * ms MonitorStream * The stream to select registers from.
604  * dowait int If non-zero, don't return until the
605  * selection has been sent to the supplier
606  * or an error occurs. If zero, return immediately
607  * with a return code of MS_READ_AGAIN if the
608  * message can't be sent without blocking. In the
609  * latter case subsequent calls to ms_send_msg()
610  * will be required to complete the transaction.
611  * pedantic int If true, treat the non-existence of any of
612  * the registers in *sel as a fatal error. If
613  * false, simply emit a warning and arrange
614  * to substitute zero for the value of each
615  * missing register. The corresponding regs[]
616  * element will have its 'slot' member set to
617  * -1.
618  * sel MonitorSelection * An array of 'nsel' specifications of registers
619  * that are to be read on subsequent calls to
620  * ms_read_frame(). Note that the id field of
621  * each element must match the index of the element
622  * in the sel[] array.
623  * nsel unsigned The number of register selections in sel[]
624  * and the corresponding number of selection
625  * results to be recorded in regs[].
626  * Input/Output:
627  * regs ArrRegMapReg * On input pass an array of nsel elements.
628  * On output this will contain the details of
629  * each selection. Note that the contents are
630  * specific to the current register map, so
631  * they should be renewed via a further call
632  * to ms_select_regs() whenever ms_read_frame()
633  * reports the receipt of a new register map.
634  * ArrRegMapReg is defined in regmap.h.
635  * Output:
636  * return MsSendState The completion status of the transaction, from:
637  * MS_SEND_ERROR - An error occurred
638  * MS_SEND_AGAIN - The send operation remains
639  * incomplete (only if dowait=0).
640  * MS_SEND_DONE - The selection has been
641  * dispatched.
642  */
643 sza::array::MsSendState ms_select_regs(sza::array::MonitorStream *ms,
644  bool dowait, bool pedantic,
645  std::vector<MonitorSelection>& selections,
646  std::vector<sza::util::RegDescription>& regs);
647 
648 /*-----------------------------------------------------------------------
649  * Functions that provide readonly access to selected stream internals.
650  *---------------------------------------------------------------------*/
651 
652 /*
653  * Get the array map of a monitor stream (or NULL if the stream
654  * is unconnected). See arraymap.h for a description of the ArrayMap
655  * datatype.
656  */
657 ArrayMap *ms_ArrayMap(sza::array::MonitorStream *ms);
658 
659 /*
660  * Get the register map of a monitor stream (or NULL if the stream
661  * is unconnected). See regmap.h for a description of the RegMap
662  * datatype.
663  */
664 ArrayMap *ms_ArrayMap(sza::array::MonitorStream *ms);
665 
666 /*
667  * Return the container of the array of calibrated registers (or NULL
668  * if the stream is unconnected). This will only contain valid data
669  * after each call to ms_read_frame() that returns MS_READ_DONE. Its
670  * contents will be overwritten on each call to ms_read_frame().
671  * See regdata.h for a description of the RegCalData datatype.
672  */
673 sza::util::RegCal::RegCalData* ms_RegCalData(sza::array::MonitorStream *ms);
674 
675 /*
676  * Return the container of the array of uncalibrated registers (or NULL
677  * if the stream is unconnected). This will only contain valid data
678  * after each call to ms_read_frame() that returns MS_READ_DONE. Its
679  * contents will be overwritten on each call to ms_read_frame().
680  * See regdata.h for a description of the RegCalData datatype.
681  */
682 RegRawData *ms_RegRawData(sza::array::MonitorStream *ms);
683 
684 /*
685  * Return the established register selection set (or NULL if the
686  * stream is unconnected). See regset.h for a description of
687  * the RegSet datatype.
688  */
689 sza::util::RegisterSet* ms_RegSet(sza::array::MonitorStream *ms);
690 
691 /*
692  * Return the current sub-sampling interval (or 0 if the stream is
693  * unconnected).
694  */
695 unsigned ms_get_interval(sza::array::MonitorStream *ms);
696 
697 /*-----------------------------------------------------------------------
698  * Functions that provide read/write access to selected stream internals.
699  *---------------------------------------------------------------------*/
700 
701 /*
702  * You won't need this if you use ms_select_regs().
703  *
704  * Return the preparation register-selection set (or NULL if the
705  * stream is unconnected). This is to be used with ms_queue_regset()
706  * to select the set of registers to be supplied. Note that if a
707  * register set update initiated by ms_queue_regset() has to be
708  * postponed because of a preceding incomplete transaction,
709  * the re-submittal of the register set will be base on whatever is
710  * in the preparation register set at the time of the resubmission.
711  * Thus beware that while it is safe to modify this register set
712  * between calls to ms_send_msg(), the register set should be in a
713  * chosen state whenever ms_send_msg() is called.
714  */
715 sza::util::RegisterSet *ms_prep_RegSet(sza::array::MonitorStream *ms);
716 
717 
718 /*-----------------------------------------------------------------------
719  * The rest of this file regards implementation of new stream sources.
720  *
721  * The specific implementation of a particular stream source is
722  * implemented through the following method functions, plus an
723  * anonymous implementation object allocated by the stream source.
724  *---------------------------------------------------------------------*/
725 
726 /*
727  * To create an unconnected monitor stream call new_MonitorStream().
728  */
729 sza::array::MonitorStream *new_MonitorStream(bool archivedOnly);
730 
731 
732 /*.......................................................................
733  * The following function is used to connect a given stream source to
734  * a monitor stream object. It requires the register map read from the
735  * supplier, a stream-specific context object + its destructor, and
736  * the above method functions. It returns non-zero if the call fails.
737  */
738 int open_MonitorStream(sza::array::MonitorStream *ms, void *context, MS_DESTRUCTOR(*del_fn),
739  MS_READ_FRAME(*read_fn), MS_SEND_MSG(*send_fn),
740  MS_QUEUE_REGSET(*regset_fn),
741  MS_QUEUE_INTERVAL(*interval_fn),
742  MS_QUEUE_REWIND(*rewind_fn),
743  MS_SELECT_FD(*fd_fn),
744  MS_ARRAYMAP(*arraymap_fn),
745  bool archivedOnly);
746 
747 /*
748  * The above method functions can retrieve the context object that
749  * was registered with open_MonitorStream(), by calling the following
750  * function.
751  */
752 void *ms_SourceContext(sza::array::MonitorStream *ms);
753 
754 /*
755  * The following function is used to close a MonitorStream. This
756  * is done for you by del_MonitorStream(). Also open_MonitorStream()
757  * calls this function before connecting a stream to a new supplier.
758  * Note that close_MonitorStream() is idempotent.
759  */
760 void close_MonitorStream(sza::array::MonitorStream *ms);
761 
762 #endif
Tagged: Fri Oct 1 22:25:34 UTC 2004.
The following structure contains a double precision array having the same dimension as an archive fra...
Definition: RegCal.h:70
Tagged: Tue Oct 12 09:13:47 PDT 2004.
Tagged: Wed Oct 6 11:00:37 PDT 2004.
A class for iterating over slot ranges specified in a CoordRange object.
Definition: RegAxisRange.h:27
Tagged: Tue Oct 12 10:25:49 PDT 2004.