CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/FWCore/MessageLogger/src/JobReport.cc

Go to the documentation of this file.
00001 
00002 // -*- C++ -*-
00003 //
00004 //
00005 // 10/23/07 mf        In an attempt to get clues about (or ene) the
00006 //                does-not-output-branches behavior, changed the
00007 //                generic os<< lines in JobReport::JobReportImpl::writeOutputFile
00008 //                to direct use of LogInfo.
00009 //
00010 // 4/8/08   mf        Encase the logdesc for in <CDATA> ... </CDATA>
00011 //
00012 // 6/19/08  mf        reportMessageInfo()
00013 //
00014 // 24 June 2008   ewv  Correct format for CDATA and for second instance of reportError
00015 
00016 //
00017 // Original Author:  Marc Paterno
00018 //
00019 
00020 #include "FWCore/MessageLogger/interface/JobReport.h"
00021 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00022 #include "FWCore/Utilities/interface/Map.h"
00023 #include "FWCore/Utilities/interface/EDMException.h"
00024 
00025 #include "FWCore/Utilities/interface/tinyxml.h"
00026 
00027 #include <fstream>
00028 #include <iomanip>
00029 #include <iostream>
00030 #include <sstream>
00031 
00032 namespace edm {
00033   /*
00034    * Note that output formatting is spattered across these classes
00035    * If something outside these classes requires access to the
00036    * same formatting then we need to refactor it into a common library
00037    */
00038   template <typename S, typename T>
00039   S& formatFile(T const& f, S& os) {
00040 
00041     if(f.fileHasBeenClosed) {
00042       os << "\n<State  Value=\"closed\"/>";
00043     } else {
00044       os << "\n<State  Value=\"open\"/>";
00045     }
00046 
00047     os << "\n<LFN>" << TiXmlText(f.logicalFileName) << "</LFN>";
00048     os << "\n<PFN>" << TiXmlText(f.physicalFileName) << "</PFN>";
00049     os << "\n<Catalog>" << TiXmlText(f.catalog) << "</Catalog>";
00050     os << "\n<ModuleLabel>" << TiXmlText(f.moduleLabel) << "</ModuleLabel>";
00051     os << "\n<GUID>" << f.guid << "</GUID>";
00052     os << "\n<Branches>";
00053     for(std::vector<std::string>::const_iterator iBranch = f.branchNames.begin(),
00054         iBranchEnd = f.branchNames.end();
00055         iBranch != iBranchEnd;
00056         ++iBranch) {
00057       os << "\n  <Branch>" << TiXmlText(*iBranch) << "</Branch>";
00058     }
00059     os << "\n</Branches>";
00060     return os;
00061   }
00062     /*
00063      * Note that output formatting is spattered across these classes
00064      * If something outside these classes requires access to the
00065      * same formatting then we need to refactor it into a common library
00066      */
00067   template <typename S>
00068     S&
00069     print(S& os, JobReport::InputFile const& f) {
00070 
00071       os << "\n<InputFile>";
00072       formatFile(f, os);
00073       os << "\n<InputType>" << f.inputType << "</InputType>";
00074       os << "\n<InputSourceClass>" << TiXmlText(f.inputSourceClassName)
00075          << "</InputSourceClass>";
00076       os << "\n<EventsRead>" << f.numEventsRead << "</EventsRead>";
00077       return os;
00078     }
00079 
00080   template <typename S>
00081     S&
00082     print(S& os, JobReport::OutputFile const& f) {
00083       formatFile(f, os);
00084       os << "\n<OutputModuleClass>"
00085                         << TiXmlText(f.outputModuleClassName)
00086                         << "</OutputModuleClass>";
00087       os << "\n<TotalEvents>"
00088                         << f.numEventsWritten
00089                         << "</TotalEvents>\n";
00090       os << "\n<DataType>"
00091                         << TiXmlText(f.dataType)
00092                         << "</DataType>\n";
00093       os << "\n<BranchHash>"
00094                         << TiXmlText(f.branchHash)
00095                         << "</BranchHash>\n";
00096 
00097       return os;
00098     }
00099 
00100   template <typename S>
00101     S&
00102     print(S& os,
00103            JobReport::RunReport const& rep) {
00104     os << "\n<Run ID=\""
00105        << rep.runNumber
00106        << "\">\n";
00107 
00108     typedef std::set<unsigned int>::iterator iterator;
00109     for(iterator il = rep.lumiSections.begin(), ilEnd = rep.lumiSections.end(); il != ilEnd; ++il) {
00110       os << "   <LumiSection ID=\"" << *il << "\"/>\n";
00111 
00112     }
00113     os << "</Run>\n";
00114     return os;
00115   }
00116 
00117   std::ostream& operator<< (std::ostream& os, JobReport::InputFile const& f) {
00118     return print(os,f);
00119   }
00120   std::ostream& operator<< (std::ostream& os, JobReport::OutputFile const& f) {
00121     return print(os,f);
00122   }
00123 
00124   std::ostream& operator<< (std::ostream& os, JobReport::RunReport const& f) {
00125     return print(os,f);
00126   }
00127 
00128   //To talk to MessageLogger directly
00129   edm::MessageSender& operator<< (edm::MessageSender& os, JobReport::InputFile const& f) {
00130     return print(os,f);
00131   }
00132   edm::MessageSender& operator<< (edm::MessageSender& os, JobReport::OutputFile const& f) {
00133     return print(os,f);
00134   }
00135   edm::MessageSender& operator<< (edm::MessageSender& os, JobReport::RunReport const& f) {
00136     return print(os,f);
00137   }
00138 //  edm::MessageSender& operator<< (edm::MessageSender& os, JobReport::LumiSectionReport const& rep) {
00139 //    return print(os,rep);
00140 //  }
00141 //
00142 
00143     JobReport::InputFile& JobReport::JobReportImpl::getInputFileForToken(JobReport::Token t) {
00144         if(t >= inputFiles_.size()) {
00145             throw edm::Exception(edm::errors::LogicError)
00146               << "Access reported for input file with token "
00147               << t
00148               << " but no matching input file is found\n";
00149         }
00150 
00151         if(inputFiles_[t].fileHasBeenClosed) {
00152             throw edm::Exception(edm::errors::LogicError)
00153               << "Access reported for input file with token "
00154               << t
00155               << " after this file has been closed.\n"
00156               << "File record follows:\n"
00157               << inputFiles_[t]
00158               << '\n';
00159         }
00160 
00161       return inputFiles_[t];
00162     }
00163 
00164     JobReport::OutputFile& JobReport::JobReportImpl::getOutputFileForToken(JobReport::Token t) {
00165         if(t >= outputFiles_.size()) {
00166             throw edm::Exception(edm::errors::LogicError)
00167               << "Access reported for output file with token "
00168               << t
00169               << " but no matching output file is found\n";
00170         }
00171         if(outputFiles_[t].fileHasBeenClosed) {
00172             throw edm::Exception(edm::errors::LogicError)
00173               << "Access reported for output file with token "
00174               << t
00175               << " after this file has been closed.\n"
00176               << "File record follows:\n"
00177               << outputFiles_[t]
00178               << '\n';
00179         }
00180       return outputFiles_[t];
00181     }
00182 
00183     /*
00184      * Add the input file token provided to every output
00185      * file currently available.
00186      * Used whenever a new input file is opened, it's token
00187      * is added to all open output files as a contributor
00188      */
00189     void JobReport::JobReportImpl::insertInputForOutputs(JobReport::Token t) {
00190         typedef std::vector<JobReport::OutputFile>::iterator iterator;
00191         for(iterator outFile = outputFiles_.begin(), outFileEnd = outputFiles_.end(); outFile != outFileEnd; ++outFile) {
00192           outFile->contributingInputs.push_back(t);
00193         }
00194     }
00195     /*
00196      * get a vector of Tokens for all currently open
00197      * input files.
00198      * Used when a new output file is opened, all currently open
00199      * input file tokens are used to initialize its list of contributors
00200      */
00201     void JobReport::JobReportImpl::openInputFiles(std::vector<JobReport::Token>& result) {
00202         result.reserve(inputFiles_.size());
00203         for(unsigned int i = 0; i < inputFiles_.size(); ++i) {
00204           if(inputFiles_[i].fileHasBeenClosed == false) {
00205             result.push_back(i);
00206           }
00207         }
00208     }
00209 
00210     /*
00211      * get a vector of Tokens for all currently open
00212      * output files.
00213      *
00214      */
00215     void JobReport::JobReportImpl::openOutputFiles(std::vector<JobReport::Token>& result) {
00216         result.reserve(outputFiles_.size());
00217         for(unsigned int i = 0; i < outputFiles_.size(); ++i) {
00218           if(outputFiles_[i].fileHasBeenClosed == false) {
00219             result.push_back(i);
00220           }
00221         }
00222     }
00223 
00224     /*
00225      * Write anJobReport::InputFile object to the Logger
00226      * Generate XML string forJobReport::InputFile instance and dispatch to
00227      * job report via MessageLogger
00228      */
00229     void JobReport::JobReportImpl::writeInputFile(JobReport::InputFile const& f) {
00230       if(ost_) {
00231         *ost_ << f ;
00232         *ost_ << "\n<Runs>";
00233         typedef std::map<JobReport::RunNumber, JobReport::RunReport>::const_iterator const_iterator;
00234         for(const_iterator iRun = f.runReports.begin(), iRunEnd = f.runReports.end(); iRun != iRunEnd; ++iRun) {
00235           *ost_ << iRun->second;
00236         }
00237         *ost_ << "\n</Runs>\n";
00238         *ost_ << "</InputFile>\n";
00239         *ost_ << std::flush;
00240       }
00241         //LogInfo("FwkJob") << f;
00242     }
00243 
00244     /*
00245      * Write an OutputFile object to the Logger
00246      * Generate an XML string for the OutputFile provided and
00247      * dispatch it to the logger
00248      * Contributing input tokens are resolved to the input LFN and PFN
00249      *
00250      * TODO: We have not yet addressed the issue where we cleanup not
00251      * contributing input files.
00252      * Also, it is possible to get fake input to output file mappings
00253      * if an input file is open already when a new output file is opened
00254      * but the input gets closed without contributing events to the
00255      * output file due to filtering etc.
00256      *
00257      */
00258     void JobReport::JobReportImpl::writeOutputFile(JobReport::OutputFile const& f) {
00259       if(ost_) {
00260         *ost_ << "\n<File>";
00261         *ost_ << f;
00262 
00263         *ost_ << "\n<Runs>";
00264         typedef std::map<JobReport::RunNumber, JobReport::RunReport>::const_iterator const_iterator;
00265         for(const_iterator iRun = f.runReports.begin(), iRunEnd = f.runReports.end(); iRun != iRunEnd; ++iRun) {
00266           *ost_ << iRun->second;
00267         }
00268         *ost_ << "\n</Runs>\n";
00269 
00270         *ost_ << "\n<Inputs>";
00271         for(std::vector<JobReport::Token>::const_iterator
00272           iInput = f.contributingInputs.begin(),
00273           iInputEnd = f.contributingInputs.end();
00274           iInput != iInputEnd; ++iInput) {
00275             JobReport::InputFile inpFile = inputFiles_[*iInput];
00276             *ost_ << "\n<Input>";
00277             *ost_ << "\n  <LFN>" << TiXmlText(inpFile.logicalFileName) << "</LFN>";
00278             *ost_ << "\n  <PFN>" << TiXmlText(inpFile.physicalFileName) << "</PFN>";
00279             *ost_ << "\n  <FastCopying>" << findOrDefault(f.fastCopyingInputs, inpFile.physicalFileName) << "</FastCopying>";
00280             *ost_ << "\n</Input>";
00281         }
00282         *ost_ << "\n</Inputs>";
00283         *ost_ << "\n</File>\n";
00284       }
00285     }
00286 
00287     /*
00288      *  Flush all open files to logger in event of a problem.
00289      *  Called from JobReport dtor to flush any remaining open files
00290      */
00291     void JobReport::JobReportImpl::flushFiles(void) {
00292       for(std::vector<JobReport::InputFile>::iterator ipos = inputFiles_.begin(), iposEnd = inputFiles_.end();
00293           ipos != iposEnd; ++ipos) {
00294         if(!(ipos->fileHasBeenClosed)) {
00295           writeInputFile(*ipos);
00296         }
00297       }
00298       for(std::vector<JobReport::OutputFile>::iterator opos = outputFiles_.begin(), oposEnd = outputFiles_.end();
00299           opos != oposEnd; ++opos) {
00300         if(!(opos->fileHasBeenClosed)) {
00301           writeOutputFile(*opos);
00302         }
00303       }
00304     }
00305 
00306   void JobReport::JobReportImpl::addGeneratorInfo(std::string const& name,
00307                                                   std::string const& value) {
00308 
00309     generatorInfo_[name] = value;
00310   }
00311 
00312   void JobReport::JobReportImpl::writeGeneratorInfo(void) {
00313     if(ost_) {
00314       *ost_ << "\n<GeneratorInfo>\n";
00315       for(std::map<std::string, std::string>::iterator pos = generatorInfo_.begin(),
00316           posEnd = generatorInfo_.end();
00317           pos != posEnd;  ++pos) {
00318         std::ostringstream msg;
00319         msg << "\n<Data Name=\"" << pos->first
00320           << "\" Value=\"" << pos->second << "\"/>";
00321         *ost_ << msg.str();
00322       }
00323       *ost_ << "</GeneratorInfo>\n";
00324     }
00325   }
00326 
00327   void JobReport::JobReportImpl::associateRun(unsigned int runNumber) {
00328     std::vector<Token> openFiles;
00329     openOutputFiles(openFiles);
00330     for(std::vector<Token>::iterator iToken = openFiles.begin(), iTokenEnd = openFiles.end(); iToken != iTokenEnd; ++iToken) {
00331       JobReport::OutputFile& theFile = outputFiles_[*iToken];
00332 
00333       //
00334       // check run is known to file
00335       // if not, add a run report for that run
00336       if(theFile.runReports.count(runNumber) == 0) {
00337         JobReport::RunReport newReport = JobReport::RunReport();
00338         newReport.runNumber = runNumber;
00339         theFile.runReports.insert(
00340                  std::make_pair(runNumber, newReport)
00341                 );
00342       }
00343 
00344     }
00345   }
00346 
00347   void JobReport::JobReportImpl::associateInputRun(unsigned int runNumber) {
00348     std::vector<Token> openFiles;
00349     openInputFiles(openFiles);
00350     for(std::vector<Token>::iterator iToken = openFiles.begin(), iTokenEnd = openFiles.end(); iToken != iTokenEnd; ++iToken) {
00351       JobReport::InputFile& theFile = inputFiles_[*iToken];
00352 
00353       //
00354       // check run is known to file
00355       // if not, add a run report for that run
00356       if(theFile.runReports.count(runNumber) == 0) {
00357         JobReport::RunReport newReport = JobReport::RunReport();
00358         newReport.runNumber = runNumber;
00359         theFile.runReports.insert(std::make_pair(runNumber, newReport));
00360       }
00361 
00362     }
00363   }
00364 
00365   void JobReport::JobReportImpl::associateLumiSection(unsigned int runNumber, unsigned int lumiSect) {
00366     std::vector<Token> openFiles;
00367     openOutputFiles(openFiles);
00368     for(std::vector<Token>::iterator iToken = openFiles.begin(), iTokenEnd = openFiles.end(); iToken != iTokenEnd; ++iToken) {
00369       //
00370       // Loop over all open output files
00371       //
00372       JobReport::OutputFile& theFile = outputFiles_[*iToken];
00373 
00374       //
00375       // check run is known to file
00376       // if not, add a run report for that run
00377       if(theFile.runReports.count(runNumber) == 0) {
00378         JobReport::RunReport newReport = JobReport::RunReport();
00379         newReport.runNumber = runNumber;
00380         theFile.runReports.insert(std::make_pair(runNumber, newReport));
00381       }
00382 
00383       //
00384       // Get the run report for this run, now that it either was created
00385       // or already existed
00386       std::map<JobReport::RunNumber, JobReport::RunReport>::iterator finder;
00387       finder = theFile.runReports.find(runNumber);
00388 
00389       //
00390       // add the lumi section to the report, the lumi list is a Set
00391       // so duplicates dont matter
00392       (finder->second).lumiSections.insert(lumiSect);
00393     }
00394   }
00395 
00396   void JobReport::JobReportImpl::associateInputLumiSection(unsigned int runNumber, unsigned int lumiSect) {
00397     std::vector<Token> openFiles;
00398     openInputFiles(openFiles);
00399     for(std::vector<Token>::iterator iToken = openFiles.begin(), iTokenEnd = openFiles.end(); iToken != iTokenEnd; ++iToken) {
00400       //
00401       // Loop over all open input files
00402       //
00403       JobReport::InputFile& theFile = inputFiles_[*iToken];
00404 
00405       //
00406       // check run is known to file
00407       // if not, add a run report for that run
00408       if(theFile.runReports.count(runNumber) == 0) {
00409         JobReport::RunReport newReport = JobReport::RunReport();
00410         newReport.runNumber = runNumber;
00411         theFile.runReports.insert(std::make_pair(runNumber, newReport));
00412       }
00413 
00414       //
00415       // Get the run report for this run, now that it either was created
00416       // or already existed
00417       std::map<JobReport::RunNumber, JobReport::RunReport>::iterator finder;
00418       finder = theFile.runReports.find(runNumber);
00419 
00420       //
00421       // add the lumi section to the report, the lumi list is a Set
00422       // so duplicates dont matter
00423       (finder->second).lumiSections.insert(lumiSect);
00424     }
00425   }
00426 
00427   JobReport::~JobReport() {
00428     impl_->writeGeneratorInfo();
00429     impl_->flushFiles();
00430     if(impl_->ost_) {
00431       *(impl_->ost_) << "</FrameworkJobReport>\n" << std::flush;
00432     }
00433   }
00434 
00435     JobReport::JobReport() :
00436       impl_(new JobReportImpl(0)) {
00437     }
00438 
00439     JobReport::JobReport(std::ostream* iOstream) : impl_(new JobReportImpl(iOstream)) {
00440       if(impl_->ost_) {
00441         *(impl_->ost_) << "<FrameworkJobReport>\n";
00442       }
00443     }
00444 
00445   namespace {
00446     void
00447     toFileName(std::string const& jobReportFile, unsigned int childIndex, unsigned int numberOfChildren, std::ostringstream& ofilename) {
00448       unsigned int numberOfDigitsInIndex = 0U;
00449       while (numberOfChildren != 0) {
00450         ++numberOfDigitsInIndex;
00451         numberOfChildren /= 10;
00452       }
00453       if(numberOfDigitsInIndex == 0) {
00454         numberOfDigitsInIndex = 3; // Protect against zero numberOfChildren
00455       }
00456       std::string::size_type offset = jobReportFile.rfind('.');
00457       if(offset == std::string::npos) {
00458         ofilename << jobReportFile;
00459         ofilename << '_' << std::setw(numberOfDigitsInIndex) << std::setfill('0') << childIndex;
00460       } else {
00461         ofilename << jobReportFile.substr(0, offset);
00462         ofilename << '_' << std::setw(numberOfDigitsInIndex) << std::setfill('0') << childIndex;
00463         ofilename << jobReportFile.substr(offset);
00464       }
00465     }
00466   }
00467 
00468     void
00469     JobReport::parentBeforeFork(std::string const& jobReportFile, unsigned int numberOfChildren) {
00470       if(impl_->ost_) {
00471         *(impl_->ost_) << "<ChildProcessFiles>\n";
00472         for(unsigned int i = 0; i < numberOfChildren; ++i) {
00473           std::ostringstream ofilename;
00474           toFileName(jobReportFile, i, numberOfChildren, ofilename);
00475           *(impl_->ost_) << "  <ChildProcessFile>" << ofilename.str() << "</ChildProcessFile>\n";
00476         }
00477         *(impl_->ost_) << "</ChildProcessFiles>\n";
00478         *(impl_->ost_) << "</FrameworkJobReport>\n";
00479         std::ofstream* p = dynamic_cast<std::ofstream *>(impl_->ost_);
00480         if(p) {
00481           p->close();
00482         }
00483       }
00484     }
00485 
00486     void
00487     JobReport::parentAfterFork(std::string const& /*jobReportFile*/) {
00488     }
00489 
00490     void
00491     JobReport::childAfterFork(std::string const& jobReportFile, unsigned int childIndex, unsigned int numberOfChildren) {
00492       std::ofstream* p = dynamic_cast<std::ofstream*>(impl_->ost_);
00493       if(!p) return;
00494       std::ostringstream ofilename;
00495       toFileName(jobReportFile, childIndex, numberOfChildren, ofilename);
00496       p->open(ofilename.str().c_str());
00497       *p << "<FrameworkJobReport>\n";
00498     }
00499 
00500     JobReport::Token
00501     JobReport::inputFileOpened(std::string const& physicalFileName,
00502                                std::string const& logicalFileName,
00503                                std::string const& catalog,
00504                                std::string const& inputType,
00505                                std::string const& inputSourceClassName,
00506                                std::string const& moduleLabel,
00507                                std::string const& guid,
00508                                std::vector<std::string> const& branchNames) {
00509       // Do we have to worry about thread safety here? Or is this
00510       // service used in a way to make this safe?
00511       impl_->inputFiles_.push_back(JobReport::InputFile());
00512       JobReport::InputFile& r = impl_->inputFiles_.back();
00513 
00514       r.logicalFileName      = logicalFileName;
00515       r.physicalFileName     = physicalFileName;
00516       r.catalog              = catalog;
00517       r.inputType            = inputType;
00518       r.inputSourceClassName = inputSourceClassName;
00519       r.moduleLabel          = moduleLabel;
00520       r.guid                 = guid;
00521       // r.runsSeen is not modified
00522       r.numEventsRead        = 0;
00523       r.branchNames          = branchNames;
00524       r.fileHasBeenClosed    = false;
00525 
00526       JobReport::Token newToken = impl_->inputFiles_.size()-1;
00527         //
00528        // Add the new input file token to all output files
00529       //  currently open.
00530       impl_->insertInputForOutputs(newToken);
00531       return newToken;
00532     }
00533 
00534     void
00535     JobReport::eventReadFromFile(JobReport::Token fileToken, unsigned int /*run*/, unsigned int) {
00536       JobReport::InputFile& f = impl_->getInputFileForToken(fileToken);
00537       ++f.numEventsRead;
00538       //f.runsSeen.insert(run);
00539     }
00540 
00541     void
00542     JobReport::reportDataType(Token fileToken, std::string const& dataType) {
00543       JobReport::OutputFile& f = impl_->getOutputFileForToken(fileToken);
00544       f.dataType = dataType;
00545     }
00546 
00547     void
00548     JobReport::inputFileClosed(JobReport::Token fileToken) {
00549       JobReport::InputFile& f = impl_->getInputFileForToken(fileToken);
00550       // Dump information to the MessageLogger's JobSummary
00551       // about this file.
00552       // After setting the file to 'closed', we will no longer be able
00553       // to reference it by ID.
00554       f.fileHasBeenClosed = true;
00555       impl_->writeInputFile(f);
00556     }
00557 
00558     JobReport::Token
00559     JobReport::outputFileOpened(std::string const& physicalFileName,
00560                                 std::string const& logicalFileName,
00561                                 std::string const& catalog,
00562                                 std::string const& outputModuleClassName,
00563                                 std::string const& moduleLabel,
00564                                 std::string const& guid,
00565                                 std::string const& dataType,
00566                                 std::string const& branchHash,
00567                                 std::vector<std::string> const& branchNames) {
00568       impl_->outputFiles_.push_back(JobReport::OutputFile());
00569       JobReport::OutputFile& r = impl_->outputFiles_.back();
00570 
00571       r.logicalFileName       = logicalFileName;
00572       r.physicalFileName      = physicalFileName;
00573       r.catalog               = catalog;
00574       r.outputModuleClassName = outputModuleClassName;
00575       r.moduleLabel           = moduleLabel;
00576       r.guid           = guid;
00577       r.dataType = dataType;
00578       r.branchHash = branchHash;
00579       // r.runsSeen is not modified
00580       r.numEventsWritten      = 0;
00581       r.branchNames           = branchNames;
00582       r.fileHasBeenClosed     = false;
00583         //
00584        // Init list of contributors to list of open input file Tokens
00585       //
00586       impl_->openInputFiles(r.contributingInputs);
00587       return impl_->outputFiles_.size()-1;
00588     }
00589 
00590     void
00591     JobReport::eventWrittenToFile(JobReport::Token fileToken, unsigned int /*run*/, unsigned int) {
00592       JobReport::OutputFile& f = impl_->getOutputFileForToken(fileToken);
00593       ++f.numEventsWritten;
00594       //f.runsSeen.insert(run);
00595     }
00596 
00597     void
00598     JobReport::outputFileClosed(JobReport::Token fileToken) {
00599       JobReport::OutputFile& f = impl_->getOutputFileForToken(fileToken);
00600       // Dump information to the MessageLogger's JobSummary
00601       // about this file.
00602       // After setting the file to 'closed', we will no longer be able
00603       // to reference it by ID.
00604       f.fileHasBeenClosed = true;
00605       impl_->writeOutputFile(f);
00606     }
00607 
00608     void
00609     JobReport:: reportFastCopyingStatus(JobReport::Token fileToken, std::string const& inputFileName, bool fastCopying) {
00610       JobReport::OutputFile& f = impl_->getOutputFileForToken(fileToken);
00611       f.fastCopyingInputs.insert(std::make_pair(inputFileName, fastCopying));
00612     }
00613 
00614     void
00615     JobReport::overrideEventsWritten(Token fileToken, int const eventsWritten) {
00616       // Get the required output file instance using the token
00617       JobReport::OutputFile& f = impl_->getOutputFileForToken(fileToken);
00618       // set the eventsWritten parameter to the provided value
00619       f.numEventsWritten = eventsWritten;
00620     }
00621 
00622     void
00623     JobReport::overrideEventsRead(Token fileToken, int const eventsRead) {
00624       // Get the required input file instance using the token
00625       JobReport::InputFile& f = impl_->getInputFileForToken(fileToken);
00626       // set the events read parameter to the provided value
00627       f.numEventsRead = eventsRead;
00628     }
00629 
00630     void
00631     JobReport::overrideContributingInputs(Token outputToken,
00632                                           std::vector<Token> const& inputTokens) {
00633        // Get the required output file instance using the token
00634       JobReport::OutputFile& f = impl_->getOutputFileForToken(outputToken);
00635       // override its contributing inputs data
00636       f.contributingInputs = inputTokens;
00637     }
00638 
00639     void
00640     JobReport::reportSkippedEvent(unsigned int run, unsigned int event) {
00641       if(impl_->ost_) {
00642         std::ostream& msg = *(impl_->ost_);
00643         msg << "<SkippedEvent Run=\"" << run << "\"";
00644         msg << " Event=\"" << event << "\" />\n";
00645         msg << std::flush;
00646         //LogInfo("FwkJob") << msg.str();
00647       }
00648     }
00649 
00650   void
00651   JobReport::reportLumiSection(unsigned int run, unsigned int lumiSectId) {
00652     impl_->associateLumiSection(run, lumiSectId);
00653   }
00654 
00655   void
00656   JobReport::reportInputLumiSection(unsigned int run, unsigned int lumiSectId) {
00657     impl_->associateInputLumiSection(run, lumiSectId);
00658   }
00659 
00660   void
00661   JobReport::reportRunNumber(unsigned int run) {
00662     impl_->associateRun(run);
00663   }
00664   void
00665   JobReport::reportInputRunNumber(unsigned int run) {
00666     impl_->associateInputRun(run);
00667   }
00668 
00669   void
00670   JobReport::reportError(std::string const& shortDesc,
00671                            std::string const& longDesc) {
00672     if(impl_->ost_) {
00673       std::ostream& msg = *(impl_->ost_);
00674       msg << "<FrameworkError ExitStatus=\"1\" Type=\"" << shortDesc << "\" >\n";
00675       msg << "<![CDATA[\n" << longDesc << "\n]]>\n";
00676       msg << "</FrameworkError>\n";
00677    //LogError("FwkJob") << msg.str();
00678       msg << std::flush;
00679     }
00680   }
00681 
00682   void
00683   JobReport::reportAnalysisFile(std::string const& fileName, std::map<std::string, std::string> const& fileData) {
00684     if(impl_->ost_) {
00685       std::ostream& msg = *(impl_->ost_);
00686       //std::ostringstream msg;
00687       msg << "<AnalysisFile>\n"
00688           << "  <FileName>" << TiXmlText(fileName) << "</FileName>\n";
00689 
00690       typedef std::map<std::string, std::string>::const_iterator const_iterator;
00691       for(const_iterator pos = fileData.begin(), posEnd = fileData.end(); pos != posEnd; ++pos) {
00692         msg <<  "  <" << pos->first
00693             <<  "  Value=\"" << pos->second  << "\" />"
00694             <<  "\n";
00695       }
00696       msg << "</AnalysisFile>\n";
00697       //LogError("FwkJob") << msg.str();
00698       msg << std::flush;
00699     }
00700   }
00701 
00702   void
00703   JobReport::reportError(std::string const& shortDesc,
00704                          std::string const& longDesc,
00705                          int const& exitCode) {
00706     if(impl_->ost_) {
00707       std::ostream& msg = *(impl_->ost_);
00708       //std::ostringstream msg;
00709       msg << "<FrameworkError ExitStatus=\""<< exitCode
00710             << "\" Type=\"" << shortDesc << "\" >\n";
00711       msg << "<![CDATA[\n" << longDesc << "\n]]>\n";
00712       msg << "</FrameworkError>\n";
00713       //LogError("FwkJob") << msg.str();
00714       msg << std::flush;
00715     }
00716   }
00717 
00718   void
00719   JobReport::reportSkippedFile(std::string const& pfn,
00720                                std::string const& lfn) {
00721     if(impl_->ost_) {
00722       std::ostream& msg = *(impl_->ost_);
00723       TiXmlElement skipped("SkippedFile");
00724       skipped.SetAttribute("Pfn", pfn);
00725       skipped.SetAttribute("Lfn", lfn);
00726       msg << skipped << "\n";
00727       msg << std::flush;
00728       //LogInfo("FwkJob") << msg.str();
00729     }
00730   }
00731 
00732   void
00733   JobReport::reportMemoryInfo(std::vector<std::string> const& memoryData) {
00734     if(impl_->ost_) {
00735       std::ostream& msg = *(impl_->ost_);
00736       msg << "<MemoryService>\n";
00737 
00738       typedef std::vector<std::string>::const_iterator const_iterator;
00739       for(const_iterator pos = memoryData.begin(), posEnd = memoryData.end(); pos != posEnd; ++pos) {
00740         msg << *pos << "\n";
00741       }
00742       msg << "</MemoryService>\n";
00743       msg << std::flush;
00744     }
00745   }
00746 
00747   void
00748   JobReport::reportMessageInfo(std::map<std::string, double> const& messageData) {
00749     if(impl_->ost_) {
00750       std::ostream& msg = *(impl_->ost_);
00751       msg << "<MessageSummary>\n";
00752       typedef std::map<std::string, double>::const_iterator const_iterator;
00753       for(const_iterator pos = messageData.begin(), posEnd = messageData.end(); pos != posEnd; ++pos) {
00754         msg <<  "  <" << pos->first
00755         <<  "  Value=\"" << pos->second  << "\" />"
00756         <<  "\n";
00757       }
00758       msg << "</MessageSummary>\n";
00759       msg << std::flush;
00760     }
00761   }
00762 
00763   void
00764   JobReport::reportGeneratorInfo(std::string const& name, std::string const& value) {
00765     impl_->addGeneratorInfo(name, value);
00766   }
00767 
00768   void JobReport::reportRandomStateFile(std::string const& name) {
00769     if(impl_->ost_) {
00770       std::ostream& msg = *(impl_->ost_);
00771       msg << "<RandomServiceStateFile>\n"
00772         << TiXmlText(name) << "\n"
00773         <<  "</RandomServiceStateFile>\n";
00774       //LogInfo("FwkJob") << msg.str();
00775       msg << std::flush;
00776     }
00777   }
00778 
00779   void
00780   JobReport::reportPSetHash(std::string const& hashValue) {
00781     if(impl_->ost_) {
00782       std::ostream& msg = *(impl_->ost_);
00783       msg << "<PSetHash>"
00784         <<  hashValue
00785         <<  "</PSetHash>\n";
00786       //LogInfo("FwkJob") << msg.str();
00787       msg << std::flush;
00788     }
00789   }
00790 
00791   void
00792   JobReport::reportPerformanceSummary(std::string const& metricClass,
00793                                       std::map<std::string, std::string> const& metrics) {
00794     if(impl_->ost_) {
00795       std::ostream& msg = *(impl_->ost_);
00796       msg << "<PerformanceReport>\n"
00797         << "  <PerformanceSummary Metric=\"" << metricClass << "\">\n";
00798 
00799       typedef std::map<std::string, std::string>::const_iterator const_iterator;
00800       for(const_iterator iter = metrics.begin(), iterEnd = metrics.end(); iter != iterEnd; ++iter) {
00801         msg << "    <Metric Name=\"" << iter->first << "\" "
00802         << "Value=\"" << iter->second << "\"/>\n";
00803       }
00804 
00805       msg << "  </PerformanceSummary>\n"
00806         << "</PerformanceReport>\n";
00807       msg << std::flush;
00808       //LogInfo("FwkJob") << msg.str();
00809     }
00810   }
00811 
00812   void
00813   JobReport::reportPerformanceForModule(std::string const&  metricClass,
00814                                         std::string const&  moduleName,
00815                                         std::map<std::string, std::string> const& metrics) {
00816     if(impl_->ost_) {
00817       std::ostream& msg = *(impl_->ost_);
00818       msg << "<PerformanceReport>\n"
00819         << "  <PerformanceModule Metric=\"" << metricClass << "\" "
00820         << " Module=\"" << moduleName << "\" >\n";
00821 
00822       typedef std::map<std::string, std::string>::const_iterator const_iterator;
00823       for(const_iterator iter = metrics.begin(), iterEnd = metrics.end(); iter != iterEnd; ++iter) {
00824         msg << "    <Metric Name=\"" << iter->first << "\" "
00825         << "Value=\"" << iter->second << "\"/>\n";
00826       }
00827 
00828       msg << "  </PerformanceModule>\n"
00829         << "</PerformanceReport>\n";
00830       msg << std::flush;
00831       //LogInfo("FwkJob") << msg.str();
00832     }
00833   }
00834 
00835   std::string
00836   JobReport::dumpFiles(void) {
00837     std::ostringstream msg;
00838 
00839     typedef std::vector<JobReport::OutputFile>::iterator iterator;
00840 
00841     for(iterator f = impl_->outputFiles_.begin(), fEnd = impl_->outputFiles_.end(); f != fEnd; ++f) {
00842 
00843       msg << "\n<File>";
00844       msg << *f;
00845 
00846       msg << "\n<LumiSections>";
00847       //typedef std::vector<JobReport::LumiSectionReport>::iterator Iter;
00848       //for(Iter iLumi = f->lumiSections.begin(),
00849       //     iLumiEnd = f->lumiSections.end();
00850       //     iLumi != iLumiEnd;  ++iLumi) {
00851       //  msg << *iLumi;
00852       //}
00853       //msg << "\n</LumiSections>\n";
00854       msg << "\n<Inputs>";
00855       typedef std::vector<JobReport::Token>::iterator iterator;
00856       for(iterator iInput = f->contributingInputs.begin(),
00857           iInputEnd = f->contributingInputs.end();
00858           iInput != iInputEnd; ++iInput) {
00859         JobReport::InputFile inpFile = impl_->inputFiles_[*iInput];
00860         msg << "\n<Input>";
00861         msg << "\n  <LFN>" << TiXmlText(inpFile.logicalFileName) << "</LFN>";
00862         msg << "\n  <PFN>" << TiXmlText(inpFile.physicalFileName) << "</PFN>";
00863         msg << "\n  <FastCopying>" << findOrDefault(f->fastCopyingInputs, inpFile.physicalFileName) << "</FastCopying>";
00864         msg << "\n</Input>";
00865       }
00866       msg << "\n</Inputs>";
00867       msg << "\n</File>";
00868 
00869     }
00870     return msg.str();
00871   }
00872 
00873 } //namspace edm