CFEL - ASG Software Suite  2.5.0
CASS
machine_data.h
Go to the documentation of this file.
1 //Copyright (C) 2010 Lutz Foucar
2 
3 /**
4  * @file machine_data.h file contains declaration of processors that
5  * extract information from the beamline and epics data.
6  *
7  * @author Lutz Foucar
8  */
9 
10 #ifndef _MACHINE_DATA_H_
11 #define _MACHINE_DATA_H_
12 
13 #include <string>
14 
15 #include "processor.h"
16 #include "cass_event.h"
17 
18 namespace cass
19 {
20 /** retrieval of beamline data.
21  *
22  * @PPList "120":Beamline data
23  *
24  * This processor will retrieve the requested Beamline Data from
25  * the cass event.
26  *
27  * @see Processor for a list of all commonly available cass.ini
28  * settings.
29  *
30  * @cassttng Processor/\%name\%/{VariableName}
31  * The name of the beamline data variable you are interested in.
32  * Default is "". Available values are:
33  * - FEE Gas Detector values
34  * - f_11_ENRC
35  * - f_12_ENRC
36  * - f_21_ENRC
37  * - f_22_ENRC
38  * - E-Beam values
39  * - EbeamCharge
40  * - EbeamL3Energy
41  * - EbeamLTUAngX
42  * - EbeamLTUAngY
43  * - EbeamLTUPosX
44  * - EbeamLTUPosY
45  * - EbeamPkCurrBC1
46  * - EbeamPkEnergyBC1
47  * - EbeamPkCurrBC2
48  * - EbeamPkEnergyBC2
49  * - EbeamUndAngX
50  * - EbeamUndAngY
51  * - EbeamUndPosX
52  * - EbeamUndPosY
53  * - Phase Cavity values
54  * - Charge1
55  * - Charge2
56  * - FitTime1
57  * - FitTime2
58  * - Ipimb values
59  * - %DetectorName%_Channel0
60  * - %DetectorName%_Channel1
61  * - %DetectorName%_Channel2
62  * - %DetectorName%_Channel3
63  * - IpmFex values
64  * - %DetectorName%_CorrectChannel0
65  * - %DetectorName%_CorrectChannel1
66  * - %DetectorName%_CorrectChannel2
67  * - %DetectorName%_CorrectChannel3
68  * - %DetectorName%_sum
69  * - %DetectorName%_xPos
70  * - %DetectorName%_yPos
71  *
72  * @author Lutz Foucar
73  */
74 class pp120 : public Processor
75 {
76 public:
77  /** constructor */
78  pp120(const name_t &);
79 
80  /** copy data from CASS event to histogram storage */
81  virtual void process(const CASSEvent&, result_t&);
82 
83  /** load the settings from cass.ini */
84  virtual void loadSettings(size_t);
85 
86 protected:
87  /** name of the variable in the beamline data */
88  std::string _varname;
89 };
90 
91 
92 
93 
94 
95 
96 
97 /** check whether event contains eventcode
98  *
99  * @PPList "121":Eventcode check
100  *
101  * This processor will check whether an eventcode is present in the event.
102  *
103  * @see Processor for a list of all commonly available cass.ini
104  * settings.
105  *
106  * @cassttng Processor/\%name\%/{EventCode}
107  * The EventCode to check for. Default is 0
108  *
109  * @author Lutz Foucar
110  */
111 class pp121 : public Processor
112 {
113 public:
114  /** constructor */
115  pp121(const name_t &);
116 
117  /** copy data from CASS event to histogram storage */
118  virtual void process(const CASSEvent&, result_t&);
119 
120  /** load the settings from cass.ini */
121  virtual void loadSettings(size_t);
122 
123 protected:
124  /** name of the variable in the beamline data */
125  size_t _eventcode;
126 };
127 
128 
129 
130 
131 
132 
133 
134 
135 
136 
137 /** retrieve the eventId from event
138  *
139  * @PPList "122":EventID retrival
140  *
141  *
142  * @see Processor for a list of all commonly available cass.ini
143  * settings.
144  *
145  * @cassttng Processor/\%name\%/{EventIDPart}
146  * The part of the event id that is of interest.
147  * The event id is a 64 bit value, but Processors can only return
148  * a float (32 bit) value. Therefore this allows to retrieve either the
149  * upper or lower 32 bit of the 64 bit variable.
150  * Default is 0, possible values are:
151  * - 0: Unambiguous. historically the default, don't use.
152  * - 1: the lower 32 bits of the id
153  * - 2: the upper 32 bits of the id.
154  * @author Lutz Foucar
155  */
156 class pp122 : public Processor
157 {
158 public:
159  /** constructor */
160  pp122(const name_t &);
161 
162  /** copy data from CASS event to histogram storage */
163  virtual void process(const CASSEvent&, result_t&);
164 
165  /** load the settings from cass.ini */
166  virtual void loadSettings(size_t);
167 
168 private:
169  /** define the part name */
170  enum {both, lower, upper};
171 
172  /** which part of the eventid should be retrieved */
173  int _part;
174 };
175 
176 
177 
178 
179 
180 
181 
182 
183 
184 
185 
186 
187 
188 
189 /** retrieve beamline spectrometer data
190  *
191  * @PPList "123": retrieve beamline spectrometer data
192  *
193  * @cassttng Processor/\%name\%/{SpectrometerName}
194  * The name of the spectrometer one is interested in. One needs to add
195  * either "_horiz" or "_vert" to the name to tell wether one wants to
196  * use the vertical or horizontal projection.
197  * @cassttng Processor/\%name\%/{Size}
198  * The size of the projection. Will defaulty be determined from the
199  * spectrometer name addition. If "horiz" its set to 1024, if its
200  * "vert" it is set to 256. Only set this when the default values are
201  * not working.
202  *
203  * @see Processor for a list of all commonly available cass.ini settings.
204  *
205  * @author Lutz Foucar
206  */
207 class pp123 : public Processor
208 {
209 public:
210  /** constructor */
211  pp123(const name_t &);
212 
213  /** copy data from CASS event to histogram storage */
214  virtual void process(const CASSEvent&, result_t&);
215 
216  /** load the settings from cass.ini */
217  virtual void loadSettings(size_t);
218 
219 private:
220  /** the name of the spectrometer to retrieve from the machine device */
221  std::string _specname;
222 };
223 
224 
225 
226 
227 
228 
229 
230 
231 
232 
233 
234 /** retrieval of Epics data.
235  *
236  * @PPList "130":Epics data
237  *
238  * This processor will retrieve the requested epics data from the cass-event.
239  *
240  * @see Processor for a list of all commonly available cass.ini
241  * settings.
242  *
243  * @cassttng Processor/\%name\%/{VariableName}
244  * The name of the epics data variable you are interested in.
245  * Default is "". If the EPICS variable is not part of the standart
246  * list, but contained in an additional list, you have to prepend
247  * the additional lists name to the epics variable. For a complete
248  * list of available variables, please look into the casslog, when
249  * the logging level is set to INFO
250  *
251  * @author Lutz Foucar
252  */
253 class pp130 : public Processor
254 {
255 public:
256  /** constructor */
257  pp130(const name_t &);
258 
259  /** copy data from CASS event to histogram storage */
260  virtual void process(const CASSEvent&, result_t&);
261 
262  /** load the settings from cass.ini */
263  virtual void loadSettings(size_t);
264 
265 protected:
266  /** name of the variable in the beamline data */
267  std::string _varname;
268 };
269 
270 
271 
272 
273 
274 
275 
276 
277 
278 
279 /** retrieve photonenergy.
280  *
281  * @PPList "230":Photon energy of Shot
282  *
283  * This processor will calculate the photonenergy from the BLD. Here is an
284  * email corrospondence from Andy Acquila and Anton Barty explaining where the
285  * calculation comes from:
286  *
287 @verbatim
288 Hi Benedikt,
289 
290 I wish I had a paper about the wakefield correction, however I can't find it
291 However below is an email from James (Jim) Welch to Mark Messerschmidt.
292 It contains matlab code that we copied for the correction. Also attached is a
293 plot from Anton of the effect of the correction as compared to the undulator
294 equation.
295 
296 Please let me know if you have any questions.
297 
298 Cheers,
299 Andy
300 
301 Marc,
302 
303 The formula I use calculates the resonant photon energy based on an estimate of
304 the electron beam energy at the first in-line undulator segment, and the K of
305 that segment.
306 
307 The energy estimate for the first in-line segment starts with the DL2 bend
308 energy, and on a shot by shot basis, adds a correction based on the DL2 bpms for
309 the incoming energy, a correction for the wakefield energy loss which depends on
310 the measured peak bunch current (averaged over 10 shots), and a correction for
311 the spontaneous energy loss due to emission from the undulator segments.
312 
313 The matlab code is below. We still have some problems coming up with good values
314 for wakeloss, especially if beam conditions are unusual. Also there may be a
315 slight shift between the resonant photon energy and the FEL peak of the
316 spectrum. Another factor that is uncertain is what exact value to use for the K
317 in the resonance formula. Any suggestions would be appreciated.
318 
319  - Jim
320 
321 
322 function photonEnergyeV = photonEnergyeV(DL2energyGeV,
323 peakCurrent, charge,K,xltu250, xltu450, display_output)
324 %
325 % photonEnergyeV = photonEnergyeV(DL2energyGeV,peakCurrent,charge,K,xltu25, xltu450, display_output)
326 %
327 % Return the resonant photon energy eV for the fundamental based on the peak
328 % current, DL2 beam energy, and K of first active segment, beam position in
329 % the two dogleg bpms.
330 %
331 % If no input arguments are present it will get the input from the machine
332 
333 % If no input, parameters are set actual machine parameters
334 if nargin==0
335  display_output = 0; % set to 1 to do displays
336 
337  % Get the present peak current
338  for q=1:10 % average over several reads
339  temp(q) = lcaGet('BLEN:LI24:886:BIMAX');
340  end
341  peakCurrent= mean(temp);
342 
343  % Get present charge in pC
344  charge = 1000*lcaGet('FBCK:BCI0:1:CHRGSP');
345 
346  % Get present beam energy in DL2
347  npts = 100;
348  [xltu250, xltu450 ] = bpmDoglegRead(npts);
349  if any([xltu250, xltu450]==0); % if bpms not reading, assume zero
350  xltu250=0; xltu450=0;
351  end
352  DL2energyGeV = energyCorrectDL2(xltu250, xltu450, display_output);
353  if display_output
354  display(['DL2 energy ' num2str(DL2energyGeV) 'GeV' ]);
355  end
356 end
357 
358 % Get the present taper configuration
359 taper = segmentTranslate;
360 
361 % Get total energy loss in each segment. Extracted segments have only wake
362 % loss
363 activeSegments = find(taper < 11); % these are active
364 energyLossPerSegment(1:33) = wakefield(peakCurrent, charge, display_output); % MeV loss per segment
365 energyLossPerSegment(activeSegments) = ...% add wakefield to active segments
366  energyLossPerSegment(activeSegments) + SRloss( DL2energyGeV, display_output);
367 
368 % Calculate energy profile [GeV]
369 energyProfile(1:33) = DL2energyGeV - LTUwakeLoss(peakCurrent,charge, display_output)/1000;
370 for q=1:33 % energyProfile represents average electron energy in each segment.
371  energyProfile(q) = energyProfile(q)...
372  - 0.001*sum(energyLossPerSegment(1:q)) - 0.0005*energyLossPerSegment(q);
373 end
374 
375 % Calculate the resonant photon energy of the first active segment)
376 for q=1:33
377  pvKACT{q,1} = sprintf('USEG:UND1:%d50:KACT',q);
378 end
379 if nargin==0
380  Kprofile = lcaGetSmart(pvKACT);
381 else
382  Kprofile = K*ones(33,1); % pretend they are all the same if K is supplied
383 end
384 photonEnergyeV = 8265.9 * ( energyProfile( activeSegments(1) ) / 13.64 )^2 *...
385  (1 + 3.5^2/2) /(1 + Kprofile( activeSegments(1) )^2 / 2 ) ;
386 if display_output
387  display(['1st harmonic photon energy: ', num2str(photonEnergyeV,'%5.0f') ' eV']);
388 end
389 
390 
391 function wakeLossPerSegment = wakefield(peakCurrent, charge, display_output)
392 % return the wake field induced energy loss per electron per segment
393 % Assume proportion to peak current.
394 % wakeLossPerSegment = 0.15 * peakCurrent/500; % MeV/segment, from Juhao 8/09
395 % if abs(peakCurrent) > 4000
396 % wakeLossPerSegment = 0.15 * 300/500; % MeV/segment, adjusted to match 20 pC meas 10/6/09
397 % end
398 
399 % Use Nuhn calculation for undulator
400 segmentLength = mean(diff(segmentCenters));
401 compressState = charge>25; % assume undercompressed for more than 25 pC, else overcompressed
402 wakeLossPerSegment = segmentLength * 0.001 *...
403  util_UndulatorWakeAmplitude(abs(peakCurrent)/1000, charge, compressState);
404 if display_output
405  display([ 'Wake loss/segment ' num2str(-wakeLossPerSegment,2) ' MeV']);
406 end
407 
408 function LTUwakeLoss = LTUwakeLoss(peakCurrent, charge, display_output)
409 % Add LTU loss per Novohatsky
410 LTUfactor = 7.8; % MeV loss for 20 pC 0.5 micron rms bunch length
411 peakCurrentRef = 20e-12 * 3e8/0.5e-6/sqrt(2*pi); % Amps of peak current for LTUfactor
412 LTUwakeLoss = LTUfactor * (peakCurrent/peakCurrentRef);% scale with peak current^2/Q
413 if display_output
414  display(['LTU wake loss ', num2str(LTUwakeLoss,2) ' MeV']);
415 end
416 
417 function SRlossPerSegment = SRloss(electronEnergy, display_output)
418 % returns energy loss per segment [MeV] from spontaneous radiation in MeV
419 SRlossPerSegment = 0.63 * (electronEnergy/13.64)^2;
420 if display_output
421  display(['SR loss/segment ', num2str(SRlossPerSegment,2) ' MeV']);
422 end
423 
424 % This function is not used but could be added
425 function DL2energyGeV = energyCorrectDL2(xltu250, xltu450, display_output)
426 % correctedEnergy = energyCorrectDL2(xltu250, xltu450)
427 %
428 % returns the "corrected" = measured energies for a set of BSA bpm readings based on
429 % DL2 bpm readings and the DL2 magnet strengths. Use an average of the last
430 % npts stored in BSA buffers
431 
432 bendEnergyGeV = lcaGetSmart('BEND:DMP1:400:BDES'); %use dump bend power supply
433 etax = .125 ; % [m] design value for dispersion at bpms in dogleg
434 DL2energyGeV = bendEnergyGeV + bendEnergyGeV*0.001*(xltu250(1,:)...
435  - xltu450(1,:))/(2*etax);
436 if display_output
437  display(['DL2 bend energy ' num2str(bendEnergyGeV) 'GeV' ]);
438 end
439 
440 function [xltu250, xltu450 ] = bpmDoglegRead(npts, display_output)
441 % Return the averaged dogleg2 bpm x readings from buffered data
442 pvBPM = {'BPMS:LTU1:250:XHSTBR'; 'BPMS:LTU1:450:XHSTBR'};
443 bpms = lcaGet(pvBPM, npts);
444 xltu250 = mean(bpms(1,:));
445 xltu450 = mean(bpms(2,:));
446 
447 
448 On Aug 10, 2011, at 5:52 AM, Anton Barty wrote:
449 
450 > Hi Benedikt
451 >
452 > At a conference right now, so no web access for papers.
453 > I'll cc' to Andy who may be able to dig up a paper online.
454 >
455 >
456 > The formulae came from LCLS machine physics, possibly via Marc Messerschmidt.
457 >
458 > To first order, it's the standard undulator equation - which requires such
459 > stuff as undulator K-factors (known from the undulator design and calibrations).
460 > This is the energy at which SASE lasing initiates. The formulae basically
461 > relate electron beam energy to
462 >
463 > You can find a summary of formulae here (in B.2 - undulator radiation)
464 > http://xdb.lbl.gov/Section2/Sec_2-1.html
465 >
466 > The other terms are corrections to the electron energy due to wakefield losses
467 > and the like and make for relatively small corrections (<1%) to the undulator
468 > energy.
469 >
470 @endverbatim
471  *
472  * @see Processor for a list of all commonly available cass.ini
473  * settings.
474  *
475  * @author Lutz Foucar
476  */
477 class pp230 : public Processor
478 {
479 public:
480  /** constructor */
481  pp230(const name_t &);
482 
483  /** calc the photonenergy from the bld */
484  virtual void process(const CASSEvent&, result_t&);
485 
486  /** load the settings from cass.ini */
487  virtual void loadSettings(size_t);
488 };
489 }//end namespace cass
490 
491 #endif
Event to store all LCLS Data.
Definition: cass_event.h:32
virtual void loadSettings(size_t)
load the settings from cass.ini
virtual void process(const CASSEvent &, result_t &)
copy data from CASS event to histogram storage
virtual void process(const CASSEvent &, result_t &)
calc the photonenergy from the bld
std::string _specname
the name of the spectrometer to retrieve from the machine device
Definition: machine_data.h:221
pp230(const name_t &)
constructor
virtual void process(const CASSEvent &, result_t &)
copy data from CASS event to histogram storage
file contains declaration of the CASSEvent
int _part
which part of the eventid should be retrieved
Definition: machine_data.h:173
retrieval of beamline data.
Definition: machine_data.h:74
virtual void loadSettings(size_t)
load the settings from cass.ini
virtual void loadSettings(size_t)
load the settings from cass.ini
virtual void process(const CASSEvent &, result_t &)
copy data from CASS event to histogram storage
pp130(const name_t &)
constructor
base class for processors.
Definition: processor.h:39
virtual void process(const CASSEvent &, result_t &)
copy data from CASS event to histogram storage
check whether event contains eventcode
Definition: machine_data.h:111
file contains processors baseclass declaration
virtual void loadSettings(size_t)
load the settings from cass.ini
pp120(const name_t &)
constructor
std::string _varname
name of the variable in the beamline data
Definition: machine_data.h:267
virtual void loadSettings(size_t)
load the settings from cass.ini
virtual void loadSettings(size_t)
load the settings from cass.ini
std::string _varname
name of the variable in the beamline data
Definition: machine_data.h:88
pp121(const name_t &)
constructor
virtual void process(const CASSEvent &, result_t &)
copy data from CASS event to histogram storage
retrieval of Epics data.
Definition: machine_data.h:253
retrieve photonenergy.
Definition: machine_data.h:477
retrieve the eventId from event
Definition: machine_data.h:156
pp122(const name_t &)
constructor
std::string name_t
define the name type
Definition: processor.h:46
size_t _eventcode
name of the variable in the beamline data
Definition: machine_data.h:125
pp123(const name_t &)
constructor
retrieve beamline spectrometer data
Definition: machine_data.h:207