ROOT logo
//*-- Author : Vladimir Pechenov 24.11.2011

#include "halignmentmeta.h"
#include "TMinuit.h"
#include "TFile.h"
#include "TString.h"
#include "TNtuple.h"
#include "hmdcsizescells.h"
#include "hades.h"
#include "hruntimedb.h"
#include "hspecgeompar.h"
#include "hgeomvolume.h"
#include <iostream>

using namespace std;

ClassImp(HAlignmentMeta)
    
HAlignmentMeta::HAlignmentMeta() {
  trackSelecCutX  = 1.5;
  trackSelecCutY  = 1.0;
  filterFlag      = kTRUE;
  nMetaModules    = 0;
  metaDetector    = 3;
  fitTofModYPos   = kFALSE;
  xShitfRpc       = 0.;
  calcCellXOffset = kFALSE;
  nCells          = 0;
  nCellsTot       = 0;
}

void HAlignmentMeta::setTofDetector(Double_t cutX,Double_t cutY) {
  metaDetector = 0;
  nMetaModules = 8;
  setCuts(cutX,cutY);
  nCells       = 8;
  nCellsTot    = nMetaModules*nCells;
}

void HAlignmentMeta::setShowerDetector(Double_t cutX,Double_t cutY) {
  metaDetector = 1;
  nMetaModules = 1;
  setCuts(cutX,cutY);
  nCells       = 32;       // number of rows
  nCellsTot    = nCells;
}

void HAlignmentMeta::setRpcDetector(Double_t cutX,Double_t cutY) {
  metaDetector = 2;
  nMetaModules = 1;
  setCuts(cutX,cutY);
  nCells       = 32;
  nCellsTot    = 6*nCells; // 6-number of columns in RPC
}

void HAlignmentMeta::setCuts(Double_t cutX,Double_t cutY) {
  trackSelecCutX = cutX;
  trackSelecCutY = cutY;
  if(trackSelecCutX > 0. && trackSelecCutY > 0.) filterFlag = kTRUE;
  else                                           filterFlag = kFALSE;
}

void HAlignmentMeta::setNtuple(TNtuple *ntp) {
  nt = ntp;
  nt -> SetBranchAddress("s",&sec);
  nt -> SetBranchAddress("x1s",&x1); // yuxari dubna 
  nt -> SetBranchAddress("y1s",&y1); // yuxari dubna
  nt -> SetBranchAddress("z1s",&z1);
  nt -> SetBranchAddress("x2s",&x2); // yuxari gsi 
  nt -> SetBranchAddress("y2s",&y2); // yuxari gsi
  nt -> SetBranchAddress("z2s",&z2);
  nt -> SetBranchAddress("metaMod",&metaModule);
  nt -> SetBranchAddress("col",&metaColumn);
  nt -> SetBranchAddress("cell",&metaCell);
  nt -> SetBranchAddress("xMeta",&xMetaLocal); // ashagi gsi
  nt -> SetBranchAddress("yMeta",&yMetaLocal);
  nt -> SetBranchAddress("zMeta",&zMetaLocal);
  nt -> SetBranchAddress("sigX",&xRMS);
  nt -> SetBranchAddress("sigY",&yRMS);
  nt -> SetBranchAddress("sigZ",&zRMS);
//nt -> SetBranchAddress("beta",&beta);
}

HAlignmentMeta::~HAlignmentMeta() {
  if(gMinuit != NULL) delete gMinuit;
}

void HAlignmentMeta::fcnMeta(Int_t &npar, Double_t *gin, Double_t &fn, Double_t *par, Int_t iflag) {
  static int count = 1;
  count++;
  HAlignmentMeta *myObject   = (HAlignmentMeta*)(gMinuit -> GetObjectFit());
  fn = myObject->getMinFunction(par);
  if(count%100 == 0)  cout<<"iter:  "<<count<<"  function  "<<fn<<" "<<par[0]<<"  "<<par[1]<<"  "
                      <<par[2]<<"  "<<par[3]<<"  "<<par[4]<<"  "<<par[5]<< endl;
}

void HAlignmentMeta::alignMeta(Int_t sec,TNtuple *ntp) {
  if(metaDetector<0 || metaDetector>2) {
    Error("alignMeta","Meta detector type is not setted! Stop!");
    exit(1);
  }
  alignSec = sec;
  setNtuple(ntp);

  HSpecGeomPar*         fSpecGeomPar = (HSpecGeomPar*)gHades->getRuntimeDb()->getContainer("SpecGeomPar");
  const HGeomTransform& secLabTrans  = fSpecGeomPar->getSector(alignSec)->getTransform();
  
  xShitfRpc = 0.;
  for(Int_t im=0;im<nMetaModules;im++) {
    transMetaModSecOld[im] = transMetaModLabOld[im];
    transMetaModSecOld[im].transTo(secLabTrans);  // trans.from lab. to sector coor.sys.
  }

  Int_t ierflg = 0;
  if(gMinuit == NULL) {
    if(metaDetector == 0) new TMinuit(6+8);
    else                  new TMinuit(6);
  }
  gMinuit->mncler();
  gMinuit->SetFCN(fcnMeta);
  gMinuit->SetObjectFit(this);
  Double_t arglist[6];
  
  fillArray();

  gMinuit->mnparm(0,"x",     0.,  1.,0,0,ierflg);
  gMinuit->mnparm(1,"y",     0.,  1.,0,0,ierflg);
  gMinuit->mnparm(2,"z",     0.,  1.,0,0,ierflg);
  gMinuit->mnparm(3,"alpha", 0., 0.1,0,0,ierflg);
  gMinuit->mnparm(4,"beta",  0., 0.1,0,0,ierflg);
  gMinuit->mnparm(5,"gamma", 0., 0.1,0,0,ierflg);
  if(metaDetector != 1) {         // TOF&RPC
    gMinuit->FixParameter(0);
    gMinuit->FixParameter(4);
    if(metaDetector == 0) {         // TOF
      if(fitTofModYPos) {
        for(Int_t ip=0;ip<8;ip++) {
          TString parName("Ymod");
          parName += ip;
          gMinuit->mnparm(6+ip,parName.Data(),0.,1.,0,0,ierflg);
        }
        for(Int_t ip=0;ip<8;ip++) gMinuit->FixParameter(6+ip);
        for(Int_t ip=0;ip<8;ip++) tofModYSh[ip] = 0.;
      }
    }
  }

    
//  gMinuit->SetPrintLevel(-1);
gMinuit->SetPrintLevel(1);
//!!!  gMinuit->SetErrorDef(1);
  arglist[0] = 2;
  gMinuit->mnexcm("SET STR",arglist,1,ierflg);
  arglist[1] = 0.001; //0.001;
//  arglist[0] = 5000; //20000;
  arglist[0] = 20000; //5000; //20000;
  for(Int_t i=0;i<5;i++) {
    calcMinDist();
    if(filterFlag) {
      if(metaDetector == 1) selectTracks(i==0 ? 2. : 1.);
      else                  calcXOffset(i==0 ? 2. : 1.);
    }
    setWeights();
    if(i==0) for(Int_t tr = 0; tr < nTracks; tr++) {
      tracks[tr].xMinDistInit = tracks[tr].xMinDist;
      tracks[tr].yMinDistInit = tracks[tr].yMinDist;
    }
    gMinuit->mnexcm("MINI",arglist,2,ierflg);
    if(i<2) continue;  // At least do track selection 2 times
    if(ierflg == 0) break;
  }
  
  calcMinDist();
  if(metaDetector == 0 && fitTofModYPos) { 
    printf(" ------ Fit Yshifts --------------\n");
    gMinuit->mnfree(0);
    for(Int_t ip=0;ip<6;ip++) gMinuit->FixParameter(ip);
    gMinuit->mnexcm("MINI",arglist,2,ierflg);
    
    selectTracks(1.);
    setWeights();
    
    gMinuit->mnfree(0);
    for(Int_t ip=0;ip<8;ip++) gMinuit->FixParameter(6+ip);
    gMinuit->FixParameter(0);
    gMinuit->FixParameter(4);
    gMinuit->mnexcm("MINI",arglist,2,ierflg);
    calcMinDist();
  }
 
  if(metaDetector != 1) {
    calcXOffset(1.0); //1.5);
    calcMinDist();
  }
  
  for(Int_t im=0;im<nMetaModules;im++) {
    transMetaModLabNew[im] = transMetaModSecNew[im];
    transMetaModLabNew[im].transFrom(secLabTrans);
  }
}

void HAlignmentMeta::calcMinDist(void) {
  Double_t out[6];
  Double_t err;
  for(Int_t ip=0;ip<6;ip++) gMinuit->GetParameter(ip,out[ip],err);
  if(metaDetector==0 && fitTofModYPos) 
      for(Int_t ip=0;ip<8;ip++) gMinuit->GetParameter(6+ip,tofModYSh[ip],err);
  HGeomTransform trans;
  HMdcSizesCells::setTransform(out,trans);
  calcMinDist(trans);
}

void HAlignmentMeta::calcMinDist(Double_t *par) {
  HGeomTransform trans;
  HMdcSizesCells::setTransform(par,trans);
  if(metaDetector == 0 && fitTofModYPos) for(Int_t ip=0;ip<8;ip++) tofModYSh[ip] = par[6+ip];
  calcMinDist(trans);
}

void HAlignmentMeta::fillArray(void) {
  nTracks = 0;
  for(Int_t c=0;c<nCellsTot;c++) {
    cellStat[c]  = 0;
    cellXCorr[c] = 0.;
  }
  Int_t nentries = nt->GetEntries();
  HGeomVector trPoint1pr,trPoint2pr;
  Int_t strInd = 0;    
  for(Int_t i = 0; i < nentries; i++) {
    nt->GetEntry(i);
    if(sec != alignSec) continue;
    if(TMath::IsNaN(xMetaLocal+yMetaLocal+zMetaLocal)) {
      printf("NaN!!! Entry %i:   xMetaLocal=%f  yMetaLocal=%f  zMetaLocal=%f\n",
      i,xMetaLocal,yMetaLocal,zMetaLocal);
      continue;
    }

    TrackMdcMeta &t = tracks[nTracks];
    t.mdcPnt1Sec.setXYZ(x1, y1, z1);      // mdc lab
    t.mdcPnt2Sec.setXYZ(x2, y2, z2);      // mdc lab
    t.metaMod = Short_t(metaModule + 0.1);
    t.column  = Short_t(metaColumn+0.1);
    t.cell    = Short_t(metaCell+0.1);
    if     (metaDetector == 0) t.cellInd = t.metaMod*nCells + t.cell;
    else if(metaDetector == 1) t.cellInd = t.cell;
    else if(metaDetector == 2) t.cellInd = t.column*nCells + t.cell;
    t.xMeta    = xMetaLocal;
    t.yMeta    = yMetaLocal;
    t.zMeta    = zMetaLocal;
    t.sigmaX   = xRMS; // shower/rpc local error
    t.sigmaY   = yRMS; // shower/rpc local error
    t.sigmaZ   = zRMS; // shower/rpc local error 
    t.useIt    = kTRUE;
    t.wt       = 1.;
    HGeomVector dv1(trPoint1pr-t.mdcPnt1Sec);
    HGeomVector dv2(trPoint2pr-t.mdcPnt2Sec);
    if(dv1.length()+dv2.length()<0.01) t.startTrInd = strInd;
    else {
      t.startTrInd = nTracks;
      strInd       = nTracks;
      trPoint1pr   = t.mdcPnt1Sec;
      trPoint2pr   = t.mdcPnt2Sec;
    }
    if(nTracks==0 || yMetaLocal<yMinMetaLocal) yMinMetaLocal = yMetaLocal;
    if(nTracks==0 || yMetaLocal>yMaxMetaLocal) yMaxMetaLocal = yMetaLocal;
    cellStat[t.cellInd]++;
    nTracks++;
    if(nTracks==1000000) return;
  }
  if(metaDetector > 0) { // RPC & Shower:
    Double_t binSize = (yMaxMetaLocal-yMinMetaLocal)/8.;
    for(Int_t tr = 0; tr < nTracks; tr++) {
      TrackMdcMeta &t = tracks[tr];
      t.binScWt = Short_t((t.yMeta-yMinMetaLocal)/binSize);
      if(t.binScWt<0)      t.binScWt = 0;
      else if(t.binScWt>7) t.binScWt = 7;
    }
  } else {  // TOF:
    for(Int_t tr = 0; tr < nTracks; tr++) {
      TrackMdcMeta &t = tracks[tr];
      t.binScWt = t.metaMod;
    }
  }
  
}

Double_t HAlignmentMeta::getMinFunction(Double_t *par) {
  calcMinDist(par);
  Double_t dist = 0;
  for(Int_t tr = 0; tr < nTracks; tr++) if(tracks[tr].useIt) {
    dist += tracks[tr].minDist2*tracks[tr].wt;
//dist += TMath::Sqrt(tracks[tr].minDist2)*tracks[tr].wt;
  }
  return dist;
}

void HAlignmentMeta::calcMinDist(HGeomTransform& trans) {
  for(Int_t im=0;im<nMetaModules;im++) {
    transMetaModSecNew[im] = transMetaModSecOld[im];
    transMetaModSecNew[im].transTo(trans);
    if(metaDetector == 2 && xShitfRpc != 0.) { // Take into account Xmodule shift (for RPC only!):
      HGeomTransform shifterTrans;
      HGeomVector tr(xShitfRpc,0.,0.);
      shifterTrans.setTransVector(tr);
      shifterTrans.transFrom(transMetaModSecNew[im]);
      transMetaModSecNew[im] = shifterTrans;      
    }
    if(metaDetector == 0 && fitTofModYPos && tofModYSh[im] != 0.) {
      HGeomTransform trans;
      HGeomVector tr(0.,tofModYSh[im],0.);
      trans.setTransVector(tr) ;
      trans.transFrom(transMetaModSecNew[im]);
      transMetaModSecNew[im] = trans;
    }
  } 

  for(Int_t tr = 0; tr < nTracks; tr++) {
    TrackMdcMeta &t = tracks[tr];
    HGeomVector point1(transMetaModSecNew[t.metaMod].transTo(t.mdcPnt1Sec)); 
    HGeomVector point2(transMetaModSecNew[t.metaMod].transTo(t.mdcPnt2Sec));
    point1.setZ(point1.getZ() - t.zMeta);
    point2.setZ(point2.getZ() - t.zMeta);
    Double_t diffZ  = point2.getZ() - point1.getZ();
    Double_t diffX  = point2.getX() - point1.getX();
    Double_t diffY  = point2.getY() - point1.getY();
    t.xMinDist  = (point1.getX()*diffZ - point1.getZ()*diffX)/diffZ - t.xMeta;
    t.yMinDist  = (point1.getY()*diffZ - point1.getZ()*diffY)/diffZ - t.yMeta;
    t.xMinDist -= cellXCorr[t.cellInd];
    
    Double_t dYNr   = t.dYNorm();
    t.minDist2      = dYNr*dYNr;        // => chi2
    if(metaDetector == 1) {
      Double_t dXNr = t.dXNorm();
      t.minDist2   += dXNr*dXNr;
    }
  }
}

void HAlignmentMeta::setWeights(void) {
  Double_t stat[8];
  for(Int_t i=0;i<8;i++) stat[i] = 0;
  for(Int_t tr = 0; tr < nTracks; tr++) {
    TrackMdcMeta &t = tracks[tr];
    t.wt = t.useIt ? 1.:0.;
    if(t.useIt && t.startTrInd != tr) {
      Int_t nTr = 1;
      Int_t str = t.startTrInd;
      for(Int_t p=str;p<tr;p++) if(tracks[p].useIt && t.oneLay(tracks[p])) nTr++;
      if(nTr == 1) continue;
      Double_t w = 1./Double_t(nTr);
      t.wt = w;
      for(Int_t p=str;p<tr;p++) if(tracks[p].useIt && t.oneLay(tracks[p])) tracks[p].wt = w;
    }
    stat[t.binScWt] += t.wt;
  }
  Double_t statMax = 0.;
  for(Int_t i=0;i<8;i++) if(statMax < stat[i]) statMax = stat[i];
  for(Int_t tr = 0; tr < nTracks; tr++) {
    TrackMdcMeta &t = tracks[tr];
    if(t.wt>0. && stat[t.binScWt]>100.) t.wt *= statMax/stat[t.binScWt];
  }
}

void HAlignmentMeta::selectTracks(Double_t nSigmasCut) {
  meanX        = 0.;
  meanY        = 0.;
  meanZ        = 0.;
  sigmX        = 0.;
  sigmY        = 0.;
  sigmZ        = 0.;
  isFirstSIter = kTRUE;
  while(selectTracksIter(nSigmasCut));
}

Bool_t HAlignmentMeta::selectTracksIter(Double_t nSigmasCut) {
  Double_t dXM        = 0.;
  Double_t dX2M       = 0.;
  Double_t dYM        = 0.;
  Double_t dY2M       = 0.;
  Int_t    nTr        = 0;
  Bool_t   doNextIter = kFALSE;
  for(Int_t tr = 0; tr < nTracks; tr++) {
    TrackMdcMeta &t = tracks[tr];
    Double_t dXm = t.dXNorm();
    Double_t dYm = t.dYNorm();
    if(isFirstSIter) { // First iteration.
      t.useIt    = kTRUE;
      doNextIter = kTRUE;
    } else if(TMath::Abs(dXm-meanX) <= sigmX*nSigmasCut && 
              TMath::Abs(dYm-meanY) <= sigmY*nSigmasCut)  {
      if(!t.useIt) doNextIter = kTRUE;
      t.useIt = kTRUE;
    } else {
      if(t.useIt) doNextIter = kTRUE;
      t.useIt = kFALSE;
      continue;
    }
    dXM  += dXm;
    dX2M += dXm*dXm;
    dYM  += dYm;
    dY2M += dYm*dYm;
    nTr++;
  }
  meanX  = dXM/nTr;
  meanY  = dYM/nTr;
  sigmX  = TMath::Max(TMath::Sqrt(dX2M/nTr - meanX*meanX),trackSelecCutX);
  sigmY  = TMath::Max(TMath::Sqrt(dY2M/nTr - meanY*meanY),trackSelecCutY);
  if(doNextIter) printf(" * From %i tracks %i selected. <X>=%f sX=%f <Y>=%f sY=%f\n",
                        nTracks,nTr,meanX,sigmX,meanY,sigmY);
  isFirstSIter = kFALSE;
  return doNextIter;
}

void HAlignmentMeta::checkAlignment(void) {
  TString fileName("align");
  if(metaDetector == 0)      fileName += "Tof_S";
  else if(metaDetector == 1) fileName += "Shower_S";
  else if(metaDetector == 2) fileName += "Rpc_S";
  fileName += alignSec;
  fileName += ".root";
  
  TFile   *f    = new TFile(fileName.Data(),"recreate");
  TNtuple *chnt = new TNtuple("chnt","chnt",
      "alignSec:wt:xMeta:yMeta:zMeta:dXold:dYold:dX:dY:sigX:sigY:chi2:mod:col:cell");
  Float_t data[15];
  for(Int_t tr = 0; tr < nTracks; tr++) {
    TrackMdcMeta &t = tracks[tr];
    data[ 0] = sec;
    data[ 1] = t.wt;
    data[ 2] = t.xMeta + cellXCorr[t.cellInd];
    data[ 3] = t.yMeta;
    data[ 4] = t.zMeta;
    data[ 5] = t.xMinDistInit;
    data[ 6] = t.yMinDistInit;
    data[ 7] = t.xMinDist;
    data[ 8] = t.yMinDist;
    data[ 9] = t.sigmaX;
    data[10] = t.sigmaY;
    data[11] = t.minDist2;
    data[12] = t.metaMod;
    data[13] = t.column;
    data[14] = t.cell;
    chnt->Fill(data);
  }
  f->cd();
  chnt->Write();
  f->Close();
  delete f;
}
        

void HAlignmentMeta::calcXOffset(Double_t nSigmasCut) {
  Int_t nCellsC = 0;
  xShitfRpc     = 0.;
  for(Short_t c=0;c<nCellsTot;c++) {
    meanX        = 0.;
    meanY        = 0.;
    meanZ        = 0.;
    sigmX        = 0.;
    sigmY        = 0.;
    sigmZ        = 0.;
    isFirstSIter = kTRUE;
    if(cellStat[c] > 100) {
      while(calcXOffset(nSigmasCut,c));
      nCellsC++;
      if(metaDetector==2 && calcCellXOffset) {  // Calculate Xmodule shift (for RPC only):
        xShitfRpc += cellXCorr[c];
        nCellsC++;
      }
    }
  }
  if(metaDetector==2 && calcCellXOffset ) {     // Calculate Xmodule shift (for RPC only):
    if(nCellsC>0) xShitfRpc /= nCellsC;
    printf("xShitf =%f nCells=%i !!!!!!!!!!!\n",xShitfRpc,nCellsC);
    for(Short_t c=0;c<nCellsTot;c++) if(cellStat[c] > 100) cellXCorr[c] -= xShitfRpc;
  }
}

Bool_t HAlignmentMeta::calcXOffset(Double_t nSigmasCut,Short_t cellInd) {
  Double_t dXM        = 0.;
  Double_t dX2M       = 0.;
  Double_t dYM        = 0.;
  Double_t dY2M       = 0.;
  Double_t xShift     = 0.;
  Int_t    nTr        = 0;
  Bool_t   doNextIter = kFALSE;
  Int_t    nTot       = 0;
  for(Int_t tr = 0; tr < nTracks; tr++) {
    TrackMdcMeta &t = tracks[tr];
    if(cellInd != t.cellInd) continue;
    nTot++;
    Double_t dXm = t.dXNorm();
    Double_t dYm = t.dYNorm();
    if(isFirstSIter) { // First iteration.
      t.useIt    = kTRUE;
      doNextIter = kTRUE;
    } else if(TMath::Abs(dXm-meanX) <= sigmX*nSigmasCut && 
              TMath::Abs(dYm-meanY) <= sigmY*nSigmasCut)  {
      if(!t.useIt) doNextIter = kTRUE;
      t.useIt = kTRUE;
    } else {
      if(t.useIt) doNextIter = kTRUE;
      t.useIt = kFALSE;
      continue;
    }
    dXM    += dXm;
    dX2M   += dXm*dXm;
    dYM    += dYm;
    dY2M   += dYm*dYm;
    xShift += t.xMinDist;
    nTr++;
  }
  meanX  = dXM/nTr;
  meanY  = dYM/nTr;
  sigmX  = TMath::Max(TMath::Sqrt(dX2M/nTr - meanX*meanX),trackSelecCutX);
  sigmY  = TMath::Max(TMath::Sqrt(dY2M/nTr - meanY*meanY),trackSelecCutY);
  isFirstSIter = kFALSE;
  if(!doNextIter) {
    cellXCorr[cellInd] += xShift/nTr;                           // !!!!!!!!!! += vmesto =
    printf(" * %icolumn %2icell: From %i tracks %i selected. xOffset=%f\n",
                        cellInd/nCells,cellInd%nCells,nTot,nTr,cellXCorr[cellInd]);
  }
  return doNextIter;
}
 halignmentmeta.cc:1
 halignmentmeta.cc:2
 halignmentmeta.cc:3
 halignmentmeta.cc:4
 halignmentmeta.cc:5
 halignmentmeta.cc:6
 halignmentmeta.cc:7
 halignmentmeta.cc:8
 halignmentmeta.cc:9
 halignmentmeta.cc:10
 halignmentmeta.cc:11
 halignmentmeta.cc:12
 halignmentmeta.cc:13
 halignmentmeta.cc:14
 halignmentmeta.cc:15
 halignmentmeta.cc:16
 halignmentmeta.cc:17
 halignmentmeta.cc:18
 halignmentmeta.cc:19
 halignmentmeta.cc:20
 halignmentmeta.cc:21
 halignmentmeta.cc:22
 halignmentmeta.cc:23
 halignmentmeta.cc:24
 halignmentmeta.cc:25
 halignmentmeta.cc:26
 halignmentmeta.cc:27
 halignmentmeta.cc:28
 halignmentmeta.cc:29
 halignmentmeta.cc:30
 halignmentmeta.cc:31
 halignmentmeta.cc:32
 halignmentmeta.cc:33
 halignmentmeta.cc:34
 halignmentmeta.cc:35
 halignmentmeta.cc:36
 halignmentmeta.cc:37
 halignmentmeta.cc:38
 halignmentmeta.cc:39
 halignmentmeta.cc:40
 halignmentmeta.cc:41
 halignmentmeta.cc:42
 halignmentmeta.cc:43
 halignmentmeta.cc:44
 halignmentmeta.cc:45
 halignmentmeta.cc:46
 halignmentmeta.cc:47
 halignmentmeta.cc:48
 halignmentmeta.cc:49
 halignmentmeta.cc:50
 halignmentmeta.cc:51
 halignmentmeta.cc:52
 halignmentmeta.cc:53
 halignmentmeta.cc:54
 halignmentmeta.cc:55
 halignmentmeta.cc:56
 halignmentmeta.cc:57
 halignmentmeta.cc:58
 halignmentmeta.cc:59
 halignmentmeta.cc:60
 halignmentmeta.cc:61
 halignmentmeta.cc:62
 halignmentmeta.cc:63
 halignmentmeta.cc:64
 halignmentmeta.cc:65
 halignmentmeta.cc:66
 halignmentmeta.cc:67
 halignmentmeta.cc:68
 halignmentmeta.cc:69
 halignmentmeta.cc:70
 halignmentmeta.cc:71
 halignmentmeta.cc:72
 halignmentmeta.cc:73
 halignmentmeta.cc:74
 halignmentmeta.cc:75
 halignmentmeta.cc:76
 halignmentmeta.cc:77
 halignmentmeta.cc:78
 halignmentmeta.cc:79
 halignmentmeta.cc:80
 halignmentmeta.cc:81
 halignmentmeta.cc:82
 halignmentmeta.cc:83
 halignmentmeta.cc:84
 halignmentmeta.cc:85
 halignmentmeta.cc:86
 halignmentmeta.cc:87
 halignmentmeta.cc:88
 halignmentmeta.cc:89
 halignmentmeta.cc:90
 halignmentmeta.cc:91
 halignmentmeta.cc:92
 halignmentmeta.cc:93
 halignmentmeta.cc:94
 halignmentmeta.cc:95
 halignmentmeta.cc:96
 halignmentmeta.cc:97
 halignmentmeta.cc:98
 halignmentmeta.cc:99
 halignmentmeta.cc:100
 halignmentmeta.cc:101
 halignmentmeta.cc:102
 halignmentmeta.cc:103
 halignmentmeta.cc:104
 halignmentmeta.cc:105
 halignmentmeta.cc:106
 halignmentmeta.cc:107
 halignmentmeta.cc:108
 halignmentmeta.cc:109
 halignmentmeta.cc:110
 halignmentmeta.cc:111
 halignmentmeta.cc:112
 halignmentmeta.cc:113
 halignmentmeta.cc:114
 halignmentmeta.cc:115
 halignmentmeta.cc:116
 halignmentmeta.cc:117
 halignmentmeta.cc:118
 halignmentmeta.cc:119
 halignmentmeta.cc:120
 halignmentmeta.cc:121
 halignmentmeta.cc:122
 halignmentmeta.cc:123
 halignmentmeta.cc:124
 halignmentmeta.cc:125
 halignmentmeta.cc:126
 halignmentmeta.cc:127
 halignmentmeta.cc:128
 halignmentmeta.cc:129
 halignmentmeta.cc:130
 halignmentmeta.cc:131
 halignmentmeta.cc:132
 halignmentmeta.cc:133
 halignmentmeta.cc:134
 halignmentmeta.cc:135
 halignmentmeta.cc:136
 halignmentmeta.cc:137
 halignmentmeta.cc:138
 halignmentmeta.cc:139
 halignmentmeta.cc:140
 halignmentmeta.cc:141
 halignmentmeta.cc:142
 halignmentmeta.cc:143
 halignmentmeta.cc:144
 halignmentmeta.cc:145
 halignmentmeta.cc:146
 halignmentmeta.cc:147
 halignmentmeta.cc:148
 halignmentmeta.cc:149
 halignmentmeta.cc:150
 halignmentmeta.cc:151
 halignmentmeta.cc:152
 halignmentmeta.cc:153
 halignmentmeta.cc:154
 halignmentmeta.cc:155
 halignmentmeta.cc:156
 halignmentmeta.cc:157
 halignmentmeta.cc:158
 halignmentmeta.cc:159
 halignmentmeta.cc:160
 halignmentmeta.cc:161
 halignmentmeta.cc:162
 halignmentmeta.cc:163
 halignmentmeta.cc:164
 halignmentmeta.cc:165
 halignmentmeta.cc:166
 halignmentmeta.cc:167
 halignmentmeta.cc:168
 halignmentmeta.cc:169
 halignmentmeta.cc:170
 halignmentmeta.cc:171
 halignmentmeta.cc:172
 halignmentmeta.cc:173
 halignmentmeta.cc:174
 halignmentmeta.cc:175
 halignmentmeta.cc:176
 halignmentmeta.cc:177
 halignmentmeta.cc:178
 halignmentmeta.cc:179
 halignmentmeta.cc:180
 halignmentmeta.cc:181
 halignmentmeta.cc:182
 halignmentmeta.cc:183
 halignmentmeta.cc:184
 halignmentmeta.cc:185
 halignmentmeta.cc:186
 halignmentmeta.cc:187
 halignmentmeta.cc:188
 halignmentmeta.cc:189
 halignmentmeta.cc:190
 halignmentmeta.cc:191
 halignmentmeta.cc:192
 halignmentmeta.cc:193
 halignmentmeta.cc:194
 halignmentmeta.cc:195
 halignmentmeta.cc:196
 halignmentmeta.cc:197
 halignmentmeta.cc:198
 halignmentmeta.cc:199
 halignmentmeta.cc:200
 halignmentmeta.cc:201
 halignmentmeta.cc:202
 halignmentmeta.cc:203
 halignmentmeta.cc:204
 halignmentmeta.cc:205
 halignmentmeta.cc:206
 halignmentmeta.cc:207
 halignmentmeta.cc:208
 halignmentmeta.cc:209
 halignmentmeta.cc:210
 halignmentmeta.cc:211
 halignmentmeta.cc:212
 halignmentmeta.cc:213
 halignmentmeta.cc:214
 halignmentmeta.cc:215
 halignmentmeta.cc:216
 halignmentmeta.cc:217
 halignmentmeta.cc:218
 halignmentmeta.cc:219
 halignmentmeta.cc:220
 halignmentmeta.cc:221
 halignmentmeta.cc:222
 halignmentmeta.cc:223
 halignmentmeta.cc:224
 halignmentmeta.cc:225
 halignmentmeta.cc:226
 halignmentmeta.cc:227
 halignmentmeta.cc:228
 halignmentmeta.cc:229
 halignmentmeta.cc:230
 halignmentmeta.cc:231
 halignmentmeta.cc:232
 halignmentmeta.cc:233
 halignmentmeta.cc:234
 halignmentmeta.cc:235
 halignmentmeta.cc:236
 halignmentmeta.cc:237
 halignmentmeta.cc:238
 halignmentmeta.cc:239
 halignmentmeta.cc:240
 halignmentmeta.cc:241
 halignmentmeta.cc:242
 halignmentmeta.cc:243
 halignmentmeta.cc:244
 halignmentmeta.cc:245
 halignmentmeta.cc:246
 halignmentmeta.cc:247
 halignmentmeta.cc:248
 halignmentmeta.cc:249
 halignmentmeta.cc:250
 halignmentmeta.cc:251
 halignmentmeta.cc:252
 halignmentmeta.cc:253
 halignmentmeta.cc:254
 halignmentmeta.cc:255
 halignmentmeta.cc:256
 halignmentmeta.cc:257
 halignmentmeta.cc:258
 halignmentmeta.cc:259
 halignmentmeta.cc:260
 halignmentmeta.cc:261
 halignmentmeta.cc:262
 halignmentmeta.cc:263
 halignmentmeta.cc:264
 halignmentmeta.cc:265
 halignmentmeta.cc:266
 halignmentmeta.cc:267
 halignmentmeta.cc:268
 halignmentmeta.cc:269
 halignmentmeta.cc:270
 halignmentmeta.cc:271
 halignmentmeta.cc:272
 halignmentmeta.cc:273
 halignmentmeta.cc:274
 halignmentmeta.cc:275
 halignmentmeta.cc:276
 halignmentmeta.cc:277
 halignmentmeta.cc:278
 halignmentmeta.cc:279
 halignmentmeta.cc:280
 halignmentmeta.cc:281
 halignmentmeta.cc:282
 halignmentmeta.cc:283
 halignmentmeta.cc:284
 halignmentmeta.cc:285
 halignmentmeta.cc:286
 halignmentmeta.cc:287
 halignmentmeta.cc:288
 halignmentmeta.cc:289
 halignmentmeta.cc:290
 halignmentmeta.cc:291
 halignmentmeta.cc:292
 halignmentmeta.cc:293
 halignmentmeta.cc:294
 halignmentmeta.cc:295
 halignmentmeta.cc:296
 halignmentmeta.cc:297
 halignmentmeta.cc:298
 halignmentmeta.cc:299
 halignmentmeta.cc:300
 halignmentmeta.cc:301
 halignmentmeta.cc:302
 halignmentmeta.cc:303
 halignmentmeta.cc:304
 halignmentmeta.cc:305
 halignmentmeta.cc:306
 halignmentmeta.cc:307
 halignmentmeta.cc:308
 halignmentmeta.cc:309
 halignmentmeta.cc:310
 halignmentmeta.cc:311
 halignmentmeta.cc:312
 halignmentmeta.cc:313
 halignmentmeta.cc:314
 halignmentmeta.cc:315
 halignmentmeta.cc:316
 halignmentmeta.cc:317
 halignmentmeta.cc:318
 halignmentmeta.cc:319
 halignmentmeta.cc:320
 halignmentmeta.cc:321
 halignmentmeta.cc:322
 halignmentmeta.cc:323
 halignmentmeta.cc:324
 halignmentmeta.cc:325
 halignmentmeta.cc:326
 halignmentmeta.cc:327
 halignmentmeta.cc:328
 halignmentmeta.cc:329
 halignmentmeta.cc:330
 halignmentmeta.cc:331
 halignmentmeta.cc:332
 halignmentmeta.cc:333
 halignmentmeta.cc:334
 halignmentmeta.cc:335
 halignmentmeta.cc:336
 halignmentmeta.cc:337
 halignmentmeta.cc:338
 halignmentmeta.cc:339
 halignmentmeta.cc:340
 halignmentmeta.cc:341
 halignmentmeta.cc:342
 halignmentmeta.cc:343
 halignmentmeta.cc:344
 halignmentmeta.cc:345
 halignmentmeta.cc:346
 halignmentmeta.cc:347
 halignmentmeta.cc:348
 halignmentmeta.cc:349
 halignmentmeta.cc:350
 halignmentmeta.cc:351
 halignmentmeta.cc:352
 halignmentmeta.cc:353
 halignmentmeta.cc:354
 halignmentmeta.cc:355
 halignmentmeta.cc:356
 halignmentmeta.cc:357
 halignmentmeta.cc:358
 halignmentmeta.cc:359
 halignmentmeta.cc:360
 halignmentmeta.cc:361
 halignmentmeta.cc:362
 halignmentmeta.cc:363
 halignmentmeta.cc:364
 halignmentmeta.cc:365
 halignmentmeta.cc:366
 halignmentmeta.cc:367
 halignmentmeta.cc:368
 halignmentmeta.cc:369
 halignmentmeta.cc:370
 halignmentmeta.cc:371
 halignmentmeta.cc:372
 halignmentmeta.cc:373
 halignmentmeta.cc:374
 halignmentmeta.cc:375
 halignmentmeta.cc:376
 halignmentmeta.cc:377
 halignmentmeta.cc:378
 halignmentmeta.cc:379
 halignmentmeta.cc:380
 halignmentmeta.cc:381
 halignmentmeta.cc:382
 halignmentmeta.cc:383
 halignmentmeta.cc:384
 halignmentmeta.cc:385
 halignmentmeta.cc:386
 halignmentmeta.cc:387
 halignmentmeta.cc:388
 halignmentmeta.cc:389
 halignmentmeta.cc:390
 halignmentmeta.cc:391
 halignmentmeta.cc:392
 halignmentmeta.cc:393
 halignmentmeta.cc:394
 halignmentmeta.cc:395
 halignmentmeta.cc:396
 halignmentmeta.cc:397
 halignmentmeta.cc:398
 halignmentmeta.cc:399
 halignmentmeta.cc:400
 halignmentmeta.cc:401
 halignmentmeta.cc:402
 halignmentmeta.cc:403
 halignmentmeta.cc:404
 halignmentmeta.cc:405
 halignmentmeta.cc:406
 halignmentmeta.cc:407
 halignmentmeta.cc:408
 halignmentmeta.cc:409
 halignmentmeta.cc:410
 halignmentmeta.cc:411
 halignmentmeta.cc:412
 halignmentmeta.cc:413
 halignmentmeta.cc:414
 halignmentmeta.cc:415
 halignmentmeta.cc:416
 halignmentmeta.cc:417
 halignmentmeta.cc:418
 halignmentmeta.cc:419
 halignmentmeta.cc:420
 halignmentmeta.cc:421
 halignmentmeta.cc:422
 halignmentmeta.cc:423
 halignmentmeta.cc:424
 halignmentmeta.cc:425
 halignmentmeta.cc:426
 halignmentmeta.cc:427
 halignmentmeta.cc:428
 halignmentmeta.cc:429
 halignmentmeta.cc:430
 halignmentmeta.cc:431
 halignmentmeta.cc:432
 halignmentmeta.cc:433
 halignmentmeta.cc:434
 halignmentmeta.cc:435
 halignmentmeta.cc:436
 halignmentmeta.cc:437
 halignmentmeta.cc:438
 halignmentmeta.cc:439
 halignmentmeta.cc:440
 halignmentmeta.cc:441
 halignmentmeta.cc:442
 halignmentmeta.cc:443
 halignmentmeta.cc:444
 halignmentmeta.cc:445
 halignmentmeta.cc:446
 halignmentmeta.cc:447
 halignmentmeta.cc:448
 halignmentmeta.cc:449
 halignmentmeta.cc:450
 halignmentmeta.cc:451
 halignmentmeta.cc:452
 halignmentmeta.cc:453
 halignmentmeta.cc:454
 halignmentmeta.cc:455
 halignmentmeta.cc:456
 halignmentmeta.cc:457
 halignmentmeta.cc:458
 halignmentmeta.cc:459
 halignmentmeta.cc:460
 halignmentmeta.cc:461
 halignmentmeta.cc:462
 halignmentmeta.cc:463
 halignmentmeta.cc:464
 halignmentmeta.cc:465
 halignmentmeta.cc:466
 halignmentmeta.cc:467
 halignmentmeta.cc:468
 halignmentmeta.cc:469
 halignmentmeta.cc:470
 halignmentmeta.cc:471
 halignmentmeta.cc:472
 halignmentmeta.cc:473
 halignmentmeta.cc:474
 halignmentmeta.cc:475
 halignmentmeta.cc:476
 halignmentmeta.cc:477
 halignmentmeta.cc:478
 halignmentmeta.cc:479
 halignmentmeta.cc:480
 halignmentmeta.cc:481
 halignmentmeta.cc:482
 halignmentmeta.cc:483
 halignmentmeta.cc:484
 halignmentmeta.cc:485
 halignmentmeta.cc:486
 halignmentmeta.cc:487
 halignmentmeta.cc:488
 halignmentmeta.cc:489
 halignmentmeta.cc:490
 halignmentmeta.cc:491
 halignmentmeta.cc:492
 halignmentmeta.cc:493
 halignmentmeta.cc:494
 halignmentmeta.cc:495
 halignmentmeta.cc:496
 halignmentmeta.cc:497
 halignmentmeta.cc:498
 halignmentmeta.cc:499
 halignmentmeta.cc:500
 halignmentmeta.cc:501
 halignmentmeta.cc:502
 halignmentmeta.cc:503
 halignmentmeta.cc:504
 halignmentmeta.cc:505
 halignmentmeta.cc:506
 halignmentmeta.cc:507
 halignmentmeta.cc:508
 halignmentmeta.cc:509
 halignmentmeta.cc:510
 halignmentmeta.cc:511
 halignmentmeta.cc:512
 halignmentmeta.cc:513
 halignmentmeta.cc:514
 halignmentmeta.cc:515
 halignmentmeta.cc:516
 halignmentmeta.cc:517
 halignmentmeta.cc:518
 halignmentmeta.cc:519
 halignmentmeta.cc:520
 halignmentmeta.cc:521
 halignmentmeta.cc:522
 halignmentmeta.cc:523
 halignmentmeta.cc:524