-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] : preliminary datamodels for SDD bank #103
Conversation
- Change SDD datamodels 'architecture' - Remove Sim Digi event data and readout data. - Architecture is : 1 SDD is composed by 3 collection : - collection of calo digitized hits - collection of tracker digitized hits - collection of trigger data
Hi @goliviero, many thanks for starting this. I'll have some further comments once I've had a chance to look through things in more detail. In the meantime, could you review the formatting of the code, e.g. The use of tabs/8 spaces for indent is slightly too big (see https://github.com/SuperNEMO-DBD/Falaise/blob/develop/source/falaise/version.h.in and https://github.com/SuperNEMO-DBD/Falaise/blob/develop/source/falaise/version.c for the recommended layout), but more importantl is to keep things lined up! |
- Also fix indentation
{ | ||
itcalo->get().tree_dump(); | ||
} | ||
|
||
datatools::data_writer writer("test_snemo_datamodel_sim_digi_data.xml", | ||
datatools::using_multi_archives); | ||
writer.store(sddWrite); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test is broken during the READ (not the store). The code compiles but, here is the error during execution :
[fatal:int main(int, char**):45] [void datatools::data_reader::basic_load(Data&) [with Data = snemo::datamodel::sim_digi_data]:684: input stream error]
So I add a new handle to the calorimeter collection and then take the reference to the calo hit in order to update it. I do it 3 times for 3 calo. Then I push back them in the calorimeter collection. The store method of the writer works because it produce the file.
The execution error happens during the reader.read(sddReadback)
. I don't understand why the reader can not read and restore the snemo::datamodel::sim_digi_data
object.
Fun fact : the test works at execution if I push back only 1 handle (so with 1 calo_digi hit).
So help is needed here !
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Error found : it was because of boost::serialization on uninitialized boolean. It can store boolean even if the value is not 0 or 1 but it can not load / restore the value and it threw an exception.
In the source code of boost serialization it says :
// trap usage of invalid uninitialized boolean which would
// otherwise crash on load.
But the error is not manage here during the store, only in the load. Maybe an 'error' is made in boost because it should manages this error during the storage.
/// Constructor | ||
sim_calo_digi_hit(); | ||
/// \brief Simulated calo digitized hit. | ||
class sim_calo_digi_hit : public mctools::digitization::sampled_signal |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given the simplicity of this data (I'm going from RDD/SDD
in DocDB-4612), could the inheritance be replaced with composition here, e.g.
class sim_calo_digi_hit {
...
private:
geomtools::geom_id geomID_;
geomtools::geom_id elecID_;
...
std::vector<int16_t> waveform; // maybe even std::array if size known
... sample frequency etc?
};
Or, if attributes go along with the waveform, then define an additional struct to organise this? The mctools
object brings a lot of complexity the requirement for which is not obvious yet. Composition can also make persistency easier, and schema evolution more robust.
sim_digi_data::~sim_digi_data() | ||
{ | ||
return; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No return
needed.
_tracker_digi_hits_.clear(); | ||
_trigger_data_.clear(); | ||
_auxiliaries_.clear(); | ||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The clear()
calls are superfluous here I think, as the implicit default construction should create the necessary initialization.
The return
is also superfluous.
_trigger_data_.clear(); | ||
_auxiliaries_.clear(); | ||
return; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the rationale (use cases) for resetting the data? Should data, once created, be read-only?
|
||
private: | ||
|
||
datatools::properties _auxiliaries_; //!< Auxiliary properties |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please explain the purpose and use cases of this data member. What data does it represent?
{ | ||
return; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As in other places, default construction (even the C++11 = default
mechanism) should be sufficient here, and return
s are pointless code.
reset_cathode_R5(); | ||
reset_cathode_R6(); | ||
return; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As with the calo data, what is the rationale and use cases for reseting the data here? Why would it change later?
_elec_id_ = a_gid; | ||
return; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, surely an electronic id is really an invariant of the instance once created? Why would it change after the data is created?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I want to keep this interface for EID because a sim_tracker_digi_hit
can be created with a given GID and then the EID will be set once the GID has been converted into an EID by the electronic mapping.
A sim_tracker_digi_hit
and a sim_calo_digi_hit
have 2 geomtools::geom_id
:
- A Geometric ID (cell ID with Module/Row/Layer etc... for example)
- And an Electronic ID (channel ID with : Crate:Board:Feast:Channel)
It is useful to have these 2 IDs during the digi process and maybe it will be useful later so we store them both
DT_THROW_IF(!has_anode_R0(), std::logic_error, "Missing anode t0"); | ||
return _anode_R0_; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm confused by this "store mask" pattern for each timestamp. The class provides an INVALID_TIME
constant used as a marker of an unmeasured/bad value, why not just use this and let the client of the data decide what to do? The has_XXX
interfaces can then go (same for the reset
) and, the get_/set_
methods are simplified.
I don't think the get_...
should they and throw exceptions. The presence of invalid data isn't an "execeptional" case here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, the value should be stored even if it's an invalid time. The invalid time is an information.
And it will garanty that there are 7 times recorded even if there is no data.
I'll remove the DT throw too because we want to access to timestamps even if they are invalid
static const int16_t OVERFLOW_TIME = std::numeric_limits<int16_t>::min() + 1; | ||
static const int16_t UNDERFLOW_TIME = std::numeric_limits<int16_t>::max(); | ||
/// \brief Simulated tracker digitized hit. | ||
class sim_tracker_digi_hit : public geomtools::base_hit |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As with the calo, I think simple composition rather than inheritance should be explored here. Can inheritance from base_hit
be replaced by a "geom_id" data member?
- Fix failing test. Have to initialized boolean for boost serialization - Sim calo and tracker hits should inherit from a geomtools base hit conceptually - Sim calo digi hit embeded a vector representing the waveform. The size is not static so it is a vector and not an array
- Also fill the serialization part
@goliviero, just to note and cross-reference #110 here. We are seeing some issues with Bayeux/Boost serialization with clang. Please ensure that comprehensive serialize/deserialize tests are provided to see if these objects are affected. |
Closing due to lack of response |
Changes proprosed in this pull request:
Does this pull request fix any reported issues?
Additional comments or information
Work is still in progress and can change and evolve later.
PR is open in order to track commits and evolution.
Feedback is required and code can be update.