This section contains the files that make up the Readout software in their entirety. We include the Makefiles and scripts as well as the C++ source code. This software is also available online at http://docs.nscl.msu.edu/daq/samples/CAENV785/CAENV785.zip
Example 5-1. MyEventSegment.h
/* This is the header file to define the MyEventSegment class, which is derived from CEventSegment. This class can be used to read out any number of CAEN modules covered by the CAENcard class. Those cards include the V785, V775, and V792. Tim Hoagland 11/3/04 s04.thoagland@wittenberg.edu */ #ifndef __MYEVENTSEGMENT_H // co:protect #define __MTEVENTSEGMENT_H #ifdef HAVE_STD_NAMESPACE using namespace std; // co:namespace #endif #include <spectrodaq.h> #include <CEventSegment.h> #include <CDocumentedPacket.h> #include <CAENcard.h> #define CAENTIMEOUT 50 // Declares a class derived from CEventSegment class MyEventSegment : public CEventSegment // co:eventsegderived { private: CDocumentedPacket m_MyPacket; // co:docpacket CAENcard* module; // co:hardwareobject public: MyEventSegment(short slot,unsigned short Id); // co:mysegconstructor // Defines packet info ~MyEventSegment(); // co:mysegdestructor virtual void Initialize(); // co:myseginit // One time Module setup virtual void Clear(); // co:mysegclear // Resets data buffer virtual unsigned int MaxSize(); // co:mysegobsoletemaxsize virtual DAQWordBufferPtr& Read(DAQWordBufferPtr& rBuf); // co:mysegread // Reads data buffer }; #endif
Example 5-2. MyEventSegment.cpp
/* This software is Copyright by the Board of Trustees of Michigan State University (c) Copyright 2005. You may use this software under the terms of the GNU public license (GPL). The terms of this license are described at: http://www.gnu.org/licenses/gpl.txt Author: Ron Fox NSCL Michigan State University East Lansing, MI 48824-1321 */ /* This is the implementation file for the MyEventSegment class. This class defines funtions that can be used to readout any module covered in the CAENcard class. These include the V785, V775, and V792 Tim Hoagland 11/3/04 s04.thoagland@wittenberg.edu */ #include <config.h> #ifdef HAVE_STD_NAMESPACE // co:boilerplate using namespace std; #endif #include "MyEventSegment.h" // co:myheader static char* pPacketVersion = "1.0"; // co:packetversion // Packet version -should be changed whenever major changes are made // to the packet structure. //constructor set Packet details MyEventSegment::MyEventSegment(short slot, unsigned short Id): m_MyPacket(Id, string("My Packet"), string("Sample documented packet"), string(pPacketVersion)) // co:packetinit { module = new CAENcard(slot); // co:cardcreate } // Destructor: MyEventSegment::~MyEventSegment() { delete module; // co:destroy } // Is called right after the module is created. All one time Setup // should be done now. void MyEventSegment::Initialize() { module->reset(); // co:moduleInit Clear(); } // Is called after reading data buffer void MyEventSegment::Clear() { module->clearData(); // Clear data buffer co:cleardata } unsigned int MyEventSegment::MaxSize() { return 0; } //Is called to readout data on module DAQWordBufferPtr& MyEventSegment::Read(DAQWordBufferPtr& rBuf) { for(int i=0;i<CAENTIMEOUT;i++) // co:waitready // Loop waits for data to become ready { if(module->dataPresent()) // If data is ready stop looping { break; } } if(module->dataPresent()) // Tests again that data is ready { rBuf = m_MyPacket.Begin(rBuf); // co:openpacket // Opens a new Packet module->readEvent(rBuf); // co:readdata // Reads data into the Packet rBuf= m_MyPacket.End(rBuf); // co:closepacket // Closes the open Packet } return rBuf; // co:returnpointer }
Example 5-3. Skeleton.cpp
/* This software is Copyright by the Board of Trustees of Michigan State University (c) Copyright 2005. You may use this software under the terms of the GNU public license (GPL). The terms of this license are described at: http://www.gnu.org/licenses/gpl.txt Author: Ron Fox NSCL Michigan State University East Lansing, MI 48824-1321 */ /* This file was modified to readout segments from the MyEventSegment class. It is set to read only one card although that is easily changed. Tim Hoagland 11/3/04 s04.thoagland@wittenberg.edu Modified to be an 8.1 example Ron Fox 3/28/2006 fox@nscl.msu.edu */ static const char* Copyright = "(C) Copyright Michigan State University 2002, All rights reserved"; // This file contains a test readout system. // It derives from the CReadoutMain class // to setup our experiment specific requirements // creates an instance of it and lets the base classes // do most of the work: #include <config.h> // co:config #include <CReadoutMain.h> #include <CExperiment.h> #include <CInterpreterStartup.h> #include <CInterpreterCore.h> #include <CRunVariableCommand.h> #include <CRunVariable.h> #include <CStateVariableCommand.h> #include <CStateVariable.h> #include <TCLInterpreter.h> #include <CDAQTCLProcessor.h> #include <CVMEScalerLRS1151.h> #include <CTraditionalEventSegment.h> #include <CTraditionalScalerReadout.h> #include <CEventSegment.h> #include "MyEventSegment.h" // co:myeventseginclude #ifdef HAVE_STD_NAMESPACE using namespace std; // co:stdnamespace #endif // Added MyEventSegement Header File /*! Sample implementation of an experiment specific1 tailoring of the production readout software. */ class CMyExperiment : public CReadoutMain { public: // Constructors and other canonical operations: CMyExperiment() { } virtual ~CMyExperiment() { } // Copy construction, assignment and comparison // make no sense and are therefore disallowed: private: CMyExperiment(const CMyExperiment& rhs); CMyExperiment& operator=(const CMyExperiment& rhs); int operator==(const CMyExperiment& rhs); int operator!=(const CMyExperiment& rhs); public: // The member functions below allow us to override/extend base // class behavior for experiment specific stuff. protected: virtual void SetupReadout(CExperiment& rExperiment); virtual void SetupScalers(CExperiment& rExperiment); public: virtual void SetupRunVariables(CExperiment& rExperiment, CInterpreterStartup& rStartup, CInterpreterCore& rCore); virtual void SetupStateVariables(CExperiment& rExperiment, CInterpreterStartup& rStartup, CInterpreterCore& rCore); virtual void AddUserCommands(CExperiment& rExperiment, CInterpreterStartup& rStartup, CInterpreterCore& rCore); }; // The system relies on a globally accessible instance of a CReadoutMain // derived object called MyApp so here it is: CMyExperiment MyApp; /*! In SetupReadout, you are expected to add Event segments to your experiment. Event segments read out logical sections of your experiment. The following types of event segments are available for your use: - Simple event segments: These are derived from the abstract base class CEventSegment, and are intended to readout a coherent piece of an experiment. - Compatibility mode segments: These are objects of type CTraditionalEventSegment they provide all the callouts to code that lives in an old-style skeleton.cpp file. You will need to modify the skeleton makefile to add the oldstyle skeleton.cpp to the build. There can be only one CTraditionalEventSegment in the system due to function naming. - Compound segments: These are objects of type CCompoundEventSegment They consist of an ordered list of event segments of any type (including if you like other compound event segments. \param rExperiment - CExperiment& - A reference to the experiment object that runs the readout. You will normally be making calls to CExperiment::AddEventSegment to register your own event segments in the experiment readout */ void CMyExperiment::SetupReadout(CExperiment& rExperiment) // co:setupreadout { CReadoutMain::SetupReadout(rExperiment); rExperiment.AddEventSegment(new MyEventSegment(10, 0xff00)); // co:addmysegment // Make a new object of type MyEventSegment(slot#, ID) } /*! This function allows you to describe your scaler readout configuration. This is done by inserting scalers into the experiment object. Scalers come in the following flavors (all derived from CScaler - CCAMACScalerLRS2551 - CAMAC LeCroy model 2551 12 channel scalers. - CCAMACScalerLRS4434 - CAMAC LeCroy model 4434 32 channel scalers. - CVMEScalerCAENV830 - VME CAEN model V830 32 channel scalers. - CVMEScalerLRS1151 - VME LeCroy model 1151 scalers. - CScalerBank - A collection of scalers sequentially read out. \param rExperiment - CExperiment& reference to the experiment object. Normally you will call CExperiment::AddScalerModule to add scaler modules to the readout. */ void CMyExperiment::SetupScalers(CExperiment& rExperiment) // co:setupscalers { CReadoutMain::SetupScalers(rExperiment); // Insert your code below this comment. // For test,setup an LRS 1151 at 0x200c00 // CScaler* pScaler = new CVMEScalerLRS1151(0xc00200); // rExperiment.AddScalerModule(pScaler); } /*! In this function create and define any run variables you need. A run variable is a TCL Variable whose value is logged to the event stream. Run variables are always modifiable. If, for example, you have a thermocouple that is monitoring the temperature of a temperature senstive detector, you could create a RunVariable, monitor the temperature periodically and update the RunVariable. See CRunVariable and CRunVariableCommand Run variables can also be create at the command line using the runvar command. \param rExperiment - CExperiment& the experiment object. \param rStartup - CInterpreterStartup& the interpreter startup object. \param rCore - CInterpreterCore& the core TCL interpreter add on functionality. Normally you will obtain the run variable command object and do CRunVariableCommand::Create calls to add your run variables. \note The base class creates key run variables. It is therefore very important to be sure the base class version of this function is called. */ void CMyExperiment::SetupRunVariables(CExperiment& rExperiment, CInterpreterStartup& rStartup, CInterpreterCore& rCore) { CReadoutMain::SetupRunVariables(rExperiment, rStartup, rCore); CRunVariableCommand& rCommand(*(rCore.getRunVariables())); // Add your code below this commet. rCommand is a reference to the run variable // commands object. } /* This function allows you to create run state variables. Run state variables are TCL variables that are write locked during a run. Their values are logged to run state variable buffers at run state transitions. An example of a run state variable is the run number; created by the base class. An example of run variables you might like to create are fixed run conditions, such as beam species, energy, target species, trigger conditions etc. The Tcl command statevar can also be used to create list and delete state variables. \param rExperiment - CExperiment& the experiment object. \param rStartup - CInterpreterStartup& the interpreter startup object. \param rCore - CInterpreterCore& the core TCL interpreter add on functionality. Normally you will obtain the state variable command object and do CStateVariableCommand::Create calls to add your run variables. \note The base class creates key run variables. It is therefore very important to be sure the base class version of this function is called. */ void CMyExperiment::SetupStateVariables(CExperiment& rExperiment, CInterpreterStartup& rStartup, CInterpreterCore& rCore) { CReadoutMain::SetupStateVariables(rExperiment, rStartup, rCore); CStateVariableCommand& rCommand(*(rCore.getStateVariables())); // Insert your code below this comment. Note that rCommand is the // state variable command object. } /*! Add user written commands in this function. User written commands should be objects derived from CDAQTCLProcessor This will ensure that command execution will be properly synchronized to the rest of the application. \param rExperiment - CExperiment& the experiment object. \param rStartup - CInterpreterStartup& the interpreter startup object. Normally you will use this object to locate the interpreter on which your commands will be registered. \param rCore - CInterpreterCore& the core TCL interpreter add on functionality. \note The base class creates key command extensions (e.g. begin) it is important that the base class version of this function be called. */ void CMyExperiment::AddUserCommands(CExperiment& rExperiment, CInterpreterStartup& rStartup, CInterpreterCore& rCore) { CReadoutMain::AddUserCommands(rExperiment, rStartup, rCore); CTCLInterpreter& rInterp(rStartup.Interp()); // Add your command definitions after this comment. rInterp // is a reference to the interpreter. } void* gpTCLApplication;
Example 5-4. Makefile
INSTDIR=/usr/opt/daq/8.1 # User makefile for the Production readout skeleton. Read the comments # in the code below to know what you can modify. # include $(INSTDIR)/etc/ProductionReadout_Makefile.include # # Below, define any additional C++ compilation switches you might need. # # If you are using camac you will need to add at least: # -DCESCAMAC # or -DVC32CAMAC # to select between the CES 8210 and WIENER CAMAC interface modules. # respectively. # USERCXXFLAGS= # # Below, define any additional C compilation switches you may need. # By default, this is defined to be the same as the C++ additional # switches: USERCCFLAGS=$(USERCXXFLAGS) # # Below, define any additional linker flags you may need: # USERLDFLAGS= # # Add any objects you require to the defintion below. Note that the # Makefile knows by default how to correctly compile most C++ and C files. # Unless ther are problems, don't add any compilation rules for your objects. # # # If you are using a 'traditional readout skeleton, # Comment the Objects line two down and uncomment the next line: # #Objects= Skeleton.o CTraditionalEventSegment.o CTraditionalScalerReadout.o # co:listobjects Objects=Skeleton.o MyEventSegment.o # Readout: $(Objects) $(CXXLD) -o Readout $(Objects) $(USERLDFLAGS) $(LDFLAGS) clean: rm -f $(Objects) Readout depend: makedepend $(USERCXXFLAGS) *.cpp help: echo "make - Create the readout program." echo "make clean - Clean up objects etc. created by previous builds" echo "make depend- Add include file dependencies to the Makefile." # DO NOT DELETE MyEventSegment.o: MyEventSegment.h Skeleton.o: MyEventSegment.h