Commits (42)
LIMA Release Notes
This is the release notes of LIMA, the library for image acquisition.
You can find information releated to new features and bug fixes. The notes are ordered by branch and release number.
The notes are prefixed with a category name for core, subsystems image/saving/processlib/..., camera names andor/andor3/basler..., windows, applications tango python/tango c++/spec and third-party submodules sps/processlib/...
Stable branch core-1.6
core-1.6.2 2016-09-29
* tango python: added support for edf.lz4
* basler: Merge pull request for new initialisation with serial number, user name or IP address.
* pixirad: documentation updated, final cleanup of the code.
Bug fixes
* image: fixed getRoi, returns now full frame roi if no roi was set.
core-1.6.1 2016-08-04
* maxipix: added initialization sequence in PriamSerial contructor in case of cold start.
* andor: added enum type for BaselineClamp()
* tango python andor: updated properties vs_speed/p_gain/adc_speed to DevString type as for the attributes
Changed baseline_clamp property/attribute to DevString type
Managed UNSUPPORTED enum for baseline_clamp/high_capacity/fan_mode property/attributes
Removes label for all attributes (default is now label = attribute name) * Updated the doc/index.rst documentation
for new/changed properties/attributes
Bug fixes
* core: buildfix on arm
* andor: fixed inverted enum value for BaselineClamp
* tango python: fix in LimaCCDs configStore() command, now it accepts a list of module names
* andor: fixed a bug in getImageType() throwing exception in some conditions
core-1.6.0 2016-05-23
* marccd: merged marccd from esrf
* merlin: new plugin for Merlin camera family
* pco: windows 64 version working
* xapd: refactoring and new version delivered
* sps: move Sps project to github.com
* maxipix: c++ version delivered !!
* spec: added a new hook for user macros (user2_) for add and remove of roicoutner, for further use like for zap pseudo counter.
* core: accumulation, use sse register to sum 16 bits images (optimization)
* core: prepare optimization, for linux just retrieved memory pages instead of clearing all memory.
* pixirad: new camera plugin for Pixirad camera family
* rayonixhs: a new readout mode been added, HDR16, thanks to the latest rayonix craydl sdk update.
* dexela: linux version available
* saving: add lz4 compression for edf format
* saving: changed the buffer write size to optimize GPFS throughput,
this optimization was done for cbf and edf
* perkinelmer: new version to manage XRD_1611_CP3
* tango python: added tiff as saving format
* core: Synchronize with ImageStatusCallbacks at the beginning of prepareAcq
Added CtControl::set/getPrepareTimeout methods (default 2 sec)
Include Simulator test_prepare_timeout.py script
* frelon: added Frelon::Camera::DeadTimeChangedCallback to notify Lima (Sync) about changes
in the detector-defined min_lat_time (valid_ranges)
Added Frelon TimeCalc and Acc. Mode test Python scripts
Added Frelon Readout & Charge-Transfer times by means of float registers * Frelon::SyncCtrlObj
latency time now includes the detector dead time
* core: support dynamic min_latency_time with Accumulation in CtAcquisition
* andor3: compressed data (Mono12Packed) speed up acquisition and IntTrigMult trigger mode added
* imxpad: stable version working with XpadServer version 3.0.X
* background subtraction: add constant offset before subtraction to avoid data truncated to 0
* eiger: new version with stream and hardware saving tested
* eiger: added camera module (hardware saving + stream)
* saving: Could now disable the directory event feature
add frames per file parameters in hardware saving
* tango: split python and cpp server into two submodules
* v4l2:f ixed pb when calling prepareAcq() several times
now start in the native camera video mode. fixed setMode
* ueye: patched for new sdk (4.61)
* prosilica: new version with monitor mode
* core: Manage monitor mode for cameras like prosilica or basler
* imxpad: for server version 3.X
* accumulation: enhanced Accumulation and acc_mode with new mode for threshold and/or offset correction.
Updated Spec and Tango for that purpose too.
* spec: add new accumulation mode for threshold and/or offset correction
* simulator: add IntTrigMulti capability
* saving: add timestamp in Nexus file
* v4l2: new camera plugin v4l2 now managed.
* CCfits and cfitsio: configure script will be called only once
* accumulation: extend accumulation algorithm to be able to ignore noise lower than a threshold
* added extr module type CameraPlugin for exception
* added extra path for future maxipix_c++ in configure.py
Bug Fixes
* core: accumulation, fixed a memory allocation.
* basler: external trigger fixed for ace,scout and pilot cameras
* imxpad: camWaitAcqEnd remove from prepareAcq and startAcq, waiting time move to 1s for camWaitAcqEnd()
SetModuleMask function added allowing to acquire smaller images, Abort fixed when images are transfered via TCP
* marccd: Add Mutex to setImagePath/getImagePath/..., removed useless getNbAcquiredFrames()
* merlin:check status for detector idle before startAcq, added image resizing & (image stacking - Soleil request)
* pco: a lot of fixes !!
* pilatus: extra delay removed due to wrong test in internal trigger
* ueye: fixed image bytes depth for mono 12bits camera
* spec:fixed pb when removing a roicounter, now update properly LIMA_ROI_SRV * Set the RunLevel
to 5 to allow other tasks (mask/bgd/ff/..) to be applied before roicounter
* rayonixhs: added missing callback function call for readout mode change in image_type (bpp16<-->bpp32)
* core: ThreadUtils, moved thread id to protected
* tango python: windows, fixed path issue
* processlib: windows, fixed compilation issue
* core: fixed CPU overload bug in ImageStatusThread after registering multiple ImageStatusCallbacks
* core: fixed bug crashing when SyncCtrlObj is deleted before CtAcquisition
* image: disable roi when equal to full size (optimization)
* andor: fix for mt-safe in error exception handling
* saving: fixed checkValid() missing #ifdef for TIFF, only 1 frame per file supported
* image: fixed a infinite loop in checkDirectoryAccess() when dir is an empty string
* image: fixed in reevalutation with _setHSRoi
* andor3: fixed bugs with Bin/Roi, Bin can change the hw_roi with extra stride columns
fixed bug with Bin enum. and bug with getBin
* buffer: memory management, avoid allocating memory if hardware saving is activated (optimization)
* image: reevaluate software roi when binning change
* image: fixed bug with new monitor mode
* sip: replaced tabs with blanks, otherwise will not work with python 3.
* saving: take into account the frame id in the saving callback
* xh:use int32_t instead of long
remove polluting debug message
correct sip for getMaxFrames (use str::string instead of string)
added getMaxFrames
* windows: fix export in ValidRangesCallback
* espia: added Espia::BufferMgr::CamMultiFrameXferMode enumeration type
* maxipix: fixed bug in Maxipix priam port number, now range from 1 to 5
* tango python: fixed again wizard mode
* processlib: windows compilation + roi counters mask patch
* prosilica: fixed a bug with non-color camera continuous acquisition
* spec: fixed bug with getNames() call when server is stopped.
* CCfits: fixed installation path
* control: fixed deadlock in unregisterImageStatusCallback
* video: fixing dead lock when stopping and changing expo time.
* spec: limaroi_server_initarr: use only rois that are defined for the actual lima ccdname
* accumulation: fixed memory allocation.
Stable branch core-1.5
core-1.5.6 2015-12-21
* New tags for submodules: frelon-1.5.0/andor-1.5.0/pilatus-1.5.0
* Include Simulator test_prepare_timeout.py script
* Include COMPILE_MYTHEN3 into list of exported vars in config.inc_default
* frelon: Added Frelon native min_latency_time (Readout & Transfer) support
* control: Support dynamic min_latency_time with Accumulation in CtAcquisition
Bug Fixes
* control: Synchronize with ImageStatusCallbacks at the beginning of prepareAcq
* control: Added set/getPrepareTimeout methods (default 2 sec)
core-1.5.5 2015-12-11
* New tags for submodules: spec-1.4.7/andor3.1.5.1/tango-camera-andor3-1.5.1
* andor3: Compressed data (Mono12Packed) and IntTrigMult trigger mode
* tango python: andor3 updaded, no more destride attr
* spec: andor3 updaded, no more destride option
Bug Fixes
* image: fixed checkValid() missing #ifdef for TIFF, only 1 frame per file supported
* saving: Fixed a infinite loop in checkDirectoryAccess() when dir is an empty string
* image: fixed in reevalutation with _setHSRoi
* basler: external trigger fixes
* image: reevaluate software roi when binning change
core-1.5.4 2015-08-14
* New tags for submodules: Espia-1.5.1/maxipix-1.5.2/v4l2-1.5.3/ueye-1.5.0/tango-camera-andor3-1.5.0
Bug Fixes
* hdf5: revert install in Makefile
core.1.5.3 2015-08-12
* control: accumalation mode enhanced again
core-1.5.2 2015-07-27
* New tag for andor3 needs core-1.5 for using accumulation mode
* New tag for prosilica under core-1.5
* simulator: add IntTrigMulti capability
* Updated camera/prosilica
Bug Fixes
* control: fixed deadlock in unregisterImageStatusCallback
* video: fixing dead lock when stopping and changing expo time.
core-1.5.1 2015-06-19
* New tags: v4l2, basler, tango/camera/v4l2. basler-1.5.1/tango-camera-v4l2-1.5.1/v4l2-1.5.1
* Enhanced Accumulation and acc_mode with new mode for threshold and/or offset correction. Updated Spec and Tango for that purpose too.
* accumulation: extend accumulation algorithm to be able to ignore noise lower than a threshold
......@@ -135,28 +135,35 @@ mod_version_data = {
'rayonixhs': 'camera/rayonixhs/VERSION',
'v4l2': 'camera/v4l2/VERSION',
'xh': 'camera/xh/VERSION',
'pointgrey': 'camera/pointgrey/VERSION',
'pixirad': 'camera/pixirad/VERSION',
'dexela': 'camera/dexela/VERSION',
'meta': 'camera/common/meta/VERSION',
'spec': 'applications/spec/VERSION',
'taco/camera/frelon': 'applications/taco/VERSION',
'tango/common': 'applications/tango/VERSION',
'tango/camera/maxipix': 'applications/tango/camera/Maxipix_VERSION',
'tango/camera/pilatus': 'applications/tango/camera/Pilatus_VERSION',
'tango/camera/frelon': 'applications/tango/camera/Frelon_VERSION',
'tango/camera/basler': 'applications/tango/camera/Basler_VERSION',
'tango/camera/prosilica': 'applications/tango/camera/Prosilica_VERSION',
'tango/camera/andor': 'applications/tango/camera/Andor_VERSION',
'tango/camera/andor3': 'applications/tango/camera/Andor3_VERSION',
'tango/camera/perkinelmer': 'applications/tango/camera/PerkinElmer_VERSION',
'tango/camera/xpad': 'applications/tango/camera/Xpad_VERSION',
'tango/camera/pco': 'applications/tango/camera/Pco_VERSION',
'tango/camera/ueye': 'applications/tango/camera/Ueye_VERSION',
'tango/camera/simulator': 'applications/tango/camera/Simulator_VERSION',
'tango/camera/roperscientific': 'applications/python/tango/camera/RoperScientific_VERSION',
'tango/common': 'applications/tango/python/VERSION',
'tango/camera/maxipix': 'applications/tango/python/camera/Maxipix_VERSION',
'tango/camera/pilatus': 'applications/tango/python/camera/Pilatus_VERSION',
'tango/camera/frelon': 'applications/tango/python/camera/Frelon_VERSION',
'tango/camera/basler': 'applications/tango/python/camera/Basler_VERSION',
'tango/camera/prosilica': 'applications/tango/python/camera/Prosilica_VERSION',
'tango/camera/andor': 'applications/tango/python/camera/Andor_VERSION',
'tango/camera/andor3': 'applications/tango/python/camera/Andor3_VERSION',
'tango/camera/perkinelmer': 'applications/python/tango/camera/PerkinElmer_VERSION',
'tango/camera/xpad': 'applications/tango/python/camera/Xpad_VERSION',
'tango/camera/pco': 'applications/tango/python/camera/Pco_VERSION',
'tango/camera/ueye': 'applications/tango/python/camera/Ueye_VERSION',
'tango/camera/simulator': 'applications/tango/python/camera/Simulator_VERSION',
'tango/camera/roperscientific': 'applications/tango/python/camera/RoperScientific_VERSION',
'tango/camera/v4l2': 'applications/tango/python/camera/V4l2_VERSION',
'tango/camera/xh': 'applications/tango/python/camera/Xh_VERSION',
'tango/camera/rayonixhs': 'applications/tango/python/camera/RayonixHs_VERSION',
'tango/camera/pointgrey': 'applications/tango/python/camera/PointGrey_VERSION',
'tango/camera/pixirad': 'applications/tango/python/camera/Pixirad_VERSION',
'tango/camera/dexela': 'applications/tango/python/camera/Dexela_VERSION',
windows_plugins = ['pco', 'perkinelmer']
windows_plugins = ['perkinelmer']
all_submodules = []
modified_submodules = []
base_mod_depend = {'espia': ['frelon', 'maxipix']}
Subproject commit a5b9be5efd7916a28cf0ab06fcc6f17e19194605
Subproject commit 65690d3b7d24783256b279542a796c8a8a3f795f
Subproject commit ff318c2d96e076cdcd9d1696ef32546e098acbd0
Subproject commit 75531aaf9bcda8b27a09b92cf355307847835d6c
Subproject commit 3fd7cae1890e9137dd619806a546441613451e51
Subproject commit e056b619aa8312d11fea357bb857cdb2aeed3815
Subproject commit 80e3bca060b1d2acd29551c9ca7b1b0b032723fb
Subproject commit 0cd1373e3a86114dd61cd463e7cd507244e24b56
Subproject commit 4f66bf26f270a5807bf2ecb2b0ebadcb7f91589d
Subproject commit 15fb34b8c91944fd14ae7a0c0e21fa5ee65f58da
Subproject commit 0e5b9306a3aae2002c80850eac4c158375913b66
Subproject commit 96146499930bd00adc73794e5d7c09a339a0dfc5
Subproject commit 50a1015660c8c13147560dde7d4b328df465aed9
Subproject commit ed83d4c4bbbd7bea4b8e254f1daa68adade4a395
Subproject commit 27ae0081024378ae249ba7173a4c6a17c6fb28e9
Subproject commit 7417bd9b7566e08fbbf61b04caccc8ab8702de48
Subproject commit 07496b95f1f09a56a055aca3cb32f5a830decbf2
Subproject commit 04b117bb8cdc54d4067122f32d8f8e9290437bb3
Subproject commit 65dac9aab50c13577dfc3134c30bc14ead7b26cc
Subproject commit 41a247e681940ba4d37bb4a4058ffeaaea8e9681
Subproject commit b8f551eab71af1fda808819e26c1c786798cc085
Subproject commit d923c9b427eeb7025c14e630c16c3de7286a6bd6
Subproject commit 7a02725eb9cb74e89594df607187e1808a74a04f
Subproject commit 2a6518eeb505972e060e20dad2838cc1397ea6f6
Subproject commit 1f78af2f5a1d43262899d4e01824352c7feaa43f
Subproject commit 3fae772ff9900d6940becca859d34b5faac067ac
Subproject commit 35e277de74e435725ade8dcfd227a0fdbae70dbc
Subproject commit dc0442e42ed4f2a974ccf9e1858d0664320f5310
Subproject commit 79121e19fcfcbbb847f8872a093546a0899ee177
Subproject commit 9e3ba2149c7f5f33335d22226a0b79cd5665b9bd
Subproject commit 28385da8cf9898c289244f70809403dfb87542dc
Subproject commit 9f6654c848858e72c292dfce49d039de801f883b
Subproject commit 293d42ef0f4d82e923733dbd8015a743e98eb677
Subproject commit 9bc5f38a6f720d8bdff0336494391a78440b7018
Subproject commit a782449dcd24a849c8e6d3a6db80b4b3df8dc4f8
Subproject commit fba4a36718a4b142f28710de2615a5f8b9b418e1
Subproject commit 55bda1c1c8ae76c66af685fcbcb4a1b442fe0fbe
Subproject commit c6c1bdf1806bd0c1ef206859ee50139b0da93768
Subproject commit f6e6cffd9af1022b07f87e33f9cb79fe2e5a1637
Subproject commit 65c609449ebe316a863ead5567ba9c25a289d8dd
Subproject commit d78f221cc350e9c3648e2962952b62aba79da915
Subproject commit dd4f9378082044c93586bf5f42747c9edef7f5ff
Subproject commit 02fe733d00e5c0731a1c56954b3dc50c19c692f3
Subproject commit 8b2f7e003c87210961fb2abce1df46c31d1a32f1
Subproject commit 4482e20806f9df0c1940d56afb14d6a4b8bd13f7
Subproject commit 13e641256c464792d8480fea60343639bdbdcb45
Subproject commit cbe3e8c5f749701ccee8553545aed8e63716d8e0
Subproject commit aecadc494adcae4f86c44d14fe3ec40d54096f37
Subproject commit b73c21d74983609cb9d04caf682dd9f2f67c0913
Subproject commit c502186bb93c8a690230903bf47244d1256570b4
Subproject commit cc06d18a5c924729ed90343ab8fef43cb44f1d00
Subproject commit eb4c4c25f87ec3e82481006f1c33e4ea37a79f64
Subproject commit 86725312f26481740a32e43756ac7242a8cd127c
Subproject commit 7d1b46a0874cc2b8ca4ab3fdbaa328aea410291e
Subproject commit b78dd2aeefc7d66f4b734fe413148e5414d0e2ff
Subproject commit 0c5c29faffd3fec69e4cdaa1ccc509dcad975a92
Subproject commit ccb7c8b5744101233dcc21a96e0e58ef035dad8b
Subproject commit 8a6ceb1567f87c7506e94e340d927aaaa64fee92
Subproject commit 901c07f5e71c8a7aa755c34d19221852b683a188
Subproject commit 7b24003b03525f3e81719a7d0b19f9911f90cdb3
Subproject commit 7e230c660031f8ab9d5a32a3fb323245dab38315
Subproject commit 134d2e1597fc03da0c6eb55798e1f8304877bcbe
......@@ -112,10 +112,11 @@ MemBuffer::MemBuffer(int size)
: m_size(0), m_ptr(NULL)
char* ptr = (char*)m_ptr;
#ifdef __unix
long page_size = sysconf(_SC_PAGESIZE);
#ifdef __SSE2__
char* ptr = (char*)m_ptr;
if(!((long)ptr & 15)) // aligned to 128 bits
__m128i zero = _mm_setzero_si128();
......@@ -23,6 +23,9 @@
#include "lima/CtAcquisition.h"
#include "lima/CtBuffer.h"
#include "processlib/SinkTask.h"
#include <algorithm>
using std::min;
using std::max;
#ifndef __unix
#include "processlib/SinkTaskMgr.i"
......@@ -579,8 +582,8 @@ void CtAccumulation::prepare()
max_nb_buffers = long(max_nb_buffers * double(image_depth) / sizeof(int));
if(m_pars.active) max_nb_buffers /= 2;
m_buffers_size = std::min(m_buffers_size,max_nb_buffers);
m_buffers_size = std::max(m_buffers_size,16L);
m_buffers_size = min(m_buffers_size,max_nb_buffers);
m_buffers_size = max(m_buffers_size,16L);
CtAcquisition *acquisition = m_ct.acquisition();
int acc_nframes;
......@@ -112,7 +112,7 @@ void CtSwBinRoiFlip::setRoi(const Roi& roi)
if (roi.isEmpty())
THROW_CTL_ERROR(InvalidValue) << "Software roi is empty";
if (!m_max_roi.containsRoi(roi))
THROW_CTL_ERROR(InvalidValue) << "Roi out of limts";
THROW_CTL_ERROR(InvalidValue) << "Roi out of limits" << DEB_VAR2(m_max_roi,roi);
m_roi= roi;
......@@ -221,7 +221,11 @@ CtHwBinRoiFlip::CtHwBinRoiFlip(HwInterface *hw, CtSwBinRoiFlip *sw_bin_roi, Size
m_max_size= size;
m_max_roi= Roi(Point(0,0), m_max_size / m_bin);
//WARNINGGGGGGGGGGGGGGGGGGGGGGGGG: called Roi() constructor is Roi(Point topleft, Point bottomright)
// becaus Size /Point -> Point and not Size !!!!
// So if size = 1024*1024 and m_bin = 1x1 then m_max_roi = 0,0 x 1025,1025
Size roi_size = m_max_size/m_bin;
m_max_roi= Roi(Point(0,0), roi_size);
m_size= m_max_size;
......@@ -753,6 +757,8 @@ void CtImage::_setHSBin(const Bin &bin)
DEB_PARAM() << DEB_VAR1(bin);
Roi user_roi;getRoi(user_roi);
Bin user_bin;getBin(user_bin);
if (m_hw->hasBinCapability()) {
Bin set_hw_bin = bin;
......@@ -764,7 +770,9 @@ void CtImage::_setHSBin(const Bin &bin)
Bin set_sw_bin= bin / set_hw_bin;
user_roi = user_roi.getUnbinned(user_bin);
user_roi = user_roi.getBinned(bin);
} else {
......@@ -790,15 +798,22 @@ void CtImage::_setHSRoi(const Roi &roi)
roi_unbin= roi.getUnbinned(bin_total);
roi_by_hw= roi_unbin.getBinned(bin_by_hw);
const Size& max_roi_size = m_hw->getMaxRoiSize();
// Remove the rotation to hardware Roi
RotationMode aSoftwareRotation = m_sw->getRotation();
roi_by_hw= roi_by_hw.getUnrotated(aSoftwareRotation,max_roi_size);
// Remove the software Flip to hardware Roi
const Flip &aSoftwareFlip = m_sw->getFlip();
roi_by_hw= roi_by_hw.getFlipped(aSoftwareFlip,max_roi_size);
roi_set_hw= roi_by_hw;
m_hw->setRoi(roi_set_hw, true);
DEB_TRACE() << DEB_VAR2(roi_by_hw, roi_set_hw);
_completeWithSoftRoi(roi_by_hw, roi_set_hw);
_completeWithSoftRoi(roi, roi_set_hw);
} else {
......@@ -809,30 +824,27 @@ void CtImage::_completeWithSoftRoi(Roi roi_set,Roi hw_roi)
DEB_PARAM() << DEB_VAR2(roi_set,hw_roi);
if (roi_set==hw_roi) {
} else {
const Size& max_roi_size = m_hw->getMaxRoiSize();
RotationMode aSoftwareRotation = m_sw->getRotation();
// Remove the rotation to hardware Roi
hw_roi= hw_roi.getUnrotated(aSoftwareRotation,max_roi_size);
// Remove the software Flip to hardware Roi
const Flip &aSoftwareFlip = m_sw->getFlip();
hw_roi= hw_roi.getFlipped(aSoftwareFlip,max_roi_size);
const Size& max_roi_size = m_hw->getMaxRoiSize();
// Apply software flip to hardware roi
roi_set = roi_set.getFlipped(aSoftwareFlip,max_roi_size);
hw_roi = hw_roi.getFlipped(aSoftwareFlip,max_roi_size);
//Apply software rotation to hardware roi
roi_set = roi_set.getRotated(aSoftwareRotation,max_roi_size);
hw_roi = hw_roi.getRotated(aSoftwareRotation,max_roi_size);
//Calc the roi by soft needed
Bin bin_by_sw = m_sw->getBin();
// First flip the hardware roi
const Flip &aSoftwareFlip = m_sw->getFlip();
Roi hw_roi_ref_soft= hw_roi.getFlipped(aSoftwareFlip,max_roi_size);
// than the rotation if needed to have the same referential than the soft roi
RotationMode aSoftwareRotation = m_sw->getRotation();
hw_roi_ref_soft = hw_roi_ref_soft.getRotated(aSoftwareRotation,max_roi_size);
if (roi_set.isEmpty() || roi_set==hw_roi_ref_soft) {
} else {
Roi roi_by_sw;
roi_by_sw= hw_roi.subRoiAbs2Rel(roi_set);
roi_by_sw= roi_by_sw.getBinned(bin_by_sw);
roi_by_sw = roi_set;
roi_by_sw = hw_roi_ref_soft.subRoiAbs2Rel(roi_set);
DEB_TRACE() << DEB_VAR1(roi_by_sw);
......@@ -927,8 +939,8 @@ void CtImage::resetBin()
Bin bin(1,1);
void CtImage::resetRoi()
......@@ -1014,6 +1026,12 @@ void CtImage::getRoi(Roi& roi) const
roi= m_sw->getRoi();
FrameDim dim;
roi = Roi(Point(0,0),dim.getSize());
DEB_RETURN() << DEB_VAR1(roi);
Subproject commit 682fb943ed73bb838973bafd34b6e8e91c6e91de
Subproject commit 690f821e0e51e345f9b441680c74f47942a1477a
Subproject commit a8f09804378695fcd1aae0c6afa25596415ee511
Subproject commit 9c757ac5b8edd533b1e02b72e4e1a4d51b0be052