CFEL - ASG Software Suite  2.5.0
CASS
lcls_converter.h
Go to the documentation of this file.
1 // Copyright (C) 2009, 2010, 2011 Lutz Foucar
2 
3 /**
4  * @file lcls_converter.h contains the converters to convert ccd and pnccd data
5  * to CASSEvent
6  *
7  * @author Lutz Foucar
8  */
9 
10 #ifndef _LCLSCONVERTER_H_
11 #define _LCLSCONVERTER_H_
12 
13 #include <map>
14 #include <vector>
15 #include <tr1/memory>
16 #include <utility>
17 
18 #include <QtCore/QMutex>
19 
20 #include "conversion_backend.h"
21 
22 
23 namespace cass
24 {
25 class CASSEvent;
26 namespace lclsid
27 {
28 class Key;
29 }
30 namespace pixeldetector
31 {
32 
33 /** Converter for pnCCD, CsPad and commercial CCD Data.
34  *
35  * @note that for pnCCD and CsPad data one must assing also the corresponding
36  * config, as the config is needed to be able to parse the data part.
37  *
38  * @cassttng Converter/LCLSPixelDetectors/{size} \n
39  * Number of user defined detectors to be pulled out of the xtc
40  * @cassttng Converter/LCLSPixelDetectors/\%id\%/{TypeName} \n
41  * The type of the detector. Only the following types are supported:
42  * - Id_pnCCDconfig : config for pnCCD data
43  * - Id_pnCCDframe : the pnCCD data
44  * - Id_Frame : Opal, TM6740 images
45  * - Id_CspadConfig: config for CsPad data
46  * - Id_CspadElement: the CsPad data
47  * - Id_Cspad2x2Element: the CsPad2x2 data
48  * @cassttng Converter/LCLSPixelDetectors/\%id\%/{DetectorName} \n
49  * Name of the detector. Default is invalid
50  * @cassttng Converter/LCLSPixelDetectors/\%id\%/{DetectorID} \n
51  * the id of the detector. Default is 0.
52  * @cassttng Converter/LCLSPixelDetectors/\%id\%/{DeviceName} \n
53  * Name of the detector device
54  * @cassttng Converter/LCLSPixelDetectors/\%id\%/{DeviceID} \n
55  * Id of the detector device
56  * @cassttng Converter/LCLSPixelDetectors/\%id\%/{CASSID} \n
57  * the Id the detector should get in the CASSEvent. One needs this
58  * number for further processing. Note that the config and the data
59  * part must have the same CASSID.
60  *
61  * see Converter::operator() for details about the functionality
62  *
63  * @author Lutz Foucar
64  * @author Stephan Kassemeyer
65  */
67 {
68 public:
69  /** create singleton if doesnt exist already */
71 
72  /** operator to convert the LCLS Data to CASSEvent
73  *
74  * retrieve the corresponding CASS key from the lcls xtc that are contained in
75  * the TypeId and Src (DetInfo) parts of the Xtc. Use the_LCLSToCASSId to do
76  * this.
77  *
78  * in case that xtc is a Id_pnCCDconfig:\n
79  * extract the version and create a config object toghether with this. Then
80  * copy the information from the xtc config to the config object. Then store
81  * the config object in the _pnccdConfigStore map.
82  *
83  * in case that xtc is a Id_pnCCDframe:\n
84  * the conversion will only be performed if there is an config present for
85  * the data. The config of version 1 does not contain information about the
86  * frame size, therefore one needs to set it manually. In version 2 these
87  * values are present, but sometimes there is a problem and one gets wrong
88  * data. To prevent this, a check for consistency is implemented that will
89  * output the wrong values and set them to the default values.\n
90  * The frame data of the pnccd is subdived into 4 segments in the lcls data
91  * format and one is provided with pointers to the beginning of the segments.
92  * The data of the segments is put into a linearised array.
93  * The frame looks as follows in the lab (when viwing into the beam)
94  @verbatim
95 
96  -----------
97 | | 2 | 3 | ^
98 | | D | B | |
99 | -----O----- |
100 | | 1 | 0 | |
101 v | C | A | |
102  -----------
103 
104  @endverbatim
105  * Here the numbers indicate the segment number in the lcls data.
106  * The data alignmet of the array is indicated with the arrows. This means
107  * that the slow increasing axis for segments 0 and 3 is going to the left and
108  * for segments 1 and 2 to the right. In order to read the segments fast, it
109  * is decided that one should read the segments data of segment 0 and 3 first
110  * and then 1 and 2, with the fast increasing axis being upward. This effectively
111  * rotates the frame in the cass representation 90 degress clockwise with
112  * respect to the lab. The resulting segments in CASS are therefore given in
113  * letters.\n
114  * To copy one now has to copy the first row of segment 0 (A in CASS coordinates)
115  * then copy the the first row of segment 3 (B in CASS coordinates). Then one
116  * copies 2nd row of segment 0 and 2nd row of segment 3. This keeps going
117  * until one has copied all rows of segment 0 and 3. Then one needs to copy
118  * the data from segment 1 reversely, meaning that one copies the last row in
119  * reverse direction. After that one does the same with segment 2. Then one
120  * reversly copies the 2nd to last row of segment 1 and the 2nd to last row of
121  * segment 2. This is done until all the data has been copied.\n
122  * This gives to following assignment from lcls segments to CASS coordinates:
123  * LCLS segment -> CASS Tiles \n
124  * 0 -> A \n
125  * 3 -> B \n
126  * 1 (reverse) -> C \n
127  * 2 (reverse) -> D \n
128  * If one wants to see the fram as it is oriented in the lab one has to rotate
129  * the data by 90 degrees counterclockwise. There is a processor that can
130  * do this.\n
131  * While copying the data one has to ignore the upper two bits of the data.
132  *
133  * in case that xtc is a Id_Frame:\n
134  * the frame data of the lcls is just copied to the detectors frame. The
135  * alignment is already like it is within CASS as a linearised array of pixels
136  * with x being the fast increasing axis. One has to substract the offset from
137  * all pixels, which is done during the copying. The first 8 pixels of the
138  * frame contain status information and are therefore set to the same value
139  * that the ninth pixel has.
140  *
141  * in case that xtc is a CsPad:\n
142  * the data is layed out in the xtc in quadrants. Each quadrant contains 8
143  * segments, which results in a total sum of 32 segments. The 8 segments of
144  * each quadrant are stored in a linearized array where the fast changing axis
145  * is along the x-axis. Each segment consits of 2*194 pixels along the x axis and
146  * 185 pixels along the y axis. The data is copied into a linearized array where
147  * the segments of each quadrant are aligned on top of each other like follows:
148 @verbatim
149  \
150  +-------------+ |
151  | 31 | |
152  +-------------+ |
153  | 30 | } quadrant 3
154  +-------------+ |
155  | 29 | |
156  +-------------+ |
157  . .
158  . .
159  . .
160  +-------------+ |
161  | 02 | |
162  +-------------+ |
163 ^ | 01 | } quadrant 0
164 | +-------------+ |
165 y | 00 | |
166 | +-------------+ |
167 +---x---> /
168 @endverbatim
169  *
170  * in case that xtc is a CsPad2x2:\n
171  * the data from a CsPad2x2 is almost the same as from a regular CsPad, but
172  * much easier. The data consists of one block with a Header (same as CsPad)
173  * followed by a sequence of pairs. The first of the pair belongs to the first
174  * segement and the second to the second segment. In CASS they will be aligned
175  * like to segements of the cspad on top of each other:
176  *
177 @verbatim
178  +-------------+
179 ^ | second |
180 | +-------------+
181 y | first |
182 | +-------------+
183 +---x--->
184 @endverbatim
185  *
186  * @param xtc the part of the datagram that this converter is responsible for
187  * @param evt The CASSEvent that should store the information from the xtc.
188  */
189  void operator()(const Pds::Xtc* xtc, cass::CASSEvent* evt);
190 
191 private:
192  /** map that will map the LCLS key to the CASS key */
193  typedef std::map<lclsid::Key, int32_t> idmap_t;
194 
195  /** pair the typeid of the config with a shared pointer of the config */
196  typedef std::pair<uint32_t, std::vector<uint8_t> > config_t;
197 
198  /** map containing the detector id together with its configuration */
199  typedef std::map<int32_t, config_t> configStore_t;
200 
201  /** constructor
202  *
203  * set up the pds type ids that it is responsible for and creates the map
204  * that maps the lcls id to the cass key.
205  */
206  Converter();
207 
208  /** prevent copy construction */
209  Converter(const Converter&);
210 
211  /** prevent assignment */
212  Converter& operator=(const Converter&);
213 
214  /** the singleton container */
216 
217  /** singleton locker for mutithreaded requests */
218  static QMutex _mutex;
219 
220  /** map lcls id to cass id */
221  idmap_t _LCLSToCASSId;
222 
223  /** store for the configurations.
224  *
225  * Will store the version and the configuration itself in a pair
226  * and has the casskey as key.
227  */
228  configStore_t _configStore;
229 };
230 }//end namespace vmi
231 }//end namespace cass
232 
233 #endif
Event to store all LCLS Data.
Definition: cass_event.h:32
std::pair< uint32_t, std::vector< uint8_t > > config_t
pair the typeid of the config with a shared pointer of the config
std::map< lclsid::Key, int32_t > idmap_t
map that will map the LCLS key to the CASS key
file contains base class for all format converters
static QMutex _mutex
singleton locker for mutithreaded requests
configStore_t _configStore
store for the configurations.
void operator()(const Pds::Xtc *xtc, cass::CASSEvent *evt)
operator to convert the LCLS Data to CASSEvent
static ConversionBackend::shared_pointer _instance
the singleton container
std::map< int32_t, config_t > configStore_t
map containing the detector id together with its configuration
std::tr1::shared_ptr< ConversionBackend > shared_pointer
typedef
Converter for pnCCD, CsPad and commercial CCD Data.
Base class for Converters.
static ConversionBackend::shared_pointer instance()
create singleton if doesnt exist already
Converter & operator=(const Converter &)
prevent assignment
idmap_t _LCLSToCASSId
map lcls id to cass id