-
Notifications
You must be signed in to change notification settings - Fork 104
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
ROLU modified to also run with no trigger and online spectra added #896
Conversation
Added notrigger external file. Addded notrigger support for Rolu Map2Cal, Map2CalPar, Cal2Hit. Created R3BOnlineRoluSpectra. Fixed permissions on util/c3w/build_c3w.sh
Dear all (mostly @YanzhaoW, @hapol, @jose-luis-rs) Clearly, the clang-format and clang-tidy has failed. As far as I can see though, the vast majority of the issues are pointless at best. For starters, I added an ext_h101 file, which is generated using the structify.bash script in ucesb. This file is copied from the upexps to R3BRoot in order for R3BRoot users to convert the unpacked data in the lmd files to a ROOT format that we can use. The generation of these files is from the DAQ group (@inkdot7, @hanstt, @bl0x). I do not understand why I am being flagged here. I HAVE ZERO CONTROL OVER THIS FILE!!! In addition, the DAQ group has quite a nice track record when it comes to analysis support. Next, I have inherited this code and added features that enhance the code to allow us to use the code when a trigger is present and when it is not. This is necessary because ucesb does not generate duplicate signals. If you aren't happy with that,, you can gladly come to GSI and cable up ROLU and LOS yourself. And while you're at it, you can fix my VFTX too. Why am I being flagged for the structure of the code? I have been told that we should not use virtual with a destructor. But, IF EVERY SINCE CODE IN R3BROOT USES THIS FEATURE, WHY AM I BEING PUNISHED FOR USING YOUR CODE AND TEMPLATE!!! If you want to move away from this template, change it for every single detector, timestamp, etc. code. Don't hold me to a higher standard than you hold your current code. There are numerous flags about 'hard-coded' values. For example, in the header files, I am initializing some variables with default values. These are being flagged. Why? You can change them in the macros. But the default should be something reasonable. The same holds for my 2 canvases. They are also being flagged for having values, not variables. It's 2(!!!) canvases. Then there is the issue of auto. I have used the correct pointer at each place. Yet, I am being punished in the clang-tidy for knowing what the pointer is called and not just randomly assigning variables with auto. Then there is the clang-format, which is again flagging the ext_h101 file. THE FILE I STILL HAVE NO CONTROL OVER! It's formatting. This has no impact on whether the code compiles. Why can I not format my code how I choose to? Why am I being forced to put a space after a //. Besides being pedantically idiotic, I, personally, don't like it. I thought we could be ourselves in coding, as long as what our code compiles and shows functionality. I thought that was what makes 'R3BRoot beautiful'??? I will fix the places where the there are single letter variables. I will also fix the Int_t relics in the Reader that I oversaw. I will also work with Martin to fix issues he flags as problematic, given he actually understands c++ and the bullshit that's in this clang-tidy. If you choose not to merge my code, fine. However, you will not have any other merge requests again from anyone. And you will have shown that pedantic idiocracy is more important to you than functional code. Best, |
Dear Andrea Don't worry for the ext_h101 files, they don't need to pass the clang-tidy. About the clang-format, you only need to run the command clang-format -i name_of_files, but I don't know if this works at the GSI computers. In the case of #897 it worked fine for the clang-format ... I am busy with teaching duties, but I will check in the weekend. I don't see any big problems to accept this PR. Best |
TLDR: I could see all the new code in this PR is in rolu folder, which I won't read, use nor debug. So for me personally, it's perfect fine to merge it to the dev with the current state. :D You could disable clang-tidy checking for your PR by setting up additional Since clang-format checking is not implemented by me, you may ask other people about that. Here begins my lengthy comment:
ucesb is written in C code and the code generated by it is also in C style. Our static analyzer checks the code according to at least C++11 standard (12 years ago, so don't call it modern). The correct way to deal with this is to exclude all those C code from clang-tidy checking, which is not difficult to implement in our CI (I will do this in few weeks).
TEMPLATE has been fixed in #894 and will land very soon.
Code should be self-explanatory and documentation by itself. What's the meaning of 10000 in Then what's the meaning of constexpr int DEFAULT_MAX_EVENT = 10000;
int maxevent = DEFAULT_MAX_EVENT; Ok, it means the default value for maxevent because it's called so.
Same reason above. Values are just values and they don't have meanings. Named values (const or constexpr) has names to indicate their meanings.
I don't know what you mean. You may show me a specific example from your PR. Here ends my lengthy comment |
Hi Yanzhao, If we selectively enable and disable clang-tidy, what is the point in the clang-tidy? Shouldn't we just have a clang-tidy that flags the major issues instead of your preferred features? All the values that are variable have respective setters with it. The values that are not variable are hard-coded. There is no foreseeable change to, for example, the number of edges we plan to read out. Also, a variable called, for example, fClockFreq is pretty straight-forward. If you don't know what that is, then it's clear you are just completely blindly calibrating the detector. For the canvas, does this mean that I have to make a named value and give a full description of what it does? Do I need to replace it with: Just google it. The root documentation is good for this kind of thing. It's also not as demanding as you. ##[warning] use auto when initializing with a cast to avoid duplicating the type name [hicpp-use-auto,modernize-use-auto] ##[warning] use auto when initializing with a cast to avoid duplicating the type name [hicpp-use-auto,modernize-use-auto] ##[warning] use auto when initializing with new to avoid duplicating the type name [hicpp-use-auto,modernize-use-auto] Best, |
Without invading too much into that beautiful argument you are having, I think that generally, histogramming code should be subject to less scrutiny than the main data pipeline. Basically, if histogramming code avoids out of bounds memory writes, it has already exceeded my expectations. :) If magic constants appear in Mapped2Cal, I would be much more interested in what they mean than if they appear in some histogramming code. For auto, I feel that both Ceterum censio: There are clang-tidy checks which should be enforced project-wide with extreme prejudice (dynamic_cast), and there are clang-tidy checks which should at most be polite suggestions (auto). |
Hi @ajedele
Those features aren't my preference but rather some ideas that have been accumulated over decades in programming community to make the software robust, readable and efficient (in other words, to make everyone's life easier). Each rule can be found in clang website with a clear reason why it's necessary.
The point of clang-tidy is to improve the code quality of your pull request. If you are content with the bad quality code, which doesn't affect the people who hold higher standard, you could disable it. If you want to pay small extra efforts and learn how to program in a higher standard, you don't disable it.
If there is no foreseeable change to a variable, then declare it as a const. int ClockFreq {200}; // wrong
const int ClockFreq {200}; // correct, no warning
constexpr auto ClockFreq = 200; // best way
This reminds me of a joke ;D: // add x with 2
x = x + 2; Anyway here is what I would do: constexpr auto ROLU_CANVAS_X = 800;
constexpr auto ROLU_CANVAS_Y = 1000;
TCanvas *canvas = new TCanvas("rolu", "rolu", ROLU_CANVAS_X, ROLU_CANVAS_Y, ROLU_CANVAS_X, ROLU_CANVAS_Y); By this you are also telling the reader that you are choosing same values for window coordinates and window sizes deliberately WITHOUT ANY COMMENT.
I see now. Then change the first type to auto. You could google the reason but I could explain here as well. The reason why this is bad: Class1* obj = dynamic_cast<Class1*>(base_obj); is because if someone need to change it to Class1* obj = dynamic_cast<Class2*>(base_obj); This gets a compilation error at best. The worst case is an implicit cast. Ok, you could say we will NEVER forget. Then tell any security or safety person in the laboratory that some rules are unnecessary because we will never forget doing something. We could talk about these issues for days. But I don't want to bother you with these since you must have something more important to do at the moment. If it's ok to you, I will send you a pull request against this pull request to disable the clang-tidy checkings for rolu folders. In the end, you could just merge and squash. |
I basically agree with you. In some cases, magic numbers are not a big issue for the readability. But in other cases, they are a big issue, especially without any documentation (Does anyone still do documentation?). The problem is clang-tidy isn't very intelligent to differentiate those different situations. You either turn in on or off. Same goes for I would suggest to leave them on since we could have much bigger problem if they are off.
Like I said, if anyone feels clang-tidy checking is too strict, then define a separate and lesser strict setting in the corresponding folder. It's not like we have one single rule across whole project. |
There are counterexamples for auto, though. If I do not use auto, I can explicitly state my expectation of the return type: If it compiles, than the pointer will be of the type I want. From my understanding, C++ only allows implicit pointer casts which are safe, e.g. from a derived class to a base class. These should be fine. If I only care about the TPad properties, using |
I would say it's better to get an error (either compile or run time) if you mess something up. :D The worst case is when you mess something up, you don't get an error but rather an implicit conversion. I think the second case is the biggest reason.
They are some cases that could be very toxic due to implicit conversion. For example, if |
Dear @ajedele,
Pointless issues can be discussed and discarded, accepting the PR by the release manager. Finding major errors among those possibly pointless issues is relevant and could solve severe problems. There was additional explanations by @YanzhaoW above.
As we discussed and explained previously in analysis meetings, we (all) try to include the better possible code now and (unfortunately slowly) improve the existing one when any developer has to improve or correct any existing class. As you mention we do not have enough manpower. I assume that the upper case letters correspond to shouting; the name of the branch points to me that you are not happy: but I would ask you to make an effort to improve the code following the standards stablished and make use of the expert advise of the people that is now watching the code and can help in the corrections.
I tend to agree with you on that comment. If the return type is clear and should not be modified and you know what you are doing taking that return type, I would not use auto. But I'm oldfashioned on my programming and I can understand the arguments on auto by @klenze and @YanzhaoW.
You write code once (or rewrite it a few times), but you and many others read it many times. Having standards on the format is really important and help to structure code and sometimes to find errors. It is part of all scientific software development that I'm aware. Formatting with clang-format is a one-line process in the todo-list before a pull request. It should not be so stressful to produce a complain.
Code is usually accepted after improvements during the PR processing (thank you to everyone that is contributing to the corrections and improvements). It could take some time when we could not have it: that is the reason why we could open alternative branches, as we discussed in the last analysis meeting, under certain conditions. But again, writing this statement after your PR, before any other comment, does not sound very productive. Would you accept suggestions on how to modify the code to make it better or we should take it as it is (or nothing)? |
I am very open to feedback on the functionality of the code. I am also open to obvious coding flags that affect the functionality or compileability of the code. I have made sure the code compiles and that I see the ToT and hit pattern with a pulser |
Consider
If A* is implicitly convertable to B*, the only difference between using auto* and B* in line X is if the implicit conversion will happen in line X or Y. If they are not implicitly convertible, then you will get an error in either case. If the incorrect assumption was "f returns B*", then an error in line X will probably be more useful than one in line Y.
First of, I would define implementation inheritance as using inheritance to reuse code without a subtype relationship being implied (for example if you want to avoid the penalty of dynamic method dispatch). In C++, public inheritance implies a subtype relationship, hence the implicit type conversions. If you want pure implementation inheritance, the standard way is to place the base class in a namespace impl. Then g would have a signature Morale of the story: declaring variables with auto is insufficient to avoid bad implicit conversions. Having a class publicly inheriting from another class in an interface namespace when subtyping is not implied is an error. @hapol: Reading between the lines of @ajedele's comments, I am beginning to suspect that she may in fact not consider making github pull requests her great calling in life. In fact, for someone coming more from the detector side of things, using all of
just because they feels that we should have an online analysis for a detector during the next beam time is already a non-trivial ask. Getting then told just to write your own clang-tidy configuration to handle the CI issues might not be fully appreciated as the opportunity to learn more about a powerful and beautiful software tool that it objectively is. :) I have two practical suggestions:
(A bit more handholding with git would probably be even better. Assume that the user has not created a branch or committed their changes. "It seems like you are on branch dev. Would you like me to create a feature branch?", "Here are your uncommitted changes. Use git add to select the ones you want to include". Of course, handling every corner case is beyond the scope of anything short of a LLM (and possibly even them).) The other suggestion is that we should not always treat PRs as being the responsibility of the one making them. I read @ajedele's messages more as "this is my contribution, I do not have time to improve it" than "either merge my PR verbatim as-is or not at all". Like all our code, PRs are published under GPL3. This means that anyone can create another PR based on this one, polish it, tidy up all the warnings, add unit tests etc. From my reading of @jose-luis-rs comment, he basically suggested that he would do something to that effect. |
This statement is incorrect. Auto is sufficient to avoid any implicit conversions. Your example is not very suitable as well since the type of The case I was mentioning is: A* f();
A* res = f();
res->DoSomething(); Here replacing with
Sure, choose whatever suitable name for your class. But I can't see the relevance here to The "verdict" is use auto as much as possible because it's simpler, more reliable and less error-prone. It's just better and we should use it whenever possible. |
How about "Declaring variables auto will prevent unwanted implicit conversions in that declaration, but will not change if implicit conversions happen in other contexts, thus one should avoid having a class hierarchy where implicit conversions are invalid." |
Philipp and I looked at the clang-tidy changes and I modified what we thought was reasonable. I am still open to functionality suggestions. Best, |
BTW, we used the clang-format in R3BRoot. I don't understand why it failed |
Could you please give me feedback or merge the PR? |
I was teaching, sorry for that! |
ROLU:
Added reader without trigger for standard R3B use.
Added notrigger external file.
Addded notrigger support for Rolu Map2Cal, Map2CalPar, Cal2Hit. Created R3BOnlineRoluSpectra.
Fixed permissions on util/c3w/build_c3w.sh
Describe your proposal.
Mention any issue this PR is resolved or is related to.
Checklist:
dev
branch