Go to Notes and Further References, Exercises, top,

Plex Package

Purpose of the Plex

Strips and Alternative Lists

Notes and Further References

The Plex is fully described in the
User Manual

To access the Plex you need to create a PlexHandle, and for that you need a context. This concept was introduced in the Validity slide and the associated notes explained how to get a VldContext for a RawRecord:-

  const VldContext* vc = raw->GetVldContext();  
although any class that inherits from RecMinos (the base class for all Records) will provide a context. From the context a lightweight PlexHandle can be constructed:- PlexHandle plxh(*vc); You can examine PlexHandle.h to see what methods are available, in particular it has:- virtual PlexSEIdAltL GetSEIdAltL(const RawChannelIdY rcid, const PlexCalib* calib=0, Int_t adc=0, Double_t time=0) const; which allows you to start from a RawChannelId and get a PlexSEIdAltL (Plex strip-end alternative list) that gives information about all the possible strip ends that the channel can connect to. Methods arguments with default values (=0) allow one to leave these unspecified; in this case it returns the items uncalibrated.

For example, from a RawDigitDataBlock, the following lines of code get the PlexSEIdAltL for the hit 10:-

RawDigitDataBlock* rddb = from somewhere. if ( rddb->GetNumberOfDigits() < 10 ) { cout << " RawDigitDataBlock has < 10 hits" << endl; } else { const RawDigit* rd = rddb->At(9); // counting starts at 0! RawChannelId rcid = rd->GetChannel(); PlexSEIdAltL psal = plxh.GetSEIdAltL(rcid); } Having obtained a PlexSEIdAltL you can take a look at what its PlexSEIdAltL.h has to offer. In particular it inherits from the standard template library vector, so if you know this library you can use all those methods to iterate. Assuming that you don't then the methods you can use to loop over all alternatives are:- Bool_t IsValid() const; void Next(); void Previous(); void SetFirst(); void SetLast(); and to obtain the information on the current alternative:- const PlexSEIdAltLItem& GetCurrentItem() const; PlexSEIdAltLItem& GetCurrentItem(); PlexStripEndId GetCurrentSEId() const; Float_t GetCurrentWeight() const; with simliar methods for what is currently considered to be the "best" alternative:- const PlexSEIdAltLItem& GetBestItem() const; PlexSEIdAltLItem& GetBestItem(); PlexStripEndId GetBestSEId() const; Float_t GetBestWeight() const; Finally, from the header PlexStripEndId.h you can get to the information about the strip end. Note that PlexStripEndId inherits from PlexPlaneId so the methods in PlexPlaneId.h are also available.

For example to get the best plane number:-

PlexStripEndId bestPseid = psal.GetBestSEId(); Int_t bestPlane = bestPseid.GetPlane();


This exercise assumes you have created a test release. Modify Demo/UserAnalysis.cxx as follows:-
  1. Add the following headers to the others at the start of the file:- #include "Plex/PlexHandle.h" #include "Plex/PlexSEIdAltL.h" #include "Plex/PlexStripEndId.h" #include "RawData/RawChannelId.h" #include "RawData/RawDataBlock.h" #include "RawData/RawDigit.h" #include "RawData/RawDigitDataBlock.h" #include "RawData/RawRecord.h" #include "Validity/VldContext.h"
  2. Replace all the code of the function UserAnalysis::Ana with:- // Ask Mom for a RawRecord. RawRecord* raw = dynamic_cast<RawRecord*>(mom->GetFragment("RawRecord")); if ( ! raw ) { cout << "Cannot find a RawRecord in Mom" << endl; return JobCResult::kFailed; } const VldContext* vc = raw->GetVldContext(); PlexHandle plxh(*vc); TIter itr = raw->GetRawBlockIter(); cout << "Processing RawRecord..." << endl; RawDataBlock* rawBlk = dynamic_cast<RawDataBlock*>(itr.Next()); while ( rawBlk ) { cout << "Processing RawdataBlock..." << endl; // Does the RawDataBlock inherits from or is a RawDigitDataBlock RawDigitDataBlock* rddb = dynamic_cast<RawDigitDataBlock*>(rawBlk); if ( rddb ) { // .... See how many digitizations there are ... Int_t numDigits = rddb->GetNumberOfDigits(); if ( numDigits > 10 ) numDigits = 10; cout << " RawDigitDataBlock has " << numDigits << " digitizations. " << " The first " << numDigits << " are:-" << endl; // ... and print out the first 10 at most. for (Int_t idigit = 0; idigit < numDigits; ++idigit) { const RawDigit* rd = rddb->At(idigit); RawChannelId rcid = rd->GetChannel(); PlexSEIdAltL psal = plxh.GetSEIdAltL(rcid); cout << " RawChannelId " << rcid << " has " << psal.GetSize() << " alternative(s)\n" << " currently the \"best\" alternative has weight " << psal.GetBestWeight(); PlexStripEndId pseid = psal.GetBestSEId(); cout << " and comes from plane " << pseid.GetPlane() << endl; } } rawBlk = dynamic_cast<RawDataBlock*>(itr.Next()); } return JobCResult::kPassed;
These modifications show how the Plex can be used to get the best plane of the first 10 hits of each event.

To run the exercise first rebuild loon and then type:-

  loon -q  run_UserAnalysis.C $ROOT_DATA/fardet_data/2002_06/F00005963_0000.mdaq.root 
Contact: Nick West <n.west1@physics.ox.ac.uk>
Security, Privacy, Legal Fermi National Accelerator Laboratory