FACT++  1.0
DataWriteFits.cc
Go to the documentation of this file.
1 #include "DataWriteFits.h"
2 
3 #include "HeadersFAD.h"
4 #include "EventBuilder.h"
5 #include "Converter.h"
6 
7 
8 using namespace std;
9 
11 {
12  if (fFile.IsOpen())
13  {
14  WriteFooter();
15  fFile.Close();
16  }
17 
18  delete fConv;
19 }
20 
21 template <typename T>
22  void DataWriteFits::WriteKey(const string &name, const int idx, const T &value, const string &comment)
23 {
24  ostringstream str;
25  str << name << idx;
26 
27  ostringstream com;
28  com << "Board " << setw(2) << idx << ": " << comment;
29 
30  fFile.WriteKey(str.str(), value, com.str());
31 }
32 
33 // --------------------------------------------------------------------------
34 //
38 //
39 bool DataWriteFits::Open(const RUN_HEAD &h, const FAD::RunDescription &d)
40 {
41  if (fConv)
42  {
43  Error("DataWriteFits::Open called twice.");
44  return false;
45  }
46 
47  const int16_t realRoiTM = (h.NroiTM >= 2*h.Nroi && h.Nroi<=512) ? h.Nroi : 0;
48 
49  fFile.AddColumn('I', "EventNum");
50  fFile.AddColumn('I', "TriggerNum");
51  fFile.AddColumn('S', "TriggerType");
52  fFile.AddColumn('I', "NumBoards");
53  fFile.AddColumn('C', "Errors", 4);
54  fFile.AddColumn('I', "SoftTrig");
55  fFile.AddColumn('I', "UnixTimeUTC", 2);
56  fFile.AddColumn('I', "BoardTime", NBOARDS);
57  fFile.AddColumn('S', "StartCellData", NPIX);
58  fFile.AddColumn('S', "StartCellTimeMarker", NTMARK);
59  fFile.AddColumn('S', "Data", h.NPix*h.Nroi);
60  fFile.AddColumn('S', "TimeMarker", h.NTm*realRoiTM);
61 
62  // Write length of physical pipeline (1024)
63  fConv = new Converter(Converter::ToFormat(fFile.GetColumnTypes()));
64 
65  const size_t sz = (h.NPix*h.Nroi + h.NTm*realRoiTM)*2;
66  if (fConv->GetSize()-sz+4!=sizeof(EVENT))
67  {
68  ostringstream str;
69  str << "The EVENT structure size (" << sizeof(EVENT) << ") doesn't match the described FITS row (";
70  str << fConv->GetSize()-sz+4 << ")";
71  Error(str);
72  return false;
73  }
74 
75  //Form filename, based on runid and run-type
76  fFileName = FormFileName("fits");
77 
78  if (!fFile.OpenFile(fFileName))
79  return false;
80 
81  if (!fFile.OpenTable("Events"))
82  return false;
83 
84  if (!fFile.WriteDefaultKeys("fadctrl"))
85  return false;
86 
87  Info("==> TODO: Write sampling frequency...");
88 
89  //write header data
90  //first the "standard" keys
91  try
92  {
93  fFile.WriteKey("BLDVER", h.Version, "Builder version");
94  fFile.WriteKey("RUNID", GetRunId(), "Run number");
95 // fFile.WriteKey("RUNTYPE", h.RunType, "Type of run");
96  fFile.WriteKey("NBOARD", h.NBoard, "Number of acquisition boards");
97  fFile.WriteKey("NPIX", h.NPix, "Number of pixels");
98  fFile.WriteKey("NTMARK", h.NTm, "Number of time marker channels");
99  fFile.WriteKey("NCELLS", 1024, "Maximum number of slices per pixels");
100  fFile.WriteKey("NROI", h.Nroi, "Number of slices per pixels");
101  fFile.WriteKey("NROITM", realRoiTM, "Number of slices per time-marker");
102 
103  const uint16_t realOffset = (h.NroiTM > h.Nroi) ? h.NroiTM - 2*h.Nroi : 0;
104  fFile.WriteKey("TMSHIFT", realOffset, "Shift of the start of the time marker readout wrt to data");
105 
106  //FIXME should we also put the start and stop time of the received data ?
107  //now the events header related variables
108  fFile.WriteKey("CAMERA", "MGeomCamFACT", "");
109  fFile.WriteKey("DAQ", "DRS4", "");
110  fFile.WriteKey("ADCRANGE", 2000, "Dynamic range in mV");
111  fFile.WriteKey("ADC", 12, "Resolution in bits");
112  fFile.WriteKey("RUNTYPE", d.name, "File type according to FAD configuration");
113 
114  // Write a single key for:
115  // -----------------------
116  // Start package flag
117  // package length
118  // version number
119  // status
120  // Prescaler
121 
122  // Write 40 kays for (?)
123  // Phaseshift
124  // DAC
125 
126  for (int i=0; i<h.NBoard; i++)
127  {
128  const PEVNT_HEADER &hh = h.FADhead[i];
129 
130  // Header values whihc won't change during the run
131  WriteKey("ID", i, hh.board_id, "Board ID");
132  WriteKey("FWVER", i, hh.version_no, "Firmware Version");
133 
134  ostringstream dna;
135  dna << "0x" << hex << hh.DNA;
136  WriteKey("DNA", i, dna.str(), "Unique FPGA device identifier (DNA)");
137  }
138 
139  // FIXME: Calculate average ref clock frequency
140  for (int i=0; i<h.NBoard; i++)
141  {
142  const PEVNT_HEADER &hh = h.FADhead[i];
143 
144  if (hh.start_package_flag==0)
145  continue;
146 
147  fFile.WriteKey("BOARD", i, "Board number for RUN, PRESC, PHASE and DAC");
148  // fFile.WriteKey("RUN", hh.runnumber, "Run number");
149  fFile.WriteKey("PRESC", hh.trigger_generator_prescaler, "Trigger generator prescaler");
150  fFile.WriteKey("PHASE", (int16_t)hh.adc_clock_phase_shift, "ADC clock phase shift");
151 
152  for (int j=0; j<8; j++)
153  {
154  ostringstream dac, cmt;
155  dac << "DAC" << j;
156  cmt << "Command value for " << dac.str();
157  fFile.WriteKey(dac.str(), hh.dac[j], cmt.str());
158  }
159 
160  break;
161  }
162 
163  double avg = 0;
164  int cnt = 0;
165  for (int i=0; i<h.NBoard; i++)
166  {
167  const PEVNT_HEADER &hh = h.FADhead[i];
168 
169  if (hh.start_package_flag==0)
170  continue;
171 
172  avg += hh.REFCLK_frequency;
173  cnt ++;
174  }
175 
176  // FIXME: I cannot write a double! WHY?
177  fFile.WriteKey("REFCLK", avg/cnt*2.048, "Average reference clock frequency in Hz");
178 
179  fFile.WriteKey("DRSCALIB", GetDrsStep()>=0, "This file belongs to a DRS calibration");
180  if (GetDrsStep()>=0)
181  fFile.WriteKey("DRSSTEP", GetDrsStep(), "Step of the DRS calibration");
182 
183  }
184  catch (const CCfits::FitsException &e)
185  {
186  Error("CCfits::Table::addKey failed in '"+fFileName+"': "+e.message());
187  return false;
188  }
189 
190  fTstart[0] = h.RunTime;
191  fTstart[1] = h.RunUsec;
192 
193  fTstop[0] = 0;
194  fTstop[1] = 0;
195 
196  fTriggerCounter.fill(0);
197 
198  //Last but not least, add header keys that will be updated when closing the file
199  return WriteFooter();
200 }
201 
202 // --------------------------------------------------------------------------
203 //
206 //
208 {
209  if (!fFile.AddRow())
210  return false;
211 
212  // Remember the counter of the last written event
214 
215  // Remember the time of the last event
216  fTstop[0] = evt.time.tv_sec;
217  fTstop[1] = evt.time.tv_usec;
218 
219  const EVENT &e = *evt.fEvent;
220 
221  const int realRoiTM = (e.RoiTM > e.Roi) ? e.Roi : 0;
222  const size_t sz = sizeof(EVENT) + sizeof(e.StartPix)*e.Roi+sizeof(e.StartTM)*realRoiTM; //ETIENNE from RoiTm to Roi
223 
224  const vector<char> data = fConv->ToFits(reinterpret_cast<const char*>(&e)+4, sz-4);
225 
226  return fFile.WriteData(data.data(), data.size());
227 }
228 
230 {
231  try
232  {
233  /*
234  fFile.WriteKey("NBEVTOK", rt ? rt->nEventsOk : uint32_t(0),
235  "How many events were written");
236 
237  fFile.WriteKey("NBEVTREJ", rt ? rt->nEventsRej : uint32_t(0),
238  "How many events were rejected by SW-trig");
239 
240  fFile.WriteKey("NBEVTBAD", rt ? rt->nEventsBad : uint32_t(0),
241  "How many events were rejected by Error");
242  */
243 
244  //FIXME shouldn't we convert start and stop time to MjD first ?
245  //FIXME shouldn't we also add an MjD reference ?
246 
247  const Time start(fTstart[0], fTstart[1]);
248  const Time stop (fTstop[0], fTstop[1]);
249 
250  fFile.WriteKey("TSTARTI", uint32_t(floor(start.UnixDate())),
251  "Time when first event received (integral part)");
252  fFile.WriteKey("TSTARTF", fmod(start.UnixDate(), 1),
253  "Time when first event received (fractional part)");
254  fFile.WriteKey("TSTOPI", uint32_t(floor(stop.UnixDate())),
255  "Time when last event received (integral part)");
256  fFile.WriteKey("TSTOPF", fmod(stop.UnixDate(), 1),
257  "Time when last event received (fractional part)");
258  fFile.WriteKey("DATE-OBS", start.Iso(),
259  "Time when first event received");
260  fFile.WriteKey("DATE-END", stop.Iso(),
261  "Time when last event received");
262 
263  fFile.WriteKey("NTRG", fTriggerCounter[0], "No of physics triggered events");
264  fFile.WriteKey("NTRGPED", fTriggerCounter[1], "No of pure pedestal triggered events");
265  fFile.WriteKey("NTRGLPE", fTriggerCounter[2], "No of external light pulser triggered events");
266  fFile.WriteKey("NTRGTIM", fTriggerCounter[3], "No of time calibration triggered events");
267  fFile.WriteKey("NTRGLPI", fTriggerCounter[4], "No of internal light pulser triggered events");
268  fFile.WriteKey("NTRGEXT1", fTriggerCounter[5], "No of triggers from ext1 triggered events");
269  fFile.WriteKey("NTRGEXT2", fTriggerCounter[6], "No of triggers from ext2 triggered events");
270  fFile.WriteKey("NTRGMISC", fTriggerCounter[7], "No of all other triggered events");
271  }
272  catch (const CCfits::FitsException &e)
273  {
274  Error("CCfits::Table::addKey failed in '"+fFile.GetName()+"': "+e.message());
275  return false;
276  }
277  return true;
278 }
279 
280 // --------------------------------------------------------------------------
281 //
284 //
286 {
287  if (!fFile.IsOpen())
288  return false;
289 
290  WriteFooter();
291 
292  fFile.Close();
293 
294  return true;
295 }
int start(int initState)
Definition: feeserver.c:1740
uint32_t RunTime
Definition: FAD.h:96
uint16_t NroiTM
Definition: FAD.h:102
uint16_t NTm
Definition: FAD.h:100
EVENT * fEvent
Definition: EventBuilder.h:132
int i
Definition: db_dim_client.c:21
std::string Iso() const
Definition: Time.cc:253
Adds some functionality to boost::posix_time::ptime for our needs.
Definition: Time.h:30
char str[80]
Definition: test_client.c:7
STL namespace.
bool Close(const EVT_CTRL2 &)
uint32_t fTriggerCounter
Definition: HeadersFAD.h:177
void WriteKey(const string &name, const int idx, const T &value, const string &comment)
Definition: FAD.h:92
uint32_t Version
Definition: FAD.h:94
#define NPIX
Definition: BasicGlCamera.h:5
uint16_t Nroi
Definition: FAD.h:101
uint16_t NBoard
Definition: FAD.h:98
double UnixDate() const
Definition: Time.cc:204
#define NTMARK
Definition: BasicGlCamera.h:6
#define NBOARDS
Definition: BasicGlCamera.h:4
float data[4 *1440]
timeval time
Definition: EventBuilder.h:129
bool Open(const RUN_HEAD &h, const FAD::RunDescription &d)
uint32_t RunUsec
Definition: FAD.h:97
static std::string ToFormat(const std::vector< std::string > &fits)
Definition: Converter.cc:1004
uint16_t NPix
Definition: FAD.h:99
Error()
Definition: HeadersFTM.h:197
std::array< uint32_t, 8 > triggerCounter
Definition: EventBuilder.h:137
bool WriteEvt(const EVT_CTRL2 &)
A compiler for the DIM data format string.
Definition: Converter.h:16
PEVNT_HEADER FADhead[NBOARDS]
Definition: FAD.h:105