Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 14:22:46

0001 // HardwareSortingMethods.cc
0002 // Authors: R. Alex Barbieri
0003 //          Ben Kreis
0004 //
0005 // This file should contain the C++ equivalents of the sorting
0006 // algorithms used in Hardware. Most C++ methods originally written by
0007 // Ben Kreis.
0008 
0009 #include <iostream>
0010 #include "L1Trigger/L1TCalorimeter/interface/HardwareSortingMethods.h"
0011 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0012 
0013 namespace {
0014   constexpr bool verbose = false;
0015 
0016   constexpr int fw_to_gt_phi_map[] = {4, 3, 2, 1, 0, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5};
0017   constexpr int gt_to_fw_phi_map[] = {4, 3, 2, 1, 0, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5};
0018 }  // namespace
0019 
0020 namespace l1t {
0021   unsigned int pack15bits(int pt, int eta, int phi) {
0022     return (((pt & 0x3f)) + ((eta & 0xf) << 6) + ((phi & 0x1f) << 10));
0023   }
0024 
0025   unsigned int pack16bits(int pt, int eta, int phi) {
0026     return (0x8000 + ((pt & 0x3f)) + ((eta & 0xf) << 6) + ((phi & 0x1f) << 10));
0027   }
0028 
0029   unsigned int pack16bitsEgammaSpecial(int pt, int eta, int phi) {
0030     return (0x8000 + ((pt & 0x3f) << 9) + ((eta & 0xf)) + ((phi & 0x1f) << 4));
0031   }
0032 }  // namespace l1t
0033 
0034 void print2DVector(std::vector<std::vector<l1t::L1Candidate> > const& myVector) {
0035   int nrows = myVector.size();
0036   int ncols = myVector[0].size();
0037   std::cout << std::endl;
0038   std::cout << "rows: " << nrows << std::endl;
0039   std::cout << "cols: " << ncols << std::endl;
0040 
0041   for (int r = 0; r < nrows; r++) {
0042     for (int c = 0; c < ncols; c++) {
0043       std::cout << std::setw(5) << myVector[r][c].hwPt() << ' ';
0044     }
0045     std::cout << std::endl;
0046   }
0047 }
0048 
0049 std::vector<l1t::L1Candidate> sort_array(std::vector<l1t::L1Candidate> const& inputArray) {
0050   std::vector<l1t::L1Candidate> outputArray(inputArray.size());
0051   for (unsigned int i = 0; i < inputArray.size(); i++) {
0052     int rank = 0;
0053     for (unsigned int j = 0; j < inputArray.size(); j++) {
0054       if ((inputArray[i].hwPt() > inputArray[j].hwPt()) || ((inputArray[i].hwPt() == inputArray[j].hwPt()) && i < j))
0055         rank++;
0056     }  //j
0057     outputArray[outputArray.size() - 1 - rank] = inputArray[i];
0058   }  //i
0059   return outputArray;
0060 }
0061 
0062 std::vector<std::vector<l1t::L1Candidate> > presort(std::vector<std::vector<l1t::L1Candidate> > const& energies,
0063                                                     int rows,
0064                                                     int cols) {
0065   int row_block_length = energies.size() / cols;
0066   if (energies.size() % cols != 0)
0067     row_block_length++;
0068 
0069   l1t::L1Candidate dummyJet;
0070   dummyJet.setHwPt(0);
0071   dummyJet.setHwPhi(99);
0072   dummyJet.setHwEta(99);
0073   dummyJet.setHwQual(0x10);
0074   std::vector<std::vector<l1t::L1Candidate> > sorted_energies(rows, std::vector<l1t::L1Candidate>(cols, dummyJet));
0075   if (verbose)
0076     print2DVector(sorted_energies);
0077 
0078   unsigned int row = 0, col = 0;
0079   std::vector<l1t::L1Candidate> energy_feeder(cols, dummyJet);
0080   std::vector<l1t::L1Candidate> energy_result(cols, dummyJet);
0081   for (int r = 0; r < rows; r++) {
0082     for (int c = 0; c < cols; c++) {
0083       row = (r % row_block_length) * cols + c;  //row goes up to 19 and we pad with zeros
0084 
0085       if (row < energies.size()) {
0086         energy_feeder[c] = energies[row][col];
0087       } else {
0088         energy_feeder[c] = dummyJet;
0089       }
0090 
0091     }  //c
0092 
0093     energy_result = sort_array(energy_feeder);  //sort!
0094 
0095     sorted_energies[r] = energy_result;
0096 
0097     if (r % row_block_length == row_block_length - 1)
0098       col++;
0099 
0100   }  //r
0101   if (verbose)
0102     print2DVector(sorted_energies);
0103 
0104   return sorted_energies;
0105 }
0106 
0107 std::vector<std::vector<l1t::L1Candidate> > extract_sub_jet_energy_position_matrix(
0108     std::vector<std::vector<l1t::L1Candidate> > const& input_matrix,
0109     unsigned int row_i,
0110     unsigned int row_f,
0111     unsigned int col_i,
0112     unsigned int col_f) {
0113   std::vector<std::vector<l1t::L1Candidate> > output_matrix(row_f - row_i + 1,
0114                                                             std::vector<l1t::L1Candidate>(col_f - col_i + 1));
0115   l1t::L1Candidate dummyJet;
0116   dummyJet.setHwPt(0);
0117   dummyJet.setHwPhi(99);
0118   dummyJet.setHwEta(99);
0119   dummyJet.setHwQual(0x10);
0120   for (unsigned int i = 0; i < row_f - row_i + 1; i++) {
0121     for (unsigned int j = 0; j < col_f - col_i + 1; j++) {
0122       if (row_i + i > input_matrix.size() - 1)
0123         output_matrix[i][j] = dummyJet;
0124       else
0125         output_matrix[i][j] = input_matrix[row_i + i][col_i + j];
0126     }  //j
0127   }    //i
0128   return output_matrix;
0129 }
0130 
0131 std::vector<std::vector<l1t::L1Candidate> > sort_matrix_rows(
0132     std::vector<std::vector<l1t::L1Candidate> > const& input_matrix) {
0133   std::vector<std::vector<l1t::L1Candidate> > output_matrix(input_matrix.size(),
0134                                                             std::vector<l1t::L1Candidate>(input_matrix[0].size()));
0135 
0136   for (unsigned int i = 0; i < input_matrix.size(); i++) {
0137     int rank = 0;
0138     for (unsigned int j = 0; j < input_matrix.size(); j++) {
0139       if ((input_matrix[i][0].hwPt() > input_matrix[j][0].hwPt()) ||
0140           ((input_matrix[i][0].hwPt() == input_matrix[j][0].hwPt()) && i < j))
0141         rank++;
0142     }  //j
0143     output_matrix[input_matrix.size() - 1 - rank] = input_matrix[i];
0144   }  //i
0145 
0146   return output_matrix;
0147 }
0148 
0149 std::vector<std::vector<l1t::L1Candidate> > sort_by_row_in_groups(
0150     std::vector<std::vector<l1t::L1Candidate> > const& input_matrix, int group_size) {
0151   int n_groups =
0152       input_matrix.size() / group_size +
0153       (1 - input_matrix.size() / group_size * group_size / input_matrix.size());  //constants must make this an integer
0154   //std::vector<std::vector<l1t::L1Candidate> > output_matrix(input_matrix.size()+(input_matrix.size() % group_size), std::vector<l1t::L1Candidate> (input_matrix[0].size()));
0155   std::vector<std::vector<l1t::L1Candidate> > output_matrix(
0156       input_matrix.size() +
0157           (group_size * (1 - ((input_matrix.size() / group_size) * group_size) / input_matrix.size())) -
0158           (input_matrix.size() % group_size),
0159       std::vector<l1t::L1Candidate>(input_matrix[0].size()));
0160 
0161   for (int g = 0; g < n_groups; g++) {
0162     std::vector<std::vector<l1t::L1Candidate> > small_output_matrix = extract_sub_jet_energy_position_matrix(
0163         input_matrix, g * group_size, (g + 1) * group_size - 1, 0, input_matrix[0].size() - 1);
0164     small_output_matrix = sort_matrix_rows(small_output_matrix);
0165 
0166     for (unsigned int i = 0; i < small_output_matrix.size(); i++) {
0167       output_matrix[g * group_size + i] = small_output_matrix[i];
0168     }
0169   }
0170 
0171   if (verbose)
0172     print2DVector(output_matrix);
0173   return output_matrix;
0174 }
0175 
0176 std::vector<l1t::L1Candidate> array_from_row_sorted_matrix(
0177     std::vector<std::vector<l1t::L1Candidate> > const& input_matrix, unsigned int n_keep) {
0178   std::vector<l1t::L1Candidate> output_array(n_keep * (n_keep + 1) / 2);
0179   unsigned int max_row = n_keep - 1;
0180   unsigned int max_col = n_keep - 1;
0181 
0182   //compute size
0183   if (input_matrix.size() < n_keep)
0184     max_row = input_matrix.size() - 1;
0185   if (input_matrix[0].size() < n_keep)
0186     max_col = input_matrix[0].size() - 1;
0187 
0188   unsigned int array_position = 0;
0189   for (unsigned int i = 0; i <= max_row; i++) {
0190     for (unsigned int j = 0; j <= max_col - i; j++) {
0191       //cout << input_matrix[i][j].hwPt() << endl;
0192       output_array[array_position] = input_matrix[i][j];
0193       array_position++;
0194     }  //j
0195   }    //i
0196 
0197   //fill rest with zeros
0198   l1t::L1Candidate dummyJet;
0199   dummyJet.setHwPt(0);
0200   dummyJet.setHwPhi(99);
0201   dummyJet.setHwEta(99);
0202   dummyJet.setHwQual(0x10);
0203   for (unsigned int k = array_position; k < output_array.size(); k++) {
0204     output_array[k] = dummyJet;
0205   }
0206 
0207   //printVector(output_array);
0208   return output_array;
0209 }
0210 
0211 std::vector<std::vector<l1t::L1Candidate> > super_sort_matrix_rows(
0212     std::vector<std::vector<l1t::L1Candidate> > const& input_matrix, unsigned int group_size, unsigned int n_keep) {
0213   unsigned int n_groups =
0214       input_matrix.size() / group_size +
0215       (1 - input_matrix.size() / group_size * group_size / input_matrix.size());  //constants must make this an integer
0216   std::vector<std::vector<l1t::L1Candidate> > output_matrix(n_groups, std::vector<l1t::L1Candidate>(n_keep));
0217 
0218   for (unsigned int g = 0; g < n_groups; g++) {
0219     std::vector<std::vector<l1t::L1Candidate> > small_output_matrix = extract_sub_jet_energy_position_matrix(
0220         input_matrix, g * group_size, (g + 1) * group_size - 1, 0, input_matrix[0].size() - 1);
0221     std::vector<l1t::L1Candidate> unsorted_array = array_from_row_sorted_matrix(small_output_matrix, n_keep);
0222     std::vector<l1t::L1Candidate> unsorted_array_without_largest(unsorted_array.size() -
0223                                                                  1);  //we know first element is the biggest
0224     for (unsigned int i = 0; i < unsorted_array.size() - 1; i++) {
0225       unsorted_array_without_largest[i] = unsorted_array[1 + i];
0226     }
0227     std::vector<l1t::L1Candidate> sorted_array_without_largest = sort_array(unsorted_array_without_largest);
0228 
0229     std::vector<l1t::L1Candidate> sorted_array(n_keep);
0230     sorted_array[0] = unsorted_array[0];
0231     for (unsigned int i = 0; i < n_keep - 1; i++) {
0232       sorted_array[1 + i] = sorted_array_without_largest[i];
0233     }
0234 
0235     output_matrix[g] = sorted_array;
0236   }  //g
0237 
0238   if (verbose)
0239     print2DVector(output_matrix);
0240   return output_matrix;
0241 }
0242 
0243 std::vector<std::vector<l1t::L1Candidate> > presort_egamma(std::vector<l1t::L1Candidate> const& input_egamma,
0244                                                            int rows,
0245                                                            int cols) {
0246   int row_block_length = input_egamma.size() / cols;
0247   if (input_egamma.size() % cols != 0)
0248     row_block_length++;
0249 
0250   //Initialize output
0251   l1t::L1Candidate dummyJet;
0252   dummyJet.setHwPt(0);
0253   dummyJet.setHwPhi(99);
0254   dummyJet.setHwEta(99);
0255   dummyJet.setHwQual(0x10);
0256   std::vector<std::vector<l1t::L1Candidate> > sorted_energies(rows, std::vector<l1t::L1Candidate>(cols, dummyJet));
0257   if (verbose)
0258     print2DVector(sorted_energies);
0259 
0260   unsigned int row = 0, col = 0;
0261   std::vector<l1t::L1Candidate> energy_feeder(cols, dummyJet);
0262   std::vector<l1t::L1Candidate> energy_result(cols, dummyJet);
0263   for (int r = 0; r < rows; r++) {
0264     for (int c = 0; c < cols; c++) {
0265       row = (r % row_block_length) * cols + c;  //row goes up to 19 and we pad with zeros
0266       //cout << "row, col = " << row << ", " << col << endl;
0267 
0268       if (row < input_egamma.size()) {
0269         energy_feeder[c] = input_egamma[row];
0270       } else {
0271         energy_feeder[c] = dummyJet;
0272       }
0273 
0274     }  //c
0275 
0276     energy_result = sort_array(energy_feeder);  //sort!
0277 
0278     sorted_energies[r] = energy_result;
0279 
0280     if (r % row_block_length == row_block_length - 1)
0281       col++;
0282 
0283   }  //r
0284   if (verbose)
0285     print2DVector(sorted_energies);
0286 
0287   return sorted_energies;
0288 }
0289 
0290 namespace l1t {
0291   void SortJets(std::vector<l1t::Jet>* input, std::vector<l1t::Jet>* output) {
0292     //verbose = true;
0293     const int CENTRAL_ETA_SLICES = 14;
0294     const int N_PHI_GROUPS = 5;
0295     const int N_PRESORTED_ROWS_CENTRAL = CENTRAL_ETA_SLICES * N_PHI_GROUPS;
0296     const int PRESORT_DEPTH = 4;
0297     const int N_KEEP_CENTRAL = 4;
0298     const int N_ETA_GROUP_SIZE_CENTRAL = 4;
0299     const int N_ETA_GROUPS_CENTRAL = 4;
0300 
0301     const int HFM_ETA_SLICES = 4;
0302     const int HFP_ETA_SLICES = 4;
0303     const int N_PRESORTED_ROWS_HFM = HFM_ETA_SLICES * N_PHI_GROUPS;
0304     const int N_PRESORTED_ROWS_HFP = HFP_ETA_SLICES * N_PHI_GROUPS;
0305     const int N_KEEP_FORWARD = 4;
0306 
0307     const int cen_nrows = 18;
0308     const int cen_ncols = 14;
0309     const int hfm_nrows = 18, hfp_nrows = 18;
0310     const int hfm_ncols = 4, hfp_ncols = 4;
0311 
0312     std::vector<std::vector<l1t::L1Candidate> > cen_input_energy(cen_nrows, std::vector<l1t::L1Candidate>(cen_ncols));
0313     std::vector<std::vector<l1t::L1Candidate> > hfm_input_energy(hfm_nrows, std::vector<l1t::L1Candidate>(hfm_ncols));
0314     std::vector<std::vector<l1t::L1Candidate> > hfp_input_energy(hfp_nrows, std::vector<l1t::L1Candidate>(hfp_ncols));
0315 
0316     for (std::vector<l1t::Jet>::const_iterator injet = input->begin(); injet != input->end(); ++injet) {
0317       if (injet->hwEta() >= 4 && injet->hwEta() <= 17) {
0318         unsigned int myrow = gt_to_fw_phi_map[injet->hwPhi()];
0319         unsigned int mycol = injet->hwEta() - 4;  //hardcoding is bad
0320         cen_input_energy[myrow][mycol] = *injet;
0321       } else if (injet->hwEta() < 4) {
0322         unsigned int myrow = gt_to_fw_phi_map[injet->hwPhi()];
0323         unsigned int mycol = injet->hwEta();  //hardcoding is bad
0324         hfm_input_energy[myrow][mycol] = *injet;
0325       } else if (injet->hwEta() > 17) {
0326         unsigned int myrow = gt_to_fw_phi_map[injet->hwPhi()];
0327         unsigned int mycol = injet->hwEta() - 18;  //hardcoding is bad
0328         hfp_input_energy[myrow][mycol] = *injet;
0329       } else
0330         edm::LogError("HardwareJetSort") << "Region out of bounds: " << injet->hwEta();
0331     }
0332 
0333     for (int i = 0; i < cen_nrows; ++i)
0334       for (int j = 0; j < cen_ncols; ++j) {
0335         if (cen_input_energy[i][j].hwPt() == 0) {
0336           cen_input_energy[i][j].setHwPhi(fw_to_gt_phi_map[i]);
0337           cen_input_energy[i][j].setHwEta(4 + j);
0338         }
0339       }
0340 
0341     for (int i = 0; i < hfm_nrows; ++i)
0342       for (int j = 0; j < hfm_ncols; ++j) {
0343         if (hfm_input_energy[i][j].hwPt() == 0) {
0344           hfm_input_energy[i][j].setHwPhi(fw_to_gt_phi_map[i]);
0345           hfm_input_energy[i][j].setHwEta(j);
0346           hfm_input_energy[i][j].setHwQual(2);
0347         }
0348       }
0349 
0350     for (int i = 0; i < hfp_nrows; ++i)
0351       for (int j = 0; j < hfp_ncols; ++j) {
0352         if (hfp_input_energy[i][j].hwPt() == 0) {
0353           hfp_input_energy[i][j].setHwPhi(fw_to_gt_phi_map[i]);
0354           hfp_input_energy[i][j].setHwEta(j + 18);
0355           hfp_input_energy[i][j].setHwQual(2);
0356         }
0357       }
0358 
0359     //Each CLK is one clock
0360 
0361     //CLK 1
0362     std::vector<std::vector<l1t::L1Candidate> > presorted_energies_matrix_sig =
0363         presort(cen_input_energy, N_PRESORTED_ROWS_CENTRAL, PRESORT_DEPTH);
0364     std::vector<std::vector<l1t::L1Candidate> > hfm_presorted_energies_matrix_sig =
0365         presort(hfm_input_energy, N_PRESORTED_ROWS_HFM, PRESORT_DEPTH);
0366     std::vector<std::vector<l1t::L1Candidate> > hfp_presorted_energies_matrix_sig =
0367         presort(hfp_input_energy, N_PRESORTED_ROWS_HFP, PRESORT_DEPTH);
0368 
0369     //CLK 2
0370     std::vector<std::vector<l1t::L1Candidate> > row_presorted_energies_matrix_sig =
0371         sort_by_row_in_groups(presorted_energies_matrix_sig, N_PHI_GROUPS);
0372     std::vector<std::vector<l1t::L1Candidate> > hfm_row_presorted_energies_matrix_sig =
0373         sort_by_row_in_groups(hfm_presorted_energies_matrix_sig, N_PHI_GROUPS);
0374     std::vector<std::vector<l1t::L1Candidate> > hfp_row_presorted_energies_matrix_sig =
0375         sort_by_row_in_groups(hfp_presorted_energies_matrix_sig, N_PHI_GROUPS);
0376 
0377     //CLK 3
0378     std::vector<std::vector<l1t::L1Candidate> > sorted_eta_slices_energies_matrix_sig =
0379         super_sort_matrix_rows(row_presorted_energies_matrix_sig, N_PHI_GROUPS, N_KEEP_CENTRAL);
0380     std::vector<std::vector<l1t::L1Candidate> > hfm_sorted_eta_slices_energies_matrix_sig =
0381         super_sort_matrix_rows(hfm_row_presorted_energies_matrix_sig, N_PHI_GROUPS, N_KEEP_FORWARD);
0382     std::vector<std::vector<l1t::L1Candidate> > hfp_sorted_eta_slices_energies_matrix_sig =
0383         super_sort_matrix_rows(hfp_row_presorted_energies_matrix_sig, N_PHI_GROUPS, N_KEEP_FORWARD);
0384 
0385     //CLK 4
0386     std::vector<std::vector<l1t::L1Candidate> > row_presorted_eta_slices_energies_matrix_sig =
0387         sort_by_row_in_groups(sorted_eta_slices_energies_matrix_sig, N_ETA_GROUP_SIZE_CENTRAL);
0388     std::vector<std::vector<l1t::L1Candidate> > hfm_row_presorted_eta_slices_energies_matrix_sig =
0389         sort_by_row_in_groups(hfm_sorted_eta_slices_energies_matrix_sig, HFM_ETA_SLICES);
0390     std::vector<std::vector<l1t::L1Candidate> > hfp_row_presorted_eta_slices_energies_matrix_sig =
0391         sort_by_row_in_groups(hfp_sorted_eta_slices_energies_matrix_sig, HFP_ETA_SLICES);
0392 
0393     //CLK 5
0394     std::vector<std::vector<l1t::L1Candidate> > sorted_eta_groups_energies_matrix_sig =
0395         super_sort_matrix_rows(row_presorted_eta_slices_energies_matrix_sig, N_ETA_GROUP_SIZE_CENTRAL, N_KEEP_CENTRAL);
0396     std::vector<std::vector<l1t::L1Candidate> > hfm_sorted_final_energies_matrix_sig =
0397         super_sort_matrix_rows(hfm_row_presorted_eta_slices_energies_matrix_sig, HFM_ETA_SLICES, N_KEEP_FORWARD);
0398     std::vector<std::vector<l1t::L1Candidate> > hfp_sorted_final_energies_matrix_sig =
0399         super_sort_matrix_rows(hfp_row_presorted_eta_slices_energies_matrix_sig, HFP_ETA_SLICES, N_KEEP_FORWARD);
0400 
0401     //CLK 6
0402     std::vector<std::vector<l1t::L1Candidate> > row_presorted_eta_groups_energies_matrix_sig =
0403         sort_by_row_in_groups(sorted_eta_groups_energies_matrix_sig, N_ETA_GROUPS_CENTRAL);
0404     std::vector<std::vector<l1t::L1Candidate> > hf_merged_plus_minus_forward_energies_matrix_sig(
0405         2, std::vector<l1t::L1Candidate>(N_KEEP_FORWARD));
0406     hf_merged_plus_minus_forward_energies_matrix_sig[0] = hfm_sorted_final_energies_matrix_sig[0];
0407     hf_merged_plus_minus_forward_energies_matrix_sig[1] = hfp_sorted_final_energies_matrix_sig[0];
0408     std::vector<std::vector<l1t::L1Candidate> > hf_row_presorted_merged_plus_minus_forward_energies_matrix_sig =
0409         sort_by_row_in_groups(hf_merged_plus_minus_forward_energies_matrix_sig, 2);
0410 
0411     //CLK 7
0412     std::vector<std::vector<l1t::L1Candidate> > sorted_final_energies_matrix_sig =
0413         super_sort_matrix_rows(row_presorted_eta_groups_energies_matrix_sig, N_ETA_GROUPS_CENTRAL, N_KEEP_CENTRAL);
0414     std::vector<std::vector<l1t::L1Candidate> > hf_sorted_final_merged_plus_minus_forward_energies_matrix_sig =
0415         super_sort_matrix_rows(hf_row_presorted_merged_plus_minus_forward_energies_matrix_sig, 2, N_KEEP_FORWARD);
0416 
0417     for (unsigned int i = 0; i < 4; ++i) {
0418       auto const& tmp = sorted_final_energies_matrix_sig[0][i];
0419       output->emplace_back(tmp.p4(), tmp.hwPt(), tmp.hwEta(), tmp.hwPhi(), tmp.hwQual());
0420     }
0421     for (unsigned int i = 0; i < 4; ++i) {
0422       auto const& tmp = hf_sorted_final_merged_plus_minus_forward_energies_matrix_sig[0][i];
0423       output->emplace_back(tmp.p4(), tmp.hwPt(), tmp.hwEta(), tmp.hwPhi(), tmp.hwQual() | 2);
0424     }
0425     //verbose = false;
0426   }
0427 
0428   void SortEGammas(std::vector<l1t::EGamma>* input, std::vector<l1t::EGamma>* output) {
0429     //Initialize
0430     const int FIBER_PAIRS = 18;
0431     const int N_INPUT_EGAMMAS = 4;
0432     const int N_PRESORTED_ROWS_EGAMMA = 36;
0433     const int PRESORT_DEPTH = 4;
0434     const int N_EGAMMA_FIRST_GROUP_SIZE = 6;
0435     const int N_EGAMMA_SECOND_GROUP_SIZE = 6;
0436     const int N_EGAMMA_FIRST_GROUPS = 6;
0437     const int N_KEEP_EGAMMA = 4;
0438 
0439     //Input
0440     //Each egamma: RCT isolation, RCT order, phi index, eta index
0441 
0442     vector<l1t::L1Candidate> iso_egamma_array_p,
0443         iso_egamma_array_m;  //reusing objects.  should probably rename to something like "object"
0444     vector<l1t::L1Candidate> noniso_egamma_array_p, noniso_egamma_array_m;
0445 
0446     for (int k = 0; k < 2 * N_INPUT_EGAMMAS * FIBER_PAIRS; k++) {
0447       l1t::L1Candidate dummyJet;
0448       dummyJet.setHwPt(0);
0449       dummyJet.setHwEta(99);
0450       dummyJet.setHwPhi(99);
0451       dummyJet.setHwQual(0x10);
0452       if (k < N_INPUT_EGAMMAS * FIBER_PAIRS) {
0453         iso_egamma_array_p.push_back(dummyJet);
0454         noniso_egamma_array_p.push_back(dummyJet);
0455       } else {
0456         iso_egamma_array_m.push_back(dummyJet);
0457         noniso_egamma_array_m.push_back(dummyJet);
0458       }
0459     }
0460 
0461     for (std::vector<l1t::EGamma>::const_iterator ineg = input->begin(); ineg != input->end(); ++ineg) {
0462       int fiberNum = (int)floor(gt_to_fw_phi_map[ineg->hwPhi()] / 2);
0463       int index = ineg->hwQual();
0464       bool iso = ineg->hwIso();
0465       bool minus = (ineg->hwEta() < 11);
0466 
0467       // while waiting for firmware LUT, set all iso to true
0468       //iso = true;
0469 
0470       if (iso && minus)
0471         iso_egamma_array_m[8 * fiberNum + index] = *ineg;
0472       else if (iso && !minus)
0473         iso_egamma_array_p[8 * fiberNum + index] = *ineg;
0474       else if (!iso && minus)
0475         noniso_egamma_array_m[8 * fiberNum + index] = *ineg;
0476       else if (!iso && !minus)
0477         noniso_egamma_array_p[8 * fiberNum + index] = *ineg;
0478     }
0479 
0480     // std::cout << "iso_egamma_array_m" << std::endl;
0481     // for(int i = 0; i < (int)iso_egamma_array_m.size(); ++i)
0482     // {
0483     //   std::cout << iso_egamma_array_m[i].hwPt() << " "
0484     //     << iso_egamma_array_m[i].hwEta() << " "
0485     //     << iso_egamma_array_m[i].hwPhi() << std::endl;
0486     // }
0487 
0488     // std::cout << "iso_egamma_array_p" << std::endl;
0489     // for(int i = 0; i < (int)iso_egamma_array_p.size(); ++i)
0490     // {
0491     //   std::cout << iso_egamma_array_p[i].hwPt() << " "
0492     //     << iso_egamma_array_p[i].hwEta() << " "
0493     //     << iso_egamma_array_p[i].hwPhi() << std::endl;
0494     // }
0495 
0496     //verbose = true;
0497     //1
0498     std::vector<std::vector<l1t::L1Candidate> > presorted_iso_matrix_sig_p =
0499         presort_egamma(iso_egamma_array_p, N_PRESORTED_ROWS_EGAMMA / 2, PRESORT_DEPTH);
0500     std::vector<std::vector<l1t::L1Candidate> > presorted_iso_matrix_sig_m =
0501         presort_egamma(iso_egamma_array_m, N_PRESORTED_ROWS_EGAMMA / 2, PRESORT_DEPTH);
0502     std::vector<std::vector<l1t::L1Candidate> > presorted_non_iso_matrix_sig_p =
0503         presort_egamma(noniso_egamma_array_p, N_PRESORTED_ROWS_EGAMMA / 2, PRESORT_DEPTH);
0504     std::vector<std::vector<l1t::L1Candidate> > presorted_non_iso_matrix_sig_m =
0505         presort_egamma(noniso_egamma_array_m, N_PRESORTED_ROWS_EGAMMA / 2, PRESORT_DEPTH);
0506 
0507     //2
0508     std::vector<std::vector<l1t::L1Candidate> > iso_row_presorted_energies_matrix_sig_p =
0509         sort_by_row_in_groups(presorted_iso_matrix_sig_p, N_EGAMMA_FIRST_GROUP_SIZE);
0510     std::vector<std::vector<l1t::L1Candidate> > iso_row_presorted_energies_matrix_sig_m =
0511         sort_by_row_in_groups(presorted_iso_matrix_sig_m, N_EGAMMA_FIRST_GROUP_SIZE);
0512     std::vector<std::vector<l1t::L1Candidate> > non_iso_row_presorted_energies_matrix_sig_p =
0513         sort_by_row_in_groups(presorted_non_iso_matrix_sig_p, N_EGAMMA_FIRST_GROUP_SIZE);
0514     std::vector<std::vector<l1t::L1Candidate> > non_iso_row_presorted_energies_matrix_sig_m =
0515         sort_by_row_in_groups(presorted_non_iso_matrix_sig_m, N_EGAMMA_FIRST_GROUP_SIZE);
0516 
0517     //3
0518     std::vector<std::vector<l1t::L1Candidate> > iso_super_sorted_energies_matrix_sig_p =
0519         super_sort_matrix_rows(iso_row_presorted_energies_matrix_sig_p, N_EGAMMA_FIRST_GROUP_SIZE, N_KEEP_EGAMMA);
0520     std::vector<std::vector<l1t::L1Candidate> > iso_super_sorted_energies_matrix_sig_m =
0521         super_sort_matrix_rows(iso_row_presorted_energies_matrix_sig_m, N_EGAMMA_FIRST_GROUP_SIZE, N_KEEP_EGAMMA);
0522     std::vector<std::vector<l1t::L1Candidate> > non_iso_super_sorted_energies_matrix_sig_p =
0523         super_sort_matrix_rows(non_iso_row_presorted_energies_matrix_sig_p, N_EGAMMA_FIRST_GROUP_SIZE, N_KEEP_EGAMMA);
0524     std::vector<std::vector<l1t::L1Candidate> > non_iso_super_sorted_energies_matrix_sig_m =
0525         super_sort_matrix_rows(non_iso_row_presorted_energies_matrix_sig_m, N_EGAMMA_FIRST_GROUP_SIZE, N_KEEP_EGAMMA);
0526     //combine plus and minus
0527     std::vector<std::vector<l1t::L1Candidate> > iso_super_sorted_energies_matrix_sig(
0528         N_EGAMMA_FIRST_GROUPS, std::vector<l1t::L1Candidate>(N_KEEP_EGAMMA));
0529     std::vector<std::vector<l1t::L1Candidate> > non_iso_super_sorted_energies_matrix_sig(
0530         N_EGAMMA_FIRST_GROUPS, std::vector<l1t::L1Candidate>(N_KEEP_EGAMMA));
0531     for (int r = 0; r < N_EGAMMA_FIRST_GROUPS / 2; r++) {
0532       iso_super_sorted_energies_matrix_sig[r] = iso_super_sorted_energies_matrix_sig_m[r];
0533       iso_super_sorted_energies_matrix_sig[r + N_EGAMMA_FIRST_GROUPS / 2] = iso_super_sorted_energies_matrix_sig_p[r];
0534       non_iso_super_sorted_energies_matrix_sig[r] = non_iso_super_sorted_energies_matrix_sig_m[r];
0535       non_iso_super_sorted_energies_matrix_sig[r + N_EGAMMA_FIRST_GROUPS / 2] =
0536           non_iso_super_sorted_energies_matrix_sig_p[r];
0537     }
0538 
0539     //4
0540     std::vector<std::vector<l1t::L1Candidate> > iso_stage2_row_sorted_matrix_sig =
0541         sort_by_row_in_groups(iso_super_sorted_energies_matrix_sig, N_EGAMMA_SECOND_GROUP_SIZE);
0542     std::vector<std::vector<l1t::L1Candidate> > non_iso_stage2_row_sorted_matrix_sig =
0543         sort_by_row_in_groups(non_iso_super_sorted_energies_matrix_sig, N_EGAMMA_SECOND_GROUP_SIZE);
0544 
0545     //5
0546     std::vector<std::vector<l1t::L1Candidate> > iso_stage2_super_sorted_matrix_sig =
0547         super_sort_matrix_rows(iso_stage2_row_sorted_matrix_sig, N_EGAMMA_SECOND_GROUP_SIZE, N_KEEP_EGAMMA);
0548     std::vector<std::vector<l1t::L1Candidate> > non_iso_stage2_super_sorted_matrix_sig =
0549         super_sort_matrix_rows(non_iso_stage2_row_sorted_matrix_sig, N_EGAMMA_SECOND_GROUP_SIZE, N_KEEP_EGAMMA);
0550 
0551     //Prepare output
0552     std::vector<l1t::L1Candidate> sorted_iso_egammas = iso_stage2_super_sorted_matrix_sig[0];
0553     std::vector<l1t::L1Candidate> sorted_noniso_egammas = non_iso_stage2_super_sorted_matrix_sig[0];
0554 
0555     //verbose = false;
0556 
0557     for (unsigned int i = 0; i < 4; ++i) {
0558       auto const& tmp = sorted_iso_egammas[i];
0559       output->emplace_back(tmp.p4(), tmp.hwPt(), tmp.hwEta(), tmp.hwPhi(), tmp.hwQual(), 1 /*Iso*/);
0560     }
0561     for (unsigned int i = 0; i < 4; ++i) {
0562       auto const& tmp = sorted_noniso_egammas[i];
0563       output->emplace_back(tmp.p4(), tmp.hwPt(), tmp.hwEta(), tmp.hwPhi(), tmp.hwQual(), tmp.hwIso());
0564     }
0565   }
0566 
0567   void SortTaus(std::vector<l1t::Tau>* input, std::vector<l1t::Tau>* output) {
0568     const int CENTRAL_ETA_SLICES = 14;
0569     const int N_PHI_GROUPS = 5;
0570     const int N_PRESORTED_ROWS_CENTRAL = CENTRAL_ETA_SLICES * N_PHI_GROUPS;
0571     const int PRESORT_DEPTH = 4;
0572     const int N_KEEP_CENTRAL = 4;
0573     const int N_ETA_GROUP_SIZE_CENTRAL = 4;
0574     const int N_ETA_GROUPS_CENTRAL = 4;
0575 
0576     const int cen_nrows = 18;
0577     const int cen_ncols = 14;
0578 
0579     std::vector<std::vector<l1t::L1Candidate> > cen_input_energy(cen_nrows, std::vector<l1t::L1Candidate>(cen_ncols));
0580 
0581     for (std::vector<l1t::Tau>::const_iterator injet = input->begin(); injet != input->end(); ++injet) {
0582       if (injet->hwEta() >= 4 && injet->hwEta() <= 17) {
0583         unsigned int myrow = gt_to_fw_phi_map[injet->hwPhi()];
0584         unsigned int mycol = injet->hwEta() - 4;  //hardcoding is bad
0585         cen_input_energy[myrow][mycol] = *injet;
0586       } else
0587         edm::LogError("HardwareTauSort") << "Region out of bounds: " << injet->hwEta();
0588     }
0589 
0590     for (int i = 0; i < cen_nrows; ++i)
0591       for (int j = 0; j < cen_ncols; ++j) {
0592         if (cen_input_energy[i][j].hwPt() == 0) {
0593           cen_input_energy[i][j].setHwPhi(fw_to_gt_phi_map[i]);
0594           cen_input_energy[i][j].setHwEta(4 + j);
0595         }
0596       }
0597 
0598     //Each CLK is one clock
0599 
0600     //CLK 1
0601     std::vector<std::vector<l1t::L1Candidate> > presorted_energies_matrix_sig =
0602         presort(cen_input_energy, N_PRESORTED_ROWS_CENTRAL, PRESORT_DEPTH);
0603     //CLK 2
0604     std::vector<std::vector<l1t::L1Candidate> > row_presorted_energies_matrix_sig =
0605         sort_by_row_in_groups(presorted_energies_matrix_sig, N_PHI_GROUPS);
0606     //CLK 3
0607     std::vector<std::vector<l1t::L1Candidate> > sorted_eta_slices_energies_matrix_sig =
0608         super_sort_matrix_rows(row_presorted_energies_matrix_sig, N_PHI_GROUPS, N_KEEP_CENTRAL);
0609     //CLK 4
0610     std::vector<std::vector<l1t::L1Candidate> > row_presorted_eta_slices_energies_matrix_sig =
0611         sort_by_row_in_groups(sorted_eta_slices_energies_matrix_sig, N_ETA_GROUP_SIZE_CENTRAL);
0612     //CLK 5
0613     std::vector<std::vector<l1t::L1Candidate> > sorted_eta_groups_energies_matrix_sig =
0614         super_sort_matrix_rows(row_presorted_eta_slices_energies_matrix_sig, N_ETA_GROUP_SIZE_CENTRAL, N_KEEP_CENTRAL);
0615     //CLK 6
0616     std::vector<std::vector<l1t::L1Candidate> > row_presorted_eta_groups_energies_matrix_sig =
0617         sort_by_row_in_groups(sorted_eta_groups_energies_matrix_sig, N_ETA_GROUPS_CENTRAL);
0618     //CLK 7
0619     std::vector<std::vector<l1t::L1Candidate> > sorted_final_energies_matrix_sig =
0620         super_sort_matrix_rows(row_presorted_eta_groups_energies_matrix_sig, N_ETA_GROUPS_CENTRAL, N_KEEP_CENTRAL);
0621 
0622     for (unsigned int i = 0; i < 4; ++i) {
0623       auto const& tmp = sorted_final_energies_matrix_sig[0][i];
0624       output->emplace_back(tmp.p4(), tmp.hwPt(), tmp.hwEta(), tmp.hwPhi(), tmp.hwQual(), tmp.hwIso());
0625     }
0626   }
0627 }  // namespace l1t