1 ////////////////////////////////////////////////////////////////////////////////
3 // AliFemtoCorrFctnDirectYlm - Correlation function that is binned in Ylms //
4 // directly. Provides a way to store the numerator and denominator //
5 // in Ylms directly and correctly calculate the correlation //
6 // function from them. //
8 // Authors: Adam Kisiel kisiel@mps.ohio-state.edu //
10 ////////////////////////////////////////////////////////////////////////////////
11 #include "AliFemtoCorrFctnDirectYlm.h"
17 AliFemtoCorrFctnDirectYlm::AliFemtoCorrFctnDirectYlm(const char *name, int maxl, int ibin=30, double vmin=0.0, double vmax=0.3, int aUseLCMS=0):
43 fMaxJM = (maxl+1)*(maxl+1);
45 // *DEB* cout << "Size is " << sizeof(double) << " " << sizeof(complex<double>) << endl;
47 // Fill in factorials table
48 factorials = (double *) malloc(sizeof(double) * (4 * (maxl + 1)));
51 for (int iter=1; iter<4*(maxl+1); iter++)
54 factorials[iter] = fac;
57 // Fill in els and ems table
61 fels = (double *) malloc(sizeof(double) * (fMaxJM));
62 fems = (double *) malloc(sizeof(double) * (fMaxJM));
63 felsi = (int *) malloc(sizeof(int) * (fMaxJM));
64 femsi = (int *) malloc(sizeof(int) * (fMaxJM));
71 // *DEB* cout << "il el em " << il << " " << felsi[il] << " " << femsi[il] << endl;
81 // *DEB* for (il=0; il<fMaxJM; il++)
82 // *DEB* cout << "il el em " << il << " " << felsi[il] << " " << femsi[il] << endl;
84 // Create numerator and denominator historgrams
85 // int sthp = sizeof(TH1D *);
86 // fnumsreal = (TH1D **) malloc(sthp * fMaxJM);
87 // fnumsreal = new TH1D * [fMaxJM];
88 // fnumsimag = new TH1D * [fMaxJM];
89 // fdensreal = new TH1D * [fMaxJM];
90 // fdensimag = new TH1D * [fMaxJM];
91 fnumsreal = (TH1D **) malloc(sizeof(TH1D *) * fMaxJM);
92 fnumsimag = (TH1D **) malloc(sizeof(TH1D *) * fMaxJM);
93 fdensreal = (TH1D **) malloc(sizeof(TH1D *) * fMaxJM);
94 fdensimag = (TH1D **) malloc(sizeof(TH1D *) * fMaxJM);
97 for (int ihist=0; ihist<fMaxJM; ihist++) {
98 snprintf(bufname , 200, "NumReYlm%i%i%s", felsi[ihist], femsi[ihist]<0 ? felsi[ihist]-femsi[ihist] : femsi[ihist], name);
99 fnumsreal[ihist] = new TH1D(bufname, bufname, ibin, vmin, vmax);
100 snprintf(bufname , 200, "NumImYlm%i%i%s", felsi[ihist], femsi[ihist]<0 ? felsi[ihist]-femsi[ihist] : femsi[ihist], name);
101 fnumsimag[ihist] = new TH1D(bufname, bufname, ibin, vmin, vmax);
102 snprintf(bufname , 200, "DenReYlm%i%i%s", felsi[ihist], femsi[ihist]<0 ? felsi[ihist]-femsi[ihist] : femsi[ihist], name);
103 fdensreal[ihist] = new TH1D(bufname, bufname, ibin, vmin, vmax);
104 snprintf(bufname , 200, "DenImYlm%i%i%s", felsi[ihist], femsi[ihist]<0 ? felsi[ihist]-femsi[ihist] : femsi[ihist], name);
105 fdensimag[ihist] = new TH1D(bufname, bufname, ibin, vmin, vmax);
107 fnumsreal[ihist]->Sumw2();
108 fnumsimag[ihist]->Sumw2();
109 fdensreal[ihist]->Sumw2();
110 fdensimag[ihist]->Sumw2();
113 snprintf(bufname , 200, "BinCountNum%s", name);
114 fbinctn = new TH1D(bufname, bufname, ibin, vmin, vmax);
116 snprintf(bufname , 200, "BinCountDen%s", name);
117 fbinctd = new TH1D(bufname, bufname, ibin, vmin, vmax);
119 fYlmBuffer = (complex<double> *) malloc(sizeof(complex<double>) * fMaxJM);
121 // Covariance matrices
122 fcovmnum = (double *) malloc(sizeof(double) * fMaxJM * fMaxJM * 4 * ibin);
123 fcovmden = (double *) malloc(sizeof(double) * fMaxJM * fMaxJM * 4 * ibin);
128 AliFemtoYlm::InitializeYlms();
132 AliFemtoCorrFctnDirectYlm::AliFemtoCorrFctnDirectYlm():
156 // Default constructor
157 AliFemtoCorrFctnDirectYlm("AliFemtoCorrFctnDirectYlm",2);
160 AliFemtoCorrFctnDirectYlm::AliFemtoCorrFctnDirectYlm(const AliFemtoCorrFctnDirectYlm& aCorrFctn):
187 if (aCorrFctn.fbinctn)
188 ibin = aCorrFctn.fbinctn->GetNbinsX();
190 fMaxL = aCorrFctn.fMaxL;
191 fMaxJM = (fMaxL+1)*(fMaxL+1);
193 // Fill in factorials table
194 factorials = (double *) malloc(sizeof(double) * (4 * (fMaxL + 1)));
195 for (int iter=1; iter<4*(fMaxL+1); iter++)
197 factorials[iter] = aCorrFctn.factorials[iter];
200 // Fill in els and ems table
204 fels = (double *) malloc(sizeof(double) * (fMaxJM));
205 fems = (double *) malloc(sizeof(double) * (fMaxJM));
206 felsi = (int *) malloc(sizeof(int) * (fMaxJM));
207 femsi = (int *) malloc(sizeof(int) * (fMaxJM));
211 felsi[il] = (int) el;
212 femsi[il] = (int) em;
223 fnumsreal = (TH1D **) malloc(sizeof(TH1D *) * fMaxJM);
224 fnumsimag = (TH1D **) malloc(sizeof(TH1D *) * fMaxJM);
225 fdensreal = (TH1D **) malloc(sizeof(TH1D *) * fMaxJM);
226 fdensimag = (TH1D **) malloc(sizeof(TH1D *) * fMaxJM);
228 for (int ihist=0; ihist<fMaxJM; ihist++) {
229 if (aCorrFctn.fnumsreal[ihist])
230 fnumsreal[ihist] = new TH1D(*aCorrFctn.fnumsreal[ihist]);
232 fnumsreal[ihist] = 0;
233 if (aCorrFctn.fnumsimag[ihist])
234 fnumsimag[ihist] = new TH1D(*aCorrFctn.fnumsimag[ihist]);
236 fnumsimag[ihist] = 0;
237 if (aCorrFctn.fdensreal[ihist])
238 fdensreal[ihist] = new TH1D(*aCorrFctn.fdensreal[ihist]);
240 fdensreal[ihist] = 0;
241 if (aCorrFctn.fdensimag[ihist])
242 fdensimag[ihist] = new TH1D(*aCorrFctn.fdensimag[ihist]);
244 fdensimag[ihist] = 0;
247 if (aCorrFctn.fbinctn)
248 fbinctn = new TH1D(*aCorrFctn.fbinctn);
251 if (aCorrFctn.fbinctd)
252 fbinctd = new TH1D(*aCorrFctn.fbinctd);
256 fYlmBuffer = (complex<double> *) malloc(sizeof(complex<double>) * fMaxJM);
258 // Covariance matrices
259 fcovmnum = (double *) malloc(sizeof(double) * fMaxJM * fMaxJM * 4 * ibin);
260 fcovmden = (double *) malloc(sizeof(double) * fMaxJM * fMaxJM * 4 * ibin);
262 for (int iter=0; iter<fMaxJM * fMaxJM * 4 * ibin; iter++) {
263 fcovmnum[iter] = aCorrFctn.fcovmnum[iter];
264 fcovmden[iter] = aCorrFctn.fcovmden[iter];
267 if (aCorrFctn.fcovnum)
268 fcovnum = new TH3D(*aCorrFctn.fcovnum);
271 if (aCorrFctn.fcovden)
272 fcovden = new TH3D(*aCorrFctn.fcovden);
276 fSout = aCorrFctn.fSout;
277 fSside = aCorrFctn.fSside;
278 fSlong = aCorrFctn.fSlong;
280 if (aCorrFctn.fPairCut)
281 fPairCut = aCorrFctn.fPairCut;
283 fUseLCMS = aCorrFctn.fUseLCMS;
286 AliFemtoCorrFctnDirectYlm& AliFemtoCorrFctnDirectYlm::operator=(const AliFemtoCorrFctnDirectYlm& aCorrFctn)
288 // assignment operator
289 if (this == &aCorrFctn)
293 if (aCorrFctn.fbinctn)
294 ibin = aCorrFctn.fbinctn->GetNbinsX();
296 fMaxL = aCorrFctn.fMaxL;
297 fMaxJM = (fMaxL+1)*(fMaxL+1);
299 // Fill in factorials table
300 if (factorials) free (factorials);
301 factorials = (double *) malloc(sizeof(double) * (4 * (fMaxL + 1)));
302 for (int iter=1; iter<4*(fMaxL+1); iter++)
304 factorials[iter] = aCorrFctn.factorials[iter];
307 // Fill in els and ems table
312 if (fels) free (fels);
313 if (fems) free (fems);
314 if (felsi) free (felsi);
315 if (femsi) free (femsi);
317 fels = (double *) malloc(sizeof(double) * (fMaxJM));
318 fems = (double *) malloc(sizeof(double) * (fMaxJM));
319 felsi = (int *) malloc(sizeof(int) * (fMaxJM));
320 femsi = (int *) malloc(sizeof(int) * (fMaxJM));
324 felsi[il] = (int) el;
325 femsi[il] = (int) em;
336 if (fnumsreal) free (fnumsreal);
337 if (fnumsimag) free (fnumsimag);
338 if (fdensreal) free (fdensreal);
339 if (fdensimag) free (fdensimag);
341 fnumsreal = (TH1D **) malloc(sizeof(TH1D *) * fMaxJM);
342 fnumsimag = (TH1D **) malloc(sizeof(TH1D *) * fMaxJM);
343 fdensreal = (TH1D **) malloc(sizeof(TH1D *) * fMaxJM);
344 fdensimag = (TH1D **) malloc(sizeof(TH1D *) * fMaxJM);
346 for (int ihist=0; ihist<fMaxJM; ihist++) {
347 if (aCorrFctn.fnumsreal[ihist])
348 fnumsreal[ihist] = new TH1D(*aCorrFctn.fnumsreal[ihist]);
350 fnumsreal[ihist] = 0;
351 if (aCorrFctn.fnumsimag[ihist])
352 fnumsimag[ihist] = new TH1D(*aCorrFctn.fnumsimag[ihist]);
354 fnumsimag[ihist] = 0;
355 if (aCorrFctn.fdensreal[ihist])
356 fdensreal[ihist] = new TH1D(*aCorrFctn.fdensreal[ihist]);
358 fdensreal[ihist] = 0;
359 if (aCorrFctn.fdensimag[ihist])
360 fdensimag[ihist] = new TH1D(*aCorrFctn.fdensimag[ihist]);
362 fdensimag[ihist] = 0;
365 if (aCorrFctn.fbinctn)
366 fbinctn = new TH1D(*aCorrFctn.fbinctn);
369 if (aCorrFctn.fbinctd)
370 fbinctd = new TH1D(*aCorrFctn.fbinctd);
374 if (fYlmBuffer) free (fYlmBuffer);
376 fYlmBuffer = (complex<double> *) malloc(sizeof(complex<double>) * fMaxJM);
378 // Covariance matrices
380 if (fcovmnum) free (fcovmnum);
381 if (fcovmden) free (fcovmden);
383 fcovmnum = (double *) malloc(sizeof(double) * fMaxJM * fMaxJM * 4 * ibin);
384 fcovmden = (double *) malloc(sizeof(double) * fMaxJM * fMaxJM * 4 * ibin);
386 for (int iter=0; iter<fMaxJM * fMaxJM * 4 * ibin; iter++) {
387 fcovmnum[iter] = aCorrFctn.fcovmnum[iter];
388 fcovmden[iter] = aCorrFctn.fcovmden[iter];
391 if (aCorrFctn.fcovnum)
392 fcovnum = new TH3D(*aCorrFctn.fcovnum);
395 if (aCorrFctn.fcovden)
396 fcovden = new TH3D(*aCorrFctn.fcovden);
400 fSout = aCorrFctn.fSout;
401 fSside = aCorrFctn.fSside;
402 fSlong = aCorrFctn.fSlong;
404 if (aCorrFctn.fPairCut)
405 fPairCut = aCorrFctn.fPairCut;
407 fUseLCMS = aCorrFctn.fUseLCMS;
412 AliFemtoCorrFctnDirectYlm::~AliFemtoCorrFctnDirectYlm()
415 for (int ihist=0; ihist<fMaxJM; ihist++) {
416 delete fnumsreal[ihist];
417 delete fnumsimag[ihist];
418 delete fdensreal[ihist];
419 delete fdensimag[ihist];
445 if (fcovnum) delete fcovnum;
446 if (fcovden) delete fcovden;
448 if (fPairCut) delete fPairCut;
451 double AliFemtoCorrFctnDirectYlm::ClebschGordan(double aJot1, double aEm1, double aJot2, double aEm2, double aJot, double aEm)
453 // Calculate Clebsh-Gordan coefficient
459 maxt = lrint(aJot1 + aJot2 - aJot);
461 if (lrint(aJot1 - aEm1) < maxt) maxt = lrint(aJot1 - aEm1);
462 if (lrint(aJot2 + aEm2) < maxt) maxt = lrint(aJot2 + aEm2);
463 if (lrint(-(aJot-aJot2+aEm1)) > mint) mint = lrint(-(aJot-aJot2+aEm1));
464 if (lrint(-(aJot-aJot1-aEm2)) > mint) mint = lrint(-(aJot-aJot1-aEm2));
466 for (titer = mint; titer<=maxt; titer ++)
468 coef = TMath::Power(-1, titer);
469 coef *= TMath::Sqrt((2*aJot+1)*
470 factorials[lrint(aJot1+aEm1)] *
471 factorials[lrint(aJot1-aEm1)] *
472 factorials[lrint(aJot2+aEm2)] *
473 factorials[lrint(aJot2-aEm2)] *
474 factorials[lrint(aJot+aEm)] *
475 factorials[lrint(aJot-aEm)]);
476 coef /= (factorials[titer] *
477 factorials[lrint(aJot1+aJot2-aJot-titer)] *
478 factorials[lrint(aJot1-aEm1-titer)] *
479 factorials[lrint(aJot2+aEm2-titer)] *
480 factorials[lrint(aJot-aJot2+aEm1+titer)] *
481 factorials[lrint(aJot-aJot1-aEm2+titer)]);
486 cgc *= DeltaJ(aJot1, aJot2, aJot);
491 double AliFemtoCorrFctnDirectYlm::DeltaJ(double aJot1, double aJot2, double aJot)
493 // Calculate J for the Clebsh-Gordan coefficient
494 if ((aJot1+aJot2-aJot) < 0) {
495 // cout << "J1+J2-J3 < 0 !!!" << " " << aJot1 << " " << aJot2 << " " << aJot << endl;
498 if ((aJot1-aJot2+aJot) < 0) {
499 // cout << "J1-J2+J3 < 0 !!!" << " " << aJot1 << " " << aJot2 << " " << aJot << endl;
502 if ((-aJot1+aJot2+aJot) < 0) {
503 // cout << "-J1+J2+J3 < 0 !!!" << " " << aJot1 << " " << aJot2 << " " << aJot << endl;
506 if ((aJot1+aJot2+aJot+1) < 0) {
507 // cout << "J1+J2+J3+1 < 0 !!!" << " " << aJot1 << " " << aJot2 << " " << aJot << endl;
510 double res = TMath::Sqrt(1.0 *
511 factorials[lrint(aJot1+aJot2-aJot)] *
512 factorials[lrint(aJot1-aJot2+aJot)] *
513 factorials[lrint(-aJot1+aJot2+aJot)] /
514 factorials[lrint(aJot1+aJot2+aJot+1)]);
519 double AliFemtoCorrFctnDirectYlm::WignerSymbol(double aJot1, double aEm1, double aJot2, double aEm2, double aJot, double aEm)
522 if (lrint(aEm1+aEm2+aEm) != 0.0)
524 double cge = ClebschGordan(aJot1, aEm1, aJot2, aEm2, aJot, -aEm);
525 if (lrint(abs(aJot1 - aJot2 - aEm)) % 2)
527 cge /= sqrt(2*aJot + 1);
529 if (cge == -0.0) cge = 0.0;
535 void AliFemtoCorrFctnDirectYlm::GetMtilde(complex<double> *aMat, double *aMTilde)
537 // Create the Mtilde for a given q bin
546 complex<double> mcomp;
548 for (int izero = 0; izero<GetMaxJM(); izero++) {
549 GetElEmForIndex(izero, &lzero, &mzero);
550 GetElEmForIndex(izero, &lzeroi, &mzeroi);
551 for (int ibis = 0; ibis<GetMaxJM(); ibis++) {
552 GetElEmForIndex(ibis, &lbis, &mbis);
553 GetElEmForIndex(ibis, &lbisi, &mbisi);
554 complex<double> val = complex<double>(0.0, 0.0);
555 for (int iprim = 0; iprim<GetMaxJM(); iprim++) {
557 GetElEmForIndex(iprim, &lprim, &mprim);
558 GetElEmForIndex(iprim, &lprimi, &mprimi);
560 if (abs(mzeroi) % 2) mcomp = complex<double>(-1.0, 0.0); // (-1)^m
561 else mcomp = complex<double>(1.0, 0.0);
563 mcomp *= sqrt((2*lzero+1)*(2*lprim+1)*(2*lbis+1)); // P1
564 mcomp *= WignerSymbol(lzero, 0, lprim, 0, lbis, 0); // W1
565 mcomp *= WignerSymbol(lzero, -mzero, lprim, mprim, lbis, mbis); // W2
566 mcomp *= aMat[iprim];
569 aMTilde[(izero*2)*(2*GetMaxJM()) + (ibis*2)] = real(val);
570 aMTilde[(izero*2+1)*(2*GetMaxJM()) + (ibis*2)] = imag(val);
571 if (imag(val) != 0.0)
572 aMTilde[(izero*2)*(2*GetMaxJM()) + (ibis*2+1)] = -imag(val);
574 aMTilde[(izero*2)*(2*GetMaxJM()) + (ibis*2+1)] = 0.0;
575 aMTilde[(izero*2+1)*(2*GetMaxJM()) + (ibis*2+1)] = real(val);
581 int AliFemtoCorrFctnDirectYlm::GetMaxJM() const
584 void AliFemtoCorrFctnDirectYlm::GetElEmForIndex(int aIndex, double *aEl, double *aEm) const
586 // Get l,m for a given index
591 void AliFemtoCorrFctnDirectYlm::GetElEmForIndex(int aIndex, int *aEl, int *aEm) const
593 // Get l,m for a given index
594 *aEl = felsi[aIndex];
595 *aEm = femsi[aIndex];
598 int AliFemtoCorrFctnDirectYlm::GetBin(int qbin, int ilmzero, int zeroimag, int ilmprim, int primimag)
600 return (qbin*GetMaxJM()*GetMaxJM()*4 +
601 (ilmprim*2 + primimag) * GetMaxJM()*2 +
602 ilmzero*2 + zeroimag);
605 void AliFemtoCorrFctnDirectYlm::AddRealPair(double qout, double qside, double qlong, double weight)
608 double kv = sqrt(qout*qout + qside*qside + qlong*qlong);
609 int nqbin = fbinctn->GetXaxis()->FindFixBin(kv) - 1;
611 // Use saved ylm values for same qout, qside, qlong
612 if ((qout != fSout) || (qside != fSside) || (qlong != fSlong)) {
613 AliFemtoYlm::YlmUpToL(fMaxL, qout, qside, qlong, fYlmBuffer);
614 fSout = qout; fSside = qside; fSlong = qlong;
616 for (int ilm=0; ilm<GetMaxJM(); ilm++) {
617 // fYlmBuffer[ilm] = AliFemtoYlm::Ylm(elsi[ilm], emsi[ilm], qout, qside, qlong);
619 fnumsreal[ilm]->Fill(kv, real(fYlmBuffer[ilm])*weight);
620 fnumsimag[ilm]->Fill(kv, -imag(fYlmBuffer[ilm])*weight);
622 fbinctn->Fill(kv, 1.0);
625 // Fill in the error matrix
626 // int tabshift = nqbin*GetMaxJM()*GetMaxJM()*4;
627 if (nqbin < fbinctn->GetNbinsX())
628 for (int ilmzero=0; ilmzero<GetMaxJM(); ilmzero++)
629 for (int ilmprim=0; ilmprim<GetMaxJM(); ilmprim++) {
630 fcovmnum[GetBin(nqbin, ilmzero, 0, ilmprim, 0)] += real(fYlmBuffer[ilmzero])*real(fYlmBuffer[ilmprim])*weight*weight;
631 fcovmnum[GetBin(nqbin, ilmzero, 0, ilmprim, 1)] += real(fYlmBuffer[ilmzero])*-imag(fYlmBuffer[ilmprim])*weight*weight;
632 fcovmnum[GetBin(nqbin, ilmzero, 1, ilmprim, 0)] += -imag(fYlmBuffer[ilmzero])*real(fYlmBuffer[ilmprim])*weight*weight;
633 fcovmnum[GetBin(nqbin, ilmzero, 1, ilmprim, 1)] += -imag(fYlmBuffer[ilmzero])*-imag(fYlmBuffer[ilmprim])*weight*weight;
639 void AliFemtoCorrFctnDirectYlm::AddMixedPair(double qout, double qside, double qlong, double weight)
642 double kv = sqrt(qout*qout + qside*qside + qlong*qlong);
644 // Use saved ylm values for same qout, qside, qlong
645 if ((qout != fSout) || (qside != fSside) || (qlong != fSlong)) {
646 AliFemtoYlm::YlmUpToL(fMaxL, qout, qside, qlong, fYlmBuffer);
647 fSout = qout; fSside = qside; fSlong = qlong;
649 for (int ilm=0; ilm<GetMaxJM(); ilm++) {
650 // fYlmBuffer[ilm] = AliFemtoYlm::Ylm(elsi[ilm], emsi[ilm], qout, qside, qlong);
652 fdensreal[ilm]->Fill(kv, real(fYlmBuffer[ilm])*weight);
653 fdensimag[ilm]->Fill(kv, -imag(fYlmBuffer[ilm])*weight);
655 fbinctd->Fill(kv, 1.0);
658 // Fill in the error matrix
659 int nqbin = fbinctn->GetXaxis()->FindFixBin(kv) - 1;
660 // int tabshift = nqbin*GetMaxJM()*GetMaxJM()*4;
661 if (nqbin < fbinctn->GetNbinsX())
662 for (int ilmzero=0; ilmzero<GetMaxJM(); ilmzero++)
663 for (int ilmprim=0; ilmprim<GetMaxJM(); ilmprim++) {
664 fcovmden[GetBin(nqbin, ilmzero, 0, ilmprim, 0)] += real(fYlmBuffer[ilmzero])*real(fYlmBuffer[ilmprim]);
665 fcovmden[GetBin(nqbin, ilmzero, 0, ilmprim, 1)] += real(fYlmBuffer[ilmzero])*-imag(fYlmBuffer[ilmprim]);
666 fcovmden[GetBin(nqbin, ilmzero, 1, ilmprim, 0)] += -imag(fYlmBuffer[ilmzero])*real(fYlmBuffer[ilmprim]);
667 fcovmden[GetBin(nqbin, ilmzero, 1, ilmprim, 1)] += -imag(fYlmBuffer[ilmzero])*-imag(fYlmBuffer[ilmprim]);
672 void AliFemtoCorrFctnDirectYlm::AddRealPair(double *qvec, double weight) {
673 AddRealPair(qvec[0], qvec[1], qvec[2], weight);
676 void AliFemtoCorrFctnDirectYlm::AddMixedPair(double *qvec, double weight) {
677 AddMixedPair(qvec[0], qvec[1], qvec[2], weight);
680 void AliFemtoCorrFctnDirectYlm::Finish()
685 void AliFemtoCorrFctnDirectYlm::Write()
687 // Write out output histograms
688 if ((!fcovnum) || (!fcovden))
691 for (int ilm=0; ilm<fMaxJM; ilm++) {
692 fnumsreal[ilm]->Write();
693 fdensreal[ilm]->Write();
694 fnumsimag[ilm]->Write();
695 fdensimag[ilm]->Write();
697 if (fcovnum) fcovnum->Write();
698 if (fcovden) fcovden->Write();
701 TList* AliFemtoCorrFctnDirectYlm::GetOutputList()
703 // Prepare the list of objects to be written to the output
704 if ((!fcovnum) || (!fcovden))
707 TList *tOutputList = new TList();
709 for (int ilm=0; ilm<fMaxJM; ilm++) {
710 tOutputList->Add(fnumsreal[ilm]);
711 tOutputList->Add(fdensreal[ilm]);
712 tOutputList->Add(fnumsimag[ilm]);
713 tOutputList->Add(fdensimag[ilm]);
715 if (fcovnum) tOutputList->Add(fcovnum);
716 if (fcovden) tOutputList->Add(fcovden);
722 void AliFemtoCorrFctnDirectYlm::ReadFromFile(TFile *infile, const char *name, int maxl)
724 // Raad in the numerator and denominator from file
726 cout << "Cannot read function for L " << maxl << " into a container with L "<< fMaxL << endl;
729 cout << "Reading in numerators and denominators" << endl;
732 for (int ihist=0; ihist<fMaxJM; ihist++) {
733 snprintf(bufname , 200, "NumReYlm%i%i%s", felsi[ihist], femsi[ihist]<0 ? felsi[ihist]-femsi[ihist] : femsi[ihist], name);
734 if (fnumsreal[ihist]) delete fnumsreal[ihist];
735 fnumsreal[ihist] = new TH1D(*((TH1D *) infile->Get(bufname)));
737 snprintf(bufname , 200, "NumImYlm%i%i%s", felsi[ihist], femsi[ihist]<0 ? felsi[ihist]-femsi[ihist] : femsi[ihist], name);
738 if (fnumsimag[ihist]) delete fnumsimag[ihist];
739 fnumsimag[ihist] = new TH1D(*((TH1D *) infile->Get(bufname)));
741 snprintf(bufname , 200, "DenReYlm%i%i%s", felsi[ihist], femsi[ihist]<0 ? felsi[ihist]-femsi[ihist] : femsi[ihist], name);
742 if (fdensreal[ihist]) delete fdensreal[ihist];
743 fdensreal[ihist] = new TH1D(*((TH1D *) infile->Get(bufname)));
745 snprintf(bufname , 200, "DenImYlm%i%i%s", felsi[ihist], femsi[ihist]<0 ? felsi[ihist]-femsi[ihist] : femsi[ihist], name);
746 if (fdensimag[ihist]) delete fdensimag[ihist];
747 fdensimag[ihist] = new TH1D(*((TH1D *) infile->Get(bufname)));
750 if (fcovnum) delete fcovnum;
751 snprintf(bufname , 200, "covNum%s", name);
752 fcovnum = new TH3D (*((TH3D *) infile->Get(bufname)));
754 if (fcovden) delete fcovden;
755 snprintf(bufname , 200, "CovDen%s", name);
756 fcovden = new TH3D (*((TH3D *) infile->Get(bufname)));
758 if ((fcovnum) && (fcovden)) {
759 cout << "Unpacking covariance matrices from file " << endl;
764 cout << "Creating fake covariance matrices" << endl;
766 for (int ibin=1; ibin<=fnumsreal[0]->GetNbinsX(); ibin++) {
767 double nent = fnumsreal[0]->GetEntries();
768 double nentd = fdensreal[0]->GetEntries();
769 for (int ilmx=0; ilmx<GetMaxJM(); ilmx++) {
770 for (int ilmy=0; ilmy<GetMaxJM(); ilmy++) {
771 double t1t2rr = fnumsreal[ilmx]->GetBinContent(ibin)*fnumsreal[ilmy]->GetBinContent(ibin)/nent/nent;
772 double t1t2ri = fnumsreal[ilmx]->GetBinContent(ibin)*fnumsimag[ilmy]->GetBinContent(ibin)/nent/nent;
773 double t1t2ir = fnumsimag[ilmx]->GetBinContent(ibin)*fnumsreal[ilmy]->GetBinContent(ibin)/nent/nent;
774 double t1t2ii = fnumsimag[ilmx]->GetBinContent(ibin)*fnumsimag[ilmy]->GetBinContent(ibin)/nent/nent;
776 fcovmnum[GetBin(ibin-1, ilmx, 0, ilmy, 0)] = nent*(TMath::Power(fnumsreal[ilmx]->GetBinError(ibin)/nent,2)*(nent-1) + t1t2rr);
777 fcovmnum[GetBin(ibin-1, ilmx, 0, ilmy, 1)] = nent*t1t2ri;
778 fcovmnum[GetBin(ibin-1, ilmx, 1, ilmy, 0)] = nent*t1t2ir;
779 fcovmnum[GetBin(ibin-1, ilmx, 1, ilmy, 1)] = nent*(TMath::Power(fnumsimag[ilmx]->GetBinError(ibin)/nent,2)*(nent-1) + t1t2rr);
782 fcovmnum[GetBin(ibin-1, ilmx, 0, ilmy, 0)] = nent*t1t2rr;
783 fcovmnum[GetBin(ibin-1, ilmx, 0, ilmy, 1)] = nent*t1t2ri;
784 fcovmnum[GetBin(ibin-1, ilmx, 1, ilmy, 0)] = nent*t1t2ir;
785 fcovmnum[GetBin(ibin-1, ilmx, 1, ilmy, 1)] = nent*t1t2ii;
787 t1t2rr = fdensreal[ilmx]->GetBinContent(ibin)*fdensreal[ilmy]->GetBinContent(ibin)/nentd/nentd;
788 t1t2ri = fdensreal[ilmx]->GetBinContent(ibin)*fdensimag[ilmy]->GetBinContent(ibin)/nentd/nentd;
789 t1t2ir = fdensimag[ilmx]->GetBinContent(ibin)*fdensreal[ilmy]->GetBinContent(ibin)/nentd/nentd;
790 t1t2ii = fdensimag[ilmx]->GetBinContent(ibin)*fdensimag[ilmy]->GetBinContent(ibin)/nentd/nentd;
792 fcovmden[GetBin(ibin-1, ilmx, 0, ilmy, 0)] = nentd*t1t2rr;
793 fcovmden[GetBin(ibin-1, ilmx, 0, ilmy, 1)] = nentd*t1t2ri;
794 fcovmden[GetBin(ibin-1, ilmx, 1, ilmy, 0)] = nentd*t1t2ir;
795 fcovmden[GetBin(ibin-1, ilmx, 1, ilmy, 1)] = nentd*t1t2ii;
801 // Recalculating the correlation functions
805 int AliFemtoCorrFctnDirectYlm::PackYlmVector(const double *invec, double *outvec)
807 // Pack a vector in l,m into an array using
808 // only independent components
811 for (int ilm=0; ilm<GetMaxJM(); ilm++) {
812 GetElEmForIndex(ilm, &el, &em);
813 outvec[ioutcount++] = invec[ilm*2];
816 outvec[ioutcount++] = invec[ilm*2 + 1];
822 int AliFemtoCorrFctnDirectYlm::PackYlmMatrix(const double *inmat, double *outmat)
824 // Pack a matrix in l,m x l,m into an array using
825 // only independent components
832 for (int ilm=0; ilm<GetMaxJM(); ilm++) {
833 GetElEmForIndex(ilm, &elz, &emz);
835 if (emz == 0) continue;
839 for (int ilmz=0; ilmz<GetMaxJM(); ilmz++) {
840 GetElEmForIndex(ilmz, &elz, &emz);
842 for (int ilmp=0; ilmp<GetMaxJM(); ilmp++) {
843 GetElEmForIndex(ilmp, &elp, &emp);
844 outmat[ioutcountz*finalsize + ioutcountp] = inmat[GetBin(0, ilmz, 0, ilmp, 0)];
846 if (emp == 0) continue;
847 outmat[ioutcountz*finalsize + ioutcountp] = inmat[GetBin(0, ilmz, 0, ilmp, 1)];
852 if (emz == 0) continue;
854 for (int ilmp=0; ilmp<GetMaxJM(); ilmp++) {
855 GetElEmForIndex(ilmp, &elp, &emp);
856 outmat[ioutcountz*finalsize + ioutcountp] = inmat[GetBin(0, ilmz, 1, ilmp, 0)];
858 if (emp == 0) continue;
859 outmat[ioutcountz*finalsize + ioutcountp] = inmat[GetBin(0, ilmz, 1, ilmp, 1)];
868 void AliFemtoCorrFctnDirectYlm::PackCovariances()
870 // Migrate the covariance matrix into a 3D histogram for storage
872 snprintf(bufname , 200, "CovNum%s", fnumsreal[0]->GetName()+10);
874 // if (fcovnum) delete fcovnum;
876 fcovnum = new TH3D(bufname,bufname,
877 fnumsreal[0]->GetNbinsX(), fnumsreal[0]->GetXaxis()->GetXmin(), fnumsreal[0]->GetXaxis()->GetXmax(),
878 GetMaxJM()*2, -0.5, GetMaxJM()*2 - 0.5,
879 GetMaxJM()*2, -0.5, GetMaxJM()*2 - 0.5);
881 for (int ibin=1; ibin<=fcovnum->GetNbinsX(); ibin++)
882 for (int ilmz=0; ilmz<GetMaxJM()*2; ilmz++)
883 for (int ilmp=0; ilmp<GetMaxJM()*2; ilmp++)
884 fcovnum->SetBinContent(ibin, ilmz+1, ilmp+1, fcovmnum[GetBin(ibin-1, ilmz/2, ilmz%2, ilmp/2, ilmp%2)]);
886 snprintf(bufname , 100, "CovDen%s", fnumsreal[0]->GetName()+10);
888 // if (fcovden) delete fcovden;
890 fcovden = new TH3D(bufname,bufname,
891 fdensreal[0]->GetNbinsX(), fdensreal[0]->GetXaxis()->GetXmin(), fdensreal[0]->GetXaxis()->GetXmax(),
892 GetMaxJM()*2, -0.5, GetMaxJM()*2 - 0.5,
893 GetMaxJM()*2, -0.5, GetMaxJM()*2 - 0.5);
895 for (int ibin=1; ibin<=fcovden->GetNbinsX(); ibin++)
896 for (int ilmz=0; ilmz<GetMaxJM()*2; ilmz++)
897 for (int ilmp=0; ilmp<GetMaxJM()*2; ilmp++)
898 fcovden->SetBinContent(ibin, ilmz+1, ilmp+1, fcovmden[GetBin(ibin-1, ilmz/2, ilmz%2, ilmp/2, ilmp%2)]);
902 void AliFemtoCorrFctnDirectYlm::UnpackCovariances()
904 // Extract the covariance matrices from storage
906 for (int ibin=1; ibin<=fcovnum->GetNbinsX(); ibin++)
907 for (int ilmz=0; ilmz<GetMaxJM()*2; ilmz++)
908 for (int ilmp=0; ilmp<GetMaxJM()*2; ilmp++)
909 fcovmnum[GetBin(ibin-1, ilmz/2, ilmz%2, ilmp/2, ilmp%2)] = fcovnum->GetBinContent(ibin, ilmz+1, ilmp+1);
913 for (int ibin=1; ibin<=fcovden->GetNbinsX(); ibin++)
914 for (int ilmz=0; ilmz<GetMaxJM()*2; ilmz++)
915 for (int ilmp=0; ilmp<GetMaxJM()*2; ilmp++)
916 fcovmden[GetBin(ibin-1, ilmz/2, ilmz%2, ilmp/2, ilmp%2)] = fcovden->GetBinContent(ibin, ilmz+1, ilmp+1);
920 int AliFemtoCorrFctnDirectYlm::GetIndexForLM(int el, int em) const
922 // Get array index for a given l,m
923 for (int iter=0; iter<fMaxJM; iter++)
924 if ((el == felsi[iter]) && (em == femsi[iter]))
929 TH1D *AliFemtoCorrFctnDirectYlm::GetNumRealHist(int el, int em)
931 // Get numerator hist for a given l,m
932 if (GetIndexForLM(el, em)>=0)
933 return fnumsreal[GetIndexForLM(el, em)];
937 TH1D *AliFemtoCorrFctnDirectYlm::GetNumImagHist(int el, int em)
939 // Get numerator hist for a given l,m
940 if (GetIndexForLM(el, em)>=0)
941 return fnumsimag[GetIndexForLM(el, em)];
946 TH1D *AliFemtoCorrFctnDirectYlm::GetDenRealHist(int el, int em)
948 // Get denominator hist for a given l,m
949 if (GetIndexForLM(el, em)>=0)
950 return fdensreal[GetIndexForLM(el, em)];
954 TH1D *AliFemtoCorrFctnDirectYlm::GetDenImagHist(int el, int em)
956 // Get denominator hist for a given l,m
957 if (GetIndexForLM(el, em)>=0)
958 return fdensimag[GetIndexForLM(el, em)];
963 AliFemtoString AliFemtoCorrFctnDirectYlm::Report()
965 return "AliFemtoCorrFctnDirectYlm::Finish";
968 void AliFemtoCorrFctnDirectYlm::AddRealPair(AliFemtoPair* aPair)
970 // Fill in the numerator
972 if (!fPairCut->Pass(aPair)) return;
975 AddRealPair(aPair->QOutCMS(), aPair->QSideCMS(), aPair->QLongCMS(), 1.0);
977 AddRealPair(aPair->KOut(), aPair->KSide(), aPair->KLong(), 1.0);
980 void AliFemtoCorrFctnDirectYlm::AddMixedPair(AliFemtoPair* aPair)
982 // Fill in the denominator
984 if (!fPairCut->Pass(aPair)) return;
987 AddMixedPair(aPair->QOutCMS(), aPair->QSideCMS(), aPair->QLongCMS(), 1.0);
989 AddMixedPair(aPair->KOut(), aPair->KSide(), aPair->KLong(), 1.0);
992 void AliFemtoCorrFctnDirectYlm::SetUseLCMS(int aUseLCMS)
997 int AliFemtoCorrFctnDirectYlm::GetUseLCMS()