Conversation
|
Example usage |
|
@tgiani could you perhaps test this running some kind of fit. |
|
A test case that didn't work and works now is |
|
@scarrazza @scarlehoff the fit failure doesn't seem my fault. Would you have a look? |
|
Interesting, the fit is in the server. How long does it take the server to update the list of fits? Maybe it would be good to add a few seconds of sleep to avoid race conditions there? @scarrazza |
|
I think there is some bug in the script which updates the json containing the list of fits, sometimes I had to restart it manually. @Zaharid any idea? |
|
Open a new issue describing the problem and I'll have a look. In any case there is #223 |
| raise ValueError("Expecting cuts to be the same for all datasets") | ||
| self.inputs = inputs | ||
| self.threshold = threshold | ||
| super().__init__(self.inputs, self.threshold) |
There was a problem hiding this comment.
@Zaharid just a general question about why we are inheriting from TupleComp here and in the other related classes because I can't see anywhere where the methods from TupleComp are used?
There was a problem hiding this comment.
The methods of TupleComp mean, amongst other things, that the subclasses are hashable. For example you can initiate two such classes with the same arguments and you will see that they are equal. See with PDF:
>>> from validphys.core import PDF
>>> pdf1 = PDF("foo")
>>> pdf2 = PDF("foo")
>>> pdf1 == pdf2
TrueWhich is useful because as far as we are concerned in this case a PDF is fully defined by its name (there should only be one NNPDF31_nnlo_as_0118 and that's all I need to know to get the correct pdf from the LHAPDF share folder).
Answering where this gets used: probably by the reportengine resource builder at some point to find unique dependencies (but I don't know - Zahari can answer). However, also all the classes which have their load method decorated with @functools.lru_cache must be hashable because the lru_cache stores the result of calling a function with a set of arguments, and so to check if it already cached the result you need to be able to see whether the arguments are actually the same. Since load always takes self as the first positional, you need to be able to check that self is indeed the same for two subsequent calls, which TupleComp facilitates.
There is also another double underscore method which means that classes print nicely:
>>> pdf1
PDF(name='foo')There was a problem hiding this comment.
Oh and I should say by default the first thing I said isn't the case:
>>> class TestClass:
... def __init__(self, a, b): self.a = a; self.b = b
...
>>> cls1 = TestClass(1, 2)
>>> cls2 = TestClass(1, 2)
>>> cls1 == cls2
FalsePerhaps I misunderstood something but that's my understanding anyway
There was a problem hiding this comment.
TupleComp is mostly a simpleminded attempt to implement something like dataclasses from the standard library, before they existed (and with only the required properties). I would probably use that nowadays, despite some unwelcome complexity (and in fact this is done in various newer interfaces already such as the fkparser). Note there is #408.
wilsonmr
left a comment
There was a problem hiding this comment.
I can't help but feel like the cuts should be an explicit node because there is a lot of functionality in the production rule.
The main hurdle is that loading data with the similarity cuts would require matched cuts -> dataset with matched cuts -> similarity cuts -> dataset with similarity cuts.
I suppose this could be achieved by creating a prod rule which set use_cuts: fromintersection, then collected the dataset over that and then the similarity cuts would take that as input. I'm not sure in the end whether this would actually make the code better but since the original comment talks about discussing a more reportengine idiomatic way of doing this, that's the best I can come up with.
This was the first thing I tried and found it to be unworkable, even with some pretty ideal version of reportengine that was designed to handle explicit nodes from the start. There is a bigger problem, namely that at the moment we have I think in order to have this behaviour one would need to be able to say: "I want this node to be attached to all the nodes where production rules containing |
Right, I hadn't even thought of that! Ok well from my perspective this gets an approval, subject to the test fits. |
|
As a side note, a possible workaround is to give nodes the ability to present themselves as "fake compiletime objects" that is useful for check purposes. Would also be useful in a context like: Then every production rule touched by this would become nodes that set themselves as "fake". |
|
Greetings from your nice fit 🤖 !
Check the report carefully, and please buy me a ☕ , or better, a GPU 😉! |
|
@scarlehoff I am confused, should I expect any differences at all here? |
|
This is why I did #1025, to reduce a bit the fluctuations, the change to 1.37 is expected. |
|
Right. So it seems that this needs to be tweaked a bit: specifically it should look at the ratio between the difference in predictions and the experimental uncertainty. This could be done with pretty much the same structure but changing the .load() function. |
|
This is even more complicated: We need different data specifications for the NLO and NNLO namespace, because of the cfactors. |
|
Right, this is not going to be particularly pretty (example runcard https://vp.nnpdf.science/5m_N3Dl-SAO9W__2rvlIrw==/input/runcard.yaml) and certainly not fast, but it works in a reproducible way. |
Add a cut option that throws away data such that predictions two different namespaces are too different, specifically that do not fulfill (threshold < ratio) & (ratio < 1/threshold) where the threshold is set as the `cut_similarity_threshold` parameter in the runcard. The two namespaces are defined as thee cuts_intersection_spec list. Some discussion: - This isn't the smartest code I have ever written. - The use of central_predictions inside load is a bit of a hack, but it is not clear to me it can be done much better in a more "reportengine idiomatic" style. The logic is rather convoluted if you sit down to think about it. In any case validphys.convolution is too convenient for this to use anything else. - Moreover central_predictions is slow because it needs to load fktables as csv. We should probably stick calls lru_cahces in various places. - Tests and documentation are missing at the moment.
Use from_: None with the right namespace override instead of calling the production rule directly. There are a few reasons for this: - The rather trivial problem that the cut_similarity_threshold parameter was not propagated because it was not being passed to the function call. The alternative would have been to add the parameter everywhere `cuts` is required. - The more serious problem that we do want to resolve things like dataset with some funky namespace settings. For this to work properly we need to execute the production rule withing the right context, namely one containing the relevant dataset_input within each experiment/data_input. Alternatives are not clear since the construction of `dataset` for the similarity cuts requires inspecting for the cuts.
Trust automated mechanisms to resolve each dataset given the correct context instead of resolving some dependencies manually for no particular reason. This also allows to clean up the signatures. Take advantage of the code to process `data` for the handling of experiments.
Co-authored-by: wilsonmr <33907451+wilsonmr@users.noreply.github.com>
Read datasets from a dataset_inputs list defined for each of the namespaces. Currently this is much slower that it could (since we are parsing the list every time) but I cannot think of a good way of doing it quickly.
| ): | ||
| _, ds = self.parse_from_(None, "dataset", write=False) | ||
| _, pdf = self.parse_from_(None, "pdf", write=False) | ||
| print(ds, ds.fkspecs[0].cfactors) |
There was a problem hiding this comment.
you seem quite determined to include a print here
| di = next(d for d in dins if d.name == name) | ||
| except StopIteration as e: | ||
| raise ConfigError( | ||
| f"cuts_intersection_spec dataset inputs must define {name}" |
There was a problem hiding this comment.
Seeing as the input is quite long and a bit hard to parse, I wonder if we enumerated the namespaces and told them which one was raising this error it might help?
| ns=self._curr_ns.new_child( | ||
| { | ||
| "dataset_input": di, | ||
| "use_cuts": CutsPolicy.FROM_CUT_INTERSECTION_NAMESPACE, |
There was a problem hiding this comment.
can we not just set the "cuts":matched_cuts or does that break something?
There was a problem hiding this comment.
seems sub optimal to have to reproduce the exact same set of cuts, especially considering we saved them earlier but I don't know about patching objects into the namespace directly.
wilsonmr
left a comment
There was a problem hiding this comment.
left some minor comments. Overall it is a bit ugly but I also think it's the most logical way to reliably do this.
Improve error message a bit and re-use the already computed cuts.
This is added to the guide, which is otherwise outdated, but this studd isn't anywhere at the moment.
|
Ok, I would be happy for this to be merged and not happy to think about it more. |
Add a cut option that throws away data such that predictions two
different namespaces are too different. This used the existing cuts from intersection functionality and further refines to filter points
that do not fulfill
(threshold < ratio) & (ratio < 1/threshold)
where the threshold is set as the
cut_similarity_thresholdparameterin the runcard. The two namespaces are defined as thee
cuts_intersection_spec list and the ratio is the first over the second namespace.
Some discussion:
This isn't the smartest code I have ever written.
I am using actual predictions instead of cfactors. This is because cfactors are incidental rather than physical meaningful but more importantly because it starts looking very cumbersome once one starts considering things like compound observables. I the end it pays off to do the proper job and solve the problem in general.
The use of central_predictions inside load is a bit of a hack, but
it is not clear to me it can be done much better in a more
"reportengine idiomatic" style. The logic is rather convoluted if you
sit down to think about it. In any case validphys.convolution is too
convenient for this to use anything else.
Moreover central_predictions is slow because it needs to load
fktables as csv. We should probably stick calls lru_cahces in various
places.
Tests and documentation are missing at the moment.