{"id":50672622,"url":"https://github.com/gipert/hmixfit","last_synced_at":"2026-06-08T12:32:54.236Z","repository":{"id":187277222,"uuid":"676608445","full_name":"gipert/hmixfit","owner":"gipert","description":"Fit linear mixtures of histograms to data with Bayesian statistics","archived":false,"fork":false,"pushed_at":"2025-10-24T02:14:45.000Z","size":1428,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-24T04:14:50.878Z","etag":null,"topics":["bayesian-inference","histograms","particle-physics"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gipert.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-08-09T15:34:54.000Z","updated_at":"2025-10-24T02:14:52.000Z","dependencies_parsed_at":"2023-08-09T18:13:02.823Z","dependency_job_id":"70d6a563-ec49-453b-a611-93c30ebc3a84","html_url":"https://github.com/gipert/hmixfit","commit_stats":null,"previous_names":["gipert/hmixfit"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/gipert/hmixfit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gipert%2Fhmixfit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gipert%2Fhmixfit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gipert%2Fhmixfit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gipert%2Fhmixfit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gipert","download_url":"https://codeload.github.com/gipert/hmixfit/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gipert%2Fhmixfit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34063150,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-08T02:00:07.615Z","response_time":111,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bayesian-inference","histograms","particle-physics"],"created_at":"2026-06-08T12:32:52.212Z","updated_at":"2026-06-08T12:32:54.228Z","avatar_url":"https://github.com/gipert.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# hmixfit ![CI](https://github.com/gipert/hmixfit/workflows/CI/badge.svg)\n\nA fully JSON-configurable bayesian fitting engine (based on\n[BAT](https://github.com/bat/bat) and\n[ROOT](https://github.com/root-project/root)) for data in the form of ROOT\nhistograms.\n\n*hmixfit* defines the following Poissonian likelihood function:\n\n```math\n  \\mathcal{L}(p_1, \\ldots, p_m \\ |\\ \\text{data}) =\n  \\prod^\\text{data set}_i \\prod^\\text{bins}_j \\ \\text{Poisson} \\big[ n_{ij} \\ |\\ \\sum_k p_k \\ \\nu_{ij} \\big] \\quad\n  \\text{where:} \\quad n = \\text{data} \\ /\\ \\nu = \\text{pdf}\n```\n\nwhere $p_1, \\ldots, p_m$ are the weights of the linear combination of histograms (the model) on which statistical inference is performed.\nMultiple data histograms (labeled by $i$) can be fit simultaneously. The $p_k$ can be common to each dataset model.\n\n### Run with a Linux container\n\n#### Docker\n\nPre-built container images are available [on Docker Hub](https://hub.docker.com/repository/docker/gipert/hmixfit).\n\n```console\n\u003e docker run gipert/hmixfit:latest\nUSAGE: /opt/hmixfit/bin/hmixfit [-h|--help] json-config\n\u003e docker run gipert/hmixfit:latest \u003cconfig.json\u003e\n +------------------------------------------------------+\n |                                                      |\n | BAT version 1.0.0                                    |\n | Copyright (C) 2007-2018, the BAT core developer team |\n | All rights reserved.                                 |\n...\n```\n\n#### Apptainer\n\n```console\n\u003e apptainer build hmixfit_latest.sif docker://gipert/hmixfit:latest\n\u003e apptainer run hmixfit_latest.sif \u003cconfig.json\u003e\n...\n```\n\n### Compile and install\n\nRequirements\n - [ROOT](https://github.com/root-project/root) ≥ v6.12/04\n - [BAT](https://github.com/bat/bat) ≥ v1.0.0 (with Cuba enabled)\n\n\u003e **Note**\n\u003e Pre-built container images with BAT and ROOT are available [on Docker Hub](https://hub.docker.com/repository/docker/gipert/bat/).\n\nThen just `PREFIX=/path/to/prefix make install`.\n\n### Usage\n\nThe `hmixfit` executable acceps a JSON config file as the only argument.\nExamples can be found in this repository under `config/`.\n\nThe JSON config file begins with some general settings:\n```js\n{\n    \"id\" : \"phIIAfterLAr\",       // model name\n    \"logging\" : \"summary\",       // BAT verbosity level, see manual\n    \"precision\" : \"kMedium\",     // precision (number and length of Markov chains), see BAT manual\n    \"output-dir\" : \"../results\", // folder with fit results\n    // ...\n```\nsettings about the global mode search algorithm:\n```js\n    \"global-mode-search\" : {\n        \"method\" : \"kOptMinuit\" // see the BAT manual to learn about the other algorithms\n    },\n```\nsettings about the numerical integration needed to compute the evidence:\n```js\n    \"integration\" : {\n        \"enabled\" : false,               // enable/disable the integration step\n        \"method\" : \"kIntCuba\",           // see the BAT manual to learn about the other algorithms\n        \"cuba-method\" : \"kCubaDivonne\",  // see the Cuba manual\n        \"integrator-settings\" : {\n            \"kIntCuba\" : {               // here you can tweak the Cuba integration settings\n                \"kCubaDivonne\" : {       // here for the Divonne algorithm\n                    \"niter-max\" : 1E07,\n                    \"niter-min\" : 0,\n                    \"flags\" : 0\n                },\n                \"kCubaVegas\" : {         // here for Vegas...\n                    // ...\n                }\n                // ...\n            }\n        }\n    },\n    // ...\n```\nsettings about the p-value determination\n```js\n    \"p-value\" : {\n        \"enabled\" : false,   // enable/disable the computation\n        \"iterations\" : 1E07  // play with this number until the p-value is stable\n    },\n```\nand finally the fit configuration section `\"fit\"`, where everything about the data and\nthe fit components is specified in a modular fashion:\n```js\n    // ...\n    \"fit\" : {\n        \"parameters\" : { /* ... */ },  // define fit parameters globally\n        \"theoretical-expectations\" : { /* ... */ }  // import PDFs and associated parameters\n    }\n}\n```\nLet's start with the `\"parameters\"` section, here the fit parameters must be defined:\n```js\n\"parameters\" : {\n    \"alpha-slope-bege\" : {  // unique internal name\n        \"range\" : [2E-5, 1E-4],\n        \"long-name\" : \"#alpha-model BEGe - slope\",\n        \"units\" : \"cts\",\n        \"prior\" : { \"histogram\" : \"priorfile.root:objname\" }  // specify prior via external TH1\n    },\n    \"alpha-offset-bege\" : {\n        \"range\" : [0, 1E-1],\n        \"long-name\" : \"#alpha-model BEGe - offset\",\n        \"units\" : \"cts\"\n        \"prior\" : { \"TFormula\" : \"gaus:1,10,5\" }  // specify prior via TFormula\n    },\n    \"background\" : {\n        \"fixed\" : 1234,  // parameters can be fixed to a value (not fit parameters anymore)\n        \"long-name\" : \"Background model\",\n        \"units\" : \"cts\"\n    },\n    // ...\n}\n```\nand then associated to PDFs in the `\"theoretical-expectations\"` section:\n```js\n\"theoretical-expectations\" : { // takes a list of files with data histograms\n    \"../data/gerda-data-bkgmodel-phaseII-v04.00-lar.root\" : {  // takes a list of object names in the file\n        \"M1_enrBEGe\" : {  // this is a 1D histogram\n            \"gerda-pdfs\" : \"../data/gerda-pdfs/v2.1\",  // set here the path to the gerda-pdfs, if you want\n            \"fit-range\" : [[560, 2014], [2064, 5300]],  // note the possibility to skip regions\n            \"rebin-factor\" : 5,  // fixed-size rebin\n            \"rebin-factor\" : \"560:10:700,700:20:900,1000:100:5300\",  // support for variable binning!\n            \"components\" : [  // here you must specify a list of PDFs you want to use\n                { /* ... */ }, { /* ... */ }, // ...\n            ]\n        },\n        \"M1_enrCoax\" : { /* ... */ },\n        \"M2_enrGe\" : {  // this is a 2D histogram\n            \"fit-range-x\" : [[560, 2014], [2064, 5300]],\n            \"fit-range-y\" : [700, 5300],\n            \"rebin-factor-x\" : 5,  // or just \"rebin-factor\" to rebin both axes\n            \"rebin-factor-y\" : 2,\n            \"components\" : [  // here you must specify a list of PDFs you want to use\n                { /* ... */ }, { /* ... */ }, // ...\n            ]\n        },\n        // ...\n    },\n    \"../data/gerda-data-bkgmodel-phaseII-v04.00-raw.root\" : { /* ... */ }\n    // ...\n}\n```\nthe keys in the `\"theoretical-expectations\"` dictionary must be paths to the\nfiles that contain histograms to be fitted (the data). Then for each of these\nfiles the user must specify what histograms (ROOT objects) the program should\ntry to fit. For every data histogram a list of fit components must be provided\nin the `\"components\"` array. The array is filled with JSON objects that can be\nof multiple types.\n\nAs instance, one might want to use the GERDA PDFs distributed within\n[gerda-mage-sim](https://github.com/mppmu/gerda-mage-sim) using the following\nstructure:\n```js\n{\n    \"gerda-pdfs\" : \"../data/gerda-pdfs/v2.1\"  // the gerda-pdfs path might be set here to override the global one\n    \"part\": \"cables/cables_all\",\n    \"components\" : {\n        \"Th228-cables\" : {  // this parameter name must be defined in the \"parameters\" section!\n            \"isotope\" : { \"Tl208-larveto\" : 0.3539, \"Bi212-larveto\" : 1 },  // specify a mixture of isotopes\n        },\n        \"Co60-cables\" : {\n            \"isotope\": \"Co60-run68pca\", // no mixture here\n            // ...\n        },\n        // ...\n    }\n},\n{\n    \"part\": {  // you can also specify a mixture of parts!\n        \"calib/single_s2_8220\" : 52183,\n        \"calib/single_s2_8408\" : 25337,\n        \"calib/single_s2_8570\" : 79868,\n        \"calib/single_s3_8220\" : 55438,\n        \"calib/single_s3_8405\" : 43433,\n        \"calib/single_s3_8570\" : 24130\n    },\n    \"components\" : { /* ... */ }\n}\n```\nor even provide manually a ROOT histogram:\n```js\n{\n    \"root-file\" : \"../data/gerda-pdfs/v2.0-RC/alphas/analytic/pdf-functions.root\",\n    \"components\" : {\n        \"alpha-offset\" : {\n            \"hist-name\" : \"flat\",\n        },\n        // ...\n    }\n},\n```\nor even a ROOT `TFormula` in the form `\"formula:par1,par2,...\"`:\n```js\n{\n    \"components\" : {\n        \"alpha-slope\" : {\n            \"TFormula\" : \"gaus:1,34,2\",\n        },\n        // ...\n    }\n},\n```\nLast but not least, observables that depend on the model parameters only can be\ndefined via JSON file with the following syntax:\n```js\n\"parameters\" : {\n    \"2nbb-half-life-bege\" : {  // unique internal name\n        \"TFormula\": \"1.13380E26/[2nbb-bege]\",  // ROOT's TFormula\n        \"multiply-fit-parameter-by-pdf-integral\" : {  // there's the possibility to multiply each parameter\n                                                      // above by the pdf integral in a range:\n                                                      // [2nbb-bege] -\u003e ([2nbb-bege]*Int)\n            \"range\" : [[10,19], [80,89]],  // range for the integral\n            \"dataset\" : \"h_data\"  // dataset pdf refers to\n        },\n        \"range\" : [2E-5, 1E-4],\n        \"long-name\" : \"T_{1/2}^{2#nu} - BEGe\",\n        \"units\" : \"cts\",\n    },\n    // ...\n```\nModel parameters must be specified as they were a `TFormula` parameter,\nenclosing their name in square brackets.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgipert%2Fhmixfit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgipert%2Fhmixfit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgipert%2Fhmixfit/lists"}