19 #include "FairEventHeader.h"
20 #include "FairRootManager.h"
22 #include <TClonesArray.h>
23 #include <TGeoManager.h>
26 #include <TMatrixFLazy.h>
43 : FairTask(
"MuchFindVectorsGem")
56 for (Int_t
i = 0;
i < 9; ++
i)
68 for (map<Int_t, TDecompLU*>::iterator it =
fLus.begin(); it !=
fLus.end();
78 FairRootManager* ioman = FairRootManager::Instance();
79 if (ioman == NULL) Fatal(
"Init",
"RootManager not instantiated!");
82 fTrackArray =
static_cast<TClonesArray*
>(ioman->GetObject(
"MuchVector"));
84 fTrackArray =
new TClonesArray(
"CbmMuchTrack", 100);
85 ioman->Register(
"MuchVector",
"Much",
fTrackArray, kTRUE);
90 fVecPool =
new TClonesArray(
"CbmMuchTrack", 1000);
99 fHits =
static_cast<TClonesArray*
>(ioman->GetObject(
"MuchPixelHit"));
100 fClusters =
static_cast<TClonesArray*
>(ioman->GetObject(
"MuchCluster"));
101 fDigiMatches =
static_cast<TClonesArray*
>(ioman->GetObject(
"MuchDigiMatch"));
102 fTrdVectors =
static_cast<TClonesArray*
>(ioman->GetObject(
"TrdVector"));
105 if (NULL == mcManager) LOG(fatal) << GetName() <<
": No CbmMCDataManager!";
111 for (Int_t
i = 0;
i < nSt; ++
i) {
122 for (Int_t lay = 0; lay < nLays; ++lay) {
125 for (Int_t iside = 0; iside < 2; ++iside) {
127 Int_t plane = lay * 2 + iside;
150 TString tag, fileName;
153 cout <<
" ******* MUCH tag ******** " << tag << endl;
154 tag.Prepend(
"much_");
156 Double_t dzAbs[9] = {0}, zAbs[9] = {0}, radlAbs[9] = {0}, xyzl[3] = {0},
159 TGeoVolume* vol = NULL;
160 TGeoNode* much = NULL;
163 gGeoManager->CdTop();
164 TGeoNode* cave = gGeoManager->GetCurrentNode();
165 for (Int_t iNode = 0; iNode < cave->GetNdaughters(); iNode++) {
166 TGeoNode* node = cave->GetDaughter(iNode);
167 TString name = node->GetName();
168 if (name.Contains(
"much")) {
170 gGeoManager->CdDown(iNode);
175 TGeoVolume* muchV = gGeoManager->GetVolume(tag);
176 Int_t ndaught = muchV->GetNdaughters();
179 for (Int_t
i = 0;
i < ndaught; ++
i) {
180 vol = muchV->GetNode(
i)->GetVolume();
181 if (!(TString(vol->GetName()).Contains(
"absorber")))
continue;
182 gGeoManager->CdDown(
i);
183 nAbs = vol->GetNdaughters();
186 for (Int_t iabs = 0; iabs < nAbs; ++iabs) {
187 TGeoVolume* block = vol->GetNode(iabs)->GetVolume();
188 gGeoManager->CdDown(iabs);
189 TGeoVolume* abso = block->GetNode(0)->GetVolume();
190 gGeoManager->CdDown(0);
192 gGeoManager->LocalToMaster(xyzl, xyzg);
193 zAbs[iabs] = xyzg[2];
196 dzAbs[iabs] = ((TGeoBBox*) abso->GetShape())->GetDZ();
197 radlAbs[iabs] = abso->GetMaterial()->GetRadLen();
198 fZabs0[iabs][0] = zAbs[iabs] - dzAbs[iabs];
199 fZabs0[iabs][1] = zAbs[iabs] + dzAbs[iabs];
200 fX0abs[iabs] = radlAbs[iabs];
207 for (Int_t
i = 1;
i < nAbs; ++
i) {
219 cout <<
" \n !!! MUCH Absorbers: " << nAbs <<
"\n Zbeg, Zend, X0:";
220 for (Int_t j = 0; j < nAbs; ++j)
221 cout <<
" " << std::setprecision(4) <<
fZabs0[j][0] <<
", " <<
fZabs0[j][1]
222 <<
", " <<
fX0abs[j] <<
";";
223 cout << endl << endl;
227 Double_t errs[9] = {0.6, 0.8, 1.2, 1.7, 0};
228 for (Int_t j = 0; j <
fgkStat; ++j)
246 FairTask* strawHitFinder =
247 FairRun::Instance()->GetTask(
"CbmMuchFindHitsStraws");
260 for (Int_t ista =
fgkStat - 1; ista >= 0; --ista) {
285 for (map<Int_t, TDecompLU*>::iterator it =
fLus.begin(); it !=
fLus.end();
304 Int_t pattMax = 1 <<
fgkPlanes, nDouble = 0, nTot = 0;
307 for (Int_t ipat = 1; ipat < pattMax; ++ipat) {
313 if (ipat & (3 << j)) ++nDouble;
314 if (nDouble <
fgkPlanes / 2 - 1)
continue;
318 onoff[j] = (ipat & (1 << j));
322 if (!onoff[
i])
continue;
325 coef(0, 2) +=
fDz[
i];
329 if (!onoff[
i])
continue;
333 coef(1, 3) +=
fDz[
i];
336 if (!onoff[
i])
continue;
337 coef(2, 0) +=
fDz[
i];
339 coef(2, 2) += dz2[
i];
343 if (!onoff[
i])
continue;
345 coef(3, 1) +=
fDz[
i];
347 coef(3, 3) += dz2[
i];
350 TDecompLU* lu =
new TDecompLU(4);
352 lu->SetTol(0.1 * lu->GetTol());
354 fLus.insert(pair<Int_t, TDecompLU*>(ipat, lu));
356 cov.SetMatrixArray(coef.GetMatrixArray());
358 fMatr.insert(pair<Int_t, TMatrixDSym*>(ipat,
new TMatrixDSym(cov)));
361 buf += Bool_t(ipat & (1 << jp));
362 Info(
"ComputeMatrix",
363 " Determinant: %s %i %f",
369 Info(
"ComputeMatrix",
" Number of configurations: %i", nTot);
373 cout << TMath::Sqrt(cov(0, 0)) <<
" " << TMath::Sqrt(cov(1, 1)) <<
" "
374 << TMath::Sqrt(cov(2, 2)) <<
" " << TMath::Sqrt(cov(3, 3)) << endl;
375 cov *= (1.7 * 1.7 / 1.2 / 1.2);
376 cout << TMath::Sqrt(cov(0, 0)) <<
" " << TMath::Sqrt(cov(1, 1)) <<
" "
377 << TMath::Sqrt(cov(2, 2)) <<
" " << TMath::Sqrt(cov(3, 3)) << endl;
386 for (Int_t ista = 0; ista <
fgkStat; ++ista) {
394 Int_t nHits =
fHits->GetEntriesFast(), nSelTu[
fgkStat] = {0}, sel = 0;
395 for (Int_t
i = 0;
i < nHits; ++
i) {
413 pair<Int_t, Int_t>(sector,
i));
415 pair<Double_t, Int_t>(hit->
GetX(),
i));
427 Int_t nSel = 2, idSel[2] = {0, 1},
id = 0;
429 for (Int_t
i = 0;
i < nSel; ++
i) {
438 for (Int_t ip = 0; ip < np; ++ip) {
445 id = point->GetTrackID();
446 if (
id == idSel[
i])
return kTRUE;
457 vector<pair<Double_t, Double_t>>& vecDowns) {
460 Int_t nvec = 0, straw = 0;
464 }
else if (ista !=
fgkStat - 1)
467 for (Int_t
i = 0;
i < nvec; ++
i) {
470 if (tr->GetUniqueID() != ista + 1)
continue;
472 Double_t zbeg = parFirst.GetZ();
475 Double_t
x = parFirst.GetX() + dz * parFirst.GetTx();
476 Double_t
y = parFirst.GetY() + dz * parFirst.GetTy();
477 vecDowns.push_back(pair<Double_t, Double_t>(
x,
y));
479 return vecDowns.size();
488 const Double_t window0 = 5.0;
494 for (Int_t ista = ista0; ista >= ista0; --ista) {
499 if (
fRmax[ista] < 1.0)
continue;
501 Int_t lay2 =
fgkPlanes / 2 - 1, patt = 0, flag = 0,
502 nhits =
fHitPl[ista][lay2].size();
503 cout <<
" Hits: " << ista <<
" " << lay2 <<
" " << nhits << endl;
504 vector<pair<Double_t, Double_t>> vecDowns;
506 multimap<Double_t, Int_t>::iterator mit, mitb, mite, mit1;
507 Double_t window = window0;
520 vecDowns.push_back(pair<Double_t, Double_t>(0.0, 0.0));
521 vecDowns.push_back(pair<Double_t, Double_t>(0.0, 0.0));
528 for (Int_t iv = 0; iv < nvec; ++iv) {
529 if (ista > 1 && iv == 1) --lay2;
530 Double_t xv = vecDowns[iv].first, yv = vecDowns[iv].second;
531 mitb =
fHitX[ista][lay2].lower_bound(xv - window);
532 mite =
fHitX[ista][lay2].upper_bound(xv + window);
543 Double_t ywin1 = yv - window, ywin2 = yv + window;
545 for (mit = mitb; mit != mite; ++mit) {
547 fHitX[ista][lay2].erase(mit1);
550 Int_t indx = mit->second;
552 if (hit->
GetY() < ywin1 || hit->
GetY() > ywin2)
continue;
574 if (inWin == 0 && ista == 1) {
577 window = window0 * 1.5;
579 fHitX[ista][lay2].lower_bound(xv - window);
581 fHitX[ista][lay2].upper_bound(xv + window);
584 for (mit = mitb; mit != mite; ++mit) {
587 fHitX[ista][lay2].erase(mit1);
591 Int_t indx = mit->second;
593 if (hit->
GetY() < yv - window || hit->
GetY() > yv + window)
continue;
621 vector<pair<Double_t, Double_t>>& vecDowns) {
626 for (Int_t
i = 0;
i < nvec; ++
i) {
629 Double_t zbeg = parFirst.GetZ();
632 Double_t
x = parFirst.GetX() + dz * parFirst.GetTx();
633 Double_t
y = parFirst.GetY() + dz * parFirst.GetTy();
634 vecDowns.push_back(pair<Double_t, Double_t>(
x,
y));
636 return vecDowns.size();
652 const Double_t cut[2][2] = {{0.4, 0.5}, {0.4, 0.5}};
654 Double_t pars[4] = {0.0};
655 Int_t nhits =
fHitPl[ista][lay2].size();
657 Int_t sec0 = (patt & (1 << lay2 * 2 + 3)) ?
fXyi[lay2 * 2 + 3][0]
658 :
fXyi[lay2 * 2 + 2][0];
659 multimap<Int_t, Int_t>::iterator it;
660 pair<multimap<Int_t, Int_t>::iterator, multimap<Int_t, Int_t>::iterator> ret;
663 for (Int_t dsec = -1; dsec < 2; ++dsec) {
664 Int_t isec = sec0 + dsec;
667 else if (isec ==
fNsect[ista])
670 ret =
fHitPl[ista][lay2].equal_range(isec);
671 for (it = ret.first; it != ret.second; ++it) {
672 Int_t indx = it->second, sector = it->first;
688 Int_t lay0 = TString::Itoa(patt, 2).Length() - 1;
689 Double_t dx =
fXy[lay][0] -
fXy[lay0][0];
690 Double_t dz =
fXy[lay][4] -
fXy[lay0][4];
691 Double_t dTx = TMath::Abs(dx / dz -
fXy[lay][0] /
fXy[lay][4]);
692 if (TMath::Abs(dTx) > cut[0][TMath::Min(ista, 1)])
continue;
693 Double_t dy =
fXy[lay][1] -
fXy[lay0][1];
694 Double_t dTy = TMath::Abs(dy / dz -
fXy[lay][1] /
fXy[lay][4]);
695 if (TMath::Abs(dTy) > cut[1][TMath::Min(ista, 1)])
continue;
697 fXyi[lay][0] = sector;
701 patt &= ~(1 << lay2 * 2);
702 patt &= ~(1 << lay2 * 2 + 1);
713 Double_t chi2 =
FindChi2(ista, patt, pars);
717 ista, patt, chi2, pars);
731 Bool_t refit = kFALSE;
737 Refit(patt, chi2, pars, cov);
746 Int_t npool =
fVecPool->GetEntriesFast();
750 FairTrackParam par(pars[0], pars[1],
fZ0[ista], pars[2], pars[3], 0.0, cov);
756 track->SetUniqueID(ista);
758 for (Int_t ipl = 0; ipl <
fgkPlanes; ++ipl) {
759 if (!(patt & (1 << ipl)))
continue;
773 map<Int_t, Int_t> ids;
776 for (Int_t ih = 0; ih < nhits; ++ih) {
782 for (Int_t j = 0; j < nDigis; ++j) {
786 for (Int_t ip = 0; ip < np; ++ip) {
794 id = point->GetTrackID();
796 if (ids.find(
id) == ids.end())
797 ids.insert(pair<Int_t, Int_t>(
id, 1));
804 Int_t maxim = -1, idmax = -9;
805 for (map<Int_t, Int_t>::iterator it = ids.begin(); it != ids.end(); ++it) {
806 if (it->second > maxim) {
821 Bool_t ok = kFALSE, onoff;
824 onoff = patt & (1 <<
i);
825 if (!onoff)
continue;
833 TVectorD solve =
fLus[patt]->Solve(b, ok);
836 for (Int_t
i = 0;
i < 4; ++
i)
850 Double_t chi2 = 0,
x = 0,
y = 0;
854 onoff = patt & (1 <<
i);
855 if (!onoff)
continue;
856 x = pars[0] + pars[2] *
fDz[
i];
857 y = pars[1] + pars[3] *
fDz[
i];
874 const Double_t cut[2] = {0.7, 0.7};
877 for (Int_t ista = ista0; ista <= ista0; ++ista) {
880 for (Int_t iv = 0; iv < nvec; ++iv) {
883 Double_t dTx = params->GetTx() - params->GetX() / params->GetZ();
884 if (TMath::Abs(dTx) > cut[0])
887 Double_t dTy = params->GetTy() - params->GetY() / params->GetZ();
888 if (TMath::Abs(dTy) > cut[1]) vec->
SetChiSq(-1.0);
892 for (Int_t iv = nvec - 1; iv >= 0; --iv) {
897 cout <<
" Vectors after parameter check in station " << ista <<
": " << nvec
898 <<
" " <<
fVectors[ista].size() << endl;
901 for (Int_t iv = 0; iv < nvec; ++iv) {
907 fSecVec[ista].insert(pair<Int_t, CbmMuchTrack*>(isec, vec));
997 Int_t nthr = 2, planes[20];
999 pair<multimap<Int_t, CbmMuchTrack*>::iterator,
1000 multimap<Int_t, CbmMuchTrack*>::iterator>
1002 multimap<Int_t, CbmMuchTrack*>::iterator itsec;
1005 for (Int_t ista = ista0; ista <= ista0; ++ista) {
1007 Int_t nvec =
fVectors[ista].size();
1009 for (Int_t isec = 0; isec <
fNsect[ista]; ++isec) {
1010 ret =
fSecVec[ista].equal_range(isec);
1012 multimap<Double_t, CbmMuchTrack*> qMap;
1013 multimap<Double_t, CbmMuchTrack*>::iterator it, it1;
1015 for (itsec = ret.first; itsec != ret.second; ++itsec) {
1019 qMap.insert(pair<Double_t, CbmMuchTrack*>(-qual, vec));
1022 for (it = qMap.begin(); it != qMap.end(); ++it) {
1029 for (Int_t ih = 0; ih < nhits; ++ih) {
1039 for (++it1; it1 != qMap.end(); ++it1) {
1041 if (vec1->
GetChiSq() < 0)
continue;
1042 Int_t nsame = 0, same[
fgkPlanes / 2] = {0};
1047 for (Int_t ih = 0; ih < nhits1; ++ih) {
1052 if (planes[lay * 2 + side] >= 0) {
1053 if (vec1->
GetHitIndex(ih) == planes[lay * 2 + side])
1058 for (Int_t lay = 0; lay <
fgkPlanes / 2; ++lay)
1061 if (nsame >= nthr) {
1064 if (nhits > nhits1 + 0) clone = 1;
1074 for (Int_t iv = nvec - 1; iv >= 0; --iv) {
1079 cout <<
" Vectors after clones removed: " << nvec <<
" "
1091 Int_t nHitsTot =
fHits->GetEntriesFast();
1093 for (Int_t ist = 0; ist <
fgkStat; ++ist) {
1097 for (Int_t iv = 0; iv < nvec; ++iv) {
1130 for (count = 0;
x; count++)
1151 TMatrixD coef(4, 4);
1154 onoff[j] = (patt & (1 << j));
1155 if (!onoff[j])
continue;
1156 errx2[j] =
fXy[j][2] *
fXy[j][2];
1157 erry2[j] =
fXy[j][3] *
fXy[j][3];
1162 if (!onoff[
i])
continue;
1163 coef(0, 0) += 1 / errx2[
i];
1165 coef(0, 2) +=
fDz[
i] / errx2[
i];
1169 if (!onoff[
i])
continue;
1171 coef(1, 1) += 1 / erry2[
i];
1173 coef(1, 3) +=
fDz[
i] / erry2[
i];
1176 if (!onoff[
i])
continue;
1177 coef(2, 0) +=
fDz[
i] / errx2[
i];
1179 coef(2, 2) += dz2[
i] / errx2[
i];
1183 if (!onoff[
i])
continue;
1185 coef(3, 1) +=
fDz[
i] / erry2[
i];
1187 coef(3, 3) += dz2[
i] / erry2[
i];
1198 lu.SetTol(0.1 * lu.GetTol());
1204 if (!onoff[
i])
continue;
1205 b[0] +=
fXy[
i][0] / errx2[
i];
1206 b[1] +=
fXy[
i][1] / erry2[
i];
1214 TVectorD solve = lu.Solve(b, ok);
1215 for (Int_t
i = 0;
i < 4; ++
i)
1218 cov.SetMatrixArray(coef.GetMatrixArray());
1222 Double_t
x = 0,
y = 0;
1226 if (!onoff[
i])
continue;
1227 x = pars[0] + pars[2] *
fDz[
i];
1228 y = pars[1] + pars[3] *
fDz[
i];
1229 Double_t dx = (
x -
fXy[
i][0]) /
fXy[
i][2];
1230 Double_t dy = (
y -
fXy[
i][1]) /
fXy[
i][3];
1242 const Int_t iabs = 1;
1245 TMatrixF matr = TMatrixF(5, 5);
1246 TMatrixF unit(TMatrixF::kUnit, matr);
1248 for (Int_t ista = 0; ista <
fgkStat; ++ista) {
1249 Int_t nvec =
fVectors[ista].size();
1252 for (Int_t iv = 0; iv < nvec; ++iv) {
1255 Double_t zbeg = parFirst.GetZ();
1256 Double_t dz =
fZabs0[iabs][0] - zbeg;
1258 parFirst.SetX(parFirst.GetX() + dz * parFirst.GetTx());
1259 parFirst.SetY(parFirst.GetY() + dz * parFirst.GetTy());
1260 parFirst.SetZ(parFirst.GetZ() + dz);
1262 parFirst.CovMatrix(cov);
1265 ff(2, 0) = ff(3, 1) = dz;
1266 TMatrixF cf(cov, TMatrixF::kMult, ff);
1267 TMatrixF fcf(ff, TMatrixF::kTransposeMult, cf);
1268 cov.SetMatrixArray(fcf.GetMatrixArray());
1271 ista + iabs * 2,
fZabs0[iabs],
fX0abs[iabs], parFirst, cov, 0);
1273 parFirst.SetCovMatrix(cov);
1278 Int_t ista0 = 0, ista1 = 1;
1279 vector<Int_t> matchOK[2];
1281 matchOK[0].assign(nvec0, -1);
1282 matchOK[1].assign(nvec1, -1);
1284 for (Int_t iv = 0; iv < nvec0; ++iv) {
1290 Float_t pars1[5] = {(Float_t) par1.GetX(),
1291 (Float_t) par1.GetY(),
1292 (Float_t) par1.GetTx(),
1293 (Float_t) par1.GetTy(),
1295 TMatrixF p1(5, 1, pars1);
1296 TMatrixF wp1(w1, TMatrixF::kTransposeMult, p1);
1298 for (Int_t iv1 = 0; iv1 < nvec1; ++iv1) {
1303 TMatrixFSym w20 = w2;
1304 Float_t pars2[5] = {(Float_t) par2.GetX(),
1305 (Float_t) par2.GetY(),
1306 (Float_t) par2.GetTx(),
1307 (Float_t) par2.GetTy(),
1309 TMatrixF p2(5, 1, pars2);
1310 TMatrixF wp2(w2, TMatrixF::kTransposeMult, p2);
1314 TMatrixF p12(w2, TMatrixF::kTransposeMult, wp2);
1317 TMatrixF p122 = p12;
1318 TMatrixF pMerge = p12;
1320 TMatrixF wDp1(w1, TMatrixF::kMult, p12);
1321 TMatrixF chi21(p12, TMatrixF::kTransposeMult, wDp1);
1323 TMatrixF wDp2(w20, TMatrixF::kMult, p122);
1324 TMatrixF chi22(p122, TMatrixF::kTransposeMult, wDp2);
1325 Double_t c2 = chi21(0, 0) + chi22(0, 0);
1327 if (c2 < 0 || c2 >
fCutChi2[0])
continue;
1328 matchOK[0][iv] = matchOK[1][iv1] = 1;
1330 parOk.SetX(pMerge(0, 0));
1331 parOk.SetY(pMerge(1, 0));
1332 parOk.SetZ(par2.GetZ());
1333 parOk.SetTx(pMerge(2, 0));
1334 parOk.SetTy(pMerge(3, 0));
1335 parOk.SetCovMatrix(w2);
1341 for (Int_t ista = 0; ista <
fgkStat; ++ista) {
1342 Int_t nvec =
fVectors[ista].size();
1344 for (Int_t iv = nvec - 1; iv >= 0; --iv) {
1345 if (matchOK[ista][iv] > 0)
continue;
1350 cout <<
" Vectors after matching: " <<
fVectors[0].size() <<
" "
1362 while (
fX0abs[nabs] < 1.e+8) {
1363 zabs[nabs][0] =
fZabs0[nabs][0];
1364 zabs[nabs][1] =
fZabs0[nabs][1];
1365 x0abs[nabs] =
fX0abs[nabs];