Line data Source code
1 : #ifndef SDMDataObjectWriter_CLASS
2 : #define SDMDataObjectWriter_CLASS
3 :
4 : #include <string>
5 : #include <map>
6 : #include <set>
7 : #include <vector>
8 : #include <bitset>
9 :
10 : #include <iostream>
11 : #include <fstream>
12 : #include <sstream>
13 :
14 : #include <alma/ASDMBinaries/SDMDataObject.h>
15 :
16 : #include <alma/Enumerations/CAtmPhaseCorrection.h>
17 : #include <alma/Enumerations/CCorrelationMode.h>
18 : #include <alma/Enumerations/CCorrelatorType.h>
19 : #include <alma/Enumerations/CNetSideband.h>
20 : #include <alma/Enumerations/CProcessorType.h>
21 :
22 : namespace asdmbinaries {
23 : /**
24 : * A class to represent an exception thrown while writing a MIME message containing ALMA binary data.
25 : */
26 : class SDMDataObjectWriterException {
27 :
28 : public:
29 : /**
30 : * An empty contructor.
31 : */
32 : SDMDataObjectWriterException();
33 :
34 : /**
35 : * A constructor with a message associated with the exception.
36 : * @param m a string containing the message.
37 : */
38 : SDMDataObjectWriterException(const std::string& m);
39 :
40 : /**
41 : * The destructor.
42 : */
43 : virtual ~SDMDataObjectWriterException();
44 :
45 : /**
46 : * Returns the message associated to this exception.
47 : * @return a string.
48 : */
49 : std::string getMessage() const;
50 :
51 : protected:
52 : std::string message;
53 :
54 : };
55 :
56 : inline SDMDataObjectWriterException::SDMDataObjectWriterException() : message ("SDMDataObjectWritererException") {}
57 0 : inline SDMDataObjectWriterException::SDMDataObjectWriterException(const std::string& m) : message(m) {}
58 0 : inline SDMDataObjectWriterException::~SDMDataObjectWriterException() {}
59 0 : inline std::string SDMDataObjectWriterException::getMessage() const {
60 0 : return "SDMDataObjectWriterException : " + message;
61 : }
62 :
63 : /**
64 : * A general class to write MIME messages containing ALMA binary data.
65 : *
66 : * An instance of this class can be used to write :
67 : * <ul>
68 : * <li> Correlator data :
69 : * <ul>
70 : * <li>Integration : full resolution data. </li>
71 : * <li>Subintegration : channel average data. </li>
72 : * </ul>
73 : * </li>
74 : * <li> Total Power data.
75 : * <li> Water Vapor Radiometer (WVR) data.
76 : * </ul>
77 : *
78 : * The MIME message is written on standard output, a disk file or a char buffer depending on the constructor
79 : * used to create an instance of SDMDataObjectWriter.
80 : *
81 : * @section how-to-use How to use an instance of SDMDataObjectWriter.
82 : * Whatever is the type of binary data (total power, WVR, integration, subintegration) to write, the following
83 : * scheme must be respected when using an SDMDataObjectWriter.
84 : *
85 : * <ol>
86 : * <li> Instantiate an SDMDataObjectWriter by using the appropriate constructor depending on the kind of desired output
87 : * (standard output, disk file, memory).</li>
88 : * <li> Write the binary data by using the appropriate methods depending on the kind of binary data. </li>
89 : * <li> Conclude the usage of this instance of SDMDataObjectWriter by calling the done method (done()).
90 : * </ol>
91 : *
92 : * Example:
93 : *
94 : * @code
95 : * // open a disk file
96 : * ofstream osf("myCorrData.dat");
97 : *
98 : * // builds an SDMDataObjectWriter which will write the data in the file "myCorrData.dat".
99 : * SDMDataObjectWriter sdmdow(&osf, "uid://X1/X2/X3", "ALMA Binary Data");
100 : *
101 : * // Here produce the binary data by using one the sequences detailed below.
102 : * .
103 : * .
104 : * // done with sdmdow.
105 : * sdmdow.done();
106 : *
107 : * // Do not forget to close the file !!
108 : * osf.close()
109 : * .
110 : * .
111 : * @endcode
112 : *
113 : * Example of a MIME message output in an ostringstream :
114 : *
115 : * @code
116 : * // create an osstringstream
117 : * ostringstream oss;
118 : *
119 : * // builds an SDMDataObjectWriter which will write the data in the string attached to oss.
120 : * SDMDataObjectWriter sdmdow(&oss, "uid://X1/X2/X3", "ALMA Binary Data");
121 : *
122 : * // Here produce the binary data by using one the sequences detailed below.
123 : * .
124 : * .
125 : * // done with sdmdow.
126 : * sdmdow.done();
127 : *
128 : * // Do whatever you want with oss.
129 : * .
130 : * .
131 : * // And perhaps a good thing to erase the content of oss.
132 : * oss.str("");
133 : * .
134 : * .
135 : * @endcode
136 : *
137 : * We detail now the different valid sequences for writing binary data depending on their kind.
138 : * @subsection how-to-tpData How to write Total Power data.
139 : * @subsubsection One single call to the tpData() method.
140 : * @code
141 : * sdmdow.tpData(123450000, // startTime
142 : * "uid://X123/X4/X5", // execBlockUID
143 : * 1, // execBlockNum
144 : * 10, // scanNum
145 : * 3, // subscanNum
146 : * 100, // number of integrations
147 : * 2, // number of antennas
148 : * basebands, // vector of basebands.
149 : * 171450000, // time
150 : * 96000000, // interval
151 : * axis, // names of axis
152 : * autoData); // total power data values.
153 : * @endcode
154 : * One may also consider to use in that order the methods tpDataHeader and addTPSubscan.
155 : *
156 : * @subsection how-to-wvrData How to write WVR data.
157 : * One single call to the wvrData() method.
158 : * @code
159 : * sdmdow.wvrData("uid://X123/X4/X5", // execBlockUID,
160 : * 1, // execBlockNum,
161 : * 10, // scanNum,
162 : * 3, // subscanNum,
163 : * 100, // number of time stamps (i.e. size along the TIM axis),
164 : * 8, // number of antennas,
165 : * 4, // number of channels,
166 : * DSB, // NetSideband characteristic,
167 : * 171450000, // time,
168 : * 96000000, // interval,
169 : * wvrData, // the WVR data values,
170 : * flags); // flags associated to the WVR data.
171 :
172 : *
173 : * @endcode
174 : *
175 : * @subsection how-to-intData How to write integrations.
176 : * One single call to corrDataHeader() followed by one or more calls to addIntegration().
177 : * @code
178 : * // Write the global header.
179 : * sdmdow.corrDataHeader(123450000, // startTime
180 : * "uid://X123/X4/X5", // execBlockUID
181 : * 1, // execBlockNum
182 : * 10, // scanNum
183 : * 3, // subscanNum
184 : * 2, // numAntenna
185 : * correlationMode, // the correlation mode.
186 : * spectralResolution, // the spectral resolution.
187 : * correlatorType, // the processor (correlator) type.
188 : * dataStruct); // the description of the structure of the binary data.
189 : *
190 : * // And write the integrations (3 in that example).
191 : * for (uint32_t i = 0; i < 3; i++) {
192 : * .
193 : * .
194 : * .
195 : * sdmdow.addIntegration(i+1, // integration's index.
196 : * time, // midpoint
197 : * interval, // time interval
198 : * flags, // flags binary data
199 : * actualTimes, // actual times binary data
200 : * actualDurations, // actual durations binary data
201 : * zeroLags, // zero lags binary data
202 : * shortCrossData, // cross data (can be short or int)
203 : * autoData); // single dish data.
204 : * .
205 : * .
206 : * .
207 : * }
208 : * @endcode
209 : * @subsection how-to-subintData How to write subintegrations.
210 : * One single call to corrDataHeader() followed by one or more calls to addSubintegration().
211 : * @code
212 : * // Write the global header.
213 : * sdmdow.corrDataHeader(123450000, // startTime
214 : * "uid://X123/X4/X5", // execBlockUID
215 : * 1, // execBlockNum
216 : * 10, // scanNum
217 : * 3, // subscanNum
218 : * 2, // numAntenna
219 : * correlationMode, // the correlation mode.
220 : * spectralResolution, // the spectral resolution.
221 : * processorType, // the processor type.
222 : * dataStruct); // the description of the structure of the binary data.
223 : *
224 : * // And write the subintegrations (6 in that example).
225 : * for (uint32_t i = 0; i < 3; i++) {
226 : * for (uint32_t j = 0; j < 2; j++) {
227 : * .
228 : * .
229 : * .
230 : * sdmdow.addSubintegration(i+1, // integration's index.
231 : * j+1, // subintegration's index
232 : * time, // midpoint
233 : * interval, // time interval
234 : * flags, // flags binary data
235 : * actualTimes, // actual times binary data
236 : * actualDurations,// actual durations binary data
237 : * zeroLags, // zero lags binary data
238 : * shortCrossData, // cross data (can be short or int)
239 : * autoData); // single dish data.
240 : * .
241 : * .
242 : * .
243 : * }
244 : * }
245 : * @endcode
246 : * @subsection valid-calls Valid calls sequences.
247 : * The table below summarizes the valid call sequences when using an SDMDataObjectWriter. Any deviation from these
248 : * rules will result in an SDMDataObjectWriterException thrown.
249 : * <table>
250 : * <caption> Valid sequences of methods calls </caption>
251 : * <tr>
252 : * <th> Total Power data </th> <th> WVR data </th> <th> Integration </th> <th> subIntegration </th>
253 : * </tr>
254 : * <tr>
255 : * <td> ctor, tpData, done </td>
256 : * <td rowspan=2> ctor, wvrData, done </td>
257 : * <td rowspan=2> ctor, corrDataHeader, addIntegration (one or more times), done </td>
258 : * <td rowspan=2> ctor, corrDataHeader, addSubintegration (one or more times), done </td>
259 : * </tr>
260 : * <tr>
261 : * <td> ctor, tpDataHeader, addTPSubscan, done </td>
262 : * </tr>
263 : * </table>
264 : *
265 : */
266 : class SDMDataObjectWriter {
267 : public:
268 :
269 : /**
270 : * A constructor to write on standard output.
271 : * The MIME message will be written to the standard output.
272 : * @param uid a string containing the ALMA uid of the MIME message.
273 : * @param title a string defining the title for the binary data to be written.
274 : */
275 : SDMDataObjectWriter(const std::string& uid="uid://X0/X0/X0", const std::string& title="ALMA Binary Data");
276 :
277 :
278 : /**
279 : * A constructor to write in a file.
280 : * The MIME message will be written into the file attached to the ofstream argument.
281 : * @param ofs an pointer to an ofstream object.
282 : * @param uid a string containing the ALMA uid of the MIME message.
283 : * @param title a string defining the title for the binary data to be written.
284 : */
285 : SDMDataObjectWriter(std::ofstream* ofs, const std::string& uid="uid://X0/X0/X0", const std::string& title="ALMA Binary Data");
286 :
287 : /**
288 : * A constructor to write in memory.
289 : * The MIME message will be written in an ostringstream.
290 : * @param oss a pointer to an ostringstream.
291 : * @param uid a string containing the ALMA uid of the MIME message.
292 : * @param title a string defining the title for the binary data to be written.
293 : * @note *oss will be systematically cleared before the first write operation.
294 : */
295 : SDMDataObjectWriter(std::ostringstream* oss, const std::string& uid="uid://X0/X0/X0", const std::string& title="ALMA Binary Data");
296 :
297 :
298 : /**
299 : * The destructor.
300 : *
301 : */
302 : virtual ~SDMDataObjectWriter();
303 :
304 :
305 : /**
306 : * This method must be called to conclude the activity of this SDMDataObjectWriter.
307 : * It completes the MIME message.
308 : * @note Do not forget to call it when you have finished to write your binary data !
309 : * @note It <b>does not</b> close the file attached to the output stream if any, this operation is left to the user.
310 : */
311 : void done();
312 :
313 :
314 : /* /\** */
315 : /* * Writes a data subset of Total Power binary data. */
316 : /* * @param time time of the subscan. */
317 : /* * @param interval duration of the subscan. */
318 : /* * @param flags the values of flags (see note). */
319 : /* * @param actualTimes the values of actualTimes (see note). */
320 : /* * @param actualDurations the values of actualDurations (see note). */
321 : /* * @param autoData the values of autoData. */
322 : /* * */
323 : /* * @throws SDMDataObjectWriterException */
324 : /* * */
325 : /* * @note */
326 : /* * This method must called only once after a call to tpDataHeader. */
327 : /* **\/ */
328 : /* void addTPSubscan(uint64_t time, */
329 : /* uint64_t interval, */
330 : /* const vector<FLAGSTYPE>& flags, */
331 : /* const vector<ACTUALTIMESTYPE>& actualTimes, */
332 : /* const vector<ACTUALDURATIONSTYPE>& actualDurations, */
333 : /* const vector<AUTODATATYPE>& autoData); */
334 :
335 : /**
336 : * Writes the full content of Total Power data in their respective attachments (global XML header, local XML header and binary attachments)
337 : * on the MIME message stream.
338 : * @param startTime start time.
339 : * @param execBlockUID the UID of the exec block.
340 : * @param execBlockNum the index of the exec block.
341 : * @param scanNum the index of the scan.
342 : * @param subscanNum the index of the subscan.
343 : * @param numOfIntegrations the number of integrations in that Subscan.
344 : * @param numAntenna the number of antenna.
345 : * @param basebands a vector of Baseband describing the structure of the binary data.
346 : * @param time.
347 : * @param interval.
348 : * @param flags the values of flags (see note).
349 : * @param actualTimes the values of actualTimes (see note).
350 : * @param actualDurations the values of actualDurations (see note).
351 : * @param autoDataAxes the ordered set of axes names for autoData.
352 : * @param autoData the values of autoData.
353 : * @param autoDataNormalized
354 : *
355 : * @throws SDMDataObjectWriterException
356 : *
357 : * @note
358 : * A vector with a null size can be passed when the (optional) attachment is absent.
359 : *
360 : * @note this method allows to write Total Power data in a "one-call" way. An alternate solution consists
361 : * in calling tpDataHeader and then addTPSubscan.
362 : */
363 : void tpData(uint64_t startTime,
364 : const std::string& execBlockUID,
365 : uint32_t execBlockNum,
366 : uint32_t scanNum,
367 : uint32_t subscanNum,
368 : uint32_t numOfIntegrations,
369 : uint32_t numAntenna,
370 : const std::vector<SDMDataObject::Baseband>& basebands,
371 : uint64_t time,
372 : uint64_t interval,
373 : const std::vector<AxisNameMod::AxisName>& flagsAxes,
374 : const std::vector<FLAGSTYPE>& flags,
375 : const std::vector<AxisNameMod::AxisName>& actualTimesAxes,
376 : const std::vector<ACTUALTIMESTYPE>& actualTimes,
377 : const std::vector<AxisNameMod::AxisName>& actualDurationsAxes,
378 : const std::vector<ACTUALDURATIONSTYPE>& actualDurations,
379 : const std::vector<AxisNameMod::AxisName>& autoDataAxes,
380 : const std::vector<AUTODATATYPE>& autoData);
381 :
382 : /**
383 : * Writes the full content of Total Power data in their respective attachments (global XML header, local XML header and binary attachments)
384 : * on the MIME message stream.
385 : * @param startTime start time.
386 : * @param execBlockUID the UID of the exec block.
387 : * @param execBlockNum the index of the exec block.
388 : * @param scanNum the index of the scan.
389 : * @param subscanNum the index of the subscan.
390 : * @param numOfIntegrations the number of integrations in that Subscan.
391 : * @param numAntenna the number of antenna.
392 : * @param basebands a vector of Baseband describing the structure of the binary data.
393 : * @param time
394 : * @param interval
395 : * @param autoDataAxes the ordered set of axes names for autoData.
396 : * @param autoData the values of autoData.
397 : *
398 : * @throws SDMDataObjectWriterException
399 : *
400 : * @note
401 : * This method is kept for backward compatibility reasons. It's recommanded to use the "long" version of tpData which
402 : * gives a full control of the optional attachments to be written.
403 : */
404 : void tpData(uint64_t startTime,
405 : const std::string& execBlockUID,
406 : uint32_t execBlockNum,
407 : uint32_t scanNum,
408 : uint32_t subscanNum,
409 : uint32_t numOfIntegrations,
410 : uint32_t numAntenna,
411 : const std::vector<SDMDataObject::Baseband>& basebands,
412 : uint64_t time,
413 : uint64_t interval,
414 : const std::vector<AxisNameMod::AxisName>& autoDataAxes,
415 : const std::vector<AUTODATATYPE>& autoData);
416 :
417 : /**
418 : * Writes the XML global header on the MIME message stream, when binary data are Total Power data and will be written
419 : * in successive steps with calls to tpAddIntegration.
420 : *
421 : * @param startime start time.
422 : * @param execBlockUID the UID of the exec block.
423 : * @param execBlockNum the index of the exec block.
424 : * @param scanNum the index of the scan.
425 : * @param subscanNum the index of the subscan.
426 : * @param numAntenna the number of antenna.
427 : * @param dataStruct the description of the binary data structure.
428 : *
429 : * @throws SDMDataObjectWriterException
430 : */
431 : void tpDataHeader(uint64_t startTime,
432 : const std::string& execBlockUID,
433 : uint32_t execBlockNum,
434 : uint32_t scanNum,
435 : uint32_t subscanNum,
436 : uint32_t numAntenna,
437 : SDMDataObject::DataStruct& dataStruct);
438 :
439 : /**
440 : * Writes one integration (local header + binary attachment) of total power data on the MIME message stream.
441 : *
442 : * @param integrationNum the index (1 based) of the integration.
443 : * @param time time of the integration.
444 : * @param interval interval of the integration.
445 : * @param flags the values of flags.
446 : * @param actualTimes the values of actualTimes.
447 : * @param actualDurations the values of actualDurations.
448 : * @param autoData the values of autoData.
449 : *
450 : * @throws SDMDataObjectWriterException
451 : *
452 : * @note To be used repeatedly after one call to tpDataHeader until all the integrations of Total Power data have been acquired.
453 : *
454 : */
455 : void tpAddIntegration(uint32_t integrationNum,
456 : uint64_t time,
457 : uint64_t interval,
458 : const std::vector<FLAGSTYPE>& flags,
459 : const std::vector<ACTUALTIMESTYPE>& actualTimes,
460 : const std::vector<ACTUALDURATIONSTYPE>& actualDurations,
461 : const std::vector<AUTODATATYPE>& autoData);
462 :
463 : /**
464 : * Writes water vapour radiometer (WVR) data in a MIME message conform
465 : * with the BDF V2 format.
466 : *
467 : * @param execBlockUID the archive uid of the exec Block,
468 : * @param execBlockNum the index of the exec Block,
469 : * @param scanNum the number of the scan,
470 : * @param subscanNum the number of the subscan,
471 : * @param numTimes the number of time stamps (i.e. size along the TIM axis),
472 : * @param numAntennas the number of antennas producing WVR data,
473 : * @param numChannels the number of channels in WVR data,
474 : * @param netSideband the NetSideband characteristic attached to WVR data,
475 : * @param time the mid-point of the time range containing all the WVR data,
476 : * @param interval the duration of the time range containing all the WVR data,
477 : * @param wvrData the WVR data,
478 : * @param flags the flags associated to the WVR data.
479 : *
480 : * @throws SDMDataObjectWriterException
481 : *
482 : * @note
483 : *
484 : * <ul>
485 : * <li>see the constructor of the class and the done method for opening the
486 : * output stream where the MIME message is actually written (file, memory...)
487 : * and for closing it</li>
488 : * <li>the "startTime" element of the global header in the resulting MIME document
489 : * will be filled with a value equal to 'time' - 'interval'/2, </li>
490 : * <li> 'time' and 'interval' express a number of nanoseconds. 'time' is an MJD, </li>
491 : * <li> 'wvrData' and 'flags' are both 1D arrays. Nonetheless they are expected to
492 : * be the linearized versions of multi dimensional arrays whose axes are defined
493 : * by the sequence TIM ANT SPP for the WVR data and TIM ANT for their flags,
494 : * (SPP varying before ANT varying itself before TIM),</li>
495 : * <li> a vector of null size for the argument 'flags' will be interpreted as 'flags not available'.</li>
496 : * <li> a null value in at least one of the arguments 'numTimes', 'numAntennas' or 'numChannels'
497 : * will trigger an SDMDataObjectWriterException. </li>
498 : * <li> a argument 'wvrData' with a size different from 'numTimes' * 'numAntennas' * 'numChannels'
499 : * will trigger an SDMDataObjectWriterException. </li>
500 : * <li> an argument 'flags' with a size different from 0 and different from 'numTimes' * 'numAntennas'
501 : * will trigger an SDMDataObjectWriterException. </li>
502 : * </ul>
503 : *
504 : */
505 :
506 : void wvrData (const std::string & execBlockUID,
507 : uint32_t execBlockNum,
508 : uint32_t scanNum,
509 : uint32_t subscanNum,
510 : uint32_t numTimes,
511 : uint32_t numAntennas,
512 : uint32_t numChannels,
513 : NetSidebandMod::NetSideband netSideband,
514 : uint64_t time,
515 : uint64_t interval,
516 : const std::vector<AUTODATATYPE>& wvrData,
517 : const std::vector<FLAGSTYPE>& flags);
518 :
519 :
520 : /**
521 : * Writes the XML global header on the MIME message stream, when binary data are (sub)integrations
522 : * produced by the correlator.
523 : * @param startime start time.
524 : * @param execBlockUID the UID of the exec block.
525 : * @param execBlockNum the index of the exec block.
526 : * @param scanNum the index of the scan.
527 : * @param subscanNum the index of the subscan.
528 : * @param numAntenna the number of antenna.
529 : * @param correlationMode the correlation mode code.
530 : * @param spectralResolution the spectral resolution code.
531 : * @param dataStruct the description of the binary data structure.
532 : *
533 : * @throws SDMDataObjectWriterException
534 : */
535 : void corrDataHeader(uint64_t startime,
536 : const std::string& execBlockUID,
537 : uint32_t execBlockNum,
538 : uint32_t scanNum,
539 : uint32_t subscanNum,
540 : uint32_t numAntenna,
541 : CorrelationModeMod::CorrelationMode correlationMode,
542 : const OptionalSpectralResolutionType& spectralResolutionType,
543 : SDMDataObject::DataStruct& dataStruct);
544 :
545 :
546 : /**
547 : * Writes one integration (local header + binary attachment) of correlator data on the MIME message stream.
548 : * @param integrationNum the index (1 based) of the integration.
549 : * @param time time of the integration.
550 : * @param interval interval of the integration.
551 : * @param flags the values of flags.
552 : * @param actualTimes the values of actualTimes.
553 : * @param actualDurations the values of actualDurations.
554 : * @param zeroLags the values of zeroLags.
555 : * @param crossData the values of crossData (encoded in int).
556 : * @param autoData the values of autoData.
557 : *
558 : * @throws SDMDataObjectWriterException
559 : *
560 : * @note
561 : * This method is to be used when cross data are coded with "int" values.
562 : *
563 : * @par
564 : * If this integration contains only cross data (CROSS_ONLY) , the autoData
565 : * parameter is ignored. A empty vector can be passed as an actual parameter.
566 : *
567 : */
568 : void addIntegration(uint32_t integrationNum,
569 : uint64_t time,
570 : uint64_t interval,
571 : const std::vector<FLAGSTYPE>& flags,
572 : const std::vector<ACTUALTIMESTYPE>& actualTimes,
573 : const std::vector<ACTUALDURATIONSTYPE>& actualDurations,
574 : const std::vector<ZEROLAGSTYPE>& zeroLags,
575 : const std::vector<INTCROSSDATATYPE>& crossData,
576 : const std::vector<AUTODATATYPE>& autoData);
577 :
578 :
579 : /**
580 : * Writes an integration (local header + binary attachment) on the MIME message stream.
581 : * @param integrationNum the index (1 based) of the integration.
582 : * @param time time of the integration.
583 : * @param interval interval of the integration.
584 : * @param flags the values of flags.
585 : * @param actualTimes the values of actualTimes.
586 : * @param actualDurations the values of actualDurations.
587 : * @param zeroLags the values of zeroLags.
588 : * @param crossData the values of crossData (encoded in short).
589 : * @param autoData the values of autoData.
590 : *
591 : * @throws SDMDataObjectWriterException
592 : *
593 : * @note
594 : * This method is to be used when cross data are coded with "short" values.
595 : *
596 : * @par
597 : * If this integration contains only cross data (CROSS_ONLY) , the autoData
598 : * parameter is ignored. A empty vector can be passed as an actual parameter.
599 : *
600 : */
601 : void addIntegration(uint32_t integrationNum,
602 : uint64_t time,
603 : uint64_t interval,
604 : const std::vector<FLAGSTYPE>& flags,
605 : const std::vector<ACTUALTIMESTYPE>& actualTimes,
606 : const std::vector<ACTUALDURATIONSTYPE>& actualDurations,
607 : const std::vector<ZEROLAGSTYPE>& zeroLags,
608 : const std::vector<SHORTCROSSDATATYPE>& crossData,
609 : const std::vector<AUTODATATYPE>& autoData);
610 :
611 : /**
612 : * Writes an integration (local header + binary attachment) on the MIME message stream.
613 : * @param integrationNum the index (1 based) of the integration.
614 : * @param time time of the integration.
615 : * @param interval interval of the integration.
616 : * @param flags the values of flags.
617 : * @param actualTimes the values of actualTimes.
618 : * @param actualDurations the values of actualDurations.
619 : * @param zeroLags the values of zeroLags.
620 : * @param crossData the values of crossData (encoded in float).
621 : * @param autoData the values of autoData.
622 : *
623 : * @throws SDMDataObjectWriterException
624 : *
625 : * @note
626 : * This method is to be used when cross data are coded with "float" values.
627 : *
628 : * @par
629 : * If this integration contains only cross data (CROSS_ONLY) , the autoData
630 : * parameter is ignored. A empty vector can be passed as an actual parameter.
631 : *
632 : */
633 : void addIntegration(uint32_t integrationNum,
634 : uint64_t time,
635 : uint64_t interval,
636 : const std::vector<FLAGSTYPE>& flags,
637 : const std::vector<ACTUALTIMESTYPE>& actualTimes,
638 : const std::vector<ACTUALDURATIONSTYPE>& actualDurations,
639 : const std::vector<ZEROLAGSTYPE>& zeroLags,
640 : const std::vector<FLOATCROSSDATATYPE>& crossData,
641 : const std::vector<AUTODATATYPE>& autoData);
642 :
643 :
644 : /**
645 : * Writes an subintegration (local header + binary attachment) on the MIME message stream.
646 : * @param integrationNum the index (1 based) of the integration.
647 : * @param subintegrationNum the index(1 based) of the subintegration.
648 : * @param time time of the integration.
649 : * @param interval interval of the integration.
650 : * @param flags the values of flags.
651 : * @param actualTimes the values of actualTimes.
652 : * @param actualDurations the values of actualDurations.
653 : * @param zeroLags the values of zeroLags.
654 : * @param crossData the values of crossData (encoded in int).
655 : * @param autoData the values of autoData.
656 : *
657 : * @throws SDMDataObjectWriterException
658 : *
659 : * @note
660 : * This method is to be used when cross data are coded with "int" values.
661 : *
662 : * @par
663 : * If this integration contains only cross data (CROSS_ONLY) , the autoData
664 : * parameter is ignored. A empty vector can be passed as an actual parameter.
665 : *
666 : */
667 : void addSubintegration(uint32_t integrationNum,
668 : uint32_t subintegrationNum,
669 : uint64_t time,
670 : uint64_t interval,
671 : const std::vector<FLAGSTYPE>& flags,
672 : const std::vector<ACTUALTIMESTYPE>& actualTimes,
673 : const std::vector<ACTUALDURATIONSTYPE>& actualDurations,
674 : const std::vector<ZEROLAGSTYPE>& zeroLags,
675 : const std::vector<INTCROSSDATATYPE>& crossData,
676 : const std::vector<AUTODATATYPE>& autoData);
677 :
678 :
679 : /**
680 : * Writes an subintegration (local header + binary attachment) on the MIME message stream.
681 : * @param integrationNum the index (1 based) of the integration.
682 : * @param subintegrationNum the index(1 based) of the subintegration.
683 : * @param time time of the integration.
684 : * @param interval interval of the integration.
685 : * @param flags the values of flags.
686 : * @param actualTimes the values of actualTimes.
687 : * @param actualDurations the values of actualDurations.
688 : * @param zeroLags the values of zeroLags.
689 : * @param crossData the values of crossData (encoded in short).
690 : * @param autoData the values of autoData.
691 : *
692 : * @throws SDMDataObjectWriterException
693 : *
694 : * @note
695 : * This method is to be used when cross data are coded with "short" values.
696 : *
697 : * @par
698 : * If this integration contains only cross data (CROSS_ONLY) , the autoData
699 : * parameter is ignored. A empty vector can be passed as an actual parameter.
700 : *
701 : */
702 : void addSubintegration(uint32_t integrationNum,
703 : uint32_t subintegrationNum,
704 : uint64_t time,
705 : uint64_t interval,
706 : const std::vector<FLAGSTYPE>& flags,
707 : const std::vector<ACTUALTIMESTYPE>& actualTimes,
708 : const std::vector<ACTUALDURATIONSTYPE>& actualDurations,
709 : const std::vector<ZEROLAGSTYPE>& zeroLags,
710 : const std::vector<SHORTCROSSDATATYPE>& crossData,
711 : const std::vector<AUTODATATYPE>& autoData);
712 :
713 : /**
714 : * Writes an subintegration (local header + binary attachment) on the MIME message stream.
715 : * @param integrationNum the index (1 based) of the integration.
716 : * @param subintegrationNum the index(1 based) of the subintegration.
717 : * @param time time of the integration.
718 : * @param interval interval of the integration.
719 : * @param flags the values of flags.
720 : * @param actualTimes the values of actualTimes.
721 : * @param actualDurations the values of actualDurations.
722 : * @param zeroLags the values of zeroLags.
723 : * @param crossData the values of crossData (encoded in float).
724 : * @param autoData the values of autoData.
725 : *
726 : * @throws SDMDataObjectWriterException
727 : *
728 : * @note
729 : * This method is to be used when cross data are coded with "float" values.
730 : *
731 : * @par
732 : * If this integration contains only cross data (CROSS_ONLY) , the autoData
733 : * parameter is ignored. A empty vector can be passed as an actual parameter.
734 : *
735 : */
736 : void addSubintegration(uint32_t integrationNum,
737 : uint32_t subintegrationNum,
738 : uint64_t time,
739 : uint64_t interval,
740 : const std::vector<FLAGSTYPE>& flags,
741 : const std::vector<ACTUALTIMESTYPE>& actualTimes,
742 : const std::vector<ACTUALDURATIONSTYPE>& actualDurations,
743 : const std::vector<ZEROLAGSTYPE>& zeroLags,
744 : const std::vector<FLOATCROSSDATATYPE>& crossData,
745 : const std::vector<AUTODATATYPE>& autoData);
746 :
747 : /**
748 : * Returns the number of bytes written so far.
749 : * This method can be used at any time during the life of an instance of SDMDataObjectWriter.
750 : * It returns the number of bytes emitted on the output (memory, standard output, disk file...)
751 : * as the methods of this class, except done, are called.
752 : * <ul>
753 : * <li>This number is set to 0 at the creation of an SDMDataObjectWriter,</li>
754 : * <li>it is incremented accordingly with the number of bytes emitted by the different methods, except done, </li>
755 : * <li>it is reset to 0 by a call to the method done.</li>
756 : * </ul>
757 : *
758 : * @return an uint64_t.
759 : */
760 : uint64_t numBytes();
761 :
762 :
763 : void output (const std::string& s);
764 : void outputln (const std::string& s);
765 : void output (const float* data, uint32_t numData);
766 : void outputln (const float* data, uint32_t numData);
767 : void outputln (const long long* data, uint32_t numData);
768 :
769 0 : template <class T> void output(const std::vector<T>& data) {
770 0 : numBytes_ += data.size()*sizeof(T);
771 0 : switch (otype_) {
772 :
773 0 : case STDOUT:
774 0 : std::cout.write((const char*)&data.at(0), data.size()*sizeof(T));
775 0 : break;
776 :
777 0 : case MEMORY:
778 0 : oss_->write((const char*)&data.at(0), data.size()*sizeof(T));
779 0 : break;
780 :
781 0 : case FILE:
782 0 : ofs_->write((const char*)&data.at(0), data.size()*sizeof(T));
783 0 : break;
784 : }
785 0 : }
786 :
787 0 : template <class T> void outputln (const std::vector<T>& data) {
788 0 : output<T>(data);
789 0 : outputln();
790 0 : }
791 :
792 : void outputln ();
793 :
794 : void outputlnLocation(const std::string& name, const SDMDataSubset& sdmDataSubset);
795 :
796 : private:
797 : enum OUTDEST {STDOUT, MEMORY, FILE};
798 : OUTDEST otype_;
799 : std::ofstream* ofs_;
800 : std::ostringstream* oss_;
801 :
802 : // The ALMA uid of the MIME message.
803 : std::string uid_;
804 :
805 : // The title of the binary data.
806 : std::string title_;
807 :
808 : // The subscan path.
809 : std::string subscanPath_;
810 :
811 : // An SDMDataObject
812 : SDMDataObject sdmDataObject_;
813 :
814 : // The number of the SDMDataSubset being written
815 : uint32_t sdmDataSubsetNum_;
816 :
817 : // Two strings used as MIME boundaries
818 : static const std::string MIMEBOUNDARY_1;
819 : static const std::string MIMEBOUNDARY_2;
820 :
821 :
822 : // Class initialization stuff
823 : static const bool initClass_;
824 : static bool initClass();
825 :
826 : // The axes names definitions for WVR data and their related flags.
827 : static std::vector<AxisNameMod::AxisName> WVRDATAAXES, WVRDATAFLAGSAXES;
828 :
829 : // A utility to fill a vector of <Enum> from a an array of c-strings.
830 : template <class Enum, class EnumHelper> static std::vector<Enum> enumvec(const std::string& strliterals) {
831 : std::vector<Enum> result;
832 :
833 : std::string strliteral;
834 : std::stringstream ss(strliterals);
835 :
836 : std::vector<std::string> tokens;
837 : while (ss >> strliteral)
838 : result.push_back(EnumHelper::literal(strliteral));
839 :
840 : return result;
841 : }
842 :
843 : // Writes the very first part of the MIME message.
844 : void preamble();
845 :
846 : // Write the very end of the MIME message.
847 : void postamble();
848 :
849 :
850 : void addData(uint32_t integrationNum,
851 : uint32_t subintegrationNum,
852 : uint64_t time,
853 : uint64_t interval,
854 : const std::vector<FLAGSTYPE>& flags,
855 : const std::vector<ACTUALTIMESTYPE>& actualTimes,
856 : const std::vector<ACTUALDURATIONSTYPE>& actualDurations,
857 : const std::vector<ZEROLAGSTYPE>& zeroLags,
858 : const std::vector<INTCROSSDATATYPE>& intCrossData,
859 : const std::vector<SHORTCROSSDATATYPE>& shortCrossData,
860 : const std::vector<FLOATCROSSDATATYPE>& floatCrossData,
861 : const std::vector<AUTODATATYPE>& autoData);
862 :
863 : // Are we done with this ?
864 : bool done_;
865 :
866 : // The number of bytes written so far.
867 : uint64_t numBytes_;
868 :
869 :
870 : // A small finite state automaton to control the usage of SDMDataObjectWriter.
871 : enum States {START, S_TPDATA, S_TPDATAHEADER, S_ADDTPSUBSCAN, S_ADDTPINTEGRATION, S_WVRDATA, S_CORRDATAHEADER, S_ADDINTEGRATION, S_ADDSUBINTEGRATION, END};
872 : enum Transitions {T_TPDATA, T_TPDATAHEADER, T_ADDTPSUBSCAN, T_ADDTPINTEGRATION, T_WVRDATA, T_CORRDATAHEADER, T_ADDINTEGRATION, T_ADDSUBINTEGRATION, T_DONE};
873 : States currentState_;
874 :
875 : void checkState(Transitions t, const std::string& methodName);
876 :
877 : };
878 : } // namespace asdmbinaries
879 : #endif // SDMDataObjectWriter_CLASS
|