CMS 3D CMS Logo

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