Project

General

Profile

Using the Framework » History » Version 61

Susan Lein, 05/24/2013 08:36 AM

1 1 Brian Rebel
{{toc}}
2 1 Brian Rebel
3 1 Brian Rebel
h1. Using the Framework
4 1 Brian Rebel
5 14 Brian Rebel
The ART framework uses a fairly basic structure for interacting with data - all the algorithms are stored in modules, the event information is accessed using objects living in the art namespace, etc.  While the I/O uses ROOT, it is not based on TObjects in the ART framework.  The objects that are stored in a file do not derive from TObject and it is likely that TObject derived objects will also not play nicely with the I/O.  The reason for this is ROOT's way of handling pointer data members - ROOT does not store the fields for the data members of pointers, which means on readback those data members may or may not contain sensible information.
6 1 Brian Rebel
7 1 Brian Rebel
h2. Basic Concepts
8 1 Brian Rebel
9 10 Brian Rebel
The art namespace contains the handles to information stored in an event.  Objects that are stored in an event are collectively known as data products.  They can either be added to an event using an art::EDProducer derived module or they can be retrieved and operated on using an art::EDAnalyzer module.  Once an object has been stored in the event, its data cannot be altered.  
10 1 Brian Rebel
11 7 Brian Rebel
Other namespaces to be aware of are 
12 7 Brian Rebel
13 9 Jonathan Paley
* fhicl - the namespace corresponding to the ParameterSet information described below 
14 9 Jonathan Paley
* cet - the namespace where the exceptions and some other utilities live.
15 9 Jonathan Paley
* mf - the namespace of the message logger facility
16 7 Brian Rebel
17 51 Brian Rebel
There is a link to interface for each concept in the heading for that concept.
18 1 Brian Rebel
19 47 Brian Rebel
h3. "art::EDProducer":https://cdcvs.fnal.gov/redmine/projects/art/repository/revisions/master/entry/art/Framework/Core/EDProducer.h 
20 1 Brian Rebel
21 11 Brian Rebel
This is a type of module that makes data products and stores them in the art::Event. The module takes a fhicl::ParameterSet in the constructor and uses that to configure that module. 
22 1 Brian Rebel
23 11 Brian Rebel
The module can also implement a reconfigure method to allow for run time reconfiguration, for example while running the event display.  Reconfiguration during a batch job would not make sense.
24 11 Brian Rebel
25 21 Enrique Arrieta Diaz
The user must supply the implementation for the art::EDProducer::produce() method to create and store data products and the art::EDProducer::reconfigure() method to allow for reconfiguration from the event display.
26 11 Brian Rebel
27 47 Brian Rebel
h3. "art::EDAnalyzer":https://cdcvs.fnal.gov/redmine/projects/art/repository/revisions/master/entry/art/Framework/Core/EDAnalyzer.h 
28 1 Brian Rebel
29 11 Brian Rebel
This is a type of module that analyzes data products but cannot write them in an art::Event. The module takes a fhicl::ParameterSet in the constructor and uses that to configure that module.  
30 11 Brian Rebel
31 11 Brian Rebel
The module can also implement a reconfigure method to allow for run time reconfiguration, for example while running the event display.  Reconfiguration during a batch job would not make sense.
32 11 Brian Rebel
33 22 Enrique Arrieta Diaz
The user must supply the implementation for the art::EDAnalyzer::analyze() method to analyze data products and the art::EDProducer::reconfigure() method to allow for reconfiguration from the event display.
34 1 Brian Rebel
35 47 Brian Rebel
h3. art::EDProducer(Analyzer)::beginJob, endJob, etc 
36 1 Brian Rebel
37 1 Brian Rebel
These are methods that do tasks that are needed only once a job starts, ends, or a run starts or ends, etc.  For example, a beginJob method would likely contain definitions of histograms that might need to be filled during the operation of the module.
38 1 Brian Rebel
39 47 Brian Rebel
h3. "art::Event.h":https://cdcvs.fnal.gov/redmine/projects/art/repository/revisions/master/entry/art/Framework/Principal/Event.h 
40 1 Brian Rebel
41 7 Brian Rebel
The art::Event is the primary way to access products made by EDProducer type modules.  
42 1 Brian Rebel
43 1 Brian Rebel
It also provide the user with information about an event such as the run, event number, etc through methods like
44 1 Brian Rebel
45 1 Brian Rebel
<pre><code class="c">
46 1 Brian Rebel
47 7 Brian Rebel
// assume we have an art::Event &evt
48 1 Brian Rebel
49 1 Brian Rebel
// get the run number RunNumber_t is a typedef to unsigned int
50 7 Brian Rebel
art::RunNumber_t run = evt.run();
51 1 Brian Rebel
52 1 Brian Rebel
// get the subrun number SubRunNumber_t is a typedef to unsigned int
53 7 Brian Rebel
art::SubRunNumber_t subRun = evt.subRun();
54 1 Brian Rebel
55 10 Brian Rebel
// get the time stamp.  art::Timestamp::value() returns a TimeValue_t which is a typedef to unsigned long long.
56 1 Brian Rebel
// The conventional use is for the upper 32 bits to have the seconds since 1970 epoch and the lower 32 bits to be
57 10 Brian Rebel
// the number of nanoseconds with the current second.
58 7 Brian Rebel
art::Timestamp ts = evt.time();
59 3 Brian Rebel
60 3 Brian Rebel
// make it into a TTimeStamp
61 23 Brian Rebel
uint32_t tslow  = ts.timeLow();
62 23 Brian Rebel
uint32_t tshigh = ts.timeHigh();
63 1 Brian Rebel
64 23 Brian Rebel
TTimeStamp tts(tshigh, tslo);
65 1 Brian Rebel
66 7 Brian Rebel
// get the event number - this calls a reference to art::EventID().  EventNumber_t is a typedef to unsigned int
67 7 Brian Rebel
art::EventNumber_t event = evt.id().event();
68 1 Brian Rebel
</code></pre>
69 1 Brian Rebel
70 1 Brian Rebel
The header files for the classes mentioned above are at 
71 1 Brian Rebel
72 7 Brian Rebel
"art::EventID.h":https://cdcvs.fnal.gov/redmine/projects/art/repository/revisions/master/entry/art/Persistency/Provenance/EventID.h
73 7 Brian Rebel
"art::Timestamp.h":https://cdcvs.fnal.gov/redmine/projects/art/repository/revisions/master/entry/art/Persistency/Provenance/Timestamp.h
74 1 Brian Rebel
75 7 Brian Rebel
The art::Event can also be used to access products by asking it to return an art::Handle.
76 1 Brian Rebel
77 47 Brian Rebel
h3. "art::Handle":https://cdcvs.fnal.gov/redmine/projects/art/repository/revisions/master/entry/art/Framework/Principal/Handle.h 
78 1 Brian Rebel
79 7 Brian Rebel
An art::Handle is what is returned to a Module when a data product is requested.  The request can either be from a art::EDProducer that is attempting to get objects stored in a previous reconstruction or analysis step, or it can be from a art::EDAnalyzer that is attempting to do some analysis task using the information in the object.  For example, to get the data product mp::MyProd from the event, one should do
80 1 Brian Rebel
81 1 Brian Rebel
<pre><code class="c">
82 7 Brian Rebel
  art::Handle< std::vector<mp::MyProd> > mplistHandle;
83 1 Brian Rebel
  evt.getByLabel("moduleprocesslabel",mplistHandle);
84 1 Brian Rebel
</code></pre>
85 1 Brian Rebel
86 7 Brian Rebel
where evt is an object of type art::Event discussed below.  The art::Event::getByLabel method takes two arguments, the first is the name of the process associated with the module that produced the list of mp::MyProd objects, and the second is the art::Handle that is to be associated to the list.
87 1 Brian Rebel
88 13 Brian Rebel
You can also get all objects of a given type out of the event using the art::Event::getByType method:
89 13 Brian Rebel
90 13 Brian Rebel
<pre><code class="c">
91 13 Brian Rebel
  art::Handle< std::vector<mp::MyProd> > mplistHandle;
92 13 Brian Rebel
  evt.getByType(mplistHandle);
93 13 Brian Rebel
</code></pre>
94 13 Brian Rebel
95 13 Brian Rebel
Notice that no module label is used because we are getting all objects of the specified type out of the event.
96 13 Brian Rebel
97 7 Brian Rebel
art::Handles look like a pointer in the code in that the data members of the object being handled are accessed using the "->".  For example, to get the size of the list one can do
98 1 Brian Rebel
99 1 Brian Rebel
<pre><code class="c">
100 1 Brian Rebel
  mplistHandle->size();
101 1 Brian Rebel
</code></pre>
102 1 Brian Rebel
103 55 Brian Rebel
To use the objects in the handle collection, you can 
104 1 Brian Rebel
105 55 Brian Rebel
* Use the art::Handle directly, 
106 1 Brian Rebel
<pre><code class="c">
107 16 Brian Rebel
// in the code below, ev is an art::Event...
108 16 Brian Rebel
art::Handle<std::vector<mp::MyProd> > hnd;
109 16 Brian Rebel
ev.getByLabel("...", hnd); // use the appropriate label, not "..." 
110 1 Brian Rebel
111 55 Brian Rebel
for(size_t i = 0; i < hnd->size(); ++i){
112 55 Brian Rebel
    const mp::MyProd& mp = hnd->at(i);
113 55 Brian Rebel
}
114 55 Brian Rebel
</code></pre>
115 55 Brian Rebel
116 55 Brian Rebel
* Get the collection from the art::Handle,
117 55 Brian Rebel
<pre><code class="c">
118 55 Brian Rebel
// in the code below, ev is an art::Event...
119 55 Brian Rebel
art::Handle<std::vector<mp::MyProd> > hnd;
120 55 Brian Rebel
ev.getByLabel("...", hnd); // use the appropriate label, not "..." 
121 55 Brian Rebel
122 55 Brian Rebel
std::vector<mp::MyProd>& mpvec(*hnd);
123 55 Brian Rebel
}
124 55 Brian Rebel
</code></pre>
125 55 Brian Rebel
126 55 Brian Rebel
* Make a std::list of art::Ptr<mp::MyProd>,
127 55 Brian Rebel
<pre><code class="c">
128 55 Brian Rebel
// in the code below, ev is an art::Event...
129 55 Brian Rebel
art::Handle<std::vector<mp::MyProd> > hnd;
130 55 Brian Rebel
ev.getByLabel("...", hnd); // use the appropriate label, not "..." 
131 55 Brian Rebel
132 16 Brian Rebel
std::list<Ptr<mp::MyProd> > ptrs;
133 16 Brian Rebel
art::fill_ptr_list(ptrs, hnd);
134 16 Brian Rebel
// now ptrs contains Ptr<mp::MyProd> instances, each pointing
135 16 Brian Rebel
// to one of the rb::Tracks in the collection to which hnd
136 1 Brian Rebel
// refers.
137 19 Brian Rebel
</code></pre>
138 1 Brian Rebel
139 55 Brian Rebel
* Make a std::vector of art::Ptr<mp::MyProd>,
140 19 Brian Rebel
<pre><code class="c">
141 19 Brian Rebel
// in the code below, ev is an art::Event...
142 19 Brian Rebel
art::Handle<std::vector<mp::MyProd> > hnd;
143 19 Brian Rebel
ev.getByLabel("...", hnd); // use the appropriate label, not "..." 
144 19 Brian Rebel
145 46 Brian Rebel
std::vector<Ptr<mp::MyProd> > ptrs;
146 19 Brian Rebel
art::fill_ptr_vector(ptrs, hnd);
147 19 Brian Rebel
// now ptrs contains Ptr<mp::MyProd> instances, each pointing
148 1 Brian Rebel
// to one of the rb::Tracks in the collection to which hnd
149 19 Brian Rebel
// refers.
150 1 Brian Rebel
</code></pre>
151 19 Brian Rebel
152 55 Brian Rebel
Use the const std::vector<mp::MyProd>, std::list< art::Ptr<mp::MyProd> >, or std::vector< art::Ptr<mp::MyProd> > if you want to be able to modify the collection of objects. 
153 16 Brian Rebel
154 55 Brian Rebel
* Make a art::PtrVector (discussed below).  
155 16 Brian Rebel
<pre><code class="c">
156 7 Brian Rebel
// make an art::PtrVector of the objects
157 7 Brian Rebel
art::PtrVector<mp::MyProd> prodvec;
158 1 Brian Rebel
for(unsigned int i = 0; i < mplistHandle->size(); ++i){
159 1 Brian Rebel
  art::Ptr<mp::MyProd> prod(mplistHandle, i);
160 1 Brian Rebel
  prodvec.push_back(prod);
161 7 Brian Rebel
}
162 1 Brian Rebel
</code></pre>
163 55 Brian Rebel
164 55 Brian Rebel
The reason for using std::list or std::vector rather than art::PtrVector<T> for this use case is that we expected people to want to modify the collection, e.g. to re-order it, or to remove elements. This is more efficient if done with the list or vector rather than the art::PtrVector.
165 1 Brian Rebel
166 1 Brian Rebel
Most code in the modules should probably use the std::list to establish the final set of art::Ptrs to mp::MyProd data objects stored in the event.  The final set of art::Ptrs can then be saved in a new data product as an art::PtrVector if that is needed.
167 19 Brian Rebel
168 19 Brian Rebel
*NB* Only art::PtrVectors correctly save the references to objects made in other modules, so if you want to save the collection, it must be done as an art::PtrVector.
169 1 Brian Rebel
170 47 Brian Rebel
h3. Upcast on read
171 1 Brian Rebel
172 7 Brian Rebel
The upcast on read functionality can be used to read back objects written into a file that follow a simple inheritance scheme, ie reading in objects of a derived type using the base class type.  For instance, rb::Tracks which inherit from rb::Prongs.  The objects are retrieved from the art::Event by passing a std::vector<const myprod::MyObject*> to the art::Event::getView() method. An example of using this functionality is
173 1 Brian Rebel
174 1 Brian Rebel
<pre><code class="c">
175 7 Brian Rebel
    // declare the std::vector
176 7 Brian Rebel
    std::vector<const rb::Prong*> prongs;
177 7 Brian Rebel
178 2 Brian Rebel
    // Read in the list of rb::Tracks we made in fTrackModuleLabel as rb::Prongs.
179 7 Brian Rebel
    evt.getView(fTrackModuleLabel,prongs);
180 1 Brian Rebel
181 1 Brian Rebel
</code></pre>
182 1 Brian Rebel
183 7 Brian Rebel
Notice that the vector is of const pointers of the requested type.  You shouldn't save these vectors anywhere (ie as collections in other data objects).  Instead they are should only be used for information, ie in the event display.
184 2 Brian Rebel
185 7 Brian Rebel
h3. "cet::search_path":https://cdcvs.fnal.gov/redmine/projects/cetlib/repository/revisions/master/entry/cetlib/search_path.h
186 2 Brian Rebel
187 7 Brian Rebel
This is a utility that will search a list of predefined directories for a relative location of a file.  For instance, if you want to use the geometry definition for the near detector, neardet.gdml, as the input for the Geometry service, you would pass the geometry service the value "Geometry/gdml/neardet.gdml" as an std::string.  The cet::search_path object then searches through the previously defined @$FW_SEARCH_PATH@ variable to see if it can locate the specified file.  It will then allow access to information about the file, including its full path.  This is helpful when writing code that should search for a given file in several locations such as private and public contexts in the SRT build system.  The necessary variables are set when a user sets up the environment.  If a user wants the search path to include a test release, the the user should do
188 2 Brian Rebel
189 2 Brian Rebel
@$srt_setup -a@ 
190 2 Brian Rebel
191 2 Brian Rebel
from within that test release.
192 2 Brian Rebel
193 7 Brian Rebel
An example of using cet::search_path is
194 1 Brian Rebel
195 7 Brian Rebel
<pre><code class="c">
196 7 Brian Rebel
    
197 7 Brian Rebel
    // constructor decides if initialized value is a path or an environment variable
198 7 Brian Rebel
    // FW_SEARCH_PATH is set to be a cascade with SRT_PRIVATE_CONTEXT, SRT_PUBLIC_CONTEXT and
199 7 Brian Rebel
    // directory where perhaps auxiliary root files are stored 
200 7 Brian Rebel
    cet::search_path sp("FW_SEARCH_PATH");
201 7 Brian Rebel
202 7 Brian Rebel
    // taking a parameter from the parameter set passed into the geometry as the first argument,
203 7 Brian Rebel
    // the second argument is the local variable storing the full path - both are std::string objects
204 7 Brian Rebel
    sp.find_file(pset.get< std::string >("GDML"), fGDMLFile); //fGDMLFile is the relative path to a file
205 7 Brian Rebel
206 7 Brian Rebel
    // Open the GDML file and test if it is there
207 7 Brian Rebel
    struct stat sb;
208 7 Brian Rebel
    if (fGDMLFile.empty() || stat(fGDMLFile.c_str(), &sb)!=0)
209 7 Brian Rebel
      // failed to resolve the file name
210 7 Brian Rebel
      throw cet::exception("NoGDMLGeometry") 
211 7 Brian Rebel
	<< "geometry gdml file " << fGDMLFile << " not found!";
212 7 Brian Rebel
213 7 Brian Rebel
</code></pre>
214 7 Brian Rebel
215 48 Brian Rebel
h3. "fhicl::ParameterSet":https://cdcvs.fnal.gov/redmine/projects/fhicl-cpp/repository/revisions/master/entry/fhiclcpp/ParameterSet.h
216 7 Brian Rebel
217 10 Brian Rebel
This object keeps track of which parameters are to be set by the user at run time for a module or art::Service.  It can interpret several data types, including those listed below.  An example for how to read the parameter types from the module constructor is listed for each type. See [[Running Jobs]] for examples of the job configuration file syntax for each type.
218 1 Brian Rebel
219 7 Brian Rebel
* bool:                      fMyBool      (pset.get< bool >("MyBool"))
220 7 Brian Rebel
* int:                       fMyInt       (pset.get< int >("MyInt"))
221 7 Brian Rebel
* unsigned int:              fMyUInt      (pset.get< unsigned int >("MyUInt"))
222 7 Brian Rebel
* std::vector<int>:          fMyVInt      (pset.get< std::vector<int> >("MyVInt"))
223 7 Brian Rebel
* std::vector<unsigned int>: fMyVUInt     (pset.get< std::vector<unsigned int> >("MyVUInt"))
224 7 Brian Rebel
* std::string:               fMyString    (pset.get< std::string >("MyString"))
225 7 Brian Rebel
* std::vector<std::string>:  fMyVString   (pset.get< std::vector<std::string> >("MyVString"))
226 7 Brian Rebel
* double:                    fMyDouble    (pset.get< double >("MyDouble"))
227 7 Brian Rebel
* std::vector<double>:       fMyVDouble   (pset.get< std::vector<double> >("MyDouble"))
228 1 Brian Rebel
229 1 Brian Rebel
Other types are available, but the above list should serve almost all a user's needs.
230 1 Brian Rebel
231 47 Brian Rebel
h3. "art::ServiceHandle":https://cdcvs.fnal.gov/redmine/projects/art/repository/revisions/master/changes/art/Framework/Services/Registry/Service.h
232 1 Brian Rebel
233 59 Jan Zirnstein
The art::ServiceHandle is a templated object that behaves like a singleton, except that it is owned and managed by the framework. A service can be used within any module. Services can be configured using the job configuration file.  A typical example of the use of a service is the detector Geometry.  The Geometry is needed in just about every module, but you don't want to keep making instances of the Geometry.  Additionally, the different detectors may have to set different parameter values that should be handled in the job configuration. Finally, *do not* define a global service handle, it will compile, but break at runtime.
234 1 Brian Rebel
235 7 Brian Rebel
h3. "art::TFileService":https://cdcvs.fnal.gov/redmine/projects/art/repository/revisions/master/entry/art/Framework/Services/Optional/TFileService.h
236 1 Brian Rebel
237 1 Brian Rebel
This is a specialized service that connects up to the file where histograms made by modules are to be stored.  It provides a mechanism for making TObjects to be stored in that file and managing the memory for those objects.  For example
238 1 Brian Rebel
239 1 Brian Rebel
<pre><code class="c">
240 1 Brian Rebel
    // get the geometry to figure out something for the histogram
241 10 Brian Rebel
    art::ServiceHandle<geo::Geometry> geo;
242 1 Brian Rebel
243 6 Brian Rebel
    // get access to the TFile service
244 10 Brian Rebel
    art::ServiceHandle<art::TFileService> tfs;
245 1 Brian Rebel
246 10 Brian Rebel
    // make the histogram - fHist is assumed to have been declared in the .h file
247 10 Brian Rebel
    fHist    = tfs->make<TH1D>("channels",  ";channel;# PE",  geo->Nchannels(), 0, geo->Nchannels());
248 6 Brian Rebel
249 6 Brian Rebel
    // note that for some reason ROOT does not automatically connect TGraphs to the output directory when created 
250 6 Brian Rebel
    // like it does for histograms.  So we have to do that ourselves using the ROOT global directory variable gDirectory
251 6 Brian Rebel
    fGraph   = tfs->make<TGraph>(); //default constructor, set number of points and values later
252 6 Brian Rebel
    gDirectory->Append(fGraph);
253 6 Brian Rebel
254 6 Brian Rebel
</code></pre>
255 6 Brian Rebel
256 6 Brian Rebel
257 7 Brian Rebel
h3. "MessageLogger":https://cdcvs.fnal.gov/redmine/projects/messagefacility/repository/revisions/master/entry/messagefacility/MessageLogger/MessageLogger.h
258 6 Brian Rebel
259 10 Brian Rebel
The MessageLogger provides several levels of messages that can be used to print information to an output log.  The levels most likely to be useful are LogDebug, mf::LogInfo, mf::LogWarning and mf::LogError.  Note there is no mf:: in front of LogDebug because it is a macro that will include the file and line numbers of the code producing the output.  These are listed in order of severity.  The MessageLogger can be configured to set the number of messages printed and to send each class of message to a different output stream.
260 1 Brian Rebel
261 7 Brian Rebel
In order to issue messages, the module must include the MessageLogger header:
262 6 Brian Rebel
263 1 Brian Rebel
<pre><code class="c">
264 7 Brian Rebel
  #include "messagefacility/MessageLogger/MessageLogger.h"
265 1 Brian Rebel
</code></pre>
266 1 Brian Rebel
267 18 Brian Rebel
In addition, it is strongly recommended (for consistency with the way all services are used ) that the .fcl file contain at least the line
268 1 Brian Rebel
269 1 Brian Rebel
<pre>
270 18 Brian Rebel
  message: { }
271 1 Brian Rebel
</pre>
272 18 Brian Rebel
273 18 Brian Rebel
In the services block.
274 6 Brian Rebel
275 1 Brian Rebel
The braces can enclose specifications of parameters to adjust the MessageLogger behavior (see MessageLogger Parameters ); if no parameters are supplied, a sensible default behavior is provided.
276 1 Brian Rebel
277 10 Brian Rebel
If the .fcl file does not specify the MessageLogger service, or if a message is issued in code executed before any services are initiated, then the response to issuing a message will be that the content will be sent to cerr. Having included the necessary MessageLogger header, when code wishes to issue a message, one of these functions can be used:
278 6 Brian Rebel
279 6 Brian Rebel
<pre><code class="c">
280 7 Brian Rebel
  mf::LogError    ("category") << a << b << ... << z;
281 7 Brian Rebel
  mf::LogWarning  ("category") << a << b << ... << z;
282 7 Brian Rebel
  mf::LogInfo     ("category") << a << b << ... << z;
283 7 Brian Rebel
  mf::LogVerbatim ("category") << a << b << ... << z;
284 6 Brian Rebel
</code></pre>
285 6 Brian Rebel
286 6 Brian Rebel
When issuing messages:
287 6 Brian Rebel
288 6 Brian Rebel
    * LogInfo, LogWarning, and LogError represent three levels of "severity" of the message. It is possible (see MessageLogger Parameters ) to configure the job to ignore all LogInfo messages, or all messages of severity less than LogError.
289 6 Brian Rebel
    * LogVerbatim is identical in all ways to LogInfo, except that absolutely no message formatting is performed, and no context, module, or other information is appended to the message. This is appropriate, for example, if the program has prepared a nicely-formatted table for output.
290 6 Brian Rebel
    * The category should specify what this message is about. The category will generally appear as the first part of the message, but it also plays two other roles:
291 6 Brian Rebel
         1. It is possible to set limits on how many times some specific type of message will be sent to the outputs of the logger. By "type" we mean any messages with some specific category. See MessageLogger Parameters for details.
292 6 Brian Rebel
         2. When message statistics are provided, the counts of how many times messages of a given type were issued are keyed to category, module label, and (if provided) subroutine. 
293 6 Brian Rebel
      Normally a category name should be up to 20 characters long, without special characters other than underscore.
294 6 Brian Rebel
    * It is unnecessary to explicitly specify the module label or the run/event number; these are automatically provided by the logger.
295 6 Brian Rebel
    * An arbitrary number of additional objects << a << b << ... << z can be appended to the message. These can be strings, ints, doubles, or any object that has an operator<< to an ostream. (Or the message can be issued with no additional objects at all.)
296 1 Brian Rebel
    * There is no need to add spaces at the beginning or end of text items sent to the message, or to add text separators between numerical items. This spacing is taken care of by the logger. However, if any item appended to a message ends in a space, then it is assumed that the user is handling spacing explicitly, and no further automatic spaces are inserted for that message.
297 1 Brian Rebel
    * There is no need to affix any sort of endl; when the statement ends the message will be dispatched.
298 1 Brian Rebel
    * Newline characters can be included in the objects appended to the message. These will be used in formatting the message. But they are generally not necessary: Line breaks are automatically inserted if the next appended object would cause the line to exceed 80 characters. 
299 6 Brian Rebel
300 1 Brian Rebel
There is an additional form for issuing a message:
301 1 Brian Rebel
302 28 Brian Rebel
    LOG_DEBUG("category") << a << b << ... << z;
303 1 Brian Rebel
304 1 Brian Rebel
This is identical to the others, except:
305 1 Brian Rebel
306 28 Brian Rebel
    * LOG_DEBUG affixes the __FILE__ and __LINE__ number to the message.
307 28 Brian Rebel
    * LOG_DEBUG messages are considered to be lower in severity than mf::LogInfo messages.
308 28 Brian Rebel
    * By default, LOG_DEBUG messages will be rapidly discarded with a minimum of overhead. The user must specify in the .fcl file LOG_DEBUG messages from various modules are to be enabled; see Controlling LogDebug Behavior: Enabling LogDebug Messages for how that is done.
309 1 Brian Rebel
    * Because it must get __FILE__ and __LINE__ from the spot issuing the message, LogDebug is implemented as a macro rather than a free function.
310 28 Brian Rebel
    * Because LOG_DEBUG is a macro, it is not prepended with the art:: namespace designation. 
311 5 Brian Rebel
312 1 Brian Rebel
An alternative function for issuing a debug message is:
313 5 Brian Rebel
314 28 Brian Rebel
    LOG_TRACE("category") << a << b << ... << z;
315 1 Brian Rebel
316 28 Brian Rebel
LOG_TRACE is identical in every way to LOG_DEBUG, except that absolutely no formatting or in formation appending will be done. This is appropriate, for example, for trace output coming from a package which assumes it has full control of formatting.
317 1 Brian Rebel
318 28 Brian Rebel
All configuration of what is done when LOG_TRACE messages are issued is taken from the control issued for LOG_DEBUG. Similarly, the configuration of what is done when mf::LogVerbatim messages are issued is taken from the control issued for mf::LogInfo. 
319 1 Brian Rebel
320 1 Brian Rebel
Details on how to set message levels and verbosity, etc, can be found "here":http://www.uscms.org/LPC/lpc_offl/MessageLogger/MessageLogger.html
321 1 Brian Rebel
322 27 Brian Rebel
h3. art::RandomNumberGenerator Service
323 27 Brian Rebel
324 27 Brian Rebel
A nice description of how to use this service can be found "here":http://mu2e.fnal.gov/public/hep/computing/Random.shtml.  Note that this write up is for the older fw implementation of art, but there are only minor differences.
325 1 Brian Rebel
326 40 Brian Rebel
To store the "state":https://cdcvs.fnal.gov/redmine/projects/art/repository/revisions/master/entry/art/Persistency/Common/RNGsnapshot.h of the random number engines for each event one must add the RandomNumberSaver module to the list of physics producers to be run by the job.  The necessary line to add to the fcl file is
327 36 Brian Rebel
328 36 Brian Rebel
<pre><code class="C">
329 36 Brian Rebel
physics{
330 36 Brian Rebel
 producers{
331 36 Brian Rebel
   ...
332 36 Brian Rebel
   rns: { module_type: "RandomNumberSaver" }
333 36 Brian Rebel
 }
334 36 Brian Rebel
 
335 36 Brian Rebel
 ...
336 36 Brian Rebel
}
337 37 Brian Rebel
</code></pre>
338 36 Brian Rebel
339 61 Susan Lein
For a more complete description of RandomNumberSaver, how to implement it in the job fcl file and then restore the random number state saved in a later job, please see this section of the "documentation":http://mu2e.fnal.gov/public/hep/computing/Random.shtml#saverestore.
340 60 Susan Lein
341 49 Brian Rebel
h3. "cet::exception":https://cdcvs.fnal.gov/redmine/projects/cetlib/repository/revisions/master/entry/cetlib/exception.h
342 1 Brian Rebel
343 10 Brian Rebel
The cet::exception can be used to cause the framework to end a job gracefully if some predetermined bad thing happens.  The use of the art::exception can be configured to skip a module, or skip to the next event, run, etc.  Different exception classes can be set to do different things.
344 1 Brian Rebel
345 7 Brian Rebel
art::exception can be used as follows:
346 1 Brian Rebel
347 1 Brian Rebel
<pre><code class="c">
348 10 Brian Rebel
if(x > 2) throw cet::exception("SomeUsefulDescription") << "x = " << x << " is too big";
349 1 Brian Rebel
</code></pre>
350 1 Brian Rebel
351 7 Brian Rebel
Detailed instructions for using exceptions under the former incarnation of ART are attached to this page, attachment:CMS_SWGuideEdmExceptionUse.pdf.  These instructions may no longer be accurate.
352 1 Brian Rebel
353 12 Christopher Green
In short however, the default behavior of the framework upon catching an exception is to rethrow (except for some system exceptions, which skip the event). However, one can specify the behavior for exceptions with the following configuration fragment:
354 12 Christopher Green
355 12 Christopher Green
<pre>
356 12 Christopher Green
services.scheduler.XXXX: [ "SomeUsefulDescription", "SomeOtherUsefulDescription", ... ]
357 12 Christopher Green
</pre> 
358 12 Christopher Green
359 12 Christopher Green
where @XXX@ can be:
360 12 Christopher Green
* @Rethrow@;
361 12 Christopher Green
* @IgnoreCompletely@;
362 12 Christopher Green
* @SkipEevent@;
363 12 Christopher Green
* @FailModule@ (behave as if the module returned a failure value for this event);
364 12 Christopher Green
* @FailPath@ (behave as if the path rejected this event).
365 12 Christopher Green
366 12 Christopher Green
Note that the @FailModule@ setting does not imply a path rejection if the module throwing the exception so configured is a filter set to "VETO" or "IGNORE."
367 12 Christopher Green
368 57 Robert Hatcher
A NOvA specific discussion of using cet::exceptions can be found here: [[NOVA exceptions]]
369 57 Robert Hatcher
370 8 Brian Rebel
h3. "art::Ptr<T>":https://cdcvs.fnal.gov/redmine/projects/art/repository/revisions/master/entry/art/Persistency/Common/Ptr.h and "art::PtrVector<T>":https://cdcvs.fnal.gov/redmine/projects/art/repository/revisions/master/entry/art/Persistency/Common/PtrVector.h
371 1 Brian Rebel
372 7 Brian Rebel
The art::Ptr<T> is a template class that acts like a ROOT TRef.  It provides a linkage between objects written into different areas of the event (and output file).  For example, the rb::Cluster object holds an art::PtrVector<rb::CellHit> pointing to the hits contained in the rb::Cluster.  The art::Ptr<T> behaves like a pointer (ie you access the methods of the T using the "->").  It also has functionality to return the actual pointer to the object in question using art::Ptr<T>::get() or to check if the art::Ptr<T> is pointing to a legitimate object using edm::Ptr<T>::isNull().
373 1 Brian Rebel
374 7 Brian Rebel
An art::Ptr<T> can only be made from an object that has been stored in the event record and is being fetched from the event record.  Put another way, you can only make an art::Ptr<T> if you have an art::Handle to a collection of objects of type T.  art::Ptr<T> cannot be instantiated like an object of type T, 
375 1 Brian Rebel
376 1 Brian Rebel
<pre><code class="c">
377 7 Brian Rebel
// The following line will NOT work
378 7 Brian Rebel
art::Ptr<T> myt = new T(); 
379 1 Brian Rebel
</code></pre>
380 1 Brian Rebel
381 1 Brian Rebel
or similar will not work because the object you are interested in for that code has not been first stored in the event record.
382 1 Brian Rebel
383 20 Brian Rebel
An art::PtrVector<T> is a vector of art::Ptr<T> objects.  It provides the basic functionality you would expect from a std::vector, including iterators, size(), begin() and end() methods.  It is useful when storing the connections of many objects of the same type in an object, for example rb::CellHits in a rb::Cluster.  It can also be sorted, 
384 20 Brian Rebel
385 20 Brian Rebel
<pre><code class="c">
386 20 Brian Rebel
art::PtrVector< mp::MyProd > mpcol;
387 20 Brian Rebel
mpcol.sort();
388 20 Brian Rebel
</code></pre>
389 20 Brian Rebel
390 20 Brian Rebel
This example makes use of the predefined "<" operator of the mp::MyProd.  If you want to sort using a function, first define a predicate in the namespace of your module
391 20 Brian Rebel
392 20 Brian Rebel
<pre><code class="c">
393 20 Brian Rebel
namespace mymodule {
394 20 Brian Rebel
395 20 Brian Rebel
  struct SortByTime {
396 20 Brian Rebel
    bool operator()(mp::MyProd const& a, mp::MyProd const& b) const { return a.Time() < b.Time(); }
397 20 Brian Rebel
  };
398 20 Brian Rebel
399 20 Brian Rebel
  //////--------- intervening code calling constructors, destructors, etc, now we are in the produce method ---/////////
400 20 Brian Rebel
401 20 Brian Rebel
  
402 20 Brian Rebel
  art::PtrVector< mp::MyProd > mpcol;
403 20 Brian Rebel
  // fill the PtrVector as in the examples in the art::Handle section above
404 20 Brian Rebel
405 20 Brian Rebel
  mpcol.sort(mymodule::SortByTime());
406 20 Brian Rebel
407 20 Brian Rebel
</code></pre>
408 1 Brian Rebel
409 50 Brian Rebel
h3. "art::Filter":https://cdcvs.fnal.gov/redmine/projects/art/repository/revisions/master/entry/art/Framework/Core/EDFilter.h
410 1 Brian Rebel
411 34 Brian Rebel
The object allows one to filter spills based on information obtained about the event.
412 1 Brian Rebel
413 29 Brian Rebel
h3. "art::Assns":https://cdcvs.fnal.gov/redmine/projects/art/repository/revisions/master/changes/art/Persistency/Common/Assns.h
414 29 Brian Rebel
415 35 Brian Rebel
art::Assns are a way to associate (Assns is a contraction for associations) objects of one type with another.  For example, you may want to associate a recob::Cluster with the rb::Hit objects comprising the rb::Cluster.  The art:Assns object allows you to navigate these associations bidirectionally, that is you can ask a recob::Cluster which rb::Hits it contains, as well as as a rb::Hit to which rb::Cluster it belongs.  The art::Assns also allow us to avoid storing these connections in the higher level object that is being associated.  Instead the associations are stored in the event record.
416 29 Brian Rebel
417 34 Brian Rebel
A set of utility functions to perform the necessary steps to associate objects for storage in the art::Event are found in
418 44 Brian Rebel
source:Utilities/AssociationUtil.h  There are also methods to retrieve a collection of objects of one type that are not associated with objects of another type.  Those methods allow one to retrieve, for example, all rb::Hits from an event that are not associated with rb::Tracks.  The comments in that file describe how to use the functions.  
419 1 Brian Rebel
420 34 Brian Rebel
To make use of the associations and retrieve objects from the file, one would do
421 1 Brian Rebel
422 34 Brian Rebel
<pre><code class="C">
423 34 Brian Rebel
424 35 Brian Rebel
// below trackListHandle is of type art::Handle< std::vector<rb::Track> >, 
425 54 Brian Rebel
// evt is an art::Event, and assnCreatorModule is an std::string holding the 
426 54 Brian Rebel
// label of the module making the associations of hits to tracks...and possibly the same that made the tracks
427 54 Brian Rebel
art::FindMany<rb::Hit> fmh(trackListHandle, evt, assnCreatorModule);
428 34 Brian Rebel
429 34 Brian Rebel
// loop over all tracks in the handle and get their hits
430 34 Brian Rebel
for(size_t t = 0; t < trackListHandle->size(); ++t){
431 35 Brian Rebel
   std::vector<const rb::Hit*> hits = fmh.at(t);
432 34 Brian Rebel
}
433 34 Brian Rebel
434 34 Brian Rebel
// can also get a collection of art::Ptrs instead of const pointers
435 54 Brian Rebel
art::FindManyP<rb::Hit> fmh(trackListHandle, evt, assnCreatorModule);
436 34 Brian Rebel
437 34 Brian Rebel
// loop over all tracks in the handle and get their hits
438 34 Brian Rebel
for(size_t t = 0; t < trackListHandle->size(); ++t){
439 35 Brian Rebel
   std::vector<art::Ptr<rb::Hit> > hits = fmh.at(t);
440 34 Brian Rebel
}
441 34 Brian Rebel
442 34 Brian Rebel
</pre>
443 34 Brian Rebel
444 58 Ruth Toner
If the Assn being retrieved has an instance name associated with it, in addition to a module label, the std::string label (above, assnCreatorModule) can be replaced with an art::InputTag.  In this example, assnCreatorModule would be replaced with art::InputTag(assnCreatorModule, assnCreatorInstance), where assnCreatorInstance is a string with the name of the instance.
445 58 Ruth Toner
446 45 Brian Rebel
One can also use the art::FindOne and art::FindOneP, see the detailed description on how to use art::Assns is "here.":https://cdcvs.fnal.gov/redmine/projects/art/wiki/Inter-Product_References  The art::FindOne returns a cet::maybe_ref, whose interface is defined "here.":http://cdcvs.fnal.gov/lxr/cetlib/source/cetlib/maybe_ref.h#044  The cet::maybe_ref can be tested for validity, allowing a user to be sure a valid association was created.
447 34 Brian Rebel
448 34 Brian Rebel
*NB* The art::FindMany(P) and art::FindOne(P) are smart query objects and should only be instantiated once for a given collection.  If they are instantiated once for each item in a art::Handle, art::PtrVector, art::View or std::vector< art::Ptr<T> > then a heavy performance price will be paid as a lookup table is made multiple times.
449 29 Brian Rebel
450 1 Brian Rebel
h2. Making Objects to Store in the Output
451 1 Brian Rebel
452 7 Brian Rebel
Making objects to store in the art::Event is a straightforward operation.  The first step is to declare a container for the objects, 
453 1 Brian Rebel
454 1 Brian Rebel
<pre><code class="c">
455 1 Brian Rebel
std::auto_ptr<std::vector<mp::MyProd> > mpCollection(new std::vector<mp::MyProd>);
456 1 Brian Rebel
</code></pre>
457 1 Brian Rebel
458 1 Brian Rebel
Here we used the std::auto_ptr because it handles the cleanup of the memory for the collection for us.  
459 1 Brian Rebel
460 1 Brian Rebel
The mpCollection now behaves just like a std::vector, except one accesses the std::vector methods using a "->".  Once the collection has been filled (and it can be a collection of just one object), it is written to the event by doing
461 1 Brian Rebel
462 4 Brian Rebel
<pre><code class="c">
463 1 Brian Rebel
event.put(mpCollection);
464 1 Brian Rebel
</code></pre>
465 1 Brian Rebel
466 25 Brian Rebel
Now the ownership of the collection belongs to the event and the user cannot modify the collection or the objects in the collection any more.  
467 7 Brian Rebel
468 26 Brian Rebel
h2. Schema Evolution for Data Products
469 26 Brian Rebel
470 26 Brian Rebel
Data products may change over time and we will want to do everything we can to ensure backwards compatibility between old and new versions.  Please see "this page":https://cdcvs.fnal.gov/redmine/projects/art/wiki/Facilitating_Schema_Evolution_for_Data_Products on the ART wiki for information on how to evolve a data product while still maintaining backwards compatibility.
471 26 Brian Rebel
472 7 Brian Rebel
h2. Making a Module
473 7 Brian Rebel
474 53 Brian Rebel
The framework provides a command called 'artmod' to generate the boilerplate code required for adding a module to ART. See [[Using_artmod]] for more details.
475 1 Brian Rebel
Below are examples of how to make both an EDProducer module and an EDAnalyzer module.  The examples show basic .h and .cxx files for each.  One other file needs to be made for the module to be recognized by the framework at run time and that is called the _module.cc file.  An example of the module file is also included.  
476 1 Brian Rebel
477 7 Brian Rebel
To recap, you need three files to make a module and they should be named as follows:
478 1 Brian Rebel
479 1 Brian Rebel
*MyModule.h         - the file defining the interface
480 1 Brian Rebel
*MyModule.cxx       - the implementation file
481 1 Brian Rebel
*MyModule_module.cc - the file defining the connection to the framework.
482 1 Brian Rebel
483 15 Brian Rebel
*Important* Module names may not contain underscores. Underscores are special characters used by the ART system for storing data products in an event to label the products according to what module, instance and process created them. Using underscores in module names will result in your job not running.
484 15 Brian Rebel
485 56 Brian Rebel
*NB* Objects are stored in the art::Event as collections of references, not pointers.  You need to get them out of the event as collections of references, not pointers.  
486 1 Brian Rebel
487 10 Brian Rebel
Additionally, if you are getting an object out of an art::Event, you must declare the local variable in your code to be an art::Ptr<T>, not a standard C pointer. See the examples below for details*
488 10 Brian Rebel
489 1 Brian Rebel
h3. EDProducer
490 1 Brian Rebel
491 1 Brian Rebel
<pre><code class="c">
492 1 Brian Rebel
#ifndef MYPRODUCER_H
493 1 Brian Rebel
#define MYPRODUCER_H
494 1 Brian Rebel
495 7 Brian Rebel
#include "art/Framework/EDProducer.h"
496 1 Brian Rebel
497 1 Brian Rebel
class TH1D;
498 1 Brian Rebel
  
499 1 Brian Rebel
///My Module
500 1 Brian Rebel
namespace mm {
501 1 Brian Rebel
  
502 1 Brian Rebel
  ///class to produce a data product
503 7 Brian Rebel
  class MyProducer : public art::EDProducer {
504 1 Brian Rebel
    
505 1 Brian Rebel
  public:
506 1 Brian Rebel
    
507 10 Brian Rebel
    explicit MyProducer(fhicl::ParameterSet const& pset);  // the explicit tag tells the compiler that MyProducer is different from fhicl::ParameterSet
508 1 Brian Rebel
    virtual ~MyProducer();
509 7 Brian Rebel
    void produce(art::Event& evt);                         // makes the objects I want made
510 7 Brian Rebel
    void beginJob();                                      // does things like make histograms at the beginning of the job, also beginRun and beginSpill methods available.
511 1 Brian Rebel
    
512 1 Brian Rebel
  private:
513 1 Brian Rebel
        
514 1 Brian Rebel
    double      fDouble;          ///< some data member
515 1 Brian Rebel
    std::string fPrevModuleLabel; ///< label of the module making objects that i need for this step
516 1 Brian Rebel
    TH1D*       fHist;            ///< a histogram data member
517 1 Brian Rebel
    
518 1 Brian Rebel
  }; // class MyProducer
519 1 Brian Rebel
}
520 1 Brian Rebel
521 1 Brian Rebel
#endif // MYPRODUCER_H
522 1 Brian Rebel
</code></pre>
523 1 Brian Rebel
524 31 Joseph Sobek
The implementation file is then (Note: Where "Core" shows up may need to be "Principal" for your code to actually work)
525 1 Brian Rebel
526 1 Brian Rebel
<pre><code class="c">
527 1 Brian Rebel
528 1 Brian Rebel
#include <iostream>
529 1 Brian Rebel
530 7 Brian Rebel
// Framework includes
531 1 Brian Rebel
#include "art/Framework/Core/Event.h"
532 7 Brian Rebel
#include "fhiclcpp/ParameterSet.h"
533 7 Brian Rebel
#include "art/Persistency/Common/Handle.h"
534 7 Brian Rebel
#include "art/Persistency/Common/OrphanHandle.h"
535 7 Brian Rebel
#include "art/Persistency/Common/Ptr.h"
536 7 Brian Rebel
#include "art/Persistency/Common/PtrVector.h"
537 7 Brian Rebel
#include "art/Framework/Services/Registry/Service.h"
538 7 Brian Rebel
#include "art/Framework/Services/Optional/TFileService.h"
539 7 Brian Rebel
#include "art/Framework/Core/TFileDirectory.h"
540 7 Brian Rebel
#include "messagefacility/MessageLogger/MessageLogger.h"
541 1 Brian Rebel
542 1 Brian Rebel
#include "MyModule/MyProducer.h"
543 1 Brian Rebel
#include "Geometry/geo.h"
544 1 Brian Rebel
#include "MyProducts/MyProduct.h"
545 1 Brian Rebel
#include "MyProducts/MyOtherProduct.h"
546 1 Brian Rebel
547 1 Brian Rebel
#include "TH1.h"
548 1 Brian Rebel
549 1 Brian Rebel
namespace mm{
550 1 Brian Rebel
551 1 Brian Rebel
  //-----------------------------------------------------
552 10 Brian Rebel
  MyProducer::MyProducer(fhicl::ParameterSet const& pset) :
553 7 Brian Rebel
    fDouble             (pset.get< double >     ("TheDouble")),
554 7 Brian Rebel
    fPrevModuleLabel    (pset.get< std::string >("PreviousModuleLabel"))
555 1 Brian Rebel
  {
556 1 Brian Rebel
    produces< std::vector<mp::MyOtherProduct> >(); // this line tells the module what it is going to make, you must have one line
557 1 Brian Rebel
                                                   // for each type of collection to be made
558 1 Brian Rebel
559 1 Brian Rebel
  }
560 1 Brian Rebel
561 1 Brian Rebel
  //-----------------------------------------------------
562 1 Brian Rebel
  MyProducer::~MyProducer()
563 1 Brian Rebel
  {
564 1 Brian Rebel
  }
565 1 Brian Rebel
566 1 Brian Rebel
  //-----------------------------------------------------
567 7 Brian Rebel
  void MyProducer::beginJob()
568 1 Brian Rebel
  {
569 1 Brian Rebel
    // get access to the TFile service
570 7 Brian Rebel
    art::ServiceHandle<art::TFileService> tfs;
571 1 Brian Rebel
572 1 Brian Rebel
    // get the geometry to figure out something for the histogram
573 7 Brian Rebel
    art::ServiceHandle<geo::Geometry> geo;
574 1 Brian Rebel
575 1 Brian Rebel
    fHist    = tfs->make<TH1D>("channels",  ";channels;",  geo->NPlanes()*geo->Plane(0)->Ncells(), 0, geo->NPlanes()*geo->Plane(0)->Ncells());
576 1 Brian Rebel
577 1 Brian Rebel
    return;
578 1 Brian Rebel
  }
579 1 Brian Rebel
580 1 Brian Rebel
  //-----------------------------------------------------
581 7 Brian Rebel
  void MyProducer::produce(art::Event& evt)
582 1 Brian Rebel
  {
583 1 Brian Rebel
    
584 1 Brian Rebel
    //get a collection of electrons
585 1 Brian Rebel
    std::auto_ptr<std::vector<mp::MyOtherProduct> > mopcol(new std::vector<mp::MyOtherProduct>);
586 1 Brian Rebel
587 1 Brian Rebel
    // maybe I will need the geometry service here too
588 7 Brian Rebel
    art::ServiceHandle<geo::Geometry> geom;
589 1 Brian Rebel
  
590 1 Brian Rebel
    double xyz[3] = {0.};
591 1 Brian Rebel
    double xyz1[3] = {0.};
592 1 Brian Rebel
    int planes = geom->NPlanes();
593 1 Brian Rebel
  
594 1 Brian Rebel
    ///plane 0 is the first induction plane, every plane has a wire 0
595 1 Brian Rebel
    geom->Plane(0)->GetCenter(xyz);
596 1 Brian Rebel
597 1 Brian Rebel
    // grab the mp::MyProducts made in the last module
598 7 Brian Rebel
    art::Handle< std::vector<mp::MyProduct> > mplistHandle;
599 1 Brian Rebel
    evt.getByLabel(fPrevModuleLabel,mplistHandle);
600 1 Brian Rebel
601 1 Brian Rebel
    // loop over the list of MyProducts
602 1 Brian Rebel
    for(unsigned int i = 0; i < mplistHandle->size(); ++i){
603 1 Brian Rebel
604 1 Brian Rebel
      //get a edm::Ptr to the MyProducts
605 7 Brian Rebel
      art::Ptr<mp::MyProduct> mpMyProd(mplistHandle, i);
606 1 Brian Rebel
607 1 Brian Rebel
      // do something to turn out MyOtherProducts - not shown here
608 1 Brian Rebel
609 1 Brian Rebel
      // add the new MyOtherProduct to the collection
610 1 Brian Rebel
      mopcol->push_back(myOtherProd)
611 1 Brian Rebel
    }
612 1 Brian Rebel
613 1 Brian Rebel
    evt.put(mopcol);
614 1 Brian Rebel
615 1 Brian Rebel
    // mopcol is no longer a valid pointer - don't use it any more!
616 1 Brian Rebel
    // if for some reason you still want access to the products in mopcol, then use 
617 1 Brian Rebel
    // this syntax where the return value is a "read only pointer" to the data product 
618 7 Brian Rebel
    // art::OrphanHandle< std::vector<mp::MyOtherProd> > q = event.put(mopcol);
619 7 Brian Rebel
    // mf::LogInfo("NumMyProds") << "Number of products: " << q->size();
620 1 Brian Rebel
621 1 Brian Rebel
    return;
622 1 Brian Rebel
623 1 Brian Rebel
  }
624 1 Brian Rebel
625 1 Brian Rebel
}
626 1 Brian Rebel
</code></pre>
627 1 Brian Rebel
628 10 Brian Rebel
And now the _module.cc file.  The need for separate files for the implementation and this file was not obvious to me to begin with.  Having separate files allows you to produce .so libraries for both the plugin and the rest of the objects in the package.  SRT also likes to have .cxx targets to build, so that is another reason to have separate .cxx and _module.cc files.
629 1 Brian Rebel
630 1 Brian Rebel
For this example, the plugin file is named MyProducer_plugin.cc.
631 1 Brian Rebel
632 1 Brian Rebel
<pre><code class="c">
633 10 Brian Rebel
// Framework includes
634 1 Brian Rebel
#include "art/Framework/Core/ModuleMacros.h"
635 1 Brian Rebel
636 1 Brian Rebel
// NOvASoft includes
637 1 Brian Rebel
#include "MyModule/MyProducer.h"
638 1 Brian Rebel
639 1 Brian Rebel
namespace mm {
640 1 Brian Rebel
641 1 Brian Rebel
  // A macro required for a JobControl module.
642 7 Brian Rebel
  DEFINE_ART_MODULE(MyProducer);
643 1 Brian Rebel
644 1 Brian Rebel
} // namespace mm
645 1 Brian Rebel
</code></pre>
646 1 Brian Rebel
647 1 Brian Rebel
h3. EDAnalyzer
648 1 Brian Rebel
649 1 Brian Rebel
<pre><code class="c">
650 1 Brian Rebel
#ifndef MYANALYZERER_H
651 1 Brian Rebel
#define MYANALYZER_H
652 1 Brian Rebel
653 7 Brian Rebel
#include "art/Framework/Core/EDAnalyzer.h"
654 1 Brian Rebel
655 1 Brian Rebel
class TH1D;
656 1 Brian Rebel
  
657 1 Brian Rebel
658 10 Brian Rebel
// My Module
659 1 Brian Rebel
namespace mm {
660 1 Brian Rebel
  
661 10 Brian Rebel
  // class to produce a data product
662 7 Brian Rebel
  class MyAnalyzer : public art::EDAnalyzer {
663 1 Brian Rebel
    
664 1 Brian Rebel
  public:
665 7 Brian Rebel
    
666 10 Brian Rebel
    explicit MyAnalyzer(fhicl::ParameterSet const& pset);  // the explicit tag tells the compiler that MyProducer is different from fhicl::ParameterSet
667 7 Brian Rebel
    virtual ~MyAnalyzer();
668 10 Brian Rebel
    void analyze(const art::Event& evt);                   // makes the objects I want made
669 10 Brian Rebel
    void beginJob();                                       // does things like make histograms at the beginning of the job, also beginRun and beginSpill methods available.
670 1 Brian Rebel
    
671 1 Brian Rebel
  private:
672 1 Brian Rebel
        
673 1 Brian Rebel
    double      fDouble;          ///< some data member
674 1 Brian Rebel
    std::string fPrevModuleLabel; ///< label of the module making objects that i now want to look at
675 1 Brian Rebel
    TH1D*       fHist;            ///< a histogram data member
676 1 Brian Rebel
    
677 1 Brian Rebel
  }; // class MyProducer
678 1 Brian Rebel
}
679 1 Brian Rebel
680 1 Brian Rebel
#endif // MYPRODUCER_H
681 1 Brian Rebel
</code></pre>
682 1 Brian Rebel
683 1 Brian Rebel
The implementation file is then
684 1 Brian Rebel
685 1 Brian Rebel
<pre><code class="c">
686 1 Brian Rebel
#include <iostream>
687 1 Brian Rebel
688 7 Brian Rebel
// Framework includes
689 30 Joseph Sobek
#include "art/Framework/Principal/Event.h"
690 7 Brian Rebel
#include "fhiclcpp/ParameterSet.h"
691 7 Brian Rebel
#include "art/Persistency/Common/Handle.h"
692 7 Brian Rebel
#include "art/Framework/Services/Registry/ServiceHandle.h"
693 7 Brian Rebel
#include "art/Framework/Services/Optional/TFileService.h"
694 7 Brian Rebel
#include "art/Framework/Core/TFileDirectory.h"
695 7 Brian Rebel
#include "messagefacility/MessageLogger/MessageLogger.h"
696 1 Brian Rebel
697 1 Brian Rebel
#include "MyModule/MyAnalyzer.h"
698 1 Brian Rebel
#include "Geometry/geo.h"
699 1 Brian Rebel
#include "MyProducts/MyProduct.h"
700 1 Brian Rebel
#include "MyProducts/MyOtherProduct.h"
701 1 Brian Rebel
702 1 Brian Rebel
#include "TH1.h"
703 1 Brian Rebel
704 1 Brian Rebel
namespace mm{
705 1 Brian Rebel
706 1 Brian Rebel
  //-----------------------------------------------------
707 10 Brian Rebel
  MyAnalyzer::MyAnalyzer(fhicl::ParameterSet const& pset) :
708 7 Brian Rebel
    fDouble         (pset.get< double >     ("TheDouble")),
709 7 Brian Rebel
    fPrevModuleLabel(pset.get< std::string >("PreviousModuleLabel"))
710 1 Brian Rebel
  {
711 1 Brian Rebel
  }
712 1 Brian Rebel
713 1 Brian Rebel
  //-----------------------------------------------------
714 1 Brian Rebel
  MyAnalyzer::~MyAnalyzer()
715 1 Brian Rebel
  {
716 1 Brian Rebel
  }
717 1 Brian Rebel
718 1 Brian Rebel
  //-----------------------------------------------------
719 7 Brian Rebel
  void MyAnalyzer::beginJob()
720 1 Brian Rebel
  {
721 1 Brian Rebel
    // get access to the TFile service
722 7 Brian Rebel
    art::ServiceHandle<art::TFileService> tfs;
723 1 Brian Rebel
724 1 Brian Rebel
    // get the geometry to figure out something for the histogram
725 7 Brian Rebel
    art::ServiceHandle<geo::Geometry> geo;
726 1 Brian Rebel
727 1 Brian Rebel
    fHist    = tfs->make<TH1D>("channels",  ";channels;",  geo->NPlanes()*geo->Plane(0)->Ncells(), 0, geo->NPlanes()*geo->Plane(0)->Ncells());
728 1 Brian Rebel
729 1 Brian Rebel
    return;
730 1 Brian Rebel
  }
731 1 Brian Rebel
732 1 Brian Rebel
  //-----------------------------------------------------
733 7 Brian Rebel
  void MyAnalyzer::analyze(const art::Event& evt)
734 1 Brian Rebel
  {
735 1 Brian Rebel
    
736 1 Brian Rebel
    // maybe I will need the geometry service here too
737 7 Brian Rebel
    art::ServiceHandle<geo::Geometry> geom;
738 1 Brian Rebel
  
739 1 Brian Rebel
    double xyz[3] = {0.};
740 1 Brian Rebel
    double xyz1[3] = {0.};
741 1 Brian Rebel
    int planes = geom->NPlanes();
742 1 Brian Rebel
  
743 1 Brian Rebel
    ///plane 0 is the first induction plane, every plane has a wire 0
744 1 Brian Rebel
    geom->Plane(0)->GetCenter(xyz);
745 1 Brian Rebel
746 1 Brian Rebel
    // grab the mp::MyProducts made in a previous module
747 7 Brian Rebel
    art::Handle< std::vector<mp::MyProduct> > mplistHandle;
748 1 Brian Rebel
    evt.getByLabel(fPrevModuleLabel,mplistHandle);
749 1 Brian Rebel
750 1 Brian Rebel
    // loop over the list of MyProducts
751 1 Brian Rebel
    for(unsigned int i = 0; i < mplistHandle->size(); ++i){
752 1 Brian Rebel
753 1 Brian Rebel
      //get a edm::Ptr to the MyProducts
754 7 Brian Rebel
      art::Ptr<mp::MyProduct> mpMyProd(mplistHandle, i);
755 1 Brian Rebel
756 1 Brian Rebel
      // do something to analyze them
757 1 Brian Rebel
758 1 Brian Rebel
    }
759 1 Brian Rebel
760 1 Brian Rebel
    return;
761 1 Brian Rebel
762 1 Brian Rebel
  }
763 1 Brian Rebel
764 1 Brian Rebel
}
765 1 Brian Rebel
</code></pre>
766 1 Brian Rebel
767 7 Brian Rebel
And now the _module.cc file.  The need for separate files for the implementation and the module was not obvious to me to begin with.  Having separate files allows you to produce .so libraries for both the plugin and the rest of the objects in the package.  SRT also likes to have .cxx targets to build, so that is another reason to have separate .cxx and _module.cc files.
768 1 Brian Rebel
769 7 Brian Rebel
For this example, the plugin file is named MyAnalyzer_module.cc.
770 1 Brian Rebel
771 1 Brian Rebel
<pre><code class="c">
772 7 Brian Rebel
// Framework includes
773 7 Brian Rebel
#include "art/Framework/Core/ModuleMacros.h"
774 1 Brian Rebel
775 7 Brian Rebel
// NOvASoft includes
776 1 Brian Rebel
#include "MyModule/MyAnalyzer.h"
777 1 Brian Rebel
778 1 Brian Rebel
namespace mm {
779 1 Brian Rebel
780 1 Brian Rebel
  // A macro required for a JobControl module.
781 7 Brian Rebel
  DEFINE_ART_MODULE(MyAnalyzer);
782 1 Brian Rebel
783 1 Brian Rebel
} // namespace mm
784 1 Brian Rebel
</code></pre>
785 1 Brian Rebel
786 1 Brian Rebel
h3. EDFilter
787 1 Brian Rebel
788 1 Brian Rebel
A simple example of filtering on even or odd event numbers is below.
789 1 Brian Rebel
790 1 Brian Rebel
First the header file:
791 1 Brian Rebel
<pre><code class="c">
792 1 Brian Rebel
// Framework includes
793 7 Brian Rebel
#include "art/Framework/Core/EDFilter.h"
794 1 Brian Rebel
795 1 Brian Rebel
namespace filt{
796 1 Brian Rebel
797 7 Brian Rebel
 class SelectEvents : public art::EDFilter {
798 1 Brian Rebel
   public:
799 10 Brian Rebel
     explicit SelectEvents(fhicl::ParameterSet const& pset);
800 1 Brian Rebel
    virtual ~SelectEvents() { }
801 10 Brian Rebel
    virtual bool filter(art::Event& e);
802 1 Brian Rebel
    
803 1 Brian Rebel
  private:
804 1 Brian Rebel
805 1 Brian Rebel
    // Control parameter: 1 to select odd numbered events; 
806 1 Brian Rebel
    //                    else select even numbered event.
807 1 Brian Rebel
    int _keepOddOrEven;
808 1 Brian Rebel
809 1 Brian Rebel
  };
810 1 Brian Rebel
811 1 Brian Rebel
</code></pre>
812 1 Brian Rebel
813 1 Brian Rebel
Now the implementation:
814 1 Brian Rebel
815 1 Brian Rebel
<pre><code class="c">
816 1 Brian Rebel
#include "SelectEvents.h"
817 1 Brian Rebel
818 1 Brian Rebel
namespace filt{
819 1 Brian Rebel
820 10 Brian Rebel
   SelectEvents::SelectEvents(fhicl::ParameterSet const& pset):
821 7 Brian Rebel
      _keepOddOrEven(pset.get<int>("keepOddOrEven",1))
822 1 Brian Rebel
  {
823 1 Brian Rebel
  }
824 1 Brian Rebel
825 10 Brian Rebel
  bool SelectEvents::filter(art::Event& e)
826 1 Brian Rebel
  {
827 1 Brian Rebel
828 1 Brian Rebel
    // EventSetup is a cms leftover that we do not use.
829 1 Brian Rebel
    
830 1 Brian Rebel
    // Get event number from the event.
831 1 Brian Rebel
    int event = e.id().event();
832 1 Brian Rebel
    
833 1 Brian Rebel
    // Always keep event 3.
834 1 Brian Rebel
    if ( event == 3 ) return true;
835 1 Brian Rebel
836 1 Brian Rebel
    // Always discard event 4.
837 1 Brian Rebel
    if ( event == 4 ) return false;
838 1 Brian Rebel
839 1 Brian Rebel
    // Is this an odd numbered event?
840 1 Brian Rebel
    bool isOdd = ((event % 2) != 0);
841 1 Brian Rebel
  
842 1 Brian Rebel
    // Keep only events with odd or even event numbers, as 
843 1 Brian Rebel
    // controled by the parameter from the ParameterSet.
844 1 Brian Rebel
    if ( _keepOddOrEven == 1){
845 1 Brian Rebel
      return isOdd;
846 1 Brian Rebel
    } else{
847 1 Brian Rebel
      return !isOdd;
848 1 Brian Rebel
    }
849 1 Brian Rebel
  
850 1 Brian Rebel
  }
851 1 Brian Rebel
}//end namespace
852 1 Brian Rebel
</code></pre>
853 1 Brian Rebel
854 7 Brian Rebel
And now the _module.cc:
855 1 Brian Rebel
856 1 Brian Rebel
<pre><code class="c">
857 7 Brian Rebel
// Framework includes
858 7 Brian Rebel
#include "art/Framework/Core/ModuleMacros.h"
859 1 Brian Rebel
860 7 Brian Rebel
// NOvASoft includes
861 1 Brian Rebel
#include "SelectEvents.h"
862 1 Brian Rebel
863 1 Brian Rebel
namespace filt {
864 1 Brian Rebel
865 1 Brian Rebel
  // A macro required for a JobControl module.
866 7 Brian Rebel
  DEFINE_ART_MODULE(SelectEvents);
867 1 Brian Rebel
868 1 Brian Rebel
} // namespace filt
869 1 Brian Rebel
</code></pre>
870 1 Brian Rebel
871 1 Brian Rebel
h2. Configuring a Job
872 1 Brian Rebel
873 1 Brian Rebel
See the [[Running Jobs]] page.