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

Last change on this file since 12120 was 11893, checked in by tbretz, 13 years ago
Implemented a new determination fo run-number after noon in the fadctrl; created the possibility to add the date to the raw-data path; allow to set the path as program option; for all this moved some code from the datalogger to DimWriteStatistics
File size: 7.7 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', "PCTime", 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 fFile.AddColumn('S', "TimeMarker", h->NTm*h->NroiTM);
52
53 // Write length of physical pipeline (1024)
54
55 fConv = new Converter(Converter::ToFormat(fFile.GetColumnTypes()));
56
57 const size_t sz = (h->NPix*h->Nroi + h->NTm*h->NroiTM)*2;
58 if (fConv->GetSize()-sz+4!=sizeof(EVENT))
59 {
60 ostringstream str;
61 str << "The EVENT structure size (" << sizeof(EVENT) << ") doesn't match the described FITS row (";
62 str << fConv->GetSize()-sz+4 << ")";
63 Error(str);
64 return false;
65 }
66
67 //Form filename, based on runid and run-type
68 fFileName = FormFileName("fits");
69
70 if (!fFile.OpenFile(fFileName))
71 return false;
72
73 if (!fFile.OpenTable("Events"))
74 return false;
75
76 if (!fFile.WriteDefaultKeys("fadctrl"))
77 return false;
78
79 Info("==> TODO: Write sampling frequency...");
80
81 //write header data
82 //first the "standard" keys
83 try
84 {
85 fFile.WriteKey("BLDVER", h->Version, "Builder version");
86 fFile.WriteKey("RUNID", GetRunId(), "Run number");
87 fFile.WriteKey("RUNTYPE", h->RunType, "Type of run");
88 fFile.WriteKey("NBOARD", h->NBoard, "Number of acquisition boards");
89 fFile.WriteKey("NPIX", h->NPix, "Number of pixels");
90 fFile.WriteKey("NTMARK", h->NTm, "Number of Time marks");
91 fFile.WriteKey("NROI", h->Nroi, "Number of slices per pixels");
92 fFile.WriteKey("NROITM", h->NroiTM, "Number of slices per time-marker");
93
94 //FIXME should we also put the start and stop time of the received data ?
95 //now the events header related variables
96 fFile.WriteKey("CAMERA", "MGeomCamFACT", "");
97 fFile.WriteKey("DAQ", "DRS4", "");
98 fFile.WriteKey("ADCRANGE", 2000, "Dynamic range in mV");
99 fFile.WriteKey("ADC", 12, "Resolution in bits");
100
101
102 // Write a single key for:
103 // -----------------------
104 // Start package flag
105 // package length
106 // version number
107 // status
108 // Prescaler
109
110 // Write 40 kays for (?)
111 // Phaseshift
112 // DAC
113
114 for (int i=0; i<h->NBoard; i++)
115 {
116 const PEVNT_HEADER &hh = h->FADhead[i];
117
118 // Header values whihc won't change during the run
119 WriteKey("ID", i, hh.board_id, "Board ID");
120 WriteKey("DNA", i, hh.DNA, "DNA");
121 WriteKey("FWVER", i, hh.version_no, "Firmware Version");
122 }
123 }
124 catch (const CCfits::FitsException &e)
125 {
126 Error("CCfits::Table::addKey failed in "+fFileName+"': "+e.message());
127 return false;
128 }
129
130 /*
131 //now the boards related keywords
132 for (int i=0; i<h->NBoard; i++)
133 {
134 const PEVNT_HEADER &hh = h->FADhead[i];
135
136 WriteKey("STPKGFG", i, hh.start_package_flag, "Start package flag");
137 WriteKey("PKGLEN", i, hh.package_length, "Package length");
138 WriteKey("STATUS", i, hh.PLLLCK, "");
139
140 // WriteKey("TRIGCRC", i, hh.trigger_crc, "Trigger CRC");
141 // WriteKey("TRIGTYP", i, hh.trigger_type, "Trigger type");
142 // WriteKey("TRIGID", i, hh.trigger_id, "Trigger ID");
143 // WriteKey("EVTCNTR", i, hh.fad_evt_counter, "FAD Event Counter");
144 // WriteKey("REFCLK", i, hh.REFCLK_frequency, "Reference Clock Frequency");
145
146 WriteKey("PHASESH", i, hh.adc_clock_phase_shift, "ADC clock phase shift");
147 WriteKey("TRGGEN", i, hh.number_of_triggers_to_generate, "Number of triggers to generate");
148 WriteKey("PRESC", i, hh.trigger_generator_prescaler, "Trigger generator prescaler");
149 WriteKey("RUNNB", i, hh.runnumber, "Run number");
150
151 WriteKey("TIME", i, hh.time, "Time");
152
153 // for (int j=0;j<NTemp;j++)
154 // {
155 // str.str(""); str2.str("");
156 // str << "DRS_T" << i << j;
157 // str2 << "DRS temperature #" << i << " " << j;
158 // WriteKey(str.str(), h->FADhead[i].drs_temperature[j], str2.str());
159 // }
160 for (int j=0;j<NDAC;j++)
161 WriteKey("DAC", i*NDAC+j, hh.dac[j], "DAC");
162 }
163 */
164
165 //Last but not least, add header keys that will be updated when closing the file
166 return WriteFooter(NULL);
167}
168
169// --------------------------------------------------------------------------
170//
171//! This writes one event to the file
172//! @param e the pointer to the EVENT
173//
174bool DataWriteFits::WriteEvt(EVENT *e)
175{
176 if (!fFile.AddRow())
177 return false;
178
179 const size_t sz = sizeof(EVENT) + sizeof(e->StartPix)*e->Roi+sizeof(e->StartTM)*e->RoiTM;
180
181 const vector<char> data = fConv->ToFits(reinterpret_cast<char*>(e)+4, sz-4);
182
183 return fFile.WriteData(data.data(), data.size());
184}
185
186bool DataWriteFits::WriteFooter(RUN_TAIL *rt)
187{
188 try
189 {
190 /*
191 fFile.WriteKey("NBEVTOK", rt ? rt->nEventsOk : uint32_t(0),
192 "How many events were written");
193
194 fFile.WriteKey("NBEVTREJ", rt ? rt->nEventsRej : uint32_t(0),
195 "How many events were rejected by SW-trig");
196
197 fFile.WriteKey("NBEVTBAD", rt ? rt->nEventsBad : uint32_t(0),
198 "How many events were rejected by Error");
199 */
200
201 //FIXME shouldn't we convert start and stop time to MjD first ?
202 //FIXME shouldn't we also add an MjD reference ?
203
204 fFile.WriteKey("TSTART", rt ? rt->PCtime0 : uint32_t(0),
205 "Time when first event received");
206
207 fFile.WriteKey("TSTOP", rt ? rt->PCtimeX : uint32_t(0),
208 "Time when last event received");
209 }
210 catch (const CCfits::FitsException &e)
211 {
212 Error("CCfits::Table::addKey failed in '"+fFile.GetName()+"': "+e.message());
213 return false;
214 }
215 return true;
216}
217
218// --------------------------------------------------------------------------
219//
220//! Closes the file, and before this it write the TAIL data
221//! @param rt the pointer to the RUN_TAIL data structure
222//
223bool DataWriteFits::Close(RUN_TAIL *rt)
224{
225 if (!fFile.IsOpen())
226 return false;
227
228 WriteFooter(rt);
229
230 fFile.Close();
231
232 return true;
233}
Note: See TracBrowser for help on using the repository browser.