Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

UserAnalysis.cxx

Go to the documentation of this file.
00001 
00002 // $Id: UserAnalysis.cxx,v 1.29 2006/05/27 08:29:40 rhatcher Exp $
00003 //
00004 // A prototype user analysis module. This is meant to show how to make
00005 // a simple analysis module to look at the data and serve as a boiler
00006 // plate for more complicated analysis modules
00007 //
00008 // messier@huhepl.harvard.edu
00010 #include "Demo/UserAnalysis.h"
00011 #include <cstdio>
00012 #include <cmath>
00013 // ROOT includes
00014 #include "TFile.h"
00015 // MINOS includes
00016 #include "MessageService/MsgService.h"     // MSG text output
00017 #include "MinosObjectMap/MomNavigator.h"   // Data access
00018 #include "CandData/CandRecord.h"           // DigitList handling
00019 #include "CandDigit/CandDigitListHandle.h" // "                "
00020 #include "CandDigit/CandDigitHandle.h"     // "                "
00021 #include "Conventions/Munits.h"            // Unit conversions
00022 #include "DataUtil/GetCandidate.h"         // Unpack data from Mom
00023 #include <DataUtil/HistManModule.h>        // Easy access to our unique HistMan
00024 #include "JobControl/JobCommand.h"         // JobCommand handling
00025 #include "JobControl/JobCModuleRegistry.h" // JOBMODULE registration macro
00026 
00027 CVSID("$Id: UserAnalysis.cxx,v 1.29 2006/05/27 08:29:40 rhatcher Exp $");
00028 JOBMODULE(UserAnalysis,"UserAnalysis","Compute and record total charge\n");
00029 
00030 //......................................................................
00031 
00032 // Define the data structure for the ntuple
00033 //  This structure defines what data is in the ntuple
00034 typedef struct user_analysis_ntuple {
00035   Float_t qtot; // Total charge (p.e)
00036   Float_t nhit; // Total number of digitizations
00037 } UserAnalysisNtuple_t;
00038 //  This string sets the names of the ntuple variables
00039 const char* gsChTags = "qtot:nhit";
00040 
00041 //......................................................................
00042 
00043 UserAnalysis::UserAnalysis() :
00044   // Classes for drawing
00045   fCanvas(std::tmpnam(0),"User Analysis",600,600),
00046   // Histogram convenience pointers
00047   fQtotHisto(0),
00048   fNhitHisto(0),
00049   fEvtQHisto(0),
00050   fEvtTHisto(0),
00051   // Ntuple
00052   fNtuple("fNtuple","Event Summary",gsChTags),
00053   // Module data
00054   fNevents(0), 
00055   fSumQ(0.0), 
00056   fSumQsqr(0.0)
00057 {
00058 }
00059 void UserAnalysis::BeginJob()
00060 {
00061     HistMan hm = HistManModule::GetHistMan(*this);
00062 
00063     // Histograms
00064     //         Name of object Histogram title # bins Low  High
00065     //         ============== =============== ====== ==== ======
00066     fQtotHisto = hm.Book<TH1F>("fQtotHisto",  "Total Charge", 50,  0.0, 5000.0);
00067     fNhitHisto = hm.Book<TH1F>("fNhitHisto",  "N?Hit!",       50,  0.0, 500.0);
00068     fEvtTHisto = hm.Book<TH1F>("fEvtQHisto",  "Event Charge", 50,  0.0, 50.0);
00069 
00070     // Check for user tweaked timing histogram parameters.  First
00071     // start by setting the defaults.
00072     int    nbin = 100;
00073     double xmin = 0.0, xmax = 200.0;
00074 
00075     // See if the user wants to change them.  Normally one might want
00076     // to check the return value of these Get()s to see if the key
00077     // exists, however, since we are guaranteed that the values are
00078     // unchanged in that case and we set defaults, we are safe.
00079     Registry& r = this->GetConfig();
00080     r.Get("NbinT",nbin);
00081     r.Get("Tmin", xmin);
00082     r.Get("Tmax", xmax);
00083 
00084     // Finally book the histogram with the given parameters
00085     fEvtQHisto = hm.Book<TH1F>("fEvtTHisto",  "Event Times",  nbin, xmin, xmax);
00086 
00087     // Alway set clear axis titles!!!
00088     fQtotHisto->SetXTitle("Total Charge (p.e.)");
00089     fQtotHisto->SetYTitle("Events");
00090     fNhitHisto->SetXTitle("N?Hit!");
00091     fNhitHisto->SetYTitle("Events");
00092     fEvtQHisto->SetXTitle("Charge (p.e)");
00093     fEvtQHisto->SetYTitle("N?stripends!");
00094     fEvtTHisto->SetXTitle(Form("Time (%s)",Munits::base_time_name));
00095     fEvtTHisto->SetYTitle("Charge (p.e)");
00096 
00097 //======================================================================
00098 // Set the initial state of your module. The code above initializes the
00099 // variables listed to the values in parentheses. In this case that's
00100 // all I need to do so the method itself is empty...
00101 //======================================================================
00102     fCanvas.Divide(2,2); // Like PAW's zone command
00103 
00104 }
00105 
00106 //......................................................................
00107 
00108 double UserAnalysis::GetTotalCharge(const CandDigitListHandle* cdlh, 
00109                                     int* nHit) 
00110 {
00111 //======================================================================
00112 // Calculate the total charge and number of hit strips in an event
00113 //
00114 // Inputs:  cdlh - Pointer to a candidate digit list handle
00115 //
00116 // Outputs: nHit - total number of digits in the list
00117 //======================================================================
00118   int    nhit = 0;   // Number of hit strips
00119   double qtot = 0.0; // Total charge of this event in p.e.
00120 
00121   fEvtTHisto->Reset(); // Reset event histograms
00122   fEvtQHisto->Reset(); // Reset event histograms
00123   
00124   // The loop is done with a class that iterates over the list
00125   CandDigitHandleItr cdhItr(cdlh->GetDaughterIterator());
00126   for (; cdhItr.IsValid(); cdhItr.Next()) {
00127     double t; // Time of single digit
00128     double q; // Charge of single digit
00129 
00130     t = (*cdhItr)->GetTime(); // time 
00131     q = (*cdhItr)->GetCharge(CalDigitType::kPE); // charge in pe's
00132   
00133     // If this digit passes cuts then include it in tallies
00134     if (q > fQminCut) {
00135       fEvtTHisto->Fill(t/Munits::ns,q); // Fill histograms (time weighted by charge)
00136       fEvtQHisto->Fill(q);   // Fill histograms
00137       
00138       qtot += q; // Accumulate total charge
00139       ++nhit;    // Accumulate total number of hits
00140     }
00141   }
00142   // If we've been give a pointer for the nhit variable put nhit there
00143   if (nHit) *nHit = nhit;
00144   return qtot;
00145 }
00146 
00147 //......................................................................
00148 
00149 void UserAnalysis::HandleCommand(JobCommand* cmd)
00150 {
00151 //======================================================================
00152 // Handle a command send from the job controller
00153 //
00154 // ** This method should no longer be used. Use Config() method instead **
00155 // 
00156 // Inputs: cmd - The parsed job command
00157 //======================================================================
00158   if (cmd->HaveCmd()) {                      // If we have a command...
00159     string sc = cmd->PopCmd();               // Get the command
00160     if (sc == "Draw") {                      // If the command is "Draw"
00161       fDrawHistos = true;                    // Default is on
00162       if (cmd->HaveOpt()) {                  // If we have options
00163         string sopt = cmd->PopOpt();         // Get the option
00164         // If the option is "Off" turn drawing off
00165         if (sopt=="Off" || sopt=="off" || sopt=="OFF") fDrawHistos = false;
00166       }
00167       return;
00168     }
00169     if (sc == "WriteHistos") {
00170       fWriteHistos = true;
00171       return;
00172     }
00173     if (sc == "Set") {                   // "Set" command
00174       if (cmd->HaveOpt()) {
00175         string sopt = cmd->PopOpt();
00176         if (sopt == "QminCut") {         // Set Qmin cut
00177           fQminCut = cmd->PopFloatOpt(); // Get cut value
00178           return;
00179         }
00180         if (sopt == "tBins") { // Set Time Range
00181           int    nbin = cmd->PopIntOpt();
00182           double xmin = cmd->PopFloatOpt();
00183           double xmax = cmd->PopFloatOpt();
00184           fEvtTHisto->SetBins(nbin,xmin,xmax);
00185           return;
00186         }
00187       }
00188     }
00189     // Don't understand command
00190     MSG("Demo",Msg::kWarning) << "Don't understand '" << sc.c_str() << "'\n";
00191   }
00192 }
00193 
00194 //......................................................................
00195 
00196 void UserAnalysis::Help() 
00197 {
00198 //======================================================================
00199 // ** No longer needed. Use Module::Report() to see list of parameters
00200 // ** which can be set using Set("name=value").
00201 //
00202 // Print help for this module
00203 //======================================================================
00204   MSG("Demo",Msg::kInfo) << 
00205     "Help For UserAnalysis Module:\n" <<
00206     "\n" <<
00207     " UserAnalysis accepts the following commands:\n" <<
00208     "\n" <<
00209     "  Draw [off]  -- Turn drawing histograms on (default) or off\n" <<
00210     "\n"
00211     "  WriteHistos -- Write histogram file at end of run\n"<<
00212     "                 Default is not to write histograms\n"<<
00213     "\n"
00214     "  Set/QminCut [charge]            -- Set minimum charge cuts\n" <<
00215     "     /tBins [nbins] [tmin] [tmax] -- Set binning of time histogram\n";
00216 }
00217 
00218 //......................................................................
00219 
00220 JobCResult UserAnalysis::Ana(const MomNavigator *mom) 
00221 {
00222 //======================================================================
00223 // Given the object to which the data is attached perform some
00224 // analysis of the data
00225 //======================================================================
00226   // Access to the event is given through handles. In this case I want
00227   // the list of candidate digits
00228   const CandDigitListHandle* canddigit = 
00229     DataUtil::GetCandidate<CandDigitListHandle>(mom,
00230                                                 "CandDigitListHandle", 
00231                                                 "canddigitlist");
00232   
00233   // If the GetDigitList is successful, loop over the elements in the
00234   // list to add up the charge
00235   if (canddigit) {
00236     double qtot;                 // Total charge
00237     int    nhit;                 // Total number of hit strips
00238     UserAnalysisNtuple_t ntuple; // The data structure for the ntuple data
00239     
00240     // Get the total charge and Nhit and put it into the ntuple data
00241     // structure
00242     qtot = this->GetTotalCharge(canddigit,&nhit);
00243     
00244     // Accumulate statistics
00245     fQtotHisto->Fill(qtot);
00246     fNhitHisto->Fill(nhit);
00247     fSumQ    += qtot;
00248     fSumQsqr += qtot*qtot;
00249     ++fNevents;
00250 
00251     // Fill the ntuple
00252     ntuple.qtot = qtot;
00253     ntuple.nhit = nhit;
00254     fNtuple.Fill(&ntuple.qtot);
00255 
00256     // If graphics are enabled, draw the histograms
00257     if (fDrawHistos) this->DrawHistograms();
00258 
00259     // Make a filter decision on this event.
00260     if (ntuple.qtot>=fQtotCut) return JobCResult::kPassed; // Passed cut
00261     else                       return JobCResult::kFailed; // Failed cut
00262   }
00263   else {
00264     // Couldn't find a digit list...
00265     MSG("User",Msg::kError) << "No CandDigitList\n";
00266 //    return (JobCResult::kError+JobCResult::;
00267     return (JobCResult::kError);
00268   }
00269   // If we get here somehow, don't make any pass/fail decision on the event
00270   return JobCResult::kAOK;
00271 }
00272 
00273 //......................................................................
00274 
00275 const Registry& UserAnalysis::DefaultConfig() const
00276 {
00277 //======================================================================
00278 // Create a registry which holds the default configuration and return it
00279 //======================================================================
00280   static Registry r;
00281 
00282   // Set name of config
00283   std::string name = this->GetName();
00284   name += ".config.default";
00285   r.SetName(name.c_str());
00286 
00287   // Set values of config
00288   r.UnLockValues();
00289   r.Set("QminCut",    0.0);
00290   r.Set("QtotCut",    400.0);
00291   r.Set("DrawHistos", true);
00292   r.Set("WriteHistos",true);
00293   r.Set("NbinT",      200);
00294   r.Set("Tmin",       0.0);
00295   r.Set("Tmax",       200.0);
00296   r.LockValues();
00297 
00298   return r;
00299 }
00300 
00301 //......................................................................
00302 
00303 void UserAnalysis::Config(const Registry& r)
00304 {
00305 //======================================================================
00306 // Configure the module given the registry r
00307 //======================================================================
00308 //  char   tmpb;
00309   double tmpd;
00310   int    tmpi;
00311 
00312   if (r.Get("DrawHistos", tmpi)) { fDrawHistos  = tmpi; }
00313   if (r.Get("WriteHistos",tmpi)) { fWriteHistos = tmpi; }
00314   if (r.Get("QminCut",    tmpd)) { fQminCut     = tmpd; }
00315   if (r.Get("QtotCut",    tmpd)) { fQtotCut     = tmpd; }
00316 
00317   // Let parent class handle stashing any other config parameters.
00318   this->JobCModule::Config(r);
00319 
00320 }
00321 
00322 //......................................................................
00323 
00324 void UserAnalysis::DrawHistograms() 
00325 {
00326 //======================================================================
00327 // Draw the histograms
00328 //======================================================================
00329   fCanvas.cd(1); gPad->SetLogy(1); fNhitHisto->DrawCopy();
00330   fCanvas.cd(2); gPad->SetLogy(1); fQtotHisto->DrawCopy();
00331   fCanvas.cd(3); gPad->SetLogy(0); fEvtQHisto->DrawCopy();
00332   fCanvas.cd(4); gPad->SetLogy(0); fEvtTHisto->DrawCopy();
00333   fCanvas.Update();
00334 }
00335 
00336 //......................................................................
00337 
00338 void UserAnalysis::EndJob() 
00339 {
00340 //======================================================================
00341 // At the end of the job print some stuff out and save the histogram
00342 // to a file
00343 //======================================================================
00344   double aveQ   = fNevents ? fSumQ/fNevents : 0;
00345   double sigmaQ = fNevents ? sqrt(fabs(fSumQsqr/fNevents - aveQ*aveQ)) : 0;
00346   MSG("User",Msg::kInfo) << "Total Events: " << fNevents << "\n";
00347   MSG("User",Msg::kInfo) << " Average Q=" << aveQ 
00348                          << " SigmaQ=" << sigmaQ << "\n";
00349   
00350   // Create a file to write the histogram to. By default it becomes
00351   // the current directory. Write uses current directory by default
00352   if (fWriteHistos) {
00353     TFile userFile("useranalysis.root","RECREATE");
00354     fQtotHisto->Write();        // also can be written by using
00355     fNhitHisto->Write();        // HistManModule in path
00356     fNtuple.Write();
00357   }
00358 }

Generated on Mon Feb 15 11:07:49 2010 for loon by  doxygen 1.3.9.1