ROOT logo
/**
 * @file   QATrender.C
 * @author Christian Holm Christensen <cholm@nbi.dk>
 * @date   Thu Nov 17 12:28:17 2011
 * 
 * @brief  Class to make the QA trending tree
 * 
 * @ingroup pwglf_forward_qa_scripts
 */
#ifndef __CINT__
# include <TFile.h>
# include <TTree.h>
# include <TH1.h>
# include <TH2.h>
# include <TList.h>
# include <TStyle.h>
# include <TCanvas.h>
# include <TPad.h>
# include <TLatex.h>
# include <TMath.h>
# include <THStack.h>
# include <TLegend.h>
# include <TLegendEntry.h>
# include <TLine.h>
# include <TLinearFitter.h>
# include <TF1.h>
# include <TSystem.h>
# include <fstream>
# include <TFile.h>
# include <TParameter.h>
# include "QAStructs.h"
# include "QARing.h"
# include "QABase.h"
#else
class TList;
class TFile;
class TH1;
class Quantity;
class RingQuantity;
class Merge;
class FitStatus;
class Correlation;
class QARing;
class QABase;
class Global;
class THStack;
class TLatex;
class TVirtualPad;
#endif 


// --- A quantity ----------------------------------------------------
/** 
 * Class to make the QA trending tree
 * 
 * @ingroup pwglf_forward_qa_scripts
 */
struct QATrender : public QABase
{
public:
  /******************************************************************/
  /** 
   * A ring object
   * 
   */
  struct Ring : public QARing
  { 
    /** 
     * Constructor 
     * 
     * @param d Detector 
     * @param r Ring
     */
    Ring(UShort_t d, Char_t r) : QARing(d, r)  {}
    /** 
     * Get the detector specific list 
     * 
     * @param parent Parent list  
     * 
     * @return Found list or null
     */
    TList* GetDetectorList(const TList* parent) const 
    {
      TObject* o = QATrender::GetSubList(parent, Form("FMD%d%c", fD, fR));
      return static_cast<TList*>(o);
    }
    /** 
     * Calculate numbers from read histograms
     * 
     * @param parent Parent list 
     * @param name   Name of histogram
     * @param q      Qauntity to store in
     * 
     * @return true on success 
     */
    Bool_t ExtractYQuantity(const TList* parent, const char* name, 
			    Quantity* q)
    {
      q->mean  = 0;
      q->var   = 0;
      q->min   = 0;
      q->max   = 0;

      TH1* h = QATrender::GetHistogram(parent, name);
      if (!h) {
	// Warning("ExtractYQuantity", "Histogram %s not found", name);
	return false;
      }
      
      Double_t sum   = 0;
      Double_t sumw  = 0;
      Double_t min   = 1e12;
      Double_t max   = 0;
      for (Int_t i = 1; i <= h->GetNbinsX(); i++) {
	Double_t y = h->GetBinContent(i);
	Double_t e = h->GetBinError(i);
	Double_t w = 1;
	if (y <= 1e-12) continue;
	if (e != 0) w = 1 / (e*e);
	sum   += w * y;
	sumw  += w;
	min  =  TMath::Min(min, y);
	max  =  TMath::Max(max, y);
	// Info("", "  %s %3d: y=%f,\t e=%f,\t w=%f", name, i, y, e, w); 
      }
      q->min  = min;
      q->max  = max;
      if (sumw <= 1e-6) {
	// Warning("ExtractYQuantity", 
	//         "Sum of weights for %s too small %g<1e-6",
	//         name, sumw);
	return true;
      }
      q->mean = sum / sumw;
      q->var  = TMath::Sqrt(1/sumw);
      // Info(name, " mean=%f, var=%f", q->mean, q->var);
      return true;
    }
    /** 
     * Process data from the energy loss fits
     * 
     * @param parent Parent list 
     * 
     * @return true on success 
     */
    Bool_t ProcessEnergyLoss(const TList* parent)
    {
      TList* det = GetDetectorList(parent);
      if (!det) return false;

      TList* res = QATrender::GetSubList(det, "FitResults");
      if (!res) return false;
      
      ExtractYQuantity(res, Form("FMD%d%c_chi2",  fD, fR), fChi2);
      ExtractYQuantity(res, Form("FMD%d%c_c",     fD, fR), fC);
      ExtractYQuantity(res, Form("FMD%d%c_delta", fD, fR), fDelta);
      ExtractYQuantity(res, Form("FMD%d%c_xi",    fD, fR), fXi);
      ExtractYQuantity(res, Form("FMD%d%c_sigma", fD, fR), fSigma);

      TH1* status = QATrender::GetHistogram(res, "status");
      if (!status) return false;
      fFitStatus->nLow        = UShort_t(status->GetBinContent(3));
      fFitStatus->nCandidates = UShort_t(status->GetBinContent(4));
      fFitStatus->nFitted     = UShort_t(status->GetBinContent(5));
      
      return true;
    }
    /** 
     * Process data on neighbors 
     * 
     * @param parent Parent list 
     * @param p      (optional) Pad to draw
     * 
     * @return true on success
     */
    Bool_t ProcessNeighbors(const TList* parent, TVirtualPad* p) 
    {
      if (!p) return true;  // Case of no drawing 

      TList* det = GetDetectorList(parent);
      if (!det) return false;

      TH1* before = QATrender::GetHistogram(det, "neighborsBefore");
      TH1* after  = QATrender::GetHistogram(det, "neighborsAfter");
      if (!before || !after) return false;
      
      if (before->GetMaximum() > 0) p->SetLogz();
      p->SetFillColor(0);
      if (fD == 3) p->SetRightMargin(0.15);

      before->SetTitle(Form("FMD%d%c",fD,fR));
      before->Draw("colz");
      after->Draw("same box");

      before->GetXaxis()->SetRangeUser(-.5, 2);
      before->GetYaxis()->SetRangeUser(-.5, 2);

      TLatex* ltx = new TLatex(p->GetLeftMargin()+.01, 
			       p->GetBottomMargin()+.01, 
			       before->GetTitle());
      ltx->SetNDC();
      ltx->SetTextSize(.07);
      ltx->Draw();      

      return true;
    }
    /** 
     * Process data on single, double, and triple hits
     * 
     * @param parent Parent list
     * @param p      (optional) Pad to draw
     * 
     * @return true on success
     */
    Bool_t Process123(const TList* parent, TVirtualPad* p) 
    {
      TList* det = GetDetectorList(parent);
      if (!det) return false;

      fMerge->one     = 0;
      fMerge->two     = 0;
      fMerge->three   = 0;

      TH1* one   = QATrender::GetHistogram(det, "singleEloss");
      TH1* two   = QATrender::GetHistogram(det, "doubleEloss");
      TH1* three = QATrender::GetHistogram(det, "tripleEloss");
      if (!one || !two || !three) return false;

      Int_t    nOne   = one->GetEntries();
      Int_t    nTwo   = two->GetEntries();
      Int_t    nThree = three->GetEntries();
      Int_t    total  = nOne + nTwo + nThree; 
      if (total > 0) { 
	fMerge->one     = Double_t(nOne) / total;
	fMerge->two     = Double_t(nTwo) / total;
	fMerge->three   = Double_t(nThree) / total;
      }

      if (!p) return true;

      one->SetStats(0);
      one->SetTitle(Form("FMD%d%c", fD, fR));
      one->GetXaxis()->SetRangeUser(0, 8);
      
      if (one->GetMaximum() > 0) p->SetLogy();
      p->SetFillColor(0);
      if ((p->GetNumber() % 3) != 1) p->SetLeftMargin(.1);
      
      one->SetLineStyle(1);
      two->SetLineStyle(2);
      three->SetLineStyle(3);

      one->Draw();
      two->Draw("same");
      three->Draw("same");

      // Double_t ts  = 0.03;
      Double_t y = 1-p->GetTopMargin()-1.2*gStyle->GetTitleH(); // +ts;
      Double_t x = p->GetLeftMargin() + .25;
      TLatex* ltx = new TLatex(x, y, "Fraction of ...");
      ltx->SetNDC();
      ltx->SetTextColor(kBlue+3);
      ltx->SetTextAlign(13);
      // ltx->SetTextAlign(33);
      ltx->SetTextSize(.07);
      ltx->Draw();      

      // y -= .1;
      DrawText(ltx, x, y, "Singles:", Form("%5.2f%%", fMerge->one * 100));
      DrawText(ltx, x, y, "Doubles:", Form("%5.2f%%", fMerge->two * 100));
      DrawText(ltx, x, y, "Triples:", Form("%5.2f%%", fMerge->three * 100));

      p->cd();

      return true;
    }
    /** 
     * Process energy loss distributions 
     * 
     * @param p1     First parent list (sharing filter)
     * @param p2     Second parent list (density calculator)
     * @param p      (optional) Pad to draw
     * 
     * @return true on success
     */
    Bool_t ProcessELoss(TList* p1, TList* p2, TVirtualPad* p)
    {
      TList* det1 = GetDetectorList(p1);
      if (!det1) return false;

      TList* det2 = GetDetectorList(p2);
      if (!det2) return false;

      TH1* before    =  QATrender::GetHistogram(det1, "esdEloss");
      TH1* after     =  QATrender::GetHistogram(det1, "anaEloss");
      TH1* presented =  QATrender::GetHistogram(det2, "eloss");
      TH1* used      =  QATrender::GetHistogram(det2, "elossUsed");

      if (!before || !after || !presented || !used) return false;

      const Double_t lowCut = 0.15;

      Int_t low = before->GetXaxis()->FindBin(lowCut);
      Int_t ib  = Int_t(before->Integral(low,before->GetNbinsX()));
      Int_t ia  = Int_t(after->Integral(low,after->GetNbinsX()));
      Int_t ip  = Int_t(presented->Integral(low,presented->GetNbinsX()));
      Int_t iu  = Int_t(used->Integral(low,used->GetNbinsX()));

      Double_t dba = ib > 0 ? (100.*(ia-ib))/ib : 0;
      Double_t dbp = ib > 0 ? (100.*(ip-ib))/ib : 0;
      Double_t dbu = ib > 0 ? (100.*(iu-ib))/ib : 0;
      Double_t dap = ia > 0 ? (100.*(ip-ia))/ia : 0;
      Double_t dau = ia > 0 ? (100.*(iu-ia))/ia : 0;
      Double_t dpu = ip > 0 ? (100.*(iu-ip))/ip : 0;
      
      fDataLoss->merge   = dba;
      fDataLoss->density = dau;
      fDataLoss->full    = dbu;

      if (!p) return true;

      if (before->GetMaximum() > 0) p->SetLogy();
      p->SetFillColor(0);
      before->SetTitle(Form("FMD%d%c",fD,fR));

      before->SetLineStyle(1);
      after->SetLineStyle(2);
      used->SetLineStyle(3);

      before->Draw("");
      after->Draw("same");
      presented->Draw("same");
      used->Draw("same");
  
      Double_t ts  = 0.03;
      Double_t x   = p->GetLeftMargin() + .25;
      Double_t y   = 1-p->GetTopMargin()-gStyle->GetTitleH()+ts;
      TLatex*  ltx = new TLatex(x, y, Form("FMD%d%c", fD, fR));
      ltx->SetNDC();
      ltx->SetTextAlign(13);
      ltx->SetTextSize(ts);
      ltx->SetTextColor(kBlue+3);
      // ltx->Draw();
      // ltx->SetTextSize(.05);
      TString inte(Form("Integral [%4.2f,#infty]", lowCut));
      DrawText(ltx, x, y, Form("%s before:", inte.Data()), Form("%9d", ib));
      DrawText(ltx, x, y, Form("%s after:",  inte.Data()), Form("%9d", ia));
      DrawText(ltx, x, y, Form("%s input:",  inte.Data()), Form("%9d", ip));
      DrawText(ltx, x, y, Form("%s user:",   inte.Data()), Form("%9d", iu));
      TLine* l = new TLine;
      l->SetLineWidth(1);
      l->DrawLineNDC(x, y-0.9*ts, 1-p->GetRightMargin()-0.01, y-0.9*ts);
      if (ib != 0 && ia != 0) {
	DrawText(ltx, x, y, "Change (merging)", Form("%5.1f%%", dba));
	DrawText(ltx, x, y, "Change (input)",   Form("%5.1f%% (%5.1f%%)", 
						     dap, dbp));
	DrawText(ltx, x, y, "Change (use)",     Form("%5.1f%% (%5.1f%%)", 
						     dpu, dbu));
      }
      before->GetXaxis()->SetRangeUser(0, 4);
      p->cd();

      return true;
    }
    /** 
     * Process occupancy information 
     * 
     * @param parent Parent list 
     * @param p      (optional) Pad to draw
     * 
     * @return true on success
     */
    Bool_t ProcessOccupancy(const TList* parent, TVirtualPad* p) 
    {
      TList* det = GetDetectorList(parent);
      if (!det) return false;

      TH1* occ   = QATrender::GetHistogram(det, "occupancy");
      if (!occ) return false;

      fOccupancy->mean = occ->GetMean();
      fOccupancy->var  = occ->GetRMS();
      fOccupancy->min  = 1;
      fOccupancy->max  = 0;

      for (Int_t i = occ->GetNbinsX(); i >= 1; i--) {
	Double_t y = occ->GetBinContent(i);
	if (y < 1e-6) continue;
	fOccupancy->max = occ->GetXaxis()->GetBinUpEdge(i);
	break;
      }
      
      if (!p) return true;
      p->SetGridy();
      p->SetGridx();
      if (occ->GetMaximum() > 0) p->SetLogy();
      p->SetFillColor(0);
      p->SetRightMargin(0.01);
      occ->Rebin(4);
      occ->SetTitle(Form("FMD%d%c", fD, fR));
      occ->Draw("hist");

      // Double_t ts  = 0.03;
      Double_t y = 1-p->GetTopMargin()-1.2*gStyle->GetTitleH(); // +ts;
      Double_t x = p->GetLeftMargin() + .25;
      TLatex* ltx = new TLatex(x, y, "");
      ltx->SetNDC();
      ltx->SetTextColor(kBlue+3);
      ltx->SetTextAlign(13);
      // ltx->SetTextAlign(33);
      ltx->SetTextSize(.07);
      ltx->Draw();      

      // y -= .1;
      DrawText(ltx, x, y, "Mean:",     Form("%5.2f%%", fOccupancy->mean));
      DrawText(ltx, x, y, "Variance:", Form("%5.2f%%", fOccupancy->var));
      DrawText(ltx, x, y, "Max:",      Form("%5.2f%%", fOccupancy->max));

      p->cd();

      return true;
    }
    /** 
     * Process method correlations 
     * 
     * @param parent Parent list
     * @param p      (optional) Pad to draw
     * 
     * @return true on success
     */
    Bool_t ProcessCorrelation(const TList* parent, TVirtualPad* p) 
    {
      TList* det = GetDetectorList(parent);
      if (!det) return false;

      TH1* co   = QATrender::GetHistogram(det, "elossVsPoisson");
      if (!co) return false;
      TH2* corr = static_cast<TH2*>(co);

      fCorrelation->alpha = 0;
      fCorrelation->beta  = 0;
      fCorrelation->a     = 0;
      fCorrelation->ea    = 0;
      fCorrelation->b     = 0;
      fCorrelation->eb    = 0;
      fCorrelation->chi2  = 0;

      Double_t xmin = -1;
      Double_t xmax = corr->GetXaxis()->GetXmax();

      if (corr->GetEntries() > 0) {
	// Calculate the linear regression 
	// Double_t dx    = (xmax-xmin);
	// Double_t rxy   = corr->GetCorrelationFactor();
	Double_t sx    = corr->GetRMS(1);
	Double_t sy    = corr->GetRMS(2);
	Double_t sx2   = sx*sx;
	Double_t sy2   = sy*sy;
	Double_t cxy   = corr->GetCovariance();
	Double_t mx    = corr->GetMean(1);
	Double_t my    = corr->GetMean(2);
	Double_t delta = 1;
	if (TMath::Abs(cxy) > 1e-6) {
	  fCorrelation->beta  = ((sy2 - delta*sx2 + 
				  TMath::Sqrt(TMath::Power(sy2-delta*sx2,2) + 
					      4*delta*cxy*cxy)) / 2 / cxy);
	  fCorrelation->alpha = my - fCorrelation->beta * mx;
	}


#if 0
	TLinearFitter* fitter = new TLinearFitter(1);
	fitter->SetFormula("1 ++ x");
	for (Int_t i = 1; i <= corr->GetNbinsX(); i++) { 
	  Double_t x = corr->GetXaxis()->GetBinCenter(i);
	  if (x < -1 || x > xmax) continue;
	  for (Int_t j = 1; j <= corr->GetNbinsY(); j++) {
	    Double_t y = corr->GetYaxis()->GetBinCenter(j);
	    if (y < -1 || y > xmax) continue;
	    Double_t c = corr->GetBinContent(i,j);
	    if (c < .1) continue;
	    fitter->AddPoint(&x, y, c);
	  }
	}
	fitter->Eval();
	fCorrelation->a    = fitter->GetParameter(0);
	fCorrelation->ea   = fitter->GetParError(0); 
	fCorrelation->b    = fitter->GetParameter(1);
	fCorrelation->eb   = fitter->GetParError(1);
	Double_t chi2 = fitter->GetChisquare();
	Int_t    ndf  = (fitter->GetNpoints() - 
			 fitter->GetNumberFreeParameters() );
	fCorrelation->chi2 = chi2 / ndf;
#endif
      }
      if (!p) return true;

      p->SetGridy();
      p->SetGridx();
      if (corr->GetMaximum() > 0) p->SetLogz();
      // if (fD == 3) p->SetRightMargin(0.15);
      p->SetFillColor(0);
      corr->GetXaxis()->SetRangeUser(-1,xmax);
      corr->GetYaxis()->SetRangeUser(-1,xmax);
      corr->SetTitle(Form("FMD%d%c",fD,fR));
      corr->Draw("colz");

      TF1* f = new TF1("f", "[0]+[1]*x", xmin, xmax);
      f->SetParameters(fCorrelation->alpha, fCorrelation->beta);
      f->SetLineWidth(1);
      f->SetLineStyle(1);
      f->Draw("same");
      
      TLine* l = new TLine(-1,-1,xmax,xmax);
      l->SetLineWidth(1);
      l->SetLineStyle(2);
      l->SetLineColor(kBlack);
      l->Draw();

      Double_t x   = p->GetLeftMargin() + .05;
      Double_t y   = 1-p->GetTopMargin()-gStyle->GetTitleH(); // +ts;
      TLatex* ltx = new TLatex(x, y, "Deming regression: y=#alpha+#beta x");
      ltx->SetNDC();
      ltx->SetTextAlign(13);
      ltx->SetTextSize(0.06);
      ltx->SetTextColor(kBlue+3);
      ltx->Draw();

      DrawText(ltx, x, y, "#alpha:", Form("%5.3f", fCorrelation->alpha));
      DrawText(ltx, x, y, "#beta:",  Form("%5.3f", fCorrelation->beta));

#if 0
      DrawText(ltx, x, y, "A:",      Form("%5.3f#pm%5.3f", 
					  fCorrelation->a,
					  fCorrelation->ea));
      DrawText(ltx, x, y, "B:",      Form("%5.3f#pm%5.3f", 
					  fCorrelation->b,
					  fCorrelation->eb));
      DrawText(ltx, x, y, "#chi^{2}/#nu:", Form("%5.3f", fCorrelation->chi2));
#endif
      p->cd();

      return true;
    }
  };

  /******************************************************************/
  /** 
   * Backward compatibility mode constructor 
   * 
   * @param keep       Keep temporary files
   * @param single     Not used  
   * @param prodYear   Period year 
   * @param prodLetter Period letter
   */
  QATrender(Bool_t keep, 
	    Bool_t /*single*/, 
	    Int_t  prodYear, 
	    char   prodLetter) 
    : QABase("data", (prodYear < 2000 ? 2000 : 0) + prodYear,
	     Form("LHC%02d%c", (prodYear%2000), prodLetter), "pass0"),
      fRunNo(-1),
      fCurrentFile(0),
      fSharingFilter(0),
      fEventInspector(0),
      fDensityCalculator(0),
      fEnergyFitter(0),
      fFiles(0), 
      fKeep(keep)
  {
    fFMD1i = new Ring(1, 'I'); 
    fFMD2i = new Ring(2, 'I'); 
    fFMD2o = new Ring(2, 'O'); 
    fFMD3i = new Ring(3, 'I'); 
    fFMD3o = new Ring(3, 'O'); 
  }      
  /** 
   * CTOR
   * 
   * @param keep      Whehter to keep all info 
   * @param dataType  Data stype 
   * @param prodYear   Production yea4 
   * @param prodLetter Production letter
   */
  QATrender(Bool_t         keep, 
	    const TString& dataType, 
	    Int_t          prodYear,
	    const TString& period, 
	    const TString& pass, 
	    Long_t         runNo)
    : QABase(dataType, prodYear, period, pass),
      fRunNo(runNo),
      fCurrentFile(0),
      fSharingFilter(0),
      fEventInspector(0),
      fDensityCalculator(0),
      fEnergyFitter(0),
      fFiles(0), 
      fKeep(keep)
  {
    fFMD1i = new Ring(1, 'I'); 
    fFMD2i = new Ring(2, 'I'); 
    fFMD2o = new Ring(2, 'O'); 
    fFMD3i = new Ring(3, 'I'); 
    fFMD3o = new Ring(3, 'O'); 
  }
  /** 
   * DTOR
   */
  virtual ~QATrender() {} 
  /**
   * Copy CTOR
   * 
   * @param o Object to copy from 
   */
  QATrender(const QATrender& o) 
    : QABase(o), 
      fRunNo(o.fRunNo),
      fCurrentFile(o.fCurrentFile),
      fSharingFilter(o.fSharingFilter),
      fEventInspector(o.fEventInspector),
      fDensityCalculator(o.fDensityCalculator),
      fEnergyFitter(o.fEnergyFitter),
      fFiles(0), 
      fKeep(o.fKeep)
  {} 
  /**
   * Assignment operator 
   *
   * @return Reference to this 
   */
  QATrender operator=(const QATrender&) { return *this; }


  // --- Interface ---------------------------------------------------
  /** 
   * Add a file to be processed
   * 
   * @param filename Name of file 
   */
  void AddFile(const char* filename)
  {
    fFiles.Add(new TObjString(filename));
  }
  /** 
   * Run the job
   * 
   * @return true on success
   */
  Bool_t Run()
  {
    Init(false);
    TIter next(&fFiles);
    TObject* o = 0;
    Bool_t ret = true;
    while ((o = next())) {
      if (!ProcessOne(o->GetName())) ret = false;
    }
    Finish();
    return ret;
  }
  /** 
   * Finish the job
   * 
   */
  void Finish()
  {
    if (!fOutput) return;
    TList* l = fTree->GetUserInfo();
    l->Add(new TNamed("period", fPeriod.Data()));
    l->Add(new TNamed("pass", fPass.Data()));
    l->Add(new TNamed("type", fDataType.Data()));
    l->Add(new TParameter<Long_t>("year", fYear));
    fOutput->Write();
    fOutput->Close();
    fOutput = 0;
    fTree   = 0;
    std::ofstream doc(".doc");
    doc << fPeriod << " " << fPass << " ("
	<< fDataType << ") " << fRunNo << std::endl;
    doc.close();
    gSystem->Exec(Form("chmod g+rw %s", OutputName()));
  }
  /** 
   * Process a single file 
   * 
   * @param filename File to open. 
   * 
   * @return true on success 
   */
  Bool_t ProcessOne(const char* filename)
  {
    if (fCurrentFile) { 
      fCurrentFile->Close();
      fCurrentFile = 0;
    }

    fCurrentFile = TFile::Open(filename, "READ");
    if (!fCurrentFile) { 
      Error("ProcessOne", "Failed to open %s", filename);
      return false;
    }
    
    if (!GetLists()) { 
      // Error("ProcessOne", "Failed to get lists from %s", filename);
      return false;
    }
    
    if (!ProcessGlobal()) { 
      Error("ProcessOne", "Failed to get global stuff from %s", filename);
      return false;
    }
    // fTeXName = Form("qa_%09d", fGlobal->runNo);
    TString title;
    if (!fPeriod.IsNull() && !fPass.IsNull())
      title.Form("QA plots for %s/%s run %ld (%s)", 
		 fPeriod.Data(), fPass.Data(), fRunNo, fDataType.Data());
    else 
      title.Form("QA plots for run %d", fGlobal->runNo);
    MakeCanvas(title);
    Bool_t eloss = ProcessELossFitter();
    Bool_t merge = ProcessSharingFilter();
    Bool_t dense = ProcessDensityCalculator();
    if (fTree) fTree->Fill();
    CloseCurrent();

    return eloss && merge && dense;
  }
  // --- Processing member functions ---------------------------------
  /** 
   * Get global stuff 
   * 
   * @return true on success
   */
  Bool_t ProcessGlobal()
  {
    TObject* oRun = GetObject(fEventInspector, "runNo");
    if (!oRun) return false;
    
    fGlobal->runNo = oRun->GetUniqueID();
    if (fRunNo <= 0) fRunNo = fGlobal->runNo;

    TH1* oAcc = GetHistogram(fEventInspector,"nEventsAccepted");
    if (!oAcc) return false; 

    fGlobal->nAccepted = oAcc->GetEntries();
    fGlobal->meanVz    = oAcc->GetMean();
    fGlobal->sigmaVz   = oAcc->GetRMS();
    
    return true;
  }
  /** 
   * Clean a stack for histograms that match @a what 
   * 
   * @param stack Stack to clean 
   * @param what  Pattern 
   */
  void CleanStack(THStack* stack, const char* what)
  {
    TList*   l = stack->GetHists();
    if (!l || l->GetEntries() <= 0) {
      Warning("CleanStack", "No histograms in stack %s", stack->GetName());
      return;
    }
    Printf("Stack to clean %s", stack->GetName());
    l->ls();
    
    // Clean up list of histogram.  Histograms with no entries or 
    // no functions are deleted.  We have to do this using the TObjLink 
    // objects stored in the list since ROOT cannot guaranty the validity 
    // of iterators when removing from a list - tsck.  Should just implement
    // TIter::Remove(). 
    TObjLink* lnk = l->FirstLink();
    while (lnk) {
      TObject* o = lnk->GetObject();
      TString  s(o->GetName());
      if (s.Contains(what)) {
	TObjLink* keep = lnk->Next();
	l->Remove(lnk);
	lnk = keep;
	continue;
      }
      lnk = lnk->Next();
    }
  }
  /** 
   * Process the information from the energy loss fitter 
   * 
   * 
   * @return true on succes
   */
  Bool_t ProcessELossFitter()
  {
    if (!fEnergyFitter) return true;

    MakeCanvasTitle("Summary of energy loss fits");

    THStack* chi2  = static_cast<THStack*>(GetObject(fEnergyFitter, "chi2"));
    THStack* c     = static_cast<THStack*>(GetObject(fEnergyFitter, "c"));
    THStack* delta = static_cast<THStack*>(GetObject(fEnergyFitter, "delta"));
    THStack* xi    = static_cast<THStack*>(GetObject(fEnergyFitter, "xi"));
    THStack* sigma = static_cast<THStack*>(GetObject(fEnergyFitter, "sigma"));

    if (!chi2)  return false;
    if (!c)     return false;
    if (!delta) return false;
    if (!xi)    return false;
    if (!sigma) return false;

    CleanStack(chi2, "_n");
    CleanStack(c,    "status");
    if (fCanvas) {
      const int nL = 3;
      THStack* stacks[] = { chi2, c, delta, xi, sigma, 0 };
      for (int i = 0; i < 5; i++) { 
	THStack*     stack = stacks[i];
	if (!stack->GetHists() || stack->GetHists()->GetEntries() < 0) {
	  Warning("", "No histograms in stack %s", stack->GetName());
	  continue;
	}
	TVirtualPad* p     = GetPad(i+1);
	// stack->GetHists()->ls();

	p->SetLeftMargin(.6/nL);
	p->SetTopMargin(.01);
	p->SetRightMargin(.01);
	p->SetFillColor(0);
	p->SetFillStyle(0);
	p->SetGridx();
	stack->Draw("nostack");
	stack->GetHistogram()->SetYTitle(stack->GetTitle());
	stack->GetHistogram()->SetXTitle("#eta");
	
	TAxis* yaxis = stack->GetHistogram()->GetYaxis();
	if (i == 0) yaxis->SetRangeUser(0,20); // Chi2
	if (i == 1) stack->SetMaximum(1);      // c
	if (i == 2) stack->SetMaximum(1);      // delta
	if (i == 3) stack->SetMaximum(0.1);   // xi
	if (i == 4) stack->SetMaximum(0.5);    // sigma{,n}
	// if (i == 0) p->SetLogy();
	yaxis->SetTitleSize(0.3/nL);
	yaxis->SetLabelSize(0.08);
	yaxis->SetTitleOffset(3/nL);
	yaxis->SetNdivisions(5);
	yaxis->SetTitleFont(42);
	yaxis->SetLabelFont(42);
	yaxis->SetDecimals();
	
	TAxis* xaxis = stack->GetHistogram()->GetXaxis();
	xaxis->SetTitleSize(0.3/nL);
	xaxis->SetLabelSize(0.08);
	xaxis->SetTitleOffset(2./nL);
	xaxis->SetNdivisions(10);
	xaxis->SetTitleFont(42);
	xaxis->SetLabelFont(42);
	xaxis->SetDecimals();      
	
	stack->Draw("nostack");
	p->cd();
      }
      TVirtualPad* p     = GetPad(6);
      p->SetFillColor(kWhite);
      Double_t x = .3;
      Double_t y = .8;
      TLatex* l = new TLatex(x, y, "Fits to #Delta (energy loss) spectra");
      l->SetTextColor(kBlue+3);
      l->SetNDC();
      l->Draw();
      x = .05;
      y -= 2 * 1.2*l->GetTextSize();
      l->DrawLatex(x, y, "F(#Delta;c,#Delta_{p},#xi,#sigma)="
		   "#frac{c}{#sqrt{2#pi}#sigma}#int_{-#infty}^{#infty}d#Delta'"
		   "L(#Delta;#Delta',#xi) G(#Delta_{p};#Delta',#sigma^{2})");
      y -= 1.2*l->GetTextSize();
      x += .1;
      DrawText(l, x, y, "#chi^{2}/#nu", "Goodness of fit",         .2);
      DrawText(l, x, y, "c",            "Overall constant",        .2); 
      DrawText(l, x, y, "#Delta_{p}",   "Most probable value",     .2);
      DrawText(l, x, y, "#xi",          "'Width' of Landau (L)",   .2);
      DrawText(l, x, y, "#sigma",       "'Width' of Gaussian (G)", .2);
      
      // stack->GetHists()->ls();

      PrintCanvas("fitResults", fGlobal->runNo);
    }
    
    static_cast<Ring*>(fFMD1i)->ProcessEnergyLoss(fEnergyFitter);
    static_cast<Ring*>(fFMD2i)->ProcessEnergyLoss(fEnergyFitter);
    static_cast<Ring*>(fFMD2o)->ProcessEnergyLoss(fEnergyFitter);
    static_cast<Ring*>(fFMD3i)->ProcessEnergyLoss(fEnergyFitter);
    static_cast<Ring*>(fFMD3o)->ProcessEnergyLoss(fEnergyFitter);

    return true;
  }
  /** 
   * Process the information from the sharing filter 
   * 
   * 
   * @return true on success
   */
  Bool_t ProcessSharingFilter()
  {
    // --- Neighbors -------------------------------------------------
    MakeCanvasTitle("Correlation of neighboring strips");
    
    for (Int_t i = 1; i <= 6; i++) { 
      TVirtualPad* p = GetPad(i);

      Ring* r = GetRing(i);
      if (!r) continue;

      r->ProcessNeighbors(fSharingFilter, p);
    }
    TVirtualPad* p = 0;
    if ((p = GetPad(4))) {
      p->SetFillColor(kWhite);
      
      TLatex* l = new TLatex(.2, .7, "Gradient: before merging");
      l->SetNDC();
      l->SetTextColor(kBlue+3);
      l->Draw();
      l->DrawText(.2, .6, "Boxes: after merging");
      
      fCanvas->cd();
      PrintCanvas("neighbors", fGlobal->runNo);
    }

    // --- 123 -------------------------------------------------------
    MakeCanvasTitle("#Delta for singles, doubles, and triples");
    
    for (Int_t i = 1; i <= 6; i++) { 
      p = GetPad(i);

      Ring* r = GetRing(i);
      if (!r) continue;

      r->Process123(fSharingFilter, p);
    }
    if ((p = GetPad(4))) { 
      TLegend* ll = new TLegend(.2, .2, .8, .8);
      ll->SetFillColor(0);
      ll->SetBorderSize(0);
      TLegendEntry* e = ll->AddEntry("dummy", "Singles", "l");
      e->SetLineStyle(1);
      e = ll->AddEntry("dummy", "Doubles", "l");
      e->SetLineStyle(2);
      e = ll->AddEntry("dummy", "Triples", "l");
      e->SetLineStyle(3);
      ll->Draw();
      
      PrintCanvas("123", fGlobal->runNo);
    }
    return true;
  }
  /** 
   * Process the information from the density calculator 
   * 
   * 
   * @return true on success
   */
  Bool_t ProcessDensityCalculator()
  {
    // --- ELoss -----------------------------------------------------
    MakeCanvasTitle("Energy loss from ESD, after merging, used");
    
    for (Int_t i = 1; i <= 6; i++) { 
      TVirtualPad* p = GetPad(i);

      Ring* r = GetRing(i);
      if (!r) continue;

      r->ProcessELoss(fSharingFilter, fDensityCalculator, p);
    }
    TVirtualPad* p = 0;
    if ((p = GetPad(4))) {
      TLegend* ll = new TLegend(.2, .2, .8, .8);
      ll->SetFillColor(0);
      ll->SetBorderSize(0);
      TLegendEntry* e = ll->AddEntry("dummy", "From ESDs", "l");
      e->SetLineStyle(1);
      e = ll->AddEntry("dummy", "After Merging", "l");
      e->SetLineStyle(2);
      e = ll->AddEntry("dummy", "Used", "l");
      e->SetLineStyle(3);
      ll->Draw();
      
      PrintCanvas("recAna", fGlobal->runNo);
    }

    // --- Occupancy -------------------------------------------------
    MakeCanvasTitle("Occupancy");
    
    for (Int_t i = 1; i <= 6; i++) { 
      p = GetPad(i);

      Ring* r = GetRing(i);
      if (!r) continue;

      r->ProcessOccupancy(fDensityCalculator, p);
    }
    if ((p = GetPad(4))) {
      TLatex* ltx = new TLatex(.2, .8, "Calculated assuming Poisson stat.");
      ltx->SetNDC();
      ltx->SetTextColor(kBlue+3);
      ltx->Draw();
      
      TObject* etaL = GetObject(fDensityCalculator, "etaLumping");
      TObject* phiL = GetObject(fDensityCalculator, "phiLumping");
      if (etaL && phiL) 
	ltx->DrawLatex(.2, .7, Form("Regions of %s strips #times %s sectors",
				    etaL->GetTitle(), phiL->GetTitle()));
      
      PrintCanvas("occupancy", fGlobal->runNo);
    }

    // --- Correlation of methods ------------------------------------
    MakeCanvasTitle("Correlation of N_{ch} methods");
    
    for (Int_t i = 1; i <= 6; i++) { 
      p = GetPad(i);

      Ring* r = GetRing(i);
      if (!r) continue;

      r->ProcessCorrelation(fDensityCalculator, p);
    }
    if ((p = GetPad(4))) {
      TLatex* ltx = new TLatex(.2, .8, "Correlation of N_{ch} methods");
      ltx->SetNDC();
      ltx->SetTextColor(kBlue+3);
      ltx->Draw();
      ltx->DrawLatex(.24, .7, "From #DeltaE fits along x");
      ltx->DrawLatex(.24, .6, "From Poisson assumption along y");
      ltx->DrawLatex(.24, .4, "Solid line: regression");
      ltx->DrawLatex(.24, .3, "Dashed line: x=y to guide the eye");
      
      PrintCanvas("elossVsPoisson", fGlobal->runNo);
    }

    return true;
  }

  // --- Utilities ---------------------------------------------------
  /** 
   * Close current file if open, and reset other pointers
   * 
   */
  void CloseCurrent()
  {
    if (fCurrentFile) {
      fCurrentFile->Close();
      fCurrentFile       = 0;
      fSharingFilter     = 0;
      fEventInspector    = 0;
      fDensityCalculator = 0;
      fEnergyFitter      = 0;
    }
    bool keep = fKeep; 
    // if (fSingle) keep = true;

    Close(!keep);
  }
  /** 
   * Write full job footer 
   * 
   */
  virtual void WriteLinks() 
  {
    const char* lbUrl = "https://alice-logbook.cern.ch/logbook/date_online.php";
    const char* crUrl = "http://alimonitor.cern.ch/configuration/index.jsp";
    const char* rpUrl = "http://alimonitor.cern.ch/runview/?run=";
    QABase::WriteLinks();

    TFile* results = TFile::Open("QAresults.root", "READ");
    if (results) { 
      *fHtml << "<h3>QA results</h3>\n"
	     << "<ul>\n"
	     << "<li><a href='QAresults.root'>ROOT file</a></li>\n"
	     << "</ul>"
	     << std::endl;
      results->Close();
    }

    *fHtml << "<h3>External links</h3>\n"
	   << "<ul>\n"
	   << "  <li><a target='_blank' href='" << lbUrl 
	   << "?p_cont=rund&p_run=" <<  fGlobal->runNo
	   << "&p_tab=dqm&p_dqmagent=FMDQAshifter'>DQM plots</a>"
	   << " (restricted)</li>\n" 
	   << "  <li><a target='_blank' href='" << crUrl 
	   << "?raw_run=" << fGlobal->runNo;
    if (!fPeriod.IsNull()) 
      *fHtml << "&partition=" << fPeriod;
    *fHtml << "'>Condition Table</a></li>\n"
	   << "  <li><a target='_blank' href='" << rpUrl << fGlobal->runNo 
	   << "'>Processing Details</a></li>\n"
	   << "</ul>" << std::endl;
  }

  /** 
   * Get the ring corresponding to a pad 
   * 
   * @param padNo Pad number 
   * 
   * @return Pointer to ring
   */
  Ring* GetRing(Int_t padNo) 
  {
    QARing* r = 0;
    switch(padNo) { 
    case 1: r = fFMD1i; break;
    case 2: r = fFMD2i; break;
    case 3: r = fFMD3i; break;
    case 5: r = fFMD2o; break;
    case 6: r = fFMD3o; break;
    }
    if (r) return static_cast<Ring*>(r);
    return 0;
  }
  /** 
   * Get the pad corresponding to a number.  Also clears the pad 
   * 
   * @param padNo Pad number to get
   * 
   * @return Pointer to pad or null
   */
  TVirtualPad* GetPad(Int_t padNo)
  {
    if (!fCanvas) return 0;
    TVirtualPad* p = fCanvas->cd(padNo);
    if (!p) return 0;
    p->Clear();
    p->SetFillColor(kWhite);
    return p;
  }

  /** 
   * Make canvas title. Canvas is divided into 3x2 pads 
   * 
   * @param what Title on canvas
   */
  void MakeCanvasTitle(const char* what)
  {
    if (!fCanvas) return;
    fCanvas->cd();

    CanvasTitle(what);
    fCanvas->Divide(3,2,0,0);
  }
  // --- List utilities ----------------------------------------------
  /** 
   * Get a sub-list from parent list 
   * 
   * @param parent Parent list 
   * @param name   Name of sub-list 
   * 
   * @return Pointer to the list 
   */
  static TList* GetSubList(const TList* parent, const char* name)
  {
    TList* tmp = static_cast<TList*>(parent->FindObject(name));
    if (!tmp) { 
      Error("GetLists", "List %s not found in %s", name, 
	    parent->GetName());
      return 0;
    }
    return tmp;
  }
  /** 
   * Get the lists from the file 
   * 
   * 
   * @return true on success
   */    
  Bool_t GetLists()
  {
    if (!fCurrentFile) return 0;
    
    const char* folder = "ForwardResults";
    TList* forward = static_cast<TList*>(fCurrentFile->Get(folder));
    if (!forward) { 
      const char* folder2 = "ForwardQAResults";
      forward = static_cast<TList*>(fCurrentFile->Get(folder2));
      if (!forward) { 
	const char* folder3 = "forwardQAResults";
	forward = static_cast<TList*>(fCurrentFile->Get(folder3));
	if (!forward) {
	  Error("GetLists", "List %s/%s/%s not found in %s", 
		folder, folder2, folder3, fCurrentFile->GetName());
	  return false;
	}
      }
    }
    
    fEventInspector    = GetSubList(forward, "fmdEventInspector");
    if (!fEventInspector) { 
      const char* sfolder = "ForwardSums";
      forward = static_cast<TList*>(fCurrentFile->Get(sfolder));
    }

    fEventInspector    = GetSubList(forward, "fmdEventInspector");
    fSharingFilter     = GetSubList(forward, "fmdSharingFilter");
    fDensityCalculator = GetSubList(forward, "fmdDensityCalculator");
    fEnergyFitter      = GetSubList(forward, "fmdEnergyFitter");

    if (!fSharingFilter)     return false; 
    if (!fEventInspector)    return false;
    if (!fDensityCalculator) return false;
    // if (!fEnergyFitter)      return false;

    return true;
  }
  /** 
   * Find and object in a list
   * 
   * @param list List to look in
   * @param name Name of object 
   * 
   * @return Pointer to object or null
   */
  static TObject* GetObject(const TList* list, const char* name)
  {
    if (!list) return 0;
    TObject* o = list->FindObject(name);
    if (!o) { 
      Error("GetObject", "Failed to find object %s in %s", 
	    name, list->GetName());
      return 0;
    }
    return o;
  }
  /** 
   * Get a histogram from a list 
   * 
   * @param list List 
   * @param name Name of histogram
   * 
   * @return Pointer to object or null
   */
  static TH1* GetHistogram(const TList* list, const char* name)
  {
    return static_cast<TH1*>(GetObject(list, name));
  }
  /** 
   * Draw some text on a pad 
   * 
   * @param l   LaTeX object to use 
   * @param x   x coordinate 
   * @param y   y coordinate (incremented on return)
   * @param c1  First text 
   * @param c2  Second text 
   * @param dx  Distance between c1 start and c2 start 
   */
  static void 
  DrawText(TLatex* l, Double_t x, Double_t& y, const char* c1, const char* c2,
	   Double_t dx=.4)
  {
    y -= 1.2*l->GetTextSize();
    l->DrawLatex(x,    y, c1);
    l->DrawLatex(x+dx, y, c2);
  }
  

  // --- Members -----------------------------------------------------
  Long_t  fRunNo;                // Run number (external)
  TFile*  fCurrentFile;          // Current input file 
  TList*  fSharingFilter;        // Sharing filter list
  TList*  fEventInspector;       // Event inspector list
  TList*  fDensityCalculator;    // Density calculator list 
  TList*  fEnergyFitter;         // Energy fitter list 
  TList   fFiles;                // List of files to process 
  Bool_t  fKeep;                 // Keep PNGs
};
//
// EOF
//



 QATrender.C:1
 QATrender.C:2
 QATrender.C:3
 QATrender.C:4
 QATrender.C:5
 QATrender.C:6
 QATrender.C:7
 QATrender.C:8
 QATrender.C:9
 QATrender.C:10
 QATrender.C:11
 QATrender.C:12
 QATrender.C:13
 QATrender.C:14
 QATrender.C:15
 QATrender.C:16
 QATrender.C:17
 QATrender.C:18
 QATrender.C:19
 QATrender.C:20
 QATrender.C:21
 QATrender.C:22
 QATrender.C:23
 QATrender.C:24
 QATrender.C:25
 QATrender.C:26
 QATrender.C:27
 QATrender.C:28
 QATrender.C:29
 QATrender.C:30
 QATrender.C:31
 QATrender.C:32
 QATrender.C:33
 QATrender.C:34
 QATrender.C:35
 QATrender.C:36
 QATrender.C:37
 QATrender.C:38
 QATrender.C:39
 QATrender.C:40
 QATrender.C:41
 QATrender.C:42
 QATrender.C:43
 QATrender.C:44
 QATrender.C:45
 QATrender.C:46
 QATrender.C:47
 QATrender.C:48
 QATrender.C:49
 QATrender.C:50
 QATrender.C:51
 QATrender.C:52
 QATrender.C:53
 QATrender.C:54
 QATrender.C:55
 QATrender.C:56
 QATrender.C:57
 QATrender.C:58
 QATrender.C:59
 QATrender.C:60
 QATrender.C:61
 QATrender.C:62
 QATrender.C:63
 QATrender.C:64
 QATrender.C:65
 QATrender.C:66
 QATrender.C:67
 QATrender.C:68
 QATrender.C:69
 QATrender.C:70
 QATrender.C:71
 QATrender.C:72
 QATrender.C:73
 QATrender.C:74
 QATrender.C:75
 QATrender.C:76
 QATrender.C:77
 QATrender.C:78
 QATrender.C:79
 QATrender.C:80
 QATrender.C:81
 QATrender.C:82
 QATrender.C:83
 QATrender.C:84
 QATrender.C:85
 QATrender.C:86
 QATrender.C:87
 QATrender.C:88
 QATrender.C:89
 QATrender.C:90
 QATrender.C:91
 QATrender.C:92
 QATrender.C:93
 QATrender.C:94
 QATrender.C:95
 QATrender.C:96
 QATrender.C:97
 QATrender.C:98
 QATrender.C:99
 QATrender.C:100
 QATrender.C:101
 QATrender.C:102
 QATrender.C:103
 QATrender.C:104
 QATrender.C:105
 QATrender.C:106
 QATrender.C:107
 QATrender.C:108
 QATrender.C:109
 QATrender.C:110
 QATrender.C:111
 QATrender.C:112
 QATrender.C:113
 QATrender.C:114
 QATrender.C:115
 QATrender.C:116
 QATrender.C:117
 QATrender.C:118
 QATrender.C:119
 QATrender.C:120
 QATrender.C:121
 QATrender.C:122
 QATrender.C:123
 QATrender.C:124
 QATrender.C:125
 QATrender.C:126
 QATrender.C:127
 QATrender.C:128
 QATrender.C:129
 QATrender.C:130
 QATrender.C:131
 QATrender.C:132
 QATrender.C:133
 QATrender.C:134
 QATrender.C:135
 QATrender.C:136
 QATrender.C:137
 QATrender.C:138
 QATrender.C:139
 QATrender.C:140
 QATrender.C:141
 QATrender.C:142
 QATrender.C:143
 QATrender.C:144
 QATrender.C:145
 QATrender.C:146
 QATrender.C:147
 QATrender.C:148
 QATrender.C:149
 QATrender.C:150
 QATrender.C:151
 QATrender.C:152
 QATrender.C:153
 QATrender.C:154
 QATrender.C:155
 QATrender.C:156
 QATrender.C:157
 QATrender.C:158
 QATrender.C:159
 QATrender.C:160
 QATrender.C:161
 QATrender.C:162
 QATrender.C:163
 QATrender.C:164
 QATrender.C:165
 QATrender.C:166
 QATrender.C:167
 QATrender.C:168
 QATrender.C:169
 QATrender.C:170
 QATrender.C:171
 QATrender.C:172
 QATrender.C:173
 QATrender.C:174
 QATrender.C:175
 QATrender.C:176
 QATrender.C:177
 QATrender.C:178
 QATrender.C:179
 QATrender.C:180
 QATrender.C:181
 QATrender.C:182
 QATrender.C:183
 QATrender.C:184
 QATrender.C:185
 QATrender.C:186
 QATrender.C:187
 QATrender.C:188
 QATrender.C:189
 QATrender.C:190
 QATrender.C:191
 QATrender.C:192
 QATrender.C:193
 QATrender.C:194
 QATrender.C:195
 QATrender.C:196
 QATrender.C:197
 QATrender.C:198
 QATrender.C:199
 QATrender.C:200
 QATrender.C:201
 QATrender.C:202
 QATrender.C:203
 QATrender.C:204
 QATrender.C:205
 QATrender.C:206
 QATrender.C:207
 QATrender.C:208
 QATrender.C:209
 QATrender.C:210
 QATrender.C:211
 QATrender.C:212
 QATrender.C:213
 QATrender.C:214
 QATrender.C:215
 QATrender.C:216
 QATrender.C:217
 QATrender.C:218
 QATrender.C:219
 QATrender.C:220
 QATrender.C:221
 QATrender.C:222
 QATrender.C:223
 QATrender.C:224
 QATrender.C:225
 QATrender.C:226
 QATrender.C:227
 QATrender.C:228
 QATrender.C:229
 QATrender.C:230
 QATrender.C:231
 QATrender.C:232
 QATrender.C:233
 QATrender.C:234
 QATrender.C:235
 QATrender.C:236
 QATrender.C:237
 QATrender.C:238
 QATrender.C:239
 QATrender.C:240
 QATrender.C:241
 QATrender.C:242
 QATrender.C:243
 QATrender.C:244
 QATrender.C:245
 QATrender.C:246
 QATrender.C:247
 QATrender.C:248
 QATrender.C:249
 QATrender.C:250
 QATrender.C:251
 QATrender.C:252
 QATrender.C:253
 QATrender.C:254
 QATrender.C:255
 QATrender.C:256
 QATrender.C:257
 QATrender.C:258
 QATrender.C:259
 QATrender.C:260
 QATrender.C:261
 QATrender.C:262
 QATrender.C:263
 QATrender.C:264
 QATrender.C:265
 QATrender.C:266
 QATrender.C:267
 QATrender.C:268
 QATrender.C:269
 QATrender.C:270
 QATrender.C:271
 QATrender.C:272
 QATrender.C:273
 QATrender.C:274
 QATrender.C:275
 QATrender.C:276
 QATrender.C:277
 QATrender.C:278
 QATrender.C:279
 QATrender.C:280
 QATrender.C:281
 QATrender.C:282
 QATrender.C:283
 QATrender.C:284
 QATrender.C:285
 QATrender.C:286
 QATrender.C:287
 QATrender.C:288
 QATrender.C:289
 QATrender.C:290
 QATrender.C:291
 QATrender.C:292
 QATrender.C:293
 QATrender.C:294
 QATrender.C:295
 QATrender.C:296
 QATrender.C:297
 QATrender.C:298
 QATrender.C:299
 QATrender.C:300
 QATrender.C:301
 QATrender.C:302
 QATrender.C:303
 QATrender.C:304
 QATrender.C:305
 QATrender.C:306
 QATrender.C:307
 QATrender.C:308
 QATrender.C:309
 QATrender.C:310
 QATrender.C:311
 QATrender.C:312
 QATrender.C:313
 QATrender.C:314
 QATrender.C:315
 QATrender.C:316
 QATrender.C:317
 QATrender.C:318
 QATrender.C:319
 QATrender.C:320
 QATrender.C:321
 QATrender.C:322
 QATrender.C:323
 QATrender.C:324
 QATrender.C:325
 QATrender.C:326
 QATrender.C:327
 QATrender.C:328
 QATrender.C:329
 QATrender.C:330
 QATrender.C:331
 QATrender.C:332
 QATrender.C:333
 QATrender.C:334
 QATrender.C:335
 QATrender.C:336
 QATrender.C:337
 QATrender.C:338
 QATrender.C:339
 QATrender.C:340
 QATrender.C:341
 QATrender.C:342
 QATrender.C:343
 QATrender.C:344
 QATrender.C:345
 QATrender.C:346
 QATrender.C:347
 QATrender.C:348
 QATrender.C:349
 QATrender.C:350
 QATrender.C:351
 QATrender.C:352
 QATrender.C:353
 QATrender.C:354
 QATrender.C:355
 QATrender.C:356
 QATrender.C:357
 QATrender.C:358
 QATrender.C:359
 QATrender.C:360
 QATrender.C:361
 QATrender.C:362
 QATrender.C:363
 QATrender.C:364
 QATrender.C:365
 QATrender.C:366
 QATrender.C:367
 QATrender.C:368
 QATrender.C:369
 QATrender.C:370
 QATrender.C:371
 QATrender.C:372
 QATrender.C:373
 QATrender.C:374
 QATrender.C:375
 QATrender.C:376
 QATrender.C:377
 QATrender.C:378
 QATrender.C:379
 QATrender.C:380
 QATrender.C:381
 QATrender.C:382
 QATrender.C:383
 QATrender.C:384
 QATrender.C:385
 QATrender.C:386
 QATrender.C:387
 QATrender.C:388
 QATrender.C:389
 QATrender.C:390
 QATrender.C:391
 QATrender.C:392
 QATrender.C:393
 QATrender.C:394
 QATrender.C:395
 QATrender.C:396
 QATrender.C:397
 QATrender.C:398
 QATrender.C:399
 QATrender.C:400
 QATrender.C:401
 QATrender.C:402
 QATrender.C:403
 QATrender.C:404
 QATrender.C:405
 QATrender.C:406
 QATrender.C:407
 QATrender.C:408
 QATrender.C:409
 QATrender.C:410
 QATrender.C:411
 QATrender.C:412
 QATrender.C:413
 QATrender.C:414
 QATrender.C:415
 QATrender.C:416
 QATrender.C:417
 QATrender.C:418
 QATrender.C:419
 QATrender.C:420
 QATrender.C:421
 QATrender.C:422
 QATrender.C:423
 QATrender.C:424
 QATrender.C:425
 QATrender.C:426
 QATrender.C:427
 QATrender.C:428
 QATrender.C:429
 QATrender.C:430
 QATrender.C:431
 QATrender.C:432
 QATrender.C:433
 QATrender.C:434
 QATrender.C:435
 QATrender.C:436
 QATrender.C:437
 QATrender.C:438
 QATrender.C:439
 QATrender.C:440
 QATrender.C:441
 QATrender.C:442
 QATrender.C:443
 QATrender.C:444
 QATrender.C:445
 QATrender.C:446
 QATrender.C:447
 QATrender.C:448
 QATrender.C:449
 QATrender.C:450
 QATrender.C:451
 QATrender.C:452
 QATrender.C:453
 QATrender.C:454
 QATrender.C:455
 QATrender.C:456
 QATrender.C:457
 QATrender.C:458
 QATrender.C:459
 QATrender.C:460
 QATrender.C:461
 QATrender.C:462
 QATrender.C:463
 QATrender.C:464
 QATrender.C:465
 QATrender.C:466
 QATrender.C:467
 QATrender.C:468
 QATrender.C:469
 QATrender.C:470
 QATrender.C:471
 QATrender.C:472
 QATrender.C:473
 QATrender.C:474
 QATrender.C:475
 QATrender.C:476
 QATrender.C:477
 QATrender.C:478
 QATrender.C:479
 QATrender.C:480
 QATrender.C:481
 QATrender.C:482
 QATrender.C:483
 QATrender.C:484
 QATrender.C:485
 QATrender.C:486
 QATrender.C:487
 QATrender.C:488
 QATrender.C:489
 QATrender.C:490
 QATrender.C:491
 QATrender.C:492
 QATrender.C:493
 QATrender.C:494
 QATrender.C:495
 QATrender.C:496
 QATrender.C:497
 QATrender.C:498
 QATrender.C:499
 QATrender.C:500
 QATrender.C:501
 QATrender.C:502
 QATrender.C:503
 QATrender.C:504
 QATrender.C:505
 QATrender.C:506
 QATrender.C:507
 QATrender.C:508
 QATrender.C:509
 QATrender.C:510
 QATrender.C:511
 QATrender.C:512
 QATrender.C:513
 QATrender.C:514
 QATrender.C:515
 QATrender.C:516
 QATrender.C:517
 QATrender.C:518
 QATrender.C:519
 QATrender.C:520
 QATrender.C:521
 QATrender.C:522
 QATrender.C:523
 QATrender.C:524
 QATrender.C:525
 QATrender.C:526
 QATrender.C:527
 QATrender.C:528
 QATrender.C:529
 QATrender.C:530
 QATrender.C:531
 QATrender.C:532
 QATrender.C:533
 QATrender.C:534
 QATrender.C:535
 QATrender.C:536
 QATrender.C:537
 QATrender.C:538
 QATrender.C:539
 QATrender.C:540
 QATrender.C:541
 QATrender.C:542
 QATrender.C:543
 QATrender.C:544
 QATrender.C:545
 QATrender.C:546
 QATrender.C:547
 QATrender.C:548
 QATrender.C:549
 QATrender.C:550
 QATrender.C:551
 QATrender.C:552
 QATrender.C:553
 QATrender.C:554
 QATrender.C:555
 QATrender.C:556
 QATrender.C:557
 QATrender.C:558
 QATrender.C:559
 QATrender.C:560
 QATrender.C:561
 QATrender.C:562
 QATrender.C:563
 QATrender.C:564
 QATrender.C:565
 QATrender.C:566
 QATrender.C:567
 QATrender.C:568
 QATrender.C:569
 QATrender.C:570
 QATrender.C:571
 QATrender.C:572
 QATrender.C:573
 QATrender.C:574
 QATrender.C:575
 QATrender.C:576
 QATrender.C:577
 QATrender.C:578
 QATrender.C:579
 QATrender.C:580
 QATrender.C:581
 QATrender.C:582
 QATrender.C:583
 QATrender.C:584
 QATrender.C:585
 QATrender.C:586
 QATrender.C:587
 QATrender.C:588
 QATrender.C:589
 QATrender.C:590
 QATrender.C:591
 QATrender.C:592
 QATrender.C:593
 QATrender.C:594
 QATrender.C:595
 QATrender.C:596
 QATrender.C:597
 QATrender.C:598
 QATrender.C:599
 QATrender.C:600
 QATrender.C:601
 QATrender.C:602
 QATrender.C:603
 QATrender.C:604
 QATrender.C:605
 QATrender.C:606
 QATrender.C:607
 QATrender.C:608
 QATrender.C:609
 QATrender.C:610
 QATrender.C:611
 QATrender.C:612
 QATrender.C:613
 QATrender.C:614
 QATrender.C:615
 QATrender.C:616
 QATrender.C:617
 QATrender.C:618
 QATrender.C:619
 QATrender.C:620
 QATrender.C:621
 QATrender.C:622
 QATrender.C:623
 QATrender.C:624
 QATrender.C:625
 QATrender.C:626
 QATrender.C:627
 QATrender.C:628
 QATrender.C:629
 QATrender.C:630
 QATrender.C:631
 QATrender.C:632
 QATrender.C:633
 QATrender.C:634
 QATrender.C:635
 QATrender.C:636
 QATrender.C:637
 QATrender.C:638
 QATrender.C:639
 QATrender.C:640
 QATrender.C:641
 QATrender.C:642
 QATrender.C:643
 QATrender.C:644
 QATrender.C:645
 QATrender.C:646
 QATrender.C:647
 QATrender.C:648
 QATrender.C:649
 QATrender.C:650
 QATrender.C:651
 QATrender.C:652
 QATrender.C:653
 QATrender.C:654
 QATrender.C:655
 QATrender.C:656
 QATrender.C:657
 QATrender.C:658
 QATrender.C:659
 QATrender.C:660
 QATrender.C:661
 QATrender.C:662
 QATrender.C:663
 QATrender.C:664
 QATrender.C:665
 QATrender.C:666
 QATrender.C:667
 QATrender.C:668
 QATrender.C:669
 QATrender.C:670
 QATrender.C:671
 QATrender.C:672
 QATrender.C:673
 QATrender.C:674
 QATrender.C:675
 QATrender.C:676
 QATrender.C:677
 QATrender.C:678
 QATrender.C:679
 QATrender.C:680
 QATrender.C:681
 QATrender.C:682
 QATrender.C:683
 QATrender.C:684
 QATrender.C:685
 QATrender.C:686
 QATrender.C:687
 QATrender.C:688
 QATrender.C:689
 QATrender.C:690
 QATrender.C:691
 QATrender.C:692
 QATrender.C:693
 QATrender.C:694
 QATrender.C:695
 QATrender.C:696
 QATrender.C:697
 QATrender.C:698
 QATrender.C:699
 QATrender.C:700
 QATrender.C:701
 QATrender.C:702
 QATrender.C:703
 QATrender.C:704
 QATrender.C:705
 QATrender.C:706
 QATrender.C:707
 QATrender.C:708
 QATrender.C:709
 QATrender.C:710
 QATrender.C:711
 QATrender.C:712
 QATrender.C:713
 QATrender.C:714
 QATrender.C:715
 QATrender.C:716
 QATrender.C:717
 QATrender.C:718
 QATrender.C:719
 QATrender.C:720
 QATrender.C:721
 QATrender.C:722
 QATrender.C:723
 QATrender.C:724
 QATrender.C:725
 QATrender.C:726
 QATrender.C:727
 QATrender.C:728
 QATrender.C:729
 QATrender.C:730
 QATrender.C:731
 QATrender.C:732
 QATrender.C:733
 QATrender.C:734
 QATrender.C:735
 QATrender.C:736
 QATrender.C:737
 QATrender.C:738
 QATrender.C:739
 QATrender.C:740
 QATrender.C:741
 QATrender.C:742
 QATrender.C:743
 QATrender.C:744
 QATrender.C:745
 QATrender.C:746
 QATrender.C:747
 QATrender.C:748
 QATrender.C:749
 QATrender.C:750
 QATrender.C:751
 QATrender.C:752
 QATrender.C:753
 QATrender.C:754
 QATrender.C:755
 QATrender.C:756
 QATrender.C:757
 QATrender.C:758
 QATrender.C:759
 QATrender.C:760
 QATrender.C:761
 QATrender.C:762
 QATrender.C:763
 QATrender.C:764
 QATrender.C:765
 QATrender.C:766
 QATrender.C:767
 QATrender.C:768
 QATrender.C:769
 QATrender.C:770
 QATrender.C:771
 QATrender.C:772
 QATrender.C:773
 QATrender.C:774
 QATrender.C:775
 QATrender.C:776
 QATrender.C:777
 QATrender.C:778
 QATrender.C:779
 QATrender.C:780
 QATrender.C:781
 QATrender.C:782
 QATrender.C:783
 QATrender.C:784
 QATrender.C:785
 QATrender.C:786
 QATrender.C:787
 QATrender.C:788
 QATrender.C:789
 QATrender.C:790
 QATrender.C:791
 QATrender.C:792
 QATrender.C:793
 QATrender.C:794
 QATrender.C:795
 QATrender.C:796
 QATrender.C:797
 QATrender.C:798
 QATrender.C:799
 QATrender.C:800
 QATrender.C:801
 QATrender.C:802
 QATrender.C:803
 QATrender.C:804
 QATrender.C:805
 QATrender.C:806
 QATrender.C:807
 QATrender.C:808
 QATrender.C:809
 QATrender.C:810
 QATrender.C:811
 QATrender.C:812
 QATrender.C:813
 QATrender.C:814
 QATrender.C:815
 QATrender.C:816
 QATrender.C:817
 QATrender.C:818
 QATrender.C:819
 QATrender.C:820
 QATrender.C:821
 QATrender.C:822
 QATrender.C:823
 QATrender.C:824
 QATrender.C:825
 QATrender.C:826
 QATrender.C:827
 QATrender.C:828
 QATrender.C:829
 QATrender.C:830
 QATrender.C:831
 QATrender.C:832
 QATrender.C:833
 QATrender.C:834
 QATrender.C:835
 QATrender.C:836
 QATrender.C:837
 QATrender.C:838
 QATrender.C:839
 QATrender.C:840
 QATrender.C:841
 QATrender.C:842
 QATrender.C:843
 QATrender.C:844
 QATrender.C:845
 QATrender.C:846
 QATrender.C:847
 QATrender.C:848
 QATrender.C:849
 QATrender.C:850
 QATrender.C:851
 QATrender.C:852
 QATrender.C:853
 QATrender.C:854
 QATrender.C:855
 QATrender.C:856
 QATrender.C:857
 QATrender.C:858
 QATrender.C:859
 QATrender.C:860
 QATrender.C:861
 QATrender.C:862
 QATrender.C:863
 QATrender.C:864
 QATrender.C:865
 QATrender.C:866
 QATrender.C:867
 QATrender.C:868
 QATrender.C:869
 QATrender.C:870
 QATrender.C:871
 QATrender.C:872
 QATrender.C:873
 QATrender.C:874
 QATrender.C:875
 QATrender.C:876
 QATrender.C:877
 QATrender.C:878
 QATrender.C:879
 QATrender.C:880
 QATrender.C:881
 QATrender.C:882
 QATrender.C:883
 QATrender.C:884
 QATrender.C:885
 QATrender.C:886
 QATrender.C:887
 QATrender.C:888
 QATrender.C:889
 QATrender.C:890
 QATrender.C:891
 QATrender.C:892
 QATrender.C:893
 QATrender.C:894
 QATrender.C:895
 QATrender.C:896
 QATrender.C:897
 QATrender.C:898
 QATrender.C:899
 QATrender.C:900
 QATrender.C:901
 QATrender.C:902
 QATrender.C:903
 QATrender.C:904
 QATrender.C:905
 QATrender.C:906
 QATrender.C:907
 QATrender.C:908
 QATrender.C:909
 QATrender.C:910
 QATrender.C:911
 QATrender.C:912
 QATrender.C:913
 QATrender.C:914
 QATrender.C:915
 QATrender.C:916
 QATrender.C:917
 QATrender.C:918
 QATrender.C:919
 QATrender.C:920
 QATrender.C:921
 QATrender.C:922
 QATrender.C:923
 QATrender.C:924
 QATrender.C:925
 QATrender.C:926
 QATrender.C:927
 QATrender.C:928
 QATrender.C:929
 QATrender.C:930
 QATrender.C:931
 QATrender.C:932
 QATrender.C:933
 QATrender.C:934
 QATrender.C:935
 QATrender.C:936
 QATrender.C:937
 QATrender.C:938
 QATrender.C:939
 QATrender.C:940
 QATrender.C:941
 QATrender.C:942
 QATrender.C:943
 QATrender.C:944
 QATrender.C:945
 QATrender.C:946
 QATrender.C:947
 QATrender.C:948
 QATrender.C:949
 QATrender.C:950
 QATrender.C:951
 QATrender.C:952
 QATrender.C:953
 QATrender.C:954
 QATrender.C:955
 QATrender.C:956
 QATrender.C:957
 QATrender.C:958
 QATrender.C:959
 QATrender.C:960
 QATrender.C:961
 QATrender.C:962
 QATrender.C:963
 QATrender.C:964
 QATrender.C:965
 QATrender.C:966
 QATrender.C:967
 QATrender.C:968
 QATrender.C:969
 QATrender.C:970
 QATrender.C:971
 QATrender.C:972
 QATrender.C:973
 QATrender.C:974
 QATrender.C:975
 QATrender.C:976
 QATrender.C:977
 QATrender.C:978
 QATrender.C:979
 QATrender.C:980
 QATrender.C:981
 QATrender.C:982
 QATrender.C:983
 QATrender.C:984
 QATrender.C:985
 QATrender.C:986
 QATrender.C:987
 QATrender.C:988
 QATrender.C:989
 QATrender.C:990
 QATrender.C:991
 QATrender.C:992
 QATrender.C:993
 QATrender.C:994
 QATrender.C:995
 QATrender.C:996
 QATrender.C:997
 QATrender.C:998
 QATrender.C:999
 QATrender.C:1000
 QATrender.C:1001
 QATrender.C:1002
 QATrender.C:1003
 QATrender.C:1004
 QATrender.C:1005
 QATrender.C:1006
 QATrender.C:1007
 QATrender.C:1008
 QATrender.C:1009
 QATrender.C:1010
 QATrender.C:1011
 QATrender.C:1012
 QATrender.C:1013
 QATrender.C:1014
 QATrender.C:1015
 QATrender.C:1016
 QATrender.C:1017
 QATrender.C:1018
 QATrender.C:1019
 QATrender.C:1020
 QATrender.C:1021
 QATrender.C:1022
 QATrender.C:1023
 QATrender.C:1024
 QATrender.C:1025
 QATrender.C:1026
 QATrender.C:1027
 QATrender.C:1028
 QATrender.C:1029
 QATrender.C:1030
 QATrender.C:1031
 QATrender.C:1032
 QATrender.C:1033
 QATrender.C:1034
 QATrender.C:1035
 QATrender.C:1036
 QATrender.C:1037
 QATrender.C:1038
 QATrender.C:1039
 QATrender.C:1040
 QATrender.C:1041
 QATrender.C:1042
 QATrender.C:1043
 QATrender.C:1044
 QATrender.C:1045
 QATrender.C:1046
 QATrender.C:1047
 QATrender.C:1048
 QATrender.C:1049
 QATrender.C:1050
 QATrender.C:1051
 QATrender.C:1052
 QATrender.C:1053
 QATrender.C:1054
 QATrender.C:1055
 QATrender.C:1056
 QATrender.C:1057
 QATrender.C:1058
 QATrender.C:1059
 QATrender.C:1060
 QATrender.C:1061
 QATrender.C:1062
 QATrender.C:1063
 QATrender.C:1064
 QATrender.C:1065
 QATrender.C:1066
 QATrender.C:1067
 QATrender.C:1068
 QATrender.C:1069
 QATrender.C:1070
 QATrender.C:1071
 QATrender.C:1072
 QATrender.C:1073
 QATrender.C:1074
 QATrender.C:1075
 QATrender.C:1076
 QATrender.C:1077
 QATrender.C:1078
 QATrender.C:1079
 QATrender.C:1080
 QATrender.C:1081
 QATrender.C:1082
 QATrender.C:1083
 QATrender.C:1084
 QATrender.C:1085
 QATrender.C:1086
 QATrender.C:1087
 QATrender.C:1088
 QATrender.C:1089
 QATrender.C:1090
 QATrender.C:1091
 QATrender.C:1092
 QATrender.C:1093
 QATrender.C:1094
 QATrender.C:1095
 QATrender.C:1096
 QATrender.C:1097
 QATrender.C:1098
 QATrender.C:1099
 QATrender.C:1100
 QATrender.C:1101
 QATrender.C:1102
 QATrender.C:1103
 QATrender.C:1104
 QATrender.C:1105
 QATrender.C:1106
 QATrender.C:1107
 QATrender.C:1108
 QATrender.C:1109
 QATrender.C:1110
 QATrender.C:1111
 QATrender.C:1112
 QATrender.C:1113
 QATrender.C:1114
 QATrender.C:1115
 QATrender.C:1116
 QATrender.C:1117
 QATrender.C:1118
 QATrender.C:1119
 QATrender.C:1120
 QATrender.C:1121
 QATrender.C:1122
 QATrender.C:1123
 QATrender.C:1124
 QATrender.C:1125
 QATrender.C:1126
 QATrender.C:1127
 QATrender.C:1128
 QATrender.C:1129
 QATrender.C:1130
 QATrender.C:1131
 QATrender.C:1132
 QATrender.C:1133
 QATrender.C:1134
 QATrender.C:1135
 QATrender.C:1136
 QATrender.C:1137
 QATrender.C:1138
 QATrender.C:1139
 QATrender.C:1140
 QATrender.C:1141
 QATrender.C:1142
 QATrender.C:1143
 QATrender.C:1144
 QATrender.C:1145
 QATrender.C:1146
 QATrender.C:1147
 QATrender.C:1148
 QATrender.C:1149
 QATrender.C:1150
 QATrender.C:1151
 QATrender.C:1152
 QATrender.C:1153
 QATrender.C:1154
 QATrender.C:1155
 QATrender.C:1156
 QATrender.C:1157
 QATrender.C:1158
 QATrender.C:1159
 QATrender.C:1160
 QATrender.C:1161
 QATrender.C:1162
 QATrender.C:1163
 QATrender.C:1164
 QATrender.C:1165
 QATrender.C:1166
 QATrender.C:1167
 QATrender.C:1168
 QATrender.C:1169
 QATrender.C:1170
 QATrender.C:1171
 QATrender.C:1172
 QATrender.C:1173
 QATrender.C:1174
 QATrender.C:1175
 QATrender.C:1176
 QATrender.C:1177
 QATrender.C:1178
 QATrender.C:1179
 QATrender.C:1180
 QATrender.C:1181
 QATrender.C:1182
 QATrender.C:1183
 QATrender.C:1184
 QATrender.C:1185
 QATrender.C:1186
 QATrender.C:1187
 QATrender.C:1188
 QATrender.C:1189
 QATrender.C:1190
 QATrender.C:1191
 QATrender.C:1192
 QATrender.C:1193
 QATrender.C:1194
 QATrender.C:1195
 QATrender.C:1196
 QATrender.C:1197
 QATrender.C:1198
 QATrender.C:1199
 QATrender.C:1200
 QATrender.C:1201
 QATrender.C:1202
 QATrender.C:1203
 QATrender.C:1204
 QATrender.C:1205
 QATrender.C:1206
 QATrender.C:1207
 QATrender.C:1208
 QATrender.C:1209
 QATrender.C:1210
 QATrender.C:1211
 QATrender.C:1212
 QATrender.C:1213
 QATrender.C:1214
 QATrender.C:1215
 QATrender.C:1216
 QATrender.C:1217
 QATrender.C:1218
 QATrender.C:1219
 QATrender.C:1220
 QATrender.C:1221
 QATrender.C:1222
 QATrender.C:1223
 QATrender.C:1224
 QATrender.C:1225
 QATrender.C:1226
 QATrender.C:1227
 QATrender.C:1228
 QATrender.C:1229
 QATrender.C:1230
 QATrender.C:1231
 QATrender.C:1232
 QATrender.C:1233
 QATrender.C:1234
 QATrender.C:1235
 QATrender.C:1236
 QATrender.C:1237
 QATrender.C:1238
 QATrender.C:1239
 QATrender.C:1240
 QATrender.C:1241
 QATrender.C:1242
 QATrender.C:1243
 QATrender.C:1244
 QATrender.C:1245
 QATrender.C:1246
 QATrender.C:1247
 QATrender.C:1248
 QATrender.C:1249
 QATrender.C:1250
 QATrender.C:1251
 QATrender.C:1252
 QATrender.C:1253
 QATrender.C:1254
 QATrender.C:1255
 QATrender.C:1256
 QATrender.C:1257
 QATrender.C:1258
 QATrender.C:1259
 QATrender.C:1260
 QATrender.C:1261
 QATrender.C:1262
 QATrender.C:1263
 QATrender.C:1264
 QATrender.C:1265
 QATrender.C:1266
 QATrender.C:1267
 QATrender.C:1268
 QATrender.C:1269
 QATrender.C:1270
 QATrender.C:1271
 QATrender.C:1272
 QATrender.C:1273
 QATrender.C:1274
 QATrender.C:1275
 QATrender.C:1276
 QATrender.C:1277
 QATrender.C:1278
 QATrender.C:1279
 QATrender.C:1280