void saveDownSampleIm(const string &path,const Size& tileSz,const Size& gridDim, int scaleLevel, Mat &outIm)
{
	Size outTileSz((int)(tileSz.width / pow(2.0, (double)scaleLevel)), (int)(tileSz.height / pow(2.0, (double)scaleLevel)));
	Size outFullSz(gridDim.width * outTileSz.width, gridDim.height * outTileSz.height);
	assert((outFullSz.width < 32768) && (outFullSz.height < 32768));

	printf("outTileSz: (%d, %d)\n", outTileSz.width, outTileSz.height);
	printf("outFullSz: (%d, %d)\n", outFullSz.width, outFullSz.height);

	outIm.create(outFullSz, CV_32FC1);
	Point relTL; // relTL is relative to top-left of outIm

	for (int i = 0; i < gridDim.height; i++)
	{
		for (int j = 0; j < gridDim.width; j++)
		{
			Mat temp;
			loadGridIm(path, makePt(j, i), temp, tileSz.width, tileSz.height);
			resize(temp, temp, Size(0, 0), 1 / pow(2.0, (double)scaleLevel), 1 / pow(2.0, (double)scaleLevel), INTER_NEAREST);
			assert((temp.size().width == outTileSz.width) && (temp.size().height == outTileSz.height));
			relTL.x = j * outTileSz.width;
			relTL.y = i * outTileSz.height;
			blit(temp, outIm, relTL);
		}
	}

	saveFloatTiff("../../../bin/down.tif", outIm);
}
void TauAnalysisSelector::setOutput(TDirectory *dir) {
  if(dir)
    dir->cd();

  hTau_AfterDecayModeFindingIsolation.book("tau_AfterDecayModeFindingIsolation");
  hGenTau_AfterDecayModeFindingIsolation.book("gentau_AfterDecayModeFindingIsolation");
  hVertexCount_AfterDecayModeFindingIsolation = makeVertexCount("vertexCount_AfterDecayModeFindingIsolation");

  hTau_AfterEtaCutIsolation.book("tau_AfterEtaCutIsolation");
  hGenTau_AfterEtaCutIsolation.book("gentau_AfterEtaCutIsolation");
  hVertexCount_AfterEtaCutIsolation = makeVertexCount("vertexCount_AfterEtaCutIsolation");

  hTau_AfterPtCutIsolation.book("tau_AfterPtCutIsolation");
  hGenTau_AfterPtCutIsolation.book("gentau_AfterPtCutIsolation");
  hTauLeadingTrackPt_AfterPtCutIsolation = makePt("tau_AfterPtCutIsolation_leadingTrackPt");
  hVertexCount_AfterPtCutIsolation = makeVertexCount("vertexCount_AfterPtCutIsolation");

  hTau_AfterLeadingTrackPtCutIsolation.book("tau_AfterLeadingTrackPtCutIsolation");
  hGenTau_AfterLeadingTrackPtCutIsolation.book("gentau_AfterLeadingTrackPtCutIsolation");

  hTau_AfterAgainstElectronIsolation.book("tau_AfterAgainstElectronIsolation");
  hGenTau_AfterAgainstElectronIsolation.book("gentau_AfterAgainstElectronIsolation");

  hTau_AfterAgainstMuonIsolation.book("tau_AfterAgainstMuonIsolation");
  hGenTau_AfterAgainstMuonIsolation.book("gentau_AfterAgainstMuonIsolation");

  hTau_AfterIsolation.book("tau_AfterIsolation");
  hGenTau_AfterIsolation.book("gentau_AfterIsolation");
  hTauDecayMode_AfterIsolation = makeTH<TH1F>("tauDecayMode_AfterIsolation", "Decay mode", 5, 0, 5);
  hTauDecayModeAll_AfterIsolation = makeTH<TH1F>("tauDecayModeAll_AfterIsolation", "Decay mode", 16, 0, 16);
  hVertexCount_AfterIsolation = makeVertexCount("vertexCount_AfterIsolation");

  hTau_AfterOneProng.book("tau_AfterOneProng");
  hGenTau_AfterOneProng.book("gentau_AfterOneProng");
  hTauP_AfterOneProng = makePt("tau_AfterOneProng_p");
  hTauLeadingTrackPt_AfterOneProng = makePt("tau_AfterOneProng_leadingTrackPt");
  hTauLeadingTrackP_AfterOneProng = makePt("tau_AfterOneProng_leadingTrackP");
  hTauRtau_AfterOneProng = makeTH<TH1F>("tau_AfterOneProng_rtau", "Rtau", 22, 0, 1.1);
  hVertexCount_AfterOneProng = makeVertexCount("vertexCount_AfterOneProng");

  hTau_AfterRtau.book("tau_AfterRtau");
  hGenTau_AfterRtau.book("gentau_AfterRtau");
  hVertexCount_AfterRtau = makeVertexCount("vertexCount_AfterRtau");
}
void imCrop(const string &outPath, const string &inPath, const Rect& outRec,const Size& tileSz,const Size& gridDim, const string &fileName)
{
	// check validity
	Point tl = outRec.tl();
	Point br = outRec.br();
	Size sz = outRec.size();

	Size fullSz(tileSz.width * gridDim.width, tileSz.height * gridDim.height);
	printf("tl: %d, %d/br: %d, %d\n", tl.x, tl.y, br.x, br.y);
	assert(br.x > 0 && br.y > 0 && tl.x < fullSz.width && tl.y < fullSz.height);

	Mat outIm(sz, CV_32FC1);
	printf("size of outIm: w: %d, h: %d\n", outIm.size().width, outIm.size().height);
	Point relTL; // relTL is relative to top-left of outIm

	int startX = tl.x / tileSz.width;
	int endX = br.x / tileSz.width;
	int startY = tl.y / tileSz.height;
	int endY = br.y / tileSz.height;

	printf("start: (%d, %d), end: (%d, %d)\n", startX, startY, endX, endY);

	for (int i = startY; i <= endY; i++)
	{
		for (int j = startX; j <= endX; j++)
		{
			if (i < 0 || i >= gridDim.height || j < 0 || j >= gridDim.width)
				continue;
			Mat temp;
			printf("j: %d, i: %d\n", j, i);
			relTL.x = tileSz.width * j - tl.x;
			relTL.y = tileSz.height * i - tl.y;
			printf("relTL.x: %d, relTL.y: %d\n", relTL.x, relTL.y);
			loadGridIm(inPath, makePt(j, i), temp, tileSz.width, tileSz.height); 
			blit(temp, outIm, relTL);
		}
	}

	ostringstream ss;
	ss << outPath << "/" << fileName << ".tiff";
	string s = ss.str();
	saveFloatTiff(s, outIm);
}
 void book(const std::string& prefix) {
   hPt = makePt((prefix+"_pt").c_str());
   hEta = makeTH<TH1F>((prefix+"_eta").c_str(), "Eta", 44, -2.1, 2.1);
   hPhi = makeTH<TH1F>((prefix+"_phi").c_str(), "Phi", 128, -3.2, 3.2);
 }