08-dec-2006 NvE Memberfunctions SetUT introduced in AliTimestamp to provide convenient
authornick <nick@f7af4fe6-9843-0410-8265-dc069ae4e863>
Sat, 16 Dec 2006 18:39:59 +0000 (18:39 +0000)
committernick <nick@f7af4fe6-9843-0410-8265-dc069ae4e863>
Sat, 16 Dec 2006 18:39:59 +0000 (18:39 +0000)
                ways to set a specific UT date/time.
14-dec-2006 NvE IceF2k updated to include a Daq device into the event structure
                containing an indication of the DAQ system that was used to produce
                the hit data (i.e. ADC, LE, TOT).
16-dec-2006 NvE New class IceRawTWR introduced to read raw TWR data into the Ralice/IcePack
                event structures.

14 files changed:
RALICE/AliTimestamp.cxx
RALICE/AliTimestamp.h
RALICE/history.txt
RALICE/icepack/iceconvert/ICEConvHeaders.h
RALICE/icepack/iceconvert/ICEConvLinkDef.h
RALICE/icepack/iceconvert/IceF2k.cxx
RALICE/icepack/iceconvert/IceRawTWR.cxx [new file with mode: 0644]
RALICE/icepack/iceconvert/IceRawTWR.h [new file with mode: 0644]
RALICE/icepack/iceconvert/history.txt
RALICE/icepack/iceconvert/twr_config.h [new file with mode: 0644]
RALICE/icepack/iceconvert/twr_event.h [new file with mode: 0644]
RALICE/icepack/iceconvert/twr_globalconst.h [new file with mode: 0644]
RALICE/icepack/iceconvert/twr_gps.h [new file with mode: 0644]
RALICE/icepack/iceconvert/twr_reader.h [new file with mode: 0644]

index f6f6fe6..19326f2 100644 (file)
 // the yy-mm-dd hh:mm:ss:ns TTimeStamp from a given input (M/T)JD and time.
 // Obviously this TTimeStamp implementation would prevent usage of values
 // smaller than JD=2440587.5 or MJD=40587 or TJD=587.
+// Furthermore, due to a limitation on the "seconds since the EPOCH start" count
+// in TTimeStamp, the latest accessible date/time is 19-jan-2038 02:14:08 UTC.
 // However, this AliTimestamp facility provides support for the full range
 // of (M/T)JD values, but the setting of the corresponding TTimeStamp parameters
 // is restricted to the values allowed by the TTimeStamp implementation.
-// For these earlier (M/T)JD values, the standard TTimeStamp parameters will
+// For these earlier/later (M/T)JD values, the standard TTimeStamp parameters will
 // be set corresponding to the start of the TTimeStamp EPOCH.
-// This implies that for these earlier (M/T)JD values the TTimeStamp parameters
+// This implies that for these earlier/later (M/T)JD values the TTimeStamp parameters
 // do not match the Julian parameters of AliTimestamp.
 // As such the standard TTimeStamp parameters do not appear on the print output
-// when invoking the Date() memberfunction for these earlier (M/T)JD values.  
+// when invoking the Date() memberfunction for these earlier/later (M/T)JD values.  
 //
 // Examples :
 // ==========
@@ -194,8 +196,11 @@ void AliTimestamp::Date(Int_t mode)
 
   Int_t mjd,mjsec,mjns;
   GetMJD(mjd,mjsec,mjns);
-
- if ((mode==1 || mode==3) && mjd>=40587) cout << " " << AsString() << endl;
+ if ((mode==1 || mode==3) && mjd>=40587 && (mjd<65442 || (mjd==65442 && mjsec<8047)))
+ {
+  cout << " " << AsString() << endl;
+ }
  if (mode==2 || mode==3)
  {
   Int_t jd,jsec,jns;
@@ -452,7 +457,7 @@ void AliTimestamp::FillJulian()
  fCalcns=GetNanoSec();
 }
 ///////////////////////////////////////////////////////////////////////////
-void AliTimestamp::GetMJD(Int_t& mjd,Int_t& sec, Int_t& ns)
+void AliTimestamp::GetMJD(Int_t& mjd,Int_t& sec,Int_t& ns)
 {
 // Provide the Modified Julian Date (MJD) and time corresponding to the
 // currently stored AliTimestamp date/time parameters.
@@ -584,12 +589,14 @@ void AliTimestamp::SetMJD(Int_t mjd,Int_t sec,Int_t ns,Int_t ps)
 // the yy-mm-dd hh:mm:ss:ns TTimeStamp from a given input MJD and time.
 // Obviously this TTimeStamp implementation would prevent usage of MJD values
 // smaller than 40587.
+// Furthermore, due to a limitation on the "seconds since the EPOCH start" count
+// in TTimeStamp, the latest accessible date/time is 19-jan-2038 02:14:08 UTC.
 // However, this AliTimestamp facility provides support for the full range
 // of (M)JD values, but the setting of the corresponding TTimeStamp parameters
 // is restricted to the values allowed by the TTimeStamp implementation.
-// For these earlier MJD values, the standard TTimeStamp parameters will
+// For these earlier/later MJD values, the standard TTimeStamp parameters will
 // be set corresponding to the start of the TTimeStamp EPOCH.  
-// This implies that for these earlier MJD values the TTimeStamp parameters
+// This implies that for these earlier/later MJD values the TTimeStamp parameters
 // do not match the Julian parameters of AliTimestamp.  
 //
 // The input arguments represent the following :
@@ -612,11 +619,16 @@ void AliTimestamp::SetMJD(Int_t mjd,Int_t sec,Int_t ns,Int_t ps)
  fJns=ns;
  fJps=ps;
 
- Int_t epoch=40587;
+ Int_t epoch=40587; // MJD of the start of the epoch
+ Int_t limit=65442; // MJD of the latest possible TTimeStamp date/time
  
- if (mjd<epoch)
+ Int_t date,time;
+ if (mjd<epoch || (mjd>=limit && sec>=8047))
  {
   Set(0,kFALSE,0,kFALSE);
+  date=GetDate();
+  time=GetTime();
+  Set(date,time,0,kTRUE,0);
  }
  else
  {
@@ -625,8 +637,8 @@ void AliTimestamp::SetMJD(Int_t mjd,Int_t sec,Int_t ns,Int_t ps)
   UInt_t secs=days*24*3600;
   secs+=sec;
   Set(secs,kFALSE,0,kFALSE);
-  Int_t date=GetDate();
-  Int_t time=GetTime();
+  date=GetDate();
+  time=GetTime();
   Set(date,time,ns,kTRUE,0);
  }
 
@@ -651,12 +663,14 @@ void AliTimestamp::SetMJD(Double_t mjd)
 // the yy-mm-dd hh:mm:ss:ns TTimeStamp from a given input MJD and time.
 // Obviously this TTimeStamp implementation would prevent usage of MJD values
 // smaller than 40587.
+// Furthermore, due to a limitation on the "seconds since the EPOCH start" count
+// in TTimeStamp, the latest accessible date/time is 19-jan-2038 02:14:08 UTC.
 // However, this AliTimestamp facility provides support for the full range
 // of (M)JD values, but the setting of the corresponding TTimeStamp parameters
 // is restricted to the values allowed by the TTimeStamp implementation.
-// For these earlier MJD values, the standard TTimeStamp parameters will
+// For these earlier/later MJD values, the standard TTimeStamp parameters will
 // be set corresponding to the start of the TTimeStamp EPOCH.  
-// This implies that for these earlier MJD values the TTimeStamp parameters
+// This implies that for these earlier/later MJD values the TTimeStamp parameters
 // do not match the Julian parameters of AliTimestamp.  
 //
 // Due to computer accuracy the ns precision may be lost.
@@ -685,12 +699,14 @@ void AliTimestamp::SetJD(Int_t jd,Int_t sec,Int_t ns,Int_t ps)
 // the yy-mm-dd hh:mm:ss:ns TTimeStamp from a given input MJD and time.
 // Obviously this TTimeStamp implementation would prevent usage of values
 // smaller than JD=2440587.5.
+// Furthermore, due to a limitation on the "seconds since the EPOCH start" count
+// in TTimeStamp, the latest accessible date/time is 19-jan-2038 02:14:08 UTC.
 // However, this AliTimestamp facility provides support for the full range
 // of (M)JD values, but the setting of the corresponding TTimeStamp parameters
 // is restricted to the values allowed by the TTimeStamp implementation.
-// For these earlier JD values, the standard TTimeStamp parameters will
+// For these earlier/later JD values, the standard TTimeStamp parameters will
 // be set corresponding to the start of the TTimeStamp EPOCH.  
-// This implies that for these earlier (M)JD values the TTimeStamp parameters
+// This implies that for these earlier/later (M)JD values the TTimeStamp parameters
 // do not match the Julian parameters of AliTimestamp.  
 //
 // The input arguments represent the following :
@@ -725,12 +741,14 @@ void AliTimestamp::SetJD(Double_t jd)
 // the yy-mm-dd hh:mm:ss:ns TTimeStamp from a given input MJD and time.
 // Obviously this TTimeStamp implementation would prevent usage of values
 // smaller than JD=2440587.5.
+// Furthermore, due to a limitation on the "seconds since the EPOCH start" count
+// in TTimeStamp, the latest accessible date/time is 19-jan-2038 02:14:08 UTC.
 // However, this AliTimestamp facility provides support for the full range
 // of (M)JD values, but the setting of the corresponding TTimeStamp parameters
 // is restricted to the values allowed by the TTimeStamp implementation.
-// For these earlier JD values, the standard TTimeStamp parameters will
+// For these earlier/later JD values, the standard TTimeStamp parameters will
 // be set corresponding to the start of the TTimeStamp EPOCH.  
-// This implies that for these earlier (M)JD values the TTimeStamp parameters
+// This implies that for these earlier/later (M)JD values the TTimeStamp parameters
 // do not match the Julian parameters of AliTimestamp.  
 //
 // Due to computer accuracy the ns precision may be lost.
@@ -760,12 +778,14 @@ void AliTimestamp::SetTJD(Int_t tjd,Int_t sec,Int_t ns,Int_t ps)
 // the yy-mm-dd hh:mm:ss:ns TTimeStamp from a given input MJD and time.
 // Obviously this TTimeStamp implementation would prevent usage of values
 // smaller than TJD=587.
+// Furthermore, due to a limitation on the "seconds since the EPOCH start" count
+// in TTimeStamp, the latest accessible date/time is 19-jan-2038 02:14:08 UTC.
 // However, this AliTimestamp facility provides support for the full range
 // of (T)JD values, but the setting of the corresponding TTimeStamp parameters
 // is restricted to the values allowed by the TTimeStamp implementation.
-// For these earlier JD values, the standard TTimeStamp parameters will
+// For these earlier/later JD values, the standard TTimeStamp parameters will
 // be set corresponding to the start of the TTimeStamp EPOCH.  
-// This implies that for these earlier (T)JD values the TTimeStamp parameters
+// This implies that for these earlier/later (T)JD values the TTimeStamp parameters
 // do not match the Julian parameters of AliTimestamp.  
 //
 // The input arguments represent the following :
@@ -794,12 +814,14 @@ void AliTimestamp::SetTJD(Double_t tjd)
 // the yy-mm-dd hh:mm:ss:ns TTimeStamp from a given input MJD and time.
 // Obviously this TTimeStamp implementation would prevent usage of values
 // smaller than TJD=587.
+// Furthermore, due to a limitation on the "seconds since the EPOCH start" count
+// in TTimeStamp, the latest accessible date/time is 19-jan-2038 02:14:08 UTC.
 // However, this AliTimestamp facility provides support for the full range
 // of (T)JD values, but the setting of the corresponding TTimeStamp parameters
 // is restricted to the values allowed by the TTimeStamp implementation.
-// For these earlier JD values, the standard TTimeStamp parameters will
+// For these earlier/later JD values, the standard TTimeStamp parameters will
 // be set corresponding to the start of the TTimeStamp EPOCH.  
-// This implies that for these earlier (T)JD values the TTimeStamp parameters
+// This implies that for these earlier/later (T)JD values the TTimeStamp parameters
 // do not match the Julian parameters of AliTimestamp.  
 //
 // Due to computer accuracy the ns precision may be lost.
@@ -1187,3 +1209,82 @@ Double_t AliTimestamp::GetDifference(AliTimestamp& t,TString u,Int_t mode)
  return GetDifference(&t,u,mode);
 }
 ///////////////////////////////////////////////////////////////////////////
+void AliTimestamp::SetUT(Int_t y,Int_t m,Int_t d,Int_t hh,Int_t mm,Int_t ss,Int_t ns,Int_t ps)
+{
+// Set the AliTimestamp parameters corresponding to the UT date and time
+// in the Gregorian calendar as specified by the input arguments.
+// This facility is exact upto picosecond precision and as such is
+// for scientific observations preferable above the corresponding
+// Set function(s) of TTimestamp.
+// The latter has a random spread in the sub-second part, which
+// might be of use in generating distinguishable timestamps while
+// still keeping second precision.
+//
+// The input arguments represent the following :
+// y  : year in UT (e.g. 1952, 2003 etc...)
+// m  : month in UT (1=jan  2=feb etc...)
+// d  : day in UT (1-31)
+// hh : elapsed hours in UT (0-23) 
+// mm : elapsed minutes in UT (0-59)
+// ss : elapsed seconds in UT (0-59)
+// ns : remaining fractional elapsed second of UT in nanosecond
+// ps : remaining fractional elapsed nanosecond of UT in picosecond
+//
+// Note : ns=0 and ps=0 are the default values.
+//
+// This facility first determines the elapsed days, seconds etc...
+// since the beginning of the specified UT year on bais of the
+// input arguments. Subsequently it invokes the SetUT memberfunction
+// for the elapsed timespan.
+// As such this facility is valid for all AD dates in the Gregorian
+// calendar with picosecond precision.
+
+ Int_t day=GetDayOfYear(d,m,y);
+ Int_t secs=hh*3600+mm*60+ss;
+ SetUT(y,day-1,secs,ns,ps);
+}
+///////////////////////////////////////////////////////////////////////////
+void AliTimestamp::SetUT(Int_t y,Int_t d,Int_t s,Int_t ns,Int_t ps)
+{
+// Set the AliTimestamp parameters corresponding to the specified elapsed
+// timespan since the beginning of the new UT year.
+// This facility is exact upto picosecond precision and as such is
+// for scientific observations preferable above the corresponding
+// Set function(s) of TTimestamp.
+// The latter has a random spread in the sub-second part, which
+// might be of use in generating distinguishable timestamps while
+// still keeping second precision.
+//
+// The UT year and elapsed time span is entered via the following input arguments :
+//
+// y  : year in UT (e.g. 1952, 2003 etc...)
+// d  : elapsed number of days 
+// s  : (remaining) elapsed number of seconds
+// ns : (remaining) elapsed number of nanoseconds
+// ps : (remaining) elapsed number of picoseconds
+//
+// The specified d, s, ns and ps values will be used in an additive
+// way to determine the elapsed timespan.
+// So, specification of d=1, s=100, ns=0, ps=0 will result in the
+// same elapsed time span as d=0, s=24*3600+100, ns=0, ps=0.
+// However, by making use of the latter the user should take care
+// of possible integer overflow problems in the input arguments,
+// which obviously will provide incorrect results. 
+//
+// Note : ns=0 and ps=0 are the default values.
+//
+// This facility first sets the (M)JD corresponding to the start (01-jan 00:00:00)
+// of the specified UT year following the recipe of R.W. Sinnott
+// Sky & Telescope 82, (aug. 1991) 183.
+// Subsequently the day and (sub)second parts are added to the AliTimestamp.
+// As such this facility is valid for all AD dates in the Gregorian calendar.
+
+ Double_t jd=GetJD(y,1,1,0,0,0,0);
+ SetJD(jd);
+
+ Int_t mjd,sec,nsec;
+ GetMJD(mjd,sec,nsec);
+ SetMJD(mjd,0,0,0);
+ Add(d,s,ns,ps);
+}
+///////////////////////////////////////////////////////////////////////////
index a931d73..bf5ce43 100644 (file)
@@ -45,6 +45,8 @@ class AliTimestamp : public TTimeStamp
   Int_t GetDifference(AliTimestamp& t,Int_t& days,Int_t& sec,Int_t& ns,Int_t& ps); // Provide time difference
   Double_t GetDifference(AliTimestamp* t,TString u,Int_t mode=1); // Provide time diff. in specified units
   Double_t GetDifference(AliTimestamp& t,TString u,Int_t mode=1); // Provide time diff. in specified units
+  void SetUT(Int_t y,Int_t m,Int_t d,Int_t hh,Int_t mm,Int_t ss,Int_t ns=0,Int_t ps=0); // Set specified UT
+  void SetUT(Int_t y,Int_t d,Int_t s,Int_t ns=0,Int_t ps=0); // Set UT based on elapsed days, secs etc...
 
  protected:
   Int_t fMJD;  // Modified Julian Date
@@ -57,6 +59,6 @@ class AliTimestamp : public TTimeStamp
   Int_t fCalcs;      // The TTimeStamp seconds counter value at Julian parameter calculation
   Int_t fCalcns;     // The TTimeStamp nanoseconds counter value at Julian parameter calculation
 
- ClassDef(AliTimestamp,4) // Handling of timestamps for (astro)particle physics research.
+ ClassDef(AliTimestamp,5) // Handling of timestamps for (astro)particle physics research.
 };
 #endif
index 28b4112..7c4d41c 100644 (file)
                 statements by while() loops in determining the remaining fractional counts.
                 Furthermore, some modulo operations have been introduced to prevent
                 integer overflows.
+08-dec-2006 NvE Memberfunctions SetUT introduced in AliTimestamp to provide convenient
+                ways to set a specific UT date/time.
 
index d8f4f9d..a94405b 100644 (file)
@@ -10,4 +10,5 @@
  
 #include "IceF2k.h"
 #include "IceCal2Root.h"
+#include "IceRawTWR.h"
 
index 0744171..6e6870c 100644 (file)
@@ -14,6 +14,7 @@
  #pragma link off all functions;
  
  #pragma link C++ class IceF2k+;
- #pragma link C++ class IceCal2Root;
+ #pragma link C++ class IceCal2Root+;
+ #pragma link C++ class IceRawTWR+;
 #endif
  
index 1fccbd7..2149491 100644 (file)
 // been specified via the SetOutputFile memberfunction.
 // In case no outputfile has been specified, this class provides a facility
 // to investigate/analyse F2K data using the Ralice/IcePack analysis tools.
+// An indication of the active DAQ system is available in the IceEvent structure
+// via a device named "Daq". Here the various daq systems (TWR, Muon, ...)
+// from which the actual hits (ADC, LE, TOT) are composed have been indicated
+// as "signals" of the device itself. 
 //
 // Note : Sometimes the filtering/reco process which produced the F2K file
 //        may have introduced a shift (i.e. offset) in the hit times w.r.t.
@@ -425,6 +429,12 @@ void IceF2k::Exec(Option_t* opt)
 
  ListEnvironment();
 
+ // Set DAQ device info
+ AliDevice daq;
+ daq.SetName("Daq");
+ daq.SetSlotName("Muon",1);
+ daq.SetSignal(1,1);
+
  Int_t nevt=0;
  for (Int_t ifile=0; ifile<ninfiles; ifile++)
  {
@@ -470,6 +480,8 @@ void IceF2k::Exec(Option_t* opt)
    evt->SetEventNumber(fEvent.enr);
    evt->SetMJD(fEvent.mjd,fEvent.secs,fEvent.nsecs);
 
+   evt->AddDevice(daq);
+
    // Take trigger offset into account which might have been
    // introduced during the filtering process.
    // For simulated data this will be treated separately in PutMcTracks().
diff --git a/RALICE/icepack/iceconvert/IceRawTWR.cxx b/RALICE/icepack/iceconvert/IceRawTWR.cxx
new file mode 100644 (file)
index 0000000..e15484a
--- /dev/null
@@ -0,0 +1,1238 @@
+/*******************************************************************************
+ * Copyright(c) 2003, IceCube Experiment at the South Pole. All rights reserved.
+ *
+ * Author: The IceCube RALICE-based Offline 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 IceRawTWR
+// Conversion of Amanda raw TWR data into IceEvent data structures.
+// The code to actually read the TWR raw data structures is an Ralice/IcePack
+// implementation of Wolfgang Wagner's (Dortmund University, Germany)
+// original read_twr_binary_file.cxx and wf2hit_new.cxx source code.
+// The trigger information as encountered in the raw data, is available
+// in the IceEvent structure via a device named "Trigger".
+// The various triggers (and times) have been stored as different "hits"
+// in this "Trigger" device, just like it was done in the IceF2k processor
+// for the mu-daq F2K data.
+// An indication of the active DAQ system is available in the IceEvent structure
+// via a device named "Daq". Here the various daq systems (TWR, Muon, ...)
+// from which the actual hits (ADC, LE, TOT) eventually will be composed
+// are indicated as "signals" of the device itself. 
+// 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 raw TWR data and before the final structures are written out.
+// Note that the data structures are only written out if an outputfile has
+// been specified via the SetOutputFile memberfunction.
+// In case no outputfile has been specified, this class provides a facility
+// to investigate/analyse raw TWR data using the Ralice/IcePack analysis tools.
+//
+// Usage example :
+// ---------------
+//
+// gSystem->Load("ralice");
+// gSystem->Load("icepack");
+// gSystem->Load("iceconvert");
+//
+// IceRawTWR q("IceRawTWR","TWR raw data to IcePack data structure conversion");
+//
+// // Limit the number of entries for testing
+// q.SetMaxEvents(10);
+//
+// // Print frequency to produce a short summary print every printfreq events
+// q.SetPrintFreq(1);
+//
+// // The TWR raw data input filename(s)
+// q.AddInputFile("twr_2005_101_009225_0983_57784_57850.dat.twr.to_tape_1");
+//
+// // Output file for the event structures
+// q.SetOutputFile("events.root");
+//
+// ///////////////////////////////////////////////////////////////////
+// // 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();
+//
+//--- Author: Nick van Eijndhoven 12-dec-2006 Utrecht University
+//- Modified: NvE $Date$ Utrecht University
+///////////////////////////////////////////////////////////////////////////
+#include "IceRawTWR.h"
+#include "Riostream.h"
+
+ClassImp(IceRawTWR) // Class implementation to enable ROOT I/O
+
+IceRawTWR::IceRawTWR(const char* name,const char* title) : AliJob(name,title)
+{
+// Default constructor.
+// By default maxevent=-1, split=0, bsize=32000, printfreq=1.
+
+ fSplit=0;
+ fBsize=32000;
+ fMaxevt=-1;
+ fPrintfreq=1;
+ fInfiles=0;
+ fOutfile=0;
+}
+///////////////////////////////////////////////////////////////////////////
+IceRawTWR::~IceRawTWR()
+{
+// Default destructor.
+
+ if (fInfiles)
+ {
+  delete fInfiles;
+  fInfiles=0;
+ }
+}
+///////////////////////////////////////////////////////////////////////////
+void IceRawTWR::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 IceRawTWR::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 IceRawTWR::SetSplitLevel(Int_t split)
+{
+// Set the split level for the ROOT data file.
+// split=0 is the default initialisation in the constructor.
+ if (split>=0) fSplit=split;
+}
+///////////////////////////////////////////////////////////////////////////
+void IceRawTWR::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 IceRawTWR::AddInputFile(TString name)
+{
+// Add the name of this TWR raw data input file to the list to be processed.
+
+ if (!fInfiles)
+ {
+  fInfiles=new TObjArray();
+  fInfiles->SetOwner();
+ }
+
+ TObjString* s=new TObjString();
+ s->SetString(name);
+ fInfiles->Add(s);
+}
+///////////////////////////////////////////////////////////////////////////
+void IceRawTWR::SetOutputFile(TFile* ofile)
+{
+// Set the output file for the ROOT data.
+ if (fOutfile) delete fOutfile;
+ fOutfile=ofile;
+}
+///////////////////////////////////////////////////////////////////////////
+void IceRawTWR::SetOutputFile(TString name)
+{
+// Create the output file for the ROOT data.
+ if (fOutfile) delete fOutfile;
+ fOutfile=new TFile(name.Data(),"RECREATE","F2K data in IceEvent structure");
+}
+///////////////////////////////////////////////////////////////////////////
+TFile* IceRawTWR::GetOutputFile()
+{
+// Provide pointer to the ROOT output file.
+ return fOutfile;
+}
+///////////////////////////////////////////////////////////////////////////
+void IceRawTWR::Exec(Option_t* opt)
+{
+// Job to loop over the specified number of events and convert the 
+// TWR raw data into the IceEvent structure.
+// 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 a raw data 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 (!fInfiles)
+ {
+  cout << " *IceRawTWR Exec* No data input file(s) specified." << endl;
+  return;
+ }
+
+ Int_t ninfiles=fInfiles->GetEntries();
+ if (!ninfiles)
+ {
+  cout << " *IceRawTWR Exec* No data input file(s) specified." << endl;
+  return;
+ }
+
+ TTree* otree=0;
+ if (fOutfile)
+ {
+  otree=new TTree("T","TWR raw data converted to IceEvent structures");
+  otree->SetDirectory(fOutfile);
+ }
+
+ IceEvent* evt=new IceEvent();
+ evt->SetTrackCopy(1);
+ evt->SetDevCopy(1);
+
+ // Branch in the tree for the event structure
+ if (otree) otree->Branch("IceEvent","IceEvent",&evt,fBsize,fSplit); 
+
+ // Initialise the job working environment
+ SetMainObject(evt);
+ if (fOutfile)
+ {
+  AddObject(fOutfile);
+  AddObject(otree);
+ }
+
+ TString inputfile;
+
+ cout << " ***" << endl;
+ cout << " *** Start processing of job " << GetName() << " ***" << endl;
+ cout << " ***" << endl;
+ for (Int_t i=0; i<ninfiles; i++)
+ {
+  TObjString* sx=(TObjString*)fInfiles->At(i);
+  if (!sx) continue;
+  inputfile=sx->GetString(); 
+  cout << " TWR raw data input file : " << inputfile.Data() << endl;
+ }
+ cout << " Maximum number of events to be processed : " << fMaxevt << endl;
+ cout << " Print frequency : " << fPrintfreq << endl;
+ if (fOutfile)
+ {
+  cout << " ROOT output file : " << fOutfile->GetName() << endl;
+  cout << " Output characteristics : splitlevel = " << fSplit << " buffersize = " << fBsize << endl;
+ }
+
+ ListEnvironment();
+
+ // Storage of the used parameters in the IceRawTWR device
+ AliDevice params;
+ params.SetNameTitle("IceRawTWR","IceRawTWR processor parameters");
+ params.SetSlotName("Nchannels",1);
+ params.SetSlotName("Ntriggers",2);
+ params.SetSlotName("BaselineOffset",3);
+ params.SetSignal(float(N_OF_CHANNELS),1);
+ params.SetSignal(float(N_OF_TRIGGERS),2);
+ params.SetSignal(float(BASELINE_MEAN_MAGIC),3);
+
+ // Set DAQ device info
+ AliDevice daq;
+ daq.SetName("Daq");
+ daq.SetSlotName("TWR",1);
+ daq.SetSignal(1,1);
+
+ twr_raw_data_file_t twr_file;
+ Int_t year,runnum,evtnum;
+
+ Int_t error;
+ UInt_t nhead;
+
+ GPS_t gps;
+ UInt_t gpslow,gpshigh,gpssecs; // The GPS time information
+ Int_t seconds,nsecs;           // Seconds and nanoseconds since start of the UT year
+
+ Int_t nevt=0;
+ fHeader=0;
+ for (Int_t ifile=0; ifile<ninfiles; ifile++)
+ {
+  TObjString* sx=(TObjString*)fInfiles->At(ifile);
+  if (!sx) continue;
+
+  inputfile=sx->GetString(); 
+  if (inputfile=="") continue;
+
+  // Open the TWR raw data input file in binary mode
+  fInput=fopen(inputfile.Data(),"rb");
+
+  if (!fInput)
+  {
+   cout << " *IceRawTWR Exec* No input file found with name : " << inputfile.Data() << endl;
+   continue;
+  }
+
+  // Extract info like run number, file number etc... from filename
+  extract_info_from_filename((char*)inputfile.Data(),&twr_file);
+
+  year=twr_file.year;
+  runnum=twr_file.run_no;
+
+  // Initialise the event structure 
+  clear_event(&fEvent);
+
+  // Read the file header information
+  error=read_header_from_file(fInput,&fHeader,&nhead);
+
+  if (error || !nhead) 
+  {
+   cout << " *IceRawTWR Exec* Error in header for input file : " << inputfile.Data() << endl;
+   continue;
+  }
+
+  // Correct the mapping
+  update_system(fHeader,runnum);
+  while (!read_event(fInput,fHeader,&fEvent))
+  {
+   if (fMaxevt>-1 && nevt>=fMaxevt) break;
+
+   evtnum=fEvent.eventcounter;
+
+   // The GPS telegram info
+   gps=fEvent.gps;
+   gpslow=gps.seconds;            // The low 24 bits of the seconds count
+   gpshigh=gps.info.bits.seconds; // The high 8 bits of the seconds count
+   gpssecs=gpshigh<<24;
+   gpssecs+=gpslow;
+
+   // Seconds and nanoseconds since the start of the UT year
+   seconds=gpssecs;
+   nsecs=100*gps.count_10MHz;
+   
+   // Reset the complete Event structure
+   evt->Reset();
+
+   evt->SetRunNumber(runnum);
+   evt->SetEventNumber(evtnum);
+   evt->SetUT(year,0,seconds,nsecs);
+
+   evt->AddDevice(params);
+   evt->AddDevice(daq);
+
+   PutTrigger(year);
+
+   PutWaveforms(year);
+
+   // Invoke all available sub-tasks (if any)
+   CleanTasks();
+   ExecuteTasks(opt);
+
+   if (fPrintfreq)
+   {
+    if (!(nevt%fPrintfreq)) evt->HeaderData();
+   }
+
+   // Write the complete structure to the output Tree
+   if (otree) otree->Fill();
+
+   // Update event counter
+   nevt++;
+
+   // Reset the raw event structure 
+   clear_event(&fEvent);
+  } // End of event reading loop
+
+  // Delete the file header structure
+  clear_system(fHeader);
+
+  if (fMaxevt>-1 && nevt>=fMaxevt) break;
+
+ } // End of input file loop
+
+ // Flush possible memory resident data to the output file
+ if (fOutfile) fOutfile->Write();
+
+ // Remove the IceEvent object from the environment
+ // and delete it as well
+ if (evt)
+ {
+  RemoveObject(evt);
+  delete evt;
+ }
+}
+///////////////////////////////////////////////////////////////////////////
+void IceRawTWR::PutWaveforms(Int_t year)
+{
+// Get the waveform info from the raw data event into the IcePack structure.
+
+ IceEvent* evt=(IceEvent*)GetMainObject();
+ if (!evt) return;
+
+ // Loop over all the waveforms and add the histo(s) to the corresponding OM's
+ TH1F histo;
+ Int_t nbins=0;
+ Float_t xlow=0;
+ Float_t xup=0;
+ TString hname;
+ IceAOM om;
+ IceAOM* omx=0;
+ Int_t omid;
+ Int_t omidmax=680;
+ Int_t error;
+ Float_t baseline;
+ for (Int_t i=0; i<N_OF_CHANNELS; i++)
+ {
+  if (!fEvent.wfm_filled[i]) continue;
+
+  omid=fEvent.twr_id_of_om[i];
+  if (omid<=0 || omid>omidmax) continue; // Skip trigger channels
+
+  // Get corresponding device from the current event structure  
+  omx=(IceAOM*)evt->GetIdDevice(omid);
+  if (!omx)
+  {
+   om.Reset(1);
+   om.SetUniqueID(omid);
+   evt->AddDevice(om);
+   omx=(IceAOM*)evt->GetIdDevice(omid);
+  }
+
+  if (!omx) continue;
+
+  clear_waveform_analysis(&fWform);
+  error=restore_waveform(fEvent.wfm[i],&fWform,year);
+
+  if (error) continue;
+
+  baseline=fWform.frag_mean[0];
+
+  hname="BASELINE-WF";
+  hname+=omx->GetNwaveforms()+1;
+  omx->AddNamedSlot(hname);
+  omx->SetSignal(baseline,hname);
+
+  // Fill the waveform histogram
+  hname="OM";
+  hname+=omid;
+  hname+="-WF";
+  hname+=omx->GetNwaveforms()+1;
+
+  histo.Reset();
+  histo.SetName(hname.Data());
+  nbins=fWform.n_point;
+  xlow=fWform.wfm_x[0];
+  xup=fWform.wfm_x[nbins-1];
+  histo.SetBins(nbins,xlow,xup);
+
+  for (Int_t jbin=1; jbin<=nbins; jbin++)
+  {
+   histo.SetBinContent(jbin,baseline-fWform.wfm_y[jbin-1]);
+  }
+
+  omx->SetWaveform(&histo,omx->GetNwaveforms()+1);
+ }
+}
+///////////////////////////////////////////////////////////////////////////
+void IceRawTWR::PutTrigger(Int_t year)
+{
+// Get the trigger info from the raw data event into the IcePack structure.
+// Currently only the trigger settings for the years 2005 and 2006 have been
+// implemented.
+// In addition to the hardware and software triggers as encountered in the
+// raw data, an artificial "main" trigger has been introduced.
+// This artificial "main" trigger is just an "or" of the standard hard and soft
+// triggers (except calibration and random triggers) and serves only to
+// provide a generic "main" trigger a la Amanda mu-daq so that the default
+// "IceCleanHits" hit cleaning procedure will work correctly.
+// The trigger time for the artificial "main" trigger is taken to be the
+// time of the earliest hardware trigger pulse. In case there is no hardware
+// trigger pulse available, the "main" trigger time is set to 0.
+// For other years, only the artificial "main" trigger with a trigger time
+// set to 0 will be stored in the IceEvent structure.
+
+ // Fill the trigger structure
+ Int_t error=retrigger(&fEvent,&fTrigger);
+ if (error) return;
+
+ IceEvent* evt=(IceEvent*)GetMainObject();
+ if (!evt) return;
+
+ AliDevice trig;
+ trig.SetNameTitle("Trigger","Amanda/IceCube event triggers");
+ AliSignal s;
+ Float_t trigtime=0;
+
+ if (year !=2005 && year != 2006)
+ {
+  s.SetName("main");
+  s.SetUniqueID(0);
+  s.SetSlotName("trig_pulse_le",1);
+  s.SetSignal(trigtime,1);
+  trig.AddHit(s);
+  // Store the trigger data into the IceEvent structure
+  evt->AddDevice(trig);
+  return;
+ }
+
+ // Trigger settings for 2005 and 2006
+ if (!fTrigger.n_software_trigger && !fTrigger.n_hardware_trigger) return;
+
+ TString trignames[N_OF_TRIGGERS]={"m24","m18","string","spase","cal-t0","cal-la","m12",
+                                   "main-logic","main-or","random","m20-frag","volume"};
+ Int_t imain=0;
+ for (Int_t i=0; i<N_OF_TRIGGERS; i++)
+ {
+  if (!fTrigger.trigger_active[i]) continue;
+
+  s.Reset(1);
+  s.SetName(trignames[i]);
+  s.SetUniqueID(i);
+  trigtime=0;
+  if (fTrigger.trigger_has_pulse[i]) trigtime=fTrigger.trigger_time[i];
+  s.SetSlotName("trig_pulse_le",1);
+  s.SetSignal(trigtime,1);
+  trig.AddHit(s);
+  // Set flag to indicate creation of artificial "main" trigger
+  if (i!=4 && i!=5 && i!=9) imain=1;
+ }
+
+ // Set the artificial "main" trigger
+ if (imain)
+ {
+  s.Reset(1);
+  s.SetName("main");
+  s.SetUniqueID(N_OF_TRIGGERS);
+  s.SetSlotName("trig_pulse_le",1);
+  trigtime=0;
+  if (fTrigger.first_trigger>=0) trigtime=fTrigger.first_trigger_time;
+  s.SetSignal(trigtime,1);
+  trig.AddHit(s);
+ }
+
+ // Store the trigger data into the IceEvent structure
+ evt->AddDevice(trig);
+}
+///////////////////////////////////////////////////////////////////////////
+Int_t IceRawTWR::extract_info_from_filename(char* fname,twr_raw_data_file_t* twr_file)
+{
+  char start_str[20],year_str[20],day_str[20],run_no_str[20], 
+       file_no_str[20],begin_str[20],end_str[20];
+  char* filename;
+
+  filename = strstr(fname, "twr");
+  if(filename == NULL)
+  if(strncmp("twr_", start_str, 4)) 
+    {
+      printf("%s\n", filename);
+      return(ERROR_NOT_VALID_FILENAME);
+    }
+
+  strncpy(start_str, filename, 4);
+  if(strncmp("twr_", start_str, 4)) 
+    {
+      printf("%s %s\n", filename, start_str);
+      return(ERROR_NOT_VALID_FILENAME);
+    }
+  strncpy(year_str, &filename[4], 4);
+  twr_file->year = strtol(year_str, 0, 10);
+
+  if(twr_file->year==2003)
+    {
+      strncpy(day_str, &filename[9], 3);
+      day_str[3] = '\0';
+      twr_file->day = strtol(day_str, 0, 10);
+      
+      strncpy(run_no_str, &filename[13], 4);
+      run_no_str[4] = '\0';
+      twr_file->run_no = strtol(run_no_str, 0, 10);
+      
+      strncpy(file_no_str, &filename[18], 4);
+      file_no_str[4] = '\0';
+      twr_file->file_no = strtol(file_no_str, 0, 10);
+    }
+  
+  if(twr_file->year==2004)
+    {
+      strncpy(day_str, &filename[9], 3);
+      day_str[3] = '\0';
+      twr_file->day = strtol(day_str, 0, 10);
+      
+      strncpy(run_no_str, &filename[13], 4);
+      run_no_str[4] = '\0';
+      twr_file->run_no = strtol(run_no_str, 0, 10);
+      
+      strncpy(file_no_str, &filename[18], 4);
+      file_no_str[4] = '\0';
+      twr_file->file_no = strtol(file_no_str, 0, 10);
+      
+      strncpy(begin_str, &filename[23], 5);
+      begin_str[5] = '\0';
+      twr_file->begin = strtol(begin_str, 0, 10);
+      
+      strncpy(end_str, &filename[29], 5);
+      end_str[5] = '\0';
+      twr_file->end = strtol(end_str, 0, 10);
+    }
+
+  if(twr_file->year > 2004)      
+    {
+      strncpy(day_str, &filename[9], 3);
+      day_str[3] = '\0';
+      twr_file->day = strtol(day_str, 0, 10);
+      
+      strncpy(run_no_str, &filename[13], 6);
+      run_no_str[6] = '\0';
+      twr_file->run_no = strtol(run_no_str, 0, 10);
+      
+      strncpy(file_no_str, &filename[20], 4);
+      file_no_str[4] = '\0';
+      twr_file->file_no = strtol(file_no_str, 0, 10);
+      
+      strncpy(begin_str, &filename[25], 5);
+      begin_str[5] = '\0';
+      twr_file->begin = strtol(begin_str, 0, 10);
+      
+      strncpy(end_str, &filename[31], 5);
+      end_str[5] = '\0';
+      twr_file->end = strtol(end_str, 0, 10);
+    }
+  return(0);
+}
+///////////////////////////////////////////////////////////////////////////
+Int_t IceRawTWR::clear_system(sys_config_t* sys)
+{
+// Deletion of the file header structure.
+
+ if (!sys) return 0;
+
+ for(Int_t icrate=0; icrate < sys->n_crates; icrate++)
+ {
+  if (!sys->crate[icrate]) continue;
+  for(Int_t itwr=0; itwr < sys->crate[icrate]->n_twr; itwr++)
+  {
+   if (sys->crate[icrate]->twr[itwr]) delete sys->crate[icrate]->twr[itwr];
+  }
+  delete sys->crate[icrate];
+ }
+ delete sys;
+ sys=0;
+ return 0;
+}
+///////////////////////////////////////////////////////////////////////////
+Int_t IceRawTWR::clear_event(event_t* event_ptr)
+{
+  Int_t i_value;
+  Int_t *int_ptr = (int*) event_ptr;
+
+  for(i_value=0; i_value < sizeof(event_t)/sizeof(Int_t); i_value++)
+    {
+      *int_ptr++ = 0;
+    }
+  return(0);
+}
+///////////////////////////////////////////////////////////////////////////
+Int_t IceRawTWR::read_header_from_file(FILE* fin,sys_config_t** system_ptr,UInt_t* header_length)
+{
+  Int_t i_crate, i_twr, i_channel;
+  UInt_t count_twr_in_system = 0;
+  UInt_t length = 0;
+  UInt_t dummy;
+  
+  sys_config_t *sys;
+
+  // allocating memory for sys_config structure
+  sys = (sys_config_t*) malloc( sizeof(sys_config_t) );
+
+  fread(&dummy,sizeof(UInt_t),1,fin); // Header Begin Mark
+
+  fread(header_length,sizeof(UInt_t),1,fin);   // Length of header
+  fread(&sys->clockdiv,sizeof(UInt_t),1,fin);  
+  fread(&sys->n_crates,sizeof(UInt_t),1,fin);   
+
+  if( (sys->n_crates > MAX_N_CRATES) || (sys->n_crates < 0) )
+    return(ERROR_TOO_MANY_CRATES);
+
+  for(i_crate=0; i_crate < sys->n_crates; i_crate++)
+    {
+      sys->crate[i_crate] = 
+       (crate_config_t*) malloc( sizeof(crate_config_t) );
+
+      fread(&sys->crate[i_crate]->vme_base_bridge,sizeof(UInt_t),1,fin); 
+      fread(&sys->crate[i_crate]->vme_base_100MHz,sizeof(UInt_t),1,fin); 
+      fread(&sys->crate[i_crate]->base_gps,sizeof(UInt_t),1,fin); 
+      fread(&sys->crate[i_crate]->n_twr,sizeof(UInt_t),1,fin); 
+      
+      if( (sys->crate[i_crate]->n_twr > MAX_N_TWR_PER_CRATE) 
+         || (sys->crate[i_crate]->n_twr < 0) )
+       return(ERROR_TOO_MANY_TWRS);
+
+      for(i_twr=0; i_twr < sys->crate[i_crate]->n_twr; i_twr++)
+       {
+         sys->crate[i_crate]->twr[i_twr] = 
+           (twr_config_t*) malloc( sizeof(twr_config_t) );
+         count_twr_in_system++;
+         fread(&sys->crate[i_crate]->twr[i_twr]->base, 
+              sizeof(UInt_t),1,fin);
+         fread(&sys->crate[i_crate]->twr[i_twr]->id, 
+              sizeof(UInt_t),1,fin);
+
+         sys->crate[i_crate]->twr[i_twr]->id 
+           = sys->crate[i_crate]->twr[i_twr]->id - 0x10; /* Correct */
+
+
+         fread(&dummy,sizeof(UInt_t),1,fin); /* stat_reg */
+         fread(&sys->crate[i_crate]->twr[i_twr]->mod_id, 
+              sizeof(UInt_t),1,fin);
+         fread(&dummy,sizeof(UInt_t),1,fin); /* acq_ctrl */
+         fread(&sys->crate[i_crate]->twr[i_twr]->ext_start, 
+              sizeof(UInt_t),1,fin);
+         fread(&sys->crate[i_crate]->twr[i_twr]->ext_stop, 
+              sizeof(UInt_t),1,fin);
+         fread(&dummy,sizeof(UInt_t),1,fin); /* evtconfig */
+
+         for(i_channel = 0; i_channel < CHANNELS_PER_TWR; i_channel++)
+           {
+             fread(&sys->crate[i_crate]->twr[i_twr]->om_no[i_channel], 
+                  sizeof(UInt_t),1,fin);
+           }
+
+         for(i_channel = 0; i_channel < CHANNELS_PER_TWR; i_channel++)
+           {
+             fread(&sys->crate[i_crate]->twr[i_twr]->om_is_optical[i_channel], 
+                  sizeof(UInt_t),1,fin);
+           }
+
+         for(i_channel = 0; i_channel < CHANNELS_PER_TWR; i_channel++)
+           {
+             fread(&sys->crate[i_crate]->twr[i_twr]->baseline[i_channel], 
+                  sizeof(UInt_t),1,fin);
+           }
+
+         for(i_channel = 0; i_channel < CHANNELS_PER_TWR; i_channel++)
+           {
+             fread(&sys->crate[i_crate]->twr[i_twr]->threshold[i_channel],
+                  sizeof(UInt_t),1,fin);
+           }
+
+         sys->twr_field[(i_crate * 0x10) + i_twr]
+             = sys->crate[i_crate]->twr[i_twr];
+         
+         /* Bug fix needed */
+         for(i_channel=0; i_channel < 8; i_channel++)
+         {
+            if( sys->crate[i_crate]->twr[i_twr]->om_no[i_channel] == 9000 )
+                sys->crate[i_crate]->twr[i_twr]->om_no[i_channel] 
+                  = N_OF_CHANNELS - 1; 
+         }
+       }
+    }
+
+  // Set number of TWRs in system
+  sys->n_twr = count_twr_in_system;
+
+  *system_ptr = sys;
+  return(0);
+}
+///////////////////////////////////////////////////////////////////////////
+Int_t IceRawTWR::update_system(sys_config_t* sys,Int_t run_number)
+{
+  Int_t i_crate, i_twr, i_channel;
+
+  UInt_t ext_stop;  /* DO NOT CHANGE THIS VALUE !! */
+
+  /* Data for bug fix 1 */
+  UInt_t om_no_w1[CHANNELS_PER_TWR] 
+    = {639, 642, 1, 9, 10, 11, 12, 30}; 
+  
+  UInt_t om_no_r1[CHANNELS_PER_TWR] 
+    = {111, 112, 113, 114, 115, 116, 39, 118}; 
+  UInt_t om_is_optical_r1[CHANNELS_PER_TWR] 
+     = {0, 0, 0, 0, 0, 0, 0, 0};
+  UInt_t threshold_r1[CHANNELS_PER_TWR]
+    = {50, 50, 50, 50, 50, 50, 80, 50};
+
+  UInt_t om_no_w2[CHANNELS_PER_TWR] 
+    = {492, 493, 495, 496, 497, 499, 500, 501}; 
+  
+  UInt_t om_no_r2[CHANNELS_PER_TWR] 
+    = {473, 484, 485, 486, 487, 475, 490, 491}; 
+  UInt_t om_is_optical_r2[CHANNELS_PER_TWR] 
+     = {1, 1, 1, 1, 1, 1, 1, 1};
+  UInt_t threshold_r2[CHANNELS_PER_TWR]
+    = {15, 50, 55, 40, 15, 23, 15, 15};
+
+  
+  /* Bugfix 1 Andreas Bug */ 
+
+  /*
+    By accident this TWR was counted twice in TWR.cnf
+    as Crate 0 TWR 7 and Crate 4 TWR 7
+    from run up to run
+    TWR_OM          639     642     1       9       10      11      12      30
+    OPTICAL         0       0       0       0       0       0       0       0
+    TWR_BASELINE    110     120     110     140     150     160     170     180
+    TWR_THRESHOLD   50      50      80      80      80      80      80      80
+
+    Crate 4 TWR 7 should be replaced with this TWR
+    TWR_OM          111     112     113     114     115     116     39      118
+    OPTICAL         0       0       0       0       0       0       0       0
+    TWR_BASELINE    110     120     130     140     150     160     170     180
+    TWR_THRESHOLD   50      50      50      50      50      50      80      50
+  */
+
+  if( 
+     (run_number >= 9153 )  /* Begin season 2005 13.2.05 */  
+     && (run_number < 9800) /* Timo corrected TWR.cnf on after run ??? */
+     /* Need to find exact date */
+     )
+    {
+      i_crate = 4;
+      i_twr = 7;
+      for(i_channel = 0; i_channel < CHANNELS_PER_TWR; i_channel++)
+       {
+         sys->crate[i_crate]->twr[i_twr]->om_no[i_channel]         
+           = om_no_r1[i_channel]; 
+         sys->crate[i_crate]->twr[i_twr]->om_is_optical[i_channel] 
+           = om_is_optical_r1[i_channel]; 
+         sys->crate[i_crate]->twr[i_twr]->threshold[i_channel]     
+           = threshold_r1[i_channel];
+       }
+    }
+
+  /* Bugfix 2 Timos Bug */ 
+
+  /*
+    By accident this TWR was counted twice in TWR.cnf
+    as Crate 0 TWR 1 and Crate 5 TWR b
+    from run 9153 up to run 9188
+
+    TWR_OM          492     493     495     496     497     499     500     501
+    OPTICAL         1       1       1       1       1       1       1       1
+    TWR_BASELINE    110     120     130     140     150     160     170     180
+    TWR_THRESHOLD   16      45      25      42      35      46      15      15
+
+    Crate 5 TWR b should be corrected to 
+    TWR_OM          473     484     485     486     487     475     490     491
+    OPTICAL         1       1       1       1       1       1       1       1
+    TWR_BASELINE    4000    120     130     140     150     4000    170     180
+    TWR_THRESHOLD   15      50      55      40      15      23      15      15
+  */
+
+  if( 
+     (run_number >= 9153 )  /* Begin season 2005 = Feb 2nd 05 */  
+     && (run_number < 9189) /* Timo corrected TWR.cnf on      */
+     /* Mar 15th 05 = day 74 after run 9188                   */
+     )
+    {
+      i_crate = 5;
+      i_twr = 0xb;
+      for(i_channel = 0; i_channel < CHANNELS_PER_TWR; i_channel++)
+       {
+         sys->crate[i_crate]->twr[i_twr]->om_no[i_channel]         
+           = om_no_r2[i_channel]; 
+         sys->crate[i_crate]->twr[i_twr]->om_is_optical[i_channel] = 
+           om_is_optical_r2[i_channel]; 
+         sys->crate[i_crate]->twr[i_twr]->threshold[i_channel]     = 
+           threshold_r2[i_channel];
+       }
+    }
+ return(0);
+}
+///////////////////////////////////////////////////////////////////////////
+Int_t IceRawTWR::read_event(FILE* fin,sys_config_t* sys,event_t* event_ptr)
+{
+    UInt_t i_channel, i_twr, i_crate, i_wfm;
+    UInt_t header_length, length_of_event_block;
+    
+    Int_t n_twr, n_of_waveforms_in_event, read_number;
+    UInt_t length_wfm[CHANNELS_PER_TWR];
+    UInt_t dummy, channel_no, om_no, twr_no;
+    
+    // Reset waveform filled register
+    memset(&event_ptr->wfm_filled[0], 0, sizeof(UInt_t) * N_OF_CHANNELS);
+
+    if( !fread(&dummy,sizeof(UInt_t),1,fin) ) return(1);
+
+    if(dummy != 0xbbbbbbbb) 
+    {
+       printf("Wrong event begin mark %x\n", dummy); 
+       while( (dummy !=0xbbbbbbbb) 
+              && (fread(&dummy,sizeof(UInt_t),1,fin) != 0) )
+         {;//printf("dummy:%x\n", dummy);
+         }
+    }
+    if( !fread(&length_of_event_block,sizeof(UInt_t),1,fin) ) return(1);
+    if( !fread(&event_ptr->eventcounter,sizeof(UInt_t),1,fin) ) return(1);
+    if( !fread(&event_ptr->which_trigger,sizeof(UInt_t),1,fin) ) return(1);
+    if( !fread(&event_ptr->gps,sizeof(GPS_t),1,fin) ) return(1);
+       
+    // --reading waveforms from TWR blocks
+    n_twr = 0;
+    while(n_twr < sys->n_twr)
+    {
+       // --read TWR header
+       if( !fread(&dummy,sizeof(UInt_t),1,fin) ) return(1);
+       if(dummy != 0xffffffff) 
+       {printf("Wrong twr begin mark %x\n", dummy); return(2);}
+       if( !fread(&twr_no,sizeof(UInt_t),1,fin) ) return(1);
+
+        // nur voruebergehend !!
+       twr_no -= 0x10;
+
+       if( !fread(&event_ptr->twr[twr_no].timestamp,sizeof(UInt_t),1,fin) ) 
+           return(1);
+       if( !fread(&n_of_waveforms_in_event,sizeof(UInt_t),1,fin) ) 
+           return(1);
+       event_ptr->twr[twr_no].n_wfm = n_of_waveforms_in_event;
+
+       for(i_wfm=0; i_wfm < n_of_waveforms_in_event; i_wfm++)
+       {
+           if( !fread(&length_wfm[i_wfm],sizeof(UInt_t),1,fin) ) return(1);
+       }
+           
+       // read waveforms
+       for(i_wfm=0; i_wfm < n_of_waveforms_in_event; i_wfm++)
+       {
+           if(length_wfm[i_wfm] != 0)
+           {
+             if( !fread(&channel_no,sizeof(UInt_t),1,fin) ) return(1);
+             if(sys->twr_field[twr_no]->om_no[channel_no] 
+                  < N_OF_CHANNELS)
+                   om_no = sys->twr_field[twr_no]->om_no[channel_no];
+               else
+                   om_no = N_OF_CHANNELS-1;
+
+               /* Fix needed */
+
+               event_ptr->twr_id_of_om[om_no] = twr_no;
+
+               read_number = fread(&event_ptr->wfm[om_no], 
+                                  length_wfm[i_wfm]-sizeof(UInt_t),1,fin);
+               event_ptr->wfm_filled[om_no] = 1;
+               if( !read_number ) return(1);
+
+                // read_number correction for usage of fread() instead of read()
+                read_number*=length_wfm[i_wfm]-sizeof(UInt_t);
+
+               if( read_number != length_wfm[i_wfm]-sizeof(UInt_t) ) 
+                {
+                  cout << " read_number : " << read_number
+                       << " length_wfm["<<i_wfm<<"] : " << length_wfm[i_wfm]
+                       << " sizeof(UInt_t) : " << sizeof(UInt_t) << endl;
+                 return(2);
+                }
+           }   
+       }
+       n_twr++;
+    } // end while n_twr
+    return(0);
+}
+///////////////////////////////////////////////////////////////////////////
+Int_t IceRawTWR::retrigger(event_t* ev,trigger_hits_t* trig)
+{
+// Returns the active trigger(s)
+
+ // Initialise the trigger_hits_t structure with zeroes
+ memset(trig, 0, sizeof(trigger_hits_t) );
+
+ // Obtain the software trigger info
+ trig->n_software_trigger=0;
+ for(Int_t itrigger=0; itrigger<N_OF_TRIGGERS; itrigger++)
+ {
+  if(ev->which_trigger & trigger_bits[itrigger])
+  {
+   //printf("SetTrigger %i\n", i_trigger);
+   trig->trigger_active[itrigger]=1;
+   trig->n_software_trigger++;
+  } 
+  else
+  {
+   trig->trigger_active[itrigger]=0;
+  }
+ }
+
+ // Obtain the hardware trigger info
+ trig->n_hardware_trigger=0;
+ trig->first_trigger_time=10000000;
+ trig->first_trigger=-1;
+
+ for(Int_t jtrigger=0; jtrigger<N_OF_TRIGGERS; jtrigger++)
+ {
+  if(!trigger_channel[jtrigger]) continue;
+
+  if(ev->wfm_filled[trigger_channel[jtrigger]])
+  {
+   trig->trigger_active[jtrigger]=1;
+   trig->trigger_time[jtrigger]=(ev->wfm[trigger_channel[jtrigger]].value[2] & 0xfff);
+   trig->trigger_has_pulse[jtrigger]=1;
+   if (trig->trigger_time[jtrigger] < trig->first_trigger_time)
+   {
+    trig->first_trigger_time=trig->trigger_time[jtrigger];
+    trig->first_trigger=jtrigger;
+   }
+   trig->n_hardware_trigger++;
+  }
+ }
+ return 0;
+}
+///////////////////////////////////////////////////////////////////////////
+Int_t IceRawTWR::clear_waveform_analysis(waveform_analyse_t* wfm_om)
+{
+  Int_t i_value, i_frag, i_edge, i_peak;
+
+  if(wfm_om == 0) return(1);
+
+  // output from analysis
+  wfm_om->n_frag = 0;
+  for(i_frag=0; i_frag < MAX_N_OF_FRAGS; i_frag++)
+    {
+      wfm_om->frag_n_points[i_frag] = 0;
+      wfm_om->frag_begin[i_frag] = 0;
+      wfm_om->frag_end[i_frag] = 0;
+      wfm_om->frag_mean[i_frag] = 0;
+      wfm_om->frag_begin_time[i_frag] = 0;
+    }
+  
+  wfm_om->n_peak = 0;
+  for(i_peak=0; i_peak < MAX_N_OF_PEAKS; i_peak++)
+    {
+      wfm_om->peak_begin[i_peak] = 0;
+      wfm_om->peak_end[i_peak] = 0;
+      wfm_om->peak_max[i_peak] = 0;
+      wfm_om->peak_TDC_edge[i_peak] = 0;
+      wfm_om->peak_local_minimum[i_peak] = 0;
+      wfm_om->crosstalk_charge_n_value[i_peak] = 0;
+      wfm_om->peak_in_fragment[i_peak] = 0;
+       
+      wfm_om->peak_mean[i_peak] = 0.0;
+    
+      wfm_om->peak_m[i_peak] = 0.0;
+      wfm_om->peak_b[i_peak] = 0.0;
+      wfm_om->peak_t0[i_peak] = 0.0;
+      wfm_om->peak_begin_time[i_peak] = 0.0; 
+      wfm_om->peak_charge[i_peak] = 0.0;
+      wfm_om->peak_height[i_peak] = 0.0;
+      wfm_om->fitted_amplitude[i_peak] = 0.0;
+      wfm_om->fitted_TOT[i_peak] = 0.0;
+      wfm_om->crosstalk_charge[i_peak] = 0.0;
+      wfm_om->crosstalk_slope[i_peak] = 0.0;
+    }
+  
+  wfm_om->n_point = 0;
+  wfm_om->wfm_min = 4095; 
+  wfm_om->wfm_max = 0; 
+  wfm_om->b_out_of_range = 0;
+  
+  for(i_value=0; i_value < 1024; i_value++)
+    {
+      wfm_om->wfm_x[i_value] = 0;
+      wfm_om->wfm_y[i_value] = 0;
+    }
+
+  wfm_om->n_tdc_edges = 0;
+  for(i_edge=0; i_edge < MAX_N_OF_TDC_EDGES; i_edge++)
+    {
+      wfm_om->leading_edge[i_edge] = 0.0;
+      wfm_om->falling_edge[i_edge] = 0.0;
+      wfm_om->identified_twr_hit[i_edge] = -1;
+    }
+
+ return(0);
+}
+///////////////////////////////////////////////////////////////////////////
+Int_t IceRawTWR::restore_waveform(waveform_t f_wfm,waveform_analyse_t* wfm_om,Int_t year)
+{
+    UShort_t wfm_length, mean;
+    static UShort_t tmp_wf[2000];
+
+    Int_t debug = 0;
+    Int_t fragment_start = 0; 
+    Int_t frag_count = 0;     // position in current fragment
+    Int_t n_position = 0;     // position in displayed waveform
+    UInt_t  n_word = 2;      // position in featured waveform
+    Int_t n_fragment = 0;     // actual fragment 
+    Int_t b_wrong_value = 0;
+
+    UShort_t assumed_frag_begin, last_value; /* bug in eventbuilder */
+
+    wfm_om->wfm_min = 4095.0;
+    wfm_om->wfm_max = 0.0;
+
+    if( (f_wfm.value[0] & 0xf000) != 0xf000 ) return(1);
+    wfm_length = (f_wfm.value[0] & 0xfff)/2;
+
+    mean = f_wfm.value[1] + BASELINE_MEAN_MAGIC;    
+    while( ((f_wfm.value[n_word] & 0xf000) == 0x4000) && 
+          (n_word < wfm_length) &&
+          (n_fragment < MAX_N_OF_FRAGS) )
+    {
+      fragment_start = f_wfm.value[n_word] & 0xfff;
+      n_word++;
+      wfm_om->frag_begin_time[n_fragment] 
+       = fragment_start * NSECS_PER_TWR_BIN;
+      wfm_om->frag_begin[n_fragment] = n_position;
+      wfm_om->frag_mean[n_fragment] = mean;
+      
+      b_wrong_value = 0;
+      frag_count = 0;
+      
+      while( ((f_wfm.value[n_word] & 0xf000) != 0x2000) &&
+            ((f_wfm.value[n_word] & 0xf000) != 0x4000) &&/*Reconstructable*/
+            !b_wrong_value && /* Buggy */
+            (n_word < wfm_length) )
+       {
+         if(year > 2004)
+           {
+             /* 2005 2006 data */
+             if(frag_count == 0)
+               {
+                 tmp_wf[n_word] = f_wfm.value[n_word] + mean;
+                 wfm_om->wfm_y[n_position] = (float) tmp_wf[n_word];
+                 wfm_om->wfm_x[n_position] = (float) 
+                   wfm_om->frag_begin_time[n_fragment]
+                   + (frag_count * NSECS_PER_TWR_BIN);
+               }
+             else if(frag_count == 1)
+               {
+                 tmp_wf[n_word] = f_wfm.value[n_word] + tmp_wf[n_word-1];
+                 wfm_om->wfm_y[n_position] = (float) tmp_wf[n_word];
+                 wfm_om->wfm_x[n_position] = (float) 
+                   wfm_om->frag_begin_time[n_fragment]
+                   + (frag_count * NSECS_PER_TWR_BIN);
+               }
+             else 
+               {
+                 tmp_wf[n_word] = 
+                   2*tmp_wf[n_word-1] + f_wfm.value[n_word];
+                 tmp_wf[n_word] -= tmp_wf[n_word-2];
+                 
+                 wfm_om->wfm_y[n_position] = (float) tmp_wf[n_word];
+                 wfm_om->wfm_x[n_position] = (float) 
+                   wfm_om->frag_begin_time[n_fragment]
+                   + (frag_count * NSECS_PER_TWR_BIN);
+               }
+             
+             
+             /*
+               Hack for wrongly merged overlapping fragments
+             */
+             if(tmp_wf[n_word] > 0x1fff)
+               {
+                 /* BUG FIXXXX                                         */
+                 /* assume that fragment merge in eventbuilder caused  */
+                 /* problem two fragments overlap in EXACTLY ONE point */
+                 /* and are merged first point of the added part of    */
+                 /* the fragment is encoded using the former fragment  */
+                 /* start as a data point                              */
+                 
+                 last_value         = tmp_wf[n_word-1];
+                 assumed_frag_begin = 0x4000 + fragment_start + frag_count;
+                 tmp_wf[n_word] =  f_wfm.value[n_word] + 2 * last_value;
+                 tmp_wf[n_word] -= assumed_frag_begin;
+                 wfm_om->wfm_y[n_position] = (float) tmp_wf[n_word];
+                 
+                 /* Look if value is still buggy */
+                 if(tmp_wf[n_word] > 0x1fff) b_wrong_value = 1;
+                 
+                 debug = ERROR_MISS_FRAG_STOP;
+               }
+           } /* end year >= 2005 */
+         else
+           {
+             /* 2003 2004 data */
+             wfm_om->wfm_y[n_position] = (float) f_wfm.value[n_word];
+             wfm_om->wfm_x[n_position] = (float) 
+               wfm_om->frag_begin_time[n_fragment]
+               + (frag_count * NSECS_PER_TWR_BIN);
+           } /* end year 2003 2004 */
+         
+         /* Set min and max Y */
+         
+         if(wfm_om->wfm_y[n_position] > wfm_om->wfm_max)
+           wfm_om->wfm_max = wfm_om->wfm_y[n_position];
+         if(wfm_om->wfm_y[n_position] < wfm_om->wfm_min)
+           wfm_om->wfm_min = wfm_om->wfm_y[n_position];
+         
+         n_position++;
+         n_word++;
+         frag_count++;
+       }
+
+       if((f_wfm.value[n_word] & 0xf000) == 0x2000) /* Normal wavf */
+         {
+
+           wfm_om->frag_end[n_fragment] = n_position - 1; 
+           wfm_om->frag_n_points[n_fragment] = 
+             wfm_om->frag_end[n_fragment] 
+             - wfm_om->frag_begin[n_fragment] + 1;
+           wfm_om->n_point += wfm_om->frag_n_points[n_fragment];
+           n_word++;
+         }
+       else 
+         return(ERROR_CORRUPTED_WF);
+
+       n_fragment++;
+    } /* end while fragment */
+
+
+    wfm_om->n_frag = n_fragment;
+    if( !(n_word & 0x1) ) n_word++;
+
+    if(n_fragment >= MAX_N_OF_FRAGS) return(ERROR_MAX_N_FRAGMENTS_EXCEEDED);
+    
+
+    // Hack to get rid of last value of waveform always set to 0
+    if (wfm_om->wfm_y[wfm_om->n_point] == 0.0)
+    {
+     // erase last point of waveform
+     wfm_om->n_point--;
+
+     // Shorten last pulse if necessary
+     // if( wfm_om.peak_end[wfm_om.n_peak-1] 
+     //     == wfm_om.frag_end[wfm_om.n_frag-1] )
+     //   wfm_om.peak_end[wfm_om.n_peak-1]--;
+                 
+     // Shorten last fragment
+     wfm_om->frag_n_points[wfm_om->n_frag-1]--;
+     wfm_om->frag_end[wfm_om->n_frag-1]--;
+
+     wfm_om->wfm_min = 4095.0;
+     wfm_om->wfm_max = 0.0;
+     for (Int_t i_value=0; i_value < wfm_om->n_point; i_value++)
+     {
+      if (wfm_om->wfm_y[i_value] > wfm_om->wfm_max) wfm_om->wfm_max=wfm_om->wfm_y[i_value];
+      if (wfm_om->wfm_y[i_value] < wfm_om->wfm_min) wfm_om->wfm_min=wfm_om->wfm_y[i_value];
+     }
+    }
+
+ return(debug);
+}
+///////////////////////////////////////////////////////////////////////////
diff --git a/RALICE/icepack/iceconvert/IceRawTWR.h b/RALICE/icepack/iceconvert/IceRawTWR.h
new file mode 100644 (file)
index 0000000..8738447
--- /dev/null
@@ -0,0 +1,67 @@
+#ifndef IceRawTWR_h
+#define IceRawTWR_h
+
+// Copyright(c) 2003, IceCube Experiment at the South Pole, All rights reserved.
+// See cxx source for full Copyright notice.
+
+// $Id$
+
+#include "TFile.h"
+#include "TTree.h"
+#include "TString.h"
+#include "TObjString.h"
+#include "TObjArray.h"
+
+#include "AliJob.h"
+#include "AliObjMatrix.h"
+
+#include "IceAOM.h"
+#include "IceEvent.h"
+
+#include "twr_reader.h"
+
+class IceRawTWR : public AliJob
+{
+ public :
+  IceRawTWR(const char* name="IceRawTWR",const char* title=""); // Constructor
+  virtual ~IceRawTWR();                                         // 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 AddInputFile(TString name);  // Add name of F2K input file to the list
+  void SetOutputFile(TFile* ofile); // Set output file for the ROOT data structures       
+  void SetOutputFile(TString name); // Create output file for the ROOT data structures
+  TFile* GetOutputFile();           // Provide pointer to the ROOT output file
+  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 fMaxevt;       // The maximum number of events to be processed
+  Int_t fPrintfreq;    // The event info printing frequency
+  TObjArray* fInfiles; // Names of all the raw data input files
+  TFile* fOutfile;     // The ROOT output file
+  void PutTrigger(Int_t year);   // Put the trigger info from the raw data event into the IcePack structure
+  void PutWaveforms(Int_t year); // Put the waveforms from the raw data event into the IcePack structure
+
+  FILE* fInput;              //! Pointer to the TWR raw data input file
+  sys_config_t* fHeader;     //! Structure holding the raw configuration header info
+  event_t fEvent;            //! Structure holding the actual raw event data
+  trigger_hits_t fTrigger;   //! Structure holding the event trigger info
+  waveform_analyse_t fWform; //! Waveform info for a certain OM from (merged) fragment(s)
+
+  // Ralice/IcePack implementation of Wolfgang Wagner's original code
+  Int_t extract_info_from_filename(char* fname,twr_raw_data_file_t* twr_file);
+  Int_t clear_system(sys_config_t* sys);
+  Int_t clear_event(event_t* event_ptr);
+  Int_t read_header_from_file(FILE* fin,sys_config_t** system_ptr,UInt_t* header_length);
+  Int_t update_system(sys_config_t* sys,Int_t run_number);
+  Int_t read_event(FILE* fin,sys_config_t* sys,event_t* event_ptr);
+  Int_t retrigger(event_t* ev,trigger_hits_t* trig);
+  Int_t clear_waveform_analysis(waveform_analyse_t* wfm_om);
+  Int_t restore_waveform(waveform_t f_wfm,waveform_analyse_t* wfm_om,Int_t year);
+
+ ClassDef(IceRawTWR,1) // Job for conversion of TWR raw data into IceEvent data structures.
+};
+#endif
index 7737200..60d26ca 100644 (file)
                 resulting histos are baseline corrected.
 25-oct-2006 NvE IceF2k updated to include an IceF2k device into the event structure
                 containing the processor parameters.
+14-dec-2006 NvE IceF2k updated to include a Daq device into the event structure
+                containing an indication of the DAQ system that was used to produce
+                the hit data (i.e. ADC, LE, TOT).
+16-dec-2006 NvE New class IceRawTWR introduced to read raw TWR data into the Ralice/IcePack
+                event structures.
 
 
diff --git a/RALICE/icepack/iceconvert/twr_config.h b/RALICE/icepack/iceconvert/twr_config.h
new file mode 100644 (file)
index 0000000..328da42
--- /dev/null
@@ -0,0 +1,114 @@
+#ifndef TWR_CONFIG_H
+#define TWR_CONFIG_H
+
+// Copyright(c) 2003, IceCube Experiment at the South Pole, All rights reserved.
+// See cxx source for full Copyright notice.
+
+// $Id$
+
+/////////////////////////////////////////////////////////////////////////
+// This header file originates from the file config.h
+// of Wolfgang Wagner's TWR raw data reader.
+// The types u_int32_t etc... have been replaced by the ROOT portable
+// types UInt_t etc... to obtain identical performance on all ROOT
+// supported platforms from within the Ralice/IcePack framework.
+// In addition the low level C "read()" invokations have been replaced
+// by the standard C/C++ "fread()" invokations to even more enhance
+// portability. As a result several header files have become obsolete
+// and as such are not included anymore.
+//
+// NvE 07-dec-2006 Utrecht University
+/////////////////////////////////////////////////////////////////////////
+
+#include "twr_globalconst.h"
+
+#define LENGTH_OF_STRING 100
+#define MAX_N_VLF_VETOS_PER_HOUR 16
+
+/*
+  Enhanced structures for Analysis
+*/
+
+typedef struct  /* of one module */
+{
+  UInt_t base;   /* Baseaddress in VME-BUS */
+  UInt_t id;     /* identifier for TWR  */
+  /* id = crate no * 0x10      (begining with 1) */
+  /*     + TWR number in crate (beginnig with 0)  */
+  
+  UInt_t mod_id;    /* Module ID from internal register   0x4 */
+  UInt_t ext_start; /* Extern Start Delay Register        0x14 */
+  UInt_t ext_stop;  /* Extern Stop Delay Register         0x18 */
+  
+  UInt_t om_no[CHANNELS_PER_TWR]; 
+  UInt_t om_is_optical[CHANNELS_PER_TWR];
+  UInt_t baseline[CHANNELS_PER_TWR];
+  UInt_t threshold[CHANNELS_PER_TWR];
+} twr_config_t;
+
+
+typedef struct
+{
+  UInt_t vme_base_bridge;   /* physical base local bridge in master crate */
+  UInt_t vme_base_100MHz;   /* physical base local 100MHz module */
+  char dsp_program_name[LENGTH_OF_STRING];
+  UInt_t base_gps; /* physical base of GPSAMD in remote crate */
+  UInt_t n_twr;  
+  twr_config_t *twr[MAX_N_TWR_PER_CRATE];
+} crate_config_t;
+
+typedef struct
+{
+  Int_t pci_channel;
+  char pci_driver_name[LENGTH_OF_STRING];
+  char data_output_directory[LENGTH_OF_STRING];
+  UInt_t n_events_per_file;
+  UInt_t compression;
+
+  /* DSP parameters */
+  UInt_t preceeding_values_optical;
+  UInt_t following_values_optical;
+  UInt_t preceeding_values_electrical;
+  UInt_t following_values_electrical;
+
+  /* TWR */
+  UInt_t clockdiv;  /* Clockpredivider for Time Stamp for TWRs  */ 
+  UInt_t statreg;   /* Status Register                    0x0 */  
+  UInt_t acq_ctrl;  /* Acquisition Control Register       0x10 */
+  UInt_t evtconfig;
+  UInt_t triggerflagclearcounter;
+
+  /* GPS AMD / VLF stuff */
+  UInt_t b_vlf_trigger_veto_on; /* Enable VLF trigger veto */
+  UInt_t n_vlf_trigger_veto; /* no of trigger times per hour */
+  UInt_t start_vlf_trigger_veto[MAX_N_VLF_VETOS_PER_HOUR];
+  UInt_t duration_vlf_trigger_veto;
+  UInt_t overlap_vlf_trigger_veto;
+
+  UInt_t n_crates;
+  UInt_t n_twr;
+
+  crate_config_t *crate[MAX_N_CRATES+1];
+
+  twr_config_t *twr_field[MAX_N_CRATES * MAX_N_TWR_PER_CRATE];
+
+}sys_config_t;
+
+
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/RALICE/icepack/iceconvert/twr_event.h b/RALICE/icepack/iceconvert/twr_event.h
new file mode 100644 (file)
index 0000000..f47041f
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef TWR_EVENT_H
+#define TWR_EVENT_H
+
+// Copyright(c) 2003, IceCube Experiment at the South Pole, All rights reserved.
+// See cxx source for full Copyright notice.
+
+// $Id$
+
+/////////////////////////////////////////////////////////////////////////
+// This header file originates from the file event.h
+// of Wolfgang Wagner's TWR raw data reader.
+// The types u_int32_t etc... have been replaced by the ROOT portable
+// types UInt_t etc... to obtain identical performance on all ROOT
+// supported platforms from within the Ralice/IcePack framework.
+// In addition the low level C "read()" invokations have been replaced
+// by the standard C/C++ "fread()" invokations to even more enhance
+// portability. As a result several header files have become obsolete
+// and as such are not included anymore.
+//
+// NvE 07-dec-2006 Utrecht University
+/////////////////////////////////////////////////////////////////////////
+
+#include "twr_gps.h"
+
+typedef struct
+{
+    UShort_t value[2500];
+} waveform_t;
+
+typedef struct
+{
+    UInt_t timestamp;
+    UInt_t n_wfm;
+} twr_t;
+
+typedef struct
+{
+    UInt_t eventcounter;
+    UInt_t which_trigger;
+    GPS_t gps;
+    waveform_t wfm[N_OF_CHANNELS];
+    short wfm_filled[N_OF_CHANNELS];
+    UInt_t twr_id_of_om[N_OF_CHANNELS];
+    twr_t twr[ (MAX_N_CRATES+1) * MAX_N_TWR_PER_CRATE];
+} event_t;
+
+#endif
diff --git a/RALICE/icepack/iceconvert/twr_globalconst.h b/RALICE/icepack/iceconvert/twr_globalconst.h
new file mode 100644 (file)
index 0000000..db04d23
--- /dev/null
@@ -0,0 +1,74 @@
+#ifndef TWR_GLOBALCONST_H
+#define TWR_GLOBALCONST_H
+
+// Copyright(c) 2003, IceCube Experiment at the South Pole, All rights reserved.
+// See cxx source for full Copyright notice.
+
+// $Id$
+
+/////////////////////////////////////////////////////////////////////////
+// This header file originates from the file globalconst.h
+// of Wolfgang Wagner's TWR raw data reader.
+//
+// NvE 07-dec-2006 Utrecht University
+/////////////////////////////////////////////////////////////////////////
+
+/*
+  TWR system
+*/
+
+#define VALUES_PER_WAVEFORM 1024
+#define CHANNELS_PER_TWR 8
+#define N_OF_EVENTS_PER_BANK 128
+#define MEMORY_BANKS_PER_MODULE 2
+
+#define MAX_N_CRATES 7
+#define MAX_N_TWR_PER_CRATE 16
+
+#define MAX_N_OF_FRAGS 20
+#define MAX_N_OF_TDC_EDGES 16
+
+#define N_OF_CHANNELS 700
+#define N_OF_TRIGGERS 12
+
+#define BASELINE_MEAN_MAGIC 3100
+
+/*
+  TWR Calibration
+*/
+#define NSECS_PER_TDC_BIN 1.041667 
+#define NSECS_PER_TWR_BIN 10 
+#define MV_PER_DIGIT (5000.0/4096.0)
+#define BINxDIGIT2CHARGE ( 10.0 * 1e-9 *(5.0/4096.0) / 50.0 )
+/*
+  TWR analysis
+*/
+
+#define MAX_N_OF_PEAKS 300
+
+#define THRESHOLDTAIL_PERCENTAGE 0.1
+#define THRESHOLD_2ND_PEAK 10
+#define THRESHOLD_2ND_PEAK_PERCENTAGE 0.5
+#define THRESHOLD_OFFSET 20
+
+#define MAX_SLOPE_LENGTH_ELEC 7
+
+/*
+  TWR Trigger stuff
+*/
+
+/* 2004 */
+
+/* > 2005 */
+#define RANDOM_TRIGGER_2005    690
+#define MAIN_TRIG_OR_2005      689
+#define MAIN_TRIG_LOGIC_2005   688
+#define M12TRIGGER_2005        687
+#define CAL_TRIG_LA_2005       686
+#define CAL_TRIG_T0_2005       685
+#define SPASE_TRI_2005         684
+#define STRING_TRIG_2005       683
+#define M18TRIGGER_2005        682
+#define M24TRIGGER_2005        681
+
+#endif
diff --git a/RALICE/icepack/iceconvert/twr_gps.h b/RALICE/icepack/iceconvert/twr_gps.h
new file mode 100644 (file)
index 0000000..db41ba9
--- /dev/null
@@ -0,0 +1,76 @@
+#ifndef TWR_GPS_H
+#define TWR_GPS_H
+
+// Copyright(c) 2003, IceCube Experiment at the South Pole, All rights reserved.
+// See cxx source for full Copyright notice.
+
+// $Id$
+
+/////////////////////////////////////////////////////////////////////////
+// This header file originates from the file gps.h
+// of Wolfgang Wagner's TWR raw data reader.
+// The types u_int32_t etc... have been replaced by the ROOT portable
+// types UInt_t etc... to obtain identical performance on all ROOT
+// supported platforms from within the Ralice/IcePack framework.
+// In addition the low level C "read()" invokations have been replaced
+// by the standard C/C++ "fread()" invokations to even more enhance
+// portability. As a result several header files have become obsolete
+// and as such are not included anymore.
+//
+// NvE 07-dec-2006 Utrecht University
+/////////////////////////////////////////////////////////////////////////
+
+/* GPS Configuration Registers        */
+/* for the DAQ300                     */
+/* Wolfgang Wagner - 22.1.02          */
+/* according to new GPS Docu 13.12.01 */
+
+/* Timestructure...*/
+
+struct timebits
+{
+  UInt_t seconds:8,
+    year:8,
+    TQC:4, /* True time quality character 0 best, F worst */
+    status:4,
+    dummy:8;
+};
+
+union time
+{
+  UInt_t all;
+  struct timebits bits;
+};
+
+typedef struct                          // GPS-event => 16 bytes
+{
+  UInt_t count_10MHz;
+  UInt_t seconds;
+  union time info;
+  UInt_t counter;
+}GPS_t;
+
+#define GPS_CTRL_REG     0x0 // Write
+
+#define GPS_CTRL_RESET   0x1
+#define GPS_CTRL_WORK    0x0
+#define GPS_CTRL_YR_SRC  0x2
+// #define GPS_CTRL_CLKREF  0x4 // Clock Reference from GPS-Clock
+#define GPS_CTRL_ENPULS  0x8
+#define GPS_FIFO_NOTEMPT 0x10
+#define GPS_FIFO_FULL    0x20
+//+++++++++++++++++++++++++++
+
+#define GPS_FREQ_DIV     0x4 // Only Read
+
+//+++++++++++++++++++++++++++
+
+#define GPS_YEAR         0x8
+//+++++++++++++++++++++++++++
+
+#define GPS_LED_REG      0xc
+//+++++++++++++++++++++++++++
+
+#define GPS_DATA_REG     0x10
+
+#endif
diff --git a/RALICE/icepack/iceconvert/twr_reader.h b/RALICE/icepack/iceconvert/twr_reader.h
new file mode 100644 (file)
index 0000000..a2d8c2b
--- /dev/null
@@ -0,0 +1,177 @@
+#ifndef TWR_READER_H
+#define TWR_READER_H
+
+// Copyright(c) 2003, IceCube Experiment at the South Pole, All rights reserved.
+// See cxx source for full Copyright notice.
+
+// $Id$
+
+/////////////////////////////////////////////////////////////////////////
+// This header file originates from the files read_twr_binary_file.h
+// and lib_wf2hit_new.h of Wolfgang Wagner's TWR raw data reader.
+// The types u_int32_t etc... have been replaced by the ROOT portable
+// types UInt_t etc... to obtain identical performance on all ROOT
+// supported platforms from within the Ralice/IcePack framework.
+// In addition the low level C "read()" invokations have been replaced
+// by the standard C/C++ "fread()" invokations to even more enhance
+// portability. As a result several header files have become obsolete
+// and as such are not included anymore.
+// The source code of read_twr_binary_file.cxx and lib_wf2hit_new.cxx
+// has been implemented as memberfunctions of the class IceRawTWR,
+// so the definitions of the function prototypes have been moved to
+// the header file IceRawTWR.h.
+//
+// NvE 07-dec-2006 Utrecht University
+/////////////////////////////////////////////////////////////////////////
+
+#include "twr_globalconst.h"
+#include "twr_config.h"
+#include "twr_gps.h"
+#include "twr_event.h"
+
+/////////////////////////////////////
+// Source of raw_twr_binary_file.h //
+/////////////////////////////////////
+
+/* Readout 2005 / 2006 */
+/* offset for baseline */
+// #define BASELINE_MEAN_MAGIC 3100 // Already defined in globalconst.h
+
+/* Trigger defs */
+#define M24_TRIG_CHA          681
+#define M18_TRIG_CHA          682
+#define STRING_TRIG_CHA       683
+#define SPASE_TRIG_CHA        684
+#define CAL_TRIG_T0_CHA       685
+#define CAL_TRIG_LA_CHA       686
+#define M12_TRIG_CHA          687
+#define MAIN_TRIG_LOGIC_CHA   688
+#define MAIN_TRIG_OR_CHA      689
+#define RANDOM_TRIG_CHA       690
+
+#define M20_FRAG_BIT       0x1       /* only software no hardware signal */
+#define VOLUMEN_TRIG_BIT   0x2       /* only software no hardware signal */
+#define M18_TRIG_BIT       0x4
+#define M24_TRIG_BIT       0x8
+#define STRING_TRIG_BIT    0x10
+#define SPASE_TRIG_BIT     0x20
+#define RANDOM_TRIG_BIT    0x40
+#define CAL_TRIG_T0_BIT    0x80
+#define CAL_TRIG_LA_BIT    0x100
+
+#define MUON_VETO_MASK     0xffff0000
+
+#define M24_TRIG_NUM         0
+#define M18_TRIG_NUM         1
+#define STRING_TRIG_NUM      2
+#define SPASE_TRIG_NUM       3
+#define CAL_TRIG_T0_NUM      4
+#define CAL_TRIG_LA_NUM      5
+#define M12_TRIG_NUM         6
+#define MAIN_TRIG_LOGIC_NUM  7
+#define MAIN_TRIG_OR_NUM     8
+#define RANDOM_TRIG_NUM      9 
+#define M20_FRAG_NUM        10 /* only software no hardware signal */
+#define VOLUMEN_TRIG_NUM    11 /* only software no hardware signal */
+
+// Software triggers                       
+const UInt_t trigger_bits[N_OF_TRIGGERS]
+= { M24_TRIG_BIT, M18_TRIG_BIT, STRING_TRIG_BIT, SPASE_TRIG_BIT,
+    CAL_TRIG_T0_BIT, CAL_TRIG_LA_BIT, 0x0, 0x0, 
+    0x0, RANDOM_TRIG_BIT, M20_FRAG_BIT, VOLUMEN_TRIG_BIT };
+
+// Hardware triggers
+const UInt_t trigger_channel[N_OF_TRIGGERS]
+= { M24_TRIG_CHA, M18_TRIG_CHA, STRING_TRIG_CHA, SPASE_TRIG_CHA,
+    CAL_TRIG_T0_CHA, CAL_TRIG_LA_CHA, M12_TRIG_CHA, MAIN_TRIG_LOGIC_CHA, 
+    MAIN_TRIG_OR_CHA, RANDOM_TRIG_CHA, 0x0, 0x0 };
+
+typedef struct{
+  Int_t n_software_trigger;
+  Int_t n_hardware_trigger;
+  Int_t first_trigger;
+  UInt_t first_trigger_time;
+  UInt_t trigger_active[N_OF_TRIGGERS];
+  UInt_t trigger_has_pulse[N_OF_TRIGGERS];
+  UInt_t trigger_time[N_OF_TRIGGERS]; 
+} trigger_hits_t;
+
+/* Error codes */
+#define ERROR_NOT_VALID_FILENAME 1
+#define ERROR_TOO_MANY_CRATES 2
+#define ERROR_TOO_MANY_TWRS   1
+
+/* info from TWR filename */
+typedef struct{
+  Int_t day;
+  Int_t year;
+  Int_t run_no;
+  Int_t file_no; 
+  Int_t begin; 
+  Int_t end;
+} twr_raw_data_file_t;
+
+////////////////////////////////
+// Source of lib_wf2hit_new.h //
+////////////////////////////////
+
+typedef struct
+{
+  // output from analysis
+  Int_t n_frag;
+
+  Int_t frag_n_points[MAX_N_OF_FRAGS];
+  Int_t frag_begin[MAX_N_OF_FRAGS];
+  Int_t frag_end[MAX_N_OF_FRAGS];
+  Float_t frag_begin_time[MAX_N_OF_FRAGS]; // in TDC frame
+  //Float_t frag_t_end[MAX_N_OF_FRAGS];
+  Float_t frag_mean[MAX_N_OF_FRAGS];
+
+
+  Int_t n_peak;
+  Int_t peak_begin[MAX_N_OF_PEAKS];  
+  Int_t peak_end[MAX_N_OF_PEAKS];
+  Int_t peak_max[MAX_N_OF_PEAKS];
+  Int_t peak_local_minimum[MAX_N_OF_PEAKS];
+  Int_t peak_in_fragment[MAX_N_OF_PEAKS];
+  Int_t peak_TDC_edge[MAX_N_OF_PEAKS]; // holds the identified TDC edge
+  Int_t peak_isolated[MAX_N_OF_PEAKS];
+  Int_t crosstalk_charge_n_value[MAX_N_OF_PEAKS];
+  
+  Float_t peak_mean[MAX_N_OF_PEAKS];
+  Float_t peak_m[MAX_N_OF_PEAKS];
+  Float_t peak_b[MAX_N_OF_PEAKS];
+  Float_t peak_t0[MAX_N_OF_PEAKS];
+  Float_t peak_begin_time[MAX_N_OF_PEAKS];   
+  Float_t peak_charge[MAX_N_OF_PEAKS];
+  Float_t peak_height[MAX_N_OF_PEAKS];
+  Float_t fitted_amplitude[MAX_N_OF_PEAKS];
+  Float_t fitted_TOT[MAX_N_OF_PEAKS];
+
+  Float_t crosstalk_charge[MAX_N_OF_PEAKS];
+  Float_t crosstalk_slope[MAX_N_OF_PEAKS];
+  Int_t n_point;
+  Float_t wfm_x[1024];
+  Float_t wfm_y[1024];
+  Float_t wfm_min; 
+  Float_t wfm_max; 
+  Int_t b_out_of_range;
+
+  // TDC data
+  Int_t n_tdc_edges;
+  Int_t identified_twr_hit[MAX_N_OF_TDC_EDGES];
+  Double_t leading_edge[MAX_N_OF_TDC_EDGES];
+  Double_t falling_edge[MAX_N_OF_TDC_EDGES];
+
+} waveform_analyse_t;
+
+#define ERROR_CALIBRATING_WFM      1
+
+#define ERROR_FILL_OUT_OF_RANGE    2
+#define ERROR_FILL_MAX_N_OF_FRAGS  3
+
+#define ERROR_MISS_FRAG_STOP       4
+#define ERROR_CORRUPTED_WF         5
+#define ERROR_MAX_N_FRAGMENTS_EXCEEDED 6
+                                 
+#endif