triggerflow 0.2.1__tar.gz → 0.2.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. {triggerflow-0.2.1 → triggerflow-0.2.2}/PKG-INFO +1 -1
  2. {triggerflow-0.2.1 → triggerflow-0.2.2}/pyproject.toml +1 -1
  3. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/trigger_loader/cluster_manager.py +3 -3
  4. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/trigger_loader/loader.py +55 -3
  5. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow.egg-info/PKG-INFO +1 -1
  6. {triggerflow-0.2.1 → triggerflow-0.2.2}/MANIFEST.in +0 -0
  7. {triggerflow-0.2.1 → triggerflow-0.2.2}/README.md +0 -0
  8. {triggerflow-0.2.1 → triggerflow-0.2.2}/setup.cfg +0 -0
  9. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/trigger_dataset/__init__.py +0 -0
  10. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/trigger_dataset/core.py +0 -0
  11. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/trigger_loader/__init__.py +0 -0
  12. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/trigger_loader/processor.py +0 -0
  13. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/__init__.py +0 -0
  14. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/cli.py +0 -0
  15. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/core.py +0 -0
  16. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/mlflow_wrapper.py +0 -0
  17. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/.gitignore +0 -0
  18. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/README.md +0 -0
  19. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/cookiecutter.json +0 -0
  20. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/prompts.yml +0 -0
  21. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/.dvcignore +0 -0
  22. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/.gitignore +0 -0
  23. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/.gitlab-ci.yml +0 -0
  24. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/README.md +0 -0
  25. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/conf/README.md +0 -0
  26. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/conf/base/catalog.yml +0 -0
  27. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/conf/base/parameters.yml +0 -0
  28. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/conf/base/parameters_compile.yml +0 -0
  29. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/conf/base/parameters_data_processing.yml +0 -0
  30. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/conf/base/parameters_load_data.yml +0 -0
  31. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/conf/base/parameters_model_training.yml +0 -0
  32. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/conf/base/parameters_model_validation.yml +0 -0
  33. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/conf/local/catalog.yml +0 -0
  34. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/conf/local/parameters.yml +0 -0
  35. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/conf/local/parameters_compile.yml +0 -0
  36. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/conf/local/parameters_data_processing.yml +0 -0
  37. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/conf/local/parameters_load_data.yml +0 -0
  38. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/conf/local/parameters_model_training.yml +0 -0
  39. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/conf/local/parameters_model_validation.yml +0 -0
  40. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/conf/logging.yml +0 -0
  41. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/data/01_raw/.gitkeep +0 -0
  42. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/data/01_raw/samples.json +0 -0
  43. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/data/01_raw/samples_dummy.json +0 -0
  44. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/data/02_loaded/.gitkeep +0 -0
  45. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/data/03_preprocessed/.gitkeep +0 -0
  46. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/data/04_models/.gitkeep +0 -0
  47. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/data/05_validation/.gitkeep +0 -0
  48. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/data/06_compile/.gitkeep +0 -0
  49. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/data/07_reporting/.gitkeep +0 -0
  50. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/dvc.yaml +0 -0
  51. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/environment.yml +0 -0
  52. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/pyproject.toml +0 -0
  53. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/src/{{ cookiecutter.python_package }}/__init__.py +0 -0
  54. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/src/{{ cookiecutter.python_package }}/__main__.py +0 -0
  55. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/src/{{ cookiecutter.python_package }}/datasets/any_object.py +0 -0
  56. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/src/{{ cookiecutter.python_package }}/datasets/base_dataset.py +0 -0
  57. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/src/{{ cookiecutter.python_package }}/datasets/meta_dataset.py +0 -0
  58. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/src/{{ cookiecutter.python_package }}/datasets/{{ cookiecutter.python_package }}_dataset.py +0 -0
  59. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/src/{{ cookiecutter.python_package }}/models/__init__.py +0 -0
  60. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/src/{{ cookiecutter.python_package }}/models/base_model.py +0 -0
  61. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/src/{{ cookiecutter.python_package }}/models/{{ cookiecutter.python_package }}_model.py +0 -0
  62. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/src/{{ cookiecutter.python_package }}/pipeline_registry.py +0 -0
  63. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/src/{{ cookiecutter.python_package }}/pipelines/compile/__init__.py +0 -0
  64. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/src/{{ cookiecutter.python_package }}/pipelines/compile/nodes.py +0 -0
  65. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/src/{{ cookiecutter.python_package }}/pipelines/compile/pipeline.py +0 -0
  66. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/src/{{ cookiecutter.python_package }}/pipelines/data_processing/__init__.py +0 -0
  67. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/src/{{ cookiecutter.python_package }}/pipelines/data_processing/nodes.py +0 -0
  68. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/src/{{ cookiecutter.python_package }}/pipelines/data_processing/pipeline.py +0 -0
  69. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/src/{{ cookiecutter.python_package }}/pipelines/load_data/__init__.py +0 -0
  70. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/src/{{ cookiecutter.python_package }}/pipelines/load_data/nodes.py +0 -0
  71. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/src/{{ cookiecutter.python_package }}/pipelines/load_data/pipeline.py +0 -0
  72. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/src/{{ cookiecutter.python_package }}/pipelines/model_training/__init__.py +0 -0
  73. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/src/{{ cookiecutter.python_package }}/pipelines/model_training/nodes.py +0 -0
  74. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/src/{{ cookiecutter.python_package }}/pipelines/model_training/pipeline.py +0 -0
  75. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/src/{{ cookiecutter.python_package }}/pipelines/model_validation/__init__.py +0 -0
  76. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/src/{{ cookiecutter.python_package }}/pipelines/model_validation/nodes.py +0 -0
  77. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/src/{{ cookiecutter.python_package }}/pipelines/model_validation/pipeline.py +0 -0
  78. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/src/{{ cookiecutter.python_package }}/settings.py +0 -0
  79. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/src/{{ cookiecutter.python_package }}/utils/__init__.py +0 -0
  80. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/src/{{ cookiecutter.python_package }}/utils/metric.py +0 -0
  81. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/src/{{ cookiecutter.python_package }}/utils/plotting.py +0 -0
  82. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/tests/__init__.py +0 -0
  83. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/tests/pipelines/__init__.py +0 -0
  84. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/tests/pipelines/compile/__init__.py +0 -0
  85. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/tests/pipelines/compile/test_pipeline.py +0 -0
  86. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/tests/pipelines/data_processing/__init__.py +0 -0
  87. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/tests/pipelines/data_processing/test_pipeline.py +0 -0
  88. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/tests/pipelines/load_data/__init__.py +0 -0
  89. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/tests/pipelines/load_data/test_pipeline.py +0 -0
  90. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/tests/pipelines/model_training/__init__.py +0 -0
  91. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/tests/pipelines/model_training/test_pipeline.py +0 -0
  92. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/tests/pipelines/model_validation/__init__.py +0 -0
  93. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/tests/pipelines/model_validation/test_pipeline.py +0 -0
  94. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/starter/{{ cookiecutter.repo_name }}/tests/test_run.py +0 -0
  95. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/templates/makefile +0 -0
  96. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/templates/makefile_version +0 -0
  97. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/templates/model_template.cpp +0 -0
  98. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow/templates/scales.h +0 -0
  99. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow.egg-info/SOURCES.txt +0 -0
  100. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow.egg-info/dependency_links.txt +0 -0
  101. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow.egg-info/entry_points.txt +0 -0
  102. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow.egg-info/requires.txt +0 -0
  103. {triggerflow-0.2.1 → triggerflow-0.2.2}/src/triggerflow.egg-info/top_level.txt +0 -0
  104. {triggerflow-0.2.1 → triggerflow-0.2.2}/tests/test.py +0 -0
  105. {triggerflow-0.2.1 → triggerflow-0.2.2}/tests/test_loader.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: triggerflow
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: Utilities for ML models targeting hardware triggers
5
5
  Classifier: Programming Language :: Python :: 3
6
6
  Classifier: License :: OSI Approved :: MIT License
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "triggerflow"
7
- version = "0.2.1"
7
+ version = "0.2.2"
8
8
  description = "Utilities for ML models targeting hardware triggers"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -4,9 +4,6 @@ import logging
4
4
  from typing import Any
5
5
 
6
6
  from dask.distributed import Client, LocalCluster
7
- from dask_cuda import LocalCUDACluster
8
- from dask_jobqueue import HTCondorCluster
9
- from dask_kubernetes import KubeCluster
10
7
 
11
8
  logger = logging.getLogger(__name__)
12
9
 
@@ -63,15 +60,18 @@ class ClusterManager:
63
60
  self.cluster = LocalCluster(**self.cluster_config)
64
61
 
65
62
  elif ct == "condor":
63
+ from dask_jobqueue import HTCondorCluster
66
64
  self.cluster = HTCondorCluster(**self.cluster_config)
67
65
  if self.jobs and self.jobs > 0:
68
66
  # Scale to the requested number of jobs
69
67
  self.cluster.scale(jobs=self.jobs)
70
68
 
71
69
  elif ct == "cuda":
70
+ from dask_cuda import LocalCUDACluster
72
71
  self.cluster = LocalCUDACluster(**self.cluster_config)
73
72
 
74
73
  elif ct == "kubernetes":
74
+ from dask_kubernetes import KubeCluster
75
75
  self.cluster = KubeCluster(**self.cluster_config)
76
76
  if self.jobs and self.jobs > 0:
77
77
  try:
@@ -45,8 +45,58 @@ class TriggerLoader:
45
45
  )
46
46
 
47
47
  def _load_sample_json(self, sample_json: str) -> dict:
48
+ """
49
+ Loads the JSON and resolves file paths using the priority:
50
+ 1. Explicit 'files' list or directory path (Local/Explicit)
51
+ 2. 'DAS' query (Remote Fallback)
52
+
53
+ Returns the canonical coffea fileset format: {dataset_name: [file_path_list]}.
54
+ """
55
+ import glob
56
+ import os
57
+
58
+ # Helper function definition needed here if it's not imported:
59
+ # def _fetch_files_from_das(das_query: str) -> list[str]: ... (placeholder or actual implementation)
60
+
48
61
  with open(sample_json) as f:
49
- return json.load(f)
62
+ full_data = json.load(f)
63
+ dataset_metadata = full_data.get("samples", full_data)
64
+
65
+ fileset = {}
66
+ for ds_name, ds_info in dataset_metadata.items():
67
+ files = []
68
+
69
+ if "files" in ds_info:
70
+ file_info = ds_info["files"]
71
+
72
+ if isinstance(file_info, list):
73
+ files = file_info
74
+
75
+ elif isinstance(file_info, str):
76
+ if os.path.isdir(file_info):
77
+ path_glob = os.path.join(file_info, "*.root")
78
+ files = glob.glob(path_glob)
79
+ logger.info(f"Resolved {len(files)} files from directory {file_info}.")
80
+ else:
81
+ files = [file_info]
82
+
83
+ if files:
84
+ logger.info(f"Using {len(files)} local/explicit files for {ds_name}.")
85
+
86
+ if not files and "DAS" in ds_info:
87
+ try:
88
+ files = _fetch_files_from_das(ds_info["DAS"])
89
+ logger.info(f"Resolved {len(files)} files via DAS for {ds_name}.")
90
+ except NameError:
91
+ logger.error("DAS fetching skipped: _fetch_files_from_das is not defined.")
92
+
93
+ if not files:
94
+ logger.warning(f"No files found for dataset: {ds_name}. Skipping.")
95
+ continue
96
+
97
+ fileset[ds_name] = files
98
+
99
+ return fileset
50
100
 
51
101
  def _write_run_metadata_file(self, path: str, duration_s: float | None = None):
52
102
  meta_path = f"{path}/run_metadata.json"
@@ -58,9 +108,11 @@ class TriggerLoader:
58
108
  json.dump(data, f, indent=2)
59
109
 
60
110
  def _run(self, runner: processor.Runner, label: str):
61
- logger.log(f"Starting processing ({label})...")
111
+ logger.log(logging.INFO, f"Starting processing ({label})...")
62
112
  start = time.time()
63
113
  proc = self._build_processor()
114
+ print(self.fileset)
115
+
64
116
  acc = runner(
65
117
  self.fileset,
66
118
  treename="Events",
@@ -68,7 +120,7 @@ class TriggerLoader:
68
120
  )
69
121
  elapsed = time.time() - start
70
122
  self._write_run_metadata_file(self.output_path, elapsed)
71
- logger.log(f"Finished in {elapsed:.2f}s (run_uuid={self.run_uuid})")
123
+ logger.log(logging.INFO, f"Finished in {elapsed:.2f}s (run_uuid={self.run_uuid})")
72
124
  return acc
73
125
 
74
126
  def run_distributed(self, cluster_type: str, cluster_config: dict,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: triggerflow
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: Utilities for ML models targeting hardware triggers
5
5
  Classifier: Programming Language :: Python :: 3
6
6
  Classifier: License :: OSI Approved :: MIT License
File without changes
File without changes
File without changes
File without changes