Control Sheet No. 20
- Editorial: Celebrating Issue 20!
- ESS: Breaking New Ground in Sweden
- Managing Errors with Exceptions in C++
- Cosylab Supports Young Engineers
- Accelerator Experts go to School
- The Picture Board
By: Mark Pleško (Cosylab)
For the 20th issue of Control Sheet, we take a look back.
You’re reading our 20th issue of Control Sheet and as it is a round number, let me look back a bit in history. Control Sheet is foremost a technical newsletter, therefore I am asking for your patience if I contemplate more on the business side. The simple explanation is that I’m CEO, president or whatever similar and that I have forgotten most of the technical issues a long time ago :-). Those who know me will remember that I often say “I don’t know anything, I’m just the boss”. And it’s only half-jokingly.
Lately, we have been publishing 4 issues per year, but initially we struggled to get together enough good quality articles , so issue #1 was actually published more than six years ago , which is a long time, and you can tell! Just look at the photographs of our people, including myself :-) in the first issue . So what was happening six year ago?
In a way, the introduction of Control Sheet came at the onset of some big changes for Cosylab, although we didn’t fully realize it at that time. Actually, we started the first article in the newsletter with these - almost presumptuous - words: “New Year is usually the time for all sorts of improvements, resolutions and time to pave a road for great plans. In our case the timing is a pure coincidence, but this is how the Cosylab company actually started the year 2008,” which turned out to be more prophetic than we actually believed they would be.
Actually, the “great plans” were more or less a decision to get more organized and hopefully become a more serious company along the way - and it was about time :-). The introduction of the newsletter was one such action, streamlining sales and making a reasonable market segmentation another. And maybe the most important activity was to hold several internal workshops to figure out a coherent company strategy and align the growing number of team members to it. And so we had the “fateful” Cosylab workshop in the Slovenian countryside in May 2008.
Participants at the first 5M Workshop in May 2008.
This was our main line of thought at the workshop: By the end of 2007 we had what seemed like a nicely established “boutique” business, although only half of the revenue, about EUR 1 million, came from work on accelerator and other Big Physics control systems. Then we made a back of the envelope calculation in which we guesstimated that the attainable market should be rather about EUR 5 million per year. Naive and stupid as we were, we decided that we should therefore reach this much yearly revenue within 3 years from “now”.
We wrote ten lines in a large font on one A4 page in landscape that summarized our vision, market, competitive advantage, measurable targets and first milestones. We hung it on the inside of the door of each office, somehow hoping that if everyone looks at them each day, they will magically become true. The film The Secret  was popular at that time and maybe it influenced us, or maybe we just didn’t know how to do it any better :-).
I still remember that several people expressed open doubts on the calculation and even more just didn’t believe it would be possible to quintuple sales in only three years. Not that any of us knew at that time what we’d have to actually do to achieve our goal. Funnily, none of the “old timers” who were present admits today that he had any doubts whatsoever, including myself :-).
In any case, things started to fall into place this way or the other. We didn’t leave it at the one page. We started to systematically look for new projects, intensified our presence at conferences with booths and strongly increased the number of sales trips to potential customers. We took on larger projects where we offered the complete performance responsibility for one or several subsystems. We appointed our most organized engineer and project leader to become Chief Operating Officer (COO) to improve the efficiency of our developers and we made plans for how many people we needed to hire to actually produce work for EUR 5 million; and developed processes on how to hire the right people for the job. Still on the HRM side, we gave our people some business education and sent a bunch of them who had management potential, to management schools. We created groups/divisions that are centered around customers and led by a senior engineer with people and management skills. We required senior people to become coaches for teams of 1 to maximally 4 junior and newly hired engineers and students. At another workshop, one and a half years later, our Chief Financial Officer (CFO) already showed a reasonably solid plan, according to which we might actually achieve the 5M plan as we called it. In retrospect, he was right about one thing and wrong about another one: we did achieve (and even exceeded!) the goal, but the amount of work delivered to the customers/projects was quite different. For example, the original plan assumed 2 FTEs (full-time equivalents) for MedAustron over a long time, but we actually had a peak of 14 FTEs, because the project was accelerated. On the other hand, FAIR was delayed, so instead of the planned 7 FTE, only 2 were working on it for some time. Still, the plan was good enough, because it had foreseen more or less the correct customers.
However, there was one more wrong assumption from the workshop in 2008 that we found out after three years: there are many more accelerator projects and thus much more need for competent control system integration! Actually, it seems that by this year we will surpass a headcount of 100 employees and double the initial goal, which means that we were able to sustain this intensive growth for another 3 years. All the time, we have painstakingly made sure that we don’t trade success for our academic, open and friendly culture. Yes, we are better organized, true professionals, with worldwide presence, but we’re still the same team having fun resolving challenges and living with a healthy sense of humor and self-irony. Which I hope that this newsletter shows as well.
It would be presumptuous again to list all that has occurred at Cosylab since 2008 and even more presumptuous to attribute it to our plans and to our wisdom. A lot has happened by coincidence, we also had our fair share of luck and even more, it was you, our customers and our supporters (even if you only wear one of our Cosylab T-shirts) who really made it happen. And for this we are thankful and indebted to the whole community, even though it sounds like another cliché. I just don’t know how to phrase it better, but believe me, it comes from my heart and the hearts of all at Cosylab who were around six years ago so that we can rightfully call them “old timers”.
Cosylab’s Jože Dedič in 2008, raring to get into his new role as COO!!
ABOUT THE AUTHOR
Mark Pleško has been working with accelerators for the last 30+ years, first as a high energy physicist, then as an accelerator physicist and in the last 15 years, he has been designing and building accelerator control systems. Mark is a well known - some would say notorious - figure in the community, including but not only for publicly using a crystal ball at the 1997 ICALEPCS conference. He predicted that control system integration and turnkey control systems will be the future of accelerator control systems. As his predictions were quite radical and unlikely at that time, he had no choice but to create Cosylab to make them come true after all :-).
By: Žiga Kroflič (Cosylab)
Following the groundbreaking ceremony held on 2 September 2014, that officially signals the start of the construction of the European Spallation Source, we look at what ESS is and what is needed to control this complex machine.
The European Spallation Source (ESS)  is one of the largest science infrastructure projects being built today. The main facility will be located in Lund, Sweden, with a supporting data center in nearby Copenhagen, Denmark. ESS aims to be the brightest neutron source in the world, 30 times brighter than any existing neutron facility. With the green light for construction that was received this year, the ESS project is well under way to have first neutrons in 2019 and finish all 22 planned instruments by 2025. 
A linear accelerator will provide a 2.86 ms proton pulse at 2 GeV and a repetition rate of 14 Hz with an average power of 5 MW to a rotating tungsten target. When the proton beam hits the heavy-metal target, neutrons are emitted by a process of spallation. 22 cutting-edge neutron instruments and a supercomputing data center will offer a scientific suite to further research in the fields of life sciences, energy, environmental technologies, cultural heritage and fundamental physics. Specifically, the neutrons will be used to further the understanding of basic atomic structures and forces for various materials from these fields.
A bird’s-eye view of the ESS facility (Image courtesy of ESS/Team Henning Larsen Architects)
Besides an ambitious facility design, the ESS project is also challenging from an organizational perspective, joining 17 partner countries and a large number of industry partners under one roof - the company, European Spallation Source ESS AB.
Conceptual layout for the ESS site (Image courtesy of ESS/Team Henning Larsen Architects)
To control this complex machine, from the accelerator to target, neutron beamlines and instruments, a unique control system needs to be developed. The EPICS framework was chosen as the backbone of the ESS control system, accompanied by a number of platforms, tools and services that will together enable operators to control and diagnose the machine. Responsible for this is the Integrated Control System (ICS) division working together with Cosylab as the main subcontractor since 2010. Currently the Cosylab ESS team has more than 20 people with 4 permanently on-site in Lund.
The joint activities of the ICS and Cosylab cover all areas of the control system:
- device and subsystem integration into EPICS using the Control Box concept, standardizing hardware and software platforms and components for local control, including versatile IO capabilities, robust and flexible drivers and extensive documentation. Integration activities include beam instrumentation, RF systems, timing and synchronization, vacuum, cryogenics, conventional facilities, target, neutron beamlines and instruments.
- development environment standardizing tools used for development and deployment, such as CODAC Core System , continuous integration and test infrastructure etc.
- set of high-level applications and central services such as archiving, alarms, authentication & authorization, dedicated databases for machine and device configurations, lattice and cabling and tools for beam physicists.
To benefit from experience of established facilities and to give back to the larger physics community, ICS and Cosylab are a part of the DISCS  and OpenXAL  collaborations. DISCS is a collaborative effort between BNL, FRIB, IHEP, ESS and Cosylab, within which database-driven software services and applications are being developed. OpenXAL is a collaboration between SNS, CSNS, ESS and FRIB to provide an open source development environment used for creating accelerator physics applications, scripts and services.
How ESS Works (Image courtesy of ESS)
ABOUT THE AUTHOR
Žiga Kroflič is a Group Leader at Cosylab. He began working for Cosylab as a student while studying electrical engineering and was permanently employed in 2011. Starting with the development of real-time FPGA-based systems, such as timing systems, fast interlock systems and real-time data processing, he expanded his expertise to system architecture and management of complex control system projects. Currently, he is the project leader for the European Spallation Source project, managing a team of over 20 engineers developing the ESS control system. In his free time he enjoys making music, photography and cooking.
By: Paolo Brandoli (Cosylab)
Errors are the first thing that customers notice. Or worse, they go undetected and then they bite back some months later, amplified, leaving behind months of incorrect reports and discoveries that don’t stand the test of time.
It is almost impossible for a software program to handle all possible logic paths that the most creative users can think of, so it must not pretend that it can deal with all possible errors when it cannot. This article describes how to use C++ Software Exceptions for both expected and unexpected error conditions and how to recover (or not recover) from an erroneous state.
Software Exceptions vs Error Codes
Software exceptions allow to signal the error conditions as soon as they happen and cause the immediate execution of the exception handling code.
In contrast, error codes are values returned by functions to indicate if an error condition has happened. Error codes must be checked immediately after each function that returns them in order to identify the error conditions as soon as they happen.
Some developers dislike software exceptions because they crash the application when not handled and require exception-safe code. Some also believe that the usage of software exceptions introduces a performance tax.
In the latest generation of C++ compilers, the usage of software exceptions does not bring any loss of performance and may produce faster code compared to other techniques of error handling  .
Even coding standards for critical software that initially refused the adoption of software exceptions are now considering moving towards the acceptance of this “new” way of dealing with errors (e.g., transition from DO178B to DO178C for avionics). The initial refusal of the C++ exceptions had more to do with the tools available when the specifications were written than with the philosophy of the exceptions (e.g., see the rationale for rule AV 208 in the Joint Strike Fighter Air Vehicle C++ Coding Standards ).
Error codes are easy to use because they require less coding (when not correctly implemented), they can be ignored and they don’t require exception-safe code. While this may bring instant gratification, in the long run it may damage the results generated by the software.
Table 1: Pros and cons of managing errors with error codes and C++ exceptions
Type of error that can be signaled
Integer numbers mapped to cause of error or true/false flags
Can attach any kind of information to the error report (code, description, custom variables, etc.)
Can the error be ignored?
No, unless done intentionally
Disrupt software logic (many conditional statements)
Require an additional parameter
Yes (if the function must return a value then it requires an additional parameter that will be filled with the error or the return value)
No (useful for reporting errors in class constructors)
Yes (additional code to check the error codes)
Only when an exception is thrown (when the error happens)
Requires exception-safe code
Exception-safe code should be the norm even when the software does not use C++ exceptions at all. The term exception-safe code refers to the usage of the RAII idiom (Resource Acquisition Is Initialization), in which any usage of a resource is tied to an object that controls the resource allocation and deallocation.
We have to keep in mind that even when the software does not explicitly throw an exception, any of the APIs or methods called by the software and not directly controlled by the programmer may throw an exception at any time and therefore require the usage of RAII (e.g. most of the classes in the standard C++ library do throw exceptions to signal errors).
How to Throw an Exception
An exception should be thrown as soon as an error condition happens: the usage of the RAII idiom (resources allocation is managed by objects) allows the developer to throw the exception as soon as possible and don’t care about resources deallocation, rollbacks, etc.
An analysis of portions of a widely used open source software revealed some resource leaks that would have been avoided if the RAII idiom was used. The resource leak happened because the developers forgot to deallocate some resources before throwing exceptions and before exiting from some functions. The loss in performance introduced by RAII (if any) is balanced by the correctness of the resource management. (Figure 1)
Figure 1: RAII: a class used in a TCP API to free addrinfo structures allocated by getaddrinfo().
Exception classes should be planned carefully during the design phase. Ideally, a hierarchy of exception classes should be used to categorize the error conditions. At the root of the hierarchy there should be the standard exception classes provided by the C++ library (runtime_error, logic_error, and so on), while at the bottom of the hierarchy there should be well defined errors. This allows catching entire classes of errors or very specific error conditions. (Figure 2)
Figure 2: Hierarchy of Exception Classes thrown by a TCP-IP communication library
Contrary to what many developers believe, throwing exceptions in class constructors is legal and is the recommended way to signal errors during the construction of an object.
The alternatives to throwing exceptions in the constructor are the usage of flags that mark zombie objects (objects that are not usable because the constructor failed) or the usage of two- step initialization where each object construction is followed by a call to an initialization function. Both alternatives are not as elegant and intuitive as throwing the exception directly from the place where the error happens, the constructor.
When dealing with third party libraries that return error codes, the best strategy is to wrap the calls to the library into functions that map the library error code to specific exception classes (one class per error code).
Avoid throwing exceptions that contain an error code because they prevent catching only specific errors and they require a multitude of if/else or switch statement to know the reason of the exception.
The software should catch only the exceptions it can cope with and nothing more, even when this will cause a software crash. On most systems a crash caused by a software exception will display the exception’s class and message.
If a crash happens because we did not try to handle an unexpected software exception then the crash could actually be beneficial. In this case the crash is an immediate cause of an error that happened shortly before, and the shorter the time and executed portions of code between the anomaly and the crash, the easier it is to debug the problem and fix it properly. After the fix, the unexpected anomaly will not happen again or will become a known and expected error condition.
In contrast, a crash that happens because the programmer tried to manage an unexpected anomaly or forgot to check an error code will be much more difficult to debug and fix. These kinds of crashes are not caused by the original error, but are introduced by bad management of the unknown error condition and will leave the original cause well hidden. This kind of crash may happen months or years after the original error happened and may leave behind an important amount of incorrectly processed data.
In short, an unexpected error condition is unknown to the developer until it happens and therefore trying to manage it leaves a lot to the imagination.
There are cases in which you need a kind of “MacGyver” application, a fault tolerant software able to cope with anything you throw at it, but the solution is not just ignoring the errors or improvising a software exception catch during the coding phase: a system becomes fault tolerant by design. The architects create fault tolerant systems, not the coders.
How to Catch an Exception
As said before, the software should catch and manage only the exceptions that it can handle. When developing APIs and frameworks, consider that the main application may have a better overall picture of what is going on and therefore it may be able to catch and handle the exceptions in a nicer way.
For instance, there are very few cases when a std::bad_alloc exception can be handled nicely by an API: however the main application may be aware of some cached data that can be freed to make room for further memory allocations. In other cases, just trying to log the bad_alloc may require more memory than was required by the original failed allocation and cause a sudden crash, but this time the crash will be caused by the attempt to manage the original error and therefore it will be more difficult to debug.
Just logging an exception does not mean that the error has been resolved. A software that just logs the error condition and does nothing about it is actively hiding the error. In rare cases this may be fine, but a code reviewer should raise an eyebrow when dealing with such code. (Figure 3)
Figure 3: Don’t try this at home: Catching all the exceptions and forgetting about them.
When the exception can be caught then it should be caught by reference (possibly a constant reference) to also properly catch the derived exception classes. Once caught, an exception can be re-thrown for further processing by the caller.
The Devil’s Advocate
On the 4th of June 1996 the rocket Ariane V blew up in the skies over Kourou (French Guiana) 40 s after lift off. The cause of the unexpected pyrotechnic show? An unhandled “out-of-range” exception happened while converting a floating point value into an integer.
To add insult to injury, the incorrectly converted value was not necessary to the Ariane V and was going to be left unused: It was a leftover from the source code used in the Ariane IV.
Advocates of the “catch-all” way of dealing with exceptions would argue that if the coders had handled unknown errors then the Ariane V would have reached outer space and this paragraph would not exist: well, this is way too easy to say after the full investigation discovered the root cause of the error. The mishap started well before the rocket committed suicide 40 s after departure, and months before the launch:
- the value that triggered the wrong conversion error was not needed by the rocket and there were no specifications for it. Reusing the source code written specifically for the Ariane IV, a different rocket with different specifications, was a mistake,
- it was a design error to specify that the backup control unit was going to be identical to the primary one: when the primary unit failed, then the backup one failed with the same exception,
- the conversion of values that were useful to the Ariane V were protected from out-of-range exceptions and would not have caused the failure,
- the control unit was never tested with the flight conditions experienced by the Ariane V during its maiden flight, but only with the conditions that were common to the Ariane IV.
Now, after the full investigation, we know the root cause of the failure and we could affirm that yes, a “catch-all” statement that simply logged the exception and forgot about it would have saved the mighty Ariane V from self destruction.
We would have Ariane V rockets lifting off every now and then with that “catch-all” statement in the control unit, that maybe one day will catch and ignore an unexpected exception never thrown before by an altitude sensor and cause the rocket to continue to fly no matter what. Basically we would have a control unit on Prozac, always happy and always with a solution for every problem it faces. Imagine the citizens of Cayenne, French Guiana, watching the rocket approaching their city to deposit a telecommunication satellite in Avenue Pasteur because the control unit refuses to give up and thinks it knows better than the altitude sensor.
No, fail-safe does not mean “fly no-matter-what”, it means taking care of the basics of requirement gathering, design, implementation and testing, and to blow up a rocket if necessary.
The software should signal all the errors it encounters but should handle only errors that it recognizes and knows how to resolve, even if this brings the system to a crash, because trying to exit from an unknown error condition may cause much more severe damage than a simple crash.
Using exceptions instead of error codes helps to follow this rule, because it removes the possibility that an error conditions goes undetected (often unintentionally), together with the RAII resource management allows signaling the errors as soon as they happen (also in the object’s constructors) and simplifies the resolution of the error by concentrating the error handling code in one place.
Fault tolerant systems don’t ignore nor hide error conditions: the tolerance to errors is built into the system during the requirements gathering and design phases and must not be left as an implementation detail.
- Technical report on C++ performance ISO/IEC TR 18015:2006(E), http://www.open-std.org/jtc1/sc22/wg21/docs/TR18015.pdf
- Joint Strike Fighter Air Vehicle C++ Coding Standards http://www.stroustrup.com/JSF-AV-rules.pdf
ABOUT THE AUTHOR
Paolo Brandoli, Italian, joined Cosylab in 2013. When not diving into C++ source code he enjoys long walks or bicycle rides in Ljubljana, but occasionally he has to drive back to Italy when distant memories trigger the need for authentic Italian food.
By: Katja Perme and Marko Panjek (IEEE SB Ljubljana)
As part of Cosylab’s commitment to giving back to the scientific community, we have sponsored the IEEE Student Branch (SB) of Ljubljana  to attend the Region 8 (Europe, Africa, Middle East) Student and Young Professional Congress, held in Krakow, Poland in August 2014. The following is their report.
The SYP (Student and Young Professional)  Congress is an international event organized by the IEEE (Institute of Electrical and Electronics Engineers). This year’s congress was held in Krakow, Poland from 6 to 10 August where more than 400 students and young professionals gathered from more than 350 universities across Europe, the Middle East and Africa. The goal was to experience different cultures and to make new friendships which could lead to future professional cooperation. A huge boost was given to Career, Entrepreneurship and Social skills development and the role of IEEE in our local community.
Four electrical engineering students from IEEE Student Branch Ljubljana participated in the congress. It was an amazing experience for all of us. Apart from all the new friendships and knowledge, we have also gained plenty of new ideas for activities which we will now try to incorporate in our local student branch.
All of this would not be possible without the help from Cosylab, which funded a substantial part of our trip. We would like to thank them for giving us an opportunity to meet engineers from all over the world and to gain valuable skills which are a must-have in modern day business.
The congress took part in Krakow at one of the foremost technical universities in the world – AGH University of Science and Technology Krakow. The huge campus really felt like walking through a museum. There were many life-sized exhibits between the buildings such as an oil rig, industrial robots, solar cells, a gondola, mining vehicles, etc. We also had some great lectures by distinguished professors from all over the world as well as company representatives of Motorola, Nokia, Fideltronik, Infineon, etc.
After arriving in Krakow we attended an opening ceremony at the historic Wawel castle. The next day they took us to a gala dinner 135 m underground in the old salt mine, Wieliczka. What followed was a barbecue next to Kosciuszko Hill which is particularly interesting from an engineering point of view. The hill is artificially made and is extremely steep so they used special cables and plates to prevent landslides. On our last evening we had a chance to show the other participants a taste of our cultures. During the multicultural evening – as it was called - we had a chance to taste food and beverages from a variety of countries and to share our country’s traditions with other participants.
Experiencing such a congress is simply unforgettable. With so much to gain there is really no reason not to go. Thank you again, Cosylab, we had a great time.
IEEE Student Branch of Ljubljana members at the Student and Young Professional Congress. From left: Urban Bevc, Katja Perme, Daniel Pavlovski and Marko Panjek.
Cosylab is a partner in the oPAC (optimization of the performance of any Particle ACcelerator)  network and we are pleased to share oPAC’s report on their very successful School held in July 2014.
OPAC falls within the FP7 Marie Curie Initial Training Network (ITN) scheme.
A week-long oPAC advanced School on Accelerator Optimization took place from 7th to 11th July 2014. The event was hosted by Royal Holloway University of London (UK) and was joined by around 80 delegates from across Europe. The School covered accelerator optimization through beam physics studies, instrumentation R&D and charged particle beam simulations at an advanced level. It was opened with a welcome address by the RHUL Vice-Principal for Research and Enterprise and Dean of Science Prof. Paul Hogg. All aspects of accelerator optimization were then presented by lecturers from universities, research centres and industry throughout the week and led to many interesting discussions between participants.
Of particular interest were also the tutorials held during the week, the lively poster session on Thursday afternoon, the seminar about the discovery of the Higgs particle by Prof. Phil Burrows, University of Oxford, and a lecture about different roads into the antimatter-world by Dr. Michael Doser from CERN. The School provided excellent opportunities for networking with colleagues from other institutions and included also a visit to the city of London.
Meetings of the oPAC Steering Committee and Supervisory Board also took place during a busy week and plans were made for future events and all R&D projects within the network were discussed. Prof. Carsten P. Welsch, oPAC coordinator, said: “We received excellent feedback from the participants and had a fantastic atmosphere throughout the week. The large number of participants underlines that there is a growing need for similar training events and oPAC will provide many additional training opportunities in the near future.”
All lectures are available online via the projects’ indico site. Further information about oPAC projects can be found on the oPAC home page .
This project has received funding from the European Union’s Seventh Framework Programme for research, technological development and demonstration under grant agreement no 289485.
Marie Curie International Training Networks aim to improve career perspectives of early-stage researchers in both public and private sectors, thereby making research careers more attractive to young people. This will be achieved through a transnational networking mechanism, aimed at structuring the existing high quality initial research training capacity throughout Member States and associated countries. In particular, they aim to add to the employability of the recruited researchers through exposure to both academia and enterprise, thus extending the traditional academic research training setting and eliminating cultural and other barriers to mobility. Grants are awarded through a highly competitive process.
Participants at the Advanced School on Accelerator Optimization held in July 2014 at the Royal Holloway University of London.
Photographs from IPAC'14, LINAC14 and FEL 2014.
Did you receive a Cosylab T-shirt at a conference? We want to see a picture of you in the T-shirt next to any big (or small!) machine. Not only will we send you another T-shirt (there are many designs!), but you will also get your picture published in Control Sheet.
Send pictures to email@example.com.
Suha Alzubaidi (IAP, Goethe Universität Frankfurt) at IPAC’14.
Mikhail Yurkov (DESY), one of the pioneers of FELs, catches up on some reading on the CosyCouch.
Cosylab’s Andreja Smole with Sheng Wang (CSNS) at LINAC14.
2 thumbs up for the Cosylab-MedAustron poster from at IPAC’14.
Cosylab T-shirts, the perfect attire for breakfast, lunch or dinner! (from left Christine Darve (ESS), Eugene Tanke (ESS) & Andreja Smole (Cosylab) at LINAC14).
The crowd in front of the Cosylab booth at FEL 2014 gets restless ... "Someone said that there would be T-shirts..."
DESY’s Torsten Golz, Marie Kristin Czwalinna & Cezary Sydlo at FEL 2014.
Stefano Cleva (ELETTRA) at IPAC’14.
Gretchen Anderson and Andreja Smole at LINAC14.back to previous content