Commit 5fdd94cf authored by Alejandro Homs Puron's avatar Alejandro Homs Puron
Browse files

Add StreamStatistics, providing average transfer size, time and speed

parent 9183526a
Pipeline #20969 failed with stages
in 1 minute and 8 seconds
......@@ -40,6 +40,7 @@ namespace lima
class Camera;
class Stream;
class StreamInfo;
class StreamStatistics;
class Decompress;
/*******************************************************************
......@@ -67,6 +68,8 @@ namespace lima
Camera& getCamera() { return m_cam;}
void getLastStreamInfo(StreamInfo& info);
void latchStreamStatistics(StreamStatistics& stat,
bool reset=false);
private:
Camera& m_cam;
......
//###########################################################################
// This file is part of LImA, a Library for Image Acquisition
//
// Copyright (C) : 2009-2015
// 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/>.
//###########################################################################
#ifndef EIGERSTATISTICS_H
#define EIGERSTATISTICS_H
#include <type_traits>
#include <cmath>
namespace lima
{
namespace Eiger
{
template <typename T,
typename A=typename std::conditional<std::is_integral<T>::value,
long long, double>::type>
struct Statistics
{
int n;
A sx;
A sx2;
T xmin;
T xmax;
Statistics()
{ reset(); }
void reset()
{ sx = sx2 = xmin = xmax = n = 0; }
void add(T x)
{
sx += x;
sx2 += x * x;
++n;
if (x < xmin)
xmin = x;
if (x > xmax)
xmax = x;
}
operator bool() const
{ return n; }
double ave() const
{ return n ? (double(sx) / n) : 0; }
double std() const
{
if (!n)
return 0;
double xm = ave();
return std::sqrt(double(sx2) / n - xm * xm);
}
};
struct StreamStatistics
{
Statistics<int> stat_size;
Statistics<double> stat_time;
void reset()
{
stat_size.reset();
stat_time.reset();
}
void add(int size, double elapsed)
{
stat_size.add(size);
stat_time.add(elapsed);
}
operator bool() const
{ return stat_size && stat_time; }
int n() const
{ return std::min(stat_size.n, stat_time.n); }
double ave_size() const
{ return stat_size.ave(); }
double ave_time() const
{ return stat_time.ave(); }
double ave_speed() const
{ return *this ? (ave_size() / ave_time()) : 0; }
};
template <typename T>
std::ostream& operator <<(std::ostream& os, const Statistics<T>& s)
{
os << "<n=" << s.n;
if (s)
os << ", ave=" << s.ave() << ", std=" << s.std();
return os << ">";
}
inline
std::ostream& operator <<(std::ostream& os, const StreamStatistics& s)
{
return os << "<size=" << s.stat_size << ", time=" << s.stat_time << ", "
<< "speed=" << (s.ave_speed() / 1e9) << ">";
}
} // namespace Eiger
} // namespace lima
#endif // EIGERSTATISTICS_H
......@@ -49,5 +49,7 @@ namespace Eiger
Eiger::Camera& getCamera();
void getLastStreamInfo(Eiger::StreamInfo& last_info /Out/);
void latchStreamStatistics(Eiger::StreamStatistics& stat /Out/,
bool reset=false);
};
};
//###########################################################################
// This file is part of LImA, a Library for Image Acquisition
//
// Copyright (C) : 2009-2014
// 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/>.
//###########################################################################
namespace Eiger
{
/*******************************************************************
* \struct StreamStatistics
* \brief Eiger hardware interface
*******************************************************************/
struct StreamStatistics
{
%TypeHeaderCode
#include <EigerStatistics.h>
%End
int n() const;
double ave_size() const;
double ave_time() const;
double ave_speed() const;
};
};
......@@ -108,6 +108,7 @@ void Interface::prepareAcq()
m_decompress->setActive(!use_filewriter);
m_stream->release_all_msgs();
m_stream->resetStatistics();
m_cam.prepareAcq();
int serie_id; m_cam.getSerieId(serie_id);
......@@ -234,3 +235,9 @@ void Interface::getLastStreamInfo(StreamInfo& last_info)
m_stream->getLastStreamInfo(last_info);
}
void Interface::latchStreamStatistics(StreamStatistics& stat, bool reset)
{
DEB_MEMBER_FUNCT();
m_stream->latchStatistics(stat, reset);
}
......@@ -617,11 +617,18 @@ bool Stream::_read_zmq_messages(void *stream_socket)
HwFrameInfoType frame_info;
frame_info.acq_frame_nb = frameid;
void* buffer_ptr = m_buffer_mgr->getFrameBufferPtr(frameid);
int data_size = data_header.get("size",-1).asInt();
Timestamp t = Timestamp::now();
{
lock.lock();
m_data_2_msg[buffer_ptr] = ImageData{pending_messages[2],
anImageDim.getDepth(),
m_comp_type};
if (frameid > 0) {
double transfer_time = t - m_last_data_tstamp;
m_stat.add(data_size, transfer_time);
}
m_last_data_tstamp = t;
lock.unlock();
}
......@@ -715,3 +722,20 @@ void Stream::release_all_msgs()
AutoMutex lock(m_cond.mutex());
m_data_2_msg.clear();
}
void Stream::resetStatistics()
{
DEB_MEMBER_FUNCT();
AutoMutex lock(m_cond.mutex());
m_stat.reset();
}
void Stream::latchStatistics(StreamStatistics& stat, bool reset)
{
DEB_MEMBER_FUNCT();
AutoMutex lock(m_cond.mutex());
stat = m_stat;
if (reset)
m_stat.reset();
DEB_RETURN() << DEB_VAR1(stat);
}
......@@ -28,6 +28,8 @@
#include "EigerStreamInfo.h"
#include "lima/HwBufferMgr.h"
#include "EigerStatistics.h"
#include <json/json.h>
namespace lima
......@@ -75,10 +77,12 @@ namespace lima
void getLastStreamInfo(StreamInfo& info);
void resetStatistics();
void latchStatistics(StreamStatistics& stat, bool reset=false);
private:
class _BufferCtrlObj;
friend class _BufferCtrlObj;
friend class ImageDataPtr;
typedef std::map<void*,ImageData> Data2Message;
typedef std::vector<MessagePtr> MessageList;
......@@ -120,6 +124,9 @@ namespace lima
std::unique_ptr<_BufferCtrlObj> m_buffer_ctrl_obj;
StdBufferCbMgr* m_buffer_mgr;
Timestamp m_last_data_tstamp;
StreamStatistics m_stat;
};
std::ostream& operator <<(std::ostream& os, Stream::State state);
......
......@@ -139,6 +139,16 @@ class Eiger(PyTango.Device_4Impl):
str(last_info.packed_size)]
attr.set_value(last_info_strarr)
#==================================================================
#
# stream_statistics
#
#==================================================================
@Core.DEB_MEMBER_FUNCT
def read_stream_stats(self, attr):
stream_stats_arr = self.latchStreamStatistics(False)
attr.set_value(stream_stats_arr)
#==================================================================
#
# Eiger command methods
......@@ -159,6 +169,17 @@ class Eiger(PyTango.Device_4Impl):
def initialize(self):
_EigerCamera.initialize()
#----------------------------------------------------------------------------
# latch Stream statistics
#----------------------------------------------------------------------------
@Core.DEB_MEMBER_FUNCT
def latchStreamStatistics(self, reset):
stream_stats = _EigerInterface.latchStreamStatistics(reset)
return [stream_stats.n(),
stream_stats.ave_size(),
stream_stats.ave_time(),
stream_stats.ave_speed()]
#==================================================================
#
# EigerClass class definition
......@@ -193,6 +214,9 @@ class EigerClass(PyTango.DeviceClass):
'initialize':
[[PyTango.DevVoid, ""],
[PyTango.DevVoid, ""]],
'latchStreamStatistics':
[[PyTango.DevBoolean, "Reset statistics"],
[PyTango.DevVarDoubleArray, "[<ave_size>, <ave_time>, <ave_speed>]"]],
}
......@@ -262,6 +286,10 @@ class EigerClass(PyTango.DeviceClass):
[[PyTango.DevString,
PyTango.SCALAR,
PyTango.READ]],
'stream_stats':
[[PyTango.DevDouble,
PyTango.SPECTRUM,
PyTango.READ, 16]],
}
......
Supports Markdown
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