1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
18 ///////////////////////////////////////////////////////////////////////////
20 // Handling of a matrix structure of objects.
21 // All objects which are derived from TObject may be entered into the matrix
22 // structure. This means that also TObjArray objects can be entered,
23 // which implies an increase of the dimension of the resulting structure.
28 // AliObjMatrix* matrix=new AliObjMatrix();
29 // matrix->SetOwner();
30 // matrix->SetSwapMode();
41 // s->SetPosition(pos,"car");
42 // matrix->EnterObject(6,21,s);
45 // s->SetSignal(25.84);
49 // s->SetPosition(pos,"car");
50 // matrix->EnterObject(8,13,s);
53 // s->SetSignal(87.25);
57 // s->SetPosition(pos,"car");
58 // matrix->EnterObject(64,3,s);
60 // Int_t nrows=matrix->GetMaxRow();
61 // Int_t ncols=matrix->GetMaxColumn();
63 // cout << " Maxrow : " << nrows << " Maxcol : " << ncols
64 // << " Nobjects : " << matrix->GetNobjects() << endl;
66 // for (Int_t i=1; i<=nrows; i++)
68 // for (Int_t j=1; j<=ncols; j++)
70 // s=(AliSignal*)matrix->GetObject(i,j);
71 // if (s) cout << " At (" << i << "," << j << ") Signal : " << s->GetSignal() << endl;
75 //--- Author: Nick van Eijndhoven 23-jan-2003 Utrecht University
76 //- Modified: NvE $Date$ Utrecht University
77 ///////////////////////////////////////////////////////////////////////////
79 #include "AliObjMatrix.h"
80 #include "Riostream.h"
82 ClassImp(AliObjMatrix) // Class implementation to enable ROOT I/O
84 AliObjMatrix::AliObjMatrix() : TNamed()
86 // Default constructor.
87 // Note : The owner and swap mode flags will be initialised to 0.
88 // See the memberfunctions SetOwner() and SetSwapMode() for further
97 ///////////////////////////////////////////////////////////////////////////
98 AliObjMatrix::~AliObjMatrix()
100 // Default destructor.
112 ///////////////////////////////////////////////////////////////////////////
113 AliObjMatrix::AliObjMatrix(const AliObjMatrix& m) : TNamed(m)
125 Int_t maxrow=m.GetMaxRow();
126 Int_t maxcol=m.GetMaxColumn();
127 for (Int_t irow=1; irow<=maxrow; irow++)
129 for (Int_t icol=1; icol<=maxcol; icol++)
131 TObject* obj=m.GetObject(irow,icol);
136 EnterObject(irow,icol,obj);
140 EnterObject(irow,icol,obj->Clone());
146 ///////////////////////////////////////////////////////////////////////////
147 void AliObjMatrix::Reset()
149 // Reset the whole matrix structure.
150 // Note : The values of the owner and swap mode flags will not be modified.
151 // To modify the ownership, use the memberfunction SetOwner().
152 // To modify the swap mode, use the memberfunction SetSwapMode().
167 ///////////////////////////////////////////////////////////////////////////
168 void AliObjMatrix::SetOwner(Int_t own)
170 // Set the owner flag (0/1) for the stored objects.
171 // When the owner flag is set to 1, all entered objects are owned by the
173 // At invokation of this memberfunction the default argument is own=1.
179 for (Int_t irow=0; irow<fRows->GetSize(); irow++)
181 TObjArray* mrow=(TObjArray*)fRows->At(irow);
186 mrow->SetOwner(kTRUE);
190 mrow->SetOwner(kFALSE);
195 ///////////////////////////////////////////////////////////////////////////
196 Int_t AliObjMatrix::GetOwner() const
198 // Provide the owner flag for the stored objects.
201 ///////////////////////////////////////////////////////////////////////////
202 void AliObjMatrix::SetSwapMode(Int_t swap)
204 // Set the swap mode flag (0/1) for the internal matrix storage.
205 // In case the number of rows differs considerably from the number of columns,
206 // it might be more efficient (w.r.t. memory usage and/or output file size)
207 // to internally store the matrix with the rows and colums swapped.
208 // This swapping is only related with the internal storage and as such
209 // is completely hidden for the user.
210 // At invokation of this memberfunction the default argument is swap=1.
212 // Note : The swap mode can only be set as long as no objects have
213 // been stored in the matrix structure (i.e. a new instance
214 // of AliObjMatrix or after invokation of the Reset() function).
222 cout << " *AliObjMatrix::SetSwapMode* Matrix not empty ==> No action." << endl;
225 ///////////////////////////////////////////////////////////////////////////
226 Int_t AliObjMatrix::GetSwapMode() const
228 // Provide the swap mode flag for this matrix.
231 ///////////////////////////////////////////////////////////////////////////
232 void AliObjMatrix::EnterObject(Int_t row,Int_t col,TObject* obj)
234 // Enter an object to the matrix structure at location (row,col).
235 // In case the location already contained an object, the existing object
236 // will first be removed before the new object is stored.
237 // According to the status of the owner flag (see the SetOwner() function)
238 // the existing object will also be deleted.
239 // Note : The first location in the matrix is indicated as (1,1).
242 cout << " *AliObjMatrix::AddObject* Invalid argument(s) (row,col) : ("
243 << row << "," << col << ")" << endl;
247 if (row>fMaxrow) fMaxrow=row;
248 if (col>fMaxcol) fMaxcol=col;
257 fRows=new TObjArray(rowx);
262 if (rowx > fRows->GetSize()) fRows->Expand(rowx);
265 TObjArray* mrow=(TObjArray*)fRows->At(rowx-1);
269 TObjArray* columns=new TObjArray(colx);
270 if (fOwn) columns->SetOwner();
271 fRows->AddAt(columns,rowx-1);
276 if (colx > mrow->GetSize()) mrow->Expand(colx);
279 TObject* old=(TObject*)mrow->At(colx-1);
282 fObjects->Remove(old);
283 fObjects->Compress();
284 if (fOwn) delete old;
287 mrow->AddAt(obj,colx-1);
289 if (!fObjects) fObjects=new TObjArray();
292 ///////////////////////////////////////////////////////////////////////////
293 void AliObjMatrix::RemoveObject(Int_t row,Int_t col)
295 // Remove the object stored at the matrix location (row,col).
296 // In case the object was owned by the matrix, it will be deleted.
298 // Note : The first location in the matrix is indicated as (1,1).
302 if (!fRows || row<1 || col<1) return;
311 if (rowx <= fRows->GetSize()) mrow=(TObjArray*)fRows->At(rowx-1);
315 if (colx <= mrow->GetSize()) obj=(TObject*)mrow->At(colx-1);
319 fObjects->Remove(obj);
320 fObjects->Compress();
322 if (fOwn) delete obj;
325 ///////////////////////////////////////////////////////////////////////////
326 void AliObjMatrix::RemoveObjects(TObject* obj,Int_t row,Int_t col)
328 // Remove object(s) from the matrix according to user specified selections.
329 // In case the object was owned by the matrix, it will be deleted.
331 // An object is only removed from the matrix if the stored reference matches
332 // the argument "obj".
333 // In case obj=0 no check on the matching of the stored reference is performed
334 // and the stored object is always removed in accordance with the other
335 // selection criteria.
337 // In case the argument "row" is specified, only the object references from
338 // that matrix row will be deleted.
339 // In case row=0 (default) no checking on the row index is performed.
341 // In case the argument "col" is specified, only the object references from
342 // that matrix column will be deleted.
343 // In case col=0 (default) no checking on the column index is performed.
345 // So, invokation of RemoveObjects(obj) will remove all references to the
346 // object "obj" from the total matrix, whereas RemoveObjects(obj,0,col)
347 // will remove all references to the object "obj" only from column "col".
351 // The first location in the matrix is indicated as (1,1).
353 // Invokation of RemoveObjects(0,row,col) is equivalent to invoking the
354 // memberfunction RemoveObject(row,col).
355 // Invoking the latter directly is slightly faster.
357 // Invokation of RemoveObjects(0) is equivalent to invoking Reset().
358 // Invoking the latter directly is slightly faster.
368 RemoveObject(row,col);
372 TObject* objx=GetObject(row,col);
373 if (objx==obj) RemoveObject(row,col);
387 nrefs=GetIndices(obj,rows,cols);
391 if (row && !col) nrefs=GetIndices(obj,row,cols);
392 if (!row && col) nrefs=GetIndices(obj,rows,col);
394 // Remove the selected objects based on the obtained row and column indices
396 for (Int_t i=0; i<nrefs; i++)
399 if (!irow) irow=rows.At(i);
401 if (!icol) icol=cols.At(i);
402 RemoveObject(irow,icol);
405 ///////////////////////////////////////////////////////////////////////////
406 TObject* AliObjMatrix::GetObject(Int_t row,Int_t col) const
408 // Provide a pointer to the object stored at the matrix location (row,col).
409 // In case no object was stored at the indicated location or the location
410 // would reside outside the matrix boundaries, a value 0 will be returned.
411 // Note : The first location in the matrix is indicated as (1,1).
415 if (!fRows || row<1 || col<1) return obj;
424 if (rowx <= fRows->GetSize()) mrow=(TObjArray*)fRows->At(rowx-1);
426 if (!mrow) return obj;
428 if (colx <= mrow->GetSize()) obj=(TObject*)mrow->At(colx-1);
432 ///////////////////////////////////////////////////////////////////////////
433 TObject* AliObjMatrix::GetObject(Int_t j) const
435 // Provide a pointer to the j-th stored object.
436 // In case the index j is invalid, a value 0 will be returned.
437 // The first stored object is indicated as j=1.
439 // Note : Do NOT delete the object.
440 // To remove an object, the memberfunction RemoveObject() or
441 // RemoveObjects() should be used.
445 if (fObjects) nobj=fObjects->GetSize();
447 if (j>0 && j<=nobj) obj=(TObject*)fObjects->At(j-1);
451 ///////////////////////////////////////////////////////////////////////////
452 TObjArray* AliObjMatrix::GetObjects()
454 // Provide references to all the stored objects.
455 // In case no objects are present, a value 0 will be returned.
457 // Note : Do NOT make any changes to the reference array apart from
458 // changing the order of the pointers of the various objects.
459 // For addition or removal of objects, the memberfunctions
460 // EnterObject(), RemoveObject() or RemoveObjects() should be used.
464 ///////////////////////////////////////////////////////////////////////////
465 Int_t AliObjMatrix::GetMaxRow() const
467 // Provide the maximum row number index.
470 ///////////////////////////////////////////////////////////////////////////
471 Int_t AliObjMatrix::GetMaxColumn() const
473 // Provide the maximum column number index.
476 ///////////////////////////////////////////////////////////////////////////
477 Int_t AliObjMatrix::GetNobjects() const
479 // Provide the number of stored objects.
481 if (fObjects) nobj=fObjects->GetEntries();
485 ///////////////////////////////////////////////////////////////////////////
486 Int_t AliObjMatrix::GetNrefs(TObject* obj) const
488 // Provide the number of stored references to the specified object.
489 // If obj=0 the total number of stored references for all objects is returned.
490 Int_t nobjs=GetNobjects();
492 if (!obj) return nobjs;
495 for (Int_t i=1; i<=nobjs; i++)
497 TObject* objx=GetObject(i);
498 if (objx==obj) nrefs++;
502 ///////////////////////////////////////////////////////////////////////////
503 Int_t AliObjMatrix::GetIndices(TObject* obj,TArrayI& rows,TArrayI& cols) const
505 // Provide the (row,col) indices of all the storage locations of the
507 // The row and column indices are returned in the two separate TArrayI arrays
508 // from which the (row,col) pairs can be obtained from the corresponding
509 // array indices like (row,col)=(rows.At(j),cols.At(j)).
510 // The integer return argument represents the number of (row,col) pairs which
511 // were encountered for the specified object.
513 // If obj=0 no object selection is performed and all (row,col) indices
514 // of the stored references for all objects are returned.
518 // As usual the convention is that row and column numbering starts at 1.
520 // This memberfunction always resets the two TArrayI arrays at the start.
522 // This memberfunction can only be used to obtain the (row,col) indices
523 // of the object as stored via the EnterObject() memberfunction.
524 // This means that in case the user has entered a TObjArray as object
525 // (to increase the dimension of the resulting structure), the (row,col)
526 // indices of that TObjArray are obtained and NOT the indices of the
527 // actual objects contained in that TObjArray structure.
529 Int_t nrefs=GetNrefs(obj);
534 if (!nrefs) return 0;
538 for (Int_t i=0; i<fRows->GetSize(); i++)
540 TObjArray* columns=(TObjArray*)fRows->At(i);
541 if (!columns) continue;
543 for (Int_t j=0; j<columns->GetSize(); j++)
545 TObject* objx=(TObject*)columns->At(j);
546 if (objx && (objx==obj || !obj))
552 rows.AddAt(irow,jref);
553 cols.AddAt(icol,jref);
556 // All references found ==> Done
557 if (jref==nrefs) break;
559 // All references found ==> Done
560 if (jref==nrefs) break;
564 ///////////////////////////////////////////////////////////////////////////
565 Int_t AliObjMatrix::GetIndices(TObject* obj,Int_t row,TArrayI& cols) const
567 // Provide the column indices of all the storage locations of the
568 // specified object in the specified row of the matrix.
569 // The column indices are returned in the TArrayI array.
570 // The integer return argument represents the number of storage locations which
571 // were encountered for the specified object in the specified matrix row.
573 // If obj=0 no object selection is performed and all column indices
574 // of the stored references for all objects in this specified matrix row
577 // If row=0 all rows will be scanned and all column indices matching the
578 // object selection are returned.
579 // Note that in this case multiple appearances of the same column index
580 // will only be recorded once in the returned TArrayI array.
584 // As usual the convention is that row and column numbering starts at 1.
586 // This memberfunction always resets the TArrayI array at the start.
588 // This memberfunction can only be used to obtain the column indices
589 // of the object as stored via the EnterObject() memberfunction.
590 // This means that in case the user has entered a TObjArray as object
591 // (to increase the dimension of the resulting structure), the column
592 // indices of that TObjArray are obtained and NOT the indices of the
593 // actual objects contained in that TObjArray structure.
597 if (row<0 || row>GetMaxRow()) return 0;
599 Int_t nrefs=GetNrefs(obj);
601 if (!nrefs) return 0;
606 // No specific row selection
611 Int_t n=GetIndices(obj,ar,ac);
613 for (Int_t idx=0; idx<n; idx++)
617 for (Int_t k=0; k<jref; k++)
619 if (icol==cols.At(k)) found=1;
623 cols.AddAt(icol,jref);
627 // Set the array size to the actual number of different column indices
633 // Specific row selection
634 for (Int_t i=0; i<fRows->GetSize(); i++)
636 TObjArray* columns=(TObjArray*)fRows->At(i);
637 if (!columns) continue;
639 for (Int_t j=0; j<columns->GetSize(); j++)
641 TObject* objx=(TObject*)columns->At(j);
642 if (objx && (objx==obj || !obj))
650 cols.AddAt(icol,jref);
654 // All references found ==> Done
655 if (jref==nrefs) break;
657 // All references found ==> Done
658 if (jref==nrefs) break;
660 // Set the array size to the actual number of found occurrences
665 ///////////////////////////////////////////////////////////////////////////
666 Int_t AliObjMatrix::GetIndices(TObject* obj,TArrayI& rows,Int_t col) const
668 // Provide the row indices of all the storage locations of the
669 // specified object in the specified column of the matrix.
670 // The row indices are returned in the TArrayI array.
671 // The integer return argument represents the number of storage locations which
672 // were encountered for the specified object in the specified matrix column.
674 // If obj=0 no object selection is performed and all row indices
675 // of the stored references for all objects in this specified matrix column
678 // If col=0 all columns will be scanned and all row indices matching the
679 // object selection are returned.
680 // Note that in this case multiple appearances of the same row index
681 // will only be recorded once in the returned TArrayI array.
685 // As usual the convention is that row and column numbering starts at 1.
687 // This memberfunction always resets the TArrayI array at the start.
689 // This memberfunction can only be used to obtain the row indices
690 // of the object as stored via the EnterObject() memberfunction.
691 // This means that in case the user has entered a TObjArray as object
692 // (to increase the dimension of the resulting structure), the row
693 // indices of that TObjArray are obtained and NOT the indices of the
694 // actual objects contained in that TObjArray structure.
698 if (col<0 || col>GetMaxColumn()) return 0;
700 Int_t nrefs=GetNrefs(obj);
702 if (!nrefs) return 0;
707 // No specific column selection
712 Int_t n=GetIndices(obj,ar,ac);
714 for (Int_t idx=0; idx<n; idx++)
718 for (Int_t k=0; k<jref; k++)
720 if (irow==rows.At(k)) found=1;
724 rows.AddAt(irow,jref);
728 // Set the array size to the actual number of different row indices
734 // Specific column selection
735 for (Int_t i=0; i<fRows->GetSize(); i++)
737 TObjArray* columns=(TObjArray*)fRows->At(i);
738 if (!columns) continue;
740 for (Int_t j=0; j<columns->GetSize(); j++)
742 TObject* objx=(TObject*)columns->At(j);
743 if (objx && (objx==obj || !obj))
751 rows.AddAt(irow,jref);
755 // All references found ==> Done
756 if (jref==nrefs) break;
758 // All references found ==> Done
759 if (jref==nrefs) break;
761 // Set the array size to the actual number of found occurrences
766 ///////////////////////////////////////////////////////////////////////////
767 TObject* AliObjMatrix::Clone(const char* name) const
769 // Make a deep copy of the current object and provide the pointer to the copy.
770 // This memberfunction enables automatic creation of new objects of the
771 // correct type depending on the object type, a feature which may be very useful
772 // for containers when adding objects in case the container owns the objects.
774 AliObjMatrix* m=new AliObjMatrix(*this);
777 if (strlen(name)) m->SetName(name);
781 ///////////////////////////////////////////////////////////////////////////