Releases: key4hep/k4FWCore
v01-03
v01-03
-
2025-05-27 Thomas Madlener (PR#317)
- Move the
DataHandle
andMetaDataHandle
into thek4FWCore
namespace to make origins more obvious- Keep deprecated
DataHandle
andMetaDataHandle
aliases in global namespace for compatibility to allow for a smoother migration
- Keep deprecated
- Move the
-
2025-05-26 Thomas Madlener (PR#321)
- Remove the usage of
PodioDataSvc
from theDataHandle
as it's not necessary - Harmonize the behavior of the constructors
- Remove the declaration of the unimplemented default constructor
- Remove the usage of
-
2025-05-21 jmcarcell (PR#306)
- Add a
--log-level
flag tok4run
to make it possible to configure the log level at runtime via the command line- accpeted values are
verbose
,debug
,info
,warning
anderror
- The log level will apply to the python logging facilities and will also be set in the
ApplicationMgr.OutputLevel
- accpeted values are
- Make the python logging a bit more informative by adding the log level as well as some module and function information to the message
- Deprecate the
--verbose
option in favor of--log-level=verbose
- Add a
-
2025-05-20 Thomas Madlener (PR#320)
- Remove the declaration of
DataHandle::getCollMetadataCellID
since the implementation has been removed long ago
- Remove the declaration of
-
2025-05-20 jmcarcell (PR#315)
- Bump the required version of podio. 1.3 is needed since #305 because of
edm4hep::DataTypes
andedm4hep::LinkTypes
- Bump the required version of podio. 1.3 is needed since #305 because of
-
2025-05-15 jmcarcell (PR#313)
- Use signal to stop immediately after receiving a SIGPIPE. Before, the output from k4run itself would always print and the pipe command (for example
| head
) would only be applied to the output from Gaudi. - Add a test that uses pipes
- Use signal to stop immediately after receiving a SIGPIPE. Before, the output from k4run itself would always print and the pipe command (for example
-
2025-05-13 jmcarcell (PR#305)
- Remove the hardcoded collections in the CollectionMerger, using AIDASoft/podio#761. This applies to all collections that are available in EDM4hep.
- Fix link collections that are currently not working since the data type name is not
edm4hep::...LinkCollection
butpodio::LinkCollection...
- Require a newer version of podio in the CMakeLists.txt
-
2025-05-05 jmcarcell (PR#304)
- Fix running algorithms with RNTuples as their input and add tests, not working before because the TTRee reader in podio was being used
- Add two tests to create an rntuple and read it
- Bump the required version of podio to 1.3 since the function
get_reader
in podio only has support for lists of files as an input after AIDASoft/podio#729
-
2025-04-30 jmcarcell (PR#307)
- Clean up several CMakeLists.txt files. For example, remove redundant calls to
find_package
. - Move python files that will be installed to a single place
- Clean up several CMakeLists.txt files. For example, remove redundant calls to
-
2025-04-29 Thomas Madlener (PR#308)
- Add some documentation about the
AlgTimingAuditor
and theTimelineSvc
to show how timing information can be obtained from Gaudi at different levels of details.
- Add some documentation about the
-
2025-03-27 Giovanni Marchiori (PR#299)
- Remove ICaloReadCellNoisMap interface since it provides the same functionality as INoiseConstTool
-
2025-03-18 jmcarcell (PR#297)
- Remove the deprecated
input
andoutput
properties for IOSvc
- Remove the deprecated
-
2025-03-07 Mateusz Jakub Fila (PR#288)
- Update
UniqueIDGenSvc
documentation and add example usage with a functional algorithm
- Update
-
2025-03-05 Mateusz Jakub Fila (PR#295)
- Replace
UniqueIDGenSvc
propertyThrowIfDuplicate
withCheckDuplicates
. The service will cache ids and check duplicates only ifCheckDuplicates
is set totrue
. It's enabled by default for the Debug builds.
- Replace
-
2025-03-05 Thomas Madlener (PR#290)
- Make the
PodioInput.collections
,IOSvc.CollectionNames
andReader.InputCollections
properties actually work like expected. They now properly limit the collections that are read and no other collections will be available. This requires building against podio > v1.2`, otherwiset the current behavior will be used, where collections that are not requested will still be available.
- Make the
-
2025-02-26 Mateusz Jakub Fila (PR#287)
- Use the same event and run type in
UniqueIDGenSvc
as inedm4hep::EventHeader
. Add generating id directly fromedm4hep::EventHeader
. This changes the ID values !
- Use the same event and run type in
-
2025-02-25 Mateusz Jakub Fila (PR#293)
- Fix typo in docs about migrating from
k4DataSvc
- Fix typo in docs about migrating from
-
2025-02-23 Mateusz Jakub Fila (PR#291)
- Fix fixture used in FunctionalMTFile test
-
2025-02-17 Thomas Madlener (PR#289)
- Bump the
cvmfs-contrib
github action to lastet versionv5
to fix caching issues.
- Bump the
-
2025-02-13 jmcarcell (PR#286)
- Add a dev3 workflow using the key4hep-build action
-
2025-02-12 jmcarcell (PR#284)
- Add LANGUAGES CXX to CMakeLists.txt to disable checks for a C compiler
-
2025-02-11 jmcarcell (PR#283)
- Add a Link collection to the tests
v01-02
v01-02
-
2025-02-04 jmcarcell (PR#282)
- Use typeid instead of
EDM4hep::typeName
since not every EDM4hep type has::typeName
.
- Use typeid instead of
-
2025-02-04 Mateusz Jakub Fila (PR#279)
- Fix algorithm properties related to
eventNumber
andrunNumber
to deduce their type
- Fix algorithm properties related to
-
2025-02-03 jmcarcell (PR#281)
- Improve the responsiveness of k4run by importing a Reader from podio only when it's needed.
-
2025-02-03 jmcarcell (PR#280)
- Make functional algorithms read
DataWrapper<podio::CollectionBase>
- Add a test producing a collection in a
DataWrapper<podio::CollectionBase>
and reading it in a functional algorithm
- Make functional algorithms read
-
2025-02-03 jmcarcell (PR#278)
- Fix compilation warning about comparing integers with different signs, related to key4hep/EDM4hep#398
-
2025-02-03 jmcarcell (PR#275)
- Make sure that the internal casts that happen for functional algorithms do not silently cast to wrong types.
-
2025-01-31 jmcarcell (PR#277)
- Use typeid to allow compiling functional algorithms that use Links
-
2025-01-31 Thomas Madlener (PR#276)
- Clean up the function that reads inputs in functional algorithms by defining an alias for the EDM4hep type and using that when possible. Remove
const
from this type and add it where needed. - Change
std::remove_cvref_t
tostd::remove_cv_t
since there the former is not needed.
- Clean up the function that reads inputs in functional algorithms by defining an alias for the EDM4hep type and using that when possible. Remove
-
2025-01-29 Thomas Madlener (PR#273)
- Make it possible to use
edm4hep::utils::ParticleIDMeta
with theMetadataSvc
- Add template specializations for
get
andput
that defer to the corresponding utility calls in EDM4hep - Add tests to ensure that metadata is indeed usable this way with the utilities in EDM4hep
- Add template specializations for
- Make it possible to use
-
2025-01-24 jmcarcell (PR#269)
- Improve the documentation about extending the parser for k4run
-
2025-01-16 tmadlener (PR#230)
- Configure the
k4FWCoreConfig.cmake
to put a bit more information in there- Make sure all dependencies are also found for dependent packages
- Make sure dependency versions are discovered again consistently
- Make sure to export the current k4FWCore version for downstream consumers
- Configure the
-
2025-01-09 jmcarcell (PR#270)
- Use CMake fixtures for tests that require other tests
- Tests will now run only if all the setup tests pass, otherwise they will be skipped
- Use CMake fixtures for tests that require other tests
-
2024-12-20 Thomas Madlener (PR#271)
- Remove an unnecessary r-value reference qualifier for sinking the metadata Frame into the
MetadataSvc
.
- Remove an unnecessary r-value reference qualifier for sinking the metadata Frame into the
-
2024-12-20 Mateusz Jakub Fila (PR#267)
- Added documentation for reading and writing EDM4hep files with the
IOSvc
- Moved documentation on
k4DataSvc
to legacy page
- Added documentation for reading and writing EDM4hep files with the
-
2024-12-18 jmcarcell (PR#264)
- Writer: Ignore objects that are not collections in the store and write an output Frame
- Add
const
where possible - Add
[[maybe_unused]]
to avoid a warning about not using the result of a.release()
(the warning is correct in most cases, in this case it's the Gaudi store who owns it). - Remove some code in the Writer that is not necessary.
- Add
- Writer: Ignore objects that are not collections in the store and write an output Frame
-
2024-12-10 jmcarcell (PR#265)
- Remove the check for TrackerHit3D from edm4hep
-
2024-12-09 jmcarcell (PR#263)
- Mark the DataHandle and DataWrapper destructors with override
-
2024-12-09 jmcarcell (PR#262)
- Write the configuration_metadata at initialize() in the Writer, to avoid having properties that are deleted because other algorithms are wrapped in a Sequencer and this Sequencer is deleted before
finalize()
is called for Writer. - Add tests for different combinations of old/functional algorithms and using PodioOutput or IOSvc and Writer.
- Write the configuration_metadata at initialize() in the Writer, to avoid having properties that are deleted because other algorithms are wrapped in a Sequencer and this Sequencer is deleted before
-
2024-12-04 jmcarcell (PR#261)
- Add missing test dependencies
-
2024-11-28 Wouter Deconinck (PR#257)
- Require podio 1.0.1 in CMake
-
2024-11-01 jmcarcell (PR#256)
- Update service retrieval after deprecations in Gaudi v39.1, see https://gitlab.cern.ch/gaudi/Gaudi/-/merge_requests/1637
- Throw when it's not possible to retrieve ApplicationMgr - it should not happen
-
2024-10-30 Mateusz Jakub Fila (PR#252)
- Added thread-safe
EventCounter
algorithm
- Added thread-safe
v01-01-02
v01-01-02
-
2024-10-29 jmcarcell (PR#253)
- Fix DataHandle::get() for non-collection types and remove dead code. A
reinterpret_cast
was changed tostatic_cast
in #250 that made it fail at compile time for non-collection types. Now thestatic_cast
is properly wrapped around anif constexpr
and code around it has been deleted since it looked impossible to trigger.
- Fix DataHandle::get() for non-collection types and remove dead code. A
-
2024-10-28 jmcarcell (PR#254)
- Don't add duplicated options for ToolSvcs
v01-01-01
v01-01-01
-
2024-10-28 jmcarcell (PR#250)
- Use
std::unique_ptr<podio::CollectionBase>
for the collections in the store instead ofstd::shared_ptr<podio::CollectionBase>
. - Fix leak in the
Writer
that otherwise would have been difficult to fix (without the change above) - Clean up
FunctionalUtils.h
: remove some unused overloads and change some names.
- Use
-
2024-10-17 jmcarcell (PR#251)
- Use size_t in the arguments for getting the input and output locations to remove warnings, and fix some comments
-
2024-10-15 jmcarcell (PR#247)
- Overhaul the
UniqueIDGenSvc
:- Use bit manipulation with the
UniqueIDGenSvc
which is about 1000 times faster than the string manipulation that was being done - Add a check for the case where an ID is repeated - trying to catch the case where the event number and run number is always the same, then the same random number sequence will be generated.
- Use bit manipulation with the
- Overhaul the
-
2024-10-09 jmcarcell (PR#244)
- Update README: remove note about GaudiAlg being outdated since it's not there anymore and Use Key4hep instead of Key4HEP
v01-01
v01-01
-
2024-10-03 jmcarcell (PR#243)
- Fix overwritting the input file for IOSvc from the command line. The k4FWCore wrapper of the ApplicationMgr checks the number of events (needed for multithreading) and if the file exists but this was happening right after the parsing of the file, without taking into account the input file can be overwritten from the command line.
- Add a test where the input file is being overwritten from the command line
-
2024-10-01 jmcarcell (PR#233)
- Use podio::Reader and podio::Writer with IOSvc, so that it is easy to write TTrees or RNTuples by changing the
IOType
parameter given toIOSvc
in the steering file.
- Use podio::Reader and podio::Writer with IOSvc, so that it is easy to write TTrees or RNTuples by changing the
-
2024-09-30 jmcarcell (PR#242)
- Add a docstring for the function that adds the arguments
- Remove dead code, obvious comments and global variables
- Use f-strings
- Fix arguments when a property is a std::vector. Related to this fix now
k4run
will also display properties for which the default value is an empty list, previously these were not displayed. - Improve formatting of the message with all the values of all the properties
-
2024-09-29 Leonhard Reichenbach (PR#207)
- Ensure ROOT is in batch mode by setting
gROOT.SetBatch(True)
ink4run
- Ensure ROOT is in batch mode by setting
-
2024-09-26 jmcarcell (PR#236)
- Add an argument for add_test_with_env not to have to repeat the test names
- Also add some documentation for the function since it's getting complicated
-
2024-09-25 jmcarcell (PR#239)
- Fix histograms for Gaudi v39. After https://gitlab.cern.ch/gaudi/Gaudi/-/merge_requests/1586 the "old" histograms are renamed to
StaticRootHistogram
fromRootHistogram
- Add a configurable histogram:
RootHistogram
, whose bins, title and other properties can be set from python as shown in the test file
- Fix histograms for Gaudi v39. After https://gitlab.cern.ch/gaudi/Gaudi/-/merge_requests/1586 the "old" histograms are renamed to
-
2024-09-20 jmcarcell (PR#237)
- Assign to a const char* when using std::getenv
-
2024-09-17 Mateusz Jakub Fila (PR#223)
- Added tests reading metadata from input file
- Fixed accessing input file metadata in MetadataSvc
-
2024-09-16 jmcarcell (PR#234)
- Add the possibility of starting from the Nth event instead of the first one with the argument
FirstEventEntry
toIOSvc
. - Add a test that ignores some events.
- Add the possibility of starting from the Nth event instead of the first one with the argument
-
2024-09-12 Mateusz Jakub Fila (PR#224)
- Fixed data race in
EventHeaderCreator
and make it ready for GaudiHive
- Fixed data race in
-
2024-09-10 jmcarcell (PR#235)
- Use the Key4hepConfig flag to set the standard, compiler flags and rpath magic.
-
2024-09-05 jmcarcell (PR#232)
- Remove a few unused properties that do not exist anymore or belong to GaudiAlg which is not being built
-
2024-09-05 jmcarcell (PR#213)
- Fail if
IOSvc
orApplicationMgr
are not imported withfrom k4FWCore import IOSvc
(it can be imported fromConfigurables
). The python wrapper in k4FWCore does a few minor things and importing fromConfigurables
doesn't fail currently and can lead to hard to solve issues. - Add an error message when reading a file without the
events
category. Currently it fails with an error in python that is not very clear. - Use
Input
andOutput
for IOSvc, deprecateinput
andoutput
since all the other properties are capitalized. The same forIOType
instead ofioType
. This will print a warning about a duplicated property that should be ignored for now. - Suppress two warnings about using external input when using the default
EventLoopMgr
. - Import
ApplicationMgr
always fromk4FWCore
- Fail if
-
2024-09-04 Mateusz Jakub Fila (PR#231)
- Fixed missing checks for accessing metadata with
MetaDataHandle
when used withIOSvc
- Fixed missing checks for accessing metadata with
-
2024-09-02 Mateusz Jakub Fila (PR#228)
- fixed virtual specifiers, removed redundant methods, uncluttered code
-
2024-08-26 jmcarcell (PR#222)
- Fix warnings when warnings are enabled. Warnings will be enabled later.
-
2024-08-23 Mateusz Jakub Fila (PR#227)
- fixed typos
- updated the usage example in readme
-
2024-08-09 jmcarcell (PR#221)
- Fix wrong error message when using std::map as input or output with transformers
-
2024-08-09 jmcarcell (PR#220)
- Use Links instead of Associations
-
2024-08-08 jmcarcell (PR#215)
- Add a metadata service that is automatically added when importing
IOSvc
fromk4FWCore
, if no metadata is added then the service won't do anything. If metadata is added, the metadata service will hold apodio::Frame
with the metadata that theWriter
will write. The metadata service only works when there is an output file. - Add a test showing an example of its usage
- Make changes in the
MetadaHandle
to make it possible to save and read metadata from DataHandle-based algorithms, so that when switching toIOSvc
metadata for existing DataHandle algorithms will keep working. Add a test using IOSvc with DataHandle algorithms that write and read metadata.
- Add a metadata service that is automatically added when importing
-
2024-08-07 jmcarcell (PR#218)
- Remove a few unnecessary includes
-
2024-07-30 tmadlener (PR#217)
- Add the legacy
AssociationCollection
headers to keep things building after key4hep/EDM4hep#341 has been merged
- Add the legacy
-
2024-07-26 jmcarcell (PR#206)
- Delete the version checks before Podio 1.0
-
2024-07-25 Giovanni Marchiori (PR#214)
- renamed NoiseConstant by NoiseRMS in the noise interfaces (ICaloReadCellNoiseMap, INoiseCaloCellsTool.h and INoiseConstTool.h) to make its physical meaning clearer
-
2024-07-25 jmcarcell (PR#210)
- Add a filter algorithm, using the
PredicateFilter
algorithm from Gaudi. - Add the minimum handle needed to be able to use the filter from Gaudi and make it work with the rest of the functional algorithms
- Add a test using this filter
- Add a filter algorithm, using the
-
2024-07-19 jmcarcell (PR#209)
- Add an algorithm for merging collections that can merge any number of collections into a new one of the same type. The algorithm supports either creating a subset collection (default) or cloning every object in the collection.
- Add a test using this algorithm to merge a few collections
-
2024-07-15 jmcarcell (PR#208)
- Add a new test producing histograms, making use of the corresponding service in Gaudi
- Improve comments and descriptions in tests
-
2024-07-15 jmcarcell (PR#201)
- FunctionalAlgorithms: Use std::vector instead of std::map for input or output an arbitrary number of collections.
- Add an
inputLocations
andoutputLocations
methods to be able to retrieve the locations set in the steering file.
-
2024-06-27 tmadlener (PR#205)
- Remove some of the drift chamber datatypes again as they are going to disappear in EDM4hep with EDM4hep#333
-
2024-06-27 tmadlener (PR#204)
- Remove the
MCRecoTrackerHitPlaneAssociation
since it has been / will be removed from EDM4hep in EDM4hep#331
- Remove the
-
2024-06-25 jmcarcell (PR#203)
- Try to find podio 1.0 if the version found is not compatible
-
2024-06-24 jmcarcell (PR#202)
- Don't use
radiusOfInnermostHit
from EDM4hep tracks
- Don't use
-
2024-06-18 jmcarcell (PR#200)
- Use
edm4hep::labels
- Use
-
2024-06-05 tmadlener (PR#199)
- Remove the
rootUtils.h
header that has been copied from podio since it has become obsolete with #171
- Remove the
-
2024-06-05 tmadlener (PR#195)
- Make
MetaDataHandle::get
throw an exception in case the value for the handle is not (yet) available. - Add
MetaDataHandle::get(T defaultValue)
overload to get a default value and no exception in case the value is not (yet) available. - Add
MetaDataHandle::get_optional()
to retrieve an optional that is engaged and holds the value if the handle already has a value available.- The optional is returned directly from the underlying Frame in case that is available (see AIDASoft/podio#580) or is constructed in place in case it is not yet available.
- Make
-
2024-05-29 jmcarcell (PR#197)
- Remove unnecessary messages (IOSvc saying at which entry we are when reading a file and an error message when a cast doesn't work, which is foreseen and will always happen when a functional algorithm reads something generated by the "old" algorithms), one of them an error message that is not an error
...
- Remove unnecessary messages (IOSvc saying at which entry we are when reading a file and an error message when a cast doesn't work, which is foreseen and will always happen when a functional algorithm reads something generated by the "old" algorithms), one of them an error message that is not an error
v01-00pre19
What's Changed
- update sliding-window clustering for Theta-Module readout by @dasphy in #158
- Remove the deprecated lcdd() from GeoSvc Interface by @kjvbrt in #176
- Clean up the build workflows by @jmcarcell in #179
New Contributors
Full Changelog: v01-00pre18...v01-00pre19
v01-00pre18
What's Changed
- Fix issue with narrowing by @jmcarcell in #167
- Add documentation for k4run custom arguments by @Zehvogel in #169
- PodioInput: Read all collections by default, allow to limit them with the
collections
property by @tmadlener in #162 - Remove the legacy component that depend on the podio EventStore by @tmadlener in #171
Full Changelog: v01-00pre17...v01-00pre18
v01-00pre17
What's Changed
- Improvements to k4run by @jmcarcell in #93
- Make type names string_view safe by @tmadlener in #108
- Rename SubDetectorHitNumbers -> SubdetectorHitNumbers by @jmcarcell in #111
- Fix test dependency by @jmcarcell in #112
- Fix crash without arguments by @jmcarcell in #110
- Fix compilation with gcc13. by @scott-snyder in #113
- add new frame based podio interface by @hegner in #100
- Add a temporary workaround for k4MarlinWrapper by @jmcarcell in #115
- Fix pre-commit workflow to actually run by @tmadlener in #116
- Fix segfault when trying to read potentially non-existant category by @tmadlener in #118
- Fix DataHandle to work as expected when used with LegacyDataSvc by @tmadlener in #117
- Rename
CMAKE_{SOURCE,BIN}_DIR
toPROJECT_{SOURCE,BIN}_DIR
by @jmcarcell in #120 - Rename
CMAKE_BINARY_DIR
toPROJECT_BINARY_DIR
by @jmcarcell in #121 - Introduce a quick workaround for collection metadata creation by @tmadlener in #119
- Make MetaDataHandle handle all keys correctly by @tmadlener in #124
- Fix k4run -l by @jmcarcell in #126
- Remove LIKELY and UNLIKELY by @jmcarcell in #130
- Remove a call of the DataWrapperBase constructor by @jmcarcell in #128
- Setting RPATH by @kjvbrt in #99
- k4run: allow addition of additional parameters from steering files by @Zehvogel in #134
- k4run: add missing import for VERBOSE by @kjvbrt in #137
- Allow help without config file by @kjvbrt in #135
- Keep looping through configurables by @kjvbrt in #138
- Add Apache License by @andresailer in #127
- Add LICENSE file explicitely by @andresailer in #139
- k4run: fix more bugs by @Zehvogel in #140
- k4run: return exit code 0 if
-n -1
was used and Gaudi returned exit code 4 by @Zehvogel in #132 - Change finding of EDM4hep, ROOT and podio to use generator expressions by @jmcarcell in #122
- Fix clang warnings by adding final by @jmcarcell in #143
- Remove init.sh by @jmcarcell in #144
- Add a Gaudi Algorithm filling EventHeader eventNumber and runNumber by @BrieucF in #133
- IGeoSvc: add constantAsString accessor by @andresailer in #142
- Adapt to new optional return values from collID table by @tmadlener in #146
- Use Gaudi::Functional, add examples and adapt PodioInput to use Gaudi::Functional by @jmcarcell in #129
- Add a how-to page for using podio in-/output by @tmadlener in #149
- Allow compiling with C++20 by @jmcarcell in #151
- Add edm4hep::EventHeaderCollection to the list of clasess that can be used with Gaudi::Functional by @jmcarcell in #152
- Clean up the CMakeLists.txt for tests by @jmcarcell in #153
- Use genConfDir in the paths by @jmcarcell in #154
- Use the new edm4hep::CellIDEncoding by @jmcarcell in #157
- PodioInput: always read EventHeader by @Zehvogel in #160
- Clean up and rewrite the tests in cmake by @jmcarcell in #155
- Make PodioOutput exit gracefully instead of crashing by @tmadlener in #159
- Make "always read EventHeader" collection more robust by @tmadlener in #161
- Switch from push_back to variadic create in examples by @tmadlener in #165
New Contributors
- @scott-snyder made their first contribution in #113
- @Zehvogel made their first contribution in #134
Full Changelog: v01-00pre16...v01-00pre17
v01-00pre16
What's Changed
- Couple of interface changes by @gartrog in #86
- Add clang-format config and basic pre-commit workflow by @tmadlener in #87
- Fix a deprecation warning by @jmcarcell in #91
- ci: use gcc11 for dev3 workflow by @vvolkl in #92
New Contributors
- @gartrog made their first contribution in #86
- @jmcarcell made their first contribution in #91
Full Changelog: v01-00pre15...v01-00pre16
v01-00pre15: Add UniqueIDGenSvc
What's Changed
- Add Gaudi Service to generate Unique IDs based on event number, run number and Gaudi Algorithm by @fdplacido in #80
- Add comments for uniqueID svc by @fdplacido in #83
- Gaudi v36r5 removes SetRead in DataHandle by @vvolkl in #85
- Add documentation on how to use uniqueidgensvc by @fdplacido in #84
Full Changelog: v01-00pre14...v01-00pre15