// pos[1]=78.25
// pos[3]=12.93
// s->SetPosition(pos,"car");
-// m->EnterObject(6,21,s);
+// matrix->EnterObject(6,21,s);
//
// s=new AliSignal();
// s->SetSignal(25.84);
// pos[1]=-53.88
// pos[3]=22.69
// s->SetPosition(pos,"car");
-// m->EnterObject(8,13,s);
+// matrix->EnterObject(8,13,s);
//
// s=new AliSignal();
// s->SetSignal(87.25);
// pos[1]=932.576
// pos[3]=-1382.754
// s->SetPosition(pos,"car");
-// m->EnterObject(64,3,s);
+// matrix->EnterObject(64,3,s);
//
// Int_t nrows=matrix->GetMaxRow();
// Int_t ncols=matrix->GetMaxColumn();
///////////////////////////////////////////////////////////////////////////
#include "AliObjMatrix.h"
+#include "Riostream.h"
ClassImp(AliObjMatrix) // Class implementation to enable ROOT I/O
-AliObjMatrix::AliObjMatrix()
+AliObjMatrix::AliObjMatrix() : TNamed()
{
// Default constructor.
// Note : The owner and swap mode flags will be initialised to 0.
fSwap=0;
fMaxrow=0;
fMaxcol=0;
- fNobjects=0;
+ fObjects=0;
}
///////////////////////////////////////////////////////////////////////////
AliObjMatrix::~AliObjMatrix()
delete fRows;
fRows=0;
}
+ if (fObjects)
+ {
+ delete fObjects;
+ fObjects=0;
+ }
}
///////////////////////////////////////////////////////////////////////////
void AliObjMatrix::Reset()
delete fRows;
fRows=0;
}
+ if (fObjects)
+ {
+ delete fObjects;
+ fObjects=0;
+ }
fMaxrow=0;
fMaxcol=0;
- fNobjects=0;
}
///////////////////////////////////////////////////////////////////////////
void AliObjMatrix::SetOwner(Int_t own)
}
}
///////////////////////////////////////////////////////////////////////////
-Int_t AliObjMatrix::GetOwner()
+Int_t AliObjMatrix::GetOwner() const
{
// Provide the owner flag for the stored objects.
return fOwn;
}
}
///////////////////////////////////////////////////////////////////////////
-Int_t AliObjMatrix::GetSwapMode()
+Int_t AliObjMatrix::GetSwapMode() const
{
// Provide the swap mode flag for this matrix.
return fSwap;
// Enter an object to the matrix structure at location (row,col).
// In case the location already contained an object, the existing object
// will first be removed before the new object is stored.
-// According to the status of the copy flag (see the SetCopy() function)
+// According to the status of the owner flag (see the SetOwner() function)
// the existing object will also be deleted.
// Note : The first location in the matrix is indicated as (1,1).
if (row<1 || col<1)
}
TObject* old=(TObject*)mrow->At(colx-1);
- if (!old) fNobjects++;
- if (old && fOwn) delete old;
+ if (old)
+ {
+ fObjects->Remove(old);
+ fObjects->Compress();
+ if (fOwn) delete old;
+ }
mrow->AddAt(obj,colx-1);
+
+ if (!fObjects) fObjects=new TObjArray();
+ fObjects->Add(obj);
+}
+///////////////////////////////////////////////////////////////////////////
+void AliObjMatrix::RemoveObject(Int_t row,Int_t col)
+{
+// Remove the object stored at the matrix location (row,col).
+// In case the object was owned by the matrix, it will be deleted.
+//
+// Note : The first location in the matrix is indicated as (1,1).
+
+ TObject* obj=0;
+
+ if (!fRows || row<1 || col<1) return;
+
+
+ Int_t rowx=row;
+ if (fSwap) rowx=col;
+ Int_t colx=col;
+ if (fSwap) colx=row;
+
+ TObjArray* mrow=0;
+ if (rowx <= fRows->GetSize()) mrow=(TObjArray*)fRows->At(rowx-1);
+
+ if (!mrow) return;
+
+ if (colx <= mrow->GetSize()) obj=(TObject*)mrow->At(colx-1);
+
+ if (obj)
+ {
+ fObjects->Remove(obj);
+ fObjects->Compress();
+ mrow->Remove(obj);
+ if (fOwn) delete obj;
+ }
}
///////////////////////////////////////////////////////////////////////////
-TObject* AliObjMatrix::GetObject(Int_t row,Int_t col)
+void AliObjMatrix::RemoveObjects(TObject* obj,Int_t row,Int_t col)
+{
+// Remove object(s) from the matrix according to user specified selections.
+// In case the object was owned by the matrix, it will be deleted.
+//
+// An object is only removed from the matrix if the stored reference matches
+// the argument "obj".
+// In case obj=0 no check on the matching of the stored reference is performed
+// and the stored object is always removed in accordance with the other
+// selection criteria.
+//
+// In case the argument "row" is specified, only the object references from
+// that matrix row will be deleted.
+// In case row=0 (default) no checking on the row index is performed.
+//
+// In case the argument "col" is specified, only the object references from
+// that matrix column will be deleted.
+// In case col=0 (default) no checking on the column index is performed.
+//
+// So, invokation of RemoveObjects(obj) will remove all references to the
+// object "obj" from the total matrix, whereas RemoveObjects(obj,0,col)
+// will remove all references to the object "obj" only from column "col".
+//
+// Notes :
+// -------
+// The first location in the matrix is indicated as (1,1).
+//
+// Invokation of RemoveObjects(0,row,col) is equivalent to invoking the
+// memberfunction RemoveObject(row,col).
+// Invoking the latter directly is slightly faster.
+//
+// Invokation of RemoveObjects(0) is equivalent to invoking Reset().
+// Invoking the latter directly is slightly faster.
+//
+ TArrayI rows;
+ TArrayI cols;
+ Int_t nrefs=0;
+
+ if (row && col)
+ {
+ if (!obj)
+ {
+ RemoveObject(row,col);
+ }
+ else
+ {
+ TObject* objx=GetObject(row,col);
+ if (objx==obj) RemoveObject(row,col);
+ }
+ return;
+ }
+
+ if (!row && !col)
+ {
+ if (!obj)
+ {
+ Reset();
+ return;
+ }
+ else
+ {
+ nrefs=GetIndices(obj,rows,cols);
+ }
+ }
+
+ if (row && !col) nrefs=GetIndices(obj,row,cols);
+ if (!row && col) nrefs=GetIndices(obj,rows,col);
+
+ // Remove the selected objects based on the obtained row and column indices
+ Int_t irow,icol;
+ for (Int_t i=0; i<nrefs; i++)
+ {
+ irow=row;
+ if (!irow) irow=rows.At(i);
+ icol=col;
+ if (!icol) icol=cols.At(i);
+ RemoveObject(irow,icol);
+ }
+}
+///////////////////////////////////////////////////////////////////////////
+TObject* AliObjMatrix::GetObject(Int_t row,Int_t col) const
{
// Provide a pointer to the object stored at the matrix location (row,col).
// In case no object was stored at the indicated location or the location
return obj;
}
///////////////////////////////////////////////////////////////////////////
-Int_t AliObjMatrix::GetMaxRow()
+TObject* AliObjMatrix::GetObject(Int_t j) const
+{
+// Provide a pointer to the j-th stored object.
+// In case the index j is invalid, a value 0 will be returned.
+// The first stored object is indicated as j=1.
+//
+// Note : Do NOT delete the object.
+// To remove an object, the memberfunction RemoveObject() or
+// RemoveObjects() should be used.
+
+ TObject* obj=0;
+ Int_t nobj=0;
+ if (fObjects) nobj=fObjects->GetSize();
+
+ if (j>0 && j<=nobj) obj=(TObject*)fObjects->At(j-1);
+
+ return obj;
+}
+///////////////////////////////////////////////////////////////////////////
+TObjArray* AliObjMatrix::GetObjects()
+{
+// Provide references to all the stored objects.
+// In case no objects are present, a value 0 will be returned.
+//
+// Note : Do NOT make any changes to the reference array apart from
+// changing the order of the pointers of the various objects.
+// For addition or removal of objects, the memberfunctions
+// EnterObject(), RemoveObject() or RemoveObjects() should be used.
+
+ return fObjects;
+}
+///////////////////////////////////////////////////////////////////////////
+Int_t AliObjMatrix::GetMaxRow() const
{
// Provide the maximum row number index.
return fMaxrow;
}
///////////////////////////////////////////////////////////////////////////
-Int_t AliObjMatrix::GetMaxColumn()
+Int_t AliObjMatrix::GetMaxColumn() const
{
// Provide the maximum column number index.
return fMaxcol;
}
///////////////////////////////////////////////////////////////////////////
-Int_t AliObjMatrix::GetNobjects()
+Int_t AliObjMatrix::GetNobjects() const
{
// Provide the number of stored objects.
- return fNobjects;
+ Int_t nobj=0;
+ if (fObjects) nobj=fObjects->GetEntries();
+
+ return nobj;
+}
+///////////////////////////////////////////////////////////////////////////
+Int_t AliObjMatrix::GetNrefs(TObject* obj) const
+{
+// Provide the number of stored references to the specified object.
+// If obj=0 the total number of stored references for all objects is returned.
+ Int_t nobjs=GetNobjects();
+
+ if (!obj) return nobjs;
+
+ Int_t nrefs=0;
+ for (Int_t i=1; i<=nobjs; i++)
+ {
+ TObject* objx=GetObject(i);
+ if (objx==obj) nrefs++;
+ }
+ return nrefs;
+}
+///////////////////////////////////////////////////////////////////////////
+Int_t AliObjMatrix::GetIndices(TObject* obj,TArrayI& rows,TArrayI& cols) const
+{
+// Provide the (row,col) indices of all the storage locations of the
+// specified object.
+// The row and column indices are returned in the two separate TArrayI arrays
+// from which the (row,col) pairs can be obtained from the corresponding
+// array indices like (row,col)=(rows.At(j),cols.At(j)).
+// The integer return argument represents the number of (row,col) pairs which
+// were encountered for the specified object.
+//
+// If obj=0 no object selection is performed and all (row,col) indices
+// of the stored references for all objects are returned.
+//
+// Notes :
+// -------
+// As usual the convention is that row and column numbering starts at 1.
+//
+// This memberfunction always resets the two TArrayI arrays at the start.
+//
+// This memberfunction can only be used to obtain the (row,col) indices
+// of the object as stored via the EnterObject() memberfunction.
+// This means that in case the user has entered a TObjArray as object
+// (to increase the dimension of the resulting structure), the (row,col)
+// indices of that TObjArray are obtained and NOT the indices of the
+// actual objects contained in that TObjArray structure.
+//
+ Int_t nrefs=GetNrefs(obj);
+ rows.Reset();
+ cols.Reset();
+ rows.Set(nrefs);
+ cols.Set(nrefs);
+ if (!nrefs) return 0;
+
+ Int_t irow,icol;
+ Int_t jref=0;
+ for (Int_t i=0; i<fRows->GetSize(); i++)
+ {
+ TObjArray* columns=(TObjArray*)fRows->At(i);
+ if (!columns) continue;
+
+ for (Int_t j=0; j<columns->GetSize(); j++)
+ {
+ TObject* objx=(TObject*)columns->At(j);
+ if (objx && (objx==obj || !obj))
+ {
+ irow=i+1;
+ if (fSwap) irow=j+1;
+ icol=j+1;
+ if (fSwap) icol=i+1;
+ rows.AddAt(irow,jref);
+ cols.AddAt(icol,jref);
+ jref++;
+ }
+ // All references found ==> Done
+ if (jref==nrefs) break;
+ }
+ // All references found ==> Done
+ if (jref==nrefs) break;
+ }
+ return nrefs;
+}
+///////////////////////////////////////////////////////////////////////////
+Int_t AliObjMatrix::GetIndices(TObject* obj,Int_t row,TArrayI& cols) const
+{
+// Provide the column indices of all the storage locations of the
+// specified object in the specified row of the matrix.
+// The column indices are returned in the TArrayI array.
+// The integer return argument represents the number of storage locations which
+// were encountered for the specified object in the specified matrix row.
+//
+// If obj=0 no object selection is performed and all column indices
+// of the stored references for all objects in this specified matrix row
+// are returned.
+//
+// If row=0 all rows will be scanned and all column indices matching the
+// object selection are returned.
+// Note that in this case multiple appearances of the same column index
+// will only be recorded once in the returned TArrayI array.
+//
+// Notes :
+// -------
+// As usual the convention is that row and column numbering starts at 1.
+//
+// This memberfunction always resets the TArrayI array at the start.
+//
+// This memberfunction can only be used to obtain the column indices
+// of the object as stored via the EnterObject() memberfunction.
+// This means that in case the user has entered a TObjArray as object
+// (to increase the dimension of the resulting structure), the column
+// indices of that TObjArray are obtained and NOT the indices of the
+// actual objects contained in that TObjArray structure.
+//
+ cols.Reset();
+
+ if (row<0 || row>GetMaxRow()) return 0;
+
+ Int_t nrefs=GetNrefs(obj);
+ cols.Set(nrefs);
+ if (!nrefs) return 0;
+
+ Int_t irow,icol;
+ Int_t jref=0;
+
+ // No specific row selection
+ if (!row)
+ {
+ TArrayI ar;
+ TArrayI ac;
+ Int_t n=GetIndices(obj,ar,ac);
+ Int_t found=0;
+ for (Int_t idx=0; idx<n; idx++)
+ {
+ icol=ac.At(idx);
+ found=0;
+ for (Int_t k=0; k<jref; k++)
+ {
+ if (icol==cols.At(k)) found=1;
+ }
+ if (!found)
+ {
+ cols.AddAt(icol,jref);
+ jref++;
+ }
+ }
+ // Set the array size to the actual number of different column indices
+ cols.Set(jref);
+
+ return jref;
+ }
+
+ // Specific row selection
+ for (Int_t i=0; i<fRows->GetSize(); i++)
+ {
+ TObjArray* columns=(TObjArray*)fRows->At(i);
+ if (!columns) continue;
+
+ for (Int_t j=0; j<columns->GetSize(); j++)
+ {
+ TObject* objx=(TObject*)columns->At(j);
+ if (objx && (objx==obj || !obj))
+ {
+ irow=i+1;
+ if (fSwap) irow=j+1;
+ icol=j+1;
+ if (fSwap) icol=i+1;
+ if (irow==row)
+ {
+ cols.AddAt(icol,jref);
+ jref++;
+ }
+ }
+ // All references found ==> Done
+ if (jref==nrefs) break;
+ }
+ // All references found ==> Done
+ if (jref==nrefs) break;
+ }
+ // Set the array size to the actual number of found occurrences
+ cols.Set(jref);
+
+ return jref;
+}
+///////////////////////////////////////////////////////////////////////////
+Int_t AliObjMatrix::GetIndices(TObject* obj,TArrayI& rows,Int_t col) const
+{
+// Provide the row indices of all the storage locations of the
+// specified object in the specified column of the matrix.
+// The row indices are returned in the TArrayI array.
+// The integer return argument represents the number of storage locations which
+// were encountered for the specified object in the specified matrix column.
+//
+// If obj=0 no object selection is performed and all row indices
+// of the stored references for all objects in this specified matrix column
+// are returned.
+//
+// If col=0 all columns will be scanned and all row indices matching the
+// object selection are returned.
+// Note that in this case multiple appearances of the same row index
+// will only be recorded once in the returned TArrayI array.
+//
+// Notes :
+// -------
+// As usual the convention is that row and column numbering starts at 1.
+//
+// This memberfunction always resets the TArrayI array at the start.
+//
+// This memberfunction can only be used to obtain the row indices
+// of the object as stored via the EnterObject() memberfunction.
+// This means that in case the user has entered a TObjArray as object
+// (to increase the dimension of the resulting structure), the row
+// indices of that TObjArray are obtained and NOT the indices of the
+// actual objects contained in that TObjArray structure.
+//
+ rows.Reset();
+
+ if (col<0 || col>GetMaxColumn()) return 0;
+
+ Int_t nrefs=GetNrefs(obj);
+ rows.Set(nrefs);
+ if (!nrefs) return 0;
+
+ Int_t irow,icol;
+ Int_t jref=0;
+
+ // No specific column selection
+ if (!col)
+ {
+ TArrayI ar;
+ TArrayI ac;
+ Int_t n=GetIndices(obj,ar,ac);
+ Int_t found=0;
+ for (Int_t idx=0; idx<n; idx++)
+ {
+ irow=ar.At(idx);
+ found=0;
+ for (Int_t k=0; k<jref; k++)
+ {
+ if (irow==rows.At(k)) found=1;
+ }
+ if (!found)
+ {
+ rows.AddAt(irow,jref);
+ jref++;
+ }
+ }
+ // Set the array size to the actual number of different row indices
+ rows.Set(jref);
+
+ return jref;
+ }
+
+ // Specific column selection
+ for (Int_t i=0; i<fRows->GetSize(); i++)
+ {
+ TObjArray* columns=(TObjArray*)fRows->At(i);
+ if (!columns) continue;
+
+ for (Int_t j=0; j<columns->GetSize(); j++)
+ {
+ TObject* objx=(TObject*)columns->At(j);
+ if (objx && (objx==obj || !obj))
+ {
+ irow=i+1;
+ if (fSwap) irow=j+1;
+ icol=j+1;
+ if (fSwap) icol=i+1;
+ if (icol==col)
+ {
+ rows.AddAt(irow,jref);
+ jref++;
+ }
+ }
+ // All references found ==> Done
+ if (jref==nrefs) break;
+ }
+ // All references found ==> Done
+ if (jref==nrefs) break;
+ }
+ // Set the array size to the actual number of found occurrences
+ rows.Set(jref);
+
+ return jref;
}
///////////////////////////////////////////////////////////////////////////