CFEL - ASG Software Suite  2.5.0
CASS
achimcalibrator_hex.cpp
Go to the documentation of this file.
1 // Copyright (C) 2008-2011 Lutz Foucar
2 
3 /**
4  * @file achimcalibrator_hex.cpp file contains class that uses achims calibration
5  * capabilities
6  *
7  * @author Lutz Foucar
8  */
9 
10 #include <cmath>
11 #include <cassert>
12 
13 #include "achimcalibrator_hex.h"
14 
15 #include "resort64c.h"
16 #include "cass_settings.h"
17 #include "result.hpp"
18 #include "convenience_functions.h"
19 #include "log.h"
20 
21 using namespace cass;
22 using namespace cass::ACQIRIS;
23 using namespace std;
24 using namespace std::tr1;
25 
26 namespace cass
27 {
28 namespace ACQIRIS
29 {
30 namespace AchimCalibrator
31 {
32 
33 /** write the profile part of calibration data into an ini file
34  *
35  * extract the calibration data from the calibrators and write them into
36  * the requested ini file which will be handled by the QSettings object
37  *
38  * extract the profile data from the layer sum profiles, that later
39  * correct the timesum.
40  *
41  * @param s the QSettings object that handles the .ini file
42  * @param profile the profile that whos stuff needs to be written to the
43  * .ini file
44  *
45  * @author Lutz Foucar
46  */
47 void writeProfileData(QSettings &s, profile_class& profile)
48 {
49  const int size (profile.number_of_columns);
50  for (int i = 0; i < size; ++i)
51  {
52  s.setArrayIndex(i);
53  const double pos
54  (profile.get_bin_center_x(static_cast<double>(i)));
55  const double cor (profile.get_y(i));
56  s.setValue("Position",pos );
57  s.setValue("Correction",cor );
58  }
59 }
60 
61 /** write all calibration data into an ini file
62  *
63  * use the calibrators to extract the calibration data and then write that
64  * into the .ini file that is handled by a QSettings Object.
65  *
66  * First generate the time sum profiles and write the correction data that
67  * is contained in the profiles to the .ini file.
68  * Then use the created histogram of the detector to get the scalefactors
69  * and the w layer offset.
70  *
71  * @param s the QSettings object that handles the sorter/calibrator .ini
72  * file
73  * @param tsum_calibrator the timesum calibrator that hold infomration
74  * about the timesum calibration data
75  * @param scalefactor_calibrator the scalefactor calibrator that holds
76  * information about the scalefactor
77  * calibration data.
78  *
79  * @author Lutz Foucar
80  */
82  shared_ptr<sum_walk_calibration_class> tsum_calibrator,
83  shared_ptr<scalefactors_calibration_class> scalefactor_calibrator)
84 {
85  tsum_calibrator->generate_sum_walk_profiles();
86  if (tsum_calibrator->sumu_profile)
87  {
88  s.beginWriteArray("SumUCorrectionPoints");
89  writeProfileData(s,*tsum_calibrator->sumu_profile);
90  s.endArray();
91  }
92  if (tsum_calibrator->sumv_profile)
93  {
94  s.beginWriteArray("SumVCorrectionPoints");
95  writeProfileData(s,*tsum_calibrator->sumv_profile);
96  s.endArray();
97  }
98  if (tsum_calibrator->sumw_profile)
99  {
100  s.beginWriteArray("SumWCorrectionPoints");
101  writeProfileData(s,*tsum_calibrator->sumw_profile);
102  s.endArray();
103  }
104  scalefactor_calibrator->
105  do_auto_calibration(s.value("WLayerOffset",0).toDouble());
106  s.setValue("ScalefactorV",scalefactor_calibrator->best_fv);
107  s.setValue("ScalefactorW",scalefactor_calibrator->best_fw);
108  s.setValue("WLayerOffset",scalefactor_calibrator->best_w_offset);
109 }
110 
111 /** shift the values so that the timesum peaks around 0
112  *
113  * @param values The values that need to be shifted
114  * @param sums The sums that they need to be shifted by
115  *
116  * @author Achim Czasch
117  * @author Lutz Foucar
118  */
119 void shift_sum(vector<double> &values, const vector<pair<double,double> > &sums)
120 {
121  int direction(1);
122  const double dpOSumu = direction*sums[HexCalibrator::u].first * 0.5;
123  const double dpOSumv = direction*sums[HexCalibrator::v].first * 0.5;
124  const double dpOSumw = direction*sums[HexCalibrator::w].first * 0.5;
125  values[HexCalibrator::u1] += dpOSumu;
126  values[HexCalibrator::u2] += dpOSumu;
127  values[HexCalibrator::v1] += dpOSumv;
128  values[HexCalibrator::v2] += dpOSumv;
129  values[HexCalibrator::w1] += dpOSumw;
130  values[HexCalibrator::w2] += dpOSumw;
131 }
132 
133 /** shift the position
134  *
135  * when the image is not centered around 0 one can use this function to
136  * shift it to 0
137  *
138  * @param layer The vector containing all the layers signals
139  * @param center The center of the image in mm
140  * @param scalefactors The scalefactors for the layers
141  *
142  * @author Achim Czasch
143  * @author Lutz Foucar
144  */
145 void shift_pos(vector<double> &layer,
146  const pair<double,double> &center,
147  const vector<double> &scalefactors)
148 {
149  int direction(1);
150  const double offs_u (0.50*center.first/scalefactors[HexCalibrator::u]);
151  const double offs_v
152  (0.25*(center.first - center.second *sqrt(3))/scalefactors[HexCalibrator::v]);
153  const double offs_w
154  (0.25*(center.first + center.second *sqrt(3))/scalefactors[HexCalibrator::w]);
155 
156  layer[HexCalibrator::u1] += direction*offs_u;
157  layer[HexCalibrator::u1] -= direction*offs_u;
158  layer[HexCalibrator::v2] += direction*offs_v;
159  layer[HexCalibrator::v2] -= direction*offs_v;
160  layer[HexCalibrator::w1] += direction*offs_w;
161  layer[HexCalibrator::w2] -= direction*offs_w;
162 }
163 
164 /** shift the w-layer
165  *
166  * use this function to align the w-layer to the u and v layer.
167  *
168  * @param w1 The first signal on the w-layer
169  * @param w2 The second signal on the w-layer
170  * @param w_offset The offset of the w-layer with respect to the u and v
171  * layers
172  *
173  * @author Achim Czasch
174  * @author Lutz Foucar
175  */
176 void shift_wLayer(double &w1, double &w2, const double w_offset)
177 {
178  int direction(1);
179  const double w_offset_shift = direction * w_offset * 0.5;
180  w1 += w_offset_shift;
181  w2 -= w_offset_shift;
182 }
183 }//end namespace achimcalibrator
184 }//end namespace acqiris
185 }//end namespace cass
186 
187 
189  : Processor(name),
190  _timesums(3,make_pair(0,0)),
191  _scalefactors(2,1)
192 {
193  loadSettings(0);
194 }
195 
197 {
198  _calibwritten = false;
199  setupGeneral();
200  if (!setupCondition())
201  return;
202  CASSSettings settings;
203  settings.beginGroup("Processor");
205  _detector = loadDelayDet(settings,161,name());
206  _ratio = settings.value("RatioFullBins",0.9).toDouble();
207  const DetectorBackend &rawdet(
208  HelperAcqirisDetectors::instance(_detector)->detector());
209  const DelaylineDetector &d (dynamic_cast<const DelaylineDetector&>(rawdet));
210  if(!d.isHex())
211  throw invalid_argument("HexCalibrator::loadSettings: Error The Hex-Sorter cannot work on '" +
212  d.name() + "' which is not a Hex Detector.");
213  CASSSettings s;
214  s.beginGroup("AcqirisDetectors");
216  s.beginGroup("HexSorting");
217  _groupname = s.group();
218  assert(_timesums.size() == 3);
219  _timesums[u] = make_pair(s.value("TimeSumU",100).toDouble(),
220  s.value("TimeSumUWidth",0).toDouble());
221  _timesums[v] = make_pair(s.value("TimeSumV",100).toDouble(),
222  s.value("TimeSumVWidth",0).toDouble());
223  _timesums[w] = make_pair(s.value("TimeSumW",100).toDouble(),
224  s.value("TimeSumWWidth",0).toDouble());
225  _center = make_pair(s.value("CenterX",0).toDouble(),
226  s.value("CenterY",0).toDouble());
227  assert(_scalefactors.size() == 3);
228  _scalefactors[u] = s.value("ScalefactorU",1).toDouble();
229  _maxRuntime = s.value("MaxRuntime",130).toDouble();
230  _calibrationFilename = s.value("SettingsFilename").toString().toStdString();
233  /** @todo make sure the below works */
234  hexsettings.beginGroup(_groupname);
235  _wLayerOffset = hexsettings.value("WLayerOffset",0).toDouble();
236  _scalefactors[v] = hexsettings.value("ScalefactorV",1).toDouble();
237  _scalefactors[w] = hexsettings.value("ScalefactorW",1).toDouble();
238  s.endGroup();
240  shared_ptr<sum_walk_calibration_class>(new sum_walk_calibration_class(49,true,_maxRuntime,0.1));
242  shared_ptr<scalefactors_calibration_class>(new scalefactors_calibration_class(true,
243  _maxRuntime,
244  _maxRuntime*0.78,
245  _scalefactors[u],
246  _scalefactors[v],
247  _scalefactors[w]));
249  Log::add(Log::INFO,"Processor '" + name() + "' calibrates the hex detector '" +
250  _detector + "'. Condition is '" + _condition->name() + "'");
251 }
252 
254 {
255  DetectorBackend &rawdet(
256  HelperAcqirisDetectors::instance(_detector)->detector(evt));
257  DelaylineDetector &d (dynamic_cast<DelaylineDetector&>(rawdet));
258  vector<double> values(7);
259  values[mcp] = d.mcp().firstGood();
260  values[u1] = d.layers()['U'].wireends()['1'].firstGood();
261  values[u2] = d.layers()['U'].wireends()['2'].firstGood();
262  values[v1] = d.layers()['V'].wireends()['1'].firstGood();
263  values[v2] = d.layers()['V'].wireends()['2'].firstGood();
264  values[w1] = d.layers()['W'].wireends()['1'].firstGood();
265  values[w2] = d.layers()['W'].wireends()['2'].firstGood();
266 
267  vector<double> layer(3);
268  layer[u] = values[u1] - values[u2];
269  layer[v] = values[v1] - values[v2];
270  layer[w] = values[w1] - values[w2];
271 
272  vector<bool> layerChecksum(3);
273  layerChecksum[u] = abs(values[u1]+values[u2]-2.*values[mcp] - _timesums[u].first) < _timesums[u].second;
274  layerChecksum[v] = abs(values[v1]+values[v2]-2.*values[mcp] - _timesums[v].first) < _timesums[v].second;
275  layerChecksum[w] = abs(values[w1]+values[w2]-2.*values[mcp] - _timesums[w].first) < _timesums[w].second;
276 
280 
281  if (layerChecksum[u] && layerChecksum[v] && layerChecksum[w])
282  _scalefactor_calibrator->feed_calibration_data(layer[u],
283  layer[v],
284  layer[w],
285  layer[w]-_wLayerOffset);
286  _tsum_calibrator->fill_sum_histograms(values[u1],
287  values[u2],
288  values[v1],
289  values[v2],
290  values[w1],
291  values[w2],
292  values[mcp]);
293  /** write the parameters when we are told that we can or our set threshold is
294  * reached.but only if it has not been written yet
295  */
296  const float ratio(_scalefactor_calibrator->get_ratio_of_full_bins());
297  if (!_calibwritten)
298  {
299  if (_scalefactor_calibrator->map_is_full_enough() ||
300  ratio > _ratio)
301  {
302  _calibwritten = true;
305  /** @todo check whether one can set the goup this way */
306  hexsettings.beginGroup(_groupname);
308  hexsettings.endGroup();
309  }
310  }
311  res.setValue(ratio);
312 }
CachedList::item_type result_t
define the results
Definition: processor.h:52
setArrayIndex(int i)
Event to store all LCLS Data.
Definition: cass_event.h:32
virtual void createHistList(result_t::shared_pointer result)
create result list.
Definition: processor.cpp:79
direction
enum for easier code
std::tr1::shared_ptr< scalefactors_calibration_class > _scalefactor_calibrator
pointer to scalfactor calibrator
const name_t name() const
retrieve the name of this processor
Definition: processor.h:167
Settings for CASS.
Definition: cass_settings.h:30
std::tr1::shared_ptr< self_type > shared_pointer
a shared pointer of this class
Definition: result.hpp:323
std::vector< double > _scalefactors
the scalefactors
file contains class that uses achims calibration capabilities
QString _groupname
the group name of the cass settings for this calibrator
void shift_wLayer(double &w1, double &w2, const double w_offset)
shift the w-layer
STL namespace.
things written only at end of run H5Dump ProcessorSummary size
result classes
beginWriteArray(const QString &prefix, int size=-1)
SignalProducer & mcp()
retrieve the mcp
Definition: tof_detector.h:67
setValue(const QString &key, const QVariant &value)
static void add(Level level, const std::string &line)
add a string to the log
Definition: log.cpp:31
void setValue(const_reference value)
assign the result container to a value
Definition: result.hpp:543
std::pair< double, double > _center
the center of the image
fromStdString(const std::string &str)
ACQIRIS::HelperAcqirisDetectors::helperinstancesmap_t::key_type _detector
The detector we are there for.
std::string _calibrationFilename
the .ini filename for the sorting information
anodelayers_t & layers()
return the layers
base class for processors.
Definition: processor.h:39
std::vector< std::pair< double, double > > _timesums
the timesums and their width
file contains declaration of classes and functions that help other processors to do their job...
double _maxRuntime
the maximum runtime
bool _calibwritten
flag to tell wether the calibration has been written already
HexCalibrator(const name_t &name)
constructor
void process(const CASSEvent &evt, result_t &res)
create the calibration
std::string loadDelayDet(CASSSettings &s, int ppNbr, const std::string &key)
load detector from file
value(const QString &key, const QVariant &defaultValue=QVariant()
const std::string name() const
return the detector name
double _wLayerOffset
the w-layer offset
bool isHex() const
retrieve the anode type property
void loadSettings(size_t)
load the detector analyzers settings from .ini file
double firstGood(const std::pair< double, double > &range)
returns the time of the first peak in the time range
void setupGeneral()
general setup of the processor
Definition: processor.cpp:85
double _ratio
the ratio to check whether the calibration can be started
void writeCalibData(QSettings &s, shared_ptr< sum_walk_calibration_class > tsum_calibrator, shared_ptr< scalefactors_calibration_class > scalefactor_calibrator)
write all calibration data into an ini file
std::tr1::shared_ptr< sum_walk_calibration_class > _tsum_calibrator
the time sum calibrator
void writeProfileData(QSettings &s, profile_class &profile)
write the profile part of calibration data into an ini file
file contains specialized class that do the settings for cass
Base class for all Detectors attached to an Acqiris Instrument.
shared_pointer _condition
pointer to the processor that will contain the condition
Definition: processor.h:277
void shift_sum(vector< double > &values, const vector< pair< double, double > > &sums)
shift the values so that the timesum peaks around 0
void shift_pos(vector< double > &layer, const pair< double, double > &center, const vector< double > &scalefactors)
shift the position
Electron detector
Definition: hdf5-input.ini:62
bool setupCondition(bool defaultConditionType=true)
setup the condition.
Definition: processor.cpp:94
std::string name_t
define the name type
Definition: processor.h:46
contains a logger for cass
beginGroup(const QString &prefix)