/////////////////////////////////////////////////////////////////////////// // // FPS_L1ClusterChunk.cpp // /////////////////////////////////////////////////////////////////////////// // Created: JUN-99: A. Lucotte // // Purpose: L1 FPS Cluster Finder code // - Form FPS clusters as defined in FPS_L1Cluster Class // - Count total number of FPS clusters found // // History: JUL-99 A.L. // - completed the modification due to the use of // FPS_L1Cluster Class // - used packing/unpacking function by Mrinmoy // SEP-99 A.L. // - got rid of packing/unpacking functions // - switched to M. Fortner Format in his new class // D0MCH::CTTClusterChannel --still incomplete // - Added MIP bit pattern info, seen as an integer: // pattern = 7 bits:xxxxxxx <==> integer ranging 1 to 64 // Method Get_ClusterMip() has been used. // SEP-99 // - Added L1 Data (cluster Count): // electron / shower count per sector (==Analog Front End Board) // electron / shower count per quadrant(==Broadcaster level) // troncation used: // maximum of 16 e- + 16 shower / Sector // maximum of 32 e- + 32 shower / Quadrant // Note: sector index is 0 to 15 (NORTH) // 16 to 31 (SOUTH) // quadrant indx is 0 to 3 (NORTH) // 4 to 7 (SOUTH) // - Added event count in the Class: // FPS_L1ClusterChunk( _count, Event ) /////////////////////////////////////////////////////////////////////////// #include "fps_reco/FPSClusterChunk.hpp" #include "fps_reco/FPSClusterWedgeData.hpp" #include "fps_address/FPSChannelAddress.hpp" #include "fps_address/FPSChannelCluster.hpp" #include "tsim_l1ft/cft_hittrk.hpp" #include "tsim_l1ft/FPS_L1ClusterChunk.hpp" #include "tsim_l1ft/FPS_L1Cluster.hpp" #include "HepTuple/HepNtuple.h" #include "edm/TKey.hpp" #include "edm/THandle.hpp" int FPS_L1ClusterChunk::_l1fpsClusterCount = 0 ; // Constructor: FPS_L1ClusterChunk::FPS_L1ClusterChunk( int _count, edm::Event& event ) { // Make L1 cluster & output std::vector _l1fpsClusterCount = 0; for( int isector =0; isector < 32; isector++){ _l1FEelectronCount[isector] = 0; _l1FEshowerCount[isector] = 0; } for( int iquadrant = 0; iquadrant < 8; iquadrant++){ _l1BRelectronCount[ iquadrant ] = 0; _l1BRshowerCount[ iquadrant ] = 0; } for( int cand=0; cand < 512; cand++ ){ FPS_L1Cluster fps_l1cluster; _fps_l1cluster[ cand ] = fps_l1cluster; } FPS_L1ClusterChunkForm(event) ; } // Destructor: FPS_L1ClusterChunk::~FPS_L1ClusterChunk(){} // Accessor: int FPS_L1ClusterChunk::Get_L1ClusterCount( edm::Event& event ){ return _l1fpsClusterCount;} //=================================================================== // Method: void FPS_L1ClusterChunk::FPS_L1ClusterChunkForm //=================================================================== // Created : A.L. July 99 // Purpose : Form cluster chunk of fps_l1clusters. // Modified: A.L. SEP-99 // - Change names of methods // - Accomodate for CTTClusterChannel Class format //=================================================================== void FPS_L1ClusterChunk::FPS_L1ClusterChunkForm( edm::Event& event){ // (1) Extract ClusterChunk from the event: const edm::TKey cluster_key; typedef std::list > ClusterChunkList; ClusterChunkList cluster_chunk_list = cluster_key.findAll( event ); // (2) Loop over Cluster Chunk List item: edm::THandle the_clusters; for( ClusterChunkList::const_iterator i = cluster_chunk_list.begin(); i != cluster_chunk_list.end(); i++) { if( i != cluster_chunk_list.begin() || cluster_chunk_list.size() ==1 ) { the_clusters = *i ; } } const FPSClusterChunk* cluster_ptr = the_clusters.ptr(); // Initialization of geometrical parameters // (has to be replaced by rcp file..) const int shower_addr_max = 144; const int mip_addr_max = 103; const int nmax = 1000; const int sector_max = 16; // Initialization of #clusters arrays const int nsector =32; const int nquadrant = 8; int _l1fpsClusterCount = 0; int _FEelectronCount[ nsector ]; int _BRelectronCount[ nquadrant]; int _FEshowerCount[ nsector ]; int _BRshowerCount[ nquadrant]; // Initialization of Local arrays & counters int icand; int shower_count = {0}; int mip_count = {0}; int nb_electron = {0}; int shower_high[ nmax ]; int shower_lowt[ nmax ]; int shower_side[ nmax ]; int shower_sect[ nmax ]; int shower_addr[ nmax ]; int shower_type[ nmax ]; int shower_widt[ nmax ]; int shower_orie[ nmax ]; int shower_bits[ nmax ]; int mip_orie[ nmax ]; int mip_side[ nmax ]; int mip_sect[ nmax ]; int mip_addr[ nmax ]; for( int ini=0; ini <= nmax; ini++){ shower_high[ ini ] = 0; shower_lowt[ ini ] = 0; shower_side[ ini ] = 0; shower_type[ ini ] = 0; shower_widt[ ini ] = 0; shower_orie[ ini ] = 0; shower_bits[ ini ] = 0; mip_orie[ ini ] = 0; mip_side[ ini ] = 0; mip_sect[ ini ] = 0; mip_addr[ ini ] = 0; } // (3) cluster-finder Code begins here if( cluster_ptr != 0 ){ FPSClusterChunk::DataMap chunk_data = cluster_ptr->wedges(); // if( chunk_data.begin() != chunk_data.end() ) _events_written++; for( FPSClusterChunk::DataMap::const_iterator i = chunk_data.begin(); i != chunk_data.end(); i++ ) { // get reconstructed wedge: const FPSClusterWedgeData* the_wedge = (*i).second; assert( the_wedge != 0 ); // proceed only if we have reconstructed hits in wedge: // ------------------------------------------------- //cout << "----> DEBUG: " << "hit_count= " << the_wedge->hit_count() << endl; if( the_wedge->hit_count() > 0 ){ const FPSWedgeAddress waddr = the_wedge->wedge(); typedef std::vector UV; UV uv; uv.push_back( FPSChannelAddress::U); uv.push_back( FPSChannelAddress::V); // Loop over sublayer u/v of a wedge: // ---------------------------------- for( int j=0; j < uv.size(); j++){ //cout << "----> DEBUG: " << uv.size() << " j= " << j // << " U/V = " << uv[j] << " wedge->cluster_count = " // << the_wedge->cluster_count(uv[j]) << endl; // Loop over clusters: // ------------------- for( int k=0; k < the_wedge->cluster_count( uv[j] ); k++ ){ const FPSChannelCluster the_cluster = the_wedge->cluster( uv[j],k ); int address = the_cluster.strip_index(0); int width = the_cluster.strip_count(); int iwedge = the_cluster.wedge().wedge_index(); int ilayer = the_cluster.wedge().layer_index(); int iside = the_wedge->wedge().unit_index(); int subindex = uv[j] ; int isector = 0; if( ilayer == 3)isector = 2*iwedge; if( ilayer == 2)isector = 2*iwedge+1; if( ilayer == 1)isector = 2*iwedge; if( ilayer == 0)isector = 2*iwedge+1; // cout << "----> count " << k << " cluster addr = " << address // << " width = " << width << " layer = " << ilayer // << " Side = " << iside << " U/V = " << uv[j] // << " Sector = " << isector << endl; // Controls that parameters are in physical boudaries //cout << "----> count " << k << " cluster addr = " // << the_cluster.strip_index(0) // << " width = " << the_cluster.strip_count() // << " wedge = " // << the_cluster.wedge().wedge_index() // << " Layer = " // << the_cluster.wedge().layer_index() // << " Side = " << the_wedge->wedge().unit_index() // << " U/V = " // << uv[j] // << " sector = " // << isector // << endl; bool proceed_shower = ( subindex >= 0 && subindex <= 1) && ( iside >= 0 && iside <= 1) && ( isector >= 1 && isector <= sector_max ) && ( address > 0 && address <= shower_addr_max ) && ( width > 0 && width <= shower_addr_max ) ; bool proceed_mip = ( subindex >= 0 && subindex <= 1) && ( iside >= 0 && iside <= 1) && ( isector >= 1 && isector <= sector_max ) && ( address > 0 && address <= mip_addr_max ); // DOWNstream clusters if( the_wedge->wedge().is_downstream() ){ if(proceed_shower){ shower_orie[shower_count] = subindex; shower_side[shower_count] = iside; shower_sect[shower_count] = isector; shower_addr[shower_count] = address; shower_widt[shower_count] = width; shower_count++ ; } } // UPstream clusters else{ if( the_wedge->wedge().is_upstream() ){ if( proceed_mip ){ mip_count++ ; mip_orie[mip_count] = subindex; mip_side[mip_count] = iside; mip_sect[mip_count] = isector; mip_addr[mip_count] = address; } } } } } } } } //-------------------------------------------------------- // Fills Level-2 Data information if there is >= 1 cluster //-------------------------------------------------------- // // Initialization _l1fpsClusterCount = 0; for( int is=0; is <= 32; is++){ _FEelectronCount[ is ]= 0; _FEshowerCount[ is ] = 0; } for( int iq=0; iq <= 4; iq++){ _BRelectronCount[ iq ]= 0; _BRshowerCount[ iq ] = 0; } if( shower_count > 0 && shower_count <= 2*sector_max*shower_addr_max){ for(int isho = 1; isho <= shower_count ; isho++){ // proceed if variables in physical boundaries bool shower_sect_ok = ( shower_sect[isho] <= 16 ); bool shower_side_ok = ( abs(shower_side[isho]) <= 1 ); bool shower_orie_ok = ( abs(shower_orie[isho]) <= 1 ); bool shower_addr_ok = ( shower_addr[isho] <= shower_addr_max); bool mip_sect_ok = ( shower_sect[isho] <= 16 ); bool mip_side_ok = ( abs(shower_side[isho]) <= 1 ); bool mip_orie_ok = ( abs(shower_orie[isho]) <= 1 ); bool mip_addr_ok = ( shower_addr[isho] <= mip_addr_max); bool proceed = (shower_sect_ok && shower_side_ok && shower_orie_ok && shower_addr_ok && mip_sect_ok && mip_side_ok && mip_orie_ok && mip_addr_ok); // Determine Cluster Type if( proceed ){ shower_bits[isho] = 0; int mip_bit = 0; for(int imip = 1; imip <= mip_count; imip++){ if(shower_side[isho] == mip_side[imip] && shower_orie[isho] == mip_orie[imip] && shower_sect[isho] == mip_sect[imip] && mip_addr[imip] >= shower_addr[isho]-6 && mip_addr[imip] <= shower_addr[isho]){ mip_bit = shower_addr[isho]-mip_addr[imip]; shower_bits[isho] = shower_bits[isho] + mip_bit; } } int isector = shower_sect[ isho ]; if( shower_bits[isho] > 0 ){ shower_type[isho] = 1; if(shower_side[isho] == 1)_FEelectronCount[ isector ]++; if(shower_side[isho] == 0)_FEelectronCount[ isector+15 ]++; } else{ if(shower_bits[isho] == 0 ){ shower_type[isho] = 0; if(shower_side[isho] == 1)_FEshowerCount[ isector ]++; if(shower_side[isho] == 0)_FEshowerCount[ isector+15 ]++; } } _l1fpsClusterCount++; FPS_L1Cluster fps_l1cluster( shower_type[isho], shower_high[isho], shower_lowt[isho], shower_side[isho], shower_sect[isho], shower_addr[isho], shower_widt[isho], shower_orie[isho], shower_bits[isho]); _fps_l1cluster[ _l1fpsClusterCount ] = fps_l1cluster; } // if (proceed ) } // for (int isho = ...) } // if( shower_count > ) for(int isec=0; isec<=32; isec++){ if(_FEelectronCount[ isec ]> 16)_FEelectronCount[ isec ]=16; if(_FEshowerCount[ isec ]> 16)_FEshowerCount[ isec ]=16; } for(int iq=1; iq<=8; iq++){ _BRelectronCount[ iq ] = _FEelectronCount[ 4*iq-4 ]+ _FEelectronCount[ 4*iq-3 ]+ _FEelectronCount[ 4*iq-2 ]+ _FEelectronCount[ 4*iq-1 ]; _BRshowerCount[ iq ] = _FEshowerCount[ 4*iq-4 ]+ _FEshowerCount[ 4*iq-3 ]+ _FEshowerCount[ 4*iq-2 ]+ _FEshowerCount[ 4*iq-1 ]; } // cout << " -- FPS Cluster (e- + shower) Count: " << _l1fpsClusterCount << endl; //for( int isec = 0; isec <= 32; isec++){ // if( _FEelectronCount[ isec ] != 0 ){ //cout << " o Electrons: sector= " << isec << " candidates= " // << _FEelectronCount[ isec ] << " " << endl; //} //if( _FEshowerCount[ isec ] != 0 ){ //cout << " o Showers : sector= " << isec << " candidates= " // << _FEshowerCount[ isec ] << " " << endl; //} // cout << "=========================================" << endl; if ( cft_trk::wrintp) { cft_trk::CFTL1_ntuple->capture("FPSL1::nfps", _l1fpsClusterCount ); // array size if( _l1fpsClusterCount > 0 ){ cft_trk::CFTL1_ntuple->capture("FPSL1::sector",&shower_sect[0] , _l1fpsClusterCount); cft_trk::CFTL1_ntuple->capture("FPSL1::side",&shower_side[0] , _l1fpsClusterCount); cft_trk::CFTL1_ntuple->capture("FPSL1::layer",&shower_orie[0] , _l1fpsClusterCount); cft_trk::CFTL1_ntuple->capture("FPSL1::address",&shower_addr[0], _l1fpsClusterCount); cft_trk::CFTL1_ntuple->capture("FPSL1::width",&shower_widt[0] , _l1fpsClusterCount); cft_trk::CFTL1_ntuple->capture("FPSL1::mipbits",&shower_bits[0], _l1fpsClusterCount); } cft_trk::CFTL1_ntuple->captureBlock("FPSL1"); } } //============================================================================= // Method: FPS_L1ClusterChunk::create_fpsl1Chunk //============================================================================= // // Created: SEP-99 A.L. // // Purpose: Fill fps_l1chunk using standard format CTTClusterChannel // History: SEP-22 A.L. Wait for Mike Fortner's update: // - setOrientation(), setType() do not exist yet in CTTClusterChannel // - setThreshold, setAddress still need to be modified //============================================================================= std::vector FPS_L1ClusterChunk::create_fpsl1Chunk(){ int version = 1; // set arbitrarily int modid = 4; // FPS = 4 std::vector fps_l1chunk; // Loop over FPSClusters for ( int iobj = 0; iobj < _l1fpsClusterCount ; iobj++ ){ D0MCH::CTTClusterChannel chan; chan.setID( modid, iobj+1 ); chan.setThreshold( _fps_l1cluster[iobj].Get_ClusterLow() ); // _fps_l1cluster[iobj].Get_ClusterHig() ); // Temporary Fixes for: // Address = 1000*sector + Strip index int adress = 1000*_fps_l1cluster[iobj].Get_ClusterSect() + _fps_l1cluster[iobj].Get_ClusterAddr(); chan.setAddress( adress ); chan.setWidth(_fps_l1cluster[iobj].Get_ClusterWidt() ); //chan.setOrientation( _fps_l1cluster[iobj].Get_ClusterOrie() ); chan.setMipPattern(_fps_l1cluster[iobj].Get_ClusterMip() ); //chan.setType( _fps_l1cluster[iobj].Get_ClusterType() ); chan.setError( 0 ); fps_l1chunk.push_back( chan ) ; } return fps_l1chunk; } void FPS_L1ClusterChunk::initFPSHistogram() { cft_trk::CFTL1_ntuple->columnAt("FPSL1::nfps",&(_l1fpsClusterCount),(int)0); cft_trk::CFTL1_ntuple->span("FPSL1::nfps",0,l1fps_const::maxfps_cls); }