fOffsets=0;
fCalflags=0;
fNames=0;
+ fCalfuncs=0;
+ fDecalfuncs=0;
}
///////////////////////////////////////////////////////////////////////////
AliAttrib::~AliAttrib()
delete fNames;
fNames=0;
}
+ if (fCalfuncs)
+ {
+ delete fCalfuncs;
+ fCalfuncs=0;
+ }
+ if (fDecalfuncs)
+ {
+ delete fDecalfuncs;
+ fDecalfuncs=0;
+ }
}
///////////////////////////////////////////////////////////////////////////
AliAttrib::AliAttrib(const AliAttrib& a)
fOffsets=0;
fCalflags=0;
fNames=0;
+ fCalfuncs=0;
+ fDecalfuncs=0;
Int_t n=0;
Double_t val=0;
s=a.GetSlotName(in);
if (s!="") SetSlotName(s,in);
}
+
+ n=a.GetNcalfuncs();
+ for (Int_t icalf=1; icalf<=n; icalf++)
+ {
+ TF1* f=a.GetCalFunction(icalf);
+ if (f) SetCalFunction(f,icalf);
+ }
+
+ n=a.GetNdecalfuncs();
+ for (Int_t idecalf=1; idecalf<=n; idecalf++)
+ {
+ TF1* f=a.GetDecalFunction(idecalf);
+ if (f) SetDecalFunction(f,idecalf);
+ }
}
///////////////////////////////////////////////////////////////////////////
Int_t AliAttrib::GetNgains() const
void AliAttrib::DeleteCalibrations(Int_t mode)
{
// User selected delete of all gains and/or offsets.
-// mode = 0 : All attributes (names, gains, offsets, edge and dead values) are deleted.
+// mode = 0 : All attributes (names,gains,offsets,(de)calfuncs, edge and dead values) are deleted.
// 1 : Only the gains are deleted.
// 2 : Only the offsets are deleted.
-// 3 : Both gains and offsets are deleted, but names, edge and dead values are kept.
+// 3 : Gains, offsets and (de)calfuncs are deleted, but names, edge and dead values are kept.
+// 4 : Only the calib. functions are deleted.
+// 5 : Only the de-calib. functions are deleted.
+// 6 : Only the calib. and de-calib. functions are deleted.
//
// The default when invoking DeleteCalibrations() corresponds to mode=0.
- if (mode<0 || mode>3)
+ if (mode<0 || mode>6)
{
cout << " *AliAttrib::DeleteCalibrations* Unknown mode : " << mode << endl;
cout << " Default mode=0 will be used." << endl;
delete fNames;
fNames=0;
}
+ if (fCalfuncs)
+ {
+ delete fCalfuncs;
+ fCalfuncs=0;
+ }
+ if (fDecalfuncs)
+ {
+ delete fDecalfuncs;
+ fDecalfuncs=0;
+ }
return;
}
fGains=0;
}
}
- else
+
+ if (mode==2)
{
ResetOffset(0);
if (fOffsets)
fOffsets=0;
}
}
+
+ if (mode==4 || mode==6)
+ {
+ if (fCalfuncs)
+ {
+ delete fCalfuncs;
+ fCalfuncs=0;
+ }
+ }
+
+ if (mode==5 || mode==6)
+ {
+ if (fDecalfuncs)
+ {
+ delete fDecalfuncs;
+ fDecalfuncs=0;
+ }
+ }
}
///////////////////////////////////////////////////////////////////////////
void AliAttrib::SetDead(Int_t j)
if (GetOffsetFlag(j)) cout << " offset : " << GetOffset(j);
if (GetEdgeValue(j)) cout << " edge : " << GetEdgeValue(j);
if (GetDeadValue(j)) cout << " dead : " << GetDeadValue(j);
+ if (GetCalFunction(j)) cout << " *Fcalib*";
+ if (GetDecalFunction(j)) cout << " *Fdecalib*";
TString s=GetSlotName(j);
if (s!="") cout << " name : " << s.Data();
}
for (Int_t i=1; i<=n; i++)
{
printf=0;
- if (GetGainFlag(i)) {cout << " gain : " << GetGain(i); printf=1;}
- if (GetOffsetFlag(i)) {cout << " offset : " << GetOffset(i); printf=1;}
- if (GetEdgeValue(i)) {cout << " edge : " << GetEdgeValue(i); printf=1;}
- if (GetDeadValue(i)) {cout << " dead : " << GetDeadValue(i); printf=1;}
+ if (GetGainFlag(i)) {cout << " gain : " << GetGain(i); printf=1;}
+ if (GetOffsetFlag(i)) {cout << " offset : " << GetOffset(i); printf=1;}
+ if (GetEdgeValue(i)) {cout << " edge : " << GetEdgeValue(i); printf=1;}
+ if (GetDeadValue(i)) {cout << " dead : " << GetDeadValue(i); printf=1;}
+ if (GetCalFunction(i)) {cout << " *Fcalib*"; printf=1;}
+ if (GetDecalFunction(i)) {cout << " *Fdecalib*"; printf=1;}
s=GetSlotName(i);
if (s!="") {cout << " name : " << s.Data(); printf=1;}
if (printf) cout << endl;
}
}
n=a.GetNnames();
+ TString s;
+ for (Int_t in=1; in<=n; in++)
{
- TString s;
- for (Int_t in=1; in<=n; in++)
- {
- s=a.GetSlotName(in);
- if (s!="") SetSlotName(s,in);
- }
+ s=a.GetSlotName(in);
+ SetSlotName(s,in);
+ }
+ n=a.GetNcalfuncs();
+ for (Int_t icalf=1; icalf<=n; icalf++)
+ {
+ TF1* f=a.GetCalFunction(icalf);
+ SetCalFunction(f,icalf);
+ }
+ n=a.GetNdecalfuncs();
+ for (Int_t idecalf=1; idecalf<=n; idecalf++)
+ {
+ TF1* f=a.GetDecalFunction(idecalf);
+ SetDecalFunction(f,idecalf);
}
}
else // load attributes for specified j-th slot only
}
}
n=a.GetNnames();
+ TString s;
+ if (j<=n)
{
- TString s;
- if (j<=n)
- {
- s=a.GetSlotName(j);
- if (s!="") SetSlotName(s,j);
- }
+ s=a.GetSlotName(j);
+ SetSlotName(s,j);
+ }
+ n=a.GetNcalfuncs();
+ if (j<=n)
+ {
+ TF1* f=a.GetCalFunction(j);
+ SetCalFunction(f,j);
+ }
+ n=a.GetNdecalfuncs();
+ if (j<=n)
+ {
+ TF1* f=a.GetDecalFunction(j);
+ SetDecalFunction(f,j);
}
}
}
if (j>0) Load(a,j);
}
///////////////////////////////////////////////////////////////////////////
+Int_t AliAttrib::GetNcalfuncs() const
+{
+// Provide the number of specified calib. functions for this attribute.
+
+ Int_t n=0;
+ if (fCalfuncs) n=fCalfuncs->GetSize();
+ return n;
+}
+///////////////////////////////////////////////////////////////////////////
+Int_t AliAttrib::GetNdecalfuncs() const
+{
+// Provide the number of specified de-calib. functions for this attribute.
+
+ Int_t n=0;
+ if (fDecalfuncs) n=fDecalfuncs->GetSize();
+ return n;
+}
+///////////////////////////////////////////////////////////////////////////
+TF1* AliAttrib::GetCalFunction(Int_t j) const
+{
+// Provide pointer to the calib. function of the j-th (default j=1) slot.
+// Note : The first attribute slot is at j=1.
+
+ TF1* f=0;
+ if (j>0 && j<=GetNcalfuncs()) f=(TF1*)fCalfuncs->At(j-1);
+ return f;
+}
+///////////////////////////////////////////////////////////////////////////
+TF1* AliAttrib::GetCalFunction(TString name) const
+{
+// Provide pointer to the calib. function of the name-specified slot.
+// In case no match is found, zero is returned.
+
+ TF1* f=0;
+ Int_t j=GetSlotIndex(name);
+ if (j>0) GetCalFunction(j);
+ return f;
+}
+///////////////////////////////////////////////////////////////////////////
+void AliAttrib::SetCalFunction(TF1* f,Int_t j)
+{
+// Set the calib. function of the j-th (default j=1) slot.
+// Note : The first attribute slot is at j=1.
+//
+// In case the value of the index j exceeds the maximum number of reserved
+// positions for the functions, the number of reserved positions for the functions
+// is increased automatically.
+//
+// In case the function pointer argument has the same value as the current function
+// pointer value, no action is taken since the user has already modified the actual
+// function.
+//
+// In case the function pointer argument is zero, the current function
+// is deleted and the pointer set to zero.
+//
+// In all other cases the current function is deleted and a new
+// copy of the input function is created which becomes the current function.
+
+ if (j<1) return;
+
+ if (!fCalfuncs)
+ {
+ fCalfuncs=new TObjArray(j);
+ fCalfuncs->SetOwner();
+ }
+
+ if (j > fCalfuncs->GetSize()) fCalfuncs->Expand(j);
+
+ TF1* fcur=(TF1*)fCalfuncs->At(j-1);
+ if (f != fcur)
+ {
+ if (fcur)
+ {
+ fCalfuncs->Remove(fcur);
+ delete fcur;
+ fcur=0;
+ }
+ if (f)
+ {
+ fcur=new TF1(*f);
+ fCalfuncs->AddAt(fcur,j-1);
+ }
+ }
+}
+///////////////////////////////////////////////////////////////////////////
+void AliAttrib::SetCalFunction(TF1* f,TString name)
+{
+// Set the calib. function of the name-specified slot.
+//
+// In case the function pointer argument has the same value as the current function
+// pointer value, no action is taken since the user has already modified the actual
+// function.
+//
+// In case the function pointer argument is zero, the current function
+// is deleted and the pointer set to zero.
+//
+// In all other cases the current function is deleted and a new
+// copy of the input function is created which becomes the current function.
+
+ Int_t j=GetSlotIndex(name);
+ if (j>0) SetCalFunction(f,j);
+}
+///////////////////////////////////////////////////////////////////////////
+TF1* AliAttrib::GetDecalFunction(Int_t j) const
+{
+// Provide pointer to the de-calib. function of the j-th (default j=1) slot.
+// Note : The first attribute slot is at j=1.
+
+ TF1* f=0;
+ if (j>0 && j<=GetNdecalfuncs()) f=(TF1*)fDecalfuncs->At(j-1);
+ return f;
+}
+///////////////////////////////////////////////////////////////////////////
+TF1* AliAttrib::GetDecalFunction(TString name) const
+{
+// Provide pointer to the de-calib. function of the name-specified slot.
+// In case no match is found, zero is returned.
+
+ TF1* f=0;
+ Int_t j=GetSlotIndex(name);
+ if (j>0) GetDecalFunction(j);
+ return f;
+}
+///////////////////////////////////////////////////////////////////////////
+void AliAttrib::SetDecalFunction(TF1* f,Int_t j)
+{
+// Set the de-calib. function of the j-th (default j=1) slot.
+// Note : The first attribute slot is at j=1.
+//
+// In case the value of the index j exceeds the maximum number of reserved
+// positions for the functions, the number of reserved positions for the functions
+// is increased automatically.
+//
+// In case the function pointer argument has the same value as the current function
+// pointer value, no action is taken since the user has already modified the actual
+// function.
+//
+// In case the function pointer argument is zero, the current function
+// is deleted and the pointer set to zero.
+//
+// In all other cases the current function is deleted and a new
+// copy of the input function is created which becomes the current function.
+
+ if (j<1) return;
+
+ if (!fDecalfuncs)
+ {
+ fDecalfuncs=new TObjArray(j);
+ fDecalfuncs->SetOwner();
+ }
+
+ if (j > fDecalfuncs->GetSize()) fDecalfuncs->Expand(j);
+
+ TF1* fcur=(TF1*)fDecalfuncs->At(j-1);
+ if (f != fcur)
+ {
+ if (fcur)
+ {
+ fDecalfuncs->Remove(fcur);
+ delete fcur;
+ fcur=0;
+ }
+ if (f)
+ {
+ fcur=new TF1(*f);
+ fDecalfuncs->AddAt(fcur,j-1);
+ }
+ }
+}
+///////////////////////////////////////////////////////////////////////////
+void AliAttrib::SetDecalFunction(TF1* f,TString name)
+{
+// Set the de-calib. function of the name-specified slot.
+//
+// In case the function pointer argument has the same value as the current function
+// pointer value, no action is taken since the user has already modified the actual
+// function.
+//
+// In case the function pointer argument is zero, the current function
+// is deleted and the pointer set to zero.
+//
+// In all other cases the current function is deleted and a new
+// copy of the input function is created which becomes the current function.
+
+ Int_t j=GetSlotIndex(name);
+ if (j>0) SetDecalFunction(f,j);
+}
+///////////////////////////////////////////////////////////////////////////
// Class AliSignal
// Generic handling of (extrapolated) detector signals.
//
+// The user can decide to store either calibrated or uncalibrated signals.
+// Via the specification of a gain and offset or/and an explicit
+// (de)calibration function both calibrated and uncalibrated signals
+// can always be obtained. For details see the documentation of the
+// memberfunction GetSignal() and the class AliAttrib.
+// The explicit specification of a (de)calibration function offers the
+// maximum flexibility and also allows automatic indication whether
+// calibrated or uncalibrated data has been stored.
+// The latter can be achieved by only specifying a calibration function
+// (and no de-calibration function) in case uncalibrated data is stored,
+// whereas in case of stored calibrated data the user should only
+// provide a de-calibration function (and no calibration function).
+//
// Note :
// ------
// Signal positions (r) and reference frames (f) are specified via
// signal=82.5; // e.g. signal time in ns
// error=2.01;
// offset=0.003;
-// q.SetSlotName("TOF");
+// q.SetSlotName("TOF",1);
// q.SetSignal(signal,1);
// q.SetSignalError(error,1);
// q.SetOffset(offset,1);
// signal=268.1; // e.g. ADC value of signal
// error=3.75;
// gain=120.78;
+// offset=1.5732;
// // Addressing via name specification instead of index
-// q.SetSlotName("ADC");
+// q.SetSlotName("ADC",2);
// q.SetSignal(signal,"ADC");
// q.SetSignalError(error,"ADC");
// q.SetGain(gain,"ADC");
+// q.SetOffset(offset,"ADC");
// signal=23.7; // e.g. corresponding dE/dx value
// error=0.48;
-// offset=0.2;
-// gain=150;
-// q.SetSlotName("dE/dx");
-// q.SetSignal(signal,3);
-// q.SetSignalError(error,3);
-// q.SetOffset(offset,3);
-// q.SetGain(gain,3);
-//
-// Float_t dedx=q.GetSignal("dE/dx");
+// TF1 f=("calib","[0]*pow(x,2)+[1]"); // dE/dx calib. function
+// f.SetParameter(0,3.285);
+// f.SetParameter(1,-18.67);
+// q.SetSlotName("dE/dx",3);
+// q.SetCalFunction(&f,"dE/dx");
+// q.SetSignal(signal,"dE/dx");
+// q.SetSignalError(error,"dE/dx");
+//
+// // Signal retrieval with various (de)calibration modes
+// Float_t tof=q.GetSignal("TOF");
+// Float_t adc=q.GetSignal("ADC",1);
+// Float_t dedx=q.GetSignal("dE/dx",3);
//
//--- Author: Nick van Eijndhoven 23-jan-1999 UU-SAP Utrecht
//- Modified: NvE $Date$ UU-SAP Utrecht
{
// Provide signal value of the j-th (default j=1) slot.
// Note : The first signal slot is at j=1.
-// In case no signal is present or the argument j is invalid, 0 is returned.
-// The parameter "mode" allows for automatic gain etc... correction of the signal.
+// In case no signal is present or the input argument "j" or "mode" is invalid,
+// the value 0 is returned.
+// The parameter "mode" allows for automatic (de)calibration of the signal
+// (e.g. gain etc... correction or via explicit (de)calibration functions).
//
// mode = 0 : Just the j-th signal is returned.
// 1 : The j-th signal is corrected for the gain, offset, dead flag etc...
+// In case the j-th slot was marked dead, 0 is returned.
// In case the gain value was not set, gain=1 will be assumed.
// In case the gain value was 0, a signal value of 0 is returned.
// In case the offset value was not set, offset=0 will be assumed.
+// 2 : Same as mode=1 but gain, offset dead flag etc... are taken from
+// the AliDevice which owns this AliSignal object.
+// In case this AliSignal object has no parent AliDevice, just
+// the j-th signal is returned (like with mode=0).
+// 3 : The j-th signal is corrected using the corresponding calibration
+// function.
// In case the j-th slot was marked dead, 0 is returned.
+// In case no calibration function is present, just the j-th signal
+// is returned (like with mode=0).
+// 4 : Same as mode=3 but the calibration function is taken from
+// the AliDevice which owns this AliSignal object.
+// 5 : Same as mode=2 but in case no parent AliDevice is present
+// an automatic switch to mode=1 will be made.
+// 6 : Same as mode=4 but in case no parent AliDevice is present
+// an automatic switch to mode=3 will be made.
+//
+// <0 : The corresponding de-correction or de-calibration is performed
//
// The corrected signal (sigc) is determined as follows :
//
// sigc=(signal/gain)-offset
//
+// The de-corrected signal is determined as follows :
+//
+// signal=(sigc+offset)*gain
+//
// The default is mode=0.
+ if (abs(mode)>6) return 0;
+
Float_t sig=0;
Float_t gain=1;
Float_t offset=0;
+
+ AliSignal* sx=(AliSignal*)this;
+ if (abs(mode)==2 || abs(mode)>=4) sx=(AliSignal*)GetDevice();
+ if (!sx && abs(mode)>=5) sx=(AliSignal*)this;
+ if (mode==5) mode=2;
+ if (mode==-5) mode=-2;
+ if (mode==6) mode=3;
+ if (mode==-6) mode=-3;
+
if (fSignals)
{
if (j>0 && j<=(fSignals->GetSize()))
{
sig=fSignals->At(j-1);
- if (mode==0) return sig;
-
- // Correct the signal for the gain, offset, dead flag etc...
- if (GetDeadValue(j)) return 0;
+ if (mode==0 || !sx) return sig;
- if (GetGainFlag(j)) gain=GetGain(j);
- if (GetOffsetFlag(j)) offset=GetOffset(j);
+ // Check for the dead flag setting
+ if (sx->GetDeadValue(j)) return 0;
- if (fabs(gain)>0.)
+ // (De)correct the signal for the gain and offset
+ if (abs(mode)==1 || abs(mode)==2)
{
- sig=(sig/gain)-offset;
+ if (sx->GetGainFlag(j)) gain=sx->GetGain(j);
+ if (sx->GetOffsetFlag(j)) offset=sx->GetOffset(j);
+
+ if (fabs(gain)>0.)
+ {
+ if (mode>0) sig=(sig/gain)-offset; // Gain and offset correction
+ if (mode<0) sig=(sig+offset)*gain; // Gain and offset de-correction
+ }
+ else
+ {
+ sig=0;
+ }
+ return sig;
}
- else
+
+ // (De)calibrate the signal with the corresponding (de)calibration function
+ if (abs(mode)==3 || abs(mode)==4)
{
- sig=0;
+ TF1* f=sx->GetCalFunction(j);
+ if (mode<0) f=sx->GetDecalFunction(j);
+ if (f) sig=f->Eval(sig);
+ return sig;
}
}
else
Int_t nerrors=GetNerrors();
Int_t nlinkslots=0;
if (fLinks) nlinkslots=fLinks->GetMaxColumn();
+ Int_t ncalibs=GetNcalflags();
+ Int_t ncalfuncs=GetNcalfuncs();
+ Int_t ndecalfuncs=GetNdecalfuncs();
+
Int_t n=nvalues;
if (nerrors>n) n=nerrors;
if (nlinkslots>n) n=nlinkslots;
-
+ if (InheritsFrom("AliDevice"))
+ {
+ if (ncalibs>n) n=ncalibs;
+ if (ncalfuncs>n) n=ncalfuncs;
+ if (ndecalfuncs>n) n=ndecalfuncs;
+ }
+
TObject* obj=0;
Int_t nrefs=0;
TArrayI posarr;