# BCJet reconstruction framework

### Author: O. Peters

## Introduction

The bcjet reconstruction tags reconstructed jets as light or heavy, i.e.
produced by b- or c-quarks. To achieve this goal, it uses multiple
tagging algorithms, such as lepton and vertex tagging algorithms, as
well as combinations of these tagging algorithms. It consists of a
framework that handles the data streams, and the actual tagging
algorithms that are called by the framework. This document describes the
implementation of the framework, and the requirements on the
implementation of the tagging algorithms. The first chapter will give an
overview of how to run the code, starting from a reconstructed data
file. Chapter two deals with the implementation of the framework, and
chapter three explains the requirements on the tagging algorithms.
Chapter four describes the way the analysis package reads the correct
output of the bcjet reconstruction.

## Chapter 1: Running bcjet reconstruction

The input for the bcjet reconstruction consists of one or more
reconstructed JetChunks, as well as one or more chunks that are needed
for the tagging algorithms. In this chapter, the muon tagging algorithm
is used as an example. This tagger needs a MuonParticleChunk as input.

To call the reconstruction, it is necessary to add a call to bcjetreco
on the 'Packages' line in the RCP file that steers the main program:

Furthermore, the OBJECTS and LIBRARIES files in the bin directory of the
package that is providing the binary have to contain some (additional)
lines:

OBJECTS needs: RegbcJetReco

LIBRARIES needs: bcjetreco

After 'gmake', the binary is ready to run with the bcjet reconstruction
added. An example of such a binary can be found in the bcjet_analyze
package.

As shown, the bcjetreco package is steered by the bcJetReco RCP file.
This RCP file is shown in Listing 2.

The bcJetReco package is a 'Controller' -- to do the processing of the
event, it calls other packages (just like the d0 framework). The
packages that it calls are listed on the 'Packages' line. This line
*has* to start with a call to the bcJetInit package, and finish with a
call to the bcJetFinish package. In between, the tagging algorithms are
called. To select different tagging algorithms, one can add or remove
them from this line. Thus, to run only with the muon tagging algorithm,
we have to remove the entries etag, vtxtag, imptag and nntag from the
'Packages' line in Listing 2.

The bcJetInit package selects which JetChunk will be used in the tagging
algorithms. This selection is steered by the bcJetInit RCP file, as
shown in Listing 3.

Each JetChunk is created using a certain clustering algorithm, which is
determined in the JetReco RCP file. To select the JetChunk that is
created by that JetReco RCP for tagging in the bcjet framework, the
clustering algorithms mentioned in the JetReco and bcJetInit RCP files
have to be the same. If the requested JetChunk is not present in the
event, bcJetInit will print out an error message and the rest of the
bcjetreco stream is skipped.

The way each tagging algorithm behaves is governed by the parameters in
its RCP file. Thus, to change this behavior, these RCP files have to be
edited according to the rules of that tagging algorithm.

The final package in the bcJetReco packages line, bcJetFinish, inserts
the final reconstructed bcJetChunk in the event. This bcJetChunk is the
input to the bcjet_analyze package. To select the bcJetChunk that is
created by above bcJetReco RCP file, the bcJetAnalyze RCP file needs to
have the correct settings (see Listing 4)

The line 'RCP bcjetreco = \<bcjetreco bcJetReco\>' tells bcJetAnalyze to
use that RCP file to select the bcJetChunk. Thus, to select the
bcJetChunk which is made with the above bcJetReco RCP file, this RCP
entry has to be exactly the same as the one in Listing 1.

## Chapter 2: Framework implementation

One of the requirements of the bcjet reconstruction framework is that it
is capable of running multiple bcjetreco streams[^1] in the same
reconstruction job. This calls for a system that keeps track of all the
chunks involved in selecting the correct JetChunk, the chunks that are
inserted by the tagging algorithms and the bcJetChunk itself, and this
in a manner that is transparent to the user and tagging algorithm
developer. To explain this system in detail, first a single bcjetreco
stream is considered that takes the only JetChunk in the event and
creates the corresponding bcJetChunk. Only the muon tagging algorithm is
considered here,

but all other tagging algorithms work in a similar way.

Figure 1 shows the input event with the required chunks: the chunk
holding the reconstructed Jets and the chunk holding the reconstructed
muons. Listing 5 shows the minimum RCP file that is needed to run an
executable (e.g. bcJetAnalyze) that reconstructs bcJets and analyses
them. It reads in the event with the ReadEvent package and initializes
the geometry with the geometry_management package. Since all the
reconstructed objects are already available in the event, we can proceed
now with the bcjet reconstruction. The RCP file needed for this
reconstruction is shown in Listing 6.

The bcjet reconstruction takes three steps:

1.  Initialization: chooses the JetChunk to run on, and prepare the
    event such that consequent tagging algorithms and bcJetFinish can
    find this JetChunk;

2.  Tagging: runs one or more tagging algorithms, which use the JetChunk
    that is chosen in the previous initialization step, and physics
    information already present in the event to store tagging
    information in the event;

3.  Finalizing: creates the bcJetChunk and fills it with bcJets, which
    hold references to the tagging information created by the tagging
    algorithms.

These steps are explained in detail below.

### 

### 2.1: Initialization

### The initialization of the bcjet reconstruction is done by the bcJetInit object (package bcjetreco). It is steered by the bcJetInit RCP file, which is shown in Listing 7.

To select the correct JetChunk in the event, the 'ClusterAlgorithm' RCP
entry has to point to the same RCP file that is pointed to in the
JetReco RCP file used to create the JetChunk. With this
'ClusterAlgorithm' RCP file, the bcJetInit object creates a
JetChunkSelector and stores it in a bcJetInitChunk. Using this
JetChunkSelector, the correct JetChunk can always be retrieved from the
event. After the initialization, the event looks like is shown in Figure
2.

### 2.2: Tagging

After the initialization stage, the tagging algorithms are run. These
need at least the correct JetChunk as input, which they retrieve using a
function in the EventUtilities class, called getJetChunk(Event)
(explained later).

In most cases, the tagging algorithms also need additional chunks, e.g.
a MuonParticleChunk for the muon tagging algorithm. It is the
responsibility of the tagging algorithm to retrieve this information out
of the event -- the framework does not provide means to do this.

Using the jet and additional information, the tagging algorithm can now
tag each jet, and insert information about this tag in the event. Each
tag holds information about the jet tagged and about the physics object
tagging it. These tags are collected in a tagChunk, which for the muon
tagging algorithm is a muTagChunk. Both the tag and the tagChunk need to
adhere to some restrictions, which are explained in detail in chapter 3.
After the tagging algorithm has run, the event looks like is shown in
Figure 3.

### 2.3: Finalization

After all tagging algorithms have run, the bcJetFinish object will
gather the information stored in the tagChunks and insert the
bcJetChunk. It retrieves the correct JetChunk through the
EventUtilities::getJetChunk(Event) method, just like the tagging
algorithms. To get the tagChunks that tagged that particular JetChunk,
it calls another utility function in EventUtilities, called
getTagChunk(Event). This function returns the tagChunk that has been
tagging the JetChunk selected in the stream, and is explained later.

After retrieving the necessary chunks, the bcJetFinish object takes the
following steps:

1.  The ChunkID of each input chunk, in this case the JetChunk and
    MuTagChunk, are stored in a temporary list for later insertion in
    the bcJetChunk;

2.  The bcJetChunk is created, with the list of ChunkID's as one of the
    arguments;

3.  For each input chunk, the *first* RCPID in the RCP list of the chunk
    is stored in the bcJetChunk. In most cases, this RCPID will point to
    the RCP used for the tagging algorithm[^2]. These RCPID's are stored
    in a map\<string, RCPID\> in the bcJetChunk, where the first
    argument is the name of the package that created the chunk, e.g for
    the muTagChunk, this is bc_muTagreco. Also, the RCPID of the
    bcJetReco RCP file is stored, since this is needed later in for
    example bcjet_analyze to retrieve the correct bcJetChunk from the
    event.

4.  For each Jet in the chosen JetChunk, a bcJet is created and each
    tagChunk is asked to provide a list of all tags that have tagged
    that Jet. However, instead of returning a copy of the tag, the
    tagChunks return a LinkIndex to the tag, which can be seen as a
    pointer to that tag. The LinkIndices to the tags are then stored in
    the bcJet.

5.  Finally, the bcJets are stored in the bcJetChunk, and the bcJetChunk
    is inserted in the event.

> After the last step, the event looks like Figure 4, and is ready for
> analysis.

### 

### 2.4 Running multiple streams

The previous paragraph described how to run the bcjet reconstruction
once in a reconstruction job. However, sometimes it is desired to run
the bcjet reconstruction multiple times, for example to run on different
JetChunks and/or use different variables in the tagging algorithms. This
paragraph will explain how the framework implements this situation, and
as an example we use an event with two different reconstructed JetChunks
and two different reconstructed MuonParticleChunks as input (see Figure
5). Also, the muon tagging algorithm is run with different options.

The minimal main RCP file for the above situation is shown in Listing 8.
In this RCP file, the bcjetreco package is called twice, each time with
a different RCP file. Also, the bcjet_analyze package is called twice
with a different RCP file. To use a different JetChunk and
MuonParticleChunk, as well as to use different tagging algorithms in the
two bcjetreco streams, the two different bcjetreco RCP files will have
to call different RCP files for the packages in the stream. This can be
seen in Listings 9 and 10.

### 

###  

### 

To be able to select different JetChunks in the different
bcJetInit_Cone0x RCP files, the line

RCP ClusterAlgorithm = \<calreco CalCone07\>

in those RCP files needs to be pointing to the correct calorimeter
clustering algorithm that was used to make the JetChunk.

The two instances of the muon tagging algorithm in the different
bcjetreco streams are steered by the two different bc_muTagreco RCP
files. These RCP files are shown in Listing 11 and 12. The muon tagging
algorithm retrieves the correct JetChunk through the EventUtilities
object, but it has to make sure itself that it retrieves the correct
MuonParticleChunk based on the information in the bc_muTagreco RCP file
-- the framework cannot do this[^3]. After retrieving both correct
chunks from the event, the algorithms can tag the jets using the muons
and insert a muTagChunk in the event. Since the muon tagging algorithm
is run twice, it will insert two muTagChunks in the event, both tagging
a different JetChunk with different muons. These two muTagChunks can
later be distinguished only by the fact that they store the ChunkID of
the chunks that were used to create the muTagChunk, thus, the ChunkID of
the JetChunk and of the muTagChunk.

After the tagging algorithms have inserted the tagChunks, the
bcJetFinish objects in both streams create and insert the bcJetChunks.
Using the bcJetUtilities::getJetChunk(Event) and
bcJetUtilities::getTagChunk(Event) functions to retrieve the correct
input chunks, the LinkIndices to the correct tags are taken out of the
tagChunks and inserted in the new bcJets. After all jets have been made
into bcJets, the bcJetChunk is inserted in the event. After this, the
event looks like it is depicted in Figure 6.

To clarify the order in which the chunks are inserted in the event, a
timeline of the packages run and the chunks that are inserted is shown
below:

The bcJetInitChunk inserted at time 0 is pointing to the JetChunk that
is reconstructed with a 0.5 cone size. This bcJetInitChunk is the latest
(in time) in the event, and as such will be used for selection of the
correct JetChunk.

The muon tagging algorithm, using the LinkedList reconstruction
algorithm and the default algorithm to tag, creates and inserts the
muTagChunk. The JetChunk used is given by the latest inserted
bcJetInitChunk.

Using the JetChunk pointed to by the bcJetInitChunk inserted at time 0,
the bcJetChunk is created, using the information stored in the
muTagChunk. Note, that not the latest muTagChunk is taken, but the
muTagChunk that is tagging the current JetChunk. This is the end of the
first stream, and the second stream now starts.

The muon tagging algorithm now uses this bcJetInitChunk to retrieve and
tag the 0.7 cone reconstructed JetChunk, using the combinatorial muon
reconstruction and a neural network tagging algorithm.

Finally, the bcJetFinish object uses the correct jetChunk pointed to by
the bcJetInitChunk inserted at time 3 to create a new bcJetChunk. This
bcJetChunk holds information of the muTagChunk inserted at time 4, which
was tagging the same JetChunk.

### 2.5 Framework utitilities

To select the correct JetChunks and tagChunks out of the event, a
singleton utility object is provided that returns these chunks based on
information already present in the event. There are two functions
implemented in this singleton: getJetChunk(Event) that returns the
correct JetChunk, and getTagChunk(Event) that returns the correct
tagChunk. The inner workings of both are explained below.

##### THandle\<JetChunk\> EventUtilities::getJetChunk(Event)

First, this function retrieves the latest bcJetInitChunk. This is done
by taking out all bcJetInitChunks, and comparing their generation time.
The bcJetInitChunk with the highest generation time is selected. Since
this bcJetInitChunk contains a JetChunkSelector, this selector can be
used to extract the correct JetChunk from the event.

##### template\<class TagChunk\>

##### edm::THandle EventUtilities::getTagChunk(Event)

The template argument of this function is the type of tagChunk that is
to be retrieved from the event. The retrieval of the correct tagChunk is
done by first getting the correct JetChunk from the event using the
previous function. Then, all tagChunks (of the template type) are
extracted from the event. Since each of these tagChunks contains the
ChunkID of the JetChunk that was used to create the tagChunk, the
tagChunks that do not contain the ChunkID of the correct JetChunk are
discarded. Then, the generation time of all leftover tagChunks are
compared, and the tagChunk with the highest generation time is returned.

*Using any other function than these two will not guarantee that the
correct JetChunks and tagChunks are extracted from the event!*

### 2.6 BCJet data components

The data from the bcjet reconstruction is stored in the bcJetChunk,
which is a collection of bcJets. Both of these components will be
explained in some detail below.

###### bcJet

The bcJet component is a Jet with added information about the tags that
are tagging this jet. Therefore, the bcJet inherits from Jet and adds an
interface to manipulate these tags. The bcJet does not store the tags
directly, since this would mean that the tags are stored twice, once in
a tagChunk and once in the bcJet. Instead, the bcJet stores collections
of LinkIndices[^4] that point to the tags. Using LinkIndices puts some
requirements on both the framework and the tagging chunks:

1.  The LinkIndices are inserted in the bcJet in the bcJetFinish stage
    of the bcjetreco stream. The correct LinkIndex to the tag has to be
    retrieved from the specific tagChunk. This has to be implemented in
    each tagChunk by two functions: a function getTagIndex(Jet) that
    returns one LinkIndex to the tag in that tagChunk that is tagging
    the given Jet, and getTagIndices(Jet, vector\<TagIndex\>) that fills
    a vector with LinkIndices to all the tags found;

2.  LinkIndices need to be resolved before they can be used. This is
    done in the function completeLinks that is called from the
    bcJetChunk. This function loops over all the LinkIndices in the
    bcJet and resolves them. It is called as soon as the bcJetChunk is
    retrieved from the event.

In all other aspects, the bcJet can be treated as a regular Jet.

###### bcJetChunk

The bcJetChunk inherits from the D0PhysObjChunk[^5] with bcJet as a
template argument. The D0PhysObjChunk makes sure that before any bcJet
in the collection that it stores is accessed, it calls the completeLinks
function of all bcJets. This ensures all LinkIndices in the bcJets are
resolved before they are used. In addition to the functionality in
D0PhysObjChunk, the bcJetChunk also stores a map of RCPID's, with their
name as the key. In the bcJetFinish stage of the bcjetreco stream, this
map is filled with the RCPID's of all the tagging algorithm RCP's that
inserted a tagChunk in the event.

### 2.7 Registration of framework packages

All packages that are used in the bcjet reconstruction stream need to be
registered with the framework in order to be instantiated during the
initialization of the framework. This is normally done with a separate
'Register' object for each package, which is located in the /src
directory of the package. For the bcjetreco package, this is done in a
different way, and only one Register object exists for all packages run
in the bcjetreco stream. Therefore, the Register object for bcjetreco,
called RegbcJetReco, registers both the bcJetInit and the bcJetFinish
framework packages, as well as all the tagging packages.

## Chapter 3: Requirements on tagging algorithms

To be used in the bcjet reconstruction framework, a tagging algorithm
has to consist of a minimum number of classes, which are located in
different packages. Each of these classes has to adhere to some
interface. This chapter will list all necessary components for a
jet-tagging algorithm.

### 3.1 Tagging package

Each tagging algorithm has its own package, which is controlled by the
author of the tagging algorithm and the b-id group leader(s). The name
of the package has to look like bc_xxTagreco, where xx is the short for
your tagging algorithm (e.g. for the muon tagging algorithm, the package
name is bc_muTagreco). This short should be 2-4 letters long.

### 3.2 Tag

The tag object is the smallest block of output from the tagging
algorithm. All the tags used in the bcjet reconstruction reside in the
bcjet_evt package to avoid circular dependencies. A tag tags one jet
using physics information from the event. It therefore stores a
LinkIndex to the jet, and one or more LinkIndices to that physics
information. Also, it should provide a useful interface to access the
data in the tag. To explain this interface, the muTag class will be used
as an example, part of which is shown in Listing 13.

As can be seen from the first line, the muTag is part of the bcjetid
namespace. All classes that are used in the bcjet reconstruction have to
be part of the bcjetid namespace to avoid naming conflicts. The class
starts of with two typedef's for the information stored in the tag.
Although this is not needed for the framework, it does make coding a lot
easier.

The tag contains two constructors: one with no arguments that is needed
for storage in containers, and one taking a JetLink and a MuonLink that
initializes the private data members \_jet and \_muon. To retrieve the
Jet and MuonParticle objects, two accessors are implemented that resolve
the LinkIndices and return the objects that the LinkIndices point to.
The implementation of these functions will be explained in more detail
below. Since these LinkIndices need to be resolved before these
functions can be called, an activate() method needs to be implemented
that is called by the tagChunk in which this tag is stored (also
explained below). Finally, the tag also provides functions to access
some of the variables that were used in the tagging algorithm, in this
case the P~TRel~ between the muon and the jet, and the momentum of the
muon. It is not necessary to store all this information in the tag,
since it can be recalculated using the information in the jet and the
muon. In the case of the muTag, only the P~TRel~ is stored, and the
momentum of the muon is taken by calling a function of the MuonParticle
object. Note, that the P~TRel~ could have been recalculated too using
the information in the jet and the muon. Finally, a function is added to
retrieve the discriminant of the tag, which is a number between 0 and 1
indicating the likelihood that this jet is a b-jet.

Listing 14 shows the implementation of the jet() function, that returns
the Jet object that is pointed to by the JetIndex in the tag.

The function first creates a LinkPtr to the jet, using the JetLink
contained in the tag. After checking if this is a valid pointer, the
object pointed to by this pointer is returned.

This system only works when the LinkIndex has been resolved. This is
done in the activate() method, shown in listing 15.

The activate() method is called by the tagChunk when it is accessed or
read from the event, and resolves all LinkIndices in the tag.

### 

### 

### 3.3 TagChunk

Except for the normal functions that are implemented for a chunk storing
physics data[^6], there are a couple of functions that need to be
implemented specifically for the bcjetreco framework (note that examples
from the muTagChunk are used; some of the names of the functions and
objects should therefore be changed).

##### MuTagIndex getMuTagIndex(const jetid::Jet &jet) const

Given a certain jet, the tagChunk has to return a LinkIndex to the tag
that is tagging that jet. The implementation of such a function is shown
in Listing 16. Here, the function loops over all the tags in the chunk
and compares the jet that is stored in each tag with the jet provided.
If both jets are the same, meaning that the tag is tagging that
particular jet, a LinkIndex is created using the tag object, the ChunkID
of the tagChunk and the position of the tag in the chunk (starting at
0!).

##### void getMuTagIndices (const jetid::Jet &jet, vector\<MuTagLink\> &tags) const

Given a certain jet, fill the vector 'tags' with LinkIndices to all tags
that are tagging the jet.

##### const muTag &at(int index) const

Given a certain index, the tagChunk has to return the tag that is stored
at that index. This function is used to resolve the LinkIndices that are
pointing to tags stored in this chunk. An implementation of the at()
function is shown in Listing 17. It is a good idea to have the assert
statements in the function to make sure that no invalid object is
returned.

##### 

##### void activate()

This function is called when the tagChunk is read from the event, before
any other function can be called on that chunk. Therefore, it is a good
place to resolve all the links stored in the tags. The implementation of
this function is shown in Listing 18, which demonstrates a simple loop
over all the tags in the chunk and calling the function activate() on
each of them.

### 3.4 Tagging algorithm

The tagging algorithm resides in the bc_xxTagreco package. This package
should contain at least one class that inherits from the fwk::Process
and fwk::Package class and can thus be registered with the
framework[^7]. The most important function in this class is the
processEvent method, which contains the follwing steps:

1.  Extraction of the JetChunk *using the
    EventUtilities::getJetChunk(Event) method;*

2.  Extraction of the physics information chunks needed for the tagging
    information (optional);

3.  Loop over all jets in the JetChunk;

4.  If a jet is tagged by the physics information, create a new tag with
    a JetLink and a LinkIndex to the specific physics information. Note,
    that the correct position of the jet in the chunk, and the correct
    position of the physics information in the physics chunk has to be
    stored in these LinkIndices. This is very important; if this is not
    done correctly, the event will be left in an unstable state but will
    not crash immediately!

5.  Create a new tagChunk and insert all the created tags in it;

6.  Add the ChunkID's of the JetChunk and all the other chunks that were
    used in the event;

7.  Store the RCPID of the tagging algorithm's RCP file in the tagChunk
    and make sure that this RCPID is the first one in the chunk (i.e.
    rcps().front() is pointing to the RCPID of the tagging algorithm's
    RCPID)

8.  Insert the new tagChunk in the event

### 3.5 Changes in the bcjetreco framework

Unfortunately, registering the new tagging algorithm requires code
changes in some of the components of the bcjetreco framework. The
following components and functions are affected:

##### bcjet_evt/bcJet.hpp

-   Include the header defining the new tag;

-   Add a private vector of LinkIndices to the new tag;

-   Add two add functions, one taking a LinkIndex to the new tag, the
    other taking the tag, the ChunkID of the chunk in which the tag
    resides, and the position of the tag in that chunk;

-   Add a get function which fills a vector of LinkIndices to the
    current tag.

##### bcjetreco/bcJetFinish.cpp

-   Include the header defining the new tagChunk;

-   Add the following pieces of code to the processEvent method in the
    correct places, thereby changing the names from 'muon' to your tag
    name:

##### bcjetreco/RegbcJetReco.cpp

-   Add a framework forward declaration to your tagger, similar to the
    ones present. Make sure the declaration is in the same namespace as
    the one in which your tagger is located!

That is all. Now test the new code extensively using a plethora of data
samples, Monte Carlo and real data.

To analyze the code, a new block has to be added in the bcjet_analyze
package, but a description of that is outside the scope of this
document.

### 3.6 Writing higher level tagging algorithms

A higher level tagging algorithm is an algorithm that uses the output of
the other tagging algorithms to make a new tagging decision. Examples of
currently higher level tagging algorithms are the likelihood tagging
algorithm and the neural net tagging algorithm. These algorithms have to
run in the bcjetreco stream after all the other tagging algorithms that
are used. To access the lower level tagChunks, the algorithm has to use
the EventUtilities::getTagChunk(Event) function to make sure that those
tagChunks are used that are tagging the current JetChunk. To get the tag
in the tagChunk that is tagging a certain jet, the getTagIndex(Jet)
function of the tagChunk can be used, with the caveat that the LinkIndex
to the tag has to be de-referenced using the LinkPtr mechanism (see
Listing 14 on page 12). Apart from this, the rest of the implementation
is the same as for the lower level tagging algorithms.

## Chapter 4: Using bcjet_analyze with multiple streams

This chapter will not give an overview of bcjet_analyze[^8], but will
explain how to run bcjet_analyze with multiple bcjetreco streams, and
how to select the correct bcJetChunk to analyze.

Each bcjetreco stream creates one new bcJetChunk, and for each
bcJetChunk that has to be analyzed, a separate instance of the
bcjet_analyze package has to be run (see for example Listing 8 on page
6). The selection of the correct bcJetChunk is made in the bcJetAnalyze
RCP file. Here, there is a line:

RCP bcjetreco = \<bcjetreco bcJetReco1\>

This line tells bcJetAnalyze which bcjetreco stream is creating the
bcJetChunk that it will analyze. Therefore, in the example of Listing 8,
if we tell bcJetAnalyze to use the bcJetReco1 RCP file, it will select
the bcJetChunk that is created by the first bcjetreco stream. Thus, to
analyze both bcJetChunks that are made in the two streams, the
bcJetAnalyze1 RCP file has to have the entry:

RCP bcjetreco = \<bcjetreco bcJetReco1\>

while the bcJetAnalyze2 RCP file has to have the entry

RCP bcjetreco = \<bcjetreco bcJetReco2\>

[^1]: A bcjetreco stream is the consecutive execution of the list of
    packages listed in the bcJetReco RCP file. Such a stream selects a
    JetChunk, calls the tagging algorithms and inserts a bcJetChunk in
    the event.

[^2]: Since the input chunks only have a list of RCPID's, without any
    description, it is not possible to know for sure that the first
    RCPID points to the algorithm RCP file.

[^3]: At the time of the write-up of this document, the
    MuonParticleChunk did not store information about the algorithm that
    was used to create it. Thus, the muon tagging algorithm cannot
    distinguish between the different MuonParticleChunks in an event,
    based on a 'algorithm' switch in the bc_muTagreco RCP file. If this
    information is put in the MuonParticleChunk, above scenario can
    become true.

[^4]: For more information about LinkIndices, see:
    http://cdspecialproj.fnal.gov/d0/edm/Links.htm

[^5]: See:
    http://www-d0.fnal.gov/d0dist/dist/releases/current/kinem/doc/README.TXT

[^6]: See for example
    http://www-d0.fnal.gov/d0dist/dist/releases/current/bcjet_evt/bcjet_evt/muTagChunk.hpp

[^7]: See:
    http://www-d0.fnal.gov/d0dist/dist/releases/current/bc_muTagreco/bc_muTagreco/muTagReco.hpp

[^8]: For that, see
    http://www-d0.fnal.gov/d0dist/dist/releases/current/bcjet_analyze/doc/