ROOT logo
#include "AliMassFitControl.h"

// Function for fitting back ground away from peak
Float_t quad(Double_t *x, Double_t *par){
  if (x[0] > par[3] && x[0] < par[4]){
    TF1::RejectPoint();
    return 0;
  }
  return par[0] + par[1]*x[0] + par[2]*x[0]*x[0]; //a+bx+cx**2
}

TH1F* PtMassAna2(TH2F *PtMass, Int_t mode,Int_t ihist, const Int_t NControl, TObjArray *ControlArray,Char_t* fulllabel){

  gROOT->SetStyle("Plain");
  gStyle->SetOptFit(1111);
  //TString *tLabel = new TString(fulllabel); //not reqd

  //Arguments TH2F *PtMass - 2D histogram of some variable versus mass
  //          Int_t mode - mode for switching things depending on particle
  //          const Int_t NControl - number of bins to project into which must
  //          be the same as the number of controller objects (see next arg).
  //          TObjArray *ContolArray - holds the controllers objects, 1 per bin

  //const Int_t NDefault=27; // Used in default array (change as required)
  // Trap user errors
  if (ControlArray->GetEntries() != NControl){
    cout << "PtMassAna2: Problem: Specified number of bins and number of bins in supplied TObjArray do not match" << endl;
    return 0;
  }
  //Set up mode mapping to particle and names for histograms
  if(mode == 0){ 
    const Char_t* part = "K0";
    const Char_t* partName = "K^{0}_{s}";
  }
  else if (mode == 1 ){
    const Char_t* part = "LAM";
    const Char_t* partName = "#Lambda";
  }
  else if (mode == 2 ){//since lambda and anti-Lambda have same limits etc.
    const Char_t* part = "LAM"; 
    const Char_t* partName = "#bar{#Lambda}";
  }
  else if (mode ==3) {// This is for combined Lambda + anti-Lambda
    const Char_t* part = "LAM";
    const Char_t* partName = "#Lambda + #bar{#Lambda}";
  }
  else if (mode ==4) {
    const Char_t* part = "XI";
    const Char_t* partName = "#Xi";
  }
  else{
    cout << "Mode not recognized, defaulting to K0" << endl;
    const Char_t* part = "K0";
  }
  cout << "Debug info. Particle: " << part << endl;

  Float_t xxlo, xxhi; //Exclusion limits for fitting
  // FUTURE - these can also be part of AliMassFitControl to allow different regions
  // in different bins
  Float_t NSigmaEx=4.0;  // Number of sigma to exclude from bkgd fit
  Float_t NSigmaInt=3.5; // Number of sigma to integrate histo over

  // Fitting function for initial combined peak + background fit
  TF1 *gausQuad = new TF1("gausQuad","(([1]/([2]*pow(6.2831,0.5)))*[6]*exp(-0.5*pow((x-[0])/[2],2)))+ [3] + [4]*x + [5]*x*x",0.3,1.8);
  //>>>>>>>>> NB Need to set proper range when it is used <<<<<<<<<<<<<<<<<<<<<
  //>>>>>>>>> AND use 'R' in fit option                   <<<<<<<<<<<<<<<<<<<<<
  gausQuad->SetLineWidth(1);
  gausQuad->SetLineColor(kRed);

  // Fitting function for background 
  TF1* quad = new TF1("quad",quad,0.3,1.8,5);
  quad->SetLineWidth(2);
  quad->SetLineColor(kBlue);
  quad->SetLineStyle(2);

  // Function for background under peak - to be integrated and drawn
  TF1* qback = new TF1("qback","[0]+[1]*x+[2]*x*x",0.3,1.8);
  qback->SetLineWidth(2);
  qback->SetLineColor(kRed);
  qback->SetLineStyle(2);
  qback->SetFillStyle(3013);
  qback->SetFillColor(kRed);

  // Set ranges and limits according to particle
  Float_t xmin,xmax;
  Float_t defMean,defArea,defWidth,defa0,defa1,defa2,defBW; //defaults
  Float_t defMnLo, defMnHi;
  if (part=="K0"){
    // FUTURE: xmin, xmax define the range considered in fit so could go into
    // AliMassFitControl
    //xmin=0.418;
    //xmax=0.578;
    //    xxlo=0.46;xxhi=0.53;
    //    gausQuad->SetParameters(0.4977,2000,0.003,1,1,0,0.001*RBFact);
    //gausQuad->SetParameters(0.4977,2000,0.003,1,1,0,0.001);
    defMean=0.4977; defArea=1000; defWidth=0.01;
    defa0=2; defa1=2; defa2=0;
    //gausQuad->SetParLimits(0,0.483,0.523); // Constrain mean
    defMnLo = 0.483; defMnHi=0.523;
  }
  if (part=="LAM"){
    // FUTURE: See above
    //xmin=1.085;
    //xmax=1.17;
    //  xxlo=1.10;xxhi=1.135;
    //    gausQuad->SetParameters(1.115,2000,0.0028,10,100,-100,0.001*RBFact);
    //  gausQuad->SetParameters(1.115,2000,0.0028,10,100,-100,0.001);
    defMean=1.115; defArea=1000; defWidth=0.08;
    defa0=100; defa1=-10; defa2=0;
    //    gausQuad->SetParLimits(0,1.113,1.123); // Constrain mean
    defMnLo=1.113; defMnHi=1.123;
  }
  if (part=="XI"){
    defMean=1.32171; defArea=500; defWidth=0.08;
    defa0=100; defa1=-10; defa2=0;
    defMnLo=1.301; defMnHi=1.341;
  }
  //gausQuad->SetRange(xmin,xmax);
  gausQuad->SetParLimits(1,0.0,1E7); // Constrain area 0 to 10 million
  gausQuad->SetParLimits(2,0.0001,0.04); // Constrain width 0.1 MeV to 40 MeV
  gausQuad->SetParNames("Mean","Area1","Sigma1","p0","p1","p2","BinWid"); 

  // Deciding how to divide up the canvas
  c1->Clear();
  c1->SetWindowSize(1024,768);
  Int_t NDraw = NControl;
  if(NDraw==16){c1->Divide(4,4);}
  elseif(NDraw<=36 && NDraw>30){ c1->Divide(6,6);}
  elseif(NDraw<=30 && NDraw>25) { c1->Divide(6,5);}
  elseif(NDraw<=25 && NDraw>20){ c1->Divide(5,5);}
  elseif(NDraw<=20 && NDraw>16){  c1->Divide(5,4);}
  elseif(NDraw<=15 && NDraw>12){ c1->Divide(5,3);}
  elseif(NDraw<=12 && NDraw>8){ c1->Divide(4,3);}
  elseif(NDraw<=8 && NDraw>6){ c1->Divide(4,2);}
  elseif(NDraw<=6 && NDraw>4){c1->Divide(3,2);}
  elseif(NDraw<=4 && NDraw>2){c1->Divide(2,2);}
  elseif(NDraw==2){c1->Divide(2,1);}
  elseif(NDraw==1){/*do nothing*/;}
  else{c1->Divide(7,6);}

  //
  // Project out the histograms from 2D into 1D 'slices'
  //
  Char_t id[20], title[80];
  //cout << "NControl: " << NControl << endl;
  TH1D* hMassSlice[NControl];
  //Arrays to store various quantities which can later be histogrammed.
  //  const Int_t NBinsArrays = NBins+1-NFirst; // array of 1D projection histograms is counted from 0 but other arrays are used for histograms contents and therefore N+1 are need because element zero is left empty
  const Int_t NBinsArrays = NControl+1;
  Stat_t sigBkgd[NBinsArrays], errSigBkgd[NBinsArrays]; // Signal+background and error on this
  Stat_t bkgd[NBinsArrays], errBkgd[NBinsArrays]; // Background and error on this
  Stat_t signal[NBinsArrays], errSignal[NBinsArrays]; // Net signal and error

  Stat_t chi2PerDOF1[NBinsArrays], errChi2PerDOF1[NBinsArrays]; // Chi-squared per defree of freedom from the initial fit
  Stat_t chi2PerDOF2[NBinsArrays], errChi2PerDOF2[NBinsArrays]; // Chi-squared per defree of freedom from the 2nd (background) fit

  // REDO won't need this?
  // Zero the signal - avoids problems with plotting
  for(Int_t j=0;j<NBinsArrays;j++){
    signal[j]=0.0;
    errSignal[j]=1.0;
  } // <<< Not actually in use a the moment <<<

  Stat_t mean[NBinsArrays], errMean[NBinsArrays]; // Mean and error
  Stat_t sigma[NBinsArrays], errSigma[NBinsArrays]; // Gaussian width and error
  Stat_t area[NBinsArrays], errArea[NBinsArrays]; // Peak area from fit and error
  Stat_t integLow[NBinsArrays], integUp[NBinsArrays]; // Lower/upper limits for integration

  // Float_t DefaultBinPtEdges[NDefault]={0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.8,1.0,1.2,1.4,1.6,1.8,2.0,2.2,2.4,2.6,2.8,3.0,3.5,4.0,4.5,5.0,5.5,6.0,6.5,7.0};
  Float_t BinPtEdges[NBinsArrays];
  
  //  Float_t BinPtEdges[NBins+1]={0.0,0.2,0.4,0.6,0.8,1.0,1.2,1.4,1.6,1.8,2.0,2.2,2.4,2.6,2.8,3.0,3.5,4.0,4.5,5.0,5.5,6.0,6.5,7.0};

  Int_t BinLo, BinHi; //For pt bins
  // **** Main loop over the AliMassFitControllers ****
 
  TIter controlIter(ControlArray);
  AliMassFitControl *controller;
  while (controller=(AliMassFitControl*)controlIter.Next()) { 
    if(ihist == 0)controller->CalcBinLimits(20); //This BinsPerGeV argument should be calculated from the data
    if(ihist == 1)controller->CalcBinLimits(50); //This BinsPerGeV argument should be calculated from the data
    if(ihist == 2)controller->CalcBinLimits(50); //This BinsPerGeV argument should be calculated from the data
    if(ihist == 3)controller->CalcBinLimits(1); //This BinsPerGeV argument should be calculated from the data
    if(ihist == 4)controller->CalcBinLimits(1); //This BinsPerGeV argument should be calculated from the data
    if(ihist == 6)controller->CalcBinLimits(20000); //This BinsPerGeV argument should be calculated from the data
    if(ihist == 5)controller->CalcBinLimits(100); //This BinsPerGeV argument should be calculated from the data
    //Had to introduce this Nint fn otherwise got inconsistencies after type implicit conversion
    //    BinLo=TMath::Nint(1.+BinPtEdges[N]*20.); //cout << "BinLo: " << BinLo << ", " << 1+BinPtEdges[N]*20. << endl;
    //    BinHi=TMath::Nint(BinPtEdges[N+1]*20.); //cout << "BinHi: " << BinHi << ", " << BinPtEdges[N+1]*20. << endl;
    BinLo=controller->BinLower();
    BinHi=controller->BinUpper();
    Int_t N=ControlArray->IndexOf(controller) - 1;
    sprintf(id,"Mass%d",N);
    cout << "Mass histo:" << N << " Firstbin: " << BinLo << " Last bin:" << BinHi << " " << controller->PtLower() << "-" << controller->PtUpper() << " GeV" << endl; 
    //cout << "About to create mass projection " << N << endl;
    if(ihist == 0) hMassSlice[N] = PtMass->ProjectionX(id,BinLo,BinHi);
    if(ihist != 0) hMassSlice[N] = PtMass->ProjectionY(id,BinLo,BinHi);
    //cout << "Mass projection " << N << " created." << endl;
   sprintf(title,"%s Mass, %.2f < p_{t} < %.2f",partName,controller->PtLower(),controller->PtUpper());
    hMassSlice[N]->SetTitle(title);
    hMassSlice[N]->SetXTitle("GeV/c^{2}");
    // cout << "Mass projection " << N << " titles set." << endl;
    hMassSlice[N]->Rebin(controller->RebinFactor());
    // } // End of creating the projections
    Int_t massBinLo,massBinHi; //For mass histogram bins
    Int_t NArray;
  // Do all the fitting
    //REDO this is all one loop (iteration over TObjArray) now
  //for(Int_t N=0;N<NBins-NFirst;N++){
    NArray=N+1; // Arrays numbered from 1 not 0..
    c1->cd(N+1); //Canvas subdivisions numbered from 1 and NOT 0

    // Set range - can be different each time
    xmin=controller->MinMass();
    xmax=controller->MaxMass();
    gausQuad->SetRange(xmin,xmax);
    // Everytime need to set some sensible parameters for both fits
    gausQuad->SetParameters(defMean,defArea,defWidth,defa0,defa1,defa2,0.1);
    quad->SetParameters(defa0,defa1,defa2,0.49,0.51);// Last 2 parameters are
    // the range to exclude but these are fixed later by FixParameter(3,.. etc.
    gausQuad->FixParameter(6,hMassSlice[N]->GetBinWidth(1));
    // Release Linear parameter
    gausQuad->ReleaseParameter(4);
    quad->ReleaseParameter(1);
    // Release Quadratic parameter
    gausQuad->ReleaseParameter(5);
    quad->ReleaseParameter(2);
    gausQuad->SetParLimits(0,defMnLo,defMnHi);
    gausQuad->SetParLimits(1,0.0,1E7); // Constrain area 0 to 10 million
    gausQuad->SetParLimits(2,0.0001,0.04); // Constrain width 0.1 MeV to 40 MeV
//     gausQuad->SetParLimits(4,0,0); // Releases linear parameter
//     quad->SetParLimits(1,0,0); // Releases linear parameter
//     gausQuad->SetParLimits(5,0,0); // Releases quadratic parameter
//     quad->SetParLimits(2,0,0); // Releases quadratic parameter
    if(controller->FixedLin()){
      quad->FixParameter(1,0.0);
      gausQuad->FixParameter(4,0.0);
      cout << "Info: linear part fixed to zero." << endl;
      gausQuad->SetParLimits(3,0.0,1000); // Ensure constant is +ve
      // NB documentation indicates that limits only used when option B
      // is specified. Also how are they can they be freed later?
    }
    if(controller->FixedQuad()){ 
      quad->FixParameter(2,0.0);
      gausQuad->FixParameter(5,0.0);
      cout << "Info: quadratic part fixed to zero." << endl;
    }
    hMassSlice[N]->Fit(gausQuad,"LR");
    hMassSlice[N]->Draw("E,SAME");
    gausQuad->DrawCopy("SAME");
    hMassSlice[N]->Clone("hMySlice");
    //Fit the background:
    xxlo=gausQuad->GetParameter(0)-NSigmaEx*gausQuad->GetParameter(2);
    xxhi=gausQuad->GetParameter(0)+NSigmaEx*gausQuad->GetParameter(2);
    // Limits have to be adjusted to match bins
    massBinLo=hMassSlice[N]->FindBin(xxlo);
    xxlo = hMassSlice[N]->GetBinLowEdge(massBinLo);
    massBinHi=hMassSlice[N]->FindBin(xxhi)+1;
    xxhi = hMassSlice[N]->GetBinLowEdge(massBinHi);
    quad->SetParameters(gausQuad->GetParameter(3),gausQuad->GetParameter(4),gausQuad->GetParameter(5),xxlo,xxhi);
    quad->FixParameter(3,xxlo);
    quad->FixParameter(4,xxhi);
    quad->SetRange(xmin,xmax);
    hMassSlice[N]->Fit(quad,"LRN+");
    quad->SetFillColor(30);
    quad->SetFillStyle(3013);
    quad->SetRange(xmin,xxlo);
    quad->DrawCopy("SAME");
    quad->SetRange(xxhi,xmax);
    quad->DrawCopy("SAME");

    // Draw the background - use a new function since other one not defined everywhere
    xxlo=gausQuad->GetParameter(0)-NSigmaInt*gausQuad->GetParameter(2);
    xxhi=gausQuad->GetParameter(0)+NSigmaInt*gausQuad->GetParameter(2);
    massBinLo=hMassSlice[N]->FindBin(xxlo);
    xxlo = hMassSlice[N]->GetBinLowEdge(massBinLo);
    massBinHi=hMassSlice[N]->FindBin(xxhi)+1;
    xxhi = hMassSlice[N]->GetBinLowEdge(massBinHi);
    qback->SetRange(xxlo,xxhi);
    qback->SetParameter(0,quad->GetParameter(0));
    qback->SetParameter(1,quad->GetParameter(1));
    qback->SetParameter(2,quad->GetParameter(2));
    qback->DrawCopy("SAME");
    if(N==28){
TCanvas *myCan = new TCanvas();
TPad *mypad = new TPad();
myCan->cd();
mypad->Draw();
hMassSlice[N]->Draw();
quad->SetRange(xmin,xxlo);
quad->DrawCopy("SAME");
quad->SetRange(xxhi,xmax);
quad->DrawCopy("SAME");
qback->DrawCopy("SAME");

}
   

    //Integrate the signal+background (i.e. original histo)
    sigBkgd[NArray]=hMassSlice[N]->Integral(massBinLo,massBinHi-1);
    errSigBkgd[NArray]=TMath::Sqrt(sigBkgd[NArray]);
    //Integrate background - better to do this analytically ?
    bkgd[NArray]=qback->Integral(xxlo,xxhi)/gausQuad->GetParameter(6);//Divide by bin width
    errBkgd[NArray]=TMath::Sqrt(bkgd[NArray]); //Get errors from fit parameters?

    // Fill arrays for diagnostic histograms
    mean[NArray]=gausQuad->GetParameter(0);
    errMean[NArray]=gausQuad->GetParError(0);
    area[NArray]=gausQuad->GetParameter(1);
    errArea[NArray]=gausQuad->GetParError(1);
    sigma[NArray]=gausQuad->GetParameter(2);
    errSigma[NArray]=gausQuad->GetParError(2);
    chi2PerDOF1[NArray]=gausQuad->GetChisquare()/(Double_t)gausQuad->GetNDF();
    errChi2PerDOF1[NArray]= 0.0; // Don't know how to calc. error for this?
    chi2PerDOF2[NArray]=quad->GetChisquare()/(Double_t)quad->GetNDF();
    errChi2PerDOF2[NArray]= 0.0; // Don't know how to calc. error for this?

    BinPtEdges[N]=controller->PtLower();
    //    BinPtEdges(N+1)=controller->PtUpper();
  }
    BinPtEdges[NBinsArrays-1]=((AliMassFitControl*)ControlArray->Last())->PtUpper();
//     for (Int_t jj=0;jj<NBinsArrays;jj++){
//       cout << "BinPtEdges " << jj << " = " << BinPtEdges[jj] << endl;
//       cout << "Mean " << jj << " = " << mean[jj] << endl;
//       cout << "Sigma " << jj << " = " << sigma[jj] << endl;
//       cout << "Signal + bkgd " << jj << " = " << sigBkgd[jj] << endl;
//       cout << "Background " << jj << " = " << bkgd[jj] << endl;
//     }
  // Yields in each bin returned in a histogram
  TH1F* hYields= new TH1F("Yield","Raw Particle Yield",NBinsArrays-1,BinPtEdges);
  //hYields->Reset("ICE");
  hYields->SetXTitle("p_{t} / (GeV/c)");
  //hYields->SetContent(sigBkgd);
  //hYields->SetError(errSigBkgd);
  //c1->cd(4);
  //hYields->Draw();

  // Fill the diagnostic histograms: clone, set title, contents, errors.
  TH1F* hMeans = hYields->Clone("Means");
  hMeans->SetTitle("Mean from Gaussian Fit");
  hMeans->SetContent(mean);
  hMeans->SetError(errMean);
  //hMeans->Sumw2();
  TH1F* hSigmas = hYields->Clone("Sigmas");
  hSigmas->SetTitle("Sigma from Gaussian Fit");
  hSigmas->SetContent(sigma);
  hSigmas->SetError(errSigma);
  TH1F* hAreas = hYields->Clone("Areas");
  hAreas->SetTitle("Area from Gaussian Fit");
  hAreas->SetContent(area);
  hAreas->SetError(errArea);
  TH1F* hSigBkgd = hYields->Clone("SigBkgd");
  hSigBkgd->SetTitle("Signal + Background (Histo. Integral)");
  hSigBkgd->SetContent(sigBkgd);
  hSigBkgd->SetError(errSigBkgd);
  TH1F* hBkgd = hYields->Clone("Bkgd");
  hBkgd->SetTitle("Background (Fn. integral)");
  hBkgd->SetContent(bkgd);
  hBkgd->SetError(errBkgd);

  hYields->Sumw2();
  hYields->Add(hSigBkgd,hBkgd,1.0,-1.0);

  TH1F* hSoverB = hYields->Clone("SoverB");
  hSoverB->SetTitle("Signal to Background ratio");
  hSoverB->Sumw2();
  hSoverB->Divide(hBkgd);

  TH1F* hSoverA = hYields->Clone("SoverA"); // Signal over area
  hSoverA->SetTitle("Ratio of Signal to Area from Fit");
  hSoverA->Sumw2();
  hSoverA->Divide(hAreas);

  TH1F* hChi2PerDOF1 = hYields->Clone("Chi2PerDOF1");
  hChi2PerDOF1->SetTitle("Chi-squared per d.o.f. - initial fit");
  hChi2PerDOF1->SetContent(chi2PerDOF1);
  hChi2PerDOF1->SetError(errChi2PerDOF1);

  TH1F* hChi2PerDOF2 = hYields->Clone("Chi2PerDOF2");
  hChi2PerDOF2->SetTitle("Chi-squared per d.o.f. - background fit");
  hChi2PerDOF2->SetContent(chi2PerDOF2);
  hChi2PerDOF2->SetError(errChi2PerDOF2);

  // Draw the diagnostic histograms on their own canvas
  TCanvas* cDiag = new TCanvas("Diag","Diagnostics",600,600);
  cDiag->Divide(2,3);

  cDiag->cd(1);
  Float_t bookmass;
  if(part=="LAM"){
    bookmass=1.11563;
    hMeans->SetMinimum(bookmass-0.01);
    hMeans->SetMaximum(bookmass+0.01);
  } else if (part=="K0"){
    bookmass=0.4976;
    hMeans->SetMinimum(bookmass-0.01);
    hMeans->SetMaximum(bookmass+0.01);
  } else if (part=="XI") {
    hMeans->SetMaximum(1.34);
    hMeans->SetMinimum(1.30);
    bookmass=1.32171;
  }
  Float_t maxPt = hMeans->GetBinLowEdge(hMeans->GetNbinsX()+1);
  TLine PDGmass;
  PDGmass.SetLineStyle(2);
  hMeans->Draw();
  PDGmass.DrawLine(0,bookmass,maxPt,bookmass);

  cDiag->cd(2);
  if (part=="K0"){
    hSigmas->SetMaximum(0.06);
  }else{
    hSigmas->SetMaximum(0.006);}
  hSigmas->SetMinimum(0.0);
  hSigmas->Draw();

  cDiag->cd(3);
  hSoverB->SetMinimum(0.0);
  hSoverB->Draw();

  cDiag->cd(4);
  hSoverA->SetMinimum(0.5);
  hSoverA->SetMaximum(1.5);
  hSoverA->Draw();

  cDiag->cd(5);
  hChi2PerDOF1->SetMinimum(0);
  hChi2PerDOF1->SetMaximum(6);
  hChi2PerDOF1->Draw();

  cDiag->cd(6);
  hChi2PerDOF2->SetMinimum(0);
  hChi2PerDOF2->SetMaximum(6);
  hChi2PerDOF2->Draw();

  Char_t fileNameBase[80];
  sprintf(fileNameBase,"Diagnostics%s_%s",part,fulllabel);
  Char_t fileNamePng[80];
  sprintf(fileNamePng,"%s.png",fileNameBase);
  Char_t fileNameEps[80];
  sprintf(fileNameEps,"%s.eps",fileNameBase);
  Char_t fileNamePdf[80];
  sprintf(fileNamePdf,"%s.pdf",fileNameBase);
  
  cDiag->SaveAs(fileNamePng);
  cDiag->SaveAs(fileNameEps);
  cDiag->SaveAs(fileNamePdf);
 
  // Scale result by the bin size to get dN/dpT and by bin centre to get 1/pt...
  Float_t y, ey;
  for(Int_t j=0;j<=hYields->GetNbinsX();j++){
    y = hYields->GetBinContent(j)/hYields->GetBinWidth(j);
    ey = hYields->GetBinError(j)/hYields->GetBinWidth(j);
    hYields->SetBinContent(j,y);
    hYields->SetBinError(j,ey);
//    y = hYields->GetBinContent(j)/hYields->GetBinCenter(j);
//    ey = hYields->GetBinError(j)/hYields->GetBinCenter(j);
    hYields->SetBinContent(j,y);
    hYields->SetBinError(j,ey);
  }
  return hYields;

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