Commit 7ea15f1f authored by ahoms's avatar ahoms

* Fixed problem catching Exceptions in C++ called from Python

  by forcing RTLD_GLOBAL in sys.setdlopenflags
* Created checksipexc.py script to patch SIP-generated C++
  files in order to handle Exception if not already done
  called from sip/configure.py on all SIP-generated files
* Added stream-like operator << to Exception appending strings 
  to err_desc; added public methods to query Exception fields
* Unified Exception throw and debug messages creation through
  DebExcProxy, used by the THROW_COM/HW/CTL_FATAL/ERROR macros,
  allowing Exceptions with dynamic error description;
  applied in core-hardware, espia and frelon code
* Linking Frelon test programs with shared libraries
* Created the Frelon::Model class managing all model-specific
  information (name, pixel size, ADC, ...)
* Detect Frelon serial timeout when creating the Camera and
  suggest the verification of the camera power and connection



git-svn-id: https://scm.blissgarden.org/svn/lima/trunk@308 45c4679d-1946-429d-baad-37912b19538b
parent fd4ca667
......@@ -80,10 +80,12 @@ extern FTMInputChanListMapType FTMInputChanListMap;
enum SerNbParam {
SerNb = 0x00ff,
F4M = 0x2000,
F2k16 = 0x4000,
Taper = 0x8000,
SerNb = 0x00ff,
SPB1Kodak = 0x2000,
SPB1Adc16 = 0x4000,
SPB2Sign = 0x0100,
SPB2Type = 0x7000,
Taper = 0x8000,
};
enum RoiMode {
......
......@@ -2,6 +2,7 @@
#define FRELONCAMERA_H
#include "FrelonSerialLine.h"
#include "FrelonModel.h"
#include "HwMaxImageSizeCallback.h"
namespace lima
......@@ -25,12 +26,8 @@ class Camera : public HwMaxImageSizeCallbackGen
void hardReset();
void getVersion(std::string& ver);
void getComplexSerialNb(int& complex_ser_nb);
void getSerialNb(int& ser_nb);
void isFrelon2k16(bool& is_frelon_2k16);
void isFrelon4M(bool& is_frelon_4m);
void hasTaper(bool& has_taper);
Model& getModel();
void setInputChan(InputChan input_chan);
void getInputChan(InputChan& input_chan);
......@@ -94,8 +91,6 @@ class Camera : public HwMaxImageSizeCallbackGen
void sendCmd(Cmd cmd);
void getSerialNbParam(SerNbParam param, int& val);
void setChanMode(int chan_mode);
void getChanMode(int& chan_mode);
......@@ -134,6 +129,7 @@ class Camera : public HwMaxImageSizeCallbackGen
void getTimeUnitFactor(TimeUnitFactor& time_unit_factor);
SerialLine m_ser_line;
Model m_model;
Point m_roi_offset;
TrigMode m_trig_mode;
int m_nb_frames;
......
#ifndef FRELONMODEL_H
#define FRELONMODEL_H
#include "Frelon.h"
namespace lima
{
namespace Frelon
{
class Model
{
DEB_CLASS_NAMESPC(DebModCamera, "Model", "Frelon");
public:
Model();
~Model();
void setVersion(const std::string& ver);
void getVersion(std::string& ver);
void setComplexSerialNb(int complex_ser_nb);
void getComplexSerialNb(int& complex_ser_nb);
void reset();
bool isValid();
int getSerialNb();
bool isSPB1();
bool isSPB2();
int getAdcBits();
ChipType getChipType();
bool hasTaper();
double getPixelSize();
std::string getName();
private:
void checkValid();
int getSerialNbParam(SerNbParam param);
std::string m_ver;
int m_complex_ser_nb;
};
} // namespace Frelon
} // namespace lima
#endif // FRELONMODEL_H
import os, sys, imp, glob
import os, sys, imp, glob, DLFCN
root_name = __path__[0]
mod_name = os.path.basename(root_name)
......@@ -33,13 +33,19 @@ if not (os.path.isdir(mod_path) or os.path.islink(mod_path)):
sys.path.insert(0, mod_path)
ld_open_flags = sys.getdlopenflags()
sys.setdlopenflags(ld_open_flags | DLFCN.RTLD_GLOBAL)
from limafrelon import *
sys.setdlopenflags(ld_open_flags)
globals().update(Frelon.__dict__)
from FrelonAcq import FrelonAcq
sys.path.remove(mod_path)
del root_name, mod_name, mod_path, x, env_var_name
del root_name, mod_name, mod_path, x, env_var_name, ld_open_flags
del version, req_version, version_dirs, version_code, version_cmp
del os, sys, imp, glob
del os, sys, imp, glob, DLFCN
......@@ -76,10 +76,12 @@ extern FTMInputChanListMapType FTMInputChanListMap;
*/
enum SerNbParam {
SerNb = 0x00ff,
F4M = 0x2000,
F2k16 = 0x4000,
Taper = 0x8000,
SerNb = 0x00ff,
SPB1Kodak = 0x2000,
SPB1Adc16 = 0x4000,
SPB2Sign = 0x0100,
SPB2Type = 0x7000,
Taper = 0x8000,
};
enum RoiMode {
......
......@@ -8,9 +8,6 @@ class Camera
%TypeHeaderCode
#include "FrelonCamera.h"
#include "RegEx.h"
#include "MiscUtils.h"
#include <sstream>
%End
public:
......@@ -24,12 +21,8 @@ class Camera
void hardReset();
void getVersion(std::string& ver /Out/);
void getComplexSerialNb(int& complex_ser_nb /Out/);
void getSerialNb(int& ser_nb /Out/);
void isFrelon2k16(bool& is_frelon_2k16 /Out/);
void isFrelon4M(bool& is_frelon_4m /Out/);
void hasTaper(bool& has_taper /Out/);
Frelon::Model& getModel();
void setInputChan(Frelon::InputChan input_chan);
void getInputChan(Frelon::InputChan& input_chan /Out/);
......
namespace Frelon
{
class Model
{
%TypeHeaderCode
#include "FrelonModel.h"
%End
public:
Model();
~Model();
void setVersion(const std::string& ver);
void getVersion(std::string& ver /Out/);
void setComplexSerialNb(int complex_ser_nb);
void getComplexSerialNb(int& complex_ser_nb /Out/);
void reset();
bool isValid();
int getSerialNb();
bool isSPB1();
bool isSPB2();
int getAdcBits();
int getChipType();
bool hasTaper();
double getPixelSize();
std::string getName();
};
}; // namespace Frelon
\ No newline at end of file
......@@ -7,9 +7,6 @@ class SerialLine : HwSerialLine
%TypeHeaderCode
#include "FrelonSerialLine.h"
#include "RegEx.h"
#include "MiscUtils.h"
#include <sstream>
%End
public:
......
#include "FrelonCamera.h"
#include "RegEx.h"
#include "MiscUtils.h"
#include <sstream>
......@@ -35,10 +34,32 @@ void Camera::sync()
DEB_TRACE() << "Synchronizing with the camera";
m_model.reset();
try {
string ver;
getVersion(ver);
m_model.setVersion(ver);
} catch (Exception e) {
string err_msg = e.getErrMsg();
DEB_ERROR() << "Error getting version: " << DEB_VAR1(err_msg);
string timeout_msg = Espia::StrError(SCDXIPCI_ERR_TIMEOUT);
bool timeout = (err_msg.find(timeout_msg) != string::npos);
if (!timeout)
throw;
THROW_HW_ERROR(Error) << "Serial connection timeout: "
"is camera ON and connected?";
}
int complex_ser_nb;
getComplexSerialNb(complex_ser_nb);
m_model.setComplexSerialNb(complex_ser_nb);
string ver;
getVersion(ver);
int ser_nb;
getSerialNb(ser_nb);
m_model.getVersion(ver);
DEB_ALWAYS() << "Found Frelon " << m_model.getName()
<< " #" << m_model.getSerialNb() << ", FW:" << ver;
double exp_time;
getExpTime(exp_time);
......@@ -66,10 +87,9 @@ void Camera::sendCmd(Cmd cmd)
DEB_MEMBER_FUNCT();
const string& cmd_str = CmdStrMap[cmd];
DEB_PARAM() << DEB_VAR2(cmd, cmd_str);
if (cmd_str.empty()) {
DEB_ERROR() << "Invalid command cmd=" << cmd;
throw LIMA_HW_EXC(InvalidValue, "Invalid command");
}
if (cmd_str.empty())
THROW_HW_ERROR(InvalidValue) << "Invalid "
<< DEB_VAR1(cmd);
string resp;
m_ser_line.sendFmtCmd(cmd_str, resp);
......@@ -112,47 +132,9 @@ void Camera::getComplexSerialNb(int& complex_ser_nb)
DEB_RETURN() << DEB_VAR1(DEB_HEX(complex_ser_nb));
}
void Camera::getSerialNbParam(SerNbParam param, int& val)
{
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR1(DEB_HEX(param));
int complex_ser_nb;
getComplexSerialNb(complex_ser_nb);
val = complex_ser_nb & int(param);
}
void Camera::getSerialNb(int& ser_nb)
{
DEB_MEMBER_FUNCT();
getSerialNbParam(SerNb, ser_nb);
DEB_RETURN() << DEB_VAR1(ser_nb);
}
void Camera::isFrelon2k16(bool& is_frelon_2k16)
{
DEB_MEMBER_FUNCT();
int frelon_2k16;
getSerialNbParam(F2k16, frelon_2k16);
is_frelon_2k16 = bool(frelon_2k16);
DEB_RETURN() << DEB_VAR1(is_frelon_2k16);
}
void Camera::isFrelon4M(bool& is_frelon_4m)
{
DEB_MEMBER_FUNCT();
int f4m;
getSerialNbParam(F4M, f4m);
is_frelon_4m = bool(f4m);
DEB_RETURN() << DEB_VAR1(is_frelon_4m);
}
void Camera::hasTaper(bool& has_taper)
Model& Camera::getModel()
{
DEB_MEMBER_FUNCT();
int taper;
getSerialNbParam(Taper, taper);
has_taper = bool(taper);
DEB_RETURN() << DEB_VAR1(has_taper);
return m_model;
}
void Camera::setChanMode(int chan_mode)
......@@ -187,7 +169,8 @@ void Camera::getInputChanMode(FrameTransferMode ftm, InputChan input_chan,
InputChanList::const_iterator it;
it = find(chan_list.begin(), chan_list.end(), input_chan);
if (it == chan_list.end())
throw LIMA_HW_EXC(InvalidValue, "Invalid input channel");
THROW_HW_ERROR(InvalidValue) << "Invalid "
<< DEB_VAR1(input_chan);
chan_mode += it - chan_list.begin();
DEB_RETURN() << DEB_VAR1(chan_mode);
......@@ -263,7 +246,7 @@ void Camera::getFrameTransferMode(FrameTransferMode& ftm)
}
}
throw LIMA_HW_EXC(Error, "Invalid chan mode");
THROW_HW_ERROR(Error) << "Invalid " << DEB_VAR1(chan_mode);
}
void Camera::getFrameDim(FrameDim& frame_dim)
......@@ -338,10 +321,9 @@ void Camera::setBin(const Bin& bin)
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR1(bin);
if ((bin.getX() > 8) || (bin.getY() > 1024)) {
DEB_ERROR() << "Invalid bin: " << bin << ". Must be <= 8x1024";
throw LIMA_HW_EXC(InvalidValue, "Bin must be <= 8x1024");
}
if ((bin.getX() > 8) || (bin.getY() > 1024))
THROW_HW_ERROR(InvalidValue) << "Invalid " << DEB_VAR1(bin)
<< ". Must be <= 8x1024";
Bin curr_bin;
getBin(curr_bin);
......@@ -734,13 +716,12 @@ void Camera::setRoiBinOffset(const Point& roi_bin_offset)
Size bin_size = Point(bin);
Roi valid_offset_range(Point(0), bin_size);
if (!valid_offset_range.containsPoint(roi_bin_offset)) {
string err_msg = "Invalid unaligned ";
DEB_ERROR() << err_msg << DEB_VAR1(roi_bin_offset);
throw LIMA_HW_EXC(InvalidValue, err_msg + "roi_bin_offset");
THROW_HW_ERROR(InvalidValue) << "Invalid unaligned "
<< DEB_VAR1(roi_bin_offset);
} else if (roi_bin_offset.x != 0) {
string err_msg = "Roi must be horizontally aligned to bin";
DEB_ERROR() << err_msg;
throw LIMA_HW_EXC(InvalidValue, err_msg);
THROW_HW_ERROR(InvalidValue)
<< "Invalid " << DEB_VAR1(roi_bin_offset) << ". "
<< "Must be horizontally aligned to " << DEB_VAR1(bin);
}
Roi chan_roi;
......@@ -772,11 +753,9 @@ void Camera::setRoiBinOffset(const Point& roi_bin_offset)
image_roi.setTopLeft(image_tl);
ok = max_chan_roi.containsRoi(image_roi);
}
if (!ok) {
string err_msg = "Cannot apply requested ";
DEB_ERROR() << err_msg << DEB_VAR1(roi_bin_offset);
throw LIMA_HW_EXC(InvalidValue, err_msg + "roi_bin_offset");
}
if (!ok)
THROW_HW_ERROR(InvalidValue) << "Cannot apply requested "
<< DEB_VAR1(roi_bin_offset);
Point chan_tl, chan_br;
xformChanCoords(image_roi.getTopLeft(), chan_tl, c_tl);
......@@ -848,10 +827,9 @@ void Camera::setExpTime(double exp_time)
if (ok)
break;
}
if (!ok) {
DEB_ERROR() << "Exp. time too high: " << DEB_VAR1(exp_time);
throw LIMA_HW_EXC(InvalidValue, "Exposure time too high");
}
if (!ok)
THROW_HW_ERROR(InvalidValue) << "Exp. time too high: "
<< DEB_VAR1(exp_time);
TimeUnitFactor time_unit_factor = (exp_val == 0) ? Milliseconds : *it;
setTimeUnitFactor(time_unit_factor);
......
......@@ -54,19 +54,16 @@ void DetInfoCtrlObj::setCurrImageType(ImageType curr_image_type)
DEB_MEMBER_FUNCT();
ImageType unique_image_type;
getCurrImageType(unique_image_type);
if (curr_image_type != unique_image_type) {
DEB_ERROR() << "Only " << unique_image_type << "allowed";
throw LIMA_HW_EXC(InvalidValue, "Only one image type allowed");
}
if (curr_image_type != unique_image_type)
THROW_HW_ERROR(InvalidValue)
<< "Only " << DEB_VAR1(unique_image_type) << "allowed";
}
void DetInfoCtrlObj::getPixelSize(double& pixel_size)
{
DEB_MEMBER_FUNCT();
bool is_frelon_4m;
m_cam.isFrelon4M(is_frelon_4m);
ChipType chip_type = is_frelon_4m ? Kodak : Atmel;
pixel_size = ChipPixelSizeMap[chip_type];
Model& model = m_cam.getModel();
pixel_size = model.getPixelSize();
DEB_RETURN() << DEB_VAR1(pixel_size);
}
......@@ -80,21 +77,8 @@ void DetInfoCtrlObj::getDetectorType(std::string& det_type)
void DetInfoCtrlObj::getDetectorModel(std::string& det_model)
{
DEB_MEMBER_FUNCT();
bool is_frelon_4m;
m_cam.isFrelon4M(is_frelon_4m);
det_model = is_frelon_4m ? "4M" : "2k";
if (!is_frelon_4m) {
bool is_frelon_2k16;
m_cam.isFrelon2k16(is_frelon_2k16);
det_model += is_frelon_2k16 ? "16" : "14";
}
bool has_taper;
m_cam.hasTaper(has_taper);
if (has_taper)
det_model += "T";
Model& model = m_cam.getModel();
det_model = model.getName();
DEB_RETURN() << DEB_VAR1(det_model);
}
......
#include "FrelonModel.h"
using namespace lima;
using namespace lima::Frelon;
using namespace std;
Model::Model()
{
DEB_CONSTRUCTOR();
reset();
}
Model::~Model()
{
DEB_DESTRUCTOR();
}
void Model::setVersion(const std::string& ver)
{
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR1(ver);
m_ver = ver;
}
void Model::getVersion(std::string& ver)
{
DEB_MEMBER_FUNCT();
ver = m_ver;
DEB_RETURN() << DEB_VAR1(ver);
}
void Model::setComplexSerialNb(int complex_ser_nb)
{
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR1(complex_ser_nb);
m_complex_ser_nb = complex_ser_nb;
}
void Model::getComplexSerialNb(int& complex_ser_nb)
{
DEB_MEMBER_FUNCT();
complex_ser_nb = m_complex_ser_nb;
DEB_RETURN() << DEB_VAR1(complex_ser_nb);
}
void Model::reset()
{
DEB_MEMBER_FUNCT();
m_ver.clear();
m_complex_ser_nb = 0;
}
bool Model::isValid()
{
DEB_MEMBER_FUNCT();
bool valid = (m_complex_ser_nb > 0) && !m_ver.empty();
DEB_RETURN() << DEB_VAR1(valid);
return valid;
}
void Model::checkValid()
{
DEB_MEMBER_FUNCT();
if (!isValid())
THROW_HW_ERROR(InvalidValue)
<< "Frelon model not fully initialised yet";
}
int Model::getSerialNbParam(SerNbParam param)
{
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR1(DEB_HEX(param));
int val = m_complex_ser_nb & int(param);
DEB_RETURN() << DEB_VAR1(val);
return val;
}
int Model::getSerialNb()
{
DEB_MEMBER_FUNCT();
checkValid();
int ser_nb = getSerialNbParam(SerNb);
DEB_RETURN() << DEB_VAR1(ser_nb);
return ser_nb;
}
bool Model::isSPB1()
{
DEB_MEMBER_FUNCT();
bool frelon_spb1 = !isSPB2();
DEB_RETURN() << DEB_VAR1(frelon_spb1);
return frelon_spb1;
}
bool Model::isSPB2()
{
DEB_MEMBER_FUNCT();
checkValid();
bool frelon_spb2 = bool(getSerialNbParam(SPB2Sign));
DEB_RETURN() << DEB_VAR1(frelon_spb2);
return frelon_spb2;
}
int Model::getAdcBits()
{
DEB_MEMBER_FUNCT();
int adc_bits;
if (isSPB1())
adc_bits = bool(getSerialNbParam(SPB1Adc16)) ? 16 : 14;
else
adc_bits = 16;
DEB_RETURN() << DEB_VAR1(adc_bits);
return adc_bits;
}
ChipType Model::getChipType()
{
DEB_MEMBER_FUNCT();
ChipType chip_type;
if (isSPB1())
chip_type = bool(getSerialNbParam(SPB1Kodak)) ? Kodak : Atmel;
else
chip_type = ChipType(getSerialNbParam(SPB2Type) >> 12);
DEB_RETURN() << DEB_VAR1(chip_type);
return chip_type;
}
bool Model::hasTaper()
{
DEB_MEMBER_FUNCT();
checkValid();
bool taper = bool(getSerialNbParam(Taper));
DEB_RETURN() << DEB_VAR1(taper);
return taper;
}
double Model::getPixelSize()
{
DEB_MEMBER_FUNCT();
ChipType chip_type = getChipType();
double pixel_size = ChipPixelSizeMap[chip_type];
DEB_RETURN() << DEB_VAR1(pixel_size);
return pixel_size;
}
string Model::getName()
{
DEB_MEMBER_FUNCT();
checkValid();
map<ChipType, string> chip_model;
chip_model[Atmel] = "A7899";
chip_model[Kodak] = "K4320";
chip_model[E2V] = "E230-42";
string hd = isSPB2() ? "HD " : "";
string name = hd + chip_model[getChipType()];
if (isSPB1() && (getAdcBits() == 16))
name += " 16bit";
if (hasTaper())
name += "T";
DEB_RETURN() << DEB_VAR1(name);
return name;
}
......@@ -151,10 +151,8 @@ void SerialLine::readResp(string& buffer, int max_len, double timeout)
DEB_MEMBER_FUNCT();
DEB_PARAM() << DEB_VAR3(max_len, timeout, m_curr_op);
if (m_curr_op == None) {
DEB_FATAL() << "readLine without previous write!";
throw LIMA_HW_EXC(Error, "readLine without previous write");
}
if (m_curr_op == None)
THROW_HW_FATAL(Error) << "readLine without previous write!";
ReadRespCleanup read_resp_clenup(*this);
......@@ -230,10 +228,8 @@ void SerialLine::readMultiLine(string& buffer, int max_len)
}
}
if (buffer.empty()) {
DEB_ERROR() << "Timeout reading multi-line";
throw LIMA_HW_EXC(Error, "Timeout reading Frelon multi line");
}
if (buffer.empty())
THROW_HW_ERROR(Error) << "Timeout reading Frelon multi-line";
}
bool SerialLine::isRegCacheable(Reg reg)
......@@ -304,7 +300,8 @@ void SerialLine::splitMsg(const string& msg,
RegEx::FullNameMatchType match;
if (!re.matchName(msg, match))
throw LIMA_HW_EXC(InvalidValue, "Invalid Frelon message");
THROW_HW_ERROR(InvalidValue) << "Invalid Frelon message: "
<< DEB_VAR1(msg);
typedef pair<MsgPart, string> KeyPair;
static const KeyPair key_list[] = {
......@@ -335,17 +332,14 @@ void SerialLine::decodeFmtResp(const string& ans, string& fmt_resp)
"E\a?:(?P<err>[^\r]+))\r\n");
RegEx::FullNameMatchType match;
if (!re.matchName(ans, match)) {
DEB_ERROR() << "Unexpected Frelon answer";
throw LIMA_HW_EXC(Error, "Unexpected Frelon answer");
}
if (!re.matchName(ans, match))
THROW_HW_ERROR(Error) << "Unexpected Frelon answer: "
<< DEB_VAR1(ans);
RegEx::SingleMatchType& err = match["err"];
if (err) {
string err_str(err.start, err.end);
string err_desc = string("Frelon Error: ") + err_str;
DEB_ERROR() << err_desc;
throw LIMA_HW_EXC(Error, err_desc);
THROW_HW_ERROR(Error) << "Frelon Error: " << err_str;
}
RegEx::SingleMatchType& warn = match["warn"];
......@@ -429,11 +423,9 @@ void SerialLine::writeRegister(Reg reg, int val)
if (ok && (cache_val == val)) {
DEB_TRACE() << "Value already in cache";
} else {
if (reg_str.empty()) {
DEB_ERROR() << "Invalid register reg=" << reg;
throw LIMA_HW_EXC(InvalidValue, "Invalid register");
}
if (reg_str.empty())
THROW_HW_ERROR(InvalidValue) << "Invalid "
<< DEB_VAR1(reg);
ostringstream cmd;
cmd << reg_str << val;
string resp;
......@@ -454,11 +446,9 @@ void SerialLine::readRegister(Reg reg, int& val)
if (ok) {
DEB_TRACE() << "Using cache value";
} else {
if (reg_str.empty()) {
DEB_ERROR() << "Invalid register reg=" << reg;
throw LIMA_HW_EXC(InvalidValue, "Invalid register");
}
if (reg_str.empty())
THROW_HW_ERROR(InvalidValue) << "Invalid "
<< DEB_VAR1(reg);
string resp;
sendFmtCmd(reg_str + "?", resp);
istringstream is(resp);
......
include ../../common/espia/include/espia.inc
frelon-objs = FrelonBase.o FrelonSerialLine.o FrelonCamera.o FrelonInterface.o
frelon-objs = FrelonBase.o FrelonSerialLine.o FrelonModel.o FrelonCamera.o \
FrelonInterface.o
SRCS = $(frelon-objs:.o=.cpp)
......
include ../../../config.inc
frelon-objs = ../src/Frelon.o ../../common/espia/src/Espia.o \
../../../hardware/src/Hw.o ../../../common/src/Common.o
ct-objs = ../../../control/src/Ct.o
SRCS = testfrelon.cpp testfreloninterface.cpp testfrelonspectroscopy.cpp \
testfreloncontrol.cpp
include ../../common/espia/include/espia.inc
LDFLAGS = -pthread -L$(ESPIA_DRV_LIB) -L../../../third-party/Processlib/build