21-jun-2005 NvE Install scripts for gcc corrected to also include the rdmc stuff
[u/mrichter/AliRoot.git] / RALICE / AliObjMatrix.cxx
CommitLineData
84bb7c66 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
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 **************************************************************************/
15
16// $Id$
17
18///////////////////////////////////////////////////////////////////////////
19// Class AliObjMatrix
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.
24//
25// Example :
26// =========
27//
28// AliObjMatrix* matrix=new AliObjMatrix();
29// matrix->SetOwner();
30// matrix->SetSwapMode();
31//
32// Float_t pos[3];
33//
34// AliSignal* s=0;
35//
36// s=new AliSignal();
37// s->SetSignal(135);
38// pos[0]=-120.4
39// pos[1]=78.25
40// pos[3]=12.93
41// s->SetPosition(pos,"car");
c72198f1 42// matrix->EnterObject(6,21,s);
84bb7c66 43//
44// s=new AliSignal();
45// s->SetSignal(25.84);
46// pos[0]=68.7
47// pos[1]=-53.88
48// pos[3]=22.69
49// s->SetPosition(pos,"car");
c72198f1 50// matrix->EnterObject(8,13,s);
84bb7c66 51//
52// s=new AliSignal();
53// s->SetSignal(87.25);
54// pos[0]=154.8
55// pos[1]=932.576
56// pos[3]=-1382.754
57// s->SetPosition(pos,"car");
c72198f1 58// matrix->EnterObject(64,3,s);
84bb7c66 59//
60// Int_t nrows=matrix->GetMaxRow();
61// Int_t ncols=matrix->GetMaxColumn();
62//
63// cout << " Maxrow : " << nrows << " Maxcol : " << ncols
64// << " Nobjects : " << matrix->GetNobjects() << endl;
65//
66// for (Int_t i=1; i<=nrows; i++)
67// {
68// for (Int_t j=1; j<=ncols; j++)
69// {
70// s=(AliSignal*)matrix->GetObject(i,j);
71// if (s) cout << " At (" << i << "," << j << ") Signal : " << s->GetSignal() << endl;
72// }
73// }
74//
75//--- Author: Nick van Eijndhoven 23-jan-2003 Utrecht University
76//- Modified: NvE $Date$ Utrecht University
77///////////////////////////////////////////////////////////////////////////
78
79#include "AliObjMatrix.h"
c72198f1 80#include "Riostream.h"
84bb7c66 81
82ClassImp(AliObjMatrix) // Class implementation to enable ROOT I/O
83
ea0b5b7f 84AliObjMatrix::AliObjMatrix() : TNamed()
84bb7c66 85{
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
89// details.
90 fRows=0;
91 fOwn=0;
92 fSwap=0;
93 fMaxrow=0;
94 fMaxcol=0;
c72198f1 95 fObjects=0;
84bb7c66 96}
97///////////////////////////////////////////////////////////////////////////
98AliObjMatrix::~AliObjMatrix()
99{
100// Default destructor.
101 if (fRows)
102 {
103 delete fRows;
104 fRows=0;
105 }
c72198f1 106 if (fObjects)
107 {
108 delete fObjects;
109 fObjects=0;
110 }
84bb7c66 111}
112///////////////////////////////////////////////////////////////////////////
113void AliObjMatrix::Reset()
114{
115// Reset the whole matrix structure.
116// Note : The values of the owner and swap mode flags will not be modified.
117// To modify the ownership, use the memberfunction SetOwner().
118// To modify the swap mode, use the memberfunction SetSwapMode().
119 if (fRows)
120 {
121 delete fRows;
122 fRows=0;
123 }
c72198f1 124 if (fObjects)
125 {
126 delete fObjects;
127 fObjects=0;
128 }
84bb7c66 129
130 fMaxrow=0;
131 fMaxcol=0;
84bb7c66 132}
133///////////////////////////////////////////////////////////////////////////
134void AliObjMatrix::SetOwner(Int_t own)
135{
136// Set the owner flag (0/1) for the stored objects.
137// When the owner flag is set to 1, all entered objects are owned by the
138// matrix structure.
139// At invokation of this memberfunction the default argument is own=1.
140//
141 fOwn=own;
142
143 if (!fRows) return;
144
145 for (Int_t irow=0; irow<fRows->GetSize(); irow++)
146 {
147 TObjArray* mrow=(TObjArray*)fRows->At(irow);
148 if (mrow)
149 {
150 if (own)
151 {
152 mrow->SetOwner(kTRUE);
153 }
154 else
155 {
156 mrow->SetOwner(kFALSE);
157 }
158 }
159 }
160}
161///////////////////////////////////////////////////////////////////////////
261c0caf 162Int_t AliObjMatrix::GetOwner() const
84bb7c66 163{
164// Provide the owner flag for the stored objects.
165 return fOwn;
166}
167///////////////////////////////////////////////////////////////////////////
168void AliObjMatrix::SetSwapMode(Int_t swap)
169{
170// Set the swap mode flag (0/1) for the internal matrix storage.
171// In case the number of rows differs considerably from the number of columns,
172// it might be more efficient (w.r.t. memory usage and/or output file size)
173// to internally store the matrix with the rows and colums swapped.
174// This swapping is only related with the internal storage and as such
175// is completely hidden for the user.
176// At invokation of this memberfunction the default argument is swap=1.
177//
178// Note : The swap mode can only be set as long as no objects have
179// been stored in the matrix structure (i.e. a new instance
180// of AliObjMatrix or after invokation of the Reset() function).
181//
182 if (!fRows)
183 {
184 fSwap=swap;
185 }
186 else
187 {
188 cout << " *AliObjMatrix::SetSwapMode* Matrix not empty ==> No action." << endl;
189 }
190}
191///////////////////////////////////////////////////////////////////////////
261c0caf 192Int_t AliObjMatrix::GetSwapMode() const
84bb7c66 193{
194// Provide the swap mode flag for this matrix.
195 return fSwap;
196}
197///////////////////////////////////////////////////////////////////////////
198void AliObjMatrix::EnterObject(Int_t row,Int_t col,TObject* obj)
199{
200// Enter an object to the matrix structure at location (row,col).
201// In case the location already contained an object, the existing object
202// will first be removed before the new object is stored.
c72198f1 203// According to the status of the owner flag (see the SetOwner() function)
84bb7c66 204// the existing object will also be deleted.
205// Note : The first location in the matrix is indicated as (1,1).
206 if (row<1 || col<1)
207 {
208 cout << " *AliObjMatrix::AddObject* Invalid argument(s) (row,col) : ("
209 << row << "," << col << ")" << endl;
210 return;
211 }
212
213 if (row>fMaxrow) fMaxrow=row;
214 if (col>fMaxcol) fMaxcol=col;
215
216 Int_t rowx=row;
217 if (fSwap) rowx=col;
218 Int_t colx=col;
219 if (fSwap) colx=row;
220
221 if (!fRows)
222 {
223 fRows=new TObjArray(rowx);
224 fRows->SetOwner();
225 }
226 else
227 {
228 if (rowx > fRows->GetSize()) fRows->Expand(rowx);
229 }
230
231 TObjArray* mrow=(TObjArray*)fRows->At(rowx-1);
232
233 if (!mrow)
234 {
235 TObjArray* columns=new TObjArray(colx);
236 if (fOwn) columns->SetOwner();
237 fRows->AddAt(columns,rowx-1);
238 mrow=columns;
239 }
240 else
241 {
242 if (colx > mrow->GetSize()) mrow->Expand(colx);
243 }
244
245 TObject* old=(TObject*)mrow->At(colx-1);
c72198f1 246 if (old)
247 {
248 fObjects->Remove(old);
249 fObjects->Compress();
250 if (fOwn) delete old;
251 }
84bb7c66 252
253 mrow->AddAt(obj,colx-1);
c72198f1 254
255 if (!fObjects) fObjects=new TObjArray();
256 fObjects->Add(obj);
257}
258///////////////////////////////////////////////////////////////////////////
259void AliObjMatrix::RemoveObject(Int_t row,Int_t col)
260{
261// Remove the object stored at the matrix location (row,col).
262// In case the object was owned by the matrix, it will be deleted.
263//
264// Note : The first location in the matrix is indicated as (1,1).
265
266 TObject* obj=0;
267
268 if (!fRows || row<1 || col<1) return;
269
270
271 Int_t rowx=row;
272 if (fSwap) rowx=col;
273 Int_t colx=col;
274 if (fSwap) colx=row;
275
276 TObjArray* mrow=0;
277 if (rowx <= fRows->GetSize()) mrow=(TObjArray*)fRows->At(rowx-1);
278
279 if (!mrow) return;
280
281 if (colx <= mrow->GetSize()) obj=(TObject*)mrow->At(colx-1);
282
283 if (obj)
284 {
285 fObjects->Remove(obj);
286 fObjects->Compress();
287 mrow->Remove(obj);
288 if (fOwn) delete obj;
289 }
84bb7c66 290}
291///////////////////////////////////////////////////////////////////////////
d0a8ef71 292void AliObjMatrix::RemoveObjects(TObject* obj,Int_t row,Int_t col)
e604d3a8 293{
d0a8ef71 294// Remove object(s) from the matrix according to user specified selections.
e604d3a8 295// In case the object was owned by the matrix, it will be deleted.
296//
297// An object is only removed from the matrix if the stored reference matches
298// the argument "obj".
299// In case obj=0 no check on the matching of the stored reference is performed
300// and the stored object is always removed in accordance with the other
301// selection criteria.
302//
303// In case the argument "row" is specified, only the object references from
304// that matrix row will be deleted.
305// In case row=0 (default) no checking on the row index is performed.
306//
307// In case the argument "col" is specified, only the object references from
308// that matrix column will be deleted.
309// In case col=0 (default) no checking on the column index is performed.
310//
d0a8ef71 311// So, invokation of RemoveObjects(obj) will remove all references to the
312// object "obj" from the total matrix, whereas RemoveObjects(obj,0,col)
e604d3a8 313// will remove all references to the object "obj" only from column "col".
314//
315// Notes :
316// -------
317// The first location in the matrix is indicated as (1,1).
318//
d0a8ef71 319// Invokation of RemoveObjects(0,row,col) is equivalent to invoking the
e604d3a8 320// memberfunction RemoveObject(row,col).
321// Invoking the latter directly is slightly faster.
322//
d0a8ef71 323// Invokation of RemoveObjects(0) is equivalent to invoking Reset().
e604d3a8 324// Invoking the latter directly is slightly faster.
325//
326 TArrayI rows;
327 TArrayI cols;
328 Int_t nrefs=0;
329
330 if (row && col)
331 {
332 if (!obj)
333 {
334 RemoveObject(row,col);
335 }
336 else
337 {
338 TObject* objx=GetObject(row,col);
339 if (objx==obj) RemoveObject(row,col);
340 }
341 return;
342 }
343
344 if (!row && !col)
345 {
346 if (!obj)
347 {
348 Reset();
349 return;
350 }
351 else
352 {
353 nrefs=GetIndices(obj,rows,cols);
354 }
355 }
356
357 if (row && !col) nrefs=GetIndices(obj,row,cols);
358 if (!row && col) nrefs=GetIndices(obj,rows,col);
359
360 // Remove the selected objects based on the obtained row and column indices
361 Int_t irow,icol;
362 for (Int_t i=0; i<nrefs; i++)
363 {
364 irow=row;
365 if (!irow) irow=rows.At(i);
366 icol=col;
367 if (!icol) icol=cols.At(i);
368 RemoveObject(irow,icol);
369 }
370}
371///////////////////////////////////////////////////////////////////////////
261c0caf 372TObject* AliObjMatrix::GetObject(Int_t row,Int_t col) const
84bb7c66 373{
374// Provide a pointer to the object stored at the matrix location (row,col).
375// In case no object was stored at the indicated location or the location
376// would reside outside the matrix boundaries, a value 0 will be returned.
377// Note : The first location in the matrix is indicated as (1,1).
378
379 TObject* obj=0;
380
381 if (!fRows || row<1 || col<1) return obj;
382
383
384 Int_t rowx=row;
385 if (fSwap) rowx=col;
386 Int_t colx=col;
387 if (fSwap) colx=row;
388
389 TObjArray* mrow=0;
390 if (rowx <= fRows->GetSize()) mrow=(TObjArray*)fRows->At(rowx-1);
391
392 if (!mrow) return obj;
393
394 if (colx <= mrow->GetSize()) obj=(TObject*)mrow->At(colx-1);
395
396 return obj;
397}
398///////////////////////////////////////////////////////////////////////////
261c0caf 399TObject* AliObjMatrix::GetObject(Int_t j) const
c72198f1 400{
401// Provide a pointer to the j-th stored object.
402// In case the index j is invalid, a value 0 will be returned.
403// The first stored object is indicated as j=1.
404//
405// Note : Do NOT delete the object.
d0a8ef71 406// To remove an object, the memberfunction RemoveObject() or
407// RemoveObjects() should be used.
c72198f1 408
409 TObject* obj=0;
410 Int_t nobj=0;
411 if (fObjects) nobj=fObjects->GetSize();
412
413 if (j>0 && j<=nobj) obj=(TObject*)fObjects->At(j-1);
414
415 return obj;
416}
417///////////////////////////////////////////////////////////////////////////
418TObjArray* AliObjMatrix::GetObjects()
419{
420// Provide references to all the stored objects.
421// In case no objects are present, a value 0 will be returned.
422//
423// Note : Do NOT make any changes to the reference array apart from
424// changing the order of the pointers of the various objects.
425// For addition or removal of objects, the memberfunctions
d0a8ef71 426// EnterObject(), RemoveObject() or RemoveObjects() should be used.
c72198f1 427
428 return fObjects;
429}
430///////////////////////////////////////////////////////////////////////////
261c0caf 431Int_t AliObjMatrix::GetMaxRow() const
84bb7c66 432{
433// Provide the maximum row number index.
434 return fMaxrow;
435}
436///////////////////////////////////////////////////////////////////////////
261c0caf 437Int_t AliObjMatrix::GetMaxColumn() const
84bb7c66 438{
439// Provide the maximum column number index.
440 return fMaxcol;
441}
442///////////////////////////////////////////////////////////////////////////
261c0caf 443Int_t AliObjMatrix::GetNobjects() const
84bb7c66 444{
445// Provide the number of stored objects.
c72198f1 446 Int_t nobj=0;
447 if (fObjects) nobj=fObjects->GetEntries();
448
449 return nobj;
84bb7c66 450}
451///////////////////////////////////////////////////////////////////////////
261c0caf 452Int_t AliObjMatrix::GetNrefs(TObject* obj) const
e604d3a8 453{
454// Provide the number of stored references to the specified object.
455// If obj=0 the total number of stored references for all objects is returned.
456 Int_t nobjs=GetNobjects();
457
458 if (!obj) return nobjs;
459
460 Int_t nrefs=0;
461 for (Int_t i=1; i<=nobjs; i++)
462 {
463 TObject* objx=GetObject(i);
464 if (objx==obj) nrefs++;
465 }
466 return nrefs;
467}
468///////////////////////////////////////////////////////////////////////////
261c0caf 469Int_t AliObjMatrix::GetIndices(TObject* obj,TArrayI& rows,TArrayI& cols) const
e604d3a8 470{
471// Provide the (row,col) indices of all the storage locations of the
472// specified object.
473// The row and column indices are returned in the two separate TArrayI arrays
474// from which the (row,col) pairs can be obtained from the corresponding
475// array indices like (row,col)=(rows.At(j),cols.At(j)).
476// The integer return argument represents the number of (row,col) pairs which
477// were encountered for the specified object.
478//
479// If obj=0 no object selection is performed and all (row,col) indices
480// of the stored references for all objects are returned.
481//
482// Notes :
483// -------
484// As usual the convention is that row and column numbering starts at 1.
485//
486// This memberfunction always resets the two TArrayI arrays at the start.
487//
488// This memberfunction can only be used to obtain the (row,col) indices
489// of the object as stored via the EnterObject() memberfunction.
490// This means that in case the user has entered a TObjArray as object
491// (to increase the dimension of the resulting structure), the (row,col)
492// indices of that TObjArray are obtained and NOT the indices of the
493// actual objects contained in that TObjArray structure.
494//
495 Int_t nrefs=GetNrefs(obj);
496 rows.Reset();
497 cols.Reset();
498 rows.Set(nrefs);
499 cols.Set(nrefs);
500 if (!nrefs) return 0;
501
502 Int_t irow,icol;
503 Int_t jref=0;
504 for (Int_t i=0; i<fRows->GetSize(); i++)
505 {
506 TObjArray* columns=(TObjArray*)fRows->At(i);
507 if (!columns) continue;
508
509 for (Int_t j=0; j<columns->GetSize(); j++)
510 {
511 TObject* objx=(TObject*)columns->At(j);
512 if (objx && (objx==obj || !obj))
513 {
514 irow=i+1;
515 if (fSwap) irow=j+1;
516 icol=j+1;
517 if (fSwap) icol=i+1;
518 rows.AddAt(irow,jref);
519 cols.AddAt(icol,jref);
520 jref++;
521 }
522 // All references found ==> Done
523 if (jref==nrefs) break;
524 }
525 // All references found ==> Done
526 if (jref==nrefs) break;
527 }
528 return nrefs;
529}
530///////////////////////////////////////////////////////////////////////////
261c0caf 531Int_t AliObjMatrix::GetIndices(TObject* obj,Int_t row,TArrayI& cols) const
e604d3a8 532{
533// Provide the column indices of all the storage locations of the
534// specified object in the specified row of the matrix.
535// The column indices are returned in the TArrayI array.
536// The integer return argument represents the number of storage locations which
537// were encountered for the specified object in the specified matrix row.
538//
539// If obj=0 no object selection is performed and all column indices
d0a8ef71 540// of the stored references for all objects in this specified matrix row
541// are returned.
542//
543// If row=0 all rows will be scanned and all column indices matching the
544// object selection are returned.
545// Note that in this case multiple appearances of the same column index
546// will only be recorded once in the returned TArrayI array.
e604d3a8 547//
548// Notes :
549// -------
550// As usual the convention is that row and column numbering starts at 1.
551//
552// This memberfunction always resets the TArrayI array at the start.
553//
554// This memberfunction can only be used to obtain the column indices
555// of the object as stored via the EnterObject() memberfunction.
556// This means that in case the user has entered a TObjArray as object
557// (to increase the dimension of the resulting structure), the column
558// indices of that TObjArray are obtained and NOT the indices of the
559// actual objects contained in that TObjArray structure.
560//
d0a8ef71 561 cols.Reset();
562
563 if (row<0 || row>GetMaxRow()) return 0;
e604d3a8 564
565 Int_t nrefs=GetNrefs(obj);
e604d3a8 566 cols.Set(nrefs);
567 if (!nrefs) return 0;
568
569 Int_t irow,icol;
570 Int_t jref=0;
d0a8ef71 571
572 // No specific row selection
573 if (!row)
574 {
575 TArrayI ar;
576 TArrayI ac;
577 Int_t n=GetIndices(obj,ar,ac);
578 Int_t found=0;
579 for (Int_t idx=0; idx<n; idx++)
580 {
581 icol=ac.At(idx);
582 found=0;
583 for (Int_t k=0; k<jref; k++)
584 {
585 if (icol==cols.At(k)) found=1;
586 }
587 if (!found)
588 {
589 cols.AddAt(icol,jref);
590 jref++;
591 }
592 }
593 // Set the array size to the actual number of different column indices
594 cols.Set(jref);
595
596 return jref;
597 }
598
599 // Specific row selection
e604d3a8 600 for (Int_t i=0; i<fRows->GetSize(); i++)
601 {
602 TObjArray* columns=(TObjArray*)fRows->At(i);
603 if (!columns) continue;
604
605 for (Int_t j=0; j<columns->GetSize(); j++)
606 {
607 TObject* objx=(TObject*)columns->At(j);
608 if (objx && (objx==obj || !obj))
609 {
610 irow=i+1;
611 if (fSwap) irow=j+1;
612 icol=j+1;
613 if (fSwap) icol=i+1;
614 if (irow==row)
615 {
616 cols.AddAt(icol,jref);
617 jref++;
618 }
619 }
620 // All references found ==> Done
621 if (jref==nrefs) break;
622 }
623 // All references found ==> Done
624 if (jref==nrefs) break;
625 }
626 // Set the array size to the actual number of found occurrences
627 cols.Set(jref);
628
629 return jref;
630}
631///////////////////////////////////////////////////////////////////////////
261c0caf 632Int_t AliObjMatrix::GetIndices(TObject* obj,TArrayI& rows,Int_t col) const
e604d3a8 633{
634// Provide the row indices of all the storage locations of the
635// specified object in the specified column of the matrix.
636// The row indices are returned in the TArrayI array.
637// The integer return argument represents the number of storage locations which
638// were encountered for the specified object in the specified matrix column.
639//
640// If obj=0 no object selection is performed and all row indices
d0a8ef71 641// of the stored references for all objects in this specified matrix column
642// are returned.
643//
644// If col=0 all columns will be scanned and all row indices matching the
645// object selection are returned.
646// Note that in this case multiple appearances of the same row index
647// will only be recorded once in the returned TArrayI array.
e604d3a8 648//
649// Notes :
650// -------
651// As usual the convention is that row and column numbering starts at 1.
652//
653// This memberfunction always resets the TArrayI array at the start.
654//
655// This memberfunction can only be used to obtain the row indices
656// of the object as stored via the EnterObject() memberfunction.
657// This means that in case the user has entered a TObjArray as object
658// (to increase the dimension of the resulting structure), the row
659// indices of that TObjArray are obtained and NOT the indices of the
660// actual objects contained in that TObjArray structure.
661//
d0a8ef71 662 rows.Reset();
663
664 if (col<0 || col>GetMaxColumn()) return 0;
e604d3a8 665
666 Int_t nrefs=GetNrefs(obj);
e604d3a8 667 rows.Set(nrefs);
668 if (!nrefs) return 0;
669
670 Int_t irow,icol;
671 Int_t jref=0;
d0a8ef71 672
673 // No specific column selection
674 if (!col)
675 {
676 TArrayI ar;
677 TArrayI ac;
678 Int_t n=GetIndices(obj,ar,ac);
679 Int_t found=0;
680 for (Int_t idx=0; idx<n; idx++)
681 {
682 irow=ar.At(idx);
683 found=0;
684 for (Int_t k=0; k<jref; k++)
685 {
686 if (irow==rows.At(k)) found=1;
687 }
688 if (!found)
689 {
690 rows.AddAt(irow,jref);
691 jref++;
692 }
693 }
694 // Set the array size to the actual number of different row indices
695 rows.Set(jref);
696
697 return jref;
698 }
699
700 // Specific column selection
e604d3a8 701 for (Int_t i=0; i<fRows->GetSize(); i++)
702 {
703 TObjArray* columns=(TObjArray*)fRows->At(i);
704 if (!columns) continue;
705
706 for (Int_t j=0; j<columns->GetSize(); j++)
707 {
708 TObject* objx=(TObject*)columns->At(j);
709 if (objx && (objx==obj || !obj))
710 {
711 irow=i+1;
712 if (fSwap) irow=j+1;
713 icol=j+1;
714 if (fSwap) icol=i+1;
715 if (icol==col)
716 {
717 rows.AddAt(irow,jref);
718 jref++;
719 }
720 }
721 // All references found ==> Done
722 if (jref==nrefs) break;
723 }
724 // All references found ==> Done
725 if (jref==nrefs) break;
726 }
727 // Set the array size to the actual number of found occurrences
728 rows.Set(jref);
729
730 return jref;
731}
732///////////////////////////////////////////////////////////////////////////