Adding and removing a detector¶
Suppose you have just written a new detector class and want to try it out. The easiest way to do so is via the AddDetector()
method of the apparatus class. For example, your script could do the following:
// Instantiate the Right Arm HRS apparatus and add it to the list of
// apparatuses to be analyzed
THaApparatus* HRSR = new THaHRS("R","Electron HRS");
gHaApps->Add( HRSR );
// Create an instance of the new hyper scintillator detector
THaDetector* hs = new THaHyperScintillator("hs","Hyper Scintillator");
// Add this detector to the Right Arm HRS
HRSR->AddDetector( hs );
// ... do your analysis
That's it! No need to compile anything (except your new detector class, of course). This looks awfully simple, in fact too good to be true! Welcome to the power of object-oriented programming.
Of course, you must add appropriate database entires for your detector, unless you have hardcoded everything (urgh).
A detector added to an apparatus in this way will work like any other detector associated with the apparatus in the sense that its standard processing methods will be called in the correct order and with the correct arguments. That is, Decode()
and CoarseProcess()
/FineProcess()
or CoarseTrack()
/FineTrack()
will be called as expected. The new detector may even call methods of other detectors within the same apparatus and access any global physics variables available, within the same restrictions that apply to detectors instantiated in the apparatus's constructor.
There is no real limitation to using this method as compared to instantiating a detector in the apparatus's constructor. It should work with any detector objects, including tracking detectors. However, AddDetector()
should not be used to add detectors whose methods or global physics variables are to be used by any default detectors of the apparatus. The reason is simply that other detectors should not rely on detectors being present that are defined "manually" by the user in the steering script. It is easy to forget to define such a detector or to comment out the instantiation. Of course, well-written code should test for the detector's presence and should not crash, but correct behavior is not guaranteed in that case. In brief, detectors that other detectors need to be present should be instantiated in the apparatus's constructor.
How to clean up? Normally, no need to bother. In a simple analysis session, you will probably exit ROOT after the analysis anyway and everything will be automatically deleted. If you do want to clean up yourself:
// Be careful not to delete the detector before deleting the apparatus!
// Otherwise the analyzer will crash - guaranteed.
// Exiting ROOT will do this automatically anyway, so usually don't
// bother with it.
gHaApps->Delete(); // Deletes only default detectors of the apparatuses.
delete hs;
To make a detector more permanent, you could add its instantiation to the apparatus's constructor. For example:
void THaMyHRS::THaMyHRS( const char* name, const char* description ) :
THaHRS( name, description )
{
// Constructor. Defines the standard detectors for MyHRS.
// NB: The standard HRS detectors (VDC, S1, S2) are defined
// in the THaHRS constructor.
AddDetector( new THaHyperScintllator("hs","Hyp Scint"));
}
However, writing a new apparatus inheriting from
THaHRS
just to add your own detectors is not really necessary unless you need to do special processing that requires the presence of those detectors.
How about removing a detector from a standard apparatus? This is not as trivial. Of course, one could provide a RemoveDetector()
method. However, for the reasons mentioned above, this could cause trouble if other detectors or parts of the analysis algorithm (e.g. beta calculation) depend on the presence of the detector you want to remove. Because of this, there is no support for simple removal of a detector in the present version of the analyzer.
Updated by Ole Hansen over 6 years ago · 3 revisions