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.