/* * File: EuBuildTrack.cc * Author: daniel * * Created on 24. Januar 2014 * * v1.0 */ #include "EuBuildTrack.h" int bad_chi2 = 0, col_row = 0, hitnot9 = 0; void EuBuildTrack::init(TBCore* core) { TBLOG(kERROR, "Warning: Rotation tree is not implemented yet!") // Add idens, which can be matched to a track. int iden; for(auto dut: core->usedDUT) { iden = dut->iden; EuBuildTrack::lv1Min[iden] = core->usedDUTMap[iden]->getlv1Min(); EuBuildTrack::lv1Max[iden] = core->usedDUTMap[iden]->getlv1Max(); std::string param = core->getParam(iden, EuBuildTrack::name, "matchDUT"); if(param.compare("true") == 0) { TBLOG(kINFO, "Add iden " << iden << " to match list.") TBLOG(kINFO, "Do lv1 cut for iden " << iden << " between lv1min " << EuBuildTrack::lv1Min[iden] << " and lv1max " << EuBuildTrack::lv1Max[iden] << ".") EuBuildTrack::matchIdens.push_back(iden); } for (auto x: EuBuildTrack::matchIdens) std::cout << "Match iden: " << x << std::endl; } std::string param = core->getParam(-1, EuBuildTrack::name, "chi2"); if(param.compare("") != 0) { EuBuildTrack::chi2cut = std::fabs(std::stod(param)); } else // default { EuBuildTrack::chi2cut = 15.0; } TBLOG(kINFO, "Do chi2 cut by > " << EuBuildTrack::chi2cut << " for all idens"); // initialize pointer //Track stuff EuBuildTrack::t_posX = NULL; EuBuildTrack::t_posY = NULL; EuBuildTrack::t_dxdz = NULL; EuBuildTrack::t_dydz = NULL; EuBuildTrack::t_chi2 = NULL; EuBuildTrack::t_iden = NULL; EuBuildTrack::t_trackNum = NULL; EuBuildTrack::t_ndof = NULL; //Pixel stuff EuBuildTrack::p_col = NULL; EuBuildTrack::p_row = NULL; EuBuildTrack::p_tot = NULL; EuBuildTrack::p_iden = NULL; EuBuildTrack::p_lv1 = NULL; //ehhits stuff EuBuildTrack::e_zpos = NULL; EuBuildTrack::e_sensorID = NULL; } /* * set addresses of tbtrack file ttree to those of internal eubuildtrack ttree pointers */ void EuBuildTrack::initRun(TBCore* core) { if (core->tbtrackVersion == 0) { // old tbtrack version EuBuildTrack::tracktree = dynamic_cast(core->tInFile->Get("eutracks")); EuBuildTrack::pixeltree = dynamic_cast(core->tInFile->Get("zspix")); EuBuildTrack::euhits = dynamic_cast(core->tInFile->Get("euhits")); } else if (core->tbtrackVersion > 0) { // all other tbtrack version (at least yet) EuBuildTrack::tracktree = dynamic_cast(core->tInFile->Get("tracks")); EuBuildTrack::pixeltree = dynamic_cast(core->tInFile->Get("rawdata")); EuBuildTrack::euhits = dynamic_cast(core->tInFile->Get("fitpoints")); } EuBuildTrack::tracktree->SetBranchAddress("nTrackParams", &(EuBuildTrack::t_nTrackParams)); EuBuildTrack::tracktree->SetBranchAddress("euEvt", &(EuBuildTrack::t_euEv)); EuBuildTrack::tracktree->SetBranchAddress("dxdz", &(EuBuildTrack::t_dxdz)); EuBuildTrack::tracktree->SetBranchAddress("dydz", &(EuBuildTrack::t_dydz)); EuBuildTrack::tracktree->SetBranchAddress("iden", &(EuBuildTrack::t_iden)); EuBuildTrack::tracktree->SetBranchAddress("trackNum", &(EuBuildTrack::t_trackNum)); EuBuildTrack::tracktree->SetBranchAddress("chi2", &(EuBuildTrack::t_chi2)); EuBuildTrack::tracktree->SetBranchAddress("ndof", &(EuBuildTrack::t_ndof)); EuBuildTrack::pixeltree->SetBranchAddress("nPixHits", &(EuBuildTrack::p_nHits)); EuBuildTrack::pixeltree->SetBranchAddress("col", &(EuBuildTrack::p_col)); EuBuildTrack::pixeltree->SetBranchAddress("row", &(EuBuildTrack::p_row)); EuBuildTrack::pixeltree->SetBranchAddress("tot", &(EuBuildTrack::p_tot)); EuBuildTrack::pixeltree->SetBranchAddress("lv1", &(EuBuildTrack::p_lv1)); EuBuildTrack::pixeltree->SetBranchAddress("iden", &(EuBuildTrack::p_iden)); EuBuildTrack::pixeltree->SetBranchAddress("euEvt", &(EuBuildTrack::p_euEv)); EuBuildTrack::p_euEv = 0; EuBuildTrack::euhits->SetBranchAddress("nHits", &(EuBuildTrack::e_nHits)); EuBuildTrack::euhits->SetBranchAddress("zPos", &(EuBuildTrack::e_zpos)); EuBuildTrack::euhits->SetBranchAddress("sensorId", &(EuBuildTrack::e_sensorID)); if (core->tbtrackVersion == 0) { EuBuildTrack::tracktree->SetBranchAddress("xPos", &(EuBuildTrack::t_posX)); EuBuildTrack::tracktree->SetBranchAddress("yPos", &(EuBuildTrack::t_posY)); } else if (core->tbtrackVersion > 0) { EuBuildTrack::euhits->SetBranchAddress("xPos", &(EuBuildTrack::t_posX)); EuBuildTrack::euhits->SetBranchAddress("yPos", &(EuBuildTrack::t_posY)); } } void EuBuildTrack::initEvent(TBCore* core) { EuBuildTrack::tracktree->GetEntry(core->currentEntry); EuBuildTrack::pixeltree->GetEntry(core->currentEntry); EuBuildTrack::euhits->GetEntry(core->currentEntry); bool inEvent; bool matchDUT; int iden; int lv1; TBHit* tbhit; DUT* dut; // sort hits for(int hit = 0; hit < EuBuildTrack::p_iden->size(); hit++) { iden = EuBuildTrack::p_iden->at(hit); lv1 = EuBuildTrack::p_lv1->at(hit); // We only want hits for events and match DUTs inEvent = (core->usedDUTMap.find(iden) != core->usedDUTMap.end()); // DUT iden matchDUT = (std::find(EuBuildTrack::matchIdens.begin(), EuBuildTrack::matchIdens.end(), iden) != EuBuildTrack::matchIdens.end()); // DUT match // Drop hits if((not inEvent) and (not matchDUT)) { continue; } // Add hit to rawHits in TBEvent core->events[iden]->addRawHit( EuBuildTrack::p_euEv, EuBuildTrack::p_iden->at(hit), EuBuildTrack::p_col->at(hit), EuBuildTrack::p_row->at(hit), EuBuildTrack::p_tot->at(hit), EuBuildTrack::p_lv1->at(hit)); tbhit = core->events[iden]->rawHits.back(); dut = core->usedDUTMap[iden]; if ((tbhit->col < 0) || (tbhit->col > dut->getNcols()) || (tbhit->row < 0) || (tbhit->row > dut->getNrows())) { TBLOG(kERROR, "Warning: Hit out of detector range! Check if correct DUT config is used!") continue; } // set flags if(dut->isEdgePixel(tbhit->col, tbhit->row)) { tbhit->fEdgeHit = kGood; tbhit->fCentralHit = kBad; } else { tbhit->fEdgeHit = kBad; tbhit->fCentralHit = kGood; } // lv1 cut if(EuBuildTrack::lv1Min[iden] <= lv1 && lv1 <= EuBuildTrack::lv1Max[iden]) { tbhit->fLv1 = kGood; } else { tbhit->fLv1 = kBad; } // hit pixel masked (pixel masked because of noisy neighbours (type=2) are not removed from list) if((dut->getMask(tbhit->col, tbhit->row) != 0) && (dut->getMask(tbhit->col, tbhit->row) != 2)) { tbhit->fMaskedHit = kGood; std::cout << "Masked hit!" << std::endl; } else { tbhit->fMaskedHit = kBad; } // add hit to hits in TBEvent if(tbhit->fLv1 == kGood && tbhit->fMaskedHit == kBad) { core->events[iden]->hits.push_back(tbhit); core->events[iden]->fHits = kGood; } } // find zPos if (core->tbconfig->useRecoZ) { // use zPos from reco for(int i = 0; i < EuBuildTrack::e_sensorID->size(); i++) { if(EuBuildTrack::e_sensorID->at(i) == iden) { EuBuildTrack::zPos[iden] = EuBuildTrack::e_zpos->at(i);// * 1000; // convert mm to mu break; } } } else // use zPos from mainConfig { EuBuildTrack::zPos[iden] = core->usedDUTMap[iden]->getzPos();// * 1000; // convert mm to mu } int trackCol; int trackRow; Double_t trackY; TBTrack* tbtrack; int trackstop = 0; // sort tracks for(int track = 0; track < EuBuildTrack::t_nTrackParams; track++) { iden = EuBuildTrack::t_iden->at(track); // We only want hits for events and match DUTs inEvent = (core->usedDUTMap.find(iden) != core->usedDUTMap.end()); // DUT iden matchDUT = (std::find(EuBuildTrack::matchIdens.begin(), EuBuildTrack::matchIdens.end(), iden) != EuBuildTrack::matchIdens.end()); // DUT match // Drop tracks if((not inEvent) and (not matchDUT)) { continue; } // Read in trackY already, as it might have to be flipped trackY = EuBuildTrack::t_posY->at(track) * 1000; dut = core->usedDUTMap[iden]; // Flip trackY, if new geometry description for reconstruction was used if(core->tbconfig->usedGEAR && iden == 21) { trackY = dut->getDutPitchY() - trackY; } // Add track to rawTracks in TBEvent core->events[iden]->addRawTrack( EuBuildTrack::t_euEv, EuBuildTrack::t_iden->at(track), EuBuildTrack::t_trackNum->at(track), EuBuildTrack::t_posX->at(track) * 1000, trackY, EuBuildTrack::t_dxdz->at(track), EuBuildTrack::t_dydz->at(track), EuBuildTrack::t_chi2->at(track), EuBuildTrack::t_ndof->at(track)); if(USE_TRANSLATIONS) { EuBuildTrack::useTranslation(core, iden); } if(USE_CODEDSHIFTS) { EuBuildTrack::useHardCodedShift(core, iden); } tbtrack = core->events[iden]->rawTracks.back(); tbtrack->zpos = EuBuildTrack::zPos[iden]; //std::cout << tbtrack->chi2 << std::endl; // chi2 cut if(tbtrack->chi2 > EuBuildTrack::chi2cut) { tbtrack->fTrackChi2 = kBad; } else { tbtrack->fTrackChi2 = kGood; } // set track col and row dut->getColRow(tbtrack->trackX, tbtrack->trackY, dut->getMatchPixelMarginX(), dut->getMatchPixelMarginY(), &trackCol, &trackRow); tbtrack->trackCol = trackCol; tbtrack->trackRow = trackRow; //std::cout << "track col: " << trackCol << ", track row: " << trackRow << std::endl; // match best possible hit to track int hitType = 9; double minDis = std::numeric_limits::max(); TBHit* trackHit; if(trackCol != -1 && trackRow != -1) { for(auto hit: core->events[iden]->hits) { bool inside = dut->pixelArray[hit->col][hit->row].inside(tbtrack->trackX, tbtrack->trackY, dut->getMatchPixelMarginX(), dut->getMatchPixelMarginY()); double disX = std::fabs(dut->pixelArray[hit->col][hit->row].getGeometricCenterX() - tbtrack->trackX); double disY = std::fabs(dut->pixelArray[hit->col][hit->row].getGeometricCenterY() - tbtrack->trackY); double dis = std::sqrt(disX*disX + disY*disY); if (EuBuildTrack::t_euEv == 9770) { std::cout << iden << ": " << trackCol << ", " << trackRow << ", " << inside << ", " << disX << ", " << disY << std::endl; std::cout << iden << ": " << dut->pixelArray[hit->col][hit->row].getGeometricCenterX() << ", " << dut->pixelArray[hit->col][hit->row].getGeometricCenterY() << std::endl; std::cout << iden << ": " << tbtrack->trackX << ", " << tbtrack->trackY << ", " << dut->getMatchPixelMarginX() << ", " << dut->getMatchPixelMarginY() << std::endl; ++trackstop; } // Track position inside an unmasked and center hit if(hit->col == trackCol and hit->row == trackRow and hit->fMaskedHit == kBad and hit->fEdgeHit != kGood) { trackHit = hit; hitType = 1; break; } // Track position inside the margin of an unmasked and center hit with min distance to pixel center if(inside and hit->fMaskedHit != kGood and hit->fEdgeHit != kGood and hitType >= 2) { if(hitType > 2 or dis < minDis) { minDis = dis; trackHit = hit; hitType = 2; } continue; } // Track position inside an unmasked and edge hit if(hit->col == trackCol and hit->row == trackRow and hit->fMaskedHit == kBad and hit->fEdgeHit == kGood) { trackHit = hit; hitType = 3; continue; } // Track position inside the margin of an unmasked and edge hit with min distance to pixel center if(inside and hit->fMaskedHit == kBad and hit->fEdgeHit == kGood and hitType >= 4) { if(hitType > 4 or dis < minDis) { minDis = dis; trackHit = hit; hitType = 4; } continue; } // Track position inside a masked and center hit if(hit->col == trackCol and hit->row == trackRow and hit->fMaskedHit == kGood and hit->fEdgeHit == kBad) { trackHit = hit; hitType = 5; continue; } // Track position inside the margin of a masked and center hit with min distance to pixel center if(inside and hit->fMaskedHit == kGood and hit->fEdgeHit == kBad and hitType >= 6) { if(hitType > 6 or dis < minDis) { minDis = dis; trackHit = hit; hitType = 6; } continue; } // Track position inside a masked and edge hit if(hit->col == trackCol and hit->row == trackRow and hit->fMaskedHit == kGood and hit->fEdgeHit == kGood) { trackHit = hit; hitType = 7; continue; } // Track position inside the margin of a masked and edge hit with min distance to pixel center if(inside and hit->fMaskedHit == kGood and hit->fEdgeHit == kGood and hitType >= 8) { if(hitType > 8 or dis < minDis) { minDis = dis; trackHit = hit; hitType = 8; } continue; } } // set best matched hit and flags depend on hit if(hitType < 9) { tbtrack->matchedHit = trackHit; tbtrack->matchedHitType = hitType; tbtrack->fMatchedHit = kGood; tbtrack->trackCol = trackHit->col; tbtrack->trackRow = trackHit->row; if(trackHit->fEdgeHit == kGood) { tbtrack->fTrackEdgeRegion = kGood; tbtrack->fTrackCentralRegion = kBad; } else { tbtrack->fTrackEdgeRegion = kBad; tbtrack->fTrackCentralRegion = kGood; } if(trackHit->fMaskedHit == kGood) { tbtrack->fTrackMaskedRegion = kGood; } else { tbtrack->fTrackMaskedRegion = kBad; } } else { tbtrack->matchedHitType = hitType; tbtrack->fMatchedHit = kBad; } } } } void EuBuildTrack::buildEvent(TBCore* core, TBEvent* event) { int iden = event->iden; int matches; int tracks = 0; DUT* dut; dut = core->usedDUTMap[iden]; // loop over all tracks for(auto track: core->events[iden]->rawTracks) { matches = 0; if(track->fTrackChi2 == kBad) { //std::cout << "Track chi2 = " << track->fTrackChi2 << " (bad)" << std::endl; ++bad_chi2; continue; } if(track->trackCol == -1 || track->trackRow == -1) { //std::cout << "Track col/row = -1" << std::endl; ++col_row; continue; } // loop over all matched idens for(auto matchIden: EuBuildTrack::matchIdens) { //std::cout << matchIden << ", " << iden << std::endl; if(matchIden == iden /*&& matchIdens.size() > 1*/ ) { continue; } //std::cout << core->events[matchIden]->rawTracks.size() << std::endl; // loop oder all tracks in matched DUT for(auto matchTrack: core->events[matchIden]->rawTracks) { if(track->trackNum != matchTrack->trackNum) { //std::cout << "Problem 1: " << iden << std::endl; continue; } if(matchTrack->fTrackChi2 == kBad) { //std::cout << "Problem 2: " << iden << std::endl; continue; } if(matchTrack->trackCol == -1 || matchTrack->trackRow == -1) { //std::cout << "Problem 3: " << iden << std::endl; continue; } if(matchTrack->fMatchedHit == kBad) { //std::cout << "Problem 4: " << iden << std::endl; continue; } if(matchTrack->matchedHit->fLv1 == kBad || matchTrack->matchedHit->fMaskedHit == kGood) { //std::cout << "Problem 5:" << iden << std::endl; continue; } // if passed all cuts above matches++; } // end loop oder all tracks in matched DUT // break up if amount of matches reach the minmum matches if(matches >= NMATCHES) { break; } } // end loop over all matched idens if(matches >= NMATCHES) { track->fMatchedTrack = kGood; //check if matched track is in masked region of this DUT if (dut->getMask(track->trackCol, track->trackRow) != 0) { track->fTrackMaskedRegion = kGood; } core->events[iden]->tracks.push_back(track); core->events[iden]->fTracks = kGood; // exist matched tracks tracks++; } else { track->fMatchedTrack = kBad; } // break up if the max size of matched tracks reach if(TRACKS == tracks) { break; } } // end loop over all tracks } void EuBuildTrack::finalizeRun(TBCore* core) { t_nTrackParams = 0; t_euEv = 0; t_posX = NULL; t_posY = NULL; t_dxdz = NULL; t_dydz = NULL; t_iden = NULL; t_trackNum = NULL; t_chi2 = NULL; t_ndof = NULL; p_nHits = 0; p_euEv = 0; p_col = NULL; p_row = NULL; p_tot = NULL; p_iden = NULL; p_lv1 = NULL; e_zpos = NULL; e_sensorID = NULL; tracktree = NULL; pixeltree = NULL; euhits = NULL; } void EuBuildTrack::finalize(TBCore* core) { for(auto dut: core->usedDUT) { int iden = dut->iden; core->output->preprocessCuts[iden] += "lv1 between "+std::to_string(EuBuildTrack::lv1Min[iden])+" and "+std::to_string(EuBuildTrack::lv1Max[iden])+"; chi2 cut by "+std::to_string(EuBuildTrack::chi2cut); } EuBuildTrack::matchIdens.clear(); std::cout << "Bad chi2: " << bad_chi2 << std::endl; std::cout << "Col/row = -1: " << col_row << std::endl; } void EuBuildTrack::useTranslation(TBCore* core, int iden) { int runNumber = core->currentRun; if(core->translations.find(iden) != core->translations.end() && core->translations[iden].find(runNumber) != core->translations[iden].end()) { core->events[iden]->rawTracks.back()->trackX -= core->translations[iden][runNumber]->shiftX; core->events[iden]->rawTracks.back()->trackY -= core->translations[iden][runNumber]->shiftY; /* TODO remove the used shifts */ } } void EuBuildTrack::useHardCodedShift(TBCore* core, int iden) { if(core->usedDUTMap.find(iden) != core->usedDUTMap.end()) { DUT* dut = core->usedDUTMap[iden]; if(dut->name.compare("FE-I4") == 0) { if(core->events[iden]->rawTracks.back()->trackX > 79*250) // rechte edge Kante vom rechten chip { core->events[iden]->rawTracks.back()->trackX -= 79*250; core->events[iden]->rawTracks.back()->trackX *= 2; core->events[iden]->rawTracks.back()->trackX += 79*250; } if(core->events[iden]->rawTracks.back()->trackX > 1*250) { core->events[iden]->rawTracks.back()->trackX += 250; } if(core->events[iden]->rawTracks.back()->trackX > 0*250 && core->events[iden]->rawTracks.back()->trackX <= 1*250) // rechte edge Kante vom rechten chip { core->events[iden]->rawTracks.back()->trackX *= 2; } } if(dut->name.compare("FE-I4-double") == 0) { if(core->events[iden]->rawTracks.back()->trackX > 159*250) // rechte edge Kante vom rechten chip { core->events[iden]->rawTracks.back()->trackX -= 159*250; core->events[iden]->rawTracks.back()->trackX *= 2; core->events[iden]->rawTracks.back()->trackX += 159*250; } if(core->events[iden]->rawTracks.back()->trackX > 81*250) { core->events[iden]->rawTracks.back()->trackX += 200; } if(core->events[iden]->rawTracks.back()->trackX > 80*250 && core->events[iden]->rawTracks.back()->trackX <= 81*250) // rechte edge Kante vom rechten chip { core->events[iden]->rawTracks.back()->trackX -= 80*250; core->events[iden]->rawTracks.back()->trackX *= 450.0/250.0; core->events[iden]->rawTracks.back()->trackX += 80*250; } if(core->events[iden]->rawTracks.back()->trackX > 80*250) { core->events[iden]->rawTracks.back()->trackX += 200; } if(core->events[iden]->rawTracks.back()->trackX > 79*250 && core->events[iden]->rawTracks.back()->trackX <= 80*250) // rechte edge Kante vom rechten chip { core->events[iden]->rawTracks.back()->trackX -= 79*250; core->events[iden]->rawTracks.back()->trackX *= 450.0/250.0; core->events[iden]->rawTracks.back()->trackX += 79*250; } if(core->events[iden]->rawTracks.back()->trackX > 1*250) { core->events[iden]->rawTracks.back()->trackX += 250; } if(core->events[iden]->rawTracks.back()->trackX > 0*250 && core->events[iden]->rawTracks.back()->trackX <= 1*250) // rechte edge Kante vom rechten chip { core->events[iden]->rawTracks.back()->trackX *= 2; } } // TODO shift calc if(dut->name.compare("FE-I4-quad-v1") == 0) { if(core->events[iden]->rawTracks.back()->trackX >= 250*79) { core->events[iden]->rawTracks.back()->trackX += 400; } if(core->events[iden]->rawTracks.back()->trackY >= 50*336) { core->events[iden]->rawTracks.back()->trackY += 1580; } } } }