Outline:
The super module VMEUnpackSuperMod is used to unpack the VME data from a raw data file. Be sure to call each standard module function on this super module (StartAnalysis(), StartRun(), etc.).
This super module will place event data objects into the event for each sub-detector in the VME. Currently, this means it will put in the event a TPhSpecTrgEventData object, and two TPhPCALEventData objects (one for the PCAL and one for the PCAL's cosmic trigger). These event data objects will store the raw data in whatever way is appropriate for that sub-detector.
The super module contains the following modules:
The super module is configured in $PHATHOME/macros/pcal/vme_unpack_setup.C
The purpose of the VME software is to get the raw data from the DAQ files into a format that allows each sub-detector in the VME to easily access its data.
The unpacking scheme is different from that of the silicon and the fastbus. In the silicon detector, all signal processing is done for the entire silicon detector at once. In that case, it makes sense to use the TPhTopoData scheme to process the data in terms of electronics: FECs, strings, chips and channels. In the VME, each VME module could in principal belong to a completely separate sub-detector, so unpacking the raw data into a format which is organized by electronics does not make sense.
Thus, the goal of the VME unpacker is to get the data out of the TPhVMERawHit, where it is stored in the PhoRaw file, and into a class which is unique to each sub-detector.
This is accomplished by an abstract class, TPhVMESubDetEventData, from which any VME sub-detector's event data class must inherit. Each sub-detector's event data class must implement its own FillValueForChannel() function. This function is called by the unpacking module and allows each sub-detector to store the raw data value, given the row, column and VME data type (i.e. ADC, TDC, etc.), in whatever way is appropriate for that sub-detector.
Below is a flow chart of how this process occurs:
It's just that simple!
But let us go through each step anyway:
- During the event loop, each of the following steps happen:
- TPhVMEUnpackerMod loops over each TPhVMERawHit inside the "RawVME" container. One TPhVMERawHit object corresponds to one VME module in the electronics. For each channel in the TPhVMERawHit object, the following happens:
- TPhVMEUnpackerMod gets the raw data, crate number, module number and channel number from the TPhVMERawHit object.
- TPhVMEUnpackerMod sends the create, module and channel number to the VME map.
- The VME map returns the corresponding row, column, data type sub-detector name, sensor name and (PMT) position to TPhVMEUnpackerMod.
- TPhVMEUnpackerMod looks for an existing TPhVMESubDetEventData object using the sub-detector name.
- If one is NOT found, TPhVMEUnpackerMod sends the sub-detector name to the static function TPhVMEDetector::NewSubDetEventDataFor(). Then the following happens:
- The name of the sub-detector's event data object is looked up in the static function TPhVMEDetector::GetSubDetEventDataNameFor(), according to the sub-detector's name.
- The number of rows and columns is looked up, according to sub-detector name, in the static function TPhVMEDetector::LookupSize().
- Using the sub-detector event data's name, the number of rows and the number of columns, the static function TPhVMEDetector::NewSubDetEventDataFor() calls new on the appropriate sub-detector's event data (i.e. TPhPCALEventData, TPhSpecTrgEventData, etc.) and returns a pointer to that TPhVMESubDetEventData.
- From now on in the channel loop (but not the event loop), when TPhVMEUnpackerMod looks for an event data object with this sub-detector's name, it will find the object that TPhVMEDetector just new-ed.
- (If no existing TPhVMESubDetEventData object was found for this sub-detector, TPhVMEDetector::NewSubDetEventDataFor() makes a new one as described above and returns it to TPhVMEUnpackerMod.)
- TPhVMEUnpackerMod sends the row, column, data type and raw data value to the TPhVMESubDetEventData.
- Through C++ inheritance magic, the sub-detector's event data object (i.e. TPhPCALEventData, TPhSpecTrgEventData, etc.) uses the row, column, data type to store the raw data value in whatever way is appropriate for that sub-detector.
This scheme allows all hard coding of sub-detector names, sizes and specific sub-detector event data objects to be neatly contained in TPhVMEDetector.h.
The system was designed to make this process as simple as possible.
Bool_t FillValueForChannel(const Int_t& row, const Int_t& col, const
EVMEDataType_t& type,
UInt_t value)
. Nothing else is required of the class, but you may find it useful to
actually store the value in an array of some kind. A list of the possible data types can be
found in the enum in TPhVMERawHit.h.In TPhVMEDetector::LookupSize(const Char_t* detName, Int_t& rows,
Int_t& cols)
, you are given the sub-detector name and are asked to set the number
of rows and columns that the sub-detector has. Add the following (after the first if
,
before the last else
):
}
else if ( strcmp(detName,"YOUR_SUB_DET_NAME") == 0 ) {
rows = NUM_ROWS; cols = NUM_COLS;
In TPhVMEDetector::NewSubDetEventDataFor(const TString& detName)
,
you are given the sub-detector name and are asked to return a new event data object for that
sub-detector. Add the following (after the first if
, before the last else
):
}
else if ( detName.CompareTo("YOUR_SUB_DET_NAME") == 0 ) {
return new YOUR_SUB_DET_EVENT_DATA_CLASS;
TPhVMEDetector::GetSubDetEventDataNameFor(const TString& detName, TString&
eventDataName)
, you are given the sub-detector name and are asked to set the event
data name. The event data name defaults to being SUBDETNAME_EventData. If you like the
default, you do not need to edit this function. If you want a unique event data name, add
the following (after the first if
, before the last else
):}
else if ( detName.CompareTo("YOUR_SUB_DET_NAME") == 0 ) {
eventDataName = "YOUR_EVENT_DATA_OBJECT_NAME";
There are some useful values in the enum EVMEDescriptions of TPhVMEDetector.h. You should make note of these when creating a new sub-detector. Also please use these enums whenever possible to avoid hard-coding values.
That's all there is to it!
To change the VME map, you will need to edit the text file in $PHATHOME/init/VMEMap.txt. Each line in the text file describes one VME channel. The columns are:
1 2 3 4 5 6 7 8 9 Crate Module Channel Sub-Detector-Name Row Column Data-Type Sensor-Name Position
The rules for adding a channel are:
2 5 3 ... 2 0 6 ... 2 0 1 ... 1 2 3 ... 0 9 4 ... 0 8 6 ... 0 1 1 ... 0 0 0 ...
Once the text file has been made, you can use the macro $PHAT2HOME/macros/pcal/pro/newmap.C to save the new map.