#include "hades.h"
#include "hcategory.h"
#include "hevent.h"
#include "heventheader.h"
#include "hruntimedb.h"
#include "hspectrometer.h"
#include "hrichdetector.h"
#include "hrich700raw.h"
#include "hrichcal.h"
#include "hrichcalsim.h"
#include "hstart2hit.h"
#include "hiterator.h"
#include "hrich700calibrater.h"
#include "hrich700thresholdpar.h"
#include "richdef.h"
#include "hstartdef.h"
#include <iostream>
using namespace std;
ClassImp(HRich700Calibrater)
HRich700Calibrater::HRich700Calibrater(const Text_t* name,  const Text_t* title)
    : HReconstructor(name,title) {
  
  fCalCat = NULL;
  fRawCat = NULL;
  fStartHitCat = NULL;
  fThresholds = NULL;
  fDoTimeCut = kTRUE;
  fUseSTART  = kTRUE;
  iterRaw    = NULL;
}
Bool_t HRich700Calibrater::init(void) {
  
  HRichDetector* det = (HRichDetector*)gHades->getSetup()->getDetector("Rich");
  if (!det) {
    Error("init", "No Rich Detector found.");
    return kFALSE;
  }
  fStartHitCat = gHades->getCurrentEvent()->getCategory(catStart2Hit);
  if (NULL == fStartHitCat) {
      Warning("init", "HStartHit category not found");
  }
  fRawCat = gHades->getCurrentEvent()->getCategory(catRich700Raw);
  if (NULL == fRawCat) {
      Warning("init", "HRich700Raw category not found");
  }
  fCalCat = gHades->getCurrentEvent()->getCategory(catRichCal);
  if (NULL == fCalCat) {
      if(gHades->getEmbeddingMode() == 0) {
	  fCalCat = det->buildCategory(catRichCal);
	  if (NULL == fCalCat) {
	      Error("init", "Pointer to HRichCal category is NULL");
	      return kFALSE;
	  } else {
	      gHades->getCurrentEvent()->addCategory(catRichCal, fCalCat, "Rich");
	  }
      } else {
	  fCalCat = det->buildMatrixCat("HRichCalSim", 1);
	  if (NULL == fCalCat) {
	      Error("init", "Can not build output category catRichCalSim, returning...");
	      return kFALSE;
	  } else {
	      gHades->getCurrentEvent()->addCategory(catRichCal, fCalCat, "Rich");
	  }
      }
  }
  iterRaw=(HIterator *)((HCategory*)fRawCat)->MakeIterator("native");
  fRawLoc.set(2, 0, 0);
  fCalLoc.set(3, 0, 0, 0);
  
  fThresholds = (HRich700ThresholdPar*)(gHades->getRuntimeDb()
      ->getContainer("Rich700ThresholdPar"));
  if (!fThresholds) {
    Error("init", "No Pointer to parameter container Rich700ThresholdPar.");
    return kFALSE;
  }
  
  
  return kTRUE;
}
Bool_t HRich700Calibrater::reinit(void) {
  return kTRUE;
}
Int_t HRich700Calibrater::execute(void) {
  
  if (gHades->isCalibration()) {
    return 1;
  }
  
  if (gHades->getCurrentEvent()->getHeader()->getId() == 0xe) {
    return 1;
  }
  if(fRawCat && fCalCat){
      Double_t starttime = 0;
      if(fStartHitCat && fUseSTART){
	  if(fStartHitCat->getEntries()>0){
	      HStart2Hit* start = (HStart2Hit*)fStartHitCat->getObject(0);
              starttime = start->getTime();
	  }
      }
      Int_t pmt,pix,sec,col,row;
      Double_t t1;
      Double_t tot;
      HRich700Raw* raw =0;
      iterRaw->Reset();
      while ((raw=(HRich700Raw *)iterRaw->Next())!=0)
      {
	  Int_t n = raw->getMultiplicity();
	  raw->getAddress(pmt,pix,sec,col,row);
	  for (Int_t j = 0 ; j < n ; j ++)
	  {
	      const HRich700hit_t* hit = raw->getHit(j);
	      if(0b11 !=  hit->fFlag) { continue; }
	      t1   = hit->fLeadingEdgeTime - starttime;
	      tot  = hit->fToT;
	      fRawLoc[0] = pmt;
	      fRawLoc[1] = pix;
       
	      
	      Double_t tmin=0, tmax=1.0e-6, totmin=1e-9, totmax=1e-8; 
	      HRich700PixelThreshold* pthres =fThresholds->getObject(fRawLoc);
	      if(pthres)
	      {
		  if(pthres->getFlag() != 0) { continue; }
		  tmin   = pthres->getT_Min(); 
		  tmax   = pthres->getT_Max();
		  totmin = pthres->getTot_Min();
		  totmax = pthres->getTot_Max();
		  Int_t loc[3] = {sec,col,row};
		  if(loc[0]<0)  continue;
		  if(fDoTimeCut){
		      if( t1 <tmin   || t1 >tmax  ) { continue; }
		      if( tot<totmin || tot>totmax) { continue; }
		  }
		  addCalHitCharge(loc[0],loc[1],loc[2], t1, tot); 
	      } else {
		  Error("execute()", "Can't get threshold parameter for  pmt=%i, pixel=%i, using precompileddefaults!", fRawLoc[0], fRawLoc[1]);
		  continue;
	      }
	  }
      }
  }
  return 0; 
}
Int_t HRich700Calibrater::addCalHitCharge(Int_t sector, Int_t col, Int_t row,
                  Float_t time, Float_t tot) {
   fCalLoc[0] = sector;
   fCalLoc[1] = row;
   fCalLoc[2] = col;
   
   
   
   
   
   HRichCalSim* calsim = 0;
   HRichCal* cal = static_cast<HRichCal*>(fCalCat->getObject(fCalLoc));
   if (NULL == cal) {
      cal = static_cast<HRichCal*>(fCalCat->getSlot(fCalLoc));
      if (NULL != cal) {
	  
	  if(gHades->getEmbeddingMode() != 0){
	      cal = new (cal) HRichCalSim;
	      calsim = static_cast<HRichCalSim*> (cal);
	      if(!calsim->checkTrackId(gHades->getEmbeddingRealTrackId())) calsim->addTrackId(gHades->getEmbeddingRealTrackId());
	  }  else {
	      cal = new (cal) HRichCal;
	  }
	  cal->setMult(0);
	  cal->setSector(fCalLoc[0]);
	  cal->setRow(fCalLoc[1]);
	  cal->setCol(fCalLoc[2]);
	  cal->setTime(time);
      } else {
	  Warning("addCalHit()",
		  "Can't get slot sector=%i, row=%i, col=%i", fCalLoc[0],
		  fCalLoc[1], fCalLoc[2]);
	  return -1;
      }
   }
   
   cal->addToT(tot);
   cal->increaseMult();
   return 0;
}
 hrich700calibrater.cc:100  hrich700calibrater.cc:101  hrich700calibrater.cc:102  hrich700calibrater.cc:103  hrich700calibrater.cc:104  hrich700calibrater.cc:105  hrich700calibrater.cc:106  hrich700calibrater.cc:107  hrich700calibrater.cc:108  hrich700calibrater.cc:109  hrich700calibrater.cc:110  hrich700calibrater.cc:111  hrich700calibrater.cc:112  hrich700calibrater.cc:113  hrich700calibrater.cc:114  hrich700calibrater.cc:115  hrich700calibrater.cc:116  hrich700calibrater.cc:117  hrich700calibrater.cc:118  hrich700calibrater.cc:119  hrich700calibrater.cc:120  hrich700calibrater.cc:121  hrich700calibrater.cc:122  hrich700calibrater.cc:123  hrich700calibrater.cc:124  hrich700calibrater.cc:125  hrich700calibrater.cc:126  hrich700calibrater.cc:127  hrich700calibrater.cc:128  hrich700calibrater.cc:129  hrich700calibrater.cc:130  hrich700calibrater.cc:131  hrich700calibrater.cc:132  hrich700calibrater.cc:133  hrich700calibrater.cc:134  hrich700calibrater.cc:135  hrich700calibrater.cc:136  hrich700calibrater.cc:137  hrich700calibrater.cc:138  hrich700calibrater.cc:139  hrich700calibrater.cc:140  hrich700calibrater.cc:141  hrich700calibrater.cc:142  hrich700calibrater.cc:143  hrich700calibrater.cc:144  hrich700calibrater.cc:145  hrich700calibrater.cc:146  hrich700calibrater.cc:147  hrich700calibrater.cc:148  hrich700calibrater.cc:149  hrich700calibrater.cc:150  hrich700calibrater.cc:151  hrich700calibrater.cc:152  hrich700calibrater.cc:153  hrich700calibrater.cc:154  hrich700calibrater.cc:155  hrich700calibrater.cc:156  hrich700calibrater.cc:157  hrich700calibrater.cc:158  hrich700calibrater.cc:159  hrich700calibrater.cc:160  hrich700calibrater.cc:161  hrich700calibrater.cc:162  hrich700calibrater.cc:163  hrich700calibrater.cc:164  hrich700calibrater.cc:165  hrich700calibrater.cc:166  hrich700calibrater.cc:167  hrich700calibrater.cc:168  hrich700calibrater.cc:169  hrich700calibrater.cc:170  hrich700calibrater.cc:171  hrich700calibrater.cc:172  hrich700calibrater.cc:173  hrich700calibrater.cc:174  hrich700calibrater.cc:175  hrich700calibrater.cc:176  hrich700calibrater.cc:177  hrich700calibrater.cc:178  hrich700calibrater.cc:179  hrich700calibrater.cc:180  hrich700calibrater.cc:181  hrich700calibrater.cc:182  hrich700calibrater.cc:183  hrich700calibrater.cc:184  hrich700calibrater.cc:185  hrich700calibrater.cc:186  hrich700calibrater.cc:187  hrich700calibrater.cc:188  hrich700calibrater.cc:189  hrich700calibrater.cc:190  hrich700calibrater.cc:191  hrich700calibrater.cc:192  hrich700calibrater.cc:193  hrich700calibrater.cc:194  hrich700calibrater.cc:195  hrich700calibrater.cc:196  hrich700calibrater.cc:197  hrich700calibrater.cc:198  hrich700calibrater.cc:199  hrich700calibrater.cc:200  hrich700calibrater.cc:201  hrich700calibrater.cc:202  hrich700calibrater.cc:203  hrich700calibrater.cc:204  hrich700calibrater.cc:205  hrich700calibrater.cc:206  hrich700calibrater.cc:207  hrich700calibrater.cc:208  hrich700calibrater.cc:209  hrich700calibrater.cc:210  hrich700calibrater.cc:211  hrich700calibrater.cc:212  hrich700calibrater.cc:213  hrich700calibrater.cc:214  hrich700calibrater.cc:215  hrich700calibrater.cc:216  hrich700calibrater.cc:217  hrich700calibrater.cc:218  hrich700calibrater.cc:219  hrich700calibrater.cc:220  hrich700calibrater.cc:221  hrich700calibrater.cc:222  hrich700calibrater.cc:223  hrich700calibrater.cc:224  hrich700calibrater.cc:225  hrich700calibrater.cc:226  hrich700calibrater.cc:227  hrich700calibrater.cc:228  hrich700calibrater.cc:229  hrich700calibrater.cc:230  hrich700calibrater.cc:231  hrich700calibrater.cc:232  hrich700calibrater.cc:233  hrich700calibrater.cc:234  hrich700calibrater.cc:235  hrich700calibrater.cc:236  hrich700calibrater.cc:237  hrich700calibrater.cc:238  hrich700calibrater.cc:239