def data_reduction(instrument): log.info(f"data_reduction: {instrument}") config = AnalysisConfig.read(f"config.yaml") config.observations.datastore = f"$JOINT_CRAB/data/{instrument}" config.datasets.stack = instrument_opts[instrument]['stack'] config.datasets.containment_correction = instrument_opts[instrument][ 'containment'] config.datasets.on_region.radius = instrument_opts[instrument]['on_radius'] analysis = Analysis(config) analysis.get_observations() analysis.get_datasets() # TODO remove when safe mask can be set on config if instrument is 'fact': from gammapy.datasets import SpectrumDatasetOnOff stacked = SpectrumDatasetOnOff.create( e_reco=analysis.datasets[0]._energy_axis.edges, e_true=analysis.datasets[0]._energy_axis.edges, region=None) for ds in analysis.datasets: ds.mask_safe[:] = True stacked.stack(ds) analysis.datasets = Datasets([stacked]) analysis.datasets.write(f"reduced_{instrument}", overwrite=True)
def run_analysis(method, target_dict, debug): """If the method is "1d", runs joint spectral analysis for the selected target. If instead it is "3d", runs stacked 3D analysis.""" tag = target_dict["tag"] log.info(f"Running {method} analysis, {tag}") path_res = Path(tag + "/results/") log.info("Reading config") txt = Path(f"config_{method}.yaml").read_text() txt = txt.format_map(target_dict) config = AnalysisConfig.from_yaml(txt) if debug: config.observations.obs_ids = [target_dict["debug_run"]] config.flux_points.energy.nbins = 1 if method == "3d": config.datasets.geom.axes.energy_true.nbins = 10 analysis = Analysis(config) log.info("Running observations selection") analysis.get_observations() log.info(f"Running data reduction") analysis.get_datasets() # TODO: This is a workaround. We should somehow apply the safe mask (run by run) from the HLI from gammapy.cube import SafeMaskMaker datasets = [] maker_safe_mask = SafeMaskMaker(methods=["edisp-bias", "bkg-peak"], bias_percent=10) for dataset in analysis.datasets: dataset = maker_safe_mask.run(dataset) datasets.append(dataset) analysis.datasets = datasets log.info(f"Setting the model") txt = Path("model_config.yaml").read_text() txt = txt.format_map(target_dict) log.info(txt) analysis.set_models(txt) if method == "3d" and target_dict["spatial_model"] == "DiskSpatialModel": analysis.models[0].spatial_model.e.frozen = False analysis.models[0].spatial_model.phi.frozen = False analysis.models[0].spatial_model.r_0.value = 0.3 log.info(f"Running fit ...") analysis.run_fit() # TODO: This is a workaround. Set covariance automatically results = analysis.fit_result names = ["spectral_model", "spatial_model"] for name in names: if name == "spatial_model" and method == "1d": continue model = getattr(analysis.models[0], name) model.parameters.covariance = results.parameters.get_subcovariance( model.parameters.names) log.info(f"Writing {path_res}") write_fit_summary(analysis.models[0].parameters, str(path_res / f"results-summary-fit-{method}.yaml")) log.info(f"Running flux points estimation") # TODO: For the 3D analysis, re-optimize the background norm in each energy # bin. For now, this is not possible from the HLI. analysis.get_flux_points(source=tag) flux_points = analysis.flux_points.data flux_points.table["is_ul"] = flux_points.table["ts"] < 4 keys = [ "e_ref", "e_min", "e_max", "dnde", "dnde_errp", "dnde_errn", "is_ul", "dnde_ul", ] log.info(f"Writing {path_res}") flux_points.table_formatted[keys].write(path_res / f"flux-points-{method}.ecsv", format="ascii.ecsv")