int PHG4HoughTransformTPC::InitializeGeometry(PHCompositeNode *topNode) {

  //---------------------------------------------------------
  // Grab Run-Dependent Detector Geometry and Configure Hough
  //---------------------------------------------------------

  bool default_geo = false;
  
  PHG4CylinderCellGeomContainer* cellgeos = findNode::getClass<PHG4CylinderCellGeomContainer>(topNode,"CYLINDERCELLGEOM_SVTX");
  PHG4CylinderGeomContainer* laddergeos = findNode::getClass<PHG4CylinderGeomContainer>(topNode,"CYLINDERGEOM_SILICON_TRACKER");
  //PHG4CylinderCellContainer* cells = findNode::getClass<PHG4CylinderCellContainer>(topNode,"G4CELL_SVTX");
  
  if (cellgeos||laddergeos) {
    unsigned int ncelllayers = 0;
    if (cellgeos) ncelllayers += cellgeos->get_NLayers();
    unsigned int nladderlayers = 0;
    if (laddergeos) nladderlayers += laddergeos->get_NLayers();
    _nlayers = ncelllayers + nladderlayers;
    default_geo = false;
  } else {
    cerr << PHWHERE
	 << "Neither CYLINDERCELLGEOM_SVTX nor CYLINDERGEOM_SILICON_TRACKER available, reverting to a default geometry"
	 << std::endl;    
    _nlayers = 6;
    default_geo = true;
  }

  //=================================================//                                                                                                      
  //  Initializing HelixHough objects                //                                                                                                      
  //=================================================//                                                                                            

  _radii.assign(_nlayers, 0.0);
  _smear_xy_layer.assign(_nlayers, 0.0);
  _smear_z_layer.assign(_nlayers, 0.0);
  float sqrt_12 = sqrt(12.);
	
  if (default_geo) {

    // default geometry
    _radii[0] = 2.5;
    _radii[1] = 5.0;
    _radii[2] = 10.0;
    _radii[3] = 14.0;
    _radii[4] = 40.0;
    _radii[5] = 60.0;
    
    _smear_xy_layer[0] = (50.0e-4/sqrt_12);
    _smear_z_layer[0] = (425.0e-4/sqrt_12);
    _smear_xy_layer[1] = (50.0e-4/sqrt_12);
    _smear_z_layer[1] = (425.0e-4/sqrt_12);
    _smear_xy_layer[2] = (80.0e-4/sqrt_12);
    _smear_z_layer[2] = (1000.0e-4/sqrt_12);
    _smear_xy_layer[3] = (80.0e-4/sqrt_12);
    _smear_z_layer[3] = (1000.0e-4/sqrt_12);
    
    for(int il=4; il<_nlayers; ++il) {
      _smear_xy_layer[il] = (80.0e-4/sqrt_12);
      _smear_z_layer[il] = (30000.0e-4/sqrt_12);
    }

    _layer_ilayer_map.clear();
    for (int ilayer = 0; ilayer < _nlayers; ++ilayer) {
      _layer_ilayer_map.insert(make_pair(ilayer,ilayer));
    }
    
  } else {

    // Since the G4 layers don't necessarily correspond to the
    // silicon layers, and don't necessarily start from zero (argh),
    // we create our own layers numbers that are consecutive
    // starting from zero.

    // Now that we have two kinds of layers, I won't know in principle
    // which type is in what order, so I figure that out now...
    
    map<float,int> radius_layer_map;

    if (cellgeos) {
      PHG4CylinderCellGeomContainer::ConstRange layerrange = cellgeos->get_begin_end();
      for(PHG4CylinderCellGeomContainer::ConstIterator layeriter = layerrange.first;
	  layeriter != layerrange.second;
	  ++layeriter) {
	radius_layer_map.insert( make_pair(layeriter->second->get_radius(),
					   layeriter->second->get_layer()) );
      }
    }

    if (laddergeos) {
      PHG4CylinderGeomContainer::ConstRange layerrange = laddergeos->get_begin_end();
      for(PHG4CylinderGeomContainer::ConstIterator layeriter = layerrange.first;
	  layeriter != layerrange.second;
	  ++layeriter) {
	radius_layer_map.insert( make_pair(layeriter->second->get_radius(),
					   layeriter->second->get_layer()) );
      }
    }

    // now that the layer ids are sorted by radius, I can create a storage
    // index, ilayer, that is 0..N-1 and sorted by radius
    
    int ilayer = 0;
    for(map<float,int>::iterator iter = radius_layer_map.begin();
	iter != radius_layer_map.end();
	++iter) {
      _layer_ilayer_map.insert( make_pair(iter->second,ilayer) );
      ++ilayer;
    }   

    // now we extract the information from the cellgeos first
    if (cellgeos) {    
      PHG4CylinderCellGeomContainer::ConstRange begin_end = cellgeos->get_begin_end();
      PHG4CylinderCellGeomContainer::ConstIterator miter = begin_end.first;
      for( ; miter != begin_end.second; miter++) {
	PHG4CylinderCellGeom *cellgeo = miter->second;
      
	if (verbosity > 1) cellgeo->identify();

	_radii[_layer_ilayer_map[cellgeo->get_layer()]] = cellgeo->get_radius();      
	_smear_xy_layer[_layer_ilayer_map[cellgeo->get_layer()]] = cellgeo->get_radius()*cellgeo->get_phistep();
	_smear_z_layer[_layer_ilayer_map[cellgeo->get_layer()]] = cellgeo->get_zstep();     
      }
    }

    if (laddergeos) {    
      PHG4CylinderGeomContainer::ConstRange begin_end = laddergeos->get_begin_end();
      PHG4CylinderGeomContainer::ConstIterator miter = begin_end.first;
      for( ; miter != begin_end.second; miter++) {
	PHG4CylinderGeom *geo = miter->second;
	
	if (verbosity > 1) geo->identify();
	
	_radii[_layer_ilayer_map[geo->get_layer()]] = geo->get_radius();      
	_smear_xy_layer[_layer_ilayer_map[geo->get_layer()]] = geo->get_strip_y_spacing();
	_smear_z_layer[_layer_ilayer_map[geo->get_layer()]] = geo->get_strip_z_spacing();     
      }
    }
  }  

  // set material on each layer
  
  _material.assign(_radii.size(), 0.03);

  map<int, float>::iterator mat_it;
  for (map<int, float>::iterator iter = _user_material.begin();
       iter != _user_material.end();
       ++iter) {
    _material[_layer_ilayer_map[iter->first]] = iter->second;
  }

  float kappa_max = ptToKappa(_min_pT);

  HelixRange top_range( 0.0, 2.*M_PI,
		       -0.2, 0.2,
			0.0, kappa_max,
		       -0.9, 0.9,
		       -1.0*_dcaz_cut, 1.0*_dcaz_cut);
  if (!_use_vertex) {
    top_range.min_z0 = -10.;
    top_range.max_z0 = 10.;
  }
  
  vector<unsigned int> onezoom(5,0);
  vector<vector<unsigned int> > zoomprofile;
  zoomprofile.assign(3,onezoom);
  zoomprofile[0][0] = 16;
  zoomprofile[0][1] = 1;
  zoomprofile[0][2] = 4;
  zoomprofile[0][3] = 8;
  zoomprofile[0][4] = 1;
  
  zoomprofile[1][0] = 16;
  zoomprofile[1][1] = 1;
  zoomprofile[1][2] = 4;
  zoomprofile[1][3] = 4;
  zoomprofile[1][4] = 1;
  
  zoomprofile[2][0] = 4;
  zoomprofile[2][1] = 2;
  zoomprofile[2][2] = 2;
  zoomprofile[2][3] = 2;
  zoomprofile[2][4] = 2;
  
  // for (unsigned int i = 3; i <= 4; ++i) {
  //   zoomprofile[i][0] = 4;
  //   zoomprofile[i][1] = 2;
  //   zoomprofile[i][2] = 2;
  //   zoomprofile[i][3] = 3;
  //   zoomprofile[i][4] = 2;
  // }
    
  _tracker = new sPHENIXTracker(zoomprofile, 1, top_range, _material, _radii, _magField);
  _tracker->setIterateClustering(true);
  _tracker->setNLayers(_seed_layers);
  _tracker->requireLayers(_req_seed);
  _max_hits_init = _seed_layers*4;
  if(_seed_layers >= 10){_max_hits_init = _seed_layers*2;}
  _min_hits_init = _req_seed;
  if(_seed_layers < 10){ _tracker->setClusterStartBin(1); }
  else{ _tracker->setClusterStartBin(10); }
  _tracker->setRejectGhosts(_reject_ghosts);
  _tracker->setFastChi2Cut(_chi2_cut_fast_par0,
			   _chi2_cut_fast_par1,
			   _chi2_cut_fast_max);
  _tracker->setChi2Cut(_chi2_cut_full);
  _tracker->setChi2RemovalCut(_chi2_cut_full*0.5);
  _tracker->setCellularAutomatonChi2Cut(_ca_chi2_cut);
  _tracker->setPrintTimings(false);
  if(verbosity > 3){_tracker->setPrintTimings(true);}
  _tracker->setVerbosity(verbosity);
  _tracker->setCutOnDca(_cut_on_dca);
  _tracker->setDcaCut(_dca_cut);
  _tracker->setSmoothBack(false);
  _tracker->setBinScale(_bin_scale);
  _tracker->setZBinScale(_z_bin_scale);
  _tracker->setRemoveHits(_remove_hits);
  _tracker->setSeparateByHelicity(true);
  _tracker->setMaxHitsPairs(0);
  _tracker->setCosAngleCut(_cos_angle_cut);
  
  
  vector<vector<unsigned int> > zoomprofile_init;
  zoomprofile_init.assign(4,onezoom);
  for(unsigned int i=0;i<=1;++i)
  {
    zoomprofile_init[i][0] = 8;
    zoomprofile_init[i][1] = 1;
    zoomprofile_init[i][2] = 3;
    zoomprofile_init[i][3] = 4;
    zoomprofile_init[i][4] = 4;
  }
  for(unsigned int i=2;i<=3;++i)
  {
    zoomprofile_init[i][0] = 8;
    zoomprofile_init[i][1] = 1;
    zoomprofile_init[i][2] = 2;
    zoomprofile_init[i][3] = 2;
    zoomprofile_init[i][4] = 2;
  }
  vector<HelixRange> top_range_init;
  unsigned int nphi = 1;
  unsigned int nz0 = 5;
  double phimin = 0.;
  double phi_step = 2.0*M_PI/((double)nphi);
  float kappa_max_init = ptToKappa(_min_pT_init);
  for(unsigned int i=0;i<nphi;++i)
  {
    double z0min = -10.;
    double z0_step = 20./((double)nz0);
    for(unsigned int j=0;j<nz0;++j)
    {
      top_range_init.push_back(HelixRange(phimin, phimin+phi_step,   -0.2, 0.2,   0.0, kappa_max_init,   -0.9, 0.9,   z0min, z0min+z0_step));
      _tracker_vertex.push_back( new sPHENIXTracker(zoomprofile_init, 1, top_range_init.back(), _material, _radii, _magField) );
      if(verbosity > 3){(_tracker_vertex.back())->setPrintTimings(true);}
      (_tracker_vertex.back())->setVerbosity(verbosity);
      (_tracker_vertex.back())->setNLayers(_seed_layers);
      (_tracker_vertex.back())->requireLayers(_req_seed);
      (_tracker_vertex.back())->setClusterStartBin(1);
      (_tracker_vertex.back())->setRejectGhosts(true);
      (_tracker_vertex.back())->setFastChi2Cut(_chi2_cut_fast_par0,
					       _chi2_cut_fast_par1,
					       _chi2_cut_fast_max);
      (_tracker_vertex.back())->setChi2Cut(_chi2_cut_init);
      (_tracker_vertex.back())->setChi2RemovalCut(_chi2_cut_init*0.5);
      (_tracker_vertex.back())->setCellularAutomatonChi2Cut(_ca_chi2_cut);
      (_tracker_vertex.back())->setCutOnDca(false);
      (_tracker_vertex.back())->setSmoothBack(true);
      (_tracker_vertex.back())->setBinScale(_bin_scale);
      (_tracker_vertex.back())->setZBinScale(_z_bin_scale);
      (_tracker_vertex.back())->setRemoveHits(false);
      (_tracker_vertex.back())->setSeparateByHelicity(true);
      (_tracker_vertex.back())->setMaxHitsPairs(0);
      (_tracker_vertex.back())->setCosAngleCut(_cos_angle_cut);
      z0min += z0_step;
    }
    phimin += phi_step;
  }
  
  for(unsigned int ilayer = 0; ilayer < _fit_error_scale.size(); ++ilayer) {
    float scale1 = _fit_error_scale[ilayer];
    float scale2 = _vote_error_scale[ilayer];
    float scale = scale1/scale2;
    _tracker->setHitErrorScale(ilayer, scale);
    for(unsigned int j = 0; j < _tracker_vertex.size(); ++j) {
      _tracker_vertex[j]->setHitErrorScale(ilayer, scale);
    }
  }
  
  return Fun4AllReturnCodes::EVENT_OK;
}
Ejemplo n.º 2
0
void PHG4SvtxClusterizer::ClusterCylinderCells(PHCompositeNode *topNode) {

  //----------
  // Get Nodes
  //----------

  // get the SVX geometry object
  PHG4CylinderCellGeomContainer* geom_container = findNode::getClass<PHG4CylinderCellGeomContainer>(topNode,"CYLINDERCELLGEOM_SVTX");
  if (!geom_container) return;
  
  PHG4HitContainer* g4hits = findNode::getClass<PHG4HitContainer>(topNode,"G4HIT_SVTX");
  if (!g4hits) return;
  
  PHG4CylinderCellContainer* cells = findNode::getClass<PHG4CylinderCellContainer>(topNode,"G4CELL_SVTX");
  if (!cells) return; 
  
  //-----------
  // Clustering
  //-----------

  // sort hits layer by layer
  std::multimap<int,SvtxHit*> layer_hits_mmap;  
  for (SvtxHitMap::Iter iter = _hits->begin();
       iter != _hits->end();
       ++iter) {
    SvtxHit* hit = &iter->second;
    layer_hits_mmap.insert(make_pair(hit->get_layer(),hit));
  }
  
  // loop over cylinder layers
  PHG4CylinderCellGeomContainer::ConstRange layerrange = geom_container->get_begin_end();
  for(PHG4CylinderCellGeomContainer::ConstIterator layeriter = layerrange.first;
      layeriter != layerrange.second;
      ++layeriter) {

    int layer = layeriter->second->get_layer();
    int nphibins = layeriter->second->get_phibins();

    // loop over all hits/cells in this layer
    std::map<PHG4CylinderCell*,SvtxHit*> cell_hit_map;
    std::vector<PHG4CylinderCell*> cell_list;   
    for (std::multimap<int,SvtxHit*>::iterator hiter = layer_hits_mmap.lower_bound(layer);
	 hiter != layer_hits_mmap.upper_bound(layer);
	 ++hiter) {
      SvtxHit* hit = hiter->second;
      PHG4CylinderCell* cell = cells->findCylinderCell(hit->get_cellid());
      cell_list.push_back(cell);
      cell_hit_map.insert(make_pair(cell,hit));
    }

    if (cell_list.size() == 0) continue; // if no cells, go to the next layer
    
    sort(cell_list.begin(), cell_list.end(), PHG4SvtxClusterizer::lessthan);

    typedef adjacency_list <vecS, vecS, undirectedS> Graph;
    typedef graph_traits<Graph>::vertex_descriptor Vertex;
    Graph G;

    for(unsigned int i=0; i<cell_list.size(); i++) {
      for(unsigned int j=i+1; j<cell_list.size(); j++) {
        if( are_adjacent(cell_list[i], cell_list[j], nphibins) )
          add_edge(i,j,G);
      }
      
      add_edge(i,i,G);
    }

    // Find the connections between the vertices of the graph (vertices are the rawhits, 
    // connections are made when they are adjacent to one another)
    vector<int> component(num_vertices(G));
    
    // this is the actual clustering, performed by boost
    connected_components(G, &component[0]); 

    // Loop over the components(hit cells) compiling a list of the
    // unique connected groups (ie. clusters).
    set<int> cluster_ids; // unique components       
    multimap<int, PHG4CylinderCell*> clusters;
    for (unsigned int i=0; i<component.size(); i++) {
      cluster_ids.insert( component[i] );
      clusters.insert( make_pair(component[i], cell_list[i]) );
    }
    
    typedef multimap<int, PHG4CylinderCell*>::iterator mapiterator;
    
    for (set<int>::iterator clusiter = cluster_ids.begin(); 
	 clusiter != cluster_ids.end(); 
	 clusiter++ ) {
      
      int clusid = *clusiter;
      pair<mapiterator,mapiterator> clusrange = clusters.equal_range(clusid);
      
      mapiterator mapiter = clusrange.first;
      
      int layer = mapiter->second->get_layer();
      PHG4CylinderCellGeom* geom = geom_container->GetLayerCellGeom(layer);
      
      SvtxCluster clus;
      clus.set_layer( layer );
      float clus_energy = 0.0;
      unsigned int clus_adc = 0;

      // determine the size of the cluster in phi and z
      // useful for track fitting the cluster

      set<int> phibins;
      set<int> zbins;
      for (mapiter = clusrange.first; mapiter != clusrange.second; mapiter++ ) {
	PHG4CylinderCell* cell = mapiter->second;     
	
	phibins.insert(cell->get_binphi());
	zbins.insert(cell->get_binz());
      }
      
      float pitch = geom->get_phistep()*geom->get_radius();
      float thickness = geom->get_thickness();
      float length = geom->get_zstep();
      float phisize = phibins.size()*pitch;
      float zsize = zbins.size()*length;

      double xsum = 0.0;
      double ysum = 0.0;
      double zsum = 0.0;
      unsigned int nhits = 0;

      for(mapiter = clusrange.first; mapiter != clusrange.second; mapiter++ ) {
        PHG4CylinderCell* cell = mapiter->second;
	SvtxHit* hit = cell_hit_map[cell];
	
	clus.insert_hit(hit->get_id());
	
        clus_energy += hit->get_e();
	clus_adc    += hit->get_adc();

	// compute the hit center
	double r   = geom->get_radius();
        double phi = geom->get_phicenter(cell->get_binphi());

	double x = r*cos(phi);
	double y = r*sin(phi);
        double z = geom->get_zcenter(cell->get_binz());

	if (_make_e_weights[layer]) {
	  xsum += x * hit->get_adc();
	  ysum += y * hit->get_adc();
	  zsum += z * hit->get_adc();  
	} else {
	  xsum += x;
	  ysum += y;
	  zsum += z;
	}
	++nhits;
      }
      
      double clusx = NAN;
      double clusy = NAN;
      double clusz = NAN;

      if (_make_e_weights[layer]) {
	clusx = xsum / clus_adc;
	clusy = ysum / clus_adc;
	clusz = zsum / clus_adc;	
      } else {
	clusx = xsum / nhits;
	clusy = ysum / nhits;
	clusz = zsum / nhits;
      }
      
      double radius  = sqrt(clusx*clusx+clusy*clusy);
      double clusphi = atan2( clusy, clusx);
       
      clus.set_position( 0 , clusx );
      clus.set_position( 1 , clusy );
      clus.set_position( 2 , clusz );

      clus.set_e(clus_energy);
      clus.set_adc(clus_adc);

      float invsqrt12 = 1.0/sqrt(12.);
      
      TMatrixF DIM(3,3);
      DIM[0][0] = pow(0.5*thickness,2);
      DIM[0][1] = 0.0;
      DIM[0][2] = 0.0;
      DIM[1][0] = 0.0;
      DIM[1][1] = pow(0.5*phisize,2);
      DIM[1][2] = 0.0;
      DIM[2][0] = 0.0;
      DIM[2][1] = 0.0;
      DIM[2][2] = pow(0.5*zsize,2);

      TMatrixF ERR(3,3);
      ERR[0][0] = pow(0.5*thickness*invsqrt12,2);
      ERR[0][1] = 0.0;
      ERR[0][2] = 0.0;
      ERR[1][0] = 0.0;
      ERR[1][1] = pow(0.5*phisize*invsqrt12,2);
      ERR[1][2] = 0.0;
      ERR[2][0] = 0.0;
      ERR[2][1] = 0.0;
      ERR[2][2] = pow(0.5*zsize*invsqrt12,2);

      TMatrixF ROT(3,3);
      ROT[0][0] = cos(clusphi);
      ROT[0][1] = -sin(clusphi);
      ROT[0][2] = 0.0;
      ROT[1][0] = sin(clusphi);
      ROT[1][1] = cos(clusphi);
      ROT[1][2] = 0.0;
      ROT[2][0] = 0.0;
      ROT[2][1] = 0.0;
      ROT[2][2] = 1.0;

      TMatrixF ROT_T(3,3);
      ROT_T.Transpose(ROT);
      
      TMatrixF COVAR_DIM(3,3);
      COVAR_DIM = ROT * DIM * ROT_T;
      
      clus.set_size( 0 , 0 , COVAR_DIM[0][0] );
      clus.set_size( 0 , 1 , COVAR_DIM[0][1] );
      clus.set_size( 0 , 2 , COVAR_DIM[0][2] );
      clus.set_size( 1 , 0 , COVAR_DIM[1][0] );
      clus.set_size( 1 , 1 , COVAR_DIM[1][1] );
      clus.set_size( 1 , 2 , COVAR_DIM[1][2] );
      clus.set_size( 2 , 0 , COVAR_DIM[2][0] );
      clus.set_size( 2 , 1 , COVAR_DIM[2][1] );
      clus.set_size( 2 , 2 , COVAR_DIM[2][2] );

      TMatrixF COVAR_ERR(3,3);
      COVAR_ERR = ROT * ERR * ROT_T;

      clus.set_error( 0 , 0 , COVAR_ERR[0][0] );
      clus.set_error( 0 , 1 , COVAR_ERR[0][1] );
      clus.set_error( 0 , 2 , COVAR_ERR[0][2] );
      clus.set_error( 1 , 0 , COVAR_ERR[1][0] );
      clus.set_error( 1 , 1 , COVAR_ERR[1][1] );
      clus.set_error( 1 , 2 , COVAR_ERR[1][2] );
      clus.set_error( 2 , 0 , COVAR_ERR[2][0] );
      clus.set_error( 2 , 1 , COVAR_ERR[2][1] );
      clus.set_error( 2 , 2 , COVAR_ERR[2][2] );
      
      if (clus_energy > get_threshold_by_layer(layer)) {
	SvtxCluster* ptr = _clusterlist->insert(clus);
	if (!ptr->IsValid()) {
	  static bool first = true;
	  if (first) {
	    cout << PHWHERE << "ERROR: Invalid SvtxClusters are being produced" << endl;
	    ptr->identify();
	    first = false;
	  }
	}
	
	if (verbosity>1) {
	  cout << "r=" << radius << " phi=" << clusphi << " z=" << clusz << endl;
	  cout << "pos=(" << clus.get_position(0) << ", " << clus.get_position(1)
	       << ", " << clus.get_position(2) << ")" << endl;
	  cout << endl;
	}
      }	else if (verbosity>1) {
	cout << "removed r=" << radius << " phi=" << clusphi << " z=" << clusz << endl;
	cout << "pos=(" << clus.get_position(0) << ", " << clus.get_position(1)
	     << ", " << clus.get_position(2) << ")" << endl;
	cout << endl;
      } 
    }
  }
  
  return;
}