10-aug-2005 NvE AliSignal::GetSignal extended with mode=8 to support dead flag of...
[u/mrichter/AliRoot.git] / RALICE / icepack / iceconvert / IceF2k.cxx
index b578c0ef417676d71377b81a0ef6d0835c9aa974..2fef202e3ee4c9c75eca7985b0cdce46ec45964a 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.
+// 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 F2K data using the Ralice/IcePack analysis tools. 
 //
 // 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");
+//
+// // Output file for the event structures
+// TFile* ofile=new TFile("events.root","RECREATE","F2K data in IceEvent structure");
+// q.SetOutputFile(ofile);
 //
-// IceF2k q("run8000.f2k",split,bsize);
-// q.Loop(otree,nentries,printfreq);
+// ///////////////////////////////////////////////////////////////////
+// // 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
 //
+// ofile->cd(); // Switch to the output file directory
+//
 // AliObjMatrix* omdb=q.GetOMdbase();
 // if (omdb) omdb->Write();
 //
 // TDatabasePDG* pdg=q.GetPDG();
 // if (pdg) pdg->Write();
 //
-// // Close output file
+// // Flush the output file.
+// // The output file is not explicitly closed here
+// // to allow ineractive investigation of the data tree
+// // when this macro is run in an interactive ROOT/CINT session.
 // ofile->Write();
-// ofile->Close();
 //
 //--- Author: Nick van Eijndhoven 11-mar-2005 Utrecht University
 //- Modified: NvE $Date$ Utrecht University
 
 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.
+
  if (fPdg)
  {
   delete fPdg;
@@ -128,6 +144,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,30 +203,59 @@ 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;
+ }
 
- Double_t pi=acos(-1.);
+ // Initialise the event structure 
+ rdmc_init_mevt(&fEvent);
 
- IceEvent* evt=new IceEvent();
+ // Read the file header information
+ rdmc_rarr(fInput,&fHeader);
 
+ TTree* otree=0;
+ if (fOutfile)
+ {
+  otree=new TTree("T","F2K 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
- otree->Branch("IceEvent","IceEvent",&evt,fBsize,fSplit); 
if (otree) otree->Branch("IceEvent","IceEvent",&evt,fBsize,fSplit); 
 
  // Create the particle database and extend it with some F2000 specific definitions
  if (!fPdg) fPdg=new TDatabasePDG();
@@ -193,27 +279,32 @@ void IceF2k::Loop(TTree* otree,Int_t nentries,Int_t printfreq)
  // Set the fit definitions according to the F2000 header info
  SetFitdefs();
 
-/*************
-
- // The LEDA specific output data
- AliCalorimeter* ledaup=new AliCalorimeter(44,144);
- AliCalorimeter* ledalw=new AliCalorimeter(40,144);
-
- ledaup->SetName("LedaUp");
- ledalw->SetName("LedaDown");
-
- evt->InitLeda(ledaup);
- evt->InitLeda(ledalw);
+ // Initialise the job working environment
+ SetMainObject(evt);
+ if (fOutfile)
+ {
+  AddObject(fOutfile);
+  AddObject(otree);
+ }
 
- TDatime datim;
- Float_t pos[3],costh;
- AliSignal s;
- s.SetName("CPV signal ADC");
-************************/
+ 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;
+ if (fOutfile)
+ {
+  cout << " ROOT output file : " << fOutfile->GetName() << endl;
+  cout << " Output characteristics : splitlevel = " << fSplit << " buffersize = " << fBsize << endl;
+ }
 
- for (Int_t jentry=0; jentry<nentries; jentry++)
+ 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();
@@ -222,74 +313,34 @@ 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();
 
-/*********************************
-  datim.Set(Jdate,Jtime);
-  evt->SetDayTime(datim);
-  evt->SetProjectile(207,82,158);
-  evt->SetTarget(207,82,0);
-  evt->SetWeight(Jwscal);
-  evt->SetTrig(Itword);
-  evt->SetZdc(Zdc*1000.);
-  evt->SetMiracE(1000.*Emir,Emire,Emirh);
-  evt->SetMiracEt(Etm,Etme,Etmh);
-  ledaup->Reset();
-  ledalw->Reset();
-  // Fill calorimeter with module data
-  for (Int_t i=0; i<Nmod; i++)
-  {
-   if (Adcl[i] > 3) // Adc cut of 3 to remove noise
-   {
-    if (Irowl[i] > 0) ledaup->SetSignal(Irowl[i],Icoll[i],Adcl[i]);
-    if (Irowl[i] < 0) ledalw->SetSignal(-Irowl[i],Icoll[i],Adcl[i]);
-   }
-  }
-
-  // Store associated CPV signals
-  for (Int_t j=0; j<Ncluv; j++)
-  {
-   s.Reset();
-   s.SetSignal(Iadccv[j]);
-   pos[1]=Thetacv[j]*pi/180.;
-   pos[2]=Phicv[j]*pi/180.;
-   costh=cos(pos[1]);
-   pos[0]=0;
-   if (costh) pos[0]=2103./costh;
-   s.SetPosition(pos,"sph");
-   pos[0]=0.4;
-   pos[1]=2.2;
-   pos[2]=0;
-   s.SetPositionErrors(pos,"car");
-   if (Phicv[j]>=0. && Phicv[j]<=180.)
-   {
-    ledaup->AddVetoSignal(s);
-   }
-   else
-   {
-    ledalw->AddVetoSignal(s);
-   }
-  }
+  // Invoke all available sub-tasks (if any)
+  ExecuteTasks(opt);
 
-  evt->AddDevice(ledaup);
-  evt->AddDevice(ledalw);
-************************************/
-
-  if (!(jentry%printfreq))
+  if (fPrintfreq)
   {
-   evt->HeaderData();
+   if (!(nevt%fPrintfreq)) evt->HeaderData();
   }
 
   // Write the complete structure to the output Tree
-  otree->Fill();
+  if (otree) otree->Fill();
+
+  // Update event counter
+  nevt++;
  }
 
- if (evt) delete evt;
+ // Remove the IceEvent object from the environment
+ // and delete it as well
+ if (evt)
+ {
+  RemoveObject(evt);
+  delete evt;
+ }
 }
 ///////////////////////////////////////////////////////////////////////////
 void IceF2k::FillOMdbase()
@@ -299,6 +350,35 @@ void IceF2k::FillOMdbase()
 
  if (fHeader.nch<=0) return;
 
+ Int_t geocal=fHeader.is_calib.geo;
+ Int_t adccal=fHeader.is_calib.adc;
+ Int_t tdccal=fHeader.is_calib.tdc;
+ Int_t totcal=fHeader.is_calib.tot;
+ Int_t utccal=fHeader.is_calib.utc;
+
+ TF1 fadccal("fadccal","(x-[1])*[0]");
+ TF1 fadcdecal("fadcdecal","(x/[0])+[1]");
+ fadccal.SetParName(0,"BETA-ADC");
+ fadccal.SetParName(1,"PED-ADC");
+ fadcdecal.SetParName(0,"BETA-ADC");
+ fadcdecal.SetParName(1,"PED-ADC");
+
+ TF1 ftdccal("ftdccal","(x*[0])-[1]-([0]-1.)*32767.-[2]/sqrt([3])");
+ TF1 ftdcdecal("ftdcdecal","(x+([0]-1.)*32767.+[1]+[2]/sqrt([3]))/[0]");
+ ftdccal.SetParName(0,"BETA-TDC");
+ ftdccal.SetParName(1,"T0");
+ ftdccal.SetParName(2,"ALPHA-TDC");
+ ftdccal.SetParName(3,"ADC-SLEW");
+ ftdcdecal.SetParName(0,"BETA-TDC");
+ ftdcdecal.SetParName(1,"T0");
+ ftdcdecal.SetParName(2,"ALPHA-TDC");
+ ftdcdecal.SetParName(3,"ADC-SLEW");
+
+ TF1 ftotcal("ftotcal","x*[0]");
+ TF1 ftotdecal("ftotdecal","x/[0]");
+ ftotcal.SetParName(0,"BETA-TOT");
+ ftotdecal.SetParName(0,"BETA-TOT");
+
  if (fOmdb)
  {
   fOmdb->Reset();
@@ -316,25 +396,91 @@ void IceF2k::FillOMdbase()
  {
   dev=new IceAOM();
   dev->SetUniqueID(i+1);
-  dev->SetSlotName("TYPE",1);
-  dev->SetSlotName("ORIENT",2);
-  dev->SetSlotName("T0",3);
-  dev->SetSlotName("ALPHA",4);
-  dev->SetSlotName("KADC",5);
-  dev->SetSlotName("KTOT",6);
-  dev->SetSlotName("KTDC",7);
+
+  dev->SetSlotName("ADC",1);
+  dev->SetSlotName("LE",2);
+  dev->SetSlotName("TOT",3);
+
+  dev->SetSlotName("TYPE",4);
+  dev->SetSlotName("ORIENT",5);
+  dev->SetSlotName("THRESH",6);
+  dev->SetSlotName("SENSIT",7);
+  dev->SetSlotName("BETA-TDC",8);
+  dev->SetSlotName("T0",9);
+  dev->SetSlotName("ALPHA-TDC",10);
+  dev->SetSlotName("PED-ADC",11);
+  dev->SetSlotName("BETA-ADC",12);
+  dev->SetSlotName("KAPPA-ADC",13);
+  dev->SetSlotName("PED-TOT",14);
+  dev->SetSlotName("BETA-TOT",15);
+  dev->SetSlotName("KAPPA-TOT",16);
 
   pos[0]=fHeader.x[i];
   pos[1]=fHeader.y[i];
   pos[2]=fHeader.z[i];
   dev->SetPosition(pos,"car");
-  dev->SetSignal(fHeader.type[i],1);
-  dev->SetSignal((Float_t)fHeader.costh[i],2);
-  dev->SetSignal(fHeader.cal[i].t_0,3);
-  dev->SetSignal(fHeader.cal[i].alpha_t,4);
-  dev->SetSignal(fHeader.cal[i].beta_a,5);
-  dev->SetSignal(fHeader.cal[i].beta_tot,6);
-  dev->SetSignal(fHeader.cal[i].beta_t,7);
+
+  fadccal.SetParameter(0,fHeader.cal[i].beta_a);
+  fadccal.SetParameter(1,fHeader.cal[i].ped);
+  fadcdecal.SetParameter(0,fHeader.cal[i].beta_a);
+  if (!fHeader.cal[i].beta_a) fadcdecal.SetParameter(0,1);
+  fadcdecal.SetParameter(1,fHeader.cal[i].ped);
+
+  ftdccal.SetParameter(0,fHeader.cal[i].beta_t);
+  ftdccal.SetParameter(1,fHeader.cal[i].t_0);
+  ftdccal.SetParameter(2,fHeader.cal[i].alpha_t);
+  ftdccal.SetParameter(3,1.e20);
+  ftdcdecal.SetParameter(0,fHeader.cal[i].beta_t);
+  if (!fHeader.cal[i].beta_t) ftdcdecal.SetParameter(0,1);
+  ftdcdecal.SetParameter(1,fHeader.cal[i].t_0);
+  ftdcdecal.SetParameter(2,fHeader.cal[i].alpha_t);
+  ftdcdecal.SetParameter(3,1.e20);
+
+  ftotcal.SetParameter(0,fHeader.cal[i].beta_tot);
+  ftotdecal.SetParameter(0,fHeader.cal[i].beta_tot);
+  if (!fHeader.cal[i].beta_tot) ftotdecal.SetParameter(0,1);
+
+  if (adccal)
+  {
+   dev->SetDecalFunction(&fadcdecal,1);
+  }
+  else
+  {
+   dev->SetCalFunction(&fadccal,1);
+  }
+
+  if (tdccal)
+  {
+   dev->SetDecalFunction(&ftdcdecal,2);
+  }
+  else
+  {
+   dev->SetCalFunction(&ftdccal,2);
+  }
+
+  if (totcal)
+  {
+   dev->SetDecalFunction(&ftotdecal,3);
+  }
+  else
+  {
+   dev->SetCalFunction(&ftotcal,3);
+  }
+
+  dev->SetSignal(fHeader.type[i],4);
+  dev->SetSignal((Float_t)fHeader.costh[i],5);
+  dev->SetSignal(fHeader.thresh[i],6);
+  dev->SetSignal(fHeader.sensit[i],7);
+  dev->SetSignal(fHeader.cal[i].beta_t,8);
+  dev->SetSignal(fHeader.cal[i].t_0,9);
+  dev->SetSignal(fHeader.cal[i].alpha_t,10);
+  dev->SetSignal(fHeader.cal[i].ped,11);
+  dev->SetSignal(fHeader.cal[i].beta_a,12);
+  dev->SetSignal(fHeader.cal[i].kappa,13);
+  dev->SetSignal(fHeader.cal[i].ped_tot,14);
+  dev->SetSignal(fHeader.cal[i].beta_tot,15);
+  dev->SetSignal(fHeader.cal[i].kappa_tot,16);
+
   fOmdb->EnterObject(i+1,1,dev);
  }
 }
@@ -409,12 +555,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
@@ -511,12 +658,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
@@ -617,11 +765,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
@@ -637,6 +786,7 @@ void IceF2k::PutHits(IceEvent* evt)
  AliSignal* sx=0;
  Int_t tid=0;
  AliTrack* tx=0;
+ Float_t adc=0;
  for (Int_t i=0; i<fEvent.nhits; i++)
  {
   chan=fEvent.h[i].ch+1;
@@ -673,6 +823,25 @@ void IceF2k::PutHits(IceEvent* evt)
   sx=omx->GetHit(omx->GetNhits());
   if (!sx) continue;
 
+  // ADC dependent TDC (de)calibration function for this hit
+  TF1* fcal=omx->GetCalFunction("LE");
+  TF1* fdecal=omx->GetDecalFunction("LE");
+  if (fcal) sx->SetCalFunction(fcal,2);
+  if (fdecal) sx->SetDecalFunction(fdecal,2);
+  fcal=sx->GetCalFunction(2);
+  fdecal=sx->GetDecalFunction(2);
+  adc=sx->GetSignal(1,-4);
+  if (adc>0)
+  {
+   if (fcal) fcal->SetParameter(3,adc);
+   if (fdecal) fdecal->SetParameter(3,adc);
+  }
+  else
+  {
+   if (fcal) fcal->SetParameter(3,0);
+   if (fdecal) fdecal->SetParameter(3,0);
+  }
+
   // Bi-directional link between this hit and the track that caused the ADC value.
   // This F2K info is probably only present for MC tracks.
   tid=fEvent.h[i].ma;
@@ -738,7 +907,7 @@ void IceF2k::PutHits(IceEvent* evt)
 
   for (Int_t jbin=1; jbin<=fEvent.wf[iwf].ndigi; jbin++)
   {
-   histo.SetBinContent(jbin,fEvent.wf[iwf].digi[jbin]);
+   histo.SetBinContent(jbin,fEvent.wf[iwf].digi[jbin-1]);
   }
 
   omx->SetWaveform(&histo,omx->GetNwaveforms()+1);