Commit 886f5cd2 authored by Samuel Debionne's avatar Samuel Debionne
Browse files

Merge branch 'beb_xfer_speed_measurement' into 'master'

Add BEB xfer speed measurement

See merge request !15
parents 41db4d2c 24e436e8
Pipeline #50112 failed with stages
in 8 minutes and 40 seconds
......@@ -408,8 +408,35 @@ private:
static bool DoHist;
};
struct XYStat {
double xacc, xacc2, yacc, xyacc;
int xn;
double factor;
mutable Mutex lock;
XYStat(double f = 1);
void reset();
void add(double x, double y);
XYStat& operator =(const XYStat& o);
XYStat& operator += (const XYStat& o);
// Linear Regression
struct LinRegress {
int n;
double slope;
double offset;
LinRegress() : n(0), slope(0), offset(0)
{}
};
int n() const;
LinRegress calcLinRegress() const;
};
std::ostream& operator <<(std::ostream& os, const SimpleStat::Histogram& s);
std::ostream& operator <<(std::ostream& os, const SimpleStat& s);
std::ostream& operator <<(std::ostream& os, const XYStat::LinRegress& r);
class Camera;
......
......@@ -101,12 +101,16 @@ class FrameMap
FrameType getLastFinishedFrame() const
{ return getOldestFrame(getItemFrameArray()); }
XYStat::LinRegress calcDelayStat()
{ return m_delay_stat.calcLinRegress(); }
private:
friend class Item;
struct AtomicCounter {
int count;
Mutex mutex;
Timestamp t0;
void set(int reset)
{
......@@ -115,12 +119,17 @@ class FrameMap
mutex.unlock();
}
bool dec_test_and_reset(int reset)
bool dec_test_and_reset(int reset, double& delay)
{
mutex.lock();
Timestamp t = Timestamp::now();
if (count == reset)
t0 = t;
bool zero = (--count == 0);
if (zero)
if (zero) {
count = reset;
delay = t - t0;
}
mutex.unlock();
return zero;
}
......@@ -132,6 +141,7 @@ class FrameMap
int m_buffer_size;
CounterList m_frame_item_count_list;
ItemList m_item_list;
XYStat m_delay_stat;
};
inline bool FrameMap::Item::isBadFrame(FrameType frame)
......
Subproject commit 90c6756b1fdd4cb9c80918ba0275a05b8fd4b157
Subproject commit 07ac519ae1b6fafbeb04fd636a85f01e7a65d7c6
......@@ -210,6 +210,10 @@ void Camera::AcqThread::threadFunction()
m_cam->getStats(stats);
DEB_ALWAYS() << DEB_VAR1(stats);
FrameMap& m = m_cam->m_frame_map;
XYStat::LinRegress delay_stat = m.calcDelayStat();
DEB_ALWAYS() << DEB_VAR1(delay_stat);
if (had_frames) {
affinity_mgr.recvFinished();
affinity_mgr.waitLimaFinished();
......
......@@ -475,6 +475,76 @@ double SimpleStat::std() const
return xn ? sqrt(xacc2 / xn - pow(ave(), 2)) : 0;
}
XYStat::XYStat(double f)
: factor(f)
{
reset();
}
void XYStat::reset()
{
AutoMutex l(lock);
xacc = xacc2 = yacc = xyacc = 0;
xn = 0;
}
void XYStat::add(double x, double y) {
AutoMutex l(lock);
y *= factor;
xacc += x;
xacc2 += pow(x, 2);
yacc += y;
xyacc += x * y;
++xn;
}
XYStat& XYStat::operator =(const XYStat& o)
{
if (&o == this)
return *this;
AutoMutex l(o.lock);
xacc = o.xacc;
xacc2 = o.xacc2;
yacc = o.yacc;
xyacc = o.xyacc;
xn = o.xn;
factor = o.factor;
return *this;
}
XYStat& XYStat::operator +=(const XYStat& o)
{
if (o.factor != factor)
throw LIMA_HW_EXC(Error, "Cannot add different XYStats");
AutoMutex l(o.lock);
xacc += o.xacc;
xacc2 += o.xacc2;
yacc += o.yacc;
xyacc += o.xyacc;
xn += o.xn;
return *this;
}
int XYStat::n() const
{
AutoMutex l(lock);
return xn;
}
XYStat::LinRegress XYStat::calcLinRegress() const
{
AutoMutex l(lock);
LinRegress r;
if (!xn)
return r;
r.n = xn;
r.slope = (xn * xyacc - xacc * yacc) / (xn * xacc2 - xacc * xacc);
r.offset = (yacc - r.slope * xacc) / xn;
return r;
}
FrameType lima::SlsDetector::getLatestFrame(const FrameArray& l)
{
DEB_STATIC_FUNCT();
......@@ -569,6 +639,16 @@ ostream& lima::SlsDetector::operator <<(ostream& os, const SimpleStat& s)
return os << ">";
}
ostream& lima::SlsDetector::operator <<(ostream& os,
const XYStat::LinRegress& r)
{
os << "<";
os << "slope=" << r.slope << ", "
<< "offset=" << r.offset << ", "
<< "n=" << r.n;
return os << ">";
}
TimeRangesChangedCallback::TimeRangesChangedCallback()
: m_cam(NULL)
{
......
......@@ -68,9 +68,12 @@ FrameMap::Item::frameFinished(FrameType frame, bool no_check, bool valid)
for (FrameType f = m_last_frame + 1; f != (frame + 1); ++f) {
int idx = f % m_map->m_buffer_size;
AtomicCounter& count = m_map->m_frame_item_count_list[idx];
bool finished = count.dec_test_and_reset(nb_items);
if (finished)
double delay;
bool finished = count.dec_test_and_reset(nb_items, delay);
if (finished) {
finfo.finished.insert(f);
m_map->m_delay_stat.add(frame, delay);
}
}
if (DEB_CHECK_ANY(DebTypeReturn)) {
......@@ -133,6 +136,8 @@ void FrameMap::clear()
CounterList::iterator cit, cend = count_list.end();
for (cit = count_list.begin(); cit != cend; ++cit)
cit->set(m_nb_items);
m_delay_stat.reset();
}
FrameArray FrameMap::getItemFrameArray() const
......
......@@ -23,7 +23,8 @@
set(test_src test_slsdetector
test_slsdetector_control
test_thread_cpu_affinity
test_expand_4)
test_expand_4
test_stat)
limatools_run_camera_tests("${test_src}" ${PROJECT_NAME})
//###########################################################################
// This file is part of LImA, a Library for Image Acquisition
//
// Copyright (C) : 2009-2011
// European Synchrotron Radiation Facility
// BP 220, Grenoble 38043
// FRANCE
//
// This is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// This software is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, see <http://www.gnu.org/licenses/>.
//###########################################################################
#include "SlsDetectorDefs.h"
#include "lima/Exceptions.h"
#include <cmath>
DEB_GLOBAL(DebModTest);
using namespace std;
using namespace lima;
using namespace SlsDetector;
bool is_approx(double x, double y, double tol)
{
return fabs(x - y) <= tol;
}
bool is_approx_rel(double x, double y, double rel_tol)
{
return is_approx(x, y, fabs(rel_tol * (fabs(x) + fabs(y)) / 2));
}
void test_stat(double slope, double offset, int n)
{
DEB_GLOBAL_FUNCT();
XYStat stat;
for (int i = 0; i < n; ++i)
stat.add(i, slope * i + offset);
XYStat::LinRegress r = stat.calcLinRegress();
DEB_ALWAYS() << DEB_VAR1(r);
if (r.n != n)
THROW_HW_ERROR(Error) << DEB_VAR2(r.n, n);
else if (!is_approx_rel(r.slope, slope, 1e-3))
THROW_HW_ERROR(Error) << DEB_VAR2(r.slope, slope);
else if (!is_approx_rel(r.offset, offset, 1e-3))
THROW_HW_ERROR(Error) << DEB_VAR2(r.offset, offset);
}
int main(int argc, char *argv[])
{
DEB_GLOBAL_FUNCT();
double slope, offset;
int n;
slope = 0.12345;
offset = 123.45;
n = 100;
test_stat(slope, offset, n);
return 0;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment