]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PHOS/AliPHOSTrackSegmentMakerv1.cxx
The web becomes richer
[u/mrichter/AliRoot.git] / PHOS / AliPHOSTrackSegmentMakerv1.cxx
CommitLineData
d15a28e7 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
b2a60966 16/* $Id$ */
17
d15a28e7 18//_________________________________________________________________________
b2a60966 19// Implementation version 1 of algorithm class to construct PHOS track segments
20// Associates EMC and PPSD clusters
21// Unfolds the EMC cluster
22//
23//*-- Author: Dmitri Peressounko (RRC Ki & SUBATECH)
24//
d15a28e7 25
26// --- ROOT system ---
27
28#include "TObjArray.h"
29#include "TClonesArray.h"
9f616d61 30#include "TObjectTable.h"
d15a28e7 31
32// --- Standard library ---
33
9f616d61 34#include <iostream>
35#include <cassert>
d15a28e7 36
37// --- AliRoot header files ---
38
39#include "AliPHOSTrackSegmentMakerv1.h"
40#include "AliPHOSTrackSegment.h"
41#include "AliPHOSLink.h"
42#include "AliPHOSv0.h"
43#include "AliRun.h"
44
92862013 45extern void UnfoldingChiSquare(Int_t &nPar, Double_t *Grad, Double_t & fret, Double_t *x, Int_t iflag) ;
9f616d61 46
d15a28e7 47ClassImp( AliPHOSTrackSegmentMakerv1)
48
49
50//____________________________________________________________________________
b2a60966 51 AliPHOSTrackSegmentMakerv1::AliPHOSTrackSegmentMakerv1() : AliPHOSTrackSegmentMaker()
d15a28e7 52{
9f616d61 53 // ctor
b2a60966 54
d15a28e7 55 fR0 = 4. ;
56 AliPHOSGeometry * geom = AliPHOSGeometry::GetInstance() ;
57 //clusters are sorted in "rows" and "columns" of width geom->GetCrystalSize(0),
58 fDelta = fR0 + geom->GetCrystalSize(0) ;
6727be7e 59 fMinuit = new TMinuit(100) ;
60 fUnfoldFlag = kTRUE ;
d15a28e7 61}
62
9f616d61 63//____________________________________________________________________________
64 AliPHOSTrackSegmentMakerv1::~AliPHOSTrackSegmentMakerv1()
65{
66 // dtor
b2a60966 67
68 delete fMinuit ;
9f616d61 69}
b2a60966 70
d15a28e7 71//____________________________________________________________________________
72Bool_t AliPHOSTrackSegmentMakerv1::FindFit(AliPHOSEmcRecPoint * emcRP, int * maxAt, Float_t * maxAtEnergy,
92862013 73 Int_t nPar, Float_t * fitparameters)
9f616d61 74{
b2a60966 75 // Calls TMinuit to fit the energy distribution of a cluster with several maxima
6ad0bfa0 76
d15a28e7 77 AliPHOSGeometry * geom = AliPHOSGeometry::GetInstance() ;
d15a28e7 78
9f616d61 79 gMinuit->SetPrintLevel(-1) ; // No Printout
80 gMinuit->SetFCN(UnfoldingChiSquare) ; // To set the address of the minimization function
81 gMinuit->SetObjectFit(emcRP) ; // To tranfer pointer to UnfoldingChiSquare
82
83 // filling initial values for fit parameters
d15a28e7 84 AliPHOSDigit * digit ;
9f616d61 85
86 Int_t ierflg = 0;
87 Int_t index = 0 ;
92862013 88 Int_t nDigits = (Int_t) nPar / 3 ;
9f616d61 89
d15a28e7 90 Int_t iDigit ;
9f616d61 91
92
92862013 93 for(iDigit = 0; iDigit < nDigits; iDigit++){
d15a28e7 94 digit = (AliPHOSDigit *) maxAt[iDigit];
95
92862013 96 Int_t relid[4] ;
d15a28e7 97 Float_t x ;
98 Float_t z ;
92862013 99 geom->AbsToRelNumbering(digit->GetId(), relid) ;
100 geom->RelPosInModule(relid, x, z) ;
d15a28e7 101
92862013 102 Float_t energy = maxAtEnergy[iDigit] ;
d15a28e7 103
9f616d61 104 gMinuit->mnparm(index, "x", x, 0.1, 0, 0, ierflg) ;
105 index++ ;
d15a28e7 106 if(ierflg != 0){
107 cout << "PHOS Unfolding> Unable to set initial value for fit procedure : x = " << x << endl ;
108 return kFALSE;
109 }
9f616d61 110 gMinuit->mnparm(index, "z", z, 0.1, 0, 0, ierflg) ;
111 index++ ;
d15a28e7 112 if(ierflg != 0){
113 cout << "PHOS Unfolding> Unable to set initial value for fit procedure : z = " << z << endl ;
114 return kFALSE;
115 }
92862013 116 gMinuit->mnparm(index, "Energy", energy , 0.05*energy, 0., 4.*energy, ierflg) ;
9f616d61 117 index++ ;
d15a28e7 118 if(ierflg != 0){
92862013 119 cout << "PHOS Unfolding> Unable to set initial value for fit procedure : energy = " << energy << endl ;
d15a28e7 120 return kFALSE;
6ad0bfa0 121 }
d15a28e7 122 }
123
9f616d61 124 Double_t p0 = 0.1 ; // "Tolerance" Evaluation stops when EDM = 0.0001*p0 ; The number of function call slightly
125 // depends on it.
126 Double_t p1 = 1.0 ;
127 Double_t p2 = 0.0 ;
128
129 gMinuit->mnexcm("SET STR", &p2, 0, ierflg) ; // force TgMinuit to reduce function calls
130 gMinuit->mnexcm("SET GRA", &p1, 1, ierflg) ; // force TMinuit to use my gradient
d15a28e7 131 gMinuit->SetMaxIterations(5);
9f616d61 132 gMinuit->mnexcm("SET NOW", &p2 , 0, ierflg) ; // No Warnings
133 gMinuit->mnexcm("MIGRAD", &p0, 0, ierflg) ; // minimize
134 if(ierflg == 4){ // Minimum not found
135 cout << "PHOS Unfolding> Fit not converged, cluster abandoned "<< endl ;
d15a28e7 136 return kFALSE ;
137 }
92862013 138 for(index = 0; index < nPar; index++){
d15a28e7 139 Double_t err ;
140 Double_t val ;
9f616d61 141 gMinuit->GetParameter(index, val, err) ; // Returns value and error of parameter index
92862013 142 fitparameters[index] = val ;
d15a28e7 143 }
d15a28e7 144 return kTRUE;
9f616d61 145
d15a28e7 146}
9f616d61 147
d15a28e7 148//____________________________________________________________________________
b2a60966 149void AliPHOSTrackSegmentMakerv1::FillOneModule(DigitsList * dl, RecPointsList * emcIn, TObjArray * emcOut,
d15a28e7 150 RecPointsList * ppsdIn, TObjArray * ppsdOutUp,
92862013 151 TObjArray * ppsdOutLow, Int_t & phosmod, Int_t & emcStopedAt,
d15a28e7 152 Int_t & ppsdStopedAt)
9f616d61 153{
154 // Unfold clusters and fill xxxOut arrays with clusters from one PHOS module
155
156 AliPHOSEmcRecPoint * emcRecPoint ;
d15a28e7 157 AliPHOSPpsdRecPoint * ppsdRecPoint ;
158 Int_t index ;
6ad0bfa0 159
92862013 160 Int_t nEmcUnfolded = emcIn->GetEntries() ;
161 for(index = emcStopedAt; index < nEmcUnfolded; index++){
d15a28e7 162 emcRecPoint = (AliPHOSEmcRecPoint *) (*emcIn)[index] ;
6ad0bfa0 163
92862013 164 if(emcRecPoint->GetPHOSMod() != phosmod )
9f616d61 165 break ;
166
92862013 167 Int_t nMultipl = emcRecPoint->GetMultiplicity() ;
31aa6d6c 168 Int_t * maxAt = new Int_t[nMultipl] ;
169 Float_t * maxAtEnergy = new Float_t[nMultipl] ;
92862013 170 Int_t nMax = emcRecPoint->GetNumberOfLocalMax(maxAt, maxAtEnergy) ;
6a3f1304 171
6727be7e 172 if(nMax <= 1 ) // if cluster is very flat (no pronounced maximum) then nMax = 0
d15a28e7 173 emcOut->Add(emcRecPoint) ;
6727be7e 174 else if (fUnfoldFlag) {
b2a60966 175 UnfoldClusters(dl, emcIn, emcRecPoint, nMax, maxAt, maxAtEnergy, emcOut) ;
d15a28e7 176 emcIn->Remove(emcRecPoint);
177 emcIn->Compress() ;
92862013 178 nEmcUnfolded-- ;
d15a28e7 179 index-- ;
180 }
31aa6d6c 181
182 delete[] maxAt ;
183 delete[] maxAtEnergy ;
d15a28e7 184 }
185 emcStopedAt = index ;
186
187 for(index = ppsdStopedAt; index < ppsdIn->GetEntries(); index++){
188 ppsdRecPoint = (AliPHOSPpsdRecPoint *) (*ppsdIn)[index] ;
92862013 189 if(ppsdRecPoint->GetPHOSMod() != phosmod )
9f616d61 190 break ;
d15a28e7 191 if(ppsdRecPoint->GetUp() )
192 ppsdOutUp->Add(ppsdRecPoint) ;
193 else
194 ppsdOutLow->Add(ppsdRecPoint) ;
195 }
196 ppsdStopedAt = index ;
6ad0bfa0 197
d15a28e7 198 emcOut->Sort() ;
199 ppsdOutUp->Sort() ;
6ad0bfa0 200 ppsdOutLow->Sort() ;
d15a28e7 201}
202//____________________________________________________________________________
92862013 203Float_t AliPHOSTrackSegmentMakerv1::GetDistanceInPHOSPlane(AliPHOSEmcRecPoint * emcclu,AliPHOSPpsdRecPoint * PpsdClu, Bool_t &toofar)
d15a28e7 204{
b2a60966 205 // Calculates the distance between the EMC RecPoint and the PPSD RecPoint
206
92862013 207 Float_t r = fR0 ;
d15a28e7 208
209 TVector3 vecEmc ;
210 TVector3 vecPpsd ;
211
92862013 212 emcclu->GetLocalPosition(vecEmc) ;
d15a28e7 213 PpsdClu->GetLocalPosition(vecPpsd) ;
92862013 214 if(emcclu->GetPHOSMod() == PpsdClu->GetPHOSMod()){
d15a28e7 215 if(vecPpsd.X() >= vecEmc.X() - fDelta ){
216 if(vecPpsd.Z() >= vecEmc.Z() - fDelta ){
217 AliPHOSGeometry * geom = AliPHOSGeometry::GetInstance() ;
6ad0bfa0 218 // Correct to difference in CPV and EMC position due to different distance to center.
219 // we assume, that particle moves from center
92862013 220 Float_t dCPV = geom->GetIPtoOuterCoverDistance();
221 Float_t dEMC = geom->GetIPtoCrystalSurface() ;
222 dEMC = dEMC / dCPV ;
223 vecPpsd = dEMC * vecPpsd - vecEmc ;
224 r = vecPpsd.Mag() ;
d15a28e7 225 } // if zPpsd >= zEmc - fDelta
92862013 226 toofar = kFALSE ;
d15a28e7 227 } // if xPpsd >= xEmc - fDelta
228 else
92862013 229 toofar = kTRUE ;
d15a28e7 230 }
231 else
92862013 232 toofar = kTRUE ;
d15a28e7 233
92862013 234 return r ;
d15a28e7 235}
236
237//____________________________________________________________________________
92862013 238void AliPHOSTrackSegmentMakerv1::MakeLinks(TObjArray * emcRecPoints, TObjArray * ppsdRecPointsUp,
239 TObjArray * ppsdRecPointsLow, TClonesArray * linklowArray,
240 TClonesArray *linkupArray)
d15a28e7 241{
b2a60966 242 // Finds distances (links) between all EMC and PPSD clusters, which are not further apart from each other than fR0
243
92862013 244 TIter nextEmc(emcRecPoints) ;
d15a28e7 245 Int_t iEmcClu = 0 ;
246
92862013 247 AliPHOSPpsdRecPoint * ppsdlow ;
248 AliPHOSPpsdRecPoint * ppsdup ;
249 AliPHOSEmcRecPoint * emcclu ;
d15a28e7 250
251 Int_t iLinkLow = 0 ;
252 Int_t iLinkUp = 0 ;
253
92862013 254 while( (emcclu = (AliPHOSEmcRecPoint*)nextEmc() ) ) {
255 Bool_t toofar ;
256 TIter nextPpsdLow(ppsdRecPointsLow ) ;
d15a28e7 257 Int_t iPpsdLow = 0 ;
258
92862013 259 while( (ppsdlow = (AliPHOSPpsdRecPoint*)nextPpsdLow() ) ) {
260 Float_t r = GetDistanceInPHOSPlane(emcclu, ppsdlow, toofar) ;
d15a28e7 261
92862013 262 if(toofar)
d15a28e7 263 break ;
92862013 264 if(r < fR0)
265 new( (*linklowArray)[iLinkLow++]) AliPHOSLink(r, iEmcClu, iPpsdLow) ;
d15a28e7 266
267 iPpsdLow++ ;
268
269 }
270
92862013 271 TIter nextPpsdUp(ppsdRecPointsUp ) ;
d15a28e7 272 Int_t iPpsdUp = 0 ;
273
92862013 274 while( (ppsdup = (AliPHOSPpsdRecPoint*)nextPpsdUp() ) ) {
275 Float_t r = GetDistanceInPHOSPlane(emcclu, ppsdup, toofar) ;
d15a28e7 276
92862013 277 if(toofar)
d15a28e7 278 break ;
92862013 279 if(r < fR0)
280 new( (*linkupArray)[iLinkUp++]) AliPHOSLink(r, iEmcClu, iPpsdUp) ;
d15a28e7 281
282 iPpsdUp++ ;
283
284 }
285
286 iEmcClu++ ;
287
288 } // while nextEmC
289
92862013 290 linklowArray->Sort() ; //first links with smallest distances
291 linkupArray->Sort() ;
d15a28e7 292}
293
294//____________________________________________________________________________
92862013 295void AliPHOSTrackSegmentMakerv1::MakePairs(TObjArray * emcRecPoints, TObjArray * ppsdRecPointsUp,
296 TObjArray * ppsdRecPointsLow, TClonesArray * linklowArray,
297 TClonesArray * linkupArray, TrackSegmentsList * trsl)
6ad0bfa0 298{
299
300 // Finds the smallest links and makes pairs of PPSD and EMC clusters with smallest distance
301
92862013 302 TIter nextLow(linklowArray) ;
303 TIter nextUp(linkupArray) ;
d15a28e7 304
305 AliPHOSLink * linkLow ;
306 AliPHOSLink * linkUp ;
307
308 AliPHOSEmcRecPoint * emc ;
309 AliPHOSPpsdRecPoint * ppsdLow ;
310 AliPHOSPpsdRecPoint * ppsdUp ;
311
92862013 312 AliPHOSRecPoint * nullpointer = 0 ;
9f616d61 313
d15a28e7 314 while ( (linkLow = (AliPHOSLink *)nextLow() ) ){
92862013 315 emc = (AliPHOSEmcRecPoint *) emcRecPoints->At(linkLow->GetEmc()) ;
316 ppsdLow = (AliPHOSPpsdRecPoint *) ppsdRecPointsLow->At(linkLow->GetPpsd()) ;
6ad0bfa0 317 if( (emc) && (ppsdLow) ){ // RecPoints not removed yet
d15a28e7 318 ppsdUp = 0 ;
319
320 while ( (linkUp = (AliPHOSLink *)nextUp() ) ){
321 if(linkLow->GetEmc() == linkUp->GetEmc() ){
92862013 322 ppsdUp = (AliPHOSPpsdRecPoint *) ppsdRecPointsUp->At(linkUp->GetPpsd()) ;
d15a28e7 323 break ;
324 }
325
326 } // while nextUp
327
328 nextUp.Reset();
b2a60966 329// AliPHOSTrackSegment * subtr = new AliPHOSTrackSegment(emc, ppsdUp, ppsdLow ) ;
330// trsl->Add(subtr) ;
331 new( (*trsl)[fNTrackSegments] ) AliPHOSTrackSegment(emc, ppsdUp, ppsdLow ) ;
332 fNTrackSegments++ ;
92862013 333 emcRecPoints->AddAt(nullpointer,linkLow->GetEmc()) ;
334 ppsdRecPointsLow->AddAt(nullpointer,linkLow->GetPpsd()) ;
d15a28e7 335
336 if(ppsdUp)
92862013 337 ppsdRecPointsUp->AddAt(nullpointer,linkUp->GetPpsd()) ;
d15a28e7 338
6ad0bfa0 339 }
d15a28e7 340 }
341
92862013 342 TIter nextEmc(emcRecPoints) ;
d15a28e7 343 nextEmc.Reset() ;
344
92862013 345 while( (emc = (AliPHOSEmcRecPoint*)nextEmc()) ){ //to create pairs if no ppsdlow
9f616d61 346 ppsdLow = 0 ;
347 ppsdUp = 0 ;
d15a28e7 348
349 while ( (linkUp = (AliPHOSLink *)nextUp() ) ){
350
92862013 351 if(emcRecPoints->IndexOf(emc) == linkUp->GetEmc() ){
352 ppsdUp = (AliPHOSPpsdRecPoint *) ppsdRecPointsUp->At(linkUp->GetPpsd()) ;
d15a28e7 353 break ;
354 }
355
356 }
b2a60966 357// AliPHOSTrackSegment * subtr = new AliPHOSTrackSegment(emc, ppsdUp, ppsdLow ) ;
358// trsl->Add(subtr) ;
359 new( (*trsl)[fNTrackSegments] ) AliPHOSTrackSegment(emc, ppsdUp, ppsdLow ) ;
360 fNTrackSegments++ ;
361
362
d15a28e7 363 if(ppsdUp)
92862013 364 ppsdRecPointsUp->AddAt(nullpointer,linkUp->GetPpsd()) ;
d15a28e7 365 }
366
367}
368
369//____________________________________________________________________________
b2a60966 370void AliPHOSTrackSegmentMakerv1::MakeTrackSegments(DigitsList * dl, RecPointsList * emcl,
d15a28e7 371 RecPointsList * ppsdl, TrackSegmentsList * trsl)
372{
b2a60966 373 // Makes the track segments out of the list of EMC and PPSD Recpoints and stores them in a list
d15a28e7 374
92862013 375 Int_t phosmod = 1 ;
9f616d61 376 Int_t emcStopedAt = 0 ;
d15a28e7 377 Int_t ppsdStopedAt = 0 ;
378
92862013 379 TObjArray * emcRecPoints = new TObjArray(100) ; // these arrays keep pointers
380 TObjArray * ppsdRecPointsUp = new TObjArray(100) ; // to RecPoints, which are
381 TObjArray * ppsdRecPointsLow = new TObjArray(100) ; // kept in TClonesArray's emcl and ppsdl
d15a28e7 382
383
92862013 384 TClonesArray * linklowArray = new TClonesArray("AliPHOSLink", 100);
385 TClonesArray * linkupArray = new TClonesArray("AliPHOSLink", 100);
d15a28e7 386
387 AliPHOSGeometry * geom = AliPHOSGeometry::GetInstance() ;
388
92862013 389 while(phosmod <= geom->GetNModules() ){
d15a28e7 390
b2a60966 391 FillOneModule(dl, emcl, emcRecPoints, ppsdl, ppsdRecPointsUp, ppsdRecPointsLow, phosmod, emcStopedAt, ppsdStopedAt) ;
6ad0bfa0 392
92862013 393 MakeLinks(emcRecPoints, ppsdRecPointsUp, ppsdRecPointsLow, linklowArray, linkupArray) ;
d15a28e7 394
92862013 395 MakePairs(emcRecPoints, ppsdRecPointsUp, ppsdRecPointsLow, linklowArray, linkupArray, trsl) ;
d15a28e7 396
92862013 397 emcRecPoints->Clear() ;
9f616d61 398
92862013 399 ppsdRecPointsUp->Clear() ;
9f616d61 400
92862013 401 ppsdRecPointsLow->Clear() ;
9f616d61 402
92862013 403 linkupArray->Clear() ;
9f616d61 404
92862013 405 linklowArray->Clear() ;
9f616d61 406
92862013 407 phosmod++ ;
d15a28e7 408 }
92862013 409 delete emcRecPoints ;
410 emcRecPoints = 0 ;
9f616d61 411
92862013 412 delete ppsdRecPointsUp ;
413 ppsdRecPointsUp = 0 ;
9f616d61 414
92862013 415 delete ppsdRecPointsLow ;
416 ppsdRecPointsLow = 0 ;
9f616d61 417
92862013 418 delete linkupArray ;
419 linkupArray = 0 ;
9f616d61 420
92862013 421 delete linklowArray ;
422 linklowArray = 0 ;
d15a28e7 423}
424
425//____________________________________________________________________________
9f616d61 426Double_t AliPHOSTrackSegmentMakerv1::ShowerShape(Double_t r)
427{
b2a60966 428 // Shape of the shower (see PHOS TDR)
429 // If you change this function, change also the gradien evaluation in ChiSquare()
430
6ad0bfa0 431 Double_t r4 = r*r*r*r ;
432 Double_t r295 = TMath::Power(r, 2.95) ;
d15a28e7 433 Double_t shape = TMath::Exp( -r4 * (1. / (2.32 + 0.26 * r4) + 0.0316 / (1 + 0.0652 * r295) ) ) ;
434 return shape ;
435}
436
437//____________________________________________________________________________
b2a60966 438void AliPHOSTrackSegmentMakerv1::UnfoldClusters(DigitsList * dl, RecPointsList * emcIn, AliPHOSEmcRecPoint * iniEmc,
92862013 439 Int_t nMax, int * maxAt, Float_t * maxAtEnergy, TObjArray * emcList)
d15a28e7 440{
b2a60966 441 // Performs the unfolding of a cluster with nMax overlapping showers
442 // This is time consuming (use the (Un)SetUnfolFlag() )
443
92862013 444 Int_t nPar = 3 * nMax ;
31aa6d6c 445 Float_t * fitparameters = new Float_t[nPar] ;
d15a28e7 446 AliPHOSGeometry * geom = AliPHOSGeometry::GetInstance() ;
9f616d61 447
92862013 448 Bool_t rv = FindFit(iniEmc, maxAt, maxAtEnergy, nPar, fitparameters) ;
31aa6d6c 449 if( !rv ) {
450 // Fit failed, return and remove cluster
451 delete[] fitparameters ;
d15a28e7 452 return ;
31aa6d6c 453 }
d15a28e7 454
455 Float_t xDigit ;
456 Float_t zDigit ;
92862013 457 Int_t relid[4] ;
d15a28e7 458
92862013 459 Int_t nDigits = iniEmc->GetMultiplicity() ;
d15a28e7 460 Float_t xpar ;
461 Float_t zpar ;
92862013 462 Float_t epar ;
463 Float_t distance ;
464 Float_t ratio ;
31aa6d6c 465 Float_t * efit = new Float_t[nDigits] ;
d15a28e7 466 Int_t iparam ;
467 Int_t iDigit ;
468
469 AliPHOSDigit * digit ;
470 AliPHOSEmcRecPoint * emcRP ;
6ad0bfa0 471 Int_t * emcDigits = iniEmc->GetDigitsList() ;
d15a28e7 472 Float_t * emcEnergies = iniEmc->GetEnergiesList() ;
473
474 Int_t iRecPoint = emcIn->GetEntries() ;
475
92862013 476 for(iDigit = 0 ; iDigit < nDigits ; iDigit ++){
d15a28e7 477 digit = (AliPHOSDigit *) emcDigits[iDigit];
92862013 478 geom->AbsToRelNumbering(digit->GetId(), relid) ;
479 geom->RelPosInModule(relid, xDigit, zDigit) ;
480 efit[iDigit] = 0;
d15a28e7 481 iparam = 0 ;
482
92862013 483 while(iparam < nPar ){
484 xpar = fitparameters[iparam] ;
485 zpar = fitparameters[iparam+1] ;
486 epar = fitparameters[iparam+2] ;
d15a28e7 487 iparam += 3 ;
92862013 488 distance = (xDigit - xpar) * (xDigit - xpar) + (zDigit - zpar) * (zDigit - zpar) ;
489 distance = TMath::Sqrt(distance) ;
b2a60966 490 efit[iDigit] += epar * AliPHOSTrackSegmentMakerv1::ShowerShape(distance) ;
d15a28e7 491 }
d15a28e7 492 }
493
494 iparam = 0 ;
495 Float_t eDigit ;
496
92862013 497 while(iparam < nPar ){
498 xpar = fitparameters[iparam] ;
499 zpar = fitparameters[iparam+1] ;
500 epar = fitparameters[iparam+2] ;
d15a28e7 501 iparam += 3 ;
502 new ((*emcIn)[iRecPoint]) AliPHOSEmcRecPoint( iniEmc->GetLogWeightCut(), iniEmc->GetLocMaxCut() ) ;
503 emcRP = (AliPHOSEmcRecPoint *) emcIn->At(iRecPoint++);
504
92862013 505 for(iDigit = 0 ; iDigit < nDigits ; iDigit ++){
d15a28e7 506 digit = (AliPHOSDigit *) emcDigits[iDigit];
92862013 507 geom->AbsToRelNumbering(digit->GetId(), relid) ;
508 geom->RelPosInModule(relid, xDigit, zDigit) ;
509 distance = (xDigit - xpar) * (xDigit - xpar) + (zDigit - zpar) * (zDigit - zpar) ;
510 distance = TMath::Sqrt(distance) ;
b2a60966 511 ratio = epar * AliPHOSTrackSegmentMakerv1::ShowerShape(distance) / efit[iDigit] ;
92862013 512 eDigit = emcEnergies[iDigit] * ratio ;
9f616d61 513 emcRP->AddDigit( *digit, eDigit ) ;
d15a28e7 514 }
515
516 emcList->Add(emcRP) ;
517
518 }
31aa6d6c 519
520 delete[] fitparameters ;
521 delete[] efit ;
522
d15a28e7 523}
6ad0bfa0 524
d15a28e7 525//______________________________________________________________________________
92862013 526void UnfoldingChiSquare(Int_t & nPar, Double_t * Grad, Double_t & fret, Double_t * x, Int_t iflag)
d15a28e7 527{
b2a60966 528 // Calculates th Chi square for the cluster unfolding minimization
529 // Number of parameters, Gradient, Chi squared, parameters, what to do
9f616d61 530
d15a28e7 531 AliPHOSGeometry * geom = AliPHOSGeometry::GetInstance() ;
d15a28e7 532
9f616d61 533 AliPHOSEmcRecPoint * emcRP = (AliPHOSEmcRecPoint *) gMinuit->GetObjectFit() ; // EmcRecPoint to fit
6ad0bfa0 534 Int_t * emcDigits = emcRP->GetDigitsList() ;
d15a28e7 535 Float_t * emcEnergies = emcRP->GetEnergiesList() ;
536 fret = 0. ;
537 Int_t iparam ;
538
9f616d61 539 if(iflag == 2)
92862013 540 for(iparam = 0 ; iparam < nPar ; iparam++)
9f616d61 541 Grad[iparam] = 0 ; // Will evaluate gradient
542
92862013 543 Double_t efit ;
9f616d61 544
d15a28e7 545 AliPHOSDigit * digit ;
546 Int_t iDigit = 0 ;
9f616d61 547
d15a28e7 548 while ( (digit = (AliPHOSDigit *)emcDigits[iDigit] )){
92862013 549 Int_t relid[4] ;
d15a28e7 550 Float_t xDigit ;
551 Float_t zDigit ;
92862013 552 geom->AbsToRelNumbering(digit->GetId(), relid) ;
553 geom->RelPosInModule(relid, xDigit, zDigit) ;
d15a28e7 554
9f616d61 555 if(iflag == 2){ // calculate gradient
556 Int_t iParam = 0 ;
92862013 557 efit = 0 ;
558 while(iParam < nPar ){
559 Double_t distance = (xDigit - x[iParam]) * (xDigit - x[iParam]) ;
9f616d61 560 iParam++ ;
92862013 561 distance += (zDigit - x[iParam]) * (zDigit - x[iParam]) ;
562 distance = TMath::Sqrt( distance ) ;
9f616d61 563 iParam++ ;
92862013 564 efit += x[iParam] * AliPHOSTrackSegmentMakerv1::ShowerShape(distance) ;
9f616d61 565 iParam++ ;
566 }
92862013 567 Double_t sum = 2. * (efit - emcEnergies[iDigit]) / emcEnergies[iDigit] ; // Here we assume, that sigma = sqrt(E)
9f616d61 568 iParam = 0 ;
92862013 569 while(iParam < nPar ){
9f616d61 570 Double_t xpar = x[iParam] ;
571 Double_t zpar = x[iParam+1] ;
92862013 572 Double_t epar = x[iParam+2] ;
9f616d61 573 Double_t dr = TMath::Sqrt( (xDigit - xpar) * (xDigit - xpar) + (zDigit - zpar) * (zDigit - zpar) );
574 Double_t shape = sum * AliPHOSTrackSegmentMakerv1::ShowerShape(dr) ;
575 Double_t r4 = dr*dr*dr*dr ;
576 Double_t r295 = TMath::Power(dr,2.95) ;
577 Double_t deriv =-4. * dr*dr * ( 2.32 / ( (2.32 + 0.26 * r4) * (2.32 + 0.26 * r4) ) +
578 0.0316 * (1. + 0.0171 * r295) / ( ( 1. + 0.0652 * r295) * (1. + 0.0652 * r295) ) ) ;
579
92862013 580 Grad[iParam] += epar * shape * deriv * (xpar - xDigit) ; // Derivative over x
9f616d61 581 iParam++ ;
92862013 582 Grad[iParam] += epar * shape * deriv * (zpar - zDigit) ; // Derivative over z
9f616d61 583 iParam++ ;
584 Grad[iParam] += shape ; // Derivative over energy
585 iParam++ ;
586 }
587 }
92862013 588 efit = 0;
9f616d61 589 iparam = 0 ;
92862013 590 while(iparam < nPar ){
9f616d61 591 Double_t xpar = x[iparam] ;
592 Double_t zpar = x[iparam+1] ;
92862013 593 Double_t epar = x[iparam+2] ;
9f616d61 594 iparam += 3 ;
92862013 595 Double_t distance = (xDigit - xpar) * (xDigit - xpar) + (zDigit - zpar) * (zDigit - zpar) ;
596 distance = TMath::Sqrt(distance) ;
597 efit += epar * AliPHOSTrackSegmentMakerv1::ShowerShape(distance) ;
9f616d61 598 }
92862013 599 fret += (efit-emcEnergies[iDigit])*(efit-emcEnergies[iDigit])/emcEnergies[iDigit] ;
9f616d61 600 // Here we assume, that sigma = sqrt(E)
601 iDigit++ ;
d15a28e7 602 }
603}