ROOT logo
#if !defined(__CINT__) || defined(__MAKECINT__)
#include <TH1.h>
#include <TH2.h>
#include <TF1.h>
#include <TMath.h>
#include <TRandom.h>
#include <TObjArray.h>
#include "DetectorK.h"
#include "AliExternalTrackParam.h"
#endif

const double PTMIN = 0.03;
const double PTMAX = 30.0;
const Bool_t VERBOSE = kFALSE;
const double kMaxChi2 = 10;
const int    kNbChi2 = 100;
const int    kNDF = 5;

const double kFactdNdEta = 2;

const UInt_t kFailedBit = 0x1<<14;
// You have to load the class before ... ;-)
// .L DetectorK.cxx++


const double restR[] = {85.20, 100.20, 120.45,   136.10, 160.10, 220.20, 290};

TrackSol* ts=0;
DetectorK* its=0;

TH2F* chiComp=0;

TH1F* solPtHisto=0;
TH1F* effITSSAHisto = 0;
TH1F* hChiSig = 0;
TObjArray  arrMatchHisto;
TObjArray  arrFakeHisto;
TObjArray  chiBgMatch;
TObjArray* sigPoolITS=0,*sigPoolGlo=0;
TObjArray* bgPoolITS=0;
Double_t wghEtaRange=1;

TObjArray* GenerateSigPool(double ptMin=0.1, double ptMax=20, int nPt=100);
TObjArray* GenerateBgPool(int nFactor, double ptMin, double ptMax, double refR, double maxDZ, TObjArray* sigPool);
Double_t   GetRandomPt(double ptMin,double ptMax);
TH1F*      TestMatching(TrackSol* trGlo, double rLastUpd, double refR, int nPhiTest);
TObjArray* TestMatchingN(TrackSol* trGlo, const double* rLastUpd, int nRLastUpd, double refR, int nPhiTest);
TH1F*      PrepChi2Ndf(int ndf=kNDF, int ngen=1000000);
Double_t   CalcCorrProb(TH1* chiSig, TH1* chiBg, double &smBgRet, double maxChi=-1);
Bool_t     PassFastCheck(AliExternalTrackParam &tr1, AliExternalTrackParam &tr2, double cut=10);

void testDetRS(double ptMin=0.1, double ptMax=20, int nPt=100, int nFactor=200, double maxDZ=5, double refR=45) 
{
  //
  if (ptMin<PTMIN || ptMin>PTMAX || ptMax<PTMIN || ptMax>PTMAX || ptMin>=ptMax) {
    printf("Pt range should be within %f %f\n",PTMIN,PTMAX);
    return;
  }
  its = new DetectorK("ALICE","ITS");
  its->SetAvgRapidity(0.2);
  //
  its->AddLayer((char*)"vertex",   0,      0); // dummy vertex for matrix calculation
  its->AddLayer((char*)"bpipe",  2.0, 0.0022);
  // new ideal Pixel properties?
  Double_t x0IB     = 0.003;
  Double_t x0OB     = 0.008;
  Double_t resRPhiIB     = 0.0004;
  Double_t resZIB        = 0.0004;
  Double_t resRPhiOB     = 0.0004;
  Double_t resZOB        = 0.0004;
  Double_t eff           = 0.95;
  //
  its->AddLayer((char*)"ddd1",  2.32 ,  x0IB, resRPhiIB, resZIB,eff); 
  its->AddLayer((char*)"ddd2",  3.13 ,  x0IB, resRPhiIB, resZIB,eff); 
  its->AddLayer((char*)"ddd3",  3.91 ,  x0IB, resRPhiIB, resZIB,eff); 
  its->AddLayer((char*)"ddd4",  19.41,  x0OB, resRPhiOB, resZOB,eff); 
  its->AddLayer((char*)"ddd5",  24.71 ,  x0OB, resRPhiOB, resZOB,eff); 
  its->AddLayer((char*)"ddd6",  35.33 ,  x0OB, resRPhiOB, resZOB,eff); 
  its->AddLayer((char*)"ddd7",  40.53 ,  x0OB, resRPhiOB, resZOB,eff); 
  its->AddLayer((char*)"shell",   43.00 ,  0.01);
  //
  printf("Reference radius: %f\n",refR);
  //
  its->SetAtLeastHits(5);
  its->SetAtLeastCorr(5);
  its->SetAtLeastFake(1);
  //
  its->PrintLayout();
  //
  sigPoolITS = GenerateSigPool(ptMin,ptMax,nPt);
  bgPoolITS  = GenerateBgPool(nFactor, ptMin,ptMax, refR, maxDZ, sigPoolITS);
  //
  its->AddTPC(0.1,0.1);

  its->AddTRD();

  //
  sigPoolGlo = GenerateSigPool(ptMin,ptMax,nPt);
  //
  //  its->SolveTrack(*ts);
  //  its->CalcITSEff(*ts,kTRUE);
  //
  effITSSAHisto = (TH1F*)solPtHisto->Clone("itsSAeff");
  effITSSAHisto->SetTitle("ITS SA eff");
  effITSSAHisto->Reset();
  hChiSig = PrepChi2Ndf();
  int nrTest = sizeof(restR)/sizeof(double);
  for (int ir=0;ir<nrTest;ir++) {
    TH1F* hmt = (TH1F*)solPtHisto->Clone(Form("its_tpc_match_rupd%.1f_rref%.1f",restR[ir],refR));
    hmt->SetTitle(Form("ITS-TPC match eff, R TPCmin = %.1f, Rmatch = f%.1f",restR[ir],refR));
    hmt->Reset();
    arrMatchHisto.AddLast(hmt);
    TH1F* hfm = (TH1F*)solPtHisto->Clone(Form("its_tpc_fake_rupd%.1f_rref%.1f",restR[ir],refR));
    hfm->SetTitle(Form("ITS-TPC fake match eff, R TPCmin = %.1f, Rmatch = f%.1f",restR[ir],refR));
    hfm->Reset();
    arrFakeHisto.AddLast(hfm);
  }
  //
  for (int ipt=0;ipt<nPt;ipt++) {
    ts = (TrackSol*)sigPoolITS->At(ipt);
    if (ts && !ts->TestBit(kFailedBit)) effITSSAHisto->SetBinContent(ipt+1, ts->fProb[2][0]); // combined SA eff
    //
    ts = (TrackSol*)sigPoolGlo->At(ipt);
    if (ts->TestBit(kFailedBit)) continue;
    TObjArray* harr = TestMatchingN(ts,restR,nrTest,refR,50);
    printf("ipt = %d, pt=%.3f : %d histos vs %d tested\n",ipt,ts->fPt, harr ? harr->GetEntries() : 0, nrTest);
    if (!harr) continue;
    chiBgMatch.AddAtAndExpand(harr,ipt);
    //
    for (int ir=0;ir<nrTest;ir++) {
      TH1* hbg = (TH1*)harr->At(ir);
      if (!hbg) continue;
      double bg = 0;
      double vl = CalcCorrProb(hChiSig,hbg,bg); // matching prob
      double effITSSA = effITSSAHisto->GetBinContent(ipt+1);
      ((TH1*)arrMatchHisto.At(ir))->SetBinContent(ipt+1, vl*effITSSA);
      ((TH1*)arrFakeHisto.At(ir))->SetBinContent(ipt+1, (1.-vl)*effITSSA + bg*(1.-effITSSA));
    }
  }
  //
}

TObjArray* GenerateSigPool(double ptMin, double ptMax, int nPt)
{
  // evaluate signal tracks
  TObjArray* arr = new TObjArray(nPt);
  //
  if (!solPtHisto) {
    double dx = log(ptMax/ptMin)/nPt;
    double *xax = new Double_t[nPt+1];
    for (int i=0;i<=nPt;i++) xax[i]= ptMin*exp(dx*i);
    solPtHisto = new TH1F("solPtHisto","solved pt",nPt, xax);
    delete[] xax;
  }
  //
  for (int ip=0;ip<nPt;ip++) {
    double pt = solPtHisto->GetBinCenter(ip+1);
    ts = new TrackSol(its->GetNumberOfLayers(), pt, its->GetAvgRapidity(), -1);
    if (!its->SolveTrack(*ts) || !its->CalcITSEff(*ts,VERBOSE)) ts->SetBit(kFailedBit);
    arr->AddAtAndExpand(ts,ip);
  }
  //
  return arr;
}

TObjArray* GenerateBgPool(int nFactor, double ptMin, double ptMax, double refR, double maxDZ, TObjArray* sigPool)
{
  // Generate bg ITS tracks, which may fall within maxDZ of the average 
  // rapidity track extrapolation at refR
  //
  enum {kY,kZ,kSnp,kTgl,kPtI};              // track parameter aliases
  enum {kY2,kYZ,kZ2,kYSnp,kZSnp,kSnp2,kYTgl,kZTgl,kSnpTgl,kTgl2,kYPtI,kZPtI,kSnpPtI,kTglPtI,kPtI2,kNCovPar}; // cov.matrix aliases
  //
  // estimate eta range of generation
  double thtAv = 2*TMath::ATan(TMath::Exp(-its->GetAvgRapidity()));
  double zAv = refR*TMath::Tan(thtAv);
  double zMin = zAv - maxDZ;
  double zMax = zAv + maxDZ;
  double thtMin = TMath::ATan(zMin/refR);
  double thtMax = TMath::ATan(zMax/refR);
  double etaMax =-TMath::Log( TMath::Tan(thtMin/2.));
  double etaMin =-TMath::Log( TMath::Tan(thtMax/2.));
  //
  wghEtaRange = (etaMax-etaMin); // weight wrt to dn/deta due to the restricted eta range
  AliExternalTrackParam probTr;
  double bGauss = its->GetBField()*10;
  //
  int ndNdEta = its->GetdNdEtaCent()*kFactdNdEta;
  int nGen = ndNdEta*nFactor;
  //
  int lrRef = its->FindLayerID(refR,0); // compare at this layer
  //
  TObjArray* genArr = new TObjArray();
  //
  for (int it=0;it<nGen;it++) {
    double pt = GetRandomPt(ptMin,ptMax);
    //
    int ptBin = solPtHisto->FindBin(pt)-1;
    TrackSol* trSol = (TrackSol*)sigPool->At(ptBin); // fetch the solved track for this pt
    //
    if (trSol->TestBit(kFailedBit)) continue;
    //
    double eta = etaMin+(etaMax-etaMin)*gRandom->Rndm();
    int q = gRandom->Rndm()>0.5 ? -1:1;
    double lambda = TMath::Pi()/2.0 - 2.0*TMath::ATan(TMath::Exp(-eta));
    probTr.Reset();
    double *trPars = (double*)probTr.GetParameter();
    double *trCov  = (double*)probTr.GetCovariance();
    trPars[kY] = 0;                         // start from Y = 0
    trPars[kZ] = 0;                         //            Z = 0 
    trPars[kSnp] = 0;                       //            track along X axis at the vertex
    trPars[kTgl] = TMath::Tan(lambda);      //            dip
    trPars[kPtI] = q/pt;                    //            q/pt      
    trCov[kY2] = trCov[kZ2] = trCov[kSnp2] = trCov[kTgl2] = trCov[kPtI2] = 1e-9;
    if (!its->PropagateToR(&probTr,refR,bGauss,1)) {
      printf("FAILED to propagate to r=%f\n",refR);
      probTr.Print();
      continue;
    }
    double pos[3];
    probTr.GetXYZ(pos);  // lab position
    double phi = TMath::ATan2(pos[1],pos[0]);
    if ( TMath::Abs(TMath::Abs(phi)-TMath::Pi()/2)<1e-3) phi = 0;//TMath::Sign(TMath::Pi()/2 - 1e-3,phi);
    if (!probTr.Rotate(phi))  {
      printf("FAILED to rotate to phi=%f\n",phi);
      probTr.Print();
      continue;
    }
    //
    // assign the error matrix of the ITS outward track with closest pt, estimated with FT
    AliExternalTrackParam* tr = (AliExternalTrackParam*)trSol->fTrackOutA[lrRef]; // and track pars at requested layer
    //printf("Pick at lr %d   %p\n",lrRef,tr);
    //if (tr) tr->Print();
    memcpy(trCov, tr->GetCovariance(), kNCovPar*sizeof(double));
    //
    genArr->AddLast(new AliExternalTrackParam(probTr));
    solPtHisto->Fill(pt);
  }
  //
  return genArr;
}

Double_t GetRandomPt(double ptMin,double ptMax)
{
  // generate random thermal pt
  static TF1* dndpt = 0;
  if (!dndpt) {
    dndpt = new TF1("dndpt","pow(sqrt(x*x+0.14*0.14),1.5)*exp(-sqrt(x*x+0.14*0.14)/0.17)",PTMIN,PTMAX);
    dndpt->SetNpx(1000);
  }
  return dndpt->GetRandom(ptMin,ptMax);
  //
}

TH1F* TestMatching(TrackSol* trGlo, double rLastUpd, double refR, int nPhiTest)
{
  //
  int maxLrAcc = trGlo->fTrackInw.GetEntries()-1-3; // need at least 3 points fitted
  Int_t lrLastUpd = its->FindLayerID(rLastUpd, -1); // find the layer below last update R
  if (lrLastUpd<0 || trGlo->TestBit(kFailedBit)) return 0;
  //
  if (lrLastUpd >= maxLrAcc) return 0;
  // pick the extrapolation to the layer below last requested update layer
  AliExternalTrackParam* trSignal = (AliExternalTrackParam*)trGlo->fTrackInw[lrLastUpd];
  if (!trSignal) return 0; 
  AliExternalTrackParam trSignalC = *trSignal; // use its copy
  //
  if (!its->ExtrapolateToR(&trSignalC, refR, trGlo->fMass)) return 0;
  // bring to the tracking frame of the matching layer
  //
  double pos[3];
  trSignalC.GetXYZ(pos);  // lab position
  double phi = TMath::ATan2(pos[1],pos[0]);
  if ( TMath::Abs(TMath::Abs(phi)-TMath::Pi()/2)<1e-3) phi = 0;//TMath::Sign(TMath::Pi()/2 - 1e-3,phi);
  if (!trSignalC.Rotate(phi))  {
    printf("FAILED to rotate to phi=%f\n",phi);
    trSignalC.Print();
    return 0;
  }
  //
  int nbg = bgPoolITS->GetEntriesFast();
  double posBg[3];
  double xBg,alpBg,parBgOr[5],covBgOr[15],*parBg,*covBg;
  AliExternalTrackParam trBg;
  //
  TString tts = Form("hchi_pt%.1f_r%.1f",trSignalC.Pt()*1000,rLastUpd);
  TH1F* hchi = new TH1F(tts.Data(),tts.Data(),kNbChi2,0,kMaxChi2);
  hchi->Sumw2();
  double bGauss = its->GetBField()*10;
  //
  for (int ib=0;ib<nbg;ib++) {
    trBg = *((AliExternalTrackParam*)bgPoolITS->At(ib));
    trBg.GetXYZ(posBg);  // lab position
    //
    xBg     = trBg.GetX();
    alpBg   = trBg.GetAlpha();
    parBg = (double*)trBg.GetParameter();
    covBg = (double*)trBg.GetCovariance();
    //
    memcpy(&parBgOr,parBg,5*sizeof(double));
    memcpy(&covBgOr,covBg,15*sizeof(double));
    //
    // simulate random phi
    for (int iphi=0;iphi<nPhiTest;iphi++) {
      double alpBgR = (gRandom->Rndm() - 0.5)*TMath::Pi();
      trBg.Set(xBg,alpBgR,parBg,covBg);
      //
      if (trBg.Rotate(trSignalC.GetAlpha()) && trBg.PropagateTo( trSignalC.GetX(), bGauss)) {
	if (!PassFastCheck(trSignalC,trBg)) continue;
	double chi2 = trSignalC.GetPredictedChi2(&trBg);
	//	trSignalC.Print();
	//	trBg.Print();
	//	printf("chi2: %f\n\n\n",chi2);
	hchi->Fill(chi2/kNDF);
      }
      //
      trBg.Set(xBg,alpBg,parBgOr, covBgOr);  // restore original track
    }
    //
  }
  //
  double nTest = nbg*nPhiTest;
  if (nTest<1) return 0;
  double nCorr = wghEtaRange*its->GetdNdEtaCent()*kFactdNdEta;
  printf("Expected: %.0f Tested: %.0f\n",nCorr, nTest);
  hchi->Scale(nCorr/nTest);
  return hchi;
}

//______________________________________________________________________________
TObjArray* TestMatchingN(TrackSol* trGlo, const double* rLastUpd, int nRLastUpd, double refR, int nPhiTest)
{
  //
  if (trGlo->TestBit(kFailedBit)) return 0;
  AliExternalTrackParam trSignalC[nRLastUpd];
  //
  TObjArray *arrH = new TObjArray(nRLastUpd);
  int maxLrAcc = trGlo->fTrackInw.GetEntries()-1-3; // need at least 3 points fitted
  //
  int sgRef = -1;
  for (int ir=0;ir<nRLastUpd;ir++) {
    trSignalC[ir].SetBit(kFailedBit);
    double rl = rLastUpd[ir];
    Int_t lrLastUpd = its->FindLayerID(rl, -1); // find the layer below last update R
    if (lrLastUpd<0) continue;
    if (lrLastUpd >= maxLrAcc) continue;
    //
    // pick the extrapolation to the layer below last requested update layer
    AliExternalTrackParam* trSignal = (AliExternalTrackParam*)trGlo->fTrackInw[lrLastUpd];
    if (!trSignal) continue; 
    trSignalC[ir] = *trSignal; // use its copy
    //
    //    printf("\n\n\nPicked at lr=%d r=%f  ",lrLastUpd, rl); trSignal->Print();
    if (!its->ExtrapolateToR(&trSignalC[ir], refR, trGlo->fMass)) return 0;
    // bring to the tracking frame of the matching layer
    //
    double pos[3];
    trSignalC[ir].GetXYZ(pos);  // lab position
    double phi = TMath::ATan2(pos[1],pos[0]);
    if (!trSignalC[ir].Rotate(phi))  {
      printf("FAILED to rotate to phi=%f\n",phi);
      trSignalC[ir].Print();
      continue;
    }
    trSignalC[ir].ResetBit(kFailedBit); // validate the track
    //
    //    printf("Taken to r=%f  ",refR); trSignalC[ir].Print();
    //
    TString tts = Form("hchi_pt%.1f_r%.1f",trGlo->fPt*1000,rl);
    TH1F* hchi = new TH1F(tts.Data(),tts.Data(),kNbChi2,0,kMaxChi2);
    hchi->Sumw2();
    arrH->AddAt(hchi,ir);
    if (sgRef<0) sgRef = ir;
  }
  //
  if (sgRef<0) return 0;
  //
  int nbg = bgPoolITS->GetEntriesFast();
  double posBg[3];
  double xBg,alpBg,parBgOr[5],covBgOr[15],*parBg,*covBg;
  AliExternalTrackParam trBg;
  //
  double bGauss = its->GetBField()*10;
  //
  for (int ib=0;ib<nbg;ib++) {
    trBg = *((AliExternalTrackParam*)bgPoolITS->At(ib));
    trBg.GetXYZ(posBg);  // lab position
    //
    xBg     = trBg.GetX();
    alpBg   = trBg.GetAlpha();
    parBg = (double*)trBg.GetParameter();
    covBg = (double*)trBg.GetCovariance();
    //
    memcpy(&parBgOr,parBg,5*sizeof(double));
    memcpy(&covBgOr,covBg,15*sizeof(double));
    //
    // simulate random phi
    for (int iphi=0;iphi<nPhiTest;iphi++) {
      double alpBgR = (gRandom->Rndm() - 0.5)*TMath::Pi();
      trBg.Set(xBg,alpBgR,parBg,covBg);
      //
      if (trBg.Rotate(trSignalC[sgRef].GetAlpha()) && trBg.PropagateTo( trSignalC[sgRef].GetX(), bGauss)) {
	for (int ir=0;ir<nRLastUpd;ir++) {
	  if (trSignalC[ir].TestBit(kFailedBit)) continue;
	  if (!PassFastCheck(trSignalC[ir],trBg)) continue;
	  double chi2 = trSignalC[ir].GetPredictedChi2(&trBg);
	  ((TH1*)arrH->UncheckedAt(ir))->Fill(chi2/kNDF);
	}
	//
      }
      trBg.Set(xBg,alpBg,parBgOr, covBgOr);  // restore original track
      //
    }
  }
  //
  double nTest = nbg*nPhiTest;
  if (nTest<1) return 0;
  double nCorr = wghEtaRange*its->GetdNdEtaCent()*kFactdNdEta;
  printf("Expected: %.0f Tested: %.0f\n",nCorr, nTest);
  for (int ir=0;ir<nRLastUpd;ir++) {
    TH1* hchi = (TH1*)arrH->UncheckedAt(ir);
    if (!hchi) continue;
    hchi->Scale(nCorr/nTest);
  }
  return arrH;
}

//_________________________________________________________________________________________
TH1F* PrepChi2Ndf(int ndf, int ngen)
{
  // generate distribution for chi2 with given ndf
  TString ttl = Form("Chi2_NDF%d",ndf);
  TH1F* hh = new TH1F(ttl.Data(),ttl.Data(),kNbChi2,0,kMaxChi2);
  for (int i=0;i<ngen;i++) hh->Fill(TMath::ChisquareQuantile(gRandom->Rndm(),ndf)/ndf);
  hh->Scale(1./ngen);
  return hh;
}

//____________________________________________________
Double_t CalcCorrProb(TH1* chiSig, TH1* chiBg, double &smBgRet, double maxChi) 
{
  // Calculate probability of all fake matches being worse than correct one
  // The chi2 histos should be normalized
  int nb = chiSig->GetNbinsX();
  if (maxChi>0) {
    int nt = chiSig->FindBin(maxChi);
    if (nt<nb) nb = nt;
  }
  //
  double bgchiC = maxChi;
  if (bgchiC<0) bgchiC = 5.;
  int maxBgBinCut = chiSig->FindBin(bgchiC);
  double smBg = 0;
  smBgRet = 0;
  double probTotCorr = 0;
  for (int i=1;i<=nb;i++) {
    double wSig = chiSig->GetBinContent(i);
    probTotCorr += wSig*TMath::Exp(-smBg);  // Poisson prob of not having a bg with better chi2
    smBg += chiBg->GetBinContent(i);
    if (i<=maxBgBinCut) smBgRet = smBg;
  }
  //
  smBg = 1.-TMath::Exp(smBg); // prob. to find bg within a cut in absence of correct match
  return probTotCorr;
}

//__________________________________________________
Bool_t PassFastCheck(AliExternalTrackParam &tr1, AliExternalTrackParam &tr2, double cut)
{
  enum {kY,kZ,kSnp,kTgl,kPtI};              // track parameter aliases
  enum {kY2,kYZ,kZ2,kYSnp,kZSnp,kSnp2,kYTgl,kZTgl,kSnpTgl,kTgl2,kYPtI,kZPtI,kSnpPtI,kTglPtI,kPtI2}; // cov.matrix aliases
  const int erId[5] = {kY2,kZ2,kSnp2,kTgl2,kPtI2};
  //
  // fast check ignoring non-diagonal elements
  double *cov1 = (double*)tr1.GetCovariance();
  double *cov2 = (double*)tr2.GetCovariance();
  double *par1 = (double*)tr1.GetParameter();
  double *par2 = (double*)tr2.GetParameter();
  //
  double chi2 = 0;
  for (int i=0;i<5;i++) {
    double df = par1[i]-par2[i];
    double err2 = cov1[erId[i]]+cov2[erId[i]];
    chi2 += df*df/err2;
  }
  return (chi2>cut*kNDF) ? kFALSE : kTRUE;
  //
}
 testDetRS.C:1
 testDetRS.C:2
 testDetRS.C:3
 testDetRS.C:4
 testDetRS.C:5
 testDetRS.C:6
 testDetRS.C:7
 testDetRS.C:8
 testDetRS.C:9
 testDetRS.C:10
 testDetRS.C:11
 testDetRS.C:12
 testDetRS.C:13
 testDetRS.C:14
 testDetRS.C:15
 testDetRS.C:16
 testDetRS.C:17
 testDetRS.C:18
 testDetRS.C:19
 testDetRS.C:20
 testDetRS.C:21
 testDetRS.C:22
 testDetRS.C:23
 testDetRS.C:24
 testDetRS.C:25
 testDetRS.C:26
 testDetRS.C:27
 testDetRS.C:28
 testDetRS.C:29
 testDetRS.C:30
 testDetRS.C:31
 testDetRS.C:32
 testDetRS.C:33
 testDetRS.C:34
 testDetRS.C:35
 testDetRS.C:36
 testDetRS.C:37
 testDetRS.C:38
 testDetRS.C:39
 testDetRS.C:40
 testDetRS.C:41
 testDetRS.C:42
 testDetRS.C:43
 testDetRS.C:44
 testDetRS.C:45
 testDetRS.C:46
 testDetRS.C:47
 testDetRS.C:48
 testDetRS.C:49
 testDetRS.C:50
 testDetRS.C:51
 testDetRS.C:52
 testDetRS.C:53
 testDetRS.C:54
 testDetRS.C:55
 testDetRS.C:56
 testDetRS.C:57
 testDetRS.C:58
 testDetRS.C:59
 testDetRS.C:60
 testDetRS.C:61
 testDetRS.C:62
 testDetRS.C:63
 testDetRS.C:64
 testDetRS.C:65
 testDetRS.C:66
 testDetRS.C:67
 testDetRS.C:68
 testDetRS.C:69
 testDetRS.C:70
 testDetRS.C:71
 testDetRS.C:72
 testDetRS.C:73
 testDetRS.C:74
 testDetRS.C:75
 testDetRS.C:76
 testDetRS.C:77
 testDetRS.C:78
 testDetRS.C:79
 testDetRS.C:80
 testDetRS.C:81
 testDetRS.C:82
 testDetRS.C:83
 testDetRS.C:84
 testDetRS.C:85
 testDetRS.C:86
 testDetRS.C:87
 testDetRS.C:88
 testDetRS.C:89
 testDetRS.C:90
 testDetRS.C:91
 testDetRS.C:92
 testDetRS.C:93
 testDetRS.C:94
 testDetRS.C:95
 testDetRS.C:96
 testDetRS.C:97
 testDetRS.C:98
 testDetRS.C:99
 testDetRS.C:100
 testDetRS.C:101
 testDetRS.C:102
 testDetRS.C:103
 testDetRS.C:104
 testDetRS.C:105
 testDetRS.C:106
 testDetRS.C:107
 testDetRS.C:108
 testDetRS.C:109
 testDetRS.C:110
 testDetRS.C:111
 testDetRS.C:112
 testDetRS.C:113
 testDetRS.C:114
 testDetRS.C:115
 testDetRS.C:116
 testDetRS.C:117
 testDetRS.C:118
 testDetRS.C:119
 testDetRS.C:120
 testDetRS.C:121
 testDetRS.C:122
 testDetRS.C:123
 testDetRS.C:124
 testDetRS.C:125
 testDetRS.C:126
 testDetRS.C:127
 testDetRS.C:128
 testDetRS.C:129
 testDetRS.C:130
 testDetRS.C:131
 testDetRS.C:132
 testDetRS.C:133
 testDetRS.C:134
 testDetRS.C:135
 testDetRS.C:136
 testDetRS.C:137
 testDetRS.C:138
 testDetRS.C:139
 testDetRS.C:140
 testDetRS.C:141
 testDetRS.C:142
 testDetRS.C:143
 testDetRS.C:144
 testDetRS.C:145
 testDetRS.C:146
 testDetRS.C:147
 testDetRS.C:148
 testDetRS.C:149
 testDetRS.C:150
 testDetRS.C:151
 testDetRS.C:152
 testDetRS.C:153
 testDetRS.C:154
 testDetRS.C:155
 testDetRS.C:156
 testDetRS.C:157
 testDetRS.C:158
 testDetRS.C:159
 testDetRS.C:160
 testDetRS.C:161
 testDetRS.C:162
 testDetRS.C:163
 testDetRS.C:164
 testDetRS.C:165
 testDetRS.C:166
 testDetRS.C:167
 testDetRS.C:168
 testDetRS.C:169
 testDetRS.C:170
 testDetRS.C:171
 testDetRS.C:172
 testDetRS.C:173
 testDetRS.C:174
 testDetRS.C:175
 testDetRS.C:176
 testDetRS.C:177
 testDetRS.C:178
 testDetRS.C:179
 testDetRS.C:180
 testDetRS.C:181
 testDetRS.C:182
 testDetRS.C:183
 testDetRS.C:184
 testDetRS.C:185
 testDetRS.C:186
 testDetRS.C:187
 testDetRS.C:188
 testDetRS.C:189
 testDetRS.C:190
 testDetRS.C:191
 testDetRS.C:192
 testDetRS.C:193
 testDetRS.C:194
 testDetRS.C:195
 testDetRS.C:196
 testDetRS.C:197
 testDetRS.C:198
 testDetRS.C:199
 testDetRS.C:200
 testDetRS.C:201
 testDetRS.C:202
 testDetRS.C:203
 testDetRS.C:204
 testDetRS.C:205
 testDetRS.C:206
 testDetRS.C:207
 testDetRS.C:208
 testDetRS.C:209
 testDetRS.C:210
 testDetRS.C:211
 testDetRS.C:212
 testDetRS.C:213
 testDetRS.C:214
 testDetRS.C:215
 testDetRS.C:216
 testDetRS.C:217
 testDetRS.C:218
 testDetRS.C:219
 testDetRS.C:220
 testDetRS.C:221
 testDetRS.C:222
 testDetRS.C:223
 testDetRS.C:224
 testDetRS.C:225
 testDetRS.C:226
 testDetRS.C:227
 testDetRS.C:228
 testDetRS.C:229
 testDetRS.C:230
 testDetRS.C:231
 testDetRS.C:232
 testDetRS.C:233
 testDetRS.C:234
 testDetRS.C:235
 testDetRS.C:236
 testDetRS.C:237
 testDetRS.C:238
 testDetRS.C:239
 testDetRS.C:240
 testDetRS.C:241
 testDetRS.C:242
 testDetRS.C:243
 testDetRS.C:244
 testDetRS.C:245
 testDetRS.C:246
 testDetRS.C:247
 testDetRS.C:248
 testDetRS.C:249
 testDetRS.C:250
 testDetRS.C:251
 testDetRS.C:252
 testDetRS.C:253
 testDetRS.C:254
 testDetRS.C:255
 testDetRS.C:256
 testDetRS.C:257
 testDetRS.C:258
 testDetRS.C:259
 testDetRS.C:260
 testDetRS.C:261
 testDetRS.C:262
 testDetRS.C:263
 testDetRS.C:264
 testDetRS.C:265
 testDetRS.C:266
 testDetRS.C:267
 testDetRS.C:268
 testDetRS.C:269
 testDetRS.C:270
 testDetRS.C:271
 testDetRS.C:272
 testDetRS.C:273
 testDetRS.C:274
 testDetRS.C:275
 testDetRS.C:276
 testDetRS.C:277
 testDetRS.C:278
 testDetRS.C:279
 testDetRS.C:280
 testDetRS.C:281
 testDetRS.C:282
 testDetRS.C:283
 testDetRS.C:284
 testDetRS.C:285
 testDetRS.C:286
 testDetRS.C:287
 testDetRS.C:288
 testDetRS.C:289
 testDetRS.C:290
 testDetRS.C:291
 testDetRS.C:292
 testDetRS.C:293
 testDetRS.C:294
 testDetRS.C:295
 testDetRS.C:296
 testDetRS.C:297
 testDetRS.C:298
 testDetRS.C:299
 testDetRS.C:300
 testDetRS.C:301
 testDetRS.C:302
 testDetRS.C:303
 testDetRS.C:304
 testDetRS.C:305
 testDetRS.C:306
 testDetRS.C:307
 testDetRS.C:308
 testDetRS.C:309
 testDetRS.C:310
 testDetRS.C:311
 testDetRS.C:312
 testDetRS.C:313
 testDetRS.C:314
 testDetRS.C:315
 testDetRS.C:316
 testDetRS.C:317
 testDetRS.C:318
 testDetRS.C:319
 testDetRS.C:320
 testDetRS.C:321
 testDetRS.C:322
 testDetRS.C:323
 testDetRS.C:324
 testDetRS.C:325
 testDetRS.C:326
 testDetRS.C:327
 testDetRS.C:328
 testDetRS.C:329
 testDetRS.C:330
 testDetRS.C:331
 testDetRS.C:332
 testDetRS.C:333
 testDetRS.C:334
 testDetRS.C:335
 testDetRS.C:336
 testDetRS.C:337
 testDetRS.C:338
 testDetRS.C:339
 testDetRS.C:340
 testDetRS.C:341
 testDetRS.C:342
 testDetRS.C:343
 testDetRS.C:344
 testDetRS.C:345
 testDetRS.C:346
 testDetRS.C:347
 testDetRS.C:348
 testDetRS.C:349
 testDetRS.C:350
 testDetRS.C:351
 testDetRS.C:352
 testDetRS.C:353
 testDetRS.C:354
 testDetRS.C:355
 testDetRS.C:356
 testDetRS.C:357
 testDetRS.C:358
 testDetRS.C:359
 testDetRS.C:360
 testDetRS.C:361
 testDetRS.C:362
 testDetRS.C:363
 testDetRS.C:364
 testDetRS.C:365
 testDetRS.C:366
 testDetRS.C:367
 testDetRS.C:368
 testDetRS.C:369
 testDetRS.C:370
 testDetRS.C:371
 testDetRS.C:372
 testDetRS.C:373
 testDetRS.C:374
 testDetRS.C:375
 testDetRS.C:376
 testDetRS.C:377
 testDetRS.C:378
 testDetRS.C:379
 testDetRS.C:380
 testDetRS.C:381
 testDetRS.C:382
 testDetRS.C:383
 testDetRS.C:384
 testDetRS.C:385
 testDetRS.C:386
 testDetRS.C:387
 testDetRS.C:388
 testDetRS.C:389
 testDetRS.C:390
 testDetRS.C:391
 testDetRS.C:392
 testDetRS.C:393
 testDetRS.C:394
 testDetRS.C:395
 testDetRS.C:396
 testDetRS.C:397
 testDetRS.C:398
 testDetRS.C:399
 testDetRS.C:400
 testDetRS.C:401
 testDetRS.C:402
 testDetRS.C:403
 testDetRS.C:404
 testDetRS.C:405
 testDetRS.C:406
 testDetRS.C:407
 testDetRS.C:408
 testDetRS.C:409
 testDetRS.C:410
 testDetRS.C:411
 testDetRS.C:412
 testDetRS.C:413
 testDetRS.C:414
 testDetRS.C:415
 testDetRS.C:416
 testDetRS.C:417
 testDetRS.C:418
 testDetRS.C:419
 testDetRS.C:420
 testDetRS.C:421
 testDetRS.C:422
 testDetRS.C:423
 testDetRS.C:424
 testDetRS.C:425
 testDetRS.C:426
 testDetRS.C:427
 testDetRS.C:428
 testDetRS.C:429
 testDetRS.C:430
 testDetRS.C:431
 testDetRS.C:432
 testDetRS.C:433
 testDetRS.C:434
 testDetRS.C:435
 testDetRS.C:436
 testDetRS.C:437
 testDetRS.C:438
 testDetRS.C:439
 testDetRS.C:440
 testDetRS.C:441
 testDetRS.C:442
 testDetRS.C:443
 testDetRS.C:444
 testDetRS.C:445
 testDetRS.C:446
 testDetRS.C:447
 testDetRS.C:448
 testDetRS.C:449
 testDetRS.C:450
 testDetRS.C:451
 testDetRS.C:452
 testDetRS.C:453
 testDetRS.C:454
 testDetRS.C:455
 testDetRS.C:456
 testDetRS.C:457
 testDetRS.C:458
 testDetRS.C:459
 testDetRS.C:460
 testDetRS.C:461
 testDetRS.C:462
 testDetRS.C:463
 testDetRS.C:464
 testDetRS.C:465
 testDetRS.C:466
 testDetRS.C:467
 testDetRS.C:468
 testDetRS.C:469
 testDetRS.C:470
 testDetRS.C:471
 testDetRS.C:472
 testDetRS.C:473
 testDetRS.C:474
 testDetRS.C:475
 testDetRS.C:476
 testDetRS.C:477
 testDetRS.C:478
 testDetRS.C:479
 testDetRS.C:480
 testDetRS.C:481
 testDetRS.C:482
 testDetRS.C:483
 testDetRS.C:484
 testDetRS.C:485
 testDetRS.C:486
 testDetRS.C:487
 testDetRS.C:488
 testDetRS.C:489