// @(#)root/proof:$Id$
// Author: Long Tran-Thanh   14/09/07

/*************************************************************************
 * Copyright (C) 1995-2002, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TProofOutputFile                                                     //
//                                                                      //
// Small class to steer the merging of files produced on the workers    //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TProofOutputFile.h"
#include <TEnv.h>
#include <TError.h>
#include <TFileCollection.h>
#include <TFileInfo.h>
#include <TFileMerger.h>
#include <TFile.h>
#include <TList.h>
#include <TObjArray.h>
#include <TObject.h>
#include <TObjString.h>
#include <TProofDebug.h>
#include <TProofServ.h>
#include <TSystem.h>
#include <TUUID.h>

ClassImp(TProofOutputFile)

//________________________________________________________________________________
TProofOutputFile::TProofOutputFile(const char *path,
                                   ERunType type, UInt_t opt, const char *dsname)
                 : TNamed(path, ""), fRunType(type), fTypeOpt(opt)
{
   // Main constructor

   fIsLocal = kFALSE;
   fMerged = kFALSE;
   fMerger = 0;
   fDataSet = 0;
   ResetBit(TProofOutputFile::kRetrieve);
   ResetBit(TProofOutputFile::kSwapFile);

   Init(path, dsname);
}

//________________________________________________________________________________
TProofOutputFile::TProofOutputFile(const char *path,
                                   const char *option, const char *dsname)
                 : TNamed(path, "")
{
   // Constructor with the old signature, kept for convenience and backard compatibility.
   // Options:
   //             'M'      merge: finally merge the created files
   //             'L'      local: copy locally the files before merging (implies 'M')
   //             'D'      dataset: create a TFileCollection
   //             'R'      register: dataset run with dataset registration
   //             'O'      overwrite: force dataset replacement during registration
   //             'V'      verify: verify the registered dataset
   //             'H'      merge histograms in one go (option to TFileMerger)
   // Special 'option' values for backward compatibility:
   //              ""      equivalent to "M"
   //         "LOCAL"      equivalent to "ML" or "L"

   fIsLocal = kFALSE;
   fMerged = kFALSE;
   fMerger = 0;
   fDataSet = 0;
   fMergeHistosOneGo = kFALSE;

   // Fill the run type and option type
   fRunType = kMerge;
   fTypeOpt = kRemote;
   if (option && strlen(option) > 0) {
      TString opt(option);
      if (opt.Contains("L") || (opt == "LOCAL")) fTypeOpt = kLocal;
      if (opt.Contains("H")) fMergeHistosOneGo = kTRUE;
      if (!opt.Contains("M") && opt.Contains("D")) {
         // Dataset creation mode
         fRunType = kDataset;
         fTypeOpt = kCreate;
         if (opt.Contains("R")) fTypeOpt = (ETypeOpt) (fTypeOpt | kRegister);
         if (opt.Contains("O")) fTypeOpt = (ETypeOpt) (fTypeOpt | kOverwrite);
         if (opt.Contains("V")) fTypeOpt = (ETypeOpt) (fTypeOpt | kVerify);
      }
   }

   Init(path, dsname);
}

//________________________________________________________________________________
void TProofOutputFile::Init(const char *path, const char *dsname)
{
   // Initializer. Called by all constructors

   fLocalHost = TUrl(gSystem->HostName()).GetHostFQDN();
   Int_t port = gEnv->GetValue("ProofServ.XpdPort", -1);
   if (port > -1) {
      fLocalHost += ":";
      fLocalHost += port;
   }

   TString xpath(path);
   // Resolve the relevant placeholders in fFileName (e.g. root://a.ser.ver//data/dir/<group>/<user>/file)
   TProofServ::ResolveKeywords(xpath, 0);
   TUrl u(xpath, kTRUE);
   // File name
   fFileName = u.GetFile();
   // The name is used to identify this entity
   SetName(gSystem->BaseName(fFileName.Data()));
   // The title is the dataset name in the case such option is chosen.
   // In the merging case it can be the final location of the file on the client if the retrieve
   // option is chosen; if the case, this set in TProofPlayer::MergeOutputFiles.
   if (fRunType == kDataset) {
      if (dsname && strlen(dsname) > 0) {
         // This is the dataset name in case such option is chosen
         SetTitle(dsname);
      } else {
         // Default dataset name
         SetTitle(GetName());
      }
   }
   // Options and anchor, if any
   if (u.GetOptions() && strlen(u.GetOptions()) > 0)
      fOptionsAnchor += TString::Format("?%s", u.GetOptions());
   if (u.GetAnchor() && strlen(u.GetAnchor()) > 0)
      fOptionsAnchor += TString::Format("#%s", u.GetAnchor());
   // Path
   fIsLocal = kFALSE;
   fDir = u.GetUrl();
   Int_t pos = fDir.Index(fFileName);
   if (pos != kNPOS) fDir.Remove(pos);
   fRawDir = fDir;

   if (fDir.BeginsWith("file:")) {
      fIsLocal = kTRUE;
      // For local files, the user is allowed to create files under the specified directory.
      // If this is not the case, the file is rooted automatically to the assigned dir which
      // is the datadir for dataset creation runs, and the working dir for merging runs
      TString dirPath = gSystem->DirName(fFileName);
      fFileName = gSystem->BaseName(fFileName);
      if (AssertDir(dirPath) != 0)
         Error("Init", "problems asserting path '%s'", dirPath.Data());
      TString dirData = (!IsMerge() && gProofServ) ? gProofServ->GetDataDir()
                                                   : gSystem->WorkingDirectory();
      if ((dirPath[0] == '/') && gSystem->AccessPathName(dirPath, kWritePermission)) {
         Warning("Init", "not allowed to create files under '%s' - chrooting to '%s'",
                         dirPath.Data(), dirData.Data());
         dirPath.Insert(0, dirData);
      } else if (dirPath.BeginsWith("..")) {
         dirPath.Remove(0, 2);
         if (dirPath[0] != '/') dirPath.Insert(0, "/");
         dirPath.Insert(0, dirData);
      } else if (dirPath[0] == '.' || dirPath[0] == '~') {
         dirPath.Remove(0, 1);
         if (dirPath[0] != '/') dirPath.Insert(0, "/");
         dirPath.Insert(0, dirData);
      } else if (dirPath.IsNull()) {
         dirPath = dirData;
      }
      // Make sure that session-tag, ordinal and query sequential number are present otherwise
      // we may override outputs from other workers
      if (gProofServ) {
         if (!IsMerge() || (!dirPath.BeginsWith(gProofServ->GetDataDir()) &&
                            !dirPath.BeginsWith(gSystem->WorkingDirectory()))) {
            if (!dirPath.Contains(gProofServ->GetOrdinal())) {
               if (!dirPath.EndsWith("/")) dirPath += "/";
               dirPath += gProofServ->GetOrdinal();
            }
         }
         if (!IsMerge()) {
            if (!dirPath.Contains(gProofServ->GetSessionTag())) {
               if (!dirPath.EndsWith("/")) dirPath += "/";
               dirPath += gProofServ->GetSessionTag();
            }
            if (!dirPath.Contains("<qnum>")) {
               if (!dirPath.EndsWith("/")) dirPath += "/";
               dirPath += "<qnum>";
            }
            // Resolve the relevant placeholders
            TProofServ::ResolveKeywords(dirPath, 0);
         }
      }
      // Save the raw directory
      fRawDir = dirPath;
      // Make sure the the path exists
      if (AssertDir(dirPath) != 0)
         Error("Init", "problems asserting path '%s'", dirPath.Data());
      // Take into account local server settings
      TProofServ::GetLocalServer(fDir);
      TProofServ::FilterLocalroot(dirPath, fDir);
      // The path to be used to address the file
      fDir += dirPath;
   }
   // Notify
   Info("Init", "dir: %s (raw: %s)", fDir.Data(), fRawDir.Data());

   // Default output file name
   ResetBit(TProofOutputFile::kOutputFileNameSet);
   fOutputFileName = "<file>";
   if (gEnv->Lookup("Proof.OutputFile")) {
      fOutputFileName = gEnv->GetValue("Proof.OutputFile", "<file>");
      SetBit(TProofOutputFile::kOutputFileNameSet);
   }
   // Add default file name
   TString fileName = path;
   if (!fileName.EndsWith(".root")) fileName += ".root";
   // Make sure that the file name was inserted (may not happen if the placeholder <file> is missing)
   if (!fOutputFileName.IsNull() && !fOutputFileName.Contains("<file>")) {
      if (!fOutputFileName.EndsWith("/")) fOutputFileName += "/";
         fOutputFileName += fileName;
   }
   // Resolve placeholders
   fileName.ReplaceAll("<ord>",""); // No ordinal in the final merged file
   TProofServ::ResolveKeywords(fOutputFileName, fileName);
   Info("Init", "output file url: %s", fOutputFileName.Data());
   // Fill ordinal
   fWorkerOrdinal = "<ord>";
   TProofServ::ResolveKeywords(fWorkerOrdinal, 0);
}

//________________________________________________________________________________
TProofOutputFile::~TProofOutputFile()
{
   // Main destructor

   if (fDataSet) delete fDataSet;
   if (fMerger) delete fMerger;
}

//______________________________________________________________________________
void TProofOutputFile::SetOutputFileName(const char *name)
{
   // Set the name of the output file; in the form of an Url.

   if (name && strlen(name) > 0) {
      fOutputFileName = name;
      TProofServ::ResolveKeywords(fOutputFileName);
      PDB(kOutput,1) Info("SetOutputFileName", "output file url: %s", fOutputFileName.Data());
   } else {
      fOutputFileName = "";
   }
   SetBit(TProofOutputFile::kOutputFileNameSet);
}

//______________________________________________________________________________
TFile* TProofOutputFile::OpenFile(const char* opt)
{
   // Open the file using the unique temporary name

   if (fFileName.IsNull()) return 0;

   // Create the path
   TString fileLoc;
   fileLoc.Form("%s/%s%s", fRawDir.Data(), fFileName.Data(), fOptionsAnchor.Data());
   
   // Open the file
   TFile *retFile = TFile::Open(fileLoc, opt);

   return retFile;
}

//______________________________________________________________________________
Int_t TProofOutputFile::AdoptFile(TFile *f)
{
   // Adopt a file already open.
   // Return 0 if OK, -1 in case of failure

   if (!f || (f && f->IsZombie())) {
      Error("AdoptFile", "file is undefined or zombie!");
      return -1;
   }
   const TUrl *u = f->GetEndpointUrl();
   if (!u) {
      Error("AdoptFile", "file end-point url is undefined!");
      return -1;
   }

   // Set the name and dir
   fIsLocal = kFALSE;
   if (!strcmp(u->GetProtocol(), "file")) {
      fIsLocal = kTRUE;
      fDir = u->GetFile();
   } else {
      fDir = u->GetUrl();
   }
   fFileName = gSystem->BaseName(fDir.Data());
   fDir.ReplaceAll(fFileName, "");
   fRawDir = fDir;

   // If local remove prefix, if any
   if (fIsLocal) {
      TString localDS;
      TProofServ::GetLocalServer(localDS);
      if (!localDS.IsNull()) {
         TProofServ::FilterLocalroot(fDir, localDS);
         fDir.Insert(0, localDS);
      }
   }
   
   return 0;
}

//______________________________________________________________________________
Long64_t TProofOutputFile::Merge(TCollection* list)
{
   // Merge objects from the list into this object

   PDB(kOutput,2) Info("Merge","enter: merge? %d", IsMerge());

   // Needs somethign to merge
   if(!list || list->IsEmpty()) return 0;
   
   if (IsMerge()) {
      // Build-up the merger
      TString fileLoc;
      TString outputFileLoc = (fOutputFileName.IsNull()) ? fFileName : fOutputFileName;
      // Get the file merger instance
      Bool_t localMerge = (fRunType == kMerge && fTypeOpt == kLocal) ? kTRUE : kFALSE;
      TFileMerger *merger = GetFileMerger(localMerge);
      if (!merger) {
         Error("Merge", "could not instantiate the file merger");
         return -1;
      }

      if (!fMerged) {
         merger->OutputFile(outputFileLoc);
         fileLoc.Form("%s/%s", fDir.Data(), GetFileName());
         AddFile(merger, fileLoc);
         fMerged = kTRUE;
      }

      TIter next(list);
      TObject *o = 0;
      while((o = next())) {
         TProofOutputFile *pFile = dynamic_cast<TProofOutputFile *>(o);
         if (pFile) {
            fileLoc.Form("%s/%s", pFile->GetDir(), pFile->GetFileName());
            AddFile(merger, fileLoc);
         }
      }
   } else {
      // Get the reference MSS url, if any
      TUrl mssUrl(gEnv->GetValue("ProofServ.PoolUrl",""));
      // Build-up the TFileCollection
      TFileCollection *dataset = GetFileCollection();
      if (!dataset) {
         Error("Merge", "could not instantiate the file collection");
         return -1;
      }
      fMerged = kTRUE;
      TString path;
      TFileInfo *fi = 0;
      // If new, add ourseelves
      dataset->Update();
      PDB(kOutput,2) Info("Merge","dataset: %s (nfiles: %lld)", dataset->GetName(), dataset->GetNFiles());
      if (dataset->GetNFiles() == 0) {
         // Save the export and raw urls
         path.Form("%s/%s%s", GetDir(), GetFileName(), GetOptionsAnchor());
         fi = new TFileInfo(path);
         // Add also an URL with the redirector path, if any
         if (mssUrl.IsValid()) {
            TUrl ur(fi->GetFirstUrl()->GetUrl());
            ur.SetProtocol(mssUrl.GetProtocol());
            ur.SetHost(mssUrl.GetHost());
            ur.SetPort(mssUrl.GetPort());
            if (mssUrl.GetUser() && strlen(mssUrl.GetUser()) > 0)
               ur.SetUser(mssUrl.GetUser());
            fi->AddUrl(ur.GetUrl());
         }
         // Add special local URL to keep track of the file
         path.Form("%s/%s?node=%s", GetDir(kTRUE), GetFileName(), GetLocalHost());
         fi->AddUrl(path);
         PDB(kOutput,2) fi->Print();
         // Now add to the dataset
         dataset->Add(fi);
      }

      TIter next(list);
      TObject *o = 0;
      while((o = next())) {
         TProofOutputFile *pFile = dynamic_cast<TProofOutputFile *>(o);
         if (pFile) {
            // Save the export and raw urls
            path.Form("%s/%s%s", pFile->GetDir(), pFile->GetFileName(), pFile->GetOptionsAnchor());
            fi = new TFileInfo(path);
            // Add also an URL with the redirector path, if any
            if (mssUrl.IsValid()) {
               TUrl ur(fi->GetFirstUrl()->GetUrl());
               ur.SetProtocol(mssUrl.GetProtocol());
               ur.SetHost(mssUrl.GetHost());
               ur.SetPort(mssUrl.GetPort());
               if (mssUrl.GetUser() && strlen(mssUrl.GetUser()) > 0)
                  ur.SetUser(mssUrl.GetUser());
               fi->AddUrl(ur.GetUrl());
            }
            // Add special local URL to keep track of the file
            path.Form("%s/%s?node=%s", pFile->GetDir(kTRUE), pFile->GetFileName(), pFile->GetLocalHost());
            fi->AddUrl(path);
            PDB(kOutput,2) fi->Print();
            // Now add to the dataset
            dataset->Add(fi);
         }
      }
   }
   PDB(kOutput,2) Info("Merge","Done");

   // Done
   return 0;
}

//______________________________________________________________________________
void TProofOutputFile::Print(Option_t *) const
{
   // Dump the class content

   Info("Print","-------------- %s : start (%s) ------------", GetName(), fLocalHost.Data());
   Info("Print"," dir:              %s", fDir.Data());
   Info("Print"," raw dir:          %s", fRawDir.Data());
   Info("Print"," file name:        %s%s", fFileName.Data(), fOptionsAnchor.Data());
   if (IsMerge()) {
      Info("Print"," run type:         create a merged file");
      Info("Print"," merging option:   %s",
                       (fTypeOpt == kLocal) ? "local copy" : "keep remote");
   } else {
      TString opt;
      if ((fTypeOpt & kRegister)) opt += "R";
      if ((fTypeOpt & kOverwrite)) opt += "O";
      if ((fTypeOpt & kVerify)) opt += "V";
      Info("Print"," run type:         create dataset (name: '%s', opt: '%s')",
                                         GetTitle(), opt.Data());
   }
   Info("Print"," output file name: %s", fOutputFileName.Data());
   Info("Print"," ordinal:          %s", fWorkerOrdinal.Data());
   Info("Print","-------------- %s : done -------------", GetName());

   return;
}

//______________________________________________________________________________
void TProofOutputFile::NotifyError(const char *msg)
{
   // Notify error message

   if (msg) {
      if (gProofServ)
         gProofServ->SendAsynMessage(msg);
      else
         Printf("%s", msg);
   } else {
      Info("NotifyError","called with empty message");
   }

   return;
}

//______________________________________________________________________________
void TProofOutputFile::AddFile(TFileMerger *merger, const char *path)
{
   // Add file to merger, checking the result

   if (merger && path) {
      if (!merger->AddFile(path))
         NotifyError(Form("TProofOutputFile::AddFile:"
                          " error from TFileMerger::AddFile(%s)", path));
   }
}

//______________________________________________________________________________
void TProofOutputFile::Unlink(const char *path)
{
   // Unlink path

   if (path) {
      if (!gSystem->AccessPathName(path)) {
         if (gSystem->Unlink(path) != 0)
            NotifyError(Form("TProofOutputFile::Unlink:"
                             " error from TSystem::Unlink(%s)", path));
      }
   }
}

//______________________________________________________________________________
TFileCollection *TProofOutputFile::GetFileCollection()
{
   // Get instance of the file collection to be used in 'dataset' mode

   if (!fDataSet)
      fDataSet = new TFileCollection(GetTitle());
   return fDataSet;
}

//______________________________________________________________________________
TFileMerger *TProofOutputFile::GetFileMerger(Bool_t local)
{
   // Get instance of the file merger to be used in 'merge' mode

   if (!fMerger)
      fMerger = new TFileMerger(local, fMergeHistosOneGo);
   return fMerger;
}

//________________________________________________________________________________
Int_t TProofOutputFile::AssertDir(const char *dirpath)
{
   // Assert directory path 'dirpath', with the ownership of the last already
   // existing subpath.
   // Return 0 on success, -1 on error
   
   TString existsPath(dirpath);
   TList subPaths;
   while (existsPath != "/" && existsPath != "." && gSystem->AccessPathName(existsPath)) {
      subPaths.AddFirst(new TObjString(gSystem->BaseName(existsPath)));
      existsPath = gSystem->DirName(existsPath);
   }
   subPaths.SetOwner(kTRUE);
   FileStat_t st;
   if (gSystem->GetPathInfo(existsPath, st) == 0) {
      TString xpath = existsPath;
      TIter nxp(&subPaths);
      TObjString *os = 0;
      while ((os = (TObjString *) nxp())) {
         xpath += TString::Format("/%s", os->GetName());
         if (gSystem->mkdir(xpath, kTRUE) == 0) {
            if (gSystem->Chmod(xpath, (UInt_t) st.fMode) != 0)
               ::Warning("TProofOutputFile::AssertDir", "problems setting mode on '%s'", xpath.Data());
         } else {
            ::Error("TProofOutputFile::AssertDir", "problems creating path '%s'", xpath.Data());
            return -1;
         }
      }
   } else {
      ::Warning("TProofOutputFile::AssertDir", "could not get info for path '%s': will only try to create"
                           " the full path w/o trying to set the mode", existsPath.Data());
      if (gSystem->mkdir(existsPath, kTRUE) != 0) {
         ::Error("TProofOutputFile::AssertDir", "problems creating path '%s'", existsPath.Data());
         return -1;
      }
   }
   // Done
   return 0;
}
 TProofOutputFile.cxx:1
 TProofOutputFile.cxx:2
 TProofOutputFile.cxx:3
 TProofOutputFile.cxx:4
 TProofOutputFile.cxx:5
 TProofOutputFile.cxx:6
 TProofOutputFile.cxx:7
 TProofOutputFile.cxx:8
 TProofOutputFile.cxx:9
 TProofOutputFile.cxx:10
 TProofOutputFile.cxx:11
 TProofOutputFile.cxx:12
 TProofOutputFile.cxx:13
 TProofOutputFile.cxx:14
 TProofOutputFile.cxx:15
 TProofOutputFile.cxx:16
 TProofOutputFile.cxx:17
 TProofOutputFile.cxx:18
 TProofOutputFile.cxx:19
 TProofOutputFile.cxx:20
 TProofOutputFile.cxx:21
 TProofOutputFile.cxx:22
 TProofOutputFile.cxx:23
 TProofOutputFile.cxx:24
 TProofOutputFile.cxx:25
 TProofOutputFile.cxx:26
 TProofOutputFile.cxx:27
 TProofOutputFile.cxx:28
 TProofOutputFile.cxx:29
 TProofOutputFile.cxx:30
 TProofOutputFile.cxx:31
 TProofOutputFile.cxx:32
 TProofOutputFile.cxx:33
 TProofOutputFile.cxx:34
 TProofOutputFile.cxx:35
 TProofOutputFile.cxx:36
 TProofOutputFile.cxx:37
 TProofOutputFile.cxx:38
 TProofOutputFile.cxx:39
 TProofOutputFile.cxx:40
 TProofOutputFile.cxx:41
 TProofOutputFile.cxx:42
 TProofOutputFile.cxx:43
 TProofOutputFile.cxx:44
 TProofOutputFile.cxx:45
 TProofOutputFile.cxx:46
 TProofOutputFile.cxx:47
 TProofOutputFile.cxx:48
 TProofOutputFile.cxx:49
 TProofOutputFile.cxx:50
 TProofOutputFile.cxx:51
 TProofOutputFile.cxx:52
 TProofOutputFile.cxx:53
 TProofOutputFile.cxx:54
 TProofOutputFile.cxx:55
 TProofOutputFile.cxx:56
 TProofOutputFile.cxx:57
 TProofOutputFile.cxx:58
 TProofOutputFile.cxx:59
 TProofOutputFile.cxx:60
 TProofOutputFile.cxx:61
 TProofOutputFile.cxx:62
 TProofOutputFile.cxx:63
 TProofOutputFile.cxx:64
 TProofOutputFile.cxx:65
 TProofOutputFile.cxx:66
 TProofOutputFile.cxx:67
 TProofOutputFile.cxx:68
 TProofOutputFile.cxx:69
 TProofOutputFile.cxx:70
 TProofOutputFile.cxx:71
 TProofOutputFile.cxx:72
 TProofOutputFile.cxx:73
 TProofOutputFile.cxx:74
 TProofOutputFile.cxx:75
 TProofOutputFile.cxx:76
 TProofOutputFile.cxx:77
 TProofOutputFile.cxx:78
 TProofOutputFile.cxx:79
 TProofOutputFile.cxx:80
 TProofOutputFile.cxx:81
 TProofOutputFile.cxx:82
 TProofOutputFile.cxx:83
 TProofOutputFile.cxx:84
 TProofOutputFile.cxx:85
 TProofOutputFile.cxx:86
 TProofOutputFile.cxx:87
 TProofOutputFile.cxx:88
 TProofOutputFile.cxx:89
 TProofOutputFile.cxx:90
 TProofOutputFile.cxx:91
 TProofOutputFile.cxx:92
 TProofOutputFile.cxx:93
 TProofOutputFile.cxx:94
 TProofOutputFile.cxx:95
 TProofOutputFile.cxx:96
 TProofOutputFile.cxx:97
 TProofOutputFile.cxx:98
 TProofOutputFile.cxx:99
 TProofOutputFile.cxx:100
 TProofOutputFile.cxx:101
 TProofOutputFile.cxx:102
 TProofOutputFile.cxx:103
 TProofOutputFile.cxx:104
 TProofOutputFile.cxx:105
 TProofOutputFile.cxx:106
 TProofOutputFile.cxx:107
 TProofOutputFile.cxx:108
 TProofOutputFile.cxx:109
 TProofOutputFile.cxx:110
 TProofOutputFile.cxx:111
 TProofOutputFile.cxx:112
 TProofOutputFile.cxx:113
 TProofOutputFile.cxx:114
 TProofOutputFile.cxx:115
 TProofOutputFile.cxx:116
 TProofOutputFile.cxx:117
 TProofOutputFile.cxx:118
 TProofOutputFile.cxx:119
 TProofOutputFile.cxx:120
 TProofOutputFile.cxx:121
 TProofOutputFile.cxx:122
 TProofOutputFile.cxx:123
 TProofOutputFile.cxx:124
 TProofOutputFile.cxx:125
 TProofOutputFile.cxx:126
 TProofOutputFile.cxx:127
 TProofOutputFile.cxx:128
 TProofOutputFile.cxx:129
 TProofOutputFile.cxx:130
 TProofOutputFile.cxx:131
 TProofOutputFile.cxx:132
 TProofOutputFile.cxx:133
 TProofOutputFile.cxx:134
 TProofOutputFile.cxx:135
 TProofOutputFile.cxx:136
 TProofOutputFile.cxx:137
 TProofOutputFile.cxx:138
 TProofOutputFile.cxx:139
 TProofOutputFile.cxx:140
 TProofOutputFile.cxx:141
 TProofOutputFile.cxx:142
 TProofOutputFile.cxx:143
 TProofOutputFile.cxx:144
 TProofOutputFile.cxx:145
 TProofOutputFile.cxx:146
 TProofOutputFile.cxx:147
 TProofOutputFile.cxx:148
 TProofOutputFile.cxx:149
 TProofOutputFile.cxx:150
 TProofOutputFile.cxx:151
 TProofOutputFile.cxx:152
 TProofOutputFile.cxx:153
 TProofOutputFile.cxx:154
 TProofOutputFile.cxx:155
 TProofOutputFile.cxx:156
 TProofOutputFile.cxx:157
 TProofOutputFile.cxx:158
 TProofOutputFile.cxx:159
 TProofOutputFile.cxx:160
 TProofOutputFile.cxx:161
 TProofOutputFile.cxx:162
 TProofOutputFile.cxx:163
 TProofOutputFile.cxx:164
 TProofOutputFile.cxx:165
 TProofOutputFile.cxx:166
 TProofOutputFile.cxx:167
 TProofOutputFile.cxx:168
 TProofOutputFile.cxx:169
 TProofOutputFile.cxx:170
 TProofOutputFile.cxx:171
 TProofOutputFile.cxx:172
 TProofOutputFile.cxx:173
 TProofOutputFile.cxx:174
 TProofOutputFile.cxx:175
 TProofOutputFile.cxx:176
 TProofOutputFile.cxx:177
 TProofOutputFile.cxx:178
 TProofOutputFile.cxx:179
 TProofOutputFile.cxx:180
 TProofOutputFile.cxx:181
 TProofOutputFile.cxx:182
 TProofOutputFile.cxx:183
 TProofOutputFile.cxx:184
 TProofOutputFile.cxx:185
 TProofOutputFile.cxx:186
 TProofOutputFile.cxx:187
 TProofOutputFile.cxx:188
 TProofOutputFile.cxx:189
 TProofOutputFile.cxx:190
 TProofOutputFile.cxx:191
 TProofOutputFile.cxx:192
 TProofOutputFile.cxx:193
 TProofOutputFile.cxx:194
 TProofOutputFile.cxx:195
 TProofOutputFile.cxx:196
 TProofOutputFile.cxx:197
 TProofOutputFile.cxx:198
 TProofOutputFile.cxx:199
 TProofOutputFile.cxx:200
 TProofOutputFile.cxx:201
 TProofOutputFile.cxx:202
 TProofOutputFile.cxx:203
 TProofOutputFile.cxx:204
 TProofOutputFile.cxx:205
 TProofOutputFile.cxx:206
 TProofOutputFile.cxx:207
 TProofOutputFile.cxx:208
 TProofOutputFile.cxx:209
 TProofOutputFile.cxx:210
 TProofOutputFile.cxx:211
 TProofOutputFile.cxx:212
 TProofOutputFile.cxx:213
 TProofOutputFile.cxx:214
 TProofOutputFile.cxx:215
 TProofOutputFile.cxx:216
 TProofOutputFile.cxx:217
 TProofOutputFile.cxx:218
 TProofOutputFile.cxx:219
 TProofOutputFile.cxx:220
 TProofOutputFile.cxx:221
 TProofOutputFile.cxx:222
 TProofOutputFile.cxx:223
 TProofOutputFile.cxx:224
 TProofOutputFile.cxx:225
 TProofOutputFile.cxx:226
 TProofOutputFile.cxx:227
 TProofOutputFile.cxx:228
 TProofOutputFile.cxx:229
 TProofOutputFile.cxx:230
 TProofOutputFile.cxx:231
 TProofOutputFile.cxx:232
 TProofOutputFile.cxx:233
 TProofOutputFile.cxx:234
 TProofOutputFile.cxx:235
 TProofOutputFile.cxx:236
 TProofOutputFile.cxx:237
 TProofOutputFile.cxx:238
 TProofOutputFile.cxx:239
 TProofOutputFile.cxx:240
 TProofOutputFile.cxx:241
 TProofOutputFile.cxx:242
 TProofOutputFile.cxx:243
 TProofOutputFile.cxx:244
 TProofOutputFile.cxx:245
 TProofOutputFile.cxx:246
 TProofOutputFile.cxx:247
 TProofOutputFile.cxx:248
 TProofOutputFile.cxx:249
 TProofOutputFile.cxx:250
 TProofOutputFile.cxx:251
 TProofOutputFile.cxx:252
 TProofOutputFile.cxx:253
 TProofOutputFile.cxx:254
 TProofOutputFile.cxx:255
 TProofOutputFile.cxx:256
 TProofOutputFile.cxx:257
 TProofOutputFile.cxx:258
 TProofOutputFile.cxx:259
 TProofOutputFile.cxx:260
 TProofOutputFile.cxx:261
 TProofOutputFile.cxx:262
 TProofOutputFile.cxx:263
 TProofOutputFile.cxx:264
 TProofOutputFile.cxx:265
 TProofOutputFile.cxx:266
 TProofOutputFile.cxx:267
 TProofOutputFile.cxx:268
 TProofOutputFile.cxx:269
 TProofOutputFile.cxx:270
 TProofOutputFile.cxx:271
 TProofOutputFile.cxx:272
 TProofOutputFile.cxx:273
 TProofOutputFile.cxx:274
 TProofOutputFile.cxx:275
 TProofOutputFile.cxx:276
 TProofOutputFile.cxx:277
 TProofOutputFile.cxx:278
 TProofOutputFile.cxx:279
 TProofOutputFile.cxx:280
 TProofOutputFile.cxx:281
 TProofOutputFile.cxx:282
 TProofOutputFile.cxx:283
 TProofOutputFile.cxx:284
 TProofOutputFile.cxx:285
 TProofOutputFile.cxx:286
 TProofOutputFile.cxx:287
 TProofOutputFile.cxx:288
 TProofOutputFile.cxx:289
 TProofOutputFile.cxx:290
 TProofOutputFile.cxx:291
 TProofOutputFile.cxx:292
 TProofOutputFile.cxx:293
 TProofOutputFile.cxx:294
 TProofOutputFile.cxx:295
 TProofOutputFile.cxx:296
 TProofOutputFile.cxx:297
 TProofOutputFile.cxx:298
 TProofOutputFile.cxx:299
 TProofOutputFile.cxx:300
 TProofOutputFile.cxx:301
 TProofOutputFile.cxx:302
 TProofOutputFile.cxx:303
 TProofOutputFile.cxx:304
 TProofOutputFile.cxx:305
 TProofOutputFile.cxx:306
 TProofOutputFile.cxx:307
 TProofOutputFile.cxx:308
 TProofOutputFile.cxx:309
 TProofOutputFile.cxx:310
 TProofOutputFile.cxx:311
 TProofOutputFile.cxx:312
 TProofOutputFile.cxx:313
 TProofOutputFile.cxx:314
 TProofOutputFile.cxx:315
 TProofOutputFile.cxx:316
 TProofOutputFile.cxx:317
 TProofOutputFile.cxx:318
 TProofOutputFile.cxx:319
 TProofOutputFile.cxx:320
 TProofOutputFile.cxx:321
 TProofOutputFile.cxx:322
 TProofOutputFile.cxx:323
 TProofOutputFile.cxx:324
 TProofOutputFile.cxx:325
 TProofOutputFile.cxx:326
 TProofOutputFile.cxx:327
 TProofOutputFile.cxx:328
 TProofOutputFile.cxx:329
 TProofOutputFile.cxx:330
 TProofOutputFile.cxx:331
 TProofOutputFile.cxx:332
 TProofOutputFile.cxx:333
 TProofOutputFile.cxx:334
 TProofOutputFile.cxx:335
 TProofOutputFile.cxx:336
 TProofOutputFile.cxx:337
 TProofOutputFile.cxx:338
 TProofOutputFile.cxx:339
 TProofOutputFile.cxx:340
 TProofOutputFile.cxx:341
 TProofOutputFile.cxx:342
 TProofOutputFile.cxx:343
 TProofOutputFile.cxx:344
 TProofOutputFile.cxx:345
 TProofOutputFile.cxx:346
 TProofOutputFile.cxx:347
 TProofOutputFile.cxx:348
 TProofOutputFile.cxx:349
 TProofOutputFile.cxx:350
 TProofOutputFile.cxx:351
 TProofOutputFile.cxx:352
 TProofOutputFile.cxx:353
 TProofOutputFile.cxx:354
 TProofOutputFile.cxx:355
 TProofOutputFile.cxx:356
 TProofOutputFile.cxx:357
 TProofOutputFile.cxx:358
 TProofOutputFile.cxx:359
 TProofOutputFile.cxx:360
 TProofOutputFile.cxx:361
 TProofOutputFile.cxx:362
 TProofOutputFile.cxx:363
 TProofOutputFile.cxx:364
 TProofOutputFile.cxx:365
 TProofOutputFile.cxx:366
 TProofOutputFile.cxx:367
 TProofOutputFile.cxx:368
 TProofOutputFile.cxx:369
 TProofOutputFile.cxx:370
 TProofOutputFile.cxx:371
 TProofOutputFile.cxx:372
 TProofOutputFile.cxx:373
 TProofOutputFile.cxx:374
 TProofOutputFile.cxx:375
 TProofOutputFile.cxx:376
 TProofOutputFile.cxx:377
 TProofOutputFile.cxx:378
 TProofOutputFile.cxx:379
 TProofOutputFile.cxx:380
 TProofOutputFile.cxx:381
 TProofOutputFile.cxx:382
 TProofOutputFile.cxx:383
 TProofOutputFile.cxx:384
 TProofOutputFile.cxx:385
 TProofOutputFile.cxx:386
 TProofOutputFile.cxx:387
 TProofOutputFile.cxx:388
 TProofOutputFile.cxx:389
 TProofOutputFile.cxx:390
 TProofOutputFile.cxx:391
 TProofOutputFile.cxx:392
 TProofOutputFile.cxx:393
 TProofOutputFile.cxx:394
 TProofOutputFile.cxx:395
 TProofOutputFile.cxx:396
 TProofOutputFile.cxx:397
 TProofOutputFile.cxx:398
 TProofOutputFile.cxx:399
 TProofOutputFile.cxx:400
 TProofOutputFile.cxx:401
 TProofOutputFile.cxx:402
 TProofOutputFile.cxx:403
 TProofOutputFile.cxx:404
 TProofOutputFile.cxx:405
 TProofOutputFile.cxx:406
 TProofOutputFile.cxx:407
 TProofOutputFile.cxx:408
 TProofOutputFile.cxx:409
 TProofOutputFile.cxx:410
 TProofOutputFile.cxx:411
 TProofOutputFile.cxx:412
 TProofOutputFile.cxx:413
 TProofOutputFile.cxx:414
 TProofOutputFile.cxx:415
 TProofOutputFile.cxx:416
 TProofOutputFile.cxx:417
 TProofOutputFile.cxx:418
 TProofOutputFile.cxx:419
 TProofOutputFile.cxx:420
 TProofOutputFile.cxx:421
 TProofOutputFile.cxx:422
 TProofOutputFile.cxx:423
 TProofOutputFile.cxx:424
 TProofOutputFile.cxx:425
 TProofOutputFile.cxx:426
 TProofOutputFile.cxx:427
 TProofOutputFile.cxx:428
 TProofOutputFile.cxx:429
 TProofOutputFile.cxx:430
 TProofOutputFile.cxx:431
 TProofOutputFile.cxx:432
 TProofOutputFile.cxx:433
 TProofOutputFile.cxx:434
 TProofOutputFile.cxx:435
 TProofOutputFile.cxx:436
 TProofOutputFile.cxx:437
 TProofOutputFile.cxx:438
 TProofOutputFile.cxx:439
 TProofOutputFile.cxx:440
 TProofOutputFile.cxx:441
 TProofOutputFile.cxx:442
 TProofOutputFile.cxx:443
 TProofOutputFile.cxx:444
 TProofOutputFile.cxx:445
 TProofOutputFile.cxx:446
 TProofOutputFile.cxx:447
 TProofOutputFile.cxx:448
 TProofOutputFile.cxx:449
 TProofOutputFile.cxx:450
 TProofOutputFile.cxx:451
 TProofOutputFile.cxx:452
 TProofOutputFile.cxx:453
 TProofOutputFile.cxx:454
 TProofOutputFile.cxx:455
 TProofOutputFile.cxx:456
 TProofOutputFile.cxx:457
 TProofOutputFile.cxx:458
 TProofOutputFile.cxx:459
 TProofOutputFile.cxx:460
 TProofOutputFile.cxx:461
 TProofOutputFile.cxx:462
 TProofOutputFile.cxx:463
 TProofOutputFile.cxx:464
 TProofOutputFile.cxx:465
 TProofOutputFile.cxx:466
 TProofOutputFile.cxx:467
 TProofOutputFile.cxx:468
 TProofOutputFile.cxx:469
 TProofOutputFile.cxx:470
 TProofOutputFile.cxx:471
 TProofOutputFile.cxx:472
 TProofOutputFile.cxx:473
 TProofOutputFile.cxx:474
 TProofOutputFile.cxx:475
 TProofOutputFile.cxx:476
 TProofOutputFile.cxx:477
 TProofOutputFile.cxx:478
 TProofOutputFile.cxx:479
 TProofOutputFile.cxx:480
 TProofOutputFile.cxx:481
 TProofOutputFile.cxx:482
 TProofOutputFile.cxx:483
 TProofOutputFile.cxx:484
 TProofOutputFile.cxx:485
 TProofOutputFile.cxx:486
 TProofOutputFile.cxx:487
 TProofOutputFile.cxx:488
 TProofOutputFile.cxx:489
 TProofOutputFile.cxx:490
 TProofOutputFile.cxx:491
 TProofOutputFile.cxx:492
 TProofOutputFile.cxx:493
 TProofOutputFile.cxx:494
 TProofOutputFile.cxx:495
 TProofOutputFile.cxx:496
 TProofOutputFile.cxx:497
 TProofOutputFile.cxx:498
 TProofOutputFile.cxx:499
 TProofOutputFile.cxx:500
 TProofOutputFile.cxx:501
 TProofOutputFile.cxx:502
 TProofOutputFile.cxx:503
 TProofOutputFile.cxx:504
 TProofOutputFile.cxx:505
 TProofOutputFile.cxx:506
 TProofOutputFile.cxx:507
 TProofOutputFile.cxx:508
 TProofOutputFile.cxx:509
 TProofOutputFile.cxx:510
 TProofOutputFile.cxx:511
 TProofOutputFile.cxx:512
 TProofOutputFile.cxx:513
 TProofOutputFile.cxx:514
 TProofOutputFile.cxx:515
 TProofOutputFile.cxx:516
 TProofOutputFile.cxx:517
 TProofOutputFile.cxx:518
 TProofOutputFile.cxx:519
 TProofOutputFile.cxx:520
 TProofOutputFile.cxx:521
 TProofOutputFile.cxx:522
 TProofOutputFile.cxx:523
 TProofOutputFile.cxx:524
 TProofOutputFile.cxx:525
 TProofOutputFile.cxx:526
 TProofOutputFile.cxx:527
 TProofOutputFile.cxx:528
 TProofOutputFile.cxx:529
 TProofOutputFile.cxx:530
 TProofOutputFile.cxx:531
 TProofOutputFile.cxx:532
 TProofOutputFile.cxx:533
 TProofOutputFile.cxx:534
 TProofOutputFile.cxx:535
 TProofOutputFile.cxx:536
 TProofOutputFile.cxx:537
 TProofOutputFile.cxx:538
 TProofOutputFile.cxx:539
 TProofOutputFile.cxx:540
 TProofOutputFile.cxx:541
 TProofOutputFile.cxx:542
 TProofOutputFile.cxx:543
 TProofOutputFile.cxx:544
 TProofOutputFile.cxx:545
 TProofOutputFile.cxx:546
 TProofOutputFile.cxx:547
 TProofOutputFile.cxx:548
 TProofOutputFile.cxx:549
 TProofOutputFile.cxx:550