Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
LimaGroup
Lima-camera-slsdetector
Commits
1af420e6
Commit
1af420e6
authored
Jan 29, 2021
by
Alejandro Homs Puron
Committed by
operator for beamline
Feb 05, 2021
Browse files
Support multi-module Jungfrau detectors
* Support generic tiled detector configurations * Using sls::Geom helpers
parent
01949158
Changes
4
Hide whitespace changes
Inline
Side-by-side
include/SlsDetectorDefs.h
View file @
1af420e6
...
...
@@ -105,6 +105,8 @@ enum DetStatus {
Stopped
=
slsDetectorDefs
::
STOPPED
,
};
typedef
slsDetectorDefs
::
xy
xy
;
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
TrigMode
trig_mode
);
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
Settings
settings
);
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
DACIndex
dac_idx
);
...
...
include/SlsDetectorJungfrau.h
View file @
1af420e6
...
...
@@ -83,6 +83,30 @@ class Jungfrau : public Model
virtual
void
stopAcq
();
private:
class
Recv
{
DEB_CLASS_NAMESPC
(
DebModCamera
,
"Jungfrau::Recv"
,
"SlsDetector"
);
public:
typedef
Receiver
::
ImageData
RecvImageData
;
Recv
(
Jungfrau
*
jungfrau
,
int
idx
);
void
prepareAcq
();
bool
processOneFrame
(
FrameType
frame
,
char
*
bptr
);
void
processBadFrame
(
FrameType
frame
,
char
*
bptr
);
private:
Jungfrau
*
m_jungfrau
;
int
m_idx
;
bool
m_raw
;
Receiver
*
m_recv
;
FrameDim
m_frame_dim
;
int
m_data_offset
;
};
typedef
std
::
vector
<
AutoPtr
<
Recv
>
>
RecvList
;
class
Thread
:
public
lima
::
Thread
{
DEB_CLASS_NAMESPC
(
DebModCamera
,
"Jungfrau::Thread"
,
"SlsDetector"
);
...
...
@@ -134,6 +158,15 @@ class Jungfrau : public Model
};
typedef
std
::
vector
<
AutoPtr
<
Thread
>
>
ThreadList
;
int
getNbJungfrauModules
()
{
return
getNbDetModules
();
}
template
<
class
DG
>
Defs
::
xy
getModulePosition
(
const
DG
&
det_geom
,
int
idx
);
FrameDim
getModuleFrameDim
(
int
idx
,
bool
raw
);
int
getModuleDataOffset
(
int
idx
,
bool
raw
);
AutoMutex
lock
()
{
return
AutoMutex
(
m_cond
.
mutex
());
}
void
wait
()
...
...
@@ -144,17 +177,15 @@ class Jungfrau : public Model
bool
allFramesAcquired
()
{
return
m_next_frame
==
m_nb_frames
;
}
int
getNbRecvs
();
int
getNbProcessingThreads
();
void
setNbProcessingThreads
(
int
nb_proc_threads
);
void
processOneFrame
(
AutoMutex
&
l
);
static
const
int
ChipSize
;
static
const
int
ChipGap
;
static
const
int
HalfModuleChips
;
Cond
m_cond
;
Rec
eiver
*
m_recv
;
Rec
vList
m_recv
_list
;
FrameType
m_nb_frames
;
FrameType
m_next_frame
;
FrameType
m_last_frame
;
...
...
slsDetectorPackage
@
c985961e
Compare
586c9305
...
c985961e
Subproject commit
586c9305d9a8958aa3b3814502b7c6e9ac6734f6
Subproject commit
c985961ef61c7a0713094c2a72139a26feda96fe
src/SlsDetectorJungfrau.cpp
View file @
1af420e6
...
...
@@ -23,6 +23,8 @@
#include
"SlsDetectorJungfrau.h"
#include
"lima/MiscUtils.h"
#include
"sls/Geometry.h"
#include
<emmintrin.h>
#include
<sched.h>
...
...
@@ -31,9 +33,44 @@ using namespace lima;
using
namespace
lima
::
SlsDetector
;
using
namespace
lima
::
SlsDetector
::
Defs
;
const
int
Jungfrau
::
ChipSize
=
256
;
const
int
Jungfrau
::
ChipGap
=
2
;
const
int
Jungfrau
::
HalfModuleChips
=
4
;
Jungfrau
::
Recv
::
Recv
(
Jungfrau
*
jungfrau
,
int
idx
)
:
m_jungfrau
(
jungfrau
),
m_idx
(
idx
)
{
DEB_CONSTRUCTOR
();
DEB_PARAM
()
<<
DEB_VAR1
(
m_idx
);
Camera
*
cam
=
m_jungfrau
->
getCamera
();
m_recv
=
cam
->
getRecv
(
m_idx
);
}
void
Jungfrau
::
Recv
::
prepareAcq
()
{
DEB_MEMBER_FUNCT
();
m_jungfrau
->
getCamera
()
->
getRawMode
(
m_raw
);
m_frame_dim
=
m_jungfrau
->
getModuleFrameDim
(
m_idx
,
m_raw
);
m_data_offset
=
m_jungfrau
->
getModuleDataOffset
(
m_idx
,
m_raw
);
DEB_TRACE
()
<<
DEB_VAR3
(
m_idx
,
m_frame_dim
,
m_data_offset
);
}
bool
Jungfrau
::
Recv
::
processOneFrame
(
FrameType
frame
,
char
*
bptr
)
{
DEB_MEMBER_FUNCT
();
DEB_PARAM
()
<<
DEB_VAR2
(
m_idx
,
frame
);
RecvImageData
data
;
data
.
frame
=
frame
;
data
.
buffer
=
bptr
+
m_data_offset
;
return
m_recv
->
getImage
(
data
);
}
void
Jungfrau
::
Recv
::
processBadFrame
(
FrameType
frame
,
char
*
bptr
)
{
DEB_MEMBER_FUNCT
();
DEB_PARAM
()
<<
DEB_VAR2
(
m_idx
,
frame
);
if
(
!
m_raw
)
THROW_HW_ERROR
(
NotSupported
)
<<
"Bad Frames in assembled mode"
;
memset
(
bptr
+
m_data_offset
,
0xff
,
m_frame_dim
.
getMemSize
());
}
Jungfrau
::
Thread
::
Thread
(
Jungfrau
*
jungfrau
,
int
idx
)
:
m_jungfrau
(
jungfrau
),
m_idx
(
idx
)
...
...
@@ -112,12 +149,13 @@ Jungfrau::Jungfrau(Camera *cam)
DEB_CONSTRUCTOR
();
int
nb_det_modules
=
getNbDetModules
();
if
(
nb_det_modules
>
1
)
THROW_HW_ERROR
(
NotSupported
)
<<
"Multimodule not supported yet"
;
DEB_TRACE
()
<<
"Using Jungfrau detector, "
<<
DEB_VAR1
(
nb_det_modules
);
m_recv
=
cam
->
getRecv
(
0
);
for
(
int
i
=
0
;
i
<
nb_det_modules
;
++
i
)
{
Recv
*
r
=
new
Recv
(
this
,
i
);
m_recv_list
.
push_back
(
r
);
}
setNbProcessingThreads
(
1
);
...
...
@@ -130,17 +168,90 @@ Jungfrau::~Jungfrau()
getCamera
()
->
waitAcqState
(
Idle
);
}
#define applyDetGeom(f, raw) \
using namespace sls::Geom::Jungfrau; \
int ifaces; \
getNbUDPInterfaces(ifaces); \
auto any_nb_ifaces = AnyNbUDPIfacesFromNbUDPIfaces(ifaces); \
std::visit([&](auto nb) { \
constexpr int nb_udp_ifaces = nb; \
Defs::xy det_size = m_det->getDetectorSize(); \
auto any_geom = AnyDetGeomFromDetSize<nb_udp_ifaces>({det_size.x, \
det_size.y});\
std::visit([&](auto geom) { \
if (raw) \
f(geom.raw_geom); \
else \
f(geom.asm_wg_geom); \
}, any_geom); \
}, any_nb_ifaces);
void
Jungfrau
::
getFrameDim
(
FrameDim
&
frame_dim
,
bool
raw
)
{
DEB_MEMBER_FUNCT
();
DEB_PARAM
()
<<
DEB_VAR1
(
raw
);
Size
size
=
Point
(
ChipSize
,
ChipSize
)
*
Point
(
HalfModuleChips
,
2
);
if
(
!
raw
)
size
+=
Point
(
ChipGap
,
ChipGap
)
*
Point
(
3
,
1
);
Size
size
;
auto
f
=
[
&
](
auto
det_geom
)
{
size
=
Size
(
det_geom
.
size
.
x
,
det_geom
.
size
.
y
);
DEB_TRACE
()
<<
DEB_VAR1
(
size
);
};
applyDetGeom
(
f
,
raw
);
frame_dim
=
FrameDim
(
size
,
Bpp16
);
DEB_RETURN
()
<<
DEB_VAR1
(
frame_dim
);
}
template
<
class
DG
>
Defs
::
xy
Jungfrau
::
getModulePosition
(
const
DG
&
det_geom
,
int
idx
)
{
DEB_MEMBER_FUNCT
();
DEB_PARAM
()
<<
DEB_VAR1
(
idx
);
Defs
::
xy
mod_pos
;
auto
det_mods
=
det_geom
.
det_mods
;
// module ID is column-wise
mod_pos
.
x
=
idx
/
det_mods
.
y
;
mod_pos
.
y
=
idx
%
det_mods
.
y
;
DEB_RETURN
()
<<
DEB_VAR2
(
mod_pos
.
x
,
mod_pos
.
y
);
return
mod_pos
;
}
FrameDim
Jungfrau
::
getModuleFrameDim
(
int
idx
,
bool
raw
)
{
DEB_MEMBER_FUNCT
();
DEB_PARAM
()
<<
DEB_VAR2
(
idx
,
raw
);
Size
size
;
auto
f
=
[
&
](
auto
det_geom
)
{
auto
mod_geom
=
det_geom
.
getModGeom
({
0
,
0
});
bool
last_x
=
true
;
// only raw mode supported
bool
last_y
=
(
idx
==
getNbJungfrauModules
()
-
1
);
size
=
Size
(
!
last_x
?
det_geom
.
mod_step
.
x
:
mod_geom
.
size
.
x
,
!
last_y
?
det_geom
.
mod_step
.
y
:
mod_geom
.
size
.
y
);
DEB_TRACE
()
<<
DEB_VAR1
(
size
);
};
applyDetGeom
(
f
,
raw
);
FrameDim
frame_dim
(
size
,
Bpp16
);
DEB_RETURN
()
<<
DEB_VAR1
(
frame_dim
);
return
frame_dim
;
}
int
Jungfrau
::
getModuleDataOffset
(
int
idx
,
bool
raw
)
{
DEB_MEMBER_FUNCT
();
DEB_PARAM
()
<<
DEB_VAR2
(
idx
,
raw
);
int
data_offset
;
auto
f
=
[
&
](
auto
det_geom
)
{
auto
mod_pos
=
getModulePosition
(
det_geom
,
idx
);
auto
mod_view
=
det_geom
.
getModView
({
mod_pos
.
x
,
mod_pos
.
y
});
auto
origin
=
mod_view
.
calcViewOrigin
();
int
pixel_offset
=
mod_view
.
calcMapPixelIndex
(
origin
);
data_offset
=
pixel_offset
*
sls
::
Geom
::
Pixel16
::
depth
();
DEB_TRACE
()
<<
DEB_VAR1
(
data_offset
);
};
applyDetGeom
(
f
,
raw
);
DEB_RETURN
()
<<
DEB_VAR1
(
data_offset
);
return
data_offset
;
}
string
Jungfrau
::
getName
()
{
DEB_MEMBER_FUNCT
();
...
...
@@ -334,6 +445,14 @@ void Jungfrau::getThresholdEnergy(int& thres)
DEB_RETURN
()
<<
DEB_VAR1
(
thres
);
}
int
Jungfrau
::
getNbRecvs
()
{
DEB_MEMBER_FUNCT
();
int
nb_recvs
=
m_recv_list
.
size
();
DEB_RETURN
()
<<
DEB_VAR1
(
nb_recvs
);
return
nb_recvs
;
}
void
Jungfrau
::
setNbProcessingThreads
(
int
nb_proc_threads
)
{
DEB_MEMBER_FUNCT
();
...
...
@@ -390,6 +509,10 @@ void Jungfrau::prepareAcq()
m_last_frame
=
-
1
;
}
RecvList
::
iterator
rit
,
rend
=
m_recv_list
.
end
();
for
(
rit
=
m_recv_list
.
begin
();
rit
!=
rend
;
++
rit
)
(
*
rit
)
->
prepareAcq
();
ThreadList
::
iterator
tit
,
tend
=
m_thread_list
.
end
();
for
(
tit
=
m_thread_list
.
begin
();
tit
!=
tend
;
++
tit
)
(
*
tit
)
->
prepareAcq
();
...
...
@@ -447,11 +570,20 @@ void Jungfrau::processOneFrame(AutoMutex& l)
{
AutoMutexUnlock
u
(
l
);
Receiver
::
ImageData
data
;
data
.
frame
=
frame
;
data
.
buffer
=
getFrameBufferPtr
(
frame
);
if
(
!
m_recv
->
getImage
(
data
))
std
::
bitset
<
64
>
ok
;
int
nb_recvs
=
getNbRecvs
();
if
(
nb_recvs
>
64
)
THROW_HW_ERROR
(
Error
)
<<
"Too many receivers"
;
char
*
bptr
=
getFrameBufferPtr
(
frame
);
for
(
int
i
=
0
;
i
<
nb_recvs
;
++
i
)
ok
[
i
]
=
m_recv_list
[
i
]
->
processOneFrame
(
frame
,
bptr
);
if
(
ok
.
none
())
return
;
for
(
int
i
=
0
;
i
<
nb_recvs
;
++
i
)
if
(
!
ok
[
i
])
m_recv_list
[
i
]
->
processBadFrame
(
frame
,
bptr
);
}
if
((
int
(
m_last_frame
)
==
-
1
)
||
(
frame
>
m_last_frame
))
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment