LCOV - code coverage report
Current view: top level - alma/ASDMBinaries - SDMDataObjectWriter.h (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 11 21 52.4 %
Date: 2024-12-11 20:54:31 Functions: 4 14 28.6 %

          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       12088 :     template <class T> void output(const std::vector<T>& data) {
     770       12088 :       numBytes_ += data.size()*sizeof(T);
     771       12088 :       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       12088 :       case FILE:
     782       12088 :         ofs_->write((const char*)&data.at(0), data.size()*sizeof(T));
     783       12088 :         break;
     784             :       }       
     785       12088 :     }
     786             : 
     787       12088 :     template <class T> void outputln (const std::vector<T>& data) {
     788       12088 :       output<T>(data);
     789       12088 :       outputln();
     790       12088 :     }
     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

Generated by: LCOV version 1.16