//======================================================================= // idBlobdEdx 4 planes //======================================================================= StatusCode HTBlob::idBlobdEdx( Minerva::IDBlob *idblob, double &dEdx ) const { debug() << "CCPi0HoughTool::idBlobdEdx" << endmsg; SmartRefVector< Minerva::IDCluster > idClusters = idblob->clusters(); SmartRefVector< Minerva::IDCluster >::iterator it_clus = idClusters.begin(); TH1D *h = new TH1D ("h","h", 100,0,4500); // bin size 45mm <> 1 module dEdx = 0; Gaudi::XYZPoint vert = idblob->startPoint(); double x, z, distance, vt_x, vt_u, vt_v, vt_z; // event vertex per view vt_x = vert.x(); vt_u = -vert.y()*sqrt(3)/2 + vert.x()*.5; // -ycos30 + xsin30 vt_v = vert.y()*sqrt(3)/2 + vert.x()*.5; // ycos30 + xsin30 vt_z = vert.z(); for ( ; it_clus != idClusters.end(); it_clus++ ){ x = vt_x - (*it_clus)->position(); z = vt_z - (*it_clus)->z(); if ( (*it_clus)->view() == Minerva::IDCluster::U ){ x = vt_u - (*it_clus)->position(); z = vt_z - (*it_clus)->z(); } if ( (*it_clus)->view() == Minerva::IDCluster::V ){ x = vt_v - (*it_clus)->position(); z = vt_z - (*it_clus)->z(); } distance = sqrt( pow(x,2) + pow(z,2) ); h->Fill(distance, (*it_clus)->energy()); } // dEdx calculation, maybe not clear int binmin = h->FindFirstBinAbove(); int binmax = (h->FindLastBinAbove()-m_planesdEdx/2); for ( int i = binmin; i <= binmax; i++ ){ if ( FinddEdxPlanes(h, i, dEdx) ) break; dEdx = 0; } if ( dEdx == 0 ) dEdx = -999; else dEdx = dEdx/m_planesdEdx; info () << " dEdx = " << dEdx << " number planes " << m_planesdEdx << endmsg; delete h; return StatusCode::SUCCESS; }
//========================================================================= // Calculate the y position of a particle at a given z //========================================================================= double PrPixelDebugTool::yTrue(int key, double z) { LHCb::MCParticles* parts = get<LHCb::MCParticles>(LHCb::MCParticleLocation::Default); LHCb::MCParticle* part = parts->object(key); if (NULL == part) return -999.; const double ty = part->momentum().py() / part->momentum().pz(); Gaudi::XYZPoint origin = part->originVertex()->position(); return origin.y() + ty * (z - origin.z()); }
//============================================================================= // Create2dHTBlob //============================================================================= StatusCode HTBlob::Create2dHTSeed( SmartRefVector<Minerva::IDCluster> &idClusterView, SmartRefVector<Minerva::IDCluster> &HT2dClusters, double r, double theta, Gaudi::XYZPoint ref, double &spX, double &spZ ) const { debug() << " HTtool::Create2dHTSeed " << endmsg; double rmin, rmax, x, z, zmin = 10000, Total_e = 0; SmartRefVector<Minerva::IDCluster> ClusTemp = idClusterView; SmartRefVector<Minerva::IDCluster>::iterator itClus = ClusTemp.begin(); idClusterView.clear(); debug() << " Will study " << ClusTemp.size() << " clusters " << endmsg; debug() << " Seed with, r: " << r << ", theta = " << theta << ";contains these clusters: " << endmsg; for ( ; itClus != ClusTemp.end(); itClus++ ){ z = (*itClus)->z() - ref.z(); x = (*itClus)->tpos1() - ref.x(); rmin = x*sin(theta*CLHEP::pi/180) + z*cos(theta*CLHEP::pi/180); x = (*itClus)->tpos2() - ref.x(); rmax = x*sin(theta*CLHEP::pi/180) + z*cos(theta*CLHEP::pi/180); if ( fabs ( 2*r - rmin - rmax ) <= 90 ){ if ( (*itClus)->z()< zmin ) { zmin = (*itClus)->z(); spZ = (*itClus)->z(); spX = (*itClus)->position(); } debug() << " pe = " << (*itClus)->pe() << "; z = " << (*itClus)->z() << "; pos = " << (*itClus)->position() << endmsg; HT2dClusters.push_back(*itClus); Total_e += (*itClus)->energy(); continue; } idClusterView.push_back(*itClus); } debug() << " Total energy comming from seed = " << Total_e << "; this energy must be bigger than 19" << endmsg << endmsg; if ( Total_e < 19 ) { idClusterView.insert(idClusterView.end(),HT2dClusters.begin(),HT2dClusters.end()); return StatusCode::FAILURE; } return StatusCode::SUCCESS; }
AngleScan_V::AngleScan_V(const SmartRefVector<Minerva::IDCluster>& clusters, const Gaudi::XYZPoint& vertex) : fUVMatchTolerance(10.0), fUVMatchMoreTolerance(100.0), fAllowUVMatchWithMoreTolerance(true) { std::copy(clusters.begin(), clusters.end(), std::back_inserter(fAllClusters)); fX = vertex.X(); fY = vertex.Y(); fZ = vertex.Z(); fU = -fY*sqrt(3.)/2 + fX/2; fV = fY*sqrt(3.)/2 + fX/2; Initialize(); }
//====================================================================== // Angle //======================================================================= StatusCode HTBlob::Angle( SmartRef<Minerva::IDCluster> Cluster, Gaudi::XYZVector direction, Gaudi::XYZPoint vert, double &angle ) const { if ( direction.x() == -9999 || vert.x() == -9999 ) return StatusCode::FAILURE; double dx, dz, Dx, Dz; switch(Cluster->view()) { case Minerva::IDCluster::X: dx = Cluster->position() - vert.x(); Dx = direction.x(); break; case Minerva::IDCluster::U: dx = Cluster->position() - m_mathTool->calcUfromXY(vert.x(),vert.y()); Dx = m_mathTool->calcUfromXY(direction.x(),direction.y()); break; case Minerva::IDCluster::V: dx = Cluster->position() - m_mathTool->calcVfromXY(vert.x(),vert.y()); Dx = m_mathTool->calcVfromXY(direction.x(),direction.y()); break; default: throw MinervaException("Unknown cluster view"); } dz = Cluster->z() - vert.z(); Dz = direction.z(); double moduled = sqrt( pow(dx,2) + pow(dz,2) ); double moduleD = sqrt( pow(Dx,2) + pow(Dz,2) ); dx = dx/moduled; dz = dz/moduled; Dx = Dx/moduleD; Dz = Dz/moduleD; angle = acos(fabs(dx*Dx+dz*Dz)); debug() << " pe = " << Cluster->pe() << "; z = " << Cluster->z() << "; pos = " << Cluster->position() << " Angle " << angle << endmsg; return StatusCode::SUCCESS; }
//====================================================================== // PseudoCone //======================================================================= StatusCode HTBlob::PseudoCone(SmartRefVector<Minerva::IDCluster> &Seed, SmartRefVector<Minerva::IDCluster> &ClusVectorX, Gaudi::XYZVector direction, Gaudi::XYZPoint vert ) const { debug() << " HTBlob::PseudoCone, clusters with Angles < 0.06 will be include in the seed " << endmsg; SmartRefVector<Minerva::IDCluster> ClusTemp = ClusVectorX; ClusVectorX.clear(); SmartRefVector<Minerva::IDCluster>::iterator itClusX; double angle; for ( itClusX = ClusTemp.begin(); itClusX != ClusTemp.end(); itClusX++ ){ if ( Angle( *itClusX, direction, vert, angle ) ) { if ( angle < 0.06 && (*itClusX)->z() > vert.z() ) Seed.push_back(*itClusX); // must be carefull with backward showers else ClusVectorX.push_back(*itClusX); } else ClusVectorX.push_back(*itClusX); } debug() << endmsg; return StatusCode::SUCCESS; }
//========================================================================= // Convert the LiteClusters to PatPixelHit //========================================================================= void PatPixelHitManager::buildHits ( ) { if ( m_eventReady ) return; m_eventReady = true; //New event - new Vector m_hitsPerEvent.push_back(0); m_hits_Ids.push_back(std::vector<int>()); m_hits_trackIds.push_back(std::vector<int>()); m_hits_sensNum.push_back(std::vector<int>()); m_hits_isUsed.push_back(std::vector<int>()); m_hits_X.push_back(std::vector<double>()); m_hits_Y.push_back(std::vector<double>()); m_hits_Z.push_back(std::vector<double>()); m_hits_W.push_back(std::vector<double>()); m_sensor_hitStartPos.push_back(std::vector<int>()); m_sensor_hitsNum.push_back(std::vector<int>()); m_sensor_Z.push_back(std::vector<double>()); //-- LHCb::VeloPixLiteCluster::VeloPixLiteClusters * liteClusters = GaudiTool::get<LHCb::VeloPixLiteCluster::VeloPixLiteClusters>(LHCb::VeloPixLiteClusterLocation::Default); if ( liteClusters->size() > m_pool.size() ) { m_pool.resize( liteClusters->size() + 100 ); m_nextInPool = m_pool.begin(); } //== Sensirs info std::vector<PatPixelSensor*>::iterator it; for (it = m_sensors.begin(); it<m_sensors.end(); ++it){ m_sensor_hitStartPos[m_event_number].push_back(0); m_sensor_hitsNum[m_event_number].push_back(0); m_sensor_Z[m_event_number].push_back((*it)->z()); } LHCb::VeloPixLiteCluster::VeloPixLiteClusters::iterator iClus; unsigned int lastSensor = 9999; PatPixelSensor* mySensor = NULL; double dx = 0.050 / sqrt( 12. ); int hitNumber = 0; for ( iClus = liteClusters->begin(); liteClusters->end() != iClus; ++iClus ) { unsigned int sensor = iClus->channelID().sensor(); if ( sensor > m_sensors.size() ) break; if ( sensor != lastSensor ) { lastSensor = sensor; mySensor = m_sensors[sensor]; m_sensor_hitStartPos[m_event_number][mySensor->number()] = hitNumber; } PatPixelHit* hit = &(*(m_nextInPool++)); // get the next object in the pool Gaudi::XYZPoint point = mySensor->position( (*iClus).channelID(), (*iClus).interPixelFractionX(), (*iClus).interPixelFractionY() ); hit->setHit( LHCb::LHCbID( (*iClus).channelID() ), point, dx, dx, sensor ); mySensor->addHit( hit ); //!! m_sensor_hitsNum[m_event_number][mySensor->number()]++; m_hitsPerEvent[m_event_number]++; m_hits_Ids[m_event_number].push_back((*iClus).channelID()); m_hits_trackIds[m_event_number].push_back(-1); m_hits_sensNum[m_event_number].push_back(sensor); m_hits_isUsed[m_event_number].push_back(0); m_hits_X[m_event_number].push_back(point.x()); m_hits_Y[m_event_number].push_back(point.y()); m_hits_Z[m_event_number].push_back(point.z()); m_hits_W[m_event_number].push_back(1.0/dx/dx); hitNumber++; } if (m_hitsPerEvent[m_event_number] > m_max_hits){ m_max_hits = m_hitsPerEvent[m_event_number]; } m_event_number++; //TRZEBA GO USTAWIAC NA 0 PO KAZDEJ PACZCE!!! !!!!!!! }
//======================================================================= // isPhoton // Calculating distance from event vertex to photon, // this distance must be bigger than // m_minDistanceStripPhoton and m_minDistanceModulePhoton //======================================================================= StatusCode HTBlob::isPhoton( SmartRefVector<Minerva::IDCluster> Seed, Gaudi::XYZPoint vtX ) const { debug() << " HTBlob::isPhoton, asking vtx_z = " << vtX.z() << "; vtx_x " << vtX.x() << endmsg; SmartRefVector<Minerva::IDCluster>::iterator itClus = Seed.begin(); double min_radius = 10000.0; Gaudi::XYZPoint upstream; for ( ; itClus != Seed.end(); ++itClus ) { if ( (*itClus)->view() != Minerva::IDCluster::X ) continue; double radius =sqrt( pow(vtX.x()-(*itClus)->position(),2) + pow(vtX.z() - (*itClus)->z(),2) ); if ( radius < min_radius ){ min_radius = radius; upstream.SetX( (*itClus)->position() ); upstream.SetY( 0.0 ); upstream.SetZ( (*itClus)->z() ); } } if ( fabs(upstream.x()-vtX.x()) > m_minDistanceStripPhoton || fabs(upstream.z()-vtX.z()) > m_minDistanceModulePhoton ) return StatusCode::SUCCESS; else return StatusCode::FAILURE; }
//============================================================================= // GetStartPosition // is_vertex must be "true" when the vert is muon vertex // is_vertex must be "false" when the vert is for reference //============================================================================= bool HTBlob::GetStartPosition( Minerva::IDBlob *idBlob, Gaudi::XYZPoint vert, bool is_vertex ) const { debug() << " HTBlob::GetStartPosition " << endmsg; TH2D *hU = new TH2D ( "hU", "hU", 480,4510,9990,127,-1075,1075); TH2D *hV = new TH2D ( "hV", "hV", 480,4510,9990,127,-1075,1075); if ( is_vertex ){ hU->Fill( vert.z(), m_mathTool->calcUfromXY(vert.x(), vert.y()), 20 ); hV->Fill( vert.z(), m_mathTool->calcVfromXY(vert.x(), vert.y()), 20); } SmartRefVector<Minerva::IDCluster> idClusters = idBlob->clusters(); SmartRefVector<Minerva::IDCluster>::iterator itClus = idClusters.begin(); Gaudi::XYZPoint pos; double Dx = 0.0; double Dz = 0.0; double distance = 0.0; double vt_x = -9999; double vt_u; double vt_v; double vt_z = -9999; double vtX = -9999; double vtY = -9999; double vtZ = -9999; double dis_min_x = 10000; double xu[2] = {0.0}; double xv[2] = {0.0}; double zu[2] = {0.0}; double zv[2] = {0.0}; // to NC Pi0 events, there is no muon vertex int countu = 0; int countv = 0; // to NC Pi0 events, there is no muon vertex for ( ; itClus != idClusters.end(); itClus++ ){ Dx = (*itClus)->position() - vert.x(); Dz = (*itClus)->z() - vert.z();// to avoid 0 if( (*itClus)->view()== Minerva::IDCluster::X ) { distance = sqrt( pow(Dx,2) + pow(Dz,2) ); if (distance <= dis_min_x ) { dis_min_x = distance; vt_x = (*itClus)->position(); vt_z = (*itClus)->z(); } } if( (*itClus)->view()== Minerva::IDCluster::U ){ debug() << " StartPoint U view, pe " << (*itClus)->pe() << "; z = " << (*itClus)->z() << "; coord " << (*itClus)->position() << endmsg; Dx = (*itClus)->position() - m_mathTool->calcUfromXY(vert.x(),vert.y()); distance = sqrt( pow(Dx,2) + pow(Dz,2) ); if ( is_vertex ) { hU->Fill( (*itClus)->z()-12,(*itClus)->tpos1(), (*itClus)->pe()/distance ); hU->Fill( (*itClus)->z()+12,(*itClus)->tpos2(), (*itClus)->pe()/distance ); } hU->Fill( (*itClus)->z(),(*itClus)->position(), (*itClus)->pe()/distance ); if ( countu < 2 ){ zu[countu] = (*itClus)->z(); xu[countu] = (*itClus)->position(); countu++; } } if( (*itClus)->view()== Minerva::IDCluster::V ){ debug() << " StartPoint V view, pe " << (*itClus)->pe() << "; z = " << (*itClus)->z() << "; coord " << (*itClus)->position() << endmsg; Dx = (*itClus)->position() - m_mathTool->calcVfromXY(vert.x(),vert.y()); distance = sqrt( pow(Dx,2) + pow(Dz,2) ); if ( is_vertex ){ hV->Fill( (*itClus)->z()-12,(*itClus)->tpos1(), (*itClus)->pe()/distance ); hV->Fill( (*itClus)->z()+12,(*itClus)->tpos2(), (*itClus)->pe()/distance ); } hV->Fill( (*itClus)->z(),(*itClus)->position(), (*itClus)->pe()/distance ); if ( countv < 2 ){ zv[countu] = (*itClus)->z(); xv[countu] = (*itClus)->position(); countv++; } } } TF1 *fU, *fV; double slopeu = -9999; double slopev = -9999; double bu = -9999; double bv = -9999; bool goodFit_U = false; bool goodFit_V = false; if ( hU->GetEntries() > 3 ){ hU->Fit("pol1","Q0"); fU = hU->GetFunction("pol1"); bu = fU->GetParameter(0); slopeu = fU->GetParameter(1); goodFit_U = true; delete fU; } else if ( hU->GetEntries() == 2 ){ // to deal with 2 clusters on NCPi0 if ( zu[0] > zu[1] ){ slopeu = (xu[0] - xu[1]) / (zu[0] - zu[1]); bu = xu[1] - zu[1]*slopeu; goodFit_U = true; } else if (zu[0] < zu[1] ) { slopeu = (xu[1] - xu[0]) / (zu[1] - zu[0]); bu = xu[0] - zu[0]*slopeu; goodFit_U = true; } } if ( hV->GetEntries() > 3 ){ hV->Fit("pol1","Q0"); fV = hV->GetFunction("pol1"); bv = fV->GetParameter(0); slopev = fV->GetParameter(1); goodFit_V = true; delete fV; } else if ( hV->GetEntries() == 2 ){ // to deal with 2 clusters on NCPi0 if ( zv[0] > zv[1] ){ slopev = (xv[0] - xv[1]) / (zv[0] - zv[1]); bv = xv[1] - zv[1]*slopeu; goodFit_V = true; } else if (zu[1] < zu[0] ) { /* Trung: why zu instead of zv? */ slopev = (xv[1] - xv[0]) / (zv[1] - zv[0]); bv = xv[0] - zv[0]*slopev; goodFit_V = true; } } vtX = vt_x; vtZ = vt_z; debug() << " Startpoint, slope u " << slopeu << " slope v" << slopev << endmsg; if ( goodFit_U && goodFit_V ){ //3D blobs vt_u = slopeu*vt_z + bu; vt_v = slopev*vt_z + bv; vtY = m_mathTool->calcYfromUV(vt_u,vt_v); } else if ( goodFit_U ) { //2D blobs vt_u = slopeu*vt_z + bu; vtY = (vt_x*.5 - vt_u)*2/sqrt(3); //calcYfromXU? } else if ( goodFit_V ) { //2D blobs vt_v = slopev*vt_z + bv; vtY = (vt_v - vt_x*.5)*2/sqrt(3); //calcYfromXV? } pos.SetX(vtX); pos.SetY(vtY); pos.SetZ(vtZ); idBlob->setStartPoint(pos); debug() << " Setting StarPoint " << pos << " Blob" << idBlob << endmsg; delete hU; delete hV; if (goodFit_U || goodFit_V) return true; return false; }
//============================================================================= // GetDirection - Cesar Sotelo's idea // Calculate direction using every cluster weighted by Energy // and distance inverse weighted //============================================================================= bool HTBlob::GetDirection( Minerva::IDBlob *idBlob, Gaudi::XYZPoint vert ) const { debug() << " HTBlob::GetDirection " << endmsg; SmartRefVector<Minerva::IDCluster> idClusters = idBlob->clusters(); SmartRefVector<Minerva::IDCluster>::iterator itClus = idClusters.begin(); double Xx = 0.0; double Zx = 0.0; double Xu = 0.0; double Xv = 0.0; double totalX = 0.0; double totalU = 0.0; double totalV = 0.0; double dx = 0.0; double dy = 0.0; double dz = 0.0; double distance = 0.0; for ( ; itClus != idClusters.end(); itClus++ ){ dz = (*itClus)->z() - vert.z(); switch((*itClus)->view()) { case Minerva::IDCluster::X: dx = (*itClus)->position() - vert.x(); distance = sqrt(pow(dx,2)+pow(dz,2)); if ( distance == .0 ) distance = 25; Xx += dx*(*itClus)->energy()/distance; Zx += dz*(*itClus)->energy()/distance; totalX += (*itClus)->energy()/distance; break; case Minerva::IDCluster::U: dx = (*itClus)->position() - m_mathTool->calcUfromXY(vert.x(), vert.y()); distance = sqrt(pow(dx,2)+pow(dz,2)); if ( distance == .0 ) distance = 25; Xu += dx*(*itClus)->energy()/distance; totalU += (*itClus)->energy()/distance; break; case Minerva::IDCluster::V: dx = (*itClus)->position() - m_mathTool->calcVfromXY(vert.x(), vert.y()); distance = sqrt(pow(dx,2)+pow(dz,2)); if ( distance == .0 ) distance = 25; Xv += dx*(*itClus)->energy()/distance; totalV += (*itClus)->energy()/distance; break; default: throw MinervaException("Unknown cluster view"); } } Gaudi::XYZVector direction; dx = Xx/totalX; dz = Zx/totalX; dy = -9999; bool valid_dY = false; const double epsilon = std::numeric_limits<double>::epsilon(); if ( std::abs(Xu) > epsilon && std::abs(Xv) > epsilon ) { dy = m_mathTool->calcYfromUV(Xu/totalU,Xv/totalV); valid_dY = true; } else if ( std::abs(Xu) > epsilon ){ dy = (dx*.5 - Xu/totalU)*2/sqrt(3); //calcYfromXU? valid_dY = true; } else if ( std::abs(Xv) > epsilon ){ dy = (Xv/totalV - dx*.5)*2/sqrt(3); //calcYfromXV? valid_dY = true; } if ( !valid_dY ){ debug() << " Bad direction" << endmsg; idBlob->setDirection(Gaudi::XYZVector(-9999,-9999,-9999)); return false; } else { double mod = sqrt( pow(dx,2)+pow(dy,2)+pow(dz,2) ); direction.SetX(dx/mod); direction.SetY(dy/mod); direction.SetZ(dz/mod); } debug() << " Setting direction " << direction << " Blob" << idBlob << endmsg; idBlob->setDirection(direction); return true; }