// %sample:codesample1:cpp%
#include "xtcdata/xtc/ShapesData.hh"
#include "xtcdata/xtc/DescData.hh"
#include "xtcdata/xtc/Dgram.hh"
#include "xtcdata/xtc/TypeId.hh"
#include "xtcdata/xtc/XtcIterator.hh"
#include "xtcdata/xtc/VarDef.hh"
// various std library includes omitted...
using namespace XtcData;
#define BUFSIZE 0x4000000
HSDXtcWriter::HSDXtcWriter()
{
// Define the "signature" of the data in
// our feature extraction data set
class FexDef:public VarDef
{
public:
enum index
{
floatFex,
arrayFex,
intFex
};
FexDef()
{
NameVec.push_back({"floatFex",Name::DOUBLE});
// "arrayFex" has rank 2; 0 is the default, for scalar data
NameVec.push_back({"arrayFex",Name::FLOAT,2});
NameVec.push_back({"intFex",Name::INT64});
}
};
// Define some instance variables.
FILE *this->xtcoutfile;
// -------- Set up the metadata ------------
// Declare an Xtc::Dgram to store metadata about the output
Dgram& this->metadataDgram;
// Declare a NamesVec to store Names info
NamesVec this->namesVec;
// Declare a NamesId object to act as composite lookup key
NamesId this->namesId;
// Store the node ID of this node
unsigned this->nodeid = 1;
// -------- Set up the readout data ---------
// Declare an Xtc:Dgram to store readout data
Dgram& this->readoutDgram;
// Create one of our previously-defined FexDefs
this->FexDef = new FexDef();
// Now initialize various things
_initializeMetadataDgram();
}
void HSDXtcWriter::_initializeMetadataDgram()
{
TypeId tid(TypeId::Parent, 0);
void* configbuf = malloc(BUFSIZE);
this->metadataDgram = *(Dgram*)configbuf;
this->metadataDgram.xtc.contains = tid;
this->metadataDgram.xtc.damage = 0;
this->metadataDgram.xtc.extent = sizeof(Xtc);
}
void HSDXtcWriter::_initializeReadoutDataDgram()
{
TypeId tid(TypeId::Parent, 0);
void* buf = malloc(BUFSIZE);
this->readoutDgram = *(Dgram*)buf;
this->readoutDgram.xtc.contains = tid;
this->readoutDgram.xtc.damage = 0;
this->readoutDgram.xtc.extent = sizeof(Xtc);
}
void HSDXtcWriter::_addNames()
{
// Instantiate an Alg to define metadata for
// a feature extraction ("fex") algorithm,
// version 4.5.6
Alg hsdFexAlg("fex",4,5,6);
// Create a NamesId composite lookup key and
// then a Names structure (ID'd with that key)
// that identifies the location, algorithm,
// detector type and detectorID.
this->namesId.NamesId(this->nodeId,1); // nodeId=1, namesId = 1
Names& fexNames = *new(xtc) Names("xpphsd", hsdFexAlg, "hsd", "detnum1234", this->namesId)
// And now we add the Names structure to the
// parent Xtc metadata container along with
// the FexDef data signature.
fexNames.add(this->metadataDgram.xtc, this->FexDef);
// add this Names structure to the NamesVec
this->namesVec[namesId1] = NameIndex(this->fexNames);
}
void HSDXtcWriter::openXtcFile(xtcoutfilename)
{
this->xtcoutfile = fopen(xtcoutfilename, "w");
}
void HSDXtcWriter::setup()
{
// Behind this public method, call internal to
// set up the metadata
this->_addNames();
// Omitting code to confirm successful file operation....
fwrite(&this->metadataDgram, sizeof(this->metadataDgram) + this->metadataDgram.xtc.sizeofPayload(), 1, this->xtcoutfile)
}
void HSDXtcWriter::writeFeature()
{
// Initialize the Dgram for readout data
this->initializeReadoutDataDgram();
// Need some makebelieve code here to show how this
// callback method unpacks data from DAQ
// to cram into these Xtc structures...
// Talk to Chris. Is this event by event? Would you want
// to destruct this CreateData after each event?
CreateData fex(this->readoutDgram.xtc, this->namesVec, this->namesId);
// Need stub code here to represent getting values from DAQ
// and using set_value and allocate with something real-ish
// set_value() lets you set scalar values in the data record.
// The 'floatFex' ID is defined in our custom FexDef class.
fex.set_value(FexDef::floatFex, (double)41.0);
// Use allocate() to set up data that's better represented as
// vectors or matrices.
// The 'arrayFex' ID is defined in our custom FexDef class.
unsigned shape[MaxRank] = {2,3}; //MaxRank is an Xtc library
//global upper limit on data complexity.
Array<float> arrayT = fex.allocate<float>(this->FexDef::arrayFex, shape);
for(unsigned i=0; i<shape[0]; i++){
for (unsigned j=0; j<shape[1]; j++) {
arrayT(i,j) = 142.0+i*shape[1]+j;
}
};
// Another scalar value setter.
// The 'intFex' ID is defined in our custom FexDef class.
fex.set_value(FexDef::intFex, (int64_t) 42);
}
void HSDXtcWriter::closeXtcFile()
{
fclose(this->xtcoutfile);
}
// ...
// %endsample% |