ROOT logo
/** Welcome!
 *
 *  This macro is intended for the following tasks:
 *    1. find bad (switched off/dead/noisy/strange) cells;
 *    2. find out the status/quality of analysed data (missing RCUs, run quality);
 *    3. find the extent of problems related to bad cells: required for
 *       systematics estimation for a physical quantity related to a cluster.
 *
 *  For impatient, change the "infile" line below and execute
 *    root -l getCellsRunsQA.C
 *
 *  For curios, continue reading getCellsRunsQA() code: it is self-documented.
 *
 *  The macro options are tuned for a user (and pp runs), and in most cases no user
 *  intervension is necessary. Still, it is likely that you will have to edit
 *  nexc/excells[] in the parameters section below and run the macro several times.
 *  Consult with the output from this macro.
 *  In case of PbPb runs, a small modification is necessary:
 *   1) change ExcludeSmallRuns() line by putting a smaller number, e.g. 5-10k events;
 *   2) change FindDeadNoisyCellsPerRun() factor thresholds to a more narrow region, e.g. 0.07-2;
 *   3) probably, change fit region in FitPi0().
 *  Also, do not forget to adjust cluster cut for pi0s in AliCaloCellsQA. The value 2.5GeV
 *  is currently reasonable.
 *
 *  Generally, a QA expert uncomments all the functions which return (print to stdout)
 *  bad cell candidates and checks them by hand.
 *
 *  Detector-specific parts require to run this macro with aliroot instead of root,
 *  they are commented in getCellsRunsQA() by default.
 *
 *  This macro is written as a number of small functions and is designed both
 *  for EMCAL and for PHOS (and DCAL in future).
 *  Drawing options are chosen with respect to PPRStyle() drawing defaults.
 *
 *  Input: AliCaloCellsQA analysis output.
 *
 *  TODO: cells time spectra: currently it is not put in use. Seems that time shape fitting is
 *        not trivial due to the presence of parasite peaks (one needs to remove them first?),
 *        and this is a separate issue to think about...
 *
 *  TODO: some PHOS-specific parts
 *
 *  Author: Olga Driga (SUBATECH)
 */


// ========================== Parameters section ==============================

// input
char *infile = "CellsQAEMCAL.root";

// supermodule colors
Color_t colorsSM[] = {2,3,4,5,6,7,8,9,11,12};

// cells to exclude from averages calculations and their number: bad cells can
// mess up the results, it is suggested to list (known and newly found with
// this code) problematic cell candidates explicitly
Int_t nexc = 45+69+156+132;
Int_t excells[] = {
  74,103,152,495,871,917,1059,1263,1275,1276,1288,1376,1382,1384,1519,1712,1961,      // EMCAL, LHC10bcde
  1967,2026,2047,2112,2114,2115,2116,2117,2120,2123,2298,2540,2671,2768,2769,2770,    // 45
  2771,2773,2774,2776,2777,2778,2779,2780,2783,3135,3544,3567

  ,49,152,495,917,1248,1249,1250,1251,1252,1253,1254,1255,1256,1257,1258,1259,1260,   // EMCAL, LHC10h
  1261,1262,1263,1275,1276,1288,1296,1297,1298,1299,1300,1301,1302,1303,1304,1305,    // 69
  1306,1307,1308,1309,1310,1311,1376,1384,1414,1519,1712,1860,1967,2026,2047,2114,
  2115,2116,2117,2120,2123,2298,2671,2768,2769,2770,2771,2773,2774,2776,2777,2778,
  2779,2780,2783,3567

  ,74,103,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,368,369,    // EMCAL, LHC11a pp@7TeV
  370,371,372,373,374,375,376,377,378,379,380,381,382,383,1263,1275,1276,1288,1376,   // 156
  1382,1384,1519,1595,1704,1860,1967,2022,2026,2047,2071,2114,2115,2116,2117,2120,
  2123,2210,2298,2776,2778,3544,3567,4026,4157,4174,4494,4609,4610,4616,4620,4662,
  4670,4705,4718,4719,4752,4754,4756,4758,4762,4764,4800,4801,4802,4804,4857,4898,
  4904,4958,4997,4999,5041,5043,5044,5090,5097,5102,5137,5138,5139,5148,5184,5192,
  5208,5246,5330,5336,5384,5428,5430,5436,5437,5726,5748,5754,5767,6095,6111,6340,
  6592,6800,6801,6802,6803,6804,6805,6806,6807,6808,6809,6810,6811,6812,6813,6814,
  6815,7089,7371,7425,7430,7457,7491,7709,7874,8352,8353,8356,8357,8808,8810,8812,
  8814,9056,9815,9837,11080

  ,74,103,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,368,369,     // EMCAL, LHC11a pp@2.76TeV
  370,371,372,373,374,375,376,377,378,379,380,381,382,383,1059,1175,1263,1275,1276,    // 132
  1288,1376,1382,1384,1519,1595,1860,1967,2022,2026,2047,2071,2117,2210,2298,2362,
  2506,2776,2778,3544,4026,4157,4174,4494,4610,4616,4620,4662,4670,4719,4756,4758,
  4764,4801,4857,4898,4904,4958,4999,5041,5090,5097,5102,5138,5148,5184,5192,5246,
  5330,5336,5384,5430,5437,5767,6095,6111,6340,6592,6800,6801,6802,6803,6804,6805,
  6806,6807,6808,6809,6810,6811,6812,6813,6814,6815,7371,7375,7425,7430,7457,7491,
  7709,7874,8352,8353,8356,8357,8808,8810,8812,8814,9056,9815,9837
};

// ====================== End of parameters section ===========================


void getCellsRunsQA()
{
  // Entry point for the analysis.

  gRandom->SetSeed(0);
  gStyle->SetOptStat(0);
  gStyle->SetOptFit(111);
  gStyle->SetPalette(1);
  gStyle->SetFillColor(10);

  Printf("Input: %s", infile);
  TFile::Open(infile);

  // You may wish to extract and draw a particular histogram from infile.
  // Here are the examples:
  //
  //   TH1* hNEventsProcessedPerRun = (TH1*) gFile->Get("hNEventsProcessedPerRun");
  //   hNEventsProcessedPerRun->Draw();
  //   return;
  //
  //   TH1* hNTimesInClusterElow = (TH1*) gFile->Get("run146686_hCellLocMaxNTimesInClusterElow");
  //   hNTimesInClusterElow->Draw();
  //   return;
  //
  //   TH1* hETotalClusterEhigh = (TH1*) gFile->Get("run146686_hCellLocMaxETotalClusterEhigh");
  //   hETotalClusterEhigh->Draw();
  //   return;

  // Draw a random cell spectrum;
  // 0.2-1 GeV -- fit region;
  // 3 GeV -- the spectrum is drawn up to this value, -1 = no limit;
  // last argument -- histogram name to process, possible values are:
  //    hCellAmplitude, hCellAmplitudeEHigh, hCellAmplitudeNonLocMax or fhCellAmplitudeEhighNonLocMax.
  DrawCell(1+gRandom->Integer(4607), 0.25, 1., 2., "hCellAmplitude");  // common cell region for EMCAL2010 and for PHOS

  // Draw a random cell time spectrum
  DrawCellTime(1+gRandom->Integer(4607));


  /* RUN NUMBER SELECTION SECTION
   *
   * NOTE: at any point below runs are sorted in chronological order.
   */

  // array with run numbers and their number
  Int_t runNumbers[10000];
  Int_t nruns = 0;

  // First, fill run numbers ...
  GetRunNumbers(nruns, runNumbers);
  Printf("Total number of runs: %i", nruns);

  // ... draw events distribution ...
  // (the last argument is number of bins in this distribution)
  DrawRunsDistribution(nruns, runNumbers, 100);

  // ... and exclude runs with number of events < 50k.
  ExcludeSmallRuns(nruns, runNumbers, 100e+3);

  // You may wish to exclude particular runs:
  //   Int_t runs2Exclude[] = {111222,333444,555666};
  //   ExcludeRunNumbers(nruns, runNumbers, 3, runs2Exclude);

  Printf("Number of runs to be analysed: %i", nruns);

  // Finally, print a nice table with run index / run number / number of events.
  PrintRunNumbers(nruns, runNumbers);


  /* PER RUN BAD CELLS SEARCHING CRITERIA
   *
   * Four primary criteria on a per run basis:
   *   1 and 2: number of times cell was a local maximum in a cluster at low/high energies;
   *   3 and 4: total cluster energy for a local maximum cell at low/high energies.
   */

  // Extract the histograms with dead/noisy cell candidates per run.
  // For each of the four criteria, for each run and for each cell:
  //   1) calculate cell factor = [cell value]/[average over cells];
  //   2) mark cell as dead (candidate) if factor <= factorDead (3rd argument below);
  //   3) mark cell as noisy (candidate) if factor >= factorNoisy (4th argument below).
  //
  // Factor thresholds are quite wide by default:
  // low energy criteria are not very sensitive to them,
  // while high energy criteria are very sensitive due to limited statistics.
  //
  // The function below also draws histograms with factor distributions in all the runs
  // for all the cells. It may help to take the decision about dead/noisy factor thresholds.
  // The last two arguments -- number of bins and maximum X axis value for such histograms.
  //
  // Output: hBadCellMap[4] -- bad cell candidates per run for each of the four criteria;
  // X axis -- cell absId, Y axis -- run index, content: 0=not bad, 1=noisy, -1=dead.
  //
  TH2** hBadCellMap = FindDeadNoisyCellsPerRun(nruns, runNumbers, 0.05, 3.5, 200, 10.);

  // Print cell numbers suggested for exclusion from averages calculation;
  // see excells[] array in the parameters section in the beginning of the macro.
  // It is highly suggested to run this macro several times and add the output
  // of this function to the parameters section.
  PrintCellsToExcludeFromAverages(hBadCellMap);

  // The results can be visualized (second argument -- canvas name):
  // either per run ...
  DrawDeadNoisyCellMap(hBadCellMap[0], "hMapRuns_NTimesInClusterElow");
  DrawDeadNoisyCellMap(hBadCellMap[1], "hMapRuns_NTimesInClusterEhigh");
//   DrawDeadNoisyCellMap(hBadCellMap[2], "hMapRuns_ETotalClusterElow");
//   DrawDeadNoisyCellMap(hBadCellMap[3], "hMapRuns_ETotalClusterEhigh");

  // ... or per number of events ...
//   DrawDeadNoisyCellMap((TH2*)ConvertMapRuns2Events(nruns,runNumbers,hBadCellMap[0]), "hMapEvents_NTimesInClusterElow");
//   DrawDeadNoisyCellMap((TH2*)ConvertMapRuns2Events(nruns,runNumbers,hBadCellMap[1]), "hMapEvents_NTimesInClusterEhigh");
//   DrawDeadNoisyCellMap((TH2*)ConvertMapRuns2Events(nruns,runNumbers,hBadCellMap[2]), "hMapEvents_ETotalClusterElow");
//   DrawDeadNoisyCellMap((TH2*)ConvertMapRuns2Events(nruns,runNumbers,hBadCellMap[3]), "hMapEvents_ETotalClusterEhigh");

  // ... or we can also draw the percent for each cell being dead/noisy
//   DrawDeadNoisyCellPercent(nruns, runNumbers, hBadCellMap[0], "hPercent_NTimesInClusterElow");
//   DrawDeadNoisyCellPercent(nruns, runNumbers, hBadCellMap[1], "hPercent_NTimesInClusterEhigh");
//   DrawDeadNoisyCellPercent(nruns, runNumbers, hBadCellMap[2], "hPercent_ETotalClusterElow");
//   DrawDeadNoisyCellPercent(nruns, runNumbers, hBadCellMap[3], "hPercent_ETotalClusterEhigh");

  // Our main criteria for analytical finding of bad cells is based on the following.
  // Note that factor distributions for NTimesInCluster and ETotalCluster are very
  // similar, both at low and at high energy. Note also that we can say the same
  // for dead/noisy cell visualizations above: they are very similar. This suggests
  // that NTimesInCluster and ETotalCluster give the same results. The criteria
  // NTimesInCluster, however, is more calibration-independent (though energy thresholds
  // are still calibration-dependent) and thus is more reliable and clear. Thus, we
  // limit ourselves to NTimesInClusterElow/NTimesInClusterEhigh criteria.
  // Now, you could probably noted that NTimesInClusterEhigh give more dead
  // cells than that at low energy. This is an expected statistical effect: we have
  // much smaller number of clusters at high energy. Consequently, we will not use dead
  // cell candidates at high energy.
  //
  // Finally, we combine candidates from low/high energies and produce one TH2
  // histogram which is the primary source of our analytical results.
  //
  TH2* hBadCellMapPrimary = CombineDeadNoisyElowEhigh(hBadCellMap[0], hBadCellMap[1]);

  // Note for PHOS: if you are not happy with NTimesInClusterEhigh results (due to a lack of statistics)
  // uncomment this line:
//   hBadCellMapPrimary = hBadCellMap[0];

  // Draw everything for combined
  DrawDeadNoisyCellMap(hBadCellMapPrimary, "Primary_hMapRuns");
  DrawDeadNoisyCellMap((TH2*)ConvertMapRuns2Events(nruns,runNumbers,hBadCellMapPrimary), "Primary_hMapEvents");
  DrawDeadNoisyCellPercent(nruns, runNumbers, hBadCellMapPrimary, "Primary_hPercent");

  // Print full information on cells which are dead/noisy;
  // kTRUE -- print also the percentage % dead/% noisy
  PrintDeadNoisyCells(hBadCellMapPrimary, 0.9, 1.);          // in 90-100% of runs
  PrintDeadNoisyCells(hBadCellMapPrimary, 0.5, 0.9, kTRUE);  // in 50-90% of runs
//   PrintDeadNoisyCells(hBadCellMapPrimary, 0.3, 0.5);      // in 30-50% of runs

  // visualize dead/noisy cell map for EMCAL/PHOS; requires aliroot
//   DrawOccupancy(nruns, runNumbers, hBadCellMapPrimary, "hDeadNoisyCellsOccupancy");

  // EMCAL: print full information on missing/noisy parts (e.g. RCUs); requires aliroot
//   PrintEMCALProblematicBlocks(nruns, runNumbers, hBadCellMapPrimary);


  /* RUNS QUALITY SECTION: CLUSTER AVERAGES + PI0 AVERAGES
   *
   */

  // First, draw cluster averages per run;
  //   1 = minimum number of cells in a cluster;
  //   0.3GeV = minimum cluster energy;
  //   -1     = maximum cluster energy = infinity (in fact, 20GeV in the default configuration).
  DrawClusterAveragesPerRun(nruns, runNumbers, 1, 0.3, -1);

  // Second, draw the same cluster averages per run, but corrected for detector acceptance
  DrawClusterAveragesPerRun(nruns, runNumbers, 1, 0.3, -1, hBadCellMapPrimary);

  // Draw random slices of the pi0 peak in one supermodule and in whole detector
  DrawPi0Slice(runNumbers[gRandom->Integer(nruns)], 1 + gRandom->Integer(3));
  DrawPi0Slice(runNumbers[gRandom->Integer(nruns)], -1);

  // Draw number of pi0s per event, pi0 mass and width
  DrawPi0Averages(nruns, runNumbers);

  // Draw pi0 values per event with pi0 photons both in the same supermodule
//   DrawPi0Averages(nruns, runNumbers, kTRUE);

  // Draw pi0 values per event with pi0 photons both in the same supermodule
  // + correct for supermodule acceptance (should not be treated to be 100% reliable!)
//   DrawPi0Averages(nruns, runNumbers, kTRUE, hBadCellMap[0]);

  // Draw pi0 distributions (helps to take decision on bad runs);
  // first argument -- suffix from canvas title;
  // second argument -- number of bins in distributions
//   DrawPi0Distributions("", 100);
//   DrawPi0Distributions("SM1", 100)
//   DrawPi0Distributions("_sameSM", 100);
//   DrawPi0Distributions("_sameSM_corr4accep", 100);

  // !!!
  return;

  /* SHAPE ANALYSIS
   *
   * Lazy/curious boundary is here! -------------------------
   * Do not pass it if you do not fill curious enough! ;)
   *
   * The shape analysis below belongs to the main bad cell searching criteria.
   * However, it may require some extra work in order to make it usable.
   *
   * The idea behind is simple: fit the energy spectrum of a cell with
   * the function A*exp(-B*x)/x^2 (which proved to be a very good fit),
   * draw parameters A, B and chi2/ndf distributions and notice
   * cells which deviate too much from the averages.
   *
   * Huge statistics (>20M events) is necessary for this to work reliably.
   *
   * TODO: test on PHOS
   */

  // The analysis below defines a cell as being bad simply if it is outside
  // of some good region for any of the parameters A, B, chi2/ndf.
  // The regions are depicted by vertical orange lines. The problem is that these
  // regions are usually not automatically determined correctly.
  //
  // The function syntax is the following:
  //   0.1-1.0 GeV -- fitting region;
  //   hCellAmplitude -- the histogram which to take for processing,
  //                     the other possible choice is hCellAmplitudeNonLocMax;
  //   1000 -- number of bins is distributions.
  //
  // The next three groups of parameters are:
  //   <text label> <maximum value on distribution> <left edge of the good region> <right edge of the good region>
  //
  // It is left/right edges which usually require manual tuning.
  // -1 means to initialize a parameter automatically.
  //
  TestCellShapes(0.25, 1., "hCellAmplitude", 1000,
               // maxval / left margin / right margin
                 -1, -1,-1,     // fit A
                 -1, -1,-1,     // fit B
                 -1, -1,-1);    // fit chi2/ndf


  /* DISTRIBUTION ANALYSIS
   *
   * Test for bad cells by plotting a distribution among cells.
   *
   * It is especially useful in searching for miscalibrated cells.
   * The function parameters are similar to parameters from shape analysis section.
   */

  TestCellsTH1(nruns, runNumbers, "hCellLocMaxNTimesInClusterElow",
               "Number of times cell was local maximum, low energy, per event", "Entries",
               400, -1,-1,-1);   // nbins / maxval / left margin / right margin

  TestCellsTH1(nruns, runNumbers, "hCellLocMaxNTimesInClusterEhigh",
               "Number of times cell was local maximum, high energy, per event", "Entries",
               400, -1,-1,-1);   // nbins / maxval / left margin / right margin

//   TestCellsTH1(nruns, runNumbers, "hCellLocMaxETotalClusterElow",
//                "Total cluster energy for local maximum cell, low energy, per event", "Entries",
//                400, -1,-1,-1);   // nbins / maxval / left margin / right margin
//
//   TestCellsTH1(nruns, runNumbers, "hCellLocMaxETotalClusterEhigh",
//                "Total cluster energy for local maximum cell, high energy, per event", "Entries",
//                400, -1,-1,-1);   // nbins / maxval / left margin / right margin

  // Three more tests for bad cells:
  //  1) total deposited energy;
  //  2) total number of entries;
  //  3) average energy = [total deposited energy]/[total number of entries].
  //
  TestCellEandN(0.1, "hCellAmplitude", 1000,
             // maxval / left margin / right margin
                -1,-1,-1,    // cell E
                -1,-1,-1,    // cell N
                -1,-1,-1);   // cell E/N

  // the same at high energies
  TestCellEandN(0.1, "hCellAmplitudeEhigh", 1000,
             // maxval / left margin / right margin
                -1,-1,-1,    // cell E
                -1,-1,-1,    // cell N
                -1,-1,-1);   // cell E/N


  // The same as above, but for not a local maximum cells; require more statistics
//   TestCellsTH1(nruns, runNumbers, "hCellNonLocMaxNTimesInClusterElow",
//                "Number of times cell wasn't local maximum, low energy, per event", "Entries",
//                400, -1,-1,-1);   // nbins / maxval / left margin / right margin
//
//   TestCellsTH1(nruns, runNumbers, "hCellNonLocMaxNTimesInClusterEhigh",
//                "Number of times cell wasn't local maximum, high energy, per event", "Entries",
//                400, -1,-1,-1);   // nbins / maxval / left margin / right margin
//
//   TestCellsTH1(nruns, runNumbers, "hCellNonLocMaxETotalClusterElow",
//                "Total cluster energy for not local maximum cell, low energy, per event", "Entries",
//                400, -1,-1,-1);   // nbins / maxval / left margin / right margin
//
//   TestCellsTH1(nruns, runNumbers, "hCellNonLocMaxETotalClusterEhigh",
//                "Total cluster energy for not local maximum cell, high energy, per event", "Entries",
//                400, -1,-1,-1);   // nbins / maxval / left margin / right margin
//
//   TestCellEandN(0.1, "hCellAmplitudeNonLocMax", 1000,
//              // maxval / left margin / right margin
//                 -1,-1,-1,    // cell E
//                 -1,-1,-1,    // cell N
//                 -1,-1,-1);   // cell E/N
//
//   TestCellEandN(0.1, "hCellAmplitudeEhighNonLocMax", 1000,
//              // maxval / left margin / right margin
//                 -1,-1,-1,    // cell E
//                 -1,-1,-1,    // cell N
//                 -1,-1,-1);   // cell E/N


  // TODO: cells time

  // The end ;)
}



/* BAD CELLS SEARCHING FUNCTIONS
 *
 */

//_________________________________________________________________________
TH2** FindDeadNoisyCellsPerRun(const Int_t nruns, Int_t runNumbers[],
                               Double_t factorDead = 0.01, Double_t factorNoisy = 4.,
                               Int_t fnbins = 200, Double_t fxmax = 10.)
{
  // Return bad cell candidate maps for the four criteria;
  // X axis -- cell absId, Y axis -- run index, content: 0=not bad, 1=noisy, -1=dead.
  //
  // For each run and each cell calculate factor = [cell value]/[averate over cells],
  // mark cell as noisy if factor >= factorNoisy, mark cell as dead if factor <= factorDead.
  //
  // fnbins, fxmax -- number of bins and X axis maximum value for factor distributions.
  //
  // Four criteria in order:
  char *hname[4] = {"hCellLocMaxNTimesInClusterElow", "hCellLocMaxNTimesInClusterEhigh",
                     "hCellLocMaxETotalClusterElow", "hCellLocMaxETotalClusterEhigh"};

  TH1*  hFactorDistr[4];
  TH2** hBadCellMap = new TH2*[4];

  // take one histogram to get binning parameters
  TH1* one = (TH1*) gFile->Get(Form("run%i_%s",runNumbers[0],hname[0]));
  Int_t  ncells = one->GetNbinsX();
  Double_t amin = one->GetXaxis()->GetXmin();
  Double_t amax = one->GetXaxis()->GetXmax();

  // find dead/noisy cell candidates
  for (Int_t k = 0; k < 4; k++) {
    hBadCellMap[k] = new TH2C(Form("hBadCellMap_%s_fdead=%.3f_fnoisy=%.1f",hname[k],factorDead,factorNoisy),
                              Form("Dead/noisy cell map (%s, fdead=%.3f, fnoisy=%.1f)",hname[k],factorDead,factorNoisy),
                                    ncells,amin,amax, nruns,0,nruns);
    hBadCellMap[k]->SetXTitle("AbsId");
    hBadCellMap[k]->SetYTitle("Run index");
    hBadCellMap[k]->SetTitleOffset(1.7,"Y");

    hFactorDistr[k] = new TH1F(Form("hFactorDistr_%s_fdead=%.3f_fnoisy=%.1f",
                                     hname[k],factorDead,factorNoisy), "", fnbins,0,fxmax);
    hFactorDistr[k]->SetTitle("Factor distributions in all runs");
    hFactorDistr[k]->SetXTitle("Factor");
    hFactorDistr[k]->SetYTitle("Entries");

    // run index loop
    for (Int_t ri = 0; ri < nruns; ri++) {
      TH1* one = (TH1*) gFile->Get(Form("run%i_%s", runNumbers[ri], hname[k]));

      // calculate average
      Double_t av = 0;  // average
      Int_t count = 0;  // counted cells
      for (Int_t c = 1; c <= ncells; c++) {
        // do not count cells with zero content
        if (one->GetBinContent(c) == 0) continue;
        // do not count cells listed in the parameters section in the beginning of the macro
        if (IsCellMarked4Exclude(one->GetBinLowEdge(c))) continue;
        count++;
        av += one->GetBinContent(c);
      }

      // division by zero checks
      if (count == 0) {
        Warning("FindDeadNoisyCellsPerRun", Form("No cells counted at ri=%i",ri));
        continue;
      }
      av /= count;

      if (av == 0) {
        Warning("FindDeadNoisyCellsPerRun", Form("Average is zero at ri=%i",ri));
        continue;
      }

      // find dead/noisy candidates
      for (Int_t c = 1; c <= ncells; c++) {
        Double_t fac = one->GetBinContent(c)/av;
        hFactorDistr[k]->Fill(fac);

        if (fac <= factorDead)
          hBadCellMap[k]->SetBinContent(c, ri+1, -1);
        else if (fac >= factorNoisy)
          hBadCellMap[k]->SetBinContent(c, ri+1, 1);
      }

      delete one;
    } // run index loop
  } // criteria loop


  // draw factor distributions ...
  TCanvas *c1 = new TCanvas("hFactorDistr", "hFactorDistr", 400,400);
  gPad->SetLeftMargin(0.12);
  gPad->SetRightMargin(0.08);
  gPad->SetLogy();
  hFactorDistr[0]->SetLineColor(kBlue);
  hFactorDistr[1]->SetLineColor(kRed);
  hFactorDistr[2]->SetLineColor(kGreen);
  hFactorDistr[3]->SetLineColor(kOrange);
  hFactorDistr[0]->Draw();
  hFactorDistr[1]->Draw("same");
  hFactorDistr[2]->Draw("same");
  hFactorDistr[3]->Draw("same");

  // ... with legend
  TLegend *leg = new TLegend(0.45,0.65,0.90,0.85);
  leg->AddEntry(hFactorDistr[0], "NTimesInCluster, low energy","l");
  leg->AddEntry(hFactorDistr[2], "ETotalCluster, low energy","l");
  leg->AddEntry(hFactorDistr[1], "NTimesInCluster, high energy","l");
  leg->AddEntry(hFactorDistr[3], "EtotalCluster, high energy","l");
  leg->Draw("same");

  c1->Update();

  return hBadCellMap;
}

//_________________________________________________________________________
void PrintCellsToExcludeFromAverages(TH2** hBadCellMap)
{
  // Print cells suggested for exclusion from averages calculation

  Int_t ncells = hBadCellMap[0]->GetNbinsX();
  Int_t nruns  = hBadCellMap[0]->GetNbinsY();

  Int_t *suggested = new Int_t[ncells];
  memset(suggested, 0, ncells*sizeof(Int_t));

  for (Int_t c = 1; c <= ncells; c++)
    for (Int_t ri = 1; ri <= nruns; ri++)
      if (hBadCellMap[0]->GetBinContent(c, ri) != 0 || hBadCellMap[2]->GetBinContent(c, ri) != 0 ||
          hBadCellMap[1]->GetBinContent(c, ri)  > 0 || hBadCellMap[3]->GetBinContent(c, ri)  > 0) // NOTE: dead not counted
        suggested[c-1]++;

  printf("Suggested cells to switch off in averages calculations (copai 'n paste!):\n");
  printf("Int_t excells[] = {");
  Int_t n = 0;
  for (Int_t c = 0; c < ncells; c++)
    if (suggested[c] >= 0.4*nruns) {// 40% of runs threshold
      printf("%s%i", n == 0 ? "" : ",", c);
      n++;
    }
  printf("};\nInt_t nexc = %i;\n\n",n);
}

//_________________________________________________________________________
Bool_t IsCellMarked4Exclude(Int_t absId)
{
  // Return true if a cell is in excells[] array

  static TH1* hExclCells = NULL;

  // one time initialization
  if (!hExclCells) {
    hExclCells = new TH1F("hExclCells", "", 20000,0,20000);
    for (Int_t c = 0; c < nexc; c++)
      hExclCells->SetBinContent(hExclCells->FindBin(excells[c]), 1);
  }

  return (hExclCells->GetBinContent(hExclCells->FindBin(absId)) > 0 ? kTRUE : kFALSE);
}

//_________________________________________________________________________
void DrawDeadNoisyCellMap(TH2* hmap, char* cname)
{
  // Visualize dead/noisy cell map;
  // cname -- canvas name.

  TCanvas *c1 = new TCanvas(cname, cname, 0,0,600,600);
  gPad->SetLeftMargin(0.14);
  gPad->SetRightMargin(0.06);

  // draw dummy to initialize axis ranges
  TH2* hDummy = (TH2*) hmap->Clone(Form("hDummy_%s",cname));
  hDummy->Reset();
  hDummy->Draw();

  for (Int_t c = 1; c <= hmap->GetNbinsX(); c++) //cell number
    for (Int_t ri = 1; ri <= hmap->GetNbinsY(); ri++) { //run index
      Double_t stat = hmap->GetBinContent(c, ri); // cell status
      if (stat == 0) continue;

      Double_t x  = hmap->GetXaxis()->GetBinCenter(c);
      Double_t y1 = hmap->GetYaxis()->GetBinLowEdge(ri);
      Double_t y2 = hmap->GetYaxis()->GetBinUpEdge(ri);

      // draw a line; FIXME: what is a better choice?
      TLine* line = new TLine(x,y1,x,y2);
      line->SetLineWidth(1);
      if (stat > 0) line->SetLineColor(kRed); // noisy cell
      else line->SetLineColor(kBlue); // dead cell
      line->Draw();
    }

  c1->Update();
}

//_________________________________________________________________________
void DrawDeadNoisyCellPercent(Int_t nruns, Int_t runNumbers[], TH2* hmap, char* cname)
{
  // Show percent of runs/events for each cell being problematic;
  // cname -- canvas name.

  // binning parameters
  Int_t  ncells = hmap->GetNbinsX();
  Double_t amin = hmap->GetXaxis()->GetXmin();
  Double_t amax = hmap->GetXaxis()->GetXmax();

  // number of times cell was dead/noisy;
  Int_t *ndeadRuns    = new Int_t[ncells];
  Int_t *nnoisyRuns   = new Int_t[ncells];
  Double_t *ndeadEvents  = new Double_t[ncells];
  Double_t *nnoisyEvents = new Double_t[ncells];

  // fill arrays above
  for (Int_t c = 0; c < ncells; c++) {
    ndeadRuns[c] = 0;
    nnoisyRuns[c] = 0;
    ndeadEvents[c] = 0;
    nnoisyEvents[c] = 0;

    for (Int_t ri = 0; ri < nruns; ri++) {
      Double_t stat = hmap->GetBinContent(c+1, ri+1); // cell status
      Int_t nevents = GetNumberOfEvents(runNumbers[ri]);

      if (stat > 0) {
        nnoisyRuns[c]++;
        nnoisyEvents[c] += nevents;
      }
      else if (stat < 0) {
        ndeadRuns[c]++;
        ndeadEvents[c] += nevents;
      }
    } // run index loop
  } // cell loop

  // total number of events
  Double_t ntotal = GetTotalNumberOfEvents(nruns, runNumbers);

  TCanvas *c1 = new TCanvas(cname, cname, 0,0,600,600);
  gPad->SetLeftMargin(0.14);
  gPad->SetRightMargin(0.06);

  // draw dummy histogram to initialize canvas
  TH1* hDummy = new TH1F(Form("hDummy_%s",cname), hmap->GetTitle(), ncells,amin,amax);
  hDummy->SetAxisRange(0,100, "Y");
  hDummy->SetXTitle("AbsId");
  hDummy->SetYTitle("Percent");
  hDummy->Draw();

  // to fill legend
  TLine *line1 = NULL;
  TLine *line2 = NULL;
  TLine *line3 = NULL;
  TLine *line4 = NULL;

  // draw results, FIXME: is where a better way?
  for (Int_t c = 0; c < ncells; c++) {
    Double_t x = hmap->GetXaxis()->GetBinCenter(c+1);
    Double_t y1 = 100.*ndeadEvents[c]/ntotal;
    Double_t y2 = 100.*ndeadRuns[c]/nruns;

    // events, dead bar
    if (ndeadEvents[c] > 0) {
      line1 = new TLine(x, 0, x, y1);
      line1->SetLineWidth(1);
      line1->SetLineColor(kBlue);
      line1->Draw();
    }

    // events, noisy bar
    if (nnoisyEvents[c] > 0) {
      line2 = new TLine(x, y1, x, y1 + 100.*nnoisyEvents[c]/ntotal);
      line2->SetLineWidth(1);
      line2->SetLineColor(kRed);
      line2->Draw();
    }

    // runs, dead bar
    if (ndeadRuns[c] > 0) {
      line3 = new TLine(x, 0, x, y2);
      line3->SetLineWidth(1);
      line3->SetLineStyle(7);
      line3->SetLineColor(kBlack);
      line3->Draw();
    }

    // runs, noisy bar
    if (nnoisyRuns[c] > 0) {
      line4 = new TLine(x, y2, x, y2 + 100.*nnoisyRuns[c]/nruns);
      line4->SetLineWidth(1);
      line4->SetLineStyle(7);
      line4->SetLineColor(kOrange);
      line4->Draw();
    }
  }

  // legend
  TLegend *leg = new TLegend(0.65,0.65,0.92,0.75);
  if (line1) leg->AddEntry(line1, "% of events, dead","l");
  if (line2) leg->AddEntry(line2, "% of events, noisy","l");
  if (line3) leg->AddEntry(line3, "% of runs, dead","l");
  if (line4) leg->AddEntry(line4, "% of runs, noisy","l");
  leg->Draw("same");

  c1->Update();
}

//_________________________________________________________________________
TH1* ConvertMapRuns2Events(const Int_t nruns, Int_t runNumbers[], TH1* inhisto)
{
  // Returns a histogram in which run index axis is converted to number of events
  // by making a variable axis bin width.
  // If inhisto inherits from TH2, convert Y axis; convert X axis otherwise.

  // bin widths
  Double_t *nevents = new Double_t[nruns+1];
  nevents[0] = 0;
  for (Int_t ri = 0; ri < nruns; ri++)
    nevents[1+ri] = nevents[ri] + GetNumberOfEvents(runNumbers[ri]);

  TH1* outh = (TH1*) inhisto->Clone(Form("%s_Events",inhisto->GetName()));

  if (inhisto->InheritsFrom("TH2")) {
    outh->GetYaxis()->Set(nruns, nevents);
    outh->SetYTitle("Number of events");
    outh->SetTitleOffset(1.7,"Y");
  }
  else {// TH1 case
    outh->GetXaxis()->Set(nruns, nevents);
    outh->SetXTitle("Number of events");
  }

  return outh;
}

//_________________________________________________________________________
TH2* CombineDeadNoisyElowEhigh(TH2* hmapElow, TH2* hmapEhigh)
{
  // Combine two maps at low/high energy into one,
  // do not count dead map at high energy.
  // NOTE: if cell is dead at Elow and noisy and Ehigh, set content = 2.

  TH2* hmap_combined = (TH2*) hmapElow->Clone(Form("%s+%s",hmapElow->GetName(),hmapEhigh->GetName()));

  for (Int_t c = 1; c <= hmapElow->GetNbinsX(); c++)
    for (Int_t ri = 1; ri <= hmapElow->GetNbinsY(); ri++)
      if (hmapEhigh->GetBinContent(c, ri) > 0) {
        hmap_combined->SetBinContent(c, ri, 1);

        if (hmapElow->GetBinContent(c, ri) < 0)
          hmap_combined->SetBinContent(c, ri, 2);
      }

  hmap_combined->SetTitle("Dead/noisy cell map, combined");

  return hmap_combined;
}

//_________________________________________________________________________
void PrintDeadNoisyCells(TH2* hmap, Double_t percent1 = 0.95, Double_t percent2 = 1., Bool_t kPrintPercentage = kFALSE)
{
  // Print full information on dead/noisy cells which are present in
  // percent1-percent2 portion of runs (percent1 excluded, percent2 included).

  Int_t ncells = hmap->GetNbinsX();
  Int_t nruns  = hmap->GetNbinsY();

  Int_t nbad = 0;

  printf("Dead/noisy cells in >%.1f%% and <=%.1f%% of runs:", 100*percent1, 100*percent2);

  for (Int_t c = 1; c <= ncells; c++) {
    Int_t nrdead = 0; // count number of runs for the current cell
    Int_t nrnoisy = 0;

    for (Int_t ri = 1; ri <= nruns; ri++)
      if      (hmap->GetBinContent(c,ri) < 0) nrdead++;
      else if (hmap->GetBinContent(c,ri) > 0) nrnoisy++;

    if (nrdead+nrnoisy > percent1*nruns && nrdead+nrnoisy <= percent2*nruns) {
      printf(" %.0f", hmap->GetBinLowEdge(c));
      if (kPrintPercentage)
        printf("(%-2.0f/%-2.0f)", 100.*nrdead/nruns, 100.*nrnoisy/nruns);
      nbad++;
    }
  }

  printf(" (%i total)\n\n", nbad);
}

//_________________________________________________________________________
void DrawOccupancy(Int_t nruns, Int_t runNumbers[], TH2* hmap, char* cname)
{
  // Draw bad cell map for EMCAL or PHOS;
  // cname -- canvas name.

  // guess detector
  if (hmap->GetNbinsX() % 1152 == 0)
    DrawEMCALOccupancy(nruns, runNumbers, hmap, cname);
  else
    DrawPHOSOccupancy(nruns, runNumbers, hmap, cname);
}

//_________________________________________________________________________
void DrawEMCALOccupancy(Int_t nruns, Int_t runNumbers[], TH2* hmap, char* cname)
{
  // Draw bad cell map for EMCAL;
  // cname -- canvas name.

  Int_t nmods = hmap->GetNbinsX()/1152;  // number of supermodules
  Int_t vsize = ceil(nmods/2.);          // vertical size in canvas
  Int_t lastSector = (nmods-1)/2;        // for pad number calculation

  TCanvas *c1 = new TCanvas(cname, cname, 800,200*vsize);
  c1->Divide(2, vsize);

  for (Int_t sm = 0; sm < nmods; sm++)
  {
    // top left is SM0, bottom right is SM9
    Int_t side = sm%2;
    Int_t sector = sm/2;
    c1->cd((lastSector - sector)*2 + side + 1);

    TH2* hSM = new TH2C(Form("hEMCALSM%i_%s",sm,cname), Form("SM%i",sm), 48,0,48, 24,0,24);
    hSM->SetXTitle("iEta");
    hSM->SetYTitle("iPhi");

    // loop over supermodule cells
    for (Int_t c = 0; c < 1152; c++) {
      Int_t absId = 1152 * sm + c;

      for (Int_t ri = 0; ri < nruns; ri++) {
        if (hmap->GetBinContent(hmap->FindBin(absId,ri)) == 0) continue;

        Int_t nModule, eta, phi;
        AbsId2EtaPhi(absId, nModule, eta, phi);
        hSM->Fill(eta,phi);
      }
    }

    hSM->Draw("colz");
  } // supermodule loop

  c1->Update();
}

//_________________________________________________________________________
void DrawPHOSOccupancy(Int_t nruns, Int_t runNumbers[], TH2* hmap, char* cname)
{
  // Draw bad cell map for PHOS;
  // cname -- canvas name.

  Int_t nmods = hmap->GetNbinsX()/3584;  // number of supermodules
  Int_t vsize = nmods;                   // vertical size in canvas

  TCanvas *c1 = new TCanvas(cname, cname, 64*5,56*5*vsize);
  c1->Divide(1, vsize);

  for (Int_t sm = 1; sm <= nmods; sm++)
  {
    c1->cd(sm);

    TH2* hSM = new TH2C(Form("hPHOSSM%i_%s",sm,cname), Form("SM%i",sm), 64,0,64, 56,0,56);
    hSM->SetXTitle("iEta");
    hSM->SetYTitle("iPhi");

    // loop over supermodule cells
    for (Int_t c = 1; c <= 3584; c++) {
      Int_t absId = 3584*(sm-1) + c;

      for (Int_t ri = 0; ri < nruns; ri++) {
        if (hmap->GetBinContent(hmap->FindBin(absId,ri)) == 0) continue;

        Int_t nModule, eta, phi;
        AbsId2EtaPhi(absId, nModule, eta, phi, 1);
        hSM->Fill(eta,phi);
      }
    }

    hSM->Draw("colz");
  } // supermodule loop

  c1->Update();
}

//_________________________________________________________________________
void PrintEMCALProblematicBlocks(Int_t nruns, Int_t runNumbers[], TH2* hmap)
{
  // Print, on a per run basis, complete information about EMCAL missing
  // (or dead or noisy) blocks. Missing/noisy EMCAL atomic part is a 2x2
  // block (288 blocks per supermodule).

  // number of supermodules
  Int_t nmods = hmap->GetNbinsX()/1152;

  Printf("Problematic (missing/dead/noisy) 2x2 block numbers in EMCAL:");

  // run index loop
  for (Int_t ri = 0; ri < nruns; ri++) {
    Printf("Run %i:", runNumbers[ri]);

    // supermodule loop
    for (Int_t sm = 0; sm < nmods; sm++) {

      // will be filled with the number of missing cells (from 0 to 4)
      Int_t blk2x2[288];
      memset(blk2x2, 0, 288*sizeof(Int_t));

      for (Int_t c = 0; c < 1152; c++) {
        Int_t absId = 1152 * sm + c;

        // select problematic cells only
        if (hmap->GetBinContent(hmap->FindBin(absId,ri)) == 0) continue;

        Int_t nModule, eta, phi;
        AbsId2EtaPhi(c, nModule, eta, phi);
        blk2x2[nModule]++;
      }

      // calculate number of bad blocks
      Int_t nbad2x2 = 0;
      for (Int_t b = 0; b < 288; b++)
        if (blk2x2[b] == 4) nbad2x2++;

      // no bad
      if (nbad2x2 == 0) continue;

      printf("  SM%i:", sm);

      // whole supermodule
      if (nbad2x2 == 288) {
        printf(" missing the whole supermodule!\n");
        continue;
      }

      // RCUs
      if (nbad2x2 >= 144) {
        Int_t nRCU[2];
        nRCU[0] = 0;
        nRCU[1] = 0;

        for (Int_t b = 0; b < 288; b++)
          if (blk2x2[b] == 4) nRCU[GetEMCALRCUNumber(b)]++;

        if (nRCU[0] == 144) {
          printf(" RCU0");
          for (Int_t b = 0; b < 288; b++)
            if (blk2x2[b] == 4 && GetEMCALRCUNumber(b) == 0) blk2x2[b] = 0;
        }

        if (nRCU[1] == 144) {
          printf(" RCU1");
          for (Int_t b = 0; b < 288; b++)
            if (blk2x2[b] == 4 && GetEMCALRCUNumber(b) == 1) blk2x2[b] = 0;
        }

        nbad2x2 -= 144;
      }

      // the rest
      if (nbad2x2 > 0) {
        for (Int_t b = 0; b < 288; b++)
          if (blk2x2[b] == 4) printf(" %i", b);
        printf(" (%i)", nbad2x2);
      }

      printf("\n");

    } // supermodule loop
  } // run index loop

  Printf("");
}

//_________________________________________________________________________
Int_t GetEMCALRCUNumber(Int_t nModule)
{
  // Returns RCU number for a 2x2 block in EMCAL;
  // nModule -- block number (0-287).

  static TH1* hRCUs = NULL;

  // one-time initialization
  if (!hRCUs) {
    hRCUs = new TH1F("hRCU1", "", 288,0,288);

    Int_t RCU1[144] = {8,9,10,11,20,21,22,23,32,33,34,35,44,45,46,47,56,57,58,59,68,69,70,71,80,81,82,83,
             92,93,94,95,104,105,106,107,116,117,118,119,128,129,130,131,140,141,142,143,148,149,150,151,
             152,153,154,155,160,161,162,163,164,165,166,167,172,173,174,175,176,177,178,179,184,185,186,
             187,188,189,190,191,196,197,198,199,200,201,202,203,208,209,210,211,212,213,214,215,220,221,
             222,223,224,225,226,227,232,233,234,235,236,237,238,239,244,245,246,247,248,249,250,251,256,
             257,258,259,260,261,262,263,268,269,270,271,272,273,274,275,280,281,282,283,284,285,286,287};

    for (Int_t i = 0; i < 144; i++) hRCUs->SetBinContent(RCU1[i]+1, 1);
  }

  return hRCUs->GetBinContent(nModule+1);
}

//_________________________________________________________________________
void AbsId2EtaPhi(Int_t absId, Int_t &nModule, Int_t &eta, Int_t &phi, Int_t det = 0)
{
  // Converts cell absId --> (sm,eta,phi);
  //
  // nModule -- 2x2 block number for EMCAL;
  // det -- detector: 0/EMCAL, 1/PHOS.

  // EMCAL
  if (det == 0) {
    AliEMCALGeometry *geomEMCAL = AliEMCALGeometry::GetInstance("EMCAL_COMPLETEV1");

    Int_t nSupMod, nIphi, nIeta;
    geomEMCAL->GetCellIndex(absId, nSupMod, nModule, nIphi, nIeta);
    geomEMCAL->GetCellPhiEtaIndexInSModule(nSupMod, nModule, nIphi, nIeta, phi, eta);
    return;
  }

  // PHOS
  else if (det == 1) {
    AliPHOSGeometry *geomPHOS = AliPHOSGeometry::GetInstance("IHEP");

    Int_t relid[4];
    geomPHOS->AbsToRelNumbering(absId, relid);
    //sm = relid[0];
    eta = relid[2];
    phi = relid[3];
    return;
  }

  // DCAL
  // not implemented
  //

  Error("AbsId2EtaPhi", "Wrong detector");
  abort();
}

//_________________________________________________________________________
void TestCellsTH1(Int_t nruns, Int_t runNumbers[], char *hname,
                  char* htitle = "", char* hytitle = "",
                  Int_t dnbins = 200, Double_t dmaxval = -1, Double_t goodmin = -1, Double_t goodmax = -1)
{
  // Test for bad cells by plotting a distribution of a TH1 histogram.
  // The histogram is obtained as a sum over runs of TH1 per run.
  //
  // hname -- histogram name to process;
  // htitle, hytitle -- histogram title and Y axis title;
  // dnbins -- number of bins in distribution;
  // dmaxval -- X axis maximum in distribution.
  // goodmin,goodmax -- the region outside which a cell is considered as bad.
  //
  // -1 value for maxval/goodmin/goodmax -- process a variable automatically.

  // initialize histogram
  TH1* histo = (TH1*) gFile->Get(Form("run%i_%s", runNumbers[0], hname));
  histo->SetName(hname);
  histo->SetTitle(htitle);
  histo->SetXTitle("AbsId");
  histo->SetYTitle(hytitle);

  // sum over runs
  for (Int_t i = 1; i < nruns; i++) {
    TH1* h = (TH1*) gFile->Get(Form("run%i_%s", runNumbers[i], hname));
    histo->Add(h);
    delete h;
  }

  histo->Scale(1./(Double_t)GetTotalNumberOfEvents(nruns, runNumbers));
  Process1(histo, Form("TestCellsTH1_%s",hname), dnbins, dmaxval, goodmin, goodmax);
}

//_________________________________________________________________________
void TestCellEandN(Double_t Emin = 0.1, char* hname = "hCellAmplitude", Int_t dnbins = 200,
                   Double_t maxval1 = -1, Double_t goodmin1 = -1, Double_t goodmax1 = -1,
                   Double_t maxval2 = -1, Double_t goodmin2 = -1, Double_t goodmax2 = -1,
                   Double_t maxval3 = -1, Double_t goodmin3 = -1, Double_t goodmax3 = -1)
{
  // Three more tests for bad cells:
  //  1) total deposited energy;
  //  2) total number of entries;
  //  3) average energy = [total deposited energy]/[total number of entries].
  //
  // Based on summary histograms. Possible choises:
  //   hCellAmplitude, hCellAmplitudeEhigh, hCellAmplitudeNonLocMax, hCellAmplitudeEhighNonLocMax
  //
  // Emin -- minimum cell amplitude to count;
  // hname -- name (in file) of TH2 histogram with cell amplitudes;
  // dnbins -- number of bins in distributions;
  // maxval[123] -- maximum values on distributions for the criteria 1),2),3) respectively;
  // goodmin[123],goodmax[123] -- the regions on distributions outside those a cell is considered as bad.

  // input; X axis -- absId numbers
  TH2 *hCellAmplitude = (TH2*) gFile->Get(hname);

  // binning parameters
  Int_t ncells = hCellAmplitude->GetNbinsX();
  Double_t amin = hCellAmplitude->GetXaxis()->GetXmin();
  Double_t amax = hCellAmplitude->GetXaxis()->GetXmax();

  TH1* hCellEtotal = new TH1F(Form("%s_hCellEtotal_E%.2f",hname,Emin),
                              Form("Total deposited energy, E > %.2f GeV",Emin), ncells,amin,amax);
  hCellEtotal->SetXTitle("AbsId");
  hCellEtotal->SetYTitle("Energy, GeV");

  TH1F *hCellNtotal = new TH1F(Form("%s_hCellNtotal_E%.2f",hname,Emin),
                               Form("Total number of entries, E > %.2f GeV",Emin), ncells,amin,amax);
  hCellNtotal->SetXTitle("AbsId");
  hCellNtotal->SetYTitle("Entries");

  TH1F *hCellEtoNtotal = new TH1F(Form("%s_hCellEtoNtotal_E%.2f",hname,Emin),
                                  Form("Average energy per hit, E > %.2f GeV",Emin), ncells,amin,amax);
  hCellEtoNtotal->SetXTitle("AbsId");
  hCellEtoNtotal->SetYTitle("Energy, GeV");

  // fill cells
  for (Int_t c = 1; c <= ncells; c++) {
    Double_t Esum = 0;
    Double_t Nsum = 0;

    for (Int_t i = 1; i <= hCellAmplitude->GetNbinsY(); i++) {
      Double_t E = hCellAmplitude->GetYaxis()->GetBinCenter(i);
      Double_t N = hCellAmplitude->GetBinContent(c, i);
      if (E < Emin) continue;
      Esum += E*N;
      Nsum += N;
    }

    hCellEtotal->SetBinContent(c, Esum);
    hCellNtotal->SetBinContent(c, Nsum);

    if (Nsum > 0.5)  // number of entries >= 1
      hCellEtoNtotal->SetBinContent(c, Esum/Nsum);
  }

  delete hCellAmplitude;

  Process1(hCellEtotal,    Form("%s_CellE", hname),   dnbins, maxval1, goodmin1, goodmax1);
  Process1(hCellNtotal,    Form("%s_CellN", hname),   dnbins, maxval2, goodmin2, goodmax2);
  Process1(hCellEtoNtotal, Form("%s_CellE/N", hname), dnbins, maxval3, goodmin3, goodmax3);
}

//_________________________________________________________________________
void TestCellShapes(Double_t fitEmin, Double_t fitEmax, char* hname = "hCellAmplitude", Int_t dnbins = 1000,
                    Double_t maxval1 = -1, Double_t goodmin1 = -1, Double_t goodmax1 = -1,
                    Double_t maxval2 = -1, Double_t goodmin2 = -1, Double_t goodmax2 = -1,
                    Double_t maxval3 = -1, Double_t goodmin3 = -1, Double_t goodmax3 = -1)
{
  // Test cells shape using fit function f(x)=A*exp(-B*x)/x^2.
  // Produce values per cell + distributions for A, B and chi2/ndf parameters.
  //
  // fitEmin, fitEmax -- fit range;
  // hname -- name (in file) of TH2 histogram with cell amplitudes;
  // dnbins -- number of bins in distributions;
  // maxval[123] -- maximum values on distributions for the criteria A, B and chi2/ndf respectively;
  // goodmin[123],goodmax[123] -- the regions on distributions outside those a cell is considered as bad.
  //
  // -1 value for maxval/goodmin/goodmax -- process a variable automatically.
  //
  // Note: numbers are optimized for EMCAL.
  // TODO: check for PHOS

  // input; X axis -- absId numbers
  TH2 *hCellAmplitude = (TH2*) gFile->Get(hname);

  // binning parameters
  Int_t  ncells = hCellAmplitude->GetNbinsX();
  Double_t amin = hCellAmplitude->GetXaxis()->GetXmin();
  Double_t amax = hCellAmplitude->GetXaxis()->GetXmax();

  // initialize histograms
  TH1 *hFitA = new TH1F(Form("hFitA_%s",hname),"Fit A value", ncells,amin,amax);
  hFitA->SetXTitle("AbsId");
  hFitA->SetYTitle("A");

  TH1 *hFitB = new TH1F(Form("hFitB_%s",hname),"Fit B value", ncells,amin,amax);
  hFitB->SetXTitle("AbsId");
  hFitB->SetYTitle("B");

  TH1 *hFitChi2Ndf = new TH1F(Form("hFitChi2Ndf_%s",hname),"Fit #chi^{2}/ndf value", ncells,amin,amax);
  hFitChi2Ndf->SetXTitle("AbsId");
  hFitChi2Ndf->SetYTitle("#chi^{2}/ndf");

  // total number of events; to estimate A value
  TH1* hNEventsProcessedPerRun = (TH1*) gFile->Get("hNEventsProcessedPerRun");
  Double_t ntotal = hNEventsProcessedPerRun->Integral(1, hNEventsProcessedPerRun->GetNbinsX());

  // fitting function
  TF1 *fit = new TF1("fit", "[0]*exp(-[1]*x)/x^2");
  fit->SetParLimits(0, ntotal*1e-8,ntotal*1e-4);
  fit->SetParLimits(1, 0.,30.);
  fit->SetParameter(0, ntotal*1e-6);
  fit->SetParameter(1, 1.5);

  for (Int_t i = 1; i <= ncells; i++) {
    TH1 *hCell = hCellAmplitude->ProjectionY("",i,i);
    if (hCell->GetEntries() == 0) continue;

    hCell->Fit(fit, "0LQEM", "", fitEmin, fitEmax);
    delete hCell;

    hFitA->SetBinContent(i, fit->GetParameter(0));
    hFitB->SetBinContent(i, fit->GetParameter(1));
    if (fit->GetNDF() != 0)
      hFitChi2Ndf->SetBinContent(i, fit->GetChisquare()/fit->GetNDF());
  }

  delete hCellAmplitude;

  // automatic parameters, if requested
  if (maxval1 < 0) maxval1 = 4e-6 * ntotal;
  if (maxval2 < 0) maxval2 = 10.;
  if (maxval3 < 0) maxval3 = 15.;

  Process1(hFitA,       Form("%s_FitA", hname),       dnbins, maxval1, goodmin1, goodmax1);
  Process1(hFitB,       Form("%s_FitB", hname),       dnbins, maxval2, goodmin2, goodmax2);
  Process1(hFitChi2Ndf, Form("%s_FitChi2ndf", hname), dnbins, maxval3, goodmin3, goodmax3);
}

//_________________________________________________________________________
void Process1(TH1* inhisto, char* label = "", Int_t dnbins = 200,
              Double_t dmaxval = -1, Double_t goodmin = -1, Double_t goodmax = -1)
{
  // Actual distribution analysis for a TH1 histogram:
  //  1) create a distribution for the input histogram;
  //  2) draw nicely;
  //  3) take a decision about bad cells.
  //
  // inhisto -- input histogram;
  // label -- text label for stdout;
  // dnbins -- number of bins in distribution;
  // goodmin,goodmax -- cells outside this region are considered as bad;
  // dmaxval -- maximum value on distribution histogram.
  // The later is required in cases where a bad cell kills the whole distribution:
  // limiting distribution maximum value solves the problem.

  if (dmaxval < 0)
    dmaxval = inhisto->GetMaximum()*1.01;  // 1.01 - to see the last bin

  TH1 *distrib = new TH1F(Form("%sDistr",inhisto->GetName()), "", dnbins, inhisto->GetMinimum(), dmaxval);
  distrib->SetXTitle(inhisto->GetYaxis()->GetTitle());
  distrib->SetYTitle("Entries");

  // fill distribution
  for (Int_t c = 1; c <= inhisto->GetNbinsX(); c++)
    distrib->Fill(inhisto->GetBinContent(c));

  // draw histogram + distribution
  TCanvas *c1 = new TCanvas(inhisto->GetName(),inhisto->GetName(), 800,400);
  c1->Divide(2,1);

  c1->cd(1);
  gPad->SetLeftMargin(0.14);
  gPad->SetRightMargin(0.06);
  gPad->SetLogy();
  inhisto->SetTitleOffset(1.7,"Y");
  inhisto->Draw();

  c1->cd(2);
  gPad->SetLeftMargin(0.14);
  gPad->SetRightMargin(0.10);
  gPad->SetLogy();
  distrib->Draw();

  // simple way to estimate the left margin for good cells region:
  // go from left to right and find the first bin with content 2,
  // then go from this bin right to left while bin content is nonzero
  if (goodmin < 0) {
    goodmin = distrib->GetXaxis()->GetXmin();

    for (Int_t i = 1; i <= distrib->GetNbinsX(); i++)
      if (distrib->GetBinContent(i) == 2) {
        while (i > 1 && distrib->GetBinContent(i-1) > 0) i--;
        goodmin = distrib->GetBinLowEdge(i);
        break;
      }
  }

  // the same automatic algorithm as above, but reflected
  if (goodmax < 0) {
    goodmax = distrib->GetXaxis()->GetXmax();

    for (Int_t i = distrib->GetNbinsX(); i >= 1; i--)
      if (distrib->GetBinContent(i) == 2) {
        while (i < distrib->GetNbinsX() && distrib->GetBinContent(i+1) > 0) i++;
        goodmax = distrib->GetXaxis()->GetBinUpEdge(i);
        break;
      }
  }

  // lines
  TLine *lline = new TLine(goodmin, 0, goodmin, distrib->GetMaximum());
  lline->SetLineColor(kOrange);
  lline->SetLineStyle(7);
  lline->Draw();

  TLine *rline = new TLine(goodmax, 0, goodmax, distrib->GetMaximum());
  rline->SetLineColor(kOrange);
  rline->SetLineStyle(7);
  rline->Draw();

  // legend
  TLegend *leg = new TLegend(0.60,0.82,0.9,0.88);
  leg->AddEntry(lline, "Good region boundary","l");
  leg->Draw("same");

  c1->Update();


  printf("Bad cells by criterum \"%s\":", label);

  // print bad cell numbers (outside goodmin,goodmax region)
  Int_t ntot = 0;
  for (Int_t c = 1; c <= inhisto->GetNbinsX(); c++)
    if (inhisto->GetBinContent(c) < goodmin || inhisto->GetBinContent(c) > goodmax) {
      printf(" %.0f", inhisto->GetBinLowEdge(c));
      ntot++;
    }

  printf(" (%i total)\n\n", ntot);
}

//_________________________________________________________________________
void DrawCell(Int_t absId, Double_t fitEmin = 0.3, Double_t fitEmax = 1.,
              Double_t Emax = -1, char* hname = "hCellAmplitude")
{
  // Draw one cell spectrum with a fit.
  //
  // fitEmin, fitEmax -- fit range;
  // Emax -- maximum value on X axis to show (-1 = no limit);
  // hname -- TH2 histogram name to process, possible values:
  //    "hCellAmplitude", "hCellAmplitudeEHigh", "hCellAmplitudeNonLocMax", "hCellAmplitudeEhighNonLocMax".

  // input; X axis -- absId numbers
  TH2* hCellAmplitude = (TH2*) gFile->Get(hname);

  Int_t bin = hCellAmplitude->GetXaxis()->FindBin(absId);
  TH1* hCell = hCellAmplitude->ProjectionY(Form("hCell%i_%s",absId,hname),bin,bin);
  hCell->SetXTitle("Energy, GeV");
  hCell->SetYTitle("Entries");
  hCell->SetTitle(Form("Cell %i, %s", absId, hname));
  if (Emax > 0) hCell->SetAxisRange(0, Emax);

  // draw spectrum
  TCanvas *c1 = new TCanvas(Form("hCell%i_%s",absId,hname), Form("hCell%i_%s",absId,hname), 400,400);
  gPad->SetLeftMargin(0.12);
  gPad->SetRightMargin(0.08);
  gPad->SetBottomMargin(0.12);
  gPad->SetLogy();
  hCell->Draw();

  // total number of events
  TH1* hNEventsProcessedPerRun = (TH1*) gFile->Get("hNEventsProcessedPerRun");
  Double_t ntotal = hNEventsProcessedPerRun->Integral(1, hNEventsProcessedPerRun->GetNbinsX());

  // fit
  TF1 *fit = new TF1("fit", "[0]*exp(-[1]*x)/x^2");
  fit->SetLineColor(kRed);
  fit->SetLineWidth(2);
  fit->SetParName(0, "A");
  fit->SetParName(1, "B");
  fit->SetParLimits(0, ntotal*1e-8,ntotal*1e-4);
  fit->SetParLimits(1, 0.,30.);
  fit->SetParameter(0, ntotal*1e-6);
  fit->SetParameter(1, 1.);
  hCell->Fit(fit,"LQEM", "", fitEmin, fitEmax);

  // legend
  TLegend *leg = new TLegend(0.5,0.75,0.9,0.8);
  leg->AddEntry(fit, "A*exp(-B*x)/x^{2}","l");
  leg->Draw("same");

  c1->Update();
}

//_________________________________________________________________________
void DrawCellTime(Int_t absId)
{
  // Draw one cell time spectrum

  // input; X axis -- absId numbers
  TH2* hCellTime = (TH2*) gFile->Get("hCellTime");

  Int_t bin = hCellTime->GetXaxis()->FindBin(absId);
  TH1* hCell = hCellTime->ProjectionY(Form("hCellTime%i",absId),bin,bin);
  hCell->SetXTitle("Time, s");
  hCell->SetYTitle("Entries");
  hCell->SetTitle(Form("Cell %i time", absId));

  // draw spectrum
  TCanvas *c1 = new TCanvas(Form("hCellTime%i",absId), Form("hCellTime%i",absId), 400,400);
  gPad->SetLeftMargin(0.12);
  gPad->SetRightMargin(0.10);
  gPad->SetBottomMargin(0.12);
  gPad->SetLogy();
  hCell->Draw();

  c1->Update();
}


/* RUN AVERAGES AND RELATED FUNCTIONS
 *
 */

//_________________________________________________________________________
void DrawClusterAveragesPerRun(Int_t nruns, Int_t runNumbers[], Int_t ncellsMin = 1,
                               Double_t eclusMin = 0.3, Double_t eclusMax = -1,
                               TH2* hmap = NULL)
{
  // Draws cluster averages per run vs run index and number of events.
  // NOTE: the averages are "smoothed" a little due to a finite bin width.
  //
  // ncellsMin -- minimum number of cells in cluster (>= 1);
  // eclusMin,eclusMax -- minimum/maximum cluster energy cut
  //                      (eclusMax = -1 means infinity);
  // hmap -- dead/noisy cell map, which is used for acceptance calculation due
  //   to switched off detector parts. Acceptance is used to correct the average
  //   number of clusters per event.

  // names suffix
  TString s(Form("_NC%i_Emin=%.2fGeV",ncellsMin,eclusMin));
  if (eclusMax > 0) s += TString(Form("_Emax=%.2fGeV",eclusMax)).Data();
  if (hmap) s += "_corr4accept";
  char *suff = s.Data();

  if (eclusMax < 0) eclusMax = 1e+5;

  // supermodule region
  Int_t SM1 = 0;
  Int_t SM2 = 10;
  while (SM1 <= SM2 && !gFile->Get(Form("run%i_hNCellsInClusterSM%i",runNumbers[0],SM1)) ) SM1++;
  while (SM2 >= SM1 && !gFile->Get(Form("run%i_hNCellsInClusterSM%i",runNumbers[0],SM2)) ) SM2--;

  // initialize histograms
  hAvECluster = new TH1F(Form("hAvECluster%s",suff), "Average cluster energy", nruns,0,nruns);
  hAvECluster->SetXTitle("Run index");
  hAvECluster->SetYTitle("Energy, GeV");

  hAvNCluster = new TH1F(Form("hAvNCluster%s",suff), "Average number of clusters per event", nruns,0,nruns);
  hAvNCluster->SetXTitle("Run index");
  hAvNCluster->SetYTitle("Number of clusters");

  hAvNCellsInCluster = new TH1F(Form("hAvNCellsInCluster%s",suff), "Average number of cells in cluster", nruns,0,nruns);
  hAvNCellsInCluster->SetXTitle("Run index");
  hAvNCellsInCluster->SetYTitle("Number of cells");

  // initialize per SM histograms
  TH1* hAvEClusterSM[10];
  TH1* hAvNClusterSM[10];
  TH1* hAvNCellsInClusterSM[10];

  for (Int_t sm = SM1; sm <= SM2; sm++) {
    hAvEClusterSM[sm] = new TH1F(Form("hAvEClusterSM%i%s",sm,suff),"", nruns,0,nruns);
    hAvNClusterSM[sm] = new TH1F(Form("hAvNClusterSM%i%s",sm,suff),"", nruns,0,nruns);
    hAvNCellsInClusterSM[sm] = new TH1F(Form("hAvNCellsInClusterSM%i%s",sm,suff),"", nruns,0,nruns);
  }

  // fill all the histograms per run index
  for (Int_t ri = 0; ri < nruns; ri++)
  {
    Int_t nevents = GetNumberOfEvents(runNumbers[ri]);

    // number of switched off supermodules
    Int_t noSM = 0;

    Double_t Eclus_total = 0;  // total cluster energy
    Double_t Nclus_total = 0;  // total number of clusters
    Double_t Ncells_total = 0; // total number of cells

    // supermodule loop
    for (Int_t sm = SM1; sm <= SM2; sm++) {
      TH2* hNCellsInClusterSM = (TH2*) gFile->Get(Form("run%i_hNCellsInClusterSM%i",runNumbers[ri],sm));

      // the same as above, but per supermodule
      Double_t Eclus_totalSM = 0;
      Double_t Nclus_totalSM = 0;
      Double_t Ncells_totalSM = 0;

      // X axis -- cluster energy, Y axis -- number of cells
      for (Int_t x = 1; x <= hNCellsInClusterSM->GetNbinsX(); x++)
        for (Int_t y = 1+ncellsMin; y <= hNCellsInClusterSM->GetNbinsY(); y++) {//NOTE: bin 1 correspond to ncellsMin=0
          Double_t Eclus = hNCellsInClusterSM->GetXaxis()->GetBinCenter(x);
          Double_t Ncells = hNCellsInClusterSM->GetYaxis()->GetBinLowEdge(y);
          Double_t Nclus = hNCellsInClusterSM->GetBinContent(x,y);

          // cut on cluster energy
          if (Eclus < eclusMin || Eclus > eclusMax) continue;

          Eclus_totalSM += Eclus * Nclus;
          Nclus_totalSM += Nclus;
          Ncells_totalSM += Ncells * Nclus;
        }

        delete hNCellsInClusterSM;

      // correct for acceptance
      if (hmap) {
        Double_t accep = GetAcceptance(sm, hmap, ri);
        if (accep > 0) {
          Eclus_totalSM /= accep;
          Nclus_totalSM /= accep;
          Ncells_totalSM /= accep;
        }
        else noSM++;
      }

      Eclus_total += Eclus_totalSM;
      Nclus_total += Nclus_totalSM;
      Ncells_total += Ncells_totalSM;

      hAvNClusterSM[sm]->SetBinContent(ri+1, Nclus_totalSM/nevents);
      if (Nclus_totalSM > 0) hAvEClusterSM[sm]->SetBinContent(ri+1, Eclus_totalSM/Nclus_totalSM);
      if (Nclus_totalSM > 0) hAvNCellsInClusterSM[sm]->SetBinContent(ri+1, Ncells_totalSM/Nclus_totalSM);
    } // supermodule loop

    hAvNCluster->SetBinContent(ri+1, Nclus_total/nevents/(SM2-SM1+1-noSM));
    if (Nclus_total > 0) hAvECluster->SetBinContent(ri+1, Eclus_total/Nclus_total);
    if (Nclus_total > 0) hAvNCellsInCluster->SetBinContent(ri+1, Ncells_total/Nclus_total);
  } // run index loop


  /* Draw results vs run index
   */

  TCanvas *c1 = new TCanvas(Form("ClusterAveragesRuns%s",suff),
                            Form("ClusterAveragesRuns%s",suff), 999,333);
  c1->Divide(3,1);

  // average cluster energy
  c1->cd(1);
  gPad->SetLeftMargin(0.14);
  gPad->SetRightMargin(0.06);
  TLegend *leg = new TLegend(0.65,0.15,0.85,0.15+0.04*(SM2-SM1+1));

  hAvECluster->SetAxisRange(hAvECluster->GetMinimum()*0.5, hAvECluster->GetMaximum()*1.1,"Y");
  hAvECluster->SetTitleOffset(1.7,"Y");
  hAvECluster->SetLineWidth(2);
  hAvECluster->Draw();
  leg->AddEntry(hAvECluster, "All SM","l");
  for (Int_t sm = SM1; sm <= SM2; sm++) {
    hAvEClusterSM[sm]->SetLineColor(colorsSM[sm]);
    hAvEClusterSM[sm]->SetLineWidth(1);
    hAvEClusterSM[sm]->Draw("same");
    leg->AddEntry(hAvEClusterSM[sm], Form("SM%i",sm),"l");
  }
  hAvECluster->Draw("same"); // to top
  leg->Draw("same");

  // average number of clusters
  c1->cd(2);
  gPad->SetLeftMargin(0.14);
  gPad->SetRightMargin(0.06);
  leg = new TLegend(0.65,0.15,0.85,0.15+0.04*(SM2-SM1+1));

  hAvNCluster->SetAxisRange(0, hAvNCluster->GetMaximum()*1.3,"Y");
  hAvNCluster->SetTitleOffset(1.7,"Y");
  hAvNCluster->SetLineWidth(2);
  hAvNCluster->Draw();
  leg->AddEntry(hAvNCluster, Form("All SM/%i",SM2-SM1+1),"l");
  for (Int_t sm = SM1; sm <= SM2; sm++) {
    hAvNClusterSM[sm]->SetLineColor(colorsSM[sm]);
    hAvNClusterSM[sm]->SetLineWidth(1);
    hAvNClusterSM[sm]->Draw("same");
    leg->AddEntry(hAvNClusterSM[sm], Form("SM%i",sm),"l");
  }
  hAvNCluster->Draw("same"); // to top
  leg->Draw("same");

  // average number of cells in cluster
  c1->cd(3);
  gPad->SetLeftMargin(0.14);
  gPad->SetRightMargin(0.06);
  leg = new TLegend(0.65,0.15,0.85,0.15+0.04*(SM2-SM1+1));

  hAvNCellsInCluster->SetAxisRange(0, hAvNCellsInCluster->GetMaximum()*1.3,"Y");
  hAvNCellsInCluster->SetTitleOffset(1.7,"Y");
  hAvNCellsInCluster->SetLineWidth(2);
  hAvNCellsInCluster->Draw();
  leg->AddEntry(hAvNCellsInCluster, "All SM","l");
  for (Int_t sm = SM1; sm <= SM2; sm++) {
    hAvNCellsInClusterSM[sm]->SetLineColor(colorsSM[sm]);
    hAvNCellsInClusterSM[sm]->SetLineWidth(1);
    hAvNCellsInClusterSM[sm]->Draw("same");
    leg->AddEntry(hAvNCellsInClusterSM[sm], Form("SM%i",sm),"l");
  }
  hAvNCellsInCluster->Draw("same"); // to top
  leg->Draw("same");


  /* Draw the same vs number of events
   */

  TCanvas *c2 = new TCanvas(Form("ClusterAveragesEvents%s",suff),
                            Form("ClusterAveragesEvents%s",suff), 999,333);
  c2->Divide(3,1);

  // average cluster energy
  c2->cd(1);
  gPad->SetLeftMargin(0.14);
  gPad->SetRightMargin(0.08);
  leg = new TLegend(0.65,0.15,0.85,0.15+0.04*(SM2-SM1+1));

  TH1* hAvEClusterEvents = ConvertMapRuns2Events(nruns, runNumbers, hAvECluster);
  hAvEClusterEvents->Draw();
  leg->AddEntry(hAvEClusterEvents, "All SM","l");
  for (Int_t sm = SM1; sm <= SM2; sm++) {
    TH1* hAvEClusterSMEvents = ConvertMapRuns2Events(nruns, runNumbers, hAvEClusterSM[sm]);
    hAvEClusterSMEvents->Draw("same");
    leg->AddEntry(hAvEClusterSMEvents, Form("SM%i",sm),"l");
  }
  hAvEClusterEvents->Draw("same"); // to top
  leg->Draw("same");

  // average number of clusters
  c2->cd(2);
  gPad->SetLeftMargin(0.14);
  gPad->SetRightMargin(0.08);
  leg = new TLegend(0.65,0.15,0.85,0.15+0.04*(SM2-SM1+1));

  TH1* hAvNClusterEvents = ConvertMapRuns2Events(nruns, runNumbers, hAvNCluster);
  hAvNClusterEvents->Draw();
  leg->AddEntry(hAvNClusterEvents, Form("All SM/%i",SM2-SM1+1),"l");
  for (Int_t sm = SM1; sm <= SM2; sm++) {
    TH1* hAvNClusterSMEvents = ConvertMapRuns2Events(nruns, runNumbers, hAvNClusterSM[sm]);
    hAvNClusterSMEvents->Draw("same");
    leg->AddEntry(hAvNClusterSMEvents, Form("SM%i",sm),"l");
  }
  hAvNClusterEvents->Draw("same"); // to top
  leg->Draw("same");

  // average number of cells in cluster
  c2->cd(3);
  gPad->SetLeftMargin(0.14);
  gPad->SetRightMargin(0.08);
  leg = new TLegend(0.65,0.15,0.85,0.15+0.04*(SM2-SM1+1));

  TH1* hAvNCellsInClusterEvents = ConvertMapRuns2Events(nruns, runNumbers, hAvNCellsInCluster);
  hAvNCellsInClusterEvents->Draw();
  leg->AddEntry(hAvNCellsInClusterEvents, "All SM","l");
  for (Int_t sm = SM1; sm <= SM2; sm++) {
    TH1* hAvNCellsInClusterSMEvents = ConvertMapRuns2Events(nruns, runNumbers, hAvNCellsInClusterSM[sm]);
    hAvNCellsInClusterSMEvents->Draw("same");
    leg->AddEntry(hAvNCellsInClusterSMEvents, Form("SM%i",sm),"l");
  }
  hAvNCellsInClusterEvents->Draw("same"); // to top
  leg->Draw("same");


  c1->Update();
  c2->Update();
}

//_________________________________________________________________________
Double_t GetAcceptance(Int_t sm, TH2* hmap, Int_t ri)
{
  // Returns [#cells - #dead]/#cells for a supermodule.
  // hmap -- dead/noisy cell map;
  // ri -- run index.

  // guess number of cells per supermodule
  Int_t nSM = 1152; // EMCAL
  if (hmap->GetXaxis()->GetXmin() == 1) {// PHOS
    nSM = 3584;
    sm--; // starts from 1, convenient from 0
  }

  // count dead cells
  Int_t ndead = 0;
  for (Int_t k = 1; k <= nSM; k++)
    if (hmap->GetBinContent(nSM*sm + k, ri+1) < 0)
      ndead++;

  return ((Double_t) (nSM - ndead))/nSM;
}

//_________________________________________________________________________
void DrawPi0Slice(Int_t run, Int_t sm = -1)
{
  // Draw the pi0 peak;
  // run,sm -- run number and supermodule to take;
  // sm < 0 -- draw for whole detector.

  TH1* h = NULL;
  if (sm >= 0) {//particular supermodule
    h = (TH1*) gFile->Get(Form("run%i_hPi0MassSM%iSM%i",run,sm,sm));
    h->SetName(Form("hPi0SliceSM%i_run%i",sm,run));
    h->SetTitle(Form("#pi^{0} in SM%i, run %i, %.2fM events", sm, run, GetNumberOfEvents(run)/1e+6));
  }
  else {// whole detector
    for (Int_t sm1 = 0; sm1 < 10; sm1++)
      for (Int_t sm2 = sm1; sm2 < 10; sm2++) {
        TH1* one = (TH1*) gFile->Get(Form("run%i_hPi0MassSM%iSM%i",run,sm1,sm2));
        if (!one) continue;

        if (!h) h = one;
        else {
          h->Add(one);
          delete one;
        }
      }
    h->SetName(Form("hPi0Slice_run%i",run));
    h->SetTitle(Form("#pi^{0} in all SM, run %i, %.2fM events", run, GetNumberOfEvents(run)/1e+6));
  }

  h->SetXTitle("M_{#gamma#gamma}, GeV");
  h->SetYTitle("Entries");
  h->SetTitleOffset(1.7,"Y");

  TCanvas *c1;
  if (sm >= 0) c1 = new TCanvas(Form("hPi0SliceSM%i_run%i",sm,run),Form("hPi0SliceSM%i_run%i",sm,run), 400,400);
  else         c1 = new TCanvas(Form("hPi0Slice_run%i",run),Form("hPi0Slice_run%i",run), 400,400);

  gPad->SetLeftMargin(0.14);
  gPad->SetRightMargin(0.06);
  h->Draw();

  Double_t nraw, enraw, mass, emass, sigma, esigma;
  FitPi0(h, nraw, enraw, mass, emass, sigma, esigma);

  // draw background
  TF1* fitfun = h->GetFunction("fitfun");
  if (fitfun) {
    Double_t emin, emax;
    fitfun->GetRange(emin, emax);

    backgr = new TF1("mypol2", "[0] + [1]*(x-0.135) + [2]*(x-0.135)^2", emin, emax);
    backgr->SetLineColor(kBlue);
    backgr->SetLineWidth(2);
    backgr->SetLineStyle(3);
    backgr->SetParameters(fitfun->GetParameter(3), fitfun->GetParameter(4), fitfun->GetParameter(5));
    backgr->Draw("same");
  }

  c1->Update();
}

//_________________________________________________________________________
void DrawPi0Averages(Int_t nruns, Int_t runNumbers[], Bool_t samesm = kFALSE, TH2* hmap = NULL)
{
  // Draw average number of pi0s per event, pi0 mass position and pi0 width per run index.
  // Errors are also drawn.
  //
  // samesm -- take only pi0s for which gammas were is same SM;
  // hmap -- if not NULL, do simple (area law based) acceptance correction.
  //
  // TODO: PHOS needs pi0 between SMs rather than in one SM

  // suffix to names
  char *suff = TString(Form("%s%s", samesm ? "_sameSM":"", hmap ? "_corr4accep":"")).Data();

  // supermodule region
  Int_t SM1 = 0;
  Int_t SM2 = 10;
  while (SM1 <= SM2 && !gFile->Get(Form("run%i_hPi0MassSM%iSM%i",runNumbers[0],SM1,SM1)) ) SM1++;
  while (SM2 >= SM1 && !gFile->Get(Form("run%i_hPi0MassSM%iSM%i",runNumbers[0],SM2,SM2)) ) SM2--;

  // initialize histograms for the entire detector
  TH1* hPi0Num = new TH1F(Form("hPi0Num%s",suff),"Average number of #pi^{0}s per event", nruns,0,nruns);
  hPi0Num->SetXTitle("Run index");
  hPi0Num->SetYTitle("Number of #pi^{0}s");

  TH1* hPi0Mass = new TH1F(Form("hPi0Mass%s",suff),"#pi^{0} mass position", nruns,0,nruns);
  hPi0Mass->SetXTitle("Run index");
  hPi0Mass->SetYTitle("M_{#pi^{0}}, GeV");

  TH1* hPi0Sigma = new TH1F(Form("hPi0Sigma%s",suff),"#pi^{0} width", nruns,0,nruns);
  hPi0Sigma->SetXTitle("Run index");
  hPi0Sigma->SetYTitle("#sigma_{#pi^{0}}, GeV");

  // initialize histograms per SM
  TH1* hPi0NumSM[10];
  TH1* hPi0MassSM[10];
  TH1* hPi0SigmaSM[10];

  for (Int_t sm = SM1; sm <= SM2; sm++) {
    hPi0NumSM[sm] = new TH1F(Form("hPi0NumSM%i%s",sm,suff),"", nruns,0,nruns);
    hPi0MassSM[sm] = new TH1F(Form("hPi0MassSM%i%s",sm,suff),"", nruns,0,nruns);
    hPi0SigmaSM[sm] = new TH1F(Form("hPi0SigmaSM%i%s",sm,suff),"", nruns,0,nruns);
  }

  // run index loop
  for (Int_t ri = 0; ri < nruns; ri++)
  {
    fprintf(stderr, "\rDrawPi0Averages(): analysing run index %i/%i ...  ", ri, nruns-1);

    Int_t nevents = GetNumberOfEvents(runNumbers[ri]);

    // per SM histos
    for (Int_t sm = SM1; sm <= SM2; sm++) {
      TH1* h = (TH1*) gFile->Get(Form("run%i_hPi0MassSM%iSM%i",runNumbers[ri],sm,sm));

      // supermodule acceptance
      Double_t accep = 1.;
      if (hmap) accep = GetAcceptance(sm, hmap, ri);
      if (accep == 0) continue; // missing SM

      Double_t nraw, enraw, mass, emass, sigma, esigma;
      FitPi0(h, nraw, enraw, mass, emass, sigma, esigma);

      hPi0NumSM[sm]->SetBinContent(ri+1, nraw/nevents/accep);
      hPi0MassSM[sm]->SetBinContent(ri+1, mass);
      hPi0SigmaSM[sm]->SetBinContent(ri+1, sigma);

      hPi0NumSM[sm]->SetBinError(ri+1, enraw/nevents/accep);
      hPi0MassSM[sm]->SetBinError(ri+1, emass);
      hPi0SigmaSM[sm]->SetBinError(ri+1, esigma);

      delete h;
    } // supermodule loop


    /* fill for the entire detector
     */
    TH1* hsum = (TH1*) gFile->Get(Form("run%i_hPi0MassSM%iSM%i",runNumbers[ri],SM1,SM1));
    hsum->SetName("hSumTMP");

    // for acceptance correction
    Int_t noSM = 0;

    for (Int_t sm1 = SM1; sm1 <= SM2; sm1++)
      for (Int_t sm2 = sm1; sm2 <= SM2; sm2++) {
        if (sm1 == SM1 && sm2 == SM2) continue;
        if (samesm && sm1 != sm2) continue;

        TH1* h = (TH1*) gFile->Get(Form("run%i_hPi0MassSM%iSM%i",runNumbers[ri],sm1,sm2));

        // correct for SM acceptance
        if (hmap) {
          Double_t accep = GetAcceptance(sm1, hmap, ri);
          if (accep > 0) h->Scale(1./accep);
          else noSM++;
        }

        hsum->Add(h);
        delete h;
      }

    Double_t nraw, enraw, mass, emass, sigma, esigma;
    FitPi0(hsum, nraw, enraw, mass, emass, sigma, esigma);

    hPi0Num->SetBinContent(ri+1, nraw/nevents/(SM2-SM1+1-noSM));
    hPi0Mass->SetBinContent(ri+1, mass);
    hPi0Sigma->SetBinContent(ri+1, sigma);

    hPi0Num->SetBinError(ri+1, enraw/nevents/(SM2-SM1+1-noSM));
    hPi0Mass->SetBinError(ri+1, emass);
    hPi0Sigma->SetBinError(ri+1, esigma);

    delete hsum;
  } // run index loop

  fprintf(stderr, "\n");


  /* Draw results
   */

  // number of pi0s vs run index
  TCanvas *c1 = new TCanvas(Form("hPi0NumRuns%s",suff),Form("hPi0NumRuns%s",suff), 800,400);
  gPad->SetLeftMargin(0.08);
  gPad->SetRightMargin(0.06);
  gPad->SetTopMargin(0.12);
  TLegend *leg = new TLegend(0.75,0.15,0.95,0.15+0.04*(SM2-SM1+1));

  hPi0Num->SetAxisRange(0., hPi0Num->GetMaximum()*1.2, "Y");
  hPi0Num->SetTitleOffset(1.7, "Y");
  hPi0Num->SetLineWidth(1);
  hPi0Num->Draw();
  leg->AddEntry(hPi0Num, Form("All SM/%i",SM2-SM1+1),"l");
  for (Int_t sm = SM1; sm <= SM2; sm++) {
    hPi0NumSM[sm]->SetLineColor(colorsSM[sm]);
    hPi0NumSM[sm]->SetLineWidth(1);
    hPi0NumSM[sm]->Draw("same");
    leg->AddEntry(hPi0NumSM[sm], Form("SM%i",sm),"l");
  }
  hPi0Num->Draw("same"); // to the top
  hPi0Num->Draw("hist,same");
  leg->Draw("same");


  // number of pi0s vs event count
  TCanvas *c2 = new TCanvas(Form("hPi0NumEvents%s",suff),Form("hPi0NumEvents%s",suff), 800,400);
  gPad->SetLeftMargin(0.08);
  gPad->SetRightMargin(0.06);
  gPad->SetTopMargin(0.12);
  leg = new TLegend(0.75,0.15,0.92,0.15+0.04*(SM2-SM1+1));

  TH1* hPi0NumEvents = ConvertMapRuns2Events(nruns, runNumbers, hPi0Num);
  hPi0NumEvents->Draw();
  leg->AddEntry(hPi0NumEvents, Form("All SM/%i",SM2-SM1+1),"l");
  for (Int_t sm = SM1; sm <= SM2; sm++) {
    TH1* hPi0NumSMEvents = ConvertMapRuns2Events(nruns, runNumbers, hPi0NumSM[sm]);
    hPi0NumSMEvents->Draw("same");
    leg->AddEntry(hPi0NumSMEvents, Form("SM%i",sm),"l");
  }
  hPi0NumEvents->Draw("same"); // to the top
  hPi0NumEvents->Draw("hist,same");
  leg->Draw("same");


  // pi0 mass and width vs run index
  TCanvas *c3 = new TCanvas(Form("hPi0MassSigmaRuns%s",suff),Form("hPi0MassSigmaRuns%s",suff), 800,400);
  c3->Divide(2,1);

  c3->cd(1);
  gPad->SetLeftMargin(0.16);
  gPad->SetRightMargin(0.04);
  leg = new TLegend(0.75,0.15,0.95,0.15+0.04*(SM2-SM1+1));

  hPi0Mass->SetAxisRange(0.125, 0.145, "Y");
  hPi0Mass->SetTitleOffset(2.0, "Y");
  hPi0Mass->SetLineWidth(1);
  hPi0Mass->Draw();
  leg->AddEntry(hPi0Mass, "All SM","l");
  for (Int_t sm = SM1; sm <= SM2; sm++) {
    hPi0MassSM[sm]->SetLineColor(colorsSM[sm]);
    hPi0MassSM[sm]->SetLineWidth(1);
    hPi0MassSM[sm]->Draw("same");
    leg->AddEntry(hPi0MassSM[sm], Form("SM%i",sm),"l");
  }
  hPi0Mass->Draw("same"); // to the top
  hPi0Mass->Draw("hist,same");
  leg->Draw("same");

  c3->cd(2);
  gPad->SetLeftMargin(0.16);
  gPad->SetRightMargin(0.04);
  leg = new TLegend(0.75,0.15,0.95,0.15+0.04*(SM2-SM1+1));

  hPi0Sigma->SetAxisRange(0., hPi0Sigma->GetMaximum()*1.5, "Y");
  hPi0Sigma->SetTitleOffset(2.0, "Y");
  hPi0Sigma->SetLineWidth(1);
  hPi0Sigma->Draw();
  leg->AddEntry(hPi0Sigma, "All SM","l");
  for (Int_t sm = SM1; sm <= SM2; sm++) {
    hPi0SigmaSM[sm]->SetLineColor(colorsSM[sm]);
    hPi0SigmaSM[sm]->SetLineWidth(1);
    hPi0SigmaSM[sm]->Draw("same");
    leg->AddEntry(hPi0SigmaSM[sm], Form("SM%i",sm),"l");
  }
  hPi0Sigma->Draw("same"); // to the top
  hPi0Sigma->Draw("hist,same");
  leg->Draw("same");


  // pi0 mass and width vs number of events
  TCanvas *c4 = new TCanvas(Form("hPi0MassSigmaEvents%s",suff),Form("hPi0MassSigmaEvents%s",suff), 800,400);
  c4->Divide(2,1);

  c4->cd(1);
  gPad->SetLeftMargin(0.16);
  gPad->SetRightMargin(0.08);
  leg = new TLegend(0.75,0.15,0.91,0.15+0.04*(SM2-SM1+1));

  TH1* hPi0MassEvents = ConvertMapRuns2Events(nruns, runNumbers, hPi0Mass);
  hPi0MassEvents->Draw();
  leg->AddEntry(hPi0MassEvents, "All SM","l");
  for (Int_t sm = SM1; sm <= SM2; sm++) {
    TH1* hPi0MassSMEvents = ConvertMapRuns2Events(nruns, runNumbers, hPi0MassSM[sm]);
    hPi0MassSMEvents->Draw("same");
    leg->AddEntry(hPi0MassSMEvents, Form("SM%i",sm),"l");
  }
  hPi0MassEvents->Draw("same"); // to the top
  hPi0MassEvents->Draw("hist,same");
  leg->Draw("same");

  c4->cd(2);
  gPad->SetLeftMargin(0.16);
  gPad->SetRightMargin(0.08);
  leg = new TLegend(0.75,0.15,0.91,0.15+0.04*(SM2-SM1+1));

  TH1* hPi0SigmaEvents = ConvertMapRuns2Events(nruns, runNumbers, hPi0Sigma);
  hPi0SigmaEvents->Draw();
  leg->AddEntry(hPi0SigmaEvents, "All SM","l");
  for (Int_t sm = SM1; sm <= SM2; sm++) {
    TH1* hPi0SigmaSMEvents = ConvertMapRuns2Events(nruns, runNumbers, hPi0SigmaSM[sm]);
    hPi0SigmaSMEvents->Draw("same");
    leg->AddEntry(hPi0SigmaSMEvents, Form("SM%i",sm),"l");
  }
  hPi0SigmaEvents->Draw("same"); // to the top
  hPi0SigmaEvents->Draw("hist,same");
  leg->Draw("same");


  c1->Update();
  c2->Update();
  c3->Update();
  c4->Update();
}

//_________________________________________________________________________
void DrawPi0Distributions(char *suff, Int_t nbins = 100)
{
  // Draw distributions for
  //    1) average number of pi0s per event;
  //    2) pi0 mass position;
  //    3) pi0 width.
  //
  // Must be called after DrawPi0Averages() because it
  // searches for the corresponding histograms by name.
  //
  // suff -- histograms suffix;
  // nbins -- number of bins in distributions.

  TCanvas *c1 = new TCanvas(Form("Pi0Distributions%s",suff),Form("Pi0Distributions%s",suff), 999,333);
  c1->Divide(3,1);

  // number of pi0s
  c1->cd(1)->SetLogy();
  gPad->SetLeftMargin(0.16);
  gPad->SetRightMargin(0.04);
  TH1* hPi0Num = (TH1*) gROOT->FindObject(Form("hPi0Num%s",suff));
  MakeDistribution(hPi0Num,nbins)->Draw();

  // pi0 mass
  c1->cd(2)->SetLogy();
  gPad->SetLeftMargin(0.16);
  gPad->SetRightMargin(0.04);
  TH1* hPi0Mass = (TH1*) gROOT->FindObject(Form("hPi0Mass%s",suff));
  MakeDistribution(hPi0Mass,nbins)->Draw();

  // pi0 width
  c1->cd(3)->SetLogy();
  gPad->SetLeftMargin(0.16);
  gPad->SetRightMargin(0.04);
  TH1* hPi0Sigma = (TH1*) gROOT->FindObject(Form("hPi0Sigma%s",suff));
  MakeDistribution(hPi0Sigma,nbins)->Draw();

  c1->Update();
}

//_________________________________________________________________________
TH1* MakeDistribution(TH1* inhisto, Int_t nbins)
{
  // Returns distribution for the input histogram.
  //
  // inhisto -- input histogram;
  // nbins -- number of bins in distribution.

  // initialize distribution; 1.01 -- to see the last bin
  TH1* distr = new TH1F(Form("%sDistr",inhisto->GetName()),"",
                        nbins, inhisto->GetMinimum(),inhisto->GetMaximum()*1.01);
  distr->SetXTitle(inhisto->GetYaxis()->GetTitle());
  distr->SetYTitle("Number of runs");

  // fill distribution
  for (Int_t i = 1; i <= inhisto->GetNbinsX(); i++)
    distr->Fill(inhisto->GetBinContent(i));

  return distr;
}

//_________________________________________________________________________
void FitPi0(TH1* h, Double_t &nraw, Double_t &enraw,
            Double_t &mass, Double_t &emass,
            Double_t &sigma, Double_t &esigma,
            Double_t emin = 0.05, Double_t emax = 0.3, Int_t rebin = 1)
{
  // Fits the pi0 peak with crystal ball + pol2,
  // fills number of pi0s, mass, width and their errors.

  nraw = enraw = 0;
  mass = emass = 0;
  sigma = esigma = 0;

  if (h->GetEntries() == 0) return NULL;

  if (rebin > 1) h->Rebin(rebin);

  // crystal ball parameters (fixed by hand for EMCAL); TODO: PHOS parameters?
  Double_t alpha = 1.1;  // alpha >= 0
  Double_t n = 2.;       // n > 1

  // CB tail parameters
  Double_t a = pow((n/alpha), n) * TMath::Exp(-alpha*alpha/2.);
  Double_t b = n/alpha - alpha;

  // integral value under crystal ball with amplitude = 1, sigma = 1
  // (will be sqrt(2pi) at alpha = infinity)
  Double_t nraw11 = a * pow(b+alpha, 1.-n)/(n-1.) + TMath::Sqrt(TMath::Pi()/2.) * TMath::Erfc(-alpha/TMath::Sqrt(2.));

  // signal (crystal ball);
  new TF1("cball", Form("(x-[1])/[2] > -%f ?                        \
                           [0]*exp(-(x-[1])*(x-[1])/(2*[2]*[2]))    \
                         : [0]*%f*(%f-(x-[1])/[2])^(-%f)", alpha, a, b, n));

  // background
  new TF1("mypol2", "[0] + [1]*(x-0.135) + [2]*(x-0.135)^2", emin, emax);

  // signal + background
  TF1 *fitfun = new TF1("fitfun", "cball + mypol2", emin, emax);
  fitfun->SetParNames("A", "M", "#sigma", "a_{0}", "a_{1}", "a_{2}");
  fitfun->SetLineColor(kRed);
  fitfun->SetLineWidth(2);

  // make a preliminary fit to estimate parameters
  TF1* ff = new TF1("fastfit", "gaus(0) + [3]");
  ff->SetParLimits(0, 5., h->GetMaximum()*1.5);
  ff->SetParLimits(1, 0.1, 0.2);
  ff->SetParLimits(2, 0.005,0.030);
  ff->SetParameters(h->GetMaximum()/3., 0.135, 0.010, 0.);
  h->Fit(ff, "0QEM", "", 0.105, 0.165);

  fitfun->SetParameters(ff->GetParameter(0), ff->GetParameter(1), ff->GetParameter(2), ff->GetParameter(3));
  h->Fit(fitfun,"QLEMR", "");

  // calculate pi0 values
  mass = fitfun->GetParameter(1);
  emass = fitfun->GetParError(1);

  sigma = fitfun->GetParameter(2);
  esigma = fitfun->GetParError(2);

  Double_t A = fitfun->GetParameter(0);
  Double_t eA = fitfun->GetParError(0);

  nraw = nraw11 * A * sigma / h->GetBinWidth(1);
  enraw = nraw * (eA/A + esigma/sigma);
}


/* COMMON FUNCTIONS FOR RUN NUMBERS EXTRACTION, VISUALIZATION AND FILTERING.
 *
 * Input: histogram hNEventsProcessedPerRun which is taken from gFile.
 */

//_________________________________________________________________________
void GetRunNumbers(Int_t &nruns, Int_t runNumbers[])
{
  // Fill runNumbers array with run numbers according to hNEventsProcessedPerRun
  // histogram: actually analysed runs have positive bin content.

  TH1* hNEventsProcessedPerRun = (TH1*) gFile->Get("hNEventsProcessedPerRun");

  // check underflow/overflow
  if (hNEventsProcessedPerRun->GetBinContent(0) > 0.5)
    Warning("GetRunNumbers", "some run numbers are in underflow; they will be absent in the list of runs");
  if (hNEventsProcessedPerRun->GetBinContent(hNEventsProcessedPerRun->GetNbinsX()+1) > 0.5)
    Warning("GetRunNumbers", "some run numbers are in overflow; they will be absent in the list of runs");

  nruns = 0;

  for (Int_t i = 1; i <= hNEventsProcessedPerRun->GetNbinsX(); i++)
    if (hNEventsProcessedPerRun->GetBinContent(i) > 0.5) {
      runNumbers[nruns] = hNEventsProcessedPerRun->GetBinLowEdge(i);
      nruns++;
    }
}

//_________________________________________________________________________
Int_t GetNumberOfEvents(Int_t run)
{
  // Return number of events in run;
  // run -- run number.

  TH1* hNEventsProcessedPerRun = (TH1*) gFile->Get("hNEventsProcessedPerRun");

  // round the number of events to avoid precision surprizes
  return TMath::Nint( hNEventsProcessedPerRun->GetBinContent(hNEventsProcessedPerRun->FindBin(run)) );
}

//_________________________________________________________________________
Long64_t GetTotalNumberOfEvents(Int_t nruns, Int_t runNumbers[])
{
  // Return total number of events in all runs

  Long64_t ntotal = 0;

  for (Int_t i = 0; i < nruns; i++)
    ntotal += GetNumberOfEvents(runNumbers[i]);

  return ntotal;
}

//_________________________________________________________________________
void DrawRunsDistribution(Int_t nruns, Int_t runNumbers[], Int_t dnbins = 100)
{
  // Draw events and events distribution;
  // dnbins -- number of bins in distribution.

  // initialize run index histogram ...
  TH1* hNEventsPerRunIndex = new TH1F("hNEventsPerRunIndex", "Number of processed events per run index", nruns,0,nruns);
  hNEventsPerRunIndex->SetXTitle("Run index");
  hNEventsPerRunIndex->SetYTitle("Number of events");

  // ... and fill it
  for (Int_t i = 0; i < nruns; i++)
    hNEventsPerRunIndex->SetBinContent(i+1, GetNumberOfEvents(runNumbers[i]));

  // initialize distribution; 1.01 - to see the last bin
  TH1* distrib = new TH1F("hNEventsPerRunIndexDistr", "", dnbins, 0, hNEventsPerRunIndex->GetMaximum()*1.01);
  distrib->SetXTitle("Number of events");
  distrib->SetYTitle("Number of runs");

  // fill distribution
  for (Int_t i = 1; i <= nruns; i++)
    distrib->Fill(hNEventsPerRunIndex->GetBinContent(i));

  // draw histogram + distribution
  TCanvas *c1 = new TCanvas("hNEventsPerRunIndex","hNEventsPerRunIndex", 800,400);
  c1->Divide(2,1);

  c1->cd(1);
  gPad->SetLeftMargin(0.12);
  gPad->SetRightMargin(0.08);
  gPad->SetTopMargin(0.12);
  hNEventsPerRunIndex->SetTitleOffset(1.7,"Y");
  hNEventsPerRunIndex->Draw();

  c1->cd(2);
  gPad->SetLeftMargin(0.12);
  gPad->SetRightMargin(0.08);
  distrib->Draw();

  c1->Update();
}

//_________________________________________________________________________
void ExcludeSmallRuns(Int_t &nruns, Int_t runNumbers[], Int_t nEventsMin = 100e+3)
{
  // Exclude runs with number of events < nEventsMin

  printf("Excluding runs (< %.0fk events):", nEventsMin/1000.);

  for (Int_t i = 0; i < nruns; i++)
    if (GetNumberOfEvents(runNumbers[i]) < nEventsMin) {
      printf(" %i", runNumbers[i]);
      nruns--;
      runNumbers[i] = runNumbers[nruns];
      i--;
    }

  printf("\n");

  SortArray(nruns, runNumbers);
}

//_________________________________________________________________________
void ExcludeRunNumbers(Int_t &nruns, Int_t runNumbers[], Int_t nexcl, Int_t runs2Exclude[])
{
  // Exclude particular runs.
  //
  // nexcl -- number of runs in runs2Exclude[];
  // runs2Exclude -- array with run numbers to exclude.

  for (Int_t i = 0; i < nruns; i++)
    for (Int_t e = 0; e < nexcl; e++)
      if (runNumbers[i] == runs2Exclude[e]) {
        Printf("Excluding run: %i", runs2Exclude[e]);
        nruns--;
        runNumbers[i] = runNumbers[nruns];
        i--;
        break;
      }

  SortArray(nruns, runNumbers);
}

//_________________________________________________________________________
void SortArray(const Int_t nruns, Int_t runNumbers[])
{
  // Sort an array;
  // used for runNumbers array sorting.

  Int_t indices[nruns];
  Int_t runNumbers_unsort[nruns];

  for (Int_t i = 0; i < nruns; i++)
    runNumbers_unsort[i] = runNumbers[i];

  TMath::Sort(nruns, runNumbers_unsort, indices, kFALSE);

  for (Int_t i = 0; i < nruns; i++)
    runNumbers[i] = runNumbers_unsort[indices[i]];
}

void PrintRunNumbers(Int_t nruns, Int_t runNumbers[])
{
  // Print a table run index / run number / number of events.

  Printf("");
  Printf("| index | run number |  nevents  |");
  Printf("|-------|------------|-----------|");

  for (Int_t i = 0; i < nruns; i++)
    Printf("|  %-4i |  %-9i |  %-8i |", i, runNumbers[i], GetNumberOfEvents(runNumbers[i]));

  Printf("| Events in total:    %-10lli |\n", GetTotalNumberOfEvents(nruns, runNumbers));
}
 getCellsRunsQA.C:1
 getCellsRunsQA.C:2
 getCellsRunsQA.C:3
 getCellsRunsQA.C:4
 getCellsRunsQA.C:5
 getCellsRunsQA.C:6
 getCellsRunsQA.C:7
 getCellsRunsQA.C:8
 getCellsRunsQA.C:9
 getCellsRunsQA.C:10
 getCellsRunsQA.C:11
 getCellsRunsQA.C:12
 getCellsRunsQA.C:13
 getCellsRunsQA.C:14
 getCellsRunsQA.C:15
 getCellsRunsQA.C:16
 getCellsRunsQA.C:17
 getCellsRunsQA.C:18
 getCellsRunsQA.C:19
 getCellsRunsQA.C:20
 getCellsRunsQA.C:21
 getCellsRunsQA.C:22
 getCellsRunsQA.C:23
 getCellsRunsQA.C:24
 getCellsRunsQA.C:25
 getCellsRunsQA.C:26
 getCellsRunsQA.C:27
 getCellsRunsQA.C:28
 getCellsRunsQA.C:29
 getCellsRunsQA.C:30
 getCellsRunsQA.C:31
 getCellsRunsQA.C:32
 getCellsRunsQA.C:33
 getCellsRunsQA.C:34
 getCellsRunsQA.C:35
 getCellsRunsQA.C:36
 getCellsRunsQA.C:37
 getCellsRunsQA.C:38
 getCellsRunsQA.C:39
 getCellsRunsQA.C:40
 getCellsRunsQA.C:41
 getCellsRunsQA.C:42
 getCellsRunsQA.C:43
 getCellsRunsQA.C:44
 getCellsRunsQA.C:45
 getCellsRunsQA.C:46
 getCellsRunsQA.C:47
 getCellsRunsQA.C:48
 getCellsRunsQA.C:49
 getCellsRunsQA.C:50
 getCellsRunsQA.C:51
 getCellsRunsQA.C:52
 getCellsRunsQA.C:53
 getCellsRunsQA.C:54
 getCellsRunsQA.C:55
 getCellsRunsQA.C:56
 getCellsRunsQA.C:57
 getCellsRunsQA.C:58
 getCellsRunsQA.C:59
 getCellsRunsQA.C:60
 getCellsRunsQA.C:61
 getCellsRunsQA.C:62
 getCellsRunsQA.C:63
 getCellsRunsQA.C:64
 getCellsRunsQA.C:65
 getCellsRunsQA.C:66
 getCellsRunsQA.C:67
 getCellsRunsQA.C:68
 getCellsRunsQA.C:69
 getCellsRunsQA.C:70
 getCellsRunsQA.C:71
 getCellsRunsQA.C:72
 getCellsRunsQA.C:73
 getCellsRunsQA.C:74
 getCellsRunsQA.C:75
 getCellsRunsQA.C:76
 getCellsRunsQA.C:77
 getCellsRunsQA.C:78
 getCellsRunsQA.C:79
 getCellsRunsQA.C:80
 getCellsRunsQA.C:81
 getCellsRunsQA.C:82
 getCellsRunsQA.C:83
 getCellsRunsQA.C:84
 getCellsRunsQA.C:85
 getCellsRunsQA.C:86
 getCellsRunsQA.C:87
 getCellsRunsQA.C:88
 getCellsRunsQA.C:89
 getCellsRunsQA.C:90
 getCellsRunsQA.C:91
 getCellsRunsQA.C:92
 getCellsRunsQA.C:93
 getCellsRunsQA.C:94
 getCellsRunsQA.C:95
 getCellsRunsQA.C:96
 getCellsRunsQA.C:97
 getCellsRunsQA.C:98
 getCellsRunsQA.C:99
 getCellsRunsQA.C:100
 getCellsRunsQA.C:101
 getCellsRunsQA.C:102
 getCellsRunsQA.C:103
 getCellsRunsQA.C:104
 getCellsRunsQA.C:105
 getCellsRunsQA.C:106
 getCellsRunsQA.C:107
 getCellsRunsQA.C:108
 getCellsRunsQA.C:109
 getCellsRunsQA.C:110
 getCellsRunsQA.C:111
 getCellsRunsQA.C:112
 getCellsRunsQA.C:113
 getCellsRunsQA.C:114
 getCellsRunsQA.C:115
 getCellsRunsQA.C:116
 getCellsRunsQA.C:117
 getCellsRunsQA.C:118
 getCellsRunsQA.C:119
 getCellsRunsQA.C:120
 getCellsRunsQA.C:121
 getCellsRunsQA.C:122
 getCellsRunsQA.C:123
 getCellsRunsQA.C:124
 getCellsRunsQA.C:125
 getCellsRunsQA.C:126
 getCellsRunsQA.C:127
 getCellsRunsQA.C:128
 getCellsRunsQA.C:129
 getCellsRunsQA.C:130
 getCellsRunsQA.C:131
 getCellsRunsQA.C:132
 getCellsRunsQA.C:133
 getCellsRunsQA.C:134
 getCellsRunsQA.C:135
 getCellsRunsQA.C:136
 getCellsRunsQA.C:137
 getCellsRunsQA.C:138
 getCellsRunsQA.C:139
 getCellsRunsQA.C:140
 getCellsRunsQA.C:141
 getCellsRunsQA.C:142
 getCellsRunsQA.C:143
 getCellsRunsQA.C:144
 getCellsRunsQA.C:145
 getCellsRunsQA.C:146
 getCellsRunsQA.C:147
 getCellsRunsQA.C:148
 getCellsRunsQA.C:149
 getCellsRunsQA.C:150
 getCellsRunsQA.C:151
 getCellsRunsQA.C:152
 getCellsRunsQA.C:153
 getCellsRunsQA.C:154
 getCellsRunsQA.C:155
 getCellsRunsQA.C:156
 getCellsRunsQA.C:157
 getCellsRunsQA.C:158
 getCellsRunsQA.C:159
 getCellsRunsQA.C:160
 getCellsRunsQA.C:161
 getCellsRunsQA.C:162
 getCellsRunsQA.C:163
 getCellsRunsQA.C:164
 getCellsRunsQA.C:165
 getCellsRunsQA.C:166
 getCellsRunsQA.C:167
 getCellsRunsQA.C:168
 getCellsRunsQA.C:169
 getCellsRunsQA.C:170
 getCellsRunsQA.C:171
 getCellsRunsQA.C:172
 getCellsRunsQA.C:173
 getCellsRunsQA.C:174
 getCellsRunsQA.C:175
 getCellsRunsQA.C:176
 getCellsRunsQA.C:177
 getCellsRunsQA.C:178
 getCellsRunsQA.C:179
 getCellsRunsQA.C:180
 getCellsRunsQA.C:181
 getCellsRunsQA.C:182
 getCellsRunsQA.C:183
 getCellsRunsQA.C:184
 getCellsRunsQA.C:185
 getCellsRunsQA.C:186
 getCellsRunsQA.C:187
 getCellsRunsQA.C:188
 getCellsRunsQA.C:189
 getCellsRunsQA.C:190
 getCellsRunsQA.C:191
 getCellsRunsQA.C:192
 getCellsRunsQA.C:193
 getCellsRunsQA.C:194
 getCellsRunsQA.C:195
 getCellsRunsQA.C:196
 getCellsRunsQA.C:197
 getCellsRunsQA.C:198
 getCellsRunsQA.C:199
 getCellsRunsQA.C:200
 getCellsRunsQA.C:201
 getCellsRunsQA.C:202
 getCellsRunsQA.C:203
 getCellsRunsQA.C:204
 getCellsRunsQA.C:205
 getCellsRunsQA.C:206
 getCellsRunsQA.C:207
 getCellsRunsQA.C:208
 getCellsRunsQA.C:209
 getCellsRunsQA.C:210
 getCellsRunsQA.C:211
 getCellsRunsQA.C:212
 getCellsRunsQA.C:213
 getCellsRunsQA.C:214
 getCellsRunsQA.C:215
 getCellsRunsQA.C:216
 getCellsRunsQA.C:217
 getCellsRunsQA.C:218
 getCellsRunsQA.C:219
 getCellsRunsQA.C:220
 getCellsRunsQA.C:221
 getCellsRunsQA.C:222
 getCellsRunsQA.C:223
 getCellsRunsQA.C:224
 getCellsRunsQA.C:225
 getCellsRunsQA.C:226
 getCellsRunsQA.C:227
 getCellsRunsQA.C:228
 getCellsRunsQA.C:229
 getCellsRunsQA.C:230
 getCellsRunsQA.C:231
 getCellsRunsQA.C:232
 getCellsRunsQA.C:233
 getCellsRunsQA.C:234
 getCellsRunsQA.C:235
 getCellsRunsQA.C:236
 getCellsRunsQA.C:237
 getCellsRunsQA.C:238
 getCellsRunsQA.C:239
 getCellsRunsQA.C:240
 getCellsRunsQA.C:241
 getCellsRunsQA.C:242
 getCellsRunsQA.C:243
 getCellsRunsQA.C:244
 getCellsRunsQA.C:245
 getCellsRunsQA.C:246
 getCellsRunsQA.C:247
 getCellsRunsQA.C:248
 getCellsRunsQA.C:249
 getCellsRunsQA.C:250
 getCellsRunsQA.C:251
 getCellsRunsQA.C:252
 getCellsRunsQA.C:253
 getCellsRunsQA.C:254
 getCellsRunsQA.C:255
 getCellsRunsQA.C:256
 getCellsRunsQA.C:257
 getCellsRunsQA.C:258
 getCellsRunsQA.C:259
 getCellsRunsQA.C:260
 getCellsRunsQA.C:261
 getCellsRunsQA.C:262
 getCellsRunsQA.C:263
 getCellsRunsQA.C:264
 getCellsRunsQA.C:265
 getCellsRunsQA.C:266
 getCellsRunsQA.C:267
 getCellsRunsQA.C:268
 getCellsRunsQA.C:269
 getCellsRunsQA.C:270
 getCellsRunsQA.C:271
 getCellsRunsQA.C:272
 getCellsRunsQA.C:273
 getCellsRunsQA.C:274
 getCellsRunsQA.C:275
 getCellsRunsQA.C:276
 getCellsRunsQA.C:277
 getCellsRunsQA.C:278
 getCellsRunsQA.C:279
 getCellsRunsQA.C:280
 getCellsRunsQA.C:281
 getCellsRunsQA.C:282
 getCellsRunsQA.C:283
 getCellsRunsQA.C:284
 getCellsRunsQA.C:285
 getCellsRunsQA.C:286
 getCellsRunsQA.C:287
 getCellsRunsQA.C:288
 getCellsRunsQA.C:289
 getCellsRunsQA.C:290
 getCellsRunsQA.C:291
 getCellsRunsQA.C:292
 getCellsRunsQA.C:293
 getCellsRunsQA.C:294
 getCellsRunsQA.C:295
 getCellsRunsQA.C:296
 getCellsRunsQA.C:297
 getCellsRunsQA.C:298
 getCellsRunsQA.C:299
 getCellsRunsQA.C:300
 getCellsRunsQA.C:301
 getCellsRunsQA.C:302
 getCellsRunsQA.C:303
 getCellsRunsQA.C:304
 getCellsRunsQA.C:305
 getCellsRunsQA.C:306
 getCellsRunsQA.C:307
 getCellsRunsQA.C:308
 getCellsRunsQA.C:309
 getCellsRunsQA.C:310
 getCellsRunsQA.C:311
 getCellsRunsQA.C:312
 getCellsRunsQA.C:313
 getCellsRunsQA.C:314
 getCellsRunsQA.C:315
 getCellsRunsQA.C:316
 getCellsRunsQA.C:317
 getCellsRunsQA.C:318
 getCellsRunsQA.C:319
 getCellsRunsQA.C:320
 getCellsRunsQA.C:321
 getCellsRunsQA.C:322
 getCellsRunsQA.C:323
 getCellsRunsQA.C:324
 getCellsRunsQA.C:325
 getCellsRunsQA.C:326
 getCellsRunsQA.C:327
 getCellsRunsQA.C:328
 getCellsRunsQA.C:329
 getCellsRunsQA.C:330
 getCellsRunsQA.C:331
 getCellsRunsQA.C:332
 getCellsRunsQA.C:333
 getCellsRunsQA.C:334
 getCellsRunsQA.C:335
 getCellsRunsQA.C:336
 getCellsRunsQA.C:337
 getCellsRunsQA.C:338
 getCellsRunsQA.C:339
 getCellsRunsQA.C:340
 getCellsRunsQA.C:341
 getCellsRunsQA.C:342
 getCellsRunsQA.C:343
 getCellsRunsQA.C:344
 getCellsRunsQA.C:345
 getCellsRunsQA.C:346
 getCellsRunsQA.C:347
 getCellsRunsQA.C:348
 getCellsRunsQA.C:349
 getCellsRunsQA.C:350
 getCellsRunsQA.C:351
 getCellsRunsQA.C:352
 getCellsRunsQA.C:353
 getCellsRunsQA.C:354
 getCellsRunsQA.C:355
 getCellsRunsQA.C:356
 getCellsRunsQA.C:357
 getCellsRunsQA.C:358
 getCellsRunsQA.C:359
 getCellsRunsQA.C:360
 getCellsRunsQA.C:361
 getCellsRunsQA.C:362
 getCellsRunsQA.C:363
 getCellsRunsQA.C:364
 getCellsRunsQA.C:365
 getCellsRunsQA.C:366
 getCellsRunsQA.C:367
 getCellsRunsQA.C:368
 getCellsRunsQA.C:369
 getCellsRunsQA.C:370
 getCellsRunsQA.C:371
 getCellsRunsQA.C:372
 getCellsRunsQA.C:373
 getCellsRunsQA.C:374
 getCellsRunsQA.C:375
 getCellsRunsQA.C:376
 getCellsRunsQA.C:377
 getCellsRunsQA.C:378
 getCellsRunsQA.C:379
 getCellsRunsQA.C:380
 getCellsRunsQA.C:381
 getCellsRunsQA.C:382
 getCellsRunsQA.C:383
 getCellsRunsQA.C:384
 getCellsRunsQA.C:385
 getCellsRunsQA.C:386
 getCellsRunsQA.C:387
 getCellsRunsQA.C:388
 getCellsRunsQA.C:389
 getCellsRunsQA.C:390
 getCellsRunsQA.C:391
 getCellsRunsQA.C:392
 getCellsRunsQA.C:393
 getCellsRunsQA.C:394
 getCellsRunsQA.C:395
 getCellsRunsQA.C:396
 getCellsRunsQA.C:397
 getCellsRunsQA.C:398
 getCellsRunsQA.C:399
 getCellsRunsQA.C:400
 getCellsRunsQA.C:401
 getCellsRunsQA.C:402
 getCellsRunsQA.C:403
 getCellsRunsQA.C:404
 getCellsRunsQA.C:405
 getCellsRunsQA.C:406
 getCellsRunsQA.C:407
 getCellsRunsQA.C:408
 getCellsRunsQA.C:409
 getCellsRunsQA.C:410
 getCellsRunsQA.C:411
 getCellsRunsQA.C:412
 getCellsRunsQA.C:413
 getCellsRunsQA.C:414
 getCellsRunsQA.C:415
 getCellsRunsQA.C:416
 getCellsRunsQA.C:417
 getCellsRunsQA.C:418
 getCellsRunsQA.C:419
 getCellsRunsQA.C:420
 getCellsRunsQA.C:421
 getCellsRunsQA.C:422
 getCellsRunsQA.C:423
 getCellsRunsQA.C:424
 getCellsRunsQA.C:425
 getCellsRunsQA.C:426
 getCellsRunsQA.C:427
 getCellsRunsQA.C:428
 getCellsRunsQA.C:429
 getCellsRunsQA.C:430
 getCellsRunsQA.C:431
 getCellsRunsQA.C:432
 getCellsRunsQA.C:433
 getCellsRunsQA.C:434
 getCellsRunsQA.C:435
 getCellsRunsQA.C:436
 getCellsRunsQA.C:437
 getCellsRunsQA.C:438
 getCellsRunsQA.C:439
 getCellsRunsQA.C:440
 getCellsRunsQA.C:441
 getCellsRunsQA.C:442
 getCellsRunsQA.C:443
 getCellsRunsQA.C:444
 getCellsRunsQA.C:445
 getCellsRunsQA.C:446
 getCellsRunsQA.C:447
 getCellsRunsQA.C:448
 getCellsRunsQA.C:449
 getCellsRunsQA.C:450
 getCellsRunsQA.C:451
 getCellsRunsQA.C:452
 getCellsRunsQA.C:453
 getCellsRunsQA.C:454
 getCellsRunsQA.C:455
 getCellsRunsQA.C:456
 getCellsRunsQA.C:457
 getCellsRunsQA.C:458
 getCellsRunsQA.C:459
 getCellsRunsQA.C:460
 getCellsRunsQA.C:461
 getCellsRunsQA.C:462
 getCellsRunsQA.C:463
 getCellsRunsQA.C:464
 getCellsRunsQA.C:465
 getCellsRunsQA.C:466
 getCellsRunsQA.C:467
 getCellsRunsQA.C:468
 getCellsRunsQA.C:469
 getCellsRunsQA.C:470
 getCellsRunsQA.C:471
 getCellsRunsQA.C:472
 getCellsRunsQA.C:473
 getCellsRunsQA.C:474
 getCellsRunsQA.C:475
 getCellsRunsQA.C:476
 getCellsRunsQA.C:477
 getCellsRunsQA.C:478
 getCellsRunsQA.C:479
 getCellsRunsQA.C:480
 getCellsRunsQA.C:481
 getCellsRunsQA.C:482
 getCellsRunsQA.C:483
 getCellsRunsQA.C:484
 getCellsRunsQA.C:485
 getCellsRunsQA.C:486
 getCellsRunsQA.C:487
 getCellsRunsQA.C:488
 getCellsRunsQA.C:489
 getCellsRunsQA.C:490
 getCellsRunsQA.C:491
 getCellsRunsQA.C:492
 getCellsRunsQA.C:493
 getCellsRunsQA.C:494
 getCellsRunsQA.C:495
 getCellsRunsQA.C:496
 getCellsRunsQA.C:497
 getCellsRunsQA.C:498
 getCellsRunsQA.C:499
 getCellsRunsQA.C:500
 getCellsRunsQA.C:501
 getCellsRunsQA.C:502
 getCellsRunsQA.C:503
 getCellsRunsQA.C:504
 getCellsRunsQA.C:505
 getCellsRunsQA.C:506
 getCellsRunsQA.C:507
 getCellsRunsQA.C:508
 getCellsRunsQA.C:509
 getCellsRunsQA.C:510
 getCellsRunsQA.C:511
 getCellsRunsQA.C:512
 getCellsRunsQA.C:513
 getCellsRunsQA.C:514
 getCellsRunsQA.C:515
 getCellsRunsQA.C:516
 getCellsRunsQA.C:517
 getCellsRunsQA.C:518
 getCellsRunsQA.C:519
 getCellsRunsQA.C:520
 getCellsRunsQA.C:521
 getCellsRunsQA.C:522
 getCellsRunsQA.C:523
 getCellsRunsQA.C:524
 getCellsRunsQA.C:525
 getCellsRunsQA.C:526
 getCellsRunsQA.C:527
 getCellsRunsQA.C:528
 getCellsRunsQA.C:529
 getCellsRunsQA.C:530
 getCellsRunsQA.C:531
 getCellsRunsQA.C:532
 getCellsRunsQA.C:533
 getCellsRunsQA.C:534
 getCellsRunsQA.C:535
 getCellsRunsQA.C:536
 getCellsRunsQA.C:537
 getCellsRunsQA.C:538
 getCellsRunsQA.C:539
 getCellsRunsQA.C:540
 getCellsRunsQA.C:541
 getCellsRunsQA.C:542
 getCellsRunsQA.C:543
 getCellsRunsQA.C:544
 getCellsRunsQA.C:545
 getCellsRunsQA.C:546
 getCellsRunsQA.C:547
 getCellsRunsQA.C:548
 getCellsRunsQA.C:549
 getCellsRunsQA.C:550
 getCellsRunsQA.C:551
 getCellsRunsQA.C:552
 getCellsRunsQA.C:553
 getCellsRunsQA.C:554
 getCellsRunsQA.C:555
 getCellsRunsQA.C:556
 getCellsRunsQA.C:557
 getCellsRunsQA.C:558
 getCellsRunsQA.C:559
 getCellsRunsQA.C:560
 getCellsRunsQA.C:561
 getCellsRunsQA.C:562
 getCellsRunsQA.C:563
 getCellsRunsQA.C:564
 getCellsRunsQA.C:565
 getCellsRunsQA.C:566
 getCellsRunsQA.C:567
 getCellsRunsQA.C:568
 getCellsRunsQA.C:569
 getCellsRunsQA.C:570
 getCellsRunsQA.C:571
 getCellsRunsQA.C:572
 getCellsRunsQA.C:573
 getCellsRunsQA.C:574
 getCellsRunsQA.C:575
 getCellsRunsQA.C:576
 getCellsRunsQA.C:577
 getCellsRunsQA.C:578
 getCellsRunsQA.C:579
 getCellsRunsQA.C:580
 getCellsRunsQA.C:581
 getCellsRunsQA.C:582
 getCellsRunsQA.C:583
 getCellsRunsQA.C:584
 getCellsRunsQA.C:585
 getCellsRunsQA.C:586
 getCellsRunsQA.C:587
 getCellsRunsQA.C:588
 getCellsRunsQA.C:589
 getCellsRunsQA.C:590
 getCellsRunsQA.C:591
 getCellsRunsQA.C:592
 getCellsRunsQA.C:593
 getCellsRunsQA.C:594
 getCellsRunsQA.C:595
 getCellsRunsQA.C:596
 getCellsRunsQA.C:597
 getCellsRunsQA.C:598
 getCellsRunsQA.C:599
 getCellsRunsQA.C:600
 getCellsRunsQA.C:601
 getCellsRunsQA.C:602
 getCellsRunsQA.C:603
 getCellsRunsQA.C:604
 getCellsRunsQA.C:605
 getCellsRunsQA.C:606
 getCellsRunsQA.C:607
 getCellsRunsQA.C:608
 getCellsRunsQA.C:609
 getCellsRunsQA.C:610
 getCellsRunsQA.C:611
 getCellsRunsQA.C:612
 getCellsRunsQA.C:613
 getCellsRunsQA.C:614
 getCellsRunsQA.C:615
 getCellsRunsQA.C:616
 getCellsRunsQA.C:617
 getCellsRunsQA.C:618
 getCellsRunsQA.C:619
 getCellsRunsQA.C:620
 getCellsRunsQA.C:621
 getCellsRunsQA.C:622
 getCellsRunsQA.C:623
 getCellsRunsQA.C:624
 getCellsRunsQA.C:625
 getCellsRunsQA.C:626
 getCellsRunsQA.C:627
 getCellsRunsQA.C:628
 getCellsRunsQA.C:629
 getCellsRunsQA.C:630
 getCellsRunsQA.C:631
 getCellsRunsQA.C:632
 getCellsRunsQA.C:633
 getCellsRunsQA.C:634
 getCellsRunsQA.C:635
 getCellsRunsQA.C:636
 getCellsRunsQA.C:637
 getCellsRunsQA.C:638
 getCellsRunsQA.C:639
 getCellsRunsQA.C:640
 getCellsRunsQA.C:641
 getCellsRunsQA.C:642
 getCellsRunsQA.C:643
 getCellsRunsQA.C:644
 getCellsRunsQA.C:645
 getCellsRunsQA.C:646
 getCellsRunsQA.C:647
 getCellsRunsQA.C:648
 getCellsRunsQA.C:649
 getCellsRunsQA.C:650
 getCellsRunsQA.C:651
 getCellsRunsQA.C:652
 getCellsRunsQA.C:653
 getCellsRunsQA.C:654
 getCellsRunsQA.C:655
 getCellsRunsQA.C:656
 getCellsRunsQA.C:657
 getCellsRunsQA.C:658
 getCellsRunsQA.C:659
 getCellsRunsQA.C:660
 getCellsRunsQA.C:661
 getCellsRunsQA.C:662
 getCellsRunsQA.C:663
 getCellsRunsQA.C:664
 getCellsRunsQA.C:665
 getCellsRunsQA.C:666
 getCellsRunsQA.C:667
 getCellsRunsQA.C:668
 getCellsRunsQA.C:669
 getCellsRunsQA.C:670
 getCellsRunsQA.C:671
 getCellsRunsQA.C:672
 getCellsRunsQA.C:673
 getCellsRunsQA.C:674
 getCellsRunsQA.C:675
 getCellsRunsQA.C:676
 getCellsRunsQA.C:677
 getCellsRunsQA.C:678
 getCellsRunsQA.C:679
 getCellsRunsQA.C:680
 getCellsRunsQA.C:681
 getCellsRunsQA.C:682
 getCellsRunsQA.C:683
 getCellsRunsQA.C:684
 getCellsRunsQA.C:685
 getCellsRunsQA.C:686
 getCellsRunsQA.C:687
 getCellsRunsQA.C:688
 getCellsRunsQA.C:689
 getCellsRunsQA.C:690
 getCellsRunsQA.C:691
 getCellsRunsQA.C:692
 getCellsRunsQA.C:693
 getCellsRunsQA.C:694
 getCellsRunsQA.C:695
 getCellsRunsQA.C:696
 getCellsRunsQA.C:697
 getCellsRunsQA.C:698
 getCellsRunsQA.C:699
 getCellsRunsQA.C:700
 getCellsRunsQA.C:701
 getCellsRunsQA.C:702
 getCellsRunsQA.C:703
 getCellsRunsQA.C:704
 getCellsRunsQA.C:705
 getCellsRunsQA.C:706
 getCellsRunsQA.C:707
 getCellsRunsQA.C:708
 getCellsRunsQA.C:709
 getCellsRunsQA.C:710
 getCellsRunsQA.C:711
 getCellsRunsQA.C:712
 getCellsRunsQA.C:713
 getCellsRunsQA.C:714
 getCellsRunsQA.C:715
 getCellsRunsQA.C:716
 getCellsRunsQA.C:717
 getCellsRunsQA.C:718
 getCellsRunsQA.C:719
 getCellsRunsQA.C:720
 getCellsRunsQA.C:721
 getCellsRunsQA.C:722
 getCellsRunsQA.C:723
 getCellsRunsQA.C:724
 getCellsRunsQA.C:725
 getCellsRunsQA.C:726
 getCellsRunsQA.C:727
 getCellsRunsQA.C:728
 getCellsRunsQA.C:729
 getCellsRunsQA.C:730
 getCellsRunsQA.C:731
 getCellsRunsQA.C:732
 getCellsRunsQA.C:733
 getCellsRunsQA.C:734
 getCellsRunsQA.C:735
 getCellsRunsQA.C:736
 getCellsRunsQA.C:737
 getCellsRunsQA.C:738
 getCellsRunsQA.C:739
 getCellsRunsQA.C:740
 getCellsRunsQA.C:741
 getCellsRunsQA.C:742
 getCellsRunsQA.C:743
 getCellsRunsQA.C:744
 getCellsRunsQA.C:745
 getCellsRunsQA.C:746
 getCellsRunsQA.C:747
 getCellsRunsQA.C:748
 getCellsRunsQA.C:749
 getCellsRunsQA.C:750
 getCellsRunsQA.C:751
 getCellsRunsQA.C:752
 getCellsRunsQA.C:753
 getCellsRunsQA.C:754
 getCellsRunsQA.C:755
 getCellsRunsQA.C:756
 getCellsRunsQA.C:757
 getCellsRunsQA.C:758
 getCellsRunsQA.C:759
 getCellsRunsQA.C:760
 getCellsRunsQA.C:761
 getCellsRunsQA.C:762
 getCellsRunsQA.C:763
 getCellsRunsQA.C:764
 getCellsRunsQA.C:765
 getCellsRunsQA.C:766
 getCellsRunsQA.C:767
 getCellsRunsQA.C:768
 getCellsRunsQA.C:769
 getCellsRunsQA.C:770
 getCellsRunsQA.C:771
 getCellsRunsQA.C:772
 getCellsRunsQA.C:773
 getCellsRunsQA.C:774
 getCellsRunsQA.C:775
 getCellsRunsQA.C:776
 getCellsRunsQA.C:777
 getCellsRunsQA.C:778
 getCellsRunsQA.C:779
 getCellsRunsQA.C:780
 getCellsRunsQA.C:781
 getCellsRunsQA.C:782
 getCellsRunsQA.C:783
 getCellsRunsQA.C:784
 getCellsRunsQA.C:785
 getCellsRunsQA.C:786
 getCellsRunsQA.C:787
 getCellsRunsQA.C:788
 getCellsRunsQA.C:789
 getCellsRunsQA.C:790
 getCellsRunsQA.C:791
 getCellsRunsQA.C:792
 getCellsRunsQA.C:793
 getCellsRunsQA.C:794
 getCellsRunsQA.C:795
 getCellsRunsQA.C:796
 getCellsRunsQA.C:797
 getCellsRunsQA.C:798
 getCellsRunsQA.C:799
 getCellsRunsQA.C:800
 getCellsRunsQA.C:801
 getCellsRunsQA.C:802
 getCellsRunsQA.C:803
 getCellsRunsQA.C:804
 getCellsRunsQA.C:805
 getCellsRunsQA.C:806
 getCellsRunsQA.C:807
 getCellsRunsQA.C:808
 getCellsRunsQA.C:809
 getCellsRunsQA.C:810
 getCellsRunsQA.C:811
 getCellsRunsQA.C:812
 getCellsRunsQA.C:813
 getCellsRunsQA.C:814
 getCellsRunsQA.C:815
 getCellsRunsQA.C:816
 getCellsRunsQA.C:817
 getCellsRunsQA.C:818
 getCellsRunsQA.C:819
 getCellsRunsQA.C:820
 getCellsRunsQA.C:821
 getCellsRunsQA.C:822
 getCellsRunsQA.C:823
 getCellsRunsQA.C:824
 getCellsRunsQA.C:825
 getCellsRunsQA.C:826
 getCellsRunsQA.C:827
 getCellsRunsQA.C:828
 getCellsRunsQA.C:829
 getCellsRunsQA.C:830
 getCellsRunsQA.C:831
 getCellsRunsQA.C:832
 getCellsRunsQA.C:833
 getCellsRunsQA.C:834
 getCellsRunsQA.C:835
 getCellsRunsQA.C:836
 getCellsRunsQA.C:837
 getCellsRunsQA.C:838
 getCellsRunsQA.C:839
 getCellsRunsQA.C:840
 getCellsRunsQA.C:841
 getCellsRunsQA.C:842
 getCellsRunsQA.C:843
 getCellsRunsQA.C:844
 getCellsRunsQA.C:845
 getCellsRunsQA.C:846
 getCellsRunsQA.C:847
 getCellsRunsQA.C:848
 getCellsRunsQA.C:849
 getCellsRunsQA.C:850
 getCellsRunsQA.C:851
 getCellsRunsQA.C:852
 getCellsRunsQA.C:853
 getCellsRunsQA.C:854
 getCellsRunsQA.C:855
 getCellsRunsQA.C:856
 getCellsRunsQA.C:857
 getCellsRunsQA.C:858
 getCellsRunsQA.C:859
 getCellsRunsQA.C:860
 getCellsRunsQA.C:861
 getCellsRunsQA.C:862
 getCellsRunsQA.C:863
 getCellsRunsQA.C:864
 getCellsRunsQA.C:865
 getCellsRunsQA.C:866
 getCellsRunsQA.C:867
 getCellsRunsQA.C:868
 getCellsRunsQA.C:869
 getCellsRunsQA.C:870
 getCellsRunsQA.C:871
 getCellsRunsQA.C:872
 getCellsRunsQA.C:873
 getCellsRunsQA.C:874
 getCellsRunsQA.C:875
 getCellsRunsQA.C:876
 getCellsRunsQA.C:877
 getCellsRunsQA.C:878
 getCellsRunsQA.C:879
 getCellsRunsQA.C:880
 getCellsRunsQA.C:881
 getCellsRunsQA.C:882
 getCellsRunsQA.C:883
 getCellsRunsQA.C:884
 getCellsRunsQA.C:885
 getCellsRunsQA.C:886
 getCellsRunsQA.C:887
 getCellsRunsQA.C:888
 getCellsRunsQA.C:889
 getCellsRunsQA.C:890
 getCellsRunsQA.C:891
 getCellsRunsQA.C:892
 getCellsRunsQA.C:893
 getCellsRunsQA.C:894
 getCellsRunsQA.C:895
 getCellsRunsQA.C:896
 getCellsRunsQA.C:897
 getCellsRunsQA.C:898
 getCellsRunsQA.C:899
 getCellsRunsQA.C:900
 getCellsRunsQA.C:901
 getCellsRunsQA.C:902
 getCellsRunsQA.C:903
 getCellsRunsQA.C:904
 getCellsRunsQA.C:905
 getCellsRunsQA.C:906
 getCellsRunsQA.C:907
 getCellsRunsQA.C:908
 getCellsRunsQA.C:909
 getCellsRunsQA.C:910
 getCellsRunsQA.C:911
 getCellsRunsQA.C:912
 getCellsRunsQA.C:913
 getCellsRunsQA.C:914
 getCellsRunsQA.C:915
 getCellsRunsQA.C:916
 getCellsRunsQA.C:917
 getCellsRunsQA.C:918
 getCellsRunsQA.C:919
 getCellsRunsQA.C:920
 getCellsRunsQA.C:921
 getCellsRunsQA.C:922
 getCellsRunsQA.C:923
 getCellsRunsQA.C:924
 getCellsRunsQA.C:925
 getCellsRunsQA.C:926
 getCellsRunsQA.C:927
 getCellsRunsQA.C:928
 getCellsRunsQA.C:929
 getCellsRunsQA.C:930
 getCellsRunsQA.C:931
 getCellsRunsQA.C:932
 getCellsRunsQA.C:933
 getCellsRunsQA.C:934
 getCellsRunsQA.C:935
 getCellsRunsQA.C:936
 getCellsRunsQA.C:937
 getCellsRunsQA.C:938
 getCellsRunsQA.C:939
 getCellsRunsQA.C:940
 getCellsRunsQA.C:941
 getCellsRunsQA.C:942
 getCellsRunsQA.C:943
 getCellsRunsQA.C:944
 getCellsRunsQA.C:945
 getCellsRunsQA.C:946
 getCellsRunsQA.C:947
 getCellsRunsQA.C:948
 getCellsRunsQA.C:949
 getCellsRunsQA.C:950
 getCellsRunsQA.C:951
 getCellsRunsQA.C:952
 getCellsRunsQA.C:953
 getCellsRunsQA.C:954
 getCellsRunsQA.C:955
 getCellsRunsQA.C:956
 getCellsRunsQA.C:957
 getCellsRunsQA.C:958
 getCellsRunsQA.C:959
 getCellsRunsQA.C:960
 getCellsRunsQA.C:961
 getCellsRunsQA.C:962
 getCellsRunsQA.C:963
 getCellsRunsQA.C:964
 getCellsRunsQA.C:965
 getCellsRunsQA.C:966
 getCellsRunsQA.C:967
 getCellsRunsQA.C:968
 getCellsRunsQA.C:969
 getCellsRunsQA.C:970
 getCellsRunsQA.C:971
 getCellsRunsQA.C:972
 getCellsRunsQA.C:973
 getCellsRunsQA.C:974
 getCellsRunsQA.C:975
 getCellsRunsQA.C:976
 getCellsRunsQA.C:977
 getCellsRunsQA.C:978
 getCellsRunsQA.C:979
 getCellsRunsQA.C:980
 getCellsRunsQA.C:981
 getCellsRunsQA.C:982
 getCellsRunsQA.C:983
 getCellsRunsQA.C:984
 getCellsRunsQA.C:985
 getCellsRunsQA.C:986
 getCellsRunsQA.C:987
 getCellsRunsQA.C:988
 getCellsRunsQA.C:989
 getCellsRunsQA.C:990
 getCellsRunsQA.C:991
 getCellsRunsQA.C:992
 getCellsRunsQA.C:993
 getCellsRunsQA.C:994
 getCellsRunsQA.C:995
 getCellsRunsQA.C:996
 getCellsRunsQA.C:997
 getCellsRunsQA.C:998
 getCellsRunsQA.C:999
 getCellsRunsQA.C:1000
 getCellsRunsQA.C:1001
 getCellsRunsQA.C:1002
 getCellsRunsQA.C:1003
 getCellsRunsQA.C:1004
 getCellsRunsQA.C:1005
 getCellsRunsQA.C:1006
 getCellsRunsQA.C:1007
 getCellsRunsQA.C:1008
 getCellsRunsQA.C:1009
 getCellsRunsQA.C:1010
 getCellsRunsQA.C:1011
 getCellsRunsQA.C:1012
 getCellsRunsQA.C:1013
 getCellsRunsQA.C:1014
 getCellsRunsQA.C:1015
 getCellsRunsQA.C:1016
 getCellsRunsQA.C:1017
 getCellsRunsQA.C:1018
 getCellsRunsQA.C:1019
 getCellsRunsQA.C:1020
 getCellsRunsQA.C:1021
 getCellsRunsQA.C:1022
 getCellsRunsQA.C:1023
 getCellsRunsQA.C:1024
 getCellsRunsQA.C:1025
 getCellsRunsQA.C:1026
 getCellsRunsQA.C:1027
 getCellsRunsQA.C:1028
 getCellsRunsQA.C:1029
 getCellsRunsQA.C:1030
 getCellsRunsQA.C:1031
 getCellsRunsQA.C:1032
 getCellsRunsQA.C:1033
 getCellsRunsQA.C:1034
 getCellsRunsQA.C:1035
 getCellsRunsQA.C:1036
 getCellsRunsQA.C:1037
 getCellsRunsQA.C:1038
 getCellsRunsQA.C:1039
 getCellsRunsQA.C:1040
 getCellsRunsQA.C:1041
 getCellsRunsQA.C:1042
 getCellsRunsQA.C:1043
 getCellsRunsQA.C:1044
 getCellsRunsQA.C:1045
 getCellsRunsQA.C:1046
 getCellsRunsQA.C:1047
 getCellsRunsQA.C:1048
 getCellsRunsQA.C:1049
 getCellsRunsQA.C:1050
 getCellsRunsQA.C:1051
 getCellsRunsQA.C:1052
 getCellsRunsQA.C:1053
 getCellsRunsQA.C:1054
 getCellsRunsQA.C:1055
 getCellsRunsQA.C:1056
 getCellsRunsQA.C:1057
 getCellsRunsQA.C:1058
 getCellsRunsQA.C:1059
 getCellsRunsQA.C:1060
 getCellsRunsQA.C:1061
 getCellsRunsQA.C:1062
 getCellsRunsQA.C:1063
 getCellsRunsQA.C:1064
 getCellsRunsQA.C:1065
 getCellsRunsQA.C:1066
 getCellsRunsQA.C:1067
 getCellsRunsQA.C:1068
 getCellsRunsQA.C:1069
 getCellsRunsQA.C:1070
 getCellsRunsQA.C:1071
 getCellsRunsQA.C:1072
 getCellsRunsQA.C:1073
 getCellsRunsQA.C:1074
 getCellsRunsQA.C:1075
 getCellsRunsQA.C:1076
 getCellsRunsQA.C:1077
 getCellsRunsQA.C:1078
 getCellsRunsQA.C:1079
 getCellsRunsQA.C:1080
 getCellsRunsQA.C:1081
 getCellsRunsQA.C:1082
 getCellsRunsQA.C:1083
 getCellsRunsQA.C:1084
 getCellsRunsQA.C:1085
 getCellsRunsQA.C:1086
 getCellsRunsQA.C:1087
 getCellsRunsQA.C:1088
 getCellsRunsQA.C:1089
 getCellsRunsQA.C:1090
 getCellsRunsQA.C:1091
 getCellsRunsQA.C:1092
 getCellsRunsQA.C:1093
 getCellsRunsQA.C:1094
 getCellsRunsQA.C:1095
 getCellsRunsQA.C:1096
 getCellsRunsQA.C:1097
 getCellsRunsQA.C:1098
 getCellsRunsQA.C:1099
 getCellsRunsQA.C:1100
 getCellsRunsQA.C:1101
 getCellsRunsQA.C:1102
 getCellsRunsQA.C:1103
 getCellsRunsQA.C:1104
 getCellsRunsQA.C:1105
 getCellsRunsQA.C:1106
 getCellsRunsQA.C:1107
 getCellsRunsQA.C:1108
 getCellsRunsQA.C:1109
 getCellsRunsQA.C:1110
 getCellsRunsQA.C:1111
 getCellsRunsQA.C:1112
 getCellsRunsQA.C:1113
 getCellsRunsQA.C:1114
 getCellsRunsQA.C:1115
 getCellsRunsQA.C:1116
 getCellsRunsQA.C:1117
 getCellsRunsQA.C:1118
 getCellsRunsQA.C:1119
 getCellsRunsQA.C:1120
 getCellsRunsQA.C:1121
 getCellsRunsQA.C:1122
 getCellsRunsQA.C:1123
 getCellsRunsQA.C:1124
 getCellsRunsQA.C:1125
 getCellsRunsQA.C:1126
 getCellsRunsQA.C:1127
 getCellsRunsQA.C:1128
 getCellsRunsQA.C:1129
 getCellsRunsQA.C:1130
 getCellsRunsQA.C:1131
 getCellsRunsQA.C:1132
 getCellsRunsQA.C:1133
 getCellsRunsQA.C:1134
 getCellsRunsQA.C:1135
 getCellsRunsQA.C:1136
 getCellsRunsQA.C:1137
 getCellsRunsQA.C:1138
 getCellsRunsQA.C:1139
 getCellsRunsQA.C:1140
 getCellsRunsQA.C:1141
 getCellsRunsQA.C:1142
 getCellsRunsQA.C:1143
 getCellsRunsQA.C:1144
 getCellsRunsQA.C:1145
 getCellsRunsQA.C:1146
 getCellsRunsQA.C:1147
 getCellsRunsQA.C:1148
 getCellsRunsQA.C:1149
 getCellsRunsQA.C:1150
 getCellsRunsQA.C:1151
 getCellsRunsQA.C:1152
 getCellsRunsQA.C:1153
 getCellsRunsQA.C:1154
 getCellsRunsQA.C:1155
 getCellsRunsQA.C:1156
 getCellsRunsQA.C:1157
 getCellsRunsQA.C:1158
 getCellsRunsQA.C:1159
 getCellsRunsQA.C:1160
 getCellsRunsQA.C:1161
 getCellsRunsQA.C:1162
 getCellsRunsQA.C:1163
 getCellsRunsQA.C:1164
 getCellsRunsQA.C:1165
 getCellsRunsQA.C:1166
 getCellsRunsQA.C:1167
 getCellsRunsQA.C:1168
 getCellsRunsQA.C:1169
 getCellsRunsQA.C:1170
 getCellsRunsQA.C:1171
 getCellsRunsQA.C:1172
 getCellsRunsQA.C:1173
 getCellsRunsQA.C:1174
 getCellsRunsQA.C:1175
 getCellsRunsQA.C:1176
 getCellsRunsQA.C:1177
 getCellsRunsQA.C:1178
 getCellsRunsQA.C:1179
 getCellsRunsQA.C:1180
 getCellsRunsQA.C:1181
 getCellsRunsQA.C:1182
 getCellsRunsQA.C:1183
 getCellsRunsQA.C:1184
 getCellsRunsQA.C:1185
 getCellsRunsQA.C:1186
 getCellsRunsQA.C:1187
 getCellsRunsQA.C:1188
 getCellsRunsQA.C:1189
 getCellsRunsQA.C:1190
 getCellsRunsQA.C:1191
 getCellsRunsQA.C:1192
 getCellsRunsQA.C:1193
 getCellsRunsQA.C:1194
 getCellsRunsQA.C:1195
 getCellsRunsQA.C:1196
 getCellsRunsQA.C:1197
 getCellsRunsQA.C:1198
 getCellsRunsQA.C:1199
 getCellsRunsQA.C:1200
 getCellsRunsQA.C:1201
 getCellsRunsQA.C:1202
 getCellsRunsQA.C:1203
 getCellsRunsQA.C:1204
 getCellsRunsQA.C:1205
 getCellsRunsQA.C:1206
 getCellsRunsQA.C:1207
 getCellsRunsQA.C:1208
 getCellsRunsQA.C:1209
 getCellsRunsQA.C:1210
 getCellsRunsQA.C:1211
 getCellsRunsQA.C:1212
 getCellsRunsQA.C:1213
 getCellsRunsQA.C:1214
 getCellsRunsQA.C:1215
 getCellsRunsQA.C:1216
 getCellsRunsQA.C:1217
 getCellsRunsQA.C:1218
 getCellsRunsQA.C:1219
 getCellsRunsQA.C:1220
 getCellsRunsQA.C:1221
 getCellsRunsQA.C:1222
 getCellsRunsQA.C:1223
 getCellsRunsQA.C:1224
 getCellsRunsQA.C:1225
 getCellsRunsQA.C:1226
 getCellsRunsQA.C:1227
 getCellsRunsQA.C:1228
 getCellsRunsQA.C:1229
 getCellsRunsQA.C:1230
 getCellsRunsQA.C:1231
 getCellsRunsQA.C:1232
 getCellsRunsQA.C:1233
 getCellsRunsQA.C:1234
 getCellsRunsQA.C:1235
 getCellsRunsQA.C:1236
 getCellsRunsQA.C:1237
 getCellsRunsQA.C:1238
 getCellsRunsQA.C:1239
 getCellsRunsQA.C:1240
 getCellsRunsQA.C:1241
 getCellsRunsQA.C:1242
 getCellsRunsQA.C:1243
 getCellsRunsQA.C:1244
 getCellsRunsQA.C:1245
 getCellsRunsQA.C:1246
 getCellsRunsQA.C:1247
 getCellsRunsQA.C:1248
 getCellsRunsQA.C:1249
 getCellsRunsQA.C:1250
 getCellsRunsQA.C:1251
 getCellsRunsQA.C:1252
 getCellsRunsQA.C:1253
 getCellsRunsQA.C:1254
 getCellsRunsQA.C:1255
 getCellsRunsQA.C:1256
 getCellsRunsQA.C:1257
 getCellsRunsQA.C:1258
 getCellsRunsQA.C:1259
 getCellsRunsQA.C:1260
 getCellsRunsQA.C:1261
 getCellsRunsQA.C:1262
 getCellsRunsQA.C:1263
 getCellsRunsQA.C:1264
 getCellsRunsQA.C:1265
 getCellsRunsQA.C:1266
 getCellsRunsQA.C:1267
 getCellsRunsQA.C:1268
 getCellsRunsQA.C:1269
 getCellsRunsQA.C:1270
 getCellsRunsQA.C:1271
 getCellsRunsQA.C:1272
 getCellsRunsQA.C:1273
 getCellsRunsQA.C:1274
 getCellsRunsQA.C:1275
 getCellsRunsQA.C:1276
 getCellsRunsQA.C:1277
 getCellsRunsQA.C:1278
 getCellsRunsQA.C:1279
 getCellsRunsQA.C:1280
 getCellsRunsQA.C:1281
 getCellsRunsQA.C:1282
 getCellsRunsQA.C:1283
 getCellsRunsQA.C:1284
 getCellsRunsQA.C:1285
 getCellsRunsQA.C:1286
 getCellsRunsQA.C:1287
 getCellsRunsQA.C:1288
 getCellsRunsQA.C:1289
 getCellsRunsQA.C:1290
 getCellsRunsQA.C:1291
 getCellsRunsQA.C:1292
 getCellsRunsQA.C:1293
 getCellsRunsQA.C:1294
 getCellsRunsQA.C:1295
 getCellsRunsQA.C:1296
 getCellsRunsQA.C:1297
 getCellsRunsQA.C:1298
 getCellsRunsQA.C:1299
 getCellsRunsQA.C:1300
 getCellsRunsQA.C:1301
 getCellsRunsQA.C:1302
 getCellsRunsQA.C:1303
 getCellsRunsQA.C:1304
 getCellsRunsQA.C:1305
 getCellsRunsQA.C:1306
 getCellsRunsQA.C:1307
 getCellsRunsQA.C:1308
 getCellsRunsQA.C:1309
 getCellsRunsQA.C:1310
 getCellsRunsQA.C:1311
 getCellsRunsQA.C:1312
 getCellsRunsQA.C:1313
 getCellsRunsQA.C:1314
 getCellsRunsQA.C:1315
 getCellsRunsQA.C:1316
 getCellsRunsQA.C:1317
 getCellsRunsQA.C:1318
 getCellsRunsQA.C:1319
 getCellsRunsQA.C:1320
 getCellsRunsQA.C:1321
 getCellsRunsQA.C:1322
 getCellsRunsQA.C:1323
 getCellsRunsQA.C:1324
 getCellsRunsQA.C:1325
 getCellsRunsQA.C:1326
 getCellsRunsQA.C:1327
 getCellsRunsQA.C:1328
 getCellsRunsQA.C:1329
 getCellsRunsQA.C:1330
 getCellsRunsQA.C:1331
 getCellsRunsQA.C:1332
 getCellsRunsQA.C:1333
 getCellsRunsQA.C:1334
 getCellsRunsQA.C:1335
 getCellsRunsQA.C:1336
 getCellsRunsQA.C:1337
 getCellsRunsQA.C:1338
 getCellsRunsQA.C:1339
 getCellsRunsQA.C:1340
 getCellsRunsQA.C:1341
 getCellsRunsQA.C:1342
 getCellsRunsQA.C:1343
 getCellsRunsQA.C:1344
 getCellsRunsQA.C:1345
 getCellsRunsQA.C:1346
 getCellsRunsQA.C:1347
 getCellsRunsQA.C:1348
 getCellsRunsQA.C:1349
 getCellsRunsQA.C:1350
 getCellsRunsQA.C:1351
 getCellsRunsQA.C:1352
 getCellsRunsQA.C:1353
 getCellsRunsQA.C:1354
 getCellsRunsQA.C:1355
 getCellsRunsQA.C:1356
 getCellsRunsQA.C:1357
 getCellsRunsQA.C:1358
 getCellsRunsQA.C:1359
 getCellsRunsQA.C:1360
 getCellsRunsQA.C:1361
 getCellsRunsQA.C:1362
 getCellsRunsQA.C:1363
 getCellsRunsQA.C:1364
 getCellsRunsQA.C:1365
 getCellsRunsQA.C:1366
 getCellsRunsQA.C:1367
 getCellsRunsQA.C:1368
 getCellsRunsQA.C:1369
 getCellsRunsQA.C:1370
 getCellsRunsQA.C:1371
 getCellsRunsQA.C:1372
 getCellsRunsQA.C:1373
 getCellsRunsQA.C:1374
 getCellsRunsQA.C:1375
 getCellsRunsQA.C:1376
 getCellsRunsQA.C:1377
 getCellsRunsQA.C:1378
 getCellsRunsQA.C:1379
 getCellsRunsQA.C:1380
 getCellsRunsQA.C:1381
 getCellsRunsQA.C:1382
 getCellsRunsQA.C:1383
 getCellsRunsQA.C:1384
 getCellsRunsQA.C:1385
 getCellsRunsQA.C:1386
 getCellsRunsQA.C:1387
 getCellsRunsQA.C:1388
 getCellsRunsQA.C:1389
 getCellsRunsQA.C:1390
 getCellsRunsQA.C:1391
 getCellsRunsQA.C:1392
 getCellsRunsQA.C:1393
 getCellsRunsQA.C:1394
 getCellsRunsQA.C:1395
 getCellsRunsQA.C:1396
 getCellsRunsQA.C:1397
 getCellsRunsQA.C:1398
 getCellsRunsQA.C:1399
 getCellsRunsQA.C:1400
 getCellsRunsQA.C:1401
 getCellsRunsQA.C:1402
 getCellsRunsQA.C:1403
 getCellsRunsQA.C:1404
 getCellsRunsQA.C:1405
 getCellsRunsQA.C:1406
 getCellsRunsQA.C:1407
 getCellsRunsQA.C:1408
 getCellsRunsQA.C:1409
 getCellsRunsQA.C:1410
 getCellsRunsQA.C:1411
 getCellsRunsQA.C:1412
 getCellsRunsQA.C:1413
 getCellsRunsQA.C:1414
 getCellsRunsQA.C:1415
 getCellsRunsQA.C:1416
 getCellsRunsQA.C:1417
 getCellsRunsQA.C:1418
 getCellsRunsQA.C:1419
 getCellsRunsQA.C:1420
 getCellsRunsQA.C:1421
 getCellsRunsQA.C:1422
 getCellsRunsQA.C:1423
 getCellsRunsQA.C:1424
 getCellsRunsQA.C:1425
 getCellsRunsQA.C:1426
 getCellsRunsQA.C:1427
 getCellsRunsQA.C:1428
 getCellsRunsQA.C:1429
 getCellsRunsQA.C:1430
 getCellsRunsQA.C:1431
 getCellsRunsQA.C:1432
 getCellsRunsQA.C:1433
 getCellsRunsQA.C:1434
 getCellsRunsQA.C:1435
 getCellsRunsQA.C:1436
 getCellsRunsQA.C:1437
 getCellsRunsQA.C:1438
 getCellsRunsQA.C:1439
 getCellsRunsQA.C:1440
 getCellsRunsQA.C:1441
 getCellsRunsQA.C:1442
 getCellsRunsQA.C:1443
 getCellsRunsQA.C:1444
 getCellsRunsQA.C:1445
 getCellsRunsQA.C:1446
 getCellsRunsQA.C:1447
 getCellsRunsQA.C:1448
 getCellsRunsQA.C:1449
 getCellsRunsQA.C:1450
 getCellsRunsQA.C:1451
 getCellsRunsQA.C:1452
 getCellsRunsQA.C:1453
 getCellsRunsQA.C:1454
 getCellsRunsQA.C:1455
 getCellsRunsQA.C:1456
 getCellsRunsQA.C:1457
 getCellsRunsQA.C:1458
 getCellsRunsQA.C:1459
 getCellsRunsQA.C:1460
 getCellsRunsQA.C:1461
 getCellsRunsQA.C:1462
 getCellsRunsQA.C:1463
 getCellsRunsQA.C:1464
 getCellsRunsQA.C:1465
 getCellsRunsQA.C:1466
 getCellsRunsQA.C:1467
 getCellsRunsQA.C:1468
 getCellsRunsQA.C:1469
 getCellsRunsQA.C:1470
 getCellsRunsQA.C:1471
 getCellsRunsQA.C:1472
 getCellsRunsQA.C:1473
 getCellsRunsQA.C:1474
 getCellsRunsQA.C:1475
 getCellsRunsQA.C:1476
 getCellsRunsQA.C:1477
 getCellsRunsQA.C:1478
 getCellsRunsQA.C:1479
 getCellsRunsQA.C:1480
 getCellsRunsQA.C:1481
 getCellsRunsQA.C:1482
 getCellsRunsQA.C:1483
 getCellsRunsQA.C:1484
 getCellsRunsQA.C:1485
 getCellsRunsQA.C:1486
 getCellsRunsQA.C:1487
 getCellsRunsQA.C:1488
 getCellsRunsQA.C:1489
 getCellsRunsQA.C:1490
 getCellsRunsQA.C:1491
 getCellsRunsQA.C:1492
 getCellsRunsQA.C:1493
 getCellsRunsQA.C:1494
 getCellsRunsQA.C:1495
 getCellsRunsQA.C:1496
 getCellsRunsQA.C:1497
 getCellsRunsQA.C:1498
 getCellsRunsQA.C:1499
 getCellsRunsQA.C:1500
 getCellsRunsQA.C:1501
 getCellsRunsQA.C:1502
 getCellsRunsQA.C:1503
 getCellsRunsQA.C:1504
 getCellsRunsQA.C:1505
 getCellsRunsQA.C:1506
 getCellsRunsQA.C:1507
 getCellsRunsQA.C:1508
 getCellsRunsQA.C:1509
 getCellsRunsQA.C:1510
 getCellsRunsQA.C:1511
 getCellsRunsQA.C:1512
 getCellsRunsQA.C:1513
 getCellsRunsQA.C:1514
 getCellsRunsQA.C:1515
 getCellsRunsQA.C:1516
 getCellsRunsQA.C:1517
 getCellsRunsQA.C:1518
 getCellsRunsQA.C:1519
 getCellsRunsQA.C:1520
 getCellsRunsQA.C:1521
 getCellsRunsQA.C:1522
 getCellsRunsQA.C:1523
 getCellsRunsQA.C:1524
 getCellsRunsQA.C:1525
 getCellsRunsQA.C:1526
 getCellsRunsQA.C:1527
 getCellsRunsQA.C:1528
 getCellsRunsQA.C:1529
 getCellsRunsQA.C:1530
 getCellsRunsQA.C:1531
 getCellsRunsQA.C:1532
 getCellsRunsQA.C:1533
 getCellsRunsQA.C:1534
 getCellsRunsQA.C:1535
 getCellsRunsQA.C:1536
 getCellsRunsQA.C:1537
 getCellsRunsQA.C:1538
 getCellsRunsQA.C:1539
 getCellsRunsQA.C:1540
 getCellsRunsQA.C:1541
 getCellsRunsQA.C:1542
 getCellsRunsQA.C:1543
 getCellsRunsQA.C:1544
 getCellsRunsQA.C:1545
 getCellsRunsQA.C:1546
 getCellsRunsQA.C:1547
 getCellsRunsQA.C:1548
 getCellsRunsQA.C:1549
 getCellsRunsQA.C:1550
 getCellsRunsQA.C:1551
 getCellsRunsQA.C:1552
 getCellsRunsQA.C:1553
 getCellsRunsQA.C:1554
 getCellsRunsQA.C:1555
 getCellsRunsQA.C:1556
 getCellsRunsQA.C:1557
 getCellsRunsQA.C:1558
 getCellsRunsQA.C:1559
 getCellsRunsQA.C:1560
 getCellsRunsQA.C:1561
 getCellsRunsQA.C:1562
 getCellsRunsQA.C:1563
 getCellsRunsQA.C:1564
 getCellsRunsQA.C:1565
 getCellsRunsQA.C:1566
 getCellsRunsQA.C:1567
 getCellsRunsQA.C:1568
 getCellsRunsQA.C:1569
 getCellsRunsQA.C:1570
 getCellsRunsQA.C:1571
 getCellsRunsQA.C:1572
 getCellsRunsQA.C:1573
 getCellsRunsQA.C:1574
 getCellsRunsQA.C:1575
 getCellsRunsQA.C:1576
 getCellsRunsQA.C:1577
 getCellsRunsQA.C:1578
 getCellsRunsQA.C:1579
 getCellsRunsQA.C:1580
 getCellsRunsQA.C:1581
 getCellsRunsQA.C:1582
 getCellsRunsQA.C:1583
 getCellsRunsQA.C:1584
 getCellsRunsQA.C:1585
 getCellsRunsQA.C:1586
 getCellsRunsQA.C:1587
 getCellsRunsQA.C:1588
 getCellsRunsQA.C:1589
 getCellsRunsQA.C:1590
 getCellsRunsQA.C:1591
 getCellsRunsQA.C:1592
 getCellsRunsQA.C:1593
 getCellsRunsQA.C:1594
 getCellsRunsQA.C:1595
 getCellsRunsQA.C:1596
 getCellsRunsQA.C:1597
 getCellsRunsQA.C:1598
 getCellsRunsQA.C:1599
 getCellsRunsQA.C:1600
 getCellsRunsQA.C:1601
 getCellsRunsQA.C:1602
 getCellsRunsQA.C:1603
 getCellsRunsQA.C:1604
 getCellsRunsQA.C:1605
 getCellsRunsQA.C:1606
 getCellsRunsQA.C:1607
 getCellsRunsQA.C:1608
 getCellsRunsQA.C:1609
 getCellsRunsQA.C:1610
 getCellsRunsQA.C:1611
 getCellsRunsQA.C:1612
 getCellsRunsQA.C:1613
 getCellsRunsQA.C:1614
 getCellsRunsQA.C:1615
 getCellsRunsQA.C:1616
 getCellsRunsQA.C:1617
 getCellsRunsQA.C:1618
 getCellsRunsQA.C:1619
 getCellsRunsQA.C:1620
 getCellsRunsQA.C:1621
 getCellsRunsQA.C:1622
 getCellsRunsQA.C:1623
 getCellsRunsQA.C:1624
 getCellsRunsQA.C:1625
 getCellsRunsQA.C:1626
 getCellsRunsQA.C:1627
 getCellsRunsQA.C:1628
 getCellsRunsQA.C:1629
 getCellsRunsQA.C:1630
 getCellsRunsQA.C:1631
 getCellsRunsQA.C:1632
 getCellsRunsQA.C:1633
 getCellsRunsQA.C:1634
 getCellsRunsQA.C:1635
 getCellsRunsQA.C:1636
 getCellsRunsQA.C:1637
 getCellsRunsQA.C:1638
 getCellsRunsQA.C:1639
 getCellsRunsQA.C:1640
 getCellsRunsQA.C:1641
 getCellsRunsQA.C:1642
 getCellsRunsQA.C:1643
 getCellsRunsQA.C:1644
 getCellsRunsQA.C:1645
 getCellsRunsQA.C:1646
 getCellsRunsQA.C:1647
 getCellsRunsQA.C:1648
 getCellsRunsQA.C:1649
 getCellsRunsQA.C:1650
 getCellsRunsQA.C:1651
 getCellsRunsQA.C:1652
 getCellsRunsQA.C:1653
 getCellsRunsQA.C:1654
 getCellsRunsQA.C:1655
 getCellsRunsQA.C:1656
 getCellsRunsQA.C:1657
 getCellsRunsQA.C:1658
 getCellsRunsQA.C:1659
 getCellsRunsQA.C:1660
 getCellsRunsQA.C:1661
 getCellsRunsQA.C:1662
 getCellsRunsQA.C:1663
 getCellsRunsQA.C:1664
 getCellsRunsQA.C:1665
 getCellsRunsQA.C:1666
 getCellsRunsQA.C:1667
 getCellsRunsQA.C:1668
 getCellsRunsQA.C:1669
 getCellsRunsQA.C:1670
 getCellsRunsQA.C:1671
 getCellsRunsQA.C:1672
 getCellsRunsQA.C:1673
 getCellsRunsQA.C:1674
 getCellsRunsQA.C:1675
 getCellsRunsQA.C:1676
 getCellsRunsQA.C:1677
 getCellsRunsQA.C:1678
 getCellsRunsQA.C:1679
 getCellsRunsQA.C:1680
 getCellsRunsQA.C:1681
 getCellsRunsQA.C:1682
 getCellsRunsQA.C:1683
 getCellsRunsQA.C:1684
 getCellsRunsQA.C:1685
 getCellsRunsQA.C:1686
 getCellsRunsQA.C:1687
 getCellsRunsQA.C:1688
 getCellsRunsQA.C:1689
 getCellsRunsQA.C:1690
 getCellsRunsQA.C:1691
 getCellsRunsQA.C:1692
 getCellsRunsQA.C:1693
 getCellsRunsQA.C:1694
 getCellsRunsQA.C:1695
 getCellsRunsQA.C:1696
 getCellsRunsQA.C:1697
 getCellsRunsQA.C:1698
 getCellsRunsQA.C:1699
 getCellsRunsQA.C:1700
 getCellsRunsQA.C:1701
 getCellsRunsQA.C:1702
 getCellsRunsQA.C:1703
 getCellsRunsQA.C:1704
 getCellsRunsQA.C:1705
 getCellsRunsQA.C:1706
 getCellsRunsQA.C:1707
 getCellsRunsQA.C:1708
 getCellsRunsQA.C:1709
 getCellsRunsQA.C:1710
 getCellsRunsQA.C:1711
 getCellsRunsQA.C:1712
 getCellsRunsQA.C:1713
 getCellsRunsQA.C:1714
 getCellsRunsQA.C:1715
 getCellsRunsQA.C:1716
 getCellsRunsQA.C:1717
 getCellsRunsQA.C:1718
 getCellsRunsQA.C:1719
 getCellsRunsQA.C:1720
 getCellsRunsQA.C:1721
 getCellsRunsQA.C:1722
 getCellsRunsQA.C:1723
 getCellsRunsQA.C:1724
 getCellsRunsQA.C:1725
 getCellsRunsQA.C:1726
 getCellsRunsQA.C:1727
 getCellsRunsQA.C:1728
 getCellsRunsQA.C:1729
 getCellsRunsQA.C:1730
 getCellsRunsQA.C:1731
 getCellsRunsQA.C:1732
 getCellsRunsQA.C:1733
 getCellsRunsQA.C:1734
 getCellsRunsQA.C:1735
 getCellsRunsQA.C:1736
 getCellsRunsQA.C:1737
 getCellsRunsQA.C:1738
 getCellsRunsQA.C:1739
 getCellsRunsQA.C:1740
 getCellsRunsQA.C:1741
 getCellsRunsQA.C:1742
 getCellsRunsQA.C:1743
 getCellsRunsQA.C:1744
 getCellsRunsQA.C:1745
 getCellsRunsQA.C:1746
 getCellsRunsQA.C:1747
 getCellsRunsQA.C:1748
 getCellsRunsQA.C:1749
 getCellsRunsQA.C:1750
 getCellsRunsQA.C:1751
 getCellsRunsQA.C:1752
 getCellsRunsQA.C:1753
 getCellsRunsQA.C:1754
 getCellsRunsQA.C:1755
 getCellsRunsQA.C:1756
 getCellsRunsQA.C:1757
 getCellsRunsQA.C:1758
 getCellsRunsQA.C:1759
 getCellsRunsQA.C:1760
 getCellsRunsQA.C:1761
 getCellsRunsQA.C:1762
 getCellsRunsQA.C:1763
 getCellsRunsQA.C:1764
 getCellsRunsQA.C:1765
 getCellsRunsQA.C:1766
 getCellsRunsQA.C:1767
 getCellsRunsQA.C:1768
 getCellsRunsQA.C:1769
 getCellsRunsQA.C:1770
 getCellsRunsQA.C:1771
 getCellsRunsQA.C:1772
 getCellsRunsQA.C:1773
 getCellsRunsQA.C:1774
 getCellsRunsQA.C:1775
 getCellsRunsQA.C:1776
 getCellsRunsQA.C:1777
 getCellsRunsQA.C:1778
 getCellsRunsQA.C:1779
 getCellsRunsQA.C:1780
 getCellsRunsQA.C:1781
 getCellsRunsQA.C:1782
 getCellsRunsQA.C:1783
 getCellsRunsQA.C:1784
 getCellsRunsQA.C:1785
 getCellsRunsQA.C:1786
 getCellsRunsQA.C:1787
 getCellsRunsQA.C:1788
 getCellsRunsQA.C:1789
 getCellsRunsQA.C:1790
 getCellsRunsQA.C:1791
 getCellsRunsQA.C:1792
 getCellsRunsQA.C:1793
 getCellsRunsQA.C:1794
 getCellsRunsQA.C:1795
 getCellsRunsQA.C:1796
 getCellsRunsQA.C:1797
 getCellsRunsQA.C:1798
 getCellsRunsQA.C:1799
 getCellsRunsQA.C:1800
 getCellsRunsQA.C:1801
 getCellsRunsQA.C:1802
 getCellsRunsQA.C:1803
 getCellsRunsQA.C:1804
 getCellsRunsQA.C:1805
 getCellsRunsQA.C:1806
 getCellsRunsQA.C:1807
 getCellsRunsQA.C:1808
 getCellsRunsQA.C:1809
 getCellsRunsQA.C:1810
 getCellsRunsQA.C:1811
 getCellsRunsQA.C:1812
 getCellsRunsQA.C:1813
 getCellsRunsQA.C:1814
 getCellsRunsQA.C:1815
 getCellsRunsQA.C:1816
 getCellsRunsQA.C:1817
 getCellsRunsQA.C:1818
 getCellsRunsQA.C:1819
 getCellsRunsQA.C:1820
 getCellsRunsQA.C:1821
 getCellsRunsQA.C:1822
 getCellsRunsQA.C:1823
 getCellsRunsQA.C:1824
 getCellsRunsQA.C:1825
 getCellsRunsQA.C:1826
 getCellsRunsQA.C:1827
 getCellsRunsQA.C:1828
 getCellsRunsQA.C:1829
 getCellsRunsQA.C:1830
 getCellsRunsQA.C:1831
 getCellsRunsQA.C:1832
 getCellsRunsQA.C:1833
 getCellsRunsQA.C:1834
 getCellsRunsQA.C:1835
 getCellsRunsQA.C:1836
 getCellsRunsQA.C:1837
 getCellsRunsQA.C:1838
 getCellsRunsQA.C:1839
 getCellsRunsQA.C:1840
 getCellsRunsQA.C:1841
 getCellsRunsQA.C:1842
 getCellsRunsQA.C:1843
 getCellsRunsQA.C:1844
 getCellsRunsQA.C:1845
 getCellsRunsQA.C:1846
 getCellsRunsQA.C:1847
 getCellsRunsQA.C:1848
 getCellsRunsQA.C:1849
 getCellsRunsQA.C:1850
 getCellsRunsQA.C:1851
 getCellsRunsQA.C:1852
 getCellsRunsQA.C:1853
 getCellsRunsQA.C:1854
 getCellsRunsQA.C:1855
 getCellsRunsQA.C:1856
 getCellsRunsQA.C:1857
 getCellsRunsQA.C:1858
 getCellsRunsQA.C:1859
 getCellsRunsQA.C:1860
 getCellsRunsQA.C:1861
 getCellsRunsQA.C:1862
 getCellsRunsQA.C:1863
 getCellsRunsQA.C:1864
 getCellsRunsQA.C:1865
 getCellsRunsQA.C:1866
 getCellsRunsQA.C:1867
 getCellsRunsQA.C:1868
 getCellsRunsQA.C:1869
 getCellsRunsQA.C:1870
 getCellsRunsQA.C:1871
 getCellsRunsQA.C:1872
 getCellsRunsQA.C:1873
 getCellsRunsQA.C:1874
 getCellsRunsQA.C:1875
 getCellsRunsQA.C:1876
 getCellsRunsQA.C:1877
 getCellsRunsQA.C:1878
 getCellsRunsQA.C:1879
 getCellsRunsQA.C:1880
 getCellsRunsQA.C:1881
 getCellsRunsQA.C:1882
 getCellsRunsQA.C:1883
 getCellsRunsQA.C:1884
 getCellsRunsQA.C:1885
 getCellsRunsQA.C:1886
 getCellsRunsQA.C:1887
 getCellsRunsQA.C:1888
 getCellsRunsQA.C:1889
 getCellsRunsQA.C:1890
 getCellsRunsQA.C:1891
 getCellsRunsQA.C:1892
 getCellsRunsQA.C:1893
 getCellsRunsQA.C:1894
 getCellsRunsQA.C:1895
 getCellsRunsQA.C:1896
 getCellsRunsQA.C:1897
 getCellsRunsQA.C:1898
 getCellsRunsQA.C:1899
 getCellsRunsQA.C:1900
 getCellsRunsQA.C:1901
 getCellsRunsQA.C:1902
 getCellsRunsQA.C:1903
 getCellsRunsQA.C:1904
 getCellsRunsQA.C:1905
 getCellsRunsQA.C:1906
 getCellsRunsQA.C:1907
 getCellsRunsQA.C:1908
 getCellsRunsQA.C:1909
 getCellsRunsQA.C:1910
 getCellsRunsQA.C:1911
 getCellsRunsQA.C:1912
 getCellsRunsQA.C:1913
 getCellsRunsQA.C:1914
 getCellsRunsQA.C:1915
 getCellsRunsQA.C:1916
 getCellsRunsQA.C:1917
 getCellsRunsQA.C:1918
 getCellsRunsQA.C:1919
 getCellsRunsQA.C:1920
 getCellsRunsQA.C:1921
 getCellsRunsQA.C:1922
 getCellsRunsQA.C:1923
 getCellsRunsQA.C:1924
 getCellsRunsQA.C:1925
 getCellsRunsQA.C:1926
 getCellsRunsQA.C:1927
 getCellsRunsQA.C:1928
 getCellsRunsQA.C:1929
 getCellsRunsQA.C:1930
 getCellsRunsQA.C:1931
 getCellsRunsQA.C:1932
 getCellsRunsQA.C:1933
 getCellsRunsQA.C:1934
 getCellsRunsQA.C:1935
 getCellsRunsQA.C:1936
 getCellsRunsQA.C:1937
 getCellsRunsQA.C:1938
 getCellsRunsQA.C:1939
 getCellsRunsQA.C:1940
 getCellsRunsQA.C:1941
 getCellsRunsQA.C:1942
 getCellsRunsQA.C:1943
 getCellsRunsQA.C:1944
 getCellsRunsQA.C:1945
 getCellsRunsQA.C:1946
 getCellsRunsQA.C:1947
 getCellsRunsQA.C:1948
 getCellsRunsQA.C:1949
 getCellsRunsQA.C:1950
 getCellsRunsQA.C:1951
 getCellsRunsQA.C:1952
 getCellsRunsQA.C:1953
 getCellsRunsQA.C:1954
 getCellsRunsQA.C:1955
 getCellsRunsQA.C:1956
 getCellsRunsQA.C:1957
 getCellsRunsQA.C:1958
 getCellsRunsQA.C:1959
 getCellsRunsQA.C:1960
 getCellsRunsQA.C:1961
 getCellsRunsQA.C:1962
 getCellsRunsQA.C:1963
 getCellsRunsQA.C:1964
 getCellsRunsQA.C:1965
 getCellsRunsQA.C:1966
 getCellsRunsQA.C:1967
 getCellsRunsQA.C:1968
 getCellsRunsQA.C:1969
 getCellsRunsQA.C:1970
 getCellsRunsQA.C:1971
 getCellsRunsQA.C:1972
 getCellsRunsQA.C:1973
 getCellsRunsQA.C:1974
 getCellsRunsQA.C:1975
 getCellsRunsQA.C:1976
 getCellsRunsQA.C:1977
 getCellsRunsQA.C:1978
 getCellsRunsQA.C:1979
 getCellsRunsQA.C:1980
 getCellsRunsQA.C:1981
 getCellsRunsQA.C:1982
 getCellsRunsQA.C:1983
 getCellsRunsQA.C:1984
 getCellsRunsQA.C:1985
 getCellsRunsQA.C:1986
 getCellsRunsQA.C:1987
 getCellsRunsQA.C:1988
 getCellsRunsQA.C:1989
 getCellsRunsQA.C:1990
 getCellsRunsQA.C:1991
 getCellsRunsQA.C:1992
 getCellsRunsQA.C:1993
 getCellsRunsQA.C:1994
 getCellsRunsQA.C:1995
 getCellsRunsQA.C:1996
 getCellsRunsQA.C:1997
 getCellsRunsQA.C:1998
 getCellsRunsQA.C:1999
 getCellsRunsQA.C:2000
 getCellsRunsQA.C:2001
 getCellsRunsQA.C:2002
 getCellsRunsQA.C:2003
 getCellsRunsQA.C:2004
 getCellsRunsQA.C:2005
 getCellsRunsQA.C:2006
 getCellsRunsQA.C:2007
 getCellsRunsQA.C:2008
 getCellsRunsQA.C:2009
 getCellsRunsQA.C:2010
 getCellsRunsQA.C:2011
 getCellsRunsQA.C:2012
 getCellsRunsQA.C:2013
 getCellsRunsQA.C:2014
 getCellsRunsQA.C:2015
 getCellsRunsQA.C:2016
 getCellsRunsQA.C:2017
 getCellsRunsQA.C:2018
 getCellsRunsQA.C:2019
 getCellsRunsQA.C:2020
 getCellsRunsQA.C:2021
 getCellsRunsQA.C:2022
 getCellsRunsQA.C:2023
 getCellsRunsQA.C:2024
 getCellsRunsQA.C:2025
 getCellsRunsQA.C:2026
 getCellsRunsQA.C:2027
 getCellsRunsQA.C:2028
 getCellsRunsQA.C:2029
 getCellsRunsQA.C:2030
 getCellsRunsQA.C:2031
 getCellsRunsQA.C:2032
 getCellsRunsQA.C:2033
 getCellsRunsQA.C:2034
 getCellsRunsQA.C:2035
 getCellsRunsQA.C:2036
 getCellsRunsQA.C:2037
 getCellsRunsQA.C:2038
 getCellsRunsQA.C:2039
 getCellsRunsQA.C:2040
 getCellsRunsQA.C:2041
 getCellsRunsQA.C:2042
 getCellsRunsQA.C:2043
 getCellsRunsQA.C:2044
 getCellsRunsQA.C:2045
 getCellsRunsQA.C:2046
 getCellsRunsQA.C:2047
 getCellsRunsQA.C:2048
 getCellsRunsQA.C:2049
 getCellsRunsQA.C:2050
 getCellsRunsQA.C:2051
 getCellsRunsQA.C:2052
 getCellsRunsQA.C:2053
 getCellsRunsQA.C:2054
 getCellsRunsQA.C:2055
 getCellsRunsQA.C:2056
 getCellsRunsQA.C:2057
 getCellsRunsQA.C:2058
 getCellsRunsQA.C:2059
 getCellsRunsQA.C:2060
 getCellsRunsQA.C:2061
 getCellsRunsQA.C:2062
 getCellsRunsQA.C:2063
 getCellsRunsQA.C:2064
 getCellsRunsQA.C:2065
 getCellsRunsQA.C:2066
 getCellsRunsQA.C:2067
 getCellsRunsQA.C:2068
 getCellsRunsQA.C:2069
 getCellsRunsQA.C:2070
 getCellsRunsQA.C:2071
 getCellsRunsQA.C:2072
 getCellsRunsQA.C:2073
 getCellsRunsQA.C:2074
 getCellsRunsQA.C:2075
 getCellsRunsQA.C:2076
 getCellsRunsQA.C:2077
 getCellsRunsQA.C:2078
 getCellsRunsQA.C:2079
 getCellsRunsQA.C:2080
 getCellsRunsQA.C:2081
 getCellsRunsQA.C:2082
 getCellsRunsQA.C:2083
 getCellsRunsQA.C:2084
 getCellsRunsQA.C:2085
 getCellsRunsQA.C:2086
 getCellsRunsQA.C:2087
 getCellsRunsQA.C:2088
 getCellsRunsQA.C:2089
 getCellsRunsQA.C:2090
 getCellsRunsQA.C:2091
 getCellsRunsQA.C:2092
 getCellsRunsQA.C:2093
 getCellsRunsQA.C:2094
 getCellsRunsQA.C:2095
 getCellsRunsQA.C:2096
 getCellsRunsQA.C:2097
 getCellsRunsQA.C:2098
 getCellsRunsQA.C:2099
 getCellsRunsQA.C:2100
 getCellsRunsQA.C:2101
 getCellsRunsQA.C:2102
 getCellsRunsQA.C:2103
 getCellsRunsQA.C:2104
 getCellsRunsQA.C:2105
 getCellsRunsQA.C:2106
 getCellsRunsQA.C:2107
 getCellsRunsQA.C:2108
 getCellsRunsQA.C:2109
 getCellsRunsQA.C:2110
 getCellsRunsQA.C:2111
 getCellsRunsQA.C:2112
 getCellsRunsQA.C:2113
 getCellsRunsQA.C:2114
 getCellsRunsQA.C:2115
 getCellsRunsQA.C:2116
 getCellsRunsQA.C:2117
 getCellsRunsQA.C:2118
 getCellsRunsQA.C:2119
 getCellsRunsQA.C:2120
 getCellsRunsQA.C:2121
 getCellsRunsQA.C:2122
 getCellsRunsQA.C:2123
 getCellsRunsQA.C:2124
 getCellsRunsQA.C:2125
 getCellsRunsQA.C:2126
 getCellsRunsQA.C:2127
 getCellsRunsQA.C:2128
 getCellsRunsQA.C:2129
 getCellsRunsQA.C:2130
 getCellsRunsQA.C:2131
 getCellsRunsQA.C:2132
 getCellsRunsQA.C:2133
 getCellsRunsQA.C:2134
 getCellsRunsQA.C:2135
 getCellsRunsQA.C:2136
 getCellsRunsQA.C:2137
 getCellsRunsQA.C:2138
 getCellsRunsQA.C:2139
 getCellsRunsQA.C:2140
 getCellsRunsQA.C:2141
 getCellsRunsQA.C:2142
 getCellsRunsQA.C:2143
 getCellsRunsQA.C:2144
 getCellsRunsQA.C:2145
 getCellsRunsQA.C:2146
 getCellsRunsQA.C:2147
 getCellsRunsQA.C:2148
 getCellsRunsQA.C:2149
 getCellsRunsQA.C:2150
 getCellsRunsQA.C:2151
 getCellsRunsQA.C:2152
 getCellsRunsQA.C:2153
 getCellsRunsQA.C:2154
 getCellsRunsQA.C:2155
 getCellsRunsQA.C:2156
 getCellsRunsQA.C:2157
 getCellsRunsQA.C:2158
 getCellsRunsQA.C:2159
 getCellsRunsQA.C:2160
 getCellsRunsQA.C:2161
 getCellsRunsQA.C:2162
 getCellsRunsQA.C:2163
 getCellsRunsQA.C:2164
 getCellsRunsQA.C:2165
 getCellsRunsQA.C:2166
 getCellsRunsQA.C:2167
 getCellsRunsQA.C:2168
 getCellsRunsQA.C:2169
 getCellsRunsQA.C:2170
 getCellsRunsQA.C:2171
 getCellsRunsQA.C:2172
 getCellsRunsQA.C:2173
 getCellsRunsQA.C:2174
 getCellsRunsQA.C:2175
 getCellsRunsQA.C:2176
 getCellsRunsQA.C:2177
 getCellsRunsQA.C:2178
 getCellsRunsQA.C:2179
 getCellsRunsQA.C:2180
 getCellsRunsQA.C:2181
 getCellsRunsQA.C:2182
 getCellsRunsQA.C:2183
 getCellsRunsQA.C:2184
 getCellsRunsQA.C:2185
 getCellsRunsQA.C:2186
 getCellsRunsQA.C:2187
 getCellsRunsQA.C:2188
 getCellsRunsQA.C:2189
 getCellsRunsQA.C:2190
 getCellsRunsQA.C:2191
 getCellsRunsQA.C:2192
 getCellsRunsQA.C:2193
 getCellsRunsQA.C:2194
 getCellsRunsQA.C:2195
 getCellsRunsQA.C:2196
 getCellsRunsQA.C:2197
 getCellsRunsQA.C:2198
 getCellsRunsQA.C:2199
 getCellsRunsQA.C:2200
 getCellsRunsQA.C:2201
 getCellsRunsQA.C:2202
 getCellsRunsQA.C:2203
 getCellsRunsQA.C:2204
 getCellsRunsQA.C:2205
 getCellsRunsQA.C:2206
 getCellsRunsQA.C:2207
 getCellsRunsQA.C:2208
 getCellsRunsQA.C:2209
 getCellsRunsQA.C:2210
 getCellsRunsQA.C:2211
 getCellsRunsQA.C:2212
 getCellsRunsQA.C:2213
 getCellsRunsQA.C:2214
 getCellsRunsQA.C:2215
 getCellsRunsQA.C:2216
 getCellsRunsQA.C:2217
 getCellsRunsQA.C:2218
 getCellsRunsQA.C:2219
 getCellsRunsQA.C:2220
 getCellsRunsQA.C:2221
 getCellsRunsQA.C:2222
 getCellsRunsQA.C:2223
 getCellsRunsQA.C:2224
 getCellsRunsQA.C:2225
 getCellsRunsQA.C:2226
 getCellsRunsQA.C:2227
 getCellsRunsQA.C:2228
 getCellsRunsQA.C:2229
 getCellsRunsQA.C:2230
 getCellsRunsQA.C:2231
 getCellsRunsQA.C:2232
 getCellsRunsQA.C:2233
 getCellsRunsQA.C:2234
 getCellsRunsQA.C:2235
 getCellsRunsQA.C:2236
 getCellsRunsQA.C:2237
 getCellsRunsQA.C:2238
 getCellsRunsQA.C:2239
 getCellsRunsQA.C:2240
 getCellsRunsQA.C:2241
 getCellsRunsQA.C:2242
 getCellsRunsQA.C:2243
 getCellsRunsQA.C:2244
 getCellsRunsQA.C:2245
 getCellsRunsQA.C:2246
 getCellsRunsQA.C:2247
 getCellsRunsQA.C:2248
 getCellsRunsQA.C:2249
 getCellsRunsQA.C:2250
 getCellsRunsQA.C:2251
 getCellsRunsQA.C:2252
 getCellsRunsQA.C:2253
 getCellsRunsQA.C:2254
 getCellsRunsQA.C:2255
 getCellsRunsQA.C:2256
 getCellsRunsQA.C:2257
 getCellsRunsQA.C:2258
 getCellsRunsQA.C:2259
 getCellsRunsQA.C:2260
 getCellsRunsQA.C:2261
 getCellsRunsQA.C:2262
 getCellsRunsQA.C:2263
 getCellsRunsQA.C:2264
 getCellsRunsQA.C:2265
 getCellsRunsQA.C:2266
 getCellsRunsQA.C:2267
 getCellsRunsQA.C:2268
 getCellsRunsQA.C:2269
 getCellsRunsQA.C:2270
 getCellsRunsQA.C:2271
 getCellsRunsQA.C:2272
 getCellsRunsQA.C:2273
 getCellsRunsQA.C:2274
 getCellsRunsQA.C:2275
 getCellsRunsQA.C:2276
 getCellsRunsQA.C:2277
 getCellsRunsQA.C:2278
 getCellsRunsQA.C:2279
 getCellsRunsQA.C:2280
 getCellsRunsQA.C:2281
 getCellsRunsQA.C:2282
 getCellsRunsQA.C:2283
 getCellsRunsQA.C:2284
 getCellsRunsQA.C:2285
 getCellsRunsQA.C:2286
 getCellsRunsQA.C:2287
 getCellsRunsQA.C:2288
 getCellsRunsQA.C:2289
 getCellsRunsQA.C:2290
 getCellsRunsQA.C:2291
 getCellsRunsQA.C:2292
 getCellsRunsQA.C:2293
 getCellsRunsQA.C:2294
 getCellsRunsQA.C:2295
 getCellsRunsQA.C:2296
 getCellsRunsQA.C:2297
 getCellsRunsQA.C:2298
 getCellsRunsQA.C:2299
 getCellsRunsQA.C:2300
 getCellsRunsQA.C:2301
 getCellsRunsQA.C:2302
 getCellsRunsQA.C:2303