Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-06 08:17:54

0001 /*!
0002  * \file MicromegasMapping.cc
0003  * \author Hugo Pereira Da Costa <hugo.pereira-da-costa@cea.fr>
0004  */
0005 
0006 #include "MicromegasMapping.h"
0007 #include "MicromegasDefs.h"
0008 
0009 #include <algorithm>
0010 #include <cassert>
0011 
0012 namespace
0013 {
0014 
0015   class mec8_channel_id
0016   {
0017     public:
0018 
0019     /*
0020     * 0 or 1, corresponding to cable1 and cable 2 as defined by Takao in
0021     * https://indico.bnl.gov/event/18458/contributions/73400/attachments/46043/77969/FEE_to_MEC_map_Feb17_2023.xlsx
0022     */
0023 // NOLINTNEXTLINE(misc-non-private-member-variables-in-classes)
0024     int m_cable_id = 0;
0025 
0026     /*
0027     * 0 or 1, corresponding to j2 or j3 in transition board drawing in
0028     * https://wiki.sphenix.bnl.gov/index.php/File:HDR-225938-XX.PNG.png
0029     * https://wiki.sphenix.bnl.gov/index.php/File:HDR-225940-XX.PNG.png
0030     * and as defined by Takao in
0031     * https://indico.bnl.gov/event/18458/contributions/73400/attachments/46043/77969/FEE_to_MEC_map_Feb17_2023.xlsx
0032     */
0033 // NOLINTNEXTLINE(misc-non-private-member-variables-in-classes)
0034     int m_connector_id = 0;
0035 
0036     /*
0037     * 1 to 70 as defined in
0038     * https://wiki.sphenix.bnl.gov/index.php/File:HDR-225938-XX.PNG.png
0039     * https://wiki.sphenix.bnl.gov/index.php/File:HDR-225940-XX.PNG.png
0040     */
0041 // NOLINTNEXTLINE(misc-non-private-member-variables-in-classes)
0042     int m_channel_id = 0;
0043 
0044     // constructor
0045     mec8_channel_id( int cable_id, int connector_id, int channel_id ):
0046       m_cable_id( cable_id ),
0047       m_connector_id( connector_id ),
0048       m_channel_id( channel_id )
0049     {}
0050 
0051   };
0052 
0053   // less than operator
0054   inline bool operator < (const mec8_channel_id& lhs, const mec8_channel_id& rhs )
0055   {
0056     if( lhs.m_cable_id != rhs.m_cable_id )
0057     {
0058       return lhs.m_cable_id < rhs.m_cable_id;
0059     }
0060     if( lhs.m_connector_id != rhs.m_connector_id )
0061     {
0062       return lhs.m_connector_id < rhs.m_connector_id;
0063     }
0064     return lhs.m_channel_id < rhs.m_channel_id;
0065   }
0066 
0067   // print mapping
0068   [[maybe_unused]] void print_mapping( const std::string& name, const std::array<int, MicromegasDefs::m_nchannels_fee>& array )
0069   {
0070     int count = 0;
0071     std::cout << "int " << name << "[" << array.size() << "] = {" << std::endl << "  ";
0072     for( size_t i =0; i < array.size(); ++i )
0073     {
0074       if( i > 0 )
0075       {
0076     std::cout << ", ";
0077       }
0078       if( count == 32 )
0079       {
0080         std::cout << std::endl << "  ";
0081         count = 0;
0082       }
0083       std::cout << array[i];
0084       ++count;
0085     }
0086 
0087     std::cout << std::endl << "};" << std::endl;
0088   }
0089 
0090 }
0091 
0092 //____________________________________________________________________________________________________
0093 MicromegasMapping::MicromegasMapping():
0094 m_detectors( {
0095   /*
0096    * see https://wiki.sphenix.bnl.gov/index.php/TPc_Outer_Tracker_(TPOT)#Fiber_mapping.2C_as_of_2023.2F3.2F22
0097    */
0098   // south side
0099   {5002, 5, MicromegasDefs::genHitSetKey(55, MicromegasDefs::SegmentationType::SEGMENTATION_PHI, 4 ), "sec20.0", "R3.1", "M9P",  "SEIP" },
0100   {5002, 7, MicromegasDefs::genHitSetKey(56, MicromegasDefs::SegmentationType::SEGMENTATION_Z,   4 ), "sec20.1", "R3.2", "M9Z",  "SEIZ" },
0101   {5002, 6, MicromegasDefs::genHitSetKey(55, MicromegasDefs::SegmentationType::SEGMENTATION_PHI, 0 ), "sec21.0", "R3.3", "M5P",  "SCOP" },
0102   {5002, 8, MicromegasDefs::genHitSetKey(56, MicromegasDefs::SegmentationType::SEGMENTATION_Z,   0 ), "sec21.1", "R3.4", "M5Z",  "SCOZ" },
0103   {5002, 9, MicromegasDefs::genHitSetKey(55, MicromegasDefs::SegmentationType::SEGMENTATION_PHI, 1 ), "sec21.2", "R3.5", "M8P",  "SCIP" },
0104   {5001, 23, MicromegasDefs::genHitSetKey(56, MicromegasDefs::SegmentationType::SEGMENTATION_Z,   1 ), "sec21.3", "R3.9", "M8Z",  "SCIZ" },
0105   {5001, 24, MicromegasDefs::genHitSetKey(55, MicromegasDefs::SegmentationType::SEGMENTATION_PHI, 6 ), "sec22.0", "R3.7", "M6P",  "SWIP" },
0106   {5001, 25, MicromegasDefs::genHitSetKey(56, MicromegasDefs::SegmentationType::SEGMENTATION_Z,   6 ), "sec22.1", "R3.8", "M6Z",  "SWIZ" },
0107 
0108   // north side
0109   // on May 29 2024, fiber 11 was swapped to fiber 21
0110   // {5001, 11, MicromegasDefs::genHitSetKey(55, MicromegasDefs::SegmentationType::SEGMENTATION_PHI, 5 ), "sec8.0",  "R2.1", "M2P",  "NEIP" },
0111   {5002, 21, MicromegasDefs::genHitSetKey(55, MicromegasDefs::SegmentationType::SEGMENTATION_PHI, 5 ), "sec8.0",  "R3.10", "M2P",  "NEIP" },
0112   {5001, 12, MicromegasDefs::genHitSetKey(56, MicromegasDefs::SegmentationType::SEGMENTATION_Z,   5 ), "sec8.1",  "R2.2", "M2Z",  "NEIZ" },
0113   {5001, 19, MicromegasDefs::genHitSetKey(55, MicromegasDefs::SegmentationType::SEGMENTATION_PHI, 3 ), "sec9.0",  "R2.3", "M10P", "NCOP" },
0114   {5001, 18, MicromegasDefs::genHitSetKey(56, MicromegasDefs::SegmentationType::SEGMENTATION_Z,   3 ), "sec9.1",  "R2.4", "M10Z", "NCOZ" },
0115   {5002, 0,  MicromegasDefs::genHitSetKey(55, MicromegasDefs::SegmentationType::SEGMENTATION_PHI, 2 ), "sec9.2",  "R2.5", "M4P",  "NCIP" },
0116   {5002, 1,  MicromegasDefs::genHitSetKey(56, MicromegasDefs::SegmentationType::SEGMENTATION_Z,   2 ), "sec9.3",  "R2.6", "M4Z",  "NCIZ" },
0117   {5002, 15, MicromegasDefs::genHitSetKey(55, MicromegasDefs::SegmentationType::SEGMENTATION_PHI, 7 ), "sec10.0", "R2.7", "M7P",  "NWIP" },
0118   {5002, 14, MicromegasDefs::genHitSetKey(56, MicromegasDefs::SegmentationType::SEGMENTATION_Z,   7 ), "sec10.1", "R2.8", "M7Z",  "NWIZ" }
0119 } )
0120 {
0121   std::cout << "MicromegasMapping::MicromegasMapping." << std::endl;
0122 
0123   // sort vector based on layer/tile
0124   std::sort( m_detectors.begin(), m_detectors.end(), []( const DetectorId& lhs, const DetectorId& rhs )
0125      {
0126        if(TrkrDefs::getLayer( lhs.m_hitsetkey ) != TrkrDefs::getLayer( rhs.m_hitsetkey ) )
0127        {
0128      return TrkrDefs::getLayer( lhs.m_hitsetkey ) < TrkrDefs::getLayer( rhs.m_hitsetkey );
0129        }
0130        else
0131        {
0132      return MicromegasDefs::getTileId( lhs.m_hitsetkey ) < MicromegasDefs::getTileId( rhs.m_hitsetkey );
0133        }
0134      } );
0135 
0136   // fill detector map from vector
0137   for( const auto& detector_id:m_detectors )
0138   {
0139     m_detector_map.emplace( detector_id.m_fee_id, detector_id );
0140   }
0141 
0142   // construct channel mapping
0143   construct_channel_mapping();
0144 }
0145 
0146 //____________________________________________________________________________________________________
0147 std::vector<int> MicromegasMapping::get_fee_id_list() const
0148 {
0149   std::vector<int> out;
0150   std::transform( m_detectors.begin(), m_detectors.end(), std::back_inserter( out ), []( const DetectorId& det_id ){ return det_id.m_fee_id; } );
0151   return out;
0152 }
0153 
0154 
0155 //____________________________________________________________________________________________________
0156 std::vector<int> MicromegasMapping::get_fee_id_list( int packet_id ) const
0157 {
0158   std::vector<int> out;
0159   for( const auto& detector:m_detectors )
0160   {
0161     if( detector.m_packet_id == packet_id )
0162     {out.push_back( detector.m_fee_id );}
0163   }
0164   return out;
0165 }
0166 
0167 //____________________________________________________________________________________________________
0168 TrkrDefs::hitsetkey MicromegasMapping::get_hitsetkey( int fee_id ) const
0169 {
0170 
0171   // apply mapping changes
0172   const auto iter = m_detector_map.find( fee_id );
0173   if( iter == m_detector_map.end() )
0174   {
0175     std::cout << "MicromegasMapping::get_hitsetkey - invalid fee_id: " << fee_id << std::endl;
0176     return 0;
0177   }
0178   else
0179   {
0180     return iter->second.m_hitsetkey;
0181   }
0182 }
0183 
0184 //____________________________________________________________________________________________________
0185 std::string MicromegasMapping::get_detname_saclay( int fee_id ) const
0186 {
0187   // apply mapping changes
0188   const auto iter = m_detector_map.find( fee_id );
0189   if( iter == m_detector_map.end() )
0190   {
0191     std::cout << "MicromegasMapping::get_detname_saclay - invalid fee_id: " << fee_id << std::endl;
0192     return std::string();
0193   }
0194   else
0195   {
0196     return iter->second.m_detname_saclay;
0197   }
0198 }
0199 
0200 //____________________________________________________________________________________________________
0201 std::string MicromegasMapping::get_detname_sphenix( int fee_id ) const
0202 {
0203   // apply mapping changes
0204   const auto iter = m_detector_map.find( fee_id );
0205   if( iter == m_detector_map.end() )
0206   {
0207     std::cout << "MicromegasMapping::get_detname_sphenix - invalid fee_id: " << fee_id << std::endl;
0208     return std::string();
0209   }
0210   else
0211   {
0212     return iter->second.m_detname_sphenix;
0213   }
0214 }
0215 
0216 //____________________________________________________________________________________________________
0217 int MicromegasMapping::get_physical_strip( int fee_id, int channel_id) const
0218 {
0219   // apply mapping changes
0220   // bound check
0221   if( channel_id < 0 || channel_id >= MicromegasDefs::m_nchannels_fee )
0222   {
0223     std::cout << "MicromegasMapping::get_physical_strip - invalid channel: " << channel_id << std::endl;
0224     return -1;
0225   }
0226 
0227   // get hitsetkey and orientation
0228   const auto hitsetkey = get_hitsetkey(fee_id);
0229   const auto segmentation_type = MicromegasDefs::getSegmentationType(hitsetkey);
0230   switch (segmentation_type)
0231   {
0232     case MicromegasDefs::SegmentationType::SEGMENTATION_Z:
0233     return m_fee_to_strip_mapping_z[channel_id];
0234 
0235     case MicromegasDefs::SegmentationType::SEGMENTATION_PHI:
0236     return m_fee_to_strip_mapping_phi[channel_id];
0237   }
0238 
0239   // never reached
0240   return -1;
0241 }
0242 
0243 //____________________________________________________________________________________________________
0244 std::string MicromegasMapping::get_detname_saclay_from_hitsetkey( TrkrDefs::hitsetkey key ) const
0245 {
0246   const auto iter = std::find_if( m_detectors.begin(), m_detectors.end(), [key](const DetectorId& detector ) { return detector.m_hitsetkey == key; } );
0247   if( iter == m_detectors.end() )
0248   {
0249     std::cout << "MicromegasMapping::get_detname_saclay_from_hitsetkey - invalid key: " << key << std::endl;
0250     return std::string();
0251   }
0252   else
0253   {
0254     return iter->m_detname_saclay;
0255   }
0256 }
0257 
0258 //____________________________________________________________________________________________________
0259 std::string MicromegasMapping::get_detname_sphenix_from_hitsetkey( TrkrDefs::hitsetkey key ) const
0260 {
0261   const auto iter = std::find_if( m_detectors.begin(), m_detectors.end(), [key](const DetectorId& detector ) { return detector.m_hitsetkey == key; } );
0262   if( iter == m_detectors.end() )
0263   {
0264     std::cout << "MicromegasMapping::get_detname_sphenix_from_hitsetkey - invalid key: " << key << std::endl;
0265     return std::string();
0266   }
0267   else
0268   {
0269     return iter->m_detname_sphenix;
0270   }
0271 }
0272 
0273 //____________________________________________________________________________________________________
0274 int MicromegasMapping::get_fee_id_from_hitsetkey( TrkrDefs::hitsetkey key ) const
0275 {
0276   const auto iter = std::find_if( m_detectors.begin(), m_detectors.end(), [key](const DetectorId& detector ) { return detector.m_hitsetkey == key; } );
0277   if( iter == m_detectors.end() )
0278   {
0279     std::cout << "MicromegasMapping::get_fee_id_from_hitsetkey - invalid key: " << key << std::endl;
0280     return -1;
0281   }
0282   else
0283   {
0284     return iter->m_fee_id;
0285   }
0286 }
0287 
0288 //____________________________________________________________________________________________________
0289 void MicromegasMapping::construct_channel_mapping()
0290 {
0291   // procedure details: https://indico.bnl.gov/event/19349/contributions/75908/attachments/47219/80098/talk.pdf
0292 
0293   /*
0294    * map channel id on FEE board (0-255) to mec8 connector and channel
0295    * there are 2 cables (left and right) per FEE board
0296    * each cable has two MEC8 connector
0297    * on each MEC8 connector, channel 1,2, 35, 36, 69 and 70 are connected to the ground
0298    * the other 64 channels are signals
0299    */
0300   // source: https://indico.bnl.gov/event/18458/contributions/73400/attachments/46043/77969/FEE_to_MEC_map_Feb17_2023.xlsx
0301   std::array<mec8_channel_id, MicromegasDefs::m_nchannels_fee> fee_to_mec8_mapping =
0302   {{
0303     {0,0,34}, {0,0,33}, {0,0,32}, {0,0,31}, {0,0,30}, {0,0,29}, {0,0,28}, {0,0,27},
0304     {0,0,26}, {0,0,25}, {0,0,24}, {0,0,23}, {0,0,22}, {0,0,21}, {0,0,20}, {0,0,19},
0305     {0,0,18}, {0,0,17}, {0,0,16}, {0,0,15}, {0,0,14}, {0,0,13}, {0,0,12}, {0,0,11},
0306     {0,0,10}, {0,0,9},  {0,0,8},  {0,0,7},  {0,0,6},  {0,0,5},  {0,0,4},  {0,0,3},
0307 
0308     {0,0,68}, {0,0,67}, {0,0,66}, {0,0,65}, {0,0,64}, {0,0,63}, {0,0,62}, {0,0,61},
0309     {0,0,60}, {0,0,59}, {0,0,58}, {0,0,57}, {0,0,56}, {0,0,55}, {0,0,54}, {0,0,53},
0310     {0,0,52}, {0,0,51}, {0,0,50}, {0,0,49}, {0,0,48}, {0,0,47}, {0,0,46}, {0,0,45},
0311     {0,0,44}, {0,0,43}, {0,0,42}, {0,0,41}, {0,0,40}, {0,0,39}, {0,0,38}, {0,0,37},
0312 
0313     {0,1,34}, {0,1,33}, {0,1,32}, {0,1,31}, {0,1,30}, {0,1,29}, {0,1,28}, {0,1,27},
0314     {0,1,26}, {0,1,25}, {0,1,24}, {0,1,23}, {0,1,22}, {0,1,21}, {0,1,20}, {0,1,19},
0315     {0,1,18}, {0,1,17}, {0,1,16}, {0,1,15}, {0,1,14}, {0,1,13}, {0,1,12}, {0,1,11},
0316     {0,1,10}, {0,1,9},  {0,1,8},  {0,1,7},  {0,1,6},  {0,1,5},  {0,1,4},  {0,1,3},
0317 
0318     {0,1,68}, {0,1,67}, {0,1,66}, {0,1,65}, {0,1,64}, {0,1,63}, {0,1,62}, {0,1,61},
0319     {0,1,60}, {0,1,59}, {0,1,58}, {0,1,57}, {0,1,56}, {0,1,55}, {0,1,54}, {0,1,53},
0320     {0,1,52}, {0,1,51}, {0,1,50}, {0,1,49}, {0,1,48}, {0,1,47}, {0,1,46}, {0,1,45},
0321     {0,1,44}, {0,1,43}, {0,1,42}, {0,1,41}, {0,1,40}, {0,1,39}, {0,1,38}, {0,1,37},
0322 
0323     {1,0,34}, {1,0,33}, {1,0,32}, {1,0,31}, {1,0,30}, {1,0,29}, {1,0,28}, {1,0,27},
0324     {1,0,26}, {1,0,25}, {1,0,24}, {1,0,23}, {1,0,22}, {1,0,21}, {1,0,20}, {1,0,19},
0325     {1,0,18}, {1,0,17}, {1,0,16}, {1,0,15}, {1,0,14}, {1,0,13}, {1,0,12}, {1,0,11},
0326     {1,0,10}, {1,0,9},  {1,0,8},  {1,0,7},  {1,0,6},  {1,0,5},  {1,0,4},  {1,0,3},
0327 
0328     {1,0,68}, {1,0,67}, {1,0,66}, {1,0,65}, {1,0,64}, {1,0,63}, {1,0,62}, {1,0,61},
0329     {1,0,60}, {1,0,59}, {1,0,58}, {1,0,57}, {1,0,56}, {1,0,55}, {1,0,54}, {1,0,53},
0330     {1,0,52}, {1,0,51}, {1,0,50}, {1,0,49}, {1,0,48}, {1,0,47}, {1,0,46}, {1,0,45},
0331     {1,0,44}, {1,0,43}, {1,0,42}, {1,0,41}, {1,0,40}, {1,0,39}, {1,0,38}, {1,0,37},
0332 
0333     {1,1,34}, {1,1,33}, {1,1,32}, {1,1,31}, {1,1,30}, {1,1,29}, {1,1,28}, {1,1,27},
0334     {1,1,26}, {1,1,25}, {1,1,24}, {1,1,23}, {1,1,22}, {1,1,21}, {1,1,20}, {1,1,19},
0335     {1,1,18}, {1,1,17}, {1,1,16}, {1,1,15}, {1,1,14}, {1,1,13}, {1,1,12}, {1,1,11},
0336     {1,1,10}, {1,1,9},  {1,1,8},  {1,1,7},  {1,1,6},  {1,1,5},  {1,1,4},  {1,1,3},
0337 
0338     {1,1,68}, {1,1,67}, {1,1,66}, {1,1,65}, {1,1,64}, {1,1,63}, {1,1,62}, {1,1,61},
0339     {1,1,60}, {1,1,59}, {1,1,58}, {1,1,57}, {1,1,56}, {1,1,55}, {1,1,54}, {1,1,53},
0340     {1,1,52}, {1,1,51}, {1,1,50}, {1,1,49}, {1,1,48}, {1,1,47}, {1,1,46}, {1,1,45},
0341     {1,1,44}, {1,1,43}, {1,1,42}, {1,1,41}, {1,1,40}, {1,1,39}, {1,1,38}, {1,1,37}
0342   }};
0343 
0344   // map mec8 channel id (1-70) to mec8 signal id on detector as defined by audrey in z views (1-64)
0345   /* sources:
0346    * https://wiki.sphenix.bnl.gov/index.php/File:HDR-225938-XX.PNG.png
0347    * https://wiki.sphenix.bnl.gov/index.php/File:HDR-225940-XX.PNG.png
0348    * https://indico.bnl.gov/event/19038/contributions/75495/attachments/47029/79750/MappingGerber.pdf
0349    * https://indico.bnl.gov/event/17391/contributions/68961/attachments/47061/79816/TpotProgress.pdf, slide 2
0350    */
0351   std::map<int,int> mec8_to_signal_mapping_z = {
0352     /* bottom row on mec8 (female) connector corresponds to bottom row on detector as defined by Audrey */
0353     {1,-1},
0354     {3,1},  {5,2},   {7,3},   {9,4},   {11,5},  {13,6},  {15,7},  {17,8},
0355     {19,9}, {21,10}, {23,11}, {25,12}, {27,13}, {29,14}, {31,15}, {33,16},
0356     {35,-1},
0357     {37,17}, {39,18}, {41,19}, {43,20}, {45,21}, {47,22}, {49,23}, {51,24},
0358     {53,25}, {55,26}, {57,27}, {59,28}, {61,29}, {63,30}, {65,31}, {67,32},
0359     {69,-1},
0360     /* top row on mec8 (female) connector corresponds to top row on detector as defined by Audrey */
0361     {2,-1},
0362     {4,33},  {6,34},  {8,35},  {10,36}, {12,37}, {14,38}, {16,39}, {18,40},
0363     {20,41}, {22,42}, {24,43}, {26,44}, {28,45}, {30,46}, {32,47}, {34,48},
0364     {36,-1},
0365     {38,49}, {40,50}, {42,51}, {44,52}, {46,53}, {48,54}, {50,55}, {52,56},
0366     {54,57}, {56,58}, {58,59}, {60,60}, {62,61}, {64,62}, {66,63}, {68,64},
0367     {70,-1}
0368   };
0369 
0370   // map all mec8 channel id to signal id on detector as defined by audrey in z views (1-256)
0371   /* sources:
0372    * https://indico.bnl.gov/event/19038/contributions/75495/attachments/47029/79750/MappingGerber.pdf
0373    * https://indico.bnl.gov/event/17391/contributions/68961/attachments/47061/79816/TpotProgress.pdf, slide 2
0374    */
0375   std::map<mec8_channel_id,int> mec8_to_signal_mapping_z_all;
0376   for( const auto& [mec8_channel,signal_id]:mec8_to_signal_mapping_z )
0377   {
0378 
0379     // ignore ground channels
0380     if( signal_id == -1 ) { continue;
0381 }
0382 
0383     // cable 0, connector 0 corresponds to signal ids 1 to 64
0384     mec8_to_signal_mapping_z_all.insert(std::pair<mec8_channel_id,int>({0,0,mec8_channel}, signal_id));
0385 
0386     // cable 0, connector 1 corresponds to signal ids 65 to 128
0387     mec8_to_signal_mapping_z_all.insert(std::pair<mec8_channel_id,int>({0,1,mec8_channel}, signal_id+64));
0388 
0389     // cable 1, connector 0 corresponds to signal ids 129 to 192
0390     mec8_to_signal_mapping_z_all.insert(std::pair<mec8_channel_id,int>({1,0,mec8_channel}, signal_id+128));
0391 
0392     // cable 1, connector 1 corresponds to signal ids 193 to 256
0393     mec8_to_signal_mapping_z_all.insert(std::pair<mec8_channel_id,int>({1,1,mec8_channel}, signal_id+192));
0394   }
0395 
0396   // map phisical strips in the detector to MEC8 signal id on detector as defined by Audrey
0397   // source: https://indico.bnl.gov/event/19038/contributions/75495/attachments/47029/79824/MappingTPOT.xlsx
0398   std::map<int,int> strip_to_signal_id_mapping_all =
0399   {
0400     {1,1}, {2,33}, {3,2}, {4,34}, {5,3}, {6,35}, {7,4}, {8,36},
0401     {9,5}, {10,37}, {11,6}, {12,38}, {13,7}, {14,39}, {15,8}, {16,40},
0402     {17,9}, {18,41}, {19,10}, {20,42}, {21,11}, {22,43}, {23,12}, {24,44},
0403     {25,13}, {26,45}, {27,14}, {28,46}, {29,15}, {30,47}, {31,16}, {32,48},
0404     {33,17}, {34,49}, {35,18}, {36,50}, {37,19}, {38,51}, {39,20}, {40,52},
0405     {41,21}, {42,53}, {43,22}, {44,54}, {45,23}, {46,55}, {47,24}, {48,56},
0406     {49,25}, {50,57}, {51,26}, {52,58}, {53,27}, {54,59}, {55,28}, {56,60},
0407     {57,29}, {58,61}, {59,30}, {60,62}, {61,31}, {62,63}, {63,32}, {64,64},
0408 
0409     {65,65}, {66,97}, {67,66}, {68,98}, {69,67}, {70,99}, {71,68}, {72,100},
0410     {73,69}, {74,101}, {75,70}, {76,102}, {77,71}, {78,103}, {79,72}, {80,104},
0411     {81,73}, {82,105}, {83,74}, {84,106}, {85,75}, {86,107}, {87,76}, {88,108},
0412     {89,77}, {90,109}, {91,78}, {92,110}, {93,79}, {94,111}, {95,80}, {96,112},
0413     {97,81}, {98,113}, {99,82}, {100,114}, {101,83}, {102,115}, {103,84}, {104,116},
0414     {105,85}, {106,117}, {107,86}, {108,118}, {109,87}, {110,119}, {111,88}, {112,120},
0415     {113,89}, {114,121}, {115,90}, {116,122}, {117,91}, {118,123}, {119,92}, {120,124},
0416     {121,93}, {122,125}, {123,94}, {124,126}, {125,95}, {126,127}, {127,96}, {128,128},
0417 
0418     {129,129}, {130,161}, {131,130}, {132,162}, {133,131}, {134,163}, {135,132}, {136,164},
0419     {137,133}, {138,165}, {139,134}, {140,166}, {141,135}, {142,167}, {143,136}, {144,168},
0420     {145,137}, {146,169}, {147,138}, {148,170}, {149,139}, {150,171}, {151,140}, {152,172},
0421     {153,141}, {154,173}, {155,142}, {156,174}, {157,143}, {158,175}, {159,144}, {160,176},
0422     {161,145}, {162,177}, {163,146}, {164,178}, {165,147}, {166,179}, {167,148}, {168,180},
0423     {169,149}, {170,181}, {171,150}, {172,182}, {173,151}, {174,183}, {175,152}, {176,184},
0424     {177,153}, {178,185}, {179,154}, {180,186}, {181,155}, {182,187}, {183,156}, {184,188},
0425     {185,157}, {186,189}, {187,158}, {188,190}, {189,159}, {190,191}, {191,160}, {192,192},
0426 
0427     {193,193}, {194,225}, {195,194}, {196,226}, {197,195}, {198,227}, {199,196}, {200,228},
0428     {201,197}, {202,229}, {203,198}, {204,230}, {205,199}, {206,231}, {207,200}, {208,232},
0429     {209,201}, {210,233}, {211,202}, {212,234}, {213,203}, {214,235}, {215,204}, {216,236},
0430     {217,205}, {218,237}, {219,206}, {220,238}, {221,207}, {222,239}, {223,208}, {224,240},
0431     {225,209}, {226,241}, {227,210}, {228,242}, {229,211}, {230,243}, {231,212}, {232,244},
0432     {233,213}, {234,245}, {235,214}, {236,246}, {237,215}, {238,247}, {239,216}, {240,248},
0433     {241,217}, {242,249}, {243,218}, {244,250}, {245,219}, {246,251}, {247,220}, {248,252},
0434     {249,221}, {250,253}, {251,222}, {252,254}, {253,223}, {254,255}, {255,224}, {256,256}
0435   };
0436 
0437   // add mapping from strip number as defined by Audrey and geant convention
0438   auto get_strip_geant_z = []( int strip_audrey )
0439   {
0440     /*
0441      * for z views, audrey and geant strips are numbered in oposite directions
0442      * geant strips start from zero
0443     */
0444     return MicromegasDefs::m_nchannels_fee-strip_audrey;
0445   };
0446 
0447   // construct fee channel id to strip
0448   /*
0449    * fee channel id is from 0 to 255
0450    * strip id from 0 to 255 (-1 with respect to Audrey's convention
0451    */
0452   for( int channel_id = 0; channel_id < MicromegasDefs::m_nchannels_fee; ++channel_id )
0453   {
0454 
0455     // mec8 channel id
0456     auto mec8_channel_id = fee_to_mec8_mapping[channel_id];
0457 
0458     // mec8 signal id as defined by Audrey
0459     int mec8_signal_id = mec8_to_signal_mapping_z_all.at(mec8_channel_id);
0460 
0461     // find mec8_signal_id in detector mapping
0462     const auto iter = std::find_if( strip_to_signal_id_mapping_all.begin(), strip_to_signal_id_mapping_all.end(), [mec8_signal_id]( const std::pair<int,int>& pair ) { return pair.second == mec8_signal_id; } );
0463     assert( iter != strip_to_signal_id_mapping_all.end() );
0464     const int strip_audrey = iter->first;
0465 
0466     // convert to geant convention
0467     const int strip_geant = get_strip_geant_z( strip_audrey );
0468 
0469     // store in array
0470     m_fee_to_strip_mapping_z[channel_id] = strip_geant;
0471   }
0472 
0473   // print_mapping( "m_fee_to_strip_mapping_z", m_fee_to_strip_mapping_z );
0474 
0475   // map mec8 channel id (1-70) to mec8 signal id on detector as defined by audrey in phi views
0476   /* sources:
0477    * https://wiki.sphenix.bnl.gov/index.php/File:HDR-225938-XX.PNG.png
0478    * https://wiki.sphenix.bnl.gov/index.php/File:HDR-225940-XX.PNG.png
0479    * https://indico.bnl.gov/event/19038/contributions/75495/attachments/47029/79823/MappingGerber.pdf
0480    * https://indico.bnl.gov/event/17391/contributions/68961/attachments/47061/79816/TpotProgress.pdf, slide 2
0481    */
0482   std::map<int,int> mec8_to_signal_mapping_phi = {
0483     /* bottom row on mec8 (female) connector corresponds to top row on detector as defined by Audrey */
0484     {1,-1},
0485     {3,64},  {5,63},  {7,62},  {9,61},  {11,60}, {13,59}, {15,58}, {17,57},
0486     {19,56}, {21,55}, {23,54}, {25,53}, {27,52}, {29,51}, {31,50}, {33,49},
0487     {35,-1},
0488     {37,48}, {39,47}, {41,46}, {43,45}, {45,44}, {47,43}, {49,42}, {51,41},
0489     {53,40}, {55,39}, {57,38}, {59,37}, {61,36}, {63,35}, {65,34}, {67,33},
0490     {69,-1},
0491     /* top row on mec8 (female) connector corresponds to bottom row on detector as defined by Audrey */
0492     {2,-1},
0493     {4,32},  {6,31},  {8,30},  {10,29}, {12,28}, {14,27}, {16,26}, {18,25},
0494     {20,24}, {22,23}, {24,22}, {26,21}, {28,20}, {30,19}, {32,18}, {34,17},
0495     {36,-1},
0496     {38,16}, {40,15}, {42,14}, {44,13}, {46,12}, {48,11}, {50,10}, {52,9},
0497     {54,8},  {56,7},  {58,6},  {60,5},  {62,4},  {64,3},  {66,2},  {68,1},
0498     {70,-1}
0499   };
0500 
0501   // map all mec8 channel id to signal id on detector as defined by audrey in phi views
0502   /* sources:
0503    * https://indico.bnl.gov/event/19038/contributions/75495/attachments/47029/79823/MappingGerber.pdf
0504    * https://indico.bnl.gov/event/17391/contributions/68961/attachments/47061/79816/TpotProgress.pdf, slide 2
0505    */
0506   std::map<mec8_channel_id,int> mec8_to_signal_mapping_phi_all;
0507   for( const auto& [mec8_channel,signal_id]:mec8_to_signal_mapping_phi )
0508   {
0509 
0510     // ignore ground channels
0511     if( signal_id == -1 ) { continue;
0512 }
0513 
0514     // cable 0, connector 0 corresponds to signal ids 193 to 256
0515     mec8_to_signal_mapping_phi_all.insert(std::pair<mec8_channel_id,int>({0,0,mec8_channel}, signal_id+192));
0516 
0517     // cable 0, connector 1 corresponds to signal ids 129 to 160
0518     mec8_to_signal_mapping_phi_all.insert(std::pair<mec8_channel_id,int>({0,1,mec8_channel}, signal_id+128));
0519 
0520     // cable 1, connector 0 corresponds to signal ids 65 to 128
0521     mec8_to_signal_mapping_phi_all.insert(std::pair<mec8_channel_id,int>({1,0,mec8_channel}, signal_id+64));
0522 
0523     // cable 1, connector 1 corresponds to signal ids 1 to 64
0524     mec8_to_signal_mapping_phi_all.insert(std::pair<mec8_channel_id,int>({1,1,mec8_channel}, signal_id));
0525   }
0526 
0527   // add mapping from strip number as defined by Audrey and geant convention
0528   auto get_strip_geant_phi = []( int strip_audrey )
0529   {
0530     /*
0531      * for phi views, audrey and geant strips are numbered in oposite directions
0532      * geant strips start from zero
0533     */
0534     return MicromegasDefs::m_nchannels_fee-strip_audrey;
0535   };
0536 
0537   // construct fee channel id to strip
0538   /*
0539    * fee channel id is from 0 to 255
0540    * strip id from 0 to 255 (-1 with respect to Audrey's convention
0541    */
0542   for( int channel_id = 0; channel_id < MicromegasDefs::m_nchannels_fee; ++channel_id )
0543   {
0544 
0545     // mec8 channel id
0546     auto mec8_channel_id = fee_to_mec8_mapping[channel_id];
0547 
0548     // mec8 signal id as defined by Audrey
0549     int mec8_signal_id = mec8_to_signal_mapping_phi_all.at(mec8_channel_id);
0550 
0551     // find mec8_signal_id in detector mapping
0552     const auto iter = std::find_if( strip_to_signal_id_mapping_all.begin(), strip_to_signal_id_mapping_all.end(), [mec8_signal_id]( const std::pair<int,int>& pair ) { return pair.second == mec8_signal_id; } );
0553     assert( iter != strip_to_signal_id_mapping_all.end() );
0554     const int strip_audrey = iter->first;
0555 
0556     // convert to geant convention
0557     const int strip_geant = get_strip_geant_phi( strip_audrey );
0558 
0559     // store in array
0560     m_fee_to_strip_mapping_phi[channel_id] = strip_geant;
0561   }
0562 
0563 }
0564 
0565 //_____________________________________________________________________
0566 int MicromegasMapping::get_new_fee_id( int fee_id ) const
0567 {
0568   /*
0569   * on May 29 2024, we the fiber arriving on fee_id 11 was moved to fee_id 21
0570   * since fee_id 11 was not assigned before, we can internally convert all call to fee_id 21 to fee_id11,
0571   * while keeping backward compatibility
0572   */
0573   static const std::map<int,int> internal_fee_id_map( {{11,21}} );
0574   const auto& iter = internal_fee_id_map.find( fee_id );
0575   return iter == internal_fee_id_map.end() ? fee_id:iter->second;
0576 }
0577