00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "TimeTool/Setup.h"
00017
00018
00019
00020
00021 #include <fstream>
00022 #include "psalg/psalg.h"
00023
00024
00025
00026
00027
00028
00029 #include "MsgLogger/MsgLogger.h"
00030 #include "PSEvt/EventId.h"
00031 #include "psddl_psana/evr.ddl.h"
00032 #include "psddl_psana/lusi.ddl.h"
00033 #include "psddl_psana/camera.ddl.h"
00034 #include "psddl_psana/opal1k.ddl.h"
00035
00036 #include <iomanip>
00037 #include <fstream>
00038 #include <sstream>
00039
00040
00041
00042
00043
00044
00045 using namespace TimeTool;
00046 PSANA_MODULE_FACTORY(Setup)
00047
00048
00049
00050
00051
00052 namespace TimeTool {
00053
00054
00055
00056
00057 Setup::Setup (const std::string& name)
00058 : Module(name), m_hacf(0)
00059 {
00060
00061 m_get_key = configSrc("get_key","DetInfo(:Opal1000)");
00062
00063 m_eventcode_nobeam = config("eventcode_nobeam",162);
00064
00065 m_eventcode_skip = config("eventcode_skip");
00066
00067 m_ipm_get_key = configStr("ipm_get_key");
00068 m_ipm_beam_threshold = config("ipm_beam_threshold",0.);
00069
00070 m_projectX = config("projectX",true);
00071 m_proj_cut = config("proj_cut" ,0);
00072
00073 #define initList(l) \
00074 std::vector<unsigned> l = configList(#l);
00075
00076 initList(sig_roi_x)
00077 initList(sig_roi_y)
00078 initList(sb_roi_x)
00079 initList(sb_roi_y)
00080 #undef initList
00081
00082 m_frame_roi[0] = m_frame_roi[1] = 0;
00083
00084 if (sb_roi_x.size() && sb_roi_y.size()) {
00085 if (m_projectX) {
00086 if (sb_roi_x[0]!=sig_roi_x[0] ||
00087 sb_roi_x[1]!=sig_roi_x[1]) {
00088 sb_roi_x[0] = sig_roi_x[0];
00089 sb_roi_x[1] = sig_roi_x[1];
00090 MsgLog(name, warning,
00091 name << ": Signal and sideband roi x ranges differ. Setting sideband roi to signal.");
00092 }
00093 if ((sb_roi_y[1]-sb_roi_y[0]) != (sig_roi_y[1]-sig_roi_y[0])) {
00094 MsgLog(name, fatal,
00095 name << ": Signal and sideband roi y range sizes differ.");
00096 }
00097 }
00098 else {
00099 if (sb_roi_y[0]!=sig_roi_y[0] ||
00100 sb_roi_y[1]!=sig_roi_y[1]) {
00101 sb_roi_y[0] = sig_roi_y[0];
00102 sb_roi_y[1] = sig_roi_y[1];
00103 MsgLog(name, warning,
00104 name << ": Signal and sideband roi y ranges differ. Setting sideband roi to signal.");
00105 }
00106 if ((sb_roi_x[1]-sb_roi_x[0]) != (sig_roi_x[1]-sig_roi_x[0])) {
00107 MsgLog(name, fatal,
00108 name << ": Signal and sideband roi x range sizes differ.");
00109 }
00110 }
00111 m_sb_roi_lo[0] = sb_roi_y[0];
00112 m_sb_roi_hi[0] = sb_roi_y[1];
00113 m_sb_roi_lo[1] = sb_roi_x[0];
00114 m_sb_roi_hi[1] = sb_roi_x[1];
00115 }
00116 else {
00117 m_sb_roi_lo[0] = m_sb_roi_hi[0] = 0;
00118 m_sb_roi_lo[1] = m_sb_roi_hi[1] = 0;
00119 }
00120
00121 m_sig_roi_lo[0] = sig_roi_y[0];
00122 m_sig_roi_hi[0] = sig_roi_y[1];
00123 m_sig_roi_lo[1] = sig_roi_x[0];
00124 m_sig_roi_hi[1] = sig_roi_x[1];
00125
00126 m_sb_avg_fraction = config("sb_avg_fraction",0.05);
00127 m_ref_avg_fraction = config("ref_avg_fraction",1.);
00128
00129 std::string ref_load = configStr("ref_load");
00130 if (!ref_load.empty()) {
00131 std::ifstream s(ref_load.c_str());
00132 std::vector<double> ref;
00133 while(s.good()) {
00134 double v;
00135 s >> v;
00136 ref.push_back(v);
00137 }
00138
00139 m_ref = make_ndarray<double>(ref.size());
00140 for(unsigned i=0; i<ref.size(); i++)
00141 m_ref[i] = ref[i];
00142
00143 if (m_ref.size()==0) {
00144 MsgLog(name, fatal,
00145 name << ": Reference load failed");
00146 }
00147 }
00148 else {
00149 MsgLog(name, fatal,
00150 name << ": No ref_load parameter provided");
00151 }
00152
00153 m_pedestal = 0;
00154
00155 unsigned ndump = config("dump",0);
00156 for(unsigned i=0; i<ndump; i++)
00157 m_hdump.push_back(DumpH());
00158 }
00159
00160
00161
00162
00163 Setup::~Setup ()
00164 {
00165 }
00166
00167
00168 void
00169 Setup::beginJob(Event& evt, Env& env)
00170 {
00171 {
00172 shared_ptr<Psana::Opal1k::ConfigV1> config =
00173 env.configStore().get(m_get_key);
00174 if (config.get()) {
00175 m_pedestal = config->output_offset();
00176 MsgLog(name(), info,
00177 name() << ": found configured offset of " << m_pedestal);
00178 }
00179 }
00180
00181 {
00182 shared_ptr<Psana::Camera::FrameFexConfigV1> config =
00183 env.configStore().get(m_get_key);
00184 if (config.get() &&
00185 config->forwarding()==Psana::Camera::FrameFexConfigV1::RegionOfInterest) {
00186 MsgLog(name(), info,
00187 name() << ": found configured roi of ["
00188 << config->roiBegin().column() << ','
00189 << config->roiEnd ().column() << "] ["
00190 << config->roiBegin().row() << ','
00191 << config->roiEnd ().row() << "]");
00192
00193
00194 #if 0
00195 unsigned roi_y = config->roiBegin().row();
00196 m_frame_roi [0] = roi_y;
00197 m_sig_roi_lo[0] -= roi_y;
00198 m_sig_roi_hi[0] -= roi_y;
00199 m_sb_roi_lo [0] -= roi_y;
00200 m_sb_roi_hi [0] -= roi_y;
00201
00202 unsigned roi_x = config->roiBegin().column();
00203 m_frame_roi [1] = roi_x;
00204 m_sig_roi_lo[1] -= roi_x;
00205 m_sig_roi_hi[1] -= roi_x;
00206 m_sb_roi_lo [1] -= roi_x;
00207 m_sb_roi_hi [1] -= roi_x;
00208 #endif
00209 }
00210 }
00211
00212 if (m_hdump.size()>0) {
00213 m_hmgr = env.hmgr();
00214 if (not m_hmgr) {
00215 MsgLog(name(), error, "histogram manager returned by psana env "
00216 "is null, but histogramming has been requested in configuration. "
00217 "No histograms will be created.");
00218 }
00219 }
00220
00221 if (m_hmgr) {
00222 unsigned pdim = m_projectX ? 1:0;
00223 Axis a(m_sig_roi_hi[pdim]-m_sig_roi_lo[pdim]+1,
00224 double(m_sig_roi_lo[pdim])-0.5,double(m_sig_roi_hi[pdim]+0.5));
00225 for(unsigned i=0; i<m_hdump.size(); i++) {
00226 { std::stringstream s;
00227 s << "Raw projection: event " << i;
00228 m_hdump[i].hraw = m_hmgr->hist1d(s.str().c_str(),"projection",a); }
00229 { std::stringstream s;
00230 s << "Corr projection: event " << i;
00231 m_hdump[i].hcor = m_hmgr->hist1d(s.str().c_str(),"projection",a); }
00232 { std::stringstream s;
00233 s << "Corr reference: event " << i;
00234 m_hdump[i].href = m_hmgr->hist1d(s.str().c_str(),"projection",a); }
00235 { std::stringstream s;
00236 s << "Ratio: event " << i;
00237 m_hdump[i].hrat = m_hmgr->hist1d(s.str().c_str(),"ratio",a); }
00238 { std::stringstream s;
00239 s << "ACF: event " << i;
00240 m_hdump[i].hacf = m_hmgr->hist1d(s.str().c_str(),"acf",a); }
00241 }
00242
00243 m_hacf = m_hmgr->prof1("Reference ACF","autocorrelation",a);
00244 }
00245 m_count=0;
00246 }
00247
00248
00249 void
00250 Setup::beginRun(Event& evt, Env& env)
00251 {
00252 }
00253
00254
00255 void
00256 Setup::beginCalibCycle(Event& evt, Env& env)
00257 {
00258 }
00259
00260
00261
00262 void
00263 Setup::event(Event& evt, Env& env)
00264 {
00265 bool nobeam=false;
00266 {
00267
00268
00269
00270 shared_ptr<Psana::EvrData::DataV3> evr4 = evt.get(Source("DetInfo(:Evr)"));
00271 shared_ptr<Psana::EvrData::DataV3> evr3;
00272 if (not evr4) evr3 = evt.get(Source("DetInfo(:Evr)"));
00273 if (evr3 or evr4) {
00274 bool nolaser=false;
00275 ndarray<const Psana::EvrData::FIFOEvent,1> f = \
00276 evr4 ? evr4->fifoEvents() : evr3->fifoEvents();
00277 unsigned ec_nobeam = unsigned(abs(m_eventcode_nobeam));
00278 unsigned ec_skip = unsigned(abs(m_eventcode_skip));
00279 for(unsigned i=0; i<f.shape()[0]; i++) {
00280 nobeam |= (f[i].eventCode()==ec_nobeam);
00281 nolaser |= (f[i].eventCode()==ec_skip);
00282 MsgLog(name(), trace,
00283 name() << ": Found EVR code " << f[i].eventCode());
00284 }
00285
00286 if (m_eventcode_nobeam < 0) nobeam = !nobeam;
00287 if (m_eventcode_skip < 0) nolaser = !nolaser;
00288
00289 if (nolaser) return;
00290 }
00291 else {
00292 MsgLog(name(), warning,
00293 name() << ": Failed to retrieve EVR event data - tried DataV3 and DataV4.");
00294 }
00295
00296
00297
00298
00299 if (!m_ipm_get_key.empty()) {
00300 shared_ptr<Psana::Lusi::IpmFexV1> ipm = evt.get(m_ipm_get_key);
00301 if (ipm.get())
00302 nobeam |= ipm.get()->sum() < m_ipm_beam_threshold;
00303 }
00304 }
00305
00306 if (!nobeam) return;
00307
00308 MsgLog(name(), trace,
00309 name() << ": fetching frame data.");
00310
00311
00312 shared_ptr<Psana::Camera::FrameV1> frame = evt.get(m_get_key);
00313 if (frame.get()) {
00314 ndarray<const uint16_t,2> f = frame->data16();
00315 bool lfatal=false;
00316 for(unsigned i=0; i<2; i++) {
00317 if (m_sig_roi_hi[i] >= f.shape()[i]) {
00318 lfatal |= (m_projectX == (i==0));
00319 MsgLog(name(), warning,
00320 name() << ": signal " << (i==0 ? 'Y':'X') << " upper bound ["
00321 << m_sig_roi_hi[i] << "] exceeds frame bounds ["
00322 << f.shape()[i] << "].");
00323 m_sig_roi_hi[i] = f.shape()[i]-1;
00324 }
00325 if (m_sb_roi_hi[i] >= f.shape()[i]) {
00326 lfatal |= (m_projectX == (i==0));
00327 MsgLog(name(), warning,
00328 name() << ": sideband " << (i==0 ? 'Y':'X') << " upper bound ["
00329 << m_sb_roi_hi[i] << "] exceeds frame bounds ["
00330 << f.shape()[i] << "].");
00331 m_sb_roi_hi[i] = f.shape()[i]-1;
00332 }
00333 }
00334 if (lfatal)
00335 MsgLog(name(), fatal,
00336 name() << ": Fix bounds before proceeding.");
00337
00338 MsgLog(name(), trace,
00339 name() << ": projecting.");
00340
00341
00342
00343
00344 unsigned pdim = m_projectX ? 1:0;
00345 ndarray<const int,1> sig = psalg::project(f,
00346 m_sig_roi_lo,
00347 m_sig_roi_hi,
00348 m_pedestal, pdim);
00349
00350
00351
00352
00353 ndarray<const int,1> sb;
00354 if (m_sb_roi_lo[0]!=m_sb_roi_hi[0])
00355 sb = psalg::project(f,
00356 m_sb_roi_lo ,
00357 m_sb_roi_hi,
00358 m_pedestal, pdim);
00359
00360 ndarray<double,1> sigd = make_ndarray<double>(sig.shape()[0]);
00361
00362 MsgLog(name(), trace,
00363 name() << ": correcting for sideband.");
00364
00365
00366
00367
00368 if (sb.size()) {
00369 psalg::rolling_average(sb, m_sb_avg, m_sb_avg_fraction);
00370
00371 ndarray<const double,1> sbc = psalg::commonModeLROE(sb, m_sb_avg);
00372
00373 for(unsigned i=0; i<sig.shape()[0]; i++)
00374 sigd[i] = double(sig[i])-sbc[i];
00375 }
00376 else {
00377 for(unsigned i=0; i<sig.shape()[0]; i++)
00378 sigd[i] = double(sig[i]);
00379 }
00380
00381
00382
00383
00384 bool lcut=true;
00385 for(unsigned i=0; i<sig.shape()[0]; i++)
00386 if (sigd[i]>m_proj_cut)
00387 lcut=false;
00388
00389 if (lcut) return;
00390
00391 MsgLog(name(), trace,
00392 name() << ": Divide by the reference.");
00393
00394
00395
00396
00397 ndarray<double,1> drat = make_ndarray<double>(sig.shape()[0]);
00398 for(unsigned i=0; i<sig.shape()[0]; i++)
00399 drat[i] = sigd[i]/m_ref[i] - 1;
00400
00401 if ((m_count < m_hdump.size()) and m_hmgr) {
00402 for(unsigned i=0; i<sig.shape()[0]; i++)
00403 m_hdump[m_count].hraw->fill(double(i)+m_sig_roi_lo[pdim],double(sig[i]));
00404 for(unsigned i=0; i<sigd.shape()[0]; i++)
00405 m_hdump[m_count].hcor->fill(double(i)+m_sig_roi_lo[pdim],sigd[i]);
00406 for(unsigned i=0; i<m_ref.shape()[0]; i++)
00407 m_hdump[m_count].href->fill(double(i)+m_sig_roi_lo[pdim],m_ref[i]);
00408 for(unsigned i=0; i<sigd.shape()[0]; i++)
00409 m_hdump[m_count].hrat->fill(double(i)+m_sig_roi_lo[pdim],drat[i]);
00410 for(unsigned i=0; i<sigd.shape()[0]; i++) {
00411 double wt = 1./double(sigd.shape()[0]-i);
00412 for(unsigned j=0; (i+j)<sigd.shape()[0]; j++)
00413 m_hdump[m_count].hacf->fill(double(i)+m_sig_roi_lo[pdim],drat[j]*drat[i+j]*wt);
00414 }
00415 m_count++;
00416 }
00417
00418 MsgLog(name(), trace,
00419 name() << ": Accumulate the ACF.");
00420
00421
00422
00423
00424 if (m_hmgr) {
00425 for(unsigned i=0; i<sig.shape()[0]; i++)
00426 for(unsigned j=i; j<sig.shape()[0]; j++)
00427 m_hacf->fill(double(j-i),drat[i]*drat[j]);
00428 }
00429 psalg::rolling_average(ndarray<const double,1>(sigd),
00430 m_ref, m_ref_avg_fraction);
00431
00432 }
00433 else {
00434 MsgLog(name(), warning, name() << ": Could not fetch " << m_get_key);
00435 }
00436 }
00437
00438
00439 void
00440 Setup::endCalibCycle(Event& evt, Env& env)
00441 {
00442 }
00443
00444
00445 void
00446 Setup::endRun(Event& evt, Env& env)
00447 {
00448 }
00449
00450
00451 void
00452 Setup::endJob(Event& evt, Env& env)
00453 {
00454 }
00455
00456 }
00457