Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-10-25 09:54:58

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;
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 
0267       if (row < input_egamma.size()) {
0268         energy_feeder[c] = input_egamma[row];
0269       } else {
0270         energy_feeder[c] = dummyJet;
0271       }
0272 
0273     }  //c
0274 
0275     energy_result = sort_array(energy_feeder);  //sort!
0276 
0277     sorted_energies[r] = energy_result;
0278   }  //r
0279   if (verbose)
0280     print2DVector(sorted_energies);
0281 
0282   return sorted_energies;
0283 }
0284 
0285 namespace l1t {
0286   void SortJets(std::vector<l1t::Jet>* input, std::vector<l1t::Jet>* output) {
0287     //verbose = true;
0288     const int CENTRAL_ETA_SLICES = 14;
0289     const int N_PHI_GROUPS = 5;
0290     const int N_PRESORTED_ROWS_CENTRAL = CENTRAL_ETA_SLICES * N_PHI_GROUPS;
0291     const int PRESORT_DEPTH = 4;
0292     const int N_KEEP_CENTRAL = 4;
0293     const int N_ETA_GROUP_SIZE_CENTRAL = 4;
0294     const int N_ETA_GROUPS_CENTRAL = 4;
0295 
0296     const int HFM_ETA_SLICES = 4;
0297     const int HFP_ETA_SLICES = 4;
0298     const int N_PRESORTED_ROWS_HFM = HFM_ETA_SLICES * N_PHI_GROUPS;
0299     const int N_PRESORTED_ROWS_HFP = HFP_ETA_SLICES * N_PHI_GROUPS;
0300     const int N_KEEP_FORWARD = 4;
0301 
0302     const int cen_nrows = 18;
0303     const int cen_ncols = 14;
0304     const int hfm_nrows = 18, hfp_nrows = 18;
0305     const int hfm_ncols = 4, hfp_ncols = 4;
0306 
0307     std::vector<std::vector<l1t::L1Candidate> > cen_input_energy(cen_nrows, std::vector<l1t::L1Candidate>(cen_ncols));
0308     std::vector<std::vector<l1t::L1Candidate> > hfm_input_energy(hfm_nrows, std::vector<l1t::L1Candidate>(hfm_ncols));
0309     std::vector<std::vector<l1t::L1Candidate> > hfp_input_energy(hfp_nrows, std::vector<l1t::L1Candidate>(hfp_ncols));
0310 
0311     for (std::vector<l1t::Jet>::const_iterator injet = input->begin(); injet != input->end(); ++injet) {
0312       if (injet->hwEta() >= 4 && injet->hwEta() <= 17) {
0313         unsigned int myrow = gt_to_fw_phi_map[injet->hwPhi()];
0314         unsigned int mycol = injet->hwEta() - 4;  //hardcoding is bad
0315         cen_input_energy[myrow][mycol] = *injet;
0316       } else if (injet->hwEta() < 4) {
0317         unsigned int myrow = gt_to_fw_phi_map[injet->hwPhi()];
0318         unsigned int mycol = injet->hwEta();  //hardcoding is bad
0319         hfm_input_energy[myrow][mycol] = *injet;
0320       } else if (injet->hwEta() > 17) {
0321         unsigned int myrow = gt_to_fw_phi_map[injet->hwPhi()];
0322         unsigned int mycol = injet->hwEta() - 18;  //hardcoding is bad
0323         hfp_input_energy[myrow][mycol] = *injet;
0324       } else
0325         edm::LogError("HardwareJetSort") << "Region out of bounds: " << injet->hwEta();
0326     }
0327 
0328     for (int i = 0; i < cen_nrows; ++i)
0329       for (int j = 0; j < cen_ncols; ++j) {
0330         if (cen_input_energy[i][j].hwPt() == 0) {
0331           cen_input_energy[i][j].setHwPhi(fw_to_gt_phi_map[i]);
0332           cen_input_energy[i][j].setHwEta(4 + j);
0333         }
0334       }
0335 
0336     for (int i = 0; i < hfm_nrows; ++i)
0337       for (int j = 0; j < hfm_ncols; ++j) {
0338         if (hfm_input_energy[i][j].hwPt() == 0) {
0339           hfm_input_energy[i][j].setHwPhi(fw_to_gt_phi_map[i]);
0340           hfm_input_energy[i][j].setHwEta(j);
0341           hfm_input_energy[i][j].setHwQual(2);
0342         }
0343       }
0344 
0345     for (int i = 0; i < hfp_nrows; ++i)
0346       for (int j = 0; j < hfp_ncols; ++j) {
0347         if (hfp_input_energy[i][j].hwPt() == 0) {
0348           hfp_input_energy[i][j].setHwPhi(fw_to_gt_phi_map[i]);
0349           hfp_input_energy[i][j].setHwEta(j + 18);
0350           hfp_input_energy[i][j].setHwQual(2);
0351         }
0352       }
0353 
0354     //Each CLK is one clock
0355 
0356     //CLK 1
0357     std::vector<std::vector<l1t::L1Candidate> > presorted_energies_matrix_sig =
0358         presort(cen_input_energy, N_PRESORTED_ROWS_CENTRAL, PRESORT_DEPTH);
0359     std::vector<std::vector<l1t::L1Candidate> > hfm_presorted_energies_matrix_sig =
0360         presort(hfm_input_energy, N_PRESORTED_ROWS_HFM, PRESORT_DEPTH);
0361     std::vector<std::vector<l1t::L1Candidate> > hfp_presorted_energies_matrix_sig =
0362         presort(hfp_input_energy, N_PRESORTED_ROWS_HFP, PRESORT_DEPTH);
0363 
0364     //CLK 2
0365     std::vector<std::vector<l1t::L1Candidate> > row_presorted_energies_matrix_sig =
0366         sort_by_row_in_groups(presorted_energies_matrix_sig, N_PHI_GROUPS);
0367     std::vector<std::vector<l1t::L1Candidate> > hfm_row_presorted_energies_matrix_sig =
0368         sort_by_row_in_groups(hfm_presorted_energies_matrix_sig, N_PHI_GROUPS);
0369     std::vector<std::vector<l1t::L1Candidate> > hfp_row_presorted_energies_matrix_sig =
0370         sort_by_row_in_groups(hfp_presorted_energies_matrix_sig, N_PHI_GROUPS);
0371 
0372     //CLK 3
0373     std::vector<std::vector<l1t::L1Candidate> > sorted_eta_slices_energies_matrix_sig =
0374         super_sort_matrix_rows(row_presorted_energies_matrix_sig, N_PHI_GROUPS, N_KEEP_CENTRAL);
0375     std::vector<std::vector<l1t::L1Candidate> > hfm_sorted_eta_slices_energies_matrix_sig =
0376         super_sort_matrix_rows(hfm_row_presorted_energies_matrix_sig, N_PHI_GROUPS, N_KEEP_FORWARD);
0377     std::vector<std::vector<l1t::L1Candidate> > hfp_sorted_eta_slices_energies_matrix_sig =
0378         super_sort_matrix_rows(hfp_row_presorted_energies_matrix_sig, N_PHI_GROUPS, N_KEEP_FORWARD);
0379 
0380     //CLK 4
0381     std::vector<std::vector<l1t::L1Candidate> > row_presorted_eta_slices_energies_matrix_sig =
0382         sort_by_row_in_groups(sorted_eta_slices_energies_matrix_sig, N_ETA_GROUP_SIZE_CENTRAL);
0383     std::vector<std::vector<l1t::L1Candidate> > hfm_row_presorted_eta_slices_energies_matrix_sig =
0384         sort_by_row_in_groups(hfm_sorted_eta_slices_energies_matrix_sig, HFM_ETA_SLICES);
0385     std::vector<std::vector<l1t::L1Candidate> > hfp_row_presorted_eta_slices_energies_matrix_sig =
0386         sort_by_row_in_groups(hfp_sorted_eta_slices_energies_matrix_sig, HFP_ETA_SLICES);
0387 
0388     //CLK 5
0389     std::vector<std::vector<l1t::L1Candidate> > sorted_eta_groups_energies_matrix_sig =
0390         super_sort_matrix_rows(row_presorted_eta_slices_energies_matrix_sig, N_ETA_GROUP_SIZE_CENTRAL, N_KEEP_CENTRAL);
0391     std::vector<std::vector<l1t::L1Candidate> > hfm_sorted_final_energies_matrix_sig =
0392         super_sort_matrix_rows(hfm_row_presorted_eta_slices_energies_matrix_sig, HFM_ETA_SLICES, N_KEEP_FORWARD);
0393     std::vector<std::vector<l1t::L1Candidate> > hfp_sorted_final_energies_matrix_sig =
0394         super_sort_matrix_rows(hfp_row_presorted_eta_slices_energies_matrix_sig, HFP_ETA_SLICES, N_KEEP_FORWARD);
0395 
0396     //CLK 6
0397     std::vector<std::vector<l1t::L1Candidate> > row_presorted_eta_groups_energies_matrix_sig =
0398         sort_by_row_in_groups(sorted_eta_groups_energies_matrix_sig, N_ETA_GROUPS_CENTRAL);
0399     std::vector<std::vector<l1t::L1Candidate> > hf_merged_plus_minus_forward_energies_matrix_sig(
0400         2, std::vector<l1t::L1Candidate>(N_KEEP_FORWARD));
0401     hf_merged_plus_minus_forward_energies_matrix_sig[0] = hfm_sorted_final_energies_matrix_sig[0];
0402     hf_merged_plus_minus_forward_energies_matrix_sig[1] = hfp_sorted_final_energies_matrix_sig[0];
0403     std::vector<std::vector<l1t::L1Candidate> > hf_row_presorted_merged_plus_minus_forward_energies_matrix_sig =
0404         sort_by_row_in_groups(hf_merged_plus_minus_forward_energies_matrix_sig, 2);
0405 
0406     //CLK 7
0407     std::vector<std::vector<l1t::L1Candidate> > sorted_final_energies_matrix_sig =
0408         super_sort_matrix_rows(row_presorted_eta_groups_energies_matrix_sig, N_ETA_GROUPS_CENTRAL, N_KEEP_CENTRAL);
0409     std::vector<std::vector<l1t::L1Candidate> > hf_sorted_final_merged_plus_minus_forward_energies_matrix_sig =
0410         super_sort_matrix_rows(hf_row_presorted_merged_plus_minus_forward_energies_matrix_sig, 2, N_KEEP_FORWARD);
0411 
0412     for (unsigned int i = 0; i < 4; ++i) {
0413       auto const& tmp = sorted_final_energies_matrix_sig[0][i];
0414       output->emplace_back(tmp.p4(), tmp.hwPt(), tmp.hwEta(), tmp.hwPhi(), tmp.hwQual());
0415     }
0416     for (unsigned int i = 0; i < 4; ++i) {
0417       auto const& tmp = hf_sorted_final_merged_plus_minus_forward_energies_matrix_sig[0][i];
0418       output->emplace_back(tmp.p4(), tmp.hwPt(), tmp.hwEta(), tmp.hwPhi(), tmp.hwQual() | 2);
0419     }
0420     //verbose = false;
0421   }
0422 
0423   void SortEGammas(std::vector<l1t::EGamma>* input, std::vector<l1t::EGamma>* output) {
0424     //Initialize
0425     const int FIBER_PAIRS = 18;
0426     const int N_INPUT_EGAMMAS = 4;
0427     const int N_PRESORTED_ROWS_EGAMMA = 36;
0428     const int PRESORT_DEPTH = 4;
0429     const int N_EGAMMA_FIRST_GROUP_SIZE = 6;
0430     const int N_EGAMMA_SECOND_GROUP_SIZE = 6;
0431     const int N_EGAMMA_FIRST_GROUPS = 6;
0432     const int N_KEEP_EGAMMA = 4;
0433 
0434     //Input
0435     //Each egamma: RCT isolation, RCT order, phi index, eta index
0436 
0437     vector<l1t::L1Candidate> iso_egamma_array_p,
0438         iso_egamma_array_m;  //reusing objects.  should probably rename to something like "object"
0439     vector<l1t::L1Candidate> noniso_egamma_array_p, noniso_egamma_array_m;
0440 
0441     for (int k = 0; k < 2 * N_INPUT_EGAMMAS * FIBER_PAIRS; k++) {
0442       l1t::L1Candidate dummyJet;
0443       dummyJet.setHwPt(0);
0444       dummyJet.setHwEta(99);
0445       dummyJet.setHwPhi(99);
0446       dummyJet.setHwQual(0x10);
0447       if (k < N_INPUT_EGAMMAS * FIBER_PAIRS) {
0448         iso_egamma_array_p.push_back(dummyJet);
0449         noniso_egamma_array_p.push_back(dummyJet);
0450       } else {
0451         iso_egamma_array_m.push_back(dummyJet);
0452         noniso_egamma_array_m.push_back(dummyJet);
0453       }
0454     }
0455 
0456     for (std::vector<l1t::EGamma>::const_iterator ineg = input->begin(); ineg != input->end(); ++ineg) {
0457       int fiberNum = (int)floor(gt_to_fw_phi_map[ineg->hwPhi()] / 2);
0458       int index = ineg->hwQual();
0459       bool iso = ineg->hwIso();
0460       bool minus = (ineg->hwEta() < 11);
0461 
0462       // while waiting for firmware LUT, set all iso to true
0463       //iso = true;
0464 
0465       if (iso && minus)
0466         iso_egamma_array_m[8 * fiberNum + index] = *ineg;
0467       else if (iso && !minus)
0468         iso_egamma_array_p[8 * fiberNum + index] = *ineg;
0469       else if (!iso && minus)
0470         noniso_egamma_array_m[8 * fiberNum + index] = *ineg;
0471       else if (!iso && !minus)
0472         noniso_egamma_array_p[8 * fiberNum + index] = *ineg;
0473     }
0474 
0475     // std::cout << "iso_egamma_array_m" << std::endl;
0476     // for(int i = 0; i < (int)iso_egamma_array_m.size(); ++i)
0477     // {
0478     //   std::cout << iso_egamma_array_m[i].hwPt() << " "
0479     //     << iso_egamma_array_m[i].hwEta() << " "
0480     //     << iso_egamma_array_m[i].hwPhi() << std::endl;
0481     // }
0482 
0483     // std::cout << "iso_egamma_array_p" << std::endl;
0484     // for(int i = 0; i < (int)iso_egamma_array_p.size(); ++i)
0485     // {
0486     //   std::cout << iso_egamma_array_p[i].hwPt() << " "
0487     //     << iso_egamma_array_p[i].hwEta() << " "
0488     //     << iso_egamma_array_p[i].hwPhi() << std::endl;
0489     // }
0490 
0491     //verbose = true;
0492     //1
0493     std::vector<std::vector<l1t::L1Candidate> > presorted_iso_matrix_sig_p =
0494         presort_egamma(iso_egamma_array_p, N_PRESORTED_ROWS_EGAMMA / 2, PRESORT_DEPTH);
0495     std::vector<std::vector<l1t::L1Candidate> > presorted_iso_matrix_sig_m =
0496         presort_egamma(iso_egamma_array_m, N_PRESORTED_ROWS_EGAMMA / 2, PRESORT_DEPTH);
0497     std::vector<std::vector<l1t::L1Candidate> > presorted_non_iso_matrix_sig_p =
0498         presort_egamma(noniso_egamma_array_p, N_PRESORTED_ROWS_EGAMMA / 2, PRESORT_DEPTH);
0499     std::vector<std::vector<l1t::L1Candidate> > presorted_non_iso_matrix_sig_m =
0500         presort_egamma(noniso_egamma_array_m, N_PRESORTED_ROWS_EGAMMA / 2, PRESORT_DEPTH);
0501 
0502     //2
0503     std::vector<std::vector<l1t::L1Candidate> > iso_row_presorted_energies_matrix_sig_p =
0504         sort_by_row_in_groups(presorted_iso_matrix_sig_p, N_EGAMMA_FIRST_GROUP_SIZE);
0505     std::vector<std::vector<l1t::L1Candidate> > iso_row_presorted_energies_matrix_sig_m =
0506         sort_by_row_in_groups(presorted_iso_matrix_sig_m, N_EGAMMA_FIRST_GROUP_SIZE);
0507     std::vector<std::vector<l1t::L1Candidate> > non_iso_row_presorted_energies_matrix_sig_p =
0508         sort_by_row_in_groups(presorted_non_iso_matrix_sig_p, N_EGAMMA_FIRST_GROUP_SIZE);
0509     std::vector<std::vector<l1t::L1Candidate> > non_iso_row_presorted_energies_matrix_sig_m =
0510         sort_by_row_in_groups(presorted_non_iso_matrix_sig_m, N_EGAMMA_FIRST_GROUP_SIZE);
0511 
0512     //3
0513     std::vector<std::vector<l1t::L1Candidate> > iso_super_sorted_energies_matrix_sig_p =
0514         super_sort_matrix_rows(iso_row_presorted_energies_matrix_sig_p, N_EGAMMA_FIRST_GROUP_SIZE, N_KEEP_EGAMMA);
0515     std::vector<std::vector<l1t::L1Candidate> > iso_super_sorted_energies_matrix_sig_m =
0516         super_sort_matrix_rows(iso_row_presorted_energies_matrix_sig_m, N_EGAMMA_FIRST_GROUP_SIZE, N_KEEP_EGAMMA);
0517     std::vector<std::vector<l1t::L1Candidate> > non_iso_super_sorted_energies_matrix_sig_p =
0518         super_sort_matrix_rows(non_iso_row_presorted_energies_matrix_sig_p, N_EGAMMA_FIRST_GROUP_SIZE, N_KEEP_EGAMMA);
0519     std::vector<std::vector<l1t::L1Candidate> > non_iso_super_sorted_energies_matrix_sig_m =
0520         super_sort_matrix_rows(non_iso_row_presorted_energies_matrix_sig_m, N_EGAMMA_FIRST_GROUP_SIZE, N_KEEP_EGAMMA);
0521     //combine plus and minus
0522     std::vector<std::vector<l1t::L1Candidate> > iso_super_sorted_energies_matrix_sig(
0523         N_EGAMMA_FIRST_GROUPS, std::vector<l1t::L1Candidate>(N_KEEP_EGAMMA));
0524     std::vector<std::vector<l1t::L1Candidate> > non_iso_super_sorted_energies_matrix_sig(
0525         N_EGAMMA_FIRST_GROUPS, std::vector<l1t::L1Candidate>(N_KEEP_EGAMMA));
0526     for (int r = 0; r < N_EGAMMA_FIRST_GROUPS / 2; r++) {
0527       iso_super_sorted_energies_matrix_sig[r] = iso_super_sorted_energies_matrix_sig_m[r];
0528       iso_super_sorted_energies_matrix_sig[r + N_EGAMMA_FIRST_GROUPS / 2] = iso_super_sorted_energies_matrix_sig_p[r];
0529       non_iso_super_sorted_energies_matrix_sig[r] = non_iso_super_sorted_energies_matrix_sig_m[r];
0530       non_iso_super_sorted_energies_matrix_sig[r + N_EGAMMA_FIRST_GROUPS / 2] =
0531           non_iso_super_sorted_energies_matrix_sig_p[r];
0532     }
0533 
0534     //4
0535     std::vector<std::vector<l1t::L1Candidate> > iso_stage2_row_sorted_matrix_sig =
0536         sort_by_row_in_groups(iso_super_sorted_energies_matrix_sig, N_EGAMMA_SECOND_GROUP_SIZE);
0537     std::vector<std::vector<l1t::L1Candidate> > non_iso_stage2_row_sorted_matrix_sig =
0538         sort_by_row_in_groups(non_iso_super_sorted_energies_matrix_sig, N_EGAMMA_SECOND_GROUP_SIZE);
0539 
0540     //5
0541     std::vector<std::vector<l1t::L1Candidate> > iso_stage2_super_sorted_matrix_sig =
0542         super_sort_matrix_rows(iso_stage2_row_sorted_matrix_sig, N_EGAMMA_SECOND_GROUP_SIZE, N_KEEP_EGAMMA);
0543     std::vector<std::vector<l1t::L1Candidate> > non_iso_stage2_super_sorted_matrix_sig =
0544         super_sort_matrix_rows(non_iso_stage2_row_sorted_matrix_sig, N_EGAMMA_SECOND_GROUP_SIZE, N_KEEP_EGAMMA);
0545 
0546     //Prepare output
0547     std::vector<l1t::L1Candidate> sorted_iso_egammas = iso_stage2_super_sorted_matrix_sig[0];
0548     std::vector<l1t::L1Candidate> sorted_noniso_egammas = non_iso_stage2_super_sorted_matrix_sig[0];
0549 
0550     //verbose = false;
0551 
0552     for (unsigned int i = 0; i < 4; ++i) {
0553       auto const& tmp = sorted_iso_egammas[i];
0554       output->emplace_back(tmp.p4(), tmp.hwPt(), tmp.hwEta(), tmp.hwPhi(), tmp.hwQual(), 1 /*Iso*/);
0555     }
0556     for (unsigned int i = 0; i < 4; ++i) {
0557       auto const& tmp = sorted_noniso_egammas[i];
0558       output->emplace_back(tmp.p4(), tmp.hwPt(), tmp.hwEta(), tmp.hwPhi(), tmp.hwQual(), tmp.hwIso());
0559     }
0560   }
0561 
0562   void SortTaus(std::vector<l1t::Tau>* input, std::vector<l1t::Tau>* output) {
0563     const int CENTRAL_ETA_SLICES = 14;
0564     const int N_PHI_GROUPS = 5;
0565     const int N_PRESORTED_ROWS_CENTRAL = CENTRAL_ETA_SLICES * N_PHI_GROUPS;
0566     const int PRESORT_DEPTH = 4;
0567     const int N_KEEP_CENTRAL = 4;
0568     const int N_ETA_GROUP_SIZE_CENTRAL = 4;
0569     const int N_ETA_GROUPS_CENTRAL = 4;
0570 
0571     const int cen_nrows = 18;
0572     const int cen_ncols = 14;
0573 
0574     std::vector<std::vector<l1t::L1Candidate> > cen_input_energy(cen_nrows, std::vector<l1t::L1Candidate>(cen_ncols));
0575 
0576     for (std::vector<l1t::Tau>::const_iterator injet = input->begin(); injet != input->end(); ++injet) {
0577       if (injet->hwEta() >= 4 && injet->hwEta() <= 17) {
0578         unsigned int myrow = gt_to_fw_phi_map[injet->hwPhi()];
0579         unsigned int mycol = injet->hwEta() - 4;  //hardcoding is bad
0580         cen_input_energy[myrow][mycol] = *injet;
0581       } else
0582         edm::LogError("HardwareTauSort") << "Region out of bounds: " << injet->hwEta();
0583     }
0584 
0585     for (int i = 0; i < cen_nrows; ++i)
0586       for (int j = 0; j < cen_ncols; ++j) {
0587         if (cen_input_energy[i][j].hwPt() == 0) {
0588           cen_input_energy[i][j].setHwPhi(fw_to_gt_phi_map[i]);
0589           cen_input_energy[i][j].setHwEta(4 + j);
0590         }
0591       }
0592 
0593     //Each CLK is one clock
0594 
0595     //CLK 1
0596     std::vector<std::vector<l1t::L1Candidate> > presorted_energies_matrix_sig =
0597         presort(cen_input_energy, N_PRESORTED_ROWS_CENTRAL, PRESORT_DEPTH);
0598     //CLK 2
0599     std::vector<std::vector<l1t::L1Candidate> > row_presorted_energies_matrix_sig =
0600         sort_by_row_in_groups(presorted_energies_matrix_sig, N_PHI_GROUPS);
0601     //CLK 3
0602     std::vector<std::vector<l1t::L1Candidate> > sorted_eta_slices_energies_matrix_sig =
0603         super_sort_matrix_rows(row_presorted_energies_matrix_sig, N_PHI_GROUPS, N_KEEP_CENTRAL);
0604     //CLK 4
0605     std::vector<std::vector<l1t::L1Candidate> > row_presorted_eta_slices_energies_matrix_sig =
0606         sort_by_row_in_groups(sorted_eta_slices_energies_matrix_sig, N_ETA_GROUP_SIZE_CENTRAL);
0607     //CLK 5
0608     std::vector<std::vector<l1t::L1Candidate> > sorted_eta_groups_energies_matrix_sig =
0609         super_sort_matrix_rows(row_presorted_eta_slices_energies_matrix_sig, N_ETA_GROUP_SIZE_CENTRAL, N_KEEP_CENTRAL);
0610     //CLK 6
0611     std::vector<std::vector<l1t::L1Candidate> > row_presorted_eta_groups_energies_matrix_sig =
0612         sort_by_row_in_groups(sorted_eta_groups_energies_matrix_sig, N_ETA_GROUPS_CENTRAL);
0613     //CLK 7
0614     std::vector<std::vector<l1t::L1Candidate> > sorted_final_energies_matrix_sig =
0615         super_sort_matrix_rows(row_presorted_eta_groups_energies_matrix_sig, N_ETA_GROUPS_CENTRAL, N_KEEP_CENTRAL);
0616 
0617     for (unsigned int i = 0; i < 4; ++i) {
0618       auto const& tmp = sorted_final_energies_matrix_sig[0][i];
0619       output->emplace_back(tmp.p4(), tmp.hwPt(), tmp.hwEta(), tmp.hwPhi(), tmp.hwQual(), tmp.hwIso());
0620     }
0621   }
0622 }  // namespace l1t