#ifndef MpsAnalysisLaserPositionScan_HH
#define MpsAnalysisLaserPositionScan_HH

#include <cassert>

#include "TFile.h"
#include "TF1.h"
#include "TH1F.h"
#include "TH2F.h"
#include "TProfile.h"

#include "RcdUserRO.hh"
#include "SubAccessor.hh"

#include "MpsSensor1HitLists.hh"

#include "MpsAnalysisBase.hh"
#include "HstCfgCount1D.hh"


class MpsAnalysisLaserPositionScan : public MpsAnalysisBase {

public:
  MpsAnalysisLaserPositionScan() : 
    MpsAnalysisBase("MpsAnalysisLaserPositionScan"),
    _hCfgX("labelX","titleX"), _hCfgY("labelY","titleY") {
  }


  virtual ~MpsAnalysisLaserPositionScan() {
    endRoot();
  }

  virtual bool mpsAnalysisValidRun(IlcRunType::Type t) const {
    return (t==IlcRunType::mpsLaserPositionScan);
  }

  bool runEnd(const RcdRecord &r) {
    for(unsigned i(0);i<9;i++) {
      if(_norm[i]>0.0) {
	std::cout << "Pixel " << i << " has mean x,y = " 
		  << _mean[i][0]/_norm[i] << ", "
		  << _mean[i][1]/_norm[i] << std::endl;
      }
    } 

    _hCfgX.runEnd();
    _hCfgY.runEnd();

    return true;
  }

  bool runStart(const RcdRecord &r) {
 
    SubAccessor accessor(r);

    std::vector<const MpsLaserRunData*>
      v(accessor.access<MpsLaserRunData>());
    assert(v.size()==1);
    if(doPrint(r.recordType(),1)) v[0]->print(std::cout) << std::endl;

    for(unsigned i(0);i<9;i++) {
      _mean[i][0]=0.0;
      _mean[i][1]=0.0;
      _norm[i]=0.0;
    }

    if(_runStart.runNumber()==470404) {
      _centreX=60;
      _centreY=29;
      _vHScan.push_back(new TH2F("hScan0","Pixel 59, 28 response to scan",12,-455.0,-335.0,12,-765.0,-645.0));
      _vHScan.push_back(new TH2F("hScan1","Pixel 60, 28 response to scan",12,-455.0,-335.0,12,-765.0,-645.0));
      _vHScan.push_back(new TH2F("hScan2","Pixel 61, 28 response to scan",12,-455.0,-335.0,12,-765.0,-645.0));
      _vHScan.push_back(new TH2F("hScan3","Pixel 59, 29 response to scan",12,-455.0,-335.0,12,-765.0,-645.0));
      _vHScan.push_back(new TH2F("hScan4","Pixel 60, 29 response to scan",12,-455.0,-335.0,12,-765.0,-645.0));
      _vHScan.push_back(new TH2F("hScan5","Pixel 61, 29 response to scan",12,-455.0,-335.0,12,-765.0,-645.0));
      _vHScan.push_back(new TH2F("hScan6","Pixel 59, 30 response to scan",12,-455.0,-335.0,12,-765.0,-645.0));
      _vHScan.push_back(new TH2F("hScan7","Pixel 60, 30 response to scan",12,-455.0,-335.0,12,-765.0,-645.0));
      _vHScan.push_back(new TH2F("hScan8","Pixel 61, 30 response to scan",12,-455.0,-335.0,12,-765.0,-645.0));
    }

    if(_runStart.runNumber()==470405) {
      _centreX=30;
      _centreY=100;
      _vHScan.push_back(new TH2F("hScan0","Pixel 29, 99 response to scan",12,-2200.0,-2080.0,12,2820.0,2940.0));
      _vHScan.push_back(new TH2F("hScan1","Pixel 30, 99 response to scan",12,-2200.0,-2080.0,12,2820.0,2940.0));
      _vHScan.push_back(new TH2F("hScan2","Pixel 31, 99 response to scan",12,-2200.0,-2080.0,12,2820.0,2940.0));
      _vHScan.push_back(new TH2F("hScan3","Pixel 29,100 response to scan",12,-2200.0,-2080.0,12,2820.0,2940.0));
      _vHScan.push_back(new TH2F("hScan4","Pixel 30,100 response to scan",12,-2200.0,-2080.0,12,2820.0,2940.0));
      _vHScan.push_back(new TH2F("hScan5","Pixel 31,100 response to scan",12,-2200.0,-2080.0,12,2820.0,2940.0));
      _vHScan.push_back(new TH2F("hScan6","Pixel 29,101 response to scan",12,-2200.0,-2080.0,12,2820.0,2940.0));
      _vHScan.push_back(new TH2F("hScan7","Pixel 30,101 response to scan",12,-2200.0,-2080.0,12,2820.0,2940.0));
      _vHScan.push_back(new TH2F("hScan8","Pixel 31,101 response to scan",12,-2200.0,-2080.0,12,2820.0,2940.0));
    }

    if(_runStart.runNumber()==470406) {
      _centreX=61;
      _centreY=150;
      _vHScan.push_back(new TH2F("hScan0","Pixel 60,149 response to scan",12,-450.0,-330.0,12,5320.0,5440.0));
      _vHScan.push_back(new TH2F("hScan1","Pixel 61,149 response to scan",12,-450.0,-330.0,12,5320.0,5440.0));
      _vHScan.push_back(new TH2F("hScan2","Pixel 62,149 response to scan",12,-450.0,-330.0,12,5320.0,5440.0));
      _vHScan.push_back(new TH2F("hScan3","Pixel 60,150 response to scan",12,-450.0,-330.0,12,5320.0,5440.0));
      _vHScan.push_back(new TH2F("hScan4","Pixel 61,150 response to scan",12,-450.0,-330.0,12,5320.0,5440.0));
      _vHScan.push_back(new TH2F("hScan5","Pixel 62,150 response to scan",12,-450.0,-330.0,12,5320.0,5440.0));
      _vHScan.push_back(new TH2F("hScan6","Pixel 60,151 response to scan",12,-450.0,-330.0,12,5320.0,5440.0));
      _vHScan.push_back(new TH2F("hScan7","Pixel 61,151 response to scan",12,-450.0,-330.0,12,5320.0,5440.0));
      _vHScan.push_back(new TH2F("hScan8","Pixel 62,151 response to scan",12,-450.0,-330.0,12,5320.0,5440.0));
    }

    if(_runStart.runNumber()==470407) {
      _centreX=60;
      _centreY=29;
      _vHScan.push_back(new TH2F("hScan0","Pixel 59, 28 response to scan",12,-450.0,-330.0,12,-780.0,-660.0));
      _vHScan.push_back(new TH2F("hScan1","Pixel 60, 28 response to scan",12,-450.0,-330.0,12,-780.0,-660.0));
      _vHScan.push_back(new TH2F("hScan2","Pixel 61, 28 response to scan",12,-450.0,-330.0,12,-780.0,-660.0));
      _vHScan.push_back(new TH2F("hScan3","Pixel 59, 29 response to scan",12,-450.0,-330.0,12,-780.0,-660.0));
      _vHScan.push_back(new TH2F("hScan4","Pixel 60, 29 response to scan",12,-450.0,-330.0,12,-780.0,-660.0));
      _vHScan.push_back(new TH2F("hScan5","Pixel 61, 29 response to scan",12,-450.0,-330.0,12,-780.0,-660.0));
      _vHScan.push_back(new TH2F("hScan6","Pixel 59, 30 response to scan",12,-450.0,-330.0,12,-780.0,-660.0));
      _vHScan.push_back(new TH2F("hScan7","Pixel 60, 30 response to scan",12,-450.0,-330.0,12,-780.0,-660.0));
      _vHScan.push_back(new TH2F("hScan8","Pixel 61, 30 response to scan",12,-450.0,-330.0,12,-780.0,-660.0));
    }

    if(_runStart.runNumber()==470408) {
      _centreX=60;
      _centreY=29;
      _vHScan.push_back(new TH2F("hScan0","Pixel 59, 28 response to scan",30,-447.5,-297.5,30,-767.5,-617.5));
      _vHScan.push_back(new TH2F("hScan1","Pixel 60, 28 response to scan",30,-447.5,-297.5,30,-767.5,-617.5));
      _vHScan.push_back(new TH2F("hScan2","Pixel 61, 28 response to scan",30,-447.5,-297.5,30,-767.5,-617.5));
      _vHScan.push_back(new TH2F("hScan3","Pixel 59, 29 response to scan",30,-447.5,-297.5,30,-767.5,-617.5));
      _vHScan.push_back(new TH2F("hScan4","Pixel 60, 29 response to scan",30,-447.5,-297.5,30,-767.5,-617.5));
      _vHScan.push_back(new TH2F("hScan5","Pixel 61, 29 response to scan",30,-447.5,-297.5,30,-767.5,-617.5));
      _vHScan.push_back(new TH2F("hScan6","Pixel 59, 30 response to scan",30,-447.5,-297.5,30,-767.5,-617.5));
      _vHScan.push_back(new TH2F("hScan7","Pixel 60, 30 response to scan",30,-447.5,-297.5,30,-767.5,-617.5));
      _vHScan.push_back(new TH2F("hScan8","Pixel 61, 30 response to scan",30,-447.5,-297.5,30,-767.5,-617.5));
    }

    if(_runStart.runNumber()>=470571 && _runStart.runNumber()<=470577) {
      _centreX=60;
      _centreY=29;
      int xLo=-295;
      int yLo= 235;
      int range=150;

      _vHScan.push_back(new TH2F("hScan0","Pixel 59, 28 response to scan",30,xLo,xLo+range,30,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan1","Pixel 60, 28 response to scan",30,xLo,xLo+range,30,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan2","Pixel 61, 28 response to scan",30,xLo,xLo+range,30,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan3","Pixel 59, 29 response to scan",30,xLo,xLo+range,30,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan4","Pixel 60, 29 response to scan",30,xLo,xLo+range,30,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan5","Pixel 61, 29 response to scan",30,xLo,xLo+range,30,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan6","Pixel 59, 30 response to scan",30,xLo,xLo+range,30,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan7","Pixel 60, 30 response to scan",30,xLo,xLo+range,30,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan8","Pixel 61, 30 response to scan",30,xLo,xLo+range,30,yLo,yLo+range));
    }

    if(_runStart.runNumber()==470630) {
      _centreX=60;
      _centreY=29;
      int xLo=-505;
      int yLo= 195;
      int range=150;

      _vHScan.push_back(new TH2F("hScan0","Pixel 59, 28 response to scan",30,xLo,xLo+range,30,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan1","Pixel 60, 28 response to scan",30,xLo,xLo+range,30,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan2","Pixel 61, 28 response to scan",30,xLo,xLo+range,30,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan3","Pixel 59, 29 response to scan",30,xLo,xLo+range,30,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan4","Pixel 60, 29 response to scan",30,xLo,xLo+range,30,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan5","Pixel 61, 29 response to scan",30,xLo,xLo+range,30,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan6","Pixel 59, 30 response to scan",30,xLo,xLo+range,30,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan7","Pixel 60, 30 response to scan",30,xLo,xLo+range,30,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan8","Pixel 61, 30 response to scan",30,xLo,xLo+range,30,yLo,yLo+range));
    }

    if(_runStart.runNumber()==470631) {
      _centreX=60;
      _centreY=29;
      int xLo=-485;
      int yLo= 255;
      int range=150;

      _vHScan.push_back(new TH2F("hScan0","Pixel 59, 28 response to scan",30,xLo,xLo+range,30,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan1","Pixel 60, 28 response to scan",30,xLo,xLo+range,30,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan2","Pixel 61, 28 response to scan",30,xLo,xLo+range,30,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan3","Pixel 59, 29 response to scan",30,xLo,xLo+range,30,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan4","Pixel 60, 29 response to scan",30,xLo,xLo+range,30,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan5","Pixel 61, 29 response to scan",30,xLo,xLo+range,30,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan6","Pixel 59, 30 response to scan",30,xLo,xLo+range,30,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan7","Pixel 60, 30 response to scan",30,xLo,xLo+range,30,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan8","Pixel 61, 30 response to scan",30,xLo,xLo+range,30,yLo,yLo+range));
    }

    if(_runStart.runNumber()==470633) {
      _centreX=60;
      _centreY=129;
      int xLo=-519;
      int yLo=5276;
      int range=150;
      _vHScan.push_back(new TH2F("hScan0","Pixel 59, 128 response to scan",30,xLo,xLo+range,30,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan1","Pixel 60, 128 response to scan",30,xLo,xLo+range,30,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan2","Pixel 61, 128 response to scan",30,xLo,xLo+range,30,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan3","Pixel 59, 129 response to scan",30,xLo,xLo+range,30,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan4","Pixel 60, 129 response to scan",30,xLo,xLo+range,30,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan5","Pixel 61, 129 response to scan",30,xLo,xLo+range,30,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan6","Pixel 59, 130 response to scan",30,xLo,xLo+range,30,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan7","Pixel 60, 130 response to scan",30,xLo,xLo+range,30,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan8","Pixel 61, 130 response to scan",30,xLo,xLo+range,30,yLo,yLo+range));
    }

    if(_runStart.runNumber()==470653) {
      _centreX=63;
      _centreY=126;
      int xLo=-1909;
      int yLo=3400;
      int range=75;
      _vHScan.push_back(new TH2F("hScan0","Pixel 62, 125 response to scan",75,xLo,xLo+range,75,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan1","Pixel 63, 125 response to scan",75,xLo,xLo+range,75,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan2","Pixel 64, 125 response to scan",75,xLo,xLo+range,75,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan3","Pixel 62, 126 response to scan",75,xLo,xLo+range,75,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan4","Pixel 63, 126 response to scan",75,xLo,xLo+range,75,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan5","Pixel 64, 126 response to scan",75,xLo,xLo+range,75,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan6","Pixel 62, 127 response to scan",75,xLo,xLo+range,75,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan7","Pixel 63, 127 response to scan",75,xLo,xLo+range,75,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan8","Pixel 64, 127 response to scan",75,xLo,xLo+range,75,yLo,yLo+range));
    }

    if(_runStart.runNumber()>=470657) {
      _centreX=63;
      _centreY=126;
      int xLo=-1947;
      int yLo=3349;
      int range=150;
      _xMd=3424;
      _yMd=-1872;
      _vHScan.push_back(new TH2F("hScan0","Pixel 62, 125 response to scan",150,xLo,xLo+range,150,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan1","Pixel 63, 125 response to scan",150,xLo,xLo+range,150,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan2","Pixel 64, 125 response to scan",150,xLo,xLo+range,150,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan3","Pixel 62, 126 response to scan",150,xLo,xLo+range,150,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan4","Pixel 63, 126 response to scan",150,xLo,xLo+range,150,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan5","Pixel 64, 126 response to scan",150,xLo,xLo+range,150,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan6","Pixel 62, 127 response to scan",150,xLo,xLo+range,150,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan7","Pixel 63, 127 response to scan",150,xLo,xLo+range,150,yLo,yLo+range));
      _vHScan.push_back(new TH2F("hScan8","Pixel 64, 127 response to scan",150,xLo,xLo+range,150,yLo,yLo+range));

      _vHScan1.push_back(new TH1F("hScan1X","Pixel 63, 126 response to x scan",150,xLo,xLo+range));
      _vHScan1.push_back(new TH1F("hScan1Y","Pixel 63, 126 response to y scan",150,yLo,yLo+range));
    }

    _hCfgX.runStart(999999,"Stage X");
    _hCfgY.runStart(999999,"Stage Y");

    return true;
  }  

  bool configurationStart(const RcdRecord &r) {
    SubAccessor accessor(r);

    std::vector<const MpsLaserConfigurationData*>
      v(accessor.access<MpsLaserConfigurationData>());
    assert(v.size()==2);
    if(doPrint(r.recordType(),1)) v[v.size()-1]->print(std::cout) << std::endl;

    _stageX=v[v.size()-1]->stageX();
    _stageY=v[v.size()-1]->stageY();

    assert(_stageX==v[0]->stageX());
    assert(_stageY==v[0]->stageY());

    _hCfgX.configurationStart(_stageX);
    _hCfgY.configurationStart(_stageY);

    return true;
  }

  bool bunchTrain(const RcdRecord &r) {
    SubAccessor accessor(r);
    
    std::vector<const MpsLocationData<MpsSensor1BunchTrainData>* >
      v(accessor.access< MpsLocationData<MpsSensor1BunchTrainData> >());
    assert(v.size()==1);
    if(doPrint(r.recordType(),1)) v[0]->print(std::cout) << std::endl;

    bool hit[9];
    for(unsigned i(0);i<9;i++) hit[i]=false;

    for(unsigned region(0);region<4;region++) {
      const MpsSensor1BunchTrainDatum *p(v[0]->data()->regionData(region));
      for(unsigned j(0);j<v[0]->data()->numberOfRegionHits(region);j++) {

	unsigned y(p[j].row());
	for(unsigned c(0);c<6;c++) {
	  if(p[j].channel(c)) {
	    unsigned x(42*region+6*p[j].group()+c);
	    if(x==_centreX-1 && y==_centreY-1) hit[0]=true;
	    if(x==_centreX   && y==_centreY-1) hit[1]=true;
	    if(x==_centreX+1 && y==_centreY-1) hit[2]=true;
	    if(x==_centreX-1 && y==_centreY  ) hit[3]=true;
	    if(x==_centreX   && y==_centreY  ) hit[4]=true;
	    if(x==_centreX+1 && y==_centreY  ) hit[5]=true;
	    if(x==_centreX-1 && y==_centreY+1) hit[6]=true;
	    if(x==_centreX   && y==_centreY+1) hit[7]=true;
	    if(x==_centreX+1 && y==_centreY+1) hit[8]=true;
	  }
	}
      }
    }

    for(unsigned i(0);i<9;i++) {
      if(hit[i]) {
	_vHScan[i]->Fill(_stageY,_stageX);
	_mean[i][0]+=_stageY;
	_mean[i][1]+=_stageX;
	_norm[i]++;

	if(i==4) {
	  if(_stageY==_yMd); _hCfgX.Fill();
	  if(_stageX==_xMd); _hCfgY.Fill();

	  if(_vHScan1.size()==2) {
	    if(_stageX==_xMd) _vHScan1[0]->Fill(_stageY);
	    if(_stageY==_yMd) _vHScan1[1]->Fill(_stageX);
	  }
	}
      }
    }




	/*
	    if(x==_centreX-1 && y==_centreY-1) {
	      _vHScan[0]->Fill(_stageY,_stageX);
	      _mean[0][0]+=_stageY;
	      _mean[0][1]+=_stageX;
	      _norm[0]++;
	    }
	    if(x==_centreX   && y==_centreY-1) {
	      _vHScan[1]->Fill(_stageY,_stageX);
	      _mean[1][0]+=_stageY;
	      _mean[1][1]+=_stageX;
	      _norm[1]++;
	    }
	    if(x==_centreX+1 && y==_centreY-1) {
	      _vHScan[2]->Fill(_stageY,_stageX);
	      _mean[2][0]+=_stageY;
	      _mean[2][1]+=_stageX;
	      _norm[2]++;
	    }
	    if(x==_centreX-1 && y==_centreY  ) {
	      _vHScan[3]->Fill(_stageY,_stageX);
	      _mean[3][0]+=_stageY;
	      _mean[3][1]+=_stageX;
	      _norm[3]++;
	    }
	    if(x==_centreX   && y==_centreY  ) {
	      _vHScan[4]->Fill(_stageY,_stageX);
	      _mean[4][0]+=_stageY;
	      _mean[4][1]+=_stageX;
	      _norm[4]++;
	    }
	    if(x==_centreX+1 && y==_centreY  ) {
	      _vHScan[5]->Fill(_stageY,_stageX);
	      _mean[5][0]+=_stageY;
	      _mean[5][1]+=_stageX;
	      _norm[5]++;
	    }
	    if(x==_centreX-1 && y==_centreY+1) {
	      _vHScan[6]->Fill(_stageY,_stageX);
	      _mean[6][0]+=_stageY;
	      _mean[6][1]+=_stageX;
	      _norm[6]++;
	    }
	    if(x==_centreX   && y==_centreY+1) {
	      _vHScan[7]->Fill(_stageY,_stageX);
	      _mean[7][0]+=_stageY;
	      _mean[7][1]+=_stageX;
	      _norm[7]++;
	    }
	    if(x==_centreX+1 && y==_centreY+1) {
	      _vHScan[8]->Fill(_stageY,_stageX);
	      _mean[8][0]+=_stageY;
	      _mean[8][1]+=_stageX;
	      _norm[8]++;
	    }
	  }
	}
      }
    }
	*/

    return true;
  }
  

private:
  HstCfgCount1D _hCfgX;
  HstCfgCount1D _hCfgY;

  std::vector<TH2F*> _vHScan;
  std::vector<TH1F*> _vHScan1;
  double _mean[9][2];
  double _norm[9];
  unsigned _centreX;
  unsigned _centreY;

  int _stageX;
  int _stageY;
  int _xMd;
  int _yMd;
};

#endif
