]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PMD/AliPMDClusteringV2.cxx
da documentation page is defined in the Link
[u/mrichter/AliRoot.git] / PMD / AliPMDClusteringV2.cxx
CommitLineData
8c7250c5 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
090026bf 16/* $Id$ */
17
8c7250c5 18//-----------------------------------------------------//
19// //
20// Source File : PMDClusteringV2.cxx //
21// //
22// clustering code for alice pmd //
23// //
24//-----------------------------------------------------//
25
26/* --------------------------------------------------------------------
27 Code developed by S. C. Phatak, Institute of Physics,
28 Bhubaneswar 751 005 ( phatak@iopb.res.in ) Given the energy deposited
29 ( or ADC value ) in each cell of supermodule ( pmd or cpv ), the code
30 builds up superclusters and breaks them into clusters. The input is
562718f9 31 in TObjarray and cluster information is in TObjArray.
32 integer clno gives total number of clusters in the supermodule.
33 fClusters is the global ( public ) variables.
8c7250c5 34 Others are local ( private ) to the code.
35 At the moment, the data is read for whole detector ( all supermodules
36 and pmd as well as cpv. This will have to be modify later )
37 LAST UPDATE : October 23, 2002
38-----------------------------------------------------------------------*/
39
090026bf 40#include <Riostream.h>
41#include <TMath.h>
8c7250c5 42#include <TObjArray.h>
562718f9 43#include <TArrayI.h>
8c7250c5 44
562718f9 45#include "AliPMDcludata.h"
8c7250c5 46#include "AliPMDcluster.h"
b6d6a9b5 47#include "AliPMDisocell.h"
8c7250c5 48#include "AliPMDClustering.h"
49#include "AliPMDClusteringV2.h"
50#include "AliLog.h"
51
52ClassImp(AliPMDClusteringV2)
53
54const Double_t AliPMDClusteringV2::fgkSqroot3by2=0.8660254; // sqrt(3.)/2.
55
56AliPMDClusteringV2::AliPMDClusteringV2():
562718f9 57 fPMDclucont(new TObjArray()),
8c7250c5 58 fCutoff(0.0)
59{
60 for(int i = 0; i < kNDIMX; i++)
61 {
62 for(int j = 0; j < kNDIMY; j++)
63 {
64 fCoord[0][i][j] = i+j/2.;
65 fCoord[1][i][j] = fgkSqroot3by2*j;
8c7250c5 66 }
67 }
68}
69// ------------------------------------------------------------------------ //
562718f9 70
71
72AliPMDClusteringV2::AliPMDClusteringV2(const AliPMDClusteringV2& pmdclv2):
73 AliPMDClustering(pmdclv2),
74 fPMDclucont(0),
75 fCutoff(0)
76{
77 // copy constructor
78 AliError("Copy constructor not allowed ");
79
80}
81// ------------------------------------------------------------------------ //
82AliPMDClusteringV2 &AliPMDClusteringV2::operator=(const AliPMDClusteringV2& /*pmdclv2*/)
83{
84 // copy constructor
85 AliError("Assignment operator not allowed ");
86 return *this;
87}
88// ------------------------------------------------------------------------ //
8c7250c5 89AliPMDClusteringV2::~AliPMDClusteringV2()
90{
562718f9 91 delete fPMDclucont;
8c7250c5 92}
93// ------------------------------------------------------------------------ //
562718f9 94
95void AliPMDClusteringV2::DoClust(Int_t idet, Int_t ismn,
920e13db 96 Int_t celltrack[48][96],
97 Int_t cellpid[48][96],
98 Double_t celladc[48][96],
99 TObjArray *pmdisocell, TObjArray *pmdcont)
8c7250c5 100{
101 // main function to call other necessary functions to do clustering
102 //
103 AliPMDcluster *pmdcl = 0;
104
2c1131dd 105 const Float_t ktwobysqrt3 = 1.1547; // 2./sqrt(3.)
106 const Int_t kNmaxCell = 19; // # of cells surrounding a cluster center
562718f9 107 Int_t i, j, nmx1, incr, id, jd;
108 Int_t ndimXr = 0;
109 Int_t ndimYr = 0;
2c1131dd 110 Int_t celldataX[kNmaxCell], celldataY[kNmaxCell];
920e13db 111 Int_t celldataTr[kNmaxCell], celldataPid[kNmaxCell];
b0e4d1e1 112 Float_t celldataAdc[kNmaxCell];
562718f9 113 Float_t clusdata[6];
8c7250c5 114 Double_t cutoff, ave;
562718f9 115 Double_t edepcell[kNMX];
8c7250c5 116
8c7250c5 117
b6d6a9b5 118 // call the isolated cell search method
119
d270ca46 120 FindIsoCell(idet, ismn, celladc, pmdisocell);
b6d6a9b5 121
122
123
8c7250c5 124 if (ismn < 12)
125 {
126 ndimXr = 96;
127 ndimYr = 48;
128 }
129 else if (ismn >= 12 && ismn <= 23)
130 {
131 ndimXr = 48;
132 ndimYr = 96;
133 }
562718f9 134
78fc1b96 135 for (i =0; i < kNMX; i++)
8c7250c5 136 {
562718f9 137 edepcell[i] = 0.;
8c7250c5 138 }
562718f9 139
8c7250c5 140 for (id = 0; id < ndimXr; id++)
141 {
142 for (jd = 0; jd < ndimYr; jd++)
143 {
562718f9 144 j = jd;
145 i = id + (ndimYr/2-1) - (jd/2);
146 Int_t ij = i + j*kNDIMX;
8c7250c5 147 if (ismn < 12)
148 {
562718f9 149 edepcell[ij] = celladc[jd][id];
8c7250c5 150 }
151 else if (ismn >= 12 && ismn <= 23)
152 {
562718f9 153 edepcell[ij] = celladc[id][jd];
8c7250c5 154 }
155
156 }
157 }
158
562718f9 159 Int_t iord1[kNMX];
df4e6759 160 TMath::Sort((Int_t)kNMX,edepcell,iord1);// order the data
8c7250c5 161 cutoff = fCutoff; // cutoff used to discard cells having ener. dep.
562718f9 162 ave = 0.;
163 nmx1 = -1;
8c7250c5 164
562718f9 165 for(i = 0;i < kNMX; i++)
8c7250c5 166 {
562718f9 167 if(edepcell[i] > 0.)
168 {
169 ave += edepcell[i];
170 }
171 if(edepcell[i] > cutoff )
172 {
173 nmx1++;
174 }
8c7250c5 175 }
562718f9 176
8c7250c5 177 AliDebug(1,Form("Number of cells having energy >= %f are %d",cutoff,nmx1));
562718f9 178
179 if (nmx1 == 0)
180 {
181 nmx1 = 1;
182 }
183 ave = ave/nmx1;
184
8c7250c5 185 AliDebug(1,Form("Number of cells in a SuperM = %d and Average = %f",
186 kNMX,ave));
8c7250c5 187
562718f9 188 incr = CrClust(ave, cutoff, nmx1,iord1, edepcell);
189 RefClust(incr,edepcell );
190
191 Int_t nentries1 = fPMDclucont->GetEntries();
192 AliDebug(1,Form("Detector Plane = %d Serial Module No = %d Number of clusters = %d",idet, ismn, nentries1));
193 AliDebug(1,Form("Total number of clusters/module = %d",nentries1));
194 for (Int_t ient1 = 0; ient1 < nentries1; ient1++)
8c7250c5 195 {
562718f9 196 AliPMDcludata *pmdcludata =
197 (AliPMDcludata*)fPMDclucont->UncheckedAt(ient1);
198 Float_t cluXC = pmdcludata->GetClusX();
199 Float_t cluYC = pmdcludata->GetClusY();
200 Float_t cluADC = pmdcludata->GetClusADC();
201 Float_t cluCELLS = pmdcludata->GetClusCells();
202 Float_t cluSIGX = pmdcludata->GetClusSigmaX();
203 Float_t cluSIGY = pmdcludata->GetClusSigmaY();
204
8c7250c5 205 Float_t cluY0 = ktwobysqrt3*cluYC;
206 Float_t cluX0 = cluXC - cluY0/2.;
562718f9 207
8c7250c5 208 //
209 // Cluster X centroid is back transformed
210 //
211 if (ismn < 12)
212 {
213 clusdata[0] = cluX0 - (24-1) + cluY0/2.;
214 }
562718f9 215 else if (ismn >= 12 && ismn <= 23)
8c7250c5 216 {
217 clusdata[0] = cluX0 - (48-1) + cluY0/2.;
218 }
219
562718f9 220 clusdata[1] = cluY0;
221 clusdata[2] = cluADC;
222 clusdata[3] = cluCELLS;
223 clusdata[4] = cluSIGX;
224 clusdata[5] = cluSIGY;
8c7250c5 225 //
226 // Cells associated with a cluster
227 //
2c1131dd 228 for (Int_t ihit = 0; ihit < kNmaxCell; ihit++)
8c7250c5 229 {
562718f9 230 Int_t dummyXY = pmdcludata->GetCellXY(ihit);
231
232 Int_t celldumY = dummyXY%10000;
233 Int_t celldumX = dummyXY/10000;
c1339151 234 Float_t cellY = (Float_t) celldumY/10;
235 Float_t cellX = (Float_t) celldumX/10;
236
562718f9 237 //
238 // Cell X centroid is back transformed
239 //
240 if (ismn < 12)
241 {
c1339151 242 celldataX[ihit] = (Int_t) ((cellX - (24-1) + cellY/2.) + 0.5);
562718f9 243 }
244 else if (ismn >= 12 && ismn <= 23)
245 {
c1339151 246 celldataX[ihit] = (Int_t) ((cellX - (48-1) + cellY/2.) + 0.5 );
562718f9 247 }
b0e4d1e1 248 celldataY[ihit] = (Int_t) (cellY + 0.5);
b6d6a9b5 249
250 Int_t irow = celldataX[ihit];
251 Int_t icol = celldataY[ihit];
252
253 if ((irow >= 0 && irow < 48) && (icol >= 0 && icol < 96))
254 {
255 celldataTr[ihit] = celltrack[irow][icol];
256 celldataPid[ihit] = cellpid[irow][icol];
257 celldataAdc[ihit] = (Float_t) celladc[irow][icol];
258 }
259 else
260 {
261 celldataTr[ihit] = -1;
262 celldataPid[ihit] = -1;
263 celldataAdc[ihit] = -1;
264 }
265
8c7250c5 266 }
267
920e13db 268 pmdcl = new AliPMDcluster(idet, ismn, clusdata, celldataX, celldataY,
b0e4d1e1 269 celldataTr, celldataPid, celldataAdc);
8c7250c5 270 pmdcont->Add(pmdcl);
271 }
2c1131dd 272 fPMDclucont->Delete();
8c7250c5 273}
274// ------------------------------------------------------------------------ //
562718f9 275Int_t AliPMDClusteringV2::CrClust(Double_t ave, Double_t cutoff, Int_t nmx1,
276 Int_t iord1[], Double_t edepcell[])
8c7250c5 277{
278 // Does crude clustering
279 // Finds out only the big patch by just searching the
280 // connected cells
281 //
282
562718f9 283 Int_t i,j,k,id1,id2,icl, numcell;
284 Int_t jd1,jd2, icell, cellcount;
285 Int_t clust[2][5000];
286 static Int_t neibx[6] = {1,0,-1,-1,0,1}, neiby[6] = {0,1,1,0,-1,-1};
8c7250c5 287
288 // neibx and neiby define ( incremental ) (i,j) for the neighbours of a
289 // cell. There are six neighbours.
290 // cellcount --- total number of cells having nonzero ener dep
291 // numcell --- number of cells in a given supercluster
562718f9 292
8c7250c5 293 AliDebug(1,Form("kNMX = %d nmx1 = %d kNDIMX = %d kNDIMY = %d ave = %f cutoff = %f",kNMX,nmx1,kNDIMX,kNDIMY,ave,cutoff));
294
562718f9 295 for (j=0; j < kNDIMX; j++)
296 {
297 for(k=0; k < kNDIMY; k++)
298 {
299 fInfocl[0][j][k] = 0;
300 fInfocl[1][j][k] = 0;
301 }
302 }
303
304 for(i=0; i < kNMX; i++)
305 {
306 fInfcl[0][i] = -1;
307
308 j = iord1[i];
309 id2 = j/kNDIMX;
310 id1 = j-id2*kNDIMX;
311
312 if(edepcell[j] <= cutoff)
313 {
314 fInfocl[0][id1][id2] = -1;
315 }
8c7250c5 316 }
8c7250c5 317 // ---------------------------------------------------------------
318 // crude clustering begins. Start with cell having largest adc
319 // count and loop over the cells in descending order of adc count
320 // ---------------------------------------------------------------
562718f9 321 icl = -1;
322 cellcount = -1;
323 for(icell=0; icell <= nmx1; icell++)
324 {
325 j = iord1[icell];
326 id2 = j/kNDIMX;
327 id1 = j-id2*kNDIMX;
328 if(fInfocl[0][id1][id2] == 0 )
329 {
330 // ---------------------------------------------------------------
331 // icl -- cluster #, numcell -- # of cells in it, clust -- stores
332 // coordinates of the cells in a cluster, fInfocl[0][i1][i2] is 1 for
333 // primary and 2 for secondary cells,
334 // fInfocl[1][i1][i2] stores cluster #
335 // ---------------------------------------------------------------
336 icl++;
337 numcell = 0;
338 cellcount++;
339 fInfocl[0][id1][id2] = 1;
340 fInfocl[1][id1][id2] = icl;
341 fInfcl[0][cellcount] = icl;
342 fInfcl[1][cellcount] = id1;
343 fInfcl[2][cellcount] = id2;
344
345 clust[0][numcell] = id1;
346 clust[1][numcell] = id2;
347 for(i = 1; i < 5000; i++)
348 {
349 clust[0][i] = -1;
350 }
351 // ---------------------------------------------------------------
352 // check for adc count in neib. cells. If ne 0 put it in this clust
353 // ---------------------------------------------------------------
354 for(i = 0; i < 6; i++)
355 {
356 jd1 = id1 + neibx[i];
357 jd2 = id2 + neiby[i];
8c7250c5 358 if( (jd1 >= 0 && jd1 < kNDIMX) && (jd2 >= 0 && jd2 < kNDIMY) &&
562718f9 359 fInfocl[0][jd1][jd2] == 0)
360 {
361 numcell++;
362 fInfocl[0][jd1][jd2] = 2;
363 fInfocl[1][jd1][jd2] = icl;
364 clust[0][numcell] = jd1;
365 clust[1][numcell] = jd2;
366 cellcount++;
367 fInfcl[0][cellcount] = icl;
368 fInfcl[1][cellcount] = jd1;
369 fInfcl[2][cellcount] = jd2;
370 }
371 }
372 // ---------------------------------------------------------------
373 // check adc count for neighbour's neighbours recursively and
374 // if nonzero, add these to the cluster.
375 // ---------------------------------------------------------------
376 for(i = 1;i < 5000; i++)
377 {
378 if(clust[0][i] != -1)
379 {
380 id1 = clust[0][i];
381 id2 = clust[1][i];
382 for(j = 0; j < 6 ; j++)
383 {
384 jd1 = id1 + neibx[j];
385 jd2 = id2 + neiby[j];
386 if( (jd1 >= 0 && jd1 < kNDIMX) &&
387 (jd2 >= 0 && jd2 < kNDIMY)
388 && fInfocl[0][jd1][jd2] == 0 )
389 {
390 fInfocl[0][jd1][jd2] = 2;
391 fInfocl[1][jd1][jd2] = icl;
392 numcell++;
393 clust[0][numcell] = jd1;
394 clust[1][numcell] = jd2;
395 cellcount++;
396 fInfcl[0][cellcount] = icl;
397 fInfcl[1][cellcount] = jd1;
398 fInfcl[2][cellcount] = jd2;
399 }
400 }
401 }
8c7250c5 402 }
8c7250c5 403 }
8c7250c5 404 }
8c7250c5 405 return cellcount;
406}
407// ------------------------------------------------------------------------ //
562718f9 408 void AliPMDClusteringV2::RefClust(Int_t incr, Double_t edepcell[])
8c7250c5 409{
410 // Does the refining of clusters
411 // Takes the big patch and does gaussian fitting and
412 // finds out the more refined clusters
8c7250c5 413
c1339151 414 const Float_t ktwobysqrt3 = 1.1547;
2c1131dd 415 const Int_t kNmaxCell = 19;
416
562718f9 417 AliPMDcludata *pmdcludata = 0;
c1339151 418
78fc1b96 419 Int_t i12;
562718f9 420 Int_t i, j, k, i1, i2, id, icl, itest, ihld;
421 Int_t ig, nsupcl, clno, clX,clY;
2c1131dd 422 Int_t clxy[kNmaxCell];
c1339151 423
562718f9 424 Float_t clusdata[6];
425 Double_t x1, y1, z1, x2, y2, z2, rr;
c1339151 426
427 Int_t kndim = incr + 1;
428
429 TArrayI testncl;
430 TArrayI testindex;
431
432 Int_t *ncl, *iord;
433
434 Double_t *x, *y, *z, *xc, *yc, *zc, *cells, *rcl, *rcs;
435
436 ncl = new Int_t [kndim];
437 iord = new Int_t [kndim];
438 x = new Double_t [kndim];
439 y = new Double_t [kndim];
440 z = new Double_t [kndim];
441 xc = new Double_t [kndim];
442 yc = new Double_t [kndim];
443 zc = new Double_t [kndim];
444 cells = new Double_t [kndim];
445 rcl = new Double_t [kndim];
446 rcs = new Double_t [kndim];
562718f9 447
448 for(Int_t kk = 0; kk < 15; kk++)
449 {
450 if( kk < 6 )clusdata[kk] = 0.;
451 }
452
8c7250c5 453 // nsupcl = # of superclusters; ncl[i]= # of cells in supercluster i
454 // x, y and z store (x,y) coordinates of and energy deposited in a cell
455 // xc, yc store (x,y) coordinates of the cluster center
562718f9 456 // zc stores the energy deposited in a cluster, rc is cluster radius
8c7250c5 457
562718f9 458 clno = -1;
8c7250c5 459 nsupcl = -1;
c1339151 460
461 for(i = 0; i < kndim; i++)
562718f9 462 {
463 ncl[i] = -1;
8c7250c5 464 }
c1339151 465 for(i = 0; i <= incr; i++)
562718f9 466 {
467 if(fInfcl[0][i] != nsupcl)
468 {
469 nsupcl++;
470 }
471 if (nsupcl > 4500)
472 {
473 AliWarning("RefClust: Too many superclusters!");
474 nsupcl = 4500;
475 break;
476 }
477 ncl[nsupcl]++;
478 }
479
8c7250c5 480 AliDebug(1,Form("Number of cells = %d Number of Superclusters = %d",
481 incr+1,nsupcl+1));
562718f9 482
483 id = -1;
484 icl = -1;
c1339151 485 for(i = 0; i <= nsupcl; i++)
562718f9 486 {
487 if(ncl[i] == 0)
8c7250c5 488 {
562718f9 489 id++;
490 icl++;
491 // one cell super-clusters --> single cluster
492 // cluster center at the centyer of the cell
493 // cluster radius = half cell dimension
494 if (clno >= 5000)
8c7250c5 495 {
562718f9 496 AliWarning("RefClust: Too many clusters! more than 5000");
497 return;
8c7250c5 498 }
562718f9 499 clno++;
500 i1 = fInfcl[1][id];
501 i2 = fInfcl[2][id];
78fc1b96 502 i12 = i1 + i2*kNDIMX;
562718f9 503 clusdata[0] = fCoord[0][i1][i2];
504 clusdata[1] = fCoord[1][i1][i2];
505 clusdata[2] = edepcell[i12];
506 clusdata[3] = 1.;
507 clusdata[4] = 0.0;
508 clusdata[5] = 0.0;
509
510 //cell information
c1339151 511
512 clY = (Int_t)((ktwobysqrt3*fCoord[1][i1][i2])*10);
513 clX = (Int_t)((fCoord[0][i1][i2] - clY/20.)*10);
514 clxy[0] = clX*10000 + clY ;
515
2c1131dd 516 for(Int_t icltr = 1; icltr < kNmaxCell; icltr++)
562718f9 517 {
518 clxy[icltr] = -1;
519 }
520 pmdcludata = new AliPMDcludata(clusdata,clxy);
521 fPMDclucont->Add(pmdcludata);
522
523
8c7250c5 524 }
562718f9 525 else if(ncl[i] == 1)
8c7250c5 526 {
562718f9 527 // two cell super-cluster --> single cluster
528 // cluster center is at ener. dep.-weighted mean of two cells
529 // cluster radius == half cell dimension
530 id++;
531 icl++;
532 if (clno >= 5000)
8c7250c5 533 {
534 AliWarning("RefClust: Too many clusters! more than 5000");
535 return;
536 }
562718f9 537 clno++;
538 i1 = fInfcl[1][id];
539 i2 = fInfcl[2][id];
78fc1b96 540 i12 = i1 + i2*kNDIMX;
562718f9 541
542 x1 = fCoord[0][i1][i2];
543 y1 = fCoord[1][i1][i2];
544 z1 = edepcell[i12];
545
546 id++;
547 i1 = fInfcl[1][id];
548 i2 = fInfcl[2][id];
549 i12 = i1 + i2*kNDIMX;
550
551 x2 = fCoord[0][i1][i2];
552 y2 = fCoord[1][i1][i2];
553 z2 = edepcell[i12];
554
555 clusdata[0] = (x1*z1+x2*z2)/(z1+z2);
556 clusdata[1] = (y1*z1+y2*z2)/(z1+z2);
557 clusdata[2] = z1+z2;
558 clusdata[3] = 2.;
559 clusdata[4] = (TMath::Sqrt(z1*z2))/(z1+z2);
560 clusdata[5] = 0.0;
561
c1339151 562 clY = (Int_t)((ktwobysqrt3*y1)*10);
563 clX = (Int_t)((x1 - clY/20.)*10);
564 clxy[0] = clX*10000 + clY ;
565
c1339151 566 clY = (Int_t)((ktwobysqrt3*y2)*10);
567 clX = (Int_t)((x2 - clY/20.)*10);
568 clxy[1] = clX*10000 + clY ;
569
2c1131dd 570 for(Int_t icltr = 2; icltr < kNmaxCell; icltr++)
8c7250c5 571 {
562718f9 572 clxy[icltr] = -1;
8c7250c5 573 }
562718f9 574 pmdcludata = new AliPMDcludata(clusdata, clxy);
575 fPMDclucont->Add(pmdcludata);
8c7250c5 576 }
562718f9 577 else{
578 id++;
579 iord[0] = 0;
580 // super-cluster of more than two cells - broken up into smaller
581 // clusters gaussian centers computed. (peaks separated by > 1 cell)
582 // Begin from cell having largest energy deposited This is first
583 // cluster center
584 // *****************************************************************
585 // NOTE --- POSSIBLE MODIFICATION: ONE MAY NOT BREAKING SUPERCLUSTERS
586 // IF NO. OF CELLS IS NOT TOO LARGE ( SAY 5 OR 6 )
587 // SINCE WE EXPECT THE SUPERCLUSTER
588 // TO BE A SINGLE CLUSTER
589 //*******************************************************************
590
591 i1 = fInfcl[1][id];
592 i2 = fInfcl[2][id];
78fc1b96 593 i12 = i1 + i2*kNDIMX;
562718f9 594
595 x[0] = fCoord[0][i1][i2];
596 y[0] = fCoord[1][i1][i2];
597 z[0] = edepcell[i12];
598
599 iord[0] = 0;
600 for(j = 1; j <= ncl[i]; j++)
601 {
602
603 id++;
604 i1 = fInfcl[1][id];
605 i2 = fInfcl[2][id];
78fc1b96 606 i12 = i1 + i2*kNDIMX;
562718f9 607 iord[j] = j;
608 x[j] = fCoord[0][i1][i2];
609 y[j] = fCoord[1][i1][i2];
610 z[j] = edepcell[i12];
611 }
612
613 // arranging cells within supercluster in decreasing order
614 for(j = 1; j <= ncl[i];j++)
615 {
616 itest = 0;
617 ihld = iord[j];
618 for(i1 = 0; i1 < j; i1++)
619 {
620 if(itest == 0 && z[iord[i1]] < z[ihld])
621 {
622 itest = 1;
623 for(i2 = j-1;i2 >= i1;i2--)
624 {
625 iord[i2+1] = iord[i2];
626 }
627 iord[i1] = ihld;
628 }
629 }
630 }
631
632
633 // compute the number of clusters and their centers ( first
634 // guess )
635 // centers must be separated by cells having smaller ener. dep.
636 // neighbouring centers should be either strong or well-separated
637 ig = 0;
638 xc[ig] = x[iord[0]];
639 yc[ig] = y[iord[0]];
640 zc[ig] = z[iord[0]];
641 for(j = 1; j <= ncl[i]; j++)
642 {
643 itest = -1;
644 x1 = x[iord[j]];
645 y1 = y[iord[j]];
646 for(k = 0; k <= ig; k++)
647 {
648 x2 = xc[k];
649 y2 = yc[k];
650 rr = Distance(x1,y1,x2,y2);
651 //************************************************************
652 // finetuning cluster splitting
653 // the numbers zc/4 and zc/10 may need to be changed.
654 // Also one may need to add one more layer because our
655 // cells are smaller in absolute scale
656 //************************************************************
657
658
659 if( rr >= 1.1 && rr < 1.8 && z[iord[j]] > zc[k]/4.) itest++;
660 if( rr >= 1.8 && rr < 2.1 && z[iord[j]] > zc[k]/10.) itest++;
661 if( rr >= 2.1)itest++;
662 }
663
664 if(itest == ig)
665 {
666 ig++;
667 xc[ig] = x1;
668 yc[ig] = y1;
669 zc[ig] = z[iord[j]];
670 }
671 }
c1339151 672 ClustDetails(ncl[i], ig, x, y ,z, xc, yc, zc, rcl, rcs, cells,
673 testncl, testindex);
562718f9 674
675 Int_t pp = 0;
676 for(j = 0; j <= ig; j++)
677 {
678 clno++;
679 if (clno >= 5000)
680 {
681 AliWarning("RefClust: Too many clusters! more than 5000");
682 return;
683 }
684 clusdata[0] = xc[j];
685 clusdata[1] = yc[j];
686 clusdata[2] = zc[j];
687 clusdata[4] = rcl[j];
688 clusdata[5] = rcs[j];
689 if(ig == 0)
690 {
2c1131dd 691 clusdata[3] = ncl[i] + 1;
562718f9 692 }
693 else
694 {
695 clusdata[3] = cells[j];
696 }
697 // cell information
698 Int_t ncellcls = testncl[j];
2c1131dd 699 if( ncellcls < kNmaxCell )
562718f9 700 {
701 for(Int_t kk = 1; kk <= ncellcls; kk++)
702 {
703 Int_t ll = testindex[pp];
c1339151 704 clY = (Int_t)((ktwobysqrt3*y[ll])*10);
705 clX = (Int_t)((x[ll] - clY/20.)*10);
706 clxy[kk-1] = clX*10000 + clY ;
c1339151 707
562718f9 708 pp++;
709 }
2c1131dd 710 for(Int_t icltr = ncellcls ; icltr < kNmaxCell; icltr++)
562718f9 711 {
712 clxy[icltr] = -1;
713 }
714 }
715 pmdcludata = new AliPMDcludata(clusdata, clxy);
716 fPMDclucont->Add(pmdcludata);
717 }
718 testncl.Set(0);
719 testindex.Set(0);
720 }
8c7250c5 721 }
c1339151 722 delete [] ncl;
723 delete [] iord;
724 delete [] x;
725 delete [] y;
726 delete [] z;
727 delete [] xc;
728 delete [] yc;
729 delete [] zc;
730 delete [] cells;
731 delete [] rcl;
732 delete [] rcs;
8c7250c5 733}
8c7250c5 734// ------------------------------------------------------------------------ //
c1339151 735void AliPMDClusteringV2::ClustDetails(Int_t ncell, Int_t nclust, Double_t x[],
736 Double_t y[], Double_t z[],Double_t xc[],
737 Double_t yc[], Double_t zc[],
738 Double_t rcl[], Double_t rcs[],
739 Double_t cells[], TArrayI &testncl,
562718f9 740 TArrayI &testindex)
8c7250c5 741{
742 // function begins
743 //
8c7250c5 744
c1339151 745 Int_t kndim1 = ncell + 1;//ncell
746 Int_t kndim2 = 20;
747 Int_t kndim3 = nclust + 1;//nclust
78fc1b96 748
562718f9 749 Int_t i, j, k, i1, i2;
562718f9 750 Double_t x1, y1, x2, y2, rr, b, c, r1, r2;
751 Double_t sumx, sumy, sumxy, sumxx, sum, sum1, sumyy;
8c7250c5 752
c1339151 753 Double_t *str, *str1, *xcl, *ycl, *cln;
754 Int_t **cell;
755 Int_t ** cluster;
756 Double_t **clustcell;
757 str = new Double_t [kndim3];
758 str1 = new Double_t [kndim3];
759 xcl = new Double_t [kndim3];
760 ycl = new Double_t [kndim3];
761 cln = new Double_t [kndim3];
562718f9 762
c1339151 763 clustcell = new Double_t *[kndim3];
764 cell = new Int_t *[kndim3];
765 cluster = new Int_t *[kndim1];
562718f9 766 for(i = 0; i < kndim1; i++)
767 {
c1339151 768 cluster[i] = new Int_t [kndim2];
769 }
770
771 for(i = 0; i < kndim3; i++)
772 {
773 str[i] = 0;
774 str1[i] = 0;
775 xcl[i] = 0;
776 ycl[i] = 0;
777 cln[i] = 0;
778
779 cell[i] = new Int_t [kndim2];
780 clustcell[i] = new Double_t [kndim1];
781 for(j = 0; j < kndim1; j++)
8c7250c5 782 {
c1339151 783 clustcell[i][j] = 0;
562718f9 784 }
c1339151 785 for(j = 0; j < kndim2; j++)
562718f9 786 {
c1339151 787 cluster[i][j] = 0;
788 cell[i][j] = 0;
8c7250c5 789 }
562718f9 790 }
c1339151 791
562718f9 792 if(nclust > 0)
793 {
794 // more than one cluster
795 // checking cells shared between several clusters.
796 // First check if the cell is within
797 // one cell unit ( nearest neighbour). Else,
798 // if it is within 1.74 cell units ( next nearest )
799 // Else if it is upto 2 cell units etc.
800
801 for (i = 0; i <= ncell; i++)
8c7250c5 802 {
c1339151 803 x1 = x[i];
804 y1 = y[i];
562718f9 805 cluster[i][0] = 0;
2c1131dd 806
562718f9 807 // distance <= 1 cell unit
2c1131dd 808
562718f9 809 for(j = 0; j <= nclust; j++)
8c7250c5 810 {
c1339151 811 x2 = xc[j];
812 y2 = yc[j];
8c7250c5 813 rr = Distance(x1, y1, x2, y2);
562718f9 814 if(rr <= 1.)
8c7250c5 815 {
816 cluster[i][0]++;
817 i1 = cluster[i][0];
818 cluster[i][i1] = j;
819 }
820 }
562718f9 821 // next nearest neighbour
822 if(cluster[i][0] == 0)
823 {
824 for(j=0; j<=nclust; j++)
825 {
c1339151 826 x2 = xc[j];
827 y2 = yc[j];
562718f9 828 rr = Distance(x1, y1, x2, y2);
829 if(rr <= TMath::Sqrt(3.))
830 {
831 cluster[i][0]++;
832 i1 = cluster[i][0];
833 cluster[i][i1] = j;
834 }
835 }
836 }
837 // next-to-next nearest neighbour
838 if(cluster[i][0] == 0)
839 {
840 for(j=0; j<=nclust; j++)
841 {
c1339151 842 x2 = xc[j];
843 y2 = yc[j];
562718f9 844 rr = Distance(x1, y1, x2, y2);
845 if(rr <= 2.)
846 {
847 cluster[i][0]++;
848 i1 = cluster[i][0];
849 cluster[i][i1] = j;
850 }
851 }
852 }
853 // one more
854 if(cluster[i][0] == 0)
855 {
856 for(j = 0; j <= nclust; j++)
857 {
c1339151 858 x2 = xc[j];
859 y2 = yc[j];
562718f9 860 rr = Distance(x1, y1, x2, y2);
861 if(rr <= 2.7)
862 {
863 cluster[i][0]++;
864 i1 = cluster[i][0];
865 cluster[i][i1] = j;
866 }
867 }
868 }
8c7250c5 869 }
562718f9 870
871 // computing cluster strength. Some cells are shared.
872 for(i = 0; i <= ncell; i++)
8c7250c5 873 {
562718f9 874 if(cluster[i][0] != 0)
8c7250c5 875 {
562718f9 876 i1 = cluster[i][0];
877 for(j = 1; j <= i1; j++)
8c7250c5 878 {
562718f9 879 i2 = cluster[i][j];
c1339151 880 str[i2] += z[i]/i1;
8c7250c5 881 }
882 }
883 }
562718f9 884
885 for(k = 0; k < 5; k++)
8c7250c5 886 {
562718f9 887 for(i = 0; i <= ncell; i++)
8c7250c5 888 {
562718f9 889 if(cluster[i][0] != 0)
8c7250c5 890 {
562718f9 891 i1=cluster[i][0];
892 sum=0.;
893 for(j = 1; j <= i1; j++)
894 {
895 sum += str[cluster[i][j]];
896 }
897
898 for(j = 1; j <= i1; j++)
899 {
900 i2 = cluster[i][j];
c1339151 901 str1[i2] += z[i]*str[i2]/sum;
902 clustcell[i2][i] = z[i]*str[i2]/sum;
562718f9 903 }
8c7250c5 904 }
905 }
562718f9 906
907
908 for(j = 0; j <= nclust; j++)
909 {
910 str[j] = str1[j];
911 str1[j] = 0.;
912 }
8c7250c5 913 }
562718f9 914
915 for(i = 0; i <= nclust; i++)
916 {
917 sumx = 0.;
918 sumy = 0.;
919 sum = 0.;
920 sum1 = 0.;
921 for(j = 0; j <= ncell; j++)
922 {
923 if(clustcell[i][j] != 0)
924 {
c1339151 925 sumx += clustcell[i][j]*x[j];
926 sumy += clustcell[i][j]*y[j];
562718f9 927 sum += clustcell[i][j];
c1339151 928 sum1 += clustcell[i][j]/z[j];
562718f9 929 }
930 }
931 //** xcl and ycl are cluster centroid positions ( center of gravity )
932
933 xcl[i] = sumx/sum;
934 ycl[i] = sumy/sum;
935 cln[i] = sum1;
936 sumxx = 0.;
937 sumyy = 0.;
938 sumxy = 0.;
939 for(j = 0; j <= ncell; j++)
940 {
c1339151 941 sumxx += clustcell[i][j]*(x[j]-xcl[i])*(x[j]-xcl[i])/sum;
942 sumyy += clustcell[i][j]*(y[j]-ycl[i])*(y[j]-ycl[i])/sum;
943 sumxy += clustcell[i][j]*(x[j]-xcl[i])*(y[j]-ycl[i])/sum;
562718f9 944 }
945 b = sumxx+sumyy;
946 c = sumxx*sumyy-sumxy*sumxy;
947 // ******************r1 and r2 are major and minor axes ( r1 > r2 ).
948 r1 = b/2.+TMath::Sqrt(b*b/4.-c);
949 r2 = b/2.-TMath::Sqrt(b*b/4.-c);
950 // final assignments to proper external variables
c1339151 951 xc[i] = xcl[i];
952 yc[i] = ycl[i];
953 zc[i] = str[i];
954 cells[i] = cln[i];
955 rcl[i] = r1;
956 rcs[i] = r2;
957
8c7250c5 958 }
562718f9 959
960 //To get the cell position in a cluster
961
962 for(Int_t ii=0; ii<= ncell; ii++)
963 {
964 Int_t jj = cluster[ii][0];
965 for(Int_t kk=1; kk<= jj; kk++)
8c7250c5 966 {
562718f9 967 Int_t ll = cluster[ii][kk];
968 cell[ll][0]++;
969 cell[ll][cell[ll][0]] = ii;
8c7250c5 970 }
562718f9 971 }
972
973 testncl.Set(nclust+1);
974 Int_t counter = 0;
975
976 for(Int_t ii=0; ii <= nclust; ii++)
977 {
978 testncl[ii] = cell[ii][0];
979 counter += testncl[ii];
980 }
981 testindex.Set(counter);
982 Int_t ll = 0;
983 for(Int_t ii=0; ii<= nclust; ii++)
984 {
985 for(Int_t jj = 1; jj<= testncl[ii]; jj++)
986 {
987 Int_t kk = cell[ii][jj];
988 testindex[ll] = kk;
989 ll++;
990 }
991 }
992
993 }
c1339151 994 else if(nclust == 0)
562718f9 995 {
8c7250c5 996 sumx = 0.;
997 sumy = 0.;
998 sum = 0.;
999 sum1 = 0.;
562718f9 1000 i = 0;
1001 for(j = 0; j <= ncell; j++)
1002 {
c1339151 1003 sumx += z[j]*x[j];
1004 sumy += z[j]*y[j];
1005 sum += z[j];
562718f9 1006 sum1++;
8c7250c5 1007 }
8c7250c5 1008 xcl[i] = sumx/sum;
1009 ycl[i] = sumy/sum;
1010 cln[i] = sum1;
562718f9 1011 sumxx = 0.;
1012 sumyy = 0.;
1013 sumxy = 0.;
1014 for(j = 0; j <= ncell; j++)
1015 {
c1339151 1016 sumxx += clustcell[i][j]*(x[j]-xcl[i])*(x[j]-xcl[i])/sum;
1017 sumyy += clustcell[i][j]*(y[j]-ycl[i])*(y[j]-ycl[i])/sum;
1018 sumxy += clustcell[i][j]*(x[j]-xcl[i])*(y[j]-ycl[i])/sum;
562718f9 1019 }
1020 b = sumxx+sumyy;
1021 c = sumxx*sumyy-sumxy*sumxy;
1022 r1 = b/2.+ TMath::Sqrt(b*b/4.-c);
1023 r2 = b/2.- TMath::Sqrt(b*b/4.-c);
1024
1025 // To get the cell position in a cluster
1026 testncl.Set(nclust+1);
c1339151 1027 testindex.Set(ncell+1);
2c1131dd 1028 cell[0][0] = ncell + 1;
562718f9 1029 testncl[0] = cell[0][0];
1030 Int_t ll = 0;
c1339151 1031 for(Int_t ii = 1; ii <= ncell; ii++)
562718f9 1032 {
1033 cell[0][ii]=ii;
562718f9 1034 Int_t kk = cell[0][ii];
1035 testindex[ll] = kk;
1036 ll++;
1037 }
1038 // final assignments
c1339151 1039 xc[i] = xcl[i];
1040 yc[i] = ycl[i];
c1339151 1041 zc[i] = sum;
1042 cells[i] = cln[i];
1043 rcl[i] = r1;
1044 rcs[i] = r2;
1045 }
1046 for(i = 0; i < kndim3; i++)
1047 {
1048 delete [] clustcell[i];
1049 delete [] cell[i];
1050 }
1051 delete [] clustcell;
1052 delete [] cell;
1053 for(i = 0; i <kndim1 ; i++)
1054 {
1055 delete [] cluster[i];
8c7250c5 1056 }
c1339151 1057 delete [] cluster;
1058 delete [] str;
1059 delete [] str1;
1060 delete [] xcl;
1061 delete [] ycl;
1062 delete [] cln;
8c7250c5 1063}
1064
1065// ------------------------------------------------------------------------ //
1066Double_t AliPMDClusteringV2::Distance(Double_t x1, Double_t y1,
1067 Double_t x2, Double_t y2)
1068{
562718f9 1069 return TMath::Sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
b6d6a9b5 1070}
1071// ------------------------------------------------------------------------ //
d270ca46 1072void AliPMDClusteringV2::FindIsoCell(Int_t idet, Int_t ismn, Double_t celladc[][96], TObjArray *pmdisocell)
b6d6a9b5 1073{
1074 // Does isolated cell search for offline calibration
1075
1076 AliPMDisocell *isocell = 0;
1077
1078 const Int_t kMaxRow = 48;
1079 const Int_t kMaxCol = 96;
1080 const Int_t kCellNeighbour = 6;
1081
1082 Int_t id1, jd1;
1083
1084 Int_t neibx[6] = {1,0,-1,-1,0,1};
1085 Int_t neiby[6] = {0,1,1,0,-1,-1};
1086
1087
1088 for(Int_t irow = 0; irow < kMaxRow; irow++)
1089 {
1090 for(Int_t icol = 0; icol < kMaxCol; icol++)
1091 {
1092 if(celladc[irow][icol] > 0)
1093 {
1094 Int_t isocount = 0;
1095 for(Int_t ii = 0; ii < kCellNeighbour; ii++)
1096 {
1097 id1 = irow + neibx[ii];
1098 jd1 = icol + neiby[ii];
1099 Float_t adc = (Float_t) celladc[id1][jd1];
1100 if(adc == 0.)
1101 {
1102 isocount++;
1103 if(isocount == kCellNeighbour)
1104 {
1105 Float_t cadc = (Float_t) celladc[irow][icol];
1106
1107 isocell = new AliPMDisocell(idet,ismn,irow,icol,cadc);
1108 pmdisocell->Add(isocell);
1109
1110 }
1111 }
1112 } // neigh cell cond.
1113 }
1114 }
1115 }
1116
1117
8c7250c5 1118}
1119// ------------------------------------------------------------------------ //
1120void AliPMDClusteringV2::SetEdepCut(Float_t decut)
1121{
1122 fCutoff = decut;
1123}
1124// ------------------------------------------------------------------------ //