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 dc3bab18d085908f9accc64f1d66a5f85443b601..2fef202e3ee4c9c75eca7985b0cdce46ec45964a 100644 (file)
 // 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 :
 // ---------------
@@ -74,6 +78,8 @@
 //
 // // 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
@@ -116,8 +124,6 @@ IceF2k::IceF2k(const char* name,const char* title) : AliJob(name,title)
 IceF2k::~IceF2k()
 {
 // Default destructor.
- IceEvent* evt=(IceEvent*)GetMainObject();
- if (evt) delete evt;
 
  if (fPdg)
  {
@@ -150,7 +156,7 @@ 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;
+ if (f>=0) fPrintfreq=f;
 }
 ///////////////////////////////////////////////////////////////////////////
 void IceF2k::SetSplitLevel(Int_t split)
@@ -237,20 +243,19 @@ void IceF2k::Exec(Option_t* opt)
  // Read the file header information
  rdmc_rarr(fInput,&fHeader);
 
- if (!fOutfile)
+ TTree* otree=0;
+ if (fOutfile)
  {
-  cout << " *IceF2k Exec* No ROOT output file specified." << endl;
-  return;
+  otree=new TTree("T","F2K Data converted to IceEvent structures");
+  otree->SetDirectory(fOutfile);
  }
 
- TTree* otree=new TTree("T","F2K Data converted to IceEvent structures");
-
  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();
@@ -276,8 +281,11 @@ void IceF2k::Exec(Option_t* opt)
 
  // Initialise the job working environment
  SetMainObject(evt);
- AddObject(fOutfile);
- AddObject(otree);
+ if (fOutfile)
+ {
+  AddObject(fOutfile);
+  AddObject(otree);
+ }
 
  cout << " ***" << endl;
  cout << " *** Start processing of job " << GetName() << " ***" << endl;
@@ -285,8 +293,11 @@ void IceF2k::Exec(Option_t* opt)
  cout << " F2K input file : " << fInfile.Data() << endl;
  cout << " Maximum number of events to be processed : " << fMaxevt << endl;
  cout << " Print frequency : " << fPrintfreq << endl;
- cout << " ROOT output file : " << fOutfile->GetName() << endl;
- cout << " Output characteristics : splitlevel = " << fSplit << " buffersize = " << fBsize << endl;
+ if (fOutfile)
+ {
+  cout << " ROOT output file : " << fOutfile->GetName() << endl;
+  cout << " Output characteristics : splitlevel = " << fSplit << " buffersize = " << fBsize << endl;
+ }
 
  ListEnvironment();
  
@@ -311,14 +322,25 @@ void IceF2k::Exec(Option_t* opt)
   // Invoke all available sub-tasks (if any)
   ExecuteTasks(opt);
 
-  if (!(nevt%fPrintfreq)) evt->HeaderData();
+  if (fPrintfreq)
+  {
+   if (!(nevt%fPrintfreq)) evt->HeaderData();
+  }
 
   // Write the complete structure to the output Tree
-  otree->Fill();
+  if (otree) otree->Fill();
 
   // Update event counter
   nevt++;
  }
+
+ // Remove the IceEvent object from the environment
+ // and delete it as well
+ if (evt)
+ {
+  RemoveObject(evt);
+  delete evt;
+ }
 }
 ///////////////////////////////////////////////////////////////////////////
 void IceF2k::FillOMdbase()
@@ -328,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();
@@ -345,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);
  }
 }
@@ -669,6 +786,7 @@ void IceF2k::PutHits()
  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;
@@ -705,6 +823,25 @@ void IceF2k::PutHits()
   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;
@@ -770,7 +907,7 @@ void IceF2k::PutHits()
 
   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);