The readout framework supports a hierachical organization of
scalers using two classes CScaler
which
is intended to represent a single scaler module (but need not),
and CScalerBank
a CScaler
into which CScaler
objects including
CScalerBank
objects can be put.
Thus a CScalerBank
is to CScaler
as a CCompoundEventSegment
is to
CEventSegment
objects.
The interface of a CScaler
is similar to that
of a CScaler
:
read
All other methods are completely analagous
to their counterparts in CEventSegment
.
read
is as well, however
it is supposed to return a vector of uint32_t
values that are the scalers it reads.
The framework will append this set of values to the final set of scalers it will report to the RingDaq.
So lets look at a simple CScaler
. In
this case we will be building a CScaler
class that manages a single SIS 3820 scaler module.
First the header for the class:
Example 2-10. CScaler
header
#include <CScaler.h> class CSIS3820; class CSIS3820Scaler : public CScalerprivate: CSIS3820* m_pScaler;
public: CSIS3820Scaler(unsigned long base, int crate = 0);
~CSIS3820Scaler(); // The interface required by the CScaler class: public:
virtual void initialize(); virtual void clear(); virtual std::vector<uint32_t> read(); };
CEventSegment
discussion.
The CSIS3820Scaler
class must
be derived from the CScaler
class
in order to be registered to read scalers with the
readout framework.
CSIS3820
object that will
be used to talk to the scaler module we are reading.
CEventSegment
since we are going
to dynamically create the scaler module class, we need
to declare a destructor to allow us to destroy it when
our object is destroyed.
CScaler
base class that will
be implemented by CSIS3820Scaler
.
This must be at least the read
method as that is abstract in CScaler
.
As before, let's look at the implementation in logical pieces. The front matterr is a few #include directives to pull in the headers we need:
Example 2-11. CSIS3820Scaler
implementation includes section
#include <config.h> #include "CSIS3820Scaler.h" #include <CSIS3820.h> #include <iostream> #include <vector>
The constructor and destructor are pretty simple as well:
Example 2-12. CSIS3820Scaler
constructor/destructor
CSIS3820Scaler::CSIS3820Scaler(unsigned long base, int crate) : m_pScaler(new CSIS3820(base, crate)){ } CSIS3820Scaler::~CSIS3820Scaler() { delete m_pScaler;
}
Next lets look at the initialize
and
clear
methods as they are relatively
short.
Example 2-13. CSIS3820Scaler
initialize/clear methods
void CSIS3820Scaler::initialize() { m_pScaler->setOperatingMode(CSIS3820::LatchingScaler);m_pScaler->setLatchSource(CSIS3820::LatchVMEOnly); m_pScaler->EnableClearOnLatch();
m_pScaler->Enable();
m_pScaler->Arm(); } void CSIS3820Scaler::clear() { m_pScaler->ClearChannels();
}
![]() | Clears |
---|---|
The way in which this module is being cleared is not techincally
correct. The module supports a clear on latch. As coded,
the scalers will be cleared a read time and then a bit later
when
The correct way to handl this module is to clear it
at initialization time and then not to provide a
|
The std::vector
class makes it pretty
easy to write the read
method as well.
Example 2-14. CSIS3820Scaler
read
std::vector<uint32_t> CSIS3820Scaler::read() { std::vector<uint32_t> result;uint32_t channels[32];
m_pScaler->LatchAndRead(reinterpret_cast<unsigned long*>(channels));
result.insert(result.begin(), channels, channels + 32);
return result; }
read
method must return an
std::vector
. This declares
storage for that vector.
LatchAndRead
function
we use below will read the 32 channels of the module into
an ordinary storage array. Therefore wwe need to declare
one here to hold that output.
channels
std::vector::insert
method is then used to put the scaler channel values
into the result vector which is returned.
Before leaving this discussion of scalers lets take a short
tour of the CScalerBank
class.
This class allows us to group several CScaler
objects
into a single scaler-like object.
Suppose we have several SIS 3820 scaler modules. In a detector system. The example below organizes them into a single scaler bank which we can hand out as our detector system's scaler.
Example 2-15. Creating a scaler bank
... CSIS3820Scaler sc1(0x80000000); CSIS3820Scaler sc2(0x80010000); CSIS3820Scaler sc3(0x80020000); CScalerBank myDetectorScalers; myDetectorScalers.AddScalerModule(&sc1); myDetectorScalers.AddScalerModule(&sc2); myDetectorScalers.AddScalerModule(&sc3); ...
Naturally since, CScalerBank
objects
are themselves derived from CScaler
they
can be added, in turn, to other scaler banks.