//____________________________________________________________________
//
// Abstract analysis task
// 
//
// Batch job submission (at HU cluster):
// =====================================
//
// There are three types of batch job submission:
//
// 1. Run on all nodes: SetBatchNodeAll(kTRUE) The jobs are submitted
// to all free nodes.
//
// 2. Run on specific node: SetBatchNode(node) You can specify the
// node the job is submitted to (eg "ms01b"). Opens a window in
// TBrowser where you can enter the node name.
//
// 3. Automatic job submission: SetBatchNodeAutomatic(kTRUE) Sets node
// automatically, regarding the machine the sample files are saved on.
//
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// !!!!                                                                     !!!!
// !!!! Important note                                                      !!!!
// !!!!                                                                     !!!!
// !!!! The last case is the default and should never be changed. Otherwise !!!!
// !!!! the data will be transferred via the network file system (NFS) from !!!!
// !!!! the computer containing the data disk to the batch node in question !!!!
// !!!! This will put a heavy load both on the network and the NFS server   !!!!
// !!!! machine which causes heavy performance losses of the whole system   !!!!
// !!!! affecting all users.                                                !!!!
// !!!!                                                                     !!!!
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//
//  
// Author: Oliver Maria Kind <mailto: kind@mail.desy.de>
// Update: $Id: AtlTask.cxx,v 1.42 2017/08/08 11:35:19 kaphle Exp $
// Copyright: 2009 (C) Oliver Maria Kind
//
#ifndef ATLAS_AtlTask
#include <AtlTask.h>
#endif
#include <TObjString.h>
#include <TString.h>
#include <TList.h>
#include <TSystem.h>
#include <iostream>
#include <TDirectory.h>
#include <TDirectoryFile.h>
#include <TKey.h>
#include <TH1F.h>
#include <TH1D.h>
#include <TH2F.h>
#include <TH2D.h>

using namespace std;

#ifndef __CINT__
ClassImp(AtlTask);
#endif

//____________________________________________________________________

AtlTask::AtlTask(const char* name, const char* title) :
    TTask(name, title) {
    //
    // Default constructor
    //
    fInputFiles = new TList;
    fInputEntryLists = new TList;
    SetBatchJob(kTRUE);
    fOutputFileName = 0;
    fOutputTreeName = 0;
    fNEvents = 0;
    fFirstEntry = 0;
    fIsTest = kFALSE;
    fJobHome     = 0;
    fLogFilePath = 0;
    fRunScript   = 0;
    fTempLogFilePath = 0;
    fTempOutputPath  = 0;
    fTempOutputFileName = 0;
    fBatchNodeAll = kFALSE;
    fBatchNodeAutomatic = kTRUE;
    fBatchNode = "ms01b";
    fGridRootVersion = 0;
    fGridCmtVersion  = 0;
    fGridUserName    = 0;
    fGridSuffix      = 0;
    fDebug           = 0;
    fDebugBuild      = 0;
}

//____________________________________________________________________

AtlTask::~AtlTask() {
    //
    // Default destructor
    //
    fInputFiles->Delete(); delete fInputFiles;
    if ( fOutputFileName  != 0 ) delete fOutputFileName;
    if ( fOutputTreeName  != 0 ) delete fOutputTreeName;
    if ( fJobHome         != 0 ) delete fJobHome;
    if ( fLogFilePath     != 0 ) delete fLogFilePath;
    if ( fRunScript       != 0 ) delete fRunScript;
    if ( fTempLogFilePath != 0 ) delete fTempLogFilePath;
    if ( fTempOutputPath  != 0 ) delete fTempOutputPath;
    if ( fTempOutputFileName != 0 ) delete fTempOutputFileName;
    if ( fGridRootVersion != 0 ) delete fGridRootVersion;
    if ( fGridCmtVersion  != 0 ) delete fGridCmtVersion; 
    if ( fGridUserName    != 0 ) delete fGridUserName;
    if ( fGridSuffix      != 0 ) delete fGridSuffix;
}

//____________________________________________________________________

void AtlTask::AddInputFiles(const char* InputFiles) {
    //
    // Add files to input chain (wildcards allowed)
    //
    TObjString *item = new TObjString(InputFiles);
    fInputFiles->Add(item);
}

//____________________________________________________________________

void AtlTask::AddInputEntryLists(const char* InputFile) {
    //
    // Add files to input entrylists
    //
    
    TObjString *item = new TObjString(InputFile);
    fInputEntryLists->Add(item);
}

//____________________________________________________________________

void AtlTask::SetOutputFile(const char* OutputFile) {
    //
    // Set output file name
    //
    fOutputFileName = new TString(OutputFile);
}

//____________________________________________________________________

void AtlTask::SetTempOutputFile(const char* OutputFile) {
    //
    // Set temporarily output file name during batch job
    //
    fTempOutputFileName = new TString(OutputFile);
}

//____________________________________________________________________

void AtlTask::SetInteractiveJob(Bool_t InteractiveJob) {
    //
    // Set execution mode to interactive
    // Switch off writing to logfile
    //
    fInteractiveJob =  InteractiveJob;
    fBatchJob       = !InteractiveJob;
    fNAFBatchJob    = !InteractiveJob;
    fGridJob        = !InteractiveJob;
    SetLogFile(kFALSE);
}

//____________________________________________________________________

void AtlTask::SetBatchJob(Bool_t BatchJob) {
    //
    // Set execution mode to batch job
    // Switch on writing to logfile
    //
    fBatchJob       =  BatchJob;
    fNAFBatchJob    = !BatchJob;
    fInteractiveJob = !BatchJob;
    fGridJob        = !BatchJob;
    SetLogFile(kTRUE);
}

//____________________________________________________________________

void AtlTask::SetNAFBatchJob(Bool_t NAFBatchJob) {
    //
    // Set execution mode to batch job
    // Switch on writing to logfile
    //
    fNAFBatchJob    =  NAFBatchJob;
    fBatchJob       = !NAFBatchJob;
    fInteractiveJob = !NAFBatchJob;
    fGridJob        = !NAFBatchJob;
    SetLogFile(kTRUE);
}

//____________________________________________________________________

void AtlTask::SetGridJob(Bool_t GridJob) {
    //
    // Set execution mode to Grid job
    // Switch on writing to logfile
    //

    fGridJob        =  GridJob;
    fInteractiveJob = !GridJob;
    fBatchJob       = !GridJob;
    fNAFBatchJob    = !GridJob;
    SetLogFile(kTRUE);
}

//____________________________________________________________________

void AtlTask::SetOutputTree(const char* name, const char* title) {
    //
    // Set name and title of the output tree
    //
    if ( fOutputTreeName ==  0 ) {
	fOutputTreeName = new TNamed(name, title);
    } else{
	fOutputTreeName->SetNameTitle(name, title);
    }
}

//____________________________________________________________________

void AtlTask::SetBatchNodeAutomatic(Bool_t BatchNodeAutomatic) {
    //
    // Submit job to automatically set node
    //
    fBatchNodeAutomatic   = BatchNodeAutomatic;
    fBatchNodeAll = !BatchNodeAutomatic;
}

//____________________________________________________________________

void AtlTask::SetBatchNodeAll(Bool_t BatchNodeAll) {
    //
    // Submit job to all nodes
    //
    fBatchNodeAll         = BatchNodeAll;
    fBatchNodeAutomatic   = !BatchNodeAll;
}

//____________________________________________________________________

void AtlTask::SetBatchNode(const char* BatchNode)  {
  //
  // Set batch node (eg. "ms01b")
  //
  if( strcmp(BatchNode,"ms01b") != 0 && 
      strcmp(BatchNode,"ms02b") != 0 && 
      strcmp(BatchNode,"ms03b") != 0 &&
      strcmp(BatchNode,"ms04b") != 0 && 
      strcmp(BatchNode,"ms05b") != 0 &&
      strcmp(BatchNode,"ms06b") != 0 &&
      strcmp(BatchNode,"ms07b") != 0 &&
      strcmp(BatchNode,"ms08b") != 0 &&
      strcmp(BatchNode,"as01b") != 0 &&
      strcmp(BatchNode,"as02b") != 0 &&
      strcmp(BatchNode,"as03b") != 0 &&
      strcmp(BatchNode,"as04b") != 0 &&
      strcmp(BatchNode,"as05b") != 0 &&
      strcmp(BatchNode,"as06b") != 0 &&
      strcmp(BatchNode,"as07b") != 0 &&
      strcmp(BatchNode,"as08b") != 0 &&
      strcmp(BatchNode,"as21b") != 0 &&
      strcmp(BatchNode,"as22b") != 0 &&
      strcmp(BatchNode,"as23b") != 0 &&
      strcmp(BatchNode,"as24b") != 0 &&
      strcmp(BatchNode,"as25b") != 0 &&
      strcmp(BatchNode,"as26b") != 0 &&
      strcmp(BatchNode,"as27b") != 0 &&
      strcmp(BatchNode,"as28b") != 0 )  {
    Error("SetBatchNode", "Invalid node given. Node not set.");
  } 
  fBatchNodeAll = kFALSE;
  fBatchNodeAutomatic = kFALSE;
  fBatchNode = BatchNode;
}

//____________________________________________________________________

Char_t AtlTask::GetBatchNodeFromPath(const char* path) {
    //
    // Extract batch node from path name (usually of input filenames)
    // Jobs should run on the node where the input data resides to
    // minimise network traffic. The data disks at the HU cluster are
    // labelled /datm1, /datm2, /datm3, /dats1 etc, w.r.t. the machine name.
    // If the node name cannot be found '1' will be returned
    //
    TString path_str(path);
    if ( (path_str.Index("/datm") == 0) ||
	 (path_str.Index("/dats") == 0) ) return path_str(5);
    return '1';
}

//____________________________________________________________________

void AtlTask::Exec(Option_t *option) {
    //
    // Task execution
    //
    // Options available:
    //  "test" - run in test modus: process 1000 events only
    //           and append _test to the output filename
    //
    cout << endl;
    Info("Exec", "Task \"%s\" started", GetName());

    Bool_t success = kTRUE;

    TString opt = option;
    opt.ToLower();
    if ( opt.Contains("test") ) {
	fIsTest = kTRUE;
	fNEvents = 1000;
    }

    // Create paths
    CreateJobHome();
    if ( !fGridJob ) CreateLogFilePath();
    if ( !fGridJob ) CreateOutFilePath();
    
    // Start job
    if ( fInteractiveJob ) {
	// ================
	// Interactive mode
	// ================
	ExecInteractiveJob(option);
    } else if ( fBatchJob ) {
	// ===============
	// Batch execution
	// ===============
	CreateRunScriptPath();
	CreateRunScript();
	success = ExecBatchJob(option);
    } else if ( fGridJob ) {
	// ==================
	// Grid job execution
	// ==================
	CreateRunScriptPath();
	ExecGridJob(option);
    } else if ( fNAFBatchJob ) {
	// ===================
	// NAF Batch execution
	// ===================
	CreateRunScriptPath();
	CreateNAFBatchRunScript();
	ExecNAFBatchJob(option);
    } 

    if (success) Info("Exec", "Task \"%s\" finished", GetName());
    else Error("Exec", "Task \"%s\" execution failed.", GetName());
    cout << endl;
}

//____________________________________________________________________

void AtlTask::SetJobHome(const char* JobHome) {
    //
    // Set working directory for the job.
    //
    if ( fJobHome != 0 ) delete fJobHome;
    fJobHome = new TString(JobHome);
}

//____________________________________________________________________

void AtlTask::CreateJobHome() {
    //
    // Create working directory for this job (for log files etc) In
    // case no directory was given so far by SetJobHome() create a
    // directory with the job's name in the current working directory
    //
    if ( fJobHome == 0 ) {
	if ( fGridJob ) {
	    fJobHome = new TString(gSystem->ExpandPathName("$GRID_HOME/submitscripts"));
	} else {
	    fJobHome = new TString(gSystem->pwd());
	}
	fJobHome->Append("/");
	fJobHome->Append(GetName());
    }
    
    Info("CreateJobHome", "Create job working directory\n%s",
	 fJobHome->Data());
    gSystem->Exec(Form("rm -fr %s", fJobHome->Data()));
    gSystem->Exec(Form("mkdir -p %s", fJobHome->Data()));
}

//____________________________________________________________________

void AtlTask::CreateRunScriptPath() {
    //
    // Create full path to the runscript used for batch job submission
    //
    if ( fRunScript != 0 ) {
	delete fRunScript; fRunScript = 0;
    }
    fRunScript = new TString(fJobHome->Data());
    fRunScript->Append("/");
    fRunScript->Append(GetName());
    fRunScript->Append(".run");
    fRunScript->ReplaceAll("//", 2, "/", 1);
}

//____________________________________________________________________

void AtlTask::CreateLogFilePath() {
    //
    // Create full path to the logfile
    //
    if ( fOutputFileName == 0 ) {
      Error("CreateLogFilePath", "No output filename given for this task \"%s\". Abort!",
	    GetName());
       gSystem->Abort(0);
    }

    if ( fLogFilePath != 0 ) { delete fLogFilePath; fLogFilePath = 0; }
    fLogFilePath = new TString(fJobHome->Data());
    fLogFilePath->Append("/");
    fLogFilePath->Append(gSystem->BaseName(fOutputFileName->Data()));
    fLogFilePath->ReplaceAll(".root", 5, ".log", 4);
    fLogFilePath->ReplaceAll("//", 2, "/", 1);

    if ( fTempOutputPath != 0 && fTempOutputPath->BeginsWith("/") ) {
	fTempLogFilePath = new TString(fTempOutputPath->Data());
	fTempLogFilePath->Append("/");
	fTempLogFilePath->Append(gSystem->BaseName(fOutputFileName->Data()));
	fTempLogFilePath->ReplaceAll(".root", 5, ".log", 4);
	fTempLogFilePath->ReplaceAll("//", 2, "/", 1);
    }
}

//____________________________________________________________________

void AtlTask::CreateOutFilePath() {
    //
    // Create path to the output file(s).  In case the already given
    // outfile name is absolute (ie starts with'/') do nothing.
    // Otherwise prepend the JobHome path
    //
    TString expd_name(gSystem->ExpandPathName(fOutputFileName->Data()));
    if ( !expd_name.BeginsWith("/") ) {
	fOutputFileName->Prepend("/");
	fOutputFileName->Prepend(fJobHome->Data());
    }
    if ( fIsTest ) {
	fOutputFileName->Append("_test");
    }
    Info("CreateOutFilePath", "Create outfile path:\n%s",
	 gSystem->DirName(fOutputFileName->Data()));
    gSystem->Exec(Form("mkdir -p %s",  gSystem->DirName(fOutputFileName->Data())));
}

//____________________________________________________________________

Bool_t AtlTask::SubmitBatchJob() {
    //
    // Batch job submission If no node had been specified it is tried
    // to guess the node name from the input file list
    //
    // Returns kFALSE in case of error in batch job submission
    //
    TString jobsub_cmd("qsub ");
    TString expd_outfile(gSystem->ExpandPathName(fOutputFileName->Data()));
    TString expd_infile;
    if ( fInputFiles->GetEntries() > 0 )
	expd_infile = TString(gSystem->ExpandPathName(((TObjString*)fInputFiles
						       ->At(0))->GetString()));

    TString host2(gSystem->HostName());
    if ( host2.Contains("lx") ) {
      jobsub_cmd.Append(" -o /dev/null -j y "); // redirect std output and std error to black hole
      jobsub_cmd.Append(fRunScript->Data());
    } else { 
	if ( fBatchNodeAll ) {
	  jobsub_cmd.Append(" ");
	} else if ( fBatchNodeAutomatic  ) {
	  if ( expd_infile.Index("/rdsk/datm") == 0 ) {
	    jobsub_cmd.Append("-l nodes=ms0");
	    jobsub_cmd.Append(expd_infile(10));
	    jobsub_cmd.Append("b ");
	  }
	  if ( expd_infile.Index("/rdsk/dats") == 0 ) {
	    jobsub_cmd.Append("-l nodes=as0");
	    jobsub_cmd.Append(expd_infile(10));
	    jobsub_cmd.Append("b ");
	  }
	} else {
	  jobsub_cmd.Append("-l nodes=");
	  jobsub_cmd.Append(fBatchNode);
	  jobsub_cmd.Append(" ");
	}
	jobsub_cmd.Append(" -o /dev/null -j oe "); // redirect std output and std error to black hole
	jobsub_cmd.Append(fRunScript->Data());

	// Check for correct submission machine
	TString host(gSystem->HostName());
	host.Remove(3);
	host.Prepend("nodes=");
	if ( !jobsub_cmd.Contains(host) && !fBatchNodeAll) {
	  Error("SubmitBatchJob", "Submission from this machine to desired queue impossible.\nNote that the batch systems on the ms0Xb and as0Xb machines are separated and you cannot submit jobs from one system to the other or vice versa. Either switch to the other system for submission (make sure everything is compiled and linked on that platform), or set a node of the system you are working on explicitly.");
	  return kFALSE;
	}
    }
    Info("SubmitBatchJob", "Execute %s", jobsub_cmd.Data());
    gSystem->Exec(jobsub_cmd.Data());

    // Sleep for 2 sec to avoid overloading the batch system when
    // submitting huge numbers of jobs
    if ( ! host2.Contains("lx") ) {    
      gSystem->Sleep(2000);
    }
    
    return kTRUE;
}

//____________________________________________________________________

void AtlTask::SubmitNAFBatchJob() {
    //
    // Batch job submission If no node had been specified it is tried
    // to guess the node name from the input file list
    //
    TString jobsub_cmd("qsub ");
    TString expd_outfile(gSystem->ExpandPathName(fOutputFileName->Data()));
    TString expd_infile(gSystem->ExpandPathName(((TObjString*)fInputFiles
						 ->At(0))->GetString()));
    
    jobsub_cmd.Append(fRunScript->Data());
    Info("SubmitBatchJob", "Execute %s", jobsub_cmd.Data());
    gSystem->Exec(jobsub_cmd.Data());
}

//____________________________________________________________________

void AtlTask::SubmitGridJob() {
    //
    // Grid job submission 
    //
    TString jobsub_cmd("source "); 
    jobsub_cmd.Append(GetName());
    jobsub_cmd.Append(".run");
    Info("SubmitGridJob", "Execute %s", jobsub_cmd.Data());
    gSystem->ChangeDirectory(gSystem->ExpandPathName("$GRID_HOME"));
    gSystem->Exec(jobsub_cmd.Data());
}

//____________________________________________________________________

void AtlTask::SetTempOutputPath(const char* OutputPath) {
    //
    // Set temporarily output path for local HU batch system
    //
    
    // If you use this, make sure your outfile name is a relative one
    fTempOutputPath = new TString(OutputPath);
}

//____________________________________________________________________

void AtlTask::CopyFolder(TDirectory *SrcDir, TDirectory *DestDir,
			 Float_t scale) {
    //
    // Recursively copying of the content (histograms, subfolders) of the given source
    // directory to the destination folder.
    // All histograms will be scaled by the given factor.
    //
    
    // Search source content
    SrcDir->cd();
    
    TIter next_key(SrcDir->GetListOfKeys());
    TKey *key = 0;
    while ( (key = (TKey*)next_key()) ) {
	if ( strcmp(key->GetClassName(), "TDirectoryFile") == 0 ) {
	    TDirectory *NewSrcDir = (TDirectoryFile*)key->ReadObj();
 	    DestDir->cd();
 	    TDirectory *NewDestDir = DestDir->mkdir(key->GetName());
	    CopyFolder(NewSrcDir, NewDestDir, scale);
	} else if ( (strcmp(key->GetClassName(), "TH1F") == 0) ) {
	    DestDir->cd();
	    TH1F *h1f = (TH1F*)key->ReadObj()->Clone();
	    h1f->SetDirectory(DestDir);
	    h1f->Scale(scale);
	} else if ( (strcmp(key->GetClassName(), "TH1D") == 0) ) {
	    DestDir->cd();
	    TH1D *h1d = (TH1D*)key->ReadObj()->Clone();
	    h1d->SetDirectory(DestDir);
	    h1d->Scale(scale);
	} else if ( (strcmp(key->GetClassName(), "TH2F") == 0) ) {
	    DestDir->cd();
	    TH2F *h2f = (TH2F*)key->ReadObj()->Clone();
	    h2f->SetDirectory(DestDir);
	    h2f->Scale(scale);
	} else if ( (strcmp(key->GetClassName(), "TH2D") == 0) ) {
	    DestDir->cd();
	    TH2D *h2d = (TH2D*)key->ReadObj()->Clone();
	    h2d->SetDirectory(DestDir);
	    h2d->Scale(scale);
	}
    }
}

//____________________________________________________________________

void AtlTask::SetGridRootVersion(const char* RootVersion) {
    //
    // Set grid root version
    //
    if ( fGridRootVersion != 0 ) delete fGridRootVersion;
    fGridRootVersion = new TString(RootVersion);
}

//____________________________________________________________________

void AtlTask::SetGridCmtVersion(const char* CmtVersion) {
    //
    // Set grid cmt version
    //
    if ( fGridCmtVersion != 0 ) delete fGridCmtVersion;
    fGridCmtVersion = new TString(CmtVersion);
}

//____________________________________________________________________

void AtlTask::SetGridUserName(const char* UserName) {
    //
    // Set grid root version
    //
    if ( fGridUserName != 0 ) delete fGridUserName;
    fGridUserName = new TString(UserName);
}

//____________________________________________________________________

void AtlTask::SetGridSuffix(const char* Suffix) {
    //
    // Set grid root version
    //
    if ( fGridSuffix != 0 ) delete fGridSuffix;
    fGridSuffix = new TString(Suffix);
}

//____________________________________________________________________

Bool_t AtlTask::WriteEnvSetup(std::ofstream & out) const {
    //
    // Generates the shell command(s) that set up the current A++/ROOT/... environment.
    // Returns kFALSE if it's not known how to set up the environment.
    //
    char const * appSetupScriptPath = gSystem->Getenv("APLUSPLUS_SETUP");
    if ( !appSetupScriptPath )
        return kFALSE;

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