CFEL - ASG Software Suite  2.5.0
CASS
acqiris_converter.cpp
Go to the documentation of this file.
1 //Copyright (C) 2009, 2010, 2011 Lutz Foucar
2 
3 /**
4  * @file acqiris_converter.cpp file contains the definition of the converter
5  * for the xtc containing acqiris data.
6  *
7  * @author Lutz Foucar
8  */
9 
10 #include <cassert>
11 
12 #include "acqiris_converter.h"
13 #include "cass_event.h"
14 #include "log.h"
15 #include "cass_settings.h"
16 #include "lcls_key.hpp"
17 
18 #include "pdsdata/xtc/Xtc.hh"
19 #include "pdsdata/xtc/TypeId.hh"
20 #include "pdsdata/xtc/DetInfo.hh"
21 #include "pdsdata/acqiris/ConfigV1.hh"
22 #include "pdsdata/acqiris/DataDescV1.hh"
23 #include "pdsdata/xtc/Src.hh"
24 
25 using namespace cass;
26 using namespace ACQIRIS;
27 using namespace std;
28 using namespace Pds;
29 using namespace lclsid;
30 
31 // =================define static members =================
34 
36 {
37  QMutexLocker locker(&_mutex);
38  if(!_instance)
39  {
41  }
42  return _instance;
43 }
44 // ========================================================
45 
47 {
48  _pdsTypeList.push_back(TypeId::Id_AcqConfig);
49  _pdsTypeList.push_back(TypeId::Id_AcqWaveform);
50 
51  CASSSettings s;
52  s.beginGroup("Converter");
53 
54  int size = s.beginReadArray("LCLSAcqirisDevices");
55  for (int i = 0; i < size; ++i)
56  {
57  s.setArrayIndex(i);
58  string type(s.value("TypeName","Invalid").toString().toStdString());
59  TypeId::Type typeID(TypeId::NumberOf);
60  for (int i(0); i < TypeId::NumberOf; ++i)
61  if (TypeId::name(static_cast<TypeId::Type>(i)) == type)
62  {
63  typeID = static_cast<TypeId::Type>(i);
64  break;
65  }
66 
67  uint32_t detID(s.value("DetectorID",0).toUInt());
68  string detname(s.value("DetectorName","Invalid").toString().toStdString());
69  DetInfo::Detector detnameID(DetInfo::NumDetector);
70  for (int i(0); i < DetInfo::NumDetector; ++i)
71  if (DetInfo::name(static_cast<DetInfo::Detector>(i)) == detname)
72  {
73  detnameID = static_cast<DetInfo::Detector>(i);
74  break;
75  }
76 
77  uint32_t devID(s.value("DeviceID",0).toUInt());
78  string devname(s.value("DeviceName","Invalid").toString().toStdString());
79  DetInfo::Device devnameID(DetInfo::NumDevice);
80  for (int i(0); i < DetInfo::NumDevice; ++i)
81  if (DetInfo::name(static_cast<DetInfo::Device>(i)) == devname)
82  {
83  devnameID = static_cast<DetInfo::Device>(i);
84  break;
85  }
86 
87  /** skip if the either name has not been set or not correctly set */
88  if (typeID == TypeId::NumberOf ||
89  detnameID == DetInfo::NumDetector ||
90  devnameID == DetInfo::NumDevice)
91  continue;
92 
93  Key key(typeID, detnameID, detID, devnameID, devID);
94  _LCLSToCASSId[key] = s.value("CASSID",0).toInt();
95  }
96  s.endArray();
97 }
98 
99 void Converter::operator()(const Pds::Xtc* xtc, CASSEvent* evt)
100 {
101  /** skip if there is no corresponding cass key for that xtc */
102  idmap_t::key_type lclskey(xtc->contains.id(), xtc->src.phy());
103  idmap_t::iterator lclsmapIt(_LCLSToCASSId.find(lclskey));
104  if (lclsmapIt == _LCLSToCASSId.end())
105  {
106  Log::add(Log::DEBUG0, string("Acqiris::Converter::operator(): There is no corresponding cass key for : '") +
107  TypeId::name(xtc->contains.id()) + "'(" + toString(xtc->contains.id()) +
108  "), '" + DetInfo::name(reinterpret_cast<const DetInfo*>(&xtc->src)->detector()) +
109  "'(" + toString(reinterpret_cast<const DetInfo*>(&xtc->src)->detId()) +
110  "), '" + DetInfo::name(reinterpret_cast<const DetInfo*>(&xtc->src)->device()) +
111  "'(" + toString(reinterpret_cast<const DetInfo*>(&xtc->src)->devId()) +
112  ")");
113  return;
114  }
115  const idmap_t::mapped_type &casskey(lclsmapIt->second);
116 
117  /** check whether xtc is a configuration or a event **/
118  switch (xtc->contains.id())
119  {
120 
121  case (Pds::TypeId::Id_AcqConfig) :
122  {
123  /** use the right version to extract the info */
124  unsigned version = xtc->contains.version();
125  switch (version)
126  {
127  case 1:
128  {
129  /** get the config **/
130  const Pds::Acqiris::ConfigV1 &config =
131  *reinterpret_cast<const Pds::Acqiris::ConfigV1*>(xtc->payload());
132  //extract how many channels are in the acqiris device//
133  _configStore[casskey] = config.nbrChannels();
134  Log::add(Log::INFO, string("AcqirisConverter: Instrument ") +
135  TypeId::name(xtc->contains.id()) + "'(" + toString(xtc->contains.id()) +
136  "), '" + DetInfo::name(reinterpret_cast<const DetInfo*>(&xtc->src)->detector()) +
137  "'(" + toString(reinterpret_cast<const DetInfo*>(&xtc->src)->detId()) +
138  "), '" + DetInfo::name(reinterpret_cast<const DetInfo*>(&xtc->src)->device()) +
139  "'(" + toString(reinterpret_cast<const DetInfo*>(&xtc->src)->devId()) +
140  "); SampleInterval '" + toString(config.horiz().sampInterval()) +
141  "' NbrSamples '" + toString(config.horiz().nbrSamples()) +
142  "' NbrSegments '" + toString(config.horiz().nbrSegments()) +
143  "' DelayTime '" + toString(config.horiz().delayTime()) +
144  "' TrigCoupling '" + toString(config.trig().coupling()) +
145  "' TrigInput '" + toString(config.trig().input()) +
146  "' TrigSlope '" + toString(config.trig().slope()) +
147  "' TrigLevel '" + toString(config.trig().level()) +
148  "' NbrChannels '" + toString(config.nbrChannels()) +
149  "'");
150  for (size_t i(0); i<_configStore[casskey]; ++i)
151  {
152  Log::add(Log::INFO, string("AcqirisConverter: Instrument ") +
153  TypeId::name(xtc->contains.id()) + "'(" + toString(xtc->contains.id()) +
154  "), '" + DetInfo::name(reinterpret_cast<const DetInfo*>(&xtc->src)->detector()) +
155  "'(" + toString(reinterpret_cast<const DetInfo*>(&xtc->src)->detId()) +
156  "), '" + DetInfo::name(reinterpret_cast<const DetInfo*>(&xtc->src)->device()) +
157  "'(" + toString(reinterpret_cast<const DetInfo*>(&xtc->src)->devId()) +
158  "); Channel '" + toString(i) +
159  "': Gain '" + toString(config.vert(i).slope()) +
160  "' Offset '" + toString(config.vert(i).offset()) +
161  "' FullScale '" + toString(config.vert(i).fullScale()) +
162  "' Bandwidth '" + toString(config.vert(i).bandwidth()) +
163  "' Coupling '" + toString(config.vert(i).coupling()) +
164  "'");
165  }
166  break;
167  }
168  default:
169  throw runtime_error("Unsupported acqiris configuration version '" +
170  toString(version) + "'");
171  break;
172  }
173  break;
174  }
175 
176  /** if it is a event then extract all information from the event **/
177  case (TypeId::Id_AcqWaveform):
178  {
179  /** extract the datadescriptor (waveform etc) from the xtc **/
180  const Acqiris::DataDescV1 *datadesc =
181  reinterpret_cast<const Acqiris::DataDescV1*>(xtc->payload());
182  /** retrieve reference to the right acqiris instrument **/
183  Device &dev(dynamic_cast<Device&>(*(evt->devices()[CASSEvent::Acqiris])));
184  Instrument &instr(dev.instruments()[casskey]);
185  /** write the event id of the data to the instrument */
186  instr.id() = evt->id();
187  /** retrieve a reference to the channel container of the instrument **/
188  Instrument::channels_t &channels(instr.channels());
189  /** resize the channel vector to how many channels are in the device **/
190  const size_t nChans(_configStore[casskey]);
191  channels.resize(nChans);
192  /** copy the channel values from the datadescriptor **/
193  for (size_t i(0); i < nChans; ++i)
194  {
195  /** get a reference instead of a pointer for easier writing **/
196  const Acqiris::DataDescV1 &dd(*datadesc);
197  /** retrieve a reference to the channel we are working on **/
198  Channel &chan(channels[i]);
199  /** extract the infos from the datadesc **/
200  chan.channelNbr() = i;
201  chan.horpos() = dd.timestamp(0).horPos();
202  chan.offset() = dd.offset();
203  chan.gain() = dd.gain();
204  chan.sampleInterval() = dd.sampleInterval();
205  /** get pointer to waveform in the datadescriptor **/
206  const short* wf = dd.waveform();
207  /** need to shift the pointer so that it looks at the first real point of
208  * the waveform
209  */
210  wf += dd.indexFirstPoint();
211  /** retrieve a reference to waveform within the cassevent channel **/
212  Channel::waveform_t &waveform = chan.waveform();
213  /** resize cassevent waveform container to the correct size **/
214  const size_t nSamples(dd.nbrSamplesInSeg());
215  waveform.resize(nSamples);
216  //Log::add(Log::DEBUG4, string("AcqirisConverter: Instrument ") +
217  // TypeId::name(xtc->contains.id()) + "'(" + toString(xtc->contains.id()) +
218  // "), '" + DetInfo::name(reinterpret_cast<const DetInfo*>(&xtc->src)->detector()) +
219  // "'(" + toString(reinterpret_cast<const DetInfo*>(&xtc->src)->detId()) +
220  // "), '" + DetInfo::name(reinterpret_cast<const DetInfo*>(&xtc->src)->device()) +
221  // "'(" + toString(reinterpret_cast<const DetInfo*>(&xtc->src)->devId()) +
222  // "); Channel '" + toString(i) +
223  // "': Gain '" + toString(dd.gain()) +
224  // "' Offset '" + toString(dd.offset()) +
225  // "' idxFirstPoint '" + toString(dd.indexFirstPoint()) +
226  // "' SampleInterval '" + toString(dd.sampleInterval()) +
227  // "' NbrSamplesInSeg '" + toString(nSamples) +
228  // "'");
229  /** copy the datapoints of the waveform
230  * the byte order has to be swapped for some reason that still has
231  * to be determined
232  */
233  for (size_t iWave=0;iWave<nSamples;++iWave)
234  waveform[iWave] = (wf[iWave]&0x00ff<<8) | (wf[iWave]&0xff00>>8);
235 
236  /** iterate to next channel */
237  datadesc = datadesc->nextChannel();
238  }
239  break;
240  }
241  default:
242  throw logic_error(string("ACQIRIS::Converter(): xtc type '") +
243  Pds::TypeId::name(xtc->contains.id()) +
244  "' is not handled by Acqiris Converter");
245  break;
246  }
247 }
std::vector< int16_t > waveform_t
define the waveform
Definition: channel.hpp:35
setArrayIndex(int i)
definition of front detector[PixelDetectors] FrontPnCCD Detector
Event to store all LCLS Data.
Definition: cass_event.h:32
static QMutex _mutex
singleton locker for mutithreaded requests
contains the lcls keys
waveform_t & waveform()
setter
Definition: channel.hpp:105
An Acqiris Instrument.
file contains declaration of the CASSEvent
Settings for CASS.
Definition: cass_settings.h:30
STL namespace.
double & sampleInterval()
setter
Definition: channel.hpp:103
things written only at end of run H5Dump ProcessorSummary size
The Acqiris device.
static void add(Level level, const std::string &line)
add a string to the log
Definition: log.cpp:31
beginReadArray(const QString &prefix)
devices_t & devices()
setters
Definition: cass_event.h:66
double & horpos()
setter
Definition: channel.hpp:101
id_t & id()
setters
Definition: cass_event.h:64
std::string toString(const Type &t)
convert any type to a string
Definition: cass.h:63
double & offset()
setter
Definition: channel.hpp:102
std::tr1::shared_ptr< ConversionBackend > shared_pointer
typedef
void operator()(const Pds::Xtc *, CASSEvent *)
takes the xtc and copies the data to cassevent
value(const QString &key, const QVariant &defaultValue=QVariant()
A Channel of an Acqiris Instrument.
Definition: channel.hpp:31
std::vector< Channel > channels_t
a vector of Channels
file contains specialized class that do the settings for cass
double & gain()
setter
Definition: channel.hpp:104
file contains the declaration of the converter for the xtc containing acqiris data.
Acqiris Converter.
static ConversionBackend::shared_pointer _instance
the singleton container
size_t & channelNbr()
setter
Definition: channel.hpp:106
contains a logger for cass
static ConversionBackend::shared_pointer instance()
create singleton if doesnt exist already
beginGroup(const QString &prefix)