Exemple #1
0
bool FileUtil::saveDescriptorWithLabel(const cv::Mat &descriptor,
                                       const int32_t label,
                                       const std::string &outputPath,
                                       const std::string &descriptorFileName,
                                       const std::string &labelFileName, const std::string &prefix)
{
    FileWriter<BIN> writer;

    if(!descriptor.empty()) {
        QDir outputDir(QString::fromStdString(outputPath));
        if(outputDir.exists()) {
            if(writer.write(descriptor, outputPath, descriptorFileName, prefix)) {
                if(appendDescriptor(labelFileName,
                                    outputPath,
                                    descriptorFileName,
                                    label,
                                    prefix)) {
                    return true;
                } else {
                    return false;
                }
            } else {
                return false;
            }
        } else {
            error("Output directory doesn't exist, aborting.");
            return false;
        }
    } else {
        error("Empty output object given, aborting.");
        return false;
    }
}
Exemple #2
0
Task::ReportResult BgzipTask::report() {
    if (hasError() || isCanceled()) {
        QDir outputDir(bgzfUrl.dirPath());
        outputDir.remove(bgzfUrl.getURLString());
    }
    return ReportResult_Finished;
}
Exemple #3
0
Task::ReportResult GzipDecompressTask::report() {
    if (hasError() || isCanceled()) {
        QDir outputDir(unzippedUrl.dirPath());
        outputDir.remove(unzippedUrl.getURLString());
    }
    return ReportResult_Finished;
}
CString webkitBuildDirectory()
{
    const char* webkitOutputDir = g_getenv("WEBKIT_OUTPUTDIR");
    if (webkitOutputDir)
        return webkitOutputDir;

    GUniquePtr<char> outputDir(g_build_filename(topLevelPath().data(), "WebKitBuild", nullptr));
    return outputDir.get();
}
Exemple #5
0
CString getOutputDir()
{
    const char* webkitOutputDir = g_getenv("WEBKIT_OUTPUTDIR");
    if (webkitOutputDir)
        return webkitOutputDir;

    CString topLevelPath = WTR::topLevelPath();
    GOwnPtr<char> outputDir(g_build_filename(topLevelPath.data(), "WebKitBuild", NULL));
    return outputDir.get();
}
Exemple #6
0
void PageGenerator::beginSubPage(const Location& location,
                                 const QString& fileName)
{
    QFile *outFile = new QFile(outputDir() + "/" + fileName);
    if (!outFile->open(QFile::WriteOnly))
	location.fatal(tr("Cannot open output file '%1'")
			.arg(outFile->fileName()));
    QTextStream *out = new QTextStream(outFile);
    out->setCodec("ISO-8859-1");
    outStreamStack.push(out);
}
Exemple #7
0
void Pipeline::BuildAtlasStage(QHash<QString,ImageList> images, Task* task)
{
	for(const QString& resolution : images.keys())
	{
		int width = task->atlasParams.sizes[resolution].width();
		int height = task->atlasParams.sizes[resolution].height();

		if(!MathUtils::IsPowerOfTwo(width) || !MathUtils::IsPowerOfTwo(height))
		{
			QString error = ERROR_MASK.arg(task->name).arg("Sizes of atlas for resolution \"%1\" must be power of two");
			errors.push_back(error.arg(resolution));
			return;
		}

		QPair<QImage,QJsonObject> atlas = atlasBuilder.Run(images[resolution], width, height,
			task->outputFormat, task->atlasParams);

		// Save atlas image
		QString imageFilename = MakeFilename(task->atlasParams.name, resolution, ExtensionForFormat(task->outputFormat));
		if(!SaveImage(atlas.first, task->outputDir, imageFilename, task->outputFormat))
		{
			errors.push_back(ERROR_MASK.arg(task->name).arg(ERROR_SAVE_MASK.arg(imageFilename)));
			return;
		}

		// Save atlas json description
		QDir outputDir(task->outputDir);
		QString filename = MakeFilename(task->atlasParams.name, resolution, "atlas");
		QFile file(outputDir.absoluteFilePath(filename));
		if(!file.open(QIODevice::WriteOnly))
		{
			errors.push_back(ERROR_MASK.arg(task->name).arg(ERROR_SAVE_MASK.arg(filename)));
			return;
		}

		QJsonDocument doc(atlas.second);
		file.write(doc.toJson());

		auto atlasErrors = atlasBuilder.GetErrors();
		if(!atlasErrors.empty())
		{
			for(auto& error : atlasErrors)
			{
				QString resError = QString("%1 for \"%2\" resolution").arg(error).arg(resolution);
				errors.push_back(ERROR_MASK.arg(task->name).arg(resError));
			}
		}

		UpdateProgress();
	}
}
    foreach (const QString &dir, dirs) {
        if ((dir.at(0) == QChar('.'))
                || (dir.right(5) == "build")
                || (dir.right(flags->outputDirectory().length()) == flags->outputDirectory())) {
            // Don't touch hidden directiories
            // Don't touch build directory
            // Don't touch output directory
            continue;
        }

        QString outputPath = tempOutput.path() + "/" + dir;
        QDir outputDir(outputPath);
        QDir inputDir(tempInput.path() + "/" + dir);
        convertDirectory(inputDir, outputDir);
    }
Exemple #9
0
void WebXMLGenerator::generateTree(const Tree *tree, CodeMarker *marker)
{
    tre = tree;
    moduleClassMap.clear();
    moduleNamespaceMap.clear();
    serviceClasses.clear();
    findAllClasses(tree->root());
    findAllNamespaces(tree->root());

    PageGenerator::generateTree(tree, marker);

    if (generateIndex)
        tre->generateIndex(outputDir() + "/" + project.toLower() + ".index",
                           projectUrl, projectDescription, false);
}
void RunDumpL()
	{
	// Location of Output Directory. (File will be called DbDump.html). Final "\" required on path.   
	_LIT(KOutputDir, "?:\\");	
	TBuf<sizeof(KOutputDir)> outputDir(KOutputDir);
	outputDir[0] = (TUint8) RFs::GetSystemDriveChar();
	
	// Location of Contacts DB
	_LIT(KDBName, "?:Contacts.cdb");	
	TBuf<sizeof(KDBName)> fileDBName(KDBName);
	fileDBName[0] = (TUint8) RFs::GetSystemDriveChar();
	
	// dump dbms database 
	CDbDbmsDumper* dbmsDumper = CDbDbmsDumper::NewLC(fileDBName, outputDir);
    dbmsDumper->OutputDBContentsL();   
	CleanupStack::PopAndDestroy(dbmsDumper);   
	}
Exemple #11
0
static bool SaveImage(const QImage& image, const QString& directory, const QString& filename, OutputFormat format)
{
	QDir outputDir(directory);
	const char* strFormat = nullptr;

	switch(format)
	{
	case OutputFormat::PNG_32:
	case OutputFormat::PNG_24:
		strFormat = "PNG";
		break;
	case OutputFormat::JPEG:
		strFormat = "JPEG";
		break;
	}

	return image.save(outputDir.absoluteFilePath(filename), strFormat);
}
int main(int argc, char *argv[])
{
	if (argc!=5)
	{
		qWarning(QString("Usage: %1 <input_path> <output_path> <output_extent> <output format>").arg(argv[0]).toLocal8Bit().data());
		return -1;
	}

	int extent = QString(argv[3]).toInt();
	if (extent<=0)
	{
		qWarning(QString("Extent should be more than zero!").toLocal8Bit().data());
		return -2;
	}


	QDir inputDir(argv[1]);
	QDir outputDir(argv[2]);

	QStringList files = inputDir.entryList(QStringList("*.svg"), QDir::Files);
	for (QStringList::ConstIterator it=files.constBegin(); it!=files.constEnd(); ++it)
	{
		QFile input(inputDir.absoluteFilePath(*it));
		if (input.open(QIODevice::ReadOnly))
		{
			QImageReader reader(&input);
			reader.setScaledSize(QSize(extent, extent));
			QImage image = reader.read();
			input.close();

			QString fileName = QFileInfo(input).fileName();
			fileName.chop(fileName.length()-fileName.lastIndexOf('.')-1);
			fileName.append(argv[4]);
			QFile output(outputDir.absoluteFilePath(fileName));
			if (output.open(QIODevice::WriteOnly))
			{
				QImageWriter writer(&output, argv[4]);
				writer.write(image);
				output.close();
			}
		}
	}
}
Exemple #13
0
/*!
  \internal

  Returns true if file names for \a input and \a output are the same.
 */
bool SpdrImportPrivate::areFilesTheSame(const QString &input, const QString &output) const
{
    Q_Q(const SpdrImport);

    QFileInfo outputInfo(output);
    if (!outputInfo.exists()) {

        if (q->isSuffixCaseSensitive()) {
            return false;
        } else {
            SpdrFileData inputData(input, q->inputPath(), SpdrFileData::ShallowSearch, q);

            QDir outputDir(output);
            outputDir.cdUp();
            QFileInfoList outputFiles(outputDir.entryInfoList(QDir::Files | QDir::NoDotAndDotDot));

            foreach (const QFileInfo &file, outputFiles) {
                if (file.baseName() != outputInfo.baseName()) {
                    continue;
                }

                SpdrFileData outputData(file.absoluteFilePath(), "", SpdrFileData::ShallowSearch, q);

                if (inputData.isEqual(outputData, q->isSuffixCaseSensitive())) {
                    return true;
                } else {
                    continue;
                }
            }
        }

        return false;
    }

    SpdrFileData inputData(input, q->inputPath(), SpdrFileData::ShallowSearch, q);
    SpdrFileData outputData(output, q->inputPath(), SpdrFileData::ShallowSearch, q);

    if (inputData.isEqual(outputData, q->isSuffixCaseSensitive())) {
        return true;
    }

    return false;
}
/*!
  Main conversion routine.
  */
void ConverterCore::convert()
{
    if (helpMode)
        return;

    if ((flags->inputDirectory() == flags->outputDirectory())
            && !(flags->flags() & ConverterFlags::Force)
            && !(flags->flags() & ConverterFlags::Suffix)) {
        enterErrorState("Will not overwrite without --force or a given --suffix.");
        return;
    }

    QString input;
    QString output;

    if (flags->inputDirectory() == "") {
        input = ".";
    } else {
        input = flags->inputDirectory();
    }

    if (flags->outputDirectory() == "") {
        output = ".";
    } else {
        output = flags->outputDirectory();
    }

    QDir inputDir(input);
    QDir outputDir(output);

    convertDirectory(inputDir, outputDir);

    ConverterQrcGenerator qrcGenerator(flags, this);
    qrcGenerator.createQrcFiles();
    if (qrcGenerator.isErrorState()) {
        enterErrorState(qrcGenerator.errorMessage());
    }
}
void Foam::functionObjectFile::createFiles()
{
    if (Pstream::master())
    {
        const word startTimeName =
            obr_.time().timeName(obr_.time().startTime().value());

        label i = 0;
        forAllConstIter(wordHashSet, names_, iter)
        {
            if (!filePtrs_.set(i))
            {
                fileName outputDir(baseFileDir()/prefix_/startTimeName);

                mkDir(outputDir);

                word fName(iter.key());

                // check if file already exists
                IFstream is(outputDir/(fName + ".dat"));
                if (is.good())
                {
                    fName = fName + "_" + obr_.time().timeName();
                }

                filePtrs_.set(i, new OFstream(outputDir/(fName + ".dat")));

                initStream(filePtrs_[i]);

                writeFileHeader(i);

                i++;
            }
        }
    }
}
int
main(int argc,
     char** argv)
{
    if (argc != 6) {
        std::cout << "This program takes in input glad.h and outputs the include and implementation files for OSMesa OpenGL function and regular OpenGL functions." << std::endl;
        std::cout << "Usage: generateGLIncludes <glad.h path> <output dir path> <namespace name> <baseFileName> <inlcude glad debug symbols>" << std::endl;
        std::cout << "Example: generateGLIncludes /Users/alexandre/development/Natron/Global/gladRel/include/glad/glad.h /Users/alexandre/development/Natron/Engine Natron OSGLFunctions 1" << std::endl;

        return 1;
    }

    QFile f(argv[1]);
    if ( !f.open(QIODevice::ReadOnly) ) {
        std::cout << "Could not open " << argv[1] << std::endl;

        return 1;
    }

    // Check that output path exists

    QDir outputDir(argv[2]);
    if ( !outputDir.exists() ) {
        std::cout << argv[2] << " does not seem to be a valid directory" << std::endl;

        return 1;
    }

    QString namespaceName(argv[3]);
    QString baseFilename(argv[4]);
    bool supportGladDebug;
    {
        QString supportDebugSymbolsStr(argv[5]);
        supportGladDebug = (bool)supportDebugSymbolsStr.toInt();
    }
    QString absoluteDirPath = outputDir.absolutePath();
    QString outputHeaderFilename = absoluteDirPath + "/" + baseFilename + ".h";
    QFile of_header(outputHeaderFilename);
    if ( !of_header.open(QIODevice::WriteOnly) ) {
        std::cout << "Could not open " << outputHeaderFilename.toStdString() << std::endl;

        return 1;
    }
    QTextStream ots_header(&of_header);
    QTextStream its(&f);
    QString definesStr;

    std::list<FunctionSignature> signatures;
    QString functionTypedefsStr;
    QString prevLine;
    while ( !its.atEnd() ) {
        // Read each line of glad.h
        QString line = its.readLine();

        {
            // Search for a define
            QString toFind = "#define GL_";
            int found = line.indexOf(toFind);
            if (found != -1) {
                definesStr += line;
                definesStr += "\n";
            }
        }

        // Search for a function
        QString typedefToken("typedef ");
        QString pfnToken("(APIENTRYP PFNGL");
        int foundFuncDef = line.indexOf(typedefToken);
        int foundPNFToken = line.indexOf(pfnToken);
        if ( (foundFuncDef != -1) && (foundPNFToken != -1) ) {
            int pos = foundPNFToken + pfnToken.size();
            int foundFirstEndParenthesis = line.indexOf(')', pos);
            assert(foundFirstEndParenthesis != -1);


            FunctionSignature signature;
            QString lastFuncNameCaps = line.mid(pos, foundFirstEndParenthesis - pos);
            signature.signature = line.mid(foundFirstEndParenthesis);
            // "near" and "far" are defined as macros in windows.h
            signature.signature.replace("GLdouble near, GLdouble far", "GLdouble nearVal, GLdouble farVal");

            signature.returnType = line.mid( foundFuncDef + typedefToken.size(), foundPNFToken - 1 - ( foundFuncDef + typedefToken.size() ) );
            QString funcTypeDefStr = "typedef ";
            funcTypeDefStr += signature.returnType;
            funcTypeDefStr += " (*PFNGL";
            funcTypeDefStr += lastFuncNameCaps;
            funcTypeDefStr += signature.signature;
            funcTypeDefStr += "\n";
            functionTypedefsStr += funcTypeDefStr;

            // Remove the extraneous ; at the end of the signature
            // Also remove the prepending )
            signature.signature.remove(0, 1);
            signature.signature.remove(signature.signature.size() - 1, 1);

            signature.funcPNType = "PFNGL";
            signature.funcPNType += lastFuncNameCaps;

            // extract parameters
            {
                int i = 1; // start after the leading (
                while ( i < signature.signature.size() ) {
                    QString param;
                    while ( signature.signature[i] != QChar(',') && signature.signature[i] != QChar(')') ) {
                        param.append(signature.signature[i]);
                        ++i;
                    }

                    // Now only keep the name of the parameter
                    {
                        int j = param.size() - 1;
                        while ( j >= 0 && param[j].isLetterOrNumber() ) {
                            --j;
                        }
                        param = param.mid(j + 1);
                    }
                    signature.parameters.append(param);

                    assert( signature.signature[i] == QChar(',') || signature.signature[i] == QChar(')') );
                    ++i; // bypass last character

                    if ( signature.signature[i] == QChar(')') ) {
                        break;
                    }
                }
            }

            // we caught a function typedef before, we expect to read the following #define glXxxx function with the appropriate case
            // in release glad.h, the next line is of the type GLAPI PFNGLCOLOR4FVPROC glad_glColor4fv;
            // the line after that is the one we want #define glColor4fv glad_glColor4fv
            line = its.readLine();
            assert( !its.atEnd() );
            line = its.readLine();

            QString toFind("#define gl");
            int foundDefine = line.indexOf(toFind);
            if (foundDefine == -1) {
                std::cout << "Parser failed to find #define glXXX statement 2 lines after a function typedef, make sure that you are running this program against a release version of glad.h" << std::endl;

                return 1;
            }

            // Check that this is the same symbol
            // Remove the PROC at the end of the func def
            lastFuncNameCaps.remove("PROC");
            int checkIndex = toFind.size();
            QString symbolStart = line.mid(checkIndex);
            assert( symbolStart.startsWith(lastFuncNameCaps, Qt::CaseInsensitive) );

            {
                int i = 8; // start on the g
                //extract the function name
                while ( i < line.size() && line.at(i) != QChar(' ') ) {
                    signature.funcName.push_back( line.at(i) );
                    ++i;
                }
            }

            signatures.push_back(signature);
        } // if (foundFuncDef != -1 && foundPNFToken != -1) {

        prevLine = line;
    }

    writeHeader(ots_header);
    writePODs(ots_header);
    ots_header <<
        definesStr << "\n"
        "\n";
    ots_header <<
        functionTypedefsStr << "\n"
        "\n";
    writeStartClass(namespaceName, ots_header);

    // Define the singleton
    ots_header <<
        "    static OSGLFunctions<USEOPENGL>& getInstance()\n"
        "    {\n"
        "        static OSGLFunctions<USEOPENGL> instance;\n"
        "\n"
        "        return instance;\n"
        "    }\n"
        "\n"
        "    // load function, implemented in _gl.h and _mesa.h\n"
        "    void load_functions();\n"
        "\n"
        "    // private constructor\n"
        "    OSGLFunctions() { load_functions(); }\n"
        "\n";

    // Declare member functions
    for (std::list<FunctionSignature>::iterator it = signatures.begin(); it != signatures.end(); ++it) {
        ots_header << "    " << it->funcPNType << " _" << it->funcName << ";\n";
    }

    ots_header <<
        "\n";

    ots_header <<
        "public:\n"
        "\n";


    ots_header <<
        "    // static non MT-safe load function that must be called once to initialize functions\n"
        "    static void load()\n"
        "    {\n"
        "        (void)getInstance();\n"
        "    }\n"
        "\n"
        "    static bool isGPU()\n"
        "    {\n"
        "        return USEOPENGL;\n"
        "    }\n";

    for (std::list<FunctionSignature>::iterator it = signatures.begin(); it != signatures.end(); ++it) {
        QString lineStart = "    static " +  it->returnType + " " + it->funcName;
        QString indentedSig = it->signature;
        indentedSig.replace( ", ", ",\n" + QString(lineStart.size() + 1, ' ') );
        ots_header << "\n" <<
            lineStart << indentedSig << "\n"
            "    {\n";
        if (it->returnType == "void") {
            ots_header << "        ";
        } else {
            ots_header << "        return ";
        }
        ots_header << "getInstance()._" << it->funcName << "(";
        QStringList::const_iterator next = it->parameters.begin();
        if ( !it->parameters.isEmpty() ) {
            ++next;
        }
        for (QStringList::const_iterator it2 = it->parameters.begin(); it2 != it->parameters.end(); ++it2) {
            ots_header << *it2;
            if ( next != it->parameters.end() ) {
                ots_header << ", ";
                ++next;
            }
        }

        ots_header <<
            ");\n"
            "    }\n";
    }
    writeEndClass(namespaceName, ots_header);

    writeFooter(ots_header);

    writeImplementationCppFile(namespaceName, baseFilename, signatures, absoluteDirPath, "gl", true, supportGladDebug);
    writeImplementationCppFile(namespaceName, baseFilename, signatures, absoluteDirPath, "mesa", false, supportGladDebug);


    return 0;
} // main
int main(int argc, const char** argv) {
    
    boost::program_options::options_description desc("Allowed options");
    desc.add_options()
        ("help", "produce help message")
        ("input", boost::program_options::value<std::string>(), "the folder to process")
        ("lambda", boost::program_options::value<double>()->default_value(0.5), "lambda")
        ("sigma", boost::program_options::value<double>()->default_value(5.0), "sigma")
        ("four-connected", "use 4-connected")
        ("superpixels", boost::program_options::value<int>()->default_value(400), "number of superpixels")
        ("time", boost::program_options::value<std::string>(), "time the algorithm and save results to the given directory")
        ("process", "show additional information while processing")
        ("csv", "save segmentation as CSV file")
        ("contour", "save contour image of segmentation")
        ("mean", "save mean colored image of segmentation")
        ("output", boost::program_options::value<std::string>()->default_value("output"), "specify the output directory (default is ./output)");

    boost::program_options::positional_options_description positionals;
    positionals.add("input", 1);
    
    boost::program_options::variables_map parameters;
    boost::program_options::store(boost::program_options::command_line_parser(argc, argv).options(desc).positional(positionals).run(), parameters);
    boost::program_options::notify(parameters);

    if (parameters.find("help") != parameters.end()) {
        std::cout << desc << std::endl;
        return 1;
    }
    
    boost::filesystem::path outputDir(parameters["output"].as<std::string>());
    if (!boost::filesystem::is_directory(outputDir)) {
        boost::filesystem::create_directory(outputDir);
    }
    
    boost::filesystem::path inputDir(parameters["input"].as<std::string>());
    if (!boost::filesystem::is_directory(inputDir)) {
        std::cout << "Image directory not found ..." << std::endl;
        return 1;
    }
    
    bool process = false;
    if (parameters.find("process") != parameters.end()) {
        process = true;
    }
    
    std::vector<boost::filesystem::path> pathVector;
    std::vector<boost::filesystem::path> images;
    
    std::copy(boost::filesystem::directory_iterator(inputDir), boost::filesystem::directory_iterator(), std::back_inserter(pathVector));

    std::sort(pathVector.begin(), pathVector.end());
    
    std::string extension;
    int count = 0;
    
    for (std::vector<boost::filesystem::path>::const_iterator iterator (pathVector.begin()); iterator != pathVector.end(); ++iterator) {
        if (boost::filesystem::is_regular_file(*iterator)) {
            
            // Check supported file extensions.
            extension = iterator->extension().string();
            std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
            
            if (extension == ".png" || extension == ".jpg" || extension == ".jpeg") {
                images.push_back(*iterator);
                
                if (process == true) {
                    std::cout << "Found " << iterator->string() << " ..." << std::endl;
                }
                
                ++count;
            }
        }
    }
    
    std::cout << count << " images total ..." << std::endl;
    
    boost::timer timer;
    double totalTime = 0;
    
    int eightConnected = 1;
    if (parameters.find("four-connected") != parameters.end()) {
        eightConnected = 0;
    }
    
    int superpixels = parameters["superpixels"].as<int>();
    int kernel = 0;
    double lambda = parameters["lambda"].as<double>();
    double sigma = parameters["sigma"].as<double>();
    MERCLazyGreedy merc;
    
    cv::Mat time(images.size(), 2, cv::DataType<double>::type);
    for(std::vector<boost::filesystem::path>::iterator iterator = images.begin(); iterator != images.end(); ++iterator) {
        cv::Mat mat = cv::imread(iterator->string());
        
        Image<RGBMap> inputImage;
        MERCInputImage<RGBMap> input;

        inputImage.Resize(mat.cols, mat.rows, false);

        for (int i = 0; i < mat.rows; ++i) {
            for (int j = 0; j < mat.cols; ++j) {
                RGBMap color((int) mat.at<cv::Vec3b>(i, j)[2], (int) mat.at<cv::Vec3b>(i, j)[1], (int) mat.at<cv::Vec3b>(i, j)[0]);
                inputImage.Access(j, i) = color;
            }
        }

        input.ReadImage(&inputImage, eightConnected);
		
        timer.restart();
        int index = std::distance(images.begin(), iterator);
        
        merc.ClusteringTreeIF(input.nNodes_, input, kernel, sigma*mat.channels(), lambda*1.0*superpixels, superpixels);
        
        time.at<double>(index, 1) = timer.elapsed();
        time.at<double>(index, 0) = index + 1;
        totalTime += time.at<double>(index, 1);
        
	vector<int> label = MERCOutputImage::DisjointSetToLabel(merc.disjointSet_);
        
        int** labels = new int*[mat.rows];
        for (int i = 0; i < mat.rows; ++i) {
            labels[i] = new int[mat.cols];
            
            for (int j = 0; j < mat.cols; ++j) {
                labels[i][j] = label[j + i*mat.cols];
            }
        }
        
        Integrity::relabel(labels, mat.rows, mat.cols);
        
        boost::filesystem::path extension = iterator->filename().extension();
        int position = iterator->filename().string().find(extension.string());
        
        if (parameters.find("contour") != parameters.end()) {
            
            std::string store = outputDir.string() + DIRECTORY_SEPARATOR + iterator->filename().string().substr(0, position) + "_contours.png";
            
            int bgr[] = {0, 0, 204};
            cv::Mat contourImage = Draw::contourImage(labels, mat, bgr);
            cv::imwrite(store, contourImage);
            
            if (process == true) {
                std::cout << "Image " << iterator->string() << " with contours saved to " << store << " ..." << std::endl;
            }
        }

        if (parameters.find("mean") != parameters.end()) {
            
            std::string store = outputDir.string() + DIRECTORY_SEPARATOR + iterator->filename().string().substr(0, position) + "_mean.png";

            cv::Mat meanImage = Draw::meanImage(labels, mat);
            cv::imwrite(store, meanImage);

            if (process == true) {
                std::cout << "Image " << iterator->string() << " with mean colors saved to " << store << " ..." << std::endl;
            }
        }

        if (parameters.find("csv") != parameters.end()) {
            
            boost::filesystem::path csvFile(outputDir.string() + DIRECTORY_SEPARATOR + iterator->filename().string().substr(0, position) + ".csv");
            Export::CSV(labels, mat.rows, mat.cols, csvFile);

            if (process == true) {
                std::cout << "Labels for image " << iterator->string() << " saved in " << csvFile.string() << " ..." << std::endl;
            }
        }
        
        for (int i = 0; i < mat.rows; ++i) {
            delete[] labels[i];
        }
        
        delete[] labels;
    }
    
    if (parameters.find("time") != parameters.end()) {
        
        boost::filesystem::path timeDir(parameters["time"].as<std::string>());
        if (!boost::filesystem::is_directory(timeDir)) {
            boost::filesystem::create_directories(timeDir);
        }
        
        boost::filesystem::path timeImgFile(timeDir.string() + DIRECTORY_SEPARATOR + "eval_time_img.txt");
        boost::filesystem::path timeFile(timeDir.string() + DIRECTORY_SEPARATOR + "eval_time.txt");
        
        Export::BSDEvaluationFile<double>(time, 4, timeImgFile);
        
        cv::Mat avgTime(1, 1, cv::DataType<double>::type);
        avgTime.at<double>(0, 0) = totalTime/((double) images.size());
        Export::BSDEvaluationFile<double>(avgTime, 6, timeFile);
    }
    
    std::cout << "On average, " << totalTime/images.size() << " seconds needed ..." << std::endl;
    
    return 0;
}
int main(int argc, char ** argv)
{
	// load the line data
	typedef utils::Directory::FilenamesType FilenamesType;
	FilenamesType filenames = utils::Directory::GetFiles(argv[1], ".json");

	for(unsigned int i = 0; i < filenames.size(); i++)
	{
		std::string filename = filenames[i];		
		std::cout << filename << std::endl;

		QString inFilename = QString::fromStdString(filename);
		inFilename = inFilename.replace(QString::fromStdString(argv[1]),"");
		inFilename = inFilename.replace("/","");
		inFilename = inFilename.replace(".json","");
		//std::cout << inFilename.toStdString() << std::endl;


		vt::JsonReader::Pointer reader = vt::JsonReader::New();
		reader->SetFilename(filename);
		typedef vt::JsonReader::LineSet LineSet;
		LineSet data = reader->Read();
		
		std::string partName = inFilename.toStdString();

		LineSet::iterator lineIt = data.begin();
		while(lineIt != data.end())
		{
			QString type = QString::fromStdString(lineIt->first);
			type = type.replace(":","-");

			QString output = QString::fromStdString(argv[2]);
			QDir outputDir(output);

			QString outputPath = outputDir.absoluteFilePath(type);
			//std::cout << outputPath.toStdString() << std::endl;

			if(!outputDir.exists(outputPath))
				outputDir.mkdir(outputPath);
			

			QString fileName = QDir(outputPath).absoluteFilePath(QString::fromStdString(partName));



			vt::JsonConverter::Pointer converter = vt::JsonConverter::New();
			converter->SetInput(lineIt->second);
			converter->Convert();

			vt::ValveSequenceWriter<3>::Pointer writer = vt::ValveSequenceWriter<3>::New();
			writer->SetInput(converter->GetOutput());
			writer->SetFileName(fileName.toStdString());
			writer->Write();

			std::cout << fileName.toStdString() << " " << converter->GetOutput()->GetNumberOfLines() << std::endl;


			++lineIt;
		}	






	}


	return 0;

}
void plotDYUnfoldingMatrix(const TString input, int systematicsMode = DYTools::NORMAL, int randomSeed = 1, double reweightFsr = 1.0, double massLimit = -1.0)
//systematicsMode 0 (NORMAL) - no systematic calc
//1 (RESOLUTION_STUDY) - systematic due to smearing, 2 (FSR_STUDY) - systematics due to FSR, reweighting
//check mass spectra with reweightFsr = 0.95; 1.00; 1.05  
//mass value until which do reweighting
{

  // check whether it is a calculation
  if (input.Contains("_DebugRun_")) {
    std::cout << "plotDYUnfoldingMatrix: _DebugRun_ detected. Terminating the script\n";
    return;
  }

  // normal calculation

  gBenchmark->Start("plotDYUnfoldingMatrix");

  if (systematicsMode==DYTools::NORMAL)
    std::cout<<"Running script in the NORMAL mode"<<std::endl;
  else if (systematicsMode==DYTools::RESOLUTION_STUDY)
    std::cout<<"Running script in the RESOLUTION_STUDY mode"<<std::endl;
  else if (systematicsMode==DYTools::FSR_STUDY)
    std::cout<<"Running script in the FSR_STUDY mode"<<std::endl;
  else if (systematicsMode==DYTools::ESCALE_RESIDUAL) 
    std::cout << "Running script in the ESCALE_RESIDUAL mode\n";
  else { 
    std::cout<<"requested mode not recognized"<<std::endl;
    assert(0);
  }

  //--------------------------------------------------------------------------------------------------------------
  // Settings 
  //==============================================================================================================
  
  Bool_t doSave  = false;    // save plots?
  TString format = "png";   // output file format
  int saveMadePlots = 1;  // whether save produced canvases
  
  vector<TString> fnamev;   // file names   
  vector<TString> labelv;   // legend label
  vector<Int_t>   colorv;   // color in plots
  vector<Int_t>   linev;    // line style
  vector<Double_t> xsecv;
  vector<Double_t> lumiv;
  TString          dirTag;

  ifstream ifs;
  ifs.open(input.Data());
  if (!ifs.is_open()) std::cout << "failed to open a file <" << input.Data() << ">\n";
  assert(ifs.is_open());
  string line;
  Int_t state=0;
  const int inputFileMayContainEScaleDefinition = 1;
  int expectEscaleLine=1;
  ElectronEnergyScale escale((inputFileMayContainEScaleDefinition) ? 
	  ElectronEnergyScale::UNDEFINED : // read electron energy scale from the file
	  ElectronEnergyScale::Date20120101_default);
  while(getline(ifs,line)) {
    if(line[0]=='#') continue;
    if(state == 0){
      dirTag = TString(line);
      state++;
      continue;
    }else{
      if (inputFileMayContainEScaleDefinition && expectEscaleLine) {
	expectEscaleLine=0;
	// try to determine whether the input file was updated
	if (ElectronEnergyScale::DetermineCalibrationSet(line.c_str()) !=
	    ElectronEnergyScale::UNDEFINED) {
	  //std::cout << "got it ok: <" << line << ">" << std::endl;
	  escale.init(TString(line.c_str()));
	  if (!escale.isInitialized()) {
	    std::cout << "code error\n";
	    return;
	  }
	  // continue reading the file
	  getline(ifs,line);
	}
	else {
	  std::cout << "\n";
	  std::cout << "\n\tInput file does not contain electron energy scale. The expected file format:\n";
	  std::cout << "\tLine1: directory\n";
	  std::cout << "\tLine2: electron energy scale correction name (NEW from 2012 Jan 21)\n";
	  std::cout << "\tLine3: file_name.root xsect color linesty label\n";
	  std::cout << "using the default set\n\n";
	  escale.init("Date20120101_default");
	  if (!escale.isInitialized()) {
	    std::cout << "failed to correct the behavior\n";
	    return;
	  }
	}
	std::cout << "energy scale corrections: " << escale.calibrationSetName() << "\n";
      }
      string fname;
      Int_t color, linesty;
      stringstream ss(line);
      Double_t xsec;
      ss >> fname >> xsec >> color >> linesty;
      string label = line.substr(line.find('@')+1);
      fnamev.push_back(fname);
      labelv.push_back(label);
      colorv.push_back(color);
      linev.push_back(linesty);
      xsecv.push_back(xsec);
      lumiv.push_back(0);
    }
  }
  ifs.close();
  
  const Double_t kGAP_LOW  = 1.4442;
  const Double_t kGAP_HIGH = 1.566;


  //--------------------------------------------------------------------------------------------------------------
  // Main analysis code 
  //==============================================================================================================


  TRandom random;
  // The random seeds are needed only if we are running this script in systematics mode
  int seed = randomSeed;
  random.SetSeed(seed);
  gRandom->SetSeed(seed);
  // In the case of systematic studies, generate an array of random offsets
  TVectorD shift(escale._nEtaBins); // this vector is outdated by the new features in the escale obj.class
  shift = 0;
  if(systematicsMode==DYTools::RESOLUTION_STUDY) {
    escale.randomizeSmearingWidth(seed);
    for(int i=0; i<escale._nEtaBins; i++)
      shift[i] = gRandom->Gaus(0,1);
  }

  // prepare tools for ESCALE_RESIDUAL
  TH1F *shapeWeights=NULL;
  if (systematicsMode==DYTools::ESCALE_RESIDUAL) {
    TString shapeFName=TString("../root_files/yields/") + dirTag + TString("/shape_weights.root");
    std::cout << "Obtaining shape_weights.root from <" << shapeFName << ">\n";
    TFile fshape(shapeFName);
    if (!fshape.IsOpen()) {
      std::cout << "failed to open a file <" << shapeFName << ">\n";
      throw 2;
    }
    shapeWeights = (TH1F*)fshape.Get("weights");
    shapeWeights->SetDirectory(0);
    dirTag += TString("_escale_residual");
    std::cout << "changing dirTag to <" << dirTag << ">\n";
  }

  //  
  // Set up histograms
  //
  vector<TH1F*> hZMassv;//, hZMass2v, hZPtv, hZPt2v, hZyv, hZPhiv;  
  
  char hname[100];
  for(UInt_t ifile = 0; ifile<fnamev.size(); ifile++) {
    sprintf(hname,"hZMass_%i",ifile); hZMassv.push_back(new TH1F(hname,"",500,0,1500)); hZMassv[ifile]->Sumw2();
  }

  TH1F *hMassDiff   = new TH1F("hMassDiff","", 100, -30, 30);
  TH1F *hMassDiffBB = new TH1F("hMassDiffBB","", 100, -30, 30);
  TH1F *hMassDiffEB = new TH1F("hMassDiffEB","", 100, -30, 30);
  TH1F *hMassDiffEE = new TH1F("hMassDiffEE","", 100, -30, 30);

  TH1F *hMassDiffV[DYTools::nMassBins];
  for(int i=0; i<DYTools::nMassBins; i++){
    sprintf(hname,"hMassDiffV_%d",i);
    hMassDiffV[i] = new TH1F(hname,"",100,-50,50);
  }

  // MC spectra for storage in ROOT file
  // The FSR of RECO means that this is the spectrum of generator-level
  // post-FSR mass for events that were actually reconstructed (i.e. includes
  // efficiency and acceptances losses)
  TVectorD yieldsMcFsrOfRec    (DYTools::nMassBins);
  TVectorD yieldsMcFsrOfRecErr (DYTools::nMassBins);
  TVectorD yieldsMcRec         (DYTools::nMassBins);
  TVectorD yieldsMcRecErr      (DYTools::nMassBins);
  yieldsMcFsrOfRec     = 0;
  yieldsMcFsrOfRecErr  = 0;
  yieldsMcRec          = 0;
  yieldsMcRecErr       = 0;
  // The yields at generator level with mass bins defined by post-FSR di-leptons
  TVectorD yieldsMcFsr    (DYTools::nMassBins);
  yieldsMcFsr          = 0;

  // Vectors for bin to bin corrections
  TVectorD DetCorrFactorNumerator  (DYTools::nMassBins);
  TVectorD DetCorrFactorDenominator(DYTools::nMassBins);
  TVectorD DetCorrFactor           (DYTools::nMassBins);
  TVectorD DetCorrFactorErrPos     (DYTools::nMassBins);
  TVectorD DetCorrFactorErrNeg     (DYTools::nMassBins);
  DetCorrFactorNumerator   = 0;
  DetCorrFactorDenominator = 0;
  DetCorrFactor            = 0;
  DetCorrFactorErrPos      = 0;
  DetCorrFactorErrNeg      = 0;
  
  // Matrices for unfolding
  TMatrixD DetMigration(DYTools::nMassBins, DYTools::nMassBins);
  TMatrixD DetResponse(DYTools::nMassBins, DYTools::nMassBins);
  TMatrixD DetResponseErrPos(DYTools::nMassBins, DYTools::nMassBins);
  TMatrixD DetResponseErrNeg(DYTools::nMassBins, DYTools::nMassBins);
  for(int i=0; i<DYTools::nMassBins; i++){
    for(int j=0; j<DYTools::nMassBins; j++){
      DetMigration(i,j) = 0;
      DetResponse(i,j) = 0;
      DetResponseErrPos(i,j) = 0;
      DetResponseErrNeg(i,j) = 0;
    }
  }

  //
  // Access samples and fill histograms
  //  
  TFile *infile=0;
  TTree *eventTree=0;  
    
  // Data structures to store info from TTrees
  mithep::TEventInfo    *info = new mithep::TEventInfo();
  mithep::TGenInfo *gen  = new mithep::TGenInfo();
  TClonesArray *dielectronArr = new TClonesArray("mithep::TDielectron");
  
  // loop over samples  
  for(UInt_t ifile=0; ifile<fnamev.size(); ifile++) {
  
    // Read input file
    cout << "Processing " << fnamev[ifile] << "..." << endl;
    infile = new TFile(fnamev[ifile]); 
    assert(infile);

    // Get the TTrees
    eventTree = (TTree*)infile->Get("Events"); assert(eventTree);

    // Find weight for events for this file
    // The first file in the list comes with weight 1,
    // all subsequent ones are normalized to xsection and luminosity
    double xsec=xsecv[ifile];
    AdjustXSectionForSkim(infile,xsec,eventTree->GetEntries(),1);
    lumiv[ifile] = eventTree->GetEntries()/xsec;
    double scale = lumiv[0]/lumiv[ifile];
    cout << "       -> sample weight is " << scale << endl;

    // Set branch address to structures that will store the info  
    eventTree->SetBranchAddress("Info",&info);                TBranch *infoBr       = eventTree->GetBranch("Info");
    eventTree->SetBranchAddress("Gen",&gen);                  TBranch *genBr = eventTree->GetBranch("Gen");
    eventTree->SetBranchAddress("Dielectron",&dielectronArr); TBranch *dielectronBr = eventTree->GetBranch("Dielectron");
  
    // loop over events    
    for(UInt_t ientry=0; ientry<eventTree->GetEntries(); ientry++) {
      //if (ientry>100000) break;

      genBr->GetEntry(ientry);
      infoBr->GetEntry(ientry);

      double reweight;
      if (systematicsMode!=DYTools::FSR_STUDY) reweight=1.0;
      else if (((gen->mass)-(gen->vmass))>massLimit) reweight=1.0;
      else reweight=reweightFsr;

      if (ientry<20) std::cout<<"reweight="<<reweight<<std::endl;


      // Use post-FSR generator level mass in unfolding
      int ibinFsr = DYTools::findMassBin(gen->mass);
      if(ibinFsr != -1 && ibinFsr < yieldsMcFsr.GetNoElements()){
         yieldsMcFsr[ibinFsr] += reweight * scale * gen->weight;
      }


      /*
      // For EPS2011 for both data and MC (starting from Summer11 production)
      // we use an OR of the twi triggers below. Both are unpresecaled.
      ULong_t eventTriggerBit = kHLT_Ele17_CaloIdL_CaloIsoVL_Ele8_CaloIdL_CaloIsoVL 
	| kHLT_Ele17_CaloIdT_TrkIdVL_CaloIsoVL_TrkIsoVL_Ele8_CaloIdT_TrkIdVL_CaloIsoVL_TrkIsoVL;
      ULong_t leadingTriggerObjectBit = kHLT_Ele17_CaloIdL_CaloIsoVL_Ele8_CaloIdL_CaloIsoVL_Ele1Obj
	| kHLT_Ele17_CaloIdT_TrkIdVL_CaloIsoVL_TrkIsoVL_Ele8_CaloIdT_TrkIdVL_CaloIsoVL_TrkIsoVL_Ele1Obj;
      ULong_t trailingTriggerObjectBit = kHLT_Ele17_CaloIdL_CaloIsoVL_Ele8_CaloIdL_CaloIsoVL_Ele2Obj
	| kHLT_Ele17_CaloIdT_TrkIdVL_CaloIsoVL_TrkIsoVL_Ele8_CaloIdT_TrkIdVL_CaloIsoVL_TrkIsoVL_Ele2Obj;
      */

      const bool isData=kFALSE;
      TriggerConstantSet constantsSet = Full2011DatasetTriggers; // Enum from TriggerSelection.hh
      TriggerSelection requiredTriggers(constantsSet, isData, info->runNum);
      ULong_t eventTriggerBit = requiredTriggers.getEventTriggerBit(info->runNum);
      ULong_t leadingTriggerObjectBit = requiredTriggers.getLeadingTriggerObjectBit(info->runNum);
      ULong_t trailingTriggerObjectBit = requiredTriggers.getTrailingTriggerObjectBit(info->runNum);

      
      if(!(info->triggerBits & eventTriggerBit)) continue;  // no trigger accept? Skip to next event...                                   

      // loop through dielectrons
      dielectronArr->Clear();
      dielectronBr->GetEntry(ientry);    
      for(Int_t i=0; i<dielectronArr->GetEntriesFast(); i++) {

        const mithep::TDielectron *dielectron = (mithep::TDielectron*)((*dielectronArr)[i]);
	
	// Apply selection
	// Eta cuts
        if((fabs(dielectron->scEta_1)>kGAP_LOW) && (fabs(dielectron->scEta_1)<kGAP_HIGH)) continue;
        if((fabs(dielectron->scEta_2)>kGAP_LOW) && (fabs(dielectron->scEta_2)<kGAP_HIGH)) continue;
	if((fabs(dielectron->scEta_1) > 2.5)       || (fabs(dielectron->scEta_2) > 2.5))       continue;  // outside eta range? Skip to next event...
	
	// Asymmetric SC Et cuts
	if( ! ( ( dielectron->scEt_1 > DYTools::etMinLead  && dielectron->scEt_2 > DYTools::etMinTrail)
		|| ( dielectron->scEt_1 > DYTools::etMinTrail  && dielectron->scEt_2 > DYTools::etMinLead) )) continue;
    	
	// Both electrons must match trigger objects. At least one ordering
	// must match
	if( ! ( 
	       (dielectron->hltMatchBits_1 & leadingTriggerObjectBit && 
		dielectron->hltMatchBits_2 & trailingTriggerObjectBit )
	       ||
	       (dielectron->hltMatchBits_1 & trailingTriggerObjectBit && 
		dielectron->hltMatchBits_2 & leadingTriggerObjectBit ) ) ) continue;
	
	// The Smurf electron ID package is the same as used in HWW analysis
	// and contains cuts like VBTF WP80 for pt>20, VBTF WP70 for pt<10
	// with some customization, plus impact parameter cuts dz and dxy
	if(!passSmurf(dielectron)) continue;  

        // We have a Z candidate! HURRAY! 

	// Apply extra smearing to MC reconstructed dielectron mass
	// to better resemble the data
	/*
	  outdated lines. kept for reference
	double smear1 = escale.extraSmearingSigma(dielectron->scEta_1);
        double smear2 = escale::extraSmearingSigma(dielectron->scEta_2);
	// In systematics mode, overwrite the smear values with
	// shifted ones.
	if(systematicsMode==DYTools::RESOLUTION_STUDY){
	  smear1 = escale::extraSmearingSigmaShifted(dielectron->scEta_1,shift);
	  smear2 = escale::extraSmearingSigmaShifted(dielectron->scEta_2,shift);
	}
        double smearTotal = sqrt(smear1*smear1 + smear2*smear2);
        double massResmeared = dielectron->mass + random.Gaus(0.0,smearTotal);
	*/
	/* lines based on new features -- begin */
	double massSmear = (systematicsMode == DYTools::RESOLUTION_STUDY) ?
	  escale.generateMCSmearRandomized(dielectron->scEta_1,dielectron->scEta_2) :
	  escale.generateMCSmear(dielectron->scEta_1,dielectron->scEta_2);
        double massResmeared = dielectron->mass + massSmear;
	/* lines based on new features -- end */

	hZMassv[ifile]->Fill(massResmeared,scale * gen->weight);

	// Fill structures for response matrix and bin by bin corrections

	if(ibinFsr != -1 && ibinFsr < yieldsMcFsrOfRec.GetNoElements()){
	    yieldsMcFsrOfRec[ibinFsr] += reweight * scale * gen->weight;
	    DetCorrFactorDenominator(ibinFsr) += reweight * scale * gen->weight;
          }

	else if(ibinFsr >= yieldsMcFsrOfRec.GetNoElements())
	  cout << "ERROR: binning problem" << endl;

	int ibinRec = DYTools::findMassBin(massResmeared);
	double shape_weight = (shapeWeights && (ibinRec!=-1)) ? 
	  shapeWeights->GetBinContent(ibinRec+1) : 1.0;
	if(ibinRec != -1 && ibinRec < yieldsMcRec.GetNoElements()){
	    yieldsMcRec[ibinRec] += reweight * scale * gen->weight;
	    DetCorrFactorNumerator(ibinRec) += reweight * scale * gen->weight * shape_weight;
          }

	else if(ibinRec >= yieldsMcRec.GetNoElements())
	  cout << "ERROR: binning problem" << endl;
	
	if( ibinRec != -1 && ibinRec < yieldsMcRec.GetNoElements() 
	    && ibinFsr != -1 && ibinFsr < yieldsMcRec.GetNoElements() ){
          DetMigration(ibinFsr,ibinRec) += reweight * scale * gen->weight * shape_weight;
	}
	
        Bool_t isB1 = (fabs(dielectron->scEta_1)<kGAP_LOW);
        Bool_t isB2 = (fabs(dielectron->scEta_2)<kGAP_LOW);         
	hMassDiff->Fill(massResmeared - gen->mass);
	if( isB1 && isB2 )
	  hMassDiffBB->Fill(massResmeared - gen->mass);
	if( (isB1 && !isB2) || (!isB1 && isB2) )
	  hMassDiffEB->Fill(massResmeared - gen->mass);
	if( !isB1 && !isB2 )
	  hMassDiffEE->Fill(massResmeared - gen->mass);
	
	if(ibinFsr != -1){
	  hMassDiffV[ibinFsr]->Fill(massResmeared - gen->mass);
	}
// 	if(ibinRec == -1)
// 	  printf("Missed bin:  M_fsr=%f   M_reco=%f\n", gen->mass, massResmeared);
	
      } // end loop over dielectrons

    } // end loop over events 
    delete infile;
    infile=0, eventTree=0;
  } // end loop over files
  delete gen;


  //finish reweighting of mass spectra

  
  // Find bin by bin corrections and the errors
  double tCentral, tErrNeg, tErrPos;
  for(int i=0; i<DYTools::nMassBins; i++){
    if ( DetCorrFactorDenominator(i) != 0 ){
      // This method does not take into account correlation between numerator
      // and denominator in calculation of errors. This is a flaw to be corrected
      // in the future.
      SimpleDivide( DetCorrFactorNumerator(i), DetCorrFactorDenominator(i), tCentral, tErrNeg, tErrPos);
      DetCorrFactor(i) = tCentral;
      DetCorrFactorErrPos(i) = tErrPos;
      DetCorrFactorErrNeg(i) = tErrNeg;
    } else {
      DetCorrFactor(i) = 0;
      DetCorrFactorErrPos(i) = 0;
      DetCorrFactorErrNeg(i) = 0;
    }
  }
  
  // Find response matrix, which is simply the normalized migration matrix
  for(int ifsr = 0; ifsr < DetMigration.GetNrows(); ifsr++){
    double nEventsInFsrMassBin = 0;
    for(int ireco = 0; ireco < DetMigration.GetNcols(); ireco++)
      nEventsInFsrMassBin += DetMigration(ifsr,ireco);
    // Now normalize each element and find errors
    for(int ireco = 0; ireco < DetMigration.GetNcols(); ireco++){
      tCentral = 0;
      tErrPos  = 0;
      tErrNeg  = 0;
      // Note: the event counts supposedly are dominated with events with weight "1"
      // coming from the primary MC sample, so the error is assumed Poissonian in
      // the call for efficiency-calculating function below.
      if( nEventsInFsrMassBin != 0 ){
	EfficiencyDivide(DetMigration(ifsr,ireco), nEventsInFsrMassBin, tCentral, tErrNeg, tErrPos);
      // BayesEfficiency does not seem to be working in newer ROOT versions, 
      // so it is replaced by simler method
//         BayesEfficiency( DetMigration(ifsr,ireco), nEventsInFsrMassBin, tCentral, tErrNeg, tErrPos);
      }
      DetResponse      (ifsr,ireco) = tCentral;
      DetResponseErrPos(ifsr,ireco) = tErrPos;
      DetResponseErrNeg(ifsr,ireco) = tErrNeg;
    }
  }

  // Find inverted response matrix
  TMatrixD DetInvertedResponse = DetResponse;
  Double_t det;
  DetInvertedResponse.Invert(&det);
  TMatrixD DetInvertedResponseErr(DetInvertedResponse.GetNrows(), DetInvertedResponse.GetNcols());
  calculateInvertedMatrixErrors(DetResponse, DetResponseErrPos, DetResponseErrNeg, DetInvertedResponseErr);

  // Package bin limits into TVectorD for storing in a file
  TVectorD BinLimitsArray(DYTools::nMassBins+1);
  for(int i=0; i<DYTools::nMassBins+1; i++)
    BinLimitsArray(i) = DYTools::massBinLimits[i];

  // Store constants in the file
  TString outputDir(TString("../root_files/constants/")+dirTag);
  if((systematicsMode==DYTools::RESOLUTION_STUDY) || (systematicsMode==DYTools::FSR_STUDY))
    outputDir = TString("../root_files/systematics/")+dirTag;
  gSystem->mkdir(outputDir,kTRUE);
  TString unfoldingConstFileName(outputDir+TString("/unfolding_constants.root"));
  if(systematicsMode==DYTools::RESOLUTION_STUDY){
    unfoldingConstFileName = outputDir+TString("/unfolding_constants_seed_");
    unfoldingConstFileName += seed;
    unfoldingConstFileName += ".root";
  }
  if(systematicsMode==DYTools::FSR_STUDY){
    unfoldingConstFileName = outputDir+TString("/unfolding_constants_reweight_");
    unfoldingConstFileName += int(100*reweightFsr);
    unfoldingConstFileName += ".root";
  }

  TFile fConst(unfoldingConstFileName, "recreate" );
  DetResponse             .Write("DetResponse");
  DetInvertedResponse     .Write("DetInvertedResponse");
  DetInvertedResponseErr  .Write("DetInvertedResponseErr");
  BinLimitsArray          .Write("BinLimitsArray");
  DetCorrFactor           .Write("DetCorrFactor");
  DetCorrFactorErrPos     .Write("DetCorrFactorErrPos");
  DetCorrFactorErrNeg     .Write("DetCorrFactorErrNeg");
  fConst.Close();
  
  // Store reference MC arrays in a file
  TString refFileName(outputDir+TString("/yields_MC_unfolding_reference.root"));
  TFile fRef(refFileName, "recreate" );
  BinLimitsArray    .Write("BinLimitsArray");
  yieldsMcFsr       .Write("yieldsMcFsr");
  yieldsMcFsrOfRec  .Write("yieldsMcFsrOfRec");
  yieldsMcRec       .Write("yieldsMcRec");
  fRef.Close();


  //--------------------------------------------------------------------------------------------------------------
  // Make plots 
  //==============================================================================================================  

  std::vector<TCanvas*> canvasV; // holder for a quick saver
  canvasV.reserve(10);

  TCanvas *c = MakeCanvas("zMass1","zMass1",800,600);
  canvasV.push_back(c);

  // string buffers
  char ylabel[50];   // y-axis label

  // Z mass
  sprintf(ylabel,"a.u. / %.1f GeV/c^{2}",hZMassv[0]->GetBinWidth(1));
  CPlot plotZMass1("zmass1","","m(ee) [GeV/c^{2}]",ylabel);
  if (fnamev.size()) hZMassv[0]->GetXaxis()->SetLimits(10.,2000.);
  for(UInt_t i=0; i<fnamev.size(); i++) { 
    plotZMass1.AddHist1D(hZMassv[i],labelv[i],"hist",colorv[i],linev[i]); 
  }
  plotZMass1.SetLogy();
  plotZMass1.SetLogx(); 
  plotZMass1.TransLegend(0.02, 0.0);
  plotZMass1.Draw(c,doSave,format);

  // Create plots of how reco mass looks and how unfolded mass should look like
  TVectorD massBinCentral     (DYTools::nMassBins);
  TVectorD massBinHalfWidth   (DYTools::nMassBins);
  TVectorD yieldMcFsrOfRecErr (DYTools::nMassBins);
  TVectorD yieldMcRecErr      (DYTools::nMassBins);
  for(int i=0; i < DYTools::nMassBins; i++){
    massBinCentral  (i) = (DYTools::massBinLimits[i+1] + DYTools::massBinLimits[i])/2.0;
    massBinHalfWidth(i) = (DYTools::massBinLimits[i+1] - DYTools::massBinLimits[i])/2.0;
    yieldsMcFsrOfRecErr(i) = sqrt(yieldsMcFsrOfRec[i]);
    yieldsMcRecErr     (i) = sqrt(yieldsMcRec[i]);
  }
  TGraphErrors *grFsrOfRec = new TGraphErrors(massBinCentral, yieldsMcFsrOfRec, 
					      massBinHalfWidth, yieldsMcFsrOfRecErr);
  TGraphErrors *grRec      = new TGraphErrors(massBinCentral, yieldsMcRec, 
					      massBinHalfWidth, yieldsMcRecErr);
  TCanvas *d = MakeCanvas("zMass2","zMass2",800,600);
  canvasV.push_back(d);
  CPlot plotZMass2("zmass2","","m(ee) [GeV/c^{2}]","events");
  plotZMass2.SetLogx(1);
  plotZMass2.AddGraph(grFsrOfRec,"no detector effects","PE",kBlack);
  plotZMass2.AddGraph(grRec,"reconstructed","PE",kBlue);
  plotZMass2.Draw(d);

//   double xsize = 600;
//   double ysize = 600;
  int xsize = 600;
  int ysize = 400;

  // Create the plot of the response matrix
  TH2F *hResponse = new TH2F("hResponse","",DYTools::nMassBins, DYTools::massBinLimits,
			     DYTools::nMassBins, DYTools::massBinLimits);
  for(int i=1; i<=DYTools::nMassBins; i++)
    for(int j=1; j<=DYTools::nMassBins; j++)
      hResponse->SetBinContent(i,j,DetResponse(i-1,j-1));
  TCanvas *e = MakeCanvas("response","response",xsize,ysize);
  canvasV.push_back(e);
  CPlot plotResponse("response","",
		     "generator post-FSR m(ee) [GeV/c^{2}]",
		     "reconstructed  m(ee) [GeV/c^{2}]");
  plotResponse.AddHist2D(hResponse,"COLZ");
  e->cd();
  plotResponse.SetLogx();
  plotResponse.SetLogy();
  gPad->SetRightMargin(0.15);
  gStyle->SetPalette(1);
  hResponse->GetXaxis()->SetMoreLogLabels();
  hResponse->GetXaxis()->SetNoExponent();
  hResponse->GetYaxis()->SetNoExponent();
  plotResponse.Draw(e);

  // Create the plot of the inverted response matrix
  TH2F *hInvResponse = new TH2F("hInvResponse","",DYTools::nMassBins, DYTools::massBinLimits,
			     DYTools::nMassBins, DYTools::massBinLimits);
  for(int i=1; i<=DYTools::nMassBins; i++)
    for(int j=1; j<=DYTools::nMassBins; j++)
      hInvResponse->SetBinContent(i,j,DetInvertedResponse(i-1,j-1));
  TCanvas *f = MakeCanvas("invResponse","invResponse",xsize,ysize);
  canvasV.push_back(f);
  CPlot plotInvResponse("inverted response","",
			"reconstructed  m(ee) [GeV/c^{2}]",
			"generator post-FSR m(ee) [GeV/c^{2}]");
  plotInvResponse.AddHist2D(hInvResponse,"COLZ");
  f->cd();
  plotInvResponse.SetLogx();
  plotInvResponse.SetLogy();
  gPad->SetRightMargin(0.15);
  gStyle->SetPalette(1);
  hInvResponse->GetXaxis()->SetMoreLogLabels();
  hInvResponse->GetXaxis()->SetNoExponent();
  hInvResponse->GetYaxis()->SetNoExponent();
  plotInvResponse.Draw(f);

  // Create a plot of detector resolution without mass binning
  TCanvas *g = MakeCanvas("massDiff","massDiff",600,600);
  canvasV.push_back(g);
  CPlot plotMassDiff("massDiff","","reco mass - gen post-FSR mass [GeV/c^{2}]","a.u.");
  hMassDiffBB->Scale(1.0/hMassDiffBB->GetSumOfWeights());
  hMassDiffEB->Scale(1.0/hMassDiffEB->GetSumOfWeights());
  hMassDiffEE->Scale(1.0/hMassDiffEE->GetSumOfWeights());
  plotMassDiff.AddHist1D(hMassDiffBB,"EB-EB","hist",kBlack);
  plotMassDiff.AddHist1D(hMassDiffEB,"EE-EB","hist",kBlue);
  plotMassDiff.AddHist1D(hMassDiffEE,"EE-EE","hist",kRed);
  plotMassDiff.TransLegend(0.1, 0.0);
  plotMassDiff.Draw(g);



  // Create a plot of reco - gen post-FSR mass difference for several mass bins
  TCanvas *h = MakeCanvas("massDiffV","massDiffV",600,600);
  canvasV.push_back(h);
  CPlot plotMassDiffV("massDiffV","","reco mass - gen post-FSR mass [GeV/c^{2}]","a.u.");
  hMassDiffV[7]->Scale(1.0/hMassDiffV[7]->GetSumOfWeights());
  hMassDiffV[6]->Scale(1.0/hMassDiffV[6]->GetSumOfWeights());
  hMassDiffV[5]->Scale(1.0/hMassDiffV[5]->GetSumOfWeights());
  hMassDiffV[4]->Scale(1.0/hMassDiffV[4]->GetSumOfWeights());
  plotMassDiffV.AddHist1D(hMassDiffV[4],"50-60 GeV/c^{2}","hist",kBlack);
  plotMassDiffV.AddHist1D(hMassDiffV[5],"60-76 GeV/c^{2}","hist",kBlue);
  plotMassDiffV.AddHist1D(hMassDiffV[6],"76-86 GeV/c^{2}","hist",kRed);
  plotMassDiffV.AddHist1D(hMassDiffV[7],"86-96 GeV/c^{2}","hist",kMagenta);
  plotMassDiffV.SetXRange(-20,50);
  plotMassDiffV.Draw(h);

  // Create graph of bin-to-bin corrections
  TGraphAsymmErrors *grCorrFactor 
    = new TGraphAsymmErrors(massBinCentral, DetCorrFactor,
			    massBinHalfWidth, massBinHalfWidth,
			    DetCorrFactorErrNeg, DetCorrFactorErrPos);
  TCanvas *c11 = MakeCanvas("corrFactor","corrFactor",800,600);
  canvasV.push_back(c11);
  CPlot plotCorrFactor("corrFactor","","m(ee) [GeV/c^{2}]","correction factor");
  plotCorrFactor.AddGraph(grCorrFactor,"PE",kBlue);
  plotCorrFactor.SetLogx();
  plotCorrFactor.SetYRange(0,2.0);
  plotCorrFactor.Draw(c11);

  if (saveMadePlots) {
    TString plotPath=TString("../root_files/plots/") + dirTag; 
    TString name=plotPath + TString("/unfolding_plots.root");
    gSystem->mkdir(plotPath,true);
    TFile* fplots = TFile::Open(name,"RECREATE");
    for (unsigned int i=0; i<canvasV.size(); ++i) {
      canvasV[i]->Write();
    }
    fplots->Close();
  }

  //--------------------------------------------------------------------------------------------------------------
  // Summary print out
  //==============================================================================================================
  cout << endl;
  cout << "*" << endl;
  cout << "* SUMMARY" << endl;
  cout << "*--------------------------------------------------" << endl;
  cout << endl; 
  
  // Printout of all constants, uncomment if needed

  //printf("DetMigration:\n"); DetMigration.Print();
  //printf("DetResponse:\n"); DetResponse.Print();
  //printf("DetInvertedResponse:\n"); DetInvertedResponse.Print();

//   DetCorrFactor.Print();
//   DetResponse.Print();
  
//   printf("Detector corr factor numerator:\n");
//   DetCorrFactorNumerator.Print();
//   printf("yieldsMcRec:\n");
//   yieldsMcRec.Print();

//   printf("Detector corr factor denominator:\n");
//   DetCorrFactorDenominator.Print();
//   printf("yieldsMcFsrOfRec:\n");
//   yieldsMcFsrOfRec.Print();

  gBenchmark->Show("plotDYUnfoldingMatrix");
}
Exemple #20
0
void Renderer::Render()
{
    Preprocess();

    // --------------------------------------------------------------------------------

    // Create threads
    std::vector<std::thread> threads;

    for (int i = 0; i < commonConfig->numThreads; i++)
    {
        auto param = Create_Thread_InitParam(i);
        param->id = i;
        threads.push_back(std::thread(&Renderer::ProcessThread, this, param));
    }

    // --------------------------------------------------------------------------------

    // Timestamp
    auto start = std::chrono::high_resolution_clock::now();
    auto time = std::chrono::high_resolution_clock::to_time_t(start);
    double nextImageSaveTime = commonConfig->imageSaveIntervalTime;
    int totalImageSaves = 0;

    std::string timeStamp;
    std::stringstream ss;

#ifdef HINATA_PLATFORM_WINDOWS
    struct tm timeinfo;
    localtime_s(&timeinfo, &time);
    ss << std::put_time(&timeinfo, "%Y.%m.%d.%H.%M.%S");
#else
    ss << std::put_time(std::localtime(&time), "%Y.%m.%d.%H.%M.%S");
#endif

    timeStamp = ss.str();

    // --------------------------------------------------------------------------------

    // Render loop
    int pass = 0;
    double elapsed = 0;

    while (elapsed < commonConfig->executionTime)
    {
        if (!commonConfig->quiet)
            std::cerr << "Pass #" << pass << std::endl;

        // --------------------------------------------------------------------------------

        // Dispatch render tasks
        finishedTasks = 0;

        // Enqueue tasks
        for (int y = 0; y < commonConfig->numRenderTasks; y++)
        {
            Task task;
            task.command = Command::Render;
            task.needSync = false;
            queue.Enqueue(task);
        }

        // Wait for tasks
        {
            std::unique_lock<std::mutex> lock(taskFinishedMutex);

            taskFinished.wait(lock,
            [this] {
                // Print progress
                if (!commonConfig->quiet)
                {
                    std::cerr <<
                    (boost::format("\r  Progress : %.2lf %%")
                    % ((double)finishedTasks / commonConfig->numRenderTasks * 100.0)).str();
                }
                return finishedTasks == commonConfig->numRenderTasks;
            });

            if (!commonConfig->quiet)
                std::cerr << std::endl;
        }

        // --------------------------------------------------------------------------------

        // Gather image buffers
        finishedTasks = 0;

        for (int i = 0; i < commonConfig->numThreads; i++)
        {
            Task task;
            task.command = Command::UpdateImage;
            task.needSync = true;
            queue.Enqueue(task);
        }

        {
            std::unique_lock<std::mutex> lock(taskFinishedMutex);
            taskFinished.wait(lock, [this] { return finishedTasks == commonConfig->numThreads; });
        }

        // --------------------------------------------------------------------------------

        // Print elapsed time
        auto now = std::chrono::high_resolution_clock::now();
        elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - start).count() / 1000.0;

        if (!commonConfig->quiet)
        {
            std::cerr << (boost::format("  Elapsed time : %.2lf seconds") % elapsed).str() << std::endl;
        }

        // --------------------------------------------------------------------------------

        pass++;
        RenderPassFinished();

        // Save image
        if (elapsed > nextImageSaveTime - Eps)
        {
            namespace fs = boost::filesystem;

            totalImageSaves++;
            nextImageSaveTime += commonConfig->imageSaveIntervalTime;

            fs::path outputDir(commonConfig->outputDir);

            if (!fs::exists(outputDir))
            {
                fs::create_directories(outputDir);
            }

            auto prefix =
                commonConfig->outputFilePrefix == ""
                ? commonConfig->appName + "-" + timeStamp
                : commonConfig->outputFilePrefix;

            auto suffix =
                commonConfig->disableOutputFileSuffix
                ? ""
                : "-" + (boost::format("%d-%.2lf") % totalImageSaves % elapsed).str();

            auto fileName = prefix + suffix + ".ppm";
            auto path = outputDir / fileName;

            if (!commonConfig->quiet)
            {
                std::cerr << "  Saving image : " << path << std::endl;
            }

            image->Save(path.string(), ImageSaveWeight());
            SaveImageFinished();
        }

        if (!commonConfig->quiet)
        {
            std::cerr << std::endl;
        }
    }

    // --------------------------------------------------------------------------------

    queue.SetDone();

    for (auto& thread : threads)
    {
        thread.join();
    }
}
Exemple #21
0
int main(int argc, const char *argv[]) {
   Global::setLogger(new LoggerDefault(Logger::message));

   if(argc < 4) {
      std::cout << "Creates a location namelist by removing locations without data. Any location" << std::endl;
      std::cout << "with at least one valid data point will be kept. Unless specified otherwise," << std::endl;
      std::cout << "data for all offsets, variables, and members are checked." << std::endl;
      std::cout << std::endl;
      std::cout << "usage: namelist.exe dataset outputDir startDate [endDate] [-v variables] [--remove--locations]";
      std::cout << std::endl;
      std::cout << "Arguments:" << std::endl;
      std::cout << "   outputDir           Place new namelists here" << std::endl;
      std::cout << "   startDate           Start searching for data for this date (YYYYMMDD)" << std::endl;
      std::cout << "   endDate             End date for search" << std::endl;
      std::cout << "   variables           Only check for data for these variables" << std::endl;
      // std::cout << "   --remove-offsets    Tag of dataset from namelist" << std::endl;
      // std::cout << "   --remove-variables  Remove variabless without data" << std::endl;
      std::cout << "   --remove-locations  Remove locations with no data" << std::endl;

      return 0;
   }

   int startDate = Global::MV;
   int endDate   = Global::MV;

   std::string dataset(argv[1]);
   std::string outputDir(argv[2]);
   std::stringstream ss;
   ss << std::string(argv[3]);
   ss >> startDate;
   endDate = startDate;
   bool removeOffsets   = false;
   bool removeVariables = false;
   bool removeLocations = false;
   std::vector<std::string> keepVariables;

   for(int i = 4; i < argc; i++) {
      if(!std::strcmp(argv[i], "--remove-variabless")) {
         removeVariables = true;
      }
      else if(!std::strcmp(argv[i], "--remove-locations")) {
         removeLocations = true;
      }
      else if(!std::strcmp(argv[i], "-v")) {
         std::string keepVariablesString = argv[i+1];
         std::stringstream ss(keepVariablesString);
         Options opt("test="+keepVariablesString);
         opt.getValues("test", keepVariables);
         assert(argc > i+1);
         i++;
      }
      // else if(!std::strcmp(argv[i], "--remove-offsets")) {
      //    removeOffsets = true;
      //}
      else {
         std::stringstream ss;
         ss<< std::string(argv[i]);
         ss >> endDate;
      }
   }

   InputContainer inputContainer(Options(""));
   Input* input = inputContainer.getInput(dataset);

   std::vector<float> offsets = input->getOffsets();
   std::vector<std::string> variables = input->getVariables();
   std::vector<Location> locations = input->getLocations();
   std::vector<Member> members = input->getMembers();

   std::vector<int> numLocations(locations.size(), 0);
   std::vector<int> numVariables(variables.size(), 0);
   std::vector<int> numOffsets(offsets.size(), 0);

   if(keepVariables.size() > 0) {
      variables = keepVariables;
   }

   // Check that variables are valid

   for(int v = 0; v < variables.size(); v++) {
      if(!input->hasVariable(variables[v])) {
         Global::logger->write("Input does not contain variable: " + variables[v], Logger::warning);
      }
      else {
         int date = startDate;
         while(date <= endDate) {
            for(int i = 0; i < offsets.size(); i++) {
               for(int k = 0; k < locations.size(); k++) {
                  for(int m = 0; m < members.size(); m++) {
                     float value = input->getValue(date, 0, offsets[i], locations[k].getId(), members[m].getId(), variables[v]);
                     if(Global::isValid(value)) {
                        numLocations[k]++;
                        numVariables[v]++;
                        numOffsets[i]++;
                     }
                  }
               }
            }
            date = Global::getDate(date, 24);
         }
      }
   }

   // Write locations namelist
   std::string locationsFile = outputDir + "/" + "locations.nl";
   std::ofstream ofs(locationsFile.c_str(), std::ios_base::out);
   if(ofs) {
      for(int i = 0; i < locations.size(); i++) {
         if(numLocations[i] > 0) {
            ofs << locations[i].getNamelistLine() << std::endl;
         }
      }
      ofs.close();
   }
   else {
      Global::logger->write("Could not write file: " + locationsFile, Logger::error);
   }
}
Exemple #22
0
int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);
    int res = 0;
    QString appIni;
    QMap<QString, QString> args = convertArgs(QCoreApplication::arguments());

    if (!args.value("-f").isEmpty()) {
        appIni = args.value("-f");
        devIni = QFileInfo(appIni).dir().path() + QDir::separator() + "development.ini";
    } else {
        QString dir = QLatin1String("..") + QDir::separator() + QLatin1String("..") + QDir::separator() + "config" +  QDir::separator();
        appIni = dir + "application.ini";
        devIni = dir + "development.ini";
    }

    if (!QFile::exists(appIni)) {
        usage();
        return 1;
    }

    QSettings appSetting(appIni, QSettings::IniFormat);
    QSettings devSetting(devIni, QSettings::IniFormat);

    // Default codec
    QTextCodec *codec = QTextCodec::codecForName("UTF-8");
    QString codecName = appSetting.value("InternalEncoding").toString();
    if (!codecName.isEmpty()) {
        QTextCodec *c = QTextCodec::codecForName(codecName.toLatin1().constData());
        if (c) {
            codec = c;
        }
    }
    QTextCodec::setCodecForLocale(codec);

    defaultTrimMode = devSetting.value("Erb.DefaultTrimMode", "1").toInt();
    printf("Erb.DefaultTrimMode: %d\n", defaultTrimMode);

    QDir viewDir(".");
    if (!args.value("-v").isEmpty()) {
        viewDir.setPath(args.value("-v"));
    }
    if (!viewDir.exists()) {
        usage();
        return 1;
    }

    QDir outputDir(DEFAULT_OUTPUT_DIR);
    if (!args.value("-d").isEmpty()) {
        outputDir.setPath(args.value("-d"));
    }

    if (outputDir.exists()) {
        if (outputDir.path() != ".") {
            printf("  exists   %s\n", qPrintable(outputDir.path()));
        }
    } else {
        if (outputDir.mkpath(".")) {
            printf("  created  %s\n", qPrintable(outputDir.path()));
        } else {
            usage();
            return 1;
        }
    }

    bool createProFile = (args.contains("-p") || !args.contains("-P"));
    ViewConverter conv(viewDir, outputDir, createProFile);
    QString templateSystem = devSetting.value("TemplateSystem").toString();
    if (templateSystem.isEmpty()) {
        templateSystem = appSetting.value("TemplateSystem", "Erb").toString();
    }

    res = conv.convertView(templateSystem);
    return res;
}  
Exemple #23
0
void plotDYEfficiency(const TString input) 
{
  gBenchmark->Start("plotDYEfficiency");

  //--------------------------------------------------------------------------------------------------------------
  // Settings 
  //==============================================================================================================
  
  Bool_t doSave  = false;    // save plots?
  TString format = "png";   // output file format
  
  vector<TString> fnamev;   // file names   
  vector<TString> labelv;   // legend label
  vector<Int_t>   colorv;   // color in plots
  vector<Int_t>   linev;    // line style
  vector<Double_t> xsecv;
  vector<Double_t> lumiv;
  TString          dirTag;

  ifstream ifs;
  ifs.open(input.Data());
  assert(ifs.is_open());
  string line;
  Int_t state=0;
  while(getline(ifs,line)) {
    if(line[0]=='#') continue;
    if(state == 0){
      dirTag = TString(line);
      state++;
      continue;
    }else{
      string fname;
      Int_t color, linesty;
      stringstream ss(line);
      Double_t xsec;
      ss >> fname >> xsec >> color >> linesty;
      string label = line.substr(line.find('@')+1);
      fnamev.push_back(fname);
      labelv.push_back(label);
      colorv.push_back(color);
      linev.push_back(linesty);
      xsecv.push_back(xsec);
      lumiv.push_back(0);
    }
  }
  ifs.close();
  
  const Double_t kGAP_LOW  = 1.4442;
  const Double_t kGAP_HIGH = 1.566;


  //--------------------------------------------------------------------------------------------------------------
  // Main analysis code 
  //==============================================================================================================
  
  //  
  // Set up histograms
  //
  vector<TH1F*> hZMassv;//, hZMass2v, hZPtv, hZPt2v, hZyv, hZPhiv;  
  
  Double_t   nZv = 0;
  TVectorD nEventsv (DYTools::nMassBins);  
  TVectorD nPassv   (DYTools::nMassBins);
  TVectorD effv     (DYTools::nMassBins);
  TVectorD effErrv  (DYTools::nMassBins);

  TVectorD nEventsBBv (DYTools::nMassBins);  
  TVectorD nEventsBEv (DYTools::nMassBins);  
  TVectorD nEventsEEv (DYTools::nMassBins);  
  TVectorD nPassBBv(DYTools::nMassBins), effBBv(DYTools::nMassBins), effErrBBv(DYTools::nMassBins); 
  TVectorD nPassBEv(DYTools::nMassBins), effBEv(DYTools::nMassBins), effErrBEv(DYTools::nMassBins); 
  TVectorD nPassEEv(DYTools::nMassBins), effEEv(DYTools::nMassBins), effErrEEv(DYTools::nMassBins);

  TVectorD nEventsZPeakPU(DYTools::nPVBinCount), nPassZPeakPU(DYTools::nPVBinCount);
  TVectorD nEventsZPeakPURaw(100), nPassZPeakPURaw(100);
  TVectorD effZPeakPU(DYTools::nPVBinCount), effErrZPeakPU(DYTools::nPVBinCount);

  nEventsv   = 0;
  nEventsBBv = 0;
  nEventsBEv = 0;
  nEventsEEv = 0;
  nPassv   = 0;
  nPassBBv = 0;
  nPassBEv = 0;
  nPassEEv = 0;
    
  char hname[100];
  for(UInt_t ifile = 0; ifile<fnamev.size(); ifile++) {
    sprintf(hname,"hZMass_%i",ifile); hZMassv.push_back(new TH1F(hname,"",500,0,1500)); hZMassv[ifile]->Sumw2();
  }

  //
  // Access samples and fill histograms
  //  
  TFile *infile=0;
  TTree *eventTree=0;  
    
  // Data structures to store info from TTrees
  mithep::TEventInfo    *info = new mithep::TEventInfo();
  mithep::TGenInfo *gen  = new mithep::TGenInfo();
  TClonesArray *dielectronArr = new TClonesArray("mithep::TDielectron");
  TClonesArray *pvArr         = new TClonesArray("mithep::TVertex");
  
  // loop over samples  
  int countMismatch = 0;
  for(UInt_t ifile=0; ifile<fnamev.size(); ifile++) {
  
    // Read input file
    cout << "Processing " << fnamev[ifile] << "..." << endl;
    infile = new TFile(fnamev[ifile]); 
    assert(infile);

    // Get the TTrees
    eventTree = (TTree*)infile->Get("Events"); assert(eventTree);

    // Find weight for events for this file
    // The first file in the list comes with weight 1,
    // all subsequent ones are normalized to xsection and luminosity
    double xsec=xsecv[ifile];
    AdjustXSectionForSkim(infile,xsec,eventTree->GetEntries(),1);
    lumiv[ifile] = eventTree->GetEntries()/xsec;
    double scale = lumiv[0]/lumiv[ifile];
    cout << "       -> sample weight is " << scale << endl;

    // Set branch address to structures that will store the info  
    eventTree->SetBranchAddress("Info",&info);                TBranch *infoBr       = eventTree->GetBranch("Info");
    eventTree->SetBranchAddress("Gen",&gen);                  TBranch *genBr = eventTree->GetBranch("Gen");
    eventTree->SetBranchAddress("Dielectron",&dielectronArr); TBranch *dielectronBr = eventTree->GetBranch("Dielectron");
    eventTree->SetBranchAddress("PV", &pvArr);                TBranch *pvBr = eventTree->GetBranch("PV");
   
    // loop over events    
    nZv += scale * eventTree->GetEntries();
    for(UInt_t ientry=0; ientry<eventTree->GetEntries(); ientry++) {
      genBr->GetEntry(ientry);
      infoBr->GetEntry(ientry);

      /*
      // For EPS2011 for both data and MC (starting from Summer11 production)
      // we use an OR of the twi triggers below. Both are unpresecaled.
      ULong_t eventTriggerBit = kHLT_Ele17_CaloIdL_CaloIsoVL_Ele8_CaloIdL_CaloIsoVL 
	| kHLT_Ele17_CaloIdT_TrkIdVL_CaloIsoVL_TrkIsoVL_Ele8_CaloIdT_TrkIdVL_CaloIsoVL_TrkIsoVL;
      ULong_t leadingTriggerObjectBit = kHLT_Ele17_CaloIdL_CaloIsoVL_Ele8_CaloIdL_CaloIsoVL_Ele1Obj
	| kHLT_Ele17_CaloIdT_TrkIdVL_CaloIsoVL_TrkIsoVL_Ele8_CaloIdT_TrkIdVL_CaloIsoVL_TrkIsoVL_Ele1Obj;
      ULong_t trailingTriggerObjectBit = kHLT_Ele17_CaloIdL_CaloIsoVL_Ele8_CaloIdL_CaloIsoVL_Ele2Obj
	| kHLT_Ele17_CaloIdT_TrkIdVL_CaloIsoVL_TrkIsoVL_Ele8_CaloIdT_TrkIdVL_CaloIsoVL_TrkIsoVL_Ele2Obj;
      */
      
      const bool isData=kFALSE;
      TriggerConstantSet constantsSet = Full2011DatasetTriggers; // Enum from TriggerSelection.hh
      TriggerSelection requiredTriggers(constantsSet, isData, info->runNum);
      ULong_t eventTriggerBit = requiredTriggers.getEventTriggerBit(info->runNum);
      ULong_t leadingTriggerObjectBit = requiredTriggers.getLeadingTriggerObjectBit(info->runNum);
      ULong_t trailingTriggerObjectBit = requiredTriggers.getTrailingTriggerObjectBit(info->runNum);

      // The A_FSR starting point: gen level quantities
      // The FSR subscript means we work with post-FSR generator level quantities
      double et1 = gen->pt_1;
      double et2 = gen->pt_2;
      double eta1 = gen->eta_1;
      double eta2 = gen->eta_2;

      // Apply acceptance requirement
      if( ! ( ( et1 > DYTools::etMinLead  && et2 > DYTools::etMinTrail)
	      || ( et1 > DYTools::etMinTrail  && et2 > DYTools::etMinLead) )) continue;
      if((fabs(eta1) >= 2.5)      || (fabs(eta2) >= 2.5))       continue;
      if((fabs(eta1) >= kGAP_LOW) && (fabs(eta1) <= kGAP_HIGH)) continue;
      if((fabs(eta2) >= kGAP_LOW) && (fabs(eta2) <= kGAP_HIGH)) continue;

      // These events are in acceptance, use them for efficiency denominator
      Bool_t isBGen1 = (fabs(eta1)<kGAP_LOW);
      Bool_t isBGen2 = (fabs(eta2)<kGAP_LOW);         
      // determine number of good vertices
      pvBr->GetEntry(ientry);
      int iPUBin=-1;
      int nGoodPV=-1;
      if ((gen->mass>=60) && (gen->mass<=120)) {
	nGoodPV=0;
	for (Int_t ipv=0; ipv<pvArr->GetEntriesFast(); ipv++) {
	  const mithep::TVertex *pv = (mithep::TVertex*)((*pvArr)[ipv]);
	  if(pv->nTracksFit                        < 1)  continue;
	  if(pv->ndof                              < 4)  continue;
	  if(fabs(pv->z)                           > 24) continue;
	  if(sqrt((pv->x)*(pv->x)+(pv->y)*(pv->y)) > 2)  continue;
	  nGoodPV++;
	}
	if (nGoodPV>0) {
           if (nGoodPV<=nEventsZPeakPURaw.GetNoElements()) 
	        nEventsZPeakPURaw[nGoodPV] += scale * gen->weight;
	iPUBin=DYTools::findMassBin(double(nGoodPV),DYTools::nPVBinCount,DYTools::nPVLimits);
	//std::cout << "iPUBin=" << iPUBin << ", nGoodPV=" << nGoodPV << "\n";
	if ((iPUBin!=-1) && (iPUBin < nEventsZPeakPU.GetNoElements())) {
	  nEventsZPeakPU[iPUBin] += scale * gen->weight;
	}
	else {
	  std::cout << "error in PU bin indexing iPUBin=" << iPUBin << ", nGoodPV=" << nGoodPV << "\n";
	}
      } 
	//else std::cout << "nGoodPV=" << nGoodPV << "\n";
      }

      // Use post-FSR generator level mass for binning
      int ibinGen = DYTools::findMassBin(gen->mass);
      // Accumulate denominator for efficiency calculations
      if(ibinGen != -1 && ibinGen < nEventsv.GetNoElements()){
	nEventsv[ibinGen] += scale * gen->weight;
	// Split events barrel/endcap using matched supercluster or particle eta
	if(isBGen1 && isBGen2)                                  { nEventsBBv[ibinGen] += scale * gen->weight; } 
	else if(!isBGen1 && !isBGen2)                           { nEventsEEv[ibinGen] += scale * gen->weight; } 
	else if((isBGen1 && !isBGen2) || (!isBGen1 && isBGen2)) { nEventsBEv[ibinGen] += scale * gen->weight; }
      }else if(ibinGen >= nEventsv.GetNoElements())
	cout << "ERROR: binning problem" << endl;

      if(!(info->triggerBits & eventTriggerBit)) continue;  // no trigger accept? Skip to next event...                                   

      // loop through dielectrons
      dielectronArr->Clear();
      dielectronBr->GetEntry(ientry);    
      for(Int_t i=0; i<dielectronArr->GetEntriesFast(); i++) {
        const mithep::TDielectron *dielectron = (mithep::TDielectron*)((*dielectronArr)[i]);
	
	// Apply selection

	// Eta cuts
        if((fabs(dielectron->scEta_1)>kGAP_LOW) && (fabs(dielectron->scEta_1)<kGAP_HIGH)) continue;
        if((fabs(dielectron->scEta_2)>kGAP_LOW) && (fabs(dielectron->scEta_2)<kGAP_HIGH)) continue;
	if((fabs(dielectron->scEta_1) > 2.5)       || (fabs(dielectron->scEta_2) > 2.5))       continue;  // outside eta range? Skip to next event...
	
        Bool_t isB1 = (fabs(dielectron->scEta_1)<kGAP_LOW);
        Bool_t isB2 = (fabs(dielectron->scEta_2)<kGAP_LOW);         

	if( !( (isB1 == isBGen1 && isB2 == isBGen2 ) 
	       || (isB1 == isBGen2 && isB2 == isBGen1 ) ) )
	  countMismatch++;

	// Asymmetric SC Et cuts
	if( ! ( ( dielectron->scEt_1 > DYTools::etMinLead  && dielectron->scEt_2 > DYTools::etMinTrail)
		|| ( dielectron->scEt_1 > DYTools::etMinTrail  && dielectron->scEt_2 > DYTools::etMinLead) )) continue;

	// Both electrons must match trigger objects. At least one ordering
	// must match
 	if( ! ( 
 	       (dielectron->hltMatchBits_1 & leadingTriggerObjectBit && 
 		dielectron->hltMatchBits_2 & trailingTriggerObjectBit )
 	       ||
 	       (dielectron->hltMatchBits_1 & trailingTriggerObjectBit && 
 		dielectron->hltMatchBits_2 & leadingTriggerObjectBit ) ) ) continue;

	// The Smurf electron ID package is the same as used in HWW analysis
	// and contains cuts like VBTF WP80 for pt>20, VBTF WP70 for pt<10
	// with some customization, plus impact parameter cuts dz and dxy
	if(!passSmurf(dielectron)) continue;  

        /******** We have a Z candidate! HURRAY! ********/

	hZMassv[ifile]->Fill(gen->mass,scale * gen->weight);

	// DEBUG
// 	if(ibinGen == 12)
// 	  printf("Gen mass %f  reco mass %f  scEt_1= %f  scEt_2= %f  scEta_1= %f  scEta_2= %f\n",
// 		 gen->mass, dielectron->mass, dielectron->scEt_1, dielectron->scEt_2,
// 		 dielectron->scEta_1, dielectron->scEta_2);
	
	// Accumulate numerator for efficiency calculations
	if ((nGoodPV>0) && (iPUBin!=-1)) { // -1 may also indicate that the mass was not in Z-peak range
	  if ((nGoodPV>=0) && (nGoodPV<=nEventsZPeakPURaw.GetNoElements())) nPassZPeakPURaw[nGoodPV] += scale * gen->weight;
	  if (iPUBin < nPassZPeakPU.GetNoElements()) {
	    nPassZPeakPU[iPUBin] += scale * gen->weight;
	  }
	  else {
	    std::cout << "error in PU bin indexing\n";
	  }
	}
	if(ibinGen != -1 && ibinGen < nPassv.GetNoElements()){
	  nPassv[ibinGen] += scale * gen->weight;
	  if(isB1 && isB2)                            { nPassBBv[ibinGen] += scale * gen->weight; } 
	  else if(!isB1 && !isB2)                     { nPassEEv[ibinGen] += scale * gen->weight; } 
	  else if((isB1 && !isB2) || (!isB1 && isB2)) { nPassBEv[ibinGen] += scale * gen->weight; }
	}

      } // end loop over dielectrons
    } // end loop over events 
    delete infile;
    infile=0, eventTree=0;
  } // end loop over files
  delete gen;
  
  effv      = 0;
  effErrv   = 0;
  effBBv    = 0;
  effErrBBv = 0;
  effBEv    = 0;
  effErrBEv = 0;
  effEEv    = 0;
  effErrEEv = 0;
  for(int i=0; i<DYTools::nMassBins; i++){
    if(nEventsv[i] != 0){
      effv[i] = nPassv[i]/nEventsv[i];
      effErrv[i] = sqrt(effv[i]*(1-effv[i])/nEventsv[i]); 
    
      effBBv[i] = nPassBBv[i]/nEventsBBv[i];
      effErrBBv[i] = sqrt(effBBv[i]*(1-effBBv[i])/nEventsBBv[i]);
      
      effBEv[i] = nPassBEv[i]/nEventsBEv[i];
      effErrBEv[i] = sqrt(effBEv[i]*(1-effBEv[i])/nEventsBEv[i]);
      
      effEEv[i] = nPassEEv[i]/nEventsEEv[i];
      effErrEEv[i] = sqrt(effEEv[i]*(1-effEEv[i])/nEventsEEv[i]);
    }
  };

  effZPeakPU=0; effErrZPeakPU=0;
  for (int i=0; i<DYTools::nPVBinCount; ++i) {
    effZPeakPU[i]= nPassZPeakPU[i]/nEventsZPeakPU[i];
    effErrZPeakPU[i]= sqrt(effZPeakPU[i]*(1-effZPeakPU[i])/nEventsZPeakPU[i]);
  }

  printf("Sanity check: gen vs reco barrel-endcap assignment mismatches: %d\n",countMismatch);
  //--------------------------------------------------------------------------------------------------------------
  // Make plots 
  //==============================================================================================================  
  TCanvas *c = MakeCanvas("c","c",800,600);

  // string buffers
  char ylabel[50];   // y-axis label

  // Z mass
  sprintf(ylabel,"a.u. / %.1f GeV/c^{2}",hZMassv[0]->GetBinWidth(1));
  CPlot plotZMass1("zmass1","","m(Z) [GeV/c^{2}]",ylabel);
  for(UInt_t i=0; i<fnamev.size(); i++) { 
    plotZMass1.AddHist1D(hZMassv[i],labelv[i],"hist",colorv[i],linev[i]); 
  }
  plotZMass1.SetLogy();
  plotZMass1.Draw(c,doSave,format);
     
  // Prepare the overall efficiency plot
  double x [DYTools::nMassBins];
  double dx[DYTools::nMassBins];
  double y [DYTools::nMassBins];
  double dy[DYTools::nMassBins];
  for(int i=0; i<DYTools::nMassBins; i++){
    x[i]  = (DYTools::massBinLimits[i  ] + DYTools::massBinLimits[i+1])/2.0;
    dx[i] = (DYTools::massBinLimits[i+1] - DYTools::massBinLimits[i  ])/2.0;
    y[i] = effv[i];
    dy[i] = effErrv[i];
  }
  TGraphErrors *efficiencyGraph = 
    new TGraphErrors(DYTools::nMassBins,x,y,dx,dy);

  TCanvas *c1 = MakeCanvas("c1","c1",1000,600);
  CPlot plotEfficiency("Efficiency","","M_{ee} [GeV/c^{2}]","efficiency");
  plotEfficiency.SetLogx();
  plotEfficiency.AddGraph((TGraph*)efficiencyGraph,"PE",600,kFullDotMedium,1); 
  plotEfficiency.SetYRange(0,1.0);
  plotEfficiency.SetXRange(10,1500.0);
  efficiencyGraph->GetYaxis()->SetTitleOffset(1.0);
  efficiencyGraph->GetXaxis()->SetMoreLogLabels();
  efficiencyGraph->GetXaxis()->SetNoExponent();
  efficiencyGraph->SetMarkerStyle(20);
  efficiencyGraph->SetMarkerSize(1);
  plotEfficiency.Draw(c1,doSave,format);
          
  // Prepare the overall efficiency plot of Z-peak region vs number of primary vertices
  double x_2 [DYTools::nPVBinCount];
  double dx_2[DYTools::nPVBinCount];
  double y_2 [DYTools::nPVBinCount];
  double dy_2[DYTools::nPVBinCount];
  for(int i=0; i<DYTools::nPVBinCount; i++){
    x_2[i]  = (DYTools::nPVLimits[i  ] + DYTools::nPVLimits[i+1])/2.0;
    dx_2[i] = (DYTools::nPVLimits[i+1] - DYTools::nPVLimits[i  ])/2.0;
    y_2[i] = effZPeakPU[i];
    dy_2[i] = effErrZPeakPU[i];
  }
  TGraphErrors *efficiencyGraphZPeakPU = 
    new TGraphErrors(DYTools::nPVBinCount,x_2,y_2,dx_2,dy_2);

  TCanvas *cz = MakeCanvas("cz","cz",1000,600);
  CPlot plotEfficiencyZPeakPU("Efficiency","","number of good PVs","efficiency");
  plotEfficiencyZPeakPU.SetLogx();
  plotEfficiencyZPeakPU.AddGraph((TGraph*)efficiencyGraphZPeakPU,"PE",600,kFullDotMedium,1); 
  plotEfficiencyZPeakPU.SetYRange(0,1.0);
  plotEfficiencyZPeakPU.SetXRange(10,100.0);
  efficiencyGraph->GetYaxis()->SetTitleOffset(1.0);
  efficiencyGraph->GetXaxis()->SetMoreLogLabels();
  efficiencyGraph->GetXaxis()->SetNoExponent();
  efficiencyGraph->SetMarkerStyle(20);
  efficiencyGraph->SetMarkerSize(1);
  plotEfficiencyZPeakPU.Draw(cz,doSave,format);
          
  // Store constants in the file
  TString outputDir(TString("../root_files/constants/")+dirTag);
  gSystem->mkdir(outputDir,kTRUE);
  TString effConstFileName(outputDir+TString("/event_efficiency_constants.root"));

   TFile fa(effConstFileName,"recreate");
   effv.Write("efficiencyArray");
   effErrv.Write("efficiencyErrArray");
   effZPeakPU.Write("efficiencyZPeakPUArray");
   effErrZPeakPU.Write("efficiencyErrZPeakPUArray");
   nEventsZPeakPU.Write("nEventsZPeakPUArray");
   nPassZPeakPU.Write("nPassZPeakPUArray");
   nEventsZPeakPURaw.Write("nEventsZPeakPURawArray");
   nPassZPeakPURaw.Write("nPassZPeakPURawArray");
   fa.Close();
     
  //--------------------------------------------------------------------------------------------------------------
  // Summary print out
  //==============================================================================================================
  cout << endl;
  cout << "*" << endl;
  cout << "* SUMMARY" << endl;
  cout << "*--------------------------------------------------" << endl;
  cout << endl; 
  
  cout << labelv[0] << " file: " << fnamev[0] << endl;
  printf("     Number of generated events: %8.1lf",nZv);
  printf(" mass bin    preselected      passed     total_Eff        BB-BB_Eff        EB-BB_Eff        EB-EB_Eff   \n");
  for(int i=0; i<DYTools::nMassBins; i++){
    printf(" %4.0f-%4.0f   %10.0f   %10.0f   %7.4f+-%6.4f  %7.4f+-%6.4f  %7.4f+-%6.4f  %7.4f+-%6.4f \n",
	   DYTools::massBinLimits[i], DYTools::massBinLimits[i+1],
	   nEventsv[i], nPassv[i],
	   effv[i], effErrv[i],
	   effBBv[i], effErrBBv[i],
	   effBEv[i], effErrBEv[i],
	   effEEv[i], effErrEEv[i]);
  }

  printf("\n\nZ-peak efficiency\n");
  printf(" PU bin    preselected      passed     total_Eff\n");
  for(int i=0; i<DYTools::nPVBinCount; i++){
    printf(" %4.0f-%4.0f   %10.0f   %10.0f   %7.4f+-%6.4f\n",
	   DYTools::nPVLimits[i], DYTools::nPVLimits[i+1],
	   nEventsZPeakPU[i], nPassZPeakPU[i],
	   effZPeakPU[i], effErrZPeakPU[i]);
  }

  cout << endl;
  
  gBenchmark->Show("plotDYEfficiency");
}
void run(std::string inputFile, std::string dataType)
{
    try
    {
        // Create an output directory if it doesnt already exist
        sys::Path outputDir(sys::Path::basename(inputFile, true));
        if (!outputDir.exists())
            outputDir.makeDirectory();

        std::string xmlFile = inputFile;

        // Check if the file is a NITF - if so, extract all the parts into our outputDir
        if (nitf::Reader::getNITFVersion(inputFile) != NITF_VER_UNKNOWN)
        {
            std::vector<std::string> allFiles =
                    extractXML(inputFile, outputDir);
            if (!allFiles.size())
                throw except::Exception(
                                        Ctxt(
                                             std::string("Invalid input NITF: ")
                                                     + inputFile));
            xmlFile = allFiles[0];
        }

        // Now show the file (only if PREVIEW is defined)
        preview(xmlFile);

        // Read in the XML file from the disk location into a SICD/SIDD container
        io::FileInputStream xmlFileStream(xmlFile);
        xml::lite::MinidomParser treeBuilder;
        treeBuilder.parse(xmlFileStream);
        xmlFileStream.close();

        six::DataType dt = (dataType == "sicd") ? six::DataType::COMPLEX
                                                : six::DataType::DERIVED;

        std::auto_ptr<logging::Logger> log (new logging::NullLogger());
        six::XMLControl *control =
                six::XMLControlFactory::getInstance().newXMLControl(dt, log.get());

        six::Data *data = control->fromXML(treeBuilder.getDocument(),
                                           std::vector<std::string>());

        // Dump some core info
        std::cout << "Data Class: " << six::toString(data->getDataType())
                << std::endl;
        std::cout << "Pixel Type: " << six::toString(data->getPixelType())
                << std::endl;
        std::cout << "Num Rows  : " << six::toString(data->getNumRows())
                << std::endl;
        std::cout << "Num Cols  : " << six::toString(data->getNumCols())
                << std::endl;

        // Generate a KML in this directory
        preview(generateKML(data, outputDir));

        // Generate a Round-Trip file
        sys::Path outputFile(outputDir, "round-trip.xml");
        xml::lite::Document* outDom = 
            control->toXML(data, std::vector<std::string>());
        io::FileOutputStream outXML(outputFile.getPath());
        outDom->getRootElement()->prettyPrint(outXML);
        outXML.close();
        delete outDom;

        // Now show the output file if PREVIEW
        preview(outputFile.getPath());

        delete control;
        delete data;
    }
    catch (except::Exception& ex)
    {
        std::cout << "ERROR!: " << ex.getMessage() << std::endl;
    }
}
bool CommandCrossSection::process(ccCommandLineInterface &cmd)
{
	cmd.print("[CROSS SECTION]");

	static QString s_xmlCloudCompare = "CloudCompare";
	static QString s_xmlBoxThickness = "BoxThickness";
	static QString s_xmlBoxCenter = "BoxCenter";
	static QString s_xmlRepeatDim = "RepeatDim";
	static QString s_xmlRepeatGap = "RepeatGap";
	static QString s_xmlFilePath = "FilePath";
	static QString s_outputXmlFilePath = "OutputFilePath";

	//expected argument: XML file
	if (cmd.arguments().empty())
		return cmd.error(QString("Missing parameter: XML parameters file after \"-%1\"").arg(COMMAND_CROSS_SECTION));
	QString xmlFilename = cmd.arguments().takeFirst();

	//read the XML file
	CCVector3 boxCenter(0, 0, 0), boxThickness(0, 0, 0);
	bool repeatDim[3] = { false, false, false };
	double repeatGap = 0.0;
	bool inside = true;
	bool autoCenter = true;
	QString inputFilePath;
	QString outputFilePath;
	{
		QFile file(xmlFilename);
		if (!file.open(QFile::ReadOnly | QFile::Text))
		{
			return cmd.error(QString("Couldn't open XML file '%1'").arg(xmlFilename));
		}

		//read file content
		QXmlStreamReader stream(&file);

		//expected: CloudCompare
		if (!stream.readNextStartElement()
		        || stream.name() != s_xmlCloudCompare)
		{
			return cmd.error(QString("Invalid XML file (should start by '<%1>')").arg(s_xmlCloudCompare));
		}

		unsigned mandatoryCount = 0;
		while (stream.readNextStartElement()) //loop over the elements
		{
			if (stream.name() == s_xmlBoxThickness)
			{
				QXmlStreamAttributes attributes = stream.attributes();
				if (!readVector(attributes, boxThickness, s_xmlBoxThickness, cmd))
					return false;
				stream.skipCurrentElement();
				++mandatoryCount;
			}
			else if (stream.name() == s_xmlBoxCenter)
			{
				QXmlStreamAttributes attributes = stream.attributes();
				if (!readVector(attributes, boxCenter, s_xmlBoxCenter, cmd))
					return false;
				stream.skipCurrentElement();
				autoCenter = false;
			}
			else if (stream.name() == s_xmlRepeatDim)
			{
				QString itemValue = stream.readElementText();
				bool ok = false;
				int dim = itemValue.toInt(&ok);
				if (!ok || dim < 0 || dim > 2)
				{
					return cmd.error(QString("Invalid XML file (invalid value for '<%1>')").arg(s_xmlRepeatDim));
				}
				repeatDim[dim] = true;
			}
			else if (stream.name() == s_xmlRepeatGap)
			{
				QString itemValue = stream.readElementText();
				bool ok = false;
				repeatGap = itemValue.toDouble(&ok);
				if (!ok)
				{
					return cmd.error(QString("Invalid XML file (invalid value for '<%1>')").arg(s_xmlRepeatGap));
				}
			}
			else if (stream.name() == s_xmlFilePath)
			{
				inputFilePath = stream.readElementText();
				if (!QDir(inputFilePath).exists())
				{
					return cmd.error(QString("Invalid file path (directory pointed by '<%1>' doesn't exist)").arg(s_xmlFilePath));
				}
				//++mandatoryCount;
			}
			else if (stream.name() == s_outputXmlFilePath)
			{
				outputFilePath = stream.readElementText();
				if (!QDir(outputFilePath).exists())
				{
					return cmd.error(QString("Invalid output file path (directory pointed by '<%1>' doesn't exist)").arg(s_outputXmlFilePath));
				}
				//++mandatoryCount;
			}
			else
			{
				cmd.warning(QString("Unknown element: %1").arg(stream.name().toString()));
				stream.skipCurrentElement();
			}
		}

		if (mandatoryCount < 1 || (!repeatDim[0] && !repeatDim[1] && !repeatDim[2]))
		{
			return cmd.error(QString("Some mandatory elements are missing in the XML file (see documentation)"));
		}
	}

	//safety checks
	if (	boxThickness.x < ZERO_TOLERANCE
	        ||	boxThickness.y < ZERO_TOLERANCE
	        ||	boxThickness.z < ZERO_TOLERANCE
	        )
	{
		return cmd.error(QString("Invalid box thickness"));
	}

	CCVector3 repeatStep = boxThickness + CCVector3(repeatGap, repeatGap, repeatGap);
	if (	(repeatDim[0] && repeatStep.x < ZERO_TOLERANCE)
	        ||	(repeatDim[1] && repeatStep.y < ZERO_TOLERANCE)
	        ||	(repeatDim[2] && repeatStep.z < ZERO_TOLERANCE)
	        )
	{
		return cmd.error(QString("Repeat gap can't be equal or smaller than 'minus' box width"));
	}

	if (outputFilePath.isEmpty())
	{
		outputFilePath = inputFilePath;
	}

	int iterationCount = 1;

	//shall we load the entities?
	QStringList files;
	QDir dir;
	bool fromFiles = false;
	if (!inputFilePath.isEmpty())
	{
		//look for all files in the input directory
		dir = QDir(inputFilePath);
		assert(dir.exists());
		files = dir.entryList(QDir::Files);
		iterationCount = files.size();
		fromFiles = true;

		//remove any cloud or mesh in memory!
		cmd.removeClouds();
		cmd.removeMeshes();
	}

	for (int f = 0; f < iterationCount; ++f)
	{
		//shall we load files?
		QString filename;
		if (fromFiles)
		{
			assert(f < files.size());
			filename = dir.absoluteFilePath(files[f]);
			QFileInfo fileinfo(filename);
			if (!fileinfo.isFile() || fileinfo.suffix().toUpper() == "XML")
			{
				continue;
			}

			//let's try to load the file
			cmd.print(QString("Processing file: '%1'").arg(files[f]));

			bool result = false;
			{
				//hack: replace the current argument list by a fake 'load file' sequence
				QStringList realArguments = cmd.arguments();

				QStringList loadArguments;
				loadArguments << filename;
				cmd.arguments() = loadArguments;
				result = CommandLoad().process(cmd);

				//end of hack: restore the current argument list
				cmd.arguments() = realArguments;
			}

			if (!result)
			{
				cmd.warning("\tFailed to load file!");
				continue;
			}
		}
		else
		{
			assert(iterationCount == 1);
		}

		//repeat crop process on each file (or do it only once on the currently loaded entities)
		{
			ccHObject::Container entities;
			try
			{
				for (size_t i = 0; i < cmd.clouds().size(); ++i)
					entities.push_back(cmd.clouds()[i].pc);
				for (size_t j = 0; j < cmd.meshes().size(); ++j)
					entities.push_back(cmd.meshes()[j].mesh);
			}
			catch (const std::bad_alloc&)
			{
				return cmd.error("Not enough memory!");
			}

			for (size_t i = 0; i < entities.size(); ++i)
			{
				//check entity bounding-box
				ccHObject* ent = entities[i];
				ccBBox bbox = ent->getOwnBB();
				if (!bbox.isValid())
				{
					cmd.warning(QString("Entity '%1' has an invalid bounding-box!").arg(ent->getName()));
					continue;
				}

				//browse to/create a subdirectory with the (base) filename as name
				QString basename;
				if (fromFiles)
				{
					basename = QFileInfo(filename).baseName();
				}
				else
				{
					basename = i < cmd.clouds().size() ? cmd.clouds()[i].basename : cmd.meshes()[i - cmd.clouds().size()].basename;
				}

				if (entities.size() > 1)
					basename += QString("_%1").arg(i + 1);

				QDir outputDir(outputFilePath);
				if (outputFilePath.isEmpty())
				{
					if (fromFiles)
					{
						assert(false);
						outputDir = QDir::current();
					}
					else
					{
						outputDir = QDir(i < cmd.clouds().size() ? cmd.clouds()[i].path : cmd.meshes()[i - cmd.clouds().size()].path);
					}
				}

				assert(outputDir.exists());
				if (outputDir.cd(basename))
				{
					//if the directory already exists...
					cmd.warning(QString("Subdirectory '%1' already exists").arg(basename));
				}
				else if (outputDir.mkdir(basename))
				{
					outputDir.cd(basename);
				}
				else
				{
					cmd.warning(QString("Failed to create subdirectory '%1' (check access rights and base name validity!)").arg(basename));
					continue;
				}

				int toto = ceil(-0.4);
				int toto2 = ceil(-0.6);

				//place the initial box at the beginning of the entity bounding box
				CCVector3 C0 = autoCenter ? bbox.getCenter() : boxCenter;
				unsigned steps[3] = { 1, 1, 1 };
				for (unsigned d = 0; d < 3; ++d)
				{
					if (repeatDim[d])
					{
						PointCoordinateType boxHalfWidth = boxThickness.u[d] / 2;
						PointCoordinateType distToMinBorder = C0.u[d] - boxHalfWidth - bbox.minCorner().u[d];
						int stepsToMinBorder = static_cast<int>(ceil(distToMinBorder / repeatStep.u[d]));
						C0.u[d] -= stepsToMinBorder * repeatStep.u[d];

						PointCoordinateType distToMaxBorder = bbox.maxCorner().u[d] - C0.u[d] - boxHalfWidth;
						int stepsToMaxBoder = static_cast<int>(ceil(distToMaxBorder / repeatStep.u[d]) + 1);
						assert(stepsToMaxBoder >= 0);
						steps[d] = std::max<unsigned>(stepsToMaxBoder, 1);
					}
				}

				cmd.print(QString("Will extract up to (%1 x %2 x %3) = %4 sections").arg(steps[0]).arg(steps[1]).arg(steps[2]).arg(steps[0] * steps[1] * steps[2]));

				//now extract the slices
				for (unsigned dx = 0; dx < steps[0]; ++dx)
				{
					for (unsigned dy = 0; dy < steps[1]; ++dy)
					{
						for (unsigned dz = 0; dz < steps[2]; ++dz)
						{
							CCVector3 C = C0 + CCVector3(dx*repeatStep.x, dy*repeatStep.y, dz*repeatStep.z);
							ccBBox cropBox(C - boxThickness / 2, C + boxThickness / 2);
							cmd.print(QString("Box (%1;%2;%3) --> (%4;%5;%6)")
							          .arg(cropBox.minCorner().x).arg(cropBox.minCorner().y).arg(cropBox.minCorner().z)
							          .arg(cropBox.maxCorner().x).arg(cropBox.maxCorner().y).arg(cropBox.maxCorner().z)
							          );
							ccHObject* croppedEnt = ccCropTool::Crop(ent, cropBox, inside);
							if (croppedEnt)
							{
								QString outputBasename = basename + QString("_%1_%2_%3").arg(C.x).arg(C.y).arg(C.z);
								QString errorStr;
								//original entity is a cloud?
								if (i < cmd.clouds().size())
								{
									CLCloudDesc desc(static_cast<ccPointCloud*>(croppedEnt),
									                 outputBasename,
									                 outputDir.absolutePath(),
									                 entities.size() > 1 ? static_cast<int>(i) : -1);
									errorStr = cmd.exportEntity(desc);
								}
								else //otherwise it's a mesh
								{
									CLMeshDesc desc(static_cast<ccMesh*>(croppedEnt),
									                outputBasename,
									                outputDir.absolutePath(),
									                entities.size() > 1 ? static_cast<int>(i) : -1);
									errorStr = cmd.exportEntity(desc);
								}

								delete croppedEnt;
								croppedEnt = 0;

								if (!errorStr.isEmpty())
									return cmd.error(errorStr);
							}
						}
					}
				}
			}

			if (fromFiles)
			{
				//unload entities
				cmd.removeClouds();
				cmd.removeMeshes();
			}
		}
	}

	return true;
}
Exemple #26
0
void qAnimationDlg::render(bool asSeparateFrames)
{
	if (!m_view3d)
	{
		assert(false);
		return;
	}
	QString outputFilename = outputFileLineEdit->text();

	//save to persistent settings
	{
		QSettings settings;
		settings.beginGroup("qAnimation");
		settings.setValue("filename", outputFilename);
		settings.endGroup();
	}

	setEnabled(false);

	//count the total number of frames
	int frameCount = countFrames(0);
	int fps = fpsSpinBox->value();
	int superRes = superResolutionSpinBox->value();

	//show progress dialog
	QProgressDialog progressDialog(QString("Frames: %1").arg(frameCount), "Cancel", 0, frameCount, this);
	progressDialog.setWindowTitle("Render");
	progressDialog.show();
	QApplication::processEvents();

#ifdef QFFMPEG_SUPPORT
	QScopedPointer<QVideoEncoder> encoder(0);
	QSize originalViewSize;
	if (!asSeparateFrames)
	{
		//get original viewport size
		originalViewSize = m_view3d->qtSize();

		//hack: as the encoder requires that the video dimensions are multiples of 8, we resize the window a little bit...
		{
			//find the nearest multiples of 8
			QSize customSize = originalViewSize;
			if (originalViewSize.width() % 8 || originalViewSize.height() % 8)
			{
				if (originalViewSize.width() % 8)
					customSize.setWidth((originalViewSize.width() / 8 + 1) * 8);
				if (originalViewSize.height() % 8)
					customSize.setHeight((originalViewSize.height() / 8 + 1) * 8);
				m_view3d->resize(customSize);
				QApplication::processEvents();
			}
		}

		int bitrate = bitrateSpinBox->value() * 1024;
		int gop = fps;
		encoder.reset(new QVideoEncoder(outputFilename, m_view3d->glWidth(), m_view3d->glHeight(), bitrate, gop, static_cast<unsigned>(fpsSpinBox->value())));
		QString errorString;
		if (!encoder->open(&errorString))
		{
			QMessageBox::critical(this, "Error", QString("Failed to open file for output: %1").arg(errorString));
			setEnabled(true);
			return;
		}
	}
#else
	if (!asSeparateFrames)
	{
		QMessageBox::critical(this, "Error", QString("Animation mode is not supported (no FFMPEG support)"));
		return;
	}
#endif

	bool lodWasEnabled = m_view3d->isLODEnabled();
	m_view3d->setLODEnabled(false);

	QDir outputDir( QFileInfo(outputFilename).absolutePath() );

	int frameIndex = 0;
	bool success = true;
	size_t vp1 = 0, vp2 = 0;
	while (getNextSegment(vp1, vp2))
	{
		Step& step1 = m_videoSteps[vp1];
		Step& step2 = m_videoSteps[vp2];

		ViewInterpolate interpolator(step1.viewport, step2.viewport);
		int frameCount = static_cast<int>( fps * step1.duration_sec );
		interpolator.setMaxStep(frameCount);

		cc2DViewportObject current_params;
		while ( interpolator.nextView( current_params ) )
		{
			applyViewport ( &current_params );

			//render to image
			QImage image = m_view3d->renderToImage(superRes, false, false, true );

			if (image.isNull())
			{
				QMessageBox::critical(this, "Error", "Failed to grab the screen!");
				success = false;
				break;
			}

			if (superRes > 1)
			{
				image = image.scaled(image.width()/superRes, image.height()/superRes, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
			}

			if (asSeparateFrames)
			{
				QString filename = QString("frame_%1.png").arg(frameIndex, 6, 10, QChar('0'));
				QString fullPath = outputDir.filePath(filename);
				if (!image.save(fullPath))
				{
					QMessageBox::critical(this, "Error", QString("Failed to save frame #%1").arg(frameIndex + 1));
					success = false;
					break;
				}
			}
			else
			{
#ifdef QFFMPEG_SUPPORT
				QString errorString;
				if (!encoder->encodeImage(image, frameIndex, &errorString))
				{
					QMessageBox::critical(this, "Error", QString("Failed to encode frame #%1: %2").arg(frameIndex + 1).arg(errorString));
					success = false;
					break;
				}
#endif
			}
			++frameIndex;
			progressDialog.setValue(frameIndex);
			QApplication::processEvents();
			if (progressDialog.wasCanceled())
			{
				QMessageBox::warning(this, "Warning", QString("Process has been cancelled"));
				success = false;
				break;
			}
		}

		if (!success)
		{
			break;
		}

		if (vp2 == 0)
		{
			//stop loop here!
			break;
		}
		vp1 = vp2;
	}

	m_view3d->setLODEnabled(lodWasEnabled);

#ifdef QFFMPEG_SUPPORT
	if (encoder)
	{
		encoder->close();

		//hack: restore original size
		m_view3d->resize(originalViewSize);
		QApplication::processEvents();
	}
#endif

	progressDialog.hide();
	QApplication::processEvents();

	if (success)
	{
		QMessageBox::information(this, "Job done", "The animation has been saved successfully");
	}

	setEnabled(true);
}
Exemple #27
0
//----------------------------------------------------------------------------------------------------------------------
void Globals::initialise(const std::string& cfgFnm)
{
  // Defaults
  m_settings = 0;
  m_fnm.clear();
  
  // Current directory of the executable
  bfs::path currentPath ( bfs::current_path() );    
  std::string currentPathStr = currentPath.string();
  
  // Look for config file in current exe's directory or in subfolder specified in argument
  std::string pathToConfig;
  if(cfgFnm.empty())
  {
#if DEBUGGING
    std::cout << "No config file specified. Searching in local directory '" << currentPathStr << "'." << std::endl;    
#endif    
    // No config file name given, so load first in base directory with xml ending.
    bfs::directory_iterator end_itr;  
    for (bfs::directory_iterator itr(currentPath); itr != end_itr; ++itr)
    {
      // If it's not a directory ...
      if (!is_directory(itr->status()))
      {
        // ... and the filename contains the xml ending      
        const std::string& fnm = itr->path().filename().string();
        if(fnm.find(".xml") != std::string::npos)
        {
          m_fnm = fnm;
          pathToConfig = itr->path().string();
#if DEBUGGING
          std::cout << "Found config file '" << m_fnm << "'." << std::endl;    
#endif              
          break;
        }               
      }
    }
  }
  else
  {
    std::string pathHomeExpanded = pathExpandHome(cfgFnm);
    
    // Global paths start with a forward slash '/', local paths don't.
    if (pathHomeExpanded[0] == '/' && bfs::exists(pathHomeExpanded))
    {
      m_fnm = pathHomeExpanded.substr(pathHomeExpanded.rfind('/') + 1);
      pathToConfig = pathHomeExpanded;
#if 0
      std::cout << "Found specified config file in ABSOLUTE path '" << pathToConfig << "'." << std::endl;
#endif                
    }
    else 
    {
      const std::string localPath = currentPathStr + "/" + pathHomeExpanded;
      if(bfs::exists(localPath))
      {
        m_fnm = cfgFnm.substr(cfgFnm.rfind('/') + 1);
        pathToConfig = localPath;
#if 0
        std::cout << "Found specified config file in LOCAL path '" << pathToConfig << "'." << std::endl;
#endif
      }
    }
  }
  
  
  // If we have a valid config filename, load it
  if(!pathToConfig.empty())
  {
    try
    {    
      m_settings = new ci::XmlTree(ci::loadFile(pathToConfig));
    }
    catch (rapidxml::parse_error& e)
    {
      std::cout << "XML parse error trying to read config: '" << e.what() << "'. Aborting!" << std::endl;
    }    
  }
  else 
  {
#if DEBUGGING
    std::cout << "No config file specified. Not loading any settings! '" << std::endl;    
#endif    
  }
  
  // Choose folder to save output file. It's either a hard-coded subfolder of current directory,
  // or one specified in config file
  std::string outputDir(currentPathStr + "/Output/");
  if(m_settings && m_settings->hasChild("Config/Globals/OutputFolder"))
  {
    std::string dir = m_settings->getChild("Config/Globals/OutputFolder").getAttributeValue<std::string>("Name");
    if(!dir.empty())
    {
      // Expand home directory: replaces '~' if appropriate
      dir = pathExpandHome(dir);
      
      // Absolute or relative path?
      if(dir[0] != '/')
      {
        outputDir = currentPathStr + "/" + dir + "/";
      }
      else
      {
        outputDir = dir + "/";
      }
    }
  }


  // Create a new directory based on current data and time and store the path for global access
  time_t now = time(NULL);
  static const int TimeMaxChar = 128; 
  char dateTime[TimeMaxChar];
  dateTime[0] = '\0';
  strftime(dateTime, TimeMaxChar, "%y_%m_%d__%H_%M_%S", localtime(&now));   
  
  // Finally create the data directory
  m_dataDir = outputDir + dateTime + "/";
  bfs::create_directories(boost::filesystem::path(m_dataDir));
  
}
int main(int argc, char** argv)
{
  setTDRStyle();
    

  std::string inputDir("/gwteraz/users/deguio/PLOTS/NTUPLES_useFakeRate/");
  //std::string inputDir("/data2/deguio/Wprime/WprimeAnalysis/WprimeAnalysis/output/FAKERATE/useFakeRate/");
  //std::string outputDir("/gwteraz/users/deguio/PLOTS/FIGURES_numFakeRate/");
  std::string outputDir("/gwteraz/users/deguio/PLOTS/FIGURES_testFakeRate/");

  int step = 10;//numerator & useFakeRate & contamination(senza applicare FR)
  //int step = 8;//denominator
  //float lumi = 201.38; //May10
  float lumi = 1132; //05Jul
  

  std::string drawMode = "eventsScaled";
  //std::string drawMode = "sameAreaStack";
  
  
  // draw plots
  drawTStack_ntu* stack = new drawTStack_ntu(inputDir, "config/crossSections_wPrime_Summer11_ntu.txt", "ntu_WprimeTreeAnalysis", outputDir);
    
  //=============
  //==== Eff ====  
  //=============  
  stack -> DrawEvents("events", lumi, step, true);
  stack -> DrawEvents("eventsScaled", lumi, step, true);
  stack -> DrawEvents("eventsScaledStack", lumi, step, true);
  stack -> DrawEvents("efficiencies", lumi, step, true);
  stack -> DrawEvents("efficienciesRelative", lumi, step, true);

  std::vector<std::string> variableNames;
  variableNames.push_back("");
  std::vector<std::string> variableNames2;
  variableNames2.push_back("");
  variableNames2.push_back("");
  
  std::vector<std::string>* cuts = new std::vector<std::string>;
  cuts->push_back("");
  std::vector<std::string>* cuts2 = new std::vector<std::string>;
  cuts2->push_back("");  
  cuts2->push_back("");
  
  std::string histoName;

  //=============
  //==== MET ====  
  //=============  
  variableNames.at(0) = "met.Et()";
  histoName    = "met";
  cuts->at(0) = "hltPrescale";
  stack -> SetXaxisRange(0., 100.);
  stack -> SetXaxisTitle("PFMet (GeV)");
  stack -> Draw(variableNames, histoName, drawMode, lumi, step, 100, false, cuts);

  variableNames.at(0) = "met.px()";
  histoName    = "mex";
  cuts->at(0) = "hltPrescale";
  stack -> SetXaxisRange(-500., 500.);
  stack -> SetXaxisTitle("PFMex (GeV)");
  stack -> Draw(variableNames, histoName, drawMode, lumi, step, 100, false, cuts);

  variableNames.at(0) = "met.py()";
  histoName    = "mey";
  cuts->at(0) = "hltPrescale";
  stack -> SetXaxisRange(-500., 500.);
  stack -> SetXaxisTitle("PFMey (GeV)");
  stack -> Draw(variableNames, histoName, drawMode, lumi, step, 100, false, cuts);

  //================
  //==== Pho Et ====
  //================
  variableNames.at(0) = "pho.Et()";
  histoName    = "phoEt";
  cuts->at(0) = "hltPrescale";
  stack -> SetXaxisRange(0., 150.);
  stack -> SetXaxisTitle("pho Et (GeV)");
  stack -> Draw(variableNames, histoName, drawMode, lumi, step, 200, false, cuts, false);

  variableNames.at(0) = "pho.Et()";
  histoName    = "phoEt_cumulative";
  cuts->at(0) = "hltPrescale";
  stack -> SetXaxisRange(0., 150.);
  stack -> SetXaxisTitle("pho Et (GeV)");
  stack -> Draw(variableNames, histoName, drawMode, lumi, step, 200, false, cuts, true);

  //================
  //==== Ele Et ====  
  //================
  variableNames.at(0) = "ele.Et()";
  histoName    = "eleEt";
  cuts->at(0) = "hltPrescale";
  stack -> SetXaxisRange(0., 150.);
  stack -> SetXaxisTitle("ele Et (GeV)");
  stack -> Draw(variableNames, histoName, drawMode, lumi, step, 200, false, cuts, false);

  variableNames.at(0) = "ele.Et()";
  histoName    = "eleEt_cumulative";
  cuts->at(0) = "hltPrescale";
  stack -> SetXaxisRange(0., 150.);
  stack -> SetXaxisTitle("ele Et (GeV)");
  stack -> Draw(variableNames, histoName, drawMode, lumi, step, 200, false, cuts, true);

  //==============
  //==== hMt =====
  //==============
  variableNames.at(0) = "eleMet_mt";
  histoName    = "mT";
  cuts->at(0) = "hltPrescale";
  stack -> SetXaxisRange(0., 400.);
  stack -> SetXaxisTitle("M_{T} (GeV/c^{2})");
  stack -> Draw(variableNames, histoName, drawMode, lumi, step, 200, false, cuts, false);

  variableNames.at(0) = "eleMet_mt";
  histoName    = "mT_cumulative";
  cuts->at(0) = "hltPrescale";
  stack -> SetXaxisRange(0., 1500.);
  stack -> SetXaxisTitle("M_{T} (GeV/c^{2})");
  stack -> Draw(variableNames, histoName, drawMode, lumi, step, 200, false, cuts, true);

  variableNames.at(0) = "eleMet_mt";
  histoName    = "mT_cumulative_noReweight";
  cuts->at(0) = "";
  stack -> SetXaxisRange(0., 1500.);
  stack -> SetXaxisTitle("M_{T} (GeV/c^{2})");
  stack -> Draw(variableNames, histoName, drawMode, lumi, step, 200, false, cuts, true);
  
  // //========================
  // //==== hMt fake rate =====
  // //========================
  // variableNames.at(0) = "sqrt( 2. * pho.pt() * met.pt() * ( 1 - cos(eleMet_Dphi) ) )";
  // histoName    = "mT";
  // cuts->at(0) = "hltPrescale";
  // stack -> SetXaxisRange(0., 1500.);
  // stack -> SetXaxisTitle("M_{T} (GeV/c^{2})");
  // stack -> Draw(variableNames, histoName, drawMode, lumi, step, 200, true, cuts, false);

  // //==========================
  // //==== Ele Et fake rate ====  
  // //==========================
  // variableNames.at(0) = "ele.Et()";
  // histoName    = "eleEt";
  // cuts->at(0) = "hltPrescale";
  // stack -> SetXaxisRange(0., 150.);
  // stack -> SetXaxisTitle("ele Et (GeV)");
  // stack -> Draw(variableNames, histoName, drawMode, lumi, step, 200, false, cuts, false);

}