From $ROOTSYS/tutorials/proof/ProofSimple.C

#define ProofSimple_cxx
//////////////////////////////////////////////////////////
//
// Example of TSelector implementation to do generic
// processing (filling a set of histograms in this case).
// See tutorials/proof/runProof.C, option "simple", for an
// example of how to run this selector.
//
//////////////////////////////////////////////////////////

#include "ProofSimple.h"
#include <TCanvas.h>
#include <TFrame.h>
#include <TPaveText.h>
#include <TFormula.h>
#include <TF1.h>
#include <TH1F.h>
#include <TH3F.h>
#include <TMath.h>
#include <TRandom3.h>
#include <TString.h>
#include <TStyle.h>
#include <TSystem.h>
#include <TParameter.h>
#include <TSortedList.h>
#include "TProof.h"
#include <TFile.h>
#include <TProofOutputFile.h>
#include <TNtuple.h>
#include <TFileCollection.h>
#include <TFileInfo.h>
#include <THashList.h>

//_____________________________________________________________________________
ProofSimple::ProofSimple()
{
   // Constructor

   fNhist = -1;
   fHist = 0;
   fNhist3 = -1;
   fHist3 = 0;
   fRandom = 0;
   fHLab = 0;
   fFile = 0;
   fProofFile = 0;
   fNtp = 0;
   fHasNtuple = 0;
   fPlotNtuple = kFALSE;
}

//_____________________________________________________________________________
ProofSimple::~ProofSimple()
{
   // Destructor

   if (fFile) {
      SafeDelete(fNtp);
      SafeDelete(fFile);
   }
   SafeDelete(fRandom);
}

//_____________________________________________________________________________
void ProofSimple::Begin(TTree * /*tree*/)
{
   // The Begin() function is called at the start of the query.
   // When running with PROOF Begin() is only called on the client.
   // The tree argument is deprecated (on PROOF 0 is passed).

   TString option = GetOption();
   Ssiz_t iopt = kNPOS;

   // Histos array
   if (fInput->FindObject("ProofSimple_NHist")) {
      TParameter<Long_t> *p =
         dynamic_cast<TParameter<Long_t>*>(fInput->FindObject("ProofSimple_NHist"));
      fNhist = (p) ? (Int_t) p->GetVal() : fNhist;
   } else if ((iopt = option.Index("nhist=")) != kNPOS) {
      TString s;
      Ssiz_t from = iopt + strlen("nhist=");
      if (option.Tokenize(s, from, ";") && s.IsDigit()) fNhist = s.Atoi();
   }
   if (fNhist < 1) {
      Abort("fNhist must be > 0! Hint: proof->SetParameter(\"ProofSimple_NHist\","
            " (Long_t) <nhist>)", kAbortProcess);
      return;
   }

   if (fInput->FindObject("ProofSimple_NHist3")) {
      TParameter<Long_t> *p =
         dynamic_cast<TParameter<Long_t>*>(fInput->FindObject("ProofSimple_NHist3"));
      fNhist3 = (p) ? (Int_t) p->GetVal() : fNhist3;
   } else if ((iopt = option.Index("nhist3=")) != kNPOS) {
      TString s;
      Ssiz_t from = iopt + strlen("nhist3=");
      if (option.Tokenize(s, from, ";") && s.IsDigit()) fNhist3 = s.Atoi();
   }

   // Ntuple
   TNamed *nm = dynamic_cast<TNamed *>(fInput->FindObject("ProofSimple_Ntuple"));
   if (nm) {

      // Title is in the form
      //         merge                  merge via file
      //           |<fout>                      location of the output file if merge
      //           |retrieve                    retrieve to client machine
      //         dataset                create a dataset
      //           |<dsname>                    dataset name (default: dataset_ntuple)
      //         |plot                  for a final plot
      //         <empty> or other       keep in memory

      fHasNtuple = 1;

      TString ontp(nm->GetTitle());
      if (ontp.Contains("|plot") || ontp == "plot") {
         fPlotNtuple = kTRUE;
         ontp.ReplaceAll("|plot", "");
         if (ontp == "plot") ontp = "";
      }
      if (ontp.BeginsWith("dataset")) fHasNtuple = 2;
   }
}

//_____________________________________________________________________________
void ProofSimple::SlaveBegin(TTree * /*tree*/)
{
   // The SlaveBegin() function is called after the Begin() function.
   // When running with PROOF SlaveBegin() is called on each slave server.
   // The tree argument is deprecated (on PROOF 0 is passed).

   TString option = GetOption();
   Ssiz_t iopt = kNPOS;

   // Histos array
   if (fInput->FindObject("ProofSimple_NHist")) {
      TParameter<Long_t> *p =
         dynamic_cast<TParameter<Long_t>*>(fInput->FindObject("ProofSimple_NHist"));
      fNhist = (p) ? (Int_t) p->GetVal() : fNhist;
   } else if ((iopt = option.Index("nhist=")) != kNPOS) {
      TString s;
      Ssiz_t from = iopt + strlen("nhist=");
      if (option.Tokenize(s, from, ";") && s.IsDigit()) fNhist = s.Atoi();
   }
   if (fNhist < 1) {
      Abort("fNhist must be > 0! Hint: proof->SetParameter(\"ProofSimple_NHist\","
            " (Long_t) <nhist>)", kAbortProcess);
      return;
   }
   fHist = new TH1F*[fNhist];

   TString hn;
   // Create the histogram
   for (Int_t i=0; i < fNhist; i++) {
      hn.Form("h%d",i);
      fHist[i] = new TH1F(hn.Data(), hn.Data(), 100, -3., 3.);
      fHist[i]->SetFillColor(kRed);
      fOutput->Add(fHist[i]);
   }

   // 3D Histos array
   if (fInput->FindObject("ProofSimple_NHist3")) {
      TParameter<Long_t> *p =
         dynamic_cast<TParameter<Long_t>*>(fInput->FindObject("ProofSimple_NHist3"));
      fNhist3 = (p) ? (Int_t) p->GetVal() : fNhist3;
   } else if ((iopt = option.Index("nhist3=")) != kNPOS) {
      TString s;
      Ssiz_t from = iopt + strlen("nhist3=");
      if (option.Tokenize(s, from, ";") && s.IsDigit()) fNhist3 = s.Atoi();
   }
   if (fNhist3 > 0) {
      fHist3 = new TH3F*[fNhist3];
      Info("Begin", "%d 3D histograms requested", fNhist3);
      // Create the 3D histogram
      for (Int_t i=0; i < fNhist3; i++) {
         hn.Form("h%d_3d",i);
         fHist3[i] = new TH3F(hn.Data(), hn.Data(),
                              100, -3., 3., 100, -3., 3., 100, -3., 3.);
         fOutput->Add(fHist3[i]);
      }
   }

   // Histo with labels
   if (fInput->FindObject("ProofSimple_TestLabelMerging")) {
      fHLab = new TH1F("hlab", "Test merging of histograms with automatic labels", 10, 0., 10.);
      fOutput->Add(fHLab);
   }

   // Ntuple
   TNamed *nm = dynamic_cast<TNamed *>(fInput->FindObject("ProofSimple_Ntuple"));
   if (nm) {

      // Title is in the form
      //         merge                  merge via file
      //           |<fout>                      location of the output file if merge
      //           |retrieve                    retrieve to client machine
      //         dataset                create a dataset
      //           |<dsname>                    dataset name (default: dataset_ntuple)
      //         |plot                  for a final plot
      //         <empty> or other       keep in memory

      fHasNtuple = 1;

      TString ontp(nm->GetTitle());
      if (ontp.Contains("|plot") || ontp == "plot") {
         fPlotNtuple = kTRUE;
         ontp.ReplaceAll("|plot", "");
         if (ontp == "plot") ontp = "";
      }
      TString locfn("SimpleNtuple.root");
      if (ontp.BeginsWith("merge")) {
         ontp.Replace(0,5,"");
         fProofFile = new TProofOutputFile(locfn, "M");
         TString fn;
         Ssiz_t iret = ontp.Index("|retrieve");
         if (iret != kNPOS) {
            fProofFile->SetRetrieve(kTRUE);
            TString rettag("|retrieve");
            if ((iret = ontp.Index("|retrieve=")) != kNPOS) {
               rettag += "=";
               fn = ontp(iret + rettag.Length(), ontp.Length() - iret - rettag.Length());
               if ((iret = fn.Index('|')) != kNPOS) fn.Remove(iret);
               rettag += fn;
            }
            ontp.ReplaceAll(rettag, "");
         }
         Ssiz_t iof = ontp.Index('|');
         if (iof != kNPOS) ontp.Remove(0, iof + 1);
         if (!ontp.IsNull()) {
            fProofFile->SetOutputFileName(ontp.Data());
            if (fn.IsNull()) fn = gSystem->BaseName(TUrl(ontp.Data(), kTRUE).GetFile());
         }
         if (fn.IsNull()) fn = locfn;
         // This will be the final file on the client, the case there is one
         fProofFile->SetTitle(fn);
      } else if (ontp.BeginsWith("dataset")) {
         ontp.Replace(0,7,"");
         Ssiz_t iof = ontp.Index("|");
         if (iof != kNPOS) ontp.Remove(0, iof + 1);
         TString dsname = (!ontp.IsNull()) ? ontp.Data() : "dataset_ntuple";
         UInt_t opt = TProofOutputFile::kRegister | TProofOutputFile::kOverwrite | TProofOutputFile::kVerify;
         fProofFile = new TProofOutputFile("SimpleNtuple.root",
                                          TProofOutputFile::kDataset, opt, dsname.Data());
         fHasNtuple = 2;
      } else if (!ontp.IsNull()) {
         Warning("SlaveBegin", "ntuple options unknown: ignored (%s)", ontp.Data());
      }

      // Open the file, if required
      if (fProofFile) {
         // Open the file
         fFile = fProofFile->OpenFile("RECREATE");
         if (fFile && fFile->IsZombie()) SafeDelete(fFile);

         // Cannot continue
         if (!fFile) {
            Info("SlaveBegin", "could not create '%s': instance is invalid!", fProofFile->GetName());
            return;
         }
      }

      // Now we create the ntuple
      fNtp = new TNtuple("ntuple","Demo ntuple","px:py:pz:random:i");
      // File resident, if required
      if (fFile) {
         fNtp->SetDirectory(fFile);
         fNtp->AutoSave();
      } else {
         fOutput->Add(fNtp);
      }
   }

   // Set random seed
   fRandom = new TRandom3(0);
}

//_____________________________________________________________________________
Bool_t ProofSimple::Process(Long64_t entry)
{
   // The Process() function is called for each entry in the tree (or possibly
   // keyed object in the case of PROOF) to be processed. The entry argument
   // specifies which entry in the currently loaded tree is to be processed.
   // It can be passed to either ProofSimple::GetEntry() or TBranch::GetEntry()
   // to read either all or the required parts of the data. When processing
   // keyed objects with PROOF, the object is already loaded and is available
   // via the fObject pointer.
   //
   // This function should contain the "body" of the analysis. It can contain
   // simple or elaborate selection criteria, run algorithms on the data
   // of the event and typically fill histograms.
   //
   // The processing can be stopped by calling Abort().
   //
   // Use fStatus to set the return value of TTree::Process().
   //
   // The return value is currently not used.

   for (Int_t i=0; i < fNhist; i++) {
      if (fRandom && fHist[i]) {
         Double_t x = fRandom->Gaus(0.,1.);
         fHist[i]->Fill(x);
      }
   }
   for (Int_t i=0; i < fNhist3; i++) {
      if (fRandom && fHist3[i]) {
         Double_t x = fRandom->Gaus(0.,1.);
         fHist3[i]->Fill(x,x,x);
      }
   }
   if (fHLab && fRandom) {
      TSortedList sortl;
      Float_t rr[10];
      fRandom->RndmArray(10, rr);
      for (Int_t i=0; i < 10; i++) {
         sortl.Add(new TParameter<Int_t>(TString::Format("%f",rr[i]), i));
      }
      TIter nxe(&sortl);
      TParameter<Int_t> *pi = 0;
      while ((pi = (TParameter<Int_t> *) nxe())) {
         fHLab->Fill(TString::Format("hl%d", pi->GetVal()), pi->GetVal());
      }
   }
   if (fNtp) FillNtuple(entry);

   return kTRUE;
}

//_____________________________________________________________________________
void ProofSimple::FillNtuple(Long64_t entry)
{
   // The Process() function is called for each entry in the tree (or possibly
   // keyed object in the case of PROOF) to be processed. The entry argument
   // specifies which entry in the currently loaded tree is to be processed.
   // It can be passed to either ProofNtuple::GetEntry() or TBranch::GetEntry()
   // to read either all or the required parts of the data. When processing
   // keyed objects with PROOF, the object is already loaded and is available
   // via the fObject pointer.
   //
   // This function should contain the "body" of the analysis. It can contain
   // simple or elaborate selection criteria, run algorithms on the data
   // of the event and typically fill histograms.
   //
   // The processing can be stopped by calling Abort().
   //
   // Use fStatus to set the return value of TTree::Process().
   //
   // The return value is currently not used.

   if (!fNtp) return;

   // Fill ntuple
   Float_t px, py, random;
   if (fRandom) {
      fRandom->Rannor(px,py);
      random = fRandom->Rndm();
   } else {
      Abort("no way to get random numbers! Stop processing", kAbortProcess);
      return;
   }
   Float_t pz = px*px + py*py;
   Int_t i = (Int_t) entry;
   fNtp->Fill(px,py,pz,random,i);

   return;
}


//_____________________________________________________________________________
void ProofSimple::SlaveTerminate()
{
   // The SlaveTerminate() function is called after all entries or objects
   // have been processed. When running with PROOF SlaveTerminate() is called
   // on each slave server.

   // Write the ntuple to the file
   if (fFile) {
      if (!fNtp) {
         Error("SlaveTerminate", "'ntuple' is undefined!");
         return;
      }
      Bool_t cleanup = kFALSE;
      TDirectory *savedir = gDirectory;
      if (fNtp->GetEntries() > 0) {
         fFile->cd();
         fNtp->Write();
         fProofFile->Print();
         fOutput->Add(fProofFile);
      } else {
         cleanup = kTRUE;
      }
      fNtp->SetDirectory(0);
      gDirectory = savedir;
      fFile->Close();
      // Cleanup, if needed
      if (cleanup) {
         TUrl uf(*(fFile->GetEndpointUrl()));
         SafeDelete(fFile);
         gSystem->Unlink(uf.GetFile());
         SafeDelete(fProofFile);
      }
   }
}

//_____________________________________________________________________________
void ProofSimple::Terminate()
{
   // The Terminate() function is the last function to be called during
   // a query. It always runs on the client, it can be used to present
   // the results graphically or save the results to file.

   //
   // Create a canvas, with 100 pads
   //
   TCanvas *c1 = (TCanvas *) gDirectory->FindObject("c1");
   if (c1) {
      gDirectory->Remove(c1);
      delete c1;
   }
   c1 = new TCanvas("c1","Proof ProofSimple canvas",200,10,700,700);
   Int_t nside = (Int_t)TMath::Sqrt((Float_t)fNhist);
   nside = (nside*nside < fNhist) ? nside+1 : nside;
   c1->Divide(nside,nside,0,0);

   Bool_t tryfc = kFALSE;
   TH1F *h = 0;
   for (Int_t i=0; i < fNhist; i++) {
      if (!(h = dynamic_cast<TH1F *>(TProof::GetOutput(Form("h%d",i), fOutput)))) {
         // Not found: try TFileCollection
         tryfc = kTRUE;
         break;
      }
      c1->cd(i+1);
      h->DrawCopy();
   }

   // If the histograms are not found they may be in files: is there a file collection?
   if (tryfc && GetHistosFromFC(c1) != 0) {
      Warning("Terminate", "histograms not found");
   } else {
      // Final update
      c1->cd();
      c1->Update();
   }

   // Analyse hlab, if there
   if (fHLab && !gROOT->IsBatch()) {
      // Printout
      Int_t nb = fHLab->GetNbinsX();
      if (nb > 0) {
         Double_t entb = fHLab->GetEntries() / nb;
         if (entb) {
            for (Int_t i = 0; i < nb; i++) {
               TString lab = TString::Format("hl%d", i);
               Int_t ib = fHLab->GetXaxis()->FindBin(lab);
               Info("Terminate","  %s [%d]:\t%f", lab.Data(), ib, fHLab->GetBinContent(ib)/entb);
            }
         } else
            Warning("Terminate", "no entries in the hlab histogram!");
      }
   }

   // Process the ntuple, if required
   if (fHasNtuple != 1 || !fPlotNtuple) return;

   if (!(fNtp = dynamic_cast<TNtuple *>(TProof::GetOutput("ntuple", fOutput)))) {
      // Get the ntuple from the file
      if ((fProofFile =
            dynamic_cast<TProofOutputFile*>(fOutput->FindObject("SimpleNtuple.root")))) {

         TString outputFile(fProofFile->GetOutputFileName());
         TString outputName(fProofFile->GetName());
         outputName += ".root";
         Printf("outputFile: %s", outputFile.Data());

         // Read the ntuple from the file
         fFile = TFile::Open(outputFile);
         if (fFile) {
            Printf("Managed to open file: %s", outputFile.Data());
            fNtp = (TNtuple *) fFile->Get("ntuple");
         } else {
            Error("Terminate", "could not open file: %s", outputFile.Data());
         }
         if (!fFile) return;

      } else {
         Error("Terminate", "TProofOutputFile not found");
         return;
      }
   }
   // Plot ntuples
   if (fNtp) PlotNtuple(fNtp, "proof ntuple");
}

//_____________________________________________________________________________
void ProofSimple::PlotNtuple(TNtuple *ntp, const char *ntptitle)
{
   // Make some plots from the ntuple 'ntp'

   //
   // Create a canvas, with 2 pads
   //
   TCanvas *c1 = new TCanvas(Form("cv-%s", ntp->GetName()), ntptitle,800,10,700,780);
   c1->Divide(1,2);
   TPad *pad1 = (TPad *) c1->GetPad(1);
   TPad *pad2 = (TPad *) c1->GetPad(2);
   //
   // Display a function of one ntuple column imposing a condition
   // on another column.
   pad1->cd();
   pad1->SetGrid();
   pad1->SetLogy();
   pad1->GetFrame()->SetFillColor(15);
   ntp->SetLineColor(1);
   ntp->SetFillStyle(1001);
   ntp->SetFillColor(45);
   ntp->Draw("3*px+2","px**2+py**2>1");
   ntp->SetFillColor(38);
   ntp->Draw("2*px+2","pz>2","same");
   ntp->SetFillColor(5);
   ntp->Draw("1.3*px+2","(px^2+py^2>4) && py>0","same");
   pad1->RedrawAxis();

   //
   // Display a 3-D scatter plot of 3 columns. Superimpose a different selection.
   pad2->cd();
   ntp->Draw("pz:py:px","(pz<10 && pz>6)+(pz<4 && pz>3)");
   ntp->SetMarkerColor(4);
   ntp->Draw("pz:py:px","pz<6 && pz>4","same");
   ntp->SetMarkerColor(5);
   ntp->Draw("pz:py:px","pz<4 && pz>3","same");
   TPaveText *l2 = new TPaveText(0.,0.6,0.9,0.95);
   l2->SetFillColor(42);
   l2->SetTextAlign(12);
   l2->AddText("You can interactively rotate this view in 2 ways:");
   l2->AddText("  - With the RotateCube in clicking in this pad");
   l2->AddText("  - Selecting View with x3d in the View menu");
   l2->Draw();

   // Final update
   c1->cd();
   c1->Update();
}

//_____________________________________________________________________________
Int_t ProofSimple::GetHistosFromFC(TCanvas *cv)
{
   // Check for the histograms in the files of a possible TFileCollection

   TIter nxo(fOutput);
   TFileCollection *fc = 0;
   Bool_t fc_found = kFALSE, hs_found = kFALSE;
   while ((fc = (TFileCollection *) nxo())) {
      if (strcmp(fc->ClassName(), "TFileCollection")) continue;
      fc_found = kTRUE;
      if (!fHist) {
         fHist = new TH1F*[fNhist];
         for (Int_t i = 0; i < fNhist; i++) { fHist[i] = 0; }
      } else {
         for (Int_t i = 0; i < fNhist; i++) { SafeDelete(fHist[i]); }
      }
      // Go through the list of files
      TIter nxf(fc->GetList());
      TFileInfo *fi = 0;
      while ((fi = (TFileInfo *) nxf())) {
         TFile *f = TFile::Open(fi->GetCurrentUrl()->GetUrl());
         if (f) {
            for (Int_t i = 0; i < fNhist; i++) {
               TString hn = TString::Format("h%d", i);
               TH1F *h = (TH1F *) f->Get(hn);
               if (h) {
                  hs_found = kTRUE;
                  if (!fHist[i]) {
                     fHist[i] = (TH1F *) h->Clone();
                     fHist[i]->SetDirectory(0);
                  } else {
                     fHist[i]->Add(h);
                  }
               } else {
                  Error("GetHistosFromFC", "histo '%s' not found in file '%s'",
                        hn.Data(), fi->GetCurrentUrl()->GetUrl());
               }
            }
            f->Close();
         } else {
            Error("GetHistosFromFC", "file '%s' could not be open", fi->GetCurrentUrl()->GetUrl());
         }
      }
      if (hs_found) break;
   }
   if (!fc_found) return -1;
   if (!hs_found) return -1;

   for (Int_t i = 0; i < fNhist; i++) {
      cv->cd(i+1);
      if (fHist[i]) {
         fHist[i]->DrawCopy();
      }
   }
   Info("GetHistosFromFC", "histograms read from %d files in TFileCollection '%s'",
                           fc->GetList()->GetSize(), fc->GetName());
   // Done
   return 0;
}
 ProofSimple.C:1
 ProofSimple.C:2
 ProofSimple.C:3
 ProofSimple.C:4
 ProofSimple.C:5
 ProofSimple.C:6
 ProofSimple.C:7
 ProofSimple.C:8
 ProofSimple.C:9
 ProofSimple.C:10
 ProofSimple.C:11
 ProofSimple.C:12
 ProofSimple.C:13
 ProofSimple.C:14
 ProofSimple.C:15
 ProofSimple.C:16
 ProofSimple.C:17
 ProofSimple.C:18
 ProofSimple.C:19
 ProofSimple.C:20
 ProofSimple.C:21
 ProofSimple.C:22
 ProofSimple.C:23
 ProofSimple.C:24
 ProofSimple.C:25
 ProofSimple.C:26
 ProofSimple.C:27
 ProofSimple.C:28
 ProofSimple.C:29
 ProofSimple.C:30
 ProofSimple.C:31
 ProofSimple.C:32
 ProofSimple.C:33
 ProofSimple.C:34
 ProofSimple.C:35
 ProofSimple.C:36
 ProofSimple.C:37
 ProofSimple.C:38
 ProofSimple.C:39
 ProofSimple.C:40
 ProofSimple.C:41
 ProofSimple.C:42
 ProofSimple.C:43
 ProofSimple.C:44
 ProofSimple.C:45
 ProofSimple.C:46
 ProofSimple.C:47
 ProofSimple.C:48
 ProofSimple.C:49
 ProofSimple.C:50
 ProofSimple.C:51
 ProofSimple.C:52
 ProofSimple.C:53
 ProofSimple.C:54
 ProofSimple.C:55
 ProofSimple.C:56
 ProofSimple.C:57
 ProofSimple.C:58
 ProofSimple.C:59
 ProofSimple.C:60
 ProofSimple.C:61
 ProofSimple.C:62
 ProofSimple.C:63
 ProofSimple.C:64
 ProofSimple.C:65
 ProofSimple.C:66
 ProofSimple.C:67
 ProofSimple.C:68
 ProofSimple.C:69
 ProofSimple.C:70
 ProofSimple.C:71
 ProofSimple.C:72
 ProofSimple.C:73
 ProofSimple.C:74
 ProofSimple.C:75
 ProofSimple.C:76
 ProofSimple.C:77
 ProofSimple.C:78
 ProofSimple.C:79
 ProofSimple.C:80
 ProofSimple.C:81
 ProofSimple.C:82
 ProofSimple.C:83
 ProofSimple.C:84
 ProofSimple.C:85
 ProofSimple.C:86
 ProofSimple.C:87
 ProofSimple.C:88
 ProofSimple.C:89
 ProofSimple.C:90
 ProofSimple.C:91
 ProofSimple.C:92
 ProofSimple.C:93
 ProofSimple.C:94
 ProofSimple.C:95
 ProofSimple.C:96
 ProofSimple.C:97
 ProofSimple.C:98
 ProofSimple.C:99
 ProofSimple.C:100
 ProofSimple.C:101
 ProofSimple.C:102
 ProofSimple.C:103
 ProofSimple.C:104
 ProofSimple.C:105
 ProofSimple.C:106
 ProofSimple.C:107
 ProofSimple.C:108
 ProofSimple.C:109
 ProofSimple.C:110
 ProofSimple.C:111
 ProofSimple.C:112
 ProofSimple.C:113
 ProofSimple.C:114
 ProofSimple.C:115
 ProofSimple.C:116
 ProofSimple.C:117
 ProofSimple.C:118
 ProofSimple.C:119
 ProofSimple.C:120
 ProofSimple.C:121
 ProofSimple.C:122
 ProofSimple.C:123
 ProofSimple.C:124
 ProofSimple.C:125
 ProofSimple.C:126
 ProofSimple.C:127
 ProofSimple.C:128
 ProofSimple.C:129
 ProofSimple.C:130
 ProofSimple.C:131
 ProofSimple.C:132
 ProofSimple.C:133
 ProofSimple.C:134
 ProofSimple.C:135
 ProofSimple.C:136
 ProofSimple.C:137
 ProofSimple.C:138
 ProofSimple.C:139
 ProofSimple.C:140
 ProofSimple.C:141
 ProofSimple.C:142
 ProofSimple.C:143
 ProofSimple.C:144
 ProofSimple.C:145
 ProofSimple.C:146
 ProofSimple.C:147
 ProofSimple.C:148
 ProofSimple.C:149
 ProofSimple.C:150
 ProofSimple.C:151
 ProofSimple.C:152
 ProofSimple.C:153
 ProofSimple.C:154
 ProofSimple.C:155
 ProofSimple.C:156
 ProofSimple.C:157
 ProofSimple.C:158
 ProofSimple.C:159
 ProofSimple.C:160
 ProofSimple.C:161
 ProofSimple.C:162
 ProofSimple.C:163
 ProofSimple.C:164
 ProofSimple.C:165
 ProofSimple.C:166
 ProofSimple.C:167
 ProofSimple.C:168
 ProofSimple.C:169
 ProofSimple.C:170
 ProofSimple.C:171
 ProofSimple.C:172
 ProofSimple.C:173
 ProofSimple.C:174
 ProofSimple.C:175
 ProofSimple.C:176
 ProofSimple.C:177
 ProofSimple.C:178
 ProofSimple.C:179
 ProofSimple.C:180
 ProofSimple.C:181
 ProofSimple.C:182
 ProofSimple.C:183
 ProofSimple.C:184
 ProofSimple.C:185
 ProofSimple.C:186
 ProofSimple.C:187
 ProofSimple.C:188
 ProofSimple.C:189
 ProofSimple.C:190
 ProofSimple.C:191
 ProofSimple.C:192
 ProofSimple.C:193
 ProofSimple.C:194
 ProofSimple.C:195
 ProofSimple.C:196
 ProofSimple.C:197
 ProofSimple.C:198
 ProofSimple.C:199
 ProofSimple.C:200
 ProofSimple.C:201
 ProofSimple.C:202
 ProofSimple.C:203
 ProofSimple.C:204
 ProofSimple.C:205
 ProofSimple.C:206
 ProofSimple.C:207
 ProofSimple.C:208
 ProofSimple.C:209
 ProofSimple.C:210
 ProofSimple.C:211
 ProofSimple.C:212
 ProofSimple.C:213
 ProofSimple.C:214
 ProofSimple.C:215
 ProofSimple.C:216
 ProofSimple.C:217
 ProofSimple.C:218
 ProofSimple.C:219
 ProofSimple.C:220
 ProofSimple.C:221
 ProofSimple.C:222
 ProofSimple.C:223
 ProofSimple.C:224
 ProofSimple.C:225
 ProofSimple.C:226
 ProofSimple.C:227
 ProofSimple.C:228
 ProofSimple.C:229
 ProofSimple.C:230
 ProofSimple.C:231
 ProofSimple.C:232
 ProofSimple.C:233
 ProofSimple.C:234
 ProofSimple.C:235
 ProofSimple.C:236
 ProofSimple.C:237
 ProofSimple.C:238
 ProofSimple.C:239
 ProofSimple.C:240
 ProofSimple.C:241
 ProofSimple.C:242
 ProofSimple.C:243
 ProofSimple.C:244
 ProofSimple.C:245
 ProofSimple.C:246
 ProofSimple.C:247
 ProofSimple.C:248
 ProofSimple.C:249
 ProofSimple.C:250
 ProofSimple.C:251
 ProofSimple.C:252
 ProofSimple.C:253
 ProofSimple.C:254
 ProofSimple.C:255
 ProofSimple.C:256
 ProofSimple.C:257
 ProofSimple.C:258
 ProofSimple.C:259
 ProofSimple.C:260
 ProofSimple.C:261
 ProofSimple.C:262
 ProofSimple.C:263
 ProofSimple.C:264
 ProofSimple.C:265
 ProofSimple.C:266
 ProofSimple.C:267
 ProofSimple.C:268
 ProofSimple.C:269
 ProofSimple.C:270
 ProofSimple.C:271
 ProofSimple.C:272
 ProofSimple.C:273
 ProofSimple.C:274
 ProofSimple.C:275
 ProofSimple.C:276
 ProofSimple.C:277
 ProofSimple.C:278
 ProofSimple.C:279
 ProofSimple.C:280
 ProofSimple.C:281
 ProofSimple.C:282
 ProofSimple.C:283
 ProofSimple.C:284
 ProofSimple.C:285
 ProofSimple.C:286
 ProofSimple.C:287
 ProofSimple.C:288
 ProofSimple.C:289
 ProofSimple.C:290
 ProofSimple.C:291
 ProofSimple.C:292
 ProofSimple.C:293
 ProofSimple.C:294
 ProofSimple.C:295
 ProofSimple.C:296
 ProofSimple.C:297
 ProofSimple.C:298
 ProofSimple.C:299
 ProofSimple.C:300
 ProofSimple.C:301
 ProofSimple.C:302
 ProofSimple.C:303
 ProofSimple.C:304
 ProofSimple.C:305
 ProofSimple.C:306
 ProofSimple.C:307
 ProofSimple.C:308
 ProofSimple.C:309
 ProofSimple.C:310
 ProofSimple.C:311
 ProofSimple.C:312
 ProofSimple.C:313
 ProofSimple.C:314
 ProofSimple.C:315
 ProofSimple.C:316
 ProofSimple.C:317
 ProofSimple.C:318
 ProofSimple.C:319
 ProofSimple.C:320
 ProofSimple.C:321
 ProofSimple.C:322
 ProofSimple.C:323
 ProofSimple.C:324
 ProofSimple.C:325
 ProofSimple.C:326
 ProofSimple.C:327
 ProofSimple.C:328
 ProofSimple.C:329
 ProofSimple.C:330
 ProofSimple.C:331
 ProofSimple.C:332
 ProofSimple.C:333
 ProofSimple.C:334
 ProofSimple.C:335
 ProofSimple.C:336
 ProofSimple.C:337
 ProofSimple.C:338
 ProofSimple.C:339
 ProofSimple.C:340
 ProofSimple.C:341
 ProofSimple.C:342
 ProofSimple.C:343
 ProofSimple.C:344
 ProofSimple.C:345
 ProofSimple.C:346
 ProofSimple.C:347
 ProofSimple.C:348
 ProofSimple.C:349
 ProofSimple.C:350
 ProofSimple.C:351
 ProofSimple.C:352
 ProofSimple.C:353
 ProofSimple.C:354
 ProofSimple.C:355
 ProofSimple.C:356
 ProofSimple.C:357
 ProofSimple.C:358
 ProofSimple.C:359
 ProofSimple.C:360
 ProofSimple.C:361
 ProofSimple.C:362
 ProofSimple.C:363
 ProofSimple.C:364
 ProofSimple.C:365
 ProofSimple.C:366
 ProofSimple.C:367
 ProofSimple.C:368
 ProofSimple.C:369
 ProofSimple.C:370
 ProofSimple.C:371
 ProofSimple.C:372
 ProofSimple.C:373
 ProofSimple.C:374
 ProofSimple.C:375
 ProofSimple.C:376
 ProofSimple.C:377
 ProofSimple.C:378
 ProofSimple.C:379
 ProofSimple.C:380
 ProofSimple.C:381
 ProofSimple.C:382
 ProofSimple.C:383
 ProofSimple.C:384
 ProofSimple.C:385
 ProofSimple.C:386
 ProofSimple.C:387
 ProofSimple.C:388
 ProofSimple.C:389
 ProofSimple.C:390
 ProofSimple.C:391
 ProofSimple.C:392
 ProofSimple.C:393
 ProofSimple.C:394
 ProofSimple.C:395
 ProofSimple.C:396
 ProofSimple.C:397
 ProofSimple.C:398
 ProofSimple.C:399
 ProofSimple.C:400
 ProofSimple.C:401
 ProofSimple.C:402
 ProofSimple.C:403
 ProofSimple.C:404
 ProofSimple.C:405
 ProofSimple.C:406
 ProofSimple.C:407
 ProofSimple.C:408
 ProofSimple.C:409
 ProofSimple.C:410
 ProofSimple.C:411
 ProofSimple.C:412
 ProofSimple.C:413
 ProofSimple.C:414
 ProofSimple.C:415
 ProofSimple.C:416
 ProofSimple.C:417
 ProofSimple.C:418
 ProofSimple.C:419
 ProofSimple.C:420
 ProofSimple.C:421
 ProofSimple.C:422
 ProofSimple.C:423
 ProofSimple.C:424
 ProofSimple.C:425
 ProofSimple.C:426
 ProofSimple.C:427
 ProofSimple.C:428
 ProofSimple.C:429
 ProofSimple.C:430
 ProofSimple.C:431
 ProofSimple.C:432
 ProofSimple.C:433
 ProofSimple.C:434
 ProofSimple.C:435
 ProofSimple.C:436
 ProofSimple.C:437
 ProofSimple.C:438
 ProofSimple.C:439
 ProofSimple.C:440
 ProofSimple.C:441
 ProofSimple.C:442
 ProofSimple.C:443
 ProofSimple.C:444
 ProofSimple.C:445
 ProofSimple.C:446
 ProofSimple.C:447
 ProofSimple.C:448
 ProofSimple.C:449
 ProofSimple.C:450
 ProofSimple.C:451
 ProofSimple.C:452
 ProofSimple.C:453
 ProofSimple.C:454
 ProofSimple.C:455
 ProofSimple.C:456
 ProofSimple.C:457
 ProofSimple.C:458
 ProofSimple.C:459
 ProofSimple.C:460
 ProofSimple.C:461
 ProofSimple.C:462
 ProofSimple.C:463
 ProofSimple.C:464
 ProofSimple.C:465
 ProofSimple.C:466
 ProofSimple.C:467
 ProofSimple.C:468
 ProofSimple.C:469
 ProofSimple.C:470
 ProofSimple.C:471
 ProofSimple.C:472
 ProofSimple.C:473
 ProofSimple.C:474
 ProofSimple.C:475
 ProofSimple.C:476
 ProofSimple.C:477
 ProofSimple.C:478
 ProofSimple.C:479
 ProofSimple.C:480
 ProofSimple.C:481
 ProofSimple.C:482
 ProofSimple.C:483
 ProofSimple.C:484
 ProofSimple.C:485
 ProofSimple.C:486
 ProofSimple.C:487
 ProofSimple.C:488
 ProofSimple.C:489
 ProofSimple.C:490
 ProofSimple.C:491
 ProofSimple.C:492
 ProofSimple.C:493
 ProofSimple.C:494
 ProofSimple.C:495
 ProofSimple.C:496
 ProofSimple.C:497
 ProofSimple.C:498
 ProofSimple.C:499
 ProofSimple.C:500
 ProofSimple.C:501
 ProofSimple.C:502
 ProofSimple.C:503
 ProofSimple.C:504
 ProofSimple.C:505
 ProofSimple.C:506
 ProofSimple.C:507
 ProofSimple.C:508
 ProofSimple.C:509
 ProofSimple.C:510
 ProofSimple.C:511
 ProofSimple.C:512
 ProofSimple.C:513
 ProofSimple.C:514
 ProofSimple.C:515
 ProofSimple.C:516
 ProofSimple.C:517
 ProofSimple.C:518
 ProofSimple.C:519
 ProofSimple.C:520
 ProofSimple.C:521
 ProofSimple.C:522
 ProofSimple.C:523
 ProofSimple.C:524
 ProofSimple.C:525
 ProofSimple.C:526
 ProofSimple.C:527
 ProofSimple.C:528
 ProofSimple.C:529
 ProofSimple.C:530
 ProofSimple.C:531
 ProofSimple.C:532
 ProofSimple.C:533
 ProofSimple.C:534
 ProofSimple.C:535
 ProofSimple.C:536
 ProofSimple.C:537
 ProofSimple.C:538
 ProofSimple.C:539
 ProofSimple.C:540
 ProofSimple.C:541
 ProofSimple.C:542
 ProofSimple.C:543
 ProofSimple.C:544
 ProofSimple.C:545
 ProofSimple.C:546
 ProofSimple.C:547
 ProofSimple.C:548
 ProofSimple.C:549
 ProofSimple.C:550
 ProofSimple.C:551
 ProofSimple.C:552
 ProofSimple.C:553
 ProofSimple.C:554
 ProofSimple.C:555
 ProofSimple.C:556
 ProofSimple.C:557
 ProofSimple.C:558
 ProofSimple.C:559
 ProofSimple.C:560
 ProofSimple.C:561
 ProofSimple.C:562
 ProofSimple.C:563
 ProofSimple.C:564
 ProofSimple.C:565
 ProofSimple.C:566
 ProofSimple.C:567
 ProofSimple.C:568
 ProofSimple.C:569
 ProofSimple.C:570
 ProofSimple.C:571
 ProofSimple.C:572
 ProofSimple.C:573
 ProofSimple.C:574
 ProofSimple.C:575
 ProofSimple.C:576
 ProofSimple.C:577
 ProofSimple.C:578
 ProofSimple.C:579
 ProofSimple.C:580
 ProofSimple.C:581
 ProofSimple.C:582
 ProofSimple.C:583
 ProofSimple.C:584
 ProofSimple.C:585
 ProofSimple.C:586
 ProofSimple.C:587
 ProofSimple.C:588
 ProofSimple.C:589
 ProofSimple.C:590
 ProofSimple.C:591
 ProofSimple.C:592
 ProofSimple.C:593
 ProofSimple.C:594
 ProofSimple.C:595
 ProofSimple.C:596
 ProofSimple.C:597
 ProofSimple.C:598
 ProofSimple.C:599
 ProofSimple.C:600
 ProofSimple.C:601
 ProofSimple.C:602
 ProofSimple.C:603
 ProofSimple.C:604