source: trunk/FACT++/src/DataWriteFits.cc@ 12458

Last change on this file since 12458 was 12454, checked in by tbretz, 13 years ago
Added the number of cells per channel
File size: 7.8 KB
Line 
1#include "DataWriteFits.h"
2
3#include "FAD.h"
4#include "Converter.h"
5
6using namespace std;
7
8DataWriteFits::~DataWriteFits()
9{
10 Close();
11 delete fConv;
12}
13
14template <typename T>
15 void DataWriteFits::WriteKey(const string &name, const int idx, const T &value, const string &comment)
16{
17 ostringstream str;
18 str << name << idx;
19
20 ostringstream com;
21 com << "Board " << setw(2) << idx << ": " << comment;
22
23 fFile.WriteKey(str.str(), value, com.str());
24}
25
26// --------------------------------------------------------------------------
27//
28//! DataWriteFits constructor. This is the one that should be used, not the default one (parameter-less)
29//! @param runid This parameter should probably be removed. I first thought it was the run number, but apparently it is not
30//! @param h a pointer to the RUN_HEAD structure that contains the informations relative to this run
31//
32bool DataWriteFits::Open(RUN_HEAD* h)
33{
34 if (fConv)
35 {
36 Error("DataWriteFits::Open called twice.");
37 return false;
38 }
39
40 fFile.AddColumn('I', "EventNum");
41 fFile.AddColumn('I', "TriggerNum");
42 fFile.AddColumn('S', "TriggerType");
43 fFile.AddColumn('I', "NumBoards");
44 fFile.AddColumn('C', "Errors", 4);
45 fFile.AddColumn('I', "SoftTrig");
46 fFile.AddColumn('I', "UnixTimeUTC", 2);
47 fFile.AddColumn('I', "BoardTime", NBOARDS);
48 fFile.AddColumn('S', "StartCellData", NPIX);
49 fFile.AddColumn('S', "StartCellTimeMarker", NTMARK);
50 fFile.AddColumn('S', "Data", h->NPix*h->Nroi);
51
52 int16_t realRoiTM = (h->NroiTM > h->Nroi) ? h->Nroi : 0;
53 fFile.AddColumn('S', "TimeMarker", h->NTm*realRoiTM);//ETIENNE TM);
54
55 // Write length of physical pipeline (1024)
56
57 fConv = new Converter(Converter::ToFormat(fFile.GetColumnTypes()));
58
59 const size_t sz = (h->NPix*h->Nroi + h->NTm*realRoiTM)*2;//ETIENNE TM)*2;
60 if (fConv->GetSize()-sz+4!=sizeof(EVENT))
61 {
62 ostringstream str;
63 str << "The EVENT structure size (" << sizeof(EVENT) << ") doesn't match the described FITS row (";
64 str << fConv->GetSize()-sz+4 << ")";
65 Error(str);
66 return false;
67 }
68
69 //Form filename, based on runid and run-type
70 fFileName = FormFileName("fits");
71
72 if (!fFile.OpenFile(fFileName))
73 return false;
74
75 if (!fFile.OpenTable("Events"))
76 return false;
77
78 if (!fFile.WriteDefaultKeys("fadctrl"))
79 return false;
80
81 Info("==> TODO: Write sampling frequency...");
82
83 //write header data
84 //first the "standard" keys
85 try
86 {
87 fFile.WriteKey("BLDVER", h->Version, "Builder version");
88 fFile.WriteKey("RUNID", GetRunId(), "Run number");
89 fFile.WriteKey("RUNTYPE", h->RunType, "Type of run");
90 fFile.WriteKey("NBOARD", h->NBoard, "Number of acquisition boards");
91 fFile.WriteKey("NPIX", h->NPix, "Number of pixels");
92 fFile.WriteKey("NTMARK", h->NTm, "Number of Time marks");
93 fFile.WriteKey("NCELLS", 1024, "Maximum number of slices per pixels");
94 fFile.WriteKey("NROI", h->Nroi, "Number of slices per pixels");
95 fFile.WriteKey("NROITM", realRoiTM, "Number of slices per time-marker"); //ETIENNE from NroiTMm to Nroi
96 int realOffset = (h->NroiTM > h->Nroi) ? h->NroiTM - 2*h->Nroi : 0;
97 fFile.WriteKey("OFFSET", realOffset, "Offset between pixels ROI and TM ROi"); //ETIENNE added
98
99 //FIXME should we also put the start and stop time of the received data ?
100 //now the events header related variables
101 fFile.WriteKey("CAMERA", "MGeomCamFACT", "");
102 fFile.WriteKey("DAQ", "DRS4", "");
103 fFile.WriteKey("ADCRANGE", 2000, "Dynamic range in mV");
104 fFile.WriteKey("ADC", 12, "Resolution in bits");
105
106
107 // Write a single key for:
108 // -----------------------
109 // Start package flag
110 // package length
111 // version number
112 // status
113 // Prescaler
114
115 // Write 40 kays for (?)
116 // Phaseshift
117 // DAC
118
119 for (int i=0; i<h->NBoard; i++)
120 {
121 const PEVNT_HEADER &hh = h->FADhead[i];
122
123 // Header values whihc won't change during the run
124 WriteKey("ID", i, hh.board_id, "Board ID");
125 WriteKey("DNA", i, hh.DNA, "DNA");
126 WriteKey("FWVER", i, hh.version_no, "Firmware Version");
127 }
128
129 // FIXME: Calculate average ref clock frequency
130 for (int i=0; i<h->NBoard; i++)
131 {
132 const PEVNT_HEADER &hh = h->FADhead[i];
133
134 if (hh.start_package_flag==0)
135 continue;
136
137 fFile.WriteKey("BOARD", i, "Board number for RUN, PRESC, PHASE and DAC");
138 fFile.WriteKey("RUN", hh.runnumber, "Run number");
139 fFile.WriteKey("PRESC", hh.trigger_generator_prescaler, "Trigger generator prescaler");
140 fFile.WriteKey("PHASE", (int16_t)hh.adc_clock_phase_shift, "ADC clock phase shift");
141
142 for (int j=0; j<8; j++)
143 {
144 ostringstream dac, cmt;
145 dac << "DAC" << j;
146 cmt << "Command value for " << dac.str();
147 fFile.WriteKey(dac.str(), hh.dac[j], cmt.str());
148 }
149
150 break;
151 }
152
153 double avg = 0;
154 int cnt = 0;
155 for (int i=0; i<h->NBoard; i++)
156 {
157 const PEVNT_HEADER &hh = h->FADhead[i];
158
159 if (hh.start_package_flag==0)
160 continue;
161
162 avg += hh.REFCLK_frequency;
163 cnt ++;
164 }
165
166 // FIXME: I cannot write a double! WHY?
167 fFile.WriteKey("REFCLK", avg/cnt, "Average reference clock frequency in Hz");
168 }
169 catch (const CCfits::FitsException &e)
170 {
171 Error("CCfits::Table::addKey failed in '"+fFileName+"': "+e.message());
172 return false;
173 }
174
175 //Last but not least, add header keys that will be updated when closing the file
176 return WriteFooter(NULL);
177}
178
179// --------------------------------------------------------------------------
180//
181//! This writes one event to the file
182//! @param e the pointer to the EVENT
183//
184bool DataWriteFits::WriteEvt(EVENT *e)
185{
186 if (!fFile.AddRow())
187 return false;
188 int realRoiTM = (e->RoiTM > e->Roi) ? e->Roi : 0;
189 const size_t sz = sizeof(EVENT) + sizeof(e->StartPix)*e->Roi+sizeof(e->StartTM)*realRoiTM; //ETIENNE from RoiTm to Roi
190
191 const vector<char> data = fConv->ToFits(reinterpret_cast<char*>(e)+4, sz-4);
192
193 return fFile.WriteData(data.data(), data.size());
194}
195
196bool DataWriteFits::WriteFooter(RUN_TAIL *rt)
197{
198 try
199 {
200 /*
201 fFile.WriteKey("NBEVTOK", rt ? rt->nEventsOk : uint32_t(0),
202 "How many events were written");
203
204 fFile.WriteKey("NBEVTREJ", rt ? rt->nEventsRej : uint32_t(0),
205 "How many events were rejected by SW-trig");
206
207 fFile.WriteKey("NBEVTBAD", rt ? rt->nEventsBad : uint32_t(0),
208 "How many events were rejected by Error");
209 */
210
211 //FIXME shouldn't we convert start and stop time to MjD first ?
212 //FIXME shouldn't we also add an MjD reference ?
213
214 fFile.WriteKey("TSTART", rt ? rt->PCtime0 : uint32_t(0),
215 "Time when first event received");
216
217 fFile.WriteKey("TSTOP", rt ? rt->PCtimeX : uint32_t(0),
218 "Time when last event received");
219 }
220 catch (const CCfits::FitsException &e)
221 {
222 Error("CCfits::Table::addKey failed in '"+fFile.GetName()+"': "+e.message());
223 return false;
224 }
225 return true;
226}
227
228// --------------------------------------------------------------------------
229//
230//! Closes the file, and before this it write the TAIL data
231//! @param rt the pointer to the RUN_TAIL data structure
232//
233bool DataWriteFits::Close(RUN_TAIL *rt)
234{
235 if (!fFile.IsOpen())
236 return false;
237
238 WriteFooter(rt);
239
240 fFile.Close();
241
242 return true;
243}
Note: See TracBrowser for help on using the repository browser.