]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/ESD/AliMultiplicity.cxx
o change logic in TPC: don't do calculation only in case of kDetNoPid -> was before...
[u/mrichter/AliRoot.git] / STEER / ESD / AliMultiplicity.cxx
1 #include <string.h>
2 #include "AliMultiplicity.h"
3 #include "AliLog.h"
4 #include "AliRefArray.h"
5
6 ClassImp(AliMultiplicity)
7
8 //______________________________________________________________________
9 AliMultiplicity::AliMultiplicity():
10 AliVMultiplicity("AliMultiplicity",""),  // must be named like that to be searchable in ESDEvent
11   fNtracks(0),
12   fNsingle(0),
13   fNsingleSPD2(0),
14 //
15   fDPhiWindow2(0.08*0.08),  
16   fDThetaWindow2(0.025*0.025),
17   fDPhiShift(0.0045),
18   fNStdDev(1.0),
19 //
20   fLabels(0),
21   fLabelsL2(0),
22   fUsedClusS(0), 
23   fUsedClusT(0),
24   fTh(0),
25   fPhi(0),
26   fDeltTh(0),
27   fDeltPhi(0),
28   fThsingle(0),
29   fPhisingle(0),
30   fLabelssingle(0),
31   fFastOrFiredChips(1200),
32   fClusterFiredChips(1200)
33 {
34   // Default Constructor
35   fFiredChips[0] = 0;
36   fFiredChips[1] = 0;
37   for (int il=2;il--;) fSCl2Tracks[il] = fTCl2Tracks[il][0] = fTCl2Tracks[il][1] = 0;
38   for(Int_t ilayer = 0; ilayer < 6; ilayer++)fITSClusters[ilayer] = 0;
39 }
40
41 //______________________________________________________________________
42 AliMultiplicity::AliMultiplicity(Int_t ntr, Float_t *th,  Float_t *ph, Float_t *dth, Float_t *dph, Int_t *labels, Int_t* labelsL2, Int_t ns, Float_t *ts, Float_t *ps, Int_t *labelss, Short_t nfcL1, Short_t nfcL2, const TBits & fFastOr):
43   AliVMultiplicity("AliMultiplicity",""),
44   fNtracks(ntr),
45   fNsingle(ns),
46   fNsingleSPD2(0),
47   //
48   fDPhiWindow2(0.08*0.08),  
49   fDThetaWindow2(0.025*0.025),
50   fDPhiShift(0.0045),
51   fNStdDev(1.0),
52   //
53   fLabels(0),
54   fLabelsL2(0),
55   fUsedClusS(0),
56   fUsedClusT(0),
57   fTh(0),
58   fPhi(0),
59   fDeltTh(0),
60   fDeltPhi(0),
61   fThsingle(0),
62   fPhisingle(0),
63   fLabelssingle(0),
64   fFastOrFiredChips(1200),
65   fClusterFiredChips(1200)
66 {
67 // Standard constructor
68   for (int il=2;il--;) fSCl2Tracks[il] = fTCl2Tracks[il][0] = fTCl2Tracks[il][1] = 0;
69   if(ntr>0){
70     fLabels = new Int_t[ntr];
71     fLabelsL2 = new Int_t[ntr];
72     fTh = new Double_t [ntr];
73     fPhi = new Double_t [ntr];
74     fDeltTh = new Double_t [ntr];
75     fDeltPhi = new Double_t [ntr];
76     for(Int_t i=0;i<fNtracks;i++){
77       fTh[i]=th[i];
78       fPhi[i]=ph[i];
79       fDeltTh[i]=dth[i];
80       fDeltPhi[i]=dph[i];
81       fLabels[i] = labels[i];
82       fLabelsL2[i] = labelsL2[i];
83     }
84   }
85   if(ns>0){
86     fThsingle = new Double_t [ns];
87     fPhisingle = new Double_t [ns];
88     fLabelssingle = new Int_t [ns];
89     for(Int_t i=0;i<fNsingle;i++){
90       fThsingle[i]=ts[i];
91       fPhisingle[i]=ps[i];
92       fLabelssingle[i]=labelss[i];
93     }
94   }
95   fFiredChips[0] = nfcL1;
96   fFiredChips[1] = nfcL2;
97   fFastOrFiredChips = fFastOr;
98   for(Int_t ilayer = 0; ilayer < 6; ilayer++)fITSClusters[ilayer] = 0;
99 }
100
101 //______________________________________________________________________
102 AliMultiplicity::AliMultiplicity(Int_t ntr, Int_t ns, Short_t nfcL1, Short_t nfcL2, const TBits & fFastOr) :
103   AliVMultiplicity("AliMultiplicity",""),
104   fNtracks(ntr),
105   fNsingle(ns),
106   fNsingleSPD2(0),
107   //
108   fDPhiWindow2(0.08*0.08),  
109   fDThetaWindow2(0.025*0.025),
110   fDPhiShift(0.0045),
111   fNStdDev(1.0),
112   //
113   fLabels(0),
114   fLabelsL2(0),
115   fUsedClusS(0),
116   fUsedClusT(0),
117   fTh(0),
118   fPhi(0),
119   fDeltTh(0),
120   fDeltPhi(0),
121   fThsingle(0),
122   fPhisingle(0),
123   fLabelssingle(0),
124   fFastOrFiredChips(1200),
125   fClusterFiredChips(1200)
126 {
127   // Standard constructor to create the arrays w/o filling
128   for (int il=2;il--;) fSCl2Tracks[il] = fTCl2Tracks[il][0] = fTCl2Tracks[il][1] = 0;
129   if(ntr>0){
130     fLabels   = new Int_t[ntr];
131     fLabelsL2 = new Int_t[ntr];
132     fTh       = new Double_t [ntr];
133     fPhi      = new Double_t [ntr];
134     fDeltTh   = new Double_t [ntr];
135     fDeltPhi  = new Double_t [ntr];
136     for(Int_t i=fNtracks;i--;){
137       fTh[i]=fPhi[i]=fDeltTh[i]=fDeltPhi[i] = 0;
138       fLabels[i] = fLabelsL2[i] = 0;
139     }
140   }
141   if(ns>0){
142     fThsingle  = new Double_t [ns];
143     fPhisingle = new Double_t [ns];
144     fLabelssingle = new Int_t [ns];
145     for(Int_t i=fNsingle;i--;) fThsingle[i] = fPhisingle[i] = fLabelssingle[i] = 0;
146   }
147   fFiredChips[0] = nfcL1;
148   fFiredChips[1] = nfcL2;
149   fFastOrFiredChips = fFastOr;
150   for(Int_t ilayer=6;ilayer--;) fITSClusters[ilayer] = 0;
151 }
152
153 //______________________________________________________________________
154 AliMultiplicity::AliMultiplicity(const AliMultiplicity& m):
155   AliVMultiplicity(m),
156   fNtracks(m.fNtracks),
157   fNsingle(m.fNsingle),
158   fNsingleSPD2(m.fNsingleSPD2),
159   //
160   fDPhiWindow2(0.08*0.08),  
161   fDThetaWindow2(0.025*0.025),
162   fDPhiShift(0.0045),
163   fNStdDev(1.0),
164   //
165   fLabels(0),
166   fLabelsL2(0),
167   fUsedClusS(0),
168   fUsedClusT(0),
169   fTh(0),
170   fPhi(0),
171   fDeltTh(0),
172   fDeltPhi(0),
173   fThsingle(0),
174   fPhisingle(0),
175   fLabelssingle(0),
176   fFastOrFiredChips(1200),
177   fClusterFiredChips(1200)
178 {
179   // copy constructor
180   for (int il=2;il--;) fSCl2Tracks[il] = fTCl2Tracks[il][0] = fTCl2Tracks[il][1] = 0;
181   Duplicate(m);
182 }
183
184 //______________________________________________________________________
185 AliMultiplicity &AliMultiplicity::operator=(const AliMultiplicity& m){
186   // assignment operator
187   if(this == &m)return *this;
188   ((AliVMultiplicity*)this)->operator=(m);
189
190   if(fTh)delete [] fTh;fTh = 0;
191   if(fPhi)delete [] fPhi;fPhi = 0; 
192   if(fDeltTh)delete [] fDeltTh;fDeltTh= 0; 
193   if(fDeltPhi)delete [] fDeltPhi;fDeltPhi = 0; 
194   if(fLabels)delete [] fLabels;fLabels = 0;
195   if(fLabelsL2)delete [] fLabelsL2;fLabelsL2 = 0;
196   if(fThsingle)delete [] fThsingle;fThsingle = 0;
197   if(fPhisingle)delete [] fPhisingle;fPhisingle = 0;
198   if(fLabelssingle)delete [] fLabelssingle;fLabelssingle = 0;
199   if(fUsedClusS) delete[] fUsedClusS; fUsedClusS = 0;
200   if(fUsedClusT) delete[] fUsedClusT; fUsedClusT = 0;
201   for (int il=2;il--;) {
202     if (fSCl2Tracks[il])    delete fSCl2Tracks[il];    fSCl2Tracks[il]    = 0;
203     if (fTCl2Tracks[il][0]) delete fTCl2Tracks[il][0]; fTCl2Tracks[il][0] = 0;
204     if (fTCl2Tracks[il][1]) delete fTCl2Tracks[il][1]; fTCl2Tracks[il][1] = 0;
205   }
206   Duplicate(m);
207   //
208   return *this;
209 }
210
211 void AliMultiplicity::Copy(TObject &obj) const {
212   
213   // this overwrites the virtual TOBject::Copy()
214   // to allow run time copying without casting
215   // in AliESDEvent
216
217   if(this==&obj)return;
218   AliMultiplicity *robj = dynamic_cast<AliMultiplicity*>(&obj);
219   if(!robj)return; // not an AliMultiplicity
220   *robj = *this;
221
222 }
223
224
225 //______________________________________________________________________
226 void AliMultiplicity::Duplicate(const AliMultiplicity& m){
227   // used by copy constructor and assignment operator
228   fNtracks = m.fNtracks;
229   if(fNtracks>0){
230     fTh = new Double_t[fNtracks];
231     fPhi = new Double_t[fNtracks];
232     fDeltTh = new Double_t[fNtracks];
233     fDeltPhi = new Double_t[fNtracks];
234     fLabels = new Int_t[fNtracks];
235     fLabelsL2 = new Int_t[fNtracks];
236     if (m.fUsedClusT) fUsedClusT = new ULong64_t[fNtracks]; else fUsedClusT = 0;
237     if(m.fTh)memcpy(fTh,m.fTh,fNtracks*sizeof(Double_t));
238     if(m.fPhi)memcpy(fPhi,m.fPhi,fNtracks*sizeof(Double_t));
239     if(m.fDeltTh)memcpy(fDeltTh,m.fDeltTh,fNtracks*sizeof(Double_t));
240     if(m.fDeltPhi)memcpy(fDeltPhi,m.fDeltPhi,fNtracks*sizeof(Double_t));
241     if(m.fLabels)memcpy(fLabels,m.fLabels,fNtracks*sizeof(Int_t));
242     if(m.fLabelsL2)memcpy(fLabelsL2,m.fLabelsL2,fNtracks*sizeof(Int_t));
243     if(fUsedClusT) memcpy(fUsedClusT,m.fUsedClusT,fNtracks*sizeof(ULong64_t));
244     for (int i=2;i--;) for (int j=2;j--;) if (m.fTCl2Tracks[i][j]) fTCl2Tracks[i][j] = new AliRefArray(*m.fTCl2Tracks[i][j]);
245   }
246   else {
247     fTh = 0;
248     fPhi = 0;
249     fDeltTh = 0;
250     fDeltPhi = 0;
251     fLabels = 0;
252     fLabelsL2 = 0;
253   }
254   fNsingle = m.fNsingle;
255   fNsingleSPD2 = m.fNsingleSPD2;
256   if(fNsingle>0){
257     fThsingle = new Double_t[fNsingle];
258     fPhisingle = new Double_t[fNsingle];
259     fLabelssingle = new Int_t[fNsingle];
260     if (m.fUsedClusS) fUsedClusS = new UInt_t[fNsingle];
261     else fUsedClusS = 0;
262     if(m.fThsingle)memcpy(fThsingle,m.fThsingle,fNsingle*sizeof(Double_t));
263     if(m.fPhisingle)memcpy(fPhisingle,m.fPhisingle,fNsingle*sizeof(Double_t));
264     if(m.fLabelssingle)memcpy(fLabelssingle,m.fLabelssingle,fNsingle*sizeof(Int_t));
265     if(fUsedClusS) memcpy(fUsedClusS,m.fUsedClusS,fNsingle*sizeof(UInt_t));
266     for (int i=2;i--;) if (m.fSCl2Tracks[i]) fSCl2Tracks[i] = new AliRefArray(*m.fSCl2Tracks[i]);
267   }
268   else {
269     fThsingle = 0;
270     fPhisingle = 0;
271     fLabelssingle = 0;
272   }
273
274   fFiredChips[0] = m.fFiredChips[0];
275   fFiredChips[1] = m.fFiredChips[1];
276   for(Int_t ilayer = 0; ilayer < 6; ilayer++){
277     fITSClusters[ilayer] = m.fITSClusters[ilayer];
278   }
279   fDPhiWindow2   = m.fDPhiWindow2;
280   fDThetaWindow2 = m.fDThetaWindow2;
281   fDPhiShift     = m.fDPhiShift;
282   fNStdDev       = m.fNStdDev;
283   fFastOrFiredChips = m.fFastOrFiredChips;
284   fClusterFiredChips = m.fClusterFiredChips;
285 }
286
287 //______________________________________________________________________
288 AliMultiplicity::~AliMultiplicity(){
289   // Destructor
290   if(fTh)delete [] fTh;fTh = 0;
291   if(fPhi)delete [] fPhi;fPhi = 0; 
292   if(fDeltTh)delete [] fDeltTh;fDeltTh = 0; 
293   if(fDeltPhi)delete [] fDeltPhi;fDeltPhi = 0; 
294   if(fLabels)delete [] fLabels;fLabels = 0;
295   if(fLabelsL2)delete [] fLabelsL2;fLabelsL2 = 0;
296   if(fThsingle)delete [] fThsingle;fThsingle = 0;
297   if(fPhisingle)delete [] fPhisingle;fPhisingle = 0;
298   if(fLabelssingle)delete [] fLabelssingle;fLabelssingle = 0;
299   if(fUsedClusS) delete[] fUsedClusS; fUsedClusS = 0;
300   if(fUsedClusT) delete[] fUsedClusT; fUsedClusT = 0;
301   for (int il=2;il--;) {
302     if (fSCl2Tracks[il])    delete fSCl2Tracks[il];    fSCl2Tracks[il]    = 0;
303     if (fTCl2Tracks[il][0]) delete fTCl2Tracks[il][0]; fTCl2Tracks[il][0] = 0;
304     if (fTCl2Tracks[il][1]) delete fTCl2Tracks[il][1]; fTCl2Tracks[il][1] = 0;
305   }
306 }
307
308 //______________________________________________________________________
309 void AliMultiplicity::Clear(Option_t*)
310 {
311   // reset all
312   AliVMultiplicity::Clear();
313   if(fTh)delete [] fTh;fTh = 0;
314   if(fPhi)delete [] fPhi;fPhi = 0; 
315   if(fDeltTh)delete [] fDeltTh;fDeltTh = 0; 
316   if(fDeltPhi)delete [] fDeltPhi;fDeltPhi = 0; 
317   if(fLabels)delete [] fLabels;fLabels = 0;
318   if(fLabelsL2)delete [] fLabelsL2;fLabelsL2 = 0;
319   if(fThsingle)delete [] fThsingle;fThsingle = 0;
320   if(fPhisingle)delete [] fPhisingle;fPhisingle = 0;
321   if(fLabelssingle)delete [] fLabelssingle;fLabelssingle = 0;
322   if(fUsedClusS) delete[] fUsedClusS; fUsedClusS = 0;
323   if(fUsedClusT) delete[] fUsedClusT; fUsedClusT = 0;
324   for (int il=2;il--;) {
325     if (fSCl2Tracks[il])    delete fSCl2Tracks[il];    fSCl2Tracks[il]    = 0;
326     if (fTCl2Tracks[il][0]) delete fTCl2Tracks[il][0]; fTCl2Tracks[il][0] = 0;
327     if (fTCl2Tracks[il][1]) delete fTCl2Tracks[il][1]; fTCl2Tracks[il][1] = 0;
328   }
329   fNtracks = fNsingle = 0;
330   for (int i=6;i--;) fITSClusters[0] = 0;
331   fFiredChips[0] = fFiredChips[1] = 0;
332   fFastOrFiredChips.ResetAllBits(kTRUE);
333   fClusterFiredChips.ResetAllBits(kTRUE);
334   //
335 }
336
337 //______________________________________________________________________
338 void AliMultiplicity::SetLabel(Int_t i, Int_t layer, Int_t label)
339 {
340     if(i>=0 && i<fNtracks) {
341         if (layer == 0) {
342             fLabels[i] = label;
343             return;
344         } else if (layer == 1) {
345             if (fLabelsL2) {
346                 fLabelsL2[i] = label;
347                 return;
348             }
349         }
350     }
351     Error("SetLabel","Invalid track number %d or layer %d",i,layer);
352 }
353
354 //______________________________________________________________________
355 void AliMultiplicity::SetLabelSingle(Int_t i, Int_t label) 
356 {
357     if(i>=0 && i<fNsingle) {
358       if (fLabelssingle) {
359         fLabelssingle[i] = label;
360         return;
361       }
362     }
363     Error("SetLabelSingle","Invalid single cluster number %d",i);
364 }
365
366 //______________________________________________________________________
367 UInt_t AliMultiplicity::GetNumberOfITSClusters(Int_t layMin, Int_t layMax) const {
368
369   if(layMax < layMin) {
370     AliError("layer min > layer max");
371     return 0;
372   }
373   if(layMin < 0) {
374     AliError("layer min < 0");
375     return 0;
376   }
377   if(layMax < 0) {
378     AliError("layer max > 0");
379     return 0;
380   }
381
382   Int_t sum=0; 
383   for (Int_t i=layMin; i<=layMax; i++) sum+=fITSClusters[i]; 
384   return sum; 
385
386 }
387
388 //______________________________________________________________________
389 void AliMultiplicity::SetTrackletData(Int_t id, const Float_t* tlet, UInt_t trSPD1, UInt_t trSPD2)
390 {
391   // fill tracklet data
392   if (id>=fNtracks) {AliError(Form("Number of declared tracklets %d < %d",fNtracks,id)); return;}
393   fTh[id]      = tlet[0];
394   fPhi[id]     = tlet[1];
395   fDeltPhi[id] = tlet[2];
396   fDeltTh[id]  = tlet[3];
397   fLabels[id]   = Int_t(tlet[4]);
398   fLabelsL2[id] = Int_t(tlet[5]);
399   if (!GetMultTrackRefs()) {
400     if (!fUsedClusT) {fUsedClusT = new ULong64_t[fNtracks]; memset(fUsedClusT,0,fNtracks*sizeof(ULong64_t));}
401     fUsedClusT[id] = (((ULong64_t)trSPD2)<<32) + trSPD1;
402   }
403   //
404 }
405
406 //______________________________________________________________________
407 void AliMultiplicity::SetSingleClusterData(Int_t id, const Float_t* scl, UInt_t tr)
408 {
409   // fill single cluster data
410   if (id>=fNsingle) {AliError(Form("Number of declared singles %d < %d",fNsingle,id)); return;}
411   fThsingle[id]  = scl[0];
412   fPhisingle[id] = scl[1];
413   fLabelssingle[id] = Int_t(scl[2]); 
414   if (!GetMultTrackRefs()) {
415     if (!fUsedClusS) {fUsedClusS = new UInt_t[fNsingle]; memset(fUsedClusS,0,fNsingle*sizeof(UInt_t));}
416     fUsedClusS[id] = tr;
417   }
418   //
419 }
420
421 //______________________________________________________________________
422 Bool_t AliMultiplicity::FreeClustersTracklet(Int_t i, Int_t mode) const
423 {
424   // return kTRUE if the tracklet was not used by the track (on any of layers) of type mode: 0=TPC/ITS or ITS_SA, 1=ITS_SA_Pure
425   if (mode<0 || mode>1 || i<0 || i>fNtracks) return kFALSE;
426   if (GetMultTrackRefs()) { // new format allows multiple references
427     return !((fTCl2Tracks[0][mode] && fTCl2Tracks[0][mode]->HasReference(i)) ||
428              (fTCl2Tracks[1][mode] && fTCl2Tracks[1][mode]->HasReference(i)));
429   }
430   //
431   if (!fUsedClusT) return kFALSE;
432   const ULong64_t kMask0 = 0x0000ffff0000ffffLL;
433   const ULong64_t kMask1 = 0xffff0000ffff0000LL;
434   return (fUsedClusT[i]&(mode ? kMask1:kMask0)) == 0;
435 }
436
437 //______________________________________________________________________
438 Bool_t AliMultiplicity::GetTrackletTrackIDs(Int_t i, Int_t mode, Int_t &spd1, Int_t &spd2) const
439 {
440   // set spd1 and spd2 to ID's of the tracks using the clusters of the tracklet (-1 if not used)
441   // Mode: 0=TPC/ITS or ITS_SA, 1=ITS_SA_Pure tracks
442   // return false if the neither of clusters is used
443   // note: stored value:  [(idSAPureSPD2+1)<<16+(idTPCITS/SA_SPD2+1)]<<32 +  [(idSAPureSPD1+1)<<16+(idTPCITS/SA_SPD1+1)]
444   // Attention: new format allows references to multiple tracks, here only the 1st will be returned
445   spd1 = spd2 = -1;
446   if ( mode<0 || mode>1 || i<0 || i>fNtracks ) return kFALSE;
447   if (GetMultTrackRefs()) {
448     if (fTCl2Tracks[0][mode]) spd1 = fTCl2Tracks[0][mode]->GetReference(i,0);
449     if (fTCl2Tracks[1][mode]) spd2 = fTCl2Tracks[1][mode]->GetReference(i,0);
450   }
451   else {
452     if (!fUsedClusT) return kFALSE;
453     spd1 = (fUsedClusT[i]&0xffffffffLL);
454     spd2 = (fUsedClusT[i]>>32);
455     if (mode) { spd1 >>= 16;    spd2 >>= 16;}
456     else      { spd1 &= 0xffff; spd2 &= 0xffff;}
457     spd1--; // we are storing id+1
458     spd2--;
459   }
460   return !(spd1<0&&spd2<0);
461 }
462
463 //______________________________________________________________________
464 Int_t AliMultiplicity::GetTrackletTrackIDsLay(Int_t lr,Int_t i, Int_t mode, UInt_t* refs, UInt_t maxRef) const
465 {
466   // fill array refs with maximum maxRef references on tracks used by the cluster of layer lr of tracklet i.
467   // return number of filled references
468   // Mode: 0=TPC/ITS or ITS_SA, 1=ITS_SA_Pure tracks
469   //
470   int nrefs = 0;
471   if ( mode<0 || mode>1 || i<0 || i>fNtracks || lr<0||lr>1) return nrefs;
472   if (GetMultTrackRefs()) {
473     if (fTCl2Tracks[lr][mode]) nrefs = fTCl2Tracks[lr][mode]->GetReferences(i,refs, maxRef);
474   }
475   else {
476     if (!fUsedClusT || maxRef<1) return nrefs;
477     int tr = (fUsedClusT[i]&0xffffffffLL);
478     if (mode) { lr==0 ? tr >>= 16    : tr >>= 16;}
479     else      { lr==0 ? tr &= 0xffff : tr &= 0xffff;}
480     refs[0] = tr--; // we are storing id+1
481     nrefs = 1;
482   }
483   return nrefs;
484 }
485
486 //______________________________________________________________________
487 Int_t AliMultiplicity::GetSingleClusterTrackIDs(Int_t i, Int_t mode, UInt_t* refs, UInt_t maxRef) const
488 {
489   // fill array refs with maximum maxRef references on tracks used by the single cluster i of layer lr
490   // return number of filled references
491   // Mode: 0=TPC/ITS or ITS_SA, 1=ITS_SA_Pure tracks
492   //
493   int nrefs = 0;
494   if ( mode<0 || mode>1 || i<0 || i>fNtracks) return nrefs;
495   if (GetMultTrackRefs()) {
496     if (fSCl2Tracks[mode]) nrefs = fSCl2Tracks[mode]->GetReferences(i,refs, maxRef);
497   }
498   else {
499     if (!fUsedClusS || maxRef<1) return nrefs;
500     int tr = fUsedClusS[i];
501     if (mode) tr >>= 16;
502     else      tr &= 0xffff;
503     refs[0] = tr--; // we are storing id+1
504     nrefs = 1;
505   }
506   return nrefs;
507 }
508
509 //______________________________________________________________________
510 Bool_t AliMultiplicity::FreeSingleCluster(Int_t i, Int_t mode) const
511 {
512   // return kTRUE if the cluster was not used by the track of type mode: 0=TPC/ITS or ITS_SA, 1=ITS_SA_Pure
513   if (mode<0 || mode>1 || i<0 || i>fNsingle) return kFALSE;
514   if (GetMultTrackRefs()) { // new format allows multiple references
515     return !(fSCl2Tracks[mode] && fSCl2Tracks[mode]->HasReference(i));
516   }
517   if (!fUsedClusS) return kFALSE;
518   const UInt_t kMask0 = 0x0000ffff;
519   const UInt_t kMask1 = 0xffff0000;
520   return (fUsedClusS[i]&(mode ? kMask1:kMask0)) == 0;
521 }
522
523 //______________________________________________________________________
524 Bool_t AliMultiplicity::GetSingleClusterTrackID(Int_t i, Int_t mode, Int_t &tr) const
525 {
526   // set tr to id of the track using the single clusters  (-1 if not used)
527   // Mode: 0=TPC/ITS or ITS_SA, 1=ITS_SA_Pure tracks
528   // return false if the cluster is not used
529   //
530   // Attention: new format allows references to multiple tracks, here only the 1st will be returned
531   tr = -1;
532   if (mode<0 || mode>1 || i<0 || i>fNsingle) return kFALSE;
533   if (GetMultTrackRefs()) { if (fSCl2Tracks[mode]) tr = fSCl2Tracks[mode]->GetReference(i,0);}
534   else {
535     if (!fUsedClusS) return kFALSE;
536     tr = fUsedClusS[i];
537     if (mode) tr >>= 16;  else tr &= 0xffff;
538     tr--;
539   }
540   return tr>=0;
541 }
542
543 //______________________________________________________________________
544 void AliMultiplicity::CompactBits()
545 {
546   // sqeeze bit contrainers to minimum
547   fFastOrFiredChips.Compact();
548   fClusterFiredChips.Compact();
549 }
550
551 //______________________________________________________________________
552 void AliMultiplicity::Print(Option_t *opt) const
553 {
554   // print
555   printf("N.tracklets: %4d N.singles: %4d, Multiple cluster->track refs:%s\n"
556          "Used: DPhiShift: %.3e Sig^2: dPhi:%.3e dTht:%.3e NStdDev:%.2f ScaleDThtSin2T:%s\n",
557          fNtracks,fNsingle,GetMultTrackRefs() ? "ON":"OFF",
558          fDPhiShift,fDPhiWindow2,fDThetaWindow2,fNStdDev,GetScaleDThetaBySin2T() ? "ON":"OFF");
559   TString opts = opt; opts.ToLower();
560   int t0spd1=-1,t1spd1=-1,t0spd2=-1,t1spd2=-1,nt[2][2]={{0}};
561   UInt_t t[2][2][10]={{{0}}};
562   //
563   if (opts.Contains("t")) {
564     for (int i=0;i<fNtracks;i++) {
565       if (GetMultTrackRefs()) for (int il=2;il--;)for(int it=2;it--;) nt[il][it] = GetTrackletTrackIDsLay(il,i,it,t[il][it],10);
566       else {
567         GetTrackletTrackIDs(i,0,t0spd1,t0spd2);
568         GetTrackletTrackIDs(i,1,t1spd1,t1spd2);
569       }
570       printf("T#%3d| Eta:%+5.2f Th:%+6.3f Phi:%+6.3f DTh:%+6.3f DPhi:%+6.3f L1:%5d L2:%5d ",
571              i,GetEta(i),fTh[i],fPhi[i],fDeltTh[i],fDeltPhi[i],fLabels[i],fLabelsL2[i]);
572       if (!GetMultTrackRefs()) printf("U:L1[%4d/%4d] L2[%4d/%4d]\n",t0spd1,t1spd1,t0spd2,t1spd2);
573       else {
574         printf("U:L1[");
575         if (!nt[0][0]) printf("%4d ",-1); else for(int j=0;j<nt[0][0];j++) printf("%4d ",t[0][0][j]); printf("/");
576         if (!nt[0][1]) printf("%4d ",-1); else for(int j=0;j<nt[0][1];j++) printf("%4d ",t[0][1][j]); printf("]");
577         //
578         printf(" L2[");
579         if (!nt[1][0]) printf("%4d ",-1); else for(int j=0;j<nt[1][0];j++) printf("%4d ",t[1][0][j]); printf("/");
580         if (!nt[1][1]) printf("%4d ",-1); else for(int j=0;j<nt[1][1];j++) printf("%4d ",t[1][1][j]); printf("]\n");      
581       }      
582     }
583   }
584   if (opts.Contains("s")) {
585     for (int i=0;i<fNsingle;i++) {
586       if (GetMultTrackRefs()) for(int it=2;it--;) nt[0][it] = GetSingleClusterTrackIDs(i,it,t[0][it],10);
587       else {
588         GetSingleClusterTrackID(i,0,t0spd1);
589         GetSingleClusterTrackID(i,1,t1spd1);
590       }
591       printf("S#%3d| Th:%+6.3f Phi:%+6.3f L:%6d ",i,fThsingle[i],fPhisingle[i],fLabelssingle[i]);
592       if (!GetMultTrackRefs()) printf("U:[%4d/%4d]\n", t0spd1,t1spd1);
593       else {
594         printf("U:["); 
595         if (!nt[0][0]) printf("%4d ",-1); else for(int j=0;j<nt[0][0];j++) printf("%4d ",t[0][0][j]); printf("/");
596         if (!nt[0][1]) printf("%4d ",-1); else for(int j=0;j<nt[0][1];j++) printf("%4d ",t[0][1][j]); printf("]\n");    
597       }
598     }
599   }
600   //
601 }
602
603 Int_t AliMultiplicity::GetLabelSingleLr(Int_t i, Int_t lr) const 
604 {
605   if (lr==1) {
606     if (!AreSPD2SinglesStored()) return -1;
607     else i += GetNumberOfSingleClustersLr(0);
608   }
609   if(i>=0 && i<fNsingle) {
610       return fLabelssingle[i];
611   } else {
612     Error("GetLabelSingle","Invalid cluster number %d",i); return -9999;
613   }
614   return -9999;
615 }
616
617 Float_t AliMultiplicity::GetPhiAll(int icl, int lr) const
618 {
619   // return phi of the cluster out of total tracklets + singles
620   if (lr<0||lr>1) return -999;
621   if (icl<0||icl>(int)GetNumberOfITSClusters(lr)) {Error("GetPhiAll","Wrong cluster ID=%d for SPD%d",icl,lr); return -999;}
622   if (lr==0) return (icl<fNtracks) ? GetPhi(icl) : GetPhiSingle(icl-fNtracks);
623   return (icl<fNtracks) ? (GetPhi(icl) + GetDeltaPhi(icl)) : GetPhiSingleLr(icl-fNtracks, 1);
624
625
626 Float_t AliMultiplicity::GetThetaAll(int icl, int lr) const
627 {
628   // return theta of the cluster out of total tracklets + singles
629   if (lr<0||lr>1) return -999;
630   if (icl<0||icl>(int)GetNumberOfITSClusters(lr)) {Error("GetPhiAll","Wrong cluster ID=%d for SPD%d",icl,lr); return -999;}
631   if (lr==0) return (icl<fNtracks) ? GetTheta(icl) : GetThetaSingle(icl-fNtracks);
632   return (icl<fNtracks) ?  (GetTheta(icl) + GetDeltaTheta(icl)) : GetThetaSingleLr(icl-fNtracks, 1);
633
634
635 Int_t AliMultiplicity::GetLabelAll(int icl, int lr) const
636 {
637   // return label of the cluster out of total tracklets + singles
638   if (lr<0||lr>1) return -99999;
639   if (icl<0||icl>(int)GetNumberOfITSClusters(lr)) {Error("GetPhiAll","Wrong cluster ID=%d for SPD%d",icl,lr); return -99999;}
640   if (lr==0) return (icl<fNtracks) ? GetLabel(icl,0) : GetLabelSingle(icl-fNtracks);
641   return (icl<fNtracks) ?  GetLabel(icl,1) : GetLabelSingleLr(icl-fNtracks, 1);
642