--- /dev/null
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+// $Id$
+
+///////////////////////////////////////////////////////////////////////////
+// Class AliAttrib
+// Generic handling of detector signal (calibration) attributes.
+// Normally this class is only used as a base class to provide the various
+// attributes to the derived class. An example of this is AliSignal.
+// However, one can of course also use this class on its own as shown
+// in the simple example hereafter.
+//
+// Example :
+// ---------
+// AliAttrib a;
+// a.SetGain(250.7);
+// a.SetSlotName("PMT amplitude in Volt");
+// a.SetGain(1340,3);
+// a.SetSlotName("PMT amplitude in ADC",3);
+// a.SetEdgeOn(3);
+// a.SetOffset(-22.5,2);
+// a.SetSlotName("Time of flight in ns",2);
+// a.SetDead(1);
+// a.Data();
+//
+//--- Author: Nick van Eijndhoven 18-sep-2003 Utrecht University
+//- Modified: NvE $Date$ Utrecht University
+///////////////////////////////////////////////////////////////////////////
+
+#include "AliAttrib.h"
+#include "Riostream.h"
+
+ClassImp(AliAttrib) // Class implementation to enable ROOT I/O
+
+AliAttrib::AliAttrib()
+{
+// Creation of an AliAttrib object and initialisation of parameters.
+// Several values of the same type (e.g. gain) can be stored in different slots.
+// If needed, the storage for values will be expanded automatically
+// when entering values.
+ fGains=0;
+ fOffsets=0;
+ fCalflags=0;
+ fNames=0;
+}
+///////////////////////////////////////////////////////////////////////////
+AliAttrib::~AliAttrib()
+{
+// Destructor to delete dynamically allocated memory
+ if (fGains)
+ {
+ delete fGains;
+ fGains=0;
+ }
+ if (fOffsets)
+ {
+ delete fOffsets;
+ fOffsets=0;
+ }
+ if (fCalflags)
+ {
+ delete fCalflags;
+ fCalflags=0;
+ }
+ if (fNames)
+ {
+ delete fNames;
+ fNames=0;
+ }
+}
+///////////////////////////////////////////////////////////////////////////
+AliAttrib::AliAttrib(AliAttrib& a)
+{
+// Copy constructor
+ fGains=0;
+ fOffsets=0;
+ fCalflags=0;
+ fNames=0;
+
+ Int_t n=0;
+ Double_t val=0;
+
+ n=a.GetNgains();
+ for (Int_t ig=1; ig<=n; ig++)
+ {
+ val=a.GetGain(ig);
+ if (a.GetGainFlag(ig)) SetGain(val,ig);
+ }
+
+ n=a.GetNoffsets();
+ for (Int_t io=1; io<=n; io++)
+ {
+ val=a.GetOffset(io);
+ if (a.GetOffsetFlag(io)) SetOffset(val,io);
+ }
+
+ n=a.GetNcalflags();
+ for (Int_t ic=1; ic<=n; ic++)
+ {
+ SetEdgeValue(a.GetEdgeValue(ic),ic);
+ if (a.GetDeadValue(ic)) SetDead(ic);
+ }
+
+ n=a.GetNnames();
+ TString s;
+ for (Int_t in=1; in<=n; in++)
+ {
+ s=a.GetSlotName(in);
+ if (s!="") SetSlotName(s,in);
+ }
+}
+///////////////////////////////////////////////////////////////////////////
+Int_t AliAttrib::GetNgains()
+{
+// Provide the number of specified gains for this attribute.
+ Int_t n=0;
+ if (fGains) n=fGains->GetSize();
+ return n;
+}
+///////////////////////////////////////////////////////////////////////////
+Int_t AliAttrib::GetNoffsets()
+{
+// Provide the number of specified offsets for this attribute.
+ Int_t n=0;
+ if (fOffsets) n=fOffsets->GetSize();
+ return n;
+}
+///////////////////////////////////////////////////////////////////////////
+Int_t AliAttrib::GetNcalflags()
+{
+// Provide the number of specified calib. flags for this attribute.
+ Int_t n=0;
+ if (fCalflags) n=fCalflags->GetSize();
+ return n;
+}
+///////////////////////////////////////////////////////////////////////////
+Int_t AliAttrib::GetNnames()
+{
+// Provide the maximum number of specified names for this attribute.
+ Int_t n=0;
+ if (fNames) n=fNames->GetSize();
+ return n;
+}
+///////////////////////////////////////////////////////////////////////////
+void AliAttrib::SetGain(Double_t gain,Int_t j)
+{
+// Store gain value of the j-th (default j=1) attribute slot.
+// Note : The first attribute slot is at j=1.
+// In case the value of the index j exceeds the maximum number of reserved
+// slots for gain values, the number of reserved slots for the gain
+// values is increased automatically.
+
+ if (j<1)
+ {
+ cout << " *AliAttrib::SetGain* Invalid argument j = " << j << endl;
+ return;
+ }
+
+ if (!fGains)
+ {
+ fGains=new TArrayF(j);
+ }
+
+ Int_t size=fGains->GetSize();
+
+ if (j>size)
+ {
+ fGains->Set(j);
+ }
+
+ fGains->AddAt(float(gain),j-1);
+
+ Int_t oflag=GetOffsetFlag(j);
+
+ SetCalFlags(1,oflag,j);
+}
+///////////////////////////////////////////////////////////////////////////
+void AliAttrib::SetOffset(Double_t off,Int_t j)
+{
+// Store offset value of the j-th (default j=1) attribute slot.
+// Note : The first attribute slot is at j=1.
+// In case the value of the index j exceeds the maximum number of reserved
+// slots for offset values, the number of reserved slots for the offset
+// values is increased automatically.
+
+ if (j<1)
+ {
+ cout << " *AliAttrib::GetOffset* Invalid argument j = " << j << endl;
+ return;
+ }
+
+ if (!fOffsets)
+ {
+ fOffsets=new TArrayF(j);
+ }
+
+ Int_t size=fOffsets->GetSize();
+
+ if (j>size)
+ {
+ fOffsets->Set(j);
+ }
+
+ fOffsets->AddAt(float(off),j-1);
+
+ Int_t gflag=GetGainFlag(j);
+
+ SetCalFlags(gflag,1,j);
+}
+///////////////////////////////////////////////////////////////////////////
+void AliAttrib::SetCalFlags(Int_t gainflag,Int_t offsetflag,Int_t j)
+{
+// Store calibration flags of the j-th (default j=1) attribute slot.
+// Note : The first attribute slot is at j=1.
+// In case the value of the index j exceeds the maximum number of reserved
+// slots for the calib. flags, the number of reserved slots for the calib.
+// flags is increased automatically.
+// The value stored is : 1000*edge + 100*dead + 10*gainflag + offsetflag.
+
+ if (j<1)
+ {
+ cout << " *AliAttrib::GetCalFlags* Invalid argument j = " << j << endl;
+ return;
+ }
+
+ if (!fCalflags)
+ {
+ fCalflags=new TArrayI(j);
+ }
+
+ Int_t size=fCalflags->GetSize();
+
+ if (j>size)
+ {
+ fCalflags->Set(j);
+ }
+
+ Int_t edge=GetEdgeValue(j);
+ Int_t dead=GetDeadValue(j);
+
+ Int_t word=1000*edge+100*dead+10*gainflag+offsetflag;
+
+ fCalflags->AddAt(word,j-1);
+}
+///////////////////////////////////////////////////////////////////////////
+Int_t AliAttrib::GetGainFlag(Int_t j)
+{
+// Provide gain flag of the j-th (default j=1) attribute slot.
+//
+// flag = 1 : Gain was set
+// 0 : Gain was not set
+//
+// Note : The first attribute slot is at j=1.
+// In case j is invalid, 0 is returned.
+
+ if (j<1)
+ {
+ cout << " *AliAttrib::GetGainFlag* Invalid argument j = " << j << endl;
+ return 0;
+ }
+ Int_t gflag=0;
+ if (fCalflags)
+ {
+ if (j>0 && j<=(fCalflags->GetSize()))
+ {
+ Int_t word=fCalflags->At(j-1);
+ word=word%100;
+ gflag=word/10;
+ }
+ }
+ return gflag;
+}
+///////////////////////////////////////////////////////////////////////////
+Int_t AliAttrib::GetOffsetFlag(Int_t j)
+{
+// Provide offset flag of the j-th (default j=1) attribute slot.
+//
+// flag = 1 : Offset was set
+// 0 : Offset was not set
+//
+// Note : The first attribute slot is at j=1.
+// In case j is invalid, 0 is returned.
+
+ if (j<1)
+ {
+ cout << " *AliAttrib::GetOffsetFlag* Invalid argument j = " << j << endl;
+ return 0;
+ }
+
+ Int_t oflag=0;
+ if (fCalflags)
+ {
+ if (j>0 && j<=(fCalflags->GetSize()))
+ {
+ Int_t word=fCalflags->At(j-1);
+ oflag=word%10;
+ }
+ }
+ return oflag;
+}
+///////////////////////////////////////////////////////////////////////////
+Float_t AliAttrib::GetGain(Int_t j)
+{
+// Provide gain value of the j-th (default j=1) attribute slot.
+// The first attribute slot is at j=1.
+// In case no gain value was set or the argument j is invalid, 0 is returned.
+// Note : Use GetGainFlag(j) to check whether this gain was set or not.
+
+ if (j<1)
+ {
+ cout << " *AliAttrib::GetGain* Invalid argument j = " << j << endl;
+ return 0;
+ }
+
+ Float_t gain=0;
+ if (fGains)
+ {
+ if (j>0 && j<=(fGains->GetSize()))
+ {
+ if (GetGainFlag(j)) gain=fGains->At(j-1);
+ }
+ }
+ return gain;
+}
+///////////////////////////////////////////////////////////////////////////
+Float_t AliAttrib::GetOffset(Int_t j)
+{
+// Provide offset value of the j-th (default j=1) attribute slot.
+// The first attribute slot at j=1.
+// In case no offset value was set or the argument j is invalid, 0 is returned.
+// Note : Use GetOffsetFlag(j) to check whether this offset was set or not.
+
+ if (j<1)
+ {
+ cout << " *AliAttrib::GetOffset* Invalid argument j = " << j << endl;
+ return 0;
+ }
+
+ Float_t offset=0;
+ if (fOffsets)
+ {
+ if (j>0 && j<=(fOffsets->GetSize()))
+ {
+ if (GetOffsetFlag(j)) offset=fOffsets->At(j-1);
+ }
+ }
+ return offset;
+}
+///////////////////////////////////////////////////////////////////////////
+void AliAttrib::ResetGain(Int_t j)
+{
+// Reset the gain value of the j-th (default j=1) attribute slot.
+// Notes : The first attribute slot is at j=1.
+// j=0 ==> All gain values will be reset.
+
+ if (!fGains) return;
+
+ Int_t size=fGains->GetSize();
+
+ if ((j>=0) && (j<=size))
+ {
+ if (j)
+ {
+ fGains->AddAt(0,j-1);
+ Int_t oflag=GetOffsetFlag(j);
+ SetCalFlags(0,oflag,j);
+ }
+ else
+ {
+ for (Int_t i=0; i<size; i++)
+ {
+ fGains->AddAt(0,i);
+ Int_t oflag=GetOffsetFlag(i);
+ SetCalFlags(0,oflag,i);
+ }
+ }
+ }
+ else
+ {
+ cout << " *AliAttrib::ResetGain* Index j = " << j << " invalid." << endl;
+ return;
+ }
+}
+///////////////////////////////////////////////////////////////////////////
+void AliAttrib::ResetOffset(Int_t j)
+{
+// Reset the offset value of the j-th (default j=1) attribute slot.
+// Notes : The first attribute slot is at j=1.
+// j=0 ==> All offset values will be reset.
+
+ if (!fOffsets) return;
+
+ Int_t size=fOffsets->GetSize();
+
+ if ((j>=0) && (j<=size))
+ {
+ if (j)
+ {
+ fOffsets->AddAt(0,j-1);
+ Int_t gflag=GetGainFlag(j);
+ SetCalFlags(gflag,0,j);
+ }
+ else
+ {
+ for (Int_t i=0; i<size; i++)
+ {
+ fOffsets->AddAt(0,i);
+ Int_t gflag=GetGainFlag(i);
+ SetCalFlags(gflag,0,i);
+ }
+ }
+ }
+ else
+ {
+ cout << " *AliAttrib::ResetOffset* Index j = " << j << " invalid." << endl;
+ return;
+ }
+}
+///////////////////////////////////////////////////////////////////////////
+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.
+// 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.
+//
+// The default when invoking DeleteCalibrations() corresponds to mode=0.
+
+ if (mode<0 || mode>3)
+ {
+ cout << " *AliAttrib::DeleteCalibrations* Unknown mode : " << mode << endl;
+ cout << " Default mode=0 will be used." << endl;
+ mode=0;
+ }
+
+ if (mode==0 || mode==3)
+ {
+ ResetGain(0);
+ if (fGains)
+ {
+ delete fGains;
+ fGains=0;
+ }
+ ResetOffset(0);
+ if (fOffsets)
+ {
+ delete fOffsets;
+ fOffsets=0;
+ }
+ if (fCalflags && mode==0)
+ {
+ delete fCalflags;
+ fCalflags=0;
+ }
+ if (fNames && mode==0)
+ {
+ delete fNames;
+ fNames=0;
+ }
+ return;
+ }
+
+ if (mode==1)
+ {
+ ResetGain(0);
+ if (fGains)
+ {
+ delete fGains;
+ fGains=0;
+ }
+ }
+ else
+ {
+ ResetOffset(0);
+ if (fOffsets)
+ {
+ delete fOffsets;
+ fOffsets=0;
+ }
+ }
+}
+///////////////////////////////////////////////////////////////////////////
+void AliAttrib::SetDead(Int_t j)
+{
+// Set the dead flag to 1 for the j-th (default j=1) attribute slot.
+// Note : The first attribute slot is at j=1.
+// In case the value of the index j exceeds the maximum number of reserved
+// slots for the flags, the number of reserved slots for the flags
+// is increased automatically.
+// The value stored is : 1000*edge + 100*dead + 10*gainflag + offsetflag.
+
+ if (j<1)
+ {
+ cout << " *AliAttrib::SetDead* Invalid argument j = " << j << endl;
+ return;
+ }
+
+ if (!fCalflags)
+ {
+ fCalflags=new TArrayI(j);
+ }
+
+ Int_t size=fCalflags->GetSize();
+
+ if (j>size)
+ {
+ fCalflags->Set(j);
+ }
+
+ Int_t dead=1;
+ Int_t oflag=GetOffsetFlag(j);
+ Int_t gflag=GetGainFlag(j);
+ Int_t edge=GetEdgeValue(j);
+
+ Int_t word=1000*edge+100*dead+10*gflag+oflag;
+
+ fCalflags->AddAt(word,j-1);
+}
+///////////////////////////////////////////////////////////////////////////
+void AliAttrib::SetAlive(Int_t j)
+{
+// Set the dead flag to 0 for the j-th (default j=1) attribute slot.
+// Note : The first attribute slot is at j=1.
+// In case the value of the index j exceeds the maximum number of reserved
+// slots for the flags, no action is taken since by default the dead flag is 0.
+// The value stored is : 1000*edge + 100*dead + 10*gainflag + offsetflag.
+
+ if (j<1)
+ {
+ cout << " *AliAttrib::SetAlive* Invalid argument j = " << j << endl;
+ return;
+ }
+
+ if (!fCalflags || j>fCalflags->GetSize()) return;
+
+ Int_t dead=0;
+ Int_t oflag=GetOffsetFlag(j);
+ Int_t gflag=GetGainFlag(j);
+ Int_t edge=GetEdgeValue(j);
+
+ Int_t word=1000*edge+100*dead+10*gflag+oflag;
+
+ fCalflags->AddAt(word,j-1);
+}
+///////////////////////////////////////////////////////////////////////////
+void AliAttrib::SetEdgeOn(Int_t j)
+{
+// Set the edge value to 1 for the j-th (default j=1) attribute slot.
+// Note : The first attribute slot is at j=1.
+// In case the value of the index j exceeds the maximum number of reserved
+// slots for the flags, the number of reserved slots for the flags
+// is increased automatically.
+// The value stored is : 1000*edge + 100*dead + 10*gainflag + offsetflag.
+
+ if (j<1)
+ {
+ cout << " *AliAttrib::SetEdgeOn* Invalid argument j = " << j << endl;
+ return;
+ }
+
+ SetEdgeValue(1,j);
+}
+///////////////////////////////////////////////////////////////////////////
+void AliAttrib::SetEdgeOff(Int_t j)
+{
+// Set the edge value to 0 for the j-th (default j=1) attribute slot.
+// Note : The first attribute slot is at j=1.
+// In case the value of the index j exceeds the maximum number of reserved
+// slots for the flags, no action is taken since by default the edge flag is 0.
+// The value stored is : 1000*edge + 100*dead + 10*gainflag + offsetflag.
+
+ if (j<1)
+ {
+ cout << " *AliAttrib::SetEdgeOff* Invalid argument j = " << j << endl;
+ return;
+ }
+
+ if (!fCalflags || j>fCalflags->GetSize()) return;
+
+ SetEdgeValue(0,j);
+}
+///////////////////////////////////////////////////////////////////////////
+void AliAttrib::SetEdgeValue(Int_t val,Int_t j)
+{
+// Set the edge value to "val" for the j-th (default j=1) attribute slot.
+// Note : The first attribute slot is at j=1.
+// In case the value of the index j exceeds the maximum number of reserved
+// slots for the flags, the number of reserved slots for the flags
+// is increased automatically.
+// The value stored is : 1000*edge + 100*dead + 10*gainflag + offsetflag.
+
+ if (j<1)
+ {
+ cout << " *AliAttrib::SetEdgeValue* Invalid argument j = " << j << endl;
+ return;
+ }
+
+ if (!fCalflags)
+ {
+ fCalflags=new TArrayI(j);
+ }
+
+ Int_t size=fCalflags->GetSize();
+
+ if (j>size)
+ {
+ fCalflags->Set(j);
+ }
+
+ Int_t edge=val;
+ Int_t dead=GetDeadValue(j);
+ Int_t gflag=GetGainFlag(j);
+ Int_t oflag=GetOffsetFlag(j);
+
+ Int_t word=1000*edge+100*dead+10*gflag+oflag;
+
+ fCalflags->AddAt(word,j-1);
+}
+///////////////////////////////////////////////////////////////////////////
+void AliAttrib::IncreaseEdgeValue(Int_t j)
+{
+// Increase the edge value by 1 for the j-th (default j=1) attribute slot.
+// Note : The first attribute slot is at j=1.
+// In case the value of the index j exceeds the maximum number of reserved
+// slots for the flags, the number of reserved slots for the flags
+// is increased automatically.
+// The value stored is : 1000*edge + 100*dead + 10*gainflag + offsetflag.
+
+ if (j<1)
+ {
+ cout << " *AliAttrib::IncreaseEdgeValue* Invalid argument j = " << j << endl;
+ return;
+ }
+
+ Int_t edge=GetEdgeValue();
+ SetEdgeValue(edge+1,j);
+}
+///////////////////////////////////////////////////////////////////////////
+void AliAttrib::DecreaseEdgeValue(Int_t j)
+{
+// Decrease the edge value by 1 for the j-th (default j=1) attribute slot.
+// Note : The first attribute slot is at j=1.
+// In case the value of the index j exceeds the maximum number of reserved
+// slots for the flags, the number of reserved slots for the flags
+// is increased automatically.
+// The value stored is : 1000*edge + 100*dead + 10*gainflag + offsetflag.
+
+ if (j<1)
+ {
+ cout << " *AliAttrib::DecreaseEdgeValue* Invalid argument j = " << j << endl;
+ return;
+ }
+
+ Int_t edge=GetEdgeValue();
+ SetEdgeValue(edge-1,j);
+}
+///////////////////////////////////////////////////////////////////////////
+Int_t AliAttrib::GetEdgeValue(Int_t j)
+{
+// Provide edge value of the j-th (default j=1) attribute slot.
+// Note : The first attribute slot is at j=1.
+// In case j is invalid, 0 is returned.
+
+ if (j<1)
+ {
+ cout << " *AliAttrib::GetEdgeValue* Invalid argument j = " << j << endl;
+ return 0;
+ }
+
+ Int_t edge=0;
+ if (fCalflags)
+ {
+ if (j>0 && j<=(fCalflags->GetSize()))
+ {
+ Int_t word=fCalflags->At(j-1);
+ edge=word/1000;
+ }
+ }
+ return edge;
+}
+///////////////////////////////////////////////////////////////////////////
+Int_t AliAttrib::GetDeadValue(Int_t j)
+{
+// Provide dead value of the j-th (default j=1) attribute slot.
+// Note : The first attribute slot is at j=1.
+// In case j is invalid, 0 is returned.
+
+ if (j<1)
+ {
+ cout << " *AliAttrib::GetDeadValue* Invalid argument j = " << j << endl;
+ return 0;
+ }
+
+ Int_t dead=0;
+ if (fCalflags)
+ {
+ if (j>0 && j<=(fCalflags->GetSize()))
+ {
+ Int_t word=fCalflags->At(j-1);
+ word=word%1000;
+ dead=word/100;
+ }
+ }
+ return dead;
+}
+///////////////////////////////////////////////////////////////////////////
+AliAttrib* AliAttrib::MakeCopy(AliAttrib& a)
+{
+// Make a deep copy of the input object and provide the pointer to the copy.
+// This memberfunction enables automatic creation of new objects of the
+// correct type depending on the argument type, a feature which may be very useful
+// for containers when adding objects in case the container owns the objects.
+
+ AliAttrib* att=new AliAttrib(a);
+ return att;
+}
+///////////////////////////////////////////////////////////////////////////
+void AliAttrib::SetSlotName(TString s,Int_t j)
+{
+// Set a user defined name for the j-th (default j=1) slot.
+// Note : The first attribute slot is at j=1.
+
+ if (j<1)
+ {
+ cout << " *AliAttrib::SetSlotName* Invalid argument j = " << j << endl;
+ return;
+ }
+
+ if (!fNames)
+ {
+ fNames=new TObjArray(j);
+ fNames->SetOwner();
+ }
+
+ if (j>fNames->GetSize()) fNames->Expand(j);
+
+ TObjString* so=(TObjString*)fNames->At(j-1);
+ if (!so)
+ {
+ so=new TObjString(s.Data());
+ fNames->AddAt(so,j-1);
+ }
+ else
+ {
+ so->SetString(s);
+ }
+}
+///////////////////////////////////////////////////////////////////////////
+TString AliAttrib::GetSlotName(Int_t j)
+{
+// Provide the user defined name for the j-th (default j=1) slot.
+// Note : The first attribute slot is at j=1.
+
+ TString s="";
+ if (j<1)
+ {
+ cout << " *AliAttrib::GetSlotName* Invalid argument j = " << j << endl;
+ return s;
+ }
+
+ if (fNames)
+ {
+ if (j<=fNames->GetSize())
+ {
+ TObjString* so=(TObjString*)fNames->At(j-1);
+ if (so) s=so->GetString();
+ }
+ }
+ return s;
+}
+///////////////////////////////////////////////////////////////////////////
+Int_t AliAttrib::GetSlotIndex(TString name)
+{
+// Provide the slot index for the matching name.
+// If no matching name is found, 0 is returned.
+// Note : The first attribute slot is at j=1.
+
+ Int_t index=0;
+
+ if (fNames)
+ {
+ TString s;
+ Int_t size=fNames->GetSize();
+ for (Int_t i=0; i<size; i++)
+ {
+ TObjString* so=(TObjString*)fNames->At(i);
+ s=so->GetString();
+ if (s==name) index=i+1;
+ }
+ }
+ return index;
+}
+///////////////////////////////////////////////////////////////////////////
+void AliAttrib::Data(Int_t j)
+{
+// Provide attribute information for the j-th slot.
+// The first slot is at j=1.
+// In case j=0 (default) the data of all slots will be listed.
+
+ if (j<0)
+ {
+ cout << " *AliAttrib::Data* Invalid argument j = " << j << endl;
+ return;
+ }
+
+ if (j>0)
+ {
+ if (GetGainFlag(j)) cout << " gain : " << GetGain(j);
+ if (GetOffsetFlag(j)) cout << " offset : " << GetOffset(j);
+ if (GetEdgeValue(j)) cout << " edge : " << GetEdgeValue(j);
+ if (GetDeadValue(j)) cout << " dead : " << GetDeadValue(j);
+ TString s=GetSlotName(j);
+ if (s!="") cout << " name : " << s.Data();
+ }
+ else
+ {
+ Int_t ng=GetNgains();
+ Int_t no=GetNoffsets();
+ Int_t nf=0;
+ if (fCalflags) nf=fCalflags->GetSize();
+ Int_t nn=GetNnames();
+ Int_t n=ng;
+ if (n<no) n=no;
+ if (n<nn) n=nn;
+ if (n<nf) n=nf;
+ Int_t printf=0;
+ TString s;
+ 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;}
+ s=GetSlotName(i);
+ if (s!="") {cout << " name : " << s.Data(); printf=1;}
+ if (printf) cout << endl;
+ }
+ }
+}
+///////////////////////////////////////////////////////////////////////////
+void AliAttrib::Load(AliAttrib& a,Int_t j)
+{
+// Load attributes of the j-th slot of the input AliAttrib into this AliAttrib object.
+//
+// Note : if j=0, then all attributes of all slots are loaded
+//
+// The default is j=0.
+
+ if (j<0)
+ {
+ cout << " *AliAttrib::Load* Invalid argument j = " << j << endl;
+ return;
+ }
+
+ Int_t n=0;
+
+ if (j==0) // load attributes for all slots
+ {
+ n=a.GetNgains();
+ for (Int_t ig=1; ig<=n; ig++)
+ {
+ if (a.GetGainFlag(ig))
+ {
+ SetGain(a.GetGain(ig),ig);
+ }
+ else
+ {
+ ResetGain(ig);
+ }
+ }
+ n=a.GetNoffsets();
+ for (Int_t io=1; io<=n; io++)
+ {
+ if (a.GetOffsetFlag(io))
+ {
+ SetOffset(a.GetOffset(io),io);
+ }
+ else
+ {
+ ResetOffset(io);
+ }
+ }
+ n=a.GetNcalflags();
+ for (Int_t ic=1; ic<=n; ic++)
+ {
+ SetEdgeValue(a.GetEdgeValue(ic),ic);
+ if (a.GetDeadValue(ic))
+ {
+ SetDead(ic);
+ }
+ else
+ {
+ SetAlive(ic);
+ }
+ }
+ n=a.GetNnames();
+ {
+ TString s;
+ for (Int_t in=1; in<=n; in++)
+ {
+ s=a.GetSlotName(in);
+ if (s!="") SetSlotName(s,in);
+ }
+ }
+ }
+ else // load attributes for specified j-th slot only
+ {
+ n=a.GetNgains();
+ if (j<=n)
+ {
+ if (a.GetGainFlag(j))
+ {
+ SetGain(a.GetGain(j),j);
+ }
+ else
+ {
+ ResetGain(j);
+ }
+ }
+ n=a.GetNoffsets();
+ if (j<=n)
+ {
+ if (a.GetOffsetFlag(j))
+ {
+ SetOffset(a.GetOffset(j),j);
+ }
+ else
+ {
+ ResetOffset(j);
+ }
+ }
+ n=a.GetNcalflags();
+ if (j<=n)
+ {
+ SetEdgeValue(a.GetEdgeValue(j),j);
+ if (a.GetDeadValue(j))
+ {
+ SetDead(j);
+ }
+ else
+ {
+ SetAlive(j);
+ }
+ }
+ n=a.GetNnames();
+ {
+ TString s;
+ if (j<=n)
+ {
+ s=a.GetSlotName(j);
+ if (s!="") SetSlotName(s,j);
+ }
+ }
+ }
+}
+///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// Class AliCalorimeter
// Description of a modular calorimeter system.
-// A matrix geometry is used in which a module is identified by (row,col).
+// A generic 2D geometry is used in which a module is identified by (row,col).
+// Obviously this geometry can be a matrix, but also any other regular
+// structure is supported, provided the user has adopted a proper convention
+// to uniquely address a module via the (row,col) indices.
// Note : First module is identified as (1,1).
//
// This is the way to define and enter signals into a calorimeter :
//
-// AliCalorimeter cal(10,15); // Calorimeter of 10x15 modules
-// // All module signals set to 0.
+// AliCalorimeter cal;
+//
// cal.AddSignal(5,7,85.4);
// cal.AddSignal(5,7,25.9);
// cal.AddSignal(3,5,1000);
// // Perform grouping over 2 rings around the center
// cal.Reset(); // Reset the complete calorimeter
// // Normally to prepare for the next event data
-// // Note : Module gain, edge and dead flags remain
+// // Note : Module gain, offset, edge and dead flags remain
//
//--- Author: Nick van Eijndhoven 13-jun-1997 UU-SAP Utrecht
//- Modified: NvE $Date$ UU-SAP Utrecht
AliCalorimeter::AliCalorimeter() : TObject()
{
-// Default constructor, all parameters set to 0
+// Default constructor, all parameters set to 0.
+// Create a calorimeter module matrix with fixed row and column size.
+// Note : Due to the dynamic size extension when signals are set,
+// the "edge modules" can NOT be marked automatically.
+// This has to be done manually by the user via the SetEdgeOn()
+// memberfunction.
fNrows=0;
fNcolumns=0;
- fNsignals=0;
- fNclusters=0;
+ fSwap=0;
fMatrix=0;
fClusters=0;
- fModules=0;
fHmodules=0;
fHclusters=0;
- fNvetos=0;
fVetos=0;
fAttributes=0;
- fGains=0;
fPositions=0;
- fName="Unspecified";
+ fName="Unspecified AliCalorimeter";
}
///////////////////////////////////////////////////////////////////////////
AliCalorimeter::~AliCalorimeter()
{
// Destructor to delete memory allocated to the various arrays and matrices
- if (fModules)
- {
- delete fModules;
- fModules=0;
- }
if (fClusters)
{
delete fClusters;
delete fHclusters;
fHclusters=0;
}
-
- // Free memory allocated for (internal) module and position matrices.
- // The modules have already been deleted via the fModules I/O array,
- // so they shouldn't be deleted here anymore.
- if (fMatrix || fPositions)
+ if (fMatrix)
{
- for (Int_t i=0; i<fNrows; i++)
- {
- for (Int_t j=0; j<fNcolumns; j++)
- {
- if (fPositions[i][j]) delete fPositions[i][j];
- }
- if (fPositions[i]) delete [] fPositions[i];
- if (fMatrix[i]) delete [] fMatrix[i];
- }
- if (fMatrix)
- {
- delete [] fMatrix;
- fMatrix=0;
- }
- if (fPositions)
- {
- delete [] fPositions;
- fPositions=0;
- }
+ delete fMatrix;
+ fMatrix=0;
}
- if (fGains)
+ if (fPositions)
{
- delete fGains;
- fGains=0;
+ delete fPositions;
+ fPositions=0;
}
if (fAttributes)
{
///////////////////////////////////////////////////////////////////////////
AliCalorimeter::AliCalorimeter(Int_t nrow,Int_t ncol) : TObject()
{
-// Create a calorimeter module matrix
+// Create a calorimeter module matrix with fixed row and column size.
+// The modules at the edges are automatically marked as "edge modules".
fNrows=nrow;
fNcolumns=ncol;
- fNsignals=0;
- fModules=0;
- fNclusters=0;
fClusters=0;
- fAttributes=new TMatrix(nrow,ncol);
- fGains=new TMatrix(nrow,ncol);
- fMatrix=new AliCalmodule**[nrow];
- fPositions=new AliPosition**[nrow];
- for (Int_t row=0; row<nrow; row++)
- {
- fMatrix[row]=new AliCalmodule*[ncol];
- fPositions[row]=new AliPosition*[ncol];
- // Initialise the various matrices
- for (Int_t col=0; col<ncol; col++)
- {
- fMatrix[row][col]=0;
- fPositions[row][col]=0;
- (*fGains)(row,col)=1;
- (*fAttributes)(row,col)=0;
- }
- }
+ fSwap=0;
+ fMatrix=0;
+ fPositions=0;
+
+ fAttributes=new TObjArray(nrow);
+ fAttributes->SetOwner();
+
// Mark the edge modules
- for (Int_t j=0; j<ncol; j++)
+ for (Int_t row=1; row<=nrow; row++)
{
- (*fAttributes)(0,j)=10;
- (*fAttributes)(nrow-1,j)=10;
- }
- for (Int_t i=0; i<nrow; i++)
- {
- (*fAttributes)(i,0)=10;
- (*fAttributes)(i,ncol-1)=10;
+ AliAttribObj* a=new AliAttribObj();
+ if (row==1 || row==nrow)
+ {
+ for (Int_t col=1; col<=ncol; col++)
+ {
+ a->SetEdgeOn(col);
+ }
+ }
+ else
+ {
+ a->SetEdgeOn(1);
+ a->SetEdgeOn(ncol);
+ }
+ fAttributes->Add(a);
}
fHmodules=0;
fHclusters=0;
- fNvetos=0;
fVetos=0;
- fName="Unspecified";
+ fName="Unspecified AliCalorimeter";
}
///////////////////////////////////////////////////////////////////////////
AliCalorimeter::AliCalorimeter(AliCalorimeter& c) : TObject(c)
{
// Copy constructor
- fNsignals=0;
- fModules=0;
- fNclusters=0;
fClusters=0;
- fNvetos=0;
fVetos=0;
fAttributes=0;
- fGains=0;
fHmodules=0;
fHclusters=0;
fNcolumns=c.fNcolumns;
fName=c.fName;
- if (fNrows && fNcolumns)
+ fSwap=c.fSwap;
+
+ if (c.fPositions)
{
- if (c.fPositions)
+ Int_t nrows=(c.fPositions)->GetMaxRow();
+ Int_t ncols=(c.fPositions)->GetMaxColumn();
+ for (Int_t irow=1; irow<=nrows; irow++)
{
- for (Int_t irow=1; irow<=fNrows; irow++)
+ for (Int_t icol=1; icol<=ncols; icol++)
{
- for (Int_t icol=1; icol<=fNcolumns; icol++)
- {
- AliPosition* p=c.GetPosition(irow,icol);
- SetPosition(irow,icol,*p);
- }
- }
- }
-
- TMatrix* mat=c.fAttributes;
- if (mat) fAttributes=new TMatrix(*mat);
-
- mat=c.fGains;
- if (mat) fGains=new TMatrix(*mat);
+ AliPosition* p=c.GetPosition(irow,icol);
+ if (p) SetPosition(irow,icol,*p);
+ }
+ }
+ }
- if (c.fNclusters)
+ Int_t size=0;
+ Int_t n=0;
+ if (c.fAttributes)
+ {
+ size=c.fAttributes->GetSize();
+ n=c.fAttributes->GetEntries();
+ }
+ if (size)
+ {
+ fAttributes=new TObjArray(size);
+ fAttributes->SetOwner();
+ for (Int_t ia=0; ia<n; ia++)
{
- fClusters=new TObjArray();
- fClusters->SetOwner();
- for (Int_t icl=1; icl<=c.fNclusters; icl++)
- {
- AliCalcluster* cl=c.GetCluster(icl);
- fClusters->Add(new AliCalcluster(*cl));
- fNclusters++;
- }
+ AliAttribObj* a=(AliAttribObj*)(c.fAttributes->At(ia));
+ if (a) fAttributes->Add(new AliAttribObj(*a));
}
+ }
- for (Int_t im=1; im<=c.fNsignals; im++)
+ n=c.GetNclusters();
+ if (n)
+ {
+ fClusters=new TObjArray();
+ fClusters->SetOwner();
+ for (Int_t icl=1; icl<=n; icl++)
{
- AliCalmodule* m=c.GetModule(im);
- SetSignal(m->GetRow(),m->GetColumn(),m->GetSignal());
+ AliCalcluster* cl=c.GetCluster(icl);
+ if (cl) fClusters->Add(new AliCalcluster(*cl));
}
+ }
- for (Int_t iv=1; iv<=c.fNvetos; iv++)
+ n=c.GetNsignals();
+ if (n)
+ {
+ fMatrix=new AliObjMatrix();
+ fMatrix->SetOwner();
+ fMatrix->SetSwapMode(fSwap);
+ for (Int_t im=1; im<=n; im++)
{
- AliSignal* s=c.GetVetoSignal(iv);
- AddVetoSignal(s);
+ AliCalmodule* m=c.GetModule(im);
+ if (m) fMatrix->EnterObject(m->GetRow(),m->GetColumn(),new AliCalmodule(*m));
}
}
+
+ n=c.GetNvetos();
+ for (Int_t iv=1; iv<=n; iv++)
+ {
+ AliSignal* s=c.GetVetoSignal(iv);
+ if (s) AddVetoSignal(s);
+ }
}
///////////////////////////////////////////////////////////////////////////
Int_t AliCalorimeter::GetNrows()
{
// Provide the number of rows for the calorimeter module matrix
- return fNrows;
+ Int_t nrows=fNrows;
+ if (fMatrix && !nrows) nrows=fMatrix->GetMaxRow();
+ return nrows;
}
///////////////////////////////////////////////////////////////////////////
Int_t AliCalorimeter::GetNcolumns()
{
// Provide the number of columns for the calorimeter module matrix
- return fNcolumns;
+ Int_t ncols=fNcolumns;
+ if (fMatrix && !ncols) ncols=fMatrix->GetMaxColumn();
+ return ncols;
}
///////////////////////////////////////////////////////////////////////////
void AliCalorimeter::SetSignal(Int_t row,Int_t col,Float_t sig)
{
-// Set the signal for a certain calorimeter module
-
- if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
+// Set the signal for a certain calorimeter module.
+
+ // Check for (row,col) boundaries.
+ if (row<1 || col<1 || (fNrows && fNcolumns && (row>fNrows || col>fNcolumns)))
+ {
+ cout << " *AliCalorimeter::SetSignal* row,col : " << row << "," << col
+ << " out of range." << endl;
+ if (fNrows && fNcolumns) cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
+ return;
+ }
- if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
+ if (!fMatrix)
{
- AliCalmodule* m=fMatrix[row-1][col-1];
- if (!m) // only count new modules
+ fMatrix=new AliObjMatrix();
+ fMatrix->SetOwner();
+ fMatrix->SetSwapMode(fSwap);
+ }
+
+ AliCalmodule* m=GetModule(row,col);
+ if (!m) // initialise for a new module
+ {
+ m=new AliCalmodule();
+ AliPosition* r=0;
+ if (fPositions) r=(AliPositionObj*)fPositions->GetObject(row,col);
+ if (r) m->SetPosition(*r);
+ if (fAttributes)
{
- if (!fModules)
+ AliAttribObj* a=0;
+ if (row <= fAttributes->GetSize()) a=(AliAttribObj*)fAttributes->At(row-1);
+ if (a)
{
- fModules=new TObjArray(); // Default size, expanded automatically
- fModules->SetOwner();
+ if (a->GetGainFlag(col)) m->SetGain(a->GetGain(col));
+ if (a->GetOffsetFlag(col)) m->SetOffset(a->GetOffset(col));
+ if (a->GetDeadValue(col)) m->SetDead();
+ if (a->GetEdgeValue(col)) m->SetEdgeValue(a->GetEdgeValue(col));
}
- fNsignals++;
- m=new AliCalmodule();
- AliPosition* r=fPositions[row-1][col-1];
- if (r) m->SetPosition(*r);
- m->SetGain(GetGain(row,col));
- if (GetDeadValue(row,col)) m->SetDead();
- fModules->Add(m);
- fMatrix[row-1][col-1]=m;
}
- m->SetSignal(row,col,sig);
- }
- else
- {
- cout << " *AliCalorimeter::SetSignal* row,col : " << row << "," << col
- << " out of range." << endl;
- cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
+ fMatrix->EnterObject(row,col,m);
}
+
+ m->SetSignal(row,col,sig);
}
///////////////////////////////////////////////////////////////////////////
void AliCalorimeter::AddSignal(Int_t row, Int_t col, Float_t sig)
{
-// Add the signal to a certain calorimeter module
-
- if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
-
- if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
+// Add the signal to a certain calorimeter module.
+
+ // Check for (row,col) boundaries.
+ if (row<1 || col<1 || (fNrows && fNcolumns && (row>fNrows || col>fNcolumns)))
{
- AliCalmodule* m=fMatrix[row-1][col-1];
- if (!m) // only count new modules
+ cout << " *AliCalorimeter::AddSignal* row,col : " << row << "," << col
+ << " out of range." << endl;
+ if (fNrows && fNcolumns) cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
+ return;
+ }
+
+ AliCalmodule* m=GetModule(row,col);
+ if (!m) // initialise for new modules
{
SetSignal(row,col,sig);
}
{
m->AddSignal(row,col,sig);
}
- }
- else
- {
- cout << " *AliCalorimeter::AddSignal* row,col : " << row << "," << col
- << " out of range." << endl;
- cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
- }
}
///////////////////////////////////////////////////////////////////////////
void AliCalorimeter::AddSignal(AliCalmodule* mod)
{
// Add the signal of module mod to the current calorimeter data.
// This enables mixing of calorimeter data of various events.
-
- if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
+//
+// Note : The position and attributes according to the user provided data
+// for the corresponding (row,col) location will be used.
+// In case there is no user provided data present, the position and
+// attributes of the first module added to the corresponding (row,col)
+// location will be taken, except for the "edge" and "dead" indicators.
+// The latter will then both be set to 0.
+
+ if (!mod) return;
Int_t row=mod->GetRow();
Int_t col=mod->GetColumn();
Float_t sig=mod->GetSignal();
- AliPosition r=mod->GetPosition();
- if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
+ // Check for (row,col) boundaries.
+ if (row<1 || col<1 || (fNrows && fNcolumns && (row>fNrows || col>fNcolumns)))
+ {
+ cout << " *AliCalorimeter::AddSignal* row,col : " << row << "," << col
+ << " out of range." << endl;
+ if (fNrows && fNcolumns) cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
+ return;
+ }
+
+ if (!fMatrix)
{
- AliCalmodule* m=fMatrix[row-1][col-1];
- if (!m) // No module existed yet at this position
+ fMatrix=new AliObjMatrix();
+ fMatrix->SetOwner();
+ fMatrix->SetSwapMode(fSwap);
+ }
+
+ AliCalmodule* m=GetModule(row,col);
+ if (!m) // No module existed yet at this position
+ {
+ m=new AliCalmodule(*mod);
+ AliPosition* r=0;
+ if (fPositions) r=(AliPositionObj*)fPositions->GetObject(row,col);
+ if (r) m->SetPosition(*r);
+ // Don't take the dead and edge attributes from this module,
+ // but from the calorimeter dbase, if present.
+ m->SetEdgeOff();
+ m->SetAlive();
+ if (fAttributes)
{
- if (!fModules)
+ AliAttribObj* a=0;
+ if (row <= fAttributes->GetSize()) a=(AliAttribObj*)fAttributes->At(row-1);
+ if (a)
{
- fModules=new TObjArray(); // Default size, expanded automatically
- fModules->SetOwner();
+ if (a->GetGainFlag(col)) m->SetGain(a->GetGain(col));
+ if (a->GetOffsetFlag(col)) m->SetOffset(a->GetOffset(col));
+ if (a->GetDeadValue(col)) m->SetDead();
+ if (a->GetEdgeValue(col)) m->SetEdgeValue(a->GetEdgeValue(col));
}
- fNsignals++;
- m=new AliCalmodule;
- fModules->Add(m);
- fMatrix[row-1][col-1]=m;
- m->SetPosition(r);
}
- m->AddSignal(row,col,sig);
- if (!fPositions[row-1][col-1]) fPositions[row-1][col-1]=new AliPosition(r);
+ fMatrix->EnterObject(row,col,m);
}
else
{
- cout << " *AliCalorimeter::AddSignal* row,col : " << row << "," << col
- << " out of range." << endl;
- cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
+ m->AddSignal(row,col,sig);
}
}
///////////////////////////////////////////////////////////////////////////
void AliCalorimeter::Reset(Int_t row,Int_t col)
{
-// Reset the signal for a certain calorimeter module
-
- if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
-
- if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
- {
- AliCalmodule* m=fMatrix[row-1][col-1];
- if (m)
- {
- fModules->Remove(m);
- fNsignals--;
- fModules->Compress();
- delete m;
- fMatrix[row-1][col-1]=0;
- }
- }
- else
+// Reset the signal for a certain calorimeter module.
+// Note : Module position and attributes remain unchanged.
+
+ // Check for (row,col) boundaries.
+ if (row<1 || col<1 || (fNrows && fNcolumns && (row>fNrows || col>fNcolumns)))
{
cout << " *AliCalorimeter::Reset* row,col : " << row << "," << col
<< " out of range." << endl;
- cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
+ if (fNrows && fNcolumns) cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
+ return;
}
+
+ AliCalmodule* m=GetModule(row,col);
+ if (m) fMatrix->RemoveObject(row,col);
}
///////////////////////////////////////////////////////////////////////////
void AliCalorimeter::Reset(Int_t mode)
// Reset the signals for the complete calorimeter.
// Normally this is done to prepare for the data of the next event.
//
-// mode = 0 : Module positions, gains, edge and dead flags remain unchanged.
-// 1 : Module positions, gains, edge and dead flags are cleared.
+// mode = 0 : Swap mode, module positions and attributes remain unchanged.
+// 1 : Swap mode, module positions and attributes are cleared.
//
// The default is mode=0.
//
return;
}
- fNsignals=0;
- if (fModules)
- {
- delete fModules;
- fModules=0;
- }
-
- fNclusters=0;
if (fClusters)
{
delete fClusters;
fClusters=0;
}
- fNvetos=0;
if (fVetos)
{
delete fVetos;
fVetos=0;
}
- if (fMatrix || fPositions)
- {
- for (Int_t i=0; i<fNrows; i++)
- {
- for (Int_t j=0; j<fNcolumns; j++)
- {
- if (mode==0)
- {
- fMatrix[i][j]=0;
- }
- else
- {
- if (fPositions[i][j]) delete fPositions[i][j];
- }
- }
- if (mode==1)
- {
- if (fPositions[i]) delete [] fPositions[i];
- if (fMatrix[i]) delete [] fMatrix[i];
- }
- }
- }
-
- // Free memory allocated for various arrays and matrices.
if (mode==1)
{
if (fMatrix)
{
- delete [] fMatrix;
+ delete fMatrix;
fMatrix=0;
}
if (fPositions)
{
- delete [] fPositions;
+ delete fPositions;
fPositions=0;
}
- if (fGains)
- {
- delete fGains;
- fGains=0;
- }
+ }
+ else
+ {
+ if (fMatrix) fMatrix->Reset();
+ }
+
+ // Free memory allocated for the various arrays.
+ if (mode==1)
+ {
if (fAttributes)
{
delete fAttributes;
}
}
///////////////////////////////////////////////////////////////////////////
-Float_t AliCalorimeter::GetSignal(Int_t row,Int_t col)
+Float_t AliCalorimeter::GetSignal(Int_t row,Int_t col,Int_t mode)
{
// Provide the signal of a certain calorimeter module.
// In case the module was marked dead, 0 is returned.
-
- if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
-
- if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
- {
- Float_t signal=0;
- AliCalmodule* m=fMatrix[row-1][col-1];
- if (m)
- {
- Int_t dead=m->GetDeadValue();
- if (!dead) signal=m->GetSignal();
- }
- return signal;
- }
- else
+//
+// mode = 0 : Just the module signal is returned
+// 1 : The module signal is corrected for the gain and offset.
+// 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.
+//
+// The corrected signal (sigc) is determined as follows :
+//
+// sigc=(signal/gain)-offset
+//
+// The default is mode=0.
+
+ // Check for (row,col) boundaries.
+ if (row<1 || col<1 || (fNrows && fNcolumns && (row>fNrows || col>fNcolumns)))
{
cout << " *AliCalorimeter::GetSignal* row,col : " << row << "," << col
<< " out of range." << endl;
- cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
+ if (fNrows && fNcolumns) cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
return 0;
}
+
+ Float_t signal=0;
+ Float_t gain=1;
+ Float_t offset=0;
+ AliCalmodule* m=GetModule(row,col);
+ if (m)
+ {
+ Int_t dead=m->GetDeadValue();
+ if (!dead) signal=m->GetSignal();
+
+ if (mode==0 || dead) return signal;
+
+ // Correct the signal for the gain and offset
+ if (GetGainFlag(row,col))
+ {
+ gain=GetGain(row,col);
+ }
+ else
+ {
+ if (m->GetGainFlag()) gain=m->GetGain();
+ }
+
+ if (GetOffsetFlag(row,col))
+ {
+ offset=GetOffset(row,col);
+ }
+ else
+ {
+ if (m->GetOffsetFlag()) offset=m->GetOffset();
+ }
+
+ if (fabs(gain)>0.)
+ {
+ signal=(signal/gain)-offset;
+ }
+ else
+ {
+ signal=0;
+ }
+ }
+ return signal;
}
///////////////////////////////////////////////////////////////////////////
void AliCalorimeter::SetEdgeOn(Int_t row,Int_t col)
{
-// Indicate a certain calorimeter module as 'edge module'
-
- if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
-
- if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
+// Indicate a certain calorimeter module as 'edge module'.
+
+ // Check for (row,col) boundaries.
+ if (row<1 || col<1 || (fNrows && fNcolumns && (row>fNrows || col>fNcolumns)))
+ {
+ cout << " *AliCalorimeter::SetEdgeOn* row,col : " << row << "," << col
+ << " out of range." << endl;
+ if (fNrows && fNcolumns) cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
+ return;
+ }
+
+ if (!fAttributes)
{
- Float_t word=(*fAttributes)(row-1,col-1);
- Int_t iword=int(word+0.1);
- Int_t dead=iword%10;
- Int_t edge=1;
- (*fAttributes)(row-1,col-1)=float(dead+10*edge);
+ fAttributes=new TObjArray(row);
+ fAttributes->SetOwner();
}
else
{
- cout << " *AliCalorimeter::SetEdgeOn* row,col : " << row << "," << col
- << " out of range." << endl;
- cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
+ if (row > fAttributes->GetSize()) fAttributes->Expand(row);
}
+
+ AliAttribObj* a=(AliAttribObj*)fAttributes->At(row-1);
+ if (a)
+ {
+ a->SetEdgeOn(col);
+ }
+ else
+ {
+ a=new AliAttribObj();
+ a->SetEdgeOn(col);
+ fAttributes->AddAt(a,col-1);
+ }
+
+ AliCalmodule* m=GetModule(row,col);
+ if (m) m->SetEdgeOn();
}
///////////////////////////////////////////////////////////////////////////
void AliCalorimeter::SetEdgeOff(Int_t row,Int_t col)
{
-// Indicate a certain calorimeter module as 'non-edge module'
-
- if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
-
- if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
- {
- Float_t word=(*fAttributes)(row-1,col-1);
- Int_t iword=int(word+0.1);
- Int_t dead=iword%10;
- Int_t edge=0;
- (*fAttributes)(row-1,col-1)=float(dead+10*edge);
- }
- else
+// Indicate a certain calorimeter module as 'non-edge module'.
+
+ // Check for (row,col) boundaries.
+ if (row<1 || col<1 || (fNrows && fNcolumns && (row>fNrows || col>fNcolumns)))
{
cout << " *AliCalorimeter::SetEdgeOff* row,col : " << row << "," << col
<< " out of range." << endl;
- cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
+ if (fNrows && fNcolumns) cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
+ return;
}
+
+ // Only action on fAttributes in case an attribute is present at (row,col),
+ // since by default a module has edge=0 unless explicitly set otherwise.
+ if (fAttributes)
+ {
+ if (row <= fAttributes->GetSize())
+ {
+ AliAttribObj* a=(AliAttribObj*)fAttributes->At(row-1);
+ if (a) a->SetEdgeOff(col);
+ }
+ }
+
+ AliCalmodule* m=GetModule(row,col);
+ if (m) m->SetEdgeOff();
}
///////////////////////////////////////////////////////////////////////////
void AliCalorimeter::SetDead(Int_t row,Int_t col)
{
// Indicate a certain calorimeter module as 'dead module'
+
+ // Check for (row,col) boundaries in case of a fixed size calorimeter
+ if (row<1 || col<1 || (fNrows && fNcolumns && (row>fNrows || col>fNcolumns)))
+ {
+ cout << " *AliCalorimeter::SetDead* row,col : " << row << "," << col
+ << " out of range." << endl;
+ if (fNrows && fNcolumns) cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
+ return;
+ }
+
+ // Make Attributes storage 1 row (and also 1 column) larger than needed
+ // because the 'edge value' of the (future) surrounding modules has
+ // to be updated as well.
+ if (!fAttributes)
+ {
+ fAttributes=new TObjArray(row+1);
+ fAttributes->SetOwner();
+ }
+ else
+ {
+ if (row >= fAttributes->GetSize()) fAttributes->Expand(row+1);
+ }
+
+ AliAttribObj* a=(AliAttribObj*)fAttributes->At(row-1);
+ if (a)
+ {
+ a->SetDead(col);
+ }
+ else
+ {
+ a=new AliAttribObj();
+ a->SetDead(col);
+ fAttributes->AddAt(a,row-1);
+ }
+
+ AliCalmodule* m=GetModule(row,col);
+ if (m) m->SetDead();
- if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
-
- if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
- {
- Float_t word=(*fAttributes)(row-1,col-1);
- Int_t iword=int(word+0.1);
- Int_t edge=iword/10;
- Int_t dead=1;
- (*fAttributes)(row-1,col-1)=float(dead+10*edge);
- if (fMatrix[row-1][col-1]) (fMatrix[row-1][col-1])->SetDead();
-
- // Increase the 'edge value' of surrounding modules
- Int_t rlow=row-1;
- Int_t rup=row+1;
- Int_t clow=col-1;
- Int_t cup=col+1;
+ // Increase the 'edge value' of surrounding modules
+ Int_t rlow=row-1;
+ Int_t rup=row+1;
+ Int_t clow=col-1;
+ Int_t cup=col+1;
- if (rlow < 1) rlow=row;
- if (rup > fNrows) rup=fNrows;
- if (clow < 1) clow=col;
- if (cup > fNcolumns) cup=fNcolumns;
+ if (rlow < 1) rlow=row;
+ if (clow < 1) clow=col;
- for (Int_t i=rlow; i<=rup; i++)
+ for (Int_t i=rlow; i<=rup; i++)
+ {
+ for (Int_t j=clow; j<=cup; j++)
{
- for (Int_t j=clow; j<=cup; j++)
+ if (i!=row || j!=col) // No increase of edge value for the 'dead' module itself
{
- if (i!=row || j!=col) // No increase of edge value for the dead module itself
+ AliAttribObj* a=(AliAttribObj*)fAttributes->At(i-1);
+ if (a)
{
- word=(*fAttributes)(i-1,j-1);
- iword=int(word+0.1);
- edge=iword/10;
- dead=iword%10;
- edge++;
- (*fAttributes)(i-1,j-1)=float(dead+10*edge);
+ a->IncreaseEdgeValue(j);
}
+ else
+ {
+ a=new AliAttribObj();
+ a->SetEdgeOn(j);
+ fAttributes->AddAt(a,i-1);
+ }
+
+ AliCalmodule* m=GetModule(i,j);
+ if (m) m->IncreaseEdgeValue();
}
}
}
- else
- {
- cout << " *AliCalorimeter::SetDead* row,col : " << row << "," << col
- << " out of range." << endl;
- cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
- }
}
///////////////////////////////////////////////////////////////////////////
void AliCalorimeter::SetAlive(Int_t row,Int_t col)
{
-// Indicate a certain calorimeter module as 'active module'
-
- if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
-
- if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
- {
- Float_t word=(*fAttributes)(row-1,col-1);
- Int_t iword=int(word+0.1);
- Int_t edge=iword/10;
- Int_t dead=0;
- (*fAttributes)(row-1,col-1)=float(dead+10*edge);
- if (fMatrix[row-1][col-1]) (fMatrix[row-1][col-1])->SetAlive();
-
- // Decrease the 'edge value' of surrounding modules
- Int_t rlow=row-1;
- Int_t rup=row+1;
- Int_t clow=col-1;
- Int_t cup=col+1;
+// Indicate a certain calorimeter module as 'active module'.
+
+ // Check for (row,col) boundaries.
+ if (row<1 || col<1 || (fNrows && fNcolumns && (row>fNrows || col>fNcolumns)))
+ {
+ cout << " *AliCalorimeter::SetAlive* row,col : " << row << "," << col
+ << " out of range." << endl;
+ if (fNrows && fNcolumns) cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
+ return;
+ }
+
+ // Only action on fAttributes in case an attribute is present at (row,col),
+ // since by default a module has dead=0 unless explicitly set otherwise.
+ if (fAttributes)
+ {
+ if (row <= fAttributes->GetSize())
+ {
+ AliAttribObj* a=(AliAttribObj*)fAttributes->At(row-1);
+ if (a) a->SetAlive(col);
+ }
+ }
+
+ AliCalmodule* m=GetModule(row,col);
+ if (m) m->SetAlive();
- if (rlow < 1) rlow=row;
- if (rup > fNrows) rup=fNrows;
- if (clow < 1) clow=col;
- if (cup > fNcolumns) cup=fNcolumns;
+ // Decrease the 'edge value' of surrounding modules
+ Int_t rlow=row-1;
+ Int_t rup=row+1;
+ Int_t clow=col-1;
+ Int_t cup=col+1;
- for (Int_t i=rlow; i<=rup; i++)
+ if (rlow < 1) rlow=row;
+ if (clow < 1) clow=col;
+
+ for (Int_t i=rlow; i<=rup; i++)
+ {
+ for (Int_t j=clow; j<=cup; j++)
{
- for (Int_t j=clow; j<=cup; j++)
+ if (i!=row || j!=col) // No decrease of edge value for the 'alive' module itself
{
- if (i!=row || j!=col) // No decrease of edge value for the dead module itself
+ if (i <= fAttributes->GetSize())
{
- word=(*fAttributes)(i-1,j-1);
- iword=int(word+0.1);
- edge=iword/10;
- dead=iword%10;
- if (edge>0) edge--;
- (*fAttributes)(i-1,j-1)=float(dead+10*edge);
+ AliAttribObj* a=(AliAttribObj*)fAttributes->At(i-1);
+ if (a) a->DecreaseEdgeValue(j);
}
+ AliCalmodule* m=GetModule(i,j);
+ if (m) m->DecreaseEdgeValue();
}
}
}
+}
+///////////////////////////////////////////////////////////////////////////
+void AliCalorimeter::SetGain(Int_t row,Int_t col,Float_t gain)
+{
+// Set the gain value for a certain calorimeter module.
+// See the memberfunction GetSignal() for a definition of the gain value.
+
+ // Check for (row,col) boundaries.
+ if (row<1 || col<1 || (fNrows && fNcolumns && (row>fNrows || col>fNcolumns)))
+ {
+ cout << " *AliCalorimeter::SetGain* row,col : " << row << "," << col
+ << " out of range." << endl;
+ if (fNrows && fNcolumns) cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
+ return;
+ }
+
+ if (!fAttributes)
+ {
+ fAttributes=new TObjArray(row);
+ fAttributes->SetOwner();
+ }
else
{
- cout << " *AliCalorimeter::SetAlive* row,col : " << row << "," << col
+ if (row > fAttributes->GetSize()) fAttributes->Expand(row);
+ }
+
+ AliAttribObj* a=(AliAttribObj*)fAttributes->At(row-1);
+ if (a)
+ {
+ a->SetGain(gain,col);
+ }
+ else
+ {
+ a=new AliAttribObj();
+ a->SetGain(gain,col);
+ fAttributes->AddAt(a,col-1);
+ }
+
+ AliCalmodule* m=GetModule(row,col);
+ if (m) m->SetGain(gain);
+}
+///////////////////////////////////////////////////////////////////////////
+void AliCalorimeter::SetOffset(Int_t row,Int_t col,Float_t offset)
+{
+// Set the offset value for a certain calorimeter module.
+// See the memberfunction GetSignal() for a definition of the offset value.
+
+ // Check for (row,col) boundaries.
+ if (row<1 || col<1 || (fNrows && fNcolumns && (row>fNrows || col>fNcolumns)))
+ {
+ cout << " *AliCalorimeter::SetOffset* row,col : " << row << "," << col
<< " out of range." << endl;
- cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
+ if (fNrows && fNcolumns) cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
+ return;
}
+
+ if (!fAttributes)
+ {
+ fAttributes=new TObjArray(row);
+ fAttributes->SetOwner();
+ }
+ else
+ {
+ if (row > fAttributes->GetSize()) fAttributes->Expand(row);
+ }
+
+ AliAttribObj* a=(AliAttribObj*)fAttributes->At(row-1);
+ if (a)
+ {
+ a->SetOffset(offset,col);
+ }
+ else
+ {
+ a=new AliAttribObj();
+ a->SetOffset(offset,col);
+ fAttributes->AddAt(a,col-1);
+ }
+
+ AliCalmodule* m=GetModule(row,col);
+ if (m) m->SetOffset(offset);
}
///////////////////////////////////////////////////////////////////////////
-void AliCalorimeter::SetGain(Int_t row,Int_t col,Float_t gain)
+void AliCalorimeter::SetPosition(Int_t row,Int_t col,Float_t* vec,TString f)
{
-// Set the gain value for a certain calorimeter module
-
- if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
-
- if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
+// Set the position in user coordinates for a certain calorimeter module
+ Ali3Vector r;
+ r.SetVector(vec,f);
+ SetPosition(row,col,r);
+}
+///////////////////////////////////////////////////////////////////////////
+void AliCalorimeter::SetPosition(Int_t row,Int_t col,Ali3Vector& r)
+{
+// Set the position for a certain calorimeter module
+
+ // Check for (row,col) boundaries.
+ if (row<1 || col<1 || (fNrows && fNcolumns && (row>fNrows || col>fNcolumns)))
+ {
+ cout << " *AliCalorimeter::SetPosition* row,col : " << row << "," << col
+ << " out of range." << endl;
+ if (fNrows && fNcolumns) cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
+ return;
+ }
+
+ if (!fPositions)
+ {
+ fPositions=new AliObjMatrix();
+ fPositions->SetOwner();
+ fPositions->SetSwapMode(fSwap);
+ }
+
+ AliPositionObj* p=(AliPositionObj*)fPositions->GetObject(row,col);
+
+ if (p)
{
- (*fGains)(row-1,col-1)=gain;
- if (fMatrix[row-1][col-1]) (fMatrix[row-1][col-1])->SetGain(gain);
+ p->Load(r);
}
else
{
- cout << " *AliCalorimeter::SetGain* row,col : " << row << "," << col
+ p=new AliPositionObj();
+ p->Load(r);
+ fPositions->EnterObject(row,col,p);
+ }
+
+ // Update the position of the calorimeter module itself as well if it exists
+ AliCalmodule* m=GetModule(row,col);
+ if (m) m->SetPosition(r);
+}
+///////////////////////////////////////////////////////////////////////////
+Int_t AliCalorimeter::GetEdgeValue(Int_t row,Int_t col)
+{
+// Provide the value of the edge flag of a certain module.
+
+ // Check for (row,col) boundaries.
+ if (row<1 || col<1 || (fNrows && fNcolumns && (row>fNrows || col>fNcolumns)))
+ {
+ cout << " *AliCalorimeter::GetEdgeValue* row,col : " << row << "," << col
+ << " out of range." << endl;
+ if (fNrows && fNcolumns) cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
+ return 0;
+ }
+
+ Int_t edge=0;
+
+ if (fAttributes)
+ {
+ if (row <= fAttributes->GetSize())
+ {
+ AliAttribObj* a=(AliAttribObj*)fAttributes->At(row-1);
+ if (a)
+ {
+ if (col <= a->GetNcalflags())
+ {
+ edge=a->GetEdgeValue(col);
+ return edge;
+ }
+ }
+ }
+ }
+
+ AliCalmodule* m=GetModule(row,col);
+ if (m) edge=m->GetEdgeValue();
+ return edge;
+}
+///////////////////////////////////////////////////////////////////////////
+Int_t AliCalorimeter::GetDeadValue(Int_t row,Int_t col)
+{
+// Provide the value of the dead flag of a certain module
+
+ // Check for (row,col) boundaries.
+ if (row<1 || col<1 || (fNrows && fNcolumns && (row>fNrows || col>fNcolumns)))
+ {
+ cout << " *AliCalorimeter::GetDeadValue* row,col : " << row << "," << col
<< " out of range." << endl;
- cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
+ if (fNrows && fNcolumns) cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
+ return 0;
}
+
+ Int_t dead=0;
+
+ if (fAttributes)
+ {
+ if (row <= fAttributes->GetSize())
+ {
+ AliAttribObj* a=(AliAttribObj*)fAttributes->At(row-1);
+ if (a)
+ {
+ if (col <= a->GetNcalflags())
+ {
+ dead=a->GetDeadValue(col);
+ return dead;
+ }
+ }
+ }
+ }
+
+ AliCalmodule* m=GetModule(row,col);
+ if (m) dead=m->GetDeadValue();
+ return dead;
}
///////////////////////////////////////////////////////////////////////////
-void AliCalorimeter::SetPosition(Int_t row,Int_t col,Float_t* vec,TString f)
+Int_t AliCalorimeter::GetGainFlag(Int_t row,Int_t col)
{
-// Set the position in user coordinates for a certain calorimeter module
-
- if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
-
- if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
+// Provide the value of the gain flag of a certain module.
+
+ // Check for (row,col) boundaries.
+ if (row<1 || col<1 || (fNrows && fNcolumns && (row>fNrows || col>fNcolumns)))
{
- if (!fPositions[row-1][col-1]) fPositions[row-1][col-1]=new AliPosition;
- (fPositions[row-1][col-1])->SetVector(vec,f);
- if (fMatrix[row-1][col-1]) (fMatrix[row-1][col-1])->SetPosition(vec,f);
+ cout << " *AliCalorimeter::GetGainFlag* row,col : " << row << "," << col
+ << " out of range." << endl;
+ if (fNrows && fNcolumns) cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
+ return 0;
}
- else
+
+ Int_t gf=0;
+
+ if (fAttributes)
{
- cout << " *AliCalorimeter::SetPosition* row,col : " << row << "," << col
- << " out of range." << endl;
- cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
+ if (row <= fAttributes->GetSize())
+ {
+ AliAttribObj* a=(AliAttribObj*)fAttributes->At(row-1);
+ if (a)
+ {
+ if (col <= a->GetNcalflags())
+ {
+ gf=a->GetGainFlag(col);
+ return gf;
+ }
+ }
+ }
}
+
+ AliCalmodule* m=GetModule(row,col);
+ if (m) gf=m->GetGainFlag();
+ return gf;
}
///////////////////////////////////////////////////////////////////////////
-void AliCalorimeter::SetPosition(Int_t row,Int_t col,Ali3Vector& r)
+Int_t AliCalorimeter::GetOffsetFlag(Int_t row,Int_t col)
{
-// Set the position for a certain calorimeter module
-
- if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
-
- if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
+// Provide the value of the offset flag of a certain module.
+
+ // Check for (row,col) boundaries.
+ if (row<1 || col<1 || (fNrows && fNcolumns && (row>fNrows || col>fNcolumns)))
{
- if (!fPositions[row-1][col-1]) fPositions[row-1][col-1]=new AliPosition;
- (fPositions[row-1][col-1])->SetPosition(r);
- if (fMatrix[row-1][col-1]) (fMatrix[row-1][col-1])->SetPosition(r);
+ cout << " *AliCalorimeter::GetOffsetFlag* row,col : " << row << "," << col
+ << " out of range." << endl;
+ if (fNrows && fNcolumns) cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
+ return 0;
}
- else
+
+ Int_t of=0;
+
+ if (fAttributes)
{
- cout << " *AliCalorimeter::SetPosition* row,col : " << row << "," << col
- << " out of range." << endl;
- cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
+ if (row <= fAttributes->GetSize())
+ {
+ AliAttribObj* a=(AliAttribObj*)fAttributes->At(row-1);
+ if (a)
+ {
+ if (col <= a->GetNcalflags())
+ {
+ of=a->GetOffsetFlag(col);
+ return of;
+ }
+ }
+ }
}
+
+ AliCalmodule* m=GetModule(row,col);
+ if (m) of=m->GetOffsetFlag();
+ return of;
}
///////////////////////////////////////////////////////////////////////////
-Int_t AliCalorimeter::GetEdgeValue(Int_t row,Int_t col)
+Float_t AliCalorimeter::GetGain(Int_t row,Int_t col)
{
-// Provide the value of the edge flag of a certain module
-
- if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
- {
- Float_t word=(*fAttributes)(row-1,col-1);
- Int_t iword=int(word+0.1);
- Int_t edge=iword/10;
- return edge;
- }
- else
+// Provide the gain value of a certain module.
+// See the memberfunction GetSignal() for a definition of the gain value.
+//
+// In case the gain value is unknown, the value 0 will be returned.
+
+ // Check for (row,col) boundaries.
+ if (row<1 || col<1 || (fNrows && fNcolumns && (row>fNrows || col>fNcolumns)))
{
- cout << " *AliCalorimeter::GetEdgeValue* row,col : " << row << "," << col
+ cout << " *AliCalorimeter::GetGain* row,col : " << row << "," << col
<< " out of range." << endl;
- cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
+ if (fNrows && fNcolumns) cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
return 0;
}
-}
-///////////////////////////////////////////////////////////////////////////
-Int_t AliCalorimeter::GetDeadValue(Int_t row,Int_t col)
-{
-// Provide the value of the dead flag of a certain module
-
- if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
+
+ Float_t gain=0;
+
+ if (fAttributes)
{
- Float_t word=(*fAttributes)(row-1,col-1);
- Int_t iword=int(word+0.1);
- Int_t dead=iword%10;
- return dead;
+ if (row <= fAttributes->GetSize())
+ {
+ AliAttribObj* a=(AliAttribObj*)fAttributes->At(row-1);
+ if (a)
+ {
+ if (col <= a->GetNcalflags())
+ {
+ if (a->GetGainFlag(col))
+ {
+ gain=a->GetGain(col);
+ return gain;
+ }
+ }
+ }
+ }
}
- else
+
+ AliCalmodule* m=GetModule(row,col);
+ if (m)
{
- cout << " *AliCalorimeter::GetDeadValue* row,col : " << row << "," << col
- << " out of range." << endl;
- cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
- return 0;
+ if (m->GetGainFlag())
+ {
+ gain=m->GetGain();
+ }
}
+ return gain;
}
///////////////////////////////////////////////////////////////////////////
-Float_t AliCalorimeter::GetGain(Int_t row,Int_t col)
+Float_t AliCalorimeter::GetOffset(Int_t row,Int_t col)
{
-// Provide the gain value of a certain module
-
- if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
- {
- return (*fGains)(row-1,col-1);
- }
- else
+// Provide the offset value of a certain module.
+// See the memberfunction GetSignal() for a definition of the offset value.
+//
+// In case the offset value is unknown, the value 0 will be returned.
+
+ // Check for (row,col) boundaries.
+ if (row<1 || col<1 || (fNrows && fNcolumns && (row>fNrows || col>fNcolumns)))
{
- cout << " *AliCalorimeter::GetGain* row,col : " << row << "," << col
+ cout << " *AliCalorimeter::GetOffset* row,col : " << row << "," << col
<< " out of range." << endl;
- cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
+ if (fNrows && fNcolumns) cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
return 0;
}
+
+ Float_t offset=0;
+
+ if (fAttributes)
+ {
+ if (row <= fAttributes->GetSize())
+ {
+ AliAttribObj* a=(AliAttribObj*)fAttributes->At(row-1);
+ if (a)
+ {
+ if (col <= a->GetNcalflags())
+ {
+ if (a->GetOffsetFlag(col))
+ {
+ offset=a->GetOffset(col);
+ return offset;
+ }
+ }
+ }
+ }
+ }
+
+ AliCalmodule* m=GetModule(row,col);
+ if (m)
+ {
+ if (m->GetOffsetFlag())
+ {
+ offset=m->GetOffset();
+ }
+ }
+ return offset;
}
///////////////////////////////////////////////////////////////////////////
void AliCalorimeter::GetPosition(Int_t row,Int_t col,Float_t* vec,TString f)
{
// Return the position in user coordinates for a certain calorimeter module
-
- if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
-
- if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
- {
-// if (fMatrix[row-1][col-1]) (fMatrix[row-1][col-1])->GetPosition(vec,f);
- if (fPositions[row-1][col-1]) (fPositions[row-1][col-1])->GetVector(vec,f);
- }
- else
- {
- cout << " *AliCalorimeter::GetPosition* row,col : " << row << "," << col
- << " out of range." << endl;
- cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
- }
+ vec[0]=0;
+ vec[1]=0;
+ vec[2]=0;
+
+ AliPosition* p=GetPosition(row,col);
+ if (p) p->GetVector(vec,f);
}
///////////////////////////////////////////////////////////////////////////
AliPosition* AliCalorimeter::GetPosition(Int_t row,Int_t col)
{
-// Access to the position of a certain calorimeter module
-
- if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
-
- if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
- {
- return fPositions[row-1][col-1];
- }
- else
+// Access to the position of a certain calorimeter module.
+
+ // Check for (row,col) boundaries.
+ if (row<1 || col<1 || (fNrows && fNcolumns && (row>fNrows || col>fNcolumns)))
{
cout << " *AliCalorimeter::GetPosition* row,col : " << row << "," << col
<< " out of range." << endl;
- cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
+ if (fNrows && fNcolumns) cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
return 0;
}
+
+ if (!fPositions && !fMatrix) return 0;
+
+ AliPositionObj* po=0;
+ if (fPositions) po=(AliPositionObj*)fPositions->GetObject(row,col);
+ if (po) return po;
+
+ AliCalmodule* m=GetModule(row,col);
+ return m;
}
///////////////////////////////////////////////////////////////////////////
Float_t AliCalorimeter::GetClusteredSignal(Int_t row,Int_t col)
{
-// Provide the module signal after clustering
-
- if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
-
- if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
- {
- if (fMatrix[row-1][col-1])
- {
- return (fMatrix[row-1][col-1])->GetClusteredSignal();
- }
- else
- {
- return 0;
- }
- }
- else
+// Provide the module signal after clustering.
+
+ // Check for (row,col) boundaries.
+ if (row<1 || col<1 || (fNrows && fNcolumns && (row>fNrows || col>fNcolumns)))
{
cout << " *AliCalorimeter::GetClusteredSignal* row,col : " << row << "," << col
<< " out of range." << endl;
- cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
+ if (fNrows && fNcolumns) cout << " Nrows,Ncols = " << fNrows << "," << fNcolumns << endl;
return 0;
}
+
+ Float_t sig=0;
+
+ AliCalmodule* m=GetModule(row,col);
+ if (m) sig=m->GetClusteredSignal();
+
+ return sig;
}
///////////////////////////////////////////////////////////////////////////
Int_t AliCalorimeter::GetNsignals()
// Provide the number of modules that contain a signal
// Note : The number of modules marked 'dead' but which had a signal
// are included.
- return fNsignals;
+ Int_t nsig=0;
+ if (fMatrix) nsig=fMatrix->GetNobjects();
+ return nsig;
}
///////////////////////////////////////////////////////////////////////////
-void AliCalorimeter::Group(Int_t n)
+void AliCalorimeter::Group(Int_t n,Int_t mode)
{
-// Group the individual modules into clusters
-// Module signals of n rings around the central module will be grouped
-
- if (fNsignals > 0) // Directly return if no modules fired
+// Group the individual modules into clusters.
+// Module signals of n rings around the central module will be grouped.
+// The grouping process will start with the module containing the highest signal
+// in an iterative way.
+// For this all fired modules are ordered w.r.t. decreasing signal.
+// The search mode for the module signal hierarchy can be specified by the user.
+//
+// mode = 1 : Search performed via the (row,col) structure of the matrix (SortM)
+// 2 : Search performed via the linear array of fired modules (SortA)
+//
+// See the docs of the memberfunctions SortM and SortA for additional details.
+//
+// Default values : n=1 mode=1.
+
+ if (mode<1 || mode>2)
{
- if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
+ cout << " *AliCalorimeter::Group* Invalid mode : " << mode << endl;
+ cout << " Default value mode=1 will be used." << endl;
+ mode=1;
+ }
+
+ if (!fMatrix) return;
- if (fNclusters > 0) Ungroup(); // Restore unclustered situation if needed
+ Int_t nsignals=GetNsignals();
+ if (nsignals > 0) // Only continue if there are fired modules
+ {
+ if (GetNclusters() > 0) Ungroup(); // Restore unclustered situation if needed
// Order the modules with decreasing signal
- AliCalmodule** ordered=new AliCalmodule*[fNsignals]; // temp. array for ordered modules
+ AliCalmodule** ordered=new AliCalmodule*[nsignals]; // temp. array for ordered modules
Int_t nord=0;
- Sortm(ordered,nord);
+ if (mode==1) SortM(ordered,nord);
+ if (mode==2) SortA(ordered,nord);
// Clustering of modules. Start with the highest signal.
if (fClusters)
}
fClusters=new TObjArray();
fClusters->SetOwner();
- fNclusters=0;
Int_t row=0;
Int_t col=0;
AliCalcluster* c=0;
{
row=ordered[i]->GetRow(); // row number of cluster center
col=ordered[i]->GetColumn(); // column number of cluster center
- if (row>0 && row<=fNrows && col>0 && col<=fNcolumns)
- {
- m=fMatrix[row-1][col-1];
- if (!m) continue;
- // only use modules not yet used in a cluster
- if (m->GetClusteredSignal() > 0.)
+ m=(AliCalmodule*)fMatrix->GetObject(row,col);
+ if (!m) continue;
+
+ // only use modules not yet used in a cluster
+ if (m->GetClusteredSignal() > 0.)
+ {
+ Int_t edge=GetEdgeValue(row,col);
+ c=new AliCalcluster();
+ if (!edge) c->Start(*m); // module to start the cluster if not on edge
+ if (c->GetNmodules() > 0) // cluster started successfully (no edge)
{
- Int_t edge=GetEdgeValue(row,col);
- c=new AliCalcluster;
- if (!edge) c->Start(*m); // module to start the cluster if not on edge
- if (c->GetNmodules() > 0) // cluster started successfully (no edge)
- {
- fClusters->Add(c);
- fNclusters++; // update cluster counter
- AddRing(row,col,n); // add signals of n rings around the center
- }
- else
- {
- if (c) delete c;
- c=0;
- }
+ fClusters->Add(c);
+ AddRing(row,col,n); // add signals of n rings around the center
+ }
+ else
+ {
+ if (c) delete c;
+ c=0;
}
}
}
}
}
///////////////////////////////////////////////////////////////////////////
-void AliCalorimeter::Sortm(AliCalmodule** ordered,Int_t& nord)
+void AliCalorimeter::SortM(AliCalmodule** ordered,Int_t& nord)
{
-// Order the modules with decreasing signal
+// Order the modules with decreasing signal by looping over the (row,col) grid
+// of the matrix.
+// Modules which were declared as "Dead" will be rejected.
+// The gain etc... corrected module signals will be used in the ordering process.
+//
+// Note : This method may become slow for large, very finely granulated calorimeters.
+//
+// Very specific case :
+// ====================
+// In case of various overlapping showers of which the central modules have
+// EXACTLY the same signal this ordering procedure may have the following
+// advantages and disadvantages.
+//
+// Advantages :
+// ------------
+// * In case of multi-overlapping showers, the central shower will NOT
+// be "eaten-up" from both sides, resulting in a slightly more accurate
+// cluster signal.
+// * This method produces re-producable results, irrespective of the filling
+// order of the matrix modules.
+//
+// Disadvantages :
+// ---------------
+// * In case of a very high occupancy, there might be a slight effect on the
+// cluster signals depending on the geometrical location in the detector matrix.
+ Int_t nrows=fMatrix->GetMaxRow();
+ Int_t ncols=fMatrix->GetMaxColumn();
+
+ Float_t signal=0.;
nord=0;
- for (Int_t i=0; i<fNrows; i++) // loop over all modules of the matrix
+ for (Int_t irow=1; irow<=nrows; irow++) // loop over all modules of the matrix
{
- for (Int_t ii=0; ii<fNcolumns; ii++)
+ for (Int_t icol=1; icol<=ncols; icol++)
{
- if (GetSignal(i+1,ii+1) <= 0.) continue; // only take alive modules with a signal
+ signal=GetSignal(irow,icol,1); // get the gain etc... corrected signal
+ if (signal <= 0.) continue; // only take alive modules with a signal
if (nord == 0) // store the first module with a signal at the first ordered position
{
nord++;
- ordered[nord-1]=fMatrix[i][ii];
+ ordered[nord-1]=(AliCalmodule*)fMatrix->GetObject(irow,icol);
continue;
}
if (j == nord) // module has smallest signal seen so far
{
nord++;
- ordered[j]=fMatrix[i][ii]; // add module at the end
+ ordered[j]=(AliCalmodule*)fMatrix->GetObject(irow,icol); // add module at the end
break; // go for next matrix module
}
- if (GetSignal(i+1,ii+1) < ordered[j]->GetSignal()) continue;
+ if (signal < ordered[j]->GetSignal(1,1)) continue;
nord++;
for (Int_t k=nord-1; k>j; k--) // create empty position
{
ordered[k]=ordered[k-1];
}
- ordered[j]=fMatrix[i][ii]; // put module at empty position
+ ordered[j]=(AliCalmodule*)fMatrix->GetObject(irow,icol); // put module at empty position
+ break; // go for next matrix module
+ }
+ }
+ }
+}
+///////////////////////////////////////////////////////////////////////////
+void AliCalorimeter::SortA(AliCalmodule** ordered,Int_t& nord)
+{
+// Order the modules with decreasing signal by looping over the linear array
+// of fired modules.
+// Modules which were declared as "Dead" will be rejected.
+// The gain etc... corrected module signals will be used in the ordering process.
+//
+// Note : This method is rather fast even for large, very finely granulated calorimeters.
+//
+// Very specific case :
+// ====================
+// In case of various overlapping showers of which the central modules have
+// EXACTLY the same signal this ordering procedure may have the following
+// advantages and disadvantages.
+//
+// Advantages :
+// ------------
+// * Even in case of a very high occupancy, the resulting cluster signals
+// will in general NOT depend on the geometrical location in the detector matrix.
+//
+// Disadvantages :
+// ---------------
+// * In case of multi-overlapping showers, the central shower might be
+// "eaten-up" from both sides, resulting in a slightly too low value
+// of the resulting cluster signal.
+// * This method might produce results depending on the filling
+// order of the matrix modules.
+
+ Int_t nmods=0;
+ if (fMatrix) nmods=fMatrix->GetNobjects();
+
+ nord=0;
+ for (Int_t i=1; i<=nmods; i++) // loop over all fired modules of the matrix
+ {
+ AliCalmodule* m=(AliCalmodule*)fMatrix->GetObject(i);
+
+ if (!m) continue;
+ if (m->GetDeadValue()) continue; // only take alive modules with a signal
+
+ if (nord == 0) // store the first module with a signal at the first ordered position
+ {
+ nord++;
+ ordered[nord-1]=m;
+ continue;
+ }
+
+ for (Int_t j=0; j<=nord; j++) // put module in the right ordered position
+ {
+ if (j == nord) // module has smallest signal seen so far
+ {
+ nord++;
+ ordered[j]=m; // add module at the end
break; // go for next matrix module
}
+
+ if (m->GetSignal(1,1) < ordered[j]->GetSignal(1,1)) continue;
+
+ nord++;
+ for (Int_t k=nord-1; k>j; k--) // create empty position
+ {
+ ordered[k]=ordered[k-1];
+ }
+ ordered[j]=m; // put module at empty position
+ break; // go for next matrix module
}
}
}
///////////////////////////////////////////////////////////////////////////
void AliCalorimeter::AddRing(Int_t row, Int_t col, Int_t n)
{
-// Add module signals of 1 ring around (row,col) to current cluster
-// n denotes the maximum number of rings around cluster center
-// Note : This function is used recursively
+// Add module signals of 1 ring around (row,col) to current cluster.
+// The gain etc... corrected module signals will be used in this process.
+// The parameter n denotes the maximum number of rings around cluster center.
+// Note : This function is used recursively.
+
+ if (!fMatrix) return;
+
+ Int_t nrows=fMatrix->GetMaxRow();
+ Int_t ncols=fMatrix->GetMaxColumn();
if (n >= 1) // Check if any rings left for recursive calls
{
- Float_t signal=GetSignal(row,col); // signal of (row,col) module
+ Float_t signal=GetSignal(row,col,1); // Gain etc... corrected signal of (row,col) module
- Int_t lrow=row-1; if (lrow < 1) lrow=1; // row lowerbound for ring
- Int_t urow=row+1; if (urow > fNrows) urow=fNrows; // row upperbound for ring
- Int_t lcol=col-1; if (lcol < 1) lcol=1; // col lowerbound for ring
- Int_t ucol=col+1; if (ucol > fNcolumns) ucol=fNcolumns; // row upperbound for ring
+ Int_t lrow=row-1; if (lrow < 1) lrow=1; // row lowerbound for ring
+ Int_t urow=row+1; if (urow > nrows) urow=nrows; // row upperbound for ring
+ Int_t lcol=col-1; if (lcol < 1) lcol=1; // col lowerbound for ring
+ Int_t ucol=col+1; if (ucol > ncols) ucol=ncols; // row upperbound for ring
for (Int_t i=lrow; i<=urow; i++)
{
for (Int_t j=lcol; j<=ucol; j++)
{
// add module(i,j) to cluster if the signal <= signal(row,col)
- if (GetSignal(i,j) <= signal)
+ if (GetSignal(i,j,1) <= signal)
{
- AliCalmodule* m=fMatrix[i-1][j-1];
- if (m) ((AliCalcluster*)fClusters->At(fNclusters-1))->Add(*m);
+ AliCalmodule* m=(AliCalmodule*)fMatrix->GetObject(i,j);
+ if (m) ((AliCalcluster*)fClusters->At(GetNclusters()-1))->Add(*m);
}
AddRing(i,j,n-1); // Go for ring of modules around this (i,j) one
}
Int_t AliCalorimeter::GetNclusters()
{
// Provide the number of clusters
- return fNclusters;
+ Int_t nclu=0;
+ if (fClusters) nclu=fClusters->GetEntries();
+ return nclu;
}
///////////////////////////////////////////////////////////////////////////
AliCalcluster* AliCalorimeter::GetCluster(Int_t j)
{
// Provide cluster number j
// Note : j=1 denotes the first cluster
- if ((j >= 1) && (j <= fNclusters))
+
+ if (!fClusters) return 0;
+
+ if ((j >= 1) && (j <= GetNclusters()))
{
return (AliCalcluster*)fClusters->At(j-1);
}
else
{
cout << " *AliCalorimeter::GetCluster* cluster number : " << j
- << " out of range." << endl;
- cout << " -- Cluster number 1 (if any) returned " << endl;
- return (AliCalcluster*)fClusters->At(0);
+ << " out of range ==> 0 returned." << endl;
+ return 0;
}
}
///////////////////////////////////////////////////////////////////////////
{
// Provide 'fired' module number j
// Note : j=1 denotes the first 'fired' module
- if ((j >= 1) && (j <= fNsignals))
+
+ if (!fMatrix) return 0;
+
+ if ((j >= 1) && (j <= GetNsignals()))
{
- return (AliCalmodule*)fModules->At(j-1);
+ return (AliCalmodule*)fMatrix->GetObject(j);
}
else
{
cout << " *AliCalorimeter::GetModule* module number : " << j
- << " out of range." << endl;
- cout << " -- Fired module number 1 (if any) returned " << endl;
- return (AliCalmodule*)fModules->At(0);
+ << " out of range ==> 0 returned." << endl;
+ return 0;
}
}
///////////////////////////////////////////////////////////////////////////
// Provide access to module (row,col).
// Note : first module is at (1,1).
- if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
-
- if (row>=1 && row<=fNrows && col>=1 && col<=fNcolumns)
- {
- return fMatrix[row-1][col-1];
- }
- else
- {
- cout << " *AliCalorimeter::GetModule* row,col : " << row << ", " << col
- << " out of range." << endl;
- return 0;
- }
+ AliCalmodule* m=0;
+ if (fMatrix) m=(AliCalmodule*)fMatrix->GetObject(row,col);
+ return m;
}
///////////////////////////////////////////////////////////////////////////
-TH2F* AliCalorimeter::DrawModules()
+TH2F* AliCalorimeter::DrawModules(Float_t thresh,Int_t mode)
{
-// Provide a lego plot of the module signals
+// Provide a lego plot of the module signals.
+// The input parameter mode (default mode=0) has the same meaning as
+// specified in the memberfunction GetSignal(row,col,mode).
+// Only modules with a (corrected) signal value above the threshold
+// (default thresh=0) will be displayed.
+
+ Int_t nrows=fNrows;
+ Int_t ncols=fNcolumns;
+
+ if (fMatrix && !nrows && !ncols)
+ {
+ nrows=fMatrix->GetMaxRow();
+ ncols=fMatrix->GetMaxColumn();
+ }
if (fHmodules)
{
else
{
fHmodules=new TH2F("fHmodules","Module signals",
- fNcolumns,0.5,float(fNcolumns)+0.5,fNrows,0.5,float(fNrows)+0.5);
+ ncols,0.5,float(ncols)+0.5,nrows,0.5,float(nrows)+0.5);
fHmodules->SetDirectory(0); // Suppress global character of histo pointer
}
- AliCalmodule* m;
+ Int_t nmods=GetNsignals();
+
Float_t row,col,signal;
Int_t dead;
- for (Int_t i=0; i<fNsignals; i++)
+ for (Int_t i=1; i<=nmods; i++)
{
- m=(AliCalmodule*)fModules->At(i);
+ AliCalmodule* m=(AliCalmodule*)fMatrix->GetObject(i);
if (m)
{
row=float(m->GetRow());
col=float(m->GetColumn());
dead=m->GetDeadValue();
signal=0;
- if (!dead) signal=m->GetSignal();
- if (signal>0.) fHmodules->Fill(col,row,signal);
+ if (!dead) signal=GetSignal(row,col,mode);
+ if (signal>thresh) fHmodules->Fill(col,row,signal);
}
}
return fHmodules;
}
///////////////////////////////////////////////////////////////////////////
-TH2F* AliCalorimeter::DrawClusters()
+TH2F* AliCalorimeter::DrawClusters(Float_t thresh)
{
-// Provide a lego plot of the cluster signals
+// Provide a lego plot of the cluster signals.
+// Only clusters with a signal value above the threshold (default thresh=0)
+// will be displayed.
+
+ Int_t nrows=fNrows;
+ Int_t ncols=fNcolumns;
+
+ if (fMatrix && !nrows && !ncols)
+ {
+ nrows=fMatrix->GetMaxRow();
+ ncols=fMatrix->GetMaxColumn();
+ }
if (fHclusters)
{
else
{
fHclusters=new TH2F("fHclusters","Cluster signals",
- fNcolumns,0.5,float(fNcolumns)+0.5,fNrows,0.5,float(fNrows)+0.5);
+ ncols,0.5,float(ncols)+0.5,nrows,0.5,float(nrows)+0.5);
fHclusters->SetDirectory(0); // Suppress global character of histo pointer
}
AliCalcluster* c;
Float_t row,col,signal;
- for (Int_t i=0; i<fNclusters; i++)
+ for (Int_t i=0; i<GetNclusters(); i++)
{
c=(AliCalcluster*)fClusters->At(i);
if (c)
row=float(c->GetRow());
col=float(c->GetColumn());
signal=c->GetSignal();
- if (signal>0.) fHclusters->Fill(col,row,signal);
+ if (signal>thresh) fHclusters->Fill(col,row,signal);
}
}
return fHclusters;
}
///////////////////////////////////////////////////////////////////////////
-void AliCalorimeter::LoadMatrix()
-{
-// Load the Calorimeter module matrix data back from the TObjArray
-
- // Initialise the module matrix
- if (!fMatrix)
- {
- fMatrix=new AliCalmodule**[fNrows];
- for (Int_t i=0; i<fNrows; i++)
- {
- fMatrix[i]=new AliCalmodule*[fNcolumns];
- }
- }
-
- // Initialise the position matrix
- if (!fPositions)
- {
- fPositions=new AliPosition**[fNrows];
- for (Int_t j=0; j<fNrows; j++)
- {
- fPositions[j]=new AliPosition*[fNcolumns];
- }
- }
-
- for (Int_t jrow=0; jrow<fNrows; jrow++)
- {
- for (Int_t jcol=0; jcol<fNcolumns; jcol++)
- {
- fMatrix[jrow][jcol]=0;
- fPositions[jrow][jcol]=0;
- }
- }
-
- // Copy the module pointers back into the matrix
- AliCalmodule* m=0;
- Int_t row=0;
- Int_t col=0;
- Int_t nsig=0;
- if (fModules) nsig=fModules->GetEntries();
- for (Int_t j=0; j<nsig; j++)
- {
- m=(AliCalmodule*)fModules->At(j);
- if (m)
- {
- row=m->GetRow();
- col=m->GetColumn();
- AliPosition r=m->GetPosition();
- fMatrix[row-1][col-1]=m;
- fPositions[row-1][col-1]=new AliPosition(r);
- }
- }
-}
-///////////////////////////////////////////////////////////////////////////
void AliCalorimeter::Ungroup()
{
// Set the module signals back to the non-clustered situation
+
+ if (!fMatrix) return;
- if (!fMatrix) LoadMatrix(); // Restore matrix data in case of reading input
-
- Int_t nsig=0;
- if (fModules) nsig=fModules->GetEntries();
+ Int_t nsig=GetNsignals();
Float_t signal=0;
- AliCalmodule* m=0;
- for (Int_t j=0; j<nsig; j++)
+ for (Int_t j=1; j<=nsig; j++)
{
- m=(AliCalmodule*)fModules->At(j);
+ AliCalmodule* m=(AliCalmodule*)fMatrix->GetObject(j);
if (m)
{
signal=m->GetSignal();
// Associate an (extrapolated) AliSignal as veto to the calorimeter.
if (!fVetos)
{
- fNvetos=0;
fVetos=new TObjArray();
fVetos->SetOwner();
}
AliSignal* sx=new AliSignal(s);
fVetos->Add(sx);
- fNvetos++;
}
///////////////////////////////////////////////////////////////////////////
Int_t AliCalorimeter::GetNvetos()
{
-// Provide the number of veto signals associated to the calorimeter
- return fNvetos;
+// Provide the number of veto signals associated to the calorimeter.
+ Int_t nvetos=0;
+ if (fVetos) nvetos=fVetos->GetEntries();
+ return nvetos;
}
///////////////////////////////////////////////////////////////////////////
AliSignal* AliCalorimeter::GetVetoSignal(Int_t i)
// Provide access to the i-th veto signal of this calorimeter
// Note : The first hit corresponds to i=1
- if (i>0 && i<=fNvetos)
+ if (i>0 && i<=GetNvetos())
{
return (AliSignal*)fVetos->At(i-1);
}
else
{
cout << " *AliCalorimeter::GetVetoSignal* Signal number " << i
- << " out of range." << endl;
- cout << " --- First signal (if any) returned." << endl;
- return (AliSignal*)fVetos->At(0);
+ << " out of range ==> 0 returned." << endl;
+ return 0;
}
}
///////////////////////////////////////////////////////////////////////////
return fName;
}
///////////////////////////////////////////////////////////////////////////
+void AliCalorimeter::SetSwapMode(Int_t swap)
+{
+// Set the swap mode for the module and position matrices.
+// At invokation of this memberfunction the default argument is swap=1.
+// For further details see the documentation of AliObjMatrix.
+ if (swap==0 || swap==1)
+ {
+ fSwap=swap;
+ }
+ else
+ {
+ cout << " *AliCalorimeter::SetSwapMode* Invalid argument : swap = " << swap << endl;
+ }
+}
+///////////////////////////////////////////////////////////////////////////
+Int_t AliCalorimeter::GetSwapMode()
+{
+// Provide the swap mode for the module and position matrices.
+// For further details see the documentation of AliObjMatrix.
+ return fSwap;
+}
+///////////////////////////////////////////////////////////////////////////
// Float_t err[3]={0.03,0.7,0.18};
// Float_t signal=120.8;
// Float_t error=1.73;
+// Float_t offset=-12.78;
+// Float_t gain=250;
// s.SetPosition(pos,"car");
// s.SetPositionErrors(err,"car");
// s.SetSignal(signal);
// s.SetSignalError(error);
+// s.SetOffset(offset);
+// s.SetGain(gain);
// Float_t loc[3],dr[3],sigma;
// s.GetPosition(loc,"sph");
// s.GetPositionErrors(dr,"sph");
// q.SetPositionErrors(err,"car");
// signal=82.5; // e.g. signal time in ns
// error=2.01;
+// offset=0.003;
// 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;
// q.SetSignal(signal,2);
// q.SetSignalError(error,2);
+// q.SetGain(gain,2);
// signal=23.7; // e.g. corresponding dE/dx value
// error=0.48;
+// offset=0.2;
+// gain=150;
// q.SetSignal(signal,3);
// q.SetSignalError(error,3);
+// q.SetOffset(offset,3);
+// q.SetGain(gain,3);
//
//--- Author: Nick van Eijndhoven 23-jan-1999 UU-SAP Utrecht
//- Modified: NvE $Date$ UU-SAP Utrecht
ClassImp(AliSignal) // Class implementation to enable ROOT I/O
-AliSignal::AliSignal() : TObject(),AliPosition()
+AliSignal::AliSignal() : TObject(),AliPosition(),AliAttrib()
{
// Creation of an AliSignal object and initialisation of parameters.
-// Several values (with errors) can be stored.
+// Several signal values (with errors) can be stored in different slots.
// If needed, the storage for values (and errors) will be expanded automatically
// when entering values and/or errors.
- fSignal=0;
- fDsignal=0;
+ fSignals=0;
+ fDsignals=0;
+ fWaveforms=0;
fName="Unspecified";
- fHwaveform=0;
}
///////////////////////////////////////////////////////////////////////////
AliSignal::~AliSignal()
{
// Destructor to delete dynamically allocated memory
- if (fSignal)
+ if (fSignals)
{
- delete fSignal;
- fSignal=0;
+ delete fSignals;
+ fSignals=0;
}
- if (fDsignal)
+ if (fDsignals)
{
- delete fDsignal;
- fDsignal=0;
+ delete fDsignals;
+ fDsignals=0;
}
- if (fHwaveform)
+ if (fWaveforms)
{
- delete fHwaveform;
- fHwaveform=0;
+ delete fWaveforms;
+ fWaveforms=0;
}
}
///////////////////////////////////////////////////////////////////////////
-AliSignal::AliSignal(AliSignal& s) : TObject(s),AliPosition(s)
+AliSignal::AliSignal(AliSignal& s) : TObject(s),AliPosition(s),AliAttrib(s)
{
// Copy constructor
- fSignal=0;
- fDsignal=0;
+ fSignals=0;
+ fDsignals=0;
fName=s.fName;
- fHwaveform=0;
+ fWaveforms=0;
- Int_t nvalues=s.GetNvalues();
- Double_t sig;
- for (Int_t i=1; i<=nvalues; i++)
+ Int_t n=s.GetNvalues();
+ Double_t val;
+ for (Int_t i=1; i<=n; i++)
{
- sig=s.GetSignal(i);
- SetSignal(sig,i);
+ val=s.GetSignal(i);
+ SetSignal(val,i);
}
- Int_t nerrors=s.GetNerrors();
- Double_t err;
- for (Int_t j=1; j<=nerrors; j++)
+ n=s.GetNerrors();
+ for (Int_t j=1; j<=n; j++)
{
- err=s.GetSignalError(j);
- SetSignalError(err,j);
+ val=s.GetSignalError(j);
+ SetSignalError(val,j);
}
- TH1F* hist=s.GetWaveform();
- if (hist) fHwaveform=new TH1F(*hist);
+ n=s.GetNwaveforms();
+ for (Int_t k=1; k<=n; k++)
+ {
+ TH1F* hist=s.GetWaveform(k);
+ if (hist) SetWaveform(hist,k);
+ }
}
///////////////////////////////////////////////////////////////////////////
void AliSignal::Reset(Int_t mode)
// Reset all signal and position values and errors to 0.
//
// mode = 0 Reset position and all signal values and their errors to 0.
-// The waveform histogram is reset.
+// The waveform histograms are reset, but the calibration
+// constants (i.e. gains and offsets) are kept.
// 1 Reset position and delete the signal and error storage arrays.
-// The waveform histogram is deleted.
+// Also the waveform histograms, gains and offset arrays are deleted.
//
// The default when invoking Reset() corresponds to mode=0.
//
// The usage of mode=0 allows to re-use the allocated memory for new
// signal (and error) values. This behaviour is preferable (i.e. faster)
-// in case the various signals always contain the same number of values.
+// in case the various signals always contain the same number of values
+// and have the same calibration constants.
// The usage of mode=1 is slower, but allows a more efficient memory
// occupation (and smaller output file size) in case the different
// signals have a variable number of values.
//
-// For more specific actions see ResetPosition(), ResetSignals()
-// and DeleteSignals().
+// For more specific actions see ResetPosition(), ResetSignals(),
+// DeleteSignals(), ResetGain(), ResetOffset() and DeleteCalibrations().
//
if (mode<0 || mode>1)
else
{
DeleteSignals();
+ DeleteCalibrations();
}
}
///////////////////////////////////////////////////////////////////////////
//
// The default when invoking ResetSignals() corresponds to mode=0.
//
-// Irrespective of the mode, the waveform histogram is reset.
+// Irrespective of the mode, the waveform histograms are reset.
if (mode<0 || mode>2)
{
mode=0;
}
- if (fSignal && (mode==0 || mode==1))
+ if (fSignals && (mode==0 || mode==1))
{
- for (Int_t i=0; i<fSignal->GetSize(); i++)
+ for (Int_t i=0; i<fSignals->GetSize(); i++)
{
- fSignal->AddAt(0,i);
+ fSignals->AddAt(0,i);
}
}
- if (fDsignal && (mode==0 || mode==2))
+ if (fDsignals && (mode==0 || mode==2))
{
- for (Int_t j=0; j<fDsignal->GetSize(); j++)
+ for (Int_t j=0; j<fDsignals->GetSize(); j++)
{
- fDsignal->AddAt(0,j);
+ fDsignals->AddAt(0,j);
}
}
- if (fHwaveform) fHwaveform->Reset();
+ ResetWaveform(0);
}
///////////////////////////////////////////////////////////////////////////
void AliSignal::DeleteSignals(Int_t mode)
//
// The default when invoking DeleteSignals() corresponds to mode=0.
//
-// Irrespective of the mode, the waveform histogram is deleted.
+// Irrespective of the mode, the waveform histograms are deleted.
if (mode<0 || mode>2)
{
mode=0;
}
- if (fSignal && (mode==0 || mode==1))
+ if (fSignals && (mode==0 || mode==1))
{
- delete fSignal;
- fSignal=0;
+ delete fSignals;
+ fSignals=0;
}
- if (fDsignal && (mode==0 || mode==2))
+ if (fDsignals && (mode==0 || mode==2))
{
- delete fDsignal;
- fDsignal=0;
+ delete fDsignals;
+ fDsignals=0;
}
- if (fHwaveform)
- {
- delete fHwaveform;
- fHwaveform=0;
- }
+ DeleteWaveform(0);
}
///////////////////////////////////////////////////////////////////////////
void AliSignal::ResetPosition()
///////////////////////////////////////////////////////////////////////////
void AliSignal::SetSignal(Double_t sig,Int_t j)
{
-// Store j-th (default j=1) signal value.
-// Note : The first signal value is at j=1.
+// Store value in the j-th (default j=1) signal slot.
+// Note : The first signal slot is at j=1.
// In case the value of the index j exceeds the maximum number of reserved
// slots for signal values, the number of reserved slots for the
// signal values is increased automatically.
- if (!fSignal)
+ if (!fSignals)
{
- fSignal=new TArrayF(j);
+ fSignals=new TArrayF(j);
ResetSignals(1);
}
- Int_t size=fSignal->GetSize();
+ Int_t size=fSignals->GetSize();
if (j>size)
{
- fSignal->Set(j);
+ fSignals->Set(j);
}
- fSignal->AddAt(float(sig),j-1);
+ fSignals->AddAt(float(sig),j-1);
}
///////////////////////////////////////////////////////////////////////////
void AliSignal::AddSignal(Double_t sig,Int_t j)
{
-// Add value to j-th (default j=1) signal value.
-// Note : The first signal value is at j=1.
+// Add value to the j-th (default j=1) signal slot.
+// Note : The first signal slot is at j=1.
// In case the value of the index j exceeds the maximum number of reserved
// slots for signal values, the number of reserved slots for the
// signal values is increased automatically.
- if (!fSignal)
+ if (!fSignals)
{
- fSignal=new TArrayF(j);
+ fSignals=new TArrayF(j);
ResetSignals(1);
}
- Int_t size=fSignal->GetSize();
+ Int_t size=fSignals->GetSize();
if (j>size)
{
- fSignal->Set(j);
+ fSignals->Set(j);
}
- Float_t sum=(fSignal->At(j-1))+sig;
- fSignal->AddAt(sum,j-1);
+ Float_t sum=(fSignals->At(j-1))+sig;
+ fSignals->AddAt(sum,j-1);
}
///////////////////////////////////////////////////////////////////////////
-Float_t AliSignal::GetSignal(Int_t j)
+Float_t AliSignal::GetSignal(Int_t j,Int_t mode)
{
-// Provide j-th (default j=1) signal value.
-// Note : The first signal value is at j=1.
+// Provide value of the j-th (default j=1) signal 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.
+//
+// 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 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.
+// In case the j-th slot was marked dead, 0 is returned.
+//
+// The corrected signal (sigc) is determined as follows :
+//
+// sigc=(signal/gain)-offset
+//
+// The default is mode=0.
+
Float_t sig=0;
- if (fSignal)
+ Float_t gain=1;
+ Float_t offset=0;
+ if (fSignals)
{
- if (j>0 && j<=(fSignal->GetSize()))
+ if (j>0 && j<=(fSignals->GetSize()))
{
- sig=fSignal->At(j-1);
+ 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 (GetGainFlag(j)) gain=GetGain(j);
+ if (GetOffsetFlag(j)) offset=GetOffset(j);
+
+ if (fabs(gain)>0.)
+ {
+ sig=(sig/gain)-offset;
+ }
+ else
+ {
+ sig=0;
+ }
}
else
{
///////////////////////////////////////////////////////////////////////////
void AliSignal::SetSignalError(Double_t dsig,Int_t j)
{
-// Store error on j-th (default j=1) signal value.
-// Note : The error on the first signal value is at j=1.
+// Store error for the j-th (default j=1) signal slot.
+// Note : The first signal slot is at j=1.
// In case the value of the index j exceeds the maximum number of reserved
// slots for signal error values, the number of reserved slots for the
// signal errors is increased automatically.
- if (!fDsignal)
+ if (!fDsignals)
{
- fDsignal=new TArrayF(j);
+ fDsignals=new TArrayF(j);
ResetSignals(2);
}
- Int_t size=fDsignal->GetSize();
+ Int_t size=fDsignals->GetSize();
if (j>size)
{
- fDsignal->Set(j);
+ fDsignals->Set(j);
}
- fDsignal->AddAt(float(dsig),j-1);
+ fDsignals->AddAt(float(dsig),j-1);
}
///////////////////////////////////////////////////////////////////////////
Float_t AliSignal::GetSignalError(Int_t j)
{
-// Provide error on the j-th (default j=1) signal value.
-// Note : The error on the first signal value is at j=1.
+// Provide error of the j-th (default j=1) signal 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.
Float_t err=0;
- if (fDsignal)
+ if (fDsignals)
{
- if (j>0 && j<=(fDsignal->GetSize()))
+ if (j>0 && j<=(fDsignals->GetSize()))
{
- err=fDsignal->At(j-1);
+ err=fDsignals->At(j-1);
}
else
{
return err;
}
///////////////////////////////////////////////////////////////////////////
-void AliSignal::Data(TString f)
+void AliSignal::Data(TString f,Int_t j)
{
-// Provide signal information within the coordinate frame f
+// Provide signal information for the j-th slot within the coordinate frame f.
+// The first slot is at j=1.
+// In case j=0 (default) the data of all slots will be listed.
+
+ if (j<0)
+ {
+ cout << " *AliSignal::Data* Invalid argument j = " << j << endl;
+ return;
+ }
+
cout << " *AliSignal::Data* Signal of kind : " << fName.Data() << endl;
cout << " Position";
Ali3Vector::Data(f);
Int_t nvalues=GetNvalues();
Int_t nerrors=GetNerrors();
+ Int_t n=nvalues;
+ if (nerrors>n) n=nerrors;
- if (fSignal)
+ if (j==0)
{
- for (Int_t i=0; i<nvalues; i++)
+ for (Int_t i=1; i<=n; i++)
{
- cout << " Signal value : " << fSignal->At(i);
- if (fDsignal && i<nerrors) cout << " error : " << fDsignal->At(i);
+ cout << " Signal";
+ if (i<=nvalues) cout << " value : " << GetSignal(i);
+ if (i<=nerrors) cout << " error : " << GetSignalError(i);
+ AliAttrib::Data(i);
+ cout << endl;
+ }
+ }
+ else
+ {
+ if (j<=n)
+ {
+ cout << " Signal";
+ if (j<=nvalues) cout << " value : " << GetSignal(j);
+ if (j<=nerrors) cout << " error : " << GetSignalError(j);
+ AliAttrib::Data(j);
cout << endl;
}
}
{
// Provide the number of values for this signal.
Int_t n=0;
- if (fSignal) n=fSignal->GetSize();
+ if (fSignals) n=fSignals->GetSize();
return n;
}
///////////////////////////////////////////////////////////////////////////
{
// Provide the number specified errors on the values for this signal.
Int_t n=0;
- if (fDsignal) n=fDsignal->GetSize();
+ if (fDsignals) n=fDsignals->GetSize();
return n;
}
///////////////////////////////////////////////////////////////////////////
-TH1F* AliSignal::GetWaveform()
+Int_t AliSignal::GetNwaveforms()
{
-// Provide pointer to the 1D waveform histogram.
- return fHwaveform;
+// Provide the number specified waveforms for this signal.
+ Int_t n=0;
+ if (fWaveforms) n=fWaveforms->GetSize();
+ return n;
}
///////////////////////////////////////////////////////////////////////////
-void AliSignal::SetWaveform(TH1F* waveform)
+TH1F* AliSignal::GetWaveform(Int_t j)
{
-// Set the 1D waveform histogram.
+// Provide pointer to the j-th waveform histogram.
+ TH1F* waveform=0;
+ if (j <= GetNwaveforms()) waveform=(TH1F*)fWaveforms->At(j-1);
+ return waveform;
+}
+///////////////////////////////////////////////////////////////////////////
+void AliSignal::SetWaveform(TH1F* waveform,Int_t j)
+{
+// Set the 1D waveform histogram corresponding to the j-th signal value.
+//
+// Notes :
+// The waveform of the first signal value is at j=1.
+// j=1 is the default value.
+//
+// In case the value of the index j exceeds the maximum number of reserved
+// slots for the waveforms, the number of reserved slots for the waveforms
+// is increased automatically.
//
-// In case the input argument has the same value as the current waveform
+// In case the histo pointer argument has the same value as the current waveform
// histogram pointer value, no action is taken since the user has already
// modified the actual histogram.
//
-// In case the input argument is zero, the current waveform histogram
+// In case the histo pointer argument is zero, the current waveform histogram
// is deleted and the pointer set to zero.
//
// In all other cases the current waveform histogram is deleted and a new
// copy of the input histogram is created which becomes the current waveform
// histogram.
- if (waveform != fHwaveform)
+ if (!fWaveforms)
+ {
+ fWaveforms=new TObjArray(j);
+ fWaveforms->SetOwner();
+ }
+
+ if (j > fWaveforms->GetSize()) fWaveforms->Expand(j);
+
+ TH1F* hcur=(TH1F*)fWaveforms->At(j-1);
+ if (waveform != hcur)
{
- if (fHwaveform)
+ if (hcur)
{
- delete fHwaveform;
- fHwaveform=0;
+ fWaveforms->Remove(hcur);
+ delete hcur;
+ hcur=0;
+ }
+ if (waveform)
+ {
+ hcur=new TH1F(*waveform);
+ fWaveforms->AddAt(hcur,j-1);
}
- if (waveform) fHwaveform=new TH1F(*waveform);
}
}
///////////////////////////////////////////////////////////////////////////
+void AliSignal::ResetWaveform(Int_t j)
+{
+// Reset the waveform of the j-th (default j=1) signal value.
+// This memberfunction invokes TH1F::Reset() for the corresponding waveform(s).
+// To actually delete the histograms from memory, use DeleteWaveform().
+// Notes : The first signal value is at j=1.
+// j=0 ==> All waveforms will be reset.
+
+ if (!fWaveforms) return;
+
+ Int_t size=fWaveforms->GetSize();
+
+ if ((j>=0) && (j<=size))
+ {
+ if (j)
+ {
+ TH1F* hwave=(TH1F*)fWaveforms->At(j-1);
+ if (hwave) hwave->Reset();
+ }
+ else
+ {
+ for (Int_t i=0; i<size; i++)
+ {
+ TH1F* hwave=(TH1F*)fWaveforms->At(i);
+ if (hwave) hwave->Reset();
+ }
+ }
+ }
+ else
+ {
+ cout << " *AliSignal::ResetWaveform* Index j = " << j << " invalid." << endl;
+ return;
+ }
+}
+///////////////////////////////////////////////////////////////////////////
+void AliSignal::DeleteWaveform(Int_t j)
+{
+// Delete the waveform of the j-th (default j=1) signal value.
+// Notes : The first signal value is at j=1.
+// j=0 ==> All waveforms will be deleted.
+
+ if (!fWaveforms) return;
+
+ Int_t size=fWaveforms->GetSize();
+
+ if ((j>=0) && (j<=size))
+ {
+ if (j)
+ {
+ TH1F* hwave=(TH1F*)fWaveforms->At(j-1);
+ if (hwave)
+ {
+ fWaveforms->Remove(hwave);
+ delete hwave;
+ }
+ }
+ else
+ {
+ delete fWaveforms;
+ fWaveforms=0;
+ }
+ }
+ else
+ {
+ cout << " *AliSignal::DeleteWaveform* Index j = " << j << " invalid." << endl;
+ return;
+ }
+}
+///////////////////////////////////////////////////////////////////////////
AliSignal* AliSignal::MakeCopy(AliSignal& s)
{
// Make a deep copy of the input object and provide the pointer to the copy.