17-jun-2005 NvE New class AliJob introduced to provide a flexible (physics) analysis...
authornick <nick@f7af4fe6-9843-0410-8265-dc069ae4e863>
Fri, 17 Jun 2005 04:22:57 +0000 (04:22 +0000)
committernick <nick@f7af4fe6-9843-0410-8265-dc069ae4e863>
Fri, 17 Jun 2005 04:22:57 +0000 (04:22 +0000)
                Bug (forgotten ps transfer in AliTimestamp::SetTJD) fixed (thanks Federico Carminati).
17-jun-2005 NvE Class IceF2k modified to provide a task-based processing environment.
                For this IceF2k has been derived from the new RALICE class AliJob.
                The example macro icef2k.cc has been updated accordingly.

RALICE/AliJob.cxx [new file with mode: 0644]
RALICE/AliJob.h [new file with mode: 0644]
RALICE/AliTimestamp.cxx
RALICE/RALICEHeaders.h
RALICE/RALICELinkDef.h
RALICE/history.txt
RALICE/icepack/iceconvert/IceF2k.cxx
RALICE/icepack/iceconvert/IceF2k.h
RALICE/icepack/iceconvert/history.txt
RALICE/icepack/iceconvert/macros/icef2k.cc
RALICE/libRALICE.pkg

diff --git a/RALICE/AliJob.cxx b/RALICE/AliJob.cxx
new file mode 100644 (file)
index 0000000..08e928f
--- /dev/null
@@ -0,0 +1,331 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+// $Id$
+
+///////////////////////////////////////////////////////////////////////////
+// Class AliJob
+// Base class for the top level processor class in a task based procedure.
+// It allows stepwise invokation of various sub-tasks by the derived
+// (user defined) top level processor, based on looping over a certain
+// main object structure (e.g. AliEvent for event-by-event processing).
+// The main object structure (if needed) may be specified by the derived
+// top level processor class and will be stored automatically in the
+// working environment (see below).  
+// This base class provides a working environment for the derived
+// (user defined) processor class and all of its subtasks.
+//
+// The working environment consists of (a.o.) :
+// * A folder which may serve as a whiteboard for transferring pointers to
+//   objects which are posted there by the top level processor or any
+//   of its subtasks.
+//   Objects can be posted in the job folder via the AddObject() facility
+//   of this AliJob class.
+//   Access to the job folder is obtained via the GetFolder() memberfunction
+//   and from this the various objects can be accessed via the usual TFolder
+//   FindObject and/or iterator facilities.
+// * An array containing pointers to the objects which are stored
+//   via the AddObject() facility of this AliJob class.
+//   From this storage the objects can be (more directly) accessed via the
+//   GetObject() and GetObjects() memberfunctions.
+// * A pointer to the main object structure during job processing.
+//   This pointer can be initiated/updated only by the derived top level
+//   processor via the SetMainObject() facility but all sub-tasks can access
+//   it via the above folder/array facilities or the GetMainObject() memberfunction.
+//   The latter provides faster access to the main object structure than
+//   the GetObject() or TFolder search based procedures.
+//
+// Notes :
+// -------
+// 1) This AliJob class is derived from TTask, which implies that every
+//    (user defined) top level processor class is itself also a TTask.
+//    This allows sub-tasks to be introduced to the top level processor
+//    using the standard TTask facilities.
+//
+// 2) Only references to the various introduced objects are stored.
+//    It is the user's responsibility to delete all introduced objects,
+//    either in the destructor of the derived top level processor class
+//    or via Clear() facility as provided by the TTask machinery.
+//
+// 3) The top level processor instance is entered into the standard ROOT
+//    ListOfTasks under the name which was provided by the user in the
+//    constructor of the top level processor.
+//    The name of the top level processor is passed automatically as the
+//    opt argument to the Exec(Option_t* opt) memberfunctions of the 
+//    various sub-tasks by the ExecuteJob() memberfunction (see below).
+//    This allows all sub-tasks to obtain the pointer to the top level
+//    processor instance from its name via the statement :
+//
+//      AliJob* parent=(AliJob*)gROOT->GetListOfTasks()->FindObject(opt)
+//
+// 4) The job-specific folder will be created in the generic folder called
+//    "AliJob-folders" as a sub-folder under the same name as the one
+//    introduced in the constructor of the derived top level processor class.
+//    The folder will only be created when the first object is posted via
+//    the AddObject() or SetMainObject() facilities.
+//
+// Execution of the (user defined) top level processor has to be invoked via
+// the memberfunction ExecuteJob() of this AliJob base class.
+// This will invoke the (user written) Exec() memberfunction of the top level
+// processor class with as argument the name of the top level processor instance
+// as specified by the user in the top level processor constructor.
+// This will allow stepwise (e.g. event-by-event) execution of the various sub-tasks.
+//
+// It is the user's responsibility to invoke the sub-tasks via the
+// ExecuteTasks() statement at the appropriate location in the top level
+// processor class. 
+//
+//--- Author: Nick van Eijndhoven 07-may-2005 Utrecht University
+//- Modified: NvE $Date$ Utrecht University
+///////////////////////////////////////////////////////////////////////////
+#include "AliJob.h"
+#include "Riostream.h"
+
+ClassImp(AliJob) // Class implementation to enable ROOT I/O
+
+AliJob::AliJob(const char* name,const char* title) : TTask(name,title)
+{
+// Default constructor.
+// Initialise the working environment for general data access
+// by the derived task and its subtasks.
+
+ fMainObject=0;
+ fFolder=0;
+ fObjects=0;
+ fSelect=0;
+
+ // Introduce this AliJob based instance into the ROOT task list
+ TSeqCollection* tasks=gROOT->GetListOfTasks();
+ if (tasks) tasks->Add(this);
+}
+///////////////////////////////////////////////////////////////////////////
+AliJob::~AliJob()
+{
+// Default destructor.
+// Note : The objects belonging to the various pointers in the folder
+//        and the main processing object are NOT deleted by this base class.
+
+ if (fObjects)
+ {
+  delete fObjects;
+  fObjects=0;
+ }
+ if (fFolder)
+ {
+  delete fFolder;
+  fFolder=0;
+ }
+ if (fSelect)
+ {
+  delete fSelect;
+  fSelect=0;
+ }
+}
+///////////////////////////////////////////////////////////////////////////
+void AliJob::ListEnvironment()
+{
+// Provide listing of the job environment. 
+
+ cout << " ***" << endl;
+ cout << " *** Environment of job " << GetName() << " ***" << endl;
+ cout << " ***" << endl;
+ cout << " === Available (sub)tasks : " << endl;
+ ls();
+ cout << " === Current job-folder contents : " << endl;
+ fFolder->ls();
+ cout << endl;
+}
+///////////////////////////////////////////////////////////////////////////
+void AliJob::ExecuteJob()
+{
+// Invokation of the top level processor via its Exec() memberfunction.
+ Exec(GetName());
+}
+///////////////////////////////////////////////////////////////////////////
+TFolder* AliJob::GetFolder() const
+{
+// Provide pointer to the whiteboard folder.
+ return fFolder;
+}
+///////////////////////////////////////////////////////////////////////////
+TObject* AliJob::GetMainObject() const
+{
+// Provide pointer to the main object structure.
+ return fMainObject;
+}
+///////////////////////////////////////////////////////////////////////////
+void AliJob::SetMainObject(TObject* obj)
+{
+// Store pointer to the main object structure.
+ if (obj)
+ {
+  fMainObject=obj;
+  AddObject(obj);
+ }
+}
+///////////////////////////////////////////////////////////////////////////
+void AliJob::AddObject(TObject* obj)
+{
+// Store pointer of specified object in the working environment.
+
+ if (!obj) return;
+
+ if (!fObjects) fObjects=new TObjArray();
+
+ if (!fFolder)
+ {
+  // Create the top level environment folder for all AliJobs if needed 
+  TList* list=gROOT->GetListOfBrowsables();
+  if (list)
+  {
+   TFolder* top=(TFolder*)list->FindObject("AliJob-folders");
+   if (!top)
+   {
+    top=new TFolder("AliJob-folders","Environment for all AliJob derived tasks");
+    list->Add(top,"AliJob-folders");
+   }
+   // Create the task-specific folder as a sub-folder in the top folder 
+   fFolder=top->AddFolder(GetName(),GetTitle());
+  }
+ }
+
+ // Add object pointer to array and folder if it doesn't already exist 
+ Int_t exist=0;
+ for (Int_t i=0; i<fObjects->GetEntries(); i++)
+ {
+  if (obj==fObjects->At(i))
+  {
+   exist=1;
+   break;
+  }
+ }
+ if (!exist)
+ {
+  fObjects->Add(obj);
+  fFolder->Add(obj);
+ }
+}
+///////////////////////////////////////////////////////////////////////////
+void AliJob::AddObjects(TObjArray* arr)
+{
+// Store pointers of all the array objects individually in the working environment.
+
+ if (!arr) return;
+
+ TObject* obj=0;
+ for (Int_t i=0; i<arr->GetSize(); i++)
+ {
+  obj=arr->At(i);
+  if (obj) AddObject(obj);
+ }
+}
+///////////////////////////////////////////////////////////////////////////
+void AliJob::RemoveObject(TObject* obj)
+{
+// Remove pointer of specified object from the working environment.
+
+ if (!obj) return;
+
+ if (fObjects)
+ {
+  TObject* test=fObjects->Remove(obj);
+  if (test) fObjects->Compress();
+ }
+
+ if (fFolder) fFolder->Remove(obj);
+}
+///////////////////////////////////////////////////////////////////////////
+void AliJob::RemoveObjects(const char* classname)
+{
+// Remove all stored objects inheriting from classname.
+
+ if (!fObjects) return;
+
+ Int_t remove=0;
+ for (Int_t i=0; i<fObjects->GetEntries(); i++)
+ {
+  TObject* obj=fObjects->At(i);
+  if (obj->InheritsFrom(classname))
+  {
+   TObject* test=fObjects->Remove(obj);
+   if (test) remove=1;
+   if (fFolder) fFolder->Remove(obj);
+  }
+ }
+ if (remove) fObjects->Compress();
+}
+///////////////////////////////////////////////////////////////////////////
+TObject* AliJob::GetObject(Int_t j) const
+{
+// Provide pointer to j-th stored object.
+// Note : j=1 indicates the first object.
+
+ if (!fObjects || j<1) return 0;
+
+ TObject* obj=0;
+
+ if (j<=fObjects->GetEntries()) obj=fObjects->At(j-1);
+ return obj;
+}
+///////////////////////////////////////////////////////////////////////////
+TObject* AliJob::GetObject(const char* classname) const
+{
+// Provide pointer to the first stored object which inherits from classname.
+
+ if (!fObjects) return 0;
+
+ TObject* obj=0;
+ for (Int_t i=0; i<fObjects->GetEntries(); i++)
+ {
+  TObject* obx=fObjects->At(i);
+  if (obx->InheritsFrom(classname))
+  {
+   obj=obx;
+   break;
+  }
+ }
+ return obj;
+}
+///////////////////////////////////////////////////////////////////////////
+TObjArray* AliJob::GetObjects() const
+{
+// Provide pointers of all the stored objects.
+ return fObjects;
+}
+///////////////////////////////////////////////////////////////////////////
+TObjArray* AliJob::GetObjects(const char* classname)
+{
+// Provide pointers to all stored objects inheriting from classname.
+
+ if (!fObjects) return 0;
+
+ if (fSelect)
+ {
+  fSelect->Clear();
+ }
+ else
+ {
+  fSelect=new TObjArray();
+ }
+
+ for (Int_t i=0; i<fObjects->GetEntries(); i++)
+ {
+  TObject* obj=fObjects->At(i);
+  if (obj->InheritsFrom(classname)) fSelect->Add(obj);
+ }
+ return fSelect;
+}
+///////////////////////////////////////////////////////////////////////////
diff --git a/RALICE/AliJob.h b/RALICE/AliJob.h
new file mode 100644 (file)
index 0000000..e66e870
--- /dev/null
@@ -0,0 +1,41 @@
+#ifndef ALIJOB_H
+#define ALIJOB_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+// $Id$
+
+#include "TROOT.h"
+#include "TTask.h"
+#include "TFolder.h"
+#include "TObjArray.h"
+
+class AliJob : public TTask
+{
+ public :
+  AliJob(const char* name="AliJob",const char* title=""); // Constructor
+  virtual ~AliJob();                                      // Destructor
+  void ListEnvironment();                                 // Provide listing of the job environment
+  void ExecuteJob();                                      // Invokation of the top level processing
+  TFolder* GetFolder() const;                             // Provide pointer to the whiteboard folder 
+  TObject* GetMainObject() const;                         // Provide pointer to the main object structure
+  void AddObject(TObject* obj);                           // Add an object into the environment
+  void AddObjects(TObjArray* arr);                        // Add all array objects into the environment
+  void RemoveObject(TObject* obj);                        // Remove an object from the environment
+  void RemoveObjects(const char* classname);              // Remove all objects inheriting from "classname"
+  TObject* GetObject(const char* classname) const;        // Provide first stored object inheriting from "classname" 
+  TObject* GetObject(Int_t j) const;                      // Provide j-th stored object
+  TObjArray* GetObjects() const;                          // Provide all stored object pointers
+  TObjArray* GetObjects(const char* classname);           // Provide all objects inheriting from "classname" 
+
+ protected :
+  TFolder* fFolder;     // Pointer to the folder which serves as the job's whiteboard
+  TObject* fMainObject; // Pointer to the main processing object structure within the job
+  TObjArray* fObjects;  // Pointers to the various user-added objects 
+  TObjArray* fSelect;   //! Temp. array of pointers to user-selected stored objects 
+
+  void SetMainObject(TObject* obj); // Store pointer to the main object structure
+
+ ClassDef(AliJob,1) // Base class for top level job in a task based procedure 
+};
+#endif
index 73ab28a7a456a34acb582c110accfb9d95246c17..dc346e83abd04570849ddd8dbad796298f3f917b 100644 (file)
@@ -778,7 +778,7 @@ void AliTimestamp::SetTJD(Int_t tjd,Int_t sec,Int_t ns,Int_t ps)
 
  Int_t mjd=tjd+40000;
 
- SetMJD(mjd,sec,ns);
+ SetMJD(mjd,sec,ns,ps);
 }
 ///////////////////////////////////////////////////////////////////////////
 void AliTimestamp::SetTJD(Double_t tjd)
index 058c5147a8ee3783f0b96f81ae74d23b14926353..9e610af38f65e80686b97bbbdf2edf10d7b405b1 100644 (file)
@@ -35,3 +35,4 @@
 #include "AliHelix.h"
 #include "AliDevice.h"
 #include "AliTimestamp.h"
+#include "AliJob.h"
index 0fbf1778ec28a1601aa501cf1f8ad74220e8ed2c..d5bf5f35fb2899ece2cf6955b748fc045c150c81 100644 (file)
@@ -40,5 +40,6 @@
  #pragma link C++ class AliHelix+;
  #pragma link C++ class AliDevice+;
  #pragma link C++ class AliTimestamp+;
+ #pragma link C++ class AliJob+;
 #endif
  
index 0d5d7fd34135c02679ff105ad53aba997d0d85d0..e7f27614835d0dbd47578f7d716e688b44773cb5 100644 (file)
                 Also "cout << endl;" introduced after the Pylist() call in AliCollider in order to
                 separate the Pythia event listing from subsequent output due to the mis-interpretation
                 of Fortran carriage-control characters on some systems.
+17-jun-2005 NvE New class AliJob introduced to provide a flexible (physics) analysis environment.
+                Bug (forgotten ps transfer in AliTimestamp::SetTJD) fixed (thanks Federico Carminati).
                 
  
\ No newline at end of file
index 887d4fe36e514a066663476b99cb748eee73a21d..dc3bab18d085908f9accc64f1d66a5f85443b601 100644 (file)
 ///////////////////////////////////////////////////////////////////////////
 // Class IceF2k
 // Conversion of Amanda F2K data into IceEvent physics event structures.
+// This class is derived from AliJob providing a task-based processing
+// structure on an event-by-event basis.
+// The main object in the job environment is an IceEvent* pointer.
+// In case the user has provided sub-tasks, these will be executed
+// on an event-by-event basis after the IceEvent structure has been filled
+// with the F2K data and before the final structures are written out.
 //
 // Usage example :
 // ---------------
 // gSystem->Load("icepack");
 // gSystem->Load("iceconvert");
 //
-// // Output file for the event structures
-// TFile* ofile=new TFile("events.root","RECREATE","F2K data in IceEvent structure");
-// TTree* otree=new TTree("T","Data of an Amanda run");
+// IceF2k q("IceF2k","F2K to IcePack data structure conversion");
 //
 // // Limit the number of entries for testing
-// Int_t nentries=300;
+// q.SetMaxEvents(10);
 //
 // // Print frequency to produce a short summary print every printfreq events
-// Int_t printfreq=10;
+// q.SetPrintFreq(1);
 //
 // // Split level for the output structures
-// Int_t split=2;
+// q.SetSplitLevel(2);
 //
 // // Buffer size for the output structures
-// Int_t bsize=32000;
+// q.SetBufferSize(32000);
+//
+// // The F2K input filename
+// q.SetInputFile("run7825.f2k");
 //
-// IceF2k q("run8000.f2k",split,bsize);
-// q.Loop(otree,nentries,printfreq);
+// // Output file for the event structures
+// TFile* ofile=new TFile("events.root","RECREATE","F2K data in IceEvent structure");
+// q.SetOutputFile(ofile);
+//
+// ///////////////////////////////////////////////////////////////////
+// // Here the user can specify his/her sub-tasks to be executed
+// // on an event-by-event basis after the IceEvent structure
+// // has been filled and before the data is written out.
+// // Sub-tasks (i.e. a user classes derived from TTask) are entered
+// // as follows :
+// //
+// //    MyXtalk task1("task1","Cross talk correction");
+// //    MyClean task2("task2","Hit cleaning");
+// //    q.Add(&task1);
+// //    q.Add(&task2);
+// //
+// // The sub-tasks will be executed in the order as they are entered.
+// ///////////////////////////////////////////////////////////////////
+//
+// // Perform the conversion and execute subtasks (if any)
+// // on an event-by-event basis
+// q.ExecuteJob();
 //
 // // Select various objects to be added to the output file
 //
 
 ClassImp(IceF2k) // Class implementation to enable ROOT I/O
 
-IceF2k::IceF2k(char* fname,Int_t split,Int_t bsize)
+IceF2k::IceF2k(const char* name,const char* title) : AliJob(name,title)
 {
 // Default constructor.
-// Initialise the input file and data structres to be converted.
-// Also the required split level and buffer size of the output tree
-// can be specified in this constructor.
-// By default tree=0, split=0 and bsize=32000.
+// By default maxevent=-1, split=99, bsize=32000, printfreq=1.
 
- fSplit=split;
- fBsize=bsize;
+ fSplit=99;
+ fBsize=32000;
+ fMaxevt=-1;
+ fPrintfreq=1;
+ fInfile="";
+ fOutfile=0;
 
  fPdg=0;
  fOmdb=0;
  fFitdefs=0;
-
- if (!fname)
- {
-  cout << " *IceF2k ctor* No data input file specified." << endl;
-  return;
- }
-
- // Open the input file in the default ascii format (autodetection) for reading 
- fInput=rdmc_mcopen(fname,"r",RDMC_DEFAULT_ASCII_F);
-
- if (!fInput)
- {
-  cout << " *IceF2k ctor* No input file found with name : " << fname << endl;
-  return;
- }
-
- // Initialise the event structure 
- rdmc_init_mevt(&fEvent);
-
- // Read the file header information
- rdmc_rarr(fInput,&fHeader);
 }
 ///////////////////////////////////////////////////////////////////////////
 IceF2k::~IceF2k()
 {
 // Default destructor.
+ IceEvent* evt=(IceEvent*)GetMainObject();
+ if (evt) delete evt;
+
  if (fPdg)
  {
   delete fPdg;
@@ -128,6 +138,47 @@ IceF2k::~IceF2k()
  }
 }
 ///////////////////////////////////////////////////////////////////////////
+void IceF2k::SetMaxEvents(Int_t n)
+{
+// Set the maximum number of events to be processed.
+// n=-1 implies processing of the complete input file, which is the default
+// initialisation in the constructor.
+ fMaxevt=n;
+}
+///////////////////////////////////////////////////////////////////////////
+void IceF2k::SetPrintFreq(Int_t f)
+{
+// Set the printfrequency to produce info every f events.
+// f=1 is the default initialisation in the constructor.
+ if (f>0) fPrintfreq=f;
+}
+///////////////////////////////////////////////////////////////////////////
+void IceF2k::SetSplitLevel(Int_t split)
+{
+// Set the split level for the ROOT data file.
+// split=99 is the default initialisation in the constructor.
+ if (split>=0) fSplit=split;
+}
+///////////////////////////////////////////////////////////////////////////
+void IceF2k::SetBufferSize(Int_t bsize)
+{
+// Set the buffer size for the ROOT data file.
+// bsize=32000 is the default initialisation in the constructor.
+ if (bsize>=0) fBsize=bsize;
+}
+///////////////////////////////////////////////////////////////////////////
+void IceF2k::SetInputFile(TString name)
+{
+// Set the name of the F2K input file.
+ fInfile=name;
+}
+///////////////////////////////////////////////////////////////////////////
+void IceF2k::SetOutputFile(TFile* ofile)
+{
+// Set the output file for the ROOT data.
+ fOutfile=ofile;
+}
+///////////////////////////////////////////////////////////////////////////
 TDatabasePDG* IceF2k::GetPDG()
 {
 // Provide pointer to the PDG database
@@ -146,23 +197,55 @@ AliDevice* IceF2k::GetFitdefs()
  return fFitdefs;
 }
 ///////////////////////////////////////////////////////////////////////////
-void IceF2k::Loop(TTree* otree,Int_t nentries,Int_t printfreq)
+void IceF2k::Exec(Option_t* opt)
 {
-// Loop over the specified number of entries and convert the 
+// Job to loop over the specified number of events and convert the 
 // F2K data into the IceEvent structure.
-// The output will be written on the output tree specified as "otree".
-// If otree=0, a default standard output tree will be created.
-// If nentries<0 (default) all the entries of the input file
+// If maxevents<0 (default) all the entries of the input file
 // will be processed.
 // Every "printfreq" events a short event summary will be printed.
 // The default value is printfreq=1.
+// The output will be written on a standard output tree named "T".
+//
+// Notes :
+// -------
+// 1) This class is derived from AliJob, allowing a task based processing.
+//    After the conversion of an F2K event into an IceEvent structure,
+//    the processing of all available sub-tasks (if any) is invoked.
+//    This provides an event-by-event (sub)task processing before the
+//    final data structures are written out.
+// 2) The main object in this job environment is an IceEvent* pointer.
+
+ if (fInfile=="")
+ {
+  cout << " *IceF2k Exec* No data input file specified." << endl;
+  return;
+ }
 
- if (!fInput || fSplit<0) return;
+ // Open the input file in the default ascii format (autodetection) for reading 
+ fInput=rdmc_mcopen(fInfile.Data(),"r",RDMC_DEFAULT_ASCII_F);
 
- if (!otree) otree=new TTree("T","F2K Data");
+ if (!fInput)
+ {
+  cout << " *IceF2k Exec* No input file found with name : " << fInfile.Data() << endl;
+  return;
+ }
 
- IceEvent* evt=new IceEvent();
+ // Initialise the event structure 
+ rdmc_init_mevt(&fEvent);
+
+ // Read the file header information
+ rdmc_rarr(fInput,&fHeader);
+
+ if (!fOutfile)
+ {
+  cout << " *IceF2k Exec* No ROOT output file specified." << endl;
+  return;
+ }
 
+ TTree* otree=new TTree("T","F2K Data converted to IceEvent structures");
+
+ IceEvent* evt=new IceEvent();
  evt->SetTrackCopy(1);
  evt->SetDevCopy(1);
 
@@ -191,9 +274,26 @@ void IceF2k::Loop(TTree* otree,Int_t nentries,Int_t printfreq)
  // Set the fit definitions according to the F2000 header info
  SetFitdefs();
 
- for (Int_t jentry=0; jentry<nentries; jentry++)
+ // Initialise the job working environment
+ SetMainObject(evt);
+ AddObject(fOutfile);
+ AddObject(otree);
+
+ cout << " ***" << endl;
+ cout << " *** Start processing of job " << GetName() << " ***" << endl;
+ cout << " ***" << endl;
+ cout << " F2K input file : " << fInfile.Data() << endl;
+ cout << " Maximum number of events to be processed : " << fMaxevt << endl;
+ cout << " Print frequency : " << fPrintfreq << endl;
+ cout << " ROOT output file : " << fOutfile->GetName() << endl;
+ cout << " Output characteristics : splitlevel = " << fSplit << " buffersize = " << fBsize << endl;
+
+ ListEnvironment();
+ Int_t nevt=0;
+ while (!rdmc_revt(fInput,&fHeader,&fEvent))
  {
-  if (rdmc_revt(fInput,&fHeader,&fEvent) != 0) break;
+  if (fMaxevt>-1 && nevt>=fMaxevt) break;
 
   // Reset the complete Event structure
   evt->Reset();
@@ -202,22 +302,23 @@ void IceF2k::Loop(TTree* otree,Int_t nentries,Int_t printfreq)
   evt->SetEventNumber(fEvent.enr);
   evt->SetMJD(fEvent.mjd,fEvent.secs,fEvent.nsecs);
 
-  PutMcTracks(evt);
+  PutMcTracks();
 
-  PutRecoTracks(evt);
+  PutRecoTracks();
 
-  PutHits(evt);
+  PutHits();
 
-  if (!(jentry%printfreq))
-  {
-   evt->HeaderData();
-  }
+  // Invoke all available sub-tasks (if any)
+  ExecuteTasks(opt);
+
+  if (!(nevt%fPrintfreq)) evt->HeaderData();
 
   // Write the complete structure to the output Tree
   otree->Fill();
- }
 
- if (evt) delete evt;
+  // Update event counter
+  nevt++;
+ }
 }
 ///////////////////////////////////////////////////////////////////////////
 void IceF2k::FillOMdbase()
@@ -337,12 +438,13 @@ void IceF2k::SetFitdefs()
  }
 }
 ///////////////////////////////////////////////////////////////////////////
-void IceF2k::PutMcTracks(IceEvent* evt)
+void IceF2k::PutMcTracks()
 {
 // Get the MC tracks from the F2000 file into the IcePack structure.
 // Note : MC tracks are given negative track id's in the event structure.
 // This memberfunction is based on the original code by Adam Bouchta.
 
+ IceEvent* evt=(IceEvent*)GetMainObject();
  if (!evt || fEvent.ntrack<=0) return;
 
  // Loop over all the tracks and add them to the current event
@@ -439,12 +541,13 @@ void IceF2k::PutMcTracks(IceEvent* evt)
  }
 }
 ///////////////////////////////////////////////////////////////////////////
-void IceF2k::PutRecoTracks(IceEvent* evt)
+void IceF2k::PutRecoTracks()
 {
 // Get the reconstructed tracks from the F2000 file into the IcePack structure.
 // Note : Reco tracks are given positive track id's in the event structure.
 // This memberfunction is based on the original code by Adam Bouchta.
 
+ IceEvent* evt=(IceEvent*)GetMainObject();
  if (!evt || fEvent.nfit<=0) return;
 
  // Loop over all the tracks and add them to the current event
@@ -545,11 +648,12 @@ void IceF2k::PutRecoTracks(IceEvent* evt)
  }
 }
 ///////////////////////////////////////////////////////////////////////////
-void IceF2k::PutHits(IceEvent* evt)
+void IceF2k::PutHits()
 {
 // Get the hit and waveform info from the F2000 file into the IcePack structure.
 // This memberfunction is based on the original code by Adam Bouchta.
 
+ IceEvent* evt=(IceEvent*)GetMainObject();
  if (!evt) return;
 
  // Loop over all the hits and add them to the current event
index 68175c19f286bb5114582cd46e5dc170eb6d474b..6389f1d28d3006ce17292639486e74d450616b75 100644 (file)
@@ -6,12 +6,12 @@
 
 // $Id$
 
-#include "TObject.h"
-#include "TChain.h"
 #include "TFile.h"
-#include "TDatabasePDG.h"
+#include "TTree.h"
 #include "TString.h"
+#include "TDatabasePDG.h"
 
+#include "AliJob.h"
 #include "AliObjMatrix.h"
 
 #include "IceAOM.h"
 
 #include "rdmc.h"
 
-class IceF2k : public TObject
+class IceF2k : public AliJob
 {
  public :
-  IceF2k(char* fname=0,Int_t split=0,Int_t bsize=32000);         // Constructor
-  virtual ~IceF2k();                                             // Destructor
-  void Loop(TTree* otree=0,Int_t nentries=-1,Int_t printfreq=1); // Perform the format conversion
-  TDatabasePDG* GetPDG();     // Provide pointer to the PDG database
-  AliObjMatrix* GetOMdbase(); // Provide pointer to the OM geometry, calib. etc... database
-  AliDevice* GetFitdefs();    // Provide pointer to the Fit definition parameters
+  IceF2k(const char* name="IceF2k",const char* title=""); // Constructor
+  virtual ~IceF2k();                                      // Destructor
+  void SetMaxEvents(Int_t n);                             // Set maximum number of events to be processed
+  void SetPrintFreq(Int_t f);                             // Set printfrequency to provide info every f events
+  void SetSplitLevel(Int_t split);                        // Set split level for the produced ROOT data file
+  void SetBufferSize(Int_t bsize);                        // Set buffersize for the produced ROO data file
+  void SetInputFile(TString name);                        // Set name of F2K input file
+  void SetOutputFile(TFile* ofile);                       // Set output file for the ROOT data structures           
+  TDatabasePDG* GetPDG();           // Provide pointer to the PDG database
+  AliObjMatrix* GetOMdbase();       // Provide pointer to the OM geometry, calib. etc... database
+  AliDevice* GetFitdefs();          // Provide pointer to the Fit definition parameters
+  virtual void Exec(Option_t* opt); // Perform the format conversion
 
  protected :
-  Int_t fSplit; // The split level of the produced ROOT data file
-  Int_t fBsize; // The buffersize of the produced ROOT data file
+  Int_t fSplit;     // The split level of the produced ROOT data file
+  Int_t fBsize;     // The buffersize of the produced ROOT data file
+  Int_t fMaxevt;    // The maximum number of events to be processed
+  Int_t fPrintfreq; // The event info printing frequency
+  TString fInfile;  // Name of the F2K input file
+  TFile* fOutfile;  // The ROOT output file
 
   TDatabasePDG* fPdg;  // Database with PDG information
   AliObjMatrix* fOmdb; // Database of all OM devices with their geometry, calib. etc... data
   AliDevice* fFitdefs; // Fit definitions as indicated in the header of the F2000 input file
 
-  void FillOMdbase();                // Fill geometry and calib. parameters of all devices
-  void SetFitdefs();                 // Set the fit definitions as used in the F2000 input file
-  void PutMcTracks(IceEvent* evt);   // Put the MC tracks from the F2000 file into the IcePack structure
-  void PutRecoTracks(IceEvent* evt); // Put the reconstructed tracks from the F2000 file into the IcePack structure
-  void PutHits(IceEvent* evt);       // Put the hits and waveforms from the F2000 file into the IcePack structure
+  void FillOMdbase();   // Fill geometry and calib. parameters of all devices
+  void SetFitdefs();    // Set the fit definitions as used in the F2000 input file
+  void PutMcTracks();   // Put the MC tracks from the F2000 file into the IcePack structure
+  void PutRecoTracks(); // Put the reconstructed tracks from the F2000 file into the IcePack structure
+  void PutHits();       // Put the hits and waveforms from the F2000 file into the IcePack structure
 
   mcfile* fInput;  //! Structure holding the input file characteristics
   array   fHeader; //! Structure holding the file header info
   mevt    fEvent;  //! Structure holding the actual event data (hits, tracks, etc...)
 
- ClassDef(IceF2k,1) // Conversion of F2K data into IceEvent physics event structures.
+ ClassDef(IceF2k,2) // Job for conversion of F2K data into IceEvent physics event structures.
 };
 #endif
index 8c7012ed6c2e7c70c6b9c9749672f80507db5d40..890de3d602fdbbe6544f37d5b11e4438d2e8518a 100644 (file)
@@ -2,8 +2,11 @@
 //                                History of updates                                //
 //////////////////////////////////////////////////////////////////////////////////////
 21-apr-2005 NvE First release of the package as a subdirectory of Ralice/icepack.
-29-apr-2005 Library creation scripts for Linux gcc etc... introduced.
-            Argument 'float' changed to 'double' for function isnan in amanda.c
-            to match gcc definition and setting of unused variable 'pi' removed
-            from IceF2k.cxx.
+29-apr-2005 NvE Library creation scripts for Linux gcc etc... introduced.
+                Argument 'float' changed to 'double' for function isnan in amanda.c
+                to match gcc definition and setting of unused variable 'pi' removed
+                from IceF2k.cxx.
+17-jun-2005 NvE Class IceF2k modified to provide a task-based processing environment.
+                For this IceF2k has been derived from the new RALICE class AliJob.
+                The example macro icef2k.cc has been updated accordingly.
  
index 3047fef1e4288c75f0e9d90a7643636aa5004436..2c842e6e91c6e3b92f2c74a51467629d98f39993 100644 (file)
@@ -1,35 +1,51 @@
-//////////////////////////////////////////////
-// Macro to test new IceF2k conversion class
+/////////////////////////////////////////////////
+// Macro to test the IceF2k conversion job class
 //
 // To run this macro in batch, just do
 //
-// root -b -q 
+// root -b -q icef2k.cc
+//
+// For more details see the docs of class IceF2k
 //
 // NvE 11-mar-2005 Utrecht University
-//////////////////////////////////////////////
+/////////////////////////////////////////////////
 {
  gSystem->Load("ralice");
  gSystem->Load("icepack");
  gSystem->Load("iceconvert");
 
- // Output file for the event structures
- TFile* ofile=new TFile("events.root","RECREATE","F2K data in IceEvent structure");
- TTree* otree=new TTree("T","Data of an Amanda run");
+ IceF2k q("IceF2k","Test of IceF2k conversion job");
 
  // Limit the number of entries for testing
Int_t nentries=5;
q.SetMaxEvents(100);
 
  // Print frequency to produce a short summary print every printfreq events
Int_t printfreq=1;
q.SetPrintFreq(10);
 
- // Split level for the output structures
Int_t split=2;
+ // The F2K input filename
q.SetInputFile("run7825.f2k");
 
- // Buffer size for the output structures
- Int_t bsize=32000;
+ // Output file for the event structures
+ TFile* ofile=new TFile("events.root","RECREATE","F2K data in IceEvent structure");
+ q.SetOutputFile(ofile);
+
+ ///////////////////////////////////////////////////////////////////
+ // Here the user can specify his/her sub-tasks to be executed
+ // on an event-by-event basis after the IceEvent structure
+ // has been filled and before the data is written out.
+ // Sub-tasks (i.e. a user classes derived from TTask) are entered
+ // as follows :
+ //
+ //    MyXtalk task1("task1","Cross talk correction");
+ //    MyClean task2("task2","Hit cleaning");
+ //    q.Add(&task1);
+ //    q.Add(&task2);
+ //
+ // The sub-tasks will be executed in the order as they are entered.
+ ///////////////////////////////////////////////////////////////////
 
- IceF2k q("run7825.f2k",split,bsize);
- q.Loop(otree,nentries,printfreq);
+ // Perform the conversion
+ q.ExecuteJob();
 
  // Select various objects to be added to the output file
 
@@ -41,7 +57,7 @@
 
  TDatabasePDG* pdg=q.GetPDG();
  if (pdg) pdg->Write();
+
  // Close output file
  ofile->Write();
  ofile->Close();
index b8c3b7cfdc986e70480883e2199f20c2eeba8fb9..610993f0aa98bcaf28ce99ee96d31f8771a4a0df 100644 (file)
@@ -4,7 +4,7 @@ SRCS=  Ali3Vector.cxx Ali4Vector.cxx AliBoost.cxx AliCalcluster.cxx \
        AliTrack.cxx AliVertex.cxx Ali3VectorObj.cxx Ali4VectorObj.cxx \
        AliPositionObj.cxx AliEvent.cxx AliCollider.cxx AliObjMatrix.cxx \
         AliAttrib.cxx AliAttribObj.cxx AliHelix.cxx AliDevice.cxx \
-        AliTimestamp.cxx 
+        AliTimestamp.cxx AliJob.cxx 
 
 HDRS= $(SRCS:.cxx=.h)